Version 0.2.7.0
svn merge -r 15346:15594 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@15595 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/.gitignore b/.gitignore
index ce9b95f..1a58486 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,60 +5,31 @@
#
# Whenever possible, prefer creating ignores in svn and then generating them
# to keep git in sync.
-/api_docs.target.mk
-/benchmarks
-/compiler.target.mk
-/create_sdk.target.mk
-/dart.Makefile
-/dart.xcodeproj
-/dart2js.target.mk
-/dart2js_bot.target.mk
-/Makefile
-/out
-/runtime.target.mk
-/samples.target.mk
-/upload_sdk.target.mk
-/xcodebuild
-/upload_sdk.vcxproj
-/dart2js.vcxproj.user
-/api_docs.vcproj
-/upload_sdk.vcxproj.filters
-/api_docs.vcxproj.user
-/dart.suo
-/dart2js.vcxproj
-/compiler.vcxproj
-/dart.sdf
-/cached_results.txt
-/chromedriver.log
-/api_docs.vcxproj
-/compiler.vcproj
-/timing_info.txt
-/compiler.vcxproj.user
-/dart.sln
-/runtime.vcproj
-/upload_sdk.vcproj
-/runtime.vcxproj.user
-/upload_sdk.vcxproj.user
-/create_sdk.vcxproj
-/create_sdk.vcxproj.filters
-/create_sdk.vcproj
-/samples.vcproj
-/dart2js.vcproj
-/create_sdk.vcxproj.user
-/runtime.vcxproj
-/build
-/*.xcodeproj
/.children
/.project
+/Makefile
+/benchmarks
+/build
+/ipch
+/out
+/xcodebuild
+/*.Makefile
+/*.opensdf
/*.pyc
+/*.sdf
+/*.sln
+/*.suo
+/*.target.mk
+/*.vcproj
+/*.vcxproj
+/*.vcxproj.filters
+/*.vcxproj.user
+/*.xcodeproj
# End generated ignores. The following are hand-added because the svn:ignore
# stuff doesn't handle them well.
-# Generated XCode projects on Mac
-*.xcodeproj
-
-# Dart Editor config files
+# Dart Editor config files - also in all subdirectories.
.children
.project
diff --git a/client/dart.js b/client/dart.js
index 1c8b333..1777e22 100644
--- a/client/dart.js
+++ b/client/dart.js
@@ -161,9 +161,14 @@
var stringified = JSON.stringify(serialize(port));
var attrName = 'dart-port:' + name;
document.documentElement.setAttribute(attrName, stringified);
- // TODO(vsm): Phase out usage of localStorage. We're leaving it in
- // temporarily for backwards compatibility.
- window.localStorage[attrName] = stringified;
+ // TODO(vsm): Phase out usage of localStorage and delete the
+ // below. We're leaving it in temporarily for backwards
+ // compatibility.
+ try {
+ window.localStorage[attrName] = stringified;
+ } catch (e) {
+ // Swallow errors (e.g., Chrome apps disallow this access).
+ }
};
window.lookupPort = function(name) {
diff --git a/compiler/.gitignore b/compiler/.gitignore
index 36e20ef..02aa8f2 100644
--- a/compiler/.gitignore
+++ b/compiler/.gitignore
@@ -1,32 +1,39 @@
-/domlib_sources.gypi
-/test_sources.xml
-/compiler_corelib_sources.gypi
-/dummy.target.mk
-/dartc.target.mk
-/dart_analyzer.target.mk
-/test_sources.gypi
-/sources.gypi
-/jsonlib_sources.xml
-/domlib_sources.xml
/compiler
-/Makefile
-/corelib_sources.xml
-/sources.xml
/third_party
-/corelib_sources.gypi
-/htmllib_sources.xml
-/htmllib_sources.gypi
-/jsonlib_sources.gypi
+/compiler_corelib_sources.gypi
/compiler_corelib_sources.xml
-/dart-compiler.Makefile
-/dart-compiler.xcodeproj
+/corelib_sources.gypi
+/corelib_sources.xml
+/domlib_sources.gypi
+/domlib_sources.xml
+/htmllib_sources.gypi
+/htmllib_sources.xml
+/isolatelib_sources.gypi
+/isolatelib_sources.xml
+/jsonlib_sources.gypi
+/jsonlib_sources.xml
+/sources.gypi
+/sources.xml
+/test_sources.gypi
+/test_sources.xml
/out
/xcodebuild
-/isolatelib_sources.xml
-/isolatelib_sources.gypi
-/Release_ia32
-/Debug_ia32
+/Debug
+/DebugARM
+/DebugIA32
+/DebugSIMARM
+/DebugX64
+/Release
+/ReleaseARM
+/ReleaseIA32
+/ReleaseSIMARM
+/ReleaseX64
+/Makefile
+/*.Makefile
+/*.sln
+/*.target.mk
/*.vcproj
/*.vcxproj
/*.vcxproj.filters
/*.vcxproj.user
+/*.xcodeproj
diff --git a/compiler/java/com/google/dart/compiler/CommandLineOptions.java b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
index e264801..440b7bb 100644
--- a/compiler/java/com/google/dart/compiler/CommandLineOptions.java
+++ b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
@@ -117,6 +117,10 @@
usage = "For debugging, continue on with resolution even if there are parse errors.")
private boolean resolveDespiteParseErrors;
+ @Option(name = "--type-checks-for-inferred-types",
+ usage = "[not in spec] Enables 'interface has no method/field' for receivers with inferred types.")
+ private boolean typeChecksForInferredTypes = false;
+
@Option(name = "--version",
usage = "Show analyzer version")
private boolean showVersion = false;
@@ -157,7 +161,7 @@
* Returns whether inferred types should be used for type checks.
*/
public boolean typeChecksForInferredTypes() {
- return false;
+ return this.typeChecksForInferredTypes;
}
/**
diff --git a/compiler/java/com/google/dart/compiler/DartCompiler.java b/compiler/java/com/google/dart/compiler/DartCompiler.java
index 5cb4e52..6900a50 100644
--- a/compiler/java/com/google/dart/compiler/DartCompiler.java
+++ b/compiler/java/com/google/dart/compiler/DartCompiler.java
@@ -408,10 +408,14 @@
throws IOException {
String libSpec = libNode.getText();
LibrarySource dep;
- if (PackageLibraryManager.isDartSpec(libSpec)) {
- dep = context.getSystemLibraryFor(libSpec);
- } else {
- dep = libSrc.getImportFor(libSpec);
+ try {
+ if (PackageLibraryManager.isDartSpec(libSpec)) {
+ dep = context.getSystemLibraryFor(libSpec);
+ } else {
+ dep = libSrc.getImportFor(libSpec);
+ }
+ } catch (Throwable e) {
+ return null;
}
if (dep == null || !dep.exists()) {
return null;
diff --git a/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java b/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java
index bbf3851..a908369 100644
--- a/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java
+++ b/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java
@@ -24,22 +24,42 @@
@Override
public void format(DartCompilationError event) {
- String sourceName = "<unknown-source-file>";
- Source sourceFile = event.getSource();
- String includeFrom = getImportString(sourceFile);
-
- if (sourceFile != null) {
- sourceName = sourceFile.getUri().toString();
- }
- outputStream.printf("%s:%d:%d: %s%s\n",
- sourceName,
- event.getLineNumber(),
- event.getColumnNumber(),
- event.getMessage(),
- includeFrom);
+ StringBuilder buf = new StringBuilder();
+ appendError(buf, event);
+ outputStream.print(buf);
+ outputStream.print("\n");
}
- public String getImportString(Source sourceFile) {
+ protected void appendError(StringBuilder buf, DartCompilationError error) {
+ Source source = error.getSource();
+ String sourceName = getSourceName(source);
+ int line = error.getLineNumber();
+ int col = error.getColumnNumber();
+ int length = error.getLength();
+ if (errorFormat == ErrorFormat.MACHINE) {
+ buf.append(String.format(
+ "%s|%s|%s|%s|%d|%d|%d|%s",
+ escapePipe(error.getErrorCode().getErrorSeverity().toString()),
+ escapePipe(error.getErrorCode().getSubSystem().toString()),
+ escapePipe(error.getErrorCode().toString()),
+ escapePipe(sourceName),
+ line,
+ col,
+ length,
+ escapePipe(error.getMessage())));
+ } else {
+ String includeFrom = getImportString(source);
+ buf.append(String.format(
+ "%s:%d:%d: %s%s",
+ sourceName,
+ line,
+ col,
+ error.getMessage(),
+ includeFrom));
+ }
+ }
+
+ protected static String getImportString(Source sourceFile) {
String includeFrom = "";
if (sourceFile instanceof DartSource) {
LibrarySource lib = ((DartSource) sourceFile).getLibrary();
@@ -49,4 +69,25 @@
}
return includeFrom;
}
+
+ protected static String getSourceName(Source source) {
+ if (source instanceof UrlDartSource) {
+ return source.getUri().toString();
+ }
+ if (source != null) {
+ return source.getName();
+ }
+ return "<unknown-source-file>";
+ }
+
+ protected static String escapePipe(String input) {
+ StringBuilder result = new StringBuilder();
+ for (char c : input.toCharArray()) {
+ if (c == '\\' || c == '|') {
+ result.append('\\');
+ }
+ result.append(c);
+ }
+ return result.toString();
+ }
}
diff --git a/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java b/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java
index 315a8fb..0baa651 100644
--- a/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java
+++ b/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java
@@ -85,27 +85,7 @@
buf.append(event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING
? WARNING_BOLD_COLOR : ERROR_BOLD_COLOR);
}
- if (errorFormat == ErrorFormat.MACHINE) {
- buf.append(String.format(
- "%s|%s|%s|%s|%d|%d|%d|%s",
- escapePipe(event.getErrorCode().getErrorSeverity().toString()),
- escapePipe(event.getErrorCode().getSubSystem().toString()),
- escapePipe(event.getErrorCode().toString()),
- escapePipe(getSourceName(sourceFile)),
- event.getLineNumber(),
- 1 + col,
- length,
- escapePipe(event.getMessage())));
- } else {
- String sourceName = sourceFile.getUri().toString();
- String includeFrom = getImportString(sourceFile);
- buf.append(String.format(
- "%s:%d: %s%s",
- sourceName,
- event.getLineNumber(),
- event.getMessage(),
- includeFrom));
- }
+ appendError(buf, event);
if (useColor) {
buf.append(NO_COLOR);
}
@@ -153,24 +133,6 @@
}
}
}
-
- private static String getSourceName(Source source) {
- if (source instanceof UrlDartSource) {
- return source.getUri().toString();
- }
- return source.getName();
- }
-
- private String escapePipe(String input) {
- StringBuilder result = new StringBuilder();
- for (char c : input.toCharArray()) {
- if (c == '\\' || c == '|') {
- result.append('\\');
- }
- result.append(c);
- }
- return result.toString();
- }
private String getLineAt(BufferedReader reader, int line) throws IOException {
if (line <= 0) {
diff --git a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java b/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
index 6ea6314..63626bc 100644
--- a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
+++ b/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
@@ -43,7 +43,7 @@
public URI expandRelativeDartUri(URI uri) throws AssertionError {
String host = uri.getHost();
- if (host == null) {
+ if (host == null && uri.getAuthority() == null) {
String spec = uri.getSchemeSpecificPart();
String replacement = expansionMap.get(spec);
if (replacement != null) {
@@ -94,6 +94,7 @@
public URI translateDartUri(URI uri) {
String host = uri.getHost();
+
SystemLibrary library = hostMap.get(host);
if (library != null) {
return library.translateUri(uri);
@@ -101,6 +102,10 @@
if (host != null) {
return libraryProvider.resolveHost(host, uri);
}
+ String authorithy = uri.getAuthority();
+ if (authorithy != null){
+ return libraryProvider.resolveHost(authorithy, uri);
+ }
throw new RuntimeException("No system library defined for " + uri);
}
diff --git a/compiler/java/com/google/dart/compiler/UrlLibrarySource.java b/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
index f5ec48c..e762294 100644
--- a/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
+++ b/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
@@ -35,7 +35,7 @@
}
try {
// Force the creation of an escaped relative URI to deal with spaces, etc.
- URI uri = getUri().resolve(new URI(null, null, relPath, null, null)).normalize();
+ URI uri = getImportBaseUri().resolve(new URI(null, null, relPath, null, null)).normalize();
String path = uri.getPath();
// Resolve relative reference out of one system library into another
if (PackageLibraryManager.isDartUri(uri)) {
@@ -69,7 +69,7 @@
}
try {
// Force the creation of an escaped relative URI to deal with spaces, etc.
- URI uri = getUri().resolve(new URI(null, null, relPath, null, null)).normalize();
+ URI uri = getImportBaseUri().resolve(new URI(null, null, relPath, null, null)).normalize();
if (PackageLibraryManager.isPackageUri(uri)) {
URI fileUri = packageLibraryManager.resolveDartUri(uri);
if (fileUri != null) {
@@ -121,5 +121,13 @@
String path = uri.getPath();
return path == null || new File(path).exists();
}
-
+
+ /**
+ * @return the {@link URI} to use as a base for resolving imports. Usually same as {@link #getUri()},
+ * but in case of Dart code in HTML may be mapped {@link URI}.
+ */
+ protected URI getImportBaseUri() {
+ return getUri();
+ }
+
}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java b/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java
index 91818ad..6ab02f5 100644
--- a/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java
+++ b/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java
@@ -8,18 +8,25 @@
* Represents a Dart 'catch' block.
*/
public class DartCatchBlock extends DartStatement {
- private DartParameter exception;
- private DartParameter stackTrace;
- private DartBlock block;
+ private final int onTokenOffset;
+ private final DartParameter exception;
+ private final DartParameter stackTrace;
+ private final DartBlock block;
public DartCatchBlock(DartBlock block,
+ int onTokenOffset,
DartParameter exception,
DartParameter stackTrace) {
this.block = becomeParentOf(block);
+ this.onTokenOffset = onTokenOffset;
this.exception = becomeParentOf(exception);
this.stackTrace = becomeParentOf(stackTrace);
}
+ public int getOnTokenOffset() {
+ return onTokenOffset;
+ }
+
public DartParameter getException() {
return exception;
}
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index 1482111..591c54a 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -654,9 +654,7 @@
protected DartExportDirective parseExportDirective() {
beginExportDirective();
next(); // "export"
- beginLiteral();
- expect(Token.STRING);
- DartStringLiteral libUri = done(DartStringLiteral.get(ctx.getTokenString()));
+ DartStringLiteral libUri = parseUri();
List<ImportCombinator> combinators = new ArrayList<ImportCombinator>();
while (peekPseudoKeyword(0, HIDE_KEYWORD) || peekPseudoKeyword(0, SHOW_KEYWORD)) {
@@ -682,10 +680,7 @@
protected DartImportDirective parseImportDirective() {
beginImportDirective();
next(); // "import"
- beginLiteral();
- expect(Token.STRING);
- DartStringLiteral libUri = done(DartStringLiteral.get(ctx.getTokenString()));
-
+ DartStringLiteral libUri = parseUri();
// allow "native" if we have "dart-ext:" import
if (StringUtils.startsWith(libUri.getValue(), "dart-ext:")) {
allowNativeKeyword = true;
@@ -741,9 +736,7 @@
reportDeprecatedError(position(), ParserErrorCode.DEPRECATED_IMPORT_DIRECTIVE);
expect(Token.LPAREN);
- beginLiteral();
- expect(Token.STRING);
- DartStringLiteral libUri = done(DartStringLiteral.get(ctx.getTokenString()));
+ DartStringLiteral libUri = parseUri();
// allow "native" if we have "dart-ext:" import
if (StringUtils.startsWith(libUri.getValue(), "dart-ext:")) {
@@ -787,9 +780,7 @@
expect(Token.SOURCE);
reportDeprecatedError(position(), ParserErrorCode.DEPRECATED_SOURCE_DIRECTIVE);
expect(Token.LPAREN);
- beginLiteral();
- expect(Token.STRING);
- DartStringLiteral sourceUri = done(DartStringLiteral.get(ctx.getTokenString()));
+ DartStringLiteral sourceUri = parseUri();
expectCloseParen();
expect(Token.SEMICOLON);
return new DartSourceDirective(sourceUri);
@@ -809,10 +800,8 @@
expect(Token.RESOURCE);
reportError(position(), ParserErrorCode.DEPRECATED_RESOURCE_DIRECTIVE);
expect(Token.LPAREN);
- beginLiteral();
- expect(Token.STRING);
@SuppressWarnings("unused")
- DartStringLiteral resourceUri = done(DartStringLiteral.get(ctx.getTokenString()));
+ DartStringLiteral sourceUri = parseUri();
expectCloseParen();
expect(Token.SEMICOLON);
}
@@ -820,9 +809,7 @@
private DartNativeDirective parseNativeDirective() {
expect(Token.NATIVE);
expect(Token.LPAREN);
- beginLiteral();
- expect(Token.STRING);
- DartStringLiteral nativeUri = done(DartStringLiteral.get(ctx.getTokenString()));
+ DartStringLiteral nativeUri = parseUri();
expect(Token.RPAREN);
expect(Token.SEMICOLON);
return new DartNativeDirective(nativeUri);
@@ -2891,6 +2878,21 @@
return offset;
}
+ private DartStringLiteral parseUri() {
+ DartExpression str = parseStringWithPasting();
+ if (str instanceof DartStringLiteral) {
+ return (DartStringLiteral) str;
+ } else if (str != null) {
+ reportError(str, ParserErrorCode.URI_CANNOT_USE_INTERPOLATION);
+ DartStringLiteral result = DartStringLiteral.get("<invalid-uri>");
+ result.setSourceInfo(str.getSourceInfo());
+ return result;
+ } else {
+ expect(Token.STRING);
+ return DartStringLiteral.get(null);
+ }
+ }
+
/**
* Instances of the class {@code DepthCounter} represent the number of less than tokens that have
* not yet been matched.
@@ -5078,6 +5080,7 @@
if (peekPseudoKeyword(0, ON_KEYWORD)) {
beginCatchClause();
next();
+ int onTokenOffset = position();
DartTypeNode exceptionType = parseTypeAnnotation();
DartParameter exception = null;
DartParameter stackTrace = null;
@@ -5104,7 +5107,7 @@
setMetadata(exception, metadata);
}
DartBlock block = parseBlock();
- catches.add(done(new DartCatchBlock(block, exception, stackTrace)));
+ catches.add(done(new DartCatchBlock(block, onTokenOffset, exception, stackTrace)));
} else {
beginCatchClause();
next();
@@ -5137,7 +5140,7 @@
}
expectCloseParen();
DartBlock block = parseBlock();
- catches.add(done(new DartCatchBlock(block, exception, stackTrace)));
+ catches.add(done(new DartCatchBlock(block, -1, exception, stackTrace)));
}
}
diff --git a/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java b/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
index 1e458cb..25563a7 100644
--- a/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
@@ -141,6 +141,7 @@
UNREACHABLE_CODE_IN_CASE(ErrorSeverity.WARNING, "Unreachable code in case statement"),
UNEXPECTED_TOKEN("Unexpected token '%s'"),
UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION("Unexpected token in string interpolation: %s"),
+ URI_CANNOT_USE_INTERPOLATION("URIs cannot use string interpolation"),
VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION("'var' is not allowed on a method definition"),
VOID_FIELD("Field cannot be of type void"),
VOID_PARAMETER("Parameter cannot be of type void");
diff --git a/compiler/java/com/google/dart/compiler/resolver/Elements.java b/compiler/java/com/google/dart/compiler/resolver/Elements.java
index 66aa87c..e0474b5 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Elements.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Elements.java
@@ -912,6 +912,9 @@
if (element.getModifiers().isExternal()) {
return false;
}
+ if (element.getModifiers().isNative()) {
+ return false;
+ }
if (element.getModifiers().isStatic()) {
return false;
}
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index 66308b2..df2b8e6 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -723,23 +723,10 @@
}
DartBlock body = functionNode.getBody();
- boolean isInterface = false;
- boolean isAbstractClass = false;
- if (ElementKind.of(member.getEnclosingElement()).equals(ElementKind.CLASS)) {
- ClassElement cl = (ClassElement) member.getEnclosingElement();
- isInterface = cl.isInterface();
- isAbstractClass = cl.getModifiers().isAbstract();
- }
-
if (body == null) {
if (member.getModifiers().isStatic() && !member.getModifiers().isExternal()) {
onError(functionNode, ResolverErrorCode.STATIC_METHOD_MUST_HAVE_BODY);
}
-// else if (!Elements.isNonFactoryConstructor(member) && !member.getModifiers().isAbstract()
-// && !member.getModifiers().isExternal() && node.getRedirectedTypeName() == null
-// && !(isInterface || isAbstractClass)) {
-// onError(functionNode, ResolverErrorCode.METHOD_MUST_HAVE_BODY);
-// }
}
resolve(functionNode.getBody());
@@ -1768,7 +1755,11 @@
}
break;
case TYPE_VARIABLE:
- onError(x.getConstructor(), ResolverErrorCode.NEW_EXPRESSION_CANT_USE_TYPE_VAR);
+ if (x.isConst() ) {
+ onError(x.getConstructor(), ResolverErrorCode.CONST_EXPRESSION_CANT_USE_TYPE_VAR);
+ } else {
+ onError(x.getConstructor(), ResolverErrorCode.NEW_EXPRESSION_CANT_USE_TYPE_VAR);
+ }
return null;
default:
break;
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
index f40fd84..bd33b9a 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
@@ -67,6 +67,7 @@
CONST_CLASS_WITH_NONFINAL_FIELDS("Const class %s cannot have non-final field %s"),
CONST_CONSTRUCTOR_CANNOT_HAVE_BODY("A const constructor cannot have a body"),
CONST_CONSTRUCTOR_MUST_CALL_CONST_SUPER("const constructor must call const super constructor"),
+ CONST_EXPRESSION_CANT_USE_TYPE_VAR("Const expression cannot be invoked on type variable"),
CONST_MAP_WITH_TYPE_VARIABLE("Const map literals cannot have a type variable as a type argument"),
CONST_WITH_TYPE_VARIABLE("Const constructor cannot be invoked with a type variable as a type argument"),
CONSTANTS_MUST_BE_INITIALIZED("constants must be initialized"),
@@ -123,9 +124,9 @@
FINAL_FIELD_MUST_BE_INITIALIZED("The final field %s must be initialized"),
FORMAL_PARAMETER_NAME_EXPECTED("Formal parameter name expected"),
// TODO(zundel): error message needs JUnit test - how to test #imports in junit?
- ILLEGAL_ACCESS_TO_PRIVATE("'%s' is private and not defined in this library"),
+ ILLEGAL_ACCESS_TO_PRIVATE(ErrorSeverity.WARNING, "'%s' is private and not defined in this library"),
// TODO(zundel): error message needs JUnit test - how to test #imports in junit?
- ILLEGAL_ACCESS_TO_PRIVATE_MEMBER("\"%s\" refers to \"%s\" which is in a different library"),
+ ILLEGAL_ACCESS_TO_PRIVATE_MEMBER("ErrorSeverity.WARNING, \"%s\" refers to \"%s\" which is in a different library"),
ILLEGAL_FIELD_ACCESS_FROM_STATIC("Illegal access of instance field %s from static scope"),
ILLEGAL_METHOD_ACCESS_FROM_STATIC("Illegal access of instance method %s from static scope"),
INITIALIZER_ONLY_IN_GENERATIVE_CONSTRUCTOR("Initializers are allowed only in non-redirecting generative constructors"),
@@ -156,7 +157,7 @@
"Constructor cannot have the same name as the name of a member declared in the enclosing class"),
METHOD_MUST_HAVE_BODY(ErrorSeverity.WARNING, "Method must have a body in a non-abstract class"),
NAMED_PARAMETERS_CANNOT_START_WITH_UNDER("Named parameters cannot start with an '_' character"),
- NEW_EXPRESSION_CANT_USE_TYPE_VAR("New expression cannot be invoked on type variable"),
+ NEW_EXPRESSION_CANT_USE_TYPE_VAR(ErrorSeverity.WARNING, "New expression cannot be invoked on type variable"),
NEW_EXPRESSION_NOT_CONSTRUCTOR(
ErrorSeverity.WARNING, "New expression does not resolve to a constructor"),
NEW_EXPRESSION_NOT_CONST_CONSTRUCTOR("New expression does not resolve to a const constructor"),
@@ -209,7 +210,8 @@
TYPE_VARIABLE_DOES_NOT_MATCH("Type variable %s does not match %s in default class %s."),
TYPE_PARAMETERS_MUST_MATCH_EXACTLY(
"Type parameters in default declaration must match referenced class exactly"),
- TYPE_VARIABLE_IN_STATIC_CONTEXT("cannot access type variable %s in static context"),
+ TYPE_VARIABLE_IN_STATIC_CONTEXT(ErrorSeverity.WARNING, "cannot access type variable %s in static context"),
+ TYPE_VARIABLE_IN_STATIC_CONTEXT_ERROR("cannot access type variable %s in static context"),
TYPE_VARIABLE_NOT_ALLOWED_IN_IDENTIFIER(
"type variables are not allowed in identifier expressions"),
USE_ASSIGNMENT_ON_SETTER("Use assignment to set field '%s'"),
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index ea351ca..e7fcd7e 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -663,7 +663,8 @@
// report problem
if (member == null && problemTarget != null) {
if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(itype)) {
- if (typeChecksForInferredTypes || !TypeQuality.isInferred(receiver)) {
+ if (typeChecksForInferredTypes && !isTooGenericInferredType(receiver)
+ || !TypeQuality.isInferred(receiver)) {
ErrorCode code = TypeQuality.isInferred(receiver)
? TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED
: TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED;
@@ -1606,7 +1607,8 @@
// remember unimplemented members
{
List<Element> unimplementedMembers = findUnimplementedMembers(element);
- if (!node.getModifiers().isAbstract() && !unimplementedMembers.isEmpty()) {
+ if (!node.getModifiers().isAbstract() && !unimplementedMembers.isEmpty() &&
+ (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(type))) {
StringBuilder sb = getUnimplementedMembersMessage(element, unimplementedMembers);
onError(node.getName(), TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS,
node.getName(), sb.toString());
@@ -1785,9 +1787,15 @@
Member iteratorMember = lookupMember(iterableType, "iterator", iterableExpression);
Type elementType = null;
if (iteratorMember != null) {
+ Type memberReturnType = null;
if (TypeKind.of(iteratorMember.getType()) == TypeKind.FUNCTION) {
FunctionType iteratorMethod = (FunctionType) iteratorMember.getType();
- InterfaceType asInstanceOf = types.asInstanceOf(iteratorMethod.getReturnType(),
+ memberReturnType = iteratorMethod.getReturnType();
+ } else if (ElementKind.of(iteratorMember.getElement()) == ElementKind.FIELD) {
+ memberReturnType = iteratorMember.getType();
+ }
+ if (memberReturnType != null) {
+ InterfaceType asInstanceOf = types.asInstanceOf(memberReturnType,
dynamicIteratorType.getElement());
if (asInstanceOf != null) {
elementType = asInstanceOf.getArguments().get(0);
@@ -1795,8 +1803,7 @@
} else {
InterfaceType expectedIteratorType = dynamicIteratorType.subst(
Arrays.asList(variableType), dynamicIteratorType.getElement().getTypeParameters());
- typeError(iterableExpression,
- TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE,
+ typeError(iterableExpression, TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE,
expectedIteratorType);
}
} else {
@@ -2369,7 +2376,8 @@
// report "not a member"
if (member == null) {
if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(cls)) {
- if (typeChecksForInferredTypes || !TypeQuality.isInferred(receiver)) {
+ if (typeChecksForInferredTypes && !isTooGenericInferredType(receiver)
+ || !TypeQuality.isInferred(receiver)) {
TypeErrorCode errorCode = TypeQuality.isInferred(receiver)
? TypeErrorCode.NOT_A_MEMBER_OF_INFERRED : TypeErrorCode.NOT_A_MEMBER_OF;
typeError(node.getName(), errorCode, name, cls);
@@ -3617,4 +3625,18 @@
&& Elements.isCoreLibrarySource(type.getElement().getSourceInfo().getSource())
&& type.getElement().getName().equals(name);
}
+
+ /**
+ * Sometimes inferred type is too generic - such as "Object" or "Collection", so there are no
+ * reason to reports problems.
+ */
+ private static boolean isTooGenericInferredType(Type type) {
+ if (TypeQuality.of(type) == TypeQuality.INFERRED) {
+ String typeName = type.getElement().getName();
+ if ("Object".equals(typeName) || "Collection".equals(typeName)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java b/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java
index 471654d..94839a9 100644
--- a/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java
+++ b/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java
@@ -104,7 +104,7 @@
String errorString = getErrorString(error, false, false);
assertEquals(
Joiner.on("\n").join(
- "my/path/Test.dart:1: no such type \"Foo\" (sourced from Test_app)",
+ "my/path/Test.dart:1:3: no such type \"Foo\" (sourced from Test_app)",
" 1: lineAAA",
" ~~~",
""),
@@ -122,7 +122,7 @@
String errorString = getErrorString(error, false, false);
assertEquals(
Joiner.on("\n").join(
- "my/path/Test.dart:2: no such type \"Foo\" (sourced from Test_app)",
+ "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)",
" 1: lineAAA",
" 2: lineBBB",
" ~~~~~",
@@ -141,7 +141,7 @@
assertEquals(
Joiner.on("\n").join(
WARNING_BOLD_COLOR
- + "my/path/Test.dart:2: no such type \"Foo\" (sourced from Test_app)"
+ + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
+ NO_COLOR,
" 1: lineAAA",
" 2: li" + WARNING_COLOR + "neBBB" + NO_COLOR,
@@ -153,7 +153,7 @@
assertEquals(
Joiner.on("\n").join(
ERROR_BOLD_COLOR
- + "my/path/Test.dart:2: no such type \"Foo\" (sourced from Test_app)"
+ + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
+ NO_COLOR,
" 1: lineAAA",
" 2: li" + ERROR_COLOR + "neBBB" + NO_COLOR,
@@ -172,7 +172,7 @@
String errorString = getErrorString(error, false, false);
assertEquals(
Joiner.on("\n").join(
- "my/path/Test.dart:2: no such type \"Foo\" (sourced from Test_app)",
+ "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)",
" 1: lineAAA",
" 2: lineBBB",
" ~~~",
@@ -191,7 +191,7 @@
assertEquals(
Joiner.on("\n").join(
WARNING_BOLD_COLOR
- + "my/path/Test.dart:2: no such type \"Foo\" (sourced from Test_app)"
+ + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
+ NO_COLOR,
" 1: lineAAA",
" 2: li" + WARNING_COLOR + "neB" + NO_COLOR + "BB",
@@ -203,7 +203,7 @@
assertEquals(
Joiner.on("\n").join(
ERROR_BOLD_COLOR
- + "my/path/Test.dart:2: no such type \"Foo\" (sourced from Test_app)"
+ + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
+ NO_COLOR,
" 1: lineAAA",
" 2: li" + ERROR_COLOR + "neB" + NO_COLOR + "BB",
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
index 3b08569..7ef53ab 100644
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
+++ b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
@@ -589,6 +589,23 @@
}
/**
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6859
+ */
+ public void test_reportMissingImport_dart() throws Exception {
+ appSource.setContent(
+ APP,
+ makeCode(
+ "// filler filler filler filler filler filler filler filler filler filler filler",
+ "library app;",
+ "import 'dart:mirrors as mirrors';",
+ ""));
+ compile();
+ // Check that errors where reported (and in correct time).
+ assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 33));
+ }
+
+ /**
* Test that same prefix can be used to import several libraries.
*/
public void test_samePrefix_severalLibraries() throws Exception {
diff --git a/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java b/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
index 496653f..4f9415a 100644
--- a/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
+++ b/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
@@ -46,6 +46,27 @@
import java.util.List;
public class SyntaxTest extends AbstractParserTest {
+ /**
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6881
+ */
+ public void test_uri_adjacent() {
+ parseUnit("test.dart", Joiner.on("\n").join(
+ "import 'myLib' '.dart';",
+ ""));
+ }
+ /**
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6881
+ */
+ public void test_uri_interpolation() {
+ parseUnit("test.dart", Joiner.on("\n").join(
+ "import 'my$x' '.dart';",
+ "var a = 'Lib';",
+ ""),
+ ParserErrorCode.URI_CANNOT_USE_INTERPOLATION, 1, 8);
+ }
+
public void test_exportDirective_combinators() {
parseUnit("test.dart", Joiner.on("\n").join(
"library lib;",
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
index e27f146..fa7c795 100644
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
+++ b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
@@ -393,6 +393,18 @@
"}"),
ResolverErrorCode.NEW_EXPRESSION_CANT_USE_TYPE_VAR);
}
+
+ public void testConstExpression4() {
+ // New expression tied to an unbound type variable is not allowed.
+ resolveAndTest(Joiner.on("\n").join(
+ "class Object {}",
+ "class Foo<T> {",
+ " T create() {",
+ " return const T();",
+ " }",
+ "}"),
+ ResolverErrorCode.CONST_EXPRESSION_CANT_USE_TYPE_VAR);
+ }
public void testNewExpression5() {
// More cowbell. (Foo<T> isn't a type yet)
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index dd81e86..bfada16 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -617,6 +617,49 @@
}
}
+ /**
+ * When class implements "noSuchMethod", we presume that it will handle unimplemented methods.
+ * <p>
+ * http://code.google.com/p/dart/issues/detail?id=6964
+ */
+ public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplementedMethod_noSuchMethod()
+ throws Exception {
+ // report by default
+ {
+ AnalyzeLibraryResult libraryResult =
+ analyzeLibrary(
+ "class A {",
+ " void foo();",
+ " noSuchMethod(InvocationMirror m) {}",
+ "}",
+ "main() {",
+ " new A();",
+ "}");
+ assertErrors(
+ libraryResult.getErrors(),
+ errEx(TypeErrorCode.CONTRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
+ }
+ // disable warnings if has "noSuchMethod"
+ {
+ compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
+ @Override
+ public boolean reportNoMemberWhenHasInterceptor() {
+ return false;
+ }
+ });
+ AnalyzeLibraryResult libraryResult =
+ analyzeLibrary(
+ "class A {",
+ " void foo();",
+ " noSuchMethod(InvocationMirror m) {}",
+ "}",
+ "main() {",
+ " new A();",
+ "}");
+ assertErrors(libraryResult.getErrors());
+ }
+ }
+
public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_getter()
throws Exception {
AnalyzeLibraryResult libraryResult =
@@ -3052,6 +3095,37 @@
}
/**
+ * Sometimes inferred type is too generic - such as "Object" or "Collection", so there are no
+ * reason to reports problems.
+ */
+ public void test_typesPropagation_dontWant_ifTooGeneric() throws Exception {
+ compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
+ @Override
+ public boolean typeChecksForInferredTypes() {
+ return true;
+ }
+ });
+ AnalyzeLibraryResult libraryResult = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "typedef void HandlerObject(Object o);",
+ "typedef void HandlerCollection(Collection o);",
+ "fObject(HandlerObject h) {}",
+ "fCollection(HandlerCollection h) {}",
+ "main() {",
+ " fObject((x) {",
+ " x.myNoSuchField;",
+ " x.myNoSuchMethod();",
+ " });",
+ " fCollection((x) {",
+ " x.myNoSuchField;",
+ " x.myNoSuchMethod();",
+ " });",
+ "}",
+ "");
+ assertErrors(libraryResult.getErrors());
+ }
+
+ /**
* Helpful (but not perfectly satisfying Specification) type of "conditional" is intersection of
* then/else types, not just their "least upper bounds". And this corresponds runtime behavior.
*/
@@ -5695,4 +5769,74 @@
assertErrors(result.getErrors(),
errEx(ResolverErrorCode.VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER, 3, 11, 1));
}
+
+ public void test_ForEachStatement_method() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "class A {",
+ " Iterator<int> iterator() {}",
+ "}",
+ "main() {",
+ " A a = new A();",
+ " for (int v in a) {}",
+ "}",
+ "");
+ assertErrors(result.getErrors());
+ }
+
+ public void test_ForEachStatement_negative_method_invalidReturnType() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "class A {",
+ " int iterator() {}",
+ "}",
+ "main() {",
+ " A a = new A();",
+ " for (int v in a) {}",
+ "}",
+ "");
+ assertErrors(
+ result.getErrors(),
+ errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
+ }
+
+ /**
+ * It was negative test, but in the new <code>Iterator</code> field should be also supported.
+ */
+ public void test_ForEachStatement_field() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "class A {",
+ " Iterator iterator;",
+ "}",
+ "main() {",
+ " A a = new A();",
+ " for (int v in a) {}",
+ "}",
+ "");
+ assertErrors(result.getErrors());
+// Map<String, ClassNodeElement> fieldNotMethod = loadSource(
+// "class A {",
+// " int iterator;",
+// "}",
+// "class B {",
+// " main() { for (int i in new A()) {}}",
+// "}");
+// analyzeClasses(fieldNotMethod, TypeErrorCode.FOR_IN_WITH_ITERATOR_FIELD);
+ }
+
+ public void test_ForEachStatement_negative_field_invalidReturnType() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "class A {",
+ " int iterator;",
+ "}",
+ "main() {",
+ " A a = new A();",
+ " for (int v in a) {}",
+ "}",
+ "");
+ assertErrors(result.getErrors(),
+ errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
+ }
}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
index c4396fa..5889eb0 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
@@ -404,40 +404,6 @@
analyzeClass(classes.get("Bad"), 3);
}
- public void testForEachStatement() {
- Map<String, ClassNodeElement> invalidReturnType = loadSource(
- "class A {",
- " Iterator<int> iterator() {}",
- "}",
- "class B {",
- " main() { for (int i in new A()) {}}",
- "}");
- analyzeClasses(invalidReturnType);
- }
-
- public void testForEachStatement_Negative1() {
- Map<String, ClassNodeElement> fieldNotMethod = loadSource(
- "class A {",
- " int iterator;",
- "}",
- "class B {",
- " main() { for (int i in new A()) {}}",
- "}");
- analyzeClasses(fieldNotMethod, TypeErrorCode.FOR_IN_WITH_ITERATOR_FIELD);
- }
-
- public void testForEachStatement_Negative2() {
- Map<String, ClassNodeElement> invalidReturnType = loadSource(
- "class A {",
- " int iterator() {}",
- "}",
- "class B {",
- " main() { for (int i in new A()) {}}",
- "}");
- analyzeClasses(invalidReturnType, TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE);
- }
-
-
public void testForStatement() {
analyze("for (;true;) {}");
analyze("for (;null;) {}");
diff --git a/compiler/scripts/dart_analyzer.bat b/compiler/scripts/dart_analyzer.bat
index 0353f2b..4653020 100644
--- a/compiler/scripts/dart_analyzer.bat
+++ b/compiler/scripts/dart_analyzer.bat
@@ -44,7 +44,7 @@
setlocal EnableDelayedExpansion
set DART_SDK=""
if [%FOUND_SDK%] == [0] (
- if exist "%DART_ANALYZER_HOME%\lib\core\core_runtime.dart" (
+ if exist "%DART_ANALYZER_HOME%\lib\core\core.dart" (
set DART_SDK=--dart-sdk %DART_ANALYZER_HOME%
) else (
for /f %%i in ('echo %DART_ANALYZER_HOME%') do set DART_SDK_HOME=%%~dpi\dart-sdk
@@ -64,7 +64,7 @@
rem DART_SDK=""
rem if [ $FOUND_SDK = 0 ] ; then
-rem if [ -f $DART_ANALYZER_HOME/lib/core/core_runtime.dart ] ; then
+rem if [ -f $DART_ANALYZER_HOME/lib/core/core.dart ] ; then
rem DART_SDK="--dart-sdk $DART_ANALYZER_HOME"
rem else
rem DART_SDK_HOME=$(dirname $DART_ANALYZER_HOME)/dart-sdk
@@ -136,4 +136,4 @@
rem exec java $EXTRA_JVMARGS $DART_JVMARGS -ea -classpath "@CLASSPATH@" \
rem com.google.dart.compiler.DartCompiler ${DART_SDK} $@
-rem
\ No newline at end of file
+rem
diff --git a/compiler/scripts/dart_analyzer.sh b/compiler/scripts/dart_analyzer.sh
index 8abaf52..c07f5bc 100755
--- a/compiler/scripts/dart_analyzer.sh
+++ b/compiler/scripts/dart_analyzer.sh
@@ -5,8 +5,11 @@
set -e
-SCRIPT_DIR=$(dirname $0)
-DART_ANALYZER_HOME=$(dirname $SCRIPT_DIR)
+# Setting SCRIPT_DIR this way is ugly, but is needed to handle the case where
+# dart-sdk/bin has been symlinked to. On MacOS, readlink doesn't work
+# with this case.
+SCRIPT_DIR="$(cd "${0%/*}" ; pwd -P)"
+DART_ANALYZER_HOME="$(cd "${SCRIPT_DIR%/*}" ; pwd -P)"
FOUND_BATCH=0
FOUND_SDK=0
@@ -26,7 +29,7 @@
DART_SDK=""
if [ $FOUND_SDK = 0 ] ; then
- if [ -f $DART_ANALYZER_HOME/lib/core/core_runtime.dart ] ; then
+ if [ -f $DART_ANALYZER_HOME/lib/core/core.dart ] ; then
DART_SDK="--dart-sdk $DART_ANALYZER_HOME"
else
DART_SDK_HOME=$(dirname $DART_ANALYZER_HOME)/dart-sdk
diff --git a/dart.gyp b/dart.gyp
index b76a758..fe081d3 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -40,8 +40,8 @@
{
'action_name': 'create_sdk_py',
'inputs': [
- '<!@(["python", "tools/list_files.py", "\\.dart$", "lib"])',
- '<!@(["python", "tools/list_files.py", "import_.*\\.config$", "lib/config"])',
+ '<!@(["python", "tools/list_files.py", "\\.dart$", "sdk/lib"])',
+ '<!@(["python", "tools/list_files.py", "", "sdk/bin"])',
'tools/create_sdk.py',
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
'<(PRODUCT_DIR)/dart2js',
@@ -129,8 +129,19 @@
{
'target_name': 'samples',
'type': 'none',
- 'dependencies': [
- 'samples/sample_extension/sample_extension.gyp:sample_extension',
+ 'conditions': [
+ ['OS=="android"', {
+ 'dependencies': [
+ 'samples/android_embedder/android_embedder.gyp:android_embedder',
+ ],
+ },
+ ],
+ ['OS!="android"', {
+ 'dependencies': [
+ 'samples/sample_extension/sample_extension.gyp:sample_extension',
+ ],
+ },
+ ]
],
},
{
diff --git a/pkg/.gitignore b/pkg/.gitignore
new file mode 100644
index 0000000..256ea1f
--- /dev/null
+++ b/pkg/.gitignore
@@ -0,0 +1,9 @@
+/Makefile
+/*.Makefile
+/*.sln
+/*.target.mk
+/*.vcproj
+/*.vcxproj
+/*.vcxproj.user
+/*.vcxproj.filters
+/*.xcodeproj
diff --git a/pkg/http/lib/src/base_request.dart b/pkg/http/lib/src/base_request.dart
index ecf5f7a..4a8b5ce 100644
--- a/pkg/http/lib/src/base_request.dart
+++ b/pkg/http/lib/src/base_request.dart
@@ -5,6 +5,7 @@
library base_request;
import 'dart:io';
+import 'dart:isolate';
import 'dart:uri';
import 'client.dart';
@@ -104,9 +105,19 @@
/// requests.
Future<StreamedResponse> send() {
var client = new Client();
- var future = client.send(this);
- future.onComplete((_) => client.close());
- return future;
+ return client.send(this).transform((response) {
+ // TODO(nweiz): This makes me sick to my stomach, but it's currently the
+ // best way to listen for the response stream being closed. Kill it with
+ // fire once issue 4202 is fixed.
+ new Timer.repeating(100, (timer) {
+ if (response.stream.closed) {
+ client.close();
+ timer.cancel();
+ }
+ });
+
+ return response;
+ });
}
/// Throws an error if this request has been finalized.
diff --git a/pkg/http/lib/src/base_response.dart b/pkg/http/lib/src/base_response.dart
index 57f4a95..8b7da0c 100644
--- a/pkg/http/lib/src/base_response.dart
+++ b/pkg/http/lib/src/base_response.dart
@@ -6,11 +6,16 @@
import 'dart:io';
+import 'base_request.dart';
+
/// The base class for HTTP responses.
///
/// Subclasses of [BaseResponse] are usually not constructed manually; instead,
/// they're returned by [BaseClient.send] or other HTTP client methods.
abstract class BaseResponse {
+ /// The (frozen) request that triggered this response.
+ final BaseRequest request;
+
/// The status code of the response.
final int statusCode;
@@ -37,7 +42,8 @@
BaseResponse(
this.statusCode,
this.contentLength,
- {this.headers: const <String>{},
+ {this.request,
+ this.headers: const <String>{},
this.isRedirect: false,
this.persistentConnection: true,
this.reasonPhrase});
diff --git a/pkg/http/lib/src/io_client.dart b/pkg/http/lib/src/io_client.dart
index 995ff3b..e263c66 100644
--- a/pkg/http/lib/src/io_client.dart
+++ b/pkg/http/lib/src/io_client.dart
@@ -25,10 +25,26 @@
var completer = new Completer<StreamedResponse>();
var connection = _inner.openUrl(request.method, request.url);
+ connection.followRedirects = request.followRedirects;
+ connection.maxRedirects = request.maxRedirects;
connection.onError = (e) {
async.then((_) {
- // TODO(nweiz): remove this when issue 4974 is fixed
- if (completer.future.isComplete) throw e;
+ if (completer.future.isComplete) {
+ // TODO(nweiz): issue 7014 means that connection errors may be routed
+ // here even after onResponse has been called. Since these errors are
+ // also routed to the response input stream, we want to silently
+ // ignore them.
+ //
+ // We test if they're HTTP exceptions to distinguish them from errors
+ // caused by issue 4974 (see below).
+ if (e is HttpException) return;
+
+ // TODO(nweiz): issue 4974 means that any errors that appear in the
+ // onRequest or onResponse callbacks get passed to onError. If the
+ // completer has already fired, we want to re-throw those exceptions
+ // to the top level so that they aren't silently ignored.
+ throw e;
+ }
completer.completeException(e);
});
@@ -53,9 +69,10 @@
response.headers.forEach((key, value) => headers[key] = value);
completer.complete(new StreamedResponse(
- response.inputStream,
+ wrapInputStream(response.inputStream),
response.statusCode,
response.contentLength,
+ request: request,
headers: headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
@@ -68,7 +85,7 @@
/// Closes the client. This terminates all active connections. If a client
/// remains unclosed, the Dart process may not terminate.
void close() {
- if (_inner != null) _inner.shutdown();
+ if (_inner != null) _inner.shutdown(force: true);
_inner = null;
}
}
diff --git a/pkg/http/lib/src/mock_client.dart b/pkg/http/lib/src/mock_client.dart
index ce2916f..90c5d19 100644
--- a/pkg/http/lib/src/mock_client.dart
+++ b/pkg/http/lib/src/mock_client.dart
@@ -25,10 +25,12 @@
/// [StreamedResponse]s.
final MockClientStreamHandler _handler;
+ MockClient._(this._handler);
+
/// Creates a [MockClient] with a handler that receives [Request]s and sends
/// [Response]s.
MockClient(MockClientHandler fn)
- : this.streaming((baseRequest, bodyStream) {
+ : this._((baseRequest, bodyStream) {
return consumeInputStream(bodyStream).chain((bodyBytes) {
var request = new Request(baseRequest.method, baseRequest.url);
request.persistentConnection = baseRequest.persistentConnection;
@@ -48,6 +50,7 @@
stream,
response.statusCode,
response.contentLength,
+ request: baseRequest,
headers: response.headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
@@ -57,7 +60,20 @@
/// Creates a [MockClient] with a handler that receives [StreamedRequest]s and
/// sends [StreamedResponse]s.
- MockClient.streaming(MockClientStreamHandler this._handler);
+ MockClient.streaming(MockClientStreamHandler fn)
+ : this._((request, bodyStream) {
+ return fn(request, bodyStream).transform((response) {
+ return new StreamedResponse(
+ response.stream,
+ response.statusCode,
+ response.contentLength,
+ request: request,
+ headers: response.headers,
+ isRedirect: response.isRedirect,
+ persistentConnection: response.persistentConnection,
+ reasonPhrase: response.reasonPhrase);
+ });
+ });
/// Sends a request.
Future<StreamedResponse> send(BaseRequest request) {
diff --git a/pkg/http/lib/src/multipart_request.dart b/pkg/http/lib/src/multipart_request.dart
index b523956..b9adf9c 100644
--- a/pkg/http/lib/src/multipart_request.dart
+++ b/pkg/http/lib/src/multipart_request.dart
@@ -102,7 +102,7 @@
writeLine();
});
- forEachFuture(files, (file) {
+ Futures.forEach(files, (file) {
writeAscii('--$boundary\r\n');
writeAscii(_headerForFile(file));
return writeInputToInput(file.finalize(), stream)
diff --git a/pkg/http/lib/src/response.dart b/pkg/http/lib/src/response.dart
index d3546fe..26e5e61 100644
--- a/pkg/http/lib/src/response.dart
+++ b/pkg/http/lib/src/response.dart
@@ -7,6 +7,7 @@
import 'dart:io';
import 'dart:scalarlist';
+import 'base_request.dart';
import 'base_response.dart';
import 'streamed_response.dart';
import 'utils.dart';
@@ -28,13 +29,15 @@
Response(
String body,
int statusCode,
- {Map<String, String> headers: const <String>{},
+ {BaseRequest request,
+ Map<String, String> headers: const <String>{},
bool isRedirect: false,
bool persistentConnection: true,
String reasonPhrase})
: this.bytes(
encodeString(body, _encodingForHeaders(headers)),
statusCode,
+ request: request,
headers: headers,
isRedirect: isRedirect,
persistentConnection: persistentConnection,
@@ -44,7 +47,8 @@
Response.bytes(
List<int> bodyBytes,
int statusCode,
- {Map<String, String> headers: const <String>{},
+ {BaseRequest request,
+ Map<String, String> headers: const <String>{},
bool isRedirect: false,
bool persistentConnection: true,
String reasonPhrase})
@@ -52,6 +56,7 @@
super(
statusCode,
bodyBytes.length,
+ request: request,
headers: headers,
isRedirect: isRedirect,
persistentConnection: persistentConnection,
@@ -64,6 +69,7 @@
return new Response.bytes(
body,
response.statusCode,
+ request: response.request,
headers: response.headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
diff --git a/pkg/http/lib/src/streamed_response.dart b/pkg/http/lib/src/streamed_response.dart
index 8810df7..218643b 100644
--- a/pkg/http/lib/src/streamed_response.dart
+++ b/pkg/http/lib/src/streamed_response.dart
@@ -7,6 +7,7 @@
import 'dart:io';
import 'base_response.dart';
+import 'base_request.dart';
/// An HTTP response where the response body is received asynchronously after
/// the headers have been received.
@@ -19,13 +20,15 @@
this.stream,
int statusCode,
int contentLength,
- {Map<String, String> headers: const <String>{},
+ {BaseRequest request,
+ Map<String, String> headers: const <String>{},
bool isRedirect: false,
bool persistentConnection: true,
String reasonPhrase})
: super(
statusCode,
contentLength,
+ request: request,
headers: headers,
isRedirect: isRedirect,
persistentConnection: persistentConnection,
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index 8431603..5bc9b5f 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -144,11 +144,29 @@
return completer.future;
}
+// TODO(nweiz): this wouldn't be necessary were it not for issue 7013.
+/// Wrap an InputStream in a ListInputStream. This ensures that if the input
+/// stream has invalid onClosed/onError behavior (see issue 7013), that behavior
+/// is papered over.
+InputStream wrapInputStream(InputStream source) {
+ var sink = new ListInputStream();
+ // TODO(nweiz): Due to issuee 3657, pipeInputToInput naturally avoids calling
+ // both onClosed and onError. If 3657 gets fixed before 7013, we'll need to do
+ // that explicitly.
+ pipeInputToInput(source, sink);
+ return sink;
+}
+
/// Takes all input from [source] and writes it to [sink], then closes [sink].
+/// Returns a [Future] that completes when [source] is exhausted.
void pipeInputToInput(InputStream source, ListInputStream sink) {
- source.onClosed = () => sink.markEndOfStream();
+ source.onClosed = sink.markEndOfStream;
source.onData = () => sink.write(source.read());
// TODO(nweiz): propagate source errors to the sink. See issue 3657.
+ // TODO(nweiz): we need to use async here to avoid issue 4974.
+ source.onError = (e) => async.then((_) {
+ throw e;
+ });
}
/// Takes all input from [source] and writes it to [sink], but does not close
diff --git a/pkg/http/test/client_test.dart b/pkg/http/test/client_test.dart
index e7c3501..673ba1d 100644
--- a/pkg/http/test/client_test.dart
+++ b/pkg/http/test/client_test.dart
@@ -22,6 +22,7 @@
'application/json; charset=utf-8';
var future = client.send(request).chain((response) {
+ expect(response.request, equals(request));
expect(response.statusCode, equals(200));
return consumeInputStream(response.stream);
}).transform((bytes) => new String.fromCharCodes(bytes));
diff --git a/pkg/http/test/mock_client_test.dart b/pkg/http/test/mock_client_test.dart
index 7bc39566..44d5161 100644
--- a/pkg/http/test/mock_client_test.dart
+++ b/pkg/http/test/mock_client_test.dart
@@ -20,7 +20,7 @@
var client = new MockClient((request) {
return new Future.immediate(new http.Response(
JSON.stringify(request.bodyFields), 200,
- headers: {'content-type': 'application/json'}));
+ request: request, headers: {'content-type': 'application/json'}));
});
expect(client.post("http://example.com/foo", fields: {
diff --git a/pkg/http/test/request_test.dart b/pkg/http/test/request_test.dart
index 319abfb..e26ee75 100644
--- a/pkg/http/test/request_test.dart
+++ b/pkg/http/test/request_test.dart
@@ -183,6 +183,53 @@
// when issue 6284 is fixed.
});
+ test('#followRedirects', () {
+ print("This test is known to be flaky, please ignore "
+ "(debug prints below added by sgjesse@)");
+ print("#followRedirects test starting server...");
+ startServer();
+ print("#followRedirects test server running");
+
+ var request = new http.Request('POST', serverUrl.resolve('/redirect'))
+ ..followRedirects = false;
+ var future = request.send().transform((response) {
+ print("#followRedirects test response received");
+ expect(response.statusCode, equals(302));
+ });
+ future.onComplete((_) {
+ print("#followRedirects test stopping server...");
+ stopServer();
+ print("#followRedirects test server stopped");
+ });
+
+ expect(future, completes);
+ print("#followRedirects test started");
+ });
+
+ test('#maxRedirects', () {
+ print("This test is known to be flaky, please ignore "
+ "(debug prints below added by sgjesse@)");
+ print("#maxRedirects test starting server...");
+ startServer();
+ print("#maxRedirects test server running");
+
+ var request = new http.Request('POST', serverUrl.resolve('/loop?1'))
+ ..maxRedirects = 2;
+ var future = request.send().transformException((e) {
+ print("#maxRedirects test exception received");
+ expect(e, isRedirectLimitExceededException);
+ expect(e.redirects.length, equals(2));
+ });
+ future.onComplete((_) {
+ print("#maxRedirects test stopping server...");
+ stopServer();
+ print("#maxRedirects test server stopped");
+ });
+
+ expect(future, completes);
+ print("#maxRedirects test started");
+ });
+
group('content-type header', () {
test('defaults to empty', () {
var request = new http.Request('POST', dummyUrl);
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index 19a3cf3..9e0d010 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -29,24 +29,25 @@
(request, response) {
response.statusCode = 400;
response.contentLength = 0;
- response.outputStream.close();
+ closeResponse(request, response);
});
_server.addRequestHandler((request) => request.path == '/loop',
(request, response) {
var n = int.parse(new Uri.fromString(request.uri).query);
response.statusCode = 302;
- response.headers.set('location', '/loop?${n + 1}');
+ response.headers.set('location',
+ serverUrl.resolve('/loop?${n + 1}').toString());
response.contentLength = 0;
- response.outputStream.close();
+ closeResponse(request, response);
});
_server.addRequestHandler((request) => request.path == '/redirect',
(request, response) {
response.statusCode = 302;
- response.headers.set('location', '/');
+ response.headers.set('location', serverUrl.resolve('/').toString());
response.contentLength = 0;
- response.outputStream.close();
+ closeResponse(request, response);
});
_server.defaultRequestHandler = (request, response) {
@@ -103,6 +104,15 @@
_server = null;
}
+/// Closes [response] while ignoring the body of [request].
+///
+/// Due to issue 6984, it's necessary to drain the request body before closing
+/// the response.
+void closeResponse(HttpRequest request, HttpResponse response) {
+ request.inputStream.onData = request.inputStream.read;
+ request.inputStream.onClosed = response.outputStream.close;
+}
+
/// A matcher that matches JSON that parses to a value that matches the inner
/// matcher.
Matcher parse(matcher) => new _Parse(matcher);
diff --git a/pkg/oauth2/pubspec.yaml b/pkg/oauth2/pubspec.yaml
new file mode 100644
index 0000000..477d211
--- /dev/null
+++ b/pkg/oauth2/pubspec.yaml
@@ -0,0 +1,7 @@
+name: oauth2
+description: A composable, Future-based API for making HTTP requests.
+dependencies:
+ unittest:
+ sdk: unittest
+ http:
+ sdk: http
diff --git a/pkg/pkg.gyp b/pkg/pkg.gyp
index e5c2c35..6d09c61 100644
--- a/pkg/pkg.gyp
+++ b/pkg/pkg.gyp
@@ -23,15 +23,7 @@
'webdriver/lib',
],
'outputs': [
- '<(PRODUCT_DIR)/packages/args',
- '<(PRODUCT_DIR)/packages/fixnum',
- '<(PRODUCT_DIR)/packages/htmlescape',
- '<(PRODUCT_DIR)/packages/http',
- '<(PRODUCT_DIR)/packages/intl',
- '<(PRODUCT_DIR)/packages/logging',
- '<(PRODUCT_DIR)/packages/meta',
- '<(PRODUCT_DIR)/packages/unittest',
- '<(PRODUCT_DIR)/packages/webdriver',
+ '<(PRODUCT_DIR)/packages',
],
'action': [
'python', '../tools/make_links.py',
diff --git a/pkg/pkg.status b/pkg/pkg.status
index e8688de..5e083aa 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -34,6 +34,9 @@
intl/test/find_default_locale_browser_test: Skip
intl/test/date_time_format_http_request_test: Skip
+[ $runtime == vm && $system == windows ]
+http/test/http_test: Pass, Fail # http://dartbug.com/6967
+
# Skip http request tests on Dartium while resolving an odd
# error there that causes the tests to timeout.
[ $runtime == dartium || $runtime == drt ]
@@ -54,4 +57,3 @@
[ $compiler == none && $runtime == drt ]
dartdoc/test/dartdoc_test: Skip # See dartbug.com/4541.
-args/test/args_test: Skip # http://dartbug.com/6744
diff --git a/pkg/unittest/lib/html_config.dart b/pkg/unittest/lib/html_config.dart
index 3a8b3c4..3d87f98 100644
--- a/pkg/unittest/lib/html_config.dart
+++ b/pkg/unittest/lib/html_config.dart
@@ -14,7 +14,7 @@
void _showResultsInPage(int passed, int failed, int errors,
List<TestCase> results, bool isLayoutTest, String uncaughtError) {
if (isLayoutTest && (passed == results.length) && uncaughtError == null) {
- document.body.innerHTML = "PASS";
+ document.body.innerHtml = "PASS";
} else {
var newBody = new StringBuffer();
newBody.add("<table class='unittest-table'><tbody>");
@@ -49,7 +49,7 @@
</td></tr>""");
}
newBody.add("</tbody></table>");
- document.body.innerHTML = newBody.toString();
+ document.body.innerHtml = newBody.toString();
}
}
diff --git a/pkg/unittest/lib/html_enhanced_config.dart b/pkg/unittest/lib/html_enhanced_config.dart
index ce68ef7..faad8eb 100644
--- a/pkg/unittest/lib/html_enhanced_config.dart
+++ b/pkg/unittest/lib/html_enhanced_config.dart
@@ -65,7 +65,7 @@
cssElement = document.head.query('#${_CSSID}');
}
- cssElement.innerHTML = _htmlTestCSS;
+ cssElement.innerHtml = _htmlTestCSS;
}
void onStart() {
@@ -89,7 +89,7 @@
void _showInteractiveResultsInPage(int passed, int failed, int errors,
List<TestCase> results, bool isLayoutTest, String uncaughtError) {
if (isLayoutTest && passed == results.length) {
- document.body.innerHTML = "PASS";
+ document.body.innerHtml = "PASS";
} else {
// changed the StringBuffer to an Element fragment
Element te = new Element.html('<div class="unittest-table"></div>');
diff --git a/pkg/unittest/lib/interactive_html_config.dart b/pkg/unittest/lib/interactive_html_config.dart
index 7cc2a04..796fcd4 100644
--- a/pkg/unittest/lib/interactive_html_config.dart
+++ b/pkg/unittest/lib/interactive_html_config.dart
@@ -242,7 +242,7 @@
void onInit() {
_installErrorHandler();
_messageHandler = _handleMessage; // We need to make just one closure.
- document.query('#group-divs').innerHTML = "";
+ document.query('#group-divs').innerHtml = "";
}
void onStart() {
@@ -355,7 +355,7 @@
testItem.classes.clear();
testItem.classes.add('test-it');
testItem.classes.add('status-pending');
- testItem.query('#$_actionIdPrefix$id').innerHTML = '';
+ testItem.query('#$_actionIdPrefix$id').innerHtml = '';
}
}
diff --git a/runtime/.gitignore b/runtime/.gitignore
index 7f21541..adaa849 100644
--- a/runtime/.gitignore
+++ b/runtime/.gitignore
@@ -1,41 +1,15 @@
-/*.filters
-/*.user
-/dart-runtime.sln
+/Makefile
+/out
+/runtime
+/xcodebuild
+/*.Makefile
+/*.sln
+/*.target.mk
/*.vcproj
/*.vcxproj
-/*.mk
-/dart_no_snapshot.target.mk
-/dart-runtime.Makefile
-/dart-runtime.xcodeproj
-/dart.target.mk
-/generate_builtin_cc_file.target.mk
-/generate_corelib_cc_file.target.mk
-/generate_corelib_impl_cc_file.target.mk
-/generate_io_cc_file.target.mk
-/generate_isolate_cc_file.target.mk
-/generate_json_cc_file.target.mk
-/generate_mirrors_cc_file.target.mk
-/generate_snapshot_file.target.mk
-/generate_snapshot_test_dat_file.target.mk
-/generate_uri_cc_file.target.mk
-/generate_utf_cc_file.target.mk
-/gen_snapshot.target.mk
-/libdart_builtin.target.mk
-/libdart_export.target.mk
-/libdart_lib.target.mk
-/libdart_lib_withcore.target.mk
-/libdart.target.mk
-/libdart_vm.target.mk
-/libdart_withcore.target.mk
-/libdouble_conversion.target.mk
-/libjscre.target.mk
-/Makefile
-/process_test.target.mk
-/runtime
-/run_vm_tests.target.mk
-/test_extension.target.mk
-/out
-/xcodebuild
+/*.vcxproj.filters
+/*.vcxproj.user
+/*.xcodeproj
/Debug
/DebugARM
/DebugIA32
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index c8108b7..3a6dd8a 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -50,16 +50,35 @@
{
'target_name': 'generate_crypto_cc_file',
'type': 'none',
+ 'variables': {
+ 'crypto_dart': '<(SHARED_INTERMEDIATE_DIR)/crypto_gen.dart',
+ },
'includes': [
'crypto_sources.gypi',
],
'actions': [
{
+ 'action_name': 'generate_crypto_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(crypto_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(crypto_dart)',
+ ],
+ 'message': 'Generating ''<(crypto_dart)'' file.',
+ },
+ {
'action_name': 'generate_crypto_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(crypto_dart)',
],
'outputs': [
'<(crypto_cc_file)',
@@ -71,7 +90,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
'--var_name', 'Builtin::crypto_source_',
- '<@(_sources)',
+ '<(crypto_dart)',
],
'message': 'Generating ''<(crypto_cc_file)'' file.'
},
@@ -80,6 +99,9 @@
{
'target_name': 'generate_io_cc_file',
'type': 'none',
+ 'variables': {
+ 'io_dart': '<(SHARED_INTERMEDIATE_DIR)/io_gen.dart',
+ },
'sources': [
'io.dart',
],
@@ -88,11 +110,27 @@
],
'actions': [
{
+ 'action_name': 'generate_io_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(io_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(io_dart)',
+ ],
+ 'message': 'Generating ''<(io_dart)'' file.',
+ },
+ {
'action_name': 'generate_io_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(io_dart)',
],
'outputs': [
'<(io_cc_file)',
@@ -104,7 +142,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
'--var_name', 'Builtin::io_source_',
- '<@(_sources)',
+ '<(io_dart)',
],
'message': 'Generating ''<(io_cc_file)'' file.'
},
@@ -143,16 +181,35 @@
{
'target_name': 'generate_json_cc_file',
'type': 'none',
+ 'variables': {
+ 'json_dart': '<(SHARED_INTERMEDIATE_DIR)/json_gen.dart',
+ },
'includes': [
'json_sources.gypi',
],
'actions': [
{
+ 'action_name': 'generate_json_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(json_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(json_dart)',
+ ],
+ 'message': 'Generating ''<(json_dart)'' file.',
+ },
+ {
'action_name': 'generate_json_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(json_dart)',
],
'outputs': [
'<(json_cc_file)',
@@ -164,7 +221,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
'--var_name', 'Builtin::json_source_',
- '<@(_sources)',
+ '<(json_dart)',
],
'message': 'Generating ''<(json_cc_file)'' file.'
},
@@ -173,12 +230,12 @@
{
'target_name': 'generate_uri_cc_file',
'type': 'none',
+ 'variables': {
+ 'uri_dart': '<(SHARED_INTERMEDIATE_DIR)/uri_gen.dart',
+ },
'includes': [
'uri_sources.gypi',
],
- 'variables': {
- 'uri_dart': '<(SHARED_INTERMEDIATE_DIR)/uri.dart',
- },
'actions': [
{
'action_name': 'generate_uri_dart',
@@ -222,16 +279,35 @@
{
'target_name': 'generate_utf_cc_file',
'type': 'none',
+ 'variables': {
+ 'utf_dart': '<(SHARED_INTERMEDIATE_DIR)/utf_gen.dart',
+ },
'includes': [
'utf_sources.gypi',
],
'actions': [
{
+ 'action_name': 'generate_utf_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(utf_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(utf_dart)',
+ ],
+ 'message': 'Generating ''<(utf_dart)'' file.',
+ },
+ {
'action_name': 'generate_utf_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(utf_dart)',
],
'outputs': [
'<(utf_cc_file)',
@@ -243,7 +319,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
'--var_name', 'Builtin::utf_source_',
- '<@(_sources)',
+ '<(utf_dart)',
],
'message': 'Generating ''<(utf_cc_file)'' file.'
},
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 91e82e8..dcaf06b 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -30,6 +30,7 @@
V(File_Close, 1) \
V(File_ReadByte, 1) \
V(File_WriteByte, 2) \
+ V(File_Read, 2) \
V(File_ReadList, 4) \
V(File_WriteList, 4) \
V(File_Position, 1) \
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 88d0ef4..ae81e20 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -6,6 +6,7 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
+#include "bin/io_buffer.h"
#include "bin/thread.h"
#include "bin/utils.h"
@@ -158,6 +159,41 @@
}
+void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) {
+ Dart_EnterScope();
+ intptr_t value =
+ DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0));
+ File* file = reinterpret_cast<File*>(value);
+ ASSERT(file != NULL);
+ Dart_Handle length_object = Dart_GetNativeArgument(args, 1);
+ int64_t length = 0;
+ if (DartUtils::GetInt64Value(length_object, &length)) {
+ uint8_t* buffer = NULL;
+ Dart_Handle external_array = IOBuffer::Allocate(length, &buffer);
+ int bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
+ if (bytes_read < 0) {
+ Dart_Handle err = DartUtils::NewDartOSError();
+ if (Dart_IsError(err)) Dart_PropagateError(err);
+ Dart_SetReturnValue(args, err);
+ } else {
+ if (bytes_read < length) {
+ // TODO(ager): cache the 'length' string if this becomes a bottle neck.
+ Dart_SetField(external_array,
+ DartUtils::NewString("length"),
+ Dart_NewInteger(bytes_read));
+ }
+ Dart_SetReturnValue(args, external_array);
+ }
+ } else {
+ OSError os_error(-1, "Invalid argument", OSError::kUnknown);
+ Dart_Handle err = DartUtils::NewDartOSError(&os_error);
+ if (Dart_IsError(err)) Dart_PropagateError(err);
+ Dart_SetReturnValue(args, err);
+ }
+ Dart_ExitScope();
+}
+
+
void FUNCTION_NAME(File_ReadList)(Dart_NativeArguments args) {
Dart_EnterScope();
intptr_t value =
@@ -758,6 +794,39 @@
}
+static CObject* FileReadRequest(const CObjectArray& request) {
+ if (request.Length() == 3 &&
+ request[1]->IsIntptr() &&
+ request[2]->IsInt32OrInt64()) {
+ File* file = CObjectToFilePointer(request[1]);
+ ASSERT(file != NULL);
+ if (!file->IsClosed()) {
+ int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
+ uint8_t* buffer = new uint8_t[length];
+ int bytes_read = file->Read(buffer, length);
+ if (bytes_read >= 0) {
+ void* peer = reinterpret_cast<void*>(buffer);
+ CObject* external_array =
+ new CObjectExternalUint8Array(
+ CObject::NewExternalUint8Array(bytes_read,
+ buffer,
+ peer,
+ FinalizeExternalByteArray));
+ CObjectArray* result = new CObjectArray(CObject::NewArray(2));
+ result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0)));
+ result->SetAt(1, external_array);
+ return result;
+ } else {
+ return CObject::NewOSError();
+ }
+ } else {
+ return CObject::FileClosedError();
+ }
+ }
+ return CObject::IllegalArgumentError();
+}
+
+
static CObject* FileReadListRequest(const CObjectArray& request) {
if (request.Length() == 3 &&
request[1]->IsIntptr() &&
@@ -897,6 +966,9 @@
case File::kWriteByteRequest:
response = FileWriteByteRequest(request);
break;
+ case File::kReadRequest:
+ response = FileReadRequest(request);
+ break;
case File::kReadListRequest:
response = FileReadListRequest(request);
break;
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 1e5df5f..5f3fd00 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -60,8 +60,9 @@
kFlushRequest = 13,
kReadByteRequest = 14,
kWriteByteRequest = 15,
- kReadListRequest = 16,
- kWriteListRequest = 17
+ kReadRequest = 16,
+ kReadListRequest = 17,
+ kWriteListRequest = 18
};
~File();
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index 4ca5733..eb55dae 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -21,6 +21,7 @@
patch class _RandomAccessFile {
/* patch */ static int _close(int id) native "File_Close";
/* patch */ static _readByte(int id) native "File_ReadByte";
+ /* patch */ static _read(int id, int bytes) native "File_Read";
/* patch */ static _readList(int id, List<int> buffer, int offset, int bytes)
native "File_ReadList";
/* patch */ static _writeByte(int id, int value) native "File_WriteByte";
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 2f2c6f2..ac50f47 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -301,7 +301,7 @@
// Initialize the Dart VM.
// Note: We don't expect isolates to be created from dart code during
// snapshot generation.
- if (!Dart_Initialize(NULL, NULL, NULL)) {
+ if (!Dart_Initialize(NULL, NULL, NULL, NULL)) {
Log::PrintErr("VM initialization failed\n");
return 255;
}
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 81c1373..7505ad1 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -692,6 +692,7 @@
// Initialize the Dart VM.
if (!Dart_Initialize(CreateIsolateAndSetup,
NULL,
+ NULL,
ShutdownIsolate)) {
fprintf(stderr, "%s", "VM initialization failed\n");
fflush(stderr);
diff --git a/runtime/bin/net/.gitignore b/runtime/bin/net/.gitignore
index bfd80d7..3ca2cc5 100644
--- a/runtime/bin/net/.gitignore
+++ b/runtime/bin/net/.gitignore
@@ -1,13 +1,8 @@
-/libssl_dart.target.mk
-/minizip_dart.target.mk
-/nspr_dart.target.mk
-/nss.Makefile
-/nss_dart.target.mk
-/nss_static_dart.target.mk
-/nssckbi_dart.target.mk
-/sqlite.Makefile
-/sqlite_dart.target.mk
-/sqlite_shell_dart.target.mk
-/ssl.Makefile
-/zlib.Makefile
-/zlib_dart.target.mk
+/*.Makefile
+/*.sln
+/*.target.mk
+/*.vcproj
+/*.vcxproj
+/*.vcxproj.filters
+/*.vcxproj.user
+/*.xcodeproj
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index d73b046..f0eb3a8 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -138,7 +138,7 @@
bool set_vm_flags_success = Flags::ProcessCommandLineFlags(dart_argc,
dart_argv);
ASSERT(set_vm_flags_success);
- const char* err_msg = Dart::InitOnce(NULL, NULL, NULL);
+ const char* err_msg = Dart::InitOnce(NULL, NULL, NULL, NULL);
ASSERT(err_msg == NULL);
// Apply the filter to all registered tests.
TestCaseBase::RunAll();
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index f297aed..2c9665b 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -262,6 +262,11 @@
if (status != SECSuccess) {
ThrowPRException("Unsuccessful SSL_OptionSetDefault enable TLS call.");
}
+ status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL);
+ if (status != SECSuccess) {
+ ThrowPRException("Unsuccessful SSL_ConfigServerSessionIDCache call.");
+ }
+
} else {
ThrowException("Called SSLFilter::InitializeLibrary more than once");
}
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 6e58985..ec09d6f 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -469,10 +469,6 @@
throw new StreamException(
"Cannot set connect handler when already connected");
}
- if (_outputStream != null) {
- throw new StreamException(
- "Cannot set connect handler when output stream is used");
- }
_clientConnectHandler = callback;
_updateOutHandler();
}
@@ -507,7 +503,7 @@
OutputStream get outputStream {
if (_outputStream == null) {
- if (_handlerMap[_SocketBase._OUT_EVENT] != null) {
+ if (_clientWriteHandler != null) {
throw new StreamException(
"Cannot get output stream when socket handlers are used");
}
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index 3f6b8f5..bbd4c97 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -101,5 +101,12 @@
},
],
},
+ {
+ 'target_name': 'runtime_packages',
+ 'type': 'none',
+ 'dependencies': [
+ '../pkg/pkg.gyp:pkg_packages',
+ ],
+ },
],
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 821014c..7657441 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -622,6 +622,19 @@
// TODO(turnidge): Define and implement unwinding.
/**
+ * An isolate unhandled exception callback function.
+ *
+ * This callback, provided by the embedder, is called when an unhandled
+ * exception or internal error is thrown during isolate execution. When the
+ * callback is invoked, Dart_CurrentIsolate can be used to figure out which
+ * isolate was running when the exception was thrown.
+ *
+ * \param error The unhandled exception or error. This handle's scope is
+ * only valid until the embedder returns from this callback.
+ */
+typedef void (*Dart_IsolateUnhandledExceptionCallback)(Dart_Handle error);
+
+/**
* An isolate shutdown callback function.
*
* This callback, provided by the embedder, is called after the vm
@@ -644,12 +657,18 @@
* See Dart_IsolateCreateCallback.
* \param interrupt A function to be called when an isolate is interrupted.
* See Dart_IsolateInterruptCallback.
+ * \param unhandled_exception A function to be called if an isolate has an
+ * unhandled exception. Set Dart_IsolateUnhandledExceptionCallback.
+ * \param shutdown A function to be called when an isolate is shutdown.
+ * See Dart_IsolateShutdownCallback.
*
* \return True if initialization is successful.
*/
-DART_EXPORT bool Dart_Initialize(Dart_IsolateCreateCallback create,
- Dart_IsolateInterruptCallback interrupt,
- Dart_IsolateShutdownCallback shutdown);
+DART_EXPORT bool Dart_Initialize(
+ Dart_IsolateCreateCallback create,
+ Dart_IsolateInterruptCallback interrupt,
+ Dart_IsolateUnhandledExceptionCallback unhandled_exception,
+ Dart_IsolateShutdownCallback shutdown);
/**
* Sets command line flags. Should be called before Dart_Initialize.
@@ -1406,10 +1425,10 @@
void** peer);
/**
- * Returns a String which references an external array of UTF-8 encoded
- * characters.
+ * Returns a String which references an external array of
+ * Latin-1 (ISO-8859-1) encoded characters.
*
- * \param utf8_array An array of UTF-8 encoded characters. This must not move.
+ * \param latin1_array Array of Latin-1 encoded characters. This must not move.
* \param length The length of the characters array.
* \param peer An external pointer to associate with this string.
* \param cback A callback to be called when this string is finalized.
@@ -1417,10 +1436,11 @@
* \return The String object if no error occurs. Otherwise returns
* an error handle.
*/
-DART_EXPORT Dart_Handle Dart_NewExternalUTF8String(const uint8_t* utf8_array,
- intptr_t length,
- void* peer,
- Dart_PeerFinalizer cback);
+DART_EXPORT Dart_Handle Dart_NewExternalLatin1String(
+ const uint8_t* latin1_array,
+ intptr_t length,
+ void* peer,
+ Dart_PeerFinalizer cback);
/**
* Returns a String which references an external array of UTF-16 encoded
@@ -1986,27 +2006,13 @@
/**
* Is this a class handle?
- *
- * Most parts of the dart embedding api do not distinguish between
- * classes and interfaces. For example, Dart_GetClass can return a
- * class or an interface and Dart_New can instantiate a class or an
- * interface. The exceptions are Dart_IsClass and Dart_IsInterface,
- * which can be used to distinguish whether a handle refers to a class
- * or an interface.
*/
DART_EXPORT bool Dart_IsClass(Dart_Handle handle);
/**
- * Is this an interface handle?
- *
- * Most parts of the dart embedding api do not distinguish between
- * classes and interfaces. For example, Dart_GetClass can return a
- * class or an interface and Dart_New can instantiate a class or an
- * interface. The exceptions are Dart_IsClass and Dart_IsInterface,
- * which can be used to distinguish whether a handle refers to a class
- * or an interface.
+ * Is this an abstract class handle?
*/
-DART_EXPORT bool Dart_IsInterface(Dart_Handle handle);
+DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle);
/**
* Returns the class name for the provided class or interface.
@@ -2019,16 +2025,6 @@
DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz);
/**
- * Returns the default factory class for the provided class or
- * interface.
- *
- * Only interfaces may have default fadctory classes. If the class or
- * interface has no default factory class, this function returns
- * Dart_Null().
- */
-DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz);
-
-/**
* Returns the number of interfaces directly implemented by some class
* or interface.
*
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 76babac..abadf12 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -87,7 +87,8 @@
double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
GET_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
- double remainder = fmod(left, right);
+
+ double remainder = fmod_ieee(left, right);
if (remainder == 0.0) {
// We explicitely switch to the positive 0.0 (just in case it was negative).
remainder = +0.0;
@@ -106,7 +107,7 @@
double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
GET_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
- return Double::New(fmod(left, right));
+ return Double::New(fmod_ieee(left, right));
}
diff --git a/runtime/lib/error.dart b/runtime/lib/error.dart
index 619b16c..b3ce3b7 100644
--- a/runtime/lib/error.dart
+++ b/runtime/lib/error.dart
@@ -53,7 +53,7 @@
class CastErrorImplementation
extends TypeErrorImplementation
implements CastError {
- factory CastError._uninstantiable() {
+ factory CastErrorImplementation._uninstantiable() {
throw new UnsupportedError(
"CastError can only be allocated by the VM");
}
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index 5eedca0..4fb83f9 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -25,7 +25,7 @@
bool get isSetter => _type == SETTER;
invokeOn(Object receiver) {
- throw new UnsupportedOperation("invokeOn not implemented yet");
+ throw new UnsupportedError("invokeOn not implemented yet");
}
}
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 7219bda..3585ba9 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -91,8 +91,7 @@
Error& error = Error::Handle();
error = isolate->object_store()->sticky_error();
if (!error.IsNull()) {
- OS::PrintErr("%s\n", error.ToErrorCString());
- exit(255);
+ OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
}
}
{
diff --git a/runtime/lib/map_patch.dart b/runtime/lib/map_patch.dart
index 633b7ce..cbc03fb 100644
--- a/runtime/lib/map_patch.dart
+++ b/runtime/lib/map_patch.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-patch class _HashMapImpl<K, V> {
+patch class Map<K, V> {
// Factory constructing a Map from a parser generated Map literal.
// [elements] contains n key-value pairs.
// The keys are at position 2*n and are already type checked by the parser
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index ff4e6af..5a434c4 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -53,7 +53,7 @@
DEFINE_NATIVE_ENTRY(Math_atan2, 2) {
GET_NATIVE_ARGUMENT(Double, operand1, arguments->NativeArgAt(0));
GET_NATIVE_ARGUMENT(Double, operand2, arguments->NativeArgAt(1));
- return Double::New(atan2(operand1.value(), operand2.value()));
+ return Double::New(atan2_ieee(operand1.value(), operand2.value()));
}
DEFINE_NATIVE_ENTRY(Math_exp, 1) {
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index bfcbacc..52818a4 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -51,12 +51,11 @@
class _Random implements Random {
// Internal state of the random number generator.
- var _state;
+ final _state = new List(2);
static const kSTATE_LO = 0;
static const kSTATE_HI = 1;
_Random._internal(state) {
- _state = new List(2);
_state[kSTATE_LO] = state & _MASK_32;
_state[kSTATE_HI] = state >> 32;
}
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index e075a25..afd1bc5 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -259,7 +259,7 @@
return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
}
- if (Dart_IsClass(target) || Dart_IsInterface(target)) {
+ if (Dart_IsClass(target)) {
if (Dart_ClassIsFunctionType(target)) {
Dart_Handle cls_name = NewString("_LazyFunctionTypeMirror");
Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
@@ -364,7 +364,7 @@
static Dart_Handle CreateTypeVariableMap(Dart_Handle owner,
Dart_Handle owner_mirror) {
- ASSERT(Dart_IsClass(owner) || Dart_IsInterface(owner));
+ ASSERT(Dart_IsClass(owner));
// TODO(turnidge): This should be an immutable map.
Dart_Handle map = MapNew();
if (Dart_IsError(map)) {
@@ -436,7 +436,7 @@
Dart_Handle intf_name,
Dart_Handle lib,
Dart_Handle lib_mirror) {
- ASSERT(Dart_IsClass(intf) || Dart_IsInterface(intf));
+ ASSERT(Dart_IsClass(intf));
if (Dart_ClassIsTypedef(intf)) {
// This class is actually a typedef. Represent it specially in
// reflection.
@@ -454,7 +454,8 @@
if (Dart_IsNull(super_class)) {
super_class = Dart_GetClass(CoreLib(), NewString("Object"));
}
- Dart_Handle default_class = Dart_ClassGetDefault(intf);
+ // TODO(turnidge): Simplify code, now that default classes have been removed.
+ Dart_Handle default_class = Dart_Null();
Dart_Handle intf_mirror = CreateLazyMirror(intf);
if (Dart_IsError(intf_mirror)) {
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 797cad2..236c95d 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -8,6 +8,7 @@
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/symbols.h"
+#include "vm/unicode.h"
namespace dart {
@@ -30,15 +31,15 @@
Exceptions::ThrowByType(Exceptions::kArgument, args);
}
intptr_t value = Smi::Cast(index_object).Value();
- if (value < 0) {
+ if (Utf::IsOutOfRange(value)) {
GrowableArray<const Object*> args;
Exceptions::ThrowByType(Exceptions::kArgument, args);
} else {
- if (value > 0x7F) {
+ if (!Utf::IsLatin1(value)) {
is_one_byte_string = false;
- }
- if (value > 0xFFFF) {
- utf16_len += 1;
+ if (Utf::IsSupplementary(value)) {
+ utf16_len += 1;
+ }
}
}
utf32_array[i] = value;
@@ -51,7 +52,7 @@
DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 3) {
- GET_NATIVE_ARGUMENT(String, receiver, arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
GET_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
GET_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -61,6 +62,18 @@
}
+DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 3) {
+ const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ ASSERT(receiver.IsOneByteString());
+ GET_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
+ GET_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
+
+ const intptr_t start = start_obj.Value();
+ const intptr_t end = end_obj.Value();
+ return OneByteString::New(receiver, start, end - start, Heap::kNew);
+}
+
+
DEFINE_NATIVE_ENTRY(String_getHashCode, 1) {
const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
intptr_t hash_val = receiver.Hash();
diff --git a/runtime/lib/string_base.dart b/runtime/lib/string_base.dart
index 22e17b9..ac631ff 100644
--- a/runtime/lib/string_base.dart
+++ b/runtime/lib/string_base.dart
@@ -152,6 +152,12 @@
if (startIndex > endIndex) {
throw new RangeError.value(startIndex);
}
+ if (startIndex == endIndex) {
+ return "";
+ }
+ if ((startIndex + 1) == endIndex) {
+ return this[startIndex];
+ }
return _substringUnchecked(startIndex, endIndex);
}
@@ -263,6 +269,9 @@
}
List<String> split(Pattern pattern) {
+ if ((pattern is String) && pattern.isEmpty) {
+ return splitChars();
+ }
int length = this.length;
Iterator iterator = pattern.allMatches(this).iterator();
if (length == 0 && iterator.hasNext) {
@@ -369,6 +378,8 @@
((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
}
+ String _substringUnchecked(int startIndex, int endIndex)
+ native "OneByteString_substringUnchecked";
}
diff --git a/runtime/platform/c99_support_win.h b/runtime/platform/c99_support_win.h
index 1d09eff..10fcf2b 100644
--- a/runtime/platform/c99_support_win.h
+++ b/runtime/platform/c99_support_win.h
@@ -48,10 +48,19 @@
}
static inline double round(double x) {
- if (x < 0) {
- return ceil(x - 0.5);
+ if (!_finite(x)) {
+ return x;
+ }
+
+ double intpart;
+ double fractpart = modf(x, &intpart);
+
+ if (fractpart >= 0.5) {
+ return intpart + 1;
+ } else if (fractpart > -0.5) {
+ return intpart;
} else {
- return floor(x + 0.5);
+ return intpart - 1;
}
}
diff --git a/runtime/platform/floating_point.h b/runtime/platform/floating_point.h
new file mode 100644
index 0000000..7adaa73
--- /dev/null
+++ b/runtime/platform/floating_point.h
@@ -0,0 +1,11 @@
+// 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 PLATFORM_FLOATING_POINT_H_
+#define PLATFORM_FLOATING_POINT_H_
+
+inline double fmod_ieee(double x, double y) { return fmod(x, y); }
+inline double atan2_ieee(double y, double x) { return atan2(y, x); }
+
+#endif // PLATFORM_FLOATING_POINT_H_
diff --git a/runtime/platform/floating_point_win.cc b/runtime/platform/floating_point_win.cc
new file mode 100644
index 0000000..82aee16
--- /dev/null
+++ b/runtime/platform/floating_point_win.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <math.h>
+#include <limits>
+
+#include "platform/globals.h"
+
+// Taken from third_party/v8/src/platform-win32.cc
+double fmod_ieee(double x, double y) {
+ // x is dividend, y is divisor.
+ // Work around MS fmod bugs. ISO Standard says:
+ // If dividend is finite and divisor is an infinity or
+ // dividend is a zero and divisor is nonzero finite,
+ // then dividend is returned.
+ if (!(_finite(x) && (!_finite(y) && !isnan(y))) &&
+ !(x == 0 && (y != 0 && _finite(y)))) {
+ x = fmod(x, y);
+ }
+ return x;
+}
+
+// Bring MSVC atan2 behavior in line with ISO standard.
+// MSVC atan2 returns NaN when x and y are either +infinity or -infinity.
+// Per ISO standard:
+// - If y is +/-infinity and x is -infinity, +/-3*pi/4 is returned.
+// - If y is +/-infinity and x is +infinity, +/-pi/4 is returned.
+double atan2_ieee(double x, double y) {
+ int cls_x = _fpclass(x);
+ int cls_y = _fpclass(y);
+ if (((cls_x & (_FPCLASS_PINF | _FPCLASS_NINF)) != 0) &&
+ ((cls_y & (_FPCLASS_PINF | _FPCLASS_NINF)) != 0)) {
+ // atan2 values at infinities listed above are the same as values
+ // at (+/-1, +/-1). index_x is 0, when x is +infinty, 1 when x is -infinty.
+ // Same is with index_y.
+ int index_x = (cls_x & _FPCLASS_PINF) != 0 ? 0 : 1;
+ int index_y = (cls_y & _FPCLASS_PINF) != 0 ? 0 : 1;
+ static double atans_at_infinities[2][2] =
+ { { atan2(1., 1.), atan2(1., -1.) },
+ { atan2(-1., 1.), atan2(-1., -1.) } };
+ return atans_at_infinities[index_x][index_y];
+ } else {
+ return atan2(x, y);
+ }
+}
diff --git a/runtime/platform/floating_point_win.h b/runtime/platform/floating_point_win.h
new file mode 100644
index 0000000..a97051a
--- /dev/null
+++ b/runtime/platform/floating_point_win.h
@@ -0,0 +1,11 @@
+// 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 PLATFORM_FLOATING_POINT_WIN_H_
+#define PLATFORM_FLOATING_POINT_WIN_H_
+
+double atan2_ieee(double x, double y);
+double fmod_ieee(double x, double y);
+
+#endif // PLATFORM_FLOATING_POINT_WIN_H_
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 95585b1..597e278 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -46,8 +46,14 @@
#if defined(_WIN32)
#include "platform/c99_support_win.h"
#include "platform/inttypes_support_win.h"
+#include "platform/floating_point_win.h"
#endif
+#if !defined(_WIN32)
+#include "platform/floating_point.h"
+#endif
+
+
// Target OS detection.
// for more information on predefined macros:
// - http://msdn.microsoft.com/en-us/library/b0084kay.aspx
diff --git a/runtime/platform/platform_headers.gypi b/runtime/platform/platform_headers.gypi
index 756a1a4..514ad08 100644
--- a/runtime/platform/platform_headers.gypi
+++ b/runtime/platform/platform_headers.gypi
@@ -11,6 +11,8 @@
'hashmap.h',
'inttypes_support_win.h',
'json.h',
+ 'floating_point.h',
+ 'floating_point_win.h',
'thread.h',
'thread_linux.h',
'thread_macos.h',
diff --git a/runtime/platform/platform_sources.gypi b/runtime/platform/platform_sources.gypi
index 2e2ddc7..eadf674 100644
--- a/runtime/platform/platform_sources.gypi
+++ b/runtime/platform/platform_sources.gypi
@@ -8,6 +8,7 @@
'assert.cc',
'hashmap.cc',
'json.cc',
+ 'floating_point_win.cc',
'thread_android.cc',
'thread_linux.cc',
'thread_macos.cc',
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 9b8ab80..f5f6038 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -2,10 +2,11 @@
# 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.
-# When a spawned isolate throws an uncaught exception, we terminate the vm.
-cc/RunLoop_ExceptionChild: Fail
-
-cc/SymbolUnicode: Fail
+cc/New: Crash # Issue 6958.
+cc/TypeVariableReflection: Crash # Issue 6958.
+cc/LibraryGetClassNames: Fail # Issue 6958.
+cc/ImportLibrary5: Fail # Issue 6958.
+cc/CustomIsolates: Crash # Default factory classes are removed.
# These tests are expected to crash on all platforms.
cc/ArrayNew_Overflow_Crash: Crash
diff --git a/runtime/tools/concat_library.py b/runtime/tools/concat_library.py
index 838bd42..dfb574a 100644
--- a/runtime/tools/concat_library.py
+++ b/runtime/tools/concat_library.py
@@ -31,7 +31,10 @@
for source in arguments:
with open(source, 'r') as inpt:
for line in inpt:
- if line.startswith('#source'):
+ # Drop unneeded library tags as all the library's files
+ # are concatenated into one big file here:
+ # The 'part' and 'part of' library tags are removed.
+ if line.startswith('#source') or line.startswith('part '):
line = '// %s' % line
output.write(line)
shutil.move(tmp_name, options.output)
diff --git a/runtime/tools/gyp/runtime-configurations.gypi b/runtime/tools/gyp/runtime-configurations.gypi
index 6a52f2d..7cb0a21 100644
--- a/runtime/tools/gyp/runtime-configurations.gypi
+++ b/runtime/tools/gyp/runtime-configurations.gypi
@@ -8,6 +8,16 @@
# If we have not set dart_io_support to 1 in Dart's all.gypi or common.gypi,
# then do not build the native libraries supporting dart:io.
'dart_io_support%': 0,
+ # Intel VTune related variables.
+ 'dart_vtune_support%': 0,
+ 'conditions': [
+ ['OS=="linux"', {
+ 'dart_vtune_root%': '/opt/intel/vtune_amplifier_xe',
+ }],
+ ['OS=="win"', {
+ 'dart_vtune_root%': 'C:/Program Files (x86)/Intel/VTune Amplifier XE 2013',
+ }],
+ ],
},
'target_defaults': {
@@ -41,6 +51,18 @@
'xcode_settings': {
'ARCHS': [ 'i386' ],
},
+ 'conditions': [
+ ['OS=="linux" and dart_vtune_support==1', {
+ 'ldflags': ['-L<(dart_vtune_root)/lib32'],
+ }],
+ ['OS=="win" and dart_vtune_support==1', {
+ 'msvs_settings': {
+ 'VCLinkerTool': {
+ 'AdditionalLibraryDirectories': ['<(dart_vtune_root)/lib32'],
+ },
+ },
+ }],
+ ],
},
'Dart_x64_Base': {
@@ -48,6 +70,18 @@
'xcode_settings': {
'ARCHS': [ 'x86_64' ],
},
+ 'conditions': [
+ ['OS=="linux" and dart_vtune_support==1', {
+ 'ldflags': ['-L<(dart_vtune_root)/lib64'],
+ }],
+ ['OS=="win" and dart_vtune_support==1', {
+ 'msvs_settings': {
+ 'VCLinkerTool': {
+ 'AdditionalLibraryDirectories': ['<(dart_vtune_root)/lib32'],
+ },
+ },
+ }],
+ ],
},
'Dart_simarm_Base': {
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 4895a74..6e2e4c7 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -73,7 +73,7 @@
UNIMPLEMENTED();
return 0;
}
- int prolog_offset() const {
+ int prologue_offset() const {
UNIMPLEMENTED();
return 0;
}
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 7fa7e21..72f84ed 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -1707,8 +1707,8 @@
void Assembler::EnterFrame(intptr_t frame_size) {
- if (prolog_offset_ == -1) {
- prolog_offset_ = CodeSize();
+ if (prologue_offset_ == -1) {
+ prologue_offset_ = CodeSize();
}
pushl(EBP);
movl(EBP, ESP);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index a738df3..78afb8f 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -275,7 +275,7 @@
class Assembler : public ValueObject {
public:
- Assembler() : buffer_(), prolog_offset_(-1), comments_() { }
+ Assembler() : buffer_(), prologue_offset_(-1), comments_() { }
~Assembler() { }
static const bool kNearJump = true;
@@ -603,7 +603,7 @@
void Bind(Label* label);
int CodeSize() const { return buffer_.Size(); }
- int prolog_offset() const { return prolog_offset_; }
+ int prologue_offset() const { return prologue_offset_; }
const ZoneGrowableArray<int>& GetPointerOffsets() const {
return buffer_.pointer_offsets();
}
@@ -628,7 +628,7 @@
private:
AssemblerBuffer buffer_;
- int prolog_offset_;
+ int prologue_offset_;
class CodeComment : public ZoneAllocated {
public:
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 57ffd01..04feed8 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -328,7 +328,7 @@
// Use 0x89 encoding (instead of 0x8B encoding), which is expected by gdb64
-// older than 7.3.1-gg5 when disassembling a function's prolog (movq rbp, rsp)
+// older than 7.3.1-gg5 when disassembling a function's prologue (movq rbp, rsp)
// for proper unwinding of Dart frames (use --generate_gdb_symbols and -O0).
void Assembler::movq(Register dst, Register src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
@@ -1799,8 +1799,8 @@
void Assembler::EnterFrame(intptr_t frame_size) {
- if (prolog_offset_ == -1) {
- prolog_offset_ = CodeSize();
+ if (prologue_offset_ == -1) {
+ prologue_offset_ = CodeSize();
}
pushq(RBP);
movq(RBP, RSP);
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index ab97b2a..fb73aac 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -291,7 +291,7 @@
class Assembler : public ValueObject {
public:
- Assembler() : buffer_(), prolog_offset_(-1), comments_() { }
+ Assembler() : buffer_(), prologue_offset_(-1), comments_() { }
~Assembler() { }
static const bool kNearJump = true;
@@ -625,7 +625,7 @@
const Code::Comments& GetCodeComments() const;
int CodeSize() const { return buffer_.Size(); }
- int prolog_offset() const { return prolog_offset_; }
+ int prologue_offset() const { return prologue_offset_; }
const ZoneGrowableArray<int>& GetPointerOffsets() const {
return buffer_.pointer_offsets();
}
@@ -648,7 +648,7 @@
private:
AssemblerBuffer buffer_;
- int prolog_offset_;
+ int prologue_offset_;
class CodeComment : public ZoneAllocated {
public:
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index d719b0e..ff44ac8 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -203,10 +203,8 @@
// Create strings.
uint8_t data8[] = { 'o', 'n', 'e', 0xFF };
int external_peer_data = 123;
- Dart_Handle external_string = Dart_NewExternalUTF8String(data8,
- ARRAY_SIZE(data8),
- &external_peer_data,
- NULL);
+ Dart_Handle external_string = Dart_NewExternalLatin1String(
+ data8, ARRAY_SIZE(data8), &external_peer_data, NULL);
Dart_Handle internal_string = NewString("two");
// Run benchmark.
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index fad33c9..390860f 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -74,6 +74,7 @@
V(ObjectArray_copyFromObjectArray, 5) \
V(StringBase_createFromCodePoints, 1) \
V(StringBase_substringUnchecked, 3) \
+ V(OneByteString_substringUnchecked, 3) \
V(String_getHashCode, 1) \
V(String_getLength, 1) \
V(String_charAt, 2) \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index bae68fd..19e82a9 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -139,9 +139,6 @@
OS::Print("Resolving super and interfaces: %s\n", cls.ToCString());
}
ResolveSuperType(cls);
- if (cls.is_interface()) {
- ResolveFactoryClass(cls);
- }
GrowableArray<intptr_t> visited_interfaces;
ResolveInterfaces(cls, &visited_interfaces);
}
@@ -322,16 +319,6 @@
// Resolve failures lead to a longjmp.
ResolveType(cls, super_type, kCanonicalizeWellFormed);
const Class& super_class = Class::Handle(super_type.type_class());
- if (cls.is_interface() != super_class.is_interface()) {
- String& class_name = String::Handle(cls.Name());
- String& super_class_name = String::Handle(super_class.Name());
- const Script& script = Script::Handle(cls.script());
- ReportError(script, cls.token_pos(),
- "class '%s' and superclass '%s' are not "
- "both classes or both interfaces",
- class_name.ToCString(),
- super_class_name.ToCString());
- }
// If cls belongs to core lib or to core lib's implementation, restrictions
// about allowed interfaces are lifted.
if (cls.library() != Library::CoreLibrary()) {
@@ -400,86 +387,6 @@
}
-void ClassFinalizer::ResolveFactoryClass(const Class& interface) {
- ASSERT(interface.is_interface());
- if (interface.is_finalized() ||
- !interface.HasFactoryClass() ||
- interface.HasResolvedFactoryClass()) {
- return;
- }
- const UnresolvedClass& unresolved_factory_class =
- UnresolvedClass::Handle(interface.UnresolvedFactoryClass());
-
- // Lookup the factory class.
- const Class& factory_class =
- Class::Handle(ResolveClass(interface, unresolved_factory_class));
- if (factory_class.IsNull()) {
- const Script& script = Script::Handle(interface.script());
- ReportError(script, unresolved_factory_class.token_pos(),
- "cannot resolve factory class name '%s' from '%s'",
- String::Handle(unresolved_factory_class.Name()).ToCString(),
- String::Handle(interface.Name()).ToCString());
- }
- if (factory_class.is_interface()) {
- const String& interface_name = String::Handle(interface.Name());
- const String& factory_name = String::Handle(factory_class.Name());
- const Script& script = Script::Handle(interface.script());
- ReportError(script, unresolved_factory_class.token_pos(),
- "default clause of interface '%s' names non-class '%s'",
- interface_name.ToCString(),
- factory_name.ToCString());
- }
- interface.set_factory_class(factory_class);
- // It is not necessary to finalize the bounds before comparing them between
- // the expected and actual factory class.
- const Class& factory_signature_class = Class::Handle(
- unresolved_factory_class.factory_signature_class());
- ASSERT(!factory_signature_class.IsNull());
- // If a type parameter list is included in the default factory clause (it
- // can be omitted), verify that it matches the list of type parameters of
- // the factory class in number, names, and bounds.
- if (factory_signature_class.NumTypeParameters() > 0) {
- const TypeArguments& expected_type_parameters =
- TypeArguments::Handle(factory_signature_class.type_parameters());
- const TypeArguments& actual_type_parameters =
- TypeArguments::Handle(factory_class.type_parameters());
- const bool check_type_parameter_bounds = true;
- if (!AbstractTypeArguments::AreIdentical(expected_type_parameters,
- actual_type_parameters,
- check_type_parameter_bounds)) {
- const String& interface_name = String::Handle(interface.Name());
- const String& factory_name = String::Handle(factory_class.Name());
- const Script& script = Script::Handle(interface.script());
- ReportError(script, unresolved_factory_class.token_pos(),
- "mismatch in number, names, or bounds of type parameters "
- "between default clause of interface '%s' and actual factory "
- "class '%s'",
- interface_name.ToCString(),
- factory_name.ToCString());
- }
- }
- // Verify that the type parameters of the factory class and of the interface
- // have identical names, but not necessarily identical bounds.
- const TypeArguments& interface_type_parameters =
- TypeArguments::Handle(interface.type_parameters());
- const TypeArguments& factory_type_parameters =
- TypeArguments::Handle(factory_class.type_parameters());
- const bool check_type_parameter_bounds = false;
- if (!AbstractTypeArguments::AreIdentical(interface_type_parameters,
- factory_type_parameters,
- check_type_parameter_bounds)) {
- const String& interface_name = String::Handle(interface.Name());
- const String& factory_name = String::Handle(factory_class.Name());
- const Script& script = Script::Handle(interface.script());
- ReportError(script, unresolved_factory_class.token_pos(),
- "mismatch in number or names of type parameters between "
- "interface '%s' and default factory class '%s'",
- interface_name.ToCString(),
- factory_name.ToCString());
- }
-}
-
-
void ClassFinalizer::ResolveRedirectingFactoryTarget(
const Class& cls,
const Function& factory,
@@ -1225,11 +1132,10 @@
const String& super_class_name = String::Handle(super_class.Name());
const Script& script = Script::Handle(cls.script());
ReportError(script, function.token_pos(),
- "class '%s' overrides function '%s' of %s '%s' "
+ "class '%s' overrides function '%s' of super class '%s' "
"with incompatible parameters",
class_name.ToCString(),
function_name.ToCString(),
- super_class.is_interface() ? "interface" : "super class",
super_class_name.ToCString());
}
}
@@ -1317,19 +1223,6 @@
ASSERT(super_type.IsNull() || super_type.IsObjectType());
return;
}
- // Finalize factory class, if any.
- if (cls.is_interface()) {
- if (cls.HasFactoryClass()) {
- const Class& factory_class = Class::Handle(cls.FactoryClass());
- if (!factory_class.is_finalized()) {
- FinalizeClass(factory_class);
- // Finalizing the factory class may indirectly finalize this interface.
- if (cls.is_finalized()) {
- return;
- }
- }
- }
- }
// Finalize interface types (but not necessarily interface classes).
Array& interface_types = Array::Handle(cls.interfaces());
AbstractType& interface_type = AbstractType::Handle();
@@ -1501,6 +1394,7 @@
String::Handle(interface_class.Name()).ToCString());
}
}
+ interface_class.set_is_implemented();
// Now resolve the super interfaces.
ResolveInterfaces(interface_class, visited);
}
@@ -1542,9 +1436,7 @@
void ClassFinalizer::PrintClassInformation(const Class& cls) {
HANDLESCOPE(Isolate::Current());
const String& class_name = String::Handle(cls.Name());
- OS::Print("%s '%s'",
- cls.is_interface() ? "interface" : "class",
- class_name.ToCString());
+ OS::Print("class '%s'", class_name.ToCString());
const Library& library = Library::Handle(cls.library());
if (!library.IsNull()) {
OS::Print(" library '%s%s':\n",
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 2fe9ea6..6804b0c 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -96,7 +96,6 @@
static RawClass* ResolveClass(const Class& cls,
const UnresolvedClass& unresolved_class);
static void ResolveSuperType(const Class& cls);
- static void ResolveFactoryClass(const Class& cls);
static void ResolveRedirectingFactoryTarget(
const Class& cls,
const Function& factory,
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index abf1cdd..ed90731 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -402,20 +402,18 @@
// Converts InstantiatedTypeArguments to TypeArguments and stores it
// into the instance. The assembly code can handle only type arguments of
// class TypeArguments. Because of the overhead, do it only when needed.
-// Return false if the optimization was aborted.
-// Set type_arguments_replaced to true if they have changed.
-static bool OptimizeTypeArguments(const Instance& instance,
- bool* type_arguments_replaced) {
- *type_arguments_replaced = false;
+// Return true if type arguments have been replaced, false otherwise.
+static bool OptimizeTypeArguments(const Instance& instance) {
const Class& type_class = Class::ZoneHandle(instance.clazz());
if (!type_class.HasTypeArguments()) {
- return true;
+ return false;
}
AbstractTypeArguments& type_arguments =
AbstractTypeArguments::Handle(instance.GetTypeArguments());
if (type_arguments.IsNull()) {
- return true;
+ return false;
}
+ bool replaced = false;
if (type_arguments.IsInstantiatedTypeArguments()) {
do {
const InstantiatedTypeArguments& instantiated_type_arguments =
@@ -431,16 +429,16 @@
AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle();
new_type_arguments = type_arguments.Canonicalize();
instance.SetTypeArguments(new_type_arguments);
- *type_arguments_replaced = true;
+ replaced = true;
} else if (!type_arguments.IsCanonical()) {
AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle();
new_type_arguments = type_arguments.Canonicalize();
instance.SetTypeArguments(new_type_arguments);
- *type_arguments_replaced = true;
+ replaced = true;
}
ASSERT(AbstractTypeArguments::Handle(
instance.GetTypeArguments()).IsTypeArguments());
- return true;
+ return replaced;
}
@@ -473,26 +471,11 @@
bool type_arguments_replaced = false;
if (instance_class.HasTypeArguments()) {
// Canonicalize type arguments.
- if (!OptimizeTypeArguments(instance, &type_arguments_replaced)) {
- if (FLAG_trace_type_checks) {
- PrintTypeCheck("WARNING: Cannot canonicalize instance type arguments",
- instance, type, instantiator_type_arguments, result);
- }
- return;
- }
+ type_arguments_replaced = OptimizeTypeArguments(instance);
instance_type_arguments = instance.GetTypeArguments();
}
if (!instantiator.IsNull()) {
- bool replaced = false;
- if (!OptimizeTypeArguments(instantiator, &replaced)) {
- if (FLAG_trace_type_checks) {
- PrintTypeCheck("WARNING: Cannot canonicalize instantiator "
- "type arguments",
- instance, type, instantiator_type_arguments, result);
- }
- return;
- }
- if (replaced) {
+ if (OptimizeTypeArguments(instantiator)) {
type_arguments_replaced = true;
}
instantiator_type_arguments = instantiator.GetTypeArguments();
@@ -1380,26 +1363,6 @@
}
-// A closure object was invoked with incompatible arguments.
-// TODO(regis): Deprecated. This case should be handled by a noSuchMethod call.
-DEFINE_RUNTIME_ENTRY(ClosureArgumentMismatch, 0) {
- ASSERT(arguments.ArgCount() ==
- kClosureArgumentMismatchRuntimeEntry.argument_count());
- const Instance& instance = Instance::Handle(); // Incorrect. OK for now.
- const Array& function_args = Array::Handle(); // Incorrect. OK for now.
- const String& function_name = String::Handle(Symbols::Call());
- GrowableArray<const Object*> dart_arguments(5);
-
- const Object& null_object = Object::Handle();
- dart_arguments.Add(&instance);
- dart_arguments.Add(&function_name);
- dart_arguments.Add(&function_args);
- dart_arguments.Add(&null_object);
- Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments);
- UNREACHABLE();
-}
-
-
DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
ASSERT(arguments.ArgCount() ==
kStackOverflowRuntimeEntry.argument_count());
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index a212cea..1bd9632 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -23,7 +23,6 @@
DECLARE_RUNTIME_ENTRY(BreakpointReturnHandler);
DECLARE_RUNTIME_ENTRY(BreakpointDynamicHandler);
DECLARE_RUNTIME_ENTRY(CloneContext);
-DECLARE_RUNTIME_ENTRY(ClosureArgumentMismatch);
DECLARE_RUNTIME_ENTRY(Deoptimize);
DECLARE_RUNTIME_ENTRY(FixCallersTarget);
DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg);
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
new file mode 100644
index 0000000..b476a0d
--- /dev/null
+++ b/runtime/vm/code_observers.cc
@@ -0,0 +1,142 @@
+// 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 "vm/code_observers.h"
+
+#include "vm/dart.h"
+#include "vm/debuginfo.h"
+#include "vm/flags.h"
+#include "vm/isolate.h"
+#include "vm/os.h"
+#include "vm/vtune.h"
+#include "vm/zone.h"
+
+namespace dart {
+
+DEFINE_FLAG(bool, generate_gdb_symbols, false,
+ "Generate symbols of generated dart functions for debugging with GDB");
+
+intptr_t CodeObservers::observers_length_ = 0;
+CodeObserver** CodeObservers::observers_ = NULL;
+
+
+void CodeObservers::Register(CodeObserver* observer) {
+ observers_length_++;
+ observers_ = reinterpret_cast<CodeObserver**>(
+ realloc(observers_, sizeof(observer) * observers_length_));
+ if (observers_ == NULL) {
+ FATAL("failed to grow code observers array");
+ }
+ observers_[observers_length_ - 1] = observer;
+}
+
+
+void CodeObservers::NotifyAll(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) {
+ ASSERT(!AreActive() || (strlen(name) != 0));
+ for (intptr_t i = 0; i < observers_length_; i++) {
+ if (observers_[i]->IsActive()) {
+ observers_[i]->Notify(name, base, prologue_offset, size, optimized);
+ }
+ }
+}
+
+
+bool CodeObservers::AreActive() {
+ for (intptr_t i = 0; i < observers_length_; i++) {
+ if (observers_[i]->IsActive()) return true;
+ }
+ return false;
+}
+
+
+class PerfCodeObserver : public CodeObserver {
+ public:
+ virtual bool IsActive() const {
+ return Dart::perf_events_writer() != NULL;
+ }
+
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) {
+ Dart_FileWriterFunction perf_events_writer = Dart::perf_events_writer();
+ ASSERT(perf_events_writer != NULL);
+
+ const char* format = "%"Px" %"Px" %s%s\n";
+ const char* marker = optimized ? "*" : "";
+ intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name);
+ char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+ OS::SNPrint(buffer, len + 1, format, base, size, marker, name);
+ (*perf_events_writer)(buffer, len);
+ }
+};
+
+
+class PprofCodeObserver : public CodeObserver {
+ public:
+ virtual bool IsActive() const {
+ return Dart::pprof_symbol_generator() != NULL;
+ }
+
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) {
+ DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
+ ASSERT(pprof_symbol_generator != NULL);
+ pprof_symbol_generator->AddCode(base, size);
+ pprof_symbol_generator->AddCodeRegion(name, base, size);
+ }
+};
+
+
+class GdbCodeObserver : public CodeObserver {
+ public:
+ virtual bool IsActive() const {
+ return FLAG_generate_gdb_symbols;
+ }
+
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) {
+ if (prologue_offset > 0) {
+ // In order to ensure that gdb sees the first instruction of a function
+ // as the prologue sequence we register two symbols for the cases when
+ // the prologue sequence is not the first instruction:
+ // <name>_entry is used for code preceding the prologue sequence.
+ // <name> for rest of the code (first instruction is prologue sequence).
+ const char* kFormat = "%s_%s";
+ intptr_t len = OS::SNPrint(NULL, 0, kFormat, name, "entry");
+ char* pname = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
+ OS::SNPrint(pname, (len + 1), kFormat, name, "entry");
+ DebugInfo::RegisterSection(pname, base, size);
+ DebugInfo::RegisterSection(name,
+ (base + prologue_offset),
+ (size - prologue_offset));
+ } else {
+ DebugInfo::RegisterSection(name, base, size);
+ }
+ }
+};
+
+
+void CodeObservers::InitOnce() {
+ Register(new PerfCodeObserver);
+ Register(new PprofCodeObserver);
+ Register(new GdbCodeObserver);
+#if defined(DART_VTUNE_SUPPORT)
+ Register(new VTuneCodeObserver);
+#endif
+}
+
+
+} // namespace dart
diff --git a/runtime/vm/code_observers.h b/runtime/vm/code_observers.h
new file mode 100644
index 0000000..1891f3d
--- /dev/null
+++ b/runtime/vm/code_observers.h
@@ -0,0 +1,56 @@
+// 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 VM_CODE_OBSERVERS_H_
+#define VM_CODE_OBSERVERS_H_
+
+#include "vm/globals.h"
+
+namespace dart {
+
+// Object observing code creation events. Used by external profilers and
+// debuggers to map address ranges to function names.
+class CodeObserver {
+ public:
+ virtual ~CodeObserver() { }
+
+ // Returns true if this observer is active and should be notified
+ // about newly created code objects.
+ virtual bool IsActive() const = 0;
+
+ // Notify code observer about a newly created code object with the
+ // given properties.
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) = 0;
+};
+
+
+class CodeObservers {
+ public:
+ static void InitOnce();
+
+ static void Register(CodeObserver* observer);
+
+ // Notify all active code observers about a newly created code object.
+ static void NotifyAll(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized);
+
+ // Returns true if there is at least one active code observer.
+ static bool AreActive();
+
+ private:
+ static intptr_t observers_length_;
+ static CodeObserver** observers_;
+};
+
+
+} // namespace dart
+
+#endif // VM_CODE_OBSERVERS_H_
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 25cb8a3..c82be17 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -553,6 +553,12 @@
Error& error = Error::Handle();
Array& functions = Array::Handle(cls.functions());
Function& func = Function::Handle();
+ // Class dynamic lives in the vm isolate. Its array fields cannot be set to
+ // an empty array.
+ if (functions.IsNull()) {
+ ASSERT(cls.IsDynamicClass());
+ return error.raw();
+ }
for (int i = 0; i < functions.Length(); i++) {
func ^= functions.At(i);
ASSERT(!func.IsNull());
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index fcc3501..5c6abe5 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -4,6 +4,7 @@
#include "vm/dart.h"
+#include "vm/code_observers.h"
#include "vm/dart_api_state.h"
#include "vm/flags.h"
#include "vm/freelist.h"
@@ -49,8 +50,9 @@
// TODO(turnidge): We should add a corresponding Dart::Cleanup.
const char* Dart::InitOnce(Dart_IsolateCreateCallback create,
- Dart_IsolateInterruptCallback interrupt,
- Dart_IsolateShutdownCallback shutdown) {
+ Dart_IsolateInterruptCallback interrupt,
+ Dart_IsolateUnhandledExceptionCallback unhandled,
+ Dart_IsolateShutdownCallback shutdown) {
// TODO(iposva): Fix race condition here.
if (vm_isolate_ != NULL || !Flags::Initialized()) {
return "VM already initialized.";
@@ -61,6 +63,7 @@
PortMap::InitOnce();
FreeListElement::InitOnce();
Api::InitOnce();
+ CodeObservers::InitOnce();
// Create the VM isolate and finish the VM initialization.
ASSERT(thread_pool_ == NULL);
thread_pool_ = new ThreadPool();
@@ -90,6 +93,7 @@
Isolate::SetCurrent(NULL); // Unregister the VM isolate from this thread.
Isolate::SetCreateCallback(create);
Isolate::SetInterruptCallback(interrupt);
+ Isolate::SetUnhandledExceptionCallback(unhandled);
Isolate::SetShutdownCallback(shutdown);
return NULL;
}
@@ -191,4 +195,5 @@
}
}
+
} // namespace dart
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 585cddd..b716661 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -18,9 +18,11 @@
class Dart : public AllStatic {
public:
- static const char* InitOnce(Dart_IsolateCreateCallback create,
- Dart_IsolateInterruptCallback interrupt,
- Dart_IsolateShutdownCallback shutdown);
+ static const char* InitOnce(
+ Dart_IsolateCreateCallback create,
+ Dart_IsolateInterruptCallback interrupt,
+ Dart_IsolateUnhandledExceptionCallback unhandled,
+ Dart_IsolateShutdownCallback shutdown);
static Isolate* CreateIsolate(const char* name_prefix);
static RawError* InitializeIsolate(const uint8_t* snapshot, void* data);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index aed8a10..5173713 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -736,10 +736,12 @@
return Version::String();
}
-DART_EXPORT bool Dart_Initialize(Dart_IsolateCreateCallback create,
- Dart_IsolateInterruptCallback interrupt,
- Dart_IsolateShutdownCallback shutdown) {
- const char* err_msg = Dart::InitOnce(create, interrupt, shutdown);
+DART_EXPORT bool Dart_Initialize(
+ Dart_IsolateCreateCallback create,
+ Dart_IsolateInterruptCallback interrupt,
+ Dart_IsolateUnhandledExceptionCallback unhandled,
+ Dart_IsolateShutdownCallback shutdown) {
+ const char* err_msg = Dart::InitOnce(create, interrupt, unhandled, shutdown);
if (err_msg != NULL) {
OS::PrintErr("Dart_Initialize: %s\n", err_msg);
return false;
@@ -1615,18 +1617,19 @@
}
-DART_EXPORT Dart_Handle Dart_NewExternalUTF8String(const uint8_t* utf8_array,
- intptr_t length,
- void* peer,
- Dart_PeerFinalizer cback) {
+DART_EXPORT Dart_Handle Dart_NewExternalLatin1String(
+ const uint8_t* latin1_array,
+ intptr_t length,
+ void* peer,
+ Dart_PeerFinalizer cback) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
- if (utf8_array == NULL && length != 0) {
- RETURN_NULL_ERROR(utf8_array);
+ if (latin1_array == NULL && length != 0) {
+ RETURN_NULL_ERROR(latin1_array);
}
CHECK_LENGTH(length, String::kMaxElements);
return Api::NewHandle(isolate,
- String::NewExternal(utf8_array, length, peer, cback));
+ String::NewExternal(latin1_array, length, peer, cback));
}
@@ -1747,6 +1750,10 @@
if (array == NULL) {
RETURN_NULL_ERROR(array);
}
+ if (str_obj.IsCanonical()) {
+ return Api::NewError("Dart_MakeExternalString "
+ "cannot externalize a read-only string.");
+ }
intptr_t str_size = (str_obj.Length() * str_obj.CharSize());
if ((length < str_size) || (length > String::kMaxElements)) {
return Api::NewError("Dart_MakeExternalString "
@@ -2456,26 +2463,23 @@
}
-// --- Classes and Interfaces ---
+// --- Classes ---
DART_EXPORT bool Dart_IsClass(Dart_Handle handle) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle));
- if (obj.IsClass()) {
- return !Class::Cast(obj).is_interface();
- }
- return false;
+ return obj.IsClass();
}
-DART_EXPORT bool Dart_IsInterface(Dart_Handle handle) {
+DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle));
if (obj.IsClass()) {
- return Class::Cast(obj).is_interface();
+ return Class::Cast(obj).is_abstract();
}
return false;
}
@@ -2514,27 +2518,6 @@
}
-DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) {
- Isolate* isolate = Isolate::Current();
- DARTSCOPE(isolate);
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
- if (cls.IsNull()) {
- RETURN_TYPE_ERROR(isolate, clazz, Class);
- }
-
- // Finalize all classes.
- const char* msg = CheckIsolateState(isolate);
- if (msg != NULL) {
- return Api::NewError("%s", msg);
- }
-
- if (cls.HasFactoryClass() && cls.HasResolvedFactoryClass()) {
- return Api::NewHandle(isolate, cls.FactoryClass());
- }
- return Api::Null(isolate);
-}
-
-
DART_EXPORT Dart_Handle Dart_ClassGetInterfaceCount(Dart_Handle clazz,
intptr_t* count) {
Isolate* isolate = Isolate::Current();
@@ -3334,40 +3317,13 @@
return Api::NewError("%s", msg);
}
- // Check for interfaces with default implementations.
- if (cls.is_interface()) {
- // Make sure that the constructor is found in the interface.
- result = ResolveConstructor(
- "Dart_New", cls, base_constructor_name, dot_name, number_of_arguments);
- if (result.IsError()) {
- return Api::NewHandle(isolate, result.raw());
- }
-
- ASSERT(cls.HasResolvedFactoryClass());
- const Class& factory_class = Class::Handle(cls.FactoryClass());
-
- // If the factory class implements the requested interface, then
- // we use the name of the factory class when looking up the
- // constructor. Otherwise we use the original interface name when
- // looking up the constructor.
- const TypeArguments& no_type_args = TypeArguments::Handle(isolate);
- Error& error = Error::Handle();
- if (factory_class.IsSubtypeOf(no_type_args, cls, no_type_args, &error)) {
- base_constructor_name = factory_class.Name();
- }
- if (!error.IsNull()) {
- return Api::NewHandle(isolate, error.raw());
- }
-
- cls = cls.FactoryClass();
- }
-
// Resolve the constructor.
result = ResolveConstructor(
"Dart_New", cls, base_constructor_name, dot_name, number_of_arguments);
if (result.IsError()) {
return Api::NewHandle(isolate, result.raw());
}
+ // TODO(turnidge): Support redirecting factories.
ASSERT(result.IsFunction());
Function& constructor = Function::Handle(isolate);
constructor ^= result.raw();
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index ecc1df1..bbae17f 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -521,8 +521,8 @@
EXPECT(Dart_IsStringLatin1(str8));
EXPECT(!Dart_IsExternalString(str8));
- Dart_Handle ext8 = Dart_NewExternalUTF8String(data8, ARRAY_SIZE(data8),
- NULL, NULL);
+ Dart_Handle ext8 = Dart_NewExternalLatin1String(data8, ARRAY_SIZE(data8),
+ NULL, NULL);
EXPECT_VALID(ext8);
EXPECT(Dart_IsString(ext8));
EXPECT(Dart_IsExternalString(ext8));
@@ -575,13 +575,13 @@
TEST_CASE(ExternalStringGetPeer) {
Dart_Handle result;
- uint8_t data8[] = { 'o', 'n', 'e', 0x7F };
+ uint8_t data8[] = { 'o', 'n', 'e', 0xFF };
int peer_data = 123;
void* peer = NULL;
// Success.
- Dart_Handle ext8 = Dart_NewExternalUTF8String(data8, ARRAY_SIZE(data8),
- &peer_data, NULL);
+ Dart_Handle ext8 = Dart_NewExternalLatin1String(data8, ARRAY_SIZE(data8),
+ &peer_data, NULL);
EXPECT_VALID(ext8);
result = Dart_ExternalStringGetPeer(ext8, &peer);
@@ -596,7 +596,8 @@
// String is not external.
peer = NULL;
- Dart_Handle str8 = Dart_NewStringFromUTF8(data8, ARRAY_SIZE(data8));
+ uint8_t utf8_data8[] = { 'o', 'n', 'e', 0x7F };
+ Dart_Handle str8 = Dart_NewStringFromUTF8(utf8_data8, ARRAY_SIZE(data8));
EXPECT_VALID(str8);
result = Dart_ExternalStringGetPeer(str8, &peer);
EXPECT(Dart_IsError(result));
@@ -630,7 +631,7 @@
Dart_EnterScope();
uint8_t data8[] = { 'h', 'e', 'l', 'l', 'o' };
- Dart_Handle obj8 = Dart_NewExternalUTF8String(
+ Dart_Handle obj8 = Dart_NewExternalLatin1String(
data8,
ARRAY_SIZE(data8),
&peer8,
@@ -2014,7 +2015,7 @@
EXPECT_EQ(7, global_epilogue_callback_status);
// Garbage collect old space again. Callbacks are persistent so the
- // prolog status value should change again.
+ // prologue status value should change again.
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
EXPECT_EQ(12, global_prologue_callback_status);
EXPECT_EQ(7, global_epilogue_callback_status);
@@ -2330,79 +2331,6 @@
// Only ia32 and x64 can run execution tests.
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
-
-TEST_CASE(ClassBasics) {
- const char* kScriptChars =
- "class MyClass {\n"
- "}\n"
- "class MyDefault {\n"
- "}\n"
- "interface MyInterface default MyDefault {\n"
- "}\n";
- Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
- Dart_Handle cls = Dart_GetClass(lib, NewString("MyClass"));
- Dart_Handle interface = Dart_GetClass(lib, NewString("MyInterface"));
-
- // Test Dart_IsClass and Dart_IsInterface.
- EXPECT(Dart_IsClass(cls));
- EXPECT(!Dart_IsClass(interface));
- EXPECT(!Dart_IsClass(Dart_True()));
-
- EXPECT(!Dart_IsInterface(cls));
- EXPECT(Dart_IsInterface(interface));
- EXPECT(!Dart_IsInterface(Dart_True()));
-
- EXPECT(!Dart_IsInterface(cls));
- EXPECT(Dart_IsInterface(interface));
- EXPECT(!Dart_IsInterface(Dart_True()));
-
- // Test Dart_ClassName
- Dart_Handle cls_name = Dart_ClassName(cls);
- EXPECT_VALID(cls_name);
- const char* cls_name_cstr = "";
- EXPECT_VALID(Dart_StringToCString(cls_name, &cls_name_cstr));
- EXPECT_STREQ("MyClass", cls_name_cstr);
-
- cls_name = Dart_ClassName(interface);
- EXPECT_VALID(cls_name);
- cls_name_cstr = "";
- EXPECT_VALID(Dart_StringToCString(cls_name, &cls_name_cstr));
- EXPECT_STREQ("MyInterface", cls_name_cstr);
-
- EXPECT_ERROR(Dart_ClassName(Dart_True()),
- "Dart_ClassName expects argument 'clazz' to be of type Class.");
- EXPECT_ERROR(Dart_ClassName(Dart_NewApiError("MyError")), "MyError");
-
- // Test Dart_ClassGetLibrary
- Dart_Handle cls_lib = Dart_ClassGetLibrary(cls);
- Dart_Handle cls_lib_name = Dart_LibraryName(cls_lib);
- EXPECT_VALID(cls_lib_name);
- const char* cls_lib_name_cstr = "";
- EXPECT_VALID(Dart_StringToCString(cls_lib_name, &cls_lib_name_cstr));
- EXPECT_STREQ(TestCase::url(), cls_lib_name_cstr);
-
- EXPECT_ERROR(
- Dart_ClassGetLibrary(Dart_True()),
- "Dart_ClassGetLibrary expects argument 'clazz' to be of type Class.");
- EXPECT_ERROR(Dart_ClassGetLibrary(Dart_NewApiError("MyError")), "MyError");
-
-
- Dart_Handle dflt = Dart_ClassGetDefault(interface);
- EXPECT_VALID(dflt);
- EXPECT(Dart_IsClass(dflt));
- Dart_Handle dflt_name = Dart_ClassName(dflt);
- EXPECT_VALID(dflt_name);
- const char* dflt_name_cstr = "";
- EXPECT_VALID(Dart_StringToCString(dflt_name, &dflt_name_cstr));
- EXPECT_STREQ("MyDefault", dflt_name_cstr);
-
- EXPECT(Dart_IsNull(Dart_ClassGetDefault(cls)));
- EXPECT_ERROR(
- Dart_ClassGetDefault(Dart_True()),
- "Dart_ClassGetDefault expects argument 'clazz' to be of type Class.");
- EXPECT_ERROR(Dart_ClassGetDefault(Dart_NewApiError("MyError")), "MyError");
-}
-
TEST_CASE(ClassTypedefsEtc) {
const char* kScriptChars =
"class SomeClass {\n"
@@ -2451,16 +2379,16 @@
"class 'SomeClass' is not a function-type class.");
}
-#define CHECK_INTERFACE(handle, name) \
- { \
- Dart_Handle tmp = (handle); \
- EXPECT_VALID(tmp); \
- EXPECT(Dart_IsInterface(tmp)); \
- Dart_Handle intf_name = Dart_ClassName(tmp); \
- EXPECT_VALID(intf_name); \
- const char* intf_name_cstr = ""; \
- EXPECT_VALID(Dart_StringToCString(intf_name, &intf_name_cstr)); \
- EXPECT_STREQ((name), intf_name_cstr); \
+#define CHECK_ABSTRACT_CLASS(handle, name) \
+ { \
+ Dart_Handle tmp = (handle); \
+ EXPECT_VALID(tmp); \
+ EXPECT(Dart_IsAbstractClass(tmp)); \
+ Dart_Handle intf_name = Dart_ClassName(tmp); \
+ EXPECT_VALID(intf_name); \
+ const char* intf_name_cstr = ""; \
+ EXPECT_VALID(Dart_StringToCString(intf_name, &intf_name_cstr)); \
+ EXPECT_STREQ((name), intf_name_cstr); \
}
@@ -2475,10 +2403,10 @@
"class MyClass2 implements MyInterface0, MyInterface1 {\n"
"}\n"
"\n"
- "interface MyInterface0 {\n"
+ "abstract class MyInterface0 {\n"
"}\n"
"\n"
- "interface MyInterface1 extends MyInterface0 {\n"
+ "abstract class MyInterface1 implements MyInterface0 {\n"
"}\n";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -2498,7 +2426,7 @@
len = -1;
EXPECT_VALID(Dart_ClassGetInterfaceCount(cls1, &len));
EXPECT_EQ(1, len);
- CHECK_INTERFACE(Dart_ClassGetInterfaceAt(cls1, 0), "MyInterface1");
+ CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(cls1, 0), "MyInterface1");
EXPECT_ERROR(Dart_ClassGetInterfaceAt(cls1, -1),
"Dart_ClassGetInterfaceAt: argument 'index' out of bounds");
@@ -2510,8 +2438,8 @@
EXPECT_EQ(2, len);
// TODO(turnidge): The test relies on the ordering here. Sort this.
- CHECK_INTERFACE(Dart_ClassGetInterfaceAt(cls2, 0), "MyInterface0");
- CHECK_INTERFACE(Dart_ClassGetInterfaceAt(cls2, 1), "MyInterface1");
+ CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(cls2, 0), "MyInterface0");
+ CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(cls2, 1), "MyInterface1");
len = -1;
EXPECT_VALID(Dart_ClassGetInterfaceCount(intf0, &len));
@@ -2520,7 +2448,7 @@
len = -1;
EXPECT_VALID(Dart_ClassGetInterfaceCount(intf1, &len));
EXPECT_EQ(1, len);
- CHECK_INTERFACE(Dart_ClassGetInterfaceAt(intf1, 0), "MyInterface0");
+ CHECK_ABSTRACT_CLASS(Dart_ClassGetInterfaceAt(intf1, 0), "MyInterface0");
// Error cases.
EXPECT_ERROR(Dart_ClassGetInterfaceCount(Dart_True(), &len),
@@ -6250,11 +6178,28 @@
}
+// The error string from the last unhandled exception. This value is only
+// valid until the next Dart_ExitScope().
+static char* last_exception = NULL;
+
+
+static void RunLoopUnhandledExceptionCallback(Dart_Handle exception) {
+ Dart_Handle error_string = Dart_ToString(exception);
+ EXPECT_VALID(error_string);
+ const char* error_text;
+ Dart_Handle result = Dart_StringToCString(error_string, &error_text);
+ // Duplicate the string since error text is freed when callback is finished.
+ last_exception = strdup(error_text);
+ EXPECT_VALID(result);
+}
+
+
// Common code for RunLoop_Success/RunLoop_Failure.
static void RunLoopTest(bool throw_exception_child,
bool throw_exception_parent) {
Dart_IsolateCreateCallback saved = Isolate::CreateCallback();
Isolate::SetCreateCallback(RunLoopTestCallback);
+ Isolate::SetUnhandledExceptionCallback(RunLoopUnhandledExceptionCallback);
RunLoopTestCallback(NULL, NULL, NULL, NULL);
Dart_EnterScope();
@@ -6267,11 +6212,24 @@
args[1] = (throw_exception_parent ? Dart_True() : Dart_False());
result = Dart_Invoke(lib, NewString("main"), 2, args);
EXPECT_VALID(result);
- result = Dart_RunLoop();
- if (throw_exception_parent) {
- EXPECT_ERROR(result, "Exception: MakeParentExit");
+ if (throw_exception_child) {
+ // TODO(tball): fix race-condition
+ // EXPECT_NOTNULL(last_exception);
+ // EXPECT_STREQ("UnhandledException", last_exception);
} else {
- EXPECT_VALID(result);
+ result = Dart_RunLoop();
+ if (throw_exception_parent) {
+ EXPECT_ERROR(result, "Exception: MakeParentExit");
+ EXPECT_NOTNULL(last_exception);
+ EXPECT_STREQ("UnhandledException", last_exception);
+ } else {
+ EXPECT_VALID(result);
+ EXPECT(last_exception == NULL);
+ }
+ }
+ if (last_exception != NULL) {
+ free(last_exception);
+ last_exception = NULL;
}
Dart_ExitScope();
@@ -7218,7 +7176,7 @@
uint8_t data8[] = { 'h', 'e', 'l', 'l', 'o' };
const char* err = "string";
Dart_Handle err_str = NewString(err);
- Dart_Handle ext_err_str = Dart_NewExternalUTF8String(
+ Dart_Handle ext_err_str = Dart_NewExternalLatin1String(
data8, ARRAY_SIZE(data8), NULL, NULL);
Dart_Handle result = Dart_MakeExternalString(Dart_Null(),
data8,
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 4cee392..8d576ab 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -389,17 +389,28 @@
uint16_t *utf16 =
reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
intptr_t utf8_len = 0;
+ // Read all the UTF-16 code units.
for (intptr_t i = 0; i < len; i++) {
utf16[i] = Read<uint16_t>();
- // TODO(sgjesse): Check for surrogate pairs.
- utf8_len += Utf8::Length(utf16[i]);
+ }
+ // Calculate the UTF-8 length and check if the string can be
+ // UTF-8 encoded.
+ bool valid = true;
+ intptr_t i = 0;
+ while (i < len && valid) {
+ int32_t ch = Utf16::Next(utf16, &i, len);
+ utf8_len += Utf8::Length(ch);
+ valid = !Utf16::IsSurrogate(ch);
+ }
+ if (!valid) {
+ return AllocateDartCObjectUnsupported();
}
Dart_CObject* object = AllocateDartCObjectString(utf8_len);
AddBackRef(object_id, object, kIsDeserialized);
char* p = object->value.as_string;
- for (intptr_t i = 0; i < len; i++) {
- // TODO(sgjesse): Check for surrogate pairs.
- p += Utf8::Encode(utf16[i], p);
+ i = 0;
+ while (i < len) {
+ p += Utf8::Encode(Utf16::Next(utf16, &i, len), p);
}
*p = '\0';
ASSERT(p == (object->value.as_string + utf8_len));
@@ -807,16 +818,20 @@
if (type == Utf8::kLatin1) {
uint8_t* latin1_str =
reinterpret_cast<uint8_t*>(::malloc(len * sizeof(uint8_t)));
- Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, len);
+ bool success = Utf8::DecodeToLatin1(utf8_str,
+ utf8_len,
+ latin1_str,
+ len);
+ ASSERT(success);
for (intptr_t i = 0; i < len; i++) {
Write<uint8_t>(latin1_str[i]);
}
::free(latin1_str);
} else {
- // TODO(sgjesse): Make sure surrogate pairs are handled.
uint16_t* utf16_str =
reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t)));
- Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
+ bool success = Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len);
+ ASSERT(success);
for (intptr_t i = 0; i < len; i++) {
Write<uint16_t>(utf16_str[i]);
}
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 479ad64..ba1dae4 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -4,6 +4,7 @@
#include "vm/exceptions.h"
+#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/flags.h"
@@ -163,14 +164,20 @@
pc_offset_list);
if (handler_pc == 0) {
// There are no dart invocation frames on the stack so we do not
- // have a caller to return to. This is a case where we would have
- // to call the Isolate error handler and let it deal with the shutdown.
- // We report an error and shutdown the process as a temporary solution
- // until the isolate error handler stuff is implemented.
+ // have a caller to return to.
ASSERT(!handler_exists);
- OS::PrintErr("Exception '%s' thrown:\n", exception.ToCString());
- OS::PrintErr("Exiting the process\n");
- OS::Exit(255);
+ if (Isolate::UnhandledExceptionCallback() != NULL) {
+ // Notify embedder that an unhandled exception occurred.
+ Dart_EnterScope();
+ Dart_Handle error_handle = Api::NewHandle(Isolate::Current(),
+ incoming_exception.raw());
+ (Isolate::UnhandledExceptionCallback())(error_handle);
+ Dart_ExitScope();
+ } else {
+ OS::PrintErr("Exception '%s' thrown:\n", exception.ToCString());
+ OS::PrintErr("Shutting down the isolate\n");
+ }
+ Dart_ShutdownIsolate();
}
// TODO(5411263): At some point we can optimize by figuring out if a
// stack trace is needed based on whether the catch code specifies a
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 37be5e7..f48ac9e 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1886,13 +1886,13 @@
// The receiver cannot be null; extract its AbstractTypeArguments object.
// Note that in the factory case, the instantiator is the first parameter
// of the factory, i.e. already an AbstractTypeArguments object.
- intptr_t type_arguments_instance_field_offset =
- instantiator_class.type_arguments_instance_field_offset();
- ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
+ intptr_t type_arguments_field_offset =
+ instantiator_class.type_arguments_field_offset();
+ ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
return Bind(new LoadFieldInstr(
instantiator,
- type_arguments_instance_field_offset,
+ type_arguments_field_offset,
Type::ZoneHandle())); // Not an instance, no type.
}
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 7b8b194..869627c 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -6,6 +6,7 @@
#include "vm/flow_graph_compiler.h"
+#include "vm/cha.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/deopt_instructions.h"
@@ -28,6 +29,7 @@
DECLARE_FLAG(bool, propagate_ic_data);
DECLARE_FLAG(bool, report_usage_count);
DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, use_cha);
void CompilerDeoptInfo::BuildReturnAddress(DeoptInfoBuilder* builder,
const Function& function,
@@ -1004,4 +1006,28 @@
}
}
+
+// Returns true if checking against this type is a direct class id comparison.
+bool FlowGraphCompiler::TypeCheckAsClassEquality(const AbstractType& type) {
+ ASSERT(type.IsFinalized() && !type.IsMalformed());
+ // Requires CHA, which can be applied in optimized code only,
+ if (!FLAG_use_cha || !is_optimizing()) return false;
+ if (!type.IsInstantiated()) return false;
+ const Class& type_class = Class::Handle(type.type_class());
+ // Could be an interface check?
+ if (type_class.is_implemented()) return false;
+ const intptr_t type_cid = type_class.id();
+ if (CHA::HasSubclasses(type_cid)) return false;
+ if (type_class.HasTypeArguments()) {
+ // Only raw types can be directly compared, thus disregarding type
+ // arguments.
+ const AbstractTypeArguments& type_arguments =
+ AbstractTypeArguments::Handle(type.arguments());
+ const bool is_raw_type = type_arguments.IsNull() ||
+ type_arguments.IsRaw(type_arguments.Length());
+ return is_raw_type;
+ }
+ return true;
+}
+
} // namespace dart
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 5efe27e..832c5f1 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -132,12 +132,10 @@
if (is_raw_type) {
const Register kClassIdReg = ECX;
// dynamic type argument, check only classes.
- // List is a very common case.
__ LoadClassId(kClassIdReg, kInstanceReg);
- if (!type_class.is_interface()) {
- __ cmpl(kClassIdReg, Immediate(type_class.id()));
- __ j(EQUAL, is_instance_lbl);
- }
+ __ cmpl(kClassIdReg, Immediate(type_class.id()));
+ __ j(EQUAL, is_instance_lbl);
+ // List is a very common case.
if (type_class.IsListClass()) {
GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
}
@@ -216,11 +214,8 @@
__ Bind(&compare_classes);
const Register kClassIdReg = ECX;
__ LoadClassId(kClassIdReg, kInstanceReg);
- // If type is an interface, we can skip the class equality check.
- if (!type_class.is_interface()) {
- __ cmpl(kClassIdReg, Immediate(type_class.id()));
- __ j(EQUAL, is_instance_lbl);
- }
+ __ cmpl(kClassIdReg, Immediate(type_class.id()));
+ __ j(EQUAL, is_instance_lbl);
// Bool interface can be implemented only by core class Bool.
// (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces).
if (type.IsBoolType()) {
@@ -392,6 +387,20 @@
// type error. A null value is handled prior to executing this inline code.
return SubtypeTestCache::null();
}
+ if (TypeCheckAsClassEquality(type)) {
+ const intptr_t type_cid = Class::Handle(type.type_class()).id();
+ const Register kInstanceReg = EAX;
+ __ testl(kInstanceReg, Immediate(kSmiTagMask));
+ if (type_cid == kSmiCid) {
+ __ j(ZERO, is_instance_lbl);
+ } else {
+ __ j(ZERO, is_not_instance_lbl);
+ __ CompareClassId(kInstanceReg, type_cid, EDI);
+ __ j(EQUAL, is_instance_lbl);
+ }
+ __ jmp(is_not_instance_lbl);
+ return SubtypeTestCache::null();
+ }
if (type.IsInstantiated()) {
const Class& type_class = Class::ZoneHandle(type.type_class());
// A Smi object cannot be the instance of a parameterized class.
@@ -777,41 +786,32 @@
// stack.
__ addl(ESP, Immediate(StackSize() * kWordSize));
}
- // The calls immediately below have empty stackmaps because we have just
+ // The call below has an empty stackmap because we have just
// dropped the spill slots.
BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
- if (function.IsClosureFunction()) {
- // TODO(regis): Call NoSuchMethod with "call" as name of original function.
- // We do not use GenerateCallRuntime because of the non-standard (empty)
- // stackmap used here.
- __ CallRuntime(kClosureArgumentMismatchRuntimeEntry);
- AddCurrentDescriptor(PcDescriptors::kOther,
- Isolate::kNoDeoptId,
- 0); // No token position.
- } else {
- // Invoke noSuchMethod function.
- const int kNumArgsChecked = 1;
- ICData& ic_data = ICData::ZoneHandle();
- ic_data = ICData::New(function,
- String::Handle(function.name()),
- Isolate::kNoDeoptId,
- kNumArgsChecked);
- __ LoadObject(ECX, ic_data);
- // EBP - 4 : PC marker, allows easy identification of RawInstruction obj.
- // EBP : points to previous frame pointer.
- // EBP + 4 : points to return address.
- // EBP + 8 : address of last argument (arg n-1).
- // ESP + 8 + 4*(n-1) : address of first argument (arg 0).
- // ECX : ic-data.
- // EDX : arguments descriptor array.
- __ call(&StubCode::CallNoSuchMethodFunctionLabel());
- }
+
+ // Invoke noSuchMethod function passing the original name of the function.
+ // If the function is a closure function, use "call" as the original name.
+ const String& name = String::Handle(
+ function.IsClosureFunction() ? Symbols::Call() : function.name());
+ const int kNumArgsChecked = 1;
+ const ICData& ic_data = ICData::ZoneHandle(
+ ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+ __ LoadObject(ECX, ic_data);
+ // EBP - 4 : PC marker, allows easy identification of RawInstruction obj.
+ // EBP : points to previous frame pointer.
+ // EBP + 4 : points to return address.
+ // EBP + 8 : address of last argument (arg n-1).
+ // ESP + 8 + 4*(n-1) : address of first argument (arg 0).
+ // ECX : ic-data.
+ // EDX : arguments descriptor array.
+ __ call(&StubCode::CallNoSuchMethodFunctionLabel());
if (is_optimizing()) {
stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
empty_stack_bitmap,
0); // No registers.
}
-
+ // The noSuchMethod call may return.
__ LeaveFrame();
__ ret();
@@ -912,11 +912,38 @@
__ cmpl(EAX, Immediate(Smi::RawValue(num_fixed_params)));
__ j(EQUAL, &argc_in_range, Assembler::kNearJump);
if (function.IsClosureFunction()) {
- // TODO(regis): Call NoSuchMethod with "call" as name of original
- // function.
- GenerateCallRuntime(function.token_pos(),
- kClosureArgumentMismatchRuntimeEntry,
- prologue_locs);
+ if (StackSize() != 0) {
+ // We need to unwind the space we reserved for locals and copied
+ // parameters. The NoSuchMethodFunction stub does not expect to see
+ // that area on the stack.
+ __ addl(ESP, Immediate(StackSize() * kWordSize));
+ }
+ // The call below has an empty stackmap because we have just
+ // dropped the spill slots.
+ BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
+
+ // Invoke noSuchMethod function passing "call" as the function name.
+ const String& name = String::Handle(Symbols::Call());
+ const int kNumArgsChecked = 1;
+ const ICData& ic_data = ICData::ZoneHandle(
+ ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+ __ LoadObject(ECX, ic_data);
+ // EBP - 4 : PC marker, for easy identification of RawInstruction obj.
+ // EBP : points to previous frame pointer.
+ // EBP + 4 : points to return address.
+ // EBP + 8 : address of last argument (arg n-1).
+ // ESP + 8 + 4*(n-1) : address of first argument (arg 0).
+ // ECX : ic-data.
+ // EDX : arguments descriptor array.
+ __ call(&StubCode::CallNoSuchMethodFunctionLabel());
+ if (is_optimizing()) {
+ stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
+ empty_stack_bitmap,
+ 0); // No registers.
+ }
+ // The noSuchMethod call may return.
+ __ LeaveFrame();
+ __ ret();
} else {
__ Stop("Wrong number of arguments");
}
diff --git a/runtime/vm/flow_graph_compiler_ia32.h b/runtime/vm/flow_graph_compiler_ia32.h
index 5576041..4af53ad 100644
--- a/runtime/vm/flow_graph_compiler_ia32.h
+++ b/runtime/vm/flow_graph_compiler_ia32.h
@@ -297,6 +297,9 @@
Label* is_instance_lbl,
Label* is_not_instance_lbl);
+ // Returns true if checking against this type is a direct class id comparison.
+ bool TypeCheckAsClassEquality(const AbstractType& type);
+
void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false);
void CopyParameters();
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index f5c7e2b..6ac1af9 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -132,12 +132,10 @@
if (is_raw_type) {
const Register kClassIdReg = R10;
// dynamic type argument, check only classes.
- // List is a very common case.
__ LoadClassId(kClassIdReg, kInstanceReg);
- if (!type_class.is_interface()) {
- __ cmpl(kClassIdReg, Immediate(type_class.id()));
- __ j(EQUAL, is_instance_lbl);
- }
+ __ cmpl(kClassIdReg, Immediate(type_class.id()));
+ __ j(EQUAL, is_instance_lbl);
+ // List is a very common case.
if (type_class.IsListClass()) {
GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
}
@@ -216,11 +214,8 @@
__ Bind(&compare_classes);
const Register kClassIdReg = R10;
__ LoadClassId(kClassIdReg, kInstanceReg);
- // If type is an interface, we can skip the class equality check.
- if (!type_class.is_interface()) {
- __ cmpl(kClassIdReg, Immediate(type_class.id()));
- __ j(EQUAL, is_instance_lbl);
- }
+ __ cmpl(kClassIdReg, Immediate(type_class.id()));
+ __ j(EQUAL, is_instance_lbl);
// Bool interface can be implemented only by core class Bool.
// (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces).
if (type.IsBoolType()) {
@@ -392,6 +387,20 @@
// type error. A null value is handled prior to executing this inline code.
return SubtypeTestCache::null();
}
+ if (TypeCheckAsClassEquality(type)) {
+ const intptr_t type_cid = Class::Handle(type.type_class()).id();
+ const Register kInstanceReg = RAX;
+ __ testq(kInstanceReg, Immediate(kSmiTagMask));
+ if (type_cid == kSmiCid) {
+ __ j(ZERO, is_instance_lbl);
+ } else {
+ __ j(ZERO, is_not_instance_lbl);
+ __ CompareClassId(kInstanceReg, type_cid);
+ __ j(EQUAL, is_instance_lbl);
+ }
+ __ jmp(is_not_instance_lbl);
+ return SubtypeTestCache::null();
+ }
if (type.IsInstantiated()) {
const Class& type_class = Class::ZoneHandle(type.type_class());
// A Smi object cannot be the instance of a parameterized class.
@@ -779,41 +788,32 @@
// stack.
__ addq(RSP, Immediate(StackSize() * kWordSize));
}
- // The calls immediately below have empty stackmaps because we have just
+ // The call below has an empty stackmap because we have just
// dropped the spill slots.
BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
- if (function.IsClosureFunction()) {
- // TODO(regis): Call NoSuchMethod with "call" as name of original function.
- // We do not use GenerateCallRuntime because of the non-standard (empty)
- // stackmap used here.
- __ CallRuntime(kClosureArgumentMismatchRuntimeEntry);
- AddCurrentDescriptor(PcDescriptors::kOther,
- Isolate::kNoDeoptId,
- 0); // No token position.
- } else {
- // Invoke noSuchMethod function.
- const int kNumArgsChecked = 1;
- ICData& ic_data = ICData::ZoneHandle();
- ic_data = ICData::New(function,
- String::Handle(function.name()),
- Isolate::kNoDeoptId,
- kNumArgsChecked);
- __ LoadObject(RBX, ic_data);
- // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
- // RBP : points to previous frame pointer.
- // RBP + 8 : points to return address.
- // RBP + 16 : address of last argument (arg n-1).
- // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
- // RBX : ic-data.
- // R10 : arguments descriptor array.
- __ call(&StubCode::CallNoSuchMethodFunctionLabel());
- }
+
+ // Invoke noSuchMethod function passing the original name of the function.
+ // If the function is a closure function, use "call" as the original name.
+ const String& name = String::Handle(
+ function.IsClosureFunction() ? Symbols::Call() : function.name());
+ const int kNumArgsChecked = 1;
+ const ICData& ic_data = ICData::ZoneHandle(
+ ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+ __ LoadObject(RBX, ic_data);
+ // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
+ // RBP : points to previous frame pointer.
+ // RBP + 8 : points to return address.
+ // RBP + 16 : address of last argument (arg n-1).
+ // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
+ // RBX : ic-data.
+ // R10 : arguments descriptor array.
+ __ call(&StubCode::CallNoSuchMethodFunctionLabel());
if (is_optimizing()) {
stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
empty_stack_bitmap,
0); // No registers.
}
-
+ // The noSuchMethod call may return.
__ LeaveFrame();
__ ret();
@@ -915,11 +915,38 @@
__ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
__ j(EQUAL, &argc_in_range, Assembler::kNearJump);
if (function.IsClosureFunction()) {
- // TODO(regis): Call NoSuchMethod with "call" as name of original
- // function.
- GenerateCallRuntime(function.token_pos(),
- kClosureArgumentMismatchRuntimeEntry,
- prologue_locs);
+ if (StackSize() != 0) {
+ // We need to unwind the space we reserved for locals and copied
+ // parameters. The NoSuchMethodFunction stub does not expect to see
+ // that area on the stack.
+ __ addq(RSP, Immediate(StackSize() * kWordSize));
+ }
+ // The call below has an empty stackmap because we have just
+ // dropped the spill slots.
+ BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
+
+ // Invoke noSuchMethod function passing "call" as the function name.
+ const String& name = String::Handle(Symbols::Call());
+ const int kNumArgsChecked = 1;
+ const ICData& ic_data = ICData::ZoneHandle(
+ ICData::New(function, name, Isolate::kNoDeoptId, kNumArgsChecked));
+ __ LoadObject(RBX, ic_data);
+ // RBP - 8 : PC marker, for easy identification of RawInstruction obj.
+ // RBP : points to previous frame pointer.
+ // RBP + 8 : points to return address.
+ // RBP + 16 : address of last argument (arg n-1).
+ // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
+ // RBX : ic-data.
+ // R10 : arguments descriptor array.
+ __ call(&StubCode::CallNoSuchMethodFunctionLabel());
+ if (is_optimizing()) {
+ stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
+ empty_stack_bitmap,
+ 0); // No registers.
+ }
+ // The noSuchMethod call may return.
+ __ LeaveFrame();
+ __ ret();
} else {
__ Stop("Wrong number of arguments");
}
diff --git a/runtime/vm/flow_graph_compiler_x64.h b/runtime/vm/flow_graph_compiler_x64.h
index 8d61eda..cb6c742 100644
--- a/runtime/vm/flow_graph_compiler_x64.h
+++ b/runtime/vm/flow_graph_compiler_x64.h
@@ -298,6 +298,9 @@
Label* is_instance_lbl,
Label* is_not_instance_lbl);
+ // Returns true if checking against this type is a direct class id comparison.
+ bool TypeCheckAsClassEquality(const AbstractType& type);
+
void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false);
void CopyParameters();
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 2e5d624..d88659d 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -559,11 +559,11 @@
case kArrayCid:
case kGrowableObjectArrayCid: {
const Class& instantiator_class = Class::Handle(target.Owner());
- intptr_t type_arguments_instance_field_offset =
- instantiator_class.type_arguments_instance_field_offset();
+ intptr_t type_arguments_field_offset =
+ instantiator_class.type_arguments_field_offset();
LoadFieldInstr* load_type_args =
new LoadFieldInstr(array->Copy(),
- type_arguments_instance_field_offset,
+ type_arguments_field_offset,
Type::ZoneHandle()); // No type.
InsertBefore(call, load_type_args, NULL, Definition::kValue);
instantiator = array->Copy();
@@ -1015,6 +1015,7 @@
AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value());
+ load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
call->ReplaceWith(load, current_iterator());
RemovePushArguments(call);
}
@@ -2776,9 +2777,60 @@
}
-static intptr_t NumberLoadExpressions(FlowGraph* graph) {
+static intptr_t ComputeLoadOffsetInWords(Definition* defn) {
+ if (defn->IsLoadIndexed()) {
+ // We are assuming that LoadField is never used to load the first word.
+ return 0;
+ }
+
+ LoadFieldInstr* load_field = defn->AsLoadField();
+ if (load_field != NULL) {
+ const intptr_t idx = load_field->offset_in_bytes() / kWordSize;
+ ASSERT(idx > 0);
+ return idx;
+ }
+
+ UNREACHABLE();
+ return 0;
+}
+
+
+static bool IsInterferingStore(Instruction* instr,
+ intptr_t* offset_in_words) {
+ if (instr->IsStoreIndexed()) {
+ // We are assuming that LoadField is never used to load the first word.
+ *offset_in_words = 0;
+ return true;
+ }
+
+ StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField();
+ if (store_instance_field != NULL) {
+ ASSERT(store_instance_field->field().Offset() != 0);
+ *offset_in_words = store_instance_field->field().Offset() / kWordSize;
+ return true;
+ }
+
+ StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
+ if (store_vm_field != NULL) {
+ ASSERT(store_vm_field->offset_in_bytes() != 0);
+ *offset_in_words = store_vm_field->offset_in_bytes() / kWordSize;
+ return true;
+ }
+
+ return false;
+}
+
+
+static intptr_t NumberLoadExpressions(
+ FlowGraph* graph,
+ GrowableArray<BitVector*>* kill_by_offs) {
DirectChainedHashMap<PointerKeyValueTrait<Definition> > map;
intptr_t expr_id = 0;
+
+ // Loads representing different expression ids will be collected and
+ // used to build per offset kill sets.
+ GrowableArray<Definition*> loads(10);
+
for (BlockIterator it = graph->reverse_postorder_iterator();
!it.Done();
it.Advance()) {
@@ -2794,11 +2846,29 @@
if (result == NULL) {
map.Insert(defn);
defn->set_expr_id(expr_id++);
+ loads.Add(defn);
} else {
defn->set_expr_id(result->expr_id());
}
}
}
+
+ // Build per offset kill sets. Any store interferes only with loads from
+ // the same offset.
+ for (intptr_t i = 0; i < loads.length(); i++) {
+ Definition* defn = loads[i];
+
+ const intptr_t offset_in_words = ComputeLoadOffsetInWords(defn);
+ while (kill_by_offs->length() <= offset_in_words) {
+ kill_by_offs->Add(NULL);
+ }
+ if ((*kill_by_offs)[offset_in_words] == NULL) {
+ (*kill_by_offs)[offset_in_words] = new BitVector(expr_id);
+ }
+ (*kill_by_offs)[offset_in_words]->Add(defn->expr_id());
+ }
+
+
return expr_id;
}
@@ -2806,7 +2876,8 @@
static void ComputeAvailableLoads(
FlowGraph* graph,
intptr_t max_expr_id,
- const GrowableArray<BitVector*>& avail_in) {
+ const GrowableArray<BitVector*>& avail_in,
+ const GrowableArray<BitVector*>& kill_by_offs) {
// Initialize gen-, kill-, out-sets.
intptr_t num_blocks = graph->preorder().length();
GrowableArray<BitVector*> avail_out(num_blocks);
@@ -2827,15 +2898,29 @@
!instr_it.Done();
instr_it.Advance()) {
Instruction* instr = instr_it.Current();
- if (instr->HasSideEffect()) {
+
+ intptr_t offset_in_words = 0;
+ if (IsInterferingStore(instr, &offset_in_words)) {
+ if ((offset_in_words < kill_by_offs.length()) &&
+ (kill_by_offs[offset_in_words] != NULL)) {
+ avail_kill[preorder_number]->AddAll(kill_by_offs[offset_in_words]);
+ }
+ ASSERT(instr->IsDefinition() &&
+ !IsLoadEliminationCandidate(instr->AsDefinition()));
+ continue;
+ } else if (instr->HasSideEffect()) {
avail_kill[preorder_number]->SetAll();
break;
}
- Definition* defn = instr_it.Current()->AsDefinition();
+ Definition* defn = instr->AsDefinition();
if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
continue;
}
- avail_gen[preorder_number]->Add(defn->expr_id());
+
+ const intptr_t expr_id = defn->expr_id();
+ if (!avail_kill[preorder_number]->Contains(expr_id)) {
+ avail_gen[preorder_number]->Add(expr_id);
+ }
}
avail_out[preorder_number]->CopyFrom(avail_gen[preorder_number]);
}
@@ -2887,7 +2972,8 @@
static bool OptimizeLoads(
BlockEntryInstr* block,
GrowableArray<Definition*>* definitions,
- const GrowableArray<BitVector*>& avail_in) {
+ const GrowableArray<BitVector*>& avail_in,
+ const GrowableArray<BitVector*>& kill_by_offs) {
// TODO(fschneider): Factor out code shared with the existing CSE pass.
// Delete loads that are killed (not available) at the entry.
@@ -2902,7 +2988,21 @@
bool changed = false;
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
Instruction* instr = it.Current();
- if (instr->HasSideEffect()) {
+
+ intptr_t offset_in_words = 0;
+ if (IsInterferingStore(instr, &offset_in_words)) {
+ if ((offset_in_words < kill_by_offs.length()) &&
+ (kill_by_offs[offset_in_words] != NULL)) {
+ for (BitVector::Iterator it(kill_by_offs[offset_in_words]);
+ !it.Done();
+ it.Advance()) {
+ (*definitions)[it.Current()] = NULL;
+ }
+ }
+ ASSERT(instr->IsDefinition() &&
+ !IsLoadEliminationCandidate(instr->AsDefinition()));
+ continue;
+ } else if (instr->HasSideEffect()) {
// Handle local side effects by clearing current definitions.
for (intptr_t i = 0; i < definitions->length(); i++) {
(*definitions)[i] = NULL;
@@ -2937,9 +3037,11 @@
if (i < num_children - 1) {
GrowableArray<Definition*> child_defs(definitions->length());
child_defs.AddArray(*definitions);
- changed = OptimizeLoads(child, &child_defs, avail_in) || changed;
+ changed = OptimizeLoads(child, &child_defs, avail_in, kill_by_offs) ||
+ changed;
} else {
- changed = OptimizeLoads(child, definitions, avail_in) || changed;
+ changed = OptimizeLoads(child, definitions, avail_in, kill_by_offs) ||
+ changed;
}
}
return changed;
@@ -2949,7 +3051,8 @@
bool DominatorBasedCSE::Optimize(FlowGraph* graph) {
bool changed = false;
if (FLAG_load_cse) {
- intptr_t max_expr_id = NumberLoadExpressions(graph);
+ GrowableArray<BitVector*> kill_by_offs(10);
+ intptr_t max_expr_id = NumberLoadExpressions(graph, &kill_by_offs);
if (max_expr_id > 0) {
intptr_t num_blocks = graph->preorder().length();
GrowableArray<BitVector*> avail_in(num_blocks);
@@ -2957,13 +3060,14 @@
avail_in.Add(new BitVector(max_expr_id));
}
- ComputeAvailableLoads(graph, max_expr_id, avail_in);
+ ComputeAvailableLoads(graph, max_expr_id, avail_in, kill_by_offs);
GrowableArray<Definition*> definitions(max_expr_id);
for (intptr_t j = 0; j < max_expr_id ; j++) {
definitions.Add(NULL);
}
- changed = OptimizeLoads(graph->graph_entry(), &definitions, avail_in);
+ changed = OptimizeLoads(
+ graph->graph_entry(), &definitions, avail_in, kill_by_offs);
}
}
@@ -3438,7 +3542,20 @@
void ConstantPropagator::VisitInstantiateTypeArguments(
InstantiateTypeArgumentsInstr* instr) {
- SetValue(instr, non_constant_);
+ const Object& object =
+ instr->instantiator()->definition()->constant_value();
+ if (IsNonConstant(object)) {
+ SetValue(instr, non_constant_);
+ } else if (IsConstant(object)) {
+ if (!object.IsNull() &&
+ object.IsTypeArguments() &&
+ (TypeArguments::Cast(object).Length() ==
+ instr->type_arguments().Length())) {
+ SetValue(instr, object);
+ } else {
+ SetValue(instr, non_constant_);
+ }
+ }
}
@@ -3713,7 +3830,8 @@
// TODO(kmillikin): Extend this to handle booleans, other number
// types, etc.
if ((defn != NULL) &&
- defn->constant_value().IsSmi() &&
+ (defn->constant_value().IsSmi() ||
+ defn->constant_value().IsTypeArguments()) &&
!defn->IsConstant() &&
!defn->IsPushArgument() &&
!defn->IsStoreIndexed() &&
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 84f55df..003e5ae 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -6,7 +6,6 @@
#include "platform/assert.h"
#include "platform/utils.h"
-#include "vm/compiler_stats.h"
#include "vm/flags.h"
#include "vm/heap_profiler.h"
#include "vm/isolate.h"
diff --git a/runtime/vm/heap_profiler.cc b/runtime/vm/heap_profiler.cc
index f218a81..8f98764 100644
--- a/runtime/vm/heap_profiler.cc
+++ b/runtime/vm/heap_profiler.cc
@@ -513,7 +513,7 @@
}
// instance size (in bytes)
// TODO(cshapiro): properly account for variable sized objects
- sub.Write32(raw_class->ptr()->instance_size_);
+ sub.Write32(raw_class->ptr()->instance_size_in_words_);
// size of constant pool and number of records that follow:
sub.Write16(0);
// Number of static fields
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 5fec3ad..35802a3 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2460,10 +2460,33 @@
RangeBoundary::FromConstant(Array::kMaxElements));
return;
}
+ if ((range_ == NULL) &&
+ (recognized_kind() == MethodRecognizer::kStringBaseLength)) {
+ range_ = new Range(RangeBoundary::FromConstant(0),
+ RangeBoundary::FromConstant(String::kMaxElements));
+ return;
+ }
Definition::InferRange();
}
+
+void StringCharCodeAtInstr::InferRange() {
+ switch (class_id_) {
+ case kOneByteStringCid:
+ range_ = new Range(RangeBoundary::FromConstant(0),
+ RangeBoundary::FromConstant(0xFF));
+ break;
+ case kTwoByteStringCid:
+ range_ = new Range(RangeBoundary::FromConstant(0),
+ RangeBoundary::FromConstant(0xFFFF));
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+}
+
+
void LoadIndexedInstr::InferRange() {
switch (class_id()) {
case kExternalUint8ArrayCid:
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index a6e3452..cce4f64 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -38,10 +38,10 @@
V(_GrowableObjectArray, get:length, GrowableArrayLength, 725548050) \
V(_GrowableObjectArray, get:capacity, GrowableArrayCapacity, 725548050) \
V(_StringBase, get:length, StringBaseLength, 320803993) \
- V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1065961093) \
+ V(_StringBase, get:isEmpty, StringBaseIsEmpty, 583130725) \
V(_StringBase, charCodeAt, StringBaseCharCodeAt, 984449525) \
V(_StringBase, [], StringBaseCharAt, 1062366987) \
- V(_IntegerImplementation, toDouble, IntegerToDouble, 1396338041) \
+ V(_IntegerImplementation, toDouble, IntegerToDouble, 1252792570) \
V(_Double, toInt, DoubleToInteger, 362666636) \
V(::, sqrt, MathSqrt, 2232519) \
@@ -2694,6 +2694,8 @@
virtual bool AffectedBySideEffect() const { return true; }
+ virtual void InferRange();
+
private:
const intptr_t class_id_;
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index af4f8d4..ff07cc1 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -17,47 +17,47 @@
// build and run to get the correct fingerprint from the mismatch error.
#define INTRINSIC_LIST(V) \
V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, 726019207)\
- V(_IntegerImplementation, +, Integer_add, 13708438) \
+ V(_IntegerImplementation, +, Integer_add, 1821133110) \
V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 726019207)\
- V(_IntegerImplementation, -, Integer_sub, 284482664) \
+ V(_IntegerImplementation, -, Integer_sub, 2091907336) \
V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, 726019207)\
- V(_IntegerImplementation, *, Integer_mul, 486761895) \
- V(_IntegerImplementation, %, Integer_modulo, 1370017357) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, 450435650) \
- V(_IntegerImplementation, unary-, Integer_negate, 1734168384) \
+ V(_IntegerImplementation, *, Integer_mul, 146702919) \
+ V(_IntegerImplementation, %, Integer_modulo, 578878541) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, 1806780482) \
+ V(_IntegerImplementation, unary-, Integer_negate, 1705538272) \
V(_IntegerImplementation, _bitAndFromInteger, \
Integer_bitAndFromInteger, 726019207) \
- V(_IntegerImplementation, &, Integer_bitAnd, 1267520437) \
+ V(_IntegerImplementation, &, Integer_bitAnd, 927461461) \
V(_IntegerImplementation, _bitOrFromInteger, \
Integer_bitOrFromInteger, 726019207) \
- V(_IntegerImplementation, |, Integer_bitOr, 249432836) \
+ V(_IntegerImplementation, |, Integer_bitOr, 2056857508) \
V(_IntegerImplementation, _bitXorFromInteger, \
Integer_bitXorFromInteger, 726019207) \
- V(_IntegerImplementation, ^, Integer_bitXor, 1177061571) \
+ V(_IntegerImplementation, ^, Integer_bitXor, 837002595) \
V(_IntegerImplementation, \
_greaterThanFromInteger, \
Integer_greaterThanFromInt, 79222670) \
- V(_IntegerImplementation, >, Integer_greaterThan, 319553701) \
- V(_IntegerImplementation, ==, Integer_equal, 1163202222) \
+ V(_IntegerImplementation, >, Integer_greaterThan, 2126978373) \
+ V(_IntegerImplementation, ==, Integer_equal, 507939054) \
V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, 79222670) \
- V(_IntegerImplementation, <, Integer_lessThan, 1306209983) \
- V(_IntegerImplementation, <=, Integer_lessEqualThan, 458673122) \
- V(_IntegerImplementation, >=, Integer_greaterEqualThan, 459596643) \
- V(_IntegerImplementation, <<, Integer_shl, 1586407617) \
- V(_IntegerImplementation, >>, Integer_sar, 130211175) \
+ V(_IntegerImplementation, <, Integer_lessThan, 1277579871) \
+ V(_IntegerImplementation, <=, Integer_lessEqualThan, 806519877) \
+ V(_IntegerImplementation, >=, Integer_greaterEqualThan, 807443398) \
+ V(_IntegerImplementation, <<, Integer_shl, 1246348641) \
+ V(_IntegerImplementation, >>, Integer_sar, 1937635847) \
V(_Smi, ~, Smi_bitNegate, 882629793) \
- V(_Double, >, Double_greaterThan, 1821658410) \
- V(_Double, >=, Double_greaterEqualThan, 1317118885) \
- V(_Double, <, Double_lessThan, 177557761) \
- V(_Double, <=, Double_lessEqualThan, 1316195364) \
- V(_Double, ==, Double_equal, 1896071176) \
- V(_Double, +, Double_add, 1137022234) \
- V(_Double, -, Double_sub, 1425469940) \
- V(_Double, *, Double_mul, 1865672692) \
- V(_Double, /, Double_div, 1832148629) \
+ V(_Double, >, Double_greaterThan, 1471126121) \
+ V(_Double, >=, Double_greaterEqualThan, 1664965640) \
+ V(_Double, <, Double_lessThan, 148927649) \
+ V(_Double, <=, Double_lessEqualThan, 1664042119) \
+ V(_Double, ==, Double_equal, 900686217) \
+ V(_Double, +, Double_add, 786489945) \
+ V(_Double, -, Double_sub, 1074937651) \
+ V(_Double, *, Double_mul, 1515140403) \
+ V(_Double, /, Double_div, 1481616340) \
V(_Double, get:isNaN, Double_getIsNaN, 54462366) \
V(_Double, get:isNegative, Double_getIsNegative, 54462366) \
- V(_Double, _mulFromInteger, Double_mulFromInteger, 795128) \
+ V(_Double, _mulFromInteger, Double_mulFromInteger, 1668662807) \
V(_Double, .fromInteger, Double_fromInteger, 842078193) \
V(_Double, toInt, Double_toInt, 362666636) \
V(_ObjectArray, ., ObjectArray_Allocate, 577949617) \
@@ -71,36 +71,36 @@
V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 1048007636) \
V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 796709584) \
V(_GrowableObjectArray, _setData, GrowableArray_setData, 477312179) \
- V(_GrowableObjectArray, add, GrowableArray_add, 1776744235) \
+ V(_GrowableObjectArray, add, GrowableArray_add, 455936651) \
V(_ImmutableArray, [], ImmutableArray_getIndexed, 486821199) \
V(_ImmutableArray, get:length, ImmutableArray_getLength, 433698233) \
V(::, sqrt, Math_sqrt, 2232519) \
V(::, sin, Math_sin, 837187616) \
V(::, cos, Math_cos, 548880317) \
- V(Object, ==, Object_equal, 1512068535) \
+ V(Object, ==, Object_equal, 1511145014) \
V(_FixedSizeArrayIterator, get:hasNext, \
- FixedSizeArrayIterator_getHasNext, 1847855366) \
- V(_FixedSizeArrayIterator, next, FixedSizeArrayIterator_next, 1739352783) \
+ FixedSizeArrayIterator_getHasNext, 1819226215) \
+ V(_FixedSizeArrayIterator, next, FixedSizeArrayIterator_next, 1147008464) \
V(_StringBase, get:hashCode, String_getHashCode, 320803993) \
- V(_StringBase, get:isEmpty, String_getIsEmpty, 1065961093) \
+ V(_StringBase, get:isEmpty, String_getIsEmpty, 583130725) \
V(_StringBase, get:length, String_getLength, 320803993) \
V(_StringBase, charCodeAt, String_charCodeAt, 984449525) \
- V(_ByteArrayBase, get:length, ByteArrayBase_getLength, 1856909152) \
- V(_Int8Array, [], Int8Array_getIndexed, 239810357) \
+ V(_ByteArrayBase, get:length, ByteArrayBase_getLength, 1828280001) \
+ V(_Int8Array, [], Int8Array_getIndexed, 1499790324) \
V(_Int8Array, []=, Int8Array_setIndexed, 1469038436) \
- V(_Uint8Array, [], Uint8Array_getIndexed, 1635923899) \
+ V(_Uint8Array, [], Uint8Array_getIndexed, 748420218) \
V(_Uint8Array, []=, Uint8Array_setIndexed, 1619321522) \
- V(_Int16Array, [], Int16Array_getIndexed, 2090761657) \
- V(_Uint16Array, [], Uint16Array_getIndexed, 289929708) \
- V(_Int32Array, [], Int32Array_getIndexed, 589442411) \
- V(_Uint32Array, [], Uint32Array_getIndexed, 1474116947) \
- V(_Int64Array, [], Int64Array_getIndexed, 1506836119) \
- V(_Uint64Array, [], Uint64Array_getIndexed, 1856952148) \
- V(_Float32Array, [], Float32Array_getIndexed, 1167607283) \
+ V(_Int16Array, [], Int16Array_getIndexed, 1203257976) \
+ V(_Uint16Array, [], Uint16Array_getIndexed, 1549909675) \
+ V(_Int32Array, [], Int32Array_getIndexed, 1849422378) \
+ V(_Uint32Array, [], Uint32Array_getIndexed, 586613266) \
+ V(_Int64Array, [], Int64Array_getIndexed, 619332438) \
+ V(_Uint64Array, [], Uint64Array_getIndexed, 969448467) \
+ V(_Float32Array, [], Float32Array_getIndexed, 280103602) \
V(_Float32Array, []=, Float32Array_setIndexed, 1270729544) \
- V(_Float64Array, [], Float64Array_getIndexed, 1363897161) \
+ V(_Float64Array, [], Float64Array_getIndexed, 476393480) \
V(_Float64Array, []=, Float64Array_setIndexed, 283625119) \
- V(_ExternalUint8Array, [], ExternalUint8Array_getIndexed, 632699940) \
+ V(_ExternalUint8Array, [], ExternalUint8Array_getIndexed, 1892679907) \
// Forward declarations.
class Assembler;
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 5675214..ba42141 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -181,7 +181,7 @@
ASSERT(!cls.IsNull());
ASSERT(cls.HasTypeArguments());
ASSERT(cls.NumTypeArguments() == 1);
- const intptr_t field_offset = cls.type_arguments_instance_field_offset();
+ const intptr_t field_offset = cls.type_arguments_field_offset();
ASSERT(field_offset != Class::kNoTypeArguments);
return field_offset;
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 6b9178d..e247881 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -110,8 +110,16 @@
DartLibraryCalls::HandleMessage(
message->dest_port(), message->reply_port(), msg));
delete message;
- if (result.IsError()) {
- isolate_->object_store()->set_sticky_error(Error::Cast(result));
+ if (result.IsError() || result.IsUnhandledException()) {
+ if (result.IsError()) {
+ isolate_->object_store()->set_sticky_error(Error::Cast(result));
+ }
+ if (Isolate::UnhandledExceptionCallback() != NULL) {
+ Dart_EnterScope();
+ Dart_Handle error = Api::NewHandle(isolate_, result.raw());
+ (Isolate::UnhandledExceptionCallback())(error);
+ Dart_ExitScope();
+ }
return false;
}
ASSERT(result.IsNull());
@@ -446,6 +454,8 @@
Dart_IsolateCreateCallback Isolate::create_callback_ = NULL;
Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL;
+Dart_IsolateUnhandledExceptionCallback
+ Isolate::unhandled_exception_callback_ = NULL;
Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL;
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 5849640..6be2193 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -253,6 +253,14 @@
return interrupt_callback_;
}
+ static void SetUnhandledExceptionCallback(
+ Dart_IsolateUnhandledExceptionCallback cb) {
+ unhandled_exception_callback_ = cb;
+ }
+ static Dart_IsolateUnhandledExceptionCallback UnhandledExceptionCallback() {
+ return unhandled_exception_callback_;
+ }
+
static void SetShutdownCallback(Dart_IsolateShutdownCallback cb) {
shutdown_callback_ = cb;
}
@@ -350,6 +358,7 @@
static Dart_IsolateCreateCallback create_callback_;
static Dart_IsolateInterruptCallback interrupt_callback_;
+ static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_;
static Dart_IsolateShutdownCallback shutdown_callback_;
DISALLOW_COPY_AND_ASSIGN(Isolate);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b8088ff..fb4157a 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11,6 +11,7 @@
#include "vm/bootstrap.h"
#include "vm/class_finalizer.h"
#include "vm/code_generator.h"
+#include "vm/code_observers.h"
#include "vm/code_patcher.h"
#include "vm/compiler.h"
#include "vm/compiler_stats.h"
@@ -18,7 +19,6 @@
#include "vm/dart_api_state.h"
#include "vm/dart_entry.h"
#include "vm/datastream.h"
-#include "vm/debuginfo.h"
#include "vm/deopt_instructions.h"
#include "vm/double_conversion.h"
#include "vm/exceptions.h"
@@ -35,8 +35,6 @@
namespace dart {
-DEFINE_FLAG(bool, generate_gdb_symbols, false,
- "Generate symbols of generated dart functions for debugging with GDB");
DEFINE_FLAG(bool, show_internal_names, false,
"Show names of internal classes (e.g. \"OneByteString\") in error messages "
"instead of showing the corresponding interface names (e.g. \"String\")");
@@ -273,7 +271,7 @@
cls.set_id(Class::kClassId);
cls.raw_ptr()->state_bits_ = 0;
cls.set_is_finalized();
- cls.raw_ptr()->type_arguments_instance_field_offset_ =
+ cls.raw_ptr()->type_arguments_field_offset_in_words_ =
Class::kNoTypeArguments;
cls.raw_ptr()->num_native_fields_ = 0;
cls.InitEmptyFields();
@@ -304,7 +302,7 @@
cls = Class::New<Instance>(kDynamicCid);
cls.set_is_finalized();
- cls.set_is_interface();
+ cls.set_is_abstract();
dynamic_class_ = cls.raw();
// Allocate the remaining VM internal classes.
@@ -557,13 +555,13 @@
// Since they are pre-finalized, CalculateFieldOffsets() is not called, so we
// need to set the offset of their type_arguments_ field, which is explicitly
// declared in RawArray.
- cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset());
+ cls.set_type_arguments_field_offset(Array::type_arguments_offset());
// Set up the growable object array class (Has to be done after the array
// class is setup as one of its field is an array object).
cls = Class::New<GrowableObjectArray>();
object_store->set_growable_object_array_class(cls);
- cls.set_type_arguments_instance_field_offset(
+ cls.set_type_arguments_field_offset(
GrowableObjectArray::type_arguments_offset());
// canonical_type_arguments_ are NULL terminated.
@@ -634,7 +632,7 @@
cls = Class::New<ImmutableArray>();
object_store->set_immutable_array_class(cls);
- cls.set_type_arguments_instance_field_offset(Array::type_arguments_offset());
+ cls.set_type_arguments_field_offset(Array::type_arguments_offset());
ASSERT(object_store->immutable_array_class() != object_store->array_class());
name = Symbols::ImmutableArray();
RegisterPrivateClass(cls, name, core_lib);
@@ -1371,7 +1369,7 @@
// VM backed classes are almost ready: run checks and resolve class
// references, but do not recompute size.
result.set_is_prefinalized();
- result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments;
+ result.raw_ptr()->type_arguments_field_offset_in_words_ = kNoTypeArguments;
result.raw_ptr()->num_native_fields_ = 0;
result.raw_ptr()->token_pos_ = Scanner::kDummyTokenIndex;
result.InitEmptyFields();
@@ -1525,7 +1523,7 @@
bool Class::HasTypeArguments() const {
if (!IsSignatureClass() && (is_finalized() || is_prefinalized())) {
// More efficient than calling NumTypeArguments().
- return type_arguments_instance_field_offset() != kNoTypeArguments;
+ return type_arguments_field_offset() != kNoTypeArguments;
} else {
// No need to check NumTypeArguments() if class has type parameters.
return (NumTypeParameters() > 0) || (NumTypeArguments() > 0);
@@ -1547,40 +1545,6 @@
}
-bool Class::HasFactoryClass() const {
- const Object& factory_class = Object::Handle(raw_ptr()->factory_class_);
- return !factory_class.IsNull();
-}
-
-
-bool Class::HasResolvedFactoryClass() const {
- ASSERT(HasFactoryClass());
- const Object& factory_class = Object::Handle(raw_ptr()->factory_class_);
- return factory_class.IsClass();
-}
-
-
-RawClass* Class::FactoryClass() const {
- ASSERT(HasResolvedFactoryClass());
- Class& type_class = Class::Handle();
- type_class ^= raw_ptr()->factory_class_;
- return type_class.raw();
-}
-
-
-RawUnresolvedClass* Class::UnresolvedFactoryClass() const {
- ASSERT(!HasResolvedFactoryClass());
- UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle();
- unresolved_factory_class ^= raw_ptr()->factory_class_;
- return unresolved_factory_class.raw();
-}
-
-
-void Class::set_factory_class(const Object& value) const {
- StorePointer(&raw_ptr()->factory_class_, value.raw());
-}
-
-
// Return a TypeParameter if the type_name is a type parameter of this class.
// Return null otherwise.
RawTypeParameter* Class::LookupTypeParameter(const String& type_name,
@@ -1624,7 +1588,7 @@
if (super.IsNull()) {
offset = sizeof(RawObject);
} else {
- type_args_field_offset = super.type_arguments_instance_field_offset();
+ type_args_field_offset = super.type_arguments_field_offset();
offset = super.next_field_offset();
ASSERT(offset > 0);
// We should never call CalculateFieldOffsets for native wrapper
@@ -1642,7 +1606,7 @@
offset += kWordSize;
}
}
- set_type_arguments_instance_field_offset(type_args_field_offset);
+ set_type_arguments_field_offset(type_args_field_offset);
ASSERT(offset != 0);
Field& field = Field::Handle();
intptr_t len = flds.Length();
@@ -1791,7 +1755,7 @@
result.set_next_field_offset(FakeInstance::InstanceSize());
result.set_id(index);
result.raw_ptr()->state_bits_ = 0;
- result.raw_ptr()->type_arguments_instance_field_offset_ = kNoTypeArguments;
+ result.raw_ptr()->type_arguments_field_offset_in_words_ = kNoTypeArguments;
result.raw_ptr()->num_native_fields_ = 0;
result.raw_ptr()->token_pos_ = Scanner::kDummyTokenIndex;
result.InitEmptyFields();
@@ -1820,15 +1784,6 @@
}
-RawClass* Class::NewInterface(const String& name,
- const Script& script,
- intptr_t token_pos) {
- Class& result = Class::Handle(New<Instance>(name, script, token_pos));
- result.set_is_interface();
- return result.raw();
-}
-
-
RawClass* Class::NewSignatureClass(const String& name,
const Function& signature_function,
const Script& script) {
@@ -1856,7 +1811,7 @@
result.set_type_parameters(type_parameters);
result.SetFields(empty_array);
result.SetFunctions(empty_array);
- result.set_type_arguments_instance_field_offset(
+ result.set_type_arguments_field_offset(
Closure::type_arguments_offset());
// Implements interface "Function".
const Type& function_type = Type::Handle(Type::Function());
@@ -1951,10 +1906,11 @@
}
-void Class::set_is_interface() const {
- set_state_bits(InterfaceBit::update(true, raw_ptr()->state_bits_));
+void Class::set_is_implemented() const {
+ set_state_bits(ImplementedBit::update(true, raw_ptr()->state_bits_));
}
+
void Class::set_is_abstract() const {
set_state_bits(AbstractBit::update(true, raw_ptr()->state_bits_));
}
@@ -2080,6 +2036,11 @@
ASSERT(test_kind == kIsMoreSpecificThan);
return true;
}
+ // Check for ObjectType. Any type that is not NullType or DynamicType (already
+ // checked above), is more specific than ObjectType.
+ if (other.IsObjectClass()) {
+ return true;
+ }
// Check for reflexivity.
if (raw() == other.raw()) {
const intptr_t len = NumTypeArguments();
@@ -2102,8 +2063,7 @@
len,
malformed_error);
}
- // TODO(regis): Check for interface type S implementing method call() of
- // function type T.
+ // TODO(regis): Check if type S has a call() method of function type T.
// Check for two function types.
if (IsSignatureClass() && other.IsSignatureClass()) {
const Function& fun = Function::Handle(signature_function());
@@ -2114,9 +2074,8 @@
other_type_arguments,
malformed_error);
}
- // Check for 'direct super type' in the case of an interface
- // (i.e. other.is_interface()) or implicit interface (i.e.
- // !other.is_interface()) and check for transitivity at the same time.
+ // Check for 'direct super type' specified in the implements clause
+ // and check for transitivity at the same time.
Array& interfaces = Array::Handle(this->interfaces());
AbstractType& interface = AbstractType::Handle();
Class& interface_class = Class::Handle();
@@ -2158,15 +2117,6 @@
return true;
}
}
- // Check the interface case.
- if (is_interface()) {
- // We already checked the case where 'other' is an interface. Now, 'this',
- // an interface, cannot be more specific than a class, except class Object,
- // because although Object is not considered an interface by the vm, it is
- // one. In other words, all classes implementing this interface also extend
- // class Object. An interface is also more specific than the DynamicType.
- return (other.IsDynamicClass() || other.IsObjectClass());
- }
const Class& super_class = Class::Handle(SuperClass());
if (super_class.IsNull()) {
return false;
@@ -2388,8 +2338,7 @@
const char* Class::ToCString() const {
- const char* format = is_interface()
- ? "%s Interface: %s" : "%s Class: %s";
+ const char* format = "%s Class: %s";
const Library& lib = Library::Handle(library());
const char* library_name = lib.IsNull() ? "" : lib.ToCString();
const char* class_name = String::Handle(Name()).ToCString();
@@ -2454,11 +2403,6 @@
}
-void UnresolvedClass::set_factory_signature_class(const Class& value) const {
- StorePointer(&raw_ptr()->factory_signature_class_, value.raw());
-}
-
-
RawString* UnresolvedClass::Name() const {
if (library_prefix() != LibraryPrefix::null()) {
const LibraryPrefix& lib_prefix = LibraryPrefix::Handle(library_prefix());
@@ -2596,34 +2540,6 @@
}
-bool AbstractTypeArguments::AreIdentical(
- const AbstractTypeArguments& arguments,
- const AbstractTypeArguments& other_arguments,
- bool check_type_parameter_bounds) {
- if (arguments.raw() == other_arguments.raw()) {
- return true;
- }
- if (arguments.IsNull() || other_arguments.IsNull()) {
- return false;
- }
- intptr_t num_types = arguments.Length();
- if (num_types != other_arguments.Length()) {
- return false;
- }
- AbstractType& type = AbstractType::Handle();
- AbstractType& other_type = AbstractType::Handle();
- for (intptr_t i = 0; i < num_types; i++) {
- type = arguments.TypeAt(i);
- ASSERT(!type.IsNull());
- other_type = other_arguments.TypeAt(i);
- if (!type.IsIdentical(other_type, check_type_parameter_bounds)) {
- return false;
- }
- }
- return true;
-}
-
-
RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
const AbstractTypeArguments& instantiator_type_arguments) const {
// AbstractTypeArguments is an abstract class.
@@ -4214,7 +4130,7 @@
bool Function::CheckSourceFingerprint(intptr_t fp) const {
if (SourceFingerprint() != fp) {
- OS::Print("FP mismatch while recogbnizing method %s:"
+ OS::Print("FP mismatch while recognizing method %s:"
" expecting %"Pd" found %d\n",
ToFullyQualifiedCString(),
fp,
@@ -4497,7 +4413,7 @@
result.set_kind(kind);
result.set_literal(literal);
if (kind == Token::kINTEGER) {
- const Integer& value = Integer::Handle(Integer::New(literal, Heap::kOld));
+ const Integer& value = Integer::Handle(Integer::NewCanonical(literal));
ASSERT(value.IsSmi() || value.IsOld());
result.set_value(value);
} else if (kind == Token::kDOUBLE) {
@@ -6392,17 +6308,14 @@
ClassDictionaryIterator it(lib);
while (it.HasNext()) {
cls ^= it.GetNextClass();
- if (!cls.is_interface()) {
- error = Compiler::CompileAllFunctions(cls);
- if (!error.IsNull()) {
- return error.raw();
- }
+ error = Compiler::CompileAllFunctions(cls);
+ if (!error.IsNull()) {
+ return error.raw();
}
}
Array& anon_classes = Array::Handle(lib.raw_ptr()->anonymous_classes_);
for (int i = 0; i < lib.raw_ptr()->num_anonymous_; i++) {
cls ^= anon_classes.At(i);
- ASSERT(!cls.is_interface());
error = Compiler::CompileAllFunctions(cls);
if (!error.IsNull()) {
return error.raw();
@@ -7132,46 +7045,12 @@
MemoryRegion region(reinterpret_cast<void*>(instrs.EntryPoint()),
instrs.size());
assembler->FinalizeInstructions(region);
- Dart_FileWriterFunction perf_events_writer = Dart::perf_events_writer();
- if (perf_events_writer != NULL) {
- const char* format = "%"Px" %"Px" %s%s\n";
- uword addr = instrs.EntryPoint();
- uword size = instrs.size();
- const char* marker = optimized ? "*" : "";
- intptr_t len = OS::SNPrint(NULL, 0, format, addr, size, marker, name);
- char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
- OS::SNPrint(buffer, len + 1, format, addr, size, marker, name);
- (*perf_events_writer)(buffer, len);
- }
- DebugInfo* pprof_symbol_generator = Dart::pprof_symbol_generator();
- if (pprof_symbol_generator != NULL) {
- ASSERT(strlen(name) != 0);
- pprof_symbol_generator->AddCode(instrs.EntryPoint(), instrs.size());
- pprof_symbol_generator->AddCodeRegion(name,
- instrs.EntryPoint(),
- instrs.size());
- }
- if (FLAG_generate_gdb_symbols) {
- ASSERT(strlen(name) != 0);
- intptr_t prolog_offset = assembler->prolog_offset();
- if (prolog_offset > 0) {
- // In order to ensure that gdb sees the first instruction of a function
- // as the prolog sequence we register two symbols for the cases when
- // the prolog sequence is not the first instruction:
- // <name>_entry is used for code preceding the prolog sequence.
- // <name> for rest of the code (first instruction is prolog sequence).
- const char* kFormat = "%s_%s";
- intptr_t len = OS::SNPrint(NULL, 0, kFormat, name, "entry");
- char* pname = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
- OS::SNPrint(pname, (len + 1), kFormat, name, "entry");
- DebugInfo::RegisterSection(pname, instrs.EntryPoint(), prolog_offset);
- DebugInfo::RegisterSection(name,
- (instrs.EntryPoint() + prolog_offset),
- (instrs.size() - prolog_offset));
- } else {
- DebugInfo::RegisterSection(name, instrs.EntryPoint(), instrs.size());
- }
- }
+
+ CodeObservers::NotifyAll(name,
+ instrs.EntryPoint(),
+ assembler->prologue_offset(),
+ instrs.size(),
+ optimized);
const ZoneGrowableArray<int>& pointer_offsets =
assembler->GetPointerOffsets();
@@ -7203,9 +7082,7 @@
Assembler* assembler,
bool optimized) {
// Calling ToFullyQualifiedCString is very expensive, try to avoid it.
- if (FLAG_generate_gdb_symbols ||
- Dart::perf_events_writer() != NULL ||
- Dart::pprof_symbol_generator() != NULL) {
+ if (CodeObservers::AreActive()) {
return FinalizeCode(function.ToFullyQualifiedCString(),
assembler,
optimized);
@@ -8223,7 +8100,7 @@
RawAbstractTypeArguments* Instance::GetTypeArguments() const {
const Class& cls = Class::Handle(clazz());
- intptr_t field_offset = cls.type_arguments_instance_field_offset();
+ intptr_t field_offset = cls.type_arguments_field_offset();
ASSERT(field_offset != Class::kNoTypeArguments);
AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
type_arguments ^= *FieldAddrAtOffset(field_offset);
@@ -8233,7 +8110,7 @@
void Instance::SetTypeArguments(const AbstractTypeArguments& value) const {
const Class& cls = Class::Handle(clazz());
- intptr_t field_offset = cls.type_arguments_instance_field_offset();
+ intptr_t field_offset = cls.type_arguments_field_offset();
ASSERT(field_offset != Class::kNoTypeArguments);
SetFieldAtOffset(field_offset, value);
}
@@ -8495,14 +8372,6 @@
}
-bool AbstractType::IsIdentical(const AbstractType& other,
- bool check_type_parameter_bound) const {
- // AbstractType is an abstract class.
- UNREACHABLE();
- return false;
-}
-
-
RawAbstractType* AbstractType::InstantiateFrom(
const AbstractTypeArguments& instantiator_type_arguments) const {
// AbstractType is an abstract class.
@@ -8926,27 +8795,6 @@
}
-bool Type::IsIdentical(const AbstractType& other,
- bool check_type_parameter_bounds) const {
- if (raw() == other.raw()) {
- return true;
- }
- if (!other.IsType()) {
- return false;
- }
- // Both type classes may not be resolved yet.
- String& name = String::Handle(TypeClassName());
- String& other_name = String::Handle(Type::Cast(other).TypeClassName());
- if (!name.Equals(other_name)) {
- return false;
- }
- return AbstractTypeArguments::AreIdentical(
- AbstractTypeArguments::Handle(arguments()),
- AbstractTypeArguments::Handle(other.arguments()),
- false); // Bounds are only checked at the top level.
-}
-
-
RawAbstractType* Type::Canonicalize() const {
ASSERT(IsFinalized());
if (IsCanonical() || IsMalformed()) {
@@ -9111,38 +8959,6 @@
}
-bool TypeParameter::IsIdentical(const AbstractType& other,
- bool check_type_parameter_bound) const {
- if (raw() == other.raw()) {
- return true;
- }
- if (!other.IsTypeParameter()) {
- return false;
- }
- const TypeParameter& other_type_param = TypeParameter::Cast(other);
- // IsIdentical may be called on type parameters belonging to different
- // classes, e.g. to an interface and to its default factory class.
- // Therefore, both type parameters may have different parameterized classes
- // and different indices. Compare the type parameter names only, and their
- // bounds if requested.
- String& type_param_name = String::Handle(name());
- String& other_type_param_name = String::Handle(other_type_param.name());
- if (!type_param_name.Equals(other_type_param_name)) {
- return false;
- }
- if (check_type_parameter_bound) {
- AbstractType& this_bound = AbstractType::Handle(bound());
- AbstractType& other_bound = AbstractType::Handle(other_type_param.bound());
- // Bounds are only checked at the top level.
- const bool check_type_parameter_bounds = false;
- if (!this_bound.IsIdentical(other_bound, check_type_parameter_bounds)) {
- return false;
- }
- }
- return true;
-}
-
-
void TypeParameter::set_parameterized_class(const Class& value) const {
// Set value may be null.
StorePointer(&raw_ptr()->parameterized_class_, value.raw());
@@ -9243,8 +9059,7 @@
RawInteger* Integer::New(const String& str, Heap::Space space) {
- // We are not supposed to have integers represented as two byte or
- // four byte strings.
+ // We are not supposed to have integers represented as two byte strings.
ASSERT(str.IsOneByteString());
int64_t value;
if (!OS::StringToInt64(str.ToCString(), &value)) {
@@ -9257,6 +9072,23 @@
}
+RawInteger* Integer::NewCanonical(const String& str) {
+ // We are not supposed to have integers represented as two byte strings.
+ ASSERT(str.IsOneByteString());
+ int64_t value;
+ if (!OS::StringToInt64(str.ToCString(), &value)) {
+ const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str));
+ ASSERT(!BigintOperations::FitsIntoSmi(big));
+ ASSERT(!BigintOperations::FitsIntoMint(big));
+ return big.raw();
+ }
+ if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
+ return Smi::New(value);
+ }
+ return Mint::NewCanonical(value);
+}
+
+
RawInteger* Integer::New(int64_t value, Heap::Space space) {
if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
return Smi::New(value);
@@ -9858,6 +9690,10 @@
const Bigint& other_bgi = Bigint::Cast(other);
+ if (this->IsNegative() != other_bgi.IsNegative()) {
+ return false;
+ }
+
intptr_t len = this->Length();
if (len != other_bgi.Length()) {
return false;
@@ -9880,6 +9716,36 @@
}
+RawBigint* Bigint::NewCanonical(const String& str) {
+ const Bigint& value = Bigint::Handle(
+ BigintOperations::NewFromCString(str.ToCString(), Heap::kOld));
+ ASSERT(!BigintOperations::FitsIntoMint(value));
+ const Class& cls =
+ Class::Handle(Isolate::Current()->object_store()->bigint_class());
+ const Array& constants = Array::Handle(cls.constants());
+ const intptr_t constants_len = constants.Length();
+ // Linear search to see whether this value is already present in the
+ // list of canonicalized constants.
+ Bigint& canonical_value = Bigint::Handle();
+ intptr_t index = 0;
+ while (index < constants_len) {
+ canonical_value ^= constants.At(index);
+ if (canonical_value.IsNull()) {
+ break;
+ }
+ if (canonical_value.Equals(value)) {
+ return canonical_value.raw();
+ }
+ index++;
+ }
+ // The value needs to be added to the constants list. Grow the list if
+ // it is full.
+ cls.InsertCanonicalConstant(index, value);
+ value.SetCanonical();
+ return value.raw();
+}
+
+
double Bigint::AsDoubleValue() const {
return Double::Handle(BigintOperations::ToDouble(*this)).value();
}
@@ -9977,8 +9843,9 @@
ASSERT(len >= 0);
ASSERT((begin_index + len) <= str.Length());
StringHasher hasher;
- for (intptr_t i = 0; i < len; i++) {
- hasher.Add(str.CharAt(begin_index + i));
+ CodePointIterator it(str, begin_index, len);
+ while (it.Next()) {
+ hasher.Add(it.Current());
}
return hasher.Finalize(String::kHashBits);
}
@@ -10001,7 +9868,12 @@
intptr_t String::Hash(const uint16_t* characters, intptr_t len) {
- return HashImpl(characters, len);
+ StringHasher hasher;
+ intptr_t i = 0;
+ while (i < len) {
+ hasher.Add(Utf16::Next(characters, &i, len));
+ }
+ return hasher.Finalize(String::kHashBits);
}
@@ -10215,7 +10087,7 @@
Heap::Space space) {
bool is_one_byte_string = true;
for (intptr_t i = 0; i < array_len; ++i) {
- if (utf16_array[i] > 0xFF) {
+ if (!Utf::IsLatin1(utf16_array[i])) {
is_one_byte_string = false;
break;
}
@@ -10233,11 +10105,11 @@
bool is_one_byte_string = true;
intptr_t utf16_len = array_len;
for (intptr_t i = 0; i < array_len; ++i) {
- if (utf32_array[i] > 0xFF) {
+ if (!Utf::IsLatin1(utf32_array[i])) {
is_one_byte_string = false;
- }
- if (utf32_array[i] > 0xFFFF) {
- utf16_len += 1;
+ if (Utf::IsSupplementary(utf32_array[i])) {
+ utf16_len += 1;
+ }
}
}
if (is_one_byte_string) {
@@ -10314,7 +10186,7 @@
if (dst.IsOneByteString()) {
NoGCScope no_gc;
for (intptr_t i = 0; i < array_len; ++i) {
- ASSERT(utf16_array[i] <= 0xFF);
+ ASSERT(Utf::IsLatin1(utf16_array[i]));
*OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i];
}
} else {
@@ -10469,7 +10341,7 @@
intptr_t char_size = str.CharSize();
if (char_size == kTwoByteChar) {
for (intptr_t i = begin_index; i < begin_index + length; ++i) {
- if (str.CharAt(i) > 0xFF) {
+ if (!Utf::IsLatin1(str.CharAt(i))) {
is_one_byte_string = false;
break;
}
@@ -10519,15 +10391,16 @@
intptr_t length,
void* peer,
Dart_PeerFinalizer cback) const {
+ NoGCScope no_gc;
ASSERT(array != NULL);
intptr_t str_length = this->Length();
ASSERT(length >= (str_length * this->CharSize()));
intptr_t class_id = raw()->GetClassId();
intptr_t used_size = 0;
intptr_t original_size = 0;
- uword tags = 0;
- NoGCScope no_gc;
+ uword tags = raw_ptr()->tags_;
+ ASSERT(!IsCanonical());
if (class_id == kOneByteStringCid) {
used_size = ExternalOneByteString::InstanceSize();
original_size = OneByteString::InstanceSize(str_length);
@@ -10604,10 +10477,10 @@
if (!has_mapping) {
return str.raw();
}
- if (dst_max <= 0xFF) {
+ if (Utf::IsLatin1(dst_max)) {
return OneByteString::Transform(mapping, str, space);
}
- ASSERT(dst_max > 0xFF);
+ ASSERT(Utf::IsBmp(dst_max) || Utf::IsSupplementary(dst_max));
return TwoByteString::Transform(mapping, str, space);
}
@@ -10626,20 +10499,20 @@
bool String::CodePointIterator::Next() {
ASSERT(index_ >= -1);
- ASSERT(index_ < str_.Length());
- int d = Utf16::Length(ch_);
- if (index_ == (str_.Length() - d)) {
- return false;
- }
- index_ += d;
- ch_ = str_.CharAt(index_);
- if (Utf16::IsLeadSurrogate(ch_) && (index_ != (str_.Length() - 1))) {
- int32_t ch2 = str_.CharAt(index_ + 1);
- if (Utf16::IsTrailSurrogate(ch2)) {
- ch_ = Utf16::Decode(ch_, ch2);
+ intptr_t length = Utf16::Length(ch_);
+ if (index_ < (end_ - length)) {
+ index_ += length;
+ ch_ = str_.CharAt(index_);
+ if (Utf16::IsLeadSurrogate(ch_) && (index_ < (end_ - 1))) {
+ int32_t ch2 = str_.CharAt(index_ + 1);
+ if (Utf16::IsTrailSurrogate(ch2)) {
+ ch_ = Utf16::Decode(ch_, ch2);
+ }
}
+ return true;
}
- return true;
+ index_ = end_;
+ return false;
}
@@ -10774,7 +10647,7 @@
Heap::Space space) {
const String& result =String::Handle(OneByteString::New(len, space));
for (intptr_t i = 0; i < len; ++i) {
- ASSERT(characters[i] <= 0xFF);
+ ASSERT(Utf::IsLatin1(characters[i]));
*CharAddr(result, i) = characters[i];
}
return OneByteString::raw(result);
@@ -10786,7 +10659,7 @@
Heap::Space space) {
const String& result = String::Handle(OneByteString::New(len, space));
for (intptr_t i = 0; i < len; ++i) {
- ASSERT(characters[i] <= 0xFF);
+ ASSERT(Utf::IsLatin1(characters[i]));
*CharAddr(result, i) = characters[i];
}
return OneByteString::raw(result);
@@ -10802,6 +10675,22 @@
}
+RawOneByteString* OneByteString::New(const String& other_one_byte_string,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space) {
+ const String& result = String::Handle(OneByteString::New(other_len, space));
+ ASSERT(other_one_byte_string.IsOneByteString());
+ if (other_len > 0) {
+ NoGCScope no_gc;
+ memmove(OneByteString::CharAddr(result, 0),
+ OneByteString::CharAddr(other_one_byte_string, other_start_index),
+ other_len);
+ }
+ return OneByteString::raw(result);
+}
+
+
RawOneByteString* OneByteString::Concat(const String& str1,
const String& str2,
Heap::Space space) {
@@ -10840,7 +10729,7 @@
const String& result = String::Handle(OneByteString::New(len, space));
for (intptr_t i = 0; i < len; ++i) {
int32_t ch = mapping(str.CharAt(i));
- ASSERT(ch >= 0 && ch <= 0xFF);
+ ASSERT(Utf::IsLatin1(ch));
*CharAddr(result, i) = ch;
}
return OneByteString::raw(result);
@@ -10925,7 +10814,7 @@
NoGCScope no_gc;
intptr_t j = 0;
for (intptr_t i = 0; i < array_len; ++i) {
- if (utf32_array[i] > 0xffff) {
+ if (Utf::IsSupplementary(utf32_array[i])) {
ASSERT(j < (utf16_len - 1));
Utf16::Encode(utf32_array[i], CharAddr(result, j));
j += 2;
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a6734ad..2b43f97 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -454,25 +454,30 @@
public:
intptr_t instance_size() const {
ASSERT(is_finalized() || is_prefinalized());
- return raw_ptr()->instance_size_;
+ return (raw_ptr()->instance_size_in_words_ * kWordSize);
}
- void set_instance_size(intptr_t value) const {
- ASSERT(Utils::IsAligned(value, kObjectAlignment));
- raw_ptr()->instance_size_ = value;
+ void set_instance_size(intptr_t value_in_bytes) const {
+ ASSERT(kWordSize != 0);
+ set_instance_size_in_words(value_in_bytes / kWordSize);
}
- static intptr_t instance_size_offset() {
- return OFFSET_OF(RawClass, instance_size_);
+ void set_instance_size_in_words(intptr_t value) const {
+ ASSERT(Utils::IsAligned((value * kWordSize), kObjectAlignment));
+ raw_ptr()->instance_size_in_words_ = value;
}
intptr_t next_field_offset() const {
- return raw_ptr()->next_field_offset_;
+ return raw_ptr()->next_field_offset_in_words_ * kWordSize;
}
- void set_next_field_offset(intptr_t value) const {
- ASSERT((Utils::IsAligned(value, kObjectAlignment) &&
- (value == raw_ptr()->instance_size_)) ||
- (!Utils::IsAligned(value, kObjectAlignment) &&
- (value + kWordSize == raw_ptr()->instance_size_)));
- raw_ptr()->next_field_offset_ = value;
+ void set_next_field_offset(intptr_t value_in_bytes) const {
+ ASSERT(kWordSize != 0);
+ set_next_field_offset_in_words(value_in_bytes / kWordSize);
+ }
+ void set_next_field_offset_in_words(intptr_t value) const {
+ ASSERT((Utils::IsAligned((value * kWordSize), kObjectAlignment) &&
+ (value == raw_ptr()->instance_size_in_words_)) ||
+ (!Utils::IsAligned((value * kWordSize), kObjectAlignment) &&
+ ((value + 1) == raw_ptr()->instance_size_in_words_)));
+ raw_ptr()->next_field_offset_in_words_ = value;
}
cpp_vtable handle_vtable() const { return raw_ptr()->handle_vtable_; }
@@ -540,15 +545,28 @@
// If this class is parameterized, each instance has a type_arguments field.
static const intptr_t kNoTypeArguments = -1;
- intptr_t type_arguments_instance_field_offset() const {
+ intptr_t type_arguments_field_offset() const {
ASSERT(is_finalized() || is_prefinalized());
- return raw_ptr()->type_arguments_instance_field_offset_;
+ if (raw_ptr()->type_arguments_field_offset_in_words_ == kNoTypeArguments) {
+ return kNoTypeArguments;
+ }
+ return raw_ptr()->type_arguments_field_offset_in_words_ * kWordSize;
}
- void set_type_arguments_instance_field_offset(intptr_t value) const {
- raw_ptr()->type_arguments_instance_field_offset_ = value;
+ void set_type_arguments_field_offset(intptr_t value_in_bytes) const {
+ intptr_t value;
+ if (value_in_bytes == kNoTypeArguments) {
+ value = kNoTypeArguments;
+ } else {
+ ASSERT(kWordSize != 0);
+ value = value_in_bytes / kWordSize;
+ }
+ set_type_arguments_field_offset_in_words(value);
}
- static intptr_t type_arguments_instance_field_offset_offset() {
- return OFFSET_OF(RawClass, type_arguments_instance_field_offset_);
+ void set_type_arguments_field_offset_in_words(intptr_t value) const {
+ raw_ptr()->type_arguments_field_offset_in_words_ = value;
+ }
+ static intptr_t type_arguments_field_offset_in_words_offset() {
+ return OFFSET_OF(RawClass, type_arguments_field_offset_in_words_);
}
// The super type of this class, Object type if not explicitly specified.
@@ -561,21 +579,6 @@
// Asserts that the class of the super type has been resolved.
RawClass* SuperClass() const;
- // Return true if this interface has a factory class.
- bool HasFactoryClass() const;
-
- // Return true if the factory class of this interface is resolved.
- bool HasResolvedFactoryClass() const;
-
- // Return the resolved factory class of this interface.
- RawClass* FactoryClass() const;
-
- // Return the unresolved factory class of this interface.
- RawUnresolvedClass* UnresolvedFactoryClass() const;
-
- // Set the resolved or unresolved factory class of this interface.
- void set_factory_class(const Object& value) const;
-
// Interfaces is an array of Types.
RawArray* interfaces() const { return raw_ptr()->interfaces_; }
void set_interfaces(const Array& value) const;
@@ -676,10 +679,10 @@
return RoundedAllocationSize(sizeof(RawClass));
}
- bool is_interface() const {
- return InterfaceBit::decode(raw_ptr()->state_bits_);
+ bool is_implemented() const {
+ return ImplementedBit::decode(raw_ptr()->state_bits_);
}
- void set_is_interface() const;
+ void set_is_implemented() const;
bool is_abstract() const {
return AbstractBit::decode(raw_ptr()->state_bits_);
@@ -724,13 +727,10 @@
// Allocate a class used for VM internal objects.
template <class FakeObject> static RawClass* New();
- // Allocate instance classes and interfaces.
+ // Allocate instance classes.
static RawClass* New(const String& name,
const Script& script,
intptr_t token_pos);
- static RawClass* NewInterface(const String& name,
- const Script& script,
- intptr_t token_pos);
static RawClass* NewNativeWrapper(const Library& library,
const String& name,
int num_fields);
@@ -756,13 +756,13 @@
private:
enum {
kConstBit = 1,
- kInterfaceBit = 2,
+ kImplementedBit = 2,
kAbstractBit = 3,
kStateTagBit = 4,
kStateTagSize = 2,
};
class ConstBit : public BitField<bool, kConstBit, 1> {};
- class InterfaceBit : public BitField<bool, kInterfaceBit, 1> {};
+ class ImplementedBit : public BitField<bool, kImplementedBit, 1> {};
class AbstractBit : public BitField<bool, kAbstractBit, 1> {};
class StateBits : public BitField<RawClass::ClassState,
kStateTagBit, kStateTagSize> {}; // NOLINT
@@ -819,11 +819,6 @@
RawString* ident() const { return raw_ptr()->ident_; }
intptr_t token_pos() const { return raw_ptr()->token_pos_; }
- RawClass* factory_signature_class() const {
- return raw_ptr()->factory_signature_class_;
- }
- void set_factory_signature_class(const Class& value) const;
-
RawString* Name() const;
static intptr_t InstanceSize() {
@@ -854,12 +849,6 @@
static bool AreEqual(const AbstractTypeArguments& arguments,
const AbstractTypeArguments& other_arguments);
- // Returns true if both arguments represent vectors of possibly still
- // unresolved identical types.
- static bool AreIdentical(const AbstractTypeArguments& arguments,
- const AbstractTypeArguments& other_arguments,
- bool check_type_parameter_bounds);
-
// Return 'this' if this type argument vector is instantiated, i.e. if it does
// not refer to type parameters. Otherwise, return a new type argument vector
// where each reference to a type parameter is replaced with the corresponding
@@ -896,7 +885,7 @@
}
// Check that this type argument vector is within the declared bounds of the
- // given class or interface. If not, set malformed_error (if not yet set).
+ // given class. If not, set malformed_error (if not yet set).
bool IsWithinBoundsOf(const Class& cls,
const AbstractTypeArguments& bounds_instantiator,
Error* malformed_error) const;
@@ -1591,7 +1580,7 @@
bool is_const() const { return ConstBit::decode(raw_ptr()->kind_bits_); }
inline intptr_t Offset() const;
- inline void SetOffset(intptr_t value) const;
+ inline void SetOffset(intptr_t value_in_bytes) const;
RawInstance* value() const;
void set_value(const Instance& value) const;
@@ -3177,8 +3166,6 @@
virtual intptr_t token_pos() const;
virtual bool IsInstantiated() const;
virtual bool Equals(const Instance& other) const;
- virtual bool IsIdentical(const AbstractType& other,
- bool check_type_parameter_bound) const;
// Instantiate this type using the given type argument vector.
// Return a new type, or return 'this' if it is already instantiated.
@@ -3241,15 +3228,6 @@
// Check if this type represents the 'Function' type.
bool IsFunctionType() const;
- // Check if this type is an interface type.
- bool IsInterfaceType() const {
- if (!HasResolvedTypeClass()) {
- return false;
- }
- const Class& cls = Class::Handle(type_class());
- return !cls.IsNull() && cls.is_interface();
- }
-
// Check the subtype relationship.
bool IsSubtypeOf(const AbstractType& other, Error* malformed_error) const {
return TypeTest(kIsSubtypeOf, other, malformed_error);
@@ -3316,8 +3294,6 @@
virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
virtual bool IsInstantiated() const;
virtual bool Equals(const Instance& other) const;
- virtual bool IsIdentical(const AbstractType& other,
- bool check_type_parameter_bound) const;
virtual RawAbstractType* InstantiateFrom(
const AbstractTypeArguments& instantiator_type_arguments) const;
virtual RawAbstractType* Canonicalize() const;
@@ -3353,7 +3329,7 @@
// The 'double' type.
static RawType* Double();
- // The 'num' interface type.
+ // The 'num' type.
static RawType* Number();
// The 'String' type.
@@ -3362,7 +3338,7 @@
// The 'Array' type.
static RawType* ArrayType();
- // The 'Function' interface type.
+ // The 'Function' type.
static RawType* Function();
// The finalized type of the given non-parameterized class.
@@ -3416,8 +3392,6 @@
virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
virtual bool IsInstantiated() const { return false; }
virtual bool Equals(const Instance& other) const;
- virtual bool IsIdentical(const AbstractType& other,
- bool check_type_parameter_bound) const;
virtual RawAbstractType* InstantiateFrom(
const AbstractTypeArguments& instantiator_type_arguments) const;
virtual RawAbstractType* Canonicalize() const { return raw(); }
@@ -3465,6 +3439,10 @@
class Integer : public Number {
public:
static RawInteger* New(const String& str, Heap::Space space = Heap::kNew);
+
+ // Returns a canonical Integer object allocated in the old gen space.
+ static RawInteger* NewCanonical(const String& str);
+
static RawInteger* New(int64_t value, Heap::Space space = Heap::kNew);
virtual double AsDoubleValue() const;
@@ -3623,6 +3601,9 @@
static RawBigint* New(const String& str, Heap::Space space = Heap::kNew);
+ // Returns a canonical Bigint object allocated in the old gen space.
+ static RawBigint* NewCanonical(const String& str);
+
RawBigint* ArithmeticOp(Token::Kind operation, const Bigint& other) const;
private:
@@ -3730,13 +3711,23 @@
public:
explicit CodePointIterator(const String& str)
: str_(str),
+ ch_(0),
index_(-1),
- ch_(-1) {
+ end_(str.Length()) {
}
- int32_t Current() {
+ CodePointIterator(const String& str, intptr_t start, intptr_t length)
+ : str_(str),
+ ch_(0),
+ index_(start - 1),
+ end_(start + length) {
+ ASSERT(start >= 0);
+ ASSERT(end_ <= str.Length());
+ }
+
+ int32_t Current() const {
ASSERT(index_ >= 0);
- ASSERT(index_ < str_.Length());
+ ASSERT(index_ < end_);
return ch_;
}
@@ -3744,8 +3735,9 @@
private:
const String& str_;
- intptr_t index_;
int32_t ch_;
+ intptr_t index_;
+ intptr_t end_;
DISALLOW_IMPLICIT_CONSTRUCTORS(CodePointIterator);
};
@@ -3991,6 +3983,11 @@
Heap::Space space);
static RawOneByteString* New(const String& str,
Heap::Space space);
+ // 'other' must be OneByteString.
+ static RawOneByteString* New(const String& other_one_byte_string,
+ intptr_t other_start_index,
+ intptr_t other_len,
+ Heap::Space space);
static RawOneByteString* Concat(const String& str1,
const String& str2,
@@ -5922,13 +5919,15 @@
intptr_t Field::Offset() const {
ASSERT(!is_static()); // Offset is valid only for instance fields.
- return Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->value_));
+ intptr_t value = Smi::Value(reinterpret_cast<RawSmi*>(raw_ptr()->value_));
+ return (value * kWordSize);
}
-void Field::SetOffset(intptr_t value) const {
+void Field::SetOffset(intptr_t value_in_bytes) const {
ASSERT(!is_static()); // SetOffset is valid only for instance fields.
- raw_ptr()->value_ = Smi::New(value);
+ ASSERT(kWordSize != 0);
+ raw_ptr()->value_ = Smi::New(value_in_bytes / kWordSize);
}
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 11b7f77..f4b1c23 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -191,26 +191,9 @@
EXPECT_EQ(Utils::RoundUp((header_size + (1 * kWordSize)), kObjectAlignment),
one_field_class.instance_size());
EXPECT_EQ(header_size, field.Offset());
-}
-
-
-TEST_CASE(Interface) {
- String& class_name = String::Handle(Symbols::New("EmptyClass"));
- Script& script = Script::Handle();
- const Class& factory_class =
- Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex));
- const Array& no_fields = Array::Handle(Object::empty_array());
- // Finalizes the class.
- factory_class.SetFields(no_fields);
-
- String& interface_name = String::Handle(Symbols::New("MyInterface"));
- const Class& interface = Class::Handle(
- Class::NewInterface(interface_name, script, Scanner::kDummyTokenIndex));
- EXPECT(interface.is_interface());
- EXPECT(!factory_class.is_interface());
- EXPECT(!interface.HasFactoryClass());
- interface.set_factory_class(factory_class);
- EXPECT_EQ(factory_class.raw(), interface.FactoryClass());
+ EXPECT(!one_field_class.is_implemented());
+ one_field_class.set_is_implemented();
+ EXPECT(one_field_class.is_implemented());
}
@@ -328,13 +311,13 @@
const String& smi_str = String::Handle(String::New("1"));
const String& mint1_str = String::Handle(String::New("2147419168"));
const String& mint2_str = String::Handle(String::New("-2147419168"));
- Integer& i = Integer::Handle(Integer::New(smi_str));
+ Integer& i = Integer::Handle(Integer::NewCanonical(smi_str));
EXPECT(i.IsSmi());
- i = Integer::New(mint1_str);
+ i = Integer::NewCanonical(mint1_str);
EXPECT(i.IsMint());
EXPECT(!i.IsZero());
EXPECT(!i.IsNegative());
- i = Integer::New(mint2_str);
+ i = Integer::NewCanonical(mint2_str);
EXPECT(i.IsMint());
EXPECT(!i.IsZero());
EXPECT(i.IsNegative());
@@ -456,7 +439,7 @@
EXPECT(b.IsNull());
const char* cstr = "18446744073709551615000";
const String& test = String::Handle(String::New(cstr));
- b = Bigint::New(test);
+ b = Bigint::NewCanonical(test);
const char* str = b.ToCString();
EXPECT_STREQ(cstr, str);
@@ -493,15 +476,17 @@
TEST_CASE(Integer) {
Integer& i = Integer::Handle();
- i = Integer::New(String::Handle(String::New("12")));
+ i = Integer::NewCanonical(String::Handle(String::New("12")));
EXPECT(i.IsSmi());
- i = Integer::New(String::Handle(String::New("-120")));
+ i = Integer::NewCanonical(String::Handle(String::New("-120")));
EXPECT(i.IsSmi());
- i = Integer::New(String::Handle(String::New("0")));
+ i = Integer::NewCanonical(String::Handle(String::New("0")));
EXPECT(i.IsSmi());
- i = Integer::New(String::Handle(String::New("12345678901234567890")));
+ i = Integer::NewCanonical(
+ String::Handle(String::New("12345678901234567890")));
EXPECT(i.IsBigint());
- i = Integer::New(String::Handle(String::New("-12345678901234567890111222")));
+ i = Integer::NewCanonical(
+ String::Handle(String::New("-12345678901234567890111222")));
EXPECT(i.IsBigint());
}
@@ -1709,6 +1694,23 @@
}
+TEST_CASE(StringCodePointIteratorRange) {
+ const String& str = String::Handle(String::New("foo bar baz"));
+
+ String::CodePointIterator it0(str, 3, 0);
+ EXPECT(!it0.Next());
+
+ String::CodePointIterator it1(str, 4, 3);
+ EXPECT(it1.Next());
+ EXPECT_EQ('b', it1.Current());
+ EXPECT(it1.Next());
+ EXPECT_EQ('a', it1.Current());
+ EXPECT(it1.Next());
+ EXPECT_EQ('r', it1.Current());
+ EXPECT(!it1.Next());
+}
+
+
TEST_CASE(GrowableObjectArray) {
const int kArrayLen = 5;
Smi& value = Smi::Handle();
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index e6c4b37..68a0530 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -5,6 +5,7 @@
#include "vm/pages.h"
#include "platform/assert.h"
+#include "vm/compiler_stats.h"
#include "vm/gc_marker.h"
#include "vm/gc_sweeper.h"
#include "vm/object.h"
@@ -237,6 +238,9 @@
}
if (result != 0) {
in_use_ += size;
+ if (FLAG_compiler_stats && (type == HeapPage::kExecutable)) {
+ CompilerStats::code_allocated += size;
+ }
}
ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
return result;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 3273891..6cc95d3 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -29,10 +29,6 @@
DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
DEFINE_FLAG(bool, warn_legacy_map_literal, false,
"Warning on legacy map literal syntax (single type argument)");
-DEFINE_FLAG(bool, warn_legacy_dynamic, false,
- "Warning on legacy type Dynamic)");
-DEFINE_FLAG(bool, warn_legacy_getters, false,
- "Warning on legacy getter syntax");
DEFINE_FLAG(bool, strict_function_literals, false,
"enforce new function literal rules");
DEFINE_FLAG(bool, fail_legacy_abstract, false,
@@ -538,7 +534,6 @@
intptr_t token_pos)
: clazz_(cls),
class_name_(cls_name),
- is_interface_(is_interface),
token_pos_(token_pos),
functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())),
fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) {
@@ -629,10 +624,6 @@
return class_name_;
}
- bool is_interface() const {
- return is_interface_;
- }
-
bool has_constructor() const {
Function& func = Function::Handle();
for (int i = 0; i < functions_.Length(); i++) {
@@ -702,7 +693,6 @@
const Class& clazz_;
const String& class_name_;
- const bool is_interface_;
intptr_t token_pos_; // Token index of "class" keyword.
GrowableObjectArray& functions_;
GrowableObjectArray& fields_;
@@ -1290,15 +1280,6 @@
}
-void Parser::CheckFunctionIsCallable(intptr_t token_pos,
- const Function& function) {
- if (Class::Handle(function.Owner()).is_interface()) {
- ErrorMsg(token_pos, "cannot call function of interface '%s'",
- function.ToFullyQualifiedCString());
- }
-}
-
-
// Resolve and return the dynamic function of the given name in the superclass.
// If it is not found, and resolve_getter is true, try to resolve a getter of
// the same name. If it is still not found, return noSuchMethod and
@@ -1329,7 +1310,6 @@
} else {
*is_no_such_method = false;
}
- CheckFunctionIsCallable(token_pos, super_func);
return super_func.raw();
}
@@ -1462,7 +1442,6 @@
ArgumentListNode* op_arguments = new ArgumentListNode(super_pos);
AstNode* receiver = LoadReceiver(super_pos);
op_arguments->Add(receiver);
- CheckFunctionIsCallable(super_pos, super_operator);
if (is_no_such_method) {
op_arguments = BuildNoSuchMethodArguments(
super_pos, operator_function_name, *op_arguments);
@@ -1519,7 +1498,6 @@
op_arguments->Add(receiver);
op_arguments->Add(other_operand);
- CheckFunctionIsCallable(operator_pos, super_operator);
if (is_no_such_method) {
op_arguments = BuildNoSuchMethodArguments(
operator_pos, operator_function_name, *op_arguments);
@@ -1638,7 +1616,6 @@
String::Handle(super_class.Name()).ToCString(),
error_message.ToCString());
}
- CheckFunctionIsCallable(supercall_pos, super_ctor);
current_block_->statements->Add(
new StaticCallNode(supercall_pos, super_ctor, arguments));
}
@@ -1698,7 +1675,6 @@
ctor_name.ToCString(),
error_message.ToCString());
}
- CheckFunctionIsCallable(supercall_pos, super_ctor);
return new StaticCallNode(supercall_pos, super_ctor, arguments);
}
@@ -1912,7 +1888,6 @@
ctor_name.ToCString(),
error_message.ToCString());
}
- CheckFunctionIsCallable(call_pos, redirect_ctor);
current_block_->statements->Add(
new StaticCallNode(call_pos, redirect_ctor, arguments));
}
@@ -2451,14 +2426,6 @@
Class& cls = Class::Handle(library_.LookupClass(members->class_name()));
cls.set_is_const();
}
- if (method->has_abstract && members->is_interface()) {
- ErrorMsg(method->name_pos,
- "'abstract' method only allowed in class definition");
- }
- if (method->has_external && members->is_interface()) {
- ErrorMsg(method->name_pos,
- "'external' method only allowed in class definition");
- }
// Parse the formal parameters.
const bool are_implicitly_final = method->has_const;
@@ -2488,16 +2455,6 @@
}
if (!method->IsGetter()) {
ParseFormalParameterList(allow_explicit_default_values, &method->params);
- } else {
- // TODO(hausner): Remove this once the old getter syntax with
- // empty parameter list is no longer supported.
- if (CurrentToken() == Token::kLPAREN) {
- if (FLAG_warn_legacy_getters) {
- Warning("legacy getter syntax, remove parenthesis");
- }
- ConsumeToken();
- ExpectToken(Token::kRPAREN);
- }
}
// Now that we know the parameter list, we can distinguish between the
@@ -2619,9 +2576,6 @@
ErrorMsg(method->name_pos,
"const constructor or factory '%s' may not have a function body",
method->name->ToCString());
- } else if (members->is_interface()) {
- ErrorMsg(method->name_pos,
- "function body not allowed in interface declaration");
}
if (method->redirect_name != NULL) {
ErrorMsg(method->name_pos,
@@ -2640,9 +2594,6 @@
ErrorMsg(method->name_pos,
"abstract method '%s' may not have a function body",
method->name->ToCString());
- } else if (members->is_interface()) {
- ErrorMsg(method->name_pos,
- "function body not allowed in interface declaration");
} else if (method->IsFactoryOrConstructor() && method->has_const) {
ErrorMsg(method->name_pos,
"const constructor or factory '%s' may not be native",
@@ -2656,7 +2607,6 @@
} else {
// We haven't found a method body. Issue error if one is required.
const bool must_have_body =
- !members->is_interface() &&
method->has_static &&
!method->has_external &&
redirection_type.IsNull();
@@ -2668,8 +2618,7 @@
if (CurrentToken() == Token::kSEMICOLON) {
ConsumeToken();
- if (!members->is_interface() &&
- !method->has_static &&
+ if (!method->has_static &&
!method->has_external &&
!method->IsConstructor()) {
// Methods, getters and setters without a body are
@@ -2680,7 +2629,6 @@
// Signature is not followed by semicolon or body. Issue an
// appropriate error.
const bool must_have_semicolon =
- members->is_interface() ||
(method->redirect_name != NULL) ||
(method->IsConstructor() && method->has_const) ||
method->has_external;
@@ -2977,37 +2925,26 @@
// Optionally parse a (possibly named) constructor name or factory.
if (IsIdentifier() &&
(CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) {
+ member.name_pos = TokenPos();
+ member.name = CurrentLiteral(); // Unqualified identifier.
+ ConsumeToken();
if (member.has_factory) {
- // TODO(regis): Simplify this code once the core library is fixed.
- // See issue 6641.
- // Per specification, the name of the factory must be the name of the
- // immediately enclosing class.
-
- // The factory name may be qualified.
- QualIdent factory_name;
- ParseQualIdent(&factory_name);
- member.name_pos = factory_name.ident_pos;
- member.name = factory_name.ident; // Unqualified identifier.
- // The class of the factory result type is specified by the factory name.
- LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
- if (factory_name.lib_prefix != NULL) {
- lib_prefix = factory_name.lib_prefix->raw();
+ // The factory name may be qualified, but the first identifier must match
+ // the name of the immediately enclosing class.
+ if (!member.name->Equals(members->class_name())) {
+ ErrorMsg(member.name_pos, "factory name must be '%s'",
+ members->class_name().ToCString());
}
const Object& result_type_class = Object::Handle(
- UnresolvedClass::New(lib_prefix,
- *factory_name.ident,
- factory_name.ident_pos));
+ UnresolvedClass::New(LibraryPrefix::Handle(),
+ *member.name,
+ member.name_pos));
// The type arguments of the result type are set during finalization.
member.type = &Type::ZoneHandle(Type::New(result_type_class,
TypeArguments::Handle(),
- factory_name.ident_pos));
- } else {
- if (member.has_static) {
- ErrorMsg("constructor cannot be static");
- }
- member.name_pos = TokenPos();
- member.name = CurrentLiteral();
- ConsumeToken();
+ member.name_pos));
+ } else if (member.has_static) {
+ ErrorMsg(member.name_pos, "constructor cannot be static");
}
// We must be dealing with a constructor or named constructor.
member.kind = RawFunction::kConstructor;
@@ -3092,13 +3029,6 @@
ASSERT(member.name != NULL);
if (CurrentToken() == Token::kLPAREN || member.IsGetter()) {
- if (members->is_interface() && member.has_static) {
- if (member.has_factory) {
- ErrorMsg("factory constructors are not allowed in interfaces");
- } else {
- ErrorMsg("static methods are not allowed in interfaces");
- }
- }
// Constructor or method.
if (member.type == NULL) {
member.type = &Type::ZoneHandle(Type::DynamicType());
@@ -3121,9 +3051,6 @@
" in field declaration");
}
}
- if (members->is_interface() && member.has_static && !member.has_final) {
- ErrorMsg("static non-final fields are not allowed in interfaces");
- }
ParseFieldDefinition(members, &member);
} else {
UnexpectedToken();
@@ -3168,13 +3095,7 @@
class_name.ToCString());
}
cls ^= obj.raw();
- if (cls.is_interface()) {
- ErrorMsg(classname_pos, "'%s' %s",
- class_name.ToCString(),
- is_patch ?
- "interface cannot be patched" :
- "is already defined as interface");
- } else if (is_patch) {
+ if (is_patch) {
String& patch = String::Handle(Symbols::New("patch "));
patch = String::Concat(patch, class_name);
patch = Symbols::New(patch);
@@ -3208,12 +3129,6 @@
String::Handle(type.UserVisibleName()).ToCString());
}
super_type ^= type.raw();
- if (super_type.IsInterfaceType()) {
- ErrorMsg(type_pos,
- "class '%s' may implement, but cannot extend interface '%s'",
- class_name.ToCString(),
- String::Handle(super_type.UserVisibleName()).ToCString());
- }
} else {
// No extends clause: Implicitly extend Object.
super_type = Type::ObjectType();
@@ -3370,13 +3285,14 @@
TRACE_PARSER("ParseFunctionTypeAlias");
ExpectToken(Token::kTYPEDEF);
- // Allocate an interface to hold the type parameters and their bounds.
+ // Allocate an abstract class to hold the type parameters and their bounds.
// Make it the owner of the function type descriptor.
const Class& alias_owner = Class::Handle(
Class::New(String::Handle(Symbols::New(":alias_owner")),
Script::Handle(),
TokenPos()));
- alias_owner.set_is_interface();
+
+ alias_owner.set_is_abstract();
alias_owner.set_library(library_);
set_current_class(alias_owner);
@@ -3476,119 +3392,6 @@
}
-void Parser::ParseInterfaceDefinition(
- const GrowableObjectArray& pending_classes) {
- TRACE_PARSER("ParseInterfaceDefinition");
- const intptr_t interface_pos = TokenPos();
- ExpectToken(Token::kINTERFACE);
- const intptr_t interfacename_pos = TokenPos();
- String& interface_name =
- *ExpectUserDefinedTypeIdentifier("interface name expected");
- if (FLAG_trace_parser) {
- OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString());
- }
- Class& interface = Class::Handle();
- Object& obj = Object::Handle(library_.LookupLocalObject(interface_name));
- if (obj.IsNull()) {
- interface = Class::NewInterface(interface_name, script_, interfacename_pos);
- library_.AddClass(interface);
- } else {
- if (!obj.IsClass()) {
- ErrorMsg(interfacename_pos, "'%s' is already defined",
- interface_name.ToCString());
- }
- interface ^= obj.raw();
- if (!interface.is_interface()) {
- ErrorMsg(interfacename_pos,
- "'%s' is already defined as class",
- interface_name.ToCString());
- } else if (interface.functions() != Object::empty_array()) {
- ErrorMsg(interfacename_pos,
- "interface '%s' is already defined",
- interface_name.ToCString());
- }
- }
- ASSERT(!interface.IsNull());
- ASSERT(interface.functions() == Object::empty_array());
- set_current_class(interface);
- ParseTypeParameters(interface);
-
- if (CurrentToken() == Token::kEXTENDS) {
- Array& interfaces = Array::Handle();
- const intptr_t interfaces_pos = TokenPos();
- interfaces = ParseInterfaceList();
- AddInterfaces(interfaces_pos, interface, interfaces);
- }
-
- if (CurrentToken() == Token::kDEFAULT) {
- ConsumeToken();
- if (CurrentToken() != Token::kIDENT) {
- ErrorMsg("class name expected");
- }
- QualIdent factory_name;
- ParseQualIdent(&factory_name);
- LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
- if (factory_name.lib_prefix != NULL) {
- lib_prefix = factory_name.lib_prefix->raw();
- }
- const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle(
- UnresolvedClass::New(lib_prefix,
- *factory_name.ident,
- factory_name.ident_pos));
- const Class& factory_class = Class::Handle(
- Class::New(String::Handle(Symbols::New(":factory_signature")),
- script_,
- factory_name.ident_pos));
- factory_class.set_library(library_);
- factory_class.set_is_finalized();
- ParseTypeParameters(factory_class);
- unresolved_factory_class.set_factory_signature_class(factory_class);
- interface.set_factory_class(unresolved_factory_class);
- // If a type parameter list is included in the default factory clause (it
- // can be omitted), verify that it matches the list of type parameters of
- // the interface in number and names, but not necessarily in bounds.
- if (factory_class.NumTypeParameters() > 0) {
- const bool check_type_parameter_bounds = false;
- if (!AbstractTypeArguments::AreIdentical(
- AbstractTypeArguments::Handle(interface.type_parameters()),
- AbstractTypeArguments::Handle(factory_class.type_parameters()),
- check_type_parameter_bounds)) {
- const String& interface_name = String::Handle(interface.Name());
- ErrorMsg(factory_name.ident_pos,
- "mismatch in number or names of type parameters between "
- "interface '%s' and default factory class '%s'.\n",
- interface_name.ToCString(),
- factory_name.ident->ToCString());
- }
- }
- }
-
- ExpectToken(Token::kLBRACE);
- ClassDesc members(interface, interface_name, true, interface_pos);
- while (CurrentToken() != Token::kRBRACE) {
- ParseClassMemberDefinition(&members);
- }
- ExpectToken(Token::kRBRACE);
-
- if (members.has_constructor() && !interface.HasFactoryClass()) {
- ErrorMsg(interfacename_pos,
- "interface '%s' with constructor must declare a factory class",
- interface_name.ToCString());
- }
-
- Array& array = Array::Handle();
- array = Array::MakeArray(members.fields());
- interface.SetFields(array);
-
- // Creating a new array for functions marks the interface as parsed.
- array = Array::MakeArray(members.functions());
- interface.SetFunctions(array);
- ASSERT(interface.is_interface());
-
- pending_classes.Add(interface, Heap::kOld);
-}
-
-
// Consumes exactly one right angle bracket. If the current token is a single
// bracket token, it is consumed normally. However, if it is a double or triple
// bracket, it is replaced by a single or double bracket token without
@@ -3840,17 +3643,10 @@
AbstractType& interface = AbstractType::ZoneHandle();
interface ^= interfaces.At(i);
if (interface.IsTypeParameter()) {
- if (cls.is_interface()) {
- ErrorMsg(interfaces_pos,
- "interface '%s' may not extend type parameter '%s'",
- String::Handle(cls.Name()).ToCString(),
- String::Handle(interface.UserVisibleName()).ToCString());
- } else {
- ErrorMsg(interfaces_pos,
- "class '%s' may not implement type parameter '%s'",
- String::Handle(cls.Name()).ToCString(),
- String::Handle(interface.UserVisibleName()).ToCString());
- }
+ ErrorMsg(interfaces_pos,
+ "class '%s' may not implement type parameter '%s'",
+ String::Handle(cls.Name()).ToCString(),
+ String::Handle(interface.UserVisibleName()).ToCString());
}
AddInterfaceIfUnique(interfaces_pos, all_interfaces, interface);
}
@@ -4065,12 +3861,8 @@
const intptr_t accessor_pos = TokenPos();
ParamList params;
- if (FLAG_warn_legacy_getters &&
- is_getter && (CurrentToken() == Token::kLPAREN)) {
- Warning("legacy getter syntax, remove parenthesis");
- }
- // TODO(hausner): Remove the kLPAREN check once we remove old getter syntax.
- if (!is_getter || (CurrentToken() == Token::kLPAREN)) {
+
+ if (!is_getter) {
const bool allow_explicit_default_values = true;
ParseFormalParameterList(allow_explicit_default_values, ¶ms);
}
@@ -4534,8 +4326,6 @@
} else if ((CurrentToken() == Token::kTYPEDEF) &&
(LookaheadToken(1) != Token::kLPAREN)) {
ParseFunctionTypeAlias(pending_classes);
- } else if (CurrentToken() == Token::kINTERFACE) {
- ParseInterfaceDefinition(pending_classes);
} else if ((CurrentToken() == Token::kABSTRACT) &&
(LookaheadToken(1) == Token::kCLASS)) {
ParseClassDefinition(pending_classes);
@@ -5944,7 +5734,6 @@
arguments->names(),
Resolver::kIsQualified));
ASSERT(!func.IsNull());
- CheckFunctionIsCallable(arguments->token_pos(), func);
return new StaticCallNode(arguments->token_pos(), func, arguments);
}
@@ -6723,9 +6512,7 @@
ErrorMsg("%s", msg);
}
String* ident = CurrentLiteral();
- // TODO(hausner): Remove check for 'Dynamic' once support for upper-case
- // type dynamic is gone.
- if (ident->Equals("Dynamic") || ident->Equals("dynamic")) {
+ if (ident->Equals("dynamic")) {
ErrorMsg("%s", msg);
}
ConsumeToken();
@@ -7384,7 +7171,6 @@
// Could not resolve static method: throw a NoSuchMethodError.
return ThrowNoSuchMethodError(ident_pos, func_name);
}
- CheckFunctionIsCallable(call_pos, func);
return new StaticCallNode(call_pos, func, arguments);
}
@@ -8603,16 +8389,6 @@
SkipQualIdent();
} else {
ParseQualIdent(&type_name);
- // TODO(hausner): Remove this once support for legacy type 'Dynamic'
- // is removed.
- if ((type_name.lib_prefix == NULL) && type_name.ident->Equals("Dynamic")) {
- if (FLAG_warn_legacy_dynamic) {
- Warning(type_name.ident_pos,
- "legacy type 'Dynamic' found; auto-converting to 'dynamic'");
- }
- // Replace with lower-case 'dynamic'.
- *type_name.ident ^= Symbols::Dynamic();
- }
// An identifier cannot be resolved in a local scope when top level parsing.
if (!is_top_level_ &&
(type_name.lib_prefix == NULL) &&
@@ -9017,7 +8793,7 @@
}
} else {
// Factory call at runtime.
- String& factory_class_name = String::Handle(Symbols::MapImplementation());
+ String& factory_class_name = String::Handle(Symbols::Map());
const Class& factory_class =
Class::Handle(LookupCoreClass(factory_class_name));
ASSERT(!factory_class.IsNull());
@@ -9162,101 +8938,25 @@
AbstractTypeArguments& type_arguments =
AbstractTypeArguments::ZoneHandle(type.arguments());
- // The constructor class and its name are those of the parsed type, unless the
- // parsed type is an interface and a default factory class is specified, in
- // which case constructor_class and constructor_class_name are modified below.
- Class& constructor_class = Class::ZoneHandle(type_class.raw());
- String& constructor_class_name = String::Handle(type_class_name.raw());
-
// A constructor has an implicit 'this' parameter (instance to construct)
// and a factory has an implicit 'this' parameter (type_arguments).
// A constructor has a second implicit 'phase' parameter.
intptr_t arguments_length = arguments->length() + 2;
- if (type_class.is_interface()) {
- // We need to make sure that an appropriate constructor is
- // declared in the interface.
- const String& constructor_name =
- BuildConstructorName(type_class_name, named_constructor);
- const String& external_constructor_name =
- (named_constructor ? constructor_name : type_class_name);
- Function& constructor = Function::ZoneHandle(
- type_class.LookupConstructor(constructor_name));
- if (constructor.IsNull()) {
- // Replace the type with a malformed type and compile a throw or report
- // a compile-time error if the constructor is const.
- type = ClassFinalizer::NewFinalizedMalformedType(
- Error::Handle(), // No previous error.
- current_class(),
- call_pos,
- ClassFinalizer::kTryResolve, // No compile-time error.
- "interface '%s' has no constructor named '%s'",
- type_class_name.ToCString(),
- external_constructor_name.ToCString());
- if (is_const) {
- const Error& error = Error::Handle(type.malformed_error());
- ErrorMsg(error);
- }
- return ThrowNoSuchMethodError(call_pos, external_constructor_name);
- }
- String& error_message = String::Handle();
- if (!constructor.AreValidArguments(arguments_length,
- arguments->names(),
- &error_message)) {
- if (is_const) {
- ErrorMsg(call_pos,
- "invalid arguments passed to constructor '%s' "
- "for interface '%s': %s",
- external_constructor_name.ToCString(),
- type_class_name.ToCString(),
- error_message.ToCString());
- }
- return ThrowNoSuchMethodError(call_pos, external_constructor_name);
- }
- // TODO(regis): Remove support for obsolete default factory classes.
- if (!type_class.HasFactoryClass()) {
- ErrorMsg(type_pos,
- "cannot allocate interface '%s' without factory class",
- type_class_name.ToCString());
- }
- if (!type_class.HasResolvedFactoryClass()) {
- // This error can occur only with bootstrap classes.
- const UnresolvedClass& unresolved =
- UnresolvedClass::Handle(type_class.UnresolvedFactoryClass());
- const String& missing_class_name = String::Handle(unresolved.ident());
- ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString());
- }
- // Only change the class of the constructor to the factory class if the
- // factory class implements the interface 'type'.
- const Class& factory_class = Class::Handle(type_class.FactoryClass());
- if (factory_class.IsSubtypeOf(TypeArguments::Handle(),
- type_class,
- TypeArguments::Handle(),
- NULL)) {
- // Class finalization verifies that the factory class has identical type
- // parameters as the interface.
- constructor_class_name = factory_class.Name();
- }
- // Always change the result type of the constructor to the factory type.
- constructor_class = factory_class.raw();
- // The finalized type_arguments are still those of the interface type.
- ASSERT(!constructor_class.is_interface());
- }
-
// An additional type check of the result of a redirecting factory may be
// required.
AbstractType& type_bound = AbstractType::ZoneHandle();
// Make sure that an appropriate constructor exists.
const String& constructor_name =
- BuildConstructorName(constructor_class_name, named_constructor);
+ BuildConstructorName(type_class_name, named_constructor);
Function& constructor = Function::ZoneHandle(
- constructor_class.LookupConstructor(constructor_name));
+ type_class.LookupConstructor(constructor_name));
if (constructor.IsNull()) {
- constructor = constructor_class.LookupFactory(constructor_name);
+ constructor = type_class.LookupFactory(constructor_name);
if (constructor.IsNull()) {
const String& external_constructor_name =
- (named_constructor ? constructor_name : constructor_class_name);
+ (named_constructor ? constructor_name : type_class_name);
// Replace the type with a malformed type and compile a throw or report a
// compile-time error if the constructor is const.
type = ClassFinalizer::NewFinalizedMalformedType(
@@ -9265,7 +8965,7 @@
call_pos,
ClassFinalizer::kTryResolve, // No compile-time error.
"class '%s' has no constructor or factory named '%s'",
- String::Handle(constructor_class.Name()).ToCString(),
+ String::Handle(type_class.Name()).ToCString(),
external_constructor_name.ToCString());
if (is_const) {
const Error& error = Error::Handle(type.malformed_error());
@@ -9295,8 +8995,6 @@
type_arguments = type.arguments();
constructor = constructor.RedirectionTarget();
ASSERT(!constructor.IsNull());
- constructor_class = constructor.Owner();
- ASSERT(type_class.raw() == constructor_class.raw());
}
if (constructor.IsFactory()) {
// A factory does not have the implicit 'phase' parameter.
@@ -9307,12 +9005,12 @@
// It is ok to call a factory method of an abstract class, but it is
// a dynamic error to instantiate an abstract class.
ASSERT(!constructor.IsNull());
- if (constructor_class.is_abstract() && !constructor.IsFactory()) {
+ if (type_class.is_abstract() && !constructor.IsFactory()) {
ArgumentListNode* arguments = new ArgumentListNode(type_pos);
arguments->Add(new LiteralNode(
TokenPos(), Integer::ZoneHandle(Integer::New(type_pos))));
arguments->Add(new LiteralNode(
- TokenPos(), String::ZoneHandle(constructor_class_name.raw())));
+ TokenPos(), String::ZoneHandle(type_class_name.raw())));
const String& cls_name =
String::Handle(Symbols::AbstractClassInstantiationError());
const String& func_name = String::Handle(Symbols::ThrowNew());
@@ -9323,60 +9021,18 @@
arguments->names(),
&error_message)) {
const String& external_constructor_name =
- (named_constructor ? constructor_name : constructor_class_name);
+ (named_constructor ? constructor_name : type_class_name);
if (is_const) {
ErrorMsg(call_pos,
"invalid arguments passed to constructor '%s' "
"for class '%s': %s",
external_constructor_name.ToCString(),
- String::Handle(constructor_class.Name()).ToCString(),
+ String::Handle(type_class.Name()).ToCString(),
error_message.ToCString());
}
return ThrowNoSuchMethodError(call_pos, external_constructor_name);
}
- // Now that the constructor to be called is identified, finalize the type
- // argument vector to be passed.
- // The type argument vector of the parsed type was finalized in ParseType.
- // If the constructor class was changed from the interface class to the
- // factory class, we need to finalize the type argument vector again, because
- // it may be longer due to the factory class extending a class, or/and because
- // the bounds on the factory class may be tighter than on the interface.
- if (!constructor.IsNull() && (constructor_class.raw() != type_class.raw())) {
- const intptr_t num_type_parameters = constructor_class.NumTypeParameters();
- TypeArguments& temp_type_arguments = TypeArguments::Handle();
- if (!type_arguments.IsNull()) {
- // Copy the parsed type arguments starting at offset 0, because interfaces
- // have no super types.
- ASSERT(type_class.NumTypeArguments() == type_class.NumTypeParameters());
- const intptr_t num_type_arguments = type_arguments.Length();
- temp_type_arguments = TypeArguments::New(num_type_parameters, Heap::kNew);
- AbstractType& type_argument = AbstractType::Handle();
- for (intptr_t i = 0; i < num_type_parameters; i++) {
- if (i < num_type_arguments) {
- type_argument = type_arguments.TypeAt(i);
- } else {
- type_argument = Type::DynamicType();
- }
- temp_type_arguments.SetTypeAt(i, type_argument);
- }
- }
- Type& temp_type = Type::Handle(Type::New(
- constructor_class, temp_type_arguments, type.token_pos(), Heap::kNew));
- // No need to canonicalize temporary type.
- temp_type ^= ClassFinalizer::FinalizeType(
- current_class(), temp_type, ClassFinalizer::kFinalize);
- // The type argument vector may have been expanded with the type arguments
- // of the super type when finalizing the temporary type.
- type_arguments = temp_type.arguments();
- // The type parameter bounds of the factory class may be more specific than
- // the type parameter bounds of the interface class. Therefore, although
- // type was not malformed, temp_type may be malformed.
- if (!type.IsMalformed() && temp_type.IsMalformed()) {
- const Error& error = Error::Handle(temp_type.malformed_error());
- type.set_malformed_error(error);
- }
- }
// Return a throw in case of a malformed type or report a compile-time error
// if the constructor is const.
if (type.IsMalformed()) {
@@ -9395,7 +9051,7 @@
String::Handle(constructor.name()).ToCString());
}
const Object& constructor_result = Object::Handle(
- EvaluateConstConstructorCall(constructor_class,
+ EvaluateConstConstructorCall(type_class,
type_arguments,
constructor,
arguments));
@@ -9424,7 +9080,6 @@
}
}
} else {
- CheckFunctionIsCallable(new_pos, constructor);
CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
if (!type_arguments.IsNull() &&
!type_arguments.IsInstantiated() &&
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index e3c082d..5af3352 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -118,7 +118,7 @@
Parser(const Script& script, const Function& function, intptr_t token_pos);
// Parse the top level of a whole script file and register declared classes
- // and interfaces in the given library.
+ // in the given library.
static void ParseCompilationUnit(const Library& library,
const Script& script);
@@ -183,7 +183,7 @@
// current_function(), but is greater than zero while parsing the body of
// local functions nested in current_function().
- // The class or interface being parsed.
+ // The class being parsed.
const Class& current_class() const;
void set_current_class(const Class& value);
@@ -293,7 +293,6 @@
// Support for parsing of scripts.
void ParseTopLevel();
void ParseClassDefinition(const GrowableObjectArray& pending_classes);
- void ParseInterfaceDefinition(const GrowableObjectArray& pending_classes);
void ParseFunctionTypeAlias(const GrowableObjectArray& pending_classes);
void ParseTopLevelVariable(TopLevel* top_level);
void ParseTopLevelFunction(TopLevel* top_level);
@@ -352,7 +351,6 @@
LocalVariable* receiver,
GrowableArray<Field*>* initialized_fields);
String& ParseNativeDeclaration();
- // TODO(srdjan): Return TypeArguments instead of Array?
RawArray* ParseInterfaceList();
void AddInterfaceIfUnique(intptr_t interfaces_pos,
const GrowableObjectArray& interface_list,
@@ -576,7 +574,6 @@
AstNode* ThrowTypeError(intptr_t type_pos, const AbstractType& type);
AstNode* ThrowNoSuchMethodError(intptr_t call_pos, const String& name);
- void CheckFunctionIsCallable(intptr_t token_pos, const Function& function);
void CheckOperatorArity(const MemberDesc& member);
const LocalVariable* GetIncrementTempLocal();
@@ -597,7 +594,8 @@
Block* current_block_;
// is_top_level_ is true if parsing the "top level" of a compilation unit,
- // that is interface and class definitions.
+ // that is class definitions, function type aliases, global functions,
+ // global variables.
bool is_top_level_;
// The member currently being parsed during "top level" parsing.
@@ -614,7 +612,7 @@
// The function currently being parsed.
Function& innermost_function_;
- // The class or interface currently being parsed, or the owner class of the
+ // The class currently being parsed, or the owner class of the
// function currently being parsed. It is used for primary identifier lookups.
Class& current_class_;
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 7e37ea4..021a82f 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -48,7 +48,8 @@
ASSERT(IsHeapObject());
RawClass* raw_class = isolate->class_table()->At(GetClassId());
- intptr_t instance_size = raw_class->ptr()->instance_size_;
+ intptr_t instance_size =
+ raw_class->ptr()->instance_size_in_words_ << kWordSizeLog2;
intptr_t class_id = raw_class->ptr()->id_;
if (instance_size == 0) {
@@ -598,7 +599,7 @@
if (instance_size == 0) {
RawClass* cls =
visitor->isolate()->class_table()->At(raw_obj->GetClassId());
- instance_size = cls->ptr()->instance_size_;
+ instance_size = cls->ptr()->instance_size_in_words_ << kWordSizeLog2;
}
// Calculate the first and last raw object pointer fields.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index a99dde7..672720a 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -423,7 +423,6 @@
RawLibrary* library_;
RawTypeArguments* type_parameters_; // Array of TypeParameter.
RawType* super_type_;
- RawObject* factory_class_; // UnresolvedClass (until finalization) or Class.
RawFunction* signature_function_; // Associated function for signature class.
RawArray* constants_; // Canonicalized values of this class.
RawArray* canonical_types_; // Canonicalized types of this class.
@@ -433,13 +432,13 @@
}
cpp_vtable handle_vtable_;
- intptr_t instance_size_; // Size if fixed length or 0 if variable length.
+ intptr_t instance_size_in_words_; // Size if fixed len or 0 if variable len.
intptr_t id_; // Class Id, also index in the class table.
- intptr_t type_arguments_instance_field_offset_; // May be kNoTypeArguments.
- intptr_t next_field_offset_; // Offset of the next instance field.
+ intptr_t type_arguments_field_offset_in_words_; // Offset of type args fld.
+ intptr_t next_field_offset_in_words_; // Offset of the next instance field.
intptr_t num_native_fields_; // Number of native fields in class.
intptr_t token_pos_;
- uint8_t state_bits_; // state, is_const, is_interface.
+ uint8_t state_bits_; // state, is_const, is_implemented.
friend class Instance;
friend class Object;
@@ -457,9 +456,8 @@
}
RawLibraryPrefix* library_prefix_; // Library prefix qualifier for the ident.
RawString* ident_; // Name of the unresolved identifier.
- RawClass* factory_signature_class_; // Expected type parameters for factory.
RawObject** to() {
- return reinterpret_cast<RawObject**>(&ptr()->factory_signature_class_);
+ return reinterpret_cast<RawObject**>(&ptr()->ident_);
}
intptr_t token_pos_;
};
@@ -604,7 +602,7 @@
RawString* name_;
RawClass* owner_;
RawAbstractType* type_;
- RawInstance* value_; // Offset for instance and value for static fields.
+ RawInstance* value_; // Offset in words for instance and value for static.
RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->value_); }
intptr_t token_pos_;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index f6540c1..cd0e7be 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -57,9 +57,9 @@
cls.set_tags(tags);
// Set all non object fields.
- cls.set_instance_size(reader->ReadIntptrValue());
- cls.set_type_arguments_instance_field_offset(reader->ReadIntptrValue());
- cls.set_next_field_offset(reader->ReadIntptrValue());
+ cls.set_instance_size_in_words(reader->ReadIntptrValue());
+ cls.set_type_arguments_field_offset_in_words(reader->ReadIntptrValue());
+ cls.set_next_field_offset_in_words(reader->ReadIntptrValue());
cls.set_num_native_fields(reader->ReadIntptrValue());
cls.set_token_pos(reader->ReadIntptrValue());
cls.set_state_bits(reader->Read<uint8_t>());
@@ -96,9 +96,9 @@
// Write out all the non object pointer fields.
// NOTE: cpp_vtable_ is not written.
writer->WriteIntptrValue(ptr()->id_);
- writer->WriteIntptrValue(ptr()->instance_size_);
- writer->WriteIntptrValue(ptr()->type_arguments_instance_field_offset_);
- writer->WriteIntptrValue(ptr()->next_field_offset_);
+ writer->WriteIntptrValue(ptr()->instance_size_in_words_);
+ writer->WriteIntptrValue(ptr()->type_arguments_field_offset_in_words_);
+ writer->WriteIntptrValue(ptr()->next_field_offset_in_words_);
writer->WriteIntptrValue(ptr()->num_native_fields_);
writer->WriteIntptrValue(ptr()->token_pos_);
writer->Write<uint8_t>(ptr()->state_bits_);
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index 26920c6..f969fde 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -521,8 +521,8 @@
}
}
if (is_valid &&
- ((*code_point > 0x10FFFF) ||
- ((*code_point & 0xFFFFF800) == 0xD800))) {
+ ((Utf::IsOutOfRange(*code_point) ||
+ (Utf16::IsSurrogate(*code_point))))) {
ErrorMsg("invalid code point");
}
}
diff --git a/runtime/vm/scanner_test.cc b/runtime/vm/scanner_test.cc
index e647dd3..1e04b8d 100644
--- a/runtime/vm/scanner_test.cc
+++ b/runtime/vm/scanner_test.cc
@@ -338,7 +338,7 @@
"// This source is not meant to be valid Dart code. The text is used to"
"// test the Dart scanner."
""
- "// Cartesian point implemetation."
+ "// Cartesian point implementation."
"class Point {"
""
" // Constructor"
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 044d34b..f4f94c6 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -131,7 +131,7 @@
RawSmi* BaseReader::ReadAsSmi() {
intptr_t value = ReadIntptrValue();
- ASSERT((value & kSmiTagMask) == 0);
+ ASSERT((value & kSmiTagMask) == kSmiTag);
return reinterpret_cast<RawSmi*>(value);
}
@@ -179,7 +179,7 @@
ASSERT(kind_ != Snapshot::kFull);
// Read the class header information and lookup the class.
intptr_t class_header = ReadIntptrValue();
- ASSERT((class_header & kSmiTagMask) != 0);
+ ASSERT((class_header & kSmiTagMask) != kSmiTag);
Class& cls = Class::ZoneHandle(isolate(), Class::null());
cls = LookupInternalClass(class_header);
AddBackRef(object_id, &cls, kIsDeserialized);
@@ -198,8 +198,8 @@
RawObject* SnapshotReader::ReadObjectImpl() {
int64_t value = Read<int64_t>();
- if ((value & kSmiTagMask) == 0) {
- return Integer::New((value >> kSmiTagShift), HEAP_SPACE(kind_));
+ if ((value & kSmiTagMask) == kSmiTag) {
+ return NewInteger(value);
}
return ReadObjectImpl(value);
}
@@ -221,8 +221,8 @@
RawObject* SnapshotReader::ReadObjectRef() {
int64_t header_value = Read<int64_t>();
- if ((header_value & kSmiTagMask) == 0) {
- return Integer::New((header_value >> kSmiTagShift), HEAP_SPACE(kind_));
+ if ((header_value & kSmiTagMask) == kSmiTag) {
+ return NewInteger(header_value);
}
ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin));
if (IsVMIsolateObject(header_value)) {
@@ -255,7 +255,7 @@
}
return result.raw();
}
- ASSERT((class_header & kSmiTagMask) != 0);
+ ASSERT((class_header & kSmiTagMask) != kSmiTag);
cls_ = LookupInternalClass(class_header);
ASSERT(!cls_.IsNull());
@@ -574,6 +574,19 @@
}
+RawObject* SnapshotReader::NewInteger(int64_t value) {
+ ASSERT((value & kSmiTagMask) == kSmiTag);
+ value = value >> kSmiTagShift;
+ if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
+ return Smi::New(value);
+ }
+ if (kind_ == Snapshot::kFull) {
+ return NewMint(value);
+ }
+ return Mint::NewCanonical(value);
+}
+
+
RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) {
// If the header is an object Id, lookup singleton VM classes or classes
// stored in the object store.
@@ -704,7 +717,7 @@
}
return result->raw();
}
- ASSERT((class_header & kSmiTagMask) != 0);
+ ASSERT((class_header & kSmiTagMask) != kSmiTag);
cls_ = LookupInternalClass(class_header);
ASSERT(!cls_.IsNull());
switch (cls_.id()) {
@@ -1020,6 +1033,19 @@
return true;
}
+ // Check if the object is a Mint and could potentially be a Smi
+ // on other architectures (64 bit), if so write it out as int64_t value.
+ if (rawobj->GetClassId() == kMintCid) {
+ int64_t value = reinterpret_cast<RawMint*>(rawobj)->ptr()->value_;
+ const intptr_t kSmi64Bits = 62;
+ const int64_t kSmi64Max = (static_cast<int64_t>(1) << kSmi64Bits) - 1;
+ const int64_t kSmi64Min = -(static_cast<int64_t>(1) << kSmi64Bits);
+ if (value <= kSmi64Max && value >= kSmi64Min) {
+ Write<int64_t>((value << kSmiTagShift) | kSmiTag);
+ return true;
+ }
+ }
+
// Check if it is a code object in that case just write a Null object
// as we do not want code objects in the snapshot.
if (rawobj->GetClassId() == kCodeCid) {
@@ -1089,7 +1115,8 @@
Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle());
}
// Object is regular dart instance.
- intptr_t instance_size = cls->ptr()->instance_size_;
+ intptr_t instance_size =
+ cls->ptr()->instance_size_in_words_ << kWordSizeLog2;
ASSERT(instance_size != 0);
// Write out the serialization header value for this object.
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 378a7bd..98015d5 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -263,6 +263,7 @@
RawGrowableObjectArray* NewGrowableObjectArray();
RawApiError* NewApiError();
RawLanguageError* NewLanguageError();
+ RawObject* NewInteger(int64_t value);
private:
class BackRefNode : public ZoneAllocated {
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index beaca40..bdadf78 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -375,7 +375,7 @@
MessageWriter writer(&buffer, &zone_allocator);
const char* cstr = "0x270FFFFFFFFFFFFFD8F0";
const String& str = String::Handle(String::New(cstr));
- const Bigint& bigint = Bigint::Handle(Bigint::New(str));
+ const Bigint& bigint = Bigint::Handle(Bigint::NewCanonical(str));
writer.WriteMessage(bigint);
intptr_t buffer_len = writer.BytesWritten();
@@ -1260,6 +1260,44 @@
}
+static void CheckString(Dart_Handle string, const char* expected) {
+ StackZone zone(Isolate::Current());
+ uint8_t* buffer;
+ MessageWriter writer(&buffer, &zone_allocator);
+ String& str = String::Handle();
+ str ^= Api::UnwrapHandle(string);
+ writer.WriteMessage(str);
+ intptr_t buffer_len = writer.BytesWritten();
+
+ // Read object back from the snapshot into a C structure.
+ ApiNativeScope scope;
+ ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
+ Dart_CObject* root = api_reader.ReadMessage();
+ EXPECT_NOTNULL(root);
+ EXPECT_EQ(Dart_CObject::kString, root->type);
+ EXPECT_STREQ(expected, root->value.as_string);
+ CheckEncodeDecodeMessage(root);
+}
+
+
+static void CheckStringInvalid(Dart_Handle string) {
+ StackZone zone(Isolate::Current());
+ uint8_t* buffer;
+ MessageWriter writer(&buffer, &zone_allocator);
+ String& str = String::Handle();
+ str ^= Api::UnwrapHandle(string);
+ writer.WriteMessage(str);
+ intptr_t buffer_len = writer.BytesWritten();
+
+ // Read object back from the snapshot into a C structure.
+ ApiNativeScope scope;
+ ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
+ Dart_CObject* root = api_reader.ReadMessage();
+ EXPECT_NOTNULL(root);
+ EXPECT_EQ(Dart_CObject::kUnsupported, root->type);
+}
+
+
UNIT_TEST_CASE(DartGeneratedMessages) {
static const char* kCustomIsolateScriptChars =
"getSmi() {\n"
@@ -1274,6 +1312,21 @@
"getNonAsciiString() {\n"
" return \"Blåbærgrød\";\n"
"}\n"
+ "getNonBMPString() {\n"
+ " return \"\\u{10000}\\u{1F601}\\u{1F637}\\u{20000}\";\n"
+ "}\n"
+ "getLeadSurrogateString() {\n"
+ " return new String.fromCharCodes([0xd800]);\n"
+ "}\n"
+ "getTrailSurrogateString() {\n"
+ " return \"\\u{10000}\".substring(1);\n"
+ "}\n"
+ "getSurrogatesString() {\n"
+ " return new String.fromCharCodes([0xdc00, 0xdc00, 0xd800, 0xd800]);\n"
+ "}\n"
+ "getCrappyString() {\n"
+ " return new String.fromCharCodes([0xd800, 32, 0xdc00, 32]);\n"
+ "}\n"
"getList() {\n"
" return new List(kArrayLength);\n"
"}\n";
@@ -1292,16 +1345,48 @@
Dart_Handle bigint_result;
bigint_result = Dart_Invoke(lib, NewString("getBigint"), 0, NULL);
EXPECT_VALID(bigint_result);
+
Dart_Handle ascii_string_result;
ascii_string_result = Dart_Invoke(lib, NewString("getAsciiString"), 0, NULL);
EXPECT_VALID(ascii_string_result);
EXPECT(Dart_IsString(ascii_string_result));
+
Dart_Handle non_ascii_string_result;
non_ascii_string_result =
Dart_Invoke(lib, NewString("getNonAsciiString"), 0, NULL);
EXPECT_VALID(non_ascii_string_result);
EXPECT(Dart_IsString(non_ascii_string_result));
+ Dart_Handle non_bmp_string_result;
+ non_bmp_string_result =
+ Dart_Invoke(lib, NewString("getNonBMPString"), 0, NULL);
+ EXPECT_VALID(non_bmp_string_result);
+ EXPECT(Dart_IsString(non_bmp_string_result));
+
+ Dart_Handle lead_surrogate_string_result;
+ lead_surrogate_string_result =
+ Dart_Invoke(lib, NewString("getLeadSurrogateString"), 0, NULL);
+ EXPECT_VALID(lead_surrogate_string_result);
+ EXPECT(Dart_IsString(lead_surrogate_string_result));
+
+ Dart_Handle trail_surrogate_string_result;
+ trail_surrogate_string_result =
+ Dart_Invoke(lib, NewString("getTrailSurrogateString"), 0, NULL);
+ EXPECT_VALID(trail_surrogate_string_result);
+ EXPECT(Dart_IsString(trail_surrogate_string_result));
+
+ Dart_Handle surrogates_string_result;
+ surrogates_string_result =
+ Dart_Invoke(lib, NewString("getSurrogatesString"), 0, NULL);
+ EXPECT_VALID(surrogates_string_result);
+ EXPECT(Dart_IsString(surrogates_string_result));
+
+ Dart_Handle crappy_string_result;
+ crappy_string_result =
+ Dart_Invoke(lib, NewString("getCrappyString"), 0, NULL);
+ EXPECT_VALID(crappy_string_result);
+ EXPECT(Dart_IsString(crappy_string_result));
+
{
DARTSCOPE_NOCHECKS(isolate);
@@ -1342,42 +1427,17 @@
root->value.as_bigint);
CheckEncodeDecodeMessage(root);
}
- {
- StackZone zone(Isolate::Current());
- uint8_t* buffer;
- MessageWriter writer(&buffer, &zone_allocator);
- String& str = String::Handle();
- str ^= Api::UnwrapHandle(ascii_string_result);
- writer.WriteMessage(str);
- intptr_t buffer_len = writer.BytesWritten();
-
- // Read object back from the snapshot into a C structure.
- ApiNativeScope scope;
- ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
- Dart_CObject* root = api_reader.ReadMessage();
- EXPECT_NOTNULL(root);
- EXPECT_EQ(Dart_CObject::kString, root->type);
- EXPECT_STREQ("Hello, world!", root->value.as_string);
- CheckEncodeDecodeMessage(root);
- }
- {
- StackZone zone(Isolate::Current());
- uint8_t* buffer;
- MessageWriter writer(&buffer, &zone_allocator);
- String& str = String::Handle();
- str ^= Api::UnwrapHandle(non_ascii_string_result);
- writer.WriteMessage(str);
- intptr_t buffer_len = writer.BytesWritten();
-
- // Read object back from the snapshot into a C structure.
- ApiNativeScope scope;
- ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
- Dart_CObject* root = api_reader.ReadMessage();
- EXPECT_NOTNULL(root);
- EXPECT_EQ(Dart_CObject::kString, root->type);
- EXPECT_STREQ("Blåbærgrød", root->value.as_string);
- CheckEncodeDecodeMessage(root);
- }
+ CheckString(ascii_string_result, "Hello, world!");
+ CheckString(non_ascii_string_result, "Blåbærgrød");
+ CheckString(non_bmp_string_result,
+ "\xf0\x90\x80\x80"
+ "\xf0\x9f\x98\x81"
+ "\xf0\x9f\x98\xb7"
+ "\xf0\xa0\x80\x80");
+ CheckStringInvalid(lead_surrogate_string_result);
+ CheckStringInvalid(trail_surrogate_string_result);
+ CheckStringInvalid(crappy_string_result);
+ CheckStringInvalid(surrogates_string_result);
}
Dart_ExitScope();
Dart_ShutdownIsolate();
@@ -2073,7 +2133,6 @@
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
Dart_EnterScope();
- // xxx
Dart_Handle send_port = Dart_Invoke(lib, NewString("main"), 0, NULL);
EXPECT_VALID(send_port);
Dart_Handle result = Dart_GetField(send_port, NewString("_id"));
@@ -2109,12 +2168,6 @@
object.value.as_string = const_cast<char*>("æøå");
EXPECT(Dart_PostCObject(send_port_id, &object));
- // Try to post an invalid UTF-8 sequence (lead surrogate).
- const char* data = "\xED\xA0\x80"; // U+D800
- object.type = Dart_CObject::kString;
- object.value.as_string = const_cast<char*>(data);
- EXPECT(!Dart_PostCObject(send_port_id, &object));
-
object.type = Dart_CObject::kDouble;
object.value.as_double = 3.14;
EXPECT(Dart_PostCObject(send_port_id, &object));
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 637d1e3..140eb70 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1114,7 +1114,7 @@
Immediate(reinterpret_cast<intptr_t>(Object::null()));
// The generated code is different if the class is parameterized.
const bool is_cls_parameterized =
- cls.type_arguments_instance_field_offset() != Class::kNoTypeArguments;
+ cls.type_arguments_field_offset() != Class::kNoTypeArguments;
// kInlineInstanceSize is a constant used as a threshold for determining
// when the object initialization should be done as a loop or as
// straight line code.
@@ -1239,7 +1239,7 @@
if (is_cls_parameterized) {
// EDI: new object type arguments.
// Set the type arguments in the new object.
- __ movl(Address(EAX, cls.type_arguments_instance_field_offset()), EDI);
+ __ movl(Address(EAX, cls.type_arguments_field_offset()), EDI);
}
// Done allocating and initializing the instance.
// EAX: new object.
@@ -1881,10 +1881,10 @@
Label has_no_type_arguments;
__ movl(EBX, raw_null);
__ movl(EDI, FieldAddress(ECX,
- Class::type_arguments_instance_field_offset_offset()));
+ Class::type_arguments_field_offset_in_words_offset()));
__ cmpl(EDI, Immediate(Class::kNoTypeArguments));
__ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
- __ movl(EBX, FieldAddress(EAX, EDI, TIMES_1, 0));
+ __ movl(EBX, FieldAddress(EAX, EDI, TIMES_4, 0));
__ Bind(&has_no_type_arguments);
}
__ LoadClassId(ECX, EAX);
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index d7efa3a..5cdfeda 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1094,7 +1094,7 @@
Immediate(reinterpret_cast<intptr_t>(Object::null()));
// The generated code is different if the class is parameterized.
const bool is_cls_parameterized =
- cls.type_arguments_instance_field_offset() != Class::kNoTypeArguments;
+ cls.type_arguments_field_offset() != Class::kNoTypeArguments;
// kInlineInstanceSize is a constant used as a threshold for determining
// when the object initialization should be done as a loop or as
// straight line code.
@@ -1222,7 +1222,7 @@
if (is_cls_parameterized) {
// RDI: new object type arguments.
// Set the type arguments in the new object.
- __ movq(Address(RAX, cls.type_arguments_instance_field_offset()), RDI);
+ __ movq(Address(RAX, cls.type_arguments_field_offset()), RDI);
}
// Done allocating and initializing the instance.
// RAX: new object.
@@ -1845,10 +1845,10 @@
Label has_no_type_arguments;
__ movq(R13, raw_null);
__ movq(RDI, FieldAddress(R10,
- Class::type_arguments_instance_field_offset_offset()));
+ Class::type_arguments_field_offset_in_words_offset()));
__ cmpq(RDI, Immediate(Class::kNoTypeArguments));
__ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
- __ movq(R13, FieldAddress(RAX, RDI, TIMES_1, 0));
+ __ movq(R13, FieldAddress(RAX, RDI, TIMES_8, 0));
__ Bind(&has_no_type_arguments);
}
__ LoadClassId(R10, RAX);
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 0e6cc21..754009b 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -45,7 +45,7 @@
V(List, "List") \
V(ListLiteralFactory, "List._fromLiteral") \
V(ListFactory, "List.") \
- V(MapImplementation, "_HashMapImpl") \
+ V(Map, "Map") \
V(MapLiteralFactory, "Map._fromLiteral") \
V(ImmutableMap, "ImmutableMap") \
V(ImmutableMapConstructor, "ImmutableMap._create") \
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index f1199ff..ee57ca9 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -167,7 +167,6 @@
KW(kIMPLEMENTS, "implements", 0, kPseudoKeyword) \
KW(kIMPORT, "import", 0, kPseudoKeyword) \
KW(kIN, "in", 0, kKeyword) \
- KW(kINTERFACE, "interface", 0, kPseudoKeyword) \
KW(kIS, "is", 10, kKeyword) \
KW(kLIBRARY, "library", 0, kPseudoKeyword) \
KW(kNEW, "new", 0, kKeyword) \
diff --git a/runtime/vm/unicode.cc b/runtime/vm/unicode.cc
index 3129a06..0b15976 100644
--- a/runtime/vm/unicode.cc
+++ b/runtime/vm/unicode.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -10,7 +10,7 @@
namespace dart {
-static const int8_t kTrailBytes[256] = {
+const int8_t Utf8::kTrailBytes[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -30,8 +30,8 @@
};
-static const uint32_t kMagicBits[7] = {
- 0, // padding
+const uint32_t Utf8::kMagicBits[7] = {
+ 0, // Padding.
0x00000000,
0x00003080,
0x000E2080,
@@ -42,8 +42,8 @@
// Minimum values of code points used to check shortest form.
-static const uint32_t kOverlongMinimum[7] = {
- 0, // padding
+const uint32_t Utf8::kOverlongMinimum[7] = {
+ 0, // Padding.
0x0,
0x80,
0x800,
@@ -53,35 +53,6 @@
};
-static bool IsTrailByte(uint8_t code_unit) {
- return (code_unit & 0xc0) == 0x80;
-}
-
-
-static bool IsLatin1SequenceStart(uint8_t code_unit) {
- // Check is codepoint is <= U+00FF
- return (code_unit <= Utf8::kMaxOneByteChar);
-}
-
-
-static bool IsSupplementarySequenceStart(uint8_t code_unit) {
- // Check is codepoint is >= U+10000.
- return (code_unit >= 0xF0);
-}
-
-
-// Returns true if the code point value is above Plane 17.
-static bool IsOutOfRange(uint32_t code_point) {
- return (code_point > 0x10FFFF);
-}
-
-
-// Returns true if the byte sequence is ill-formed.
-static bool IsNonShortestForm(uint32_t code_point, size_t num_bytes) {
- return code_point < kOverlongMinimum[num_bytes];
-}
-
-
// Returns a count of the number of UTF-8 trail bytes.
intptr_t Utf8::CodePointCount(const uint8_t* utf8_array,
intptr_t array_len,
@@ -128,7 +99,7 @@
ch -= kMagicBits[num_trail_bytes];
if (!((is_malformed == false) &&
(j == num_trail_bytes) &&
- !IsOutOfRange(ch) &&
+ !Utf::IsOutOfRange(ch) &&
!IsNonShortestForm(ch, j) &&
!Utf16::IsSurrogate(ch))) {
return false;
@@ -165,6 +136,7 @@
intptr_t Utf8::Encode(int32_t ch, char* dst) {
+ ASSERT(!Utf16::IsSurrogate(ch));
static const int kMask = ~(1 << 6);
if (ch <= kMaxOneByteChar) {
dst[0] = ch;
@@ -227,7 +199,7 @@
ch -= kMagicBits[num_trail_bytes];
if (!((is_malformed == false) &&
(i == num_trail_bytes) &&
- !IsOutOfRange(ch) &&
+ !Utf::IsOutOfRange(ch) &&
!IsNonShortestForm(ch, i) &&
!Utf16::IsSurrogate(ch))) {
*dst = -1;
@@ -251,15 +223,15 @@
ASSERT(IsLatin1SequenceStart(utf8_array[i]));
num_bytes = Utf8::Decode(&utf8_array[i], (array_len - i), &ch);
if (ch == -1) {
- return false; // invalid input
+ return false; // Invalid input.
}
- ASSERT(ch <= 0xff);
+ ASSERT(Utf::IsLatin1(ch));
dst[j] = ch;
}
if ((i < array_len) && (j == len)) {
- return false; // output overflow
+ return false; // Output overflow.
}
- return true; // success
+ return true; // Success.
}
@@ -275,7 +247,7 @@
bool is_supplementary = IsSupplementarySequenceStart(utf8_array[i]);
num_bytes = Utf8::Decode(&utf8_array[i], (array_len - i), &ch);
if (ch == -1) {
- return false; // invalid input
+ return false; // Invalid input.
}
if (is_supplementary) {
Utf16::Encode(ch, &dst[j]);
@@ -285,9 +257,9 @@
}
}
if ((i < array_len) && (j == len)) {
- return false; // output overflow
+ return false; // Output overflow.
}
- return true; // success
+ return true; // Success.
}
@@ -302,19 +274,27 @@
int32_t ch;
num_bytes = Utf8::Decode(&utf8_array[i], (array_len - i), &ch);
if (ch == -1) {
- return false; // invalid input
+ return false; // Invalid input.
}
dst[j] = ch;
}
if ((i < array_len) && (j == len)) {
- return false; // output overflow
+ return false; // Output overflow.
}
- return true; // success
+ return true; // Success.
+}
+
+
+bool Utf8::DecodeCStringToUTF32(const char* str, int32_t* dst, intptr_t len) {
+ ASSERT(str != NULL);
+ intptr_t array_len = strlen(str);
+ const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str);
+ return Utf8::DecodeToUTF32(utf8_array, array_len, dst, len);
}
void Utf16::Encode(int32_t codepoint, uint16_t* dst) {
- ASSERT(codepoint > kMaxBmpCodepoint);
+ ASSERT(codepoint > Utf16::kMaxCodeUnit);
ASSERT(dst != NULL);
dst[0] = (Utf16::kLeadSurrogateOffset + (codepoint >> 10));
dst[1] = (0xDC00 + (codepoint & 0x3FF));
diff --git a/runtime/vm/unicode.h b/runtime/vm/unicode.h
index 03a4b29..9d4fc38 100644
--- a/runtime/vm/unicode.h
+++ b/runtime/vm/unicode.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -12,6 +12,29 @@
class String;
+class Utf : AllStatic {
+ public:
+ static const int32_t kMaxCodePoint = 0x10FFFF;
+
+ static bool IsLatin1(int32_t code_point) {
+ return (code_point >= 0) && (code_point <= 0xFF);
+ }
+
+ static bool IsBmp(int32_t code_point) {
+ return (code_point >= 0) && (code_point <= 0xFFFF);
+ }
+
+ static bool IsSupplementary(int32_t code_point) {
+ return (code_point > 0xFFFF) && (code_point <= kMaxCodePoint);
+ }
+
+ // Returns true if the code point value is above Plane 17.
+ static bool IsOutOfRange(int32_t code_point) {
+ return (code_point < 0) || (code_point > kMaxCodePoint);
+ }
+};
+
+
class Utf8 : AllStatic {
public:
enum Type {
@@ -20,11 +43,6 @@
kSupplementary, // Supplementary code point [U+010000, U+10FFFF].
};
- static const intptr_t kMaxOneByteChar = 0x7F;
- static const intptr_t kMaxTwoByteChar = 0x7FF;
- static const intptr_t kMaxThreeByteChar = 0xFFFF;
- static const intptr_t kMaxFourByteChar = 0x10FFFF;
-
static intptr_t CodePointCount(const uint8_t* utf8_array,
intptr_t array_len,
Type* type);
@@ -56,26 +74,43 @@
intptr_t len);
static bool DecodeCStringToUTF32(const char* str,
int32_t* dst,
- intptr_t len) {
- ASSERT(str != NULL);
- intptr_t array_len = strlen(str);
- const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str);
- return DecodeToUTF32(utf8_array, array_len, dst, len);
+ intptr_t len);
+
+ private:
+ static const int32_t kMaxOneByteChar = 0x7F;
+ static const int32_t kMaxTwoByteChar = 0x7FF;
+ static const int32_t kMaxThreeByteChar = 0xFFFF;
+ static const int32_t kMaxFourByteChar = Utf::kMaxCodePoint;
+
+ static bool IsTrailByte(uint8_t code_unit) {
+ return (code_unit & 0xc0) == 0x80;
}
+
+ static bool IsNonShortestForm(uint32_t code_point, size_t num_code_units) {
+ return code_point < kOverlongMinimum[num_code_units];
+ }
+
+ static bool IsLatin1SequenceStart(uint8_t code_unit) {
+ // Check is codepoint is <= U+00FF
+ return (code_unit <= Utf8::kMaxOneByteChar);
+ }
+
+ static bool IsSupplementarySequenceStart(uint8_t code_unit) {
+ // Check is codepoint is >= U+10000.
+ return (code_unit >= 0xF0);
+ }
+
+ static const int8_t kTrailBytes[];
+ static const uint32_t kMagicBits[];
+ static const uint32_t kOverlongMinimum[];
};
class Utf16 : AllStatic {
public:
- static const int32_t kMaxBmpCodepoint = 0xFFFF;
-
- static const int32_t kLeadSurrogateOffset = (0xD800 - (0x10000 >> 10));
-
- static const int32_t kSurrogateOffset = (0x10000 - (0xD800 << 10) - 0xDC00);
-
// Returns the length of the code point in UTF-16 code units.
static intptr_t Length(int32_t ch) {
- return (ch <= kMaxBmpCodepoint) ? 1 : 2;
+ return (ch <= Utf16::kMaxCodeUnit) ? 1 : 2;
}
// Returns true if ch is a lead or trail surrogate.
@@ -93,6 +128,21 @@
return (ch & 0xFFFFFC00) == 0xDC00;
}
+ // Returns the character at i and advances i to the next character
+ // boundary.
+ static int32_t Next(const uint16_t* characters, intptr_t* i, intptr_t len) {
+ int32_t ch = characters[*i];
+ if (Utf16::IsLeadSurrogate(ch) && (*i < (len - 1))) {
+ int32_t ch2 = characters[*i + 1];
+ if (Utf16::IsTrailSurrogate(ch2)) {
+ ch = Utf16::Decode(ch, ch2);
+ *i += 1;
+ }
+ }
+ *i += 1;
+ return ch;
+ }
+
// Decodes a surrogate pair into a supplementary code point.
static int32_t Decode(int32_t lead, int32_t trail) {
return 0x10000 + ((lead & 0x3FF) << 10) + (trail & 0x3FF);
@@ -100,6 +150,13 @@
// Encodes a single code point.
static void Encode(int32_t codepoint, uint16_t* dst);
+
+ private:
+ static const int32_t kMaxCodeUnit = 0xFFFF;
+
+ static const int32_t kLeadSurrogateOffset = (0xD800 - (0x10000 >> 10));
+
+ static const int32_t kSurrogateOffset = (0x10000 - (0xD800 << 10) - 0xDC00);
};
@@ -138,7 +195,7 @@
static const int kBlockSize = 1 << kBlockSizeLog2;
static int32_t Convert(int32_t ch, int32_t mapping) {
- if (ch <= 0xFF) {
+ if (Utf::IsLatin1(ch)) {
int32_t info = stage2_[ch];
if ((info & kTypeMask) == mapping) {
ch += info >> kTypeShift;
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 7104aa5..530f7f0 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -31,7 +31,7 @@
],
'sources/': [
# Exclude all _test.[cc|h] files.
- ['exclude', '_test\\.cc|h$'],
+ ['exclude', '_test\\.(cc|h)$'],
],
'include_dirs': [
'..',
@@ -57,7 +57,26 @@
'sources/' : [
['exclude', 'gdbjit.cc'],
],
- }]],
+ }],
+ ['dart_vtune_support==0', {
+ 'sources/' : [
+ ['exclude', 'vtune\\.(cc|h)$'],
+ ],
+ }],
+ ['dart_vtune_support==1', {
+ 'include_dirs': ['<(dart_vtune_root)/include'],
+ 'defines': ['DART_VTUNE_SUPPORT'],
+ 'link_settings': {
+ 'conditions': [
+ ['OS=="linux"', {
+ 'libraries': ['-ljitprofiling'],
+ }],
+ ['OS=="win"', {
+ 'libraries': ['-ljitprofiling.lib'],
+ }],
+ ],
+ },
+ }]],
},
{
'target_name': 'libdart_lib_withcore',
@@ -121,7 +140,9 @@
{
'target_name': 'generate_corelib_cc_file',
'type': 'none',
- 'includes': [
+ 'variables': {
+ 'core_dart': '<(SHARED_INTERMEDIATE_DIR)/core_gen.dart',
+ },'includes': [
# Load the shared core library sources.
'../../sdk/lib/core/corelib_sources.gypi',
],
@@ -134,11 +155,27 @@
],
'actions': [
{
+ 'action_name': 'generate_core_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(core_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(core_dart)',
+ ],
+ 'message': 'Generating ''<(core_dart)'' file.',
+ },
+ {
'action_name': 'generate_corelib_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(core_dart)',
],
'outputs': [
'<(corelib_cc_file)',
@@ -150,7 +187,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'vm/bootstrap.h',
'--var_name', 'dart::Bootstrap::corelib_source_',
- '<@(_sources)',
+ '<(core_dart)',
],
'message': 'Generating ''<(corelib_cc_file)'' file.'
},
@@ -197,6 +234,9 @@
{
'target_name': 'generate_collection_cc_file',
'type': 'none',
+ 'variables': {
+ 'collection_dart': '<(SHARED_INTERMEDIATE_DIR)/collection_gen.dart',
+ },
'includes': [
# Load the shared collection library sources.
'../../sdk/lib/collection/collection_sources.gypi',
@@ -210,11 +250,27 @@
],
'actions': [
{
+ 'action_name': 'generate_collection_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(collection_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(collection_dart)',
+ ],
+ 'message': 'Generating ''<(collection_dart)'' file.',
+ },
+ {
'action_name': 'generate_collection_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(collection_dart)',
],
'outputs': [
'<(collection_cc_file)',
@@ -226,7 +282,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'vm/bootstrap.h',
'--var_name', 'dart::Bootstrap::collection_source_',
- '<@(_sources)',
+ '<(collection_dart)',
],
'message': 'Generating ''<(collection_cc_file)'' file.'
},
@@ -235,6 +291,9 @@
{
'target_name': 'generate_math_cc_file',
'type': 'none',
+ 'variables': {
+ 'math_dart': '<(SHARED_INTERMEDIATE_DIR)/math_gen.dart',
+ },
'includes': [
# Load the shared math library sources.
'../../sdk/lib/math/math_sources.gypi',
@@ -248,11 +307,27 @@
],
'actions': [
{
+ 'action_name': 'generate_math_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(math_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(math_dart)',
+ ],
+ 'message': 'Generating ''<(math_dart)'' file.',
+ },
+ {
'action_name': 'generate_math_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(math_dart)',
],
'outputs': [
'<(math_cc_file)',
@@ -264,7 +339,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'vm/bootstrap.h',
'--var_name', 'dart::Bootstrap::math_source_',
- '<@(_sources)',
+ '<(math_dart)',
],
'message': 'Generating ''<(math_cc_file)'' file.'
},
@@ -311,6 +386,9 @@
{
'target_name': 'generate_mirrors_cc_file',
'type': 'none',
+ 'variables': {
+ 'mirrors_dart': '<(SHARED_INTERMEDIATE_DIR)/mirrors_gen.dart',
+ },
'includes': [
# Load the shared core library sources.
'../../sdk/lib/mirrors/mirrors_sources.gypi',
@@ -324,11 +402,27 @@
],
'actions': [
{
+ 'action_name': 'generate_mirrors_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(mirrors_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(mirrors_dart)',
+ ],
+ 'message': 'Generating ''<(mirrors_dart)'' file.',
+ },
+ {
'action_name': 'generate_mirrors_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(mirrors_dart)',
],
'outputs': [
'<(mirrors_cc_file)',
@@ -340,7 +434,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'vm/bootstrap.h',
'--var_name', 'dart::Bootstrap::mirrors_source_',
- '<@(_sources)',
+ '<(mirrors_dart)',
],
'message': 'Generating ''<(mirrors_cc_file)'' file.'
},
@@ -387,6 +481,9 @@
{
'target_name': 'generate_isolate_cc_file',
'type': 'none',
+ 'variables': {
+ 'isolate_dart': '<(SHARED_INTERMEDIATE_DIR)/isolate_gen.dart',
+ },
'includes': [
# Load the runtime implementation sources.
'../../sdk/lib/isolate/isolate_sources.gypi',
@@ -400,11 +497,27 @@
],
'actions': [
{
+ 'action_name': 'generate_isolate_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(isolate_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(isolate_dart)',
+ ],
+ 'message': 'Generating ''<(isolate_dart)'' file.',
+ },
+ {
'action_name': 'generate_isolate_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(isolate_dart)',
],
'outputs': [
'<(isolate_cc_file)',
@@ -416,7 +529,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'vm/bootstrap.h',
'--var_name', 'dart::Bootstrap::isolate_source_',
- '<@(_sources)',
+ '<(isolate_dart)',
],
'message': 'Generating ''<(isolate_cc_file)'' file.'
},
@@ -463,6 +576,9 @@
{
'target_name': 'generate_scalarlist_cc_file',
'type': 'none',
+ 'variables': {
+ 'scalarlist_dart': '<(SHARED_INTERMEDIATE_DIR)/scalarlist_gen.dart',
+ },
'includes': [
# Load the shared library sources.
'../../sdk/lib/scalarlist/scalarlist_sources.gypi',
@@ -476,11 +592,27 @@
],
'actions': [
{
+ 'action_name': 'generate_scalarlist_dart',
+ 'inputs': [
+ '../tools/concat_library.py',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(scalarlist_dart)',
+ ],
+ 'action': [
+ 'python',
+ '<@(_inputs)',
+ '--output', '<(scalarlist_dart)',
+ ],
+ 'message': 'Generating ''<(scalarlist_dart)'' file.',
+ },
+ {
'action_name': 'generate_scalarlist_cc',
'inputs': [
'../tools/create_string_literal.py',
'<(builtin_in_cc_file)',
- '<@(_sources)',
+ '<(scalarlist_dart)',
],
'outputs': [
'<(scalarlist_cc_file)',
@@ -492,7 +624,7 @@
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'vm/bootstrap.h',
'--var_name', 'dart::Bootstrap::scalarlist_source_',
- '<@(_sources)',
+ '<(scalarlist_dart)',
],
'message': 'Generating ''<(scalarlist_cc_file)'' file.'
},
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 2b2f9d4..0b18707 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -64,6 +64,8 @@
'code_generator.cc',
'code_generator.h',
'code_generator_test.cc',
+ 'code_observers.cc',
+ 'code_observers.h',
'code_patcher.h',
'code_patcher_arm.cc',
'code_patcher_ia32.cc',
@@ -302,6 +304,8 @@
'verifier.cc',
'verifier.h',
'visitor.h',
+ 'vtune.cc',
+ 'vtune.h',
'zone.cc',
'zone.h',
'zone_test.cc',
diff --git a/runtime/vm/vtune.cc b/runtime/vm/vtune.cc
new file mode 100644
index 0000000..57e065a
--- /dev/null
+++ b/runtime/vm/vtune.cc
@@ -0,0 +1,33 @@
+// 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 "vm/vtune.h"
+
+#include <jitprofiling.h>
+
+#include "platform/assert.h"
+
+namespace dart {
+
+bool VTuneCodeObserver::IsActive() const {
+ return (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON);
+}
+
+
+void VTuneCodeObserver::Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized) {
+ ASSERT(IsActive());
+ iJIT_Method_Load jmethod;
+ memset(&jmethod, 0, sizeof(jmethod));
+ jmethod.method_id = iJIT_GetNewMethodID();
+ jmethod.method_name = const_cast<char*>(name);
+ jmethod.method_load_address = reinterpret_cast<void*>(base);
+ jmethod.method_size = size;
+ iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &jmethod);
+}
+
+} // namespace dart
diff --git a/runtime/vm/vtune.h b/runtime/vm/vtune.h
new file mode 100644
index 0000000..4f62aff
--- /dev/null
+++ b/runtime/vm/vtune.h
@@ -0,0 +1,28 @@
+// 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 VM_VTUNE_H_
+#define VM_VTUNE_H_
+
+#include "vm/code_observers.h"
+
+namespace dart {
+
+#if defined(DART_VTUNE_SUPPORT)
+class VTuneCodeObserver : public CodeObserver {
+ public:
+ virtual bool IsActive() const;
+
+ virtual void Notify(const char* name,
+ uword base,
+ uword prologue_offset,
+ uword size,
+ bool optimized);
+};
+#endif
+
+
+} // namespace dart
+
+#endif // VM_VTUNE_H_
diff --git a/sdk/bin/dart b/sdk/bin/dart
index 6bb8e1c..22abed8 100755
--- a/sdk/bin/dart
+++ b/sdk/bin/dart
@@ -12,7 +12,7 @@
DART_CONFIGURATION="ReleaseIA32"
fi
-if [[ `uname` -eq 'Darwin' ]];
+if [[ `uname` == 'Darwin' ]];
then
BIN_DIR="$CUR_DIR"/../../xcodebuild/$DART_CONFIGURATION
else
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index dfa5228..3f74135 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -3,24 +3,63 @@
# 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.
-# Setting BIN_DIR this way is ugly, but is needed to handle the case where
-# dart-sdk/bin has been symlinked to. On MacOS, readlink doesn't work
-# with this case.
-BIN_DIR="$(cd "${0%/*}" ; pwd -P)"
+function follow_links() {
+ while [ -h "$1" ]; do
+ # On Mac OS, readlink -f doesn't work.
+ 1="$(readlink "$1")"
+ done
+ echo "$1"
+}
-unset COLORS
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(follow_links "$(cd "${PROG_NAME%/*}" ; pwd -P)")"
+
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+DART2JS="$SDK_DIR/lib/_internal/compiler/implementation/dart2js.dart"
+
+DART="$BIN_DIR/dart"
+
+SNAPSHOT="${DART2JS}.snapshot"
+
+unset EXTRA_OPTIONS
+declare -a EXTRA_OPTIONS
+
if test -t 1; then
# Stdout is a terminal.
if test 8 -le `tput colors`; then
# Stdout has at least 8 colors, so enable colors.
- COLORS="--enable-diagnostic-colors"
+ EXTRA_OPTIONS[${#EXTRA_OPTIONS[@]}]='--enable-diagnostic-colors'
fi
fi
-unset SNAPSHOT
-if test -f "$BIN_DIR/../lib/_internal/compiler/implementation/dart2js.dart.snapshot"; then
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+if test -f "$SNAPSHOT"; then
# TODO(ahe): Remove the following line when we are relatively sure it works.
- echo Using snapshot "$BIN_DIR/../lib/_internal/compiler/implementation/dart2js.dart.snapshot" 1>&2
- SNAPSHOT="--use_script_snapshot=$BIN_DIR/../lib/_internal/compiler/implementation/dart2js.dart.snapshot"
+ echo Using snapshot "$SNAPSHOT" 1>&2
+ EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]="--use_script_snapshot=$SNAPSHOT"
fi
-exec "$BIN_DIR"/dart --no_use_inlining --heap_growth_rate=32 $SNAPSHOT "$BIN_DIR/../lib/_internal/compiler/implementation/dart2js.dart" $COLORS "$@"
+
+# Tell the VM to grow the heap more aggressively. This should only
+# be necessary temporarily until the VM is better at detecting how
+# applications use memory.
+# TODO(ahe): Remove this option (http://dartbug.com/6495).
+EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--heap_growth_rate=512'
+
+# Tell the VM to don't bother inlining methods. So far inlining isn't
+# paying off but the VM team is working on fixing that.
+# TODO(ahe): Remove this option (http://dartbug.com/6495).
+EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--no_use_inlining'
+
+case $0 in
+ *_developer)
+ EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--checked'
+ ;;
+esac
+
+exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@"
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 86ede92..687c504 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -12,4 +12,4 @@
set SNAPSHOTNAME=%SCRIPTPATH%dart2js.snapshot
if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
-"%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=32 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
+"%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
diff --git a/sdk/bin/dart2js_developer b/sdk/bin/dart2js_developer
new file mode 100755
index 0000000..948cb4a
--- /dev/null
+++ b/sdk/bin/dart2js_developer
@@ -0,0 +1,6 @@
+#!/bin/bash
+# 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.
+
+. ${BASH_SOURCE%_developer}
diff --git a/sdk/bin/dart2js_developer.bat b/sdk/bin/dart2js_developer.bat
new file mode 100644
index 0000000..1156d9e
--- /dev/null
+++ b/sdk/bin/dart2js_developer.bat
@@ -0,0 +1,15 @@
+@echo off
+REM Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+REM for details. All rights reserved. Use of this source code is governed by a
+REM BSD-style license that can be found in the LICENSE file.
+
+set SCRIPTPATH=%~dp0
+
+REM Does the path have a trailing slash? If so, remove it.
+if %SCRIPTPATH:~-1%== set SCRIPTPATH=%SCRIPTPATH:~0,-1%
+
+set arguments=%*
+set SNAPSHOTNAME=%SCRIPTPATH%dart2js.snapshot
+if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+
+"%SCRIPTPATH%dart" --checked --no_use_inlining --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index e84d45c..608bae78 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -31,7 +31,9 @@
enableUserAssertions: hasOption(options, '--enable-checked-mode'),
enableMinification: hasOption(options, '--minify'),
enableNativeLiveTypeAnalysis:
- hasOption(options, '--enable-native-live-type-analysis'),
+ hasOption(options, '--disable-native-live-type-analysis')
+ ? false
+ : hasOption(options, '--enable-native-live-type-analysis'),
emitJavaScript: !hasOption(options, '--output-type=dart'),
disallowUnsafeEval: hasOption(options, '--disallow-unsafe-eval'),
analyzeAll: hasOption(options, '--analyze-all'),
@@ -100,23 +102,25 @@
}
leg.Script readScript(Uri uri, [tree.Node node]) {
- if (uri.scheme == 'dart') uri = translateDartUri(uri, node);
- var translated = translateUri(uri, node);
- String text = "";
- try {
- // TODO(ahe): We expect the future to be complete and call value
- // directly. In effect, we don't support truly asynchronous API.
- text = provider(translated).value;
- } catch (exception) {
- if (node != null) {
- cancel("$exception", node: node);
- } else {
- reportDiagnostic(null, "$exception", api.Diagnostic.ERROR);
- throw new leg.CompilerCancelledException("$exception");
+ return fileReadingTask.measure(() {
+ if (uri.scheme == 'dart') uri = translateDartUri(uri, node);
+ var translated = translateUri(uri, node);
+ String text = "";
+ try {
+ // TODO(ahe): We expect the future to be complete and call value
+ // directly. In effect, we don't support truly asynchronous API.
+ text = provider(translated).value;
+ } catch (exception) {
+ if (node != null) {
+ cancel("$exception", node: node);
+ } else {
+ reportDiagnostic(null, "$exception", api.Diagnostic.ERROR);
+ throw new leg.CompilerCancelledException("$exception");
+ }
}
- }
- SourceFile sourceFile = new SourceFile(translated.toString(), text);
- return new leg.Script(uri, sourceFile);
+ SourceFile sourceFile = new SourceFile(translated.toString(), text);
+ return new leg.Script(uri, sourceFile);
+ });
}
Uri translateUri(Uri uri, tree.Node node) {
@@ -156,9 +160,14 @@
bool run(Uri uri) {
bool success = super.run(uri);
+ int cumulated = 0;
for (final task in tasks) {
+ cumulated += task.timing;
log('${task.name} took ${task.timing}msec');
}
+ int total = totalCompileTime.elapsedMilliseconds;
+ log('Total compile-time ${total}msec;'
+ ' unaccounted ${total - cumulated}msec');
return success;
}
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 975d4e5..2a6adb8 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -84,10 +84,12 @@
Constant result = initialVariableValues[element];
return result;
}
- TreeElements definitions = compiler.analyzeElement(element);
- Constant constant = compileVariableWithDefinitions(
- element, definitions, isConst: isConst);
- return constant;
+ return compiler.withCurrentElement(element, () {
+ TreeElements definitions = compiler.analyzeElement(element);
+ Constant constant = compileVariableWithDefinitions(
+ element, definitions, isConst: isConst);
+ return constant;
+ });
});
}
@@ -163,7 +165,7 @@
return measure(() {
assert(node != null);
CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
- constantSystem, definitions, compiler, isConst: isConst);
+ this, definitions, compiler, isConst: isConst);
return evaluator.evaluate(node);
});
}
@@ -174,9 +176,7 @@
assert(node != null);
try {
TryCompileTimeConstantEvaluator evaluator =
- new TryCompileTimeConstantEvaluator(constantSystem,
- definitions,
- compiler);
+ new TryCompileTimeConstantEvaluator(this, definitions, compiler);
return evaluator.evaluate(node);
} on CompileTimeConstantError catch (exn) {
return null;
@@ -244,17 +244,19 @@
class CompileTimeConstantEvaluator extends Visitor {
bool isEvaluatingConstant;
- final ConstantSystem constantSystem;
+ final ConstantHandler handler;
final TreeElements elements;
final Compiler compiler;
bool enabledRuntimeTypeSupport = false;
- CompileTimeConstantEvaluator(this.constantSystem,
+ CompileTimeConstantEvaluator(this.handler,
this.elements,
this.compiler,
{bool isConst: false})
: this.isEvaluatingConstant = isConst;
+ ConstantSystem get constantSystem => handler.constantSystem;
+
Constant evaluate(Node node) {
return node.accept(this);
}
@@ -297,7 +299,7 @@
// TODO(floitsch): get type parameters.
DartType type = new InterfaceType(compiler.listClass);
Constant constant = new ListConstant(type, arguments);
- compiler.constantHandler.registerCompileTimeConstant(constant);
+ handler.registerCompileTimeConstant(constant);
return constant;
}
@@ -333,7 +335,7 @@
// TODO(floitsch): this should be a List<String> type.
DartType keysType = new InterfaceType(compiler.listClass);
ListConstant keysList = new ListConstant(keysType, keys);
- compiler.constantHandler.registerCompileTimeConstant(keysList);
+ handler.registerCompileTimeConstant(keysList);
SourceString className = hasProtoKey
? MapConstant.DART_PROTO_CLASS
: MapConstant.DART_CLASS;
@@ -343,7 +345,7 @@
DartType type = new InterfaceType(classElement);
registerInstantiatedClass(classElement);
Constant constant = new MapConstant(type, keysList, values, protoValue);
- compiler.constantHandler.registerCompileTimeConstant(constant);
+ handler.registerCompileTimeConstant(constant);
return constant;
}
@@ -415,7 +417,7 @@
DartType elementType = element.computeType(compiler).asRaw();
DartType constantType = compiler.typeClass.computeType(compiler);
Constant constant = new TypeConstant(elementType, constantType);
- compiler.constantHandler.registerCompileTimeConstant(constant);
+ handler.registerCompileTimeConstant(constant);
return constant;
}
@@ -426,15 +428,15 @@
if (Elements.isStaticOrTopLevelFunction(element)) {
compiler.codegenWorld.staticFunctionsNeedingGetter.add(element);
Constant constant = new FunctionConstant(element);
- compiler.constantHandler.registerCompileTimeConstant(constant);
+ handler.registerCompileTimeConstant(constant);
compiler.enqueuer.codegen.registerStaticUse(element);
return constant;
} else if (Elements.isStaticOrTopLevelField(element)) {
Constant result;
if (element.modifiers.isConst()) {
- result = compiler.compileConstant(element);
+ result = handler.compileConstant(element);
} else if (element.modifiers.isFinal() && !isEvaluatingConstant) {
- result = compiler.compileVariable(element);
+ result = handler.compileVariable(element);
}
if (result != null) return result;
} else if (Elements.isClass(element) || Elements.isTypedef(element)) {
@@ -584,7 +586,7 @@
List<Constant> compiledArguments = <Constant>[];
Function compileArgument = evaluateConstant;
- Function compileConstant = compiler.compileConstant;
+ Function compileConstant = handler.compileConstant;
bool succeeded = selector.addArgumentsToList(arguments,
compiledArguments,
target,
@@ -622,7 +624,7 @@
List<Constant> arguments = evaluateArgumentsToConstructor(
node, selector, send.arguments, constructor);
ConstructorEvaluator evaluator =
- new ConstructorEvaluator(node, constructor, constantSystem, compiler);
+ new ConstructorEvaluator(node, constructor, handler, compiler);
evaluator.evaluateConstructorFieldValues(arguments);
List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
@@ -630,7 +632,7 @@
// TODO(floitsch): take generic types into account.
DartType type = classElement.computeType(compiler);
Constant constant = new ConstructedConstant(type, jsNewArguments);
- compiler.constantHandler.registerCompileTimeConstant(constant);
+ handler.registerCompileTimeConstant(constant);
return constant;
}
@@ -659,10 +661,10 @@
}
class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator {
- TryCompileTimeConstantEvaluator(ConstantSystem constantSystem,
+ TryCompileTimeConstantEvaluator(ConstantHandler handler,
TreeElements elements,
Compiler compiler)
- : super(constantSystem, elements, compiler, isConst: true);
+ : super(handler, elements, compiler, isConst: true);
error(Node node) {
// Just fail without reporting it anywhere.
@@ -683,12 +685,12 @@
*/
ConstructorEvaluator(Node node,
FunctionElement constructor,
- ConstantSystem constantSystem,
+ ConstantHandler handler,
Compiler compiler)
: this.constructor = constructor,
this.definitions = new Map<Element, Constant>(),
this.fieldValues = new Map<Element, Constant>(),
- super(constantSystem,
+ super(handler,
compiler.resolver.resolveMethodElement(constructor.declaration),
compiler,
isConst: true) {
@@ -755,7 +757,7 @@
currentNode, selector, arguments, targetConstructor);
ConstructorEvaluator evaluator = new ConstructorEvaluator(
- currentNode, targetConstructor, constantSystem, compiler);
+ currentNode, targetConstructor, handler, compiler);
evaluator.evaluateConstructorFieldValues(compiledArguments);
// Copy over the fieldValues from the super/redirect-constructor.
// No need to go through [updateFieldValue] because the
@@ -844,7 +846,7 @@
Constant fieldValue = fieldValues[field];
if (fieldValue == null) {
// Use the default value.
- fieldValue = compiler.compileConstant(field);
+ fieldValue = handler.compileConstant(field);
}
jsNewArguments.add(fieldValue);
},
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index e770cff..a791281 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -58,6 +58,11 @@
}
}
+class ReadingFilesTask extends CompilerTask {
+ ReadingFilesTask(Compiler compiler) : super(compiler);
+ String get name => 'Reading input files';
+}
+
abstract class Backend {
final Compiler compiler;
final ConstantSystem constantSystem;
@@ -100,6 +105,7 @@
abstract class Compiler implements DiagnosticListener {
final Map<String, LibraryElement> libraries;
+ final Stopwatch totalCompileTime = new Stopwatch();
int nextFreeClassId = 0;
World world;
String assembledCode;
@@ -189,7 +195,9 @@
ti.TypesTask typesTask;
Backend backend;
ConstantHandler constantHandler;
+ ConstantHandler metadataHandler;
EnqueueTask enqueuer;
+ CompilerTask fileReadingTask;
static const SourceString MAIN = const SourceString('main');
static const SourceString CALL_OPERATOR_NAME = const SourceString('call');
@@ -232,27 +240,31 @@
progress = new Stopwatch() {
progress.start();
world = new World(this);
- scanner = new ScannerTask(this);
- dietParser = new DietParserTask(this);
- parser = new ParserTask(this);
- patchParser = new PatchParserTask(this);
- libraryLoader = new LibraryLoaderTask(this);
- validator = new TreeValidatorTask(this);
- resolver = new ResolverTask(this);
- closureToClassMapper = new closureMapping.ClosureTask(this);
- checker = new TypeCheckerTask(this);
- typesTask = new ti.TypesTask(this, enableConcreteTypeInference);
backend = emitJavaScript ?
new js_backend.JavaScriptBackend(this,
generateSourceMap,
disallowUnsafeEval) :
new dart_backend.DartBackend(this, strips);
- constantHandler = new ConstantHandler(this, backend.constantSystem);
- enqueuer = new EnqueueTask(this);
- tasks = [scanner, dietParser, parser, patchParser, libraryLoader,
- resolver, closureToClassMapper, checker, typesTask,
- constantHandler, enqueuer];
+
+ // No-op in production mode.
+ validator = new TreeValidatorTask(this);
+
+ tasks = [
+ fileReadingTask = new ReadingFilesTask(this),
+ libraryLoader = new LibraryLoaderTask(this),
+ scanner = new ScannerTask(this),
+ dietParser = new DietParserTask(this),
+ parser = new ParserTask(this),
+ patchParser = new PatchParserTask(this),
+ resolver = new ResolverTask(this),
+ closureToClassMapper = new closureMapping.ClosureTask(this),
+ checker = new TypeCheckerTask(this),
+ typesTask = new ti.TypesTask(this, enableConcreteTypeInference),
+ constantHandler = new ConstantHandler(this, backend.constantSystem),
+ enqueuer = new EnqueueTask(this)];
+
tasks.addAll(backend.tasks);
+ metadataHandler = new ConstantHandler(this, backend.constantSystem);
}
Universe get resolverWorld => enqueuer.resolution.universe;
@@ -340,13 +352,16 @@
}
bool run(Uri uri) {
+ totalCompileTime.start();
try {
runCompiler(uri);
} on CompilerCancelledException catch (exception) {
log('Error: $exception');
return false;
+ } finally {
+ tracer.close();
+ totalCompileTime.stop();
}
- tracer.close();
return true;
}
@@ -486,15 +501,21 @@
/** Enable the 'JS' helper for a library if needed. */
void maybeEnableJSHelper(LibraryElement library) {
String libraryName = library.uri.toString();
- if (library.entryCompilationUnit.script.name.contains(
- 'dart/tests/compiler/dart2js_native')
+ bool nativeTest = library.entryCompilationUnit.script.name.contains(
+ 'dart/tests/compiler/dart2js_native');
+ if (nativeTest
|| libraryName == 'dart:mirrors'
|| libraryName == 'dart:isolate'
|| libraryName == 'dart:math'
|| libraryName == 'dart:html'
- || libraryName == 'dart:svg') {
- if (libraryName == 'dart:html' || libraryName == 'dart:mirrors') {
- // dart:html needs access to convertDartClosureToJS.
+ || libraryName == 'dart:svg'
+ || libraryName == 'dart:web_audio') {
+ if (nativeTest
+ || libraryName == 'dart:html'
+ || libraryName == 'dart:svg'
+ || libraryName == 'dart:mirrors') {
+ // dart:html and dart:svg need access to convertDartClosureToJS and
+ // annotation classes.
// dart:mirrors needs access to the Primitives class.
importHelperLibrary(library);
}
@@ -718,27 +739,6 @@
() => resolver.computeFunctionType(element, signature));
}
- bool isLazilyInitialized(VariableElement element) {
- Constant initialValue = compileVariable(element);
- return initialValue == null;
- }
-
- /**
- * Compiles compile-time constants. Never returns [:null:].
- * If the initial value is not a compile-time constants reports an error.
- */
- Constant compileConstant(VariableElement element) {
- return withCurrentElement(element, () {
- return constantHandler.compileConstant(element);
- });
- }
-
- Constant compileVariable(VariableElement element) {
- return withCurrentElement(element, () {
- return constantHandler.compileVariable(element);
- });
- }
-
reportWarning(Node node, var message) {
if (message is TypeWarning) {
// TODO(ahe): Don't supress these warning when the type checker
@@ -863,16 +863,18 @@
int get timing => watch.elapsedMilliseconds;
measure(Function action) {
- // TODO(kasperl): Do we have to worry about exceptions here?
CompilerTask previous = compiler.measuredTask;
+ if (identical(this, previous)) return action();
compiler.measuredTask = this;
if (previous != null) previous.watch.stop();
watch.start();
- var result = action();
- watch.stop();
- if (previous != null) previous.watch.start();
- compiler.measuredTask = previous;
- return result;
+ try {
+ return action();
+ } finally {
+ watch.stop();
+ if (previous != null) previous.watch.start();
+ compiler.measuredTask = previous;
+ }
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index fdc98b9..c4687ba 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -164,6 +164,7 @@
new OptionHandler('--package-root=.+|-p.+', setPackageRoot),
new OptionHandler('--disallow-unsafe-eval', passThrough),
new OptionHandler('--analyze-all', passThrough),
+ new OptionHandler('--disable-native-live-type-analysis', passThrough),
new OptionHandler('--enable-native-live-type-analysis', passThrough),
new OptionHandler('--reject-deprecated-language-features', passThrough),
new OptionHandler('--report-sdk-use-of-deprecated-language-features',
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index c012488..fb1cf88 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -137,7 +137,7 @@
Set<DartType> processedTypes = new Set<DartType>();
List<DartType> workQueue = new List<DartType>();
workQueue.addAll(
- classMembers.keys.map((classElement) => classElement.type));
+ classMembers.keys.map((classElement) => classElement.thisType));
workQueue.addAll(compiler.resolverWorld.isChecks);
Element typeErrorElement =
compiler.coreLibrary.find(new SourceString('TypeError'));
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index 63e14f9..24859f4 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -174,14 +174,14 @@
void collectFunctionDeclarationPlaceholders(
FunctionElement element, FunctionExpression node) {
if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
- DartType type = element.getEnclosingClass().type.asRaw();
+ DartType type = element.getEnclosingClass().thisType.asRaw();
makeConstructorPlaceholder(node.name, element, type);
Return bodyAsReturn = node.body.asReturn();
if (bodyAsReturn != null && bodyAsReturn.isRedirectingFactoryBody) {
// Factory redirection.
FunctionElement redirectTarget = element.defaultImplementation;
assert(redirectTarget != null && redirectTarget != element);
- type = redirectTarget.getEnclosingClass().type.asRaw();
+ type = redirectTarget.getEnclosingClass().thisType.asRaw();
makeConstructorPlaceholder(
bodyAsReturn.expression, redirectTarget, type);
}
@@ -365,8 +365,14 @@
Element constructor = treeElements[send];
assert(constructor != null);
assert(send.receiver == null);
- if (!Elements.isErroneousElement(constructor) &&
- !Elements.isMalformedElement(constructor)) {
+
+ // For constructors that refer to malformed class types retrieve
+ // class type like it is done in [ SsaBuilder.visitNewSend ].
+ if (type.kind == TypeKind.MALFORMED_TYPE) {
+ type = constructor.getEnclosingClass().thisType;
+ }
+
+ if (!Elements.isUnresolved(constructor)) {
makeConstructorPlaceholder(node.send.selector, constructor, type);
// TODO(smok): Should this be in visitNamedArgument?
// Field names can be exposed as names of optional arguments, e.g.
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index f132df6..44daef6 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -88,7 +88,7 @@
// js-helpers.
StringBuffer result = new StringBuffer(renameElement(type.element));
if (type is InterfaceType) {
- if (!type.typeArguments.isEmpty) {
+ if (!type.isRaw) {
result.add('<');
Link<DartType> argumentsLink = type.typeArguments;
result.add(renameType(argumentsLink.head, renameElement));
@@ -285,7 +285,7 @@
}
// Rename constructors.
- placeholderCollector.constructorPlaceholders.forEach(
+ sortedForEach(placeholderCollector.constructorPlaceholders,
(Element constructor, List<ConstructorPlaceholder> placeholders) {
for (ConstructorPlaceholder ph in placeholders) {
renames[ph.node] =
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index df07e95..2289215 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -355,9 +355,11 @@
}
}
- bool _isNative = false;
- void setNative() { _isNative = true; }
- bool isNative() => _isNative;
+ String _nativeName = null;
+ bool isNative() => _nativeName != null;
+ String nativeName() => _nativeName;
+ /// Marks this element as a native element.
+ void setNative(String name) { _nativeName = name; }
FunctionElement asFunctionElement() => null;
@@ -838,6 +840,19 @@
class TypedefElement extends Element implements TypeDeclarationElement {
Typedef cachedNode;
TypedefType cachedType;
+
+ /**
+ * Canonicalize raw version of [cachedType].
+ *
+ * See [ClassElement.rawType] for motivation.
+ *
+ * The [rawType] is computed together with [cachedType] in [computeType].
+ */
+ TypedefType rawType;
+
+ /**
+ * The type annotation which defines this typedef.
+ */
DartType alias;
bool isResolved = false;
@@ -862,6 +877,16 @@
Link<DartType> parameters =
TypeDeclarationElement.createTypeVariables(this, node.typeParameters);
cachedType = new TypedefType(this, parameters);
+ if (parameters.isEmpty) {
+ rawType = cachedType;
+ } else {
+ var dynamicParameters = const Link<DartType>();
+ parameters.forEach((_) {
+ dynamicParameters =
+ dynamicParameters.prepend(compiler.types.dynamicType);
+ });
+ rawType = new TypedefType(this, dynamicParameters);
+ }
compiler.resolveTypedef(this);
return cachedType;
}
@@ -1383,11 +1408,40 @@
abstract class ClassElement extends ScopeContainerElement
implements TypeDeclarationElement {
final int id;
- InterfaceType type;
+ /**
+ * The type of [:this:] for this class declaration.
+ *
+ * The type of [:this:] is the interface type based on this element in which
+ * the type arguments are the declared type variables. For instance,
+ * [:List<E>:] for [:List:] and [:Map<K,V>:] for [:Map:].
+ *
+ * This type is computed in [computeType].
+ */
+ InterfaceType thisType;
+
+ /**
+ * The raw type for this class declaration.
+ *
+ * The raw type is the interface type base on this element in which the type
+ * arguments are all [dynamic]. For instance [:List<dynamic>:] for [:List:]
+ * and [:Map<dynamic,dynamic>:] for [:Map:]. For non-generic classes [rawType]
+ * is the same as [thisType].
+ *
+ * The [rawType] field is a canonicalization of the raw type and should be
+ * used to distinguish explicit and implicit uses of the [dynamic]
+ * type arguments. For instance should [:List:] be the [rawType] of the
+ * [:List:] class element whereas [:List<dynamic>:] should be its own
+ * instantiation of [InterfaceType] with [:dynamic:] as type argument. Using
+ * this distinction, we can print the raw type with type arguments only when
+ * the input source has used explicit type arguments.
+ *
+ * This type is computed together with [thisType] in [computeType].
+ */
+ InterfaceType rawType;
DartType supertype;
DartType defaultClass;
Link<DartType> interfaces;
- SourceString nativeName;
+ SourceString nativeTagInfo;
int supertypeLoadState;
int resolutionState;
@@ -1409,18 +1463,29 @@
ClassNode parseNode(Compiler compiler);
InterfaceType computeType(compiler) {
- if (type == null) {
+ if (thisType == null) {
if (origin == null) {
ClassNode node = parseNode(compiler);
Link<DartType> parameters =
TypeDeclarationElement.createTypeVariables(this,
node.typeParameters);
- type = new InterfaceType(this, parameters);
+ thisType = new InterfaceType(this, parameters);
+ if (parameters.isEmpty) {
+ rawType = thisType;
+ } else {
+ var dynamicParameters = const Link<DartType>();
+ parameters.forEach((_) {
+ dynamicParameters =
+ dynamicParameters.prepend(compiler.types.dynamicType);
+ });
+ rawType = new InterfaceType(this, dynamicParameters);
+ }
} else {
- type = origin.computeType(compiler);
+ thisType = origin.computeType(compiler);
+ rawType = origin.rawType;
}
}
- return type;
+ return thisType;
}
bool get isPatched => patch != null;
@@ -1435,7 +1500,7 @@
bool isObject(Compiler compiler) =>
identical(declaration, compiler.objectClass);
- Link<DartType> get typeVariables => type.typeArguments;
+ Link<DartType> get typeVariables => thisType.typeArguments;
ClassElement ensureResolved(Compiler compiler) {
if (resolutionState == STATE_NOT_STARTED) {
@@ -1724,15 +1789,11 @@
}
bool isInterface() => false;
- bool isNative() => nativeName != null;
+ bool isNative() => nativeTagInfo != null;
int get hashCode => id;
Scope buildScope() => new ClassScope(enclosingElement.buildScope(), this);
- Link<DartType> get allSupertypesAndSelf {
- return allSupertypes.prepend(new InterfaceType(this));
- }
-
String toString() {
if (origin != null) {
return 'patch ${super.toString()}';
@@ -1852,7 +1913,7 @@
} else if (identical(value, '[]')) {
return const SourceString(r'operator$index');
} else if (identical(value, '[]=')) {
- return const SourceString(r'oprator$indexSet');
+ return const SourceString(r'operator$indexSet');
} else if (identical(value, '*')) {
return const SourceString(r'operator$mul');
} else if (identical(value, '/')) {
@@ -1890,7 +1951,8 @@
}
}
- static SourceString constructOperatorName(SourceString op, bool isUnary) {
+ static SourceString constructOperatorNameOrNull(SourceString op,
+ bool isUnary) {
String value = op.stringValue;
if ((identical(value, '==')) ||
(identical(value, '~')) ||
@@ -1915,11 +1977,17 @@
} else if (identical(value, '-')) {
return isUnary ? const SourceString('unary-') : op;
} else {
- throw 'Unhandled operator: ${op.slowToString()}';
+ return null;
}
}
- static SourceString mapToUserOperator(SourceString op) {
+ static SourceString constructOperatorName(SourceString op, bool isUnary) {
+ SourceString operatorName = constructOperatorNameOrNull(op, isUnary);
+ if (operatorName == null) throw 'Unhandled operator: ${op.slowToString()}';
+ else return operatorName;
+ }
+
+ static SourceString mapToUserOperatorOrNull(SourceString op) {
String value = op.stringValue;
if (identical(value, '!=')) return const SourceString('==');
@@ -1935,7 +2003,13 @@
if (identical(value, '^=')) return const SourceString('^');
if (identical(value, '|=')) return const SourceString('|');
- throw 'Unhandled operator: ${op.slowToString()}';
+ return null;
+ }
+
+ static SourceString mapToUserOperator(SourceString op) {
+ SourceString userOperator = mapToUserOperatorOrNull(op);
+ if (userOperator == null) throw 'Unhandled operator: ${op.slowToString()}';
+ else return userOperator;
}
static bool isNumberOrStringSupertype(Element element, Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index f12d760..e066fb5 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -89,10 +89,6 @@
if (isResolutionQueue && getCachedElements(element) != null) return;
compiler.internalErrorOnElement(element, "Work list is closed.");
}
- if (!isResolutionQueue &&
- identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
- registerInstantiatedClass(element.getEnclosingClass());
- }
if (elements == null) {
elements = getCachedElements(element);
}
@@ -139,8 +135,10 @@
void registerInstantiatedClass(ClassElement cls) {
if (universe.instantiatedClasses.contains(cls)) return;
- universe.instantiatedClasses.add(cls);
- onRegisterInstantiatedClass(cls);
+ if (!cls.isAbstract(compiler)) {
+ universe.instantiatedClasses.add(cls);
+ onRegisterInstantiatedClass(cls);
+ }
compiler.backend.registerInstantiatedClass(cls, this);
}
@@ -173,6 +171,7 @@
if (member.isField()) {
// Native fields need to go into instanceMembersByName as they are virtual
// instantiation points and escape points.
+ // Test the enclosing class, since the metadata has not been parsed yet.
if (!member.enclosingElement.isNative()) return;
}
@@ -212,6 +211,7 @@
}
} else if (member.kind == ElementKind.FIELD &&
member.enclosingElement.isNative()) {
+ nativeEnqueuer.registerField(member);
if (universe.hasInvokedGetter(member, compiler) ||
universe.hasInvocation(member, compiler)) {
nativeEnqueuer.registerFieldLoad(member);
@@ -228,10 +228,9 @@
// supertypes.
cls.ensureResolved(compiler);
- for (Link<DartType> supertypes = cls.allSupertypesAndSelf;
- !supertypes.isEmpty; supertypes = supertypes.tail) {
- cls = supertypes.head.element;
- if (seenClasses.contains(cls)) continue;
+ void processClass(ClassElement cls) {
+ if (seenClasses.contains(cls)) return;
+
seenClasses.add(cls);
cls.ensureResolved(compiler);
cls.implementation.forEachMember(processInstantiatedClassMember);
@@ -255,6 +254,11 @@
});
}
}
+ processClass(cls);
+ for (Link<DartType> supertypes = cls.allSupertypes;
+ !supertypes.isEmpty; supertypes = supertypes.tail) {
+ processClass(supertypes.head.element);
+ }
});
}
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index cfc88a5..ec1469c 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -429,6 +429,9 @@
abstract class Expression extends Node {
int get precedenceLevel;
+
+ PropertyAccess dot(String name) => new PropertyAccess.field(this, name);
+ Call callWith(List<Expression> arguments) => new Call(this, arguments);
}
class LiteralExpression extends Expression {
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index 267ccc5..ce2e056 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -12,21 +12,21 @@
bool inForInit = false;
bool atStatementBegin = false;
final DanglingElseVisitor danglingElseVisitor;
- final LocalNamer localNamer;
+ final Namer namer;
bool pendingSemicolon = false;
bool pendingSpace = false;
- static final identifierRegexp = new RegExp(r'^[a-zA-Z_0-9$]');
+ static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]');
Printer(leg.Compiler compiler, { allowVariableMinification: true })
: shouldCompressOutput = compiler.enableMinification,
this.compiler = compiler,
outBuffer = new leg.CodeBuffer(),
danglingElseVisitor = new DanglingElseVisitor(compiler),
- localNamer = determineRenamer(compiler.enableMinification,
- allowVariableMinification);
+ namer = determineRenamer(compiler.enableMinification,
+ allowVariableMinification);
- static LocalNamer determineRenamer(bool shouldCompressOutput,
- bool allowVariableMinification) {
+ static Namer determineRenamer(bool shouldCompressOutput,
+ bool allowVariableMinification) {
return (shouldCompressOutput && allowVariableMinification)
? new MinifyRenamer() : new IdentityNamer();
}
@@ -51,7 +51,7 @@
outBuffer.add(";");
}
if (pendingSpace &&
- (!shouldCompressOutput || identifierRegexp.hasMatch(str))) {
+ (!shouldCompressOutput || identifierCharacterRegExp.hasMatch(str))) {
outBuffer.add(" ");
}
pendingSpace = false;
@@ -391,7 +391,7 @@
visitNestedExpression(name, PRIMARY,
newInForInit: false, newAtStatementBegin: false);
}
- localNamer.enterScope(vars);
+ namer.enterScope(vars);
out("(");
if (fun.params != null) {
visitCommaSeparated(fun.params, PRIMARY,
@@ -399,7 +399,7 @@
}
out(")");
blockBody(fun.body, needsSeparation: false, needsNewline: false);
- localNamer.leaveScope();
+ namer.leaveScope();
}
visitFunctionDeclaration(FunctionDeclaration declaration) {
@@ -639,7 +639,7 @@
}
visitVariableUse(VariableUse ref) {
- out(localNamer.getName(ref.name));
+ out(namer.getName(ref.name));
}
visitThis(This node) {
@@ -647,11 +647,11 @@
}
visitVariableDeclaration(VariableDeclaration decl) {
- out(localNamer.getName(decl.name));
+ out(namer.getName(decl.name));
}
visitParameter(Parameter param) {
- out(localNamer.getName(param.name));
+ out(namer.getName(param.name));
}
bool isDigit(int charCode) {
@@ -944,7 +944,7 @@
}
-abstract class LocalNamer {
+abstract class Namer {
String getName(String oldName);
String declareVariable(String oldName);
String declareParameter(String oldName);
@@ -953,7 +953,7 @@
}
-class IdentityNamer implements LocalNamer {
+class IdentityNamer implements Namer {
String getName(String oldName) => oldName;
String declareVariable(String oldName) => oldName;
String declareParameter(String oldName) => oldName;
@@ -962,7 +962,7 @@
}
-class MinifyRenamer implements LocalNamer {
+class MinifyRenamer implements Namer {
final List<Map<String, String>> maps = [];
final List<int> parameterNumberStack = [];
final List<int> variableNumberStack = [];
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 9aa445d..d73707a 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -101,6 +101,13 @@
HTypeMap types) {
HTypeList result;
int argumentsCount = node.inputs.length - 1;
+ int startInvokeIndex = HInvoke.ARGUMENTS_OFFSET;
+
+ if (node.isInterceptorCall) {
+ argumentsCount--;
+ startInvokeIndex++;
+ }
+
if (selector.namedArgumentCount > 0) {
result =
new HTypeList.withNamedArguments(
@@ -108,8 +115,9 @@
} else {
result = new HTypeList(argumentsCount);
}
+
for (int i = 0; i < result.types.length; i++) {
- result.types[i] = types[node.inputs[i + 1]];
+ result.types[i] = types[node.inputs[i + startInvokeIndex]];
}
return result;
}
@@ -142,38 +150,6 @@
return onlyUnknown ? HTypeList.ALL_UNKNOWN : result;
}
- /**
- * Create the union of this [HTypeList] object with the types used by
- * the [node]. If the union results in exactly the same types the receiver
- * is returned. Otherwise a different [HTypeList] object is returned
- * with the type union information.
- */
- HTypeList unionWithInvoke(HInvoke node, HTypeMap types, Compiler compiler) {
- // Union an all unknown list with something stays all unknown.
- if (allUnknown) return this;
-
- bool allUnknown = true;
- if (length != node.inputs.length - 1) {
- return HTypeList.ALL_UNKNOWN;
- }
-
- bool onlyUnknown = true;
- HTypeList result = this;
- for (int i = 0; i < length; i++) {
- HType newType = this[i].union(types[node.inputs[i + 1]], compiler);
- if (result == this && newType != this[i]) {
- // Create a new argument types object with the matching types copied.
- result = new HTypeList(length);
- result.types.setRange(0, i, this.types);
- }
- if (result != this) {
- result.types[i] = newType;
- }
- if (result[i] != HType.UNKNOWN) onlyUnknown = false;
- }
- return onlyUnknown ? HTypeList.ALL_UNKNOWN : result;
- }
-
HTypeList unionWithOptionalParameters(
Selector selector,
FunctionSignature signature,
@@ -473,18 +449,22 @@
Compiler get compiler => backend.compiler;
+ bool updateTypes(HTypeList oldTypes, HTypeList newTypes, var key, var map) {
+ if (oldTypes.allUnknown) return false;
+ newTypes = oldTypes.union(newTypes, backend.compiler);
+ if (identical(newTypes, oldTypes)) return false;
+ map[key] = newTypes;
+ return true;
+ }
+
void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
Element element = node.element;
assert(invariant(node, element.isDeclaration));
HTypeList oldTypes = staticTypeMap[element];
+ HTypeList newTypes = new HTypeList.fromStaticInvocation(node, types);
if (oldTypes == null) {
- staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types);
- } else {
- if (oldTypes.allUnknown) return;
- HTypeList newTypes =
- oldTypes.unionWithInvoke(node, types, backend.compiler);
- if (identical(newTypes, oldTypes)) return;
staticTypeMap[element] = newTypes;
+ } else if (updateTypes(oldTypes, newTypes, element, staticTypeMap)) {
if (optimizedStaticFunctions.contains(element)) {
backend.scheduleForRecompilation(element);
}
@@ -524,10 +504,7 @@
selectorTypeMap[selector] = providedTypes;
} else {
HTypeList oldTypes = selectorTypeMap[selector];
- HTypeList newTypes =
- oldTypes.unionWithInvoke(node, types, backend.compiler);
- if (identical(newTypes, oldTypes)) return;
- selectorTypeMap[selector] = newTypes;
+ updateTypes(oldTypes, providedTypes, selector, selectorTypeMap);
}
// If we're not compiling, we don't have to do anything.
@@ -657,6 +634,10 @@
ClassElement objectInterceptorClass;
Element jsArrayLength;
Element jsStringLength;
+ Element jsArrayRemoveLast;
+ Element jsArrayAdd;
+ Element jsStringSplit;
+ Element jsStringConcat;
Element getInterceptorMethod;
bool _interceptorsAreInitialized = false;
@@ -694,7 +675,24 @@
* name to the list of members that have that name. This map is used
* by the codegen to know whether a send must be intercepted or not.
*/
- final Map<SourceString, Set<Element>> interceptedElements;
+ final Map<SourceString, Set<Element>> interceptedElements;
+
+ /**
+ * A map of specialized versions of the [getInterceptorMethod].
+ * Since [getInterceptorMethod] is a hot method at runtime, we're
+ * always specializing it based on the incoming type. The keys in
+ * the map are the names of these specialized versions. Note that
+ * the generic version that contains all possible type checks is
+ * also stored in this map.
+ */
+ final Map<String, Collection<ClassElement>> specializedGetInterceptors;
+
+ /**
+ * Set of classes whose instances are intercepted. Implemented as a
+ * [LinkedHashMap] to preserve the insertion order.
+ * TODO(ngeoffray): Use a BitSet instead.
+ */
+ final Map<ClassElement, ClassElement> interceptedClasses;
List<CompilerTask> get tasks {
return <CompilerTask>[builder, optimizer, generator, emitter];
@@ -702,14 +700,19 @@
final RuntimeTypeInformation rti;
- JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
- : namer = determineNamer(compiler),
+ JavaScriptBackend(Compiler compiler,
+ bool generateSourceMap,
+ bool disableEval)
+ : namer = new Namer(compiler),
returnInfo = new Map<Element, ReturnInfo>(),
invalidateAfterCodegen = new List<Element>(),
interceptors = new Interceptors(compiler),
usedInterceptors = new Set<Selector>(),
interceptedElements = new Map<SourceString, Set<Element>>(),
rti = new RuntimeTypeInformation(compiler),
+ specializedGetInterceptors =
+ new Map<String, Collection<ClassElement>>(),
+ interceptedClasses = new LinkedHashMap<ClassElement, ClassElement>(),
super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) {
emitter = disableEval
? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap)
@@ -721,22 +724,9 @@
fieldTypes = new FieldTypesRegistry(this);
}
- static Namer determineNamer(Compiler compiler) {
- return compiler.enableMinification ?
- new MinifyNamer(compiler) :
- new Namer(compiler);
- }
-
bool isInterceptorClass(Element element) {
if (element == null) return false;
- return element == jsStringClass
- || element == jsArrayClass
- || element == jsIntClass
- || element == jsDoubleClass
- || element == jsNullClass
- || element == jsFunctionClass
- || element == jsBoolClass
- || element == jsNumberClass;
+ return interceptedClasses.containsKey(element);
}
void addInterceptedSelector(Selector selector) {
@@ -761,33 +751,47 @@
return result;
}
+ List<ClassElement> getListOfInterceptedClasses() {
+ return <ClassElement>[jsStringClass, jsArrayClass, jsIntClass,
+ jsDoubleClass, jsNumberClass, jsNullClass,
+ jsFunctionClass, jsBoolClass];
+ }
+
void initializeInterceptorElements() {
objectInterceptorClass =
compiler.findInterceptor(const SourceString('ObjectInterceptor'));
getInterceptorMethod =
compiler.findInterceptor(const SourceString('getInterceptor'));
- jsStringClass =
- compiler.findInterceptor(const SourceString('JSString'));
- jsArrayClass =
- compiler.findInterceptor(const SourceString('JSArray'));
- jsNumberClass =
- compiler.findInterceptor(const SourceString('JSNumber'));
- jsIntClass =
- compiler.findInterceptor(const SourceString('JSInt'));
- jsDoubleClass =
- compiler.findInterceptor(const SourceString('JSDouble'));
- jsNullClass =
- compiler.findInterceptor(const SourceString('JSNull'));
- jsFunctionClass =
- compiler.findInterceptor(const SourceString('JSFunction'));
- jsBoolClass =
- compiler.findInterceptor(const SourceString('JSBool'));
+ List<ClassElement> classes = [
+ jsStringClass = compiler.findInterceptor(const SourceString('JSString')),
+ jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')),
+ jsNumberClass = compiler.findInterceptor(const SourceString('JSNumber')),
+ jsIntClass = compiler.findInterceptor(const SourceString('JSInt')),
+ jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')),
+ jsNullClass = compiler.findInterceptor(const SourceString('JSNull')),
+ jsFunctionClass =
+ compiler.findInterceptor(const SourceString('JSFunction')),
+ jsBoolClass = compiler.findInterceptor(const SourceString('JSBool'))];
+
jsArrayClass.ensureResolved(compiler);
jsArrayLength =
jsArrayClass.lookupLocalMember(const SourceString('length'));
+ jsArrayRemoveLast =
+ jsArrayClass.lookupLocalMember(const SourceString('removeLast'));
+ jsArrayAdd =
+ jsArrayClass.lookupLocalMember(const SourceString('add'));
+
jsStringClass.ensureResolved(compiler);
jsStringLength =
jsStringClass.lookupLocalMember(const SourceString('length'));
+ jsStringSplit =
+ jsStringClass.lookupLocalMember(const SourceString('split'));
+ jsStringConcat =
+ jsStringClass.lookupLocalMember(const SourceString('concat'));
+
+ for (ClassElement cls in classes) {
+ if (cls != null) interceptedClasses[cls] = null;
+ }
}
void addInterceptors(ClassElement cls) {
@@ -800,24 +804,32 @@
includeSuperMembers: true);
}
+ String registerSpecializedGetInterceptor(Set<ClassElement> classes) {
+ compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass);
+ if (classes.contains(compiler.objectClass)) {
+ // We can't use a specialized [getInterceptorMethod], so we make
+ // sure we emit the one with all checks.
+ String name = namer.getName(getInterceptorMethod);
+ specializedGetInterceptors.putIfAbsent(name, () {
+ // It is important to take the order provided by this list,
+ // because we want the int type check to happen before the
+ // double type check: the double type check covers the int
+ // type check.
+ return interceptedClasses.keys;
+ });
+ return namer.isolateAccess(getInterceptorMethod);
+ } else {
+ String name = namer.getSpecializedName(getInterceptorMethod, classes);
+ specializedGetInterceptors[name] = classes;
+ return '${namer.CURRENT_ISOLATE}.$name';
+ }
+ }
+
void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
ClassElement result = null;
if (!_interceptorsAreInitialized) {
initializeInterceptorElements();
_interceptorsAreInitialized = true;
- // The null interceptor and the function interceptor are
- // currently always instantiated if a new class is instantiated.
- // TODO(ngeoffray): do this elsewhere for the function
- // interceptor?
- if (jsNullClass != null) {
- addInterceptors(jsNullClass);
- enqueuer.registerInstantiatedClass(jsNullClass);
- }
- if (jsFunctionClass != null) {
- addInterceptors(jsFunctionClass);
- enqueuer.registerInstantiatedClass(jsFunctionClass);
- }
- enqueuer.addToWorkList(getInterceptorMethod);
}
if (cls == compiler.stringClass) {
result = jsStringClass;
@@ -825,12 +837,16 @@
result = jsArrayClass;
} else if (cls == compiler.intClass) {
result = jsIntClass;
+ enqueuer.registerInstantiatedClass(jsNumberClass);
} else if (cls == compiler.doubleClass) {
result = jsDoubleClass;
+ enqueuer.registerInstantiatedClass(jsNumberClass);
} else if (cls == compiler.functionClass) {
result = jsFunctionClass;
} else if (cls == compiler.boolClass) {
result = jsBoolClass;
+ } else if (cls == compiler.nullClass) {
+ result = jsNullClass;
}
if (result == null) return;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index 7635c6a..1b8992a 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -4,84 +4,114 @@
part of js_backend;
-class ConstantEmitter implements ConstantVisitor {
+class ConstantEmitter {
+ ConstantReferenceEmitter _referenceEmitter;
+ ConstantInitializerEmitter _initializerEmitter;
+
+ ConstantEmitter(Compiler compiler, Namer namer) {
+ _referenceEmitter = new ConstantReferenceEmitter(compiler, namer);
+ _initializerEmitter = new ConstantInitializerEmitter(
+ compiler, namer, _referenceEmitter);
+ }
+
+ /**
+ * Constructs an expression that is a reference to the constant. Uses a
+ * canonical name unless the constant can be emitted multiple times (as for
+ * numbers and strings).
+ */
+ js.Expression reference(Constant constant) {
+ return _referenceEmitter.generate(constant);
+ }
+
+ /**
+ * Constructs an expression like [reference], but the expression is valid
+ * during isolate initialization.
+ */
+ js.Expression referenceInInitializationContext(Constant constant) {
+ return _referenceEmitter.generateInInitializationContext(constant);
+ }
+
+ /**
+ * Constructs an expression used to initialize a canonicalized constant.
+ */
+ js.Expression initializationExpression(Constant constant) {
+ return _initializerEmitter.generate(constant);
+ }
+}
+
+/**
+ * Visitor for generating JavaScript expressions to refer to [Constant]s.
+ * Do not use directly, use methods from [ConstantEmitter].
+ */
+class ConstantReferenceEmitter implements ConstantVisitor<js.Expression> {
final Compiler compiler;
final Namer namer;
+ bool inIsolateInitializationContext = false;
- CodeBuffer buffer;
- bool shouldEmitCanonicalVersion;
+ ConstantReferenceEmitter(this.compiler, this.namer);
- ConstantEmitter(this.compiler, this.namer);
-
- /**
- * Unless the constant can be emitted multiple times (as for numbers and
- * strings) use the canonical name.
- */
- void emitCanonicalVersionOfConstant(Constant constant, CodeBuffer newBuffer) {
- shouldEmitCanonicalVersion = true;
- buffer = newBuffer;
- _visit(constant);
+ js.Expression generate(Constant constant) {
+ inIsolateInitializationContext = false;
+ return _visit(constant);
}
- /**
- * Emit the JavaScript code of the constant. If the constant must be
- * canonicalized this method emits the initialization value.
- */
- void emitJavaScriptCodeForConstant(Constant constant, CodeBuffer newBuffer) {
- shouldEmitCanonicalVersion = false;
- buffer = newBuffer;
- _visit(constant);
+ js.Expression generateInInitializationContext(Constant constant) {
+ inIsolateInitializationContext = true;
+ return _visit(constant);
}
- _visit(Constant constant) {
- constant.accept(this);
+ js.Expression _visit(Constant constant) {
+ return constant.accept(this);
}
- void visitSentinel(SentinelConstant constant) {
- if (shouldEmitCanonicalVersion) {
- buffer.add(namer.CURRENT_ISOLATE);
- } else {
- compiler.internalError(
- "The parameter sentinel constant does not need specific JS code");
- }
+ js.Expression visitSentinel(SentinelConstant constant) {
+ return new js.VariableUse(namer.CURRENT_ISOLATE);
}
- void visitFunction(FunctionConstant constant) {
- if (shouldEmitCanonicalVersion) {
- buffer.add(namer.isolatePropertiesAccess(constant.element));
- } else {
- compiler.internalError(
- "The function constant does not need specific JS code");
- }
+ js.Expression visitFunction(FunctionConstant constant) {
+ return inIsolateInitializationContext
+ ? new js.VariableUse(namer.isolatePropertiesAccess(constant.element))
+ : new js.VariableUse(namer.isolateAccess(constant.element));
}
- void visitNull(NullConstant constant) {
- buffer.add("null");
+ js.Expression visitNull(NullConstant constant) {
+ return new js.LiteralNull();
}
- void visitInt(IntConstant constant) {
- buffer.add(constant.value.toString());
+ js.Expression visitInt(IntConstant constant) {
+ return new js.LiteralNumber('${constant.value}');
}
- void visitDouble(DoubleConstant constant) {
+ js.Expression visitDouble(DoubleConstant constant) {
double value = constant.value;
if (value.isNaN) {
- buffer.add("(0/0)");
+ return new js.LiteralNumber("(0/0)");
} else if (value == double.INFINITY) {
- buffer.add("(1/0)");
+ return new js.LiteralNumber("(1/0)");
} else if (value == -double.INFINITY) {
- buffer.add("(-1/0)");
+ return new js.LiteralNumber("(-1/0)");
} else {
- buffer.add("$value");
+ return new js.LiteralNumber("$value");
}
}
- void visitTrue(TrueConstant constant) {
- buffer.add("true");
+ js.Expression visitTrue(TrueConstant constant) {
+ if (compiler.enableMinification) {
+ // Use !0 for true.
+ return new js.Prefix("!", new js.LiteralNumber("0"));
+ } else {
+ return new js.LiteralBool(true);
+ }
+
}
- void visitFalse(FalseConstant constant) {
- buffer.add("false");
+ js.Expression visitFalse(FalseConstant constant) {
+ if (compiler.enableMinification) {
+ // Use !1 for false.
+ return new js.Prefix("!", new js.LiteralNumber("1"));
+ } else {
+ return new js.LiteralBool(false);
+ }
}
/**
@@ -89,139 +119,213 @@
* a form that is valid as JavaScript string literal content.
* The string is assumed quoted by double quote characters.
*/
- void visitString(StringConstant constant) {
- buffer.add('"');
- writeJsonEscapedCharsOn(constant.value.slowToString(), buffer);
- buffer.add('"');
+ js.Expression visitString(StringConstant constant) {
+ // TODO(sra): If the string is long *and repeated* (and not on a hot path)
+ // then it should be assigned to a name. We don't have reference counts (or
+ // profile information) here, so this is the wrong place.
+ StringBuffer sb = new StringBuffer();
+ writeJsonEscapedCharsOn(constant.value.slowToString(), sb);
+ return new js.LiteralString('"$sb"');
}
- void emitCanonicalVersion(Constant constant) {
+ js.Expression emitCanonicalVersion(Constant constant) {
String name = namer.constantName(constant);
- buffer.add(namer.isolatePropertiesAccessForConstant(name));
+ if (inIsolateInitializationContext) {
+ // $ISOLATE.$ISOLATE_PROPERTIES.$name
+ return new js.PropertyAccess.field(
+ new js.PropertyAccess.field(
+ new js.VariableUse(namer.ISOLATE),
+ namer.ISOLATE_PROPERTIES),
+ name);
+ } else {
+ return new js.PropertyAccess.field(
+ new js.VariableUse(namer.CURRENT_ISOLATE),
+ name);
+ }
}
- void visitList(ListConstant constant) {
- if (shouldEmitCanonicalVersion) {
- emitCanonicalVersion(constant);
- } else {
- shouldEmitCanonicalVersion = true;
- buffer.add("${namer.ISOLATE}.makeConstantList");
- buffer.add("([");
- for (int i = 0; i < constant.entries.length; i++) {
- if (i != 0) buffer.add(", ");
- _visit(constant.entries[i]);
- }
- buffer.add("])");
- }
+ js.Expression visitList(ListConstant constant) {
+ return emitCanonicalVersion(constant);
+ }
+
+ js.Expression visitMap(MapConstant constant) {
+ return emitCanonicalVersion(constant);
+ }
+
+ js.Expression visitType(TypeConstant constant) {
+ return emitCanonicalVersion(constant);
+ }
+
+ js.Expression visitConstructed(ConstructedConstant constant) {
+ return emitCanonicalVersion(constant);
+ }
+}
+
+/**
+ * Visitor for generating JavaScript expressions to initialize [Constant]s.
+ * Do not use directly; use methods from [ConstantEmitter].
+ */
+class ConstantInitializerEmitter implements ConstantVisitor<js.Expression> {
+ final Compiler compiler;
+ final Namer namer;
+ final ConstantReferenceEmitter referenceEmitter;
+
+ ConstantInitializerEmitter(this.compiler, this.namer, this.referenceEmitter);
+
+ js.Expression generate(Constant constant) {
+ return _visit(constant);
+ }
+
+ js.Expression _visit(Constant constant) {
+ return constant.accept(this);
+ }
+
+ js.Expression _reference(Constant constant) {
+ return referenceEmitter.generateInInitializationContext(constant);
+ }
+
+ js.Expression visitSentinel(SentinelConstant constant) {
+ compiler.internalError(
+ "The parameter sentinel constant does not need specific JS code");
+ }
+
+ js.Expression visitFunction(FunctionConstant constant) {
+ compiler.internalError(
+ "The function constant does not need specific JS code");
+ }
+
+ js.Expression visitNull(NullConstant constant) {
+ return _reference(constant);
+ }
+
+ js.Expression visitInt(IntConstant constant) {
+ return _reference(constant);
+ }
+
+ js.Expression visitDouble(DoubleConstant constant) {
+ return _reference(constant);
+ }
+
+ js.Expression visitTrue(TrueConstant constant) {
+ return _reference(constant);
+ }
+
+ js.Expression visitFalse(FalseConstant constant) {
+ return _reference(constant);
+ }
+
+ js.Expression visitString(StringConstant constant) {
+ // TODO(sra): Some larger strings are worth sharing.
+ return _reference(constant);
+ }
+
+ js.Expression visitList(ListConstant constant) {
+ return new js.Call(
+ new js.PropertyAccess.field(
+ new js.VariableUse(namer.ISOLATE),
+ 'makeConstantList'),
+ [new js.ArrayInitializer.from(_array(constant.entries))]);
}
String getJsConstructor(ClassElement element) {
return namer.isolatePropertiesAccess(element);
}
- void visitMap(MapConstant constant) {
- if (shouldEmitCanonicalVersion) {
- emitCanonicalVersion(constant);
- } else {
- void writeJsMap() {
- buffer.add("{");
- int valueIndex = 0;
- for (int i = 0; i < constant.keys.entries.length; i++) {
- StringConstant key = constant.keys.entries[i];
- if (key.value == MapConstant.PROTO_PROPERTY) continue;
+ js.Expression visitMap(MapConstant constant) {
+ js.Expression jsMap() {
+ List<js.Property> properties = <js.Property>[];
+ int valueIndex = 0;
+ for (int i = 0; i < constant.keys.entries.length; i++) {
+ StringConstant key = constant.keys.entries[i];
+ if (key.value == MapConstant.PROTO_PROPERTY) continue;
- if (valueIndex != 0) buffer.add(", ");
-
- // Keys in literal maps must be emitted in place.
- emitJavaScriptCodeForConstant(key, buffer);
-
- buffer.add(": ");
- emitCanonicalVersionOfConstant(constant.values[valueIndex++], buffer);
- }
- buffer.add("}");
- if (valueIndex != constant.values.length) {
- compiler.internalError("Bad value count.");
- }
+ // Keys in literal maps must be emitted in place.
+ js.Literal keyExpression = _visit(key);
+ js.Expression valueExpression =
+ _reference(constant.values[valueIndex++]);
+ properties.add(new js.Property(keyExpression, valueExpression));
}
+ if (valueIndex != constant.values.length) {
+ compiler.internalError("Bad value count.");
+ }
+ return new js.ObjectInitializer(properties);
+ }
- void badFieldCountError() {
- compiler.internalError(
+ void badFieldCountError() {
+ compiler.internalError(
"Compiler and ConstantMap disagree on number of fields.");
- }
-
- shouldEmitCanonicalVersion = true;
-
- ClassElement classElement = constant.type.element;
- buffer.add("new ");
- buffer.add(getJsConstructor(classElement));
- buffer.add("(");
- // The arguments of the JavaScript constructor for any given Dart class
- // are in the same order as the members of the class element.
- int emittedArgumentCount = 0;
- classElement.implementation.forEachInstanceField(
- (ClassElement enclosing, Element field) {
- if (emittedArgumentCount != 0) buffer.add(", ");
- if (field.name == MapConstant.LENGTH_NAME) {
- buffer.add(constant.keys.entries.length);
- } else if (field.name == MapConstant.JS_OBJECT_NAME) {
- writeJsMap();
- } else if (field.name == MapConstant.KEYS_NAME) {
- emitCanonicalVersionOfConstant(constant.keys, buffer);
- } else if (field.name == MapConstant.PROTO_VALUE) {
- assert(constant.protoValue != null);
- emitCanonicalVersionOfConstant(constant.protoValue, buffer);
- } else {
- badFieldCountError();
- }
- emittedArgumentCount++;
- },
- includeBackendMembers: true,
- includeSuperMembers: true);
- if ((constant.protoValue == null && emittedArgumentCount != 3) ||
- (constant.protoValue != null && emittedArgumentCount != 4)) {
- badFieldCountError();
- }
- buffer.add(")");
}
+
+ ClassElement classElement = constant.type.element;
+
+ List<js.Expression> arguments = <js.Expression>[];
+
+ // The arguments of the JavaScript constructor for any given Dart class
+ // are in the same order as the members of the class element.
+ int emittedArgumentCount = 0;
+ classElement.implementation.forEachInstanceField(
+ (ClassElement enclosing, Element field) {
+ if (field.name == MapConstant.LENGTH_NAME) {
+ arguments.add(
+ new js.LiteralNumber('${constant.keys.entries.length}'));
+ } else if (field.name == MapConstant.JS_OBJECT_NAME) {
+ arguments.add(jsMap());
+ } else if (field.name == MapConstant.KEYS_NAME) {
+ arguments.add(_reference(constant.keys));
+ } else if (field.name == MapConstant.PROTO_VALUE) {
+ assert(constant.protoValue != null);
+ arguments.add(_reference(constant.protoValue));
+ } else {
+ badFieldCountError();
+ }
+ emittedArgumentCount++;
+ },
+ includeBackendMembers: true,
+ includeSuperMembers: true);
+
+ if ((constant.protoValue == null && emittedArgumentCount != 3) ||
+ (constant.protoValue != null && emittedArgumentCount != 4)) {
+ badFieldCountError();
+ }
+
+ return new js.New(
+ new js.VariableUse(getJsConstructor(classElement)),
+ arguments);
}
- void visitType(TypeConstant constant) {
- if (shouldEmitCanonicalVersion) {
- emitCanonicalVersion(constant);
+ js.Expression visitType(TypeConstant constant) {
+ SourceString helperSourceName = const SourceString('createRuntimeType');
+ Element helper = compiler.findHelper(helperSourceName);
+ JavaScriptBackend backend = compiler.backend;
+ String helperName = backend.namer.getName(helper);
+ DartType type = constant.representedType;
+ Element element = type.element;
+ String typeName;
+ if (type.kind == TypeKind.INTERFACE) {
+ typeName =
+ backend.rti.getStringRepresentation(type, expandRawType: true);
} else {
- SourceString helperSourceName =
- const SourceString('createRuntimeType');
- Element helper = compiler.findHelper(helperSourceName);
- JavaScriptBackend backend = compiler.backend;
- String helperName = backend.namer.getName(helper);
- DartType type = constant.representedType;
- Element element = type.element;
- String typeName;
- if (type.kind == TypeKind.INTERFACE) {
- typeName =
- backend.rti.getStringRepresentation(type, expandRawType: true);
- } else {
- assert(type.kind == TypeKind.TYPEDEF);
- typeName = element.name.slowToString();
- }
- buffer.add("${namer.CURRENT_ISOLATE}.$helperName('$typeName')");
+ assert(type.kind == TypeKind.TYPEDEF);
+ typeName = element.name.slowToString();
}
+ return new js.Call(
+ new js.PropertyAccess.field(
+ new js.VariableUse(namer.CURRENT_ISOLATE),
+ helperName),
+ [new js.LiteralString("'$typeName'")]);
}
- void visitConstructed(ConstructedConstant constant) {
- if (shouldEmitCanonicalVersion) {
- emitCanonicalVersion(constant);
- } else {
- shouldEmitCanonicalVersion = true;
+ js.Expression visitConstructed(ConstructedConstant constant) {
+ return new js.New(
+ new js.VariableUse(getJsConstructor(constant.type.element)),
+ _array(constant.fields));
+ }
- buffer.add("new ");
- buffer.add(getJsConstructor(constant.type.element));
- buffer.add("(");
- for (int i = 0; i < constant.fields.length; i++) {
- if (i != 0) buffer.add(", ");
- _visit(constant.fields[i]);
- }
- buffer.add(")");
+ List<js.Expression> _array(List<Constant> values) {
+ List<js.Expression> valueList = <js.Expression>[];
+ for (int i = 0; i < values.length; i++) {
+ valueList.add(_reference(values[i]));
}
+ return valueList;
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 12a8d4f..91c072f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -81,13 +81,12 @@
});
}
- void writeConstantToBuffer(Constant value, CodeBuffer buffer,
- {emitCanonicalVersion: true}) {
- if (emitCanonicalVersion) {
- constantEmitter.emitCanonicalVersionOfConstant(value, buffer);
- } else {
- constantEmitter.emitJavaScriptCodeForConstant(value, buffer);
- }
+ js.Expression constantReference(Constant value) {
+ return constantEmitter.reference(value);
+ }
+
+ js.Expression constantInitializerExpression(Constant value) {
+ return constantEmitter.initializationExpression(value);
}
String get name => 'CodeEmitter';
@@ -107,63 +106,41 @@
String get lazyInitializerName
=> '${namer.ISOLATE}.\$lazy';
- // Property name suffixes. If the accessors are renaming then the format
- // is <accessorName>:<fieldName><suffix>. We use the suffix to know whether
- // to look for the ':' separator in order to avoid doing the indexOf operation
- // on every single property (they are quite rare). None of these characters
- // are legal in an identifier and they are related by bit patterns.
- // setter < 0x3c
- // both = 0x3d
- // getter > 0x3e
- // renaming setter | 0x7c
- // renaming both } 0x7d
- // renaming getter ~ 0x7e
- const SUFFIX_MASK = 0x3f;
- const FIRST_SUFFIX_CODE = 0x3c;
- const SETTER_CODE = 0x3c;
- const GETTER_SETTER_CODE = 0x3d;
- const GETTER_CODE = 0x3e;
- const RENAMING_FLAG = 0x40;
- String needsGetterCode(String variable) => '($variable & 3) > 0';
- String needsSetterCode(String variable) => '($variable & 2) == 0';
- String isRenaming(String variable) => '($variable & $RENAMING_FLAG) != 0';
+ final String GETTER_SUFFIX = "?";
+ final String SETTER_SUFFIX = "!";
+ final String GETTER_SETTER_SUFFIX = "=";
String get generateGetterSetterFunction {
return """
function(field, prototype) {
var len = field.length;
- var lastCharCode = field.charCodeAt(len - 1);
- var needsAccessor = (lastCharCode & $SUFFIX_MASK) >= $FIRST_SUFFIX_CODE;
- if (needsAccessor) {
- var needsGetter = ${needsGetterCode('lastCharCode')};
- var needsSetter = ${needsSetterCode('lastCharCode')};
- var renaming = ${isRenaming('lastCharCode')};
- var accessorName = field = field.substring(0, len - 1);
- if (renaming) {
- var divider = field.indexOf(":");
- accessorName = field.substring(0, divider);
- field = field.substring(divider + 1);
- }
- if (needsGetter) {
- var getterString = "return this." + field + ";";
- prototype["get\$" + accessorName] = new Function(getterString);
- }
- if (needsSetter) {
- var setterString = "this." + field + " = v;";
- prototype["set\$" + accessorName] = new Function("v", setterString);
- }
+ var lastChar = field[len - 1];
+ var needsGetter = lastChar == '$GETTER_SUFFIX' || lastChar == '$GETTER_SETTER_SUFFIX';
+ var needsSetter = lastChar == '$SETTER_SUFFIX' || lastChar == '$GETTER_SETTER_SUFFIX';
+ if (needsGetter || needsSetter) field = field.substring(0, len - 1);
+ if (needsGetter) {
+ var getterString = "return this." + field + ";";
+ """
+ /* The supportsProtoCheck below depends on the getter/setter convention.
+ When changing here, update the protoCheck too. */
+ """
+ prototype["get\$" + field] = new Function(getterString);
+ }
+ if (needsSetter) {
+ var setterString = "this." + field + " = v;";
+ prototype["set\$" + field] = new Function("v", setterString);
}
return field;
}""";
}
String get defineClassFunction {
- // First the class name, then the super class name, followed by the fields
- // (in an array) and the members (inside an Object literal).
+ // First the class name, then the field names in an array and the members
+ // (inside an Object literal).
// The caller can also pass in the constructor as a function if needed.
//
// Example:
- // defineClass("A", "B", ["x", "y"], {
+ // defineClass("A", ["x", "y"], {
// foo$1: function(y) {
// print(this.x + y);
// },
@@ -213,7 +190,7 @@
var tmp = $defineClassName('c', ['f?'], {}).prototype;
if (tmp.__proto__) {
tmp.__proto__ = {};
- if (typeof tmp.get\$f !== 'undefined') $supportsProtoName = true;
+ if (typeof tmp.get\$f !== "undefined") $supportsProtoName = true;
}
''';
}
@@ -237,10 +214,12 @@
for (var cls in collectedClasses) {
if (hasOwnProperty.call(collectedClasses, cls)) {
var desc = collectedClasses[cls];
-'''/* If the class does not have any declared fields (in the ''
- property of the description), then provide an empty list of fields. */'''
- $isolatePropertiesName[cls] = $defineClassName(cls, desc[''] || [], desc);
- if (desc['super'] !== "") $pendingClassesName[cls] = desc['super'];
+'''/* Get the superclass and the fields in the format Super;field1,field2 from
+ the null-string property on the descriptor. */'''
+ var s = desc[''].split(';'), supr = s[0];
+ var fields = s[1] == '' ? [] : s[1].split(',');
+ $isolatePropertiesName[cls] = $defineClassName(cls, fields, desc);
+ if (supr) $pendingClassesName[cls] = supr;
}
}
var pendingClasses = $pendingClassesName;
@@ -271,7 +250,7 @@
constructor.prototype = newPrototype;
newPrototype.constructor = constructor;
for (var member in prototype) {
- if (member == '' || member == 'super') continue;
+ if (!member) continue; '''/* Short version of: if (member == '') */'''
if (hasOwnProperty.call(prototype, member)) {
newPrototype[member] = prototype[member];
}
@@ -422,8 +401,6 @@
selector);
if (alreadyGenerated.contains(invocationName)) return;
alreadyGenerated.add(invocationName);
- CodeBuffer buffer = new CodeBuffer();
- buffer.add('function(');
JavaScriptBackend backend = compiler.backend;
bool isInterceptorClass =
@@ -432,23 +409,23 @@
// If the method is in an interceptor class, we need to also pass
// the actual receiver.
int extraArgumentCount = isInterceptorClass ? 1 : 0;
- // Use '$' to avoid clashes with other parameter names. Using '$'
- // works because [JsNames.getValid] used for getting parameter
- // names never returns '$'.
- String extraArgumentName = r'$';
+ // Use '$receiver' to avoid clashes with other parameter names. Using
+ // '$receiver' works because [JsNames.getValid] used for getting parameter
+ // names never returns a name beginning with a single '$'.
+ String receiverArgumentName = r'$receiver';
// The parameters that this stub takes.
- List<String> parametersBuffer =
- new List<String>(selector.argumentCount + extraArgumentCount);
+ List<js.Parameter> parametersBuffer =
+ new List<js.Parameter>(selector.argumentCount + extraArgumentCount);
// The arguments that will be passed to the real method.
- List<String> argumentsBuffer =
- new List<String>(parameters.parameterCount + extraArgumentCount);
+ List<js.Expression> argumentsBuffer =
+ new List<js.Expression>(parameters.parameterCount + extraArgumentCount);
int count = 0;
if (isInterceptorClass) {
count++;
- parametersBuffer[0] = extraArgumentName;
- argumentsBuffer[0] = extraArgumentName;
+ parametersBuffer[0] = new js.Parameter(receiverArgumentName);
+ argumentsBuffer[0] = new js.VariableUse(receiverArgumentName);
}
int indexOfLastOptionalArgumentInParameters = positionalArgumentCount - 1;
@@ -457,53 +434,56 @@
parameters.orderedForEachParameter((Element element) {
String jsName = JsNames.getValid(element.name.slowToString());
- assert(jsName != extraArgumentName);
+ assert(jsName != receiverArgumentName);
if (count < positionalArgumentCount + extraArgumentCount) {
- parametersBuffer[count] = jsName;
- argumentsBuffer[count] = jsName;
+ parametersBuffer[count] = new js.Parameter(jsName);
+ argumentsBuffer[count] = new js.VariableUse(jsName);
} else {
int index = names.indexOf(element.name);
if (index != -1) {
indexOfLastOptionalArgumentInParameters = count;
// The order of the named arguments is not the same as the
// one in the real method (which is in Dart source order).
- argumentsBuffer[count] = jsName;
- parametersBuffer[selector.positionalArgumentCount + index] = jsName;
- // Note that [elements] may be null for a synthetized [member].
+ argumentsBuffer[count] = new js.VariableUse(jsName);
+ parametersBuffer[selector.positionalArgumentCount + index] =
+ new js.Parameter(jsName);
+ // Note that [elements] may be null for a synthesized [member].
} else if (elements != null && elements.isParameterChecked(element)) {
- CodeBuffer argumentBuffer = new CodeBuffer();
- writeConstantToBuffer(SentinelConstant.SENTINEL, argumentBuffer);
- argumentsBuffer[count] = argumentBuffer.toString();
+ argumentsBuffer[count] = constantReference(SentinelConstant.SENTINEL);
} else {
Constant value = handler.initialVariableValues[element];
if (value == null) {
- argumentsBuffer[count] = NullConstant.JsNull;
+ argumentsBuffer[count] = constantReference(new NullConstant());
} else {
if (!value.isNull()) {
// If the value is the null constant, we should not pass it
// down to the native method.
indexOfLastOptionalArgumentInParameters = count;
}
- CodeBuffer argumentBuffer = new CodeBuffer();
- writeConstantToBuffer(value, argumentBuffer);
- argumentsBuffer[count] = argumentBuffer.toString();
+ argumentsBuffer[count] = constantReference(value);
}
}
}
count++;
});
- String parametersString = Strings.join(parametersBuffer, ",");
- buffer.add('$parametersString) {\n');
+ List<js.Statement> body;
if (member.isNative()) {
- nativeEmitter.generateParameterStub(
- member, invocationName, parametersString, argumentsBuffer,
- indexOfLastOptionalArgumentInParameters, buffer);
+ body = nativeEmitter.generateParameterStubStatements(
+ member, invocationName, parametersBuffer, argumentsBuffer,
+ indexOfLastOptionalArgumentInParameters);
} else {
- String arguments = Strings.join(argumentsBuffer, ",");
- buffer.add(' return this.${namer.getName(member)}($arguments)');
+ body = <js.Statement>[
+ new js.Return(
+ new js.VariableUse('this')
+ .dot(namer.getName(member))
+ .callWith(argumentsBuffer))];
}
- buffer.add('\n}');
+
+ js.Fun function = new js.Fun(parametersBuffer, new js.Block(body));
+
+ CodeBuffer buffer = new CodeBuffer();
+ buffer.add(js.prettyPrint(function, compiler));
defineInstanceMember(invocationName, buffer);
}
@@ -540,7 +520,7 @@
// on A and a typed selector on B could yield the same stub.
Set<String> generatedStubNames = new Set<String>();
if (compiler.enabledFunctionApply
- && member.name == namer.CLOSURE_INVOCATION_NAME) {
+ && member.name == Namer.CLOSURE_INVOCATION_NAME) {
// If [Function.apply] is called, we pessimistically compile all
// possible stubs for this closure.
FunctionSignature signature = member.computeSignature(compiler);
@@ -739,7 +719,6 @@
void visitClassFields(ClassElement classElement,
void addField(Element member,
String name,
- String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter)) {
@@ -750,7 +729,6 @@
compiler.codegenWorld.instantiatedClasses.contains(classElement);
void visitField(ClassElement enclosingClass, Element member) {
- assert(!member.isNative());
assert(invariant(classElement, member.isDeclaration));
LibraryElement library = member.getLibrary();
@@ -778,8 +756,9 @@
String accessorName = isShadowed
? namer.shadowedFieldName(member)
: namer.getName(member);
- String fieldName = enclosingClass.isNative() ?
- member.name.slowToString() : accessorName;
+ String fieldName = member.isNative()
+ ? member.nativeName()
+ : accessorName;
bool needsCheckedSetter = false;
if (needsSetter && compiler.enableTypeAssertions
&& canGenerateCheckedSetter(member)) {
@@ -789,7 +768,6 @@
// Getters and setters with suffixes will be generated dynamically.
addField(member,
fieldName,
- accessorName,
needsGetter,
needsSetter,
needsCheckedSetter);
@@ -806,17 +784,13 @@
includeSuperMembers: isInstantiated && !classElement.isNative());
}
- void generateGetter(Element member, String fieldName, String accessorName,
- CodeBuffer buffer) {
- String getterName =
- namer.getterName(member.getLibrary(), new SourceString(accessorName));
+ void generateGetter(Element member, String fieldName, CodeBuffer buffer) {
+ String getterName = namer.getterName(member.getLibrary(), member.name);
buffer.add("$getterName: function() { return this.$fieldName; }");
}
- void generateSetter(Element member, String fieldName, String accessorName,
- CodeBuffer buffer) {
- String setterName =
- namer.setterName(member.getLibrary(), new SourceString(accessorName));
+ void generateSetter(Element member, String fieldName, CodeBuffer buffer) {
+ String setterName = namer.setterName(member.getLibrary(), member.name);
buffer.add("$setterName: function(v) { this.$fieldName = v; }");
}
@@ -833,7 +807,6 @@
void generateCheckedSetter(Element member,
String fieldName,
- String accessorName,
CodeBuffer buffer) {
assert(canGenerateCheckedSetter(member));
DartType type = member.computeType(compiler);
@@ -844,8 +817,7 @@
if (helperElement.computeSignature(compiler).parameterCount != 1) {
additionalArgument = ", '${namer.operatorIs(type.element)}'";
}
- String setterName =
- namer.publicSetterName(new SourceString(accessorName));
+ String setterName = namer.setterName(member.getLibrary(), member.name);
buffer.add("$setterName: function(v) { "
"this.$fieldName = $helperName(v$additionalArgument); }");
}
@@ -856,39 +828,47 @@
void emitClassFields(ClassElement classElement,
CodeBuffer buffer,
- bool emitEndingComma) {
+ bool emitEndingComma,
+ { String superClass: "",
+ bool isNative: false}) {
+ assert(!isNative || superClass != "");
bool isFirstField = true;
+ bool isAnythingOutput = false;
+ if (!isNative) {
+ buffer.add('"":"$superClass;');
+ isAnythingOutput = true;
+ }
visitClassFields(classElement, (Element member,
String name,
- String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter) {
- if (isFirstField) {
- buffer.add('"": [');
- isFirstField = false;
- } else {
- buffer.add(", ");
+ if (!getterAndSetterCanBeImplementedByFieldSpec(
+ member, name, needsGetter, needsSetter)) {
+ return;
}
- buffer.add('"$accessorName');
- int flag = 0;
- if (name != accessorName) {
- buffer.add(':$name');
- assert(needsGetter || needsSetter);
- flag = RENAMING_FLAG;
+ if (!isNative || needsCheckedSetter || needsGetter || needsSetter) {
+ if (isFirstField) {
+ isFirstField = false;
+ if (!isAnythingOutput) {
+ buffer.add('"":"');
+ isAnythingOutput = true;
+ }
+ } else {
+ buffer.add(",");
+ }
+ buffer.add('$name');
+ if (needsGetter && needsSetter) {
+ buffer.add(GETTER_SETTER_SUFFIX);
+ } else if (needsGetter) {
+ buffer.add(GETTER_SUFFIX);
+ } else if (needsSetter) {
+ buffer.add(SETTER_SUFFIX);
+ }
}
- if (needsGetter && needsSetter) {
- buffer.addCharCode(GETTER_SETTER_CODE + flag);
- } else if (needsGetter) {
- buffer.addCharCode(GETTER_CODE + flag);
- } else if (needsSetter) {
- buffer.addCharCode(SETTER_CODE + flag);
- }
- buffer.add('"');
});
- if (!isFirstField) {
- // There was at least one field.
- buffer.add(']');
+ if (isAnythingOutput) {
+ buffer.add('"');
if (emitEndingComma) {
buffer.add(',');
}
@@ -899,24 +879,58 @@
void emitClassGettersSetters(ClassElement classElement,
CodeBuffer buffer,
bool emitLeadingComma) {
+ emitComma() {
+ if (emitLeadingComma) {
+ buffer.add(",\n ");
+ } else {
+ emitLeadingComma = true;
+ }
+ }
+
visitClassFields(classElement, (Element member,
String name,
- String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter) {
+ if (name == null) throw 123;
+ if (getterAndSetterCanBeImplementedByFieldSpec(
+ member, name, needsGetter, needsSetter)) {
+ needsGetter = false;
+ needsSetter = false;
+ }
+ if (needsGetter) {
+ emitComma();
+ generateGetter(member, name, buffer);
+ }
+ if (needsSetter) {
+ emitComma();
+ generateSetter(member, name, buffer);
+ }
if (needsCheckedSetter) {
assert(!needsSetter);
- if (emitLeadingComma) {
- buffer.add(",\n ");
- } else {
- emitLeadingComma = true;
- }
- generateCheckedSetter(member, name, accessorName, buffer);
+ emitComma();
+ generateCheckedSetter(member, name, buffer);
}
});
}
+ bool getterAndSetterCanBeImplementedByFieldSpec(Element member,
+ String name,
+ bool needsGetter,
+ bool needsSetter) {
+ if (needsGetter) {
+ if (namer.getterName(member.getLibrary(), member.name) != 'get\$$name') {
+ return false;
+ }
+ }
+ if (needsSetter) {
+ if (namer.setterName(member.getLibrary(), member.name) != 'set\$$name') {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* Documentation wanted -- johnniwinther
*
@@ -944,11 +958,11 @@
buffer.add('$classesCollector.$className = {');
emitClassConstructor(classElement, buffer);
- emitClassFields(classElement, buffer, true);
+ emitClassFields(classElement, buffer, false,
+ superClass: superName, isNative: false);
// TODO(floitsch): the emitInstanceMember should simply always emit a ',\n'.
// That does currently not work because the native classes have a different
// syntax.
- buffer.add('\n "super": "$superName"');
emitClassGettersSetters(classElement, buffer, true);
emitInstanceMembers(classElement, buffer, true);
buffer.add('\n};\n\n');
@@ -1138,7 +1152,7 @@
// create a fake element with the correct name.
// Note: the callElement will not have any enclosingElement.
FunctionElement callElement =
- new ClosureInvocationElement(namer.CLOSURE_INVOCATION_NAME, element);
+ new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element);
String staticName = namer.getName(element);
String invocationName = namer.instanceMethodName(callElement);
String fieldAccess = '$isolateProperties.$staticName';
@@ -1157,11 +1171,10 @@
String superName,
String extraArgument,
CodeBuffer buffer) {
- extraArgument = extraArgument.isEmpty ? '' : ", '$extraArgument'";
+ extraArgument = extraArgument.isEmpty ? '' : ",$extraArgument";
buffer.add("""
$classesCollector.$mangledName = {'':
-['self'$extraArgument, 'target'],
-'super': '$superName',
+\"$superName;self$extraArgument,target\",
""");
}
@@ -1236,8 +1249,8 @@
// its stubs we simply create a fake element with the correct name.
// Note: the callElement will not have any enclosingElement.
FunctionElement callElement =
- new ClosureInvocationElement(namer.CLOSURE_INVOCATION_NAME, member);
-
+ new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member);
+
String invocationName = namer.instanceMethodName(callElement);
List<String> arguments = new List<String>(parameterCount);
for (int i = 0; i < parameterCount; i++) {
@@ -1289,7 +1302,9 @@
if (member.isGetter()) {
getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
} else {
- String name = namer.instanceFieldName(memberLibrary, member.name);
+ String name = member.isNative()
+ ? member.nativeName()
+ : namer.instanceFieldName(memberLibrary, member.name);
getter = "this.$name";
}
for (Selector selector in selectors) {
@@ -1297,7 +1312,7 @@
String invocationName =
namer.instanceMethodInvocationName(memberLibrary, member.name,
selector);
- SourceString callName = namer.CLOSURE_INVOCATION_NAME;
+ SourceString callName = Namer.CLOSURE_INVOCATION_NAME;
String closureCallName =
namer.instanceMethodInvocationName(memberLibrary, callName,
selector);
@@ -1319,12 +1334,17 @@
List<VariableElement> staticNonFinalFields =
handler.getStaticNonFinalFieldsForEmission();
for (Element element in staticNonFinalFields) {
- buffer.add('$isolateProperties.${namer.getName(element)} = ');
compiler.withCurrentElement(element, () {
- Constant initialValue = handler.getInitialValueFor(element);
- writeConstantToBuffer(initialValue, buffer);
- });
- buffer.add(';\n');
+ Constant initialValue = handler.getInitialValueFor(element);
+ js.Expression init =
+ new js.Assignment(
+ new js.PropertyAccess.field(
+ new js.VariableUse(isolateProperties),
+ namer.getName(element)),
+ constantEmitter.referenceInInitializationContext(initialValue));
+ buffer.add(js.prettyPrint(init, compiler));
+ buffer.add(';\n');
+ });
}
}
@@ -1382,8 +1402,13 @@
addedMakeConstantList = true;
emitMakeConstantList(buffer);
}
- buffer.add('$isolateProperties.$name = ');
- writeConstantToBuffer(constant, buffer, emitCanonicalVersion: false);
+ js.Expression init =
+ new js.Assignment(
+ new js.PropertyAccess.field(
+ new js.VariableUse(isolateProperties),
+ name),
+ constantInitializerExpression(constant));
+ buffer.add(js.prettyPrint(init, compiler));
buffer.add(';\n');
}
}
@@ -1477,14 +1502,11 @@
}
String internalName = namer.instanceMethodInvocationName(
selector.library, new SourceString(methodName), selector);
- Element createInvocationMirror =
- compiler.findHelper(const SourceString('createInvocationMirror'));
CodeBuffer buffer = new CodeBuffer();
buffer.add('function($args) {\n');
buffer.add(' return this.$noSuchMethodName('
- '${namer.isolateAccess(createInvocationMirror)}('
- '"$methodName", "$internalName",'
- '$type, [$args], [$argNames]));\n');
+ '\$.createInvocationMirror("$methodName", "$internalName",'
+ ' $type, [$args], [$argNames]));\n');
buffer.add(' }');
return buffer;
}
@@ -1657,10 +1679,10 @@
//
// BEGIN invoke [main].
//
-if (typeof document !== 'undefined' && document.readyState != 'complete') {
+if (typeof document != 'undefined' && document.readyState != 'complete') {
document.addEventListener('readystatechange', function () {
if (document.readyState == 'complete') {
- if (typeof dartMainRunner === 'function') {
+ if (typeof dartMainRunner == 'function') {
dartMainRunner(function() { ${mainCall}; });
} else {
${mainCall};
@@ -1668,7 +1690,7 @@
}
}, false);
} else {
- if (typeof dartMainRunner === 'function') {
+ if (typeof dartMainRunner == 'function') {
dartMainRunner(function() { ${mainCall}; });
} else {
${mainCall};
@@ -1681,6 +1703,53 @@
""");
}
+ /**
+ * Emit the code for doing a type check on [cls]. [cls] must
+ * be an interceptor class.
+ */
+ void emitInterceptorCheck(ClassElement cls, CodeBuffer buffer) {
+ JavaScriptBackend backend = compiler.backend;
+ assert(backend.isInterceptorClass(cls));
+ if (cls == backend.jsBoolClass) {
+ buffer.add("if (typeof receiver == 'boolean')");
+ } else if (cls == backend.jsIntClass) {
+ buffer.add("if (typeof receiver == 'number' "
+ "&& Math.floor(receiver) == receiver)");
+ } else if (cls == backend.jsDoubleClass || cls == backend.jsNumberClass) {
+ buffer.add("if (typeof receiver == 'number')");
+ } else if (cls == backend.jsArrayClass) {
+ buffer.add("if (receiver != null && receiver.constructor == Array)");
+ } else if (cls == backend.jsStringClass) {
+ buffer.add("if (typeof receiver == 'string')");
+ } else if (cls == backend.jsNullClass) {
+ buffer.add("if (receiver == null)");
+ } else if (cls == backend.jsFunctionClass) {
+ buffer.add("if (typeof receiver == 'function')");
+ }
+ buffer.add(' return ${namer.isolateAccess(cls)}.prototype;');
+ }
+
+ /**
+ * Emit all versions of the [:getInterceptor:] method.
+ */
+ void emitGetInterceptorMethods(CodeBuffer buffer) {
+ JavaScriptBackend backend = compiler.backend;
+ // If no class needs to be intercepted, just return.
+ if (backend.objectInterceptorClass == null) return;
+ String objectName = namer.isolateAccess(backend.objectInterceptorClass);
+ backend.specializedGetInterceptors.forEach(
+ (String key, Collection<ClassElement> classes) {
+ buffer.add('$isolateProperties.$key = function(receiver) {');
+ for (ClassElement cls in classes) {
+ if (compiler.codegenWorld.instantiatedClasses.contains(cls)) {
+ buffer.add('\n ');
+ emitInterceptorCheck(cls, buffer);
+ }
+ }
+ buffer.add('\n return $objectName.prototype;\n};\n');
+ });
+ }
+
String assembleProgram() {
measure(() {
mainBuffer.add(HOOKS_API_USAGE);
@@ -1705,6 +1774,7 @@
// Static field initializations require the classes and compile-time
// constants to be set up.
emitStaticNonFinalFieldInitializations(mainBuffer);
+ emitGetInterceptorMethods(mainBuffer);
emitLazilyInitializedStaticFields(mainBuffer);
isolateProperties = isolatePropertiesName;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
index 0b3864e..0b6c0f5 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
@@ -108,7 +108,6 @@
List<String> fields = <String>[];
visitClassFields(classElement, (Element member,
String name,
- String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter) {
@@ -135,40 +134,16 @@
void emitClassFields(ClassElement classElement,
CodeBuffer buffer,
- bool emitEndingComma) {
+ bool emitEndingComma,
+ { String superClass: "",
+ bool isNative: false}) {
if (emitEndingComma) buffer.add(', ');
}
- void emitClassGettersSetters(ClassElement classElement,
- CodeBuffer buffer,
- bool emitLeadingComma) {
- emitComma() {
- if (emitLeadingComma) {
- buffer.add(",\n ");
- } else {
- emitLeadingComma = true;
- }
- }
-
- visitClassFields(classElement, (Element member,
- String name,
- String accessorName,
- bool needsGetter,
- bool needsSetter,
- bool needsCheckedSetter) {
- if (needsGetter) {
- emitComma();
- generateGetter(member, name, accessorName, buffer);
- }
- if (needsSetter) {
- emitComma();
- generateSetter(member, name, accessorName, buffer);
- }
- if (needsCheckedSetter) {
- assert(!needsSetter);
- emitComma();
- generateCheckedSetter(member, name, accessorName, buffer);
- }
- });
+ bool getterAndSetterCanBeImplementedByFieldSpec(Element member,
+ String name,
+ bool needsGetter,
+ bool needsSetter) {
+ return false;
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
index f24e5ba..1f2106e 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -25,5 +25,4 @@
part 'emitter_no_eval.dart';
part 'namer.dart';
part 'native_emitter.dart';
-part 'minify_namer.dart';
part 'runtime_types.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
deleted file mode 100644
index 8e292b4..0000000
--- a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of js_backend;
-
-/**
- * Assigns JavaScript identifiers to Dart variables, class-names and members.
- */
-class MinifyNamer extends Namer {
- MinifyNamer(Compiler compiler) : super(compiler);
-
- String get ISOLATE => 'I';
- String get ISOLATE_PROPERTIES => 'p';
- bool get shouldMinify => true;
-
- const ALPHABET_CHARACTERS = 52; // a-zA-Z.
- const ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9.
-
- // You can pass an invalid identifier to this and unlike its non-minifying
- // counterpart it will never return the proposedName as the new fresh name.
- String getFreshName(String proposedName, Set<String> usedNames) {
- var freshName = _getUnusedName(proposedName, usedNames);
- usedNames.add(freshName);
- return freshName;
- }
-
- // This gets a minified name based on a hash of the proposed name. This
- // is slightly less efficient than just getting the next name in a series,
- // but it means that small changes in the input program will give smallish
- // changes in the output, which can be useful for diffing etc.
- String _getUnusedName(String proposedName, Set<String> usedNames) {
- // Try single-character names with characters that occur in the
- // input.
- for (int i = 0; i < proposedName.length; i++) {
- String candidate = proposedName[i];
- int code = candidate.charCodeAt(0);
- if (code < $A) continue;
- if (code > $z) continue;
- if (code > $Z && code < $a) continue;
- if (!usedNames.contains(candidate)) return candidate;
- }
-
- int hash = _calculateHash(proposedName);
- // Avoid very small hashes that won't try many names.
- hash = hash < 1000 ? hash * 314159 : hash; // Yes, it's prime.
-
- // Try other n-character names based on the hash. We try one to three
- // character identifiers. For each length we try around 10 different names
- // in a predictable order determined by the proposed name. This is in order
- // to make the renamer stable: small changes in the input should nornally
- // result in relatively small changes in the output.
- for (var n = 1; n <= 3; n++) {
- int h = hash;
- while (h > 10) {
- var codes = <int>[_letterNumber(h)];
- int h2 = h ~/ ALPHABET_CHARACTERS;
- for (var i = 1; i < n; i++) {
- codes.add(_alphaNumericNumber(h2));
- h2 ~/= ALPHANUMERIC_CHARACTERS;
- }
- final candidate = new String.fromCharCodes(codes);
- if (!usedNames.contains(candidate) && !jsReserved.contains(candidate)) {
- return candidate;
- }
- // Try again with a slightly different hash. After around 10 turns
- // around this loop h is zero and we try a longer name.
- h ~/= 7;
- }
- }
-
- // If we can't find a hash based name in the three-letter space, then base
- // the name on a letter and a counter.
- var startLetter = new String.fromCharCodes([_letterNumber(hash)]);
- var i = 0;
- while (usedNames.contains("$startLetter$i")) {
- i++;
- }
- return "$startLetter$i";
- }
-
- int _calculateHash(String name) {
- int h = 0;
- for (int i = 0; i < name.length; i++) {
- h += name.charCodeAt(i);
- h &= 0xffffffff;
- h += h << 10;
- h &= 0xffffffff;
- h ^= h >> 6;
- h &= 0xffffffff;
- }
- return h;
- }
-
- int _letterNumber(int x) {
- if (x >= ALPHABET_CHARACTERS) x %= ALPHABET_CHARACTERS;
- if (x < 26) return $a + x;
- return $A + x - 26;
- }
-
- int _alphaNumericNumber(int x) {
- if (x >= ALPHANUMERIC_CHARACTERS) x %= ALPHANUMERIC_CHARACTERS;
- if (x < 26) return $a + x;
- if (x < 52) return $A + x - 26;
- return $0 + x - 52;
- }
-
-}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 691d73b..c4888b2 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -8,6 +8,8 @@
* Assigns JavaScript identifiers to Dart variables, class-names and members.
*/
class Namer {
+ final Compiler compiler;
+
static Set<String> _jsReserved = null;
Set<String> get jsReserved {
if (_jsReserved == null) {
@@ -18,22 +20,15 @@
return _jsReserved;
}
- final String CURRENT_ISOLATE = r'$';
-
/**
* Map from top-level or static elements to their unique identifiers provided
* by [getName].
*
* Invariant: Keys must be declaration elements.
*/
- final Compiler compiler;
final Map<Element, String> globals;
+ final Map<String, int> usedGlobals;
final Map<String, LibraryElement> shortPrivateNameOwners;
- final Set<String> usedGlobalNames;
- final Set<String> usedInstanceNames;
- final Map<String, String> instanceNameMap;
- final Map<String, String> globalNameMap;
- final Map<String, int> popularNameCounters;
/**
* A cache of names used for bailout methods. We make sure two
@@ -50,27 +45,22 @@
Namer(this.compiler)
: globals = new Map<Element, String>(),
+ usedGlobals = new Map<String, int>(),
shortPrivateNameOwners = new Map<String, LibraryElement>(),
bailoutNames = new Map<Element, String>(),
usedBailoutInstanceNames = new Set<String>(),
- usedGlobalNames = new Set<String>(),
- usedInstanceNames = new Set<String>(),
- instanceNameMap = new Map<String, String>(),
- globalNameMap = new Map<String, String>(),
- constantNames = new Map<Constant, String>(),
- popularNameCounters = new Map<String, int>();
+ constantNames = new Map<Constant, String>();
- String get ISOLATE => 'Isolate';
- String get ISOLATE_PROPERTIES => r'$isolateProperties';
+ final String CURRENT_ISOLATE = r'$';
+ final String ISOLATE = 'Isolate';
+ final String ISOLATE_PROPERTIES = r"$isolateProperties";
/**
* Some closures must contain their name. The name is stored in
* [STATIC_CLOSURE_NAME_NAME].
*/
- String get STATIC_CLOSURE_NAME_NAME => r'$name';
- SourceString get CLOSURE_INVOCATION_NAME => Compiler.CALL_OPERATOR_NAME;
- bool get shouldMinify => false;
-
- bool isReserved(String name) => name == ISOLATE;
+ final String STATIC_CLOSURE_NAME_NAME = r'$name';
+ static const SourceString CLOSURE_INVOCATION_NAME =
+ Compiler.CALL_OPERATOR_NAME;
String constantName(Constant constant) {
// In the current implementation it doesn't make sense to give names to
@@ -79,30 +69,16 @@
assert(!constant.isFunction());
String result = constantNames[constant];
if (result == null) {
- String longName;
- if (shouldMinify) {
- if (constant.isString()) {
- StringConstant stringConstant = constant;
- // The minifier never returns the same string as we suggested so we
- // can suggest any name and it will use it as input to the hashing
- // algorithm. This means that constants will tend to have the same
- // name from version to version of the program being minfied.
- longName = stringConstant.value.slowToString();
- } else {
- longName = "C";
- }
- } else {
- longName = "CTC";
- }
- result = getFreshName(longName, usedGlobalNames);
+ result = getFreshGlobalName("CTC");
constantNames[constant] = result;
}
return result;
}
String closureInvocationName(Selector selector) {
- return
- instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME, selector);
+ // TODO(floitsch): mangle, while not conflicting with instance names.
+ return instanceMethodInvocationName(null, CLOSURE_INVOCATION_NAME,
+ selector);
}
String breakLabelName(LabelElement label) {
@@ -128,7 +104,6 @@
* mangles the [name] so that each library has a unique name.
*/
String privateName(LibraryElement lib, SourceString name) {
- String result;
if (name.isPrivate()) {
String nameString = name.slowToString();
// The first library asking for a short private name wins.
@@ -137,22 +112,17 @@
// If a private name could clash with a mangled private name we don't
// use the short name. For example a private name "_lib3_foo" would
// clash with "_foo" from "lib3".
- if (owner == lib &&
- !nameString.startsWith('_$LIBRARY_PREFIX') &&
- !shouldMinify) {
- result = nameString;
- } else {
- String libName = getName(lib);
- // If a library name does not start with the [LIBRARY_PREFIX] then our
- // assumptions about clashing with mangled private members do not hold.
- assert(shouldMinify || libName.startsWith(LIBRARY_PREFIX));
- // TODO(erikcorry): Fix this with other manglings to avoid clashes.
- result = '_lib$libName\$$nameString';
+ if (identical(owner, lib) && !nameString.startsWith('_$LIBRARY_PREFIX')) {
+ return nameString;
}
+ String libName = getName(lib);
+ // If a library name does not start with the [LIBRARY_PREFIX] then our
+ // assumptions about clashing with mangled private members do not hold.
+ assert(libName.startsWith(LIBRARY_PREFIX));
+ return '_$libName$nameString';
} else {
- result = name.slowToString();
+ return name.slowToString();
}
- return result;
}
String instanceMethodName(FunctionElement element) {
@@ -165,27 +135,21 @@
FunctionSignature signature = element.computeSignature(compiler);
String methodName =
'${privateName(lib, name)}\$${signature.parameterCount}';
- if (signature.optionalParametersAreNamed &&
- !signature.optionalParameters.isEmpty) {
+ if (!signature.optionalParametersAreNamed) {
+ return methodName;
+ } else if (!signature.optionalParameters.isEmpty) {
StringBuffer buffer = new StringBuffer();
signature.orderedOptionalParameters.forEach((Element element) {
buffer.add('\$${JsNames.getValid(element.name.slowToString())}');
});
- methodName = '$methodName$buffer';
+ return '$methodName$buffer';
}
- if (name == CLOSURE_INVOCATION_NAME) return methodName;
- return getMappedInstanceName(methodName);
}
String publicInstanceMethodNameByArity(SourceString name, int arity) {
name = Elements.operatorNameToIdentifier(name);
assert(!name.isPrivate());
- var base = name.slowToString();
- // We don't mangle the closure invoking function name because it is
- // generated in applyFunction.
- var proposedName = '$base\$$arity';
- if (base == CLOSURE_INVOCATION_NAME) return proposedName;
- return getMappedInstanceName(proposedName);
+ return '${name.slowToString()}\$$arity';
}
String instanceMethodInvocationName(LibraryElement lib, SourceString name,
@@ -198,16 +162,12 @@
buffer.add(r'$');
argumentName.printOn(buffer);
}
- if (name == CLOSURE_INVOCATION_NAME) {
- return '$CLOSURE_INVOCATION_NAME\$${selector.argumentCount}$buffer';
- }
- return getMappedInstanceName(
- '${privateName(lib, name)}\$${selector.argumentCount}$buffer');
+ return '${privateName(lib, name)}\$${selector.argumentCount}$buffer';
}
String instanceFieldName(LibraryElement libraryElement, SourceString name) {
String proposedName = privateName(libraryElement, name);
- return getMappedInstanceName(proposedName);
+ return safeName(proposedName);
}
String shadowedFieldName(Element fieldElement) {
@@ -216,71 +176,45 @@
String libName = getName(libraryElement);
String clsName = getName(cls);
String instanceName = instanceFieldName(libraryElement, fieldElement.name);
- return getMappedInstanceName('$libName\$$clsName\$$instanceName');
+ return safeName('$libName\$$clsName\$$instanceName');
}
String setterName(LibraryElement lib, SourceString name) {
// We dynamically create setters from the field-name. The setter name must
// therefore be derived from the instance field-name.
- String fieldName = getMappedInstanceName(privateName(lib, name));
+ String fieldName = safeName(privateName(lib, name));
return 'set\$$fieldName';
}
String publicGetterName(SourceString name) {
// We dynamically create getters from the field-name. The getter name must
// therefore be derived from the instance field-name.
- String fieldName = getMappedInstanceName(name.slowToString());
+ String fieldName = safeName(name.slowToString());
return 'get\$$fieldName';
}
String getterName(LibraryElement lib, SourceString name) {
// We dynamically create getters from the field-name. The getter name must
// therefore be derived from the instance field-name.
- String fieldName = getMappedInstanceName(privateName(lib, name));
+ String fieldName = safeName(privateName(lib, name));
return 'get\$$fieldName';
}
- String publicSetterName(SourceString name) {
- // We dynamically create setter from the field-name. The setter name must
- // therefore be derived from the instance field-name.
- String fieldName = name.slowToString();
- return 'set\$$fieldName';
- }
-
- String getMappedGlobalName(String proposedName) {
- var newName = globalNameMap[proposedName];
- if (newName == null) {
- newName = getFreshName(proposedName, usedGlobalNames);
- globalNameMap[proposedName] = newName;
+ String getFreshGlobalName(String proposedName) {
+ String name = proposedName;
+ int count = usedGlobals[name];
+ if (count != null) {
+ // Not the first time we see this name. Append a number to make it unique.
+ do {
+ name = '$proposedName${count++}';
+ } while (usedGlobals[name] != null);
+ // Record the count in case we see this name later. We
+ // frequently see names multiple times, as all our closures use
+ // the same name for their class.
+ usedGlobals[proposedName] = count;
}
- return newName;
- }
-
- String getMappedInstanceName(String proposedName) {
- var newName = instanceNameMap[proposedName];
- if (newName == null) {
- newName = getFreshName(proposedName, usedInstanceNames);
- instanceNameMap[proposedName] = newName;
- }
- return newName;
- }
-
- String getFreshName(String proposedName, Set<String> usedNames) {
- var candidate;
- proposedName = safeName(proposedName);
- if (!usedNames.contains(proposedName)) {
- candidate = proposedName;
- } else {
- var counter = popularNameCounters[proposedName];
- var i = counter == null ? 0 : counter;
- while (usedNames.contains("$proposedName$i")) {
- i++;
- }
- popularNameCounters[proposedName] = i + 1;
- candidate = "$proposedName$i";
- }
- usedNames.add(candidate);
- return candidate;
+ usedGlobals[name] = 0;
+ return name;
}
static const String LIBRARY_PREFIX = "lib";
@@ -313,7 +247,15 @@
} else {
name = element.name.slowToString();
}
- return name;
+ return safeName(name);
+ }
+
+ String getSpecializedName(Element element, Collection<ClassElement> classes) {
+ StringBuffer buffer = new StringBuffer('${getName(element)}\$');
+ for (ClassElement cls in classes) {
+ buffer.add(getName(cls));
+ }
+ return safeName(buffer.toString());
}
String getBailoutName(Element element) {
@@ -321,15 +263,12 @@
if (name != null) return name;
bool global = !element.isInstanceMember();
String unminifiedName = '${getName(element)}\$bailout';
- if (global) {
- name = getMappedGlobalName(unminifiedName);
- } else {
- name = unminifiedName;
+ name = unminifiedName;
+ if (!global) {
int i = 0;
while (usedBailoutInstanceNames.contains(name)) {
name = '$unminifiedName${i++}';
}
- name = getMappedInstanceName(name);
usedBailoutInstanceNames.add(name);
}
bailoutNames[element] = name;
@@ -371,26 +310,18 @@
if (identical(kind, ElementKind.VARIABLE) ||
identical(kind, ElementKind.PARAMETER)) {
// The name is not guaranteed to be unique.
- return safeName(guess);
+ return guess;
}
- if (kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
- kind == ElementKind.FUNCTION ||
- kind == ElementKind.CLASS ||
- kind == ElementKind.FIELD ||
- kind == ElementKind.GETTER ||
- kind == ElementKind.SETTER ||
- kind == ElementKind.TYPEDEF ||
- kind == ElementKind.LIBRARY ||
- kind == ElementKind.MALFORMED_TYPE) {
- bool isNative = false;
- if (identical(kind, ElementKind.CLASS)) {
- ClassElement class_elt = element;
- isNative = class_elt.isNative();
- }
- if (Elements.isInstanceField(element)) {
- isNative = element.isNative();
- }
- String result = isNative ? guess : getFreshName(guess, usedGlobalNames);
+ if (identical(kind, ElementKind.GENERATIVE_CONSTRUCTOR) ||
+ identical(kind, ElementKind.FUNCTION) ||
+ identical(kind, ElementKind.CLASS) ||
+ identical(kind, ElementKind.FIELD) ||
+ identical(kind, ElementKind.GETTER) ||
+ identical(kind, ElementKind.SETTER) ||
+ identical(kind, ElementKind.TYPEDEF) ||
+ identical(kind, ElementKind.LIBRARY) ||
+ identical(kind, ElementKind.MALFORMED_TYPE)) {
+ String result = getFreshGlobalName(guess);
globals[element] = result;
return result;
}
@@ -400,25 +331,21 @@
}
String getLazyInitializerName(Element element) {
+ // TODO(floitsch): mangle while not conflicting with other statics.
assert(Elements.isStaticOrTopLevelField(element));
- return getMappedGlobalName("get\$${getName(element)}");
+ return "get\$${getName(element)}";
}
String isolatePropertiesAccess(Element element) {
return "$ISOLATE.$ISOLATE_PROPERTIES.${getName(element)}";
}
- String isolatePropertiesAccessForConstant(String constantName) {
- return "$ISOLATE.$ISOLATE_PROPERTIES.$constantName";
- }
-
String isolateAccess(Element element) {
return "$CURRENT_ISOLATE.${getName(element)}";
}
String isolateBailoutAccess(Element element) {
- String newName = getMappedGlobalName('${getName(element)}\$bailout');
- return '$CURRENT_ISOLATE.$newName';
+ return '${isolateAccess(element)}\$bailout';
}
String isolateLazyInitializerAccess(Element element) {
@@ -426,7 +353,6 @@
}
String operatorIs(Element element) {
- // TODO(erikcorry): Reduce from is$x to ix when we are minifying.
return 'is\$${getName(element)}';
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index c2542ef..076ab69 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -31,9 +31,6 @@
// Caches the methods that have a native body.
Set<FunctionElement> nativeMethods;
- // Caches the methods that redirect to a JS method.
- Map<FunctionElement, String> redirectingMethods;
-
// Do we need the native emitter to take care of handling
// noSuchMethod for us? This flag is set to true in the emitter if
// it finds any native class that needs noSuchMethod handling.
@@ -46,16 +43,11 @@
directSubtypes = new Map<ClassElement, List<ClassElement>>(),
overriddenMethods = new Set<FunctionElement>(),
nativeMethods = new Set<FunctionElement>(),
- redirectingMethods = new Map<FunctionElement, String>(),
nativeBuffer = new CodeBuffer();
Compiler get compiler => emitter.compiler;
JavaScriptBackend get backend => compiler.backend;
- void addRedirectingMethod(FunctionElement element, String name) {
- redirectingMethods[element] = name;
- }
-
String get dynamicName {
Element element = compiler.findHelper(
const SourceString('dynamicFunction'));
@@ -98,14 +90,15 @@
String get defineNativeClassFunction {
return """
function(cls, desc) {
- var fields = desc[''] || [];
var generateGetterSetter = ${emitter.generateGetterSetterFunction};
- for (var i = 0; i < fields.length; i++) {
- generateGetterSetter(fields[i], desc);
+ var fields = desc[''];
+ var fields_array = fields ? fields.split(',') : [];
+ for (var i = 0; i < fields_array.length; i++) {
+ generateGetterSetter(fields_array[i], desc);
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
for (var method in desc) {
- if (method !== '') {
+ if (method) { """/* Short version of: if (method != '') */"""
if (hasOwnProperty.call(desc, method)) {
$dynamicName(method)[cls] = desc[method];
}
@@ -115,7 +108,7 @@
}
void generateNativeLiteral(ClassElement classElement) {
- String quotedNative = classElement.nativeName.slowToString();
+ String quotedNative = classElement.nativeTagInfo.slowToString();
String nativeCode = quotedNative.substring(2, quotedNative.length - 1);
String className = backend.namer.getName(classElement);
nativeBuffer.add(className);
@@ -142,8 +135,8 @@
return identical(quotedName[1], '@');
}
- String toNativeName(ClassElement cls) {
- String quotedName = cls.nativeName.slowToString();
+ String toNativeTag(ClassElement cls) {
+ String quotedName = cls.nativeTagInfo.slowToString();
if (isNativeGlobal(quotedName)) {
// Global object, just be like the other types for now.
return quotedName.substring(3, quotedName.length - 1);
@@ -156,7 +149,7 @@
nativeClasses.add(classElement);
assert(classElement.backendMembers.isEmpty);
- String quotedName = classElement.nativeName.slowToString();
+ String quotedName = classElement.nativeTagInfo.slowToString();
if (isNativeLiteral(quotedName)) {
generateNativeLiteral(classElement);
// The native literal kind needs to be dealt with specially when
@@ -168,7 +161,7 @@
CodeBuffer getterSetterBuffer = new CodeBuffer();
CodeBuffer methodBuffer = new CodeBuffer();
- emitter.emitClassFields(classElement, fieldBuffer, false);
+ emitter.emitClassFields(classElement, fieldBuffer, false, isNative: true);
emitter.emitClassGettersSetters(classElement, getterSetterBuffer, false);
emitter.emitInstanceMembers(classElement, methodBuffer, false);
@@ -178,8 +171,8 @@
return;
}
- String nativeName = toNativeName(classElement);
- nativeBuffer.add("$defineNativeClassName('$nativeName', ");
+ String nativeTag = toNativeTag(classElement);
+ nativeBuffer.add("$defineNativeClassName('$nativeTag', ");
nativeBuffer.add('{');
bool firstInMap = true;
if (!fieldBuffer.isEmpty) {
@@ -206,34 +199,47 @@
return result == null ? const<ClassElement>[] : result;
}
- void potentiallyConvertDartClosuresToJs(CodeBuffer code,
+ void potentiallyConvertDartClosuresToJs(List<js.Statement> statements,
FunctionElement member,
- List<String> argumentsBuffer) {
+ List<js.Parameter> stubParameters) {
FunctionSignature parameters = member.computeSignature(compiler);
Element converter =
compiler.findHelper(const SourceString('convertDartClosureToJS'));
String closureConverter = backend.namer.isolateAccess(converter);
+ Set<String> stubParameterNames = new Set<String>.from(
+ stubParameters.map((param) => param.name));
parameters.forEachParameter((Element parameter) {
String name = parameter.name.slowToString();
- // If [name] is not in [argumentsBuffer], then the parameter is
- // an optional parameter that was not provided for that stub.
- if (argumentsBuffer.indexOf(name) == -1) return;
- DartType type = parameter.computeType(compiler).unalias(compiler);
- if (type is FunctionType) {
- // The parameter type is a function type either directly or through
- // typedef(s).
- int arity = type.computeArity();
- code.add(' $name = $closureConverter($name, $arity);\n');
+ // If [name] is not in [stubParameters], then the parameter is an optional
+ // parameter that was not provided for this stub.
+ for (js.Parameter stubParameter in stubParameters) {
+ if (stubParameter.name == name) {
+ DartType type = parameter.computeType(compiler).unalias(compiler);
+ if (type is FunctionType) {
+ // The parameter type is a function type either directly or through
+ // typedef(s).
+ int arity = type.computeArity();
+
+ statements.add(
+ new js.ExpressionStatement(
+ new js.Assignment(
+ new js.VariableUse(name),
+ new js.VariableUse(closureConverter)
+ .callWith([new js.VariableUse(name),
+ new js.LiteralNumber('$arity')]))));
+ break;
+ }
+ }
}
});
}
- String generateParameterStub(Element member,
- String invocationName,
- String stubParameters,
- List<String> argumentsBuffer,
- int indexOfLastOptionalArgumentInParameters,
- CodeBuffer buffer) {
+ List<js.Statement> generateParameterStubStatements(
+ Element member,
+ String invocationName,
+ List<js.Parameter> stubParameters,
+ List<js.Expression> argumentsBuffer,
+ int indexOfLastOptionalArgumentInParameters) {
// The target JS function may check arguments.length so we need to
// make sure not to pass any unspecified optional arguments to it.
// For example, for the following Dart method:
@@ -243,37 +249,92 @@
// must be turned into a JS call to:
// foo(null, y).
- List<String> nativeArgumentsBuffer = argumentsBuffer.getRange(
- 0, indexOfLastOptionalArgumentInParameters + 1);
-
ClassElement classElement = member.enclosingElement;
- String nativeName = classElement.nativeName.slowToString();
- String nativeArguments = Strings.join(nativeArgumentsBuffer, ",");
+ //String nativeTagInfo = classElement.nativeName.slowToString();
+ String nativeTagInfo = classElement.nativeTagInfo.slowToString();
- CodeBuffer code = new CodeBuffer();
- potentiallyConvertDartClosuresToJs(code, member, argumentsBuffer);
+ List<js.Statement> statements = <js.Statement>[];
+ potentiallyConvertDartClosuresToJs(statements, member, stubParameters);
+
+ String target;
+ List<js.Expression> arguments;
if (!nativeMethods.contains(member)) {
- // When calling a method that has a native body, we call it
- // with our calling conventions.
- String arguments = Strings.join(argumentsBuffer, ",");
- code.add(' return this.${backend.namer.getName(member)}($arguments)');
+ // When calling a method that has a native body, we call it with our
+ // calling conventions.
+ target = backend.namer.getName(member);
+ arguments = argumentsBuffer;
} else {
- // When calling a JS method, we call it with the native name.
- String name = redirectingMethods[member];
- if (name == null) name = member.name.slowToString();
- code.add(' return this.$name($nativeArguments);');
+ // When calling a JS method, we call it with the native name, and only the
+ // arguments up until the last one provided.
+ target = member.nativeName();
+ arguments = argumentsBuffer.getRange(
+ 0, indexOfLastOptionalArgumentInParameters + 1);
}
+ statements.add(
+ new js.Return(
+ new js.VariableUse('this').dot(target).callWith(arguments)));
- if (isNativeLiteral(nativeName) || !overriddenMethods.contains(member)) {
+ if (isNativeLiteral(nativeTagInfo) || !overriddenMethods.contains(member)) {
// Call the method directly.
- buffer.add(code.toString());
+ return statements;
} else {
- native.generateMethodWithPrototypeCheck(
- compiler, buffer, invocationName, code.toString(), stubParameters);
+ return <js.Statement>[
+ generateMethodBodyWithPrototypeCheck(
+ invocationName, new js.Block(statements), stubParameters)];
}
}
+ // If a method is overridden, we must check if the prototype of 'this' has the
+ // method available. Otherwise, we may end up calling the method from the
+ // super class. If the method is not available, we make a direct call to
+ // Object.prototype.$methodName. This method will patch the prototype of
+ // 'this' to the real method.
+ js.Statement generateMethodBodyWithPrototypeCheck(
+ String methodName,
+ js.Statement body,
+ List<js.Parameter> parameters) {
+ return new js.If(
+ new js.VariableUse('Object')
+ .dot('getPrototypeOf')
+ .callWith([new js.VariableUse('this')])
+ .dot('hasOwnProperty')
+ .callWith([new js.LiteralString("'$methodName'")]),
+ body,
+ new js.Block(
+ <js.Statement>[
+ new js.Return(
+ new js.VariableUse('Object')
+ .dot('prototype').dot(methodName).dot('call')
+ .callWith(
+ <js.Expression>[new js.VariableUse('this')]
+ ..addAll(parameters.map((param) =>
+ new js.VariableUse(param.name)))))
+ ]));
+ }
+
+ js.Block generateMethodBodyWithPrototypeCheckForElement(
+ FunctionElement element,
+ js.Block body,
+ List<js.Parameter> parameters) {
+ String methodName;
+ Namer namer = backend.namer;
+ if (element.kind == ElementKind.FUNCTION) {
+ methodName = namer.instanceMethodName(element);
+ } else if (element.kind == ElementKind.GETTER) {
+ methodName = namer.getterName(element.getLibrary(), element.name);
+ } else if (element.kind == ElementKind.SETTER) {
+ methodName = namer.setterName(element.getLibrary(), element.name);
+ } else {
+ compiler.internalError('unexpected kind: "${element.kind}"',
+ element: element);
+ }
+
+ return new js.Block(
+ [generateMethodBodyWithPrototypeCheck(methodName, body, parameters)]);
+ }
+
+
void emitDynamicDispatchMetadata() {
if (classesWithDynamicDispatch.isEmpty) return;
int length = classesWithDynamicDispatch.length;
@@ -327,14 +388,14 @@
// Expression fragments for this set of cls keys.
List<js.Expression> expressions = <js.Expression>[];
// TODO: Remove if cls is abstract.
- List<String> subtags = [toNativeName(classElement)];
+ List<String> subtags = [toNativeTag(classElement)];
void walk(ClassElement cls) {
for (final ClassElement subclass in getDirectSubclasses(cls)) {
ClassElement tag = subclass;
js.Expression existing = tagDefns[tag];
if (existing == null) {
// [subclass] is still within the subtree between dispatch classes.
- subtags.add(toNativeName(tag));
+ subtags.add(toNativeTag(tag));
walk(subclass);
} else {
// [subclass] is one of the preorderDispatchClasses, so CSE this
@@ -404,7 +465,7 @@
new js.ArrayInitializer.from(
preorderDispatchClasses.map((cls) =>
new js.ArrayInitializer.from([
- new js.LiteralString("'${toNativeName(cls)}'"),
+ new js.LiteralString("'${toNativeTag(cls)}'"),
tagDefns[cls]])));
// $.dynamicSetMetadata(table);
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index 2064f09..a4545e6 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -23,11 +23,10 @@
InterfaceType interface = t;
ClassElement element = t.element;
if (element.typeVariables.isEmpty) return;
- bool isRaw = interface.typeArguments.isEmpty;
+ bool isRaw = interface.isRaw;
if (isRaw && !expandRawType) return;
builder.add('<');
- Iterable items =
- isRaw ? element.typeVariables : interface.typeArguments;
+ Iterable items = interface.typeArguments;
var stringify = isRaw ? (_) => 'dynamic' : (type) => type.toString();
bool first = true;
for (var item in items) {
@@ -49,7 +48,7 @@
static bool hasTypeArguments(DartType type) {
if (type is InterfaceType) {
InterfaceType interfaceType = type;
- return !interfaceType.typeArguments.isEmpty;
+ return !interfaceType.isRaw;
}
return false;
}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
index c87e763..5ac5b19 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
@@ -23,15 +23,10 @@
* to emit a call to an intercepted method, that is a method that is
* defined in an interceptor class.
*/
-getInterceptor(object) {
- if (object is String) return const JSString();
- if (isJsArray(object)) return const JSArray();
- if (object is int) return const JSInt();
- if (object is double) return const JSDouble();
- if (object is bool) return const JSBool();
- if (object == null) return const JSNull();
- if (JS('String', 'typeof #', object) == 'function') return const JSFunction();
- return const ObjectInterceptor();
+getInterceptor() {
+ // This is a magic method: the compiler does specialization of it
+ // depending on the uses of intercepted methods and instantiated
+ // primitive types.
}
/**
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index a253935..796bd98 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -87,6 +87,9 @@
patch static _readByte(int id) {
throw new UnsupportedError("RandomAccessFile._readByte");
}
+ patch static _read(int id, int bytes) {
+ throw new UnsupportedError("RandomAccessFile._read");
+ }
patch static _readList(int id, List<int> buffer, int offset, int bytes) {
throw new UnsupportedError("RandomAccessFile._readList");
}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
index 9c7b19d..c6356bf 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_patch.dart
@@ -188,9 +188,9 @@
}
void _nativeDetectEnvironment() {
- JS("void", r"# = $isWorker", isWorker);
- JS("void", r"# = $supportsWorkers", supportsWorkers);
- JS("void", r"# = typeof(window) == 'undefined'", fromCommandLine);
+ isWorker = JS("bool", r"$isWorker");
+ supportsWorkers = JS("bool", r"$supportsWorkers");
+ fromCommandLine = JS("bool", r"typeof(window) == 'undefined'");
}
void _nativeInitWorkerMessageHandler() {
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index ad8d98c..7b046c9 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -540,7 +540,7 @@
var performance = JS('var', 'window.performance');
if (performance != null &&
JS('bool', 'typeof #.webkitNow == "function"', performance)) {
- return JS('num', '#.webkitNow()', performance);
+ return (1000 * JS('num', '#.webkitNow()', performance)).floor();
}
}
return 1000 * dateNow();
@@ -557,7 +557,7 @@
if (end <= kMaxApply) {
subarray = array;
} else {
- subarray = JS('List<int>', r'array.slice(#, #)',
+ subarray = JS('=List', r'array.slice(#, #)',
i, i + kMaxApply < end ? i + kMaxApply : end);
}
result = JS('String', '# + String.fromCharCode.apply(#, #)',
@@ -972,9 +972,6 @@
*
* Some native exceptions are mapped to new Dart instances, others are
* returned unmodified.
- *
- * TODO(erikcorry): Fix this to produce consistent result regardless of
- * minification.
*/
unwrapException(ex) {
// Note that we are checking if the object has the property. If it
@@ -1223,6 +1220,23 @@
}
/**
+ * A metadata annotation placed on native methods and fields of native classes
+ * to specify the JavaScript name.
+ *
+ * This example declares a Dart field + getter + setter called `$dom_title` that
+ * corresponds to the JavaScript property `title`.
+ *
+ * class Docmument native "*Foo" {
+ * @JSName('title')
+ * String $dom_title;
+ * }
+ */
+class JSName {
+ final String name;
+ const JSName(this.name);
+}
+
+/**
* Represents the type of Null. The compiler treats this specially.
* TODO(lrn): Null should be defined in core. It's a class, like int.
* It just happens to act differently in assignability tests and,
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
index c8bb16c..d45df32 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
@@ -49,11 +49,18 @@
List<String> split(Pattern pattern) {
checkNull(pattern);
- return stringSplitUnchecked(this, pattern);
+ if (pattern is String) {
+ return JS('JSArray', r'#.split(#)', this, pattern);
+ } else if (pattern is JSSyntaxRegExp) {
+ var re = regExpGetNative(pattern);
+ return JS('JSArray', r'#.split(#)', this, re);
+ } else {
+ throw "String.split(Pattern) UNIMPLEMENTED";
+ }
}
List<String> splitChars() {
- return JS('List', r'#.split("")', this);
+ return JS('JSArray', r'#.split("")', this);
}
bool startsWith(String other) {
diff --git a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
index 98eea02..46d81be 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
@@ -118,6 +118,10 @@
JS('var', '#[#] = #', array, index, value);
}
+propertyGet(var object, String property) {
+ return JS('var', '#[#]', object, property);
+}
+
void propertySet(var object, String property, var value) {
JS('var', '#[#] = #', object, property, value);
}
@@ -201,31 +205,21 @@
String name,
var methods,
List arguments) {
- // The tag is related to the class name. E.g. the dart:html class
- // '_ButtonElement' has the tag 'HTMLButtonElement'. TODO(erikcorry): rename
- // getTypeNameOf to getTypeTag.
String tag = getTypeNameOf(obj);
- var hasOwnProperty = JS('var', 'Object.prototype.hasOwnProperty');
- var method = lookupDynamicClass(hasOwnProperty, methods, tag);
+ var method = JS('var', '#[#]', methods, tag);
if (method == null && _dynamicMetadata != null) {
- // Look at the inheritance data, getting the class tags and using them
- // to check the methods table for this method name.
for (int i = 0; i < arrayLength(_dynamicMetadata); i++) {
MetaInfo entry = arrayGet(_dynamicMetadata, i);
- if (JS('bool', '#.call(#, #)', hasOwnProperty, entry._set, tag)) {
- method = lookupDynamicClass(hasOwnProperty, methods, entry._tag);
- // Stop if we found it in the methods array.
+ if (JS('bool', '#', propertyGet(entry._set, tag))) {
+ method = propertyGet(methods, entry._tag);
if (method != null) break;
}
}
}
- // If we didn't find the method then look up in the Dart Object class, using
- // getTypeNameOf in case the minifier has renamed Object.
if (method == null) {
- String nameOfObjectClass = getTypeNameOf(const Object());
- method = lookupDynamicClass(hasOwnProperty, methods, nameOfObjectClass);
+ method = propertyGet(methods, 'Object');
}
var proto = JS('var', 'Object.getPrototypeOf(#)', obj);
@@ -245,24 +239,13 @@
proto, name, name);
}
- if (JS('bool', '!#.call(#, #)', hasOwnProperty, proto, name)) {
+ if (JS('bool', '!#.hasOwnProperty(#)', proto, name)) {
defineProperty(proto, name, method);
}
return JS('var', '#.apply(#, #)', method, obj, arguments);
}
-// For each method name and class inheritance subtree, we use an ordinary JS
-// object as a hash map to store the method for each class. Entries are added
-// in native_emitter.dart (see dynamicName). In order to avoid the class names
-// clashing with the method names on Object.prototype (needed for native
-// objects) we must always use hasOwnProperty.
-var lookupDynamicClass(var hasOwnProperty, var methods, String className) {
- return JS('bool', '#.call(#, #)', hasOwnProperty, methods, className) ?
- JS('var', '#[#]', methods, className) :
- null;
-}
-
/**
* Code for doing the dynamic dispatch on JavaScript prototypes that are not
* available at compile-time. Each property of a native Dart class
@@ -290,10 +273,7 @@
var methods = JS('var', '{}');
// If there is a method attached to the Dart Object class, use it as
// the method to call in case no method is registered for that type.
- var dartMethod =
- JS('var', 'Object.getPrototypeOf(#)[#]', const Object(), name);
- // Take the method from the Dart Object class if we didn't find it yet and it
- // is there.
+ var dartMethod = JS('var', 'Object.getPrototypeOf(#)[#]', const Object(), name);
if (dartMethod != null) propertySet(methods, 'Object', dartMethod);
var bind = JS('var',
diff --git a/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
index 70580df..e3da2be 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/string_helper.dart
@@ -122,17 +122,6 @@
}
}
-stringSplitUnchecked(receiver, pattern) {
- if (pattern is String) {
- return JS('=List', r'#.split(#)', receiver, pattern);
- } else if (pattern is JSSyntaxRegExp) {
- var re = regExpGetNative(pattern);
- return JS('=List', r'#.split(#)', receiver, re);
- } else {
- throw "String.split(Pattern) UNIMPLEMENTED";
- }
-}
-
stringJoinUnchecked(array, separator) {
return JS('String', r'#.join(#)', array, separator);
}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 5d4f253..a5ee505 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -524,7 +524,7 @@
_ensureMembers();
return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
_members,
- (MemberMirror member) => member is MethodMirror);
+ (MemberMirror member) => member is MethodMirror ? member : null);
}
Map<String, MethodMirror> get getters {
@@ -532,7 +532,8 @@
return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
_members,
(MemberMirror member) =>
- member is MethodMirror && (member as MethodMirror).isGetter);
+ member is MethodMirror && (member as MethodMirror).isGetter ?
+ member : null);
}
Map<String, MethodMirror> get setters {
@@ -540,14 +541,15 @@
return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
_members,
(MemberMirror member) =>
- member is MethodMirror && (member as MethodMirror).isSetter);
+ member is MethodMirror && (member as MethodMirror).isSetter ?
+ member : null);
}
Map<String, VariableMirror> get variables {
_ensureMembers();
return new AsFilteredImmutableMap<String, MemberMirror, VariableMirror>(
_members,
- (MemberMirror member) => member is VariableMirror);
+ (MemberMirror member) => member is VariableMirror ? member : null);
}
}
@@ -1169,11 +1171,13 @@
List<TypeMirror> get typeArguments {
if (_typeArguments == null) {
_typeArguments = <TypeMirror>[];
- Link<DartType> type = _interfaceType.typeArguments;
- while (type != null && type.head != null) {
- _typeArguments.add(_convertTypeToTypeMirror(mirrors, type.head,
- mirrors.compiler.types.dynamicType));
- type = type.tail;
+ if (!_interfaceType.isRaw) {
+ Link<DartType> type = _interfaceType.typeArguments;
+ while (type != null && type.head != null) {
+ _typeArguments.add(_convertTypeToTypeMirror(mirrors, type.head,
+ mirrors.compiler.types.dynamicType));
+ type = type.tail;
+ }
}
}
return _typeArguments;
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 8de208f..3e37ed3 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -35,15 +35,18 @@
/// Initial entry point to native enqueuer.
void processNativeClasses(Collection<LibraryElement> libraries) {}
+ /// Notification of a main Enqueuer worklist element. For methods, adds
+ /// information from metadata attributes, and computes types instantiated due
+ /// to calling the method.
void registerElement(Element element) {}
- /// Method is a member of a native class.
- void registerMethod(Element method) {}
+ /// Notification of native field. Adds information from metadata attributes.
+ void registerField(Element field) {}
- /// Compute types instantiated due to getting a native field.
+ /// Computes types instantiated due to getting a native field.
void registerFieldLoad(Element field) {}
- /// Compute types instantiated due to setting a native field.
+ /// Computes types instantiated due to setting a native field.
void registerFieldStore(Element field) {}
/**
@@ -93,6 +96,7 @@
ClassElement _annotationCreatesClass;
ClassElement _annotationReturnsClass;
+ ClassElement _annotationJsNameClass;
/// Subclasses of [NativeEnqueuerBase] are constructed by the backend.
NativeEnqueuerBase(this.world, this.compiler, this.enableLiveTypeAnalysis);
@@ -122,16 +126,22 @@
}
ClassElement get annotationCreatesClass {
- if (_annotationCreatesClass == null) findAnnotationClasses();
+ findAnnotationClasses();
return _annotationCreatesClass;
}
ClassElement get annotationReturnsClass {
- if (_annotationReturnsClass == null) findAnnotationClasses();
+ findAnnotationClasses();
return _annotationReturnsClass;
}
+ ClassElement get annotationJsNameClass {
+ findAnnotationClasses();
+ return _annotationJsNameClass;
+ }
+
void findAnnotationClasses() {
+ if (_annotationCreatesClass != null) return;
ClassElement find(name) {
Element e = compiler.findHelper(name);
if (e == null || e is! ClassElement) {
@@ -141,8 +151,41 @@
}
_annotationCreatesClass = find(const SourceString('Creates'));
_annotationReturnsClass = find(const SourceString('Returns'));
+ _annotationJsNameClass = find(const SourceString('JSName'));
}
+ /// Returns the JSName annotation string or `null` if no JSName annotation is
+ /// present.
+ String findJsNameFromAnnotation(Element element) {
+ String name = null;
+ ClassElement annotationClass = annotationJsNameClass;
+ for (Link<MetadataAnnotation> link = element.metadata;
+ !link.isEmpty;
+ link = link.tail) {
+ MetadataAnnotation annotation = link.head.ensureResolved(compiler);
+ var value = annotation.value;
+ if (value is! ConstructedConstant) continue;
+ if (value.type is! InterfaceType) continue;
+ if (!identical(value.type.element, annotationClass)) continue;
+
+ var fields = value.fields;
+ // TODO(sra): Better validation of the constant.
+ if (fields.length != 1 || fields[0] is! StringConstant) {
+ PartialMetadataAnnotation partial = annotation;
+ compiler.cancel(
+ 'Annotations needs one string: ${partial.parseNode(compiler)}');
+ }
+ String specString = fields[0].toDartString().slowToString();
+ if (name == null) {
+ name = specString;
+ } else {
+ PartialMetadataAnnotation partial = annotation;
+ compiler.cancel(
+ 'Too many JSName annotations: ${partial.parseNode(compiler)}');
+ }
+ }
+ return name;
+ }
enqueueClass(ClassElement classElement, cause) {
assert(unusedClasses.contains(classElement));
@@ -179,11 +222,20 @@
}
registerElement(Element element) {
- if (element.isFunction()) return registerMethod(element);
+ if (element.isFunction() || element.isGetter() || element.isSetter()) {
+ return registerMethod(element);
+ }
+ }
+
+ registerField(Element element) {
+ if (element.enclosingElement.isNative()) {
+ setNativeName(element);
+ }
}
registerMethod(Element method) {
if (isNativeMethod(method)) {
+ setNativeName(method);
processNativeBehavior(
NativeBehavior.ofMethod(method, compiler),
method);
@@ -191,6 +243,14 @@
}
}
+ /// Sets the native name of [element], either from an annotation, or
+ /// defaulting to the Dart name.
+ void setNativeName(Element element) {
+ String name = findJsNameFromAnnotation(element);
+ if (name == null) name = element.name.slowToString();
+ element.setNative(name);
+ }
+
bool isNativeMethod(Element element) {
if (!element.getLibrary().canUseNative) return false;
// Native method?
@@ -236,7 +296,7 @@
}
assert(type is DartType);
enqueueUnusedClassesMatching(
- (nativeClass) => compiler.types.isSubtype(nativeClass.type, type),
+ (nativeClass) => compiler.types.isSubtype(nativeClass.thisType, type),
cause,
'subtypeof($type)');
}
@@ -357,7 +417,8 @@
'dart/tests/compiler/dart2js_native')
|| libraryName == 'dart:isolate'
|| libraryName == 'dart:html'
- || libraryName == 'dart:svg') {
+ || libraryName == 'dart:svg'
+ || libraryName == 'dart:web_audio') {
library.canUseNative = true;
}
}
@@ -666,15 +727,15 @@
}
SourceString checkForNativeClass(ElementListener listener) {
- SourceString nativeName;
+ SourceString nativeTagInfo;
Node node = listener.nodes.head;
if (node != null
&& node.asIdentifier() != null
&& node.asIdentifier().source.stringValue == 'native') {
- nativeName = node.asIdentifier().token.next.value;
+ nativeTagInfo = node.asIdentifier().token.next.value;
listener.popNode();
}
- return nativeName;
+ return nativeTagInfo;
}
bool isOverriddenMethod(FunctionElement element,
@@ -693,7 +754,6 @@
void handleSsaNative(SsaBuilder builder, Expression nativeBody) {
Compiler compiler = builder.compiler;
FunctionElement element = builder.work.element;
- element.setNative();
NativeEmitter nativeEmitter = builder.emitter.nativeEmitter;
// If what we're compiling is a getter named 'typeName' and the native
// class is named 'DOMType', we generate a call to the typeNameOf
@@ -723,22 +783,23 @@
}
// Check which pattern this native method follows:
- // 1) foo() native; hasBody = false, isRedirecting = false
- // 2) foo() native "bar"; hasBody = false, isRedirecting = true
- // 3) foo() native "return 42"; hasBody = true, isRedirecting = false
+ // 1) foo() native;
+ // hasBody = false, isRedirecting = false
+ // 2) foo() native "bar";
+ // hasBody = false, isRedirecting = true, no longer supported.
+ // 3) foo() native "return 42";
+ // hasBody = true, isRedirecting = false
bool hasBody = false;
- bool isRedirecting = false;
- String nativeMethodName = element.name.slowToString();
+ assert(element.isNative());
+ String nativeMethodName = element.nativeName();
if (nativeBody != null) {
LiteralString jsCode = nativeBody.asLiteralString();
String str = jsCode.dartString.slowToString();
if (nativeRedirectionRegExp.hasMatch(str)) {
- nativeMethodName = str;
- isRedirecting = true;
- nativeEmitter.addRedirectingMethod(element, nativeMethodName);
- } else {
- hasBody = true;
+ compiler.cancel("Deprecated syntax, use @JSName('name') instead.",
+ node: nativeBody);
}
+ hasBody = true;
}
if (!hasBody) {
@@ -808,47 +869,3 @@
builder.push(new HForeign.statement(jsCode.dartString, <HInstruction>[]));
}
}
-
-void generateMethodWithPrototypeCheckForElement(Compiler compiler,
- StringBuffer buffer,
- FunctionElement element,
- String code,
- String parameters) {
- String methodName;
- JavaScriptBackend backend = compiler.backend;
- Namer namer = backend.namer;
- if (element.kind == ElementKind.FUNCTION) {
- methodName = namer.instanceMethodName(element);
- } else if (element.kind == ElementKind.GETTER) {
- methodName = namer.getterName(element.getLibrary(), element.name);
- } else if (element.kind == ElementKind.SETTER) {
- methodName = namer.setterName(element.getLibrary(), element.name);
- } else {
- compiler.internalError('unexpected kind: "${element.kind}"',
- element: element);
- }
-
- generateMethodWithPrototypeCheck(
- compiler, buffer, methodName, code, parameters);
-}
-
-
-// If a method is overridden, we must check if the prototype of
-// 'this' has the method available. Otherwise, we may end up
-// calling the method from the super class. If the method is not
-// available, we make a direct call to Object.prototype.$methodName.
-// This method will patch the prototype of 'this' to the real method.
-void generateMethodWithPrototypeCheck(Compiler compiler,
- StringBuffer buffer,
- String methodName,
- String code,
- String parameters) {
- buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty");
- buffer.add("('$methodName')) {\n");
- buffer.add(" $code");
- buffer.add(" } else {\n");
- buffer.add(" return Object.prototype.$methodName.call(this");
- buffer.add(parameters == '' ? '' : ', $parameters');
- buffer.add(");\n");
- buffer.add(" }\n");
-}
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 713a03c..6b578ce 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -644,7 +644,7 @@
ResolverVisitor visitor =
visitorFor(annotation.annotatedElement.enclosingElement);
node.accept(visitor);
- annotation.value = compiler.constantHandler.compileNodeWithDefinitions(
+ annotation.value = compiler.metadataHandler.compileNodeWithDefinitions(
node, visitor.mapping, isConst: true);
annotation.resolutionState = STATE_DONE;
@@ -1038,7 +1038,7 @@
TypeResolver(this.compiler);
- bool anyMalformedTypesInThere(Link<DartType> list) {
+ bool anyMalformedTypes(Link<DartType> list) {
for (Link<DartType> link = list;
!link.isEmpty;
link = link.tail) {
@@ -1136,20 +1136,36 @@
// Use the canonical type if it has no type parameters.
type = cls.computeType(compiler);
} else {
- // In checked mode malformed-ness of the type argument bubbles up.
- if (anyMalformedTypesInThere(arguments) &&
- compiler.enableTypeAssertions) {
- type = new MalformedType(
- new MalformedTypeElement(node, element));
+ if (anyMalformedTypes(arguments)) {
+ // Build interface type (with malformed arguments in it) and
+ // call [whenResolved] to let [ConstructorResolver] create
+ // constructor selectors, which are used by
+ // [SsaBuilder.visitNewSend] to figure out what class needs
+ // to be built.
+ whenResolved(node,
+ new InterfaceType(cls.declaration, arguments));
+ // Return malformed type element below so that
+ // [ConstructorResolver.visitTypeAnnotation] gets [:MalformedType:]
+ // and can map (via resolver.mapping) NewExpression node to
+ // this malformed type.
+ // [SsaBuilder.visitNewExpression] picks up the fact that
+ // NewExpression is mapped to malformed type and generates
+ // runtime error in checked mode.
+ type = new MalformedType(new MalformedTypeElement(node, element));
+ return type;
} else {
- type = new InterfaceType(cls.declaration, arguments);
+ if (arguments.isEmpty) {
+ // Use the canonical raw type if the class is generic.
+ type = cls.rawType;
+ } else {
+ type = new InterfaceType(cls.declaration, arguments);
+ }
}
}
} else if (element.isTypedef()) {
TypedefElement typdef = element;
// TODO(ahe): Should be [ensureResolved].
compiler.resolveTypedef(typdef);
- typdef.computeType(compiler);
Link<DartType> arguments = resolveTypeArguments(
node, typdef.typeVariables, inStaticContext,
scope, onFailure, whenResolved);
@@ -1157,7 +1173,11 @@
// Return the canonical type if it has no type parameters.
type = typdef.computeType(compiler);
} else {
- type = new TypedefType(typdef, arguments);
+ if (arguments.isEmpty) {
+ type = typdef.rawType;
+ } else {
+ type = new TypedefType(typdef, arguments);
+ }
}
} else if (element.isTypeVariable()) {
if (inStaticContext) {
@@ -1808,6 +1828,10 @@
// unqualified.
useElement(node, target);
registerSend(selector, target);
+ if (node.isPropertyAccess) {
+ // It might be the closurization of a method.
+ world.registerInstantiatedClass(compiler.functionClass);
+ }
return node.isPropertyAccess ? target : null;
}
@@ -1926,6 +1950,7 @@
}
visitLiteralBool(LiteralBool node) {
+ world.registerInstantiatedClass(compiler.boolClass);
}
visitLiteralString(LiteralString node) {
@@ -1933,6 +1958,7 @@
}
visitLiteralNull(LiteralNull node) {
+ world.registerInstantiatedClass(compiler.nullClass);
}
visitStringJuxtaposition(StringJuxtaposition node) {
@@ -1961,7 +1987,7 @@
void handleRedirectingFactoryBody(Return node) {
Element redirectionTarget = resolveRedirectingFactory(node);
var type = mapping.getType(node.expression);
- if (type is InterfaceType && !type.typeArguments.isEmpty) {
+ if (type is InterfaceType && !type.isRaw) {
unimplemented(node.expression, 'type arguments on redirecting factory');
}
useElement(node.expression, redirectionTarget);
@@ -1984,6 +2010,8 @@
}
constructor.defaultImplementation = redirectionTarget;
world.registerStaticUse(redirectionTarget);
+ world.registerInstantiatedClass(
+ redirectionTarget.enclosingElement.declaration);
}
visitThrow(Throw node) {
@@ -2549,8 +2577,7 @@
} else {
objectElement.ensureResolved(compiler);
}
- // TODO(ahe): This should be objectElement.computeType(...).
- element.supertype = new InterfaceType(objectElement);
+ element.supertype = objectElement.computeType(compiler);
}
assert(element.interfaces == null);
Link<DartType> interfaces = const Link<DartType>();
@@ -2779,7 +2806,11 @@
return visit(node.selector);
}
- SourceString visitIdentifier(Identifier node) => node.source;
+ SourceString visitIdentifier(Identifier node) {
+ // The variable is initialized to null.
+ resolver.world.registerInstantiatedClass(compiler.nullClass);
+ return node.source;
+ }
visitNodeList(NodeList node) {
for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
index d1e0099..ea84f75 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
@@ -68,8 +68,7 @@
tail.next = tail;
discardOpenLt();
while (!groupingStack.isEmpty) {
- BeginGroupToken begin = groupingStack.head;
- begin.endGroup = tail;
+ unmatchedBeginGroup(groupingStack.head);
groupingStack = groupingStack.tail;
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index e8a15aa..e4ca09e 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -747,7 +747,7 @@
void endClassDeclaration(int interfacesCount, Token beginToken,
Token extendsKeyword, Token implementsKeyword,
Token endToken) {
- SourceString nativeName = native.checkForNativeClass(this);
+ SourceString nativeTagInfo = native.checkForNativeClass(this);
NodeList interfaces =
makeNodeList(interfacesCount, implementsKeyword, null, ",");
TypeAnnotation supertype = popNode();
@@ -756,7 +756,7 @@
int id = idGenerator();
ClassElement element = new PartialClassElement(
name.source, beginToken, endToken, compilationUnitElement, id);
- element.nativeName = nativeName;
+ element.nativeTagInfo = nativeTagInfo;
pushElement(element);
rejectBuiltInIdentifier(name);
}
@@ -947,7 +947,11 @@
}
Token unexpected(Token token) {
- listener.cancel("unexpected token '${token.slowToString()}'", token: token);
+ String message = "unexpected token '${token.slowToString()}'";
+ if (token.info == BAD_INPUT_INFO) {
+ message = token.stringValue;
+ }
+ listener.cancel(message, token: token);
return skipToEof(token);
}
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index f7ea476..64f712f 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -849,6 +849,7 @@
token = parseMember(token);
++count;
}
+ expect('}', token);
listener.endClassBody(count, begin, token);
return token;
}
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
index 23f7c4bc..958db2f 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
@@ -34,6 +34,23 @@
tail.next = new StringToken.fromSource(info, value, tokenStart);
tail = tail.next;
}
+
+ void unmatchedBeginGroup(BeginGroupToken begin) {
+ SourceString error = new SourceString('unmatched "${begin.stringValue}"');
+ Token close =
+ new StringToken.fromSource(BAD_INPUT_INFO, error, begin.charOffset);
+ // We want to ensure that unmatched BeginGroupTokens are reported
+ // as errors. However, the rest of the parser assume the groups
+ // are well-balanced and will never look at the endGroup
+ // token. This is a nice property that allows us to skip quickly
+ // over correct code. By inserting an additional error token in
+ // the stream, we can keep ignoring endGroup tokens.
+ Token next =
+ new StringToken.fromSource(BAD_INPUT_INFO, error, begin.charOffset);
+ begin.endGroup = close;
+ close.next = next;
+ next.next = begin.next;
+ }
}
class SubstringWrapper implements SourceString {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index a768b50..573fc4f 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -141,7 +141,15 @@
/**
* The number of characters parsed by this token.
*/
- int get slowCharCount => slowToString().length;
+ int get slowCharCount {
+ if (info == BAD_INPUT_INFO) {
+ // This is a token that wraps around an error message. Return 1
+ // instead of the size of the length of the error message.
+ return 1;
+ } else {
+ return slowToString().length;
+ }
+ }
}
/**
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index cefee59..d76be36 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -202,7 +202,7 @@
new OptionalParameterTypes(signature.optionalParameterCount);
int index = 0;
signature.forEachOptionalParameter((Element parameter) {
- Constant defaultValue = compiler.compileVariable(parameter);
+ Constant defaultValue = builder.compileVariable(parameter);
HType type = HGraph.mapConstantTypeToSsaType(defaultValue);
defaultValueTypes.update(index, parameter.name, type);
index++;
@@ -988,6 +988,24 @@
}
/**
+ * Compiles compile-time constants. Never returns [:null:]. If the
+ * initial value is not a compile-time constants, it reports an
+ * internal error.
+ */
+ Constant compileConstant(VariableElement element) {
+ return compiler.constantHandler.compileConstant(element);
+ }
+
+ Constant compileVariable(VariableElement element) {
+ return compiler.constantHandler.compileVariable(element);
+ }
+
+ bool isLazilyInitialized(VariableElement element) {
+ Constant initialValue = compileVariable(element);
+ return initialValue == null;
+ }
+
+ /**
* Documentation wanted -- johnniwinther
*
* Invariant: [functionElement] must be an implementation element.
@@ -1524,8 +1542,7 @@
// }
// Fetch the original default value of [element];
- ConstantHandler handler = compiler.constantHandler;
- Constant constant = handler.compileVariable(element);
+ Constant constant = compileVariable(element);
HConstant defaultValue = constant == null
? graph.addConstantNull(constantSystem)
: graph.addConstant(constant);
@@ -2458,11 +2475,11 @@
if (element.isField() && !element.isAssignable()) {
// A static final or const. Get its constant value and inline it if
// the value can be compiled eagerly.
- value = compiler.compileVariable(element);
+ value = compileVariable(element);
}
if (value != null) {
stack.add(graph.addConstant(value));
- } else if (element.isField() && compiler.isLazilyInitialized(element)) {
+ } else if (element.isField() && isLazilyInitialized(element)) {
push(new HLazyStatic(element));
} else {
// TODO(5346): Try to avoid the need for calling [declaration] before
@@ -2741,14 +2758,14 @@
return pop();
}
- HInstruction compileConstant(Element parameter) {
+ HInstruction handleConstant(Element parameter) {
Constant constant;
TreeElements calleeElements =
compiler.enqueuer.resolution.getCachedElements(element);
if (calleeElements.isParameterChecked(parameter)) {
constant = SentinelConstant.SENTINEL;
} else {
- constant = compiler.compileConstant(parameter);
+ constant = compileConstant(parameter);
}
return graph.addConstant(constant);
}
@@ -2757,7 +2774,7 @@
list,
element,
compileArgument,
- compileConstant,
+ handleConstant,
compiler);
}
@@ -2802,7 +2819,7 @@
List<HInstruction> inputs = <HInstruction>[];
Set<ClassElement> interceptedClasses =
- interceptors.getInterceptedClassesOn(selector);
+ getInterceptedClassesOn(node, selector);
if (interceptedClasses != null) {
inputs.add(invokeInterceptor(interceptedClasses, receiver, node));
}
@@ -3060,6 +3077,11 @@
}
HInstruction analyzeTypeArgument(DartType argument, Node currentNode) {
+ if (argument == compiler.types.dynamicType) {
+ // Represent [dynamic] as [null].
+ return graph.addConstantNull(constantSystem);
+ }
+
// These variables are shared between invocations of the helper methods.
HInstruction typeInfo;
StringBuffer template = new StringBuffer();
@@ -3119,7 +3141,7 @@
} else if (type is InterfaceType) {
bool isFirstVariable = true;
InterfaceType interfaceType = type;
- bool hasTypeArguments = !interfaceType.typeArguments.isEmpty;
+ bool hasTypeArguments = !interfaceType.isRaw;
if (!isInQuotes) template.add("'");
template.add(backend.namer.getName(type.element));
if (hasTypeArguments) {
@@ -3157,9 +3179,11 @@
HInstruction newObject) {
if (!compiler.world.needsRti(type.element)) return;
List<HInstruction> inputs = <HInstruction>[];
- type.typeArguments.forEach((DartType argument) {
- inputs.add(analyzeTypeArgument(argument, currentNode));
- });
+ if (!type.isRaw) {
+ type.typeArguments.forEach((DartType argument) {
+ inputs.add(analyzeTypeArgument(argument, currentNode));
+ });
+ }
callSetRuntimeTypeInfo(type.element, inputs, newObject);
}
@@ -3194,7 +3218,7 @@
}
} else if (element.isGenerativeConstructor()) {
ClassElement cls = element.getEnclosingClass();
- return new HBoundedType.exact(cls.type);
+ return new HBoundedType.exact(cls.thisType);
} else {
return HType.UNKNOWN;
}
@@ -3229,7 +3253,7 @@
return;
}
if (compiler.world.needsRti(constructor.enclosingElement)) {
- if (!type.typeArguments.isEmpty) {
+ if (!type.isRaw) {
type.typeArguments.forEach((DartType argument) {
inputs.add(analyzeTypeArgument(argument, node));
});
@@ -3423,8 +3447,7 @@
visitNewExpression(NewExpression node) {
Element element = elements[node.send];
- if (!Elements.isErroneousElement(element) &&
- !Elements.isMalformedElement(element)) {
+ if (!Elements.isUnresolved(element)) {
FunctionElement function = element;
element = function.redirectionTarget;
}
@@ -3446,12 +3469,15 @@
ConstantHandler handler = compiler.constantHandler;
Constant constant = handler.compileNodeWithDefinitions(node, elements);
stack.add(graph.addConstant(constant));
- } else if (Elements.isMalformedElement(element)) {
- Message message =
- MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message([element]);
- generateRuntimeError(node.send, message.toString());
} else {
- visitNewSend(node.send, elements.getType(node));
+ DartType dartType = elements.getType(node);
+ if (dartType.kind == TypeKind.MALFORMED_TYPE &&
+ compiler.enableTypeAssertions) {
+ Message message = MessageKind.MALFORMED_TYPE_REFERENCE.message([node]);
+ generateRuntimeError(node.send, message.toString());
+ } else {
+ visitNewSend(node.send, dartType);
+ }
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index d51850f..b704a11 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -73,7 +73,8 @@
FunctionElement element = work.element;
js.Block body;
ClassElement enclosingClass = element.getEnclosingClass();
- bool allowVariableMinification;
+ bool allowVariableMinification = !codegen.visitedForeignCode;
+
if (element.isInstanceMember()
&& enclosingClass.isNative()
&& native.isOverriddenMethod(
@@ -83,18 +84,13 @@
// and needs to know if the method is overridden.
nativeEmitter.overriddenMethods.add(element);
StringBuffer buffer = new StringBuffer();
- String codeString = prettyPrint(codegen.body).toString();
- String parametersString =
- Strings.join(codegen.parameterNames.values, ", ");
- native.generateMethodWithPrototypeCheckForElement(
- compiler, buffer, element, codeString, parametersString);
- js.Node nativeCode = new js.LiteralStatement(buffer.toString());
- body = new js.Block(<js.Statement>[nativeCode]);
- allowVariableMinification = false;
+ body =
+ nativeEmitter.generateMethodBodyWithPrototypeCheckForElement(
+ element, codegen.body, codegen.parameters);
} else {
body = codegen.body;
- allowVariableMinification = !codegen.visitedForeignCode;
}
+
js.Fun fun = buildJavaScriptFunction(element, codegen.parameters, body);
return prettyPrint(fun,
allowVariableMinification: allowVariableMinification);
@@ -1530,11 +1526,9 @@
}
void visitInterceptor(HInterceptor node) {
- Element element = backend.getInterceptorMethod;
- assert(element != null);
- world.registerStaticUse(element);
- js.VariableUse interceptor =
- new js.VariableUse(backend.namer.isolateAccess(element));
+ String name =
+ backend.registerSpecializedGetInterceptor(node.interceptedClasses);
+ js.VariableUse interceptor = new js.VariableUse(name);
use(node.receiver);
List<js.Expression> arguments = <js.Expression>[pop()];
push(new js.Call(interceptor, arguments), node);
@@ -1545,32 +1539,40 @@
js.Expression object = pop();
SourceString name = node.selector.name;
String methodName;
- List<js.Expression> arguments;
+ List<js.Expression> arguments = visitArguments(node.inputs);
Element target = node.element;
- // Avoid adding the generative constructor name to the list of
- // seen selectors.
- if (target != null && target.isGenerativeConstructorBody()) {
- methodName = name.slowToString();
- arguments = visitArguments(node.inputs);
- } else {
+ if (target != null) {
+ // Avoid adding the generative constructor name to the list of
+ // seen selectors.
+ if (target.isGenerativeConstructorBody()) {
+ methodName = name.slowToString();
+ } else if (target == backend.jsArrayAdd) {
+ methodName = 'push';
+ } else if (target == backend.jsArrayRemoveLast) {
+ methodName = 'pop';
+ } else if (target == backend.jsStringSplit) {
+ methodName = 'split';
+ // Split returns a List, so we make sure the backend knows the
+ // list class is instantiated.
+ world.registerInstantiatedClass(compiler.listClass);
+ } else if (target == backend.jsStringConcat) {
+ push(new js.Binary('+', object, arguments[0]), node);
+ return;
+ }
+ }
+
+ if (methodName == null) {
methodName = backend.namer.instanceMethodInvocationName(
node.selector.library, name, node.selector);
- arguments = visitArguments(node.inputs);
bool inLoop = node.block.enclosingLoopHeader != null;
- // Register this invocation to collect the types used at all call sites.
Selector selector = getOptimizedSelectorFor(node, node.selector);
- // TODO(ngeoffray): Remove the following restriction. Because
- // the second input of this interceptor call is the actual
- // receiver (the first is the interceptor), the backend gets
- // confused. We should pass a list of types instead of a node to
- // [registerDynamicInvocation].
- if (!node.isInterceptorCall) {
- backend.registerDynamicInvocation(node, selector, types);
- } else {
+ if (node.isInterceptorCall) {
backend.addInterceptedSelector(selector);
}
+ // Register this invocation to collect the types used at all call sites.
+ backend.registerDynamicInvocation(node, selector, types);
// If we don't know what we're calling or if we are calling a getter,
// we need to register that fact that we may be calling a closure
@@ -1644,6 +1646,7 @@
if (node.isInterceptorCall) {
backend.addInterceptedSelector(getter);
}
+ world.registerInstantiatedClass(compiler.functionClass);
}
visitInvokeClosure(HInvokeClosure node) {
@@ -1729,7 +1732,7 @@
// property should not be mangled.
push(new js.PropertyAccess.field(pop(), 'length'), node);
} else {
- String name = backend.namer.getName(node.element);
+ String name = _fieldPropertyName(node.element);
push(new js.PropertyAccess.field(pop(), name), node);
HType receiverHType = types[node.receiver];
DartType type = receiverHType.computeType(compiler);
@@ -1741,7 +1744,7 @@
}
visitFieldSet(HFieldSet node) {
- String name = backend.namer.getName(node.element);
+ String name = _fieldPropertyName(node.element);
DartType type = types[node.receiver].computeType(compiler);
if (type != null) {
// Field setters in the generative constructor body are handled in a
@@ -1757,9 +1760,13 @@
js.Expression receiver = pop();
use(node.value);
push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()),
- node);
+ node);
}
+ String _fieldPropertyName(Element element) => element.isNative()
+ ? element.nativeName()
+ : backend.namer.getName(element);
+
visitLocalGet(HLocalGet node) {
use(node.receiver);
}
@@ -1787,6 +1794,10 @@
}
push(new js.LiteralExpression.withData(code, data), node);
}
+ DartType type = types[node].computeType(compiler);
+ if (type != null) {
+ world.registerInstantiatedClass(type.element);
+ }
// TODO(sra): Tell world.nativeEnqueuer about the types created here.
}
@@ -1815,49 +1826,18 @@
}
void generateConstant(Constant constant) {
- Namer namer = backend.namer;
- // TODO(floitsch): should we use the ConstantVisitor here?
- if (!constant.isObject()) {
- if (constant.isBool()) {
- BoolConstant boolConstant = constant;
- push(newLiteralBool(boolConstant.value));
- } else if (constant.isNum()) {
- // TODO(floitsch): get rid of the code buffer.
- CodeBuffer buffer = new CodeBuffer();
- backend.emitter.writeConstantToBuffer(constant, buffer);
- push(new js.LiteralNumber(buffer.toString()));
- } else if (constant.isNull()) {
- push(new js.LiteralNull());
- } else if (constant.isString()) {
- // TODO(floitsch): get rid of the code buffer.
- CodeBuffer buffer = new CodeBuffer();
- backend.emitter.writeConstantToBuffer(constant, buffer);
- push(new js.LiteralString(buffer.toString()));
- } else if (constant.isFunction()) {
- FunctionConstant function = constant;
- world.registerStaticUse(function.element);
- push(new js.VariableUse(namer.isolateAccess(function.element)));
- } else if (constant.isSentinel()) {
- // TODO(floitsch): get rid of the code buffer.
- CodeBuffer buffer = new CodeBuffer();
- backend.emitter.writeConstantToBuffer(constant, buffer);
- push(new js.VariableUse(buffer.toString()));
- } else {
- compiler.internalError(
- "The compiler does not know how generate code for "
- "constant $constant");
- }
- } else {
- String name = namer.constantName(constant);
- js.VariableUse currentIsolateUse =
- new js.VariableUse(backend.namer.CURRENT_ISOLATE);
- push(new js.PropertyAccess.field(currentIsolateUse, name));
+ if (constant.isFunction()) {
+ FunctionConstant function = constant;
+ world.registerStaticUse(function.element);
}
+ push(backend.emitter.constantReference(constant));
}
visitConstant(HConstant node) {
assert(isGenerateAtUseSite(node));
generateConstant(node.constant);
+ DartType type = node.constant.computeType(compiler);
+ world.registerInstantiatedClass(type.element);
}
visitLoopBranch(HLoopBranch node) {
@@ -2091,20 +2071,20 @@
node.usedBy.forEach((HInstruction instr) {
if (instr is !HInvokeStatic) {
backend.registerNonCallStaticUse(node);
- } else if (!identical(instr.target, node)) {
- backend.registerNonCallStaticUse(node);
- } else {
- // If invoking the static is can still be passed as an argument as well
- // which will also be non call static use.
- for (int i = 1; i < node.inputs.length; i++) {
- if (identical(node.inputs, node)) {
- backend.registerNonCallStaticUse(node);
- break;
- }
+ if (node.element.isFunction()) {
+ world.registerInstantiatedClass(compiler.functionClass);
}
+ } else if (instr.target != node) {
+ backend.registerNonCallStaticUse(node);
}
});
- world.registerStaticUse(node.element);
+ Element element = node.element;
+ world.registerStaticUse(element);
+ ClassElement cls = element.getEnclosingClass();
+ if (element.isGenerativeConstructor()
+ || (element.isFactoryConstructor() && cls == compiler.listClass)) {
+ world.registerInstantiatedClass(cls);
+ }
push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
}
@@ -2159,6 +2139,7 @@
}
void visitLiteralList(HLiteralList node) {
+ world.registerInstantiatedClass(compiler.listClass);
generateArrayLiteral(node);
}
@@ -2423,15 +2404,19 @@
use(node.typeInfoCall);
int index = RuntimeTypeInformation.getTypeVariableIndex(typeVariable);
js.PropertyAccess field = new js.PropertyAccess.indexed(pop(), index);
- RuntimeTypeInformation rti = backend.rti;
- String typeName = rti.getStringRepresentation(arguments.head);
- js.Expression genericName = new js.LiteralString("'$typeName'");
- js.Binary eqTest = new js.Binary('===', field, genericName);
// Also test for 'undefined' in case the object does not have
// any type variable.
js.Prefix undefinedTest = new js.Prefix('!', field);
- result = new js.Binary(
- '&&', result, new js.Binary('||', undefinedTest, eqTest));
+ if (arguments.head == compiler.types.dynamicType) {
+ result = new js.Binary('&&', result, undefinedTest);
+ } else {
+ RuntimeTypeInformation rti = backend.rti;
+ String typeName = rti.getStringRepresentation(arguments.head);
+ js.Expression genericName = new js.LiteralString("'$typeName'");
+ js.Binary eqTest = new js.Binary('===', field, genericName);
+ result = new js.Binary(
+ '&&', result, new js.Binary('||', undefinedTest, eqTest));
+ }
arguments = arguments.tail;
}
push(result, node);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 2878379..b8144e3 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1509,6 +1509,7 @@
if (declaredType.slowToString() == 'double') return HType.DOUBLE;
if (declaredType.slowToString() == 'num') return HType.NUMBER;
if (declaredType.slowToString() == 'String') return HType.STRING;
+ if (declaredType.slowToString() == 'JSArray') return HType.READABLE_ARRAY;
return HType.UNKNOWN;
}
@@ -2370,7 +2371,7 @@
}
class HInterceptor extends HInstruction {
- final Set<ClassElement> interceptedClasses;
+ Set<ClassElement> interceptedClasses;
HInterceptor(this.interceptedClasses, HInstruction receiver)
: super(<HInstruction>[receiver]);
String toString() => 'interceptor on $interceptedClasses';
@@ -2379,9 +2380,16 @@
void prepareGvn(HTypeMap types) {
clearAllSideEffects();
+ setUseGvn();
}
int typeCode() => HInstruction.INTERCEPTOR_TYPECODE;
+ bool typeEquals(other) => other is HInterceptor;
+ bool dataEquals(HInterceptor other) {
+ return interceptedClasses == other.interceptedClasses
+ || (interceptedClasses.length == other.interceptedClasses.length
+ && interceptedClasses.containsAll(other.interceptedClasses));
+ }
}
/** An [HLazyStatic] is a static that is initialized lazily at first read. */
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index e0b8c41..995ac5b 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -39,12 +39,13 @@
new SsaConstantFolder(constantSystem, backend, work, types),
new SsaTypeConversionInserter(compiler),
new SsaTypePropagator(compiler, types),
- new SsaCheckInserter(backend, work, types, context.boundsChecked),
new SsaConstantFolder(constantSystem, backend, work, types),
+ new SsaCheckInserter(backend, work, types, context.boundsChecked),
new SsaRedundantPhiEliminator(),
new SsaDeadPhiEliminator(),
new SsaConstantFolder(constantSystem, backend, work, types),
new SsaTypePropagator(compiler, types),
+ new SsaReceiverSpecialization(compiler),
new SsaGlobalValueNumberer(compiler, types),
new SsaCodeMotion(),
new SsaValueRangeAnalyzer(constantSystem, types, work),
@@ -206,11 +207,59 @@
}
HInstruction handleInterceptorCall(HInvokeDynamic node) {
+ if (node is !HInvokeDynamicMethod) return;
HInstruction input = node.inputs[1];
if (input.isString(types)
&& node.selector.name == const SourceString('toString')) {
return node.inputs[1];
}
+ // Check if this call does not need to be intercepted.
+ HType type = types[input];
+ var interceptor = node.inputs[0];
+ if (interceptor is !HThis && !type.canBePrimitive()) {
+ // If the type can be null, and the intercepted method can be in
+ // the object class, keep the interceptor.
+ if (type.canBeNull()
+ && interceptor.interceptedClasses.contains(compiler.objectClass)) {
+ return node;
+ }
+ // Change the call to a regular invoke dynamic call.
+ return new HInvokeDynamicMethod(
+ node.selector, node.inputs.getRange(1, node.inputs.length - 1));
+ }
+
+ Selector selector = node.selector;
+ SourceString selectorName = selector.name;
+ Element target;
+ if (input.isExtendableArray(types)) {
+ if (selectorName == backend.jsArrayRemoveLast.name
+ && selector.argumentCount == 0) {
+ target = backend.jsArrayRemoveLast;
+ } else if (selectorName == backend.jsArrayAdd.name
+ && selector.argumentCount == 1
+ && selector.namedArgumentCount == 0
+ && !compiler.enableTypeAssertions) {
+ target = backend.jsArrayAdd;
+ }
+ } else if (input.isString(types)) {
+ if (selectorName == backend.jsStringSplit.name
+ && selector.argumentCount == 1
+ && selector.namedArgumentCount == 0
+ && node.inputs[2].isString(types)) {
+ target = backend.jsStringSplit;
+ } else if (selectorName == backend.jsStringConcat.name
+ && selector.argumentCount == 1
+ && selector.namedArgumentCount == 0
+ && node.inputs[2].isString(types)) {
+ target = backend.jsStringConcat;
+ }
+ }
+ if (target != null) {
+ HInvokeDynamicMethod result = new HInvokeDynamicMethod(
+ node.selector, node.inputs.getRange(1, node.inputs.length - 1));
+ result.element = target;
+ return result;
+ }
return node;
}
@@ -250,8 +299,13 @@
return node;
}
- HInstruction fromInterceptorToDynamicInvocation(HInvokeStatic node,
- Selector selector) {
+ /**
+ * Turns a primitive instruction (e.g. [HIndex], [HAdd], ...) into a
+ * [HInvokeDynamic] because we know the receiver is not a JS
+ * primitive object.
+ */
+ HInstruction fromPrimitiveInstructionToDynamicInvocation(HInvokeStatic node,
+ Selector selector) {
HBoundedType type = types[node.inputs[1]];
HInvokeDynamicMethod result = new HInvokeDynamicMethod(
selector,
@@ -281,7 +335,7 @@
HInstruction visitIndex(HIndex node) {
if (!node.receiver.canBePrimitive(types)) {
Selector selector = new Selector.index();
- return fromInterceptorToDynamicInvocation(node, selector);
+ return fromPrimitiveInstructionToDynamicInvocation(node, selector);
}
return node;
}
@@ -289,7 +343,7 @@
HInstruction visitIndexAssign(HIndexAssign node) {
if (!node.receiver.canBePrimitive(types)) {
Selector selector = new Selector.indexSet();
- return fromInterceptorToDynamicInvocation(node, selector);
+ return fromPrimitiveInstructionToDynamicInvocation(node, selector);
}
return node;
}
@@ -310,7 +364,7 @@
// The equals operation is being optimized in visitEquals.
&& node is! HEquals) {
Selector selector = new Selector.binaryOperator(operation.name);
- return fromInterceptorToDynamicInvocation(node, selector);
+ return fromPrimitiveInstructionToDynamicInvocation(node, selector);
}
return node;
}
@@ -656,24 +710,55 @@
}
return graph.addConstant(constantSystem.createString(folded, node.node));
}
+
+ HInstruction visitInterceptor(HInterceptor node) {
+ if (node.isConstant()) return node;
+ HType type = types[node.inputs[0]];
+ ClassElement constantInterceptor;
+ if (type.isInteger()) {
+ constantInterceptor = backend.jsIntClass;
+ } else if (type.isDouble()) {
+ constantInterceptor = backend.jsDoubleClass;
+ } else if (type.isBoolean()) {
+ constantInterceptor = backend.jsBoolClass;
+ } else if (type.isString()) {
+ constantInterceptor = backend.jsStringClass;
+ } else if (type.isArray()) {
+ constantInterceptor = backend.jsArrayClass;
+ } else if (type.isNull()) {
+ constantInterceptor = backend.jsIntClass;
+ } else if (type.isNumber()) {
+ Set<ClassElement> intercepted = node.interceptedClasses;
+ // If the method being intercepted is not defined in [int] or
+ // [double] we can safely use the number interceptor.
+ if (!intercepted.contains(compiler.intClass)
+ && !intercepted.contains(compiler.doubleClass)) {
+ constantInterceptor = backend.jsNumberClass;
+ }
+ }
+
+ if (constantInterceptor == null) return node;
+
+ ConstantHandler handler = compiler.constantHandler;
+ Constant constant = new ConstructedConstant(
+ constantInterceptor.computeType(compiler), <Constant>[]);
+ handler.registerCompileTimeConstant(constant);
+ return graph.addConstant(constant);
+ }
}
class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase {
final HTypeMap types;
- final ConstantSystem constantSystem;
final Set<HInstruction> boundsChecked;
final WorkItem work;
+ final JavaScriptBackend backend;
final String name = "SsaCheckInserter";
HGraph graph;
- Element lengthInterceptor;
- SsaCheckInserter(JavaScriptBackend backend,
+ SsaCheckInserter(this.backend,
this.work,
this.types,
- this.boundsChecked)
- : constantSystem = backend.constantSystem {
- lengthInterceptor = backend.jsArrayLength;
- }
+ this.boundsChecked);
void visitGraph(HGraph graph) {
this.graph = graph;
@@ -693,8 +778,8 @@
HInstruction receiver,
HInstruction index) {
bool isAssignable = !receiver.isFixedArray(types);
- HFieldGet length =
- new HFieldGet(lengthInterceptor, receiver, isAssignable: isAssignable);
+ HFieldGet length = new HFieldGet(
+ backend.jsArrayLength, receiver, isAssignable: isAssignable);
length.guaranteedType = HType.INTEGER;
types[length] = HType.INTEGER;
node.block.addBefore(node, length);
@@ -738,6 +823,14 @@
node.changeUse(node.index, index);
assert(node.isBuiltin(types));
}
+
+ void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
+ Element element = node.element;
+ if (element != backend.jsArrayRemoveLast) return;
+ if (boundsChecked.contains(node)) return;
+ insertBoundsCheck(
+ node, node.receiver, graph.addConstantInt(0, backend.constantSystem));
+ }
}
class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
@@ -1360,3 +1453,32 @@
});
}
}
+
+/**
+ * This phase specializes dominated uses of a call, where the call
+ * can give us some type information of what the receiver might be.
+ * For example, after a call to [:a.foo():], if [:foo:] is only
+ * in class [:A:], a can be of type [:A:].
+ */
+class SsaReceiverSpecialization extends HBaseVisitor
+ implements OptimizationPhase {
+ final String name = "SsaReceiverSpecialization";
+ final Compiler compiler;
+
+ SsaReceiverSpecialization(this.compiler);
+
+ void visitGraph(HGraph graph) {
+ visitDominatorTree(graph);
+ }
+
+ void visitInterceptor(HInterceptor interceptor) {
+ HInstruction receiver = interceptor.receiver;
+ for (var user in receiver.usedBy) {
+ if (user is HInterceptor && interceptor.dominates(user)) {
+ user.interceptedClasses = interceptor.interceptedClasses;
+ }
+ }
+ }
+
+ // TODO(ngeoffray): Also implement it for non-intercepted calls.
+}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 597ccf1..52a20e7 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -18,7 +18,7 @@
if (identical(element.kind, ElementKind.TYPE_VARIABLE)) {
// TODO(ngeoffray): Replace object type with [type].
return new HBoundedPotentialPrimitiveType(
- compiler.objectClass.computeType(compiler), canBeNull);
+ compiler.objectClass.computeType(compiler), canBeNull, true);
}
if (identical(element, compiler.intClass)) {
@@ -38,6 +38,9 @@
return new HBoundedPotentialPrimitiveNumberOrString(type, canBeNull);
} else if (Elements.isStringOnlySupertype(element, compiler)) {
return new HBoundedPotentialPrimitiveString(type, canBeNull);
+ } else if (identical(element, compiler.objectClass)) {
+ return new HBoundedPotentialPrimitiveType(
+ compiler.objectClass.computeType(compiler), canBeNull, true);
} else {
return canBeNull ? new HBoundedType.withNull(type)
: new HBoundedType.nonNull(type);
@@ -85,6 +88,7 @@
bool isPrimitive() => false;
bool isExact() => false;
bool isPrimitiveOrNull() => false;
+ bool isTop() => false;
bool canBePrimitive() => false;
bool canBeNull() => false;
@@ -218,6 +222,9 @@
if (other.isUnknown()) return HType.BOOLEAN_OR_NULL;
if (other.isBoolean()) return HType.BOOLEAN;
if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
+ if (other.isTop()) {
+ return other.canBeNull() ? this : HType.BOOLEAN;
+ }
if (other.canBeNull()) return HType.NULL;
return HType.CONFLICTING;
}
@@ -278,6 +285,9 @@
if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
+ if (other.isTop()) {
+ return other.canBeNull() ? this : HType.NUMBER;
+ }
if (other.canBeNull()) return HType.NULL;
return HType.CONFLICTING;
}
@@ -342,6 +352,9 @@
if (other.isDoubleOrNull()) return HType.NULL;
if (other.isNumber()) return HType.INTEGER;
if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL;
+ if (other.isTop()) {
+ return other.canBeNull() ? this : HType.INTEGER;
+ }
if (other.canBeNull()) return HType.NULL;
return HType.CONFLICTING;
}
@@ -410,6 +423,9 @@
if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
if (other.isNumber()) return HType.DOUBLE;
if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL;
+ if (other.isTop()) {
+ return other.canBeNull() ? this : HType.DOUBLE;
+ }
if (other.canBeNull()) return HType.NULL;
return HType.CONFLICTING;
}
@@ -525,6 +541,9 @@
if (other is HBoundedPotentialPrimitiveString) {
return other.canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
}
+ if (other.isTop()) {
+ return other.canBeNull() ? this : HType.STRING;
+ }
if (other.canBeNull()) return HType.NULL;
return HType.CONFLICTING;
}
@@ -679,8 +698,8 @@
final bool _canBeNull;
final bool _isExact;
- toString() {
- return 'BoundedType($type, $_canBeNull, $_isExact)';
+ String toString() {
+ return 'BoundedType($type, canBeNull: $_canBeNull, isExact: $_isExact)';
}
bool canBeNull() => _canBeNull;
@@ -764,15 +783,47 @@
}
class HBoundedPotentialPrimitiveType extends HBoundedType {
- const HBoundedPotentialPrimitiveType(DartType type, bool canBeNull)
+ final bool _isObject;
+ const HBoundedPotentialPrimitiveType(DartType type,
+ bool canBeNull,
+ this._isObject)
: super(type, canBeNull, false);
+
+ String toString() {
+ return 'BoundedPotentialPrimitiveType($type, canBeNull: $_canBeNull)';
+ }
+
bool canBePrimitive() => true;
+ bool isTop() => _isObject;
+
+ HType union(HType other, Compiler compiler) {
+ if (isTop()) {
+ // The union of the top type and another type is the top type.
+ if (!canBeNull() && other.canBeNull()) {
+ return new HBoundedPotentialPrimitiveType(type, true, true);
+ } else {
+ return this;
+ }
+ } else {
+ return super.union(other, compiler);
+ }
+ }
+
+ HType intersection(HType other, Compiler compiler) {
+ if (isTop()) {
+ // The intersection of the top type and any other type is the other type.
+ // TODO(ngeoffray): Also update the canBeNull information.
+ return other;
+ } else {
+ return super.intersection(other, compiler);
+ }
+ }
}
class HBoundedPotentialPrimitiveNumberOrString
extends HBoundedPotentialPrimitiveType {
const HBoundedPotentialPrimitiveNumberOrString(DartType type, bool canBeNull)
- : super(type, canBeNull);
+ : super(type, canBeNull, false);
HType union(HType other, Compiler compiler) {
if (other.isNumber()) return this;
@@ -812,7 +863,7 @@
class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType {
const HBoundedPotentialPrimitiveArray(DartType type, bool canBeNull)
- : super(type, canBeNull);
+ : super(type, canBeNull, false);
HType union(HType other, Compiler compiler) {
if (other.isString()) return HType.UNKNOWN;
@@ -840,7 +891,7 @@
class HBoundedPotentialPrimitiveString extends HBoundedPotentialPrimitiveType {
const HBoundedPotentialPrimitiveString(DartType type, bool canBeNull)
- : super(type, canBeNull);
+ : super(type, canBeNull, false);
bool isPrimitiveOrNull() => true;
@@ -878,17 +929,29 @@
}
class HTypeMap {
- Map<HInstruction, HType> _map;
+ // Approximately 85% of methods in the sample "swarm" have less than
+ // 32 instructions.
+ static const int INITIAL_SIZE = 32;
- HTypeMap() : _map = new Map<HInstruction, HType>();
+ List<HType> _list = new List<HType>()..length = INITIAL_SIZE;
operator [](HInstruction instruction) {
- HType result = _map[instruction];
+ HType result;
+ if (instruction.id < _list.length) result = _list[instruction.id];
if (result == null) return instruction.guaranteedType;
return result;
}
operator []=(HInstruction instruction, HType value) {
- _map[instruction] = value;
+ int length = _list.length;
+ int id = instruction.id;
+ if (length <= id) {
+ if (id + 1 < length * 2) {
+ _list.length = length * 2;
+ } else {
+ _list.length = id + 1;
+ }
+ }
+ _list[id] = value;
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index b192c23..c0c5de2 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -87,6 +87,11 @@
bool operator ==(other);
+ /**
+ * Is [: true :] if this type has no explict type arguments.
+ */
+ bool get isRaw => true;
+
DartType asRaw() => this;
}
@@ -256,15 +261,19 @@
DartType unalias(Compiler compiler) => this;
- int get hashCode => 1733;
+ int get hashCode => 1733 + 19 * element.hashCode;
- bool operator ==(other) => other is MalformedType;
+ bool operator ==(other) {
+ if (other is !MalformedType) return false;
+ if (!identical(element, other.element)) return false;
+ return true;
+ }
String toString() => name.slowToString();
}
class InterfaceType extends DartType {
- final Element element;
+ final ClassElement element;
final Link<DartType> typeArguments;
InterfaceType(this.element,
@@ -300,7 +309,7 @@
String toString() {
StringBuffer sb = new StringBuffer();
sb.add(name.slowToString());
- if (!typeArguments.isEmpty) {
+ if (!isRaw) {
sb.add('<');
typeArguments.printOn(sb, ', ');
sb.add('>');
@@ -325,10 +334,9 @@
return typeArguments == other.typeArguments;
}
- InterfaceType asRaw() {
- if (typeArguments.isEmpty) return this;
- return new InterfaceType(element);
- }
+ bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
+
+ InterfaceType asRaw() => element.rawType;
}
class FunctionType extends DartType {
@@ -445,7 +453,7 @@
String toString() {
StringBuffer sb = new StringBuffer();
sb.add(name.slowToString());
- if (!typeArguments.isEmpty) {
+ if (!isRaw) {
sb.add('<');
typeArguments.printOn(sb, ', ');
sb.add('>');
@@ -460,6 +468,10 @@
if (!identical(element, other.element)) return false;
return typeArguments == other.typeArguments;
}
+
+ bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
+
+ TypedefType asRaw() => element.rawType;
}
/**
@@ -477,7 +489,7 @@
final Compiler compiler;
// TODO(karlklose): should we have a class Void?
final VoidType voidType;
- final InterfaceType dynamicType;
+ final DynamicType dynamicType;
Types(Compiler compiler, ClassElement dynamicElement)
: this.with(compiler, dynamicElement,
@@ -488,7 +500,7 @@
LibraryElement library)
: voidType = new VoidType(new VoidElement(library)),
dynamicType = new DynamicType(dynamicElement) {
- dynamicElement.type = dynamicType;
+ dynamicElement.rawType = dynamicElement.thisType = dynamicType;
}
/** Returns true if t is a subtype of s */
@@ -505,7 +517,9 @@
if (t is VoidType) {
return false;
- } else if (t is MalformedType) {
+ } else if (t is MalformedType || s is MalformedType) {
+ // TODO(johnniwinther): Malformed types should be treated as dynamic and
+ // thus return true here.
return false;
} else if (t is InterfaceType) {
if (s is !InterfaceType) return false;
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index 1d8731d..3b2334c 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -94,6 +94,7 @@
ConcreteType union(ConcreteType other);
bool isUnkown();
+ bool isEmpty();
Set<BaseType> get baseTypes;
/**
@@ -109,6 +110,7 @@
class UnknownConcreteType implements ConcreteType {
const UnknownConcreteType();
bool isUnkown() => true;
+ bool isEmpty() => false;
bool operator ==(ConcreteType other) => identical(this, other);
Set<BaseType> get baseTypes =>
new Set<BaseType>.from([const UnknownBaseType()]);
@@ -131,6 +133,7 @@
UnionType(this.baseTypes);
bool isUnkown() => false;
+ bool isEmpty() => baseTypes.isEmpty;
bool operator ==(ConcreteType other) {
if (other is! UnionType) return false;
@@ -366,6 +369,14 @@
final Compiler compiler;
/**
+ * When true, the string litteral [:"__dynamic_for_test":] is inferred to
+ * have the unknown type.
+ */
+ // TODO(polux): get rid of this hack once we have a natural way of inferring
+ // the unknown type.
+ bool testMode = false;
+
+ /**
* Constants representing builtin base types. Initialized in [analyzeMain]
* and not in the constructor because the compiler elements are not yet
* populated.
@@ -479,9 +490,9 @@
/**
* Returns all the members with name [methodName].
*/
- List<FunctionElement> getMembersByName(SourceString methodName) {
+ List<Element> getMembersByName(SourceString methodName) {
// TODO(polux): make this faster!
- var result = new List<FunctionElement>();
+ var result = new List<Element>();
for (ClassElement cls in compiler.enqueuer.resolution.seenClasses) {
Element elem = cls.lookupLocalMember(methodName);
if (elem != null) {
@@ -601,13 +612,11 @@
ConcreteType result = new ConcreteType.empty();
Map<Element, ConcreteType> argumentMap =
associateArguments(function, argumentsTypes);
- argumentMap.forEach((Element parameter, ConcreteType type) {
- augmentParameterType(parameter, type);
- });
// if the association failed, this send will never occur or will fail
if (argumentMap == null) {
return new ConcreteType.empty();
}
+ argumentMap.forEach(augmentParameterType);
ConcreteTypeCartesianProduct product =
new ConcreteTypeCartesianProduct(receiverType, argumentMap);
for (ConcreteTypesEnvironment environment in product) {
@@ -1010,14 +1019,14 @@
}
ConcreteType analyzeSetNode(Node receiver, ConcreteType argumentType,
- SourceString source) {
+ SourceString name) {
ConcreteType receiverType = analyze(receiver);
- void augmentField(BaseType baseReceiverType, Element fieldOrSetter) {
- if (fieldOrSetter.isField()) {
- inferrer.augmentFieldType(fieldOrSetter, argumentType);
- } else {
- AbstractFieldElement abstractField = fieldOrSetter;
+ void augmentField(BaseType baseReceiverType, Element member) {
+ if (member.isField()) {
+ inferrer.augmentFieldType(member, argumentType);
+ } else if (member.isAbstractField()){
+ AbstractFieldElement abstractField = member;
FunctionElement setter = abstractField.setter;
// TODO(polux): A setter always returns void so there's no need to
// invalidate its callers even if it is called with new arguments.
@@ -1028,50 +1037,77 @@
inferrer.getSendReturnType(setter, baseReceiverType,
new ArgumentsTypes([argumentType], new Map()));
}
+ // since this is a sendSet we ignore non-fields
}
if (receiverType.isUnkown()) {
- for (FunctionElement member in inferrer.getMembersByName(source)) {
+ for (Element member in inferrer.getMembersByName(name)) {
+ if (!(member.isField() || member.isAbstractField())) continue;
Element classElem = member.getEnclosingClass();
BaseType baseReceiverType = new ClassBaseType(classElem);
augmentField(baseReceiverType, member);
}
} else {
- for (ClassBaseType baseReceiverType in receiverType.baseTypes) {
- Element member = baseReceiverType.element.lookupMember(source);
+ for (BaseType baseReceiverType in receiverType.baseTypes) {
+ if (!baseReceiverType.isClass()) continue;
+ ClassBaseType baseReceiverClassType = baseReceiverType;
+ Element member = baseReceiverClassType.element.lookupMember(name);
if (member != null) {
- augmentField(baseReceiverType, member);
+ augmentField(baseReceiverClassType, member);
}
}
}
return argumentType;
}
- SourceString canonicalizeCompoundOperator(String op) {
+ SourceString canonicalizeCompoundOperator(SourceString op) {
// TODO(ahe): This class should work on elements or selectors, not
// names. Otherwise, it is repeating work the resolver has
// already done (or should have done). In this case, the problem
// is that the resolver is not recording the selectors it is
// registering in registerBinaryOperator in
// ResolverVisitor.visitSendSet.
- if (op == '++') return const SourceString(r'+');
- else return const SourceString(r'-');
+ String stringValue = op.stringValue;
+ if (stringValue == '++') return const SourceString(r'+');
+ else if (stringValue == '--') return const SourceString(r'-');
+ else return Elements.mapToUserOperatorOrNull(op);
}
// TODO(polux): handle sendset as expression
ConcreteType visitSendSet(SendSet node) {
- Identifier selector = node.selector;
- final name = node.assignmentOperator.source.stringValue;
+ // Operator []= has a different behaviour than other send sets: it is
+ // actually a send whose return type is that of its second argument.
+ if (node.selector.asIdentifier().source.stringValue == '[]') {
+ ConcreteType receiverType = analyze(node.receiver);
+ ArgumentsTypes argumentsTypes = analyzeArguments(node.arguments);
+ analyzeDynamicSend(receiverType, const SourceString('[]='),
+ argumentsTypes);
+ return argumentsTypes.positional[1];
+ }
+
+ // All other operators have a single argument (++ and -- have an implicit
+ // argument: 1). We will store its type in argumentType.
ConcreteType argumentType;
- if (name == '++' || name == '--') {
+ SourceString operatorName = node.assignmentOperator.source;
+ SourceString compoundOperatorName =
+ canonicalizeCompoundOperator(node.assignmentOperator.source);
+ // ++, --, +=, -=, ...
+ if (compoundOperatorName != null) {
ConcreteType receiverType = visitGetterSend(node);
- SourceString canonicalizedMethodName = canonicalizeCompoundOperator(name);
- List<ConcreteType> positionalArguments = <ConcreteType>[
- new ConcreteType.singleton(inferrer.baseTypes.intBaseType)];
- ArgumentsTypes argumentsTypes =
- new ArgumentsTypes(positionalArguments, new Map());
- argumentType = analyzeDynamicSend(receiverType, canonicalizedMethodName,
+ // argumentsTypes is either computed from the actual arguments or [{int}]
+ // in case of ++ or --.
+ ArgumentsTypes argumentsTypes;
+ if (operatorName.stringValue == '++'
+ || operatorName.stringValue == '--') {
+ List<ConcreteType> positionalArguments = <ConcreteType>[
+ new ConcreteType.singleton(inferrer.baseTypes.intBaseType)];
+ argumentsTypes = new ArgumentsTypes(positionalArguments, new Map());
+ } else {
+ argumentsTypes = analyzeArguments(node.arguments);
+ }
+ argumentType = analyzeDynamicSend(receiverType, compoundOperatorName,
argumentsTypes);
+ // The simple assignment case: receiver = argument.
} else {
argumentType = analyze(node.argumentsNode);
}
@@ -1098,6 +1134,12 @@
}
ConcreteType visitLiteralString(LiteralString node) {
+ // TODO(polux): get rid of this hack once we have a natural way of inferring
+ // the unknown type.
+ if (inferrer.testMode
+ && node.dartString.slowToString() == "__dynamic_for_test") {
+ return new ConcreteType.unknown();
+ }
return new ConcreteType.singleton(inferrer.baseTypes.stringBaseType);
}
@@ -1316,22 +1358,24 @@
assert(node.receiver != null);
ConcreteType result = new ConcreteType.empty();
- void augmentResult(BaseType baseReceiverType, Element getterOrField) {
- if (getterOrField.isField()) {
- result = result.union(analyzeFieldRead(getterOrField));
- } else {
+ void augmentResult(BaseType baseReceiverType, Element member) {
+ if (member.isField()) {
+ result = result.union(analyzeFieldRead(member));
+ } else if (member.isAbstractField()){
// call to a getter
- AbstractFieldElement abstractField = getterOrField;
+ AbstractFieldElement abstractField = member;
result = result.union(analyzeGetterSend(baseReceiverType,
abstractField.getter));
}
+ // since this is a get we ignore non-fields
}
ConcreteType receiverType = analyze(node.receiver);
if (receiverType.isUnkown()) {
List<Element> members =
inferrer.getMembersByName(node.selector.asIdentifier().source);
- for (final member in members) {
+ for (Element member in members) {
+ if (!(member.isField() || member.isAbstractField())) continue;
Element classElement = member.getEnclosingClass();
ClassBaseType baseReceiverType = new ClassBaseType(classElement);
augmentResult(baseReceiverType, member);
@@ -1356,56 +1400,19 @@
inferrer.fail(node, 'not implemented');
}
- // TODO(polux): handle unary operators and share this list with the rest of
- // dart2js.
- final Set<SourceString> operators = new Set<SourceString>()
- ..add(const SourceString('=='))
- ..add(const SourceString('!='))
- ..add(const SourceString('~'))
- ..add(const SourceString('[]'))
- ..add(const SourceString('[]='))
- ..add(const SourceString('*'))
- ..add(const SourceString('*='))
- ..add(const SourceString('/'))
- ..add(const SourceString('/='))
- ..add(const SourceString('%'))
- ..add(const SourceString('%='))
- ..add(const SourceString('~/'))
- ..add(const SourceString('~/='))
- ..add(const SourceString('+'))
- ..add(const SourceString('+='))
- ..add(const SourceString('-'))
- ..add(const SourceString('-='))
- ..add(const SourceString('<<'))
- ..add(const SourceString('<<='))
- ..add(const SourceString('>>'))
- ..add(const SourceString('>>='))
- ..add(const SourceString('>='))
- ..add(const SourceString('>'))
- ..add(const SourceString('<='))
- ..add(const SourceString('<'))
- ..add(const SourceString('&'))
- ..add(const SourceString('&='))
- ..add(const SourceString('^'))
- ..add(const SourceString('^='))
- ..add(const SourceString('|'))
- ..add(const SourceString('|='));
-
- SourceString canonicalizeMethodName(SourceString s) {
- return operators.contains(s)
- ? Elements.constructOperatorName(s, false)
- : s;
- }
-
ConcreteType analyzeDynamicSend(ConcreteType receiverType,
SourceString canonicalizedMethodName,
ArgumentsTypes argumentsTypes) {
ConcreteType result = new ConcreteType.empty();
if (receiverType.isUnkown()) {
- List<FunctionElement> methods =
+ List<Element> methods =
inferrer.getMembersByName(canonicalizedMethodName);
- for (FunctionElement method in methods) {
+ for (Element element in methods) {
+ // TODO(polux): when we handle closures, we must handle sends to fields
+ // that are closures.
+ if (!element.isFunction()) continue;
+ FunctionElement method = element;
inferrer.addCaller(method, currentMethod);
Element classElem = method.enclosingElement;
ClassBaseType baseReceiverType = new ClassBaseType(classElem);
@@ -1430,6 +1437,14 @@
return result;
}
+ SourceString canonicalizeMethodName(SourceString name) {
+ // TODO(polux): handle unary-
+ SourceString operatorName =
+ Elements.constructOperatorNameOrNull(name, false);
+ if (operatorName != null) return operatorName;
+ return name;
+ }
+
ConcreteType visitDynamicSend(Send node) {
ConcreteType receiverType = (node.receiver != null)
? analyze(node.receiver)
@@ -1438,7 +1453,16 @@
SourceString name =
canonicalizeMethodName(node.selector.asIdentifier().source);
ArgumentsTypes argumentsTypes = analyzeArguments(node.arguments);
- return analyzeDynamicSend(receiverType, name, argumentsTypes);
+ if (name.stringValue == '!=') {
+ ConcreteType returnType = analyzeDynamicSend(receiverType,
+ const SourceString('=='),
+ argumentsTypes);
+ return returnType.isEmpty()
+ ? returnType
+ : new ConcreteType.singleton(inferrer.baseTypes.boolBaseType);
+ } else {
+ return analyzeDynamicSend(receiverType, name, argumentsTypes);
+ }
}
ConcreteType visitForeignSend(Send node) {
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 57f445d..be913e2 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -330,6 +330,7 @@
bool equalsUntyped(Selector other) {
return name == other.name
+ && kind == other.kind
&& identical(library, other.library)
&& argumentCount == other.argumentCount
&& namedArguments.length == other.namedArguments.length
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 536f5fc..8381bd5 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -327,6 +327,8 @@
static const ASSERT_IS_GIVEN_NAMED_ARGUMENTS = const MessageKind(
"assert takes no named arguments, but given #{1}.");
+ static const MALFORMED_TYPE_REFERENCE = const MessageKind(
+ "Malformed type reference encountered in #{1}.");
static const COMPILER_CRASHED = const MessageKind(
"Error: The compiler crashed when compiling this element.");
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 9116478..2dbc6a9 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -76,7 +76,7 @@
compiler.resolverWorld.isChecks.forEach((DartType type) {
if (type is InterfaceType) {
InterfaceType itf = type;
- if (!itf.typeArguments.isEmpty) {
+ if (!itf.isRaw) {
potentiallyAddForRti(itf.element, null);
}
}
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index a4714bb..ec86fd3 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -25,10 +25,13 @@
import '../../compiler/implementation/mirrors/mirrors_util.dart';
import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
import 'classify.dart';
+import 'universe_serializer.dart';
import 'markdown.dart' as md;
+import 'src/json_serializer.dart' as json_serializer;
import '../../compiler/implementation/scanner/scannerlib.dart' as dart2js;
import '../../libraries.dart';
+
// TODO(rnystrom): Use "package:" URL (#4968).
part 'src/dartdoc/comment_map.dart';
part 'src/dartdoc/nav.dart';
@@ -355,6 +358,12 @@
if (generateAppCache) {
generateAppCacheManifest();
}
+
+ startFile("apidoc.json");
+ var libraries = _sortedLibraries.map(
+ (lib) => new LibraryElement(lib.qualifiedName, lib, _comments));
+ write(json_serializer.serialize(libraries));
+ endFile();
}
void startFile(String path) {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart b/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
new file mode 100755
index 0000000..d67cd72
--- /dev/null
+++ b/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
@@ -0,0 +1,238 @@
+// 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.
+
+/**
+ * Simple library to serialize acyclic Dart types to JSON.
+ * This library is not intended for broad consumption and should be replaced
+ * with a more generic Dart serialization library when one is available.
+ */
+library json_serializer;
+
+import 'dart:mirrors';
+import 'dart:json';
+
+String serialize(Object o) {
+ var printer = new JsonPrinter();
+ _serialize(null, o, printer);
+ return printer.toString();
+}
+
+void _serialize(String name, Object o, JsonPrinter printer) {
+ if (o == null) return;
+
+ if (o is List) {
+ _serializeList(name, o, printer);
+ } else if (o is Map) {
+ _serializeMap(name, o, printer);
+ } else if (o is String) {
+ printer.addString(name, o);
+ } else if (o is bool) {
+ printer.addBool(name, o);
+ } else {
+ _serializeObject(name, o, printer);
+ }
+}
+
+void _serializeObject(String name, Object o, JsonPrinter printer) {
+ printer.startObject(name);
+
+ var mirror = reflect(o);
+ var classMirror = mirror.type;
+ var members = <String>[];
+ determineAllMembers(classMirror, members);
+
+ // TODO(jacobr): this code works only because futures for mirrors return
+ // immediately.
+ for(String memberName in members) {
+ mirror.getField(memberName).then((result) {
+ _serialize(memberName, result.reflectee, printer);
+ });
+ }
+ printer.endObject();
+}
+
+void determineAllMembers(ClassMirror classMirror,
+ List<String> members) {
+ for(String getterName in classMirror.getters.keys) {
+ if (!members.contains(getterName)) {
+ members.add(getterName);
+ }
+ }
+ for(String fieldName in classMirror.variables.keys) {
+ if (!members.contains(fieldName)) {
+ members.add(fieldName);
+ }
+ }
+ if (classMirror.superclass != null &&
+ classMirror.superclass.qualifiedName != classMirror.qualifiedName &&
+ classMirror.superclass.qualifiedName != 'dart:core.Object') {
+ determineAllMembers(classMirror.superclass, members);
+ }
+}
+
+void _serializeList(String name, List l, JsonPrinter printer) {
+ printer.startList(name);
+ for(var o in l) {
+ _serialize(null, o, printer);
+ }
+ printer.endList();
+}
+
+void _serializeMap(String name, Map m, JsonPrinter printer) {
+}
+
+class JsonPrinter {
+ static const int BACKSPACE = 8;
+ static const int TAB = 9;
+ static const int NEW_LINE = 10;
+ static const int FORM_FEED = 12;
+ static const int CARRIAGE_RETURN = 13;
+ static const int QUOTE = 34;
+ static const int BACKSLASH = 92;
+ static const int CHAR_B = 98;
+ static const int CHAR_F = 102;
+ static const int CHAR_N = 110;
+ static const int CHAR_R = 114;
+ static const int CHAR_T = 116;
+ static const int CHAR_U = 117;
+
+ StringBuffer _sb;
+ int _indent = 0;
+ bool _inSet = false;
+
+ bool _prettyPrint;
+ JsonPrinter({this._prettyPrint: true}) {
+ _sb = new StringBuffer();
+ }
+
+ void startObject(String name) {
+ _start(name);
+ _sb.add('{');
+
+ _indent += 1;
+ _inSet = false;
+ }
+
+ void endObject() {
+ _indent -= 1;
+ if (_inSet) {
+ _newline();
+ }
+ _sb.add('}');
+ _inSet = true;
+ }
+
+ void startList(String name) {
+ _start(name);
+ _inSet = false;
+
+ _sb.add('[');
+ _indent += 1;
+ }
+
+ void endList() {
+ _indent -= 1;
+ if (_inSet) {
+ _newline();
+ }
+ _sb.add(']');
+ _inSet = true;
+ }
+
+ void addString(String name, String value) {
+ _start(name);
+ _sb.add('"');
+ _escape(_sb, value);
+ _sb.add('"');
+ _inSet = true;
+ }
+
+ void addBool(String name, bool value) {
+ _start(name);
+ _sb.add(value.toString());
+ _inSet = true;
+ }
+
+ void addNum(String name, num value) {
+ _start(name);
+ _sb.add(value.toString());
+ _inSet = true;
+ }
+
+ void _start(String name) {
+ if (_inSet) {
+ _sb.add(',');
+ }
+ _newline();
+ if (name != null) {
+ _sb.add('"$name": ');
+ }
+ }
+
+ void _newline([int indent = 0]) {
+ _sb.add('\n');
+ _indent += indent;
+
+ for (var i = 0; i < _indent; ++i) {
+ _sb.add(' ');
+ }
+ }
+
+ String toString() {
+ if (_prettyPrint) {
+ return _sb.toString();
+ } else {
+ // Convenient hack to remove the pretty printing this serializer adds by
+ // default.
+ return JSON.stringify(JSON.parse(_sb.toString()));
+ }
+ }
+
+ static int _hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
+
+ static void _escape(StringBuffer sb, String s) {
+ final int length = s.length;
+ bool needsEscape = false;
+ final charCodes = new List<int>();
+ for (int i = 0; i < length; i++) {
+ int charCode = s.charCodeAt(i);
+ if (charCode < 32) {
+ needsEscape = true;
+ charCodes.add(JsonPrinter.BACKSLASH);
+ switch (charCode) {
+ case JsonPrinter.BACKSPACE:
+ charCodes.add(JsonPrinter.CHAR_B);
+ break;
+ case JsonPrinter.TAB:
+ charCodes.add(JsonPrinter.CHAR_T);
+ break;
+ case JsonPrinter.NEW_LINE:
+ charCodes.add(JsonPrinter.CHAR_N);
+ break;
+ case JsonPrinter.FORM_FEED:
+ charCodes.add(JsonPrinter.CHAR_F);
+ break;
+ case JsonPrinter.CARRIAGE_RETURN:
+ charCodes.add(JsonPrinter.CHAR_R);
+ break;
+ default:
+ charCodes.add(JsonPrinter.CHAR_U);
+ charCodes.add(_hexDigit((charCode >> 12) & 0xf));
+ charCodes.add(_hexDigit((charCode >> 8) & 0xf));
+ charCodes.add(_hexDigit((charCode >> 4) & 0xf));
+ charCodes.add(_hexDigit(charCode & 0xf));
+ break;
+ }
+ } else if (charCode == JsonPrinter.QUOTE ||
+ charCode == JsonPrinter.BACKSLASH) {
+ needsEscape = true;
+ charCodes.add(JsonPrinter.BACKSLASH);
+ charCodes.add(charCode);
+ } else {
+ charCodes.add(charCode);
+ }
+ }
+ sb.add(needsEscape ? new String.fromCharCodes(charCodes) : s);
+ }
+}
diff --git a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
new file mode 100755
index 0000000..c6c1ec0
--- /dev/null
+++ b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
@@ -0,0 +1,231 @@
+// 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.
+
+/**
+ * This library serializes the Dart2Js AST into a compact and easy to use
+ * [Element] tree useful for code exploration tools such as DartDoc.
+ */
+library universe_serializer;
+
+import '../../compiler/implementation/mirrors/mirrors.dart';
+import '../../compiler/implementation/mirrors/mirrors_util.dart';
+import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
+import '../../libraries.dart';
+import 'dartdoc.dart';
+
+/**
+ * Base class for all nodes.
+ */
+class Element {
+ /** Human readable type name for the node. */
+ final String kind;
+ /** Human readable name for the element. */
+ final String name;
+ /** Id for the node that is unique within its parent's children. */
+ final String id;
+ /** Raw text of the comment associated with the Element if any. */
+ final String comment;
+ /** Children of the node. */
+ List<Element> children;
+
+ Element(this.kind, this.name, this.id, this.comment);
+
+ void addChild(Element child) {
+ if (children == null) {
+ children = <Element>[];
+ }
+ children.add(child);
+ }
+}
+
+/**
+ * Converts false to null. Useful as the serialization scheme we use
+ * omits null values.
+ */
+bool _optionalBool(bool value) => value == true ? true : null;
+
+/**
+ * [Element] describing a Dart library.
+ */
+class LibraryElement extends Element {
+ LibraryElement(String name, LibraryMirror mirror, CommentMap comments)
+ : super('library', name, mirror.uri.toString(),
+ comments.findLibrary(mirror.location)) {
+
+ mirror.functions.forEach((childName, childMirror) {
+ addChild(new MethodElement(childName, childMirror, comments));
+ });
+
+ mirror.getters.forEach((childName, childMirror) {
+ addChild(new GetterElement(childName, childMirror, comments));
+ });
+
+ mirror.variables.forEach((childName, childMirror) {
+ addChild(new VariableElement(childName, childMirror));
+ });
+
+ mirror.classes.forEach((className, classMirror) {
+ if (!classMirror.isPrivate) {
+ if (classMirror is TypedefMirror) {
+ addChild(new TypedefElement(className, classMirror, comments));
+ } else {
+ addChild(new ClassElement(className, classMirror, comments));
+ }
+ }
+ });
+ }
+}
+
+/**
+ * [Element] describing a Dart class.
+ */
+class ClassElement extends Element {
+ /** Base class.*/
+ final Reference superclass;
+ /** Interfaces the class implements. */
+ List<Reference> interfaces;
+
+ ClassElement(String name, ClassMirror mirror, CommentMap comments)
+ : super('class', mirror.simpleName, name,
+ comments.find(mirror.location)),
+ superclass = mirror.superclass != null ?
+ new Reference(mirror.superclass) : null {
+ for (var interface in mirror.superinterfaces) {
+ if (this.interfaces == null) {
+ this.interfaces = <Reference>[];
+ }
+ this.interfaces.add(new Reference(interface));
+ }
+
+ mirror.methods.forEach((childName, childMirror) {
+ addChild(new MethodElement(childName, childMirror, comments));
+ });
+
+ mirror.getters.forEach((childName, childMirror) {
+ addChild(new GetterElement(childName, childMirror, comments));
+ });
+
+ mirror.variables.forEach((childName, childMirror) {
+ addChild(new VariableElement(childName, childMirror));
+ });
+
+ mirror.constructors.forEach((constructorName, methodMirror) {
+ addChild(new MethodElement(constructorName, methodMirror, comments, 'constructor'));
+ });
+ }
+}
+
+/**
+ * [Element] describing a getter.
+ */
+class GetterElement extends Element {
+ /** Type of the getter. */
+ final Reference ref;
+ final bool isStatic;
+
+ GetterElement(String name, MethodMirror mirror, CommentMap comments)
+ : super('property', mirror.simpleName, name,
+ comments.find(mirror.location)),
+ ref = mirror.returnType != null ?
+ new Reference(mirror.returnType) : null,
+ isStatic = _optionalBool(mirror.isStatic);
+}
+
+/**
+ * [Element] describing a method which may be a regular method, a setter, or an
+ * operator.
+ */
+class MethodElement extends Element {
+ final Reference returnType;
+ final bool isSetter;
+ final bool isOperator;
+ final bool isStatic;
+
+ MethodElement(String name, MethodMirror mirror, CommentMap comments, [String kind = 'method'])
+ : super(kind, name, '$name${mirror.parameters.length}()',
+ comments.find(mirror.location)),
+ returnType = mirror.returnType != null ?
+ new Reference(mirror.returnType) : null,
+ isSetter = _optionalBool(mirror.isSetter),
+ isOperator = _optionalBool(mirror.isOperator),
+ isStatic = _optionalBool(mirror.isStatic) {
+
+ for (var param in mirror.parameters) {
+ addChild(new ParameterElement(param));
+ }
+ }
+}
+
+/**
+ * Element describing a parameter.
+ */
+class ParameterElement extends Element {
+ /** Type of the parameter. */
+ final Reference ref;
+ /** Whether the parameter is optional. */
+ final bool isOptional;
+
+ ParameterElement(ParameterMirror mirror)
+ : super('param', mirror.simpleName, mirror.simpleName, null),
+ ref = new Reference(mirror.type),
+ isOptional = _optionalBool(mirror.isOptional) {
+ }
+}
+
+/**
+ * Element describing a variable.
+ */
+class VariableElement extends Element {
+ /** Type of the variable. */
+ final Reference ref;
+ final bool isStatic;
+
+ VariableElement(String name, VariableMirror mirror)
+ : super('property', mirror.simpleName, name, null),
+ ref = new Reference(mirror.type),
+ isStatic = _optionalBool(mirror.isStatic);
+}
+// TODO(jacobr): this seems incomplete.
+/**
+ * Element describing a typedef element.
+ */
+class TypedefElement extends Element {
+ TypedefElement(String name, TypedefMirror mirror, CommentMap comments)
+ : super('typedef', mirror.simpleName, name,
+ comments.find(mirror.location));
+}
+
+/**
+ * Reference to an Element with type argument if the reference is parameterized.
+ */
+class Reference {
+ final String name;
+ final String refId;
+ List<Reference> arguments;
+
+ Reference(Mirror mirror)
+ : name = mirror.simpleName,
+ refId = getId(mirror) {
+ if (mirror is ClassMirror) {
+ if (mirror is !TypedefMirror
+ && mirror.typeArguments.length > 0) {
+ arguments = <Reference>[];
+ for (var typeArg in mirror.typeArguments) {
+ arguments.add(new Reference(typeArg));
+ }
+ }
+ }
+ }
+
+ static String getId(Mirror mirror) {
+ String id = mirror.simpleName;
+ if (mirror is MemberMirror) {
+ MemberMirror memberMirror = mirror;
+ if (memberMirror.owner != null) {
+ id = '${getId(memberMirror.owner)}/$id';
+ }
+ }
+ return id;
+ }
+}
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 50bb70a..645a547 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -81,6 +81,11 @@
"utf": const LibraryInfo(
"utf/utf.dart"),
+ "web_audio": const LibraryInfo(
+ "web_audio/dartium/web_audio_dartium.dart",
+ category: "Client",
+ dart2jsPath: "web_audio/dart2js/web_audio_dart2js.dart"),
+
"_js_helper": const LibraryInfo(
"_internal/compiler/implementation/lib/js_helper.dart",
category: "Internal",
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index f0f0546..646f6e7 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -157,7 +157,7 @@
*/
static _containsRef(Collection c, Object ref) {
for (var e in c) {
- if (e === ref) return true;
+ if (identical(e, ref)) return true;
}
return false;
}
diff --git a/sdk/lib/core/future.dart b/sdk/lib/core/future.dart
index c14318b..c6cc374 100644
--- a/sdk/lib/core/future.dart
+++ b/sdk/lib/core/future.dart
@@ -259,4 +259,21 @@
}
return result;
}
+
+ /**
+ * Runs [f] for each element in [input] in order, moving to the next element
+ * only when the [Future] returned by [f] completes. Returns a [Future] that
+ * completes when all elements have been processed.
+ *
+ * The return values of all [Future]s are discarded. Any errors will cause the
+ * iteration to stop and will be piped through the returned [Future].
+ */
+ static Future forEach(Iterable input, Future f(element)) {
+ var iterator = input.iterator();
+ Future nextElement(_) {
+ if (!iterator.hasNext) return new Future.immediate(null);
+ return f(iterator.next()).chain(nextElement);
+ }
+ return nextElement(null);
+ }
}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index f9891b3..e900b2a 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -3,6 +3,7 @@
import 'dart:isolate';
import 'dart:json';
import 'dart:svg' as svg;
+import 'dart:web_audio' as web_audio;
// 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.
@@ -11,6 +12,7 @@
// Auto-generated dart:html library.
+// Not actually used, but imported since dart:html can generate these objects.
@@ -25,7 +27,7 @@
// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
-class HTMLElement extends Element native "*HTMLElement" {
+class _HTMLElement extends Element native "*HTMLElement" {
}
// Support for Send/ReceivePortSync.
@@ -56,13 +58,16 @@
new AbstractWorkerEvents(this);
/// @domName AbstractWorker.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName AbstractWorker.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName AbstractWorker.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class AbstractWorkerEvents extends Events {
@@ -75,38 +80,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName AnalyserNode; @docsEditable true
-class AnalyserNode extends AudioNode native "*AnalyserNode" {
-
- /// @domName AnalyserNode.fftSize; @docsEditable true
- int fftSize;
-
- /// @domName AnalyserNode.frequencyBinCount; @docsEditable true
- final int frequencyBinCount;
-
- /// @domName AnalyserNode.maxDecibels; @docsEditable true
- num maxDecibels;
-
- /// @domName AnalyserNode.minDecibels; @docsEditable true
- num minDecibels;
-
- /// @domName AnalyserNode.smoothingTimeConstant; @docsEditable true
- num smoothingTimeConstant;
-
- /// @domName AnalyserNode.getByteFrequencyData; @docsEditable true
- void getByteFrequencyData(Uint8Array array) native;
-
- /// @domName AnalyserNode.getByteTimeDomainData; @docsEditable true
- void getByteTimeDomainData(Uint8Array array) native;
-
- /// @domName AnalyserNode.getFloatFrequencyData; @docsEditable true
- void getFloatFrequencyData(Float32Array array) native;
-}
-// 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.
-
-
/// @domName HTMLAnchorElement; @docsEditable true
class AnchorElement extends Element implements Element native "*HTMLAnchorElement" {
@@ -400,361 +373,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName AudioBuffer; @docsEditable true
-class AudioBuffer native "*AudioBuffer" {
-
- /// @domName AudioBuffer.duration; @docsEditable true
- final num duration;
-
- /// @domName AudioBuffer.gain; @docsEditable true
- num gain;
-
- /// @domName AudioBuffer.length; @docsEditable true
- final int length;
-
- /// @domName AudioBuffer.numberOfChannels; @docsEditable true
- final int numberOfChannels;
-
- /// @domName AudioBuffer.sampleRate; @docsEditable true
- final num sampleRate;
-
- /// @domName AudioBuffer.getChannelData; @docsEditable true
- Float32Array getChannelData(int channelIndex) native;
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-typedef void AudioBufferCallback(AudioBuffer audioBuffer);
-// 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.
-
-
-class AudioBufferSourceNode extends AudioSourceNode native "*AudioBufferSourceNode" {
-
- // TODO(efortuna): Remove these methods when Chrome stable also uses start
- // instead of noteOn.
- void start(num when, [num grainOffset, num grainDuration]) {
- if (JS('bool', '!!#.start', this)) {
- if (?grainDuration) {
- JS('void', '#.start(#, #, #)', this, when, grainOffset, grainDuration);
- } else if (?grainOffset) {
- JS('void', '#.start(#, #)', this, when, grainOffset);
- } else {
- JS('void', '#.start(#)', this, when);
- }
- } else {
- if (?grainDuration) {
- JS('void', '#.noteOn(#, #, #)', this, when, grainOffset, grainDuration);
- } else if (?grainOffset) {
- JS('void', '#.noteOn(#, #)', this, when, grainOffset);
- } else {
- JS('void', '#.noteOn(#)', this, when);
- }
- }
- }
-
- void stop(num when) {
- if (JS('bool', '!!#.stop', this)) {
- JS('void', '#.stop(#)', this, when);
- } else {
- JS('void', '#.noteOff(#)', this, when);
- }
- }
-
- static const int FINISHED_STATE = 3;
-
- static const int PLAYING_STATE = 2;
-
- static const int SCHEDULED_STATE = 1;
-
- static const int UNSCHEDULED_STATE = 0;
-
- /// @domName AudioBufferSourceNode.buffer; @docsEditable true
- AudioBuffer buffer;
-
- /// @domName AudioBufferSourceNode.gain; @docsEditable true
- final AudioGain gain;
-
- /// @domName AudioBufferSourceNode.loop; @docsEditable true
- bool loop;
-
- /// @domName AudioBufferSourceNode.loopEnd; @docsEditable true
- num loopEnd;
-
- /// @domName AudioBufferSourceNode.loopStart; @docsEditable true
- num loopStart;
-
- /// @domName AudioBufferSourceNode.playbackRate; @docsEditable true
- final AudioParam playbackRate;
-
- /// @domName AudioBufferSourceNode.playbackState; @docsEditable true
- final int playbackState;
-
-}
-// 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.
-
-
-class AudioContext extends EventTarget native "*AudioContext" {
- factory AudioContext() => _AudioContextFactoryProvider.createAudioContext();
-
- /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
- AudioContextEvents get on =>
- new AudioContextEvents(this);
-
- /// @domName AudioContext.activeSourceCount; @docsEditable true
- final int activeSourceCount;
-
- /// @domName AudioContext.currentTime; @docsEditable true
- final num currentTime;
-
- /// @domName AudioContext.destination; @docsEditable true
- final AudioDestinationNode destination;
-
- /// @domName AudioContext.listener; @docsEditable true
- final AudioListener listener;
-
- /// @domName AudioContext.sampleRate; @docsEditable true
- final num sampleRate;
-
- /// @domName AudioContext.createAnalyser; @docsEditable true
- AnalyserNode createAnalyser() native;
-
- /// @domName AudioContext.createBiquadFilter; @docsEditable true
- BiquadFilterNode createBiquadFilter() native;
-
- /// @domName AudioContext.createBuffer; @docsEditable true
- AudioBuffer createBuffer(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, [num sampleRate]) native;
-
- /// @domName AudioContext.createBufferSource; @docsEditable true
- AudioBufferSourceNode createBufferSource() native;
-
- /// @domName AudioContext.createChannelMerger; @docsEditable true
- ChannelMergerNode createChannelMerger([int numberOfInputs]) native;
-
- /// @domName AudioContext.createChannelSplitter; @docsEditable true
- ChannelSplitterNode createChannelSplitter([int numberOfOutputs]) native;
-
- /// @domName AudioContext.createConvolver; @docsEditable true
- ConvolverNode createConvolver() native;
-
- /// @domName AudioContext.createDelay; @docsEditable true
- DelayNode createDelay([num maxDelayTime]) native;
-
- /// @domName AudioContext.createDynamicsCompressor; @docsEditable true
- DynamicsCompressorNode createDynamicsCompressor() native;
-
- /// @domName AudioContext.createMediaElementSource; @docsEditable true
- MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) native;
-
- /// @domName AudioContext.createMediaStreamSource; @docsEditable true
- MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) native;
-
- /// @domName AudioContext.createOscillator; @docsEditable true
- OscillatorNode createOscillator() native;
-
- /// @domName AudioContext.createPanner; @docsEditable true
- PannerNode createPanner() native;
-
- /// @domName AudioContext.createWaveShaper; @docsEditable true
- WaveShaperNode createWaveShaper() native;
-
- /// @domName AudioContext.createWaveTable; @docsEditable true
- WaveTable createWaveTable(Float32Array real, Float32Array imag) native;
-
- /// @domName AudioContext.decodeAudioData; @docsEditable true
- void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native;
-
- /// @domName AudioContext.startRendering; @docsEditable true
- void startRendering() native;
-
- GainNode createGain() {
- if (JS('bool', '#.createGain !== undefined', this)) {
- return JS('GainNode', '#.createGain()', this);
- } else {
- return JS('GainNode', '#.createGainNode()', this);
- }
- }
-
- ScriptProcessorNode createScriptProcessor(int bufferSize,
- [int numberOfInputChannels, int numberOfOutputChannels]) {
- var function = JS('dynamic', '#.createScriptProcessor || '
- '#.createJavaScriptNode', this, this);
- if (?numberOfOutputChannels) {
- return JS('ScriptProcessorNode', '#.call(#, #, #, #)', function, this,
- bufferSize, numberOfInputChannels, numberOfOutputChannels);
- } else if (?numberOfInputChannels) {
- return JS('ScriptProcessorNode', '#.call(#, #, #)', function, this,
- bufferSize, numberOfInputChannels);
- } else {
- return JS('ScriptProcessorNode', '#.call(#, #)', function, this,
- bufferSize);
- }
- }
-}
-
-class AudioContextEvents extends Events {
- AudioContextEvents(EventTarget _ptr) : super(_ptr);
-
- EventListenerList get complete => this['complete'];
-}
-// 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.
-
-
-/// @domName AudioDestinationNode; @docsEditable true
-class AudioDestinationNode extends AudioNode native "*AudioDestinationNode" {
-
- /// @domName AudioDestinationNode.numberOfChannels; @docsEditable true
- final int numberOfChannels;
-}
-// 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.
-
-
-/// @domName HTMLAudioElement; @docsEditable true
-class AudioElement extends MediaElement native "*HTMLAudioElement" {
-
- factory AudioElement([String src]) {
- if (!?src) {
- return _AudioElementFactoryProvider.createAudioElement();
- }
- return _AudioElementFactoryProvider.createAudioElement(src);
- }
-}
-// 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.
-
-
-/// @domName AudioGain; @docsEditable true
-class AudioGain extends AudioParam native "*AudioGain" {
-}
-// 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.
-
-
-/// @domName AudioListener; @docsEditable true
-class AudioListener native "*AudioListener" {
-
- /// @domName AudioListener.dopplerFactor; @docsEditable true
- num dopplerFactor;
-
- /// @domName AudioListener.speedOfSound; @docsEditable true
- num speedOfSound;
-
- /// @domName AudioListener.setOrientation; @docsEditable true
- void setOrientation(num x, num y, num z, num xUp, num yUp, num zUp) native;
-
- /// @domName AudioListener.setPosition; @docsEditable true
- void setPosition(num x, num y, num z) native;
-
- /// @domName AudioListener.setVelocity; @docsEditable true
- void setVelocity(num x, num y, num z) native;
-}
-// 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.
-
-
-/// @domName AudioNode; @docsEditable true
-class AudioNode native "*AudioNode" {
-
- /// @domName AudioNode.context; @docsEditable true
- final AudioContext context;
-
- /// @domName AudioNode.numberOfInputs; @docsEditable true
- final int numberOfInputs;
-
- /// @domName AudioNode.numberOfOutputs; @docsEditable true
- final int numberOfOutputs;
-
- /// @domName AudioNode.connect; @docsEditable true
- void connect(destination, int output, [int input]) native;
-
- /// @domName AudioNode.disconnect; @docsEditable true
- void disconnect(int output) native;
-}
-// 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.
-
-
-/// @domName AudioParam; @docsEditable true
-class AudioParam native "*AudioParam" {
-
- /// @domName AudioParam.defaultValue; @docsEditable true
- final num defaultValue;
-
- /// @domName AudioParam.maxValue; @docsEditable true
- final num maxValue;
-
- /// @domName AudioParam.minValue; @docsEditable true
- final num minValue;
-
- /// @domName AudioParam.name; @docsEditable true
- final String name;
-
- /// @domName AudioParam.units; @docsEditable true
- final int units;
-
- /// @domName AudioParam.value; @docsEditable true
- num value;
-
- /// @domName AudioParam.cancelScheduledValues; @docsEditable true
- void cancelScheduledValues(num startTime) native;
-
- /// @domName AudioParam.exponentialRampToValueAtTime; @docsEditable true
- void exponentialRampToValueAtTime(num value, num time) native;
-
- /// @domName AudioParam.linearRampToValueAtTime; @docsEditable true
- void linearRampToValueAtTime(num value, num time) native;
-
- /// @domName AudioParam.setTargetAtTime; @docsEditable true
- void setTargetAtTime(num target, num time, num timeConstant) native;
-
- /// @domName AudioParam.setValueAtTime; @docsEditable true
- void setValueAtTime(num value, num time) native;
-
- /// @domName AudioParam.setValueCurveAtTime; @docsEditable true
- void setValueCurveAtTime(Float32Array values, num time, num duration) native;
-}
-// 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.
-
-
-/// @domName AudioProcessingEvent; @docsEditable true
-class AudioProcessingEvent extends Event native "*AudioProcessingEvent" {
-
- /// @domName AudioProcessingEvent.inputBuffer; @docsEditable true
- final AudioBuffer inputBuffer;
-
- /// @domName AudioProcessingEvent.outputBuffer; @docsEditable true
- final AudioBuffer outputBuffer;
-}
-// 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.
-
-
-/// @domName AudioSourceNode; @docsEditable true
-class AudioSourceNode extends AudioNode native "*AudioSourceNode" {
-}
-// 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.
-
-
/// @domName HTMLBRElement; @docsEditable true
class BRElement extends Element implements Element native "*HTMLBRElement" {
@@ -832,13 +450,16 @@
final num level;
/// @domName BatteryManager.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName BatteryManager.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName BatteryManager.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class BatteryManagerEvents extends Events {
@@ -868,45 +489,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName BiquadFilterNode; @docsEditable true
-class BiquadFilterNode extends AudioNode native "*BiquadFilterNode" {
-
- static const int ALLPASS = 7;
-
- static const int BANDPASS = 2;
-
- static const int HIGHPASS = 1;
-
- static const int HIGHSHELF = 4;
-
- static const int LOWPASS = 0;
-
- static const int LOWSHELF = 3;
-
- static const int NOTCH = 6;
-
- static const int PEAKING = 5;
-
- /// @domName BiquadFilterNode.Q; @docsEditable true
- final AudioParam Q;
-
- /// @domName BiquadFilterNode.frequency; @docsEditable true
- final AudioParam frequency;
-
- /// @domName BiquadFilterNode.gain; @docsEditable true
- final AudioParam gain;
-
- /// @domName BiquadFilterNode.type; @docsEditable true
- int type;
-
- /// @domName BiquadFilterNode.getFrequencyResponse; @docsEditable true
- void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse) native;
-}
-// 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.
-
-
/// @domName Blob; @docsEditable true
class Blob native "*Blob" {
@@ -1023,7 +605,7 @@
String formTarget;
/// @domName HTMLButtonElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLButtonElement.name; @docsEditable true
@@ -1357,7 +939,8 @@
num getFloatValue(int unitType) native;
/// @domName CSSPrimitiveValue.getRGBColorValue; @docsEditable true
- RGBColor getRGBColorValue() native;
+ @JSName('getRGBColorValue')
+ RGBColor getRgbColorValue() native;
/// @domName CSSPrimitiveValue.getRectValue; @docsEditable true
Rect getRectValue() native;
@@ -1431,6 +1014,7 @@
return _cachedBrowserPrefix;
}
+/// @domName CSSStyleDeclaration
class CSSStyleDeclaration native "*CSSStyleDeclaration" {
factory CSSStyleDeclaration() => _CSSStyleDeclarationFactoryProvider.createCSSStyleDeclaration();
factory CSSStyleDeclaration.css(String css) =>
@@ -1447,7 +1031,8 @@
final CSSRule parentRule;
/// @domName CSSStyleDeclaration.getPropertyCSSValue; @docsEditable true
- CSSValue getPropertyCSSValue(String propertyName) native;
+ @JSName('getPropertyCSSValue')
+ CSSValue getPropertyCssValue(String propertyName) native;
/// @domName CSSStyleDeclaration.getPropertyPriority; @docsEditable true
String getPropertyPriority(String propertyName) native;
@@ -1456,7 +1041,8 @@
String getPropertyShorthand(String propertyName) native;
/// @domName CSSStyleDeclaration._getPropertyValue; @docsEditable true
- String _getPropertyValue(String propertyName) native "getPropertyValue";
+ @JSName('getPropertyValue')
+ String _getPropertyValue(String propertyName) native;
/// @domName CSSStyleDeclaration.isPropertyImplicit; @docsEditable true
bool isPropertyImplicit(String propertyName) native;
@@ -4765,6 +4351,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName HTMLCanvasElement
class CanvasElement extends Element implements Element native "*HTMLCanvasElement" {
factory CanvasElement({int width, int height}) {
@@ -4781,7 +4368,8 @@
int width;
/// @domName HTMLCanvasElement.toDataURL; @docsEditable true
- String toDataURL(String type, [num quality]) native;
+ @JSName('toDataURL')
+ String toDataUrl(String type, [num quality]) native;
CanvasRenderingContext getContext(String contextId) native;
@@ -4822,6 +4410,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName CanvasRenderingContext2D
class CanvasRenderingContext2D extends CanvasRenderingContext native "*CanvasRenderingContext2D" {
/// @domName CanvasRenderingContext2D.fillStyle; @docsEditable true
@@ -4920,10 +4509,12 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('createImageData')
@Creates('ImageData|=Object')
- _createImageData_1(imagedata) native "createImageData";
+ _createImageData_1(imagedata) native;
+ @JSName('createImageData')
@Creates('ImageData|=Object')
- _createImageData_2(num sw, sh) native "createImageData";
+ _createImageData_2(num sw, sh) native;
/// @domName CanvasRenderingContext2D.createLinearGradient; @docsEditable true
CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;
@@ -4953,8 +4544,9 @@
ImageData getImageData(num sx, num sy, num sw, num sh) {
return _convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
}
+ @JSName('getImageData')
@Creates('ImageData|=Object')
- _getImageData_1(sx, sy, sw, sh) native "getImageData";
+ _getImageData_1(sx, sy, sw, sh) native;
/// @domName CanvasRenderingContext2D.getLineDash; @docsEditable true
List<num> getLineDash() native;
@@ -4986,8 +4578,10 @@
return;
throw new ArgumentError("Incorrect number or type of arguments");
}
- void _putImageData_1(imagedata, dx, dy) native "putImageData";
- void _putImageData_2(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native "putImageData";
+ @JSName('putImageData')
+ void _putImageData_1(imagedata, dx, dy) native;
+ @JSName('putImageData')
+ void _putImageData_2(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;
/// @domName CanvasRenderingContext2D.quadraticCurveTo; @docsEditable true
void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
@@ -5053,8 +4647,9 @@
ImageData webkitGetImageDataHD(num sx, num sy, num sw, num sh) {
return _convertNativeToDart_ImageData(_webkitGetImageDataHD_1(sx, sy, sw, sh));
}
+ @JSName('webkitGetImageDataHD')
@Creates('ImageData|=Object')
- _webkitGetImageDataHD_1(sx, sy, sw, sh) native "webkitGetImageDataHD";
+ _webkitGetImageDataHD_1(sx, sy, sw, sh) native;
/// @domName CanvasRenderingContext2D.webkitPutImageDataHD; @docsEditable true
void webkitPutImageDataHD(ImageData imagedata, num dx, num dy, [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
@@ -5071,8 +4666,10 @@
return;
throw new ArgumentError("Incorrect number or type of arguments");
}
- void _webkitPutImageDataHD_1(imagedata, dx, dy) native "webkitPutImageDataHD";
- void _webkitPutImageDataHD_2(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native "webkitPutImageDataHD";
+ @JSName('webkitPutImageDataHD')
+ void _webkitPutImageDataHD_1(imagedata, dx, dy) native;
+ @JSName('webkitPutImageDataHD')
+ void _webkitPutImageDataHD_2(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;
/**
@@ -5116,22 +4713,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName ChannelMergerNode; @docsEditable true
-class ChannelMergerNode extends AudioNode native "*ChannelMergerNode" {
-}
-// 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.
-
-
-/// @domName ChannelSplitterNode; @docsEditable true
-class ChannelSplitterNode extends AudioNode native "*ChannelSplitterNode" {
-}
-// 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.
-
-
/// @domName CharacterData; @docsEditable true
class CharacterData extends Node native "*CharacterData" {
@@ -5265,6 +4846,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Console
class Console
// Console is sometimes a singleton bag-of-properties without a prototype.
native "=(typeof console == 'undefined' ? {} : console)" {
@@ -5350,7 +4932,7 @@
String select;
/// @domName HTMLContentElement.getDistributedNodes; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -5358,20 +4940,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName ConvolverNode; @docsEditable true
-class ConvolverNode extends AudioNode native "*ConvolverNode" {
-
- /// @domName ConvolverNode.buffer; @docsEditable true
- AudioBuffer buffer;
-
- /// @domName ConvolverNode.normalize; @docsEditable true
- bool normalize;
-}
-// 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.
-
-
/// @domName Coordinates; @docsEditable true
class Coordinates native "*Coordinates" {
@@ -5431,6 +4999,7 @@
// WARNING: Do not edit - generated code.
+/// @domName CustomEvent
class CustomEvent extends Event native "*CustomEvent" {
factory CustomEvent(String type, [bool canBubble = true, bool cancelable = true,
Object detail]) => _CustomEventFactoryProvider.createCustomEvent(
@@ -5440,7 +5009,8 @@
final Object detail;
/// @domName CustomEvent.initCustomEvent; @docsEditable true
- void $dom_initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native "initCustomEvent";
+ @JSName('initCustomEvent')
+ void $dom_initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -5487,13 +5057,16 @@
void abort() native;
/// @domName DOMApplicationCache.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName DOMApplicationCache.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName DOMApplicationCache.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName DOMApplicationCache.swapCache; @docsEditable true
void swapCache() native;
@@ -5639,7 +5212,8 @@
class DOMImplementation native "*DOMImplementation" {
/// @domName DOMImplementation.createCSSStyleSheet; @docsEditable true
- CSSStyleSheet createCSSStyleSheet(String title, String media) native;
+ @JSName('createCSSStyleSheet')
+ CSSStyleSheet createCssStyleSheet(String title, String media) native;
/// @domName DOMImplementation.createDocument; @docsEditable true
Document createDocument(String namespaceURI, String qualifiedName, DocumentType doctype) native;
@@ -5648,7 +5222,8 @@
DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) native;
/// @domName DOMImplementation.createHTMLDocument; @docsEditable true
- HtmlDocument createHTMLDocument(String title) native;
+ @JSName('createHTMLDocument')
+ HtmlDocument createHtmlDocument(String title) native;
/// @domName DOMImplementation.hasFeature; @docsEditable true
bool hasFeature(String feature, String version) native;
@@ -6243,8 +5818,10 @@
_postMessage_2(message_2);
return;
}
- void _postMessage_1(message, List messagePorts) native "postMessage";
- void _postMessage_2(message) native "postMessage";
+ @JSName('postMessage')
+ void _postMessage_1(message, List messagePorts) native;
+ @JSName('postMessage')
+ void _postMessage_2(message) native;
}
class DedicatedWorkerContextEvents extends WorkerContextEvents {
@@ -6257,17 +5834,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName DelayNode; @docsEditable true
-class DelayNode extends AudioNode native "*DelayNode" {
-
- /// @domName DelayNode.delayTime; @docsEditable true
- final AudioParam delayTime;
-}
-// 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.
-
-
/// @domName HTMLDetailsElement; @docsEditable true
class DetailsElement extends Element implements Element native "*HTMLDetailsElement" {
@@ -6352,10 +5918,14 @@
_getDirectory_4(path);
return;
}
- void _getDirectory_1(path, options, EntryCallback successCallback, ErrorCallback errorCallback) native "getDirectory";
- void _getDirectory_2(path, options, EntryCallback successCallback) native "getDirectory";
- void _getDirectory_3(path, options) native "getDirectory";
- void _getDirectory_4(path) native "getDirectory";
+ @JSName('getDirectory')
+ void _getDirectory_1(path, options, EntryCallback successCallback, ErrorCallback errorCallback) native;
+ @JSName('getDirectory')
+ void _getDirectory_2(path, options, EntryCallback successCallback) native;
+ @JSName('getDirectory')
+ void _getDirectory_3(path, options) native;
+ @JSName('getDirectory')
+ void _getDirectory_4(path) native;
/// @domName DirectoryEntry.getFile; @docsEditable true
void getFile(String path, {Map options, EntryCallback successCallback, ErrorCallback errorCallback}) {
@@ -6377,10 +5947,14 @@
_getFile_4(path);
return;
}
- void _getFile_1(path, options, EntryCallback successCallback, ErrorCallback errorCallback) native "getFile";
- void _getFile_2(path, options, EntryCallback successCallback) native "getFile";
- void _getFile_3(path, options) native "getFile";
- void _getFile_4(path) native "getFile";
+ @JSName('getFile')
+ void _getFile_1(path, options, EntryCallback successCallback, ErrorCallback errorCallback) native;
+ @JSName('getFile')
+ void _getFile_2(path, options, EntryCallback successCallback) native;
+ @JSName('getFile')
+ void _getFile_3(path, options) native;
+ @JSName('getFile')
+ void _getFile_4(path) native;
/// @domName DirectoryEntry.removeRecursively; @docsEditable true
void removeRecursively(VoidCallback successCallback, [ErrorCallback errorCallback]) native;
@@ -6401,14 +5975,16 @@
var flags_1 = _convertDartToNative_Dictionary(flags);
return _getDirectory_1(path, flags_1);
}
- DirectoryEntrySync _getDirectory_1(path, flags) native "getDirectory";
+ @JSName('getDirectory')
+ DirectoryEntrySync _getDirectory_1(path, flags) native;
/// @domName DirectoryEntrySync.getFile; @docsEditable true
FileEntrySync getFile(String path, Map flags) {
var flags_1 = _convertDartToNative_Dictionary(flags);
return _getFile_1(path, flags_1);
}
- FileEntrySync _getFile_1(path, flags) native "getFile";
+ @JSName('getFile')
+ FileEntrySync _getFile_1(path, flags) native;
/// @domName DirectoryEntrySync.removeRecursively; @docsEditable true
void removeRecursively() native;
@@ -6441,6 +6017,27 @@
// BSD-style license that can be found in the LICENSE file.
+/**
+ * Represents an HTML <div> element.
+ *
+ * The [DivElement] is a generic container for content and does not have any
+ * special significance. It is functionally similar to [SpanElement].
+ *
+ * The [DivElement] is a block-level element, as opposed to [SpanElement],
+ * which is an inline-level element.
+ *
+ * Example usage:
+ *
+ * DivElement div = new DivElement();
+ * div.text = 'Here's my new DivElem
+ * document.body.elements.add(elem);
+ *
+ * See also:
+ *
+ * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
+ * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
+ */
/// @domName HTMLDivElement; @docsEditable true
class DivElement extends Element implements Element native "*HTMLDivElement" {
@@ -6451,6 +6048,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Document
class Document extends Node native "*Document"
{
@@ -6460,12 +6058,8 @@
new DocumentEvents(this);
/// @domName Document.body; @docsEditable true
- Element get $dom_body => JS("Element", "#.body", this);
-
- /// @domName Document.body; @docsEditable true
- void set $dom_body(Element value) {
- JS("void", "#.body = #", this, value);
- }
+ @JSName('body')
+ Element $dom_body;
/// @domName Document.charset; @docsEditable true
String charset;
@@ -6475,7 +6069,9 @@
/// @domName Document.defaultView; @docsEditable true
Window get window => _convertNativeToDart_Window(this._window);
- dynamic get _window => JS("dynamic", "#.defaultView", this);
+ @JSName('defaultView')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _window;
/// @domName Document.documentElement; @docsEditable true
final Element documentElement;
@@ -6484,13 +6080,15 @@
final String domain;
/// @domName Document.head; @docsEditable true
- HeadElement get $dom_head => JS("HeadElement", "#.head", this);
+ @JSName('head')
+ final HeadElement $dom_head;
/// @domName Document.implementation; @docsEditable true
final DOMImplementation implementation;
/// @domName Document.lastModified; @docsEditable true
- String get $dom_lastModified => JS("String", "#.lastModified", this);
+ @JSName('lastModified')
+ final String $dom_lastModified;
/// @domName Document.preferredStylesheetSet; @docsEditable true
final String preferredStylesheetSet;
@@ -6499,97 +6097,116 @@
final String readyState;
/// @domName Document.referrer; @docsEditable true
- String get $dom_referrer => JS("String", "#.referrer", this);
+ @JSName('referrer')
+ final String $dom_referrer;
/// @domName Document.selectedStylesheetSet; @docsEditable true
String selectedStylesheetSet;
/// @domName Document.styleSheets; @docsEditable true
- List<StyleSheet> get $dom_styleSheets => JS("_StyleSheetList", "#.styleSheets", this);
+ @JSName('styleSheets')
+ @Returns('_StyleSheetList') @Creates('_StyleSheetList')
+ final List<StyleSheet> $dom_styleSheets;
/// @domName Document.title; @docsEditable true
- String get $dom_title => JS("String", "#.title", this);
-
- /// @domName Document.title; @docsEditable true
- void set $dom_title(String value) {
- JS("void", "#.title = #", this, value);
- }
+ @JSName('title')
+ String $dom_title;
/// @domName Document.webkitFullscreenElement; @docsEditable true
- Element get $dom_webkitFullscreenElement => JS("Element", "#.webkitFullscreenElement", this);
+ @JSName('webkitFullscreenElement')
+ final Element $dom_webkitFullscreenElement;
/// @domName Document.webkitFullscreenEnabled; @docsEditable true
- bool get $dom_webkitFullscreenEnabled => JS("bool", "#.webkitFullscreenEnabled", this);
+ @JSName('webkitFullscreenEnabled')
+ final bool $dom_webkitFullscreenEnabled;
/// @domName Document.webkitHidden; @docsEditable true
- bool get $dom_webkitHidden => JS("bool", "#.webkitHidden", this);
+ @JSName('webkitHidden')
+ final bool $dom_webkitHidden;
/// @domName Document.webkitIsFullScreen; @docsEditable true
- bool get $dom_webkitIsFullScreen => JS("bool", "#.webkitIsFullScreen", this);
+ @JSName('webkitIsFullScreen')
+ final bool $dom_webkitIsFullScreen;
/// @domName Document.webkitPointerLockElement; @docsEditable true
- Element get $dom_webkitPointerLockElement => JS("Element", "#.webkitPointerLockElement", this);
+ @JSName('webkitPointerLockElement')
+ final Element $dom_webkitPointerLockElement;
/// @domName Document.webkitVisibilityState; @docsEditable true
- String get $dom_webkitVisibilityState => JS("String", "#.webkitVisibilityState", this);
+ @JSName('webkitVisibilityState')
+ final String $dom_webkitVisibilityState;
/// @domName Document.caretRangeFromPoint; @docsEditable true
- Range $dom_caretRangeFromPoint(int x, int y) native "caretRangeFromPoint";
+ @JSName('caretRangeFromPoint')
+ Range $dom_caretRangeFromPoint(int x, int y) native;
/// @domName Document.createCDATASection; @docsEditable true
- CDATASection createCDATASection(String data) native;
+ @JSName('createCDATASection')
+ CDATASection createCDataSection(String data) native;
/// @domName Document.createDocumentFragment; @docsEditable true
DocumentFragment createDocumentFragment() native;
/// @domName Document.createElement; @docsEditable true
- Element $dom_createElement(String tagName) native "createElement";
+ @JSName('createElement')
+ Element $dom_createElement(String tagName) native;
/// @domName Document.createElementNS; @docsEditable true
- Element $dom_createElementNS(String namespaceURI, String qualifiedName) native "createElementNS";
+ @JSName('createElementNS')
+ Element $dom_createElementNS(String namespaceURI, String qualifiedName) native;
/// @domName Document.createEvent; @docsEditable true
- Event $dom_createEvent(String eventType) native "createEvent";
+ @JSName('createEvent')
+ Event $dom_createEvent(String eventType) native;
/// @domName Document.createRange; @docsEditable true
Range createRange() native;
/// @domName Document.createTextNode; @docsEditable true
- Text $dom_createTextNode(String data) native "createTextNode";
+ @JSName('createTextNode')
+ Text $dom_createTextNode(String data) native;
/// @domName Document.createTouch; @docsEditable true
Touch createTouch(LocalWindow window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) {
var target_1 = _convertDartToNative_EventTarget(target);
return _createTouch_1(window, target_1, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce);
}
- Touch _createTouch_1(LocalWindow window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native "createTouch";
+ @JSName('createTouch')
+ Touch _createTouch_1(LocalWindow window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
/// @domName Document.createTouchList; @docsEditable true
- TouchList $dom_createTouchList() native "createTouchList";
+ @JSName('createTouchList')
+ TouchList $dom_createTouchList() native;
/// @domName Document.elementFromPoint; @docsEditable true
- Element $dom_elementFromPoint(int x, int y) native "elementFromPoint";
+ @JSName('elementFromPoint')
+ Element $dom_elementFromPoint(int x, int y) native;
/// @domName Document.execCommand; @docsEditable true
bool execCommand(String command, bool userInterface, String value) native;
/// @domName Document.getCSSCanvasContext; @docsEditable true
- CanvasRenderingContext getCSSCanvasContext(String contextId, String name, int width, int height) native;
+ @JSName('getCSSCanvasContext')
+ CanvasRenderingContext getCssCanvasContext(String contextId, String name, int width, int height) native;
/// @domName Document.getElementById; @docsEditable true
- Element $dom_getElementById(String elementId) native "getElementById";
+ @JSName('getElementById')
+ Element $dom_getElementById(String elementId) native;
/// @domName Document.getElementsByClassName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByClassName(String tagname) native "getElementsByClassName";
+ @JSName('getElementsByClassName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByClassName(String tagname) native;
/// @domName Document.getElementsByName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByName(String elementName) native "getElementsByName";
+ @JSName('getElementsByName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByName(String elementName) native;
/// @domName Document.getElementsByTagName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByTagName(String tagname) native "getElementsByTagName";
+ @JSName('getElementsByTagName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByTagName(String tagname) native;
/// @domName Document.queryCommandEnabled; @docsEditable true
bool queryCommandEnabled(String command) native;
@@ -6607,20 +6224,25 @@
String queryCommandValue(String command) native;
/// @domName Document.querySelector; @docsEditable true
- Element $dom_querySelector(String selectors) native "querySelector";
+ @JSName('querySelector')
+ Element $dom_querySelector(String selectors) native;
/// @domName Document.querySelectorAll; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_querySelectorAll(String selectors) native "querySelectorAll";
+ @JSName('querySelectorAll')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_querySelectorAll(String selectors) native;
/// @domName Document.webkitCancelFullScreen; @docsEditable true
- void $dom_webkitCancelFullScreen() native "webkitCancelFullScreen";
+ @JSName('webkitCancelFullScreen')
+ void $dom_webkitCancelFullScreen() native;
/// @domName Document.webkitExitFullscreen; @docsEditable true
- void $dom_webkitExitFullscreen() native "webkitExitFullscreen";
+ @JSName('webkitExitFullscreen')
+ void $dom_webkitExitFullscreen() native;
/// @domName Document.webkitExitPointerLock; @docsEditable true
- void $dom_webkitExitPointerLock() native "webkitExitPointerLock";
+ @JSName('webkitExitPointerLock')
+ void $dom_webkitExitPointerLock() native;
// TODO(jacobr): implement all Element methods not on Document.
@@ -6660,100 +6282,10 @@
class DocumentEvents extends ElementEvents {
DocumentEvents(EventTarget _ptr) : super(_ptr);
- EventListenerList get abort => this['abort'];
-
- EventListenerList get beforeCopy => this['beforecopy'];
-
- EventListenerList get beforeCut => this['beforecut'];
-
- EventListenerList get beforePaste => this['beforepaste'];
-
- EventListenerList get blur => this['blur'];
-
- EventListenerList get change => this['change'];
-
- EventListenerList get click => this['click'];
-
- EventListenerList get contextMenu => this['contextmenu'];
-
- EventListenerList get copy => this['copy'];
-
- EventListenerList get cut => this['cut'];
-
- EventListenerList get doubleClick => this['dblclick'];
-
- EventListenerList get drag => this['drag'];
-
- EventListenerList get dragEnd => this['dragend'];
-
- EventListenerList get dragEnter => this['dragenter'];
-
- EventListenerList get dragLeave => this['dragleave'];
-
- EventListenerList get dragOver => this['dragover'];
-
- EventListenerList get dragStart => this['dragstart'];
-
- EventListenerList get drop => this['drop'];
-
- EventListenerList get error => this['error'];
-
- EventListenerList get focus => this['focus'];
-
- EventListenerList get input => this['input'];
-
- EventListenerList get invalid => this['invalid'];
-
- EventListenerList get keyDown => this['keydown'];
-
- EventListenerList get keyPress => this['keypress'];
-
- EventListenerList get keyUp => this['keyup'];
-
- EventListenerList get load => this['load'];
-
- EventListenerList get mouseDown => this['mousedown'];
-
- EventListenerList get mouseMove => this['mousemove'];
-
- EventListenerList get mouseOut => this['mouseout'];
-
- EventListenerList get mouseOver => this['mouseover'];
-
- EventListenerList get mouseUp => this['mouseup'];
-
- EventListenerList get mouseWheel => this['mousewheel'];
-
- EventListenerList get paste => this['paste'];
-
EventListenerList get readyStateChange => this['readystatechange'];
- EventListenerList get reset => this['reset'];
-
- EventListenerList get scroll => this['scroll'];
-
- EventListenerList get search => this['search'];
-
- EventListenerList get select => this['select'];
-
EventListenerList get selectionChange => this['selectionchange'];
- EventListenerList get selectStart => this['selectstart'];
-
- EventListenerList get submit => this['submit'];
-
- EventListenerList get touchCancel => this['touchcancel'];
-
- EventListenerList get touchEnd => this['touchend'];
-
- EventListenerList get touchMove => this['touchmove'];
-
- EventListenerList get touchStart => this['touchstart'];
-
- EventListenerList get fullscreenChange => this['webkitfullscreenchange'];
-
- EventListenerList get fullscreenError => this['webkitfullscreenerror'];
-
EventListenerList get pointerLockChange => this['webkitpointerlockchange'];
EventListenerList get pointerLockError => this['webkitpointerlockerror'];
@@ -6778,6 +6310,7 @@
bool get frozen => true;
}
+/// @domName DocumentFragment
class DocumentFragment extends Node native "*DocumentFragment" {
factory DocumentFragment() => _DocumentFragmentFactoryProvider.createDocumentFragment();
@@ -6819,21 +6352,21 @@
List<Element> queryAll(String selectors) =>
new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
- String get innerHTML {
+ String get innerHtml {
final e = new Element.tag("div");
e.nodes.add(this.clone(true));
- return e.innerHTML;
+ return e.innerHtml;
}
- String get outerHTML => innerHTML;
+ String get outerHtml => innerHtml;
- // TODO(nweiz): Do we want to support some variant of innerHTML for XML and/or
+ // TODO(nweiz): Do we want to support some variant of innerHtml for XML and/or
// SVG strings?
- void set innerHTML(String value) {
+ void set innerHtml(String value) {
this.nodes.clear();
final e = new Element.tag("div");
- e.innerHTML = value;
+ e.innerHtml = value;
// Copy list first since we don't want liveness during iteration.
List nodes = new List.from(e.nodes);
@@ -6863,16 +6396,20 @@
this._insertAdjacentNode(where, new Text(text));
}
- void insertAdjacentHTML(String where, String text) {
+ void insertAdjacentHtml(String where, String text) {
this._insertAdjacentNode(where, new DocumentFragment.html(text));
}
- void addText(String text) {
+ void append(Element element) {
+ this.children.add(element);
+ }
+
+ void appendText(String text) {
this.insertAdjacentText('beforeend', text);
}
- void addHtml(String text) {
- this.insertAdjacentHTML('beforeend', text);
+ void appendHtml(String text) {
+ this.insertAdjacentHtml('beforeend', text);
}
// If we can come up with a semi-reasonable default value for an Element
@@ -6896,7 +6433,7 @@
}
return null;
}
- Element get $m_lastElementChild() => elements.last;
+ Element get $m_lastElementChild => elements.last;
Element get nextElementSibling => null;
Element get previousElementSibling => null;
Element get offsetParent => null;
@@ -7025,11 +6562,13 @@
new ElementEvents(this);
/// @domName DocumentFragment.querySelector; @docsEditable true
- Element $dom_querySelector(String selectors) native "querySelector";
+ @JSName('querySelector')
+ Element $dom_querySelector(String selectors) native;
/// @domName DocumentFragment.querySelectorAll; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_querySelectorAll(String selectors) native "querySelectorAll";
+ @JSName('querySelectorAll')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_querySelectorAll(String selectors) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -7066,32 +6605,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName DynamicsCompressorNode; @docsEditable true
-class DynamicsCompressorNode extends AudioNode native "*DynamicsCompressorNode" {
-
- /// @domName DynamicsCompressorNode.attack; @docsEditable true
- final AudioParam attack;
-
- /// @domName DynamicsCompressorNode.knee; @docsEditable true
- final AudioParam knee;
-
- /// @domName DynamicsCompressorNode.ratio; @docsEditable true
- final AudioParam ratio;
-
- /// @domName DynamicsCompressorNode.reduction; @docsEditable true
- final AudioParam reduction;
-
- /// @domName DynamicsCompressorNode.release; @docsEditable true
- final AudioParam release;
-
- /// @domName DynamicsCompressorNode.threshold; @docsEditable true
- final AudioParam threshold;
-}
-// 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.
-
-
/// @domName EXTTextureFilterAnisotropic; @docsEditable true
class EXTTextureFilterAnisotropic native "*EXTTextureFilterAnisotropic" {
@@ -7401,171 +6914,6 @@
bool get hasNext => _index < _list.length;
}
-class _ElementAttributeMap implements Map<String, String> {
-
- final Element _element;
-
- _ElementAttributeMap(this._element);
-
- bool containsValue(String value) {
- final attributes = _element.$dom_attributes;
- for (int i = 0, len = attributes.length; i < len; i++) {
- if(value == attributes[i].value) {
- return true;
- }
- }
- return false;
- }
-
- bool containsKey(String key) {
- return _element.$dom_hasAttribute(key);
- }
-
- String operator [](String key) {
- return _element.$dom_getAttribute(key);
- }
-
- void operator []=(String key, value) {
- _element.$dom_setAttribute(key, '$value');
- }
-
- String putIfAbsent(String key, String ifAbsent()) {
- if (!containsKey(key)) {
- this[key] = ifAbsent();
- }
- return this[key];
- }
-
- String remove(String key) {
- String value = _element.$dom_getAttribute(key);
- _element.$dom_removeAttribute(key);
- return value;
- }
-
- void clear() {
- final attributes = _element.$dom_attributes;
- for (int i = attributes.length - 1; i >= 0; i--) {
- remove(attributes[i].name);
- }
- }
-
- void forEach(void f(String key, String value)) {
- final attributes = _element.$dom_attributes;
- for (int i = 0, len = attributes.length; i < len; i++) {
- final item = attributes[i];
- f(item.name, item.value);
- }
- }
-
- Collection<String> get keys {
- // TODO(jacobr): generate a lazy collection instead.
- final attributes = _element.$dom_attributes;
- final keys = new List<String>(attributes.length);
- for (int i = 0, len = attributes.length; i < len; i++) {
- keys[i] = attributes[i].name;
- }
- return keys;
- }
-
- Collection<String> get values {
- // TODO(jacobr): generate a lazy collection instead.
- final attributes = _element.$dom_attributes;
- final values = new List<String>(attributes.length);
- for (int i = 0, len = attributes.length; i < len; i++) {
- values[i] = attributes[i].value;
- }
- return values;
- }
-
- /**
- * The number of {key, value} pairs in the map.
- */
- int get length {
- return _element.$dom_attributes.length;
- }
-
- /**
- * Returns true if there is no {key, value} pair in the map.
- */
- bool get isEmpty {
- return length == 0;
- }
-}
-
-/**
- * Provides a Map abstraction on top of data-* attributes, similar to the
- * dataSet in the old DOM.
- */
-class _DataAttributeMap implements Map<String, String> {
-
- final Map<String, String> $dom_attributes;
-
- _DataAttributeMap(this.$dom_attributes);
-
- // interface Map
-
- // TODO: Use lazy iterator when it is available on Map.
- bool containsValue(String value) => values.some((v) => v == value);
-
- bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
-
- String operator [](String key) => $dom_attributes[_attr(key)];
-
- void operator []=(String key, value) {
- $dom_attributes[_attr(key)] = '$value';
- }
-
- String putIfAbsent(String key, String ifAbsent()) =>
- $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
-
- String remove(String key) => $dom_attributes.remove(_attr(key));
-
- void clear() {
- // Needs to operate on a snapshot since we are mutating the collection.
- for (String key in keys) {
- remove(key);
- }
- }
-
- void forEach(void f(String key, String value)) {
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- f(_strip(key), value);
- }
- });
- }
-
- Collection<String> get keys {
- final keys = new List<String>();
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- keys.add(_strip(key));
- }
- });
- return keys;
- }
-
- Collection<String> get values {
- final values = new List<String>();
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- values.add(value);
- }
- });
- return values;
- }
-
- int get length => keys.length;
-
- // TODO: Use lazy iterator when it is available on Map.
- bool get isEmpty => length == 0;
-
- // Helpers.
- String _attr(String key) => 'data-$key';
- bool _matches(String key) => key.startsWith('data-');
- String _strip(String key) => key.substring(5);
-}
-
class _ElementCssClassSet extends CssClassSet {
final Element _element;
@@ -7591,24 +6939,7 @@
}
}
-class _SimpleClientRect implements ClientRect {
- final num left;
- final num top;
- final num width;
- final num height;
- num get right => left + width;
- num get bottom => top + height;
-
- const _SimpleClientRect(this.left, this.top, this.width, this.height);
-
- bool operator ==(ClientRect other) {
- return other != null && left == other.left && top == other.top
- && width == other.width && height == other.height;
- }
-
- String toString() => "($left, $top, $width, $height)";
-}
-
+/// @domName Element
abstract class Element extends Node implements ElementTraversal native "*Element" {
factory Element.html(String html) =>
@@ -7630,6 +6961,14 @@
}
}
+ /**
+ * Deprecated, use innerHtml instead.
+ */
+ String get innerHTML => this.innerHtml;
+ void set innerHTML(String value) {
+ this.innerHtml = value;
+ }
+
void set elements(Collection<Element> value) {
this.children = value;
}
@@ -7678,6 +7017,14 @@
}
}
+ /**
+ * Gets a map for manipulating the attributes of a particular namespace.
+ * This is primarily useful for SVG attributes such as xref:link.
+ */
+ Map<String, String> getNamespacedAttributes(String namespace) {
+ return new _NamespacedAttributeMap(this, namespace);
+ }
+
/** @domName Window.getComputedStyle */
Future<CSSStyleDeclaration> get computedStyle {
// TODO(jacobr): last param should be null, see b/5045788
@@ -7692,9 +7039,16 @@
}
/**
+ * Adds the specified element to after the last child of this.
+ */
+ void append(Element e) {
+ this.children.add(e);
+ }
+
+ /**
* Adds the specified text as a text node after the last child of this.
*/
- void addText(String text) {
+ void appendText(String text) {
this.insertAdjacentText('beforeend', text);
}
@@ -7702,8 +7056,8 @@
* Parses the specified text as HTML and adds the resulting node after the
* last child of this.
*/
- void addHtml(String text) {
- this.insertAdjacentHTML('beforeend', text);
+ void appendHtml(String text) {
+ this.insertAdjacentHtml('beforeend', text);
}
// Hooks to support custom WebComponents.
@@ -7731,20 +7085,20 @@
}
}
- void _insertAdjacentText(String where, String text)
- native 'insertAdjacentText';
+ @JSName('insertAdjacentText')
+ void _insertAdjacentText(String where, String text) native;
/** @domName Element.insertAdjacentHTML */
- void insertAdjacentHTML(String where, String text) {
- if (JS('bool', '!!#.insertAdjacentHTML', this)) {
- _insertAdjacentHTML(where, text);
+ void insertAdjacentHtml(String where, String text) {
+ if (JS('bool', '!!#.insertAdjacentHtml', this)) {
+ _insertAdjacentHtml(where, text);
} else {
_insertAdjacentNode(where, new DocumentFragment.html(text));
}
}
- void _insertAdjacentHTML(String where, String text)
- native 'insertAdjacentHTML';
+ @JSName('insertAdjacentHTML')
+ void _insertAdjacentHTML(String where, String text) native;
/** @domName Element.insertAdjacentHTML */
Element insertAdjacentElement(String where, Element element) {
@@ -7756,8 +7110,8 @@
return element;
}
- void _insertAdjacentElement(String where, Element element)
- native 'insertAdjacentElement';
+ @JSName('insertAdjacentElement')
+ void _insertAdjacentElement(String where, Element element) native;
void _insertAdjacentNode(String where, Node node) {
switch (where.toLowerCase()) {
@@ -7785,7 +7139,8 @@
new ElementEvents(this);
/// @domName HTMLElement.children; @docsEditable true
- HTMLCollection get $dom_children => JS("HTMLCollection", "#.children", this);
+ @JSName('children')
+ final HTMLCollection $dom_children;
/// @domName HTMLElement.contentEditable; @docsEditable true
String contentEditable;
@@ -7803,7 +7158,8 @@
String id;
/// @domName HTMLElement.innerHTML; @docsEditable true
- String innerHTML;
+ @JSName('innerHTML')
+ String innerHtml;
/// @domName HTMLElement.isContentEditable; @docsEditable true
final bool isContentEditable;
@@ -7812,7 +7168,8 @@
String lang;
/// @domName HTMLElement.outerHTML; @docsEditable true
- final String outerHTML;
+ @JSName('outerHTML')
+ final String outerHtml;
/// @domName HTMLElement.spellcheck; @docsEditable true
bool spellcheck;
@@ -7835,15 +7192,12 @@
static const int ALLOW_KEYBOARD_INPUT = 1;
/// @domName Element.childElementCount; @docsEditable true
- int get $dom_childElementCount => JS("int", "#.childElementCount", this);
+ @JSName('childElementCount')
+ final int $dom_childElementCount;
/// @domName Element.className; @docsEditable true
- String get $dom_className => JS("String", "#.className", this);
-
- /// @domName Element.className; @docsEditable true
- void set $dom_className(String value) {
- JS("void", "#.className = #", this, value);
- }
+ @JSName('className')
+ String $dom_className;
/// @domName Element.clientHeight; @docsEditable true
final int clientHeight;
@@ -7861,10 +7215,12 @@
final Map<String, String> dataset;
/// @domName Element.firstElementChild; @docsEditable true
- Element get $dom_firstElementChild => JS("Element", "#.firstElementChild", this);
+ @JSName('firstElementChild')
+ final Element $dom_firstElementChild;
/// @domName Element.lastElementChild; @docsEditable true
- Element get $dom_lastElementChild => JS("Element", "#.lastElementChild", this);
+ @JSName('lastElementChild')
+ final Element $dom_lastElementChild;
/// @domName Element.nextElementSibling; @docsEditable true
final Element nextElementSibling;
@@ -7912,7 +7268,12 @@
void focus() native;
/// @domName Element.getAttribute; @docsEditable true
- String $dom_getAttribute(String name) native "getAttribute";
+ @JSName('getAttribute')
+ String $dom_getAttribute(String name) native;
+
+ /// @domName Element.getAttributeNS; @docsEditable true
+ @JSName('getAttributeNS')
+ String $dom_getAttributeNS(String namespaceURI, String localName) native;
/// @domName Element.getBoundingClientRect; @docsEditable true
ClientRect getBoundingClientRect() native;
@@ -7922,25 +7283,39 @@
List<ClientRect> getClientRects() native;
/// @domName Element.getElementsByClassName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByClassName(String name) native "getElementsByClassName";
+ @JSName('getElementsByClassName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByClassName(String name) native;
/// @domName Element.getElementsByTagName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByTagName(String name) native "getElementsByTagName";
+ @JSName('getElementsByTagName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByTagName(String name) native;
/// @domName Element.hasAttribute; @docsEditable true
- bool $dom_hasAttribute(String name) native "hasAttribute";
+ @JSName('hasAttribute')
+ bool $dom_hasAttribute(String name) native;
+
+ /// @domName Element.hasAttributeNS; @docsEditable true
+ @JSName('hasAttributeNS')
+ bool $dom_hasAttributeNS(String namespaceURI, String localName) native;
/// @domName Element.querySelector; @docsEditable true
- Element $dom_querySelector(String selectors) native "querySelector";
+ @JSName('querySelector')
+ Element $dom_querySelector(String selectors) native;
/// @domName Element.querySelectorAll; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_querySelectorAll(String selectors) native "querySelectorAll";
+ @JSName('querySelectorAll')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_querySelectorAll(String selectors) native;
/// @domName Element.removeAttribute; @docsEditable true
- void $dom_removeAttribute(String name) native "removeAttribute";
+ @JSName('removeAttribute')
+ void $dom_removeAttribute(String name) native;
+
+ /// @domName Element.removeAttributeNS; @docsEditable true
+ @JSName('removeAttributeNS')
+ void $dom_removeAttributeNS(String namespaceURI, String localName) native;
/// @domName Element.scrollByLines; @docsEditable true
void scrollByLines(int lines) native;
@@ -7949,13 +7324,20 @@
void scrollByPages(int pages) native;
/// @domName Element.scrollIntoViewIfNeeded; @docsEditable true
- void scrollIntoView([bool centerIfNeeded]) native "scrollIntoViewIfNeeded";
+ @JSName('scrollIntoViewIfNeeded')
+ void scrollIntoView([bool centerIfNeeded]) native;
/// @domName Element.setAttribute; @docsEditable true
- void $dom_setAttribute(String name, String value) native "setAttribute";
+ @JSName('setAttribute')
+ void $dom_setAttribute(String name, String value) native;
+
+ /// @domName Element.setAttributeNS; @docsEditable true
+ @JSName('setAttributeNS')
+ void $dom_setAttributeNS(String namespaceURI, String qualifiedName, String value) native;
/// @domName Element.webkitMatchesSelector; @docsEditable true
- bool matchesSelector(String selectors) native "webkitMatchesSelector";
+ @JSName('webkitMatchesSelector')
+ bool matchesSelector(String selectors) native;
/// @domName Element.webkitRequestFullScreen; @docsEditable true
void webkitRequestFullScreen(int flags) native;
@@ -8005,7 +7387,7 @@
}
}
final Element temp = new Element.tag(parentTag);
- temp.innerHTML = html;
+ temp.innerHtml = html;
Element element;
if (temp.children.length == 1) {
@@ -8265,7 +7647,8 @@
void remove(VoidCallback successCallback, [ErrorCallback errorCallback]) native;
/// @domName Entry.toURL; @docsEditable true
- String toURL() native;
+ @JSName('toURL')
+ String toUrl() native;
}
// 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
@@ -8314,7 +7697,8 @@
void remove() native;
/// @domName EntrySync.toURL; @docsEditable true
- String toURL() native;
+ @JSName('toURL')
+ String toUrl() native;
}
// 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
@@ -8348,6 +7732,7 @@
// WARNING: Do not edit - generated code.
+/// @domName Event
class Event native "*Event" {
// In JS, canBubble and cancelable are technically required parameters to
// init*Event. In practice, though, if they aren't provided they simply
@@ -8412,7 +7797,9 @@
/// @domName Event.currentTarget; @docsEditable true
EventTarget get currentTarget => _convertNativeToDart_EventTarget(this._currentTarget);
- dynamic get _currentTarget => JS("dynamic", "#.currentTarget", this);
+ @JSName('currentTarget')
+ @Creates('EventTarget|=Object') @Returns('EventTarget|=Object')
+ final dynamic _currentTarget;
/// @domName Event.defaultPrevented; @docsEditable true
final bool defaultPrevented;
@@ -8425,7 +7812,9 @@
/// @domName Event.target; @docsEditable true
EventTarget get target => _convertNativeToDart_EventTarget(this._target);
- dynamic get _target => JS("dynamic", "#.target", this);
+ @JSName('target')
+ @Creates('EventTarget|=Object') @Returns('EventTarget|=Object')
+ final dynamic _target;
/// @domName Event.timeStamp; @docsEditable true
final int timeStamp;
@@ -8434,7 +7823,8 @@
final String type;
/// @domName Event.initEvent; @docsEditable true
- void $dom_initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native "initEvent";
+ @JSName('initEvent')
+ void $dom_initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native;
/// @domName Event.preventDefault; @docsEditable true
void preventDefault() native;
@@ -8490,9 +7880,6 @@
static const int OPEN = 1;
- /// @domName EventSource.URL; @docsEditable true
- final String URL;
-
/// @domName EventSource.readyState; @docsEditable true
final int readyState;
@@ -8500,16 +7887,19 @@
final String url;
/// @domName EventSource.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName EventSource.close; @docsEditable true
void close() native;
/// @domName EventSource.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName EventSource.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class EventSourceEvents extends Events {
@@ -8571,20 +7961,23 @@
}
}
-
+/// @domName EventTarget
class EventTarget native "*EventTarget" {
/** @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent */
Events get on => new Events(this);
/// @domName EventTarget.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName EventTarget.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName EventTarget.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -8793,10 +8186,12 @@
void abort() native;
/// @domName FileReader.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName FileReader.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName FileReader.readAsArrayBuffer; @docsEditable true
void readAsArrayBuffer(Blob blob) native;
@@ -8805,13 +8200,15 @@
void readAsBinaryString(Blob blob) native;
/// @domName FileReader.readAsDataURL; @docsEditable true
- void readAsDataURL(Blob blob) native;
+ @JSName('readAsDataURL')
+ void readAsDataUrl(Blob blob) native;
/// @domName FileReader.readAsText; @docsEditable true
void readAsText(Blob blob, [String encoding]) native;
/// @domName FileReader.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class FileReaderEvents extends Events {
@@ -8846,7 +8243,8 @@
String readAsBinaryString(Blob blob) native;
/// @domName FileReaderSync.readAsDataURL; @docsEditable true
- String readAsDataURL(Blob blob) native;
+ @JSName('readAsDataURL')
+ String readAsDataUrl(Blob blob) native;
/// @domName FileReaderSync.readAsText; @docsEditable true
String readAsText(Blob blob, [String encoding]) native;
@@ -8893,13 +8291,16 @@
void abort() native;
/// @domName FileWriter.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName FileWriter.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName FileWriter.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName FileWriter.seek; @docsEditable true
void seek(int position) native;
@@ -9062,7 +8463,8 @@
// -- end List<num> mixins.
/// @domName Float32Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Float32Array.subarray; @docsEditable true
Float32Array subarray(int start, [int end]) native;
@@ -9172,7 +8574,8 @@
// -- end List<num> mixins.
/// @domName Float64Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Float64Array.subarray; @docsEditable true
Float64Array subarray(int start, [int end]) native;
@@ -9271,7 +8674,9 @@
/// @domName HTMLFrameElement.contentWindow; @docsEditable true
Window get contentWindow => _convertNativeToDart_Window(this._contentWindow);
- dynamic get _contentWindow => JS("dynamic", "#.contentWindow", this);
+ @JSName('contentWindow')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _contentWindow;
/// @domName HTMLFrameElement.frameBorder; @docsEditable true
String frameBorder;
@@ -9359,17 +8764,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName GainNode; @docsEditable true
-class GainNode extends AudioNode native "*GainNode" {
-
- /// @domName GainNode.gain; @docsEditable true
- final AudioGain gain;
-}
-// 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.
-
-
/// @domName Gamepad; @docsEditable true
class Gamepad native "*Gamepad" {
@@ -9544,7 +8938,7 @@
Node namedItem(String name) native;
/// @domName HTMLAllCollection.tags; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> tags(String name) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -9681,10 +9075,12 @@
class HashChangeEvent extends Event native "*HashChangeEvent" {
/// @domName HashChangeEvent.newURL; @docsEditable true
- final String newURL;
+ @JSName('newURL')
+ final String newUrl;
/// @domName HashChangeEvent.oldURL; @docsEditable true
- final String oldURL;
+ @JSName('oldURL')
+ final String oldUrl;
/// @domName HashChangeEvent.initHashChangeEvent; @docsEditable true
void initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native;
@@ -9732,6 +9128,7 @@
// WARNING: Do not edit - generated code.
+/// @domName HTMLDocument
class HtmlDocument extends Document native "*HTMLDocument" {
/// @domName HTMLDocument.activeElement; @docsEditable true
@@ -9824,6 +9221,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName XMLHttpRequest
class HttpRequest extends EventTarget native "*XMLHttpRequest" {
factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
_HttpRequestFactoryProvider.createHttpRequest_get(url, onComplete);
@@ -9864,7 +9262,8 @@
String responseType;
/// @domName XMLHttpRequest.responseXML; @docsEditable true
- final Document responseXML;
+ @JSName('responseXML')
+ final Document responseXml;
/// @domName XMLHttpRequest.status; @docsEditable true
final int status;
@@ -9882,10 +9281,12 @@
void abort() native;
/// @domName XMLHttpRequest.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName XMLHttpRequest.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName XMLHttpRequest.getAllResponseHeaders; @docsEditable true
String getAllResponseHeaders() native;
@@ -9900,7 +9301,8 @@
void overrideMimeType(String override) native;
/// @domName XMLHttpRequest.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName XMLHttpRequest.send; @docsEditable true
void send([data]) native;
@@ -9978,13 +9380,16 @@
new HttpRequestUploadEvents(this);
/// @domName XMLHttpRequestUpload.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName XMLHttpRequestUpload.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName XMLHttpRequestUpload.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class HttpRequestUploadEvents extends Events {
@@ -10052,8 +9457,10 @@
_continueFunction_2();
return;
}
- void _continueFunction_1(key) native "continue";
- void _continueFunction_2() native "continue";
+ @JSName('continue')
+ void _continueFunction_1(key) native;
+ @JSName('continue')
+ void _continueFunction_2() native;
/// @domName IDBCursor.delete; @docsEditable true
IDBRequest delete() native;
@@ -10063,7 +9470,8 @@
var value_1 = _convertDartToNative_SerializedScriptValue(value);
return _update_1(value_1);
}
- IDBRequest _update_1(value) native "update";
+ @JSName('update')
+ IDBRequest _update_1(value) native;
}
// 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
@@ -10082,6 +9490,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName IDBDatabase
class IDBDatabase extends EventTarget native "*IDBDatabase" {
IDBTransaction transaction(storeName_OR_storeNames, String mode) {
@@ -10120,7 +9529,8 @@
return db._transaction(stores, intMode);
}
- IDBTransaction _transaction(stores, mode) native 'transaction';
+ @JSName('transaction')
+ IDBTransaction _transaction(stores, mode) native;
static bool _hasNumericMode(txn) =>
JS('bool', 'typeof(#.mode) === "number"', txn);
@@ -10141,7 +9551,8 @@
final dynamic version;
/// @domName IDBDatabase.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName IDBDatabase.close; @docsEditable true
void close() native;
@@ -10154,17 +9565,21 @@
}
return _createObjectStore_2(name);
}
- IDBObjectStore _createObjectStore_1(name, options) native "createObjectStore";
- IDBObjectStore _createObjectStore_2(name) native "createObjectStore";
+ @JSName('createObjectStore')
+ IDBObjectStore _createObjectStore_1(name, options) native;
+ @JSName('createObjectStore')
+ IDBObjectStore _createObjectStore_2(name) native;
/// @domName IDBDatabase.deleteObjectStore; @docsEditable true
void deleteObjectStore(String name) native;
/// @domName IDBDatabase.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName IDBDatabase.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName IDBDatabase.setVersion; @docsEditable true
IDBVersionChangeRequest setVersion(String version) native;
@@ -10243,7 +9658,8 @@
var second_2 = _convertDartToNative_IDBKey(second);
return _cmp_1(first_1, second_2);
}
- int _cmp_1(first, second) native "cmp";
+ @JSName('cmp')
+ int _cmp_1(first, second) native;
/// @domName IDBFactory.deleteDatabase; @docsEditable true
IDBVersionChangeRequest deleteDatabase(String name) native;
@@ -10292,9 +9708,12 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- IDBRequest _count_1() native "count";
- IDBRequest _count_2(IDBKeyRange range) native "count";
- IDBRequest _count_3(key) native "count";
+ @JSName('count')
+ IDBRequest _count_1() native;
+ @JSName('count')
+ IDBRequest _count_2(IDBKeyRange range) native;
+ @JSName('count')
+ IDBRequest _count_3(key) native;
/// @domName IDBIndex.get; @docsEditable true
IDBRequest get(key) {
@@ -10307,10 +9726,12 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('get')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_SerializedScriptValue
- IDBRequest _get_1(IDBKeyRange key) native "get";
+ IDBRequest _get_1(IDBKeyRange key) native;
+ @JSName('get')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_SerializedScriptValue
- IDBRequest _get_2(key) native "get";
+ IDBRequest _get_2(key) native;
/// @domName IDBIndex.getKey; @docsEditable true
IDBRequest getKey(key) {
@@ -10323,10 +9744,12 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('getKey')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_SerializedScriptValue @Creates('IDBObjectStore')
- IDBRequest _getKey_1(IDBKeyRange key) native "getKey";
+ IDBRequest _getKey_1(IDBKeyRange key) native;
+ @JSName('getKey')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_SerializedScriptValue @Creates('IDBObjectStore')
- IDBRequest _getKey_2(key) native "getKey";
+ IDBRequest _getKey_2(key) native;
/// @domName IDBIndex.openCursor; @docsEditable true
IDBRequest openCursor([key_OR_range, String direction]) {
@@ -10352,16 +9775,21 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_1() native "openCursor";
+ IDBRequest _openCursor_1() native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_2(IDBKeyRange range) native "openCursor";
+ IDBRequest _openCursor_2(IDBKeyRange range) native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_3(IDBKeyRange range, direction) native "openCursor";
+ IDBRequest _openCursor_3(IDBKeyRange range, direction) native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_4(key) native "openCursor";
+ IDBRequest _openCursor_4(key) native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_5(key, direction) native "openCursor";
+ IDBRequest _openCursor_5(key, direction) native;
/// @domName IDBIndex.openKeyCursor; @docsEditable true
IDBRequest openKeyCursor([key_OR_range, String direction]) {
@@ -10387,16 +9815,21 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('openKeyCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openKeyCursor_1() native "openKeyCursor";
+ IDBRequest _openKeyCursor_1() native;
+ @JSName('openKeyCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openKeyCursor_2(IDBKeyRange range) native "openKeyCursor";
+ IDBRequest _openKeyCursor_2(IDBKeyRange range) native;
+ @JSName('openKeyCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openKeyCursor_3(IDBKeyRange range, direction) native "openKeyCursor";
+ IDBRequest _openKeyCursor_3(IDBKeyRange range, direction) native;
+ @JSName('openKeyCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openKeyCursor_4(key) native "openKeyCursor";
+ IDBRequest _openKeyCursor_4(key) native;
+ @JSName('openKeyCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openKeyCursor_5(key, direction) native "openKeyCursor";
+ IDBRequest _openKeyCursor_5(key, direction) native;
}
// 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
@@ -10411,6 +9844,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName IDBKeyRange
class IDBKeyRange native "*IDBKeyRange" {
/**
* @domName IDBKeyRange.only
@@ -10441,14 +9875,16 @@
/// @domName IDBKeyRange.lower; @docsEditable true
dynamic get lower => _convertNativeToDart_IDBKey(this._lower);
- dynamic get _lower => JS("dynamic", "#.lower", this);
+ @JSName('lower')
+ final dynamic _lower;
/// @domName IDBKeyRange.lowerOpen; @docsEditable true
final bool lowerOpen;
/// @domName IDBKeyRange.upper; @docsEditable true
dynamic get upper => _convertNativeToDart_IDBKey(this._upper);
- dynamic get _upper => JS("dynamic", "#.upper", this);
+ @JSName('upper')
+ final dynamic _upper;
/// @domName IDBKeyRange.upperOpen; @docsEditable true
final bool upperOpen;
@@ -10469,9 +9905,12 @@
var upper_6 = _convertDartToNative_IDBKey(upper);
return _bound__3(lower_5, upper_6);
}
- static IDBKeyRange _bound__1(lower, upper, lowerOpen, upperOpen) native "bound";
- static IDBKeyRange _bound__2(lower, upper, lowerOpen) native "bound";
- static IDBKeyRange _bound__3(lower, upper) native "bound";
+ @JSName('bound')
+ static IDBKeyRange _bound__1(lower, upper, lowerOpen, upperOpen) native;
+ @JSName('bound')
+ static IDBKeyRange _bound__2(lower, upper, lowerOpen) native;
+ @JSName('bound')
+ static IDBKeyRange _bound__3(lower, upper) native;
/// @domName IDBKeyRange.lowerBound_; @docsEditable true
static IDBKeyRange lowerBound_(/*IDBKey*/ bound, [bool open]) {
@@ -10482,15 +9921,18 @@
var bound_2 = _convertDartToNative_IDBKey(bound);
return _lowerBound__2(bound_2);
}
- static IDBKeyRange _lowerBound__1(bound, open) native "lowerBound";
- static IDBKeyRange _lowerBound__2(bound) native "lowerBound";
+ @JSName('lowerBound')
+ static IDBKeyRange _lowerBound__1(bound, open) native;
+ @JSName('lowerBound')
+ static IDBKeyRange _lowerBound__2(bound) native;
/// @domName IDBKeyRange.only_; @docsEditable true
static IDBKeyRange only_(/*IDBKey*/ value) {
var value_1 = _convertDartToNative_IDBKey(value);
return _only__1(value_1);
}
- static IDBKeyRange _only__1(value) native "only";
+ @JSName('only')
+ static IDBKeyRange _only__1(value) native;
/// @domName IDBKeyRange.upperBound_; @docsEditable true
static IDBKeyRange upperBound_(/*IDBKey*/ bound, [bool open]) {
@@ -10501,8 +9943,10 @@
var bound_2 = _convertDartToNative_IDBKey(bound);
return _upperBound__2(bound_2);
}
- static IDBKeyRange _upperBound__1(bound, open) native "upperBound";
- static IDBKeyRange _upperBound__2(bound) native "upperBound";
+ @JSName('upperBound')
+ static IDBKeyRange _upperBound__1(bound, open) native;
+ @JSName('upperBound')
+ static IDBKeyRange _upperBound__2(bound) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -10539,10 +9983,12 @@
var value_3 = _convertDartToNative_SerializedScriptValue(value);
return _add_2(value_3);
}
+ @JSName('add')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_IDBKey
- IDBRequest _add_1(value, key) native "add";
+ IDBRequest _add_1(value, key) native;
+ @JSName('add')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_IDBKey
- IDBRequest _add_2(value) native "add";
+ IDBRequest _add_2(value) native;
/// @domName IDBObjectStore.clear; @docsEditable true
IDBRequest clear() native;
@@ -10561,9 +10007,12 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- IDBRequest _count_1() native "count";
- IDBRequest _count_2(IDBKeyRange range) native "count";
- IDBRequest _count_3(key) native "count";
+ @JSName('count')
+ IDBRequest _count_1() native;
+ @JSName('count')
+ IDBRequest _count_2(IDBKeyRange range) native;
+ @JSName('count')
+ IDBRequest _count_3(key) native;
/// @domName IDBObjectStore.createIndex; @docsEditable true
IDBIndex createIndex(String name, keyPath, [Map options]) {
@@ -10587,10 +10036,14 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- IDBIndex _createIndex_1(name, List keyPath) native "createIndex";
- IDBIndex _createIndex_2(name, List keyPath, options) native "createIndex";
- IDBIndex _createIndex_3(name, String keyPath) native "createIndex";
- IDBIndex _createIndex_4(name, String keyPath, options) native "createIndex";
+ @JSName('createIndex')
+ IDBIndex _createIndex_1(name, List keyPath) native;
+ @JSName('createIndex')
+ IDBIndex _createIndex_2(name, List keyPath, options) native;
+ @JSName('createIndex')
+ IDBIndex _createIndex_3(name, String keyPath) native;
+ @JSName('createIndex')
+ IDBIndex _createIndex_4(name, String keyPath, options) native;
/// @domName IDBObjectStore.delete; @docsEditable true
IDBRequest delete(key_OR_keyRange) {
@@ -10603,8 +10056,10 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- IDBRequest _delete_1(IDBKeyRange keyRange) native "delete";
- IDBRequest _delete_2(key) native "delete";
+ @JSName('delete')
+ IDBRequest _delete_1(IDBKeyRange keyRange) native;
+ @JSName('delete')
+ IDBRequest _delete_2(key) native;
/// @domName IDBObjectStore.deleteIndex; @docsEditable true
void deleteIndex(String name) native;
@@ -10620,10 +10075,12 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('get')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_SerializedScriptValue
- IDBRequest _getObject_1(IDBKeyRange key) native "get";
+ IDBRequest _getObject_1(IDBKeyRange key) native;
+ @JSName('get')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_SerializedScriptValue
- IDBRequest _getObject_2(key) native "get";
+ IDBRequest _getObject_2(key) native;
/// @domName IDBObjectStore.index; @docsEditable true
IDBIndex index(String name) native;
@@ -10652,16 +10109,21 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_1() native "openCursor";
+ IDBRequest _openCursor_1() native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_2(IDBKeyRange range) native "openCursor";
+ IDBRequest _openCursor_2(IDBKeyRange range) native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_3(IDBKeyRange range, direction) native "openCursor";
+ IDBRequest _openCursor_3(IDBKeyRange range, direction) native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_4(key) native "openCursor";
+ IDBRequest _openCursor_4(key) native;
+ @JSName('openCursor')
@Returns('IDBRequest') @Creates('IDBRequest') @Creates('IDBCursor')
- IDBRequest _openCursor_5(key, direction) native "openCursor";
+ IDBRequest _openCursor_5(key, direction) native;
/// @domName IDBObjectStore.put; @docsEditable true
IDBRequest put(/*any*/ value, [/*IDBKey*/ key]) {
@@ -10673,10 +10135,12 @@
var value_3 = _convertDartToNative_SerializedScriptValue(value);
return _put_2(value_3);
}
+ @JSName('put')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_IDBKey
- IDBRequest _put_1(value, key) native "put";
+ IDBRequest _put_1(value, key) native;
+ @JSName('put')
@Returns('IDBRequest') @Creates('IDBRequest') @_annotation_Creates_IDBKey
- IDBRequest _put_2(value) native "put";
+ IDBRequest _put_2(value) native;
}
// 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
@@ -10721,7 +10185,9 @@
/// @domName IDBRequest.result; @docsEditable true
dynamic get result => _convertNativeToDart_IDBAny(this._result);
- dynamic get _result => JS("dynamic", "#.result", this);
+ @JSName('result')
+ @Creates('Null')
+ final dynamic _result;
/// @domName IDBRequest.source; @docsEditable true
@Creates('Null')
@@ -10734,13 +10200,16 @@
final String webkitErrorMessage;
/// @domName IDBRequest.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName IDBRequest.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName IDBRequest.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class IDBRequestEvents extends Events {
@@ -10781,16 +10250,19 @@
void abort() native;
/// @domName IDBTransaction.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName IDBTransaction.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName IDBTransaction.objectStore; @docsEditable true
IDBObjectStore objectStore(String name) native;
/// @domName IDBTransaction.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class IDBTransactionEvents extends Events {
@@ -10860,7 +10332,9 @@
/// @domName HTMLIFrameElement.contentWindow; @docsEditable true
Window get contentWindow => _convertNativeToDart_Window(this._contentWindow);
- dynamic get _contentWindow => JS("dynamic", "#.contentWindow", this);
+ @JSName('contentWindow')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _contentWindow;
/// @domName HTMLIFrameElement.frameBorder; @docsEditable true
String frameBorder;
@@ -11089,7 +10563,7 @@
bool indeterminate;
/// @domName HTMLInputElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLInputElement.list; @docsEditable true
@@ -11312,7 +10786,8 @@
// -- end List<int> mixins.
/// @domName Int16Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Int16Array.subarray; @docsEditable true
Int16Array subarray(int start, [int end]) native;
@@ -11422,7 +10897,8 @@
// -- end List<int> mixins.
/// @domName Int32Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Int32Array.subarray; @docsEditable true
Int32Array subarray(int start, [int end]) native;
@@ -11532,7 +11008,8 @@
// -- end List<int> mixins.
/// @domName Int8Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Int8Array.subarray; @docsEditable true
Int8Array subarray(int start, [int end]) native;
@@ -11596,6 +11073,36 @@
/// @domName KeyboardEvent; @docsEditable true
class KeyboardEvent extends UIEvent native "*KeyboardEvent" {
+ factory KeyboardEvent(String type, Window view,
+ [bool canBubble = true, bool cancelable = true,
+ String keyIdentifier = null, int keyLocation = 1, bool ctrlKey = false,
+ bool altKey = false, bool shiftKey = false, bool metaKey = false,
+ bool altGraphKey = false]) {
+ final e = document.$dom_createEvent("KeyboardEvent");
+ e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+ keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
+ return e;
+ }
+
+ /** @domName KeyboardEvent.initKeyboardEvent */
+ void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+ bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
+ // initKeyEvent is the call in Firefox, initKeyboardEvent for all other
+ // browsers.
+ var function = JS('dynamic', '#.initKeyboardEvent || #.initKeyEvent', this,
+ this);
+ JS('void', '#(#, #, #, #, #, #, #, #, #, #, #)', function, type,
+ canBubble, cancelable, view, keyIdentifier, keyLocation, ctrlKey,
+ altKey, shiftKey, metaKey, altGraphKey);
+ }
+
+ /** @domName KeyboardEvent.keyCode */
+ int get keyCode => $dom_keyCode;
+
+ /** @domName KeyboardEvent.charCode */
+ int get charCode => $dom_charCode;
+
/// @domName KeyboardEvent.altGraphKey; @docsEditable true
final bool altGraphKey;
@@ -11606,7 +11113,8 @@
final bool ctrlKey;
/// @domName KeyboardEvent.keyIdentifier; @docsEditable true
- final String keyIdentifier;
+ @JSName('keyIdentifier')
+ final String $dom_keyIdentifier;
/// @domName KeyboardEvent.keyLocation; @docsEditable true
final int keyLocation;
@@ -11617,8 +11125,6 @@
/// @domName KeyboardEvent.shiftKey; @docsEditable true
final bool shiftKey;
- /// @domName KeyboardEvent.initKeyboardEvent; @docsEditable true
- void initKeyboardEvent(String type, bool canBubble, bool cancelable, LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) native;
}
// 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
@@ -11646,7 +11152,7 @@
String keytype;
/// @domName HTMLKeygenElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLKeygenElement.name; @docsEditable true
@@ -11776,7 +11282,10 @@
final int length;
/// @domName History.state; @docsEditable true
- final dynamic state;
+ dynamic get state => _convertNativeToDart_SerializedScriptValue(this._state);
+ @JSName('state')
+ @_annotation_Creates_SerializedScriptValue @_annotation_Returns_SerializedScriptValue
+ final dynamic _state;
/// @domName History.back; @docsEditable true
void back() native;
@@ -11860,6 +11369,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Window
class LocalWindow extends EventTarget implements Window native "@*DOMWindow" {
Document get document => JS('Document', '#.document', this);
@@ -11880,7 +11390,7 @@
// API level getter and setter for Location.
// TODO: The cross domain safe wrapper can be inserted here or folded into
// _LocationWrapper.
- LocalLocation get location() {
+ LocalLocation get location {
// Firefox work-around for Location. The Firefox location object cannot be
// made to behave like a Dart object so must be wrapped.
var result = _location;
@@ -11913,7 +11423,8 @@
}
// Prevent compiled from thinking 'location' property is available for a Dart
// member.
- _protect_location() native 'location';
+ @JSName('location')
+ _protect_location() native;
static _isDartLocation(thing) {
// On Firefox the code that implements 'is Location' fails to find the patch
@@ -11945,11 +11456,11 @@
_cancelAnimationFrame(id);
}
- int _requestAnimationFrame(RequestAnimationFrameCallback callback)
- native 'requestAnimationFrame';
+ @JSName('requestAnimationFrame')
+ int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;
- void _cancelAnimationFrame(int id)
- native 'cancelAnimationFrame';
+ @JSName('cancelAnimationFrame')
+ void _cancelAnimationFrame(int id) native;
_ensureRequestAnimationFrame() {
if (JS('bool',
@@ -11977,7 +11488,7 @@
this);
}
- IDBFactory get indexedDB() =>
+ IDBFactory get indexedDB =>
JS('IDBFactory',
'#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
this, this, this);
@@ -12063,7 +11574,9 @@
/// @domName Window.opener; @docsEditable true
Window get opener => _convertNativeToDart_Window(this._opener);
- dynamic get _opener => JS("dynamic", "#.opener", this);
+ @JSName('opener')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _opener;
/// @domName Window.outerHeight; @docsEditable true
final int outerHeight;
@@ -12082,7 +11595,9 @@
/// @domName Window.parent; @docsEditable true
Window get parent => _convertNativeToDart_Window(this._parent);
- dynamic get _parent => JS("dynamic", "#.parent", this);
+ @JSName('parent')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _parent;
/// @domName Window.performance; @docsEditable true
final Performance performance;
@@ -12116,7 +11631,9 @@
/// @domName Window.self; @docsEditable true
Window get self => _convertNativeToDart_Window(this._self);
- dynamic get _self => JS("dynamic", "#.self", this);
+ @JSName('self')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _self;
/// @domName Window.sessionStorage; @docsEditable true
final Storage sessionStorage;
@@ -12135,7 +11652,9 @@
/// @domName Window.top; @docsEditable true
Window get top => _convertNativeToDart_Window(this._top);
- dynamic get _top => JS("dynamic", "#.top", this);
+ @JSName('top')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _top;
/// @domName DOMWindow.webkitIndexedDB; @docsEditable true
final IDBFactory webkitIndexedDB;
@@ -12148,10 +11667,13 @@
/// @domName Window.window; @docsEditable true
Window get window => _convertNativeToDart_Window(this._window);
- dynamic get _window => JS("dynamic", "#.window", this);
+ @JSName('window')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _window;
/// @domName Window.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName Window.alert; @docsEditable true
void alert(String message) native;
@@ -12178,17 +11700,20 @@
bool confirm(String message) native;
/// @domName Window.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName Window.find; @docsEditable true
bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native;
/// @domName Window.getComputedStyle; @docsEditable true
- CSSStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native "getComputedStyle";
+ @JSName('getComputedStyle')
+ CSSStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native;
/// @domName Window.getMatchedCSSRules; @docsEditable true
+ @JSName('getMatchedCSSRules')
@Returns('_CSSRuleList') @Creates('_CSSRuleList')
- List<CSSRule> getMatchedCSSRules(Element element, String pseudoElement) native;
+ List<CSSRule> getMatchedCssRules(Element element, String pseudoElement) native;
/// @domName Window.getSelection; @docsEditable true
DOMSelection getSelection() native;
@@ -12221,8 +11746,10 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- void _postMessage_1(message, targetOrigin) native "postMessage";
- void _postMessage_2(message, targetOrigin, List messagePorts) native "postMessage";
+ @JSName('postMessage')
+ void _postMessage_1(message, targetOrigin) native;
+ @JSName('postMessage')
+ void _postMessage_2(message, targetOrigin, List messagePorts) native;
/// @domName Window.print; @docsEditable true
void print() native;
@@ -12231,7 +11758,8 @@
void releaseEvents() native;
/// @domName Window.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName Window.resizeBy; @docsEditable true
void resizeBy(num x, num y) native;
@@ -12270,7 +11798,8 @@
void webkitRequestFileSystem(int type, int size, FileSystemCallback successCallback, [ErrorCallback errorCallback]) native;
/// @domName DOMWindow.webkitResolveLocalFileSystemURL; @docsEditable true
- void webkitResolveLocalFileSystemURL(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
+ @JSName('webkitResolveLocalFileSystemURL')
+ void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
}
@@ -12527,10 +12056,12 @@
num volume;
/// @domName MediaController.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MediaController.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName MediaController.pause; @docsEditable true
void pause() native;
@@ -12539,7 +12070,8 @@
void play() native;
/// @domName MediaController.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
// 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
@@ -12750,17 +12282,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName MediaElementAudioSourceNode; @docsEditable true
-class MediaElementAudioSourceNode extends AudioSourceNode native "*MediaElementAudioSourceNode" {
-
- /// @domName MediaElementAudioSourceNode.mediaElement; @docsEditable true
- final MediaElement mediaElement;
-}
-// 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.
-
-
/// @domName MediaError; @docsEditable true
class MediaError native "*MediaError" {
@@ -12809,7 +12330,8 @@
class MediaKeyEvent extends Event native "*MediaKeyEvent" {
/// @domName MediaKeyEvent.defaultURL; @docsEditable true
- final String defaultURL;
+ @JSName('defaultURL')
+ final String defaultUrl;
/// @domName MediaKeyEvent.errorCode; @docsEditable true
final MediaKeyError errorCode;
@@ -12906,19 +12428,22 @@
final SourceBufferList sourceBuffers;
/// @domName MediaSource.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MediaSource.addSourceBuffer; @docsEditable true
SourceBuffer addSourceBuffer(String type) native;
/// @domName MediaSource.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName MediaSource.endOfStream; @docsEditable true
void endOfStream(String error) native;
/// @domName MediaSource.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MediaSource.removeSourceBuffer; @docsEditable true
void removeSourceBuffer(SourceBuffer buffer) native;
@@ -12954,13 +12479,16 @@
final MediaStreamTrackList videoTracks;
/// @domName MediaStream.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MediaStream.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName MediaStream.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class MediaStreamEvents extends Events {
@@ -12973,17 +12501,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName MediaStreamAudioSourceNode; @docsEditable true
-class MediaStreamAudioSourceNode extends AudioSourceNode native "*MediaStreamAudioSourceNode" {
-
- /// @domName MediaStreamAudioSourceNode.mediaStream; @docsEditable true
- final MediaStream mediaStream;
-}
-// 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.
-
-
/// @domName MediaStreamEvent; @docsEditable true
class MediaStreamEvent extends Event native "*MediaStreamEvent" {
@@ -13021,13 +12538,16 @@
final int readyState;
/// @domName MediaStreamTrack.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MediaStreamTrack.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName MediaStreamTrack.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class MediaStreamTrackEvents extends Events {
@@ -13069,10 +12589,12 @@
void add(MediaStreamTrack track) native;
/// @domName MediaStreamTrackList.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MediaStreamTrackList.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName MediaStreamTrackList.item; @docsEditable true
MediaStreamTrack item(int index) native;
@@ -13081,7 +12603,8 @@
void remove(MediaStreamTrack track) native;
/// @domName MediaStreamTrackList.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class MediaStreamTrackListEvents extends Events {
@@ -13113,13 +12636,20 @@
// BSD-style license that can be found in the LICENSE file.
+/**
+ * An HTML <menu> element.
+ *
+ * A <menu> element represents an unordered list of menu commands.
+ *
+ * See also:
+ *
+ * * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
+ * * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
+ */
/// @domName HTMLMenuElement; @docsEditable true
class MenuElement extends Element implements Element native "*HTMLMenuElement" {
factory MenuElement() => document.$dom_createElement("menu");
-
- /// @domName HTMLMenuElement.compact; @docsEditable true
- bool compact;
}
// 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
@@ -13147,7 +12677,9 @@
/// @domName MessageEvent.data; @docsEditable true
dynamic get data => _convertNativeToDart_SerializedScriptValue(this._data);
- dynamic get _data => JS("dynamic", "#.data", this);
+ @JSName('data')
+ @_annotation_Creates_SerializedScriptValue @_annotation_Returns_SerializedScriptValue
+ final dynamic _data;
/// @domName MessageEvent.lastEventId; @docsEditable true
final String lastEventId;
@@ -13161,7 +12693,9 @@
/// @domName MessageEvent.source; @docsEditable true
Window get source => _convertNativeToDart_Window(this._source);
- dynamic get _source => JS("dynamic", "#.source", this);
+ @JSName('source')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _source;
/// @domName MessageEvent.initMessageEvent; @docsEditable true
void initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, LocalWindow sourceArg, List messagePorts) native;
@@ -13182,13 +12716,15 @@
new MessagePortEvents(this);
/// @domName MessagePort.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MessagePort.close; @docsEditable true
void close() native;
/// @domName MessagePort.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName MessagePort.postMessage; @docsEditable true
void postMessage(/*any*/ message, [List messagePorts]) {
@@ -13201,11 +12737,14 @@
_postMessage_2(message_2);
return;
}
- void _postMessage_1(message, List messagePorts) native "postMessage";
- void _postMessage_2(message) native "postMessage";
+ @JSName('postMessage')
+ void _postMessage_1(message, List messagePorts) native;
+ @JSName('postMessage')
+ void _postMessage_2(message) native;
/// @domName MessagePort.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName MessagePort.start; @docsEditable true
void start() native;
@@ -13272,7 +12811,7 @@
num high;
/// @domName HTMLMeterElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLMeterElement.low; @docsEditable true
@@ -13309,6 +12848,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName MouseEvent
class MouseEvent extends UIEvent native "*MouseEvent" {
factory MouseEvent(String type, Window view, int detail, int screenX,
int screenY, int clientX, int clientY, int button, [bool canBubble = true,
@@ -13347,7 +12887,9 @@
/// @domName MouseEvent.relatedTarget; @docsEditable true
EventTarget get relatedTarget => _convertNativeToDart_EventTarget(this._relatedTarget);
- dynamic get _relatedTarget => JS("dynamic", "#.relatedTarget", this);
+ @JSName('relatedTarget')
+ @Creates('EventTarget|=Object') @Returns('EventTarget|=Object')
+ final dynamic _relatedTarget;
/// @domName MouseEvent.screenX; @docsEditable true
final int screenX;
@@ -13379,7 +12921,8 @@
_$dom_initMouseEvent_1(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget_1);
return;
}
- void _$dom_initMouseEvent_1(type, canBubble, cancelable, LocalWindow view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native "initMouseEvent";
+ @JSName('initMouseEvent')
+ void _$dom_initMouseEvent_1(type, canBubble, cancelable, LocalWindow view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
int get offsetX {
@@ -13455,6 +12998,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName MutationObserver
class MutationObserver native "*MutationObserver" {
factory MutationObserver(MutationCallback callback) => _MutationObserverFactoryProvider.createMutationObserver(callback);
@@ -13468,7 +13012,8 @@
__observe_1(target, options_1);
return;
}
- void __observe_1(Node target, options) native "observe";
+ @JSName('observe')
+ void __observe_1(Node target, options) native;
/// @domName MutationObserver.takeRecords; @docsEditable true
List<MutationRecord> takeRecords() native;
@@ -13532,7 +13077,8 @@
static _fixupList(list) => list; // TODO: Ensure is a JavaScript Array.
// Call native function with no conversions.
- void _call(target, options) native 'observe';
+ @JSName('observe')
+ void _call(target, options) native;
}
// 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
@@ -13543,7 +13089,7 @@
class MutationRecord native "*MutationRecord" {
/// @domName MutationRecord.addedNodes; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> addedNodes;
/// @domName MutationRecord.attributeName; @docsEditable true
@@ -13562,7 +13108,7 @@
final Node previousSibling;
/// @domName MutationRecord.removedNodes; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> removedNodes;
/// @domName MutationRecord.target; @docsEditable true
@@ -13765,8 +13311,10 @@
_webkitGetUserMedia_2(options_2, successCallback);
return;
}
- void _webkitGetUserMedia_1(options, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback) native "webkitGetUserMedia";
- void _webkitGetUserMedia_2(options, NavigatorUserMediaSuccessCallback successCallback) native "webkitGetUserMedia";
+ @JSName('webkitGetUserMedia')
+ void _webkitGetUserMedia_1(options, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback) native;
+ @JSName('webkitGetUserMedia')
+ void _webkitGetUserMedia_2(options, NavigatorUserMediaSuccessCallback successCallback) native;
}
// 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
@@ -13905,6 +13453,7 @@
Node operator[](int index) => _this.$dom_childNodes[index];
}
+/// @domName Node
class Node extends EventTarget native "*Node" {
_ChildNodeListLazy get nodes {
return new _ChildNodeListLazy(this);
@@ -13985,54 +13534,71 @@
static const int TEXT_NODE = 3;
/// @domName Node.attributes; @docsEditable true
- NamedNodeMap get $dom_attributes => JS("NamedNodeMap", "#.attributes", this);
+ @JSName('attributes')
+ final NamedNodeMap $dom_attributes;
/// @domName Node.childNodes; @docsEditable true
- List<Node> get $dom_childNodes => JS("_NodeList", "#.childNodes", this);
+ @JSName('childNodes')
+ @Returns('NodeList') @Creates('NodeList')
+ final List<Node> $dom_childNodes;
/// @domName Node.firstChild; @docsEditable true
- Node get $dom_firstChild => JS("Node", "#.firstChild", this);
+ @JSName('firstChild')
+ final Node $dom_firstChild;
/// @domName Node.lastChild; @docsEditable true
- Node get $dom_lastChild => JS("Node", "#.lastChild", this);
+ @JSName('lastChild')
+ final Node $dom_lastChild;
+
+ /// @domName Node.localName; @docsEditable true
+ @JSName('localName')
+ final String $dom_localName;
+
+ /// @domName Node.namespaceURI; @docsEditable true
+ @JSName('namespaceURI')
+ final String $dom_namespaceUri;
/// @domName Node.nextSibling; @docsEditable true
- Node get nextNode => JS("Node", "#.nextSibling", this);
+ @JSName('nextSibling')
+ final Node nextNode;
/// @domName Node.nodeType; @docsEditable true
final int nodeType;
/// @domName Node.ownerDocument; @docsEditable true
- Document get document => JS("Document", "#.ownerDocument", this);
+ @JSName('ownerDocument')
+ final Document document;
/// @domName Node.parentNode; @docsEditable true
- Node get parent => JS("Node", "#.parentNode", this);
+ @JSName('parentNode')
+ final Node parent;
/// @domName Node.previousSibling; @docsEditable true
- Node get previousNode => JS("Node", "#.previousSibling", this);
+ @JSName('previousSibling')
+ final Node previousNode;
/// @domName Node.textContent; @docsEditable true
- String get text => JS("String", "#.textContent", this);
-
- /// @domName Node.textContent; @docsEditable true
- void set text(String value) {
- JS("void", "#.textContent = #", this, value);
- }
+ @JSName('textContent')
+ String text;
/// @domName Node.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName Node.appendChild; @docsEditable true
- Node $dom_appendChild(Node newChild) native "appendChild";
+ @JSName('appendChild')
+ Node $dom_appendChild(Node newChild) native;
/// @domName Node.cloneNode; @docsEditable true
- Node clone(bool deep) native "cloneNode";
+ @JSName('cloneNode')
+ Node clone(bool deep) native;
/// @domName Node.contains; @docsEditable true
bool contains(Node other) native;
/// @domName Node.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName Node.hasChildNodes; @docsEditable true
bool hasChildNodes() native;
@@ -14041,13 +13607,16 @@
Node insertBefore(Node newChild, Node refChild) native;
/// @domName Node.removeChild; @docsEditable true
- Node $dom_removeChild(Node oldChild) native "removeChild";
+ @JSName('removeChild')
+ Node $dom_removeChild(Node oldChild) native;
/// @domName Node.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName Node.replaceChild; @docsEditable true
- Node $dom_replaceChild(Node newChild, Node oldChild) native "replaceChild";
+ @JSName('replaceChild')
+ Node $dom_replaceChild(Node newChild, Node oldChild) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -14133,6 +13702,106 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName NodeList; @docsEditable true
+class NodeList implements JavaScriptIndexingBehavior, List<Node> native "*NodeList" {
+
+ /// @domName NodeList.length; @docsEditable true
+ final int length;
+
+ Node operator[](int index) => JS("Node", "#[#]", this, index);
+
+ void operator[]=(int index, Node value) {
+ throw new UnsupportedError("Cannot assign element of immutable List.");
+ }
+ // -- start List<Node> mixins.
+ // Node is the element type.
+
+ // From Iterable<Node>:
+
+ Iterator<Node> iterator() {
+ // Note: NodeLists are not fixed size. And most probably length shouldn't
+ // be cached in both iterator _and_ forEach method. For now caching it
+ // for consistency.
+ return new FixedSizeListIterator<Node>(this);
+ }
+
+ // From Collection<Node>:
+
+ void add(Node value) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void addLast(Node value) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void addAll(Collection<Node> collection) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ bool contains(Node element) => _Collections.contains(this, element);
+
+ void forEach(void f(Node element)) => _Collections.forEach(this, f);
+
+ Collection map(f(Node element)) => _Collections.map(this, [], f);
+
+ Collection<Node> filter(bool f(Node element)) =>
+ _Collections.filter(this, <Node>[], f);
+
+ bool every(bool f(Node element)) => _Collections.every(this, f);
+
+ bool some(bool f(Node element)) => _Collections.some(this, f);
+
+ bool get isEmpty => this.length == 0;
+
+ // From List<Node>:
+
+ void sort([Comparator<Node> compare = Comparable.compare]) {
+ throw new UnsupportedError("Cannot sort immutable List.");
+ }
+
+ int indexOf(Node element, [int start = 0]) =>
+ _Lists.indexOf(this, element, start, this.length);
+
+ int lastIndexOf(Node element, [int start]) {
+ if (start == null) start = length - 1;
+ return _Lists.lastIndexOf(this, element, start);
+ }
+
+ Node get first => this[0];
+
+ Node get last => this[length - 1];
+
+ Node removeLast() {
+ throw new UnsupportedError("Cannot removeLast on immutable List.");
+ }
+
+ void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ throw new UnsupportedError("Cannot setRange on immutable List.");
+ }
+
+ void removeRange(int start, int rangeLength) {
+ throw new UnsupportedError("Cannot removeRange on immutable List.");
+ }
+
+ void insertRange(int start, int rangeLength, [Node initialValue]) {
+ throw new UnsupportedError("Cannot insertRange on immutable List.");
+ }
+
+ List<Node> getRange(int start, int rangeLength) =>
+ _Lists.getRange(this, start, rangeLength, <Node>[]);
+
+ // -- end List<Node> mixins.
+
+ /// @domName NodeList.item; @docsEditable true
+ @JSName('item')
+ Node _item(int index) native;
+}
+// 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.
+
+
/// @domName Notation; @docsEditable true
class Notation extends Node native "*Notation" {
@@ -14174,7 +13843,8 @@
String tag;
/// @domName Notification.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName Notification.cancel; @docsEditable true
void cancel() native;
@@ -14183,10 +13853,12 @@
void close() native;
/// @domName Notification.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName Notification.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName Notification.requestPermission; @docsEditable true
static void requestPermission(NotificationPermissionCallback callback) native;
@@ -14220,7 +13892,8 @@
int checkPermission() native;
/// @domName NotificationCenter.createHTMLNotification; @docsEditable true
- Notification createHTMLNotification(String url) native;
+ @JSName('createHTMLNotification')
+ Notification createHtmlNotification(String url) native;
/// @domName NotificationCenter.createNotification; @docsEditable true
Notification createNotification(String iconUrl, String title, String body) native;
@@ -14273,16 +13946,20 @@
static const int VERTEX_ARRAY_BINDING_OES = 0x85B5;
/// @domName OESVertexArrayObject.bindVertexArrayOES; @docsEditable true
- void bindVertexArrayOES(WebGLVertexArrayObjectOES arrayObject) native;
+ @JSName('bindVertexArrayOES')
+ void bindVertexArray(WebGLVertexArrayObjectOES arrayObject) native;
/// @domName OESVertexArrayObject.createVertexArrayOES; @docsEditable true
- WebGLVertexArrayObjectOES createVertexArrayOES() native;
+ @JSName('createVertexArrayOES')
+ WebGLVertexArrayObjectOES createVertexArray() native;
/// @domName OESVertexArrayObject.deleteVertexArrayOES; @docsEditable true
- void deleteVertexArrayOES(WebGLVertexArrayObjectOES arrayObject) native;
+ @JSName('deleteVertexArrayOES')
+ void deleteVertexArray(WebGLVertexArrayObjectOES arrayObject) native;
/// @domName OESVertexArrayObject.isVertexArrayOES; @docsEditable true
- bool isVertexArrayOES(WebGLVertexArrayObjectOES arrayObject) native;
+ @JSName('isVertexArrayOES')
+ bool isVertexArray(WebGLVertexArrayObjectOES arrayObject) native;
}
// 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
@@ -14387,17 +14064,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName OfflineAudioCompletionEvent; @docsEditable true
-class OfflineAudioCompletionEvent extends Event native "*OfflineAudioCompletionEvent" {
-
- /// @domName OfflineAudioCompletionEvent.renderedBuffer; @docsEditable true
- final AudioBuffer renderedBuffer;
-}
-// 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.
-
-
/// @domName HTMLOptGroupElement; @docsEditable true
class OptGroupElement extends Element implements Element native "*HTMLOptGroupElement" {
@@ -14459,53 +14125,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName OscillatorNode; @docsEditable true
-class OscillatorNode extends AudioSourceNode native "*OscillatorNode" {
-
- static const int CUSTOM = 4;
-
- static const int FINISHED_STATE = 3;
-
- static const int PLAYING_STATE = 2;
-
- static const int SAWTOOTH = 2;
-
- static const int SCHEDULED_STATE = 1;
-
- static const int SINE = 0;
-
- static const int SQUARE = 1;
-
- static const int TRIANGLE = 3;
-
- static const int UNSCHEDULED_STATE = 0;
-
- /// @domName OscillatorNode.detune; @docsEditable true
- final AudioParam detune;
-
- /// @domName OscillatorNode.frequency; @docsEditable true
- final AudioParam frequency;
-
- /// @domName OscillatorNode.playbackState; @docsEditable true
- final int playbackState;
-
- /// @domName OscillatorNode.type; @docsEditable true
- int type;
-
- /// @domName OscillatorNode.setWaveTable; @docsEditable true
- void setWaveTable(WaveTable waveTable) native;
-
- /// @domName OscillatorNode.start; @docsEditable true
- void start(num when) native;
-
- /// @domName OscillatorNode.stop; @docsEditable true
- void stop(num when) native;
-}
-// 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.
-
-
/// @domName HTMLOutputElement; @docsEditable true
class OutputElement extends Element implements Element native "*HTMLOutputElement" {
@@ -14521,7 +14140,7 @@
DOMSettableTokenList htmlFor;
/// @domName HTMLOutputElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLOutputElement.name; @docsEditable true
@@ -14601,65 +14220,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName PannerNode; @docsEditable true
-class PannerNode extends AudioNode native "*PannerNode" {
-
- static const int EQUALPOWER = 0;
-
- static const int EXPONENTIAL_DISTANCE = 2;
-
- static const int HRTF = 1;
-
- static const int INVERSE_DISTANCE = 1;
-
- static const int LINEAR_DISTANCE = 0;
-
- static const int SOUNDFIELD = 2;
-
- /// @domName PannerNode.coneGain; @docsEditable true
- final AudioGain coneGain;
-
- /// @domName PannerNode.coneInnerAngle; @docsEditable true
- num coneInnerAngle;
-
- /// @domName PannerNode.coneOuterAngle; @docsEditable true
- num coneOuterAngle;
-
- /// @domName PannerNode.coneOuterGain; @docsEditable true
- num coneOuterGain;
-
- /// @domName PannerNode.distanceGain; @docsEditable true
- final AudioGain distanceGain;
-
- /// @domName PannerNode.distanceModel; @docsEditable true
- int distanceModel;
-
- /// @domName PannerNode.maxDistance; @docsEditable true
- num maxDistance;
-
- /// @domName PannerNode.panningModel; @docsEditable true
- int panningModel;
-
- /// @domName PannerNode.refDistance; @docsEditable true
- num refDistance;
-
- /// @domName PannerNode.rolloffFactor; @docsEditable true
- num rolloffFactor;
-
- /// @domName PannerNode.setOrientation; @docsEditable true
- void setOrientation(num x, num y, num z) native;
-
- /// @domName PannerNode.setPosition; @docsEditable true
- void setPosition(num x, num y, num z) native;
-
- /// @domName PannerNode.setVelocity; @docsEditable true
- void setVelocity(num x, num y, num z) native;
-}
-// 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.
-
-
/// @domName HTMLParagraphElement; @docsEditable true
class ParagraphElement extends Element implements Element native "*HTMLParagraphElement" {
@@ -14753,7 +14313,8 @@
final List<MediaStream> remoteStreams;
/// @domName PeerConnection00.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName PeerConnection00.addStream; @docsEditable true
void addStream(MediaStream stream, [Map mediaStreamHints]) {
@@ -14765,8 +14326,10 @@
_addStream_2(stream);
return;
}
- void _addStream_1(MediaStream stream, mediaStreamHints) native "addStream";
- void _addStream_2(MediaStream stream) native "addStream";
+ @JSName('addStream')
+ void _addStream_1(MediaStream stream, mediaStreamHints) native;
+ @JSName('addStream')
+ void _addStream_2(MediaStream stream) native;
/// @domName PeerConnection00.close; @docsEditable true
void close() native;
@@ -14779,8 +14342,10 @@
}
return _createAnswer_2(offer);
}
- SessionDescription _createAnswer_1(offer, mediaHints) native "createAnswer";
- SessionDescription _createAnswer_2(offer) native "createAnswer";
+ @JSName('createAnswer')
+ SessionDescription _createAnswer_1(offer, mediaHints) native;
+ @JSName('createAnswer')
+ SessionDescription _createAnswer_2(offer) native;
/// @domName PeerConnection00.createOffer; @docsEditable true
SessionDescription createOffer([Map mediaHints]) {
@@ -14790,17 +14355,21 @@
}
return _createOffer_2();
}
- SessionDescription _createOffer_1(mediaHints) native "createOffer";
- SessionDescription _createOffer_2() native "createOffer";
+ @JSName('createOffer')
+ SessionDescription _createOffer_1(mediaHints) native;
+ @JSName('createOffer')
+ SessionDescription _createOffer_2() native;
/// @domName PeerConnection00.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName PeerConnection00.processIceMessage; @docsEditable true
void processIceMessage(IceCandidate candidate) native;
/// @domName PeerConnection00.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName PeerConnection00.removeStream; @docsEditable true
void removeStream(MediaStream stream) native;
@@ -14821,8 +14390,10 @@
_startIce_2();
return;
}
- void _startIce_1(iceOptions) native "startIce";
- void _startIce_2() native "startIce";
+ @JSName('startIce')
+ void _startIce_1(iceOptions) native;
+ @JSName('startIce')
+ void _startIce_2() native;
}
class PeerConnection00Events extends Events {
@@ -14958,6 +14529,7 @@
// WARNING: Do not edit - generated code.
+/// @domName WebKitPoint
class Point native "*WebKitPoint" {
factory Point(num x, num y) => _PointFactoryProvider.createPoint(x, y);
@@ -14978,7 +14550,9 @@
/// @domName PopStateEvent.state; @docsEditable true
dynamic get state => _convertNativeToDart_SerializedScriptValue(this._state);
- dynamic get _state => JS("dynamic", "#.state", this);
+ @JSName('state')
+ @_annotation_Creates_SerializedScriptValue @_annotation_Returns_SerializedScriptValue
+ final dynamic _state;
}
// 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
@@ -15060,7 +14634,7 @@
factory ProgressElement() => document.$dom_createElement("progress");
/// @domName HTMLProgressElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLProgressElement.max; @docsEditable true
@@ -15145,16 +14719,19 @@
final bool reliable;
/// @domName RTCDataChannel.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName RTCDataChannel.close; @docsEditable true
void close() native;
/// @domName RTCDataChannel.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName RTCDataChannel.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName RTCDataChannel.send; @docsEditable true
void send(data) native;
@@ -15260,7 +14837,8 @@
final List<MediaStream> remoteStreams;
/// @domName RTCPeerConnection.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName RTCPeerConnection.addIceCandidate; @docsEditable true
void addIceCandidate(RTCIceCandidate candidate) native;
@@ -15275,8 +14853,10 @@
_addStream_2(stream);
return;
}
- void _addStream_1(MediaStream stream, mediaConstraints) native "addStream";
- void _addStream_2(MediaStream stream) native "addStream";
+ @JSName('addStream')
+ void _addStream_1(MediaStream stream, mediaConstraints) native;
+ @JSName('addStream')
+ void _addStream_2(MediaStream stream) native;
/// @domName RTCPeerConnection.close; @docsEditable true
void close() native;
@@ -15291,8 +14871,10 @@
_createAnswer_2(successCallback, failureCallback);
return;
}
- void _createAnswer_1(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback, mediaConstraints) native "createAnswer";
- void _createAnswer_2(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback) native "createAnswer";
+ @JSName('createAnswer')
+ void _createAnswer_1(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback, mediaConstraints) native;
+ @JSName('createAnswer')
+ void _createAnswer_2(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback) native;
/// @domName RTCPeerConnection.createDataChannel; @docsEditable true
RTCDataChannel createDataChannel(String label, [Map options]) {
@@ -15302,8 +14884,10 @@
}
return _createDataChannel_2(label);
}
- RTCDataChannel _createDataChannel_1(label, options) native "createDataChannel";
- RTCDataChannel _createDataChannel_2(label) native "createDataChannel";
+ @JSName('createDataChannel')
+ RTCDataChannel _createDataChannel_1(label, options) native;
+ @JSName('createDataChannel')
+ RTCDataChannel _createDataChannel_2(label) native;
/// @domName RTCPeerConnection.createOffer; @docsEditable true
void createOffer(RTCSessionDescriptionCallback successCallback, [RTCErrorCallback failureCallback, Map mediaConstraints]) {
@@ -15315,17 +14899,21 @@
_createOffer_2(successCallback, failureCallback);
return;
}
- void _createOffer_1(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback, mediaConstraints) native "createOffer";
- void _createOffer_2(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback) native "createOffer";
+ @JSName('createOffer')
+ void _createOffer_1(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback, mediaConstraints) native;
+ @JSName('createOffer')
+ void _createOffer_2(RTCSessionDescriptionCallback successCallback, RTCErrorCallback failureCallback) native;
/// @domName RTCPeerConnection.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName RTCPeerConnection.getStats; @docsEditable true
void getStats(RTCStatsCallback successCallback, MediaStreamTrack selector) native;
/// @domName RTCPeerConnection.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName RTCPeerConnection.removeStream; @docsEditable true
void removeStream(MediaStream stream) native;
@@ -15352,9 +14940,12 @@
_updateIce_3();
return;
}
- void _updateIce_1(configuration, mediaConstraints) native "updateIce";
- void _updateIce_2(configuration) native "updateIce";
- void _updateIce_3() native "updateIce";
+ @JSName('updateIce')
+ void _updateIce_1(configuration, mediaConstraints) native;
+ @JSName('updateIce')
+ void _updateIce_2(configuration) native;
+ @JSName('updateIce')
+ void _updateIce_3() native;
}
class RTCPeerConnectionEvents extends Events {
@@ -15451,7 +15042,7 @@
/// @domName RadioNodeList; @docsEditable true
-class RadioNodeList extends _NodeList native "*RadioNodeList" {
+class RadioNodeList extends NodeList native "*RadioNodeList" {
/// @domName RadioNodeList.value; @docsEditable true
String value;
@@ -15803,8 +15394,9 @@
Map item(int index) {
return _convertNativeToDart_Dictionary(_item_1(index));
}
+ @JSName('item')
@Creates('=Object')
- _item_1(index) native "item";
+ _item_1(index) native;
}
// 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
@@ -15939,27 +15531,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName ScriptProcessorNode; @docsEditable true
-class ScriptProcessorNode extends AudioNode implements EventTarget native "*ScriptProcessorNode" {
-
- /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
- ScriptProcessorNodeEvents get on =>
- new ScriptProcessorNodeEvents(this);
-
- /// @domName ScriptProcessorNode.bufferSize; @docsEditable true
- final int bufferSize;
-}
-
-class ScriptProcessorNodeEvents extends Events {
- ScriptProcessorNodeEvents(EventTarget _ptr) : super(_ptr);
-
- EventListenerList get audioProcess => this['audioprocess'];
-}
-// 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.
-
-
/// @domName ScriptProfile; @docsEditable true
class ScriptProfile native "*ScriptProfile" {
@@ -15981,7 +15552,8 @@
class ScriptProfileNode native "*ScriptProfileNode" {
/// @domName ScriptProfileNode.callUID; @docsEditable true
- final int callUID;
+ @JSName('callUID')
+ final int callUid;
/// @domName ScriptProfileNode.functionName; @docsEditable true
final String functionName;
@@ -16012,6 +15584,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName HTMLSelectElement
class SelectElement extends Element implements Element native "*HTMLSelectElement" {
factory SelectElement() => document.$dom_createElement("select");
@@ -16026,7 +15599,7 @@
final FormElement form;
/// @domName HTMLSelectElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLSelectElement.length; @docsEditable true
@@ -16124,6 +15697,7 @@
// WARNING: Do not edit - generated code.
+/// @domName ShadowRoot
class ShadowRoot extends DocumentFragment native "*ShadowRoot" {
factory ShadowRoot(Element host) => _ShadowRootFactoryProvider.createShadowRoot(host);
@@ -16135,24 +15709,29 @@
bool applyAuthorStyles;
/// @domName ShadowRoot.innerHTML; @docsEditable true
- String innerHTML;
+ @JSName('innerHTML')
+ String innerHtml;
/// @domName ShadowRoot.resetStyleInheritance; @docsEditable true
bool resetStyleInheritance;
/// @domName ShadowRoot.cloneNode; @docsEditable true
- Node clone(bool deep) native "cloneNode";
+ @JSName('cloneNode')
+ Node clone(bool deep) native;
/// @domName ShadowRoot.getElementById; @docsEditable true
- Element $dom_getElementById(String elementId) native "getElementById";
+ @JSName('getElementById')
+ Element $dom_getElementById(String elementId) native;
/// @domName ShadowRoot.getElementsByClassName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByClassName(String className) native "getElementsByClassName";
+ @JSName('getElementsByClassName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByClassName(String className) native;
/// @domName ShadowRoot.getElementsByTagName; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
- List<Node> $dom_getElementsByTagName(String tagName) native "getElementsByTagName";
+ @JSName('getElementsByTagName')
+ @Returns('NodeList') @Creates('NodeList')
+ List<Node> $dom_getElementsByTagName(String tagName) native;
/// @domName ShadowRoot.getSelection; @docsEditable true
DOMSelection getSelection() native;
@@ -16316,16 +15895,19 @@
// -- end List<SourceBuffer> mixins.
/// @domName SourceBufferList.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName SourceBufferList.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName SourceBufferList.item; @docsEditable true
SourceBuffer item(int index) native;
/// @domName SourceBufferList.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
// 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
@@ -16538,13 +16120,16 @@
void abort() native;
/// @domName SpeechRecognition.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName SpeechRecognition.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName SpeechRecognition.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName SpeechRecognition.start; @docsEditable true
void start() native;
@@ -16654,7 +16239,8 @@
final Document emma;
/// @domName SpeechRecognitionResult.finalValue; @docsEditable true
- bool get finalValue => JS("bool", "#.final", this);
+ @JSName('final')
+ final bool finalValue;
/// @domName SpeechRecognitionResult.length; @docsEditable true
final int length;
@@ -16667,6 +16253,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Storage
class Storage implements Map<String, String> native "*Storage" {
// TODO(nweiz): update this when maps support lazy iteration
@@ -16717,22 +16304,28 @@
bool get isEmpty => $dom_key(0) == null;
/// @domName Storage.length; @docsEditable true
- int get $dom_length => JS("int", "#.length", this);
+ @JSName('length')
+ final int $dom_length;
/// @domName Storage.clear; @docsEditable true
- void $dom_clear() native "clear";
+ @JSName('clear')
+ void $dom_clear() native;
/// @domName Storage.getItem; @docsEditable true
- String $dom_getItem(String key) native "getItem";
+ @JSName('getItem')
+ String $dom_getItem(String key) native;
/// @domName Storage.key; @docsEditable true
- String $dom_key(int index) native "key";
+ @JSName('key')
+ String $dom_key(int index) native;
/// @domName Storage.removeItem; @docsEditable true
- void $dom_removeItem(String key) native "removeItem";
+ @JSName('removeItem')
+ void $dom_removeItem(String key) native;
/// @domName Storage.setItem; @docsEditable true
- void $dom_setItem(String key, String data) native "setItem";
+ @JSName('setItem')
+ void $dom_setItem(String key, String data) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -16980,6 +16573,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName HTMLTableElement
class TableElement extends Element implements Element native "*HTMLTableElement" {
factory TableElement() => document.$dom_createElement("table");
@@ -17060,7 +16654,8 @@
return tbody;
}
- Element _createTBody() native 'createTBody';
+ @JSName('createTBody')
+ Element _createTBody() native;
}
// 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
@@ -17138,6 +16733,7 @@
// WARNING: Do not edit - generated code.
+/// @domName Text
class Text extends CharacterData native "*Text" {
factory Text(String data) => _TextFactoryProvider.createText(data);
@@ -17180,7 +16776,7 @@
final FormElement form;
/// @domName HTMLTextAreaElement.labels; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
final List<Node> labels;
/// @domName HTMLTextAreaElement.maxLength; @docsEditable true
@@ -17305,16 +16901,19 @@
void addCue(TextTrackCue cue) native;
/// @domName TextTrack.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName TextTrack.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName TextTrack.removeCue; @docsEditable true
void removeCue(TextTrackCue cue) native;
/// @domName TextTrack.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class TextTrackEvents extends Events {
@@ -17373,16 +16972,20 @@
String vertical;
/// @domName TextTrackCue.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName TextTrackCue.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName TextTrackCue.getCueAsHTML; @docsEditable true
- DocumentFragment getCueAsHTML() native;
+ @JSName('getCueAsHTML')
+ DocumentFragment getCueAsHtml() native;
/// @domName TextTrackCue.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class TextTrackCueEvents extends Events {
@@ -17595,16 +17198,19 @@
// -- end List<TextTrack> mixins.
/// @domName TextTrackList.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName TextTrackList.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName TextTrackList.item; @docsEditable true
TextTrack item(int index) native;
/// @domName TextTrackList.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
class TextTrackListEvents extends Events {
@@ -17678,7 +17284,9 @@
/// @domName Touch.target; @docsEditable true
EventTarget get target => _convertNativeToDart_EventTarget(this._target);
- dynamic get _target => JS("dynamic", "#.target", this);
+ @JSName('target')
+ @Creates('EventTarget|=Object') @Returns('EventTarget|=Object')
+ final dynamic _target;
/// @domName Touch.webkitForce; @docsEditable true
final num webkitForce;
@@ -17842,12 +17450,8 @@
static const int NONE = 0;
/// @domName HTMLTrackElement.defaultValue; @docsEditable true
- bool get defaultValue => JS("bool", "#.default", this);
-
- /// @domName HTMLTrackElement.defaultValue; @docsEditable true
- void set defaultValue(bool value) {
- JS("void", "#.default = #", this, value);
- }
+ @JSName('default')
+ bool defaultValue;
/// @domName HTMLTrackElement.kind; @docsEditable true
String kind;
@@ -17940,18 +17544,34 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// WARNING: Do not edit - generated code.
+
/// @domName UIEvent; @docsEditable true
class UIEvent extends Event native "*UIEvent" {
+ // In JS, canBubble and cancelable are technically required parameters to
+ // init*Event. In practice, though, if they aren't provided they simply
+ // default to false (since that's Boolean(undefined)).
+ //
+ // Contrary to JS, we default canBubble and cancelable to true, since that's
+ // what people want most of the time anyway.
+ factory UIEvent(String type, Window view, int detail,
+ [bool canBubble = true, bool cancelable = true]) {
+ final e = document.$dom_createEvent("UIEvent");
+ e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
+ return e;
+ }
/// @domName UIEvent.charCode; @docsEditable true
- final int charCode;
+ @JSName('charCode')
+ final int $dom_charCode;
/// @domName UIEvent.detail; @docsEditable true
final int detail;
/// @domName UIEvent.keyCode; @docsEditable true
- final int keyCode;
+ @JSName('keyCode')
+ final int $dom_keyCode;
/// @domName UIEvent.layerX; @docsEditable true
final int layerX;
@@ -17967,13 +17587,17 @@
/// @domName UIEvent.view; @docsEditable true
Window get view => _convertNativeToDart_Window(this._view);
- dynamic get _view => JS("dynamic", "#.view", this);
+ @JSName('view')
+ @Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')
+ final dynamic _view;
/// @domName UIEvent.which; @docsEditable true
final int which;
/// @domName UIEvent.initUIEvent; @docsEditable true
- void initUIEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail) native;
+ @JSName('initUIEvent')
+ void $dom_initUIEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail) native;
+
}
// 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
@@ -18096,7 +17720,8 @@
// -- end List<int> mixins.
/// @domName Uint16Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Uint16Array.subarray; @docsEditable true
Uint16Array subarray(int start, [int end]) native;
@@ -18206,7 +17831,8 @@
// -- end List<int> mixins.
/// @domName Uint32Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Uint32Array.subarray; @docsEditable true
Uint32Array subarray(int start, [int end]) native;
@@ -18316,7 +17942,8 @@
// -- end List<int> mixins.
/// @domName Uint8Array.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Uint8Array.subarray; @docsEditable true
Uint8Array subarray(int start, [int end]) native;
@@ -18342,7 +17969,8 @@
// final int length;
/// @domName Uint8ClampedArray.setElements; @docsEditable true
- void setElements(Object array, [int offset]) native "set";
+ @JSName('set')
+ void setElements(Object array, [int offset]) native;
/// @domName Uint8ClampedArray.subarray; @docsEditable true
Uint8ClampedArray subarray(int start, [int end]) native;
@@ -18360,6 +17988,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName URL
class Url native "*URL" {
static String createObjectUrl(blob_OR_source_OR_stream) =>
@@ -18469,17 +18098,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName WaveShaperNode; @docsEditable true
-class WaveShaperNode extends AudioNode native "*WaveShaperNode" {
-
- /// @domName WaveShaperNode.curve; @docsEditable true
- Float32Array curve;
-}
-// 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.
-
-
/// @domName WaveTable; @docsEditable true
class WaveTable native "*WaveTable" {
}
@@ -19579,11 +19197,16 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- void _texImage2D_1(target, level, internalformat, width, height, int border, format, type, ArrayBufferView pixels) native "texImage2D";
- void _texImage2D_2(target, level, internalformat, format, type, pixels) native "texImage2D";
- void _texImage2D_3(target, level, internalformat, format, type, ImageElement image) native "texImage2D";
- void _texImage2D_4(target, level, internalformat, format, type, CanvasElement canvas) native "texImage2D";
- void _texImage2D_5(target, level, internalformat, format, type, VideoElement video) native "texImage2D";
+ @JSName('texImage2D')
+ void _texImage2D_1(target, level, internalformat, width, height, int border, format, type, ArrayBufferView pixels) native;
+ @JSName('texImage2D')
+ void _texImage2D_2(target, level, internalformat, format, type, pixels) native;
+ @JSName('texImage2D')
+ void _texImage2D_3(target, level, internalformat, format, type, ImageElement image) native;
+ @JSName('texImage2D')
+ void _texImage2D_4(target, level, internalformat, format, type, CanvasElement canvas) native;
+ @JSName('texImage2D')
+ void _texImage2D_5(target, level, internalformat, format, type, VideoElement video) native;
/// @domName WebGLRenderingContext.texParameterf; @docsEditable true
void texParameterf(int target, int pname, num param) native;
@@ -19624,11 +19247,16 @@
}
throw new ArgumentError("Incorrect number or type of arguments");
}
- void _texSubImage2D_1(target, level, xoffset, yoffset, width, height, int format, type, ArrayBufferView pixels) native "texSubImage2D";
- void _texSubImage2D_2(target, level, xoffset, yoffset, format, type, pixels) native "texSubImage2D";
- void _texSubImage2D_3(target, level, xoffset, yoffset, format, type, ImageElement image) native "texSubImage2D";
- void _texSubImage2D_4(target, level, xoffset, yoffset, format, type, CanvasElement canvas) native "texSubImage2D";
- void _texSubImage2D_5(target, level, xoffset, yoffset, format, type, VideoElement video) native "texSubImage2D";
+ @JSName('texSubImage2D')
+ void _texSubImage2D_1(target, level, xoffset, yoffset, width, height, int format, type, ArrayBufferView pixels) native;
+ @JSName('texSubImage2D')
+ void _texSubImage2D_2(target, level, xoffset, yoffset, format, type, pixels) native;
+ @JSName('texSubImage2D')
+ void _texSubImage2D_3(target, level, xoffset, yoffset, format, type, ImageElement image) native;
+ @JSName('texSubImage2D')
+ void _texSubImage2D_4(target, level, xoffset, yoffset, format, type, CanvasElement canvas) native;
+ @JSName('texSubImage2D')
+ void _texSubImage2D_5(target, level, xoffset, yoffset, format, type, VideoElement video) native;
/// @domName WebGLRenderingContext.uniform1f; @docsEditable true
void uniform1f(WebGLUniformLocation location, num x) native;
@@ -19825,25 +19453,28 @@
final bool overset;
/// @domName WebKitNamedFlow.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName WebKitNamedFlow.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event event) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event event) native;
/// @domName WebKitNamedFlow.getContent; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> getContent() native;
/// @domName WebKitNamedFlow.getRegions; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> getRegions() native;
/// @domName WebKitNamedFlow.getRegionsByContent; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> getRegionsByContent(Node contentNode) native;
/// @domName WebKitNamedFlow.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
}
// 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
@@ -19852,6 +19483,7 @@
// WARNING: Do not edit - generated code.
+/// @domName WebSocket
class WebSocket extends EventTarget native "*WebSocket" {
factory WebSocket(String url) => _WebSocketFactoryProvider.createWebSocket(url);
@@ -19868,7 +19500,8 @@
static const int OPEN = 1;
/// @domName WebSocket.URL; @docsEditable true
- final String URL;
+ @JSName('URL')
+ final String Url;
/// @domName WebSocket.binaryType; @docsEditable true
String binaryType;
@@ -19889,16 +19522,19 @@
final String url;
/// @domName WebSocket.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName WebSocket.close; @docsEditable true
void close([int code, String reason]) native;
/// @domName WebSocket.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName WebSocket.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName WebSocket.send; @docsEditable true
void send(data) native;
@@ -19921,6 +19557,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName WheelEvent
class WheelEvent extends MouseEvent native "*WheelEvent" {
/// @domName WheelEvent.webkitDirectionInvertedFromDevice; @docsEditable true
@@ -20028,8 +19665,10 @@
_postMessage_2(message_2);
return;
}
- void _postMessage_1(message, List messagePorts) native "postMessage";
- void _postMessage_2(message) native "postMessage";
+ @JSName('postMessage')
+ void _postMessage_1(message, List messagePorts) native;
+ @JSName('postMessage')
+ void _postMessage_2(message) native;
/// @domName Worker.terminate; @docsEditable true
void terminate() native;
@@ -20075,7 +19714,8 @@
final NotificationCenter webkitNotifications;
/// @domName WorkerContext.addEventListener; @docsEditable true
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "addEventListener";
+ @JSName('addEventListener')
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName WorkerContext.clearInterval; @docsEditable true
void clearInterval(int handle) native;
@@ -20087,7 +19727,8 @@
void close() native;
/// @domName WorkerContext.dispatchEvent; @docsEditable true
- bool $dom_dispatchEvent(Event evt) native "dispatchEvent";
+ @JSName('dispatchEvent')
+ bool $dom_dispatchEvent(Event evt) native;
/// @domName WorkerContext.importScripts; @docsEditable true
void importScripts() native;
@@ -20099,7 +19740,8 @@
DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
/// @domName WorkerContext.removeEventListener; @docsEditable true
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "removeEventListener";
+ @JSName('removeEventListener')
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
/// @domName WorkerContext.setInterval; @docsEditable true
int setInterval(TimeoutHandler handler, int timeout) native;
@@ -20114,10 +19756,12 @@
DOMFileSystemSync webkitRequestFileSystemSync(int type, int size) native;
/// @domName WorkerContext.webkitResolveLocalFileSystemSyncURL; @docsEditable true
- EntrySync webkitResolveLocalFileSystemSyncURL(String url) native;
+ @JSName('webkitResolveLocalFileSystemSyncURL')
+ EntrySync webkitResolveLocalFileSystemSyncUrl(String url) native;
/// @domName WorkerContext.webkitResolveLocalFileSystemURL; @docsEditable true
- void webkitResolveLocalFileSystemURL(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
+ @JSName('webkitResolveLocalFileSystemURL')
+ void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native;
}
class WorkerContextEvents extends Events {
@@ -20259,7 +19903,8 @@
class XPathNSResolver native "*XPathNSResolver" {
/// @domName XPathNSResolver.lookupNamespaceURI; @docsEditable true
- String lookupNamespaceURI(String prefix) native;
+ @JSName('lookupNamespaceURI')
+ String lookupNamespaceUri(String prefix) native;
}
// 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
@@ -20364,17 +20009,6 @@
// BSD-style license that can be found in the LICENSE file.
-class _AudioElementFactoryProvider {
- static AudioElement createAudioElement([String src = null]) {
- if (src == null) return JS('AudioElement', 'new Audio()');
- return JS('AudioElement', 'new Audio(#)', src);
- }
-}
-// 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.
-
-
class _BlobFactoryProvider {
static Blob createBlob([List blobParts = null, String type, String endings]) {
// TODO: validate that blobParts is a JS Array and convert if not.
@@ -21455,105 +21089,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName NodeList; @docsEditable true
-class _NodeList implements JavaScriptIndexingBehavior, List<Node> native "*NodeList" {
-
- /// @domName NodeList.length; @docsEditable true
- final int length;
-
- Node operator[](int index) => JS("Node", "#[#]", this, index);
-
- void operator[]=(int index, Node value) {
- throw new UnsupportedError("Cannot assign element of immutable List.");
- }
- // -- start List<Node> mixins.
- // Node is the element type.
-
- // From Iterable<Node>:
-
- Iterator<Node> iterator() {
- // Note: NodeLists are not fixed size. And most probably length shouldn't
- // be cached in both iterator _and_ forEach method. For now caching it
- // for consistency.
- return new FixedSizeListIterator<Node>(this);
- }
-
- // From Collection<Node>:
-
- void add(Node value) {
- throw new UnsupportedError("Cannot add to immutable List.");
- }
-
- void addLast(Node value) {
- throw new UnsupportedError("Cannot add to immutable List.");
- }
-
- void addAll(Collection<Node> collection) {
- throw new UnsupportedError("Cannot add to immutable List.");
- }
-
- bool contains(Node element) => _Collections.contains(this, element);
-
- void forEach(void f(Node element)) => _Collections.forEach(this, f);
-
- Collection map(f(Node element)) => _Collections.map(this, [], f);
-
- Collection<Node> filter(bool f(Node element)) =>
- _Collections.filter(this, <Node>[], f);
-
- bool every(bool f(Node element)) => _Collections.every(this, f);
-
- bool some(bool f(Node element)) => _Collections.some(this, f);
-
- bool get isEmpty => this.length == 0;
-
- // From List<Node>:
-
- void sort([Comparator<Node> compare = Comparable.compare]) {
- throw new UnsupportedError("Cannot sort immutable List.");
- }
-
- int indexOf(Node element, [int start = 0]) =>
- _Lists.indexOf(this, element, start, this.length);
-
- int lastIndexOf(Node element, [int start]) {
- if (start == null) start = length - 1;
- return _Lists.lastIndexOf(this, element, start);
- }
-
- Node get first => this[0];
-
- Node get last => this[length - 1];
-
- Node removeLast() {
- throw new UnsupportedError("Cannot removeLast on immutable List.");
- }
-
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
- throw new UnsupportedError("Cannot setRange on immutable List.");
- }
-
- void removeRange(int start, int rangeLength) {
- throw new UnsupportedError("Cannot removeRange on immutable List.");
- }
-
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
- }
-
- List<Node> getRange(int start, int rangeLength) =>
- _Lists.getRange(this, start, rangeLength, <Node>[]);
-
- // -- end List<Node> mixins.
-
- /// @domName NodeList.item; @docsEditable true
- Node _item(int index) native "item";
-}
-// 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.
-
-
class _NotificationFactoryProvider {
static Notification createNotification(String title, [Map options]) =>
JS('Notification', 'new Notification(#,#)', title, options);
@@ -22137,6 +21672,228 @@
// BSD-style license that can be found in the LICENSE file.
+abstract class _AttributeMap implements Map<String, String> {
+
+ bool containsValue(String value) {
+ for (var v in this.values) {
+ if (value == v) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) {
+ if (!containsKey(key)) {
+ this[key] = ifAbsent();
+ }
+ return this[key];
+ }
+
+ void clear() {
+ for (var key in keys) {
+ remove(key);
+ }
+ }
+
+ void forEach(void f(String key, String value)) {
+ for (var key in keys) {
+ var value = this[key];
+ f(key, value);
+ }
+ }
+
+ Collection<String> get keys {
+ // TODO: generate a lazy collection instead.
+ var attributes = _element.$dom_attributes;
+ var keys = new List<String>();
+ for (int i = 0, len = attributes.length; i < len; i++) {
+ if (_matches(attributes[i])) {
+ keys.add(attributes[i].$dom_localName);
+ }
+ }
+ return keys;
+ }
+
+ Collection<String> get values {
+ // TODO: generate a lazy collection instead.
+ var attributes = _element.$dom_attributes;
+ var values = new List<String>();
+ for (int i = 0, len = attributes.length; i < len; i++) {
+ if (_matches(attributes[i])) {
+ values.add(attributes[i].value);
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Returns true if there is no {key, value} pair in the map.
+ */
+ bool get isEmpty {
+ return length == 0;
+ }
+
+ /**
+ * Checks to see if the node should be included in this map.
+ */
+ bool _matches(Node node);
+}
+
+/**
+ * Wrapper to expose [Element.attributes] as a typed map.
+ */
+class _ElementAttributeMap extends _AttributeMap {
+
+ final Element _element;
+
+ _ElementAttributeMap(this._element);
+
+ bool containsKey(String key) {
+ return _element.$dom_hasAttribute(key);
+ }
+
+ String operator [](String key) {
+ return _element.$dom_getAttribute(key);
+ }
+
+ void operator []=(String key, value) {
+ _element.$dom_setAttribute(key, '$value');
+ }
+
+ String remove(String key) {
+ String value = _element.$dom_getAttribute(key);
+ _element.$dom_removeAttribute(key);
+ return value;
+ }
+
+ /**
+ * The number of {key, value} pairs in the map.
+ */
+ int get length {
+ return keys.length;
+ }
+
+ bool _matches(Node node) => node.$dom_namespaceUri == null;
+}
+
+/**
+ * Wrapper to expose namespaced attributes as a typed map.
+ */
+class _NamespacedAttributeMap extends _AttributeMap {
+
+ final Element _element;
+ final String _namespace;
+
+ _NamespacedAttributeMap(this._element, this._namespace);
+
+ bool containsKey(String key) {
+ return _element.$dom_hasAttributeNS(_namespace, key);
+ }
+
+ String operator [](String key) {
+ return _element.$dom_getAttributeNS(_namespace, key);
+ }
+
+ void operator []=(String key, value) {
+ _element.$dom_setAttributeNS(_namespace, key, '$value');
+ }
+
+ String remove(String key) {
+ String value = this[key];
+ _element.$dom_removeAttributeNS(_namespace, key);
+ return value;
+ }
+
+ /**
+ * The number of {key, value} pairs in the map.
+ */
+ int get length {
+ return keys.length;
+ }
+
+ bool _matches(Node node) => node.$dom_namespaceUri == _namespace;
+}
+
+
+/**
+ * Provides a Map abstraction on top of data-* attributes, similar to the
+ * dataSet in the old DOM.
+ */
+class _DataAttributeMap implements Map<String, String> {
+
+ final Map<String, String> $dom_attributes;
+
+ _DataAttributeMap(this.$dom_attributes);
+
+ // interface Map
+
+ // TODO: Use lazy iterator when it is available on Map.
+ bool containsValue(String value) => values.some((v) => v == value);
+
+ bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
+
+ String operator [](String key) => $dom_attributes[_attr(key)];
+
+ void operator []=(String key, value) {
+ $dom_attributes[_attr(key)] = '$value';
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) =>
+ $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
+
+ String remove(String key) => $dom_attributes.remove(_attr(key));
+
+ void clear() {
+ // Needs to operate on a snapshot since we are mutating the collection.
+ for (String key in keys) {
+ remove(key);
+ }
+ }
+
+ void forEach(void f(String key, String value)) {
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ f(_strip(key), value);
+ }
+ });
+ }
+
+ Collection<String> get keys {
+ final keys = new List<String>();
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ keys.add(_strip(key));
+ }
+ });
+ return keys;
+ }
+
+ Collection<String> get values {
+ final values = new List<String>();
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ values.add(value);
+ }
+ });
+ return values;
+ }
+
+ int get length => keys.length;
+
+ // TODO: Use lazy iterator when it is available on Map.
+ bool get isEmpty => length == 0;
+
+ // Helpers.
+ String _attr(String key) => 'data-$key';
+ bool _matches(String key) => key.startsWith('data-');
+ String _strip(String key) => key.substring(5);
+}
+// 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.
+
+
/**
* An object representing the top-level context object for web scripting.
*
@@ -22166,7 +21923,7 @@
History get history;
/**
- * Indicates whether this window is closed.
+ * Indicates whether this window has been closed.
*
* print(window.closed); // 'false'
* window.close();
@@ -22219,6 +21976,34 @@
Window get top;
// Methods.
+ /**
+ * Closes the window.
+ *
+ * This method should only succeed if the [Window] object is
+ * **script-closeable** and the window calling [close] is allowed to navigate
+ * the window.
+ *
+ * A window is script-closeable if it is either a window
+ * that was opened by another window, or if it is a window with only one
+ * document in its history.
+ *
+ * A window might not be allowed to navigate, and therefore close, another
+ * window due to browser security features.
+ *
+ * var other = window.open('http://www.example.com', 'foo');
+ * // Closes other window, as it is script-closeable.
+ * other.close();
+ * print(other.closed()); // 'true'
+ *
+ * window.location('http://www.mysite.com', 'foo');
+ * // Does not close this window, as the history has changed.
+ * window.close();
+ * print(window.closed()); // 'false'
+ *
+ * See also:
+ *
+ * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
+ */
void close();
void postMessage(var message, String targetOrigin, [List messagePorts = null]);
}
@@ -22509,6 +22294,410 @@
/**
+ * Works with KeyboardEvent and KeyEvent to determine how to expose information
+ * about Key(board)Events. This class functions like an EventListenerList, and
+ * provides a consistent interface for the Dart
+ * user, despite the fact that a multitude of browsers that have varying
+ * keyboard default behavior.
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyboardEventController {
+ // This code inspired by Closure's KeyHandling library.
+ // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+
+ /**
+ * The set of keys that have been pressed down without seeing their
+ * corresponding keyup event.
+ */
+ List<KeyboardEvent> _keyDownList;
+
+ /** The set of functions that wish to be notified when a KeyEvent happens. */
+ List<Function> _callbacks;
+
+ /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
+ String _type;
+
+ /** The element we are watching for events to happen on. */
+ EventTarget _target;
+
+ // The distance to shift from upper case alphabet Roman letters to lower case.
+ int _ROMAN_ALPHABET_OFFSET = "a".charCodes[0] - "A".charCodes[0];
+
+ // Instance members referring to the internal event handlers because closures
+ // are not hashable.
+ var _keyUp, _keyDown, _keyPress;
+
+ /**
+ * An enumeration of key identifiers currently part of the W3C draft for DOM3
+ * and their mappings to keyCodes.
+ * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+ */
+ static Map<String, int> _keyIdentifier = {
+ 'Up': KeyCode.UP,
+ 'Down': KeyCode.DOWN,
+ 'Left': KeyCode.LEFT,
+ 'Right': KeyCode.RIGHT,
+ 'Enter': KeyCode.ENTER,
+ 'F1': KeyCode.F1,
+ 'F2': KeyCode.F2,
+ 'F3': KeyCode.F3,
+ 'F4': KeyCode.F4,
+ 'F5': KeyCode.F5,
+ 'F6': KeyCode.F6,
+ 'F7': KeyCode.F7,
+ 'F8': KeyCode.F8,
+ 'F9': KeyCode.F9,
+ 'F10': KeyCode.F10,
+ 'F11': KeyCode.F11,
+ 'F12': KeyCode.F12,
+ 'U+007F': KeyCode.DELETE,
+ 'Home': KeyCode.HOME,
+ 'End': KeyCode.END,
+ 'PageUp': KeyCode.PAGE_UP,
+ 'PageDown': KeyCode.PAGE_DOWN,
+ 'Insert': KeyCode.INSERT
+ };
+
+ /** Named constructor to add an onKeyPress event listener to our handler. */
+ KeyboardEventController.keypress(EventTarget target) {
+ _KeyboardEventController(target, 'keypress');
+ }
+
+ /** Named constructor to add an onKeyUp event listener to our handler. */
+ KeyboardEventController.keyup(EventTarget target) {
+ _KeyboardEventController(target, 'keyup');
+ }
+
+ /** Named constructor to add an onKeyDown event listener to our handler. */
+ KeyboardEventController.keydown(EventTarget target) {
+ _KeyboardEventController(target, 'keydown');
+ }
+
+ /**
+ * General constructor, performs basic initialization for our improved
+ * KeyboardEvent controller.
+ */
+ _KeyboardEventController(EventTarget target, String type) {
+ _callbacks = [];
+ _type = type;
+ _target = target;
+ _keyDown = processKeyDown;
+ _keyUp = processKeyUp;
+ _keyPress = processKeyPress;
+ }
+
+ /**
+ * Hook up all event listeners under the covers so we can estimate keycodes
+ * and charcodes when they are not provided.
+ */
+ void _initializeAllEventListeners() {
+ _keyDownList = [];
+ _target.on.keyDown.add(_keyDown, true);
+ _target.on.keyPress.add(_keyPress, true);
+ _target.on.keyUp.add(_keyUp, true);
+ }
+
+ /** Add a callback that wishes to be notified when a KeyEvent occurs. */
+ void add(void callback(KeyEvent)) {
+ if (_callbacks.length == 0) {
+ _initializeAllEventListeners();
+ }
+ _callbacks.add(callback);
+ }
+
+ /**
+ * Notify all callback listeners that a KeyEvent of the relevant type has
+ * occurred.
+ */
+ bool _dispatch(KeyEvent event) {
+ if (event.type == _type) {
+ // Make a copy of the listeners in case a callback gets removed while
+ // dispatching from the list.
+ List callbacksCopy = new List.from(_callbacks);
+ for(var callback in callbacksCopy) {
+ callback(event);
+ }
+ }
+ }
+
+ /** Remove the given callback from the listeners list. */
+ void remove(void callback(KeyEvent)) {
+ var index = _callbacks.indexOf(callback);
+ if (index != -1) {
+ _callbacks.removeAt(index);
+ }
+ if (_callbacks.length == 0) {
+ // If we have no listeners, don't bother keeping track of keypresses.
+ _target.on.keyDown.remove(_keyDown);
+ _target.on.keyPress.remove(_keyPress);
+ _target.on.keyUp.remove(_keyUp);
+ }
+ }
+
+ /** Determine if caps lock is one of the currently depressed keys. */
+ bool get _capsLockOn =>
+ _keyDownList.some((var element) => element.keyCode == KeyCode.CAPS_LOCK);
+
+ /**
+ * Given the previously recorded keydown key codes, see if we can determine
+ * the keycode of this keypress [event]. (Generally browsers only provide
+ * charCode information for keypress events, but with a little
+ * reverse-engineering, we can also determine the keyCode.) Returns
+ * KeyCode.UNKNOWN if the keycode could not be determined.
+ */
+ int _determineKeyCodeForKeypress(KeyboardEvent event) {
+ // Note: This function is a work in progress. We'll expand this function
+ // once we get more information about other keyboards.
+ for (var prevEvent in _keyDownList) {
+ if (prevEvent._shadowCharCode == event.charCode) {
+ return prevEvent.keyCode;
+ }
+ if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".charCodes[0]
+ && event.charCode <= "Z".charCodes[0] && event.charCode +
+ _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
+ return prevEvent.keyCode;
+ }
+ }
+ return KeyCode.UNKNOWN;
+ }
+
+ /**
+ * Given the charater code returned from a keyDown [event], try to ascertain
+ * and return the corresponding charCode for the character that was pressed.
+ * This information is not shown to the user, but used to help polyfill
+ * keypress events.
+ */
+ int _findCharCodeKeyDown(KeyboardEvent event) {
+ if (event.keyLocation == 3) { // Numpad keys.
+ switch (event.keyCode) {
+ case KeyCode.NUM_ZERO:
+ // Even though this function returns _charCodes_, for some cases the
+ // KeyCode == the charCode we want, in which case we use the keycode
+ // constant for readability.
+ return KeyCode.ZERO;
+ case KeyCode.NUM_ONE:
+ return KeyCode.ONE;
+ case KeyCode.NUM_TWO:
+ return KeyCode.TWO;
+ case KeyCode.NUM_THREE:
+ return KeyCode.THREE;
+ case KeyCode.NUM_FOUR:
+ return KeyCode.FOUR;
+ case KeyCode.NUM_FIVE:
+ return KeyCode.FIVE;
+ case KeyCode.NUM_SIX:
+ return KeyCode.SIX;
+ case KeyCode.NUM_SEVEN:
+ return KeyCode.SEVEN;
+ case KeyCode.NUM_EIGHT:
+ return KeyCode.EIGHT;
+ case KeyCode.NUM_NINE:
+ return KeyCode.NINE;
+ case KeyCode.NUM_MULTIPLY:
+ return 42; // Char code for *
+ case KeyCode.NUM_PLUS:
+ return 43; // +
+ case KeyCode.NUM_MINUS:
+ return 45; // -
+ case KeyCode.NUM_PERIOD:
+ return 46; // .
+ case KeyCode.NUM_DIVISION:
+ return 47; // /
+ }
+ } else if (event.keyCode >= 65 && event.keyCode <= 90) {
+ // Set the "char code" for key down as the lower case letter. Again, this
+ // will not show up for the user, but will be helpful in estimating
+ // keyCode locations and other information during the keyPress event.
+ return event.keyCode + _ROMAN_ALPHABET_OFFSET;
+ }
+ switch(event.keyCode) {
+ case KeyCode.SEMICOLON:
+ return KeyCode.FF_SEMICOLON;
+ case KeyCode.EQUALS:
+ return KeyCode.FF_EQUALS;
+ case KeyCode.COMMA:
+ return 44; // Ascii value for ,
+ case KeyCode.DASH:
+ return 45; // -
+ case KeyCode.PERIOD:
+ return 46; // .
+ case KeyCode.SLASH:
+ return 47; // /
+ case KeyCode.APOSTROPHE:
+ return 96; // `
+ case KeyCode.OPEN_SQUARE_BRACKET:
+ return 91; // [
+ case KeyCode.BACKSLASH:
+ return 92; // \
+ case KeyCode.CLOSE_SQUARE_BRACKET:
+ return 93; // ]
+ case KeyCode.SINGLE_QUOTE:
+ return 39; // '
+ }
+ return event.keyCode;
+ }
+
+ /**
+ * Returns true if the key fires a keypress event in the current browser.
+ */
+ bool _firesKeyPressEvent(KeyEvent event) {
+ if (!_Device.isIE && !_Device.isWebKit) {
+ return true;
+ }
+
+ if (_Device.userAgent.contains('Mac') && event.altKey) {
+ return KeyCode.isCharacterKey(event.keyCode);
+ }
+
+ // Alt but not AltGr which is represented as Alt+Ctrl.
+ if (event.altKey && !event.ctrlKey) {
+ return false;
+ }
+
+ // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
+ if (!event.shiftKey &&
+ (_keyDownList.last.keyCode == KeyCode.CTRL ||
+ _keyDownList.last.keyCode == KeyCode.ALT ||
+ _Device.userAgent.contains('Mac') &&
+ _keyDownList.last.keyCode == KeyCode.META)) {
+ return false;
+ }
+
+ // Some keys with Ctrl/Shift do not issue keypress in WebKit.
+ if (_Device.isWebKit && event.ctrlKey && event.shiftKey && (
+ event.keycode == KeyCode.BACKSLASH ||
+ event.keycode == KeyCode.OPEN_SQUARE_BRACKET ||
+ event.keycode == KeyCode.CLOSE_SQUARE_BRACKET ||
+ event.keycode == KeyCode.TILDE ||
+ event.keycode == KeyCode.SEMICOLON || event.keycode == KeyCode.DASH ||
+ event.keycode == KeyCode.EQUALS || event.keycode == KeyCode.COMMA ||
+ event.keycode == KeyCode.PERIOD || event.keycode == KeyCode.SLASH ||
+ event.keycode == KeyCode.APOSTROPHE ||
+ event.keycode == KeyCode.SINGLE_QUOTE)) {
+ return false;
+ }
+
+ switch (event.keyCode) {
+ case KeyCode.ENTER:
+ // IE9 does not fire keypress on ENTER.
+ return !_Device.isIE;
+ case KeyCode.ESC:
+ return !_Device.isWebKit;
+ }
+
+ return KeyCode.isCharacterKey(event.keyCode);
+ }
+
+ /**
+ * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
+ * Opera all use).
+ */
+ int _normalizeKeyCodes(KeyboardEvent event) {
+ // Note: This may change once we get input about non-US keyboards.
+ if (_Device.isFirefox) {
+ switch(event.keyCode) {
+ case KeyCode.FF_EQUALS:
+ return KeyCode.EQUALS;
+ case KeyCode.FF_SEMICOLON:
+ return KeyCode.SEMICOLON;
+ case KeyCode.MAC_FF_META:
+ return KeyCode.META;
+ case KeyCode.WIN_KEY_FF_LINUX:
+ return KeyCode.WIN_KEY;
+ }
+ }
+ return event.keyCode;
+ }
+
+ /** Handle keydown events. */
+ void processKeyDown(KeyboardEvent e) {
+ // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+ // before we've caught a key-up event. If the last-key was one of these
+ // we reset the state.
+ if (_keyDownList.length > 0 &&
+ (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
+ _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
+ _Device.userAgent.contains('Mac') &&
+ _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
+ _keyDownList = [];
+ }
+
+ var event = new KeyEvent(e);
+ event._shadowKeyCode = _normalizeKeyCodes(event);
+ // Technically a "keydown" event doesn't have a charCode. This is
+ // calculated nonetheless to provide us with more information in giving
+ // as much information as possible on keypress about keycode and also
+ // charCode.
+ event._shadowCharCode = _findCharCodeKeyDown(event);
+ if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
+ !_firesKeyPressEvent(event)) {
+ // Some browsers have quirks not firing keypress events where all other
+ // browsers do. This makes them more consistent.
+ processKeyPress(event);
+ }
+ _keyDownList.add(event);
+ _dispatch(event);
+ }
+
+ /** Handle keypress events. */
+ void processKeyPress(KeyboardEvent event) {
+ var e = new KeyEvent(event);
+ // IE reports the character code in the keyCode field for keypress events.
+ // There are two exceptions however, Enter and Escape.
+ if (_Device.isIE) {
+ if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
+ e._shadowCharCode = 0;
+ } else {
+ e._shadowCharCode = e.keyCode;
+ }
+ } else if (_Device.isOpera) {
+ // Opera reports the character code in the keyCode field.
+ e._shadowCharCode = KeyCode.isCharacterKey(keyCode) ? e.keyCode : 0;
+ }
+ // Now we guestimate about what the keycode is that was actually
+ // pressed, given previous keydown information.
+ e._shadowKeyCode = _determineKeyCodeForKeypress(e);
+
+ // Correct the key value for certain browser-specific quirks.
+ if (e._shadowKeyIdentifier &&
+ _keyIdentifier.contains(e._shadowKeyIdentifier)) {
+ // This is needed for Safari Windows because it currently doesn't give a
+ // keyCode/which for non printable keys.
+ e._shadowKeyCode = _keyIdentifier[keyIdentifier];
+ }
+ e._shadowAltKey = _keyDownList.some((var element) => element.altKey);
+ _dispatch(e);
+ }
+
+ /** Handle keyup events. */
+ void processKeyUp(KeyboardEvent event) {
+ var e = new KeyEvent(event);
+ KeyboardEvent toRemove = null;
+ for (var key in _keyDownList) {
+ if (key.keyCode == e.keyCode) {
+ toRemove = key;
+ }
+ }
+ if (toRemove != null) {
+ _keyDownList = _keyDownList.filter((element) => element != toRemove);
+ } else if (_keyDownList.length > 0) {
+ // This happens when we've reached some international keyboard case we
+ // haven't accounted for or we haven't correctly eliminated all browser
+ // inconsistencies. Filing bugs on when this is reached is welcome!
+ _keyDownList.removeLast();
+ }
+ _dispatch(e);
+ }
+}
+// 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.
+
+
+/**
* Defines the keycode values for keys that are returned by
* KeyboardEvent.keyCode.
*
@@ -22699,6 +22888,36 @@
static const int WIN_KEY = 224;
static const int MAC_FF_META = 224;
static const int WIN_IME = 229;
+
+ /** A sentinel value if the keycode could not be determined. */
+ static const int UNKNOWN = -1;
+
+ /**
+ * Returns true if the keyCode produces a (US keyboard) character.
+ * Note: This does not (yet) cover characters on non-US keyboards (Russian,
+ * Hebrew, etc.).
+ */
+ static bool isCharacterKey(int keyCode) {
+ if ((keyCode >= ZERO && keyCode <= NINE) ||
+ (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
+ (keyCode >= A && keyCode <= Z)) {
+ return true;
+ }
+
+ // Safari sends zero key code for non-latin characters.
+ if (_Device.isWebKit && keyCode == 0) {
+ return true;
+ }
+
+ return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
+ || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
+ keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
+ keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
+ keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
+ keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
+ keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
+ keyCode == CLOSE_SQUARE_BRACKET);
+ }
}
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -24054,7 +24273,7 @@
static DocumentFragment createDocumentFragment_html(String html) {
final fragment = new DocumentFragment();
- fragment.innerHTML = html;
+ fragment.innerHtml = html;
return fragment;
}
@@ -24062,7 +24281,7 @@
// factory DocumentFragment.xml(String xml) {
// final fragment = new DocumentFragment();
// final e = new XMLElement.tag("xml");
- // e.innerHTML = xml;
+ // e.innerHtml = xml;
//
// // Copy list first since we don't want liveness during iteration.
// final List nodes = new List.from(e.nodes);
@@ -24073,7 +24292,7 @@
static DocumentFragment createDocumentFragment_svg(String svgContent) {
final fragment = new DocumentFragment();
final e = new svg.SVGSVGElement();
- e.innerHTML = svgContent;
+ e.innerHtml = svgContent;
// Copy list first since we don't want liveness during iteration.
final List nodes = new List.from(e.nodes);
@@ -24632,19 +24851,114 @@
}
}
}
+/**
+ * A custom KeyboardEvent that attempts to eliminate cross-browser
+ * inconsistencies, and also provide both keyCode and charCode information
+ * for all key events (when such information can be determined).
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyEvent implements KeyboardEvent {
+ /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
+ KeyboardEvent _parent;
+
+ /** The "fixed" value of whether the alt key is being pressed. */
+ bool _shadowAltKey;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int _shadowCharCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int _shadowKeyCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get keyCode => _shadowKeyCode;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
+
+ /** Caculated value of whether the alt key is pressed is for this event. */
+ bool get altKey => _shadowAltKey;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get which => keyCode;
+
+ /** Accessor to the underlying keyCode value is the parent event. */
+ int get _realKeyCode => JS('int', '#.keyCode', _parent);
+
+ /** Accessor to the underlying charCode value is the parent event. */
+ int get _realCharCode => JS('int', '#.charCode', _parent);
+
+ /** Accessor to the underlying altKey value is the parent event. */
+ bool get _realAltKey => JS('int', '#.altKey', _parent);
+
+ /** Construct a KeyEvent with [parent] as event we're emulating. */
+ KeyEvent(KeyboardEvent parent) {
+ _parent = parent;
+ _shadowAltKey = _realAltKey;
+ _shadowCharCode = _realCharCode;
+ _shadowKeyCode = _realKeyCode;
+ }
+
+ /** True if the altGraphKey is pressed during this event. */
+ bool get altGraphKey => _parent.altGraphKey;
+ bool get bubbles => _parent.bubbles;
+ /** True if this event can be cancelled. */
+ bool get cancelable => _parent.cancelable;
+ bool get cancelBubble => _parent.cancelBubble;
+ set cancelBubble(bool cancel) => _parent = cancel;
+ /** Accessor to the clipboardData available for this event. */
+ Clipboard get clipboardData => _parent.clipboardData;
+ /** True if the ctrl key is pressed during this event. */
+ bool get ctrlKey => _parent.ctrlKey;
+ /** Accessor to the target this event is listening to for changes. */
+ EventTarget get currentTarget => _parent.currentTarget;
+ bool get defaultPrevented => _parent.defaultPrevented;
+ int get detail => _parent.detail;
+ int get eventPhase => _parent.eventPhase;
+ /**
+ * Accessor to the part of the keyboard that the key was pressed from (one of
+ * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
+ * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
+ */
+ int get keyLocation => _parent.keyLocation;
+ int get layerX => _parent.layerX;
+ int get layerY => _parent.layerY;
+ /** True if the Meta (or Mac command) key is pressed during this event. */
+ bool get metaKey => _parent.metaKey;
+ int get pageX => _parent.pageX;
+ int get pageY => _parent.pageY;
+ bool get returnValue => _parent.returnValue;
+ set returnValue(bool value) => _parent = value;
+ /** True if the shift key was pressed during this event. */
+ bool get shiftKey => _parent.shiftKey;
+ int get timeStamp => _parent.timeStamp;
+ /**
+ * The type of key event that occurred. One of "keydown", "keyup", or
+ * "keypress".
+ */
+ String get type => _parent.type;
+ Window get view => _parent.view;
+ void preventDefault() => _parent.preventDefault();
+ void stopImmediatePropagation() => _parent.stopImmediatePropagation();
+ void stopPropagation() => _parent.stopPropagation();
+ void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, int detail) {
+ throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
+ }
+ void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
+ bool cancelableArg) {
+ throw new UnsupportedError("Cannot initialize an Event from a KeyEvent.");
+ }
+ String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);
+}
// 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.
-class _AudioContextFactoryProvider {
-
- static AudioContext createAudioContext() {
- return JS('AudioContext',
- 'new (window.AudioContext || window.webkitAudioContext)()');
- }
-}
-
class _PointFactoryProvider {
static Point createPoint(num x, num y) =>
JS('Point', 'new WebKitPoint(#, #)', x, y);
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index e430f59..a20b646 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -4,6 +4,7 @@
import 'dart:json';
import 'dart:nativewrappers';
import 'dart:svg' as svg;
+import 'dart:web_audio' as web_audio;
// 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.
@@ -12,6 +13,7 @@
// Auto-generated dart:html library.
+// Not actually used, but imported since dart:html can generate these objects.
@@ -100,66 +102,6 @@
// WARNING: Do not edit - generated code.
-/// @domName AnalyserNode
-class AnalyserNode extends AudioNode {
- AnalyserNode.internal(): super.internal();
-
-
- /** @domName AnalyserNode.fftSize */
- int get fftSize native "AnalyserNode_fftSize_Getter";
-
-
- /** @domName AnalyserNode.fftSize */
- void set fftSize(int value) native "AnalyserNode_fftSize_Setter";
-
-
- /** @domName AnalyserNode.frequencyBinCount */
- int get frequencyBinCount native "AnalyserNode_frequencyBinCount_Getter";
-
-
- /** @domName AnalyserNode.maxDecibels */
- num get maxDecibels native "AnalyserNode_maxDecibels_Getter";
-
-
- /** @domName AnalyserNode.maxDecibels */
- void set maxDecibels(num value) native "AnalyserNode_maxDecibels_Setter";
-
-
- /** @domName AnalyserNode.minDecibels */
- num get minDecibels native "AnalyserNode_minDecibels_Getter";
-
-
- /** @domName AnalyserNode.minDecibels */
- void set minDecibels(num value) native "AnalyserNode_minDecibels_Setter";
-
-
- /** @domName AnalyserNode.smoothingTimeConstant */
- num get smoothingTimeConstant native "AnalyserNode_smoothingTimeConstant_Getter";
-
-
- /** @domName AnalyserNode.smoothingTimeConstant */
- void set smoothingTimeConstant(num value) native "AnalyserNode_smoothingTimeConstant_Setter";
-
-
- /** @domName AnalyserNode.getByteFrequencyData */
- void getByteFrequencyData(Uint8Array array) native "AnalyserNode_getByteFrequencyData_Callback";
-
-
- /** @domName AnalyserNode.getByteTimeDomainData */
- void getByteTimeDomainData(Uint8Array array) native "AnalyserNode_getByteTimeDomainData_Callback";
-
-
- /** @domName AnalyserNode.getFloatFrequencyData */
- void getFloatFrequencyData(Float32Array array) native "AnalyserNode_getFloatFrequencyData_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName HTMLAnchorElement
class AnchorElement extends _Element_Merged {
@@ -721,554 +663,6 @@
// WARNING: Do not edit - generated code.
-/// @domName AudioBuffer
-class AudioBuffer extends NativeFieldWrapperClass1 {
- AudioBuffer.internal();
-
-
- /** @domName AudioBuffer.duration */
- num get duration native "AudioBuffer_duration_Getter";
-
-
- /** @domName AudioBuffer.gain */
- num get gain native "AudioBuffer_gain_Getter";
-
-
- /** @domName AudioBuffer.gain */
- void set gain(num value) native "AudioBuffer_gain_Setter";
-
-
- /** @domName AudioBuffer.length */
- int get length native "AudioBuffer_length_Getter";
-
-
- /** @domName AudioBuffer.numberOfChannels */
- int get numberOfChannels native "AudioBuffer_numberOfChannels_Getter";
-
-
- /** @domName AudioBuffer.sampleRate */
- num get sampleRate native "AudioBuffer_sampleRate_Getter";
-
-
- /** @domName AudioBuffer.getChannelData */
- Float32Array getChannelData(int channelIndex) native "AudioBuffer_getChannelData_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-typedef void AudioBufferCallback(AudioBuffer audioBuffer);
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioBufferSourceNode
-class AudioBufferSourceNode extends AudioSourceNode {
- AudioBufferSourceNode.internal(): super.internal();
-
- static const int FINISHED_STATE = 3;
-
- static const int PLAYING_STATE = 2;
-
- static const int SCHEDULED_STATE = 1;
-
- static const int UNSCHEDULED_STATE = 0;
-
-
- /** @domName AudioBufferSourceNode.buffer */
- AudioBuffer get buffer native "AudioBufferSourceNode_buffer_Getter";
-
-
- /** @domName AudioBufferSourceNode.buffer */
- void set buffer(AudioBuffer value) native "AudioBufferSourceNode_buffer_Setter";
-
-
- /** @domName AudioBufferSourceNode.gain */
- AudioGain get gain native "AudioBufferSourceNode_gain_Getter";
-
-
- /** @domName AudioBufferSourceNode.loop */
- bool get loop native "AudioBufferSourceNode_loop_Getter";
-
-
- /** @domName AudioBufferSourceNode.loop */
- void set loop(bool value) native "AudioBufferSourceNode_loop_Setter";
-
-
- /** @domName AudioBufferSourceNode.loopEnd */
- num get loopEnd native "AudioBufferSourceNode_loopEnd_Getter";
-
-
- /** @domName AudioBufferSourceNode.loopEnd */
- void set loopEnd(num value) native "AudioBufferSourceNode_loopEnd_Setter";
-
-
- /** @domName AudioBufferSourceNode.loopStart */
- num get loopStart native "AudioBufferSourceNode_loopStart_Getter";
-
-
- /** @domName AudioBufferSourceNode.loopStart */
- void set loopStart(num value) native "AudioBufferSourceNode_loopStart_Setter";
-
-
- /** @domName AudioBufferSourceNode.playbackRate */
- AudioParam get playbackRate native "AudioBufferSourceNode_playbackRate_Getter";
-
-
- /** @domName AudioBufferSourceNode.playbackState */
- int get playbackState native "AudioBufferSourceNode_playbackState_Getter";
-
- void start(/*double*/ when, [/*double*/ grainOffset, /*double*/ grainDuration]) {
- if ((when is num || when == null) && !?grainOffset && !?grainDuration) {
- _start_1(when);
- return;
- }
- if ((when is num || when == null) && (grainOffset is num || grainOffset == null) && (grainDuration is num || grainDuration == null)) {
- _start_2(when, grainOffset, grainDuration);
- return;
- }
- throw "Incorrect number or type of arguments";
- }
-
-
- /** @domName AudioBufferSourceNode.start_1 */
- void _start_1(when) native "AudioBufferSourceNode_start_1_Callback";
-
-
- /** @domName AudioBufferSourceNode.start_2 */
- void _start_2(when, grainOffset, grainDuration) native "AudioBufferSourceNode_start_2_Callback";
-
-
- /** @domName AudioBufferSourceNode.stop */
- void stop(num when) native "AudioBufferSourceNode_stop_Callback";
-
-}
-// 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.
-
-
-class AudioContext extends EventTarget {
- factory AudioContext() => _AudioContextFactoryProvider.createAudioContext();
- AudioContext.internal(): super.internal();
-
- /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
- AudioContextEvents get on =>
- new AudioContextEvents(this);
-
-
- /** @domName AudioContext.activeSourceCount */
- int get activeSourceCount native "AudioContext_activeSourceCount_Getter";
-
-
- /** @domName AudioContext.currentTime */
- num get currentTime native "AudioContext_currentTime_Getter";
-
-
- /** @domName AudioContext.destination */
- AudioDestinationNode get destination native "AudioContext_destination_Getter";
-
-
- /** @domName AudioContext.listener */
- AudioListener get listener native "AudioContext_listener_Getter";
-
-
- /** @domName AudioContext.sampleRate */
- num get sampleRate native "AudioContext_sampleRate_Getter";
-
-
- /** @domName AudioContext.createAnalyser */
- AnalyserNode createAnalyser() native "AudioContext_createAnalyser_Callback";
-
-
- /** @domName AudioContext.createBiquadFilter */
- BiquadFilterNode createBiquadFilter() native "AudioContext_createBiquadFilter_Callback";
-
- AudioBuffer createBuffer(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, [/*float*/ sampleRate]) {
- if ((buffer_OR_numberOfChannels is int || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is int || mixToMono_OR_numberOfFrames == null) && (sampleRate is num || sampleRate == null)) {
- return _createBuffer_1(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, sampleRate);
- }
- if ((buffer_OR_numberOfChannels is ArrayBuffer || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is bool || mixToMono_OR_numberOfFrames == null) && !?sampleRate) {
- return _createBuffer_2(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames);
- }
- throw "Incorrect number or type of arguments";
- }
-
-
- /** @domName AudioContext.createBuffer_1 */
- AudioBuffer _createBuffer_1(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, sampleRate) native "AudioContext_createBuffer_1_Callback";
-
-
- /** @domName AudioContext.createBuffer_2 */
- AudioBuffer _createBuffer_2(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames) native "AudioContext_createBuffer_2_Callback";
-
-
- /** @domName AudioContext.createBufferSource */
- AudioBufferSourceNode createBufferSource() native "AudioContext_createBufferSource_Callback";
-
- ChannelMergerNode createChannelMerger([/*unsigned long*/ numberOfInputs]) {
- if (?numberOfInputs) {
- return _createChannelMerger_1(numberOfInputs);
- }
- return _createChannelMerger_2();
- }
-
-
- /** @domName AudioContext.createChannelMerger_1 */
- ChannelMergerNode _createChannelMerger_1(numberOfInputs) native "AudioContext_createChannelMerger_1_Callback";
-
-
- /** @domName AudioContext.createChannelMerger_2 */
- ChannelMergerNode _createChannelMerger_2() native "AudioContext_createChannelMerger_2_Callback";
-
- ChannelSplitterNode createChannelSplitter([/*unsigned long*/ numberOfOutputs]) {
- if (?numberOfOutputs) {
- return _createChannelSplitter_1(numberOfOutputs);
- }
- return _createChannelSplitter_2();
- }
-
-
- /** @domName AudioContext.createChannelSplitter_1 */
- ChannelSplitterNode _createChannelSplitter_1(numberOfOutputs) native "AudioContext_createChannelSplitter_1_Callback";
-
-
- /** @domName AudioContext.createChannelSplitter_2 */
- ChannelSplitterNode _createChannelSplitter_2() native "AudioContext_createChannelSplitter_2_Callback";
-
-
- /** @domName AudioContext.createConvolver */
- ConvolverNode createConvolver() native "AudioContext_createConvolver_Callback";
-
- DelayNode createDelay([/*double*/ maxDelayTime]) {
- if (?maxDelayTime) {
- return _createDelay_1(maxDelayTime);
- }
- return _createDelay_2();
- }
-
-
- /** @domName AudioContext.createDelay_1 */
- DelayNode _createDelay_1(maxDelayTime) native "AudioContext_createDelay_1_Callback";
-
-
- /** @domName AudioContext.createDelay_2 */
- DelayNode _createDelay_2() native "AudioContext_createDelay_2_Callback";
-
-
- /** @domName AudioContext.createDynamicsCompressor */
- DynamicsCompressorNode createDynamicsCompressor() native "AudioContext_createDynamicsCompressor_Callback";
-
-
- /** @domName AudioContext.createGain */
- GainNode createGain() native "AudioContext_createGain_Callback";
-
-
- /** @domName AudioContext.createMediaElementSource */
- MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) native "AudioContext_createMediaElementSource_Callback";
-
-
- /** @domName AudioContext.createMediaStreamSource */
- MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) native "AudioContext_createMediaStreamSource_Callback";
-
-
- /** @domName AudioContext.createOscillator */
- OscillatorNode createOscillator() native "AudioContext_createOscillator_Callback";
-
-
- /** @domName AudioContext.createPanner */
- PannerNode createPanner() native "AudioContext_createPanner_Callback";
-
- ScriptProcessorNode createScriptProcessor(/*unsigned long*/ bufferSize, [/*unsigned long*/ numberOfInputChannels, /*unsigned long*/ numberOfOutputChannels]) {
- if (?numberOfOutputChannels) {
- return _createScriptProcessor_1(bufferSize, numberOfInputChannels, numberOfOutputChannels);
- }
- if (?numberOfInputChannels) {
- return _createScriptProcessor_2(bufferSize, numberOfInputChannels);
- }
- return _createScriptProcessor_3(bufferSize);
- }
-
-
- /** @domName AudioContext.createScriptProcessor_1 */
- ScriptProcessorNode _createScriptProcessor_1(bufferSize, numberOfInputChannels, numberOfOutputChannels) native "AudioContext_createScriptProcessor_1_Callback";
-
-
- /** @domName AudioContext.createScriptProcessor_2 */
- ScriptProcessorNode _createScriptProcessor_2(bufferSize, numberOfInputChannels) native "AudioContext_createScriptProcessor_2_Callback";
-
-
- /** @domName AudioContext.createScriptProcessor_3 */
- ScriptProcessorNode _createScriptProcessor_3(bufferSize) native "AudioContext_createScriptProcessor_3_Callback";
-
-
- /** @domName AudioContext.createWaveShaper */
- WaveShaperNode createWaveShaper() native "AudioContext_createWaveShaper_Callback";
-
-
- /** @domName AudioContext.createWaveTable */
- WaveTable createWaveTable(Float32Array real, Float32Array imag) native "AudioContext_createWaveTable_Callback";
-
-
- /** @domName AudioContext.decodeAudioData */
- void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native "AudioContext_decodeAudioData_Callback";
-
-
- /** @domName AudioContext.startRendering */
- void startRendering() native "AudioContext_startRendering_Callback";
-
-}
-
-class AudioContextEvents extends Events {
- AudioContextEvents(EventTarget _ptr) : super(_ptr);
-
- EventListenerList get complete => this['complete'];
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioDestinationNode
-class AudioDestinationNode extends AudioNode {
- AudioDestinationNode.internal(): super.internal();
-
-
- /** @domName AudioDestinationNode.numberOfChannels */
- int get numberOfChannels native "AudioDestinationNode_numberOfChannels_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName HTMLAudioElement
-class AudioElement extends MediaElement {
-
- factory AudioElement([String src]) {
- if (!?src) {
- return _AudioElementFactoryProvider.createAudioElement();
- }
- return _AudioElementFactoryProvider.createAudioElement(src);
- }
- AudioElement.internal(): super.internal();
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioGain
-class AudioGain extends AudioParam {
- AudioGain.internal(): super.internal();
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioListener
-class AudioListener extends NativeFieldWrapperClass1 {
- AudioListener.internal();
-
-
- /** @domName AudioListener.dopplerFactor */
- num get dopplerFactor native "AudioListener_dopplerFactor_Getter";
-
-
- /** @domName AudioListener.dopplerFactor */
- void set dopplerFactor(num value) native "AudioListener_dopplerFactor_Setter";
-
-
- /** @domName AudioListener.speedOfSound */
- num get speedOfSound native "AudioListener_speedOfSound_Getter";
-
-
- /** @domName AudioListener.speedOfSound */
- void set speedOfSound(num value) native "AudioListener_speedOfSound_Setter";
-
-
- /** @domName AudioListener.setOrientation */
- void setOrientation(num x, num y, num z, num xUp, num yUp, num zUp) native "AudioListener_setOrientation_Callback";
-
-
- /** @domName AudioListener.setPosition */
- void setPosition(num x, num y, num z) native "AudioListener_setPosition_Callback";
-
-
- /** @domName AudioListener.setVelocity */
- void setVelocity(num x, num y, num z) native "AudioListener_setVelocity_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioNode
-class AudioNode extends NativeFieldWrapperClass1 {
- AudioNode.internal();
-
-
- /** @domName AudioNode.context */
- AudioContext get context native "AudioNode_context_Getter";
-
-
- /** @domName AudioNode.numberOfInputs */
- int get numberOfInputs native "AudioNode_numberOfInputs_Getter";
-
-
- /** @domName AudioNode.numberOfOutputs */
- int get numberOfOutputs native "AudioNode_numberOfOutputs_Getter";
-
- void connect(destination, /*unsigned long*/ output, [/*unsigned long*/ input]) {
- if ((destination is AudioNode || destination == null) && (output is int || output == null) && (input is int || input == null)) {
- _connect_1(destination, output, input);
- return;
- }
- if ((destination is AudioParam || destination == null) && (output is int || output == null) && !?input) {
- _connect_2(destination, output);
- return;
- }
- throw "Incorrect number or type of arguments";
- }
-
-
- /** @domName AudioNode.connect_1 */
- void _connect_1(destination, output, input) native "AudioNode_connect_1_Callback";
-
-
- /** @domName AudioNode.connect_2 */
- void _connect_2(destination, output) native "AudioNode_connect_2_Callback";
-
-
- /** @domName AudioNode.disconnect */
- void disconnect(int output) native "AudioNode_disconnect_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioParam
-class AudioParam extends NativeFieldWrapperClass1 {
- AudioParam.internal();
-
-
- /** @domName AudioParam.defaultValue */
- num get defaultValue native "AudioParam_defaultValue_Getter";
-
-
- /** @domName AudioParam.maxValue */
- num get maxValue native "AudioParam_maxValue_Getter";
-
-
- /** @domName AudioParam.minValue */
- num get minValue native "AudioParam_minValue_Getter";
-
-
- /** @domName AudioParam.name */
- String get name native "AudioParam_name_Getter";
-
-
- /** @domName AudioParam.units */
- int get units native "AudioParam_units_Getter";
-
-
- /** @domName AudioParam.value */
- num get value native "AudioParam_value_Getter";
-
-
- /** @domName AudioParam.value */
- void set value(num value) native "AudioParam_value_Setter";
-
-
- /** @domName AudioParam.cancelScheduledValues */
- void cancelScheduledValues(num startTime) native "AudioParam_cancelScheduledValues_Callback";
-
-
- /** @domName AudioParam.exponentialRampToValueAtTime */
- void exponentialRampToValueAtTime(num value, num time) native "AudioParam_exponentialRampToValueAtTime_Callback";
-
-
- /** @domName AudioParam.linearRampToValueAtTime */
- void linearRampToValueAtTime(num value, num time) native "AudioParam_linearRampToValueAtTime_Callback";
-
-
- /** @domName AudioParam.setTargetAtTime */
- void setTargetAtTime(num target, num time, num timeConstant) native "AudioParam_setTargetAtTime_Callback";
-
-
- /** @domName AudioParam.setValueAtTime */
- void setValueAtTime(num value, num time) native "AudioParam_setValueAtTime_Callback";
-
-
- /** @domName AudioParam.setValueCurveAtTime */
- void setValueCurveAtTime(Float32Array values, num time, num duration) native "AudioParam_setValueCurveAtTime_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioProcessingEvent
-class AudioProcessingEvent extends Event {
- AudioProcessingEvent.internal(): super.internal();
-
-
- /** @domName AudioProcessingEvent.inputBuffer */
- AudioBuffer get inputBuffer native "AudioProcessingEvent_inputBuffer_Getter";
-
-
- /** @domName AudioProcessingEvent.outputBuffer */
- AudioBuffer get outputBuffer native "AudioProcessingEvent_outputBuffer_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName AudioSourceNode
-class AudioSourceNode extends AudioNode {
- AudioSourceNode.internal(): super.internal();
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName HTMLBRElement
class BRElement extends _Element_Merged {
@@ -1445,58 +839,6 @@
// WARNING: Do not edit - generated code.
-/// @domName BiquadFilterNode
-class BiquadFilterNode extends AudioNode {
- BiquadFilterNode.internal(): super.internal();
-
- static const int ALLPASS = 7;
-
- static const int BANDPASS = 2;
-
- static const int HIGHPASS = 1;
-
- static const int HIGHSHELF = 4;
-
- static const int LOWPASS = 0;
-
- static const int LOWSHELF = 3;
-
- static const int NOTCH = 6;
-
- static const int PEAKING = 5;
-
-
- /** @domName BiquadFilterNode.Q */
- AudioParam get Q native "BiquadFilterNode_Q_Getter";
-
-
- /** @domName BiquadFilterNode.frequency */
- AudioParam get frequency native "BiquadFilterNode_frequency_Getter";
-
-
- /** @domName BiquadFilterNode.gain */
- AudioParam get gain native "BiquadFilterNode_gain_Getter";
-
-
- /** @domName BiquadFilterNode.type */
- int get type native "BiquadFilterNode_type_Getter";
-
-
- /** @domName BiquadFilterNode.type */
- void set type(int value) native "BiquadFilterNode_type_Setter";
-
-
- /** @domName BiquadFilterNode.getFrequencyResponse */
- void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse) native "BiquadFilterNode_getFrequencyResponse_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName Blob
class Blob extends NativeFieldWrapperClass1 {
@@ -2261,7 +1603,7 @@
/** @domName CSSPrimitiveValue.getRGBColorValue */
- RGBColor getRGBColorValue() native "CSSPrimitiveValue_getRGBColorValue_Callback";
+ RGBColor getRgbColorValue() native "CSSPrimitiveValue_getRGBColorValue_Callback";
/** @domName CSSPrimitiveValue.getRectValue */
@@ -2352,6 +1694,7 @@
return _cachedBrowserPrefix;
}
+/// @domName CSSStyleDeclaration
class CSSStyleDeclaration extends NativeFieldWrapperClass1 {
factory CSSStyleDeclaration() => _CSSStyleDeclarationFactoryProvider.createCSSStyleDeclaration();
factory CSSStyleDeclaration.css(String css) =>
@@ -2377,7 +1720,7 @@
/** @domName CSSStyleDeclaration.getPropertyCSSValue */
- CSSValue getPropertyCSSValue(String propertyName) native "CSSStyleDeclaration_getPropertyCSSValue_Callback";
+ CSSValue getPropertyCssValue(String propertyName) native "CSSStyleDeclaration_getPropertyCSSValue_Callback";
/** @domName CSSStyleDeclaration.getPropertyPriority */
@@ -5747,6 +5090,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName HTMLCanvasElement
class CanvasElement extends _Element_Merged {
factory CanvasElement({int width, int height}) {
@@ -5779,7 +5123,7 @@
/** @domName HTMLCanvasElement.toDataURL */
- String toDataURL(String type, [num quality]) native "HTMLCanvasElement_toDataURL_Callback";
+ String toDataUrl(String type, [num quality]) native "HTMLCanvasElement_toDataURL_Callback";
CanvasRenderingContext2D get context2d => getContext('2d');
@@ -5833,6 +5177,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName CanvasRenderingContext2D
class CanvasRenderingContext2D extends CanvasRenderingContext {
CanvasRenderingContext2D.internal(): super.internal();
@@ -6520,30 +5865,6 @@
// WARNING: Do not edit - generated code.
-/// @domName ChannelMergerNode
-class ChannelMergerNode extends AudioNode {
- ChannelMergerNode.internal(): super.internal();
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-/// @domName ChannelSplitterNode
-class ChannelSplitterNode extends AudioNode {
- ChannelSplitterNode.internal(): super.internal();
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName CharacterData
class CharacterData extends Node {
CharacterData.internal(): super.internal();
@@ -6870,34 +6191,6 @@
// WARNING: Do not edit - generated code.
-/// @domName ConvolverNode
-class ConvolverNode extends AudioNode {
- ConvolverNode.internal(): super.internal();
-
-
- /** @domName ConvolverNode.buffer */
- AudioBuffer get buffer native "ConvolverNode_buffer_Getter";
-
-
- /** @domName ConvolverNode.buffer */
- void set buffer(AudioBuffer value) native "ConvolverNode_buffer_Setter";
-
-
- /** @domName ConvolverNode.normalize */
- bool get normalize native "ConvolverNode_normalize_Getter";
-
-
- /** @domName ConvolverNode.normalize */
- void set normalize(bool value) native "ConvolverNode_normalize_Setter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName Coordinates
class Coordinates extends NativeFieldWrapperClass1 {
Coordinates.internal();
@@ -6978,6 +6271,7 @@
// WARNING: Do not edit - generated code.
+/// @domName CustomEvent
class CustomEvent extends Event {
factory CustomEvent(String type, [bool canBubble = true, bool cancelable = true,
Object detail]) => _CustomEventFactoryProvider.createCustomEvent(
@@ -7238,7 +6532,7 @@
/** @domName DOMImplementation.createCSSStyleSheet */
- CSSStyleSheet createCSSStyleSheet(String title, String media) native "DOMImplementation_createCSSStyleSheet_Callback";
+ CSSStyleSheet createCssStyleSheet(String title, String media) native "DOMImplementation_createCSSStyleSheet_Callback";
/** @domName DOMImplementation.createDocument */
@@ -7250,7 +6544,7 @@
/** @domName DOMImplementation.createHTMLDocument */
- HtmlDocument createHTMLDocument(String title) native "DOMImplementation_createHTMLDocument_Callback";
+ HtmlDocument createHtmlDocument(String title) native "DOMImplementation_createHTMLDocument_Callback";
/** @domName DOMImplementation.hasFeature */
@@ -8171,22 +7465,6 @@
// WARNING: Do not edit - generated code.
-/// @domName DelayNode
-class DelayNode extends AudioNode {
- DelayNode.internal(): super.internal();
-
-
- /** @domName DelayNode.delayTime */
- AudioParam get delayTime native "DelayNode_delayTime_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName HTMLDetailsElement
class DetailsElement extends _Element_Merged {
@@ -8377,6 +7655,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Document
class Document extends Node
{
@@ -8496,7 +7775,7 @@
/** @domName Document.createCDATASection */
- CDATASection createCDATASection(String data) native "Document_createCDATASection_Callback";
+ CDATASection createCDataSection(String data) native "Document_createCDATASection_Callback";
/** @domName Document.createDocumentFragment */
@@ -8540,7 +7819,7 @@
/** @domName Document.getCSSCanvasContext */
- CanvasRenderingContext getCSSCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
+ CanvasRenderingContext getCssCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
/** @domName Document.getElementById */
@@ -8636,100 +7915,10 @@
class DocumentEvents extends ElementEvents {
DocumentEvents(EventTarget _ptr) : super(_ptr);
- EventListenerList get abort => this['abort'];
-
- EventListenerList get beforeCopy => this['beforecopy'];
-
- EventListenerList get beforeCut => this['beforecut'];
-
- EventListenerList get beforePaste => this['beforepaste'];
-
- EventListenerList get blur => this['blur'];
-
- EventListenerList get change => this['change'];
-
- EventListenerList get click => this['click'];
-
- EventListenerList get contextMenu => this['contextmenu'];
-
- EventListenerList get copy => this['copy'];
-
- EventListenerList get cut => this['cut'];
-
- EventListenerList get doubleClick => this['dblclick'];
-
- EventListenerList get drag => this['drag'];
-
- EventListenerList get dragEnd => this['dragend'];
-
- EventListenerList get dragEnter => this['dragenter'];
-
- EventListenerList get dragLeave => this['dragleave'];
-
- EventListenerList get dragOver => this['dragover'];
-
- EventListenerList get dragStart => this['dragstart'];
-
- EventListenerList get drop => this['drop'];
-
- EventListenerList get error => this['error'];
-
- EventListenerList get focus => this['focus'];
-
- EventListenerList get input => this['input'];
-
- EventListenerList get invalid => this['invalid'];
-
- EventListenerList get keyDown => this['keydown'];
-
- EventListenerList get keyPress => this['keypress'];
-
- EventListenerList get keyUp => this['keyup'];
-
- EventListenerList get load => this['load'];
-
- EventListenerList get mouseDown => this['mousedown'];
-
- EventListenerList get mouseMove => this['mousemove'];
-
- EventListenerList get mouseOut => this['mouseout'];
-
- EventListenerList get mouseOver => this['mouseover'];
-
- EventListenerList get mouseUp => this['mouseup'];
-
- EventListenerList get mouseWheel => this['mousewheel'];
-
- EventListenerList get paste => this['paste'];
-
EventListenerList get readyStateChange => this['readystatechange'];
- EventListenerList get reset => this['reset'];
-
- EventListenerList get scroll => this['scroll'];
-
- EventListenerList get search => this['search'];
-
- EventListenerList get select => this['select'];
-
EventListenerList get selectionChange => this['selectionchange'];
- EventListenerList get selectStart => this['selectstart'];
-
- EventListenerList get submit => this['submit'];
-
- EventListenerList get touchCancel => this['touchcancel'];
-
- EventListenerList get touchEnd => this['touchend'];
-
- EventListenerList get touchMove => this['touchmove'];
-
- EventListenerList get touchStart => this['touchstart'];
-
- EventListenerList get fullscreenChange => this['webkitfullscreenchange'];
-
- EventListenerList get fullscreenError => this['webkitfullscreenerror'];
-
EventListenerList get pointerLockChange => this['webkitpointerlockchange'];
EventListenerList get pointerLockError => this['webkitpointerlockerror'];
@@ -8754,6 +7943,7 @@
bool get frozen => true;
}
+/// @domName DocumentFragment
class DocumentFragment extends Node {
factory DocumentFragment() => _DocumentFragmentFactoryProvider.createDocumentFragment();
@@ -8792,21 +7982,21 @@
List<Element> queryAll(String selectors) =>
new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
- String get innerHTML {
+ String get innerHtml {
final e = new Element.tag("div");
e.nodes.add(this.clone(true));
- return e.innerHTML;
+ return e.innerHtml;
}
- String get outerHTML => innerHTML;
+ String get outerHtml => innerHtml;
- // TODO(nweiz): Do we want to support some variant of innerHTML for XML and/or
+ // TODO(nweiz): Do we want to support some variant of innerHtml for XML and/or
// SVG strings?
- void set innerHTML(String value) {
+ void set innerHtml(String value) {
this.nodes.clear();
final e = new Element.tag("div");
- e.innerHTML = value;
+ e.innerHtml = value;
// Copy list first since we don't want liveness during iteration.
List nodes = new List.from(e.nodes);
@@ -8836,16 +8026,20 @@
this._insertAdjacentNode(where, new Text(text));
}
- void insertAdjacentHTML(String where, String text) {
+ void insertAdjacentHtml(String where, String text) {
this._insertAdjacentNode(where, new DocumentFragment.html(text));
}
- void addText(String text) {
+ void append(Element element) {
+ this.children.add(element);
+ }
+
+ void appendText(String text) {
this.insertAdjacentText('beforeend', text);
}
- void addHtml(String text) {
- this.insertAdjacentHTML('beforeend', text);
+ void appendHtml(String text) {
+ this.insertAdjacentHtml('beforeend', text);
}
// If we can come up with a semi-reasonable default value for an Element
@@ -8869,7 +8063,7 @@
}
return null;
}
- Element get $m_lastElementChild() => elements.last;
+ Element get $m_lastElementChild => elements.last;
Element get nextElementSibling => null;
Element get previousElementSibling => null;
Element get offsetParent => null;
@@ -9054,42 +8248,6 @@
// WARNING: Do not edit - generated code.
-/// @domName DynamicsCompressorNode
-class DynamicsCompressorNode extends AudioNode {
- DynamicsCompressorNode.internal(): super.internal();
-
-
- /** @domName DynamicsCompressorNode.attack */
- AudioParam get attack native "DynamicsCompressorNode_attack_Getter";
-
-
- /** @domName DynamicsCompressorNode.knee */
- AudioParam get knee native "DynamicsCompressorNode_knee_Getter";
-
-
- /** @domName DynamicsCompressorNode.ratio */
- AudioParam get ratio native "DynamicsCompressorNode_ratio_Getter";
-
-
- /** @domName DynamicsCompressorNode.reduction */
- AudioParam get reduction native "DynamicsCompressorNode_reduction_Getter";
-
-
- /** @domName DynamicsCompressorNode.release */
- AudioParam get release native "DynamicsCompressorNode_release_Getter";
-
-
- /** @domName DynamicsCompressorNode.threshold */
- AudioParam get threshold native "DynamicsCompressorNode_threshold_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName EXTTextureFilterAnisotropic
class EXTTextureFilterAnisotropic extends NativeFieldWrapperClass1 {
EXTTextureFilterAnisotropic.internal();
@@ -9401,171 +8559,6 @@
bool get hasNext => _index < _list.length;
}
-class _ElementAttributeMap implements Map<String, String> {
-
- final Element _element;
-
- _ElementAttributeMap(this._element);
-
- bool containsValue(String value) {
- final attributes = _element.$dom_attributes;
- for (int i = 0, len = attributes.length; i < len; i++) {
- if(value == attributes[i].value) {
- return true;
- }
- }
- return false;
- }
-
- bool containsKey(String key) {
- return _element.$dom_hasAttribute(key);
- }
-
- String operator [](String key) {
- return _element.$dom_getAttribute(key);
- }
-
- void operator []=(String key, value) {
- _element.$dom_setAttribute(key, '$value');
- }
-
- String putIfAbsent(String key, String ifAbsent()) {
- if (!containsKey(key)) {
- this[key] = ifAbsent();
- }
- return this[key];
- }
-
- String remove(String key) {
- String value = _element.$dom_getAttribute(key);
- _element.$dom_removeAttribute(key);
- return value;
- }
-
- void clear() {
- final attributes = _element.$dom_attributes;
- for (int i = attributes.length - 1; i >= 0; i--) {
- remove(attributes[i].name);
- }
- }
-
- void forEach(void f(String key, String value)) {
- final attributes = _element.$dom_attributes;
- for (int i = 0, len = attributes.length; i < len; i++) {
- final item = attributes[i];
- f(item.name, item.value);
- }
- }
-
- Collection<String> get keys {
- // TODO(jacobr): generate a lazy collection instead.
- final attributes = _element.$dom_attributes;
- final keys = new List<String>(attributes.length);
- for (int i = 0, len = attributes.length; i < len; i++) {
- keys[i] = attributes[i].name;
- }
- return keys;
- }
-
- Collection<String> get values {
- // TODO(jacobr): generate a lazy collection instead.
- final attributes = _element.$dom_attributes;
- final values = new List<String>(attributes.length);
- for (int i = 0, len = attributes.length; i < len; i++) {
- values[i] = attributes[i].value;
- }
- return values;
- }
-
- /**
- * The number of {key, value} pairs in the map.
- */
- int get length {
- return _element.$dom_attributes.length;
- }
-
- /**
- * Returns true if there is no {key, value} pair in the map.
- */
- bool get isEmpty {
- return length == 0;
- }
-}
-
-/**
- * Provides a Map abstraction on top of data-* attributes, similar to the
- * dataSet in the old DOM.
- */
-class _DataAttributeMap implements Map<String, String> {
-
- final Map<String, String> $dom_attributes;
-
- _DataAttributeMap(this.$dom_attributes);
-
- // interface Map
-
- // TODO: Use lazy iterator when it is available on Map.
- bool containsValue(String value) => values.some((v) => v == value);
-
- bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
-
- String operator [](String key) => $dom_attributes[_attr(key)];
-
- void operator []=(String key, value) {
- $dom_attributes[_attr(key)] = '$value';
- }
-
- String putIfAbsent(String key, String ifAbsent()) =>
- $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
-
- String remove(String key) => $dom_attributes.remove(_attr(key));
-
- void clear() {
- // Needs to operate on a snapshot since we are mutating the collection.
- for (String key in keys) {
- remove(key);
- }
- }
-
- void forEach(void f(String key, String value)) {
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- f(_strip(key), value);
- }
- });
- }
-
- Collection<String> get keys {
- final keys = new List<String>();
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- keys.add(_strip(key));
- }
- });
- return keys;
- }
-
- Collection<String> get values {
- final values = new List<String>();
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- values.add(value);
- }
- });
- return values;
- }
-
- int get length => keys.length;
-
- // TODO: Use lazy iterator when it is available on Map.
- bool get isEmpty => length == 0;
-
- // Helpers.
- String _attr(String key) => 'data-$key';
- bool _matches(String key) => key.startsWith('data-');
- String _strip(String key) => key.substring(5);
-}
-
class _ElementCssClassSet extends CssClassSet {
final Element _element;
@@ -9591,24 +8584,7 @@
}
}
-class _SimpleClientRect implements ClientRect {
- final num left;
- final num top;
- final num width;
- final num height;
- num get right => left + width;
- num get bottom => top + height;
-
- const _SimpleClientRect(this.left, this.top, this.width, this.height);
-
- bool operator ==(ClientRect other) {
- return other != null && left == other.left && top == other.top
- && width == other.width && height == other.height;
- }
-
- String toString() => "($left, $top, $width, $height)";
-}
-
+/// @domName Element
abstract class Element extends Node implements ElementTraversal {
factory Element.html(String html) =>
@@ -9630,6 +8606,14 @@
}
}
+ /**
+ * Deprecated, use innerHtml instead.
+ */
+ String get innerHTML => this.innerHtml;
+ void set innerHTML(String value) {
+ this.innerHtml = value;
+ }
+
void set elements(Collection<Element> value) {
this.children = value;
}
@@ -9678,6 +8662,14 @@
}
}
+ /**
+ * Gets a map for manipulating the attributes of a particular namespace.
+ * This is primarily useful for SVG attributes such as xref:link.
+ */
+ Map<String, String> getNamespacedAttributes(String namespace) {
+ return new _NamespacedAttributeMap(this, namespace);
+ }
+
/** @domName Window.getComputedStyle */
Future<CSSStyleDeclaration> get computedStyle {
// TODO(jacobr): last param should be null, see b/5045788
@@ -9692,9 +8684,16 @@
}
/**
+ * Adds the specified element to after the last child of this.
+ */
+ void append(Element e) {
+ this.children.add(e);
+ }
+
+ /**
* Adds the specified text as a text node after the last child of this.
*/
- void addText(String text) {
+ void appendText(String text) {
this.insertAdjacentText('beforeend', text);
}
@@ -9702,8 +8701,8 @@
* Parses the specified text as HTML and adds the resulting node after the
* last child of this.
*/
- void addHtml(String text) {
- this.insertAdjacentHTML('beforeend', text);
+ void appendHtml(String text) {
+ this.insertAdjacentHtml('beforeend', text);
}
// Hooks to support custom WebComponents.
@@ -9760,7 +8759,7 @@
String id;
/// @domName HTMLElement.innerHTML; @docsEditable true
- String innerHTML;
+ String innerHtml;
/// @domName HTMLElement.isContentEditable; @docsEditable true
bool get isContentEditable;
@@ -9769,7 +8768,7 @@
String lang;
/// @domName HTMLElement.outerHTML; @docsEditable true
- String get outerHTML;
+ String get outerHtml;
/// @domName HTMLElement.spellcheck; @docsEditable true
bool spellcheck;
@@ -9793,7 +8792,7 @@
Element insertAdjacentElement(String where, Element element);
/// @domName HTMLElement.insertAdjacentHTML; @docsEditable true
- void insertAdjacentHTML(String where, String html);
+ void insertAdjacentHtml(String where, String html);
/// @domName HTMLElement.insertAdjacentText; @docsEditable true
void insertAdjacentText(String where, String text);
@@ -9913,6 +8912,10 @@
String $dom_getAttribute(String name) native "Element_getAttribute_Callback";
+ /** @domName Element.getAttributeNS */
+ String $dom_getAttributeNS(String namespaceURI, String localName) native "Element_getAttributeNS_Callback";
+
+
/** @domName Element.getBoundingClientRect */
ClientRect getBoundingClientRect() native "Element_getBoundingClientRect_Callback";
@@ -9933,6 +8936,10 @@
bool $dom_hasAttribute(String name) native "Element_hasAttribute_Callback";
+ /** @domName Element.hasAttributeNS */
+ bool $dom_hasAttributeNS(String namespaceURI, String localName) native "Element_hasAttributeNS_Callback";
+
+
/** @domName Element.querySelector */
Element $dom_querySelector(String selectors) native "Element_querySelector_Callback";
@@ -9949,6 +8956,10 @@
void $dom_removeAttribute(String name) native "Element_removeAttribute_Callback";
+ /** @domName Element.removeAttributeNS */
+ void $dom_removeAttributeNS(String namespaceURI, String localName) native "Element_removeAttributeNS_Callback";
+
+
/** @domName Element.scrollByLines */
void scrollByLines(int lines) native "Element_scrollByLines_Callback";
@@ -9977,6 +8988,10 @@
void $dom_setAttribute(String name, String value) native "Element_setAttribute_Callback";
+ /** @domName Element.setAttributeNS */
+ void $dom_setAttributeNS(String namespaceURI, String qualifiedName, String value) native "Element_setAttributeNS_Callback";
+
+
/** @domName Element.webkitMatchesSelector */
bool matchesSelector(String selectors) native "Element_webkitMatchesSelector_Callback";
@@ -10031,7 +9046,7 @@
}
}
final Element temp = new Element.tag(parentTag);
- temp.innerHTML = html;
+ temp.innerHtml = html;
Element element;
if (temp.children.length == 1) {
@@ -10372,7 +9387,7 @@
/** @domName Entry.toURL */
- String toURL() native "Entry_toURL_Callback";
+ String toUrl() native "Entry_toURL_Callback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -10436,7 +9451,7 @@
/** @domName EntrySync.toURL */
- String toURL() native "EntrySync_toURL_Callback";
+ String toUrl() native "EntrySync_toURL_Callback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -10478,6 +9493,7 @@
// WARNING: Do not edit - generated code.
+/// @domName Event
class Event extends NativeFieldWrapperClass1 {
// In JS, canBubble and cancelable are technically required parameters to
// init*Event. In practice, though, if they aren't provided they simply
@@ -10654,10 +9670,6 @@
static const int OPEN = 1;
- /** @domName EventSource.URL */
- String get URL native "EventSource_URL_Getter";
-
-
/** @domName EventSource.readyState */
int get readyState native "EventSource_readyState_Getter";
@@ -10742,7 +9754,7 @@
}
}
-
+/// @domName EventTarget
class EventTarget extends NativeFieldWrapperClass1 {
/** @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent */
@@ -11045,7 +10057,7 @@
/** @domName FileReader.readAsDataURL */
- void readAsDataURL(Blob blob) native "FileReader_readAsDataURL_Callback";
+ void readAsDataUrl(Blob blob) native "FileReader_readAsDataURL_Callback";
void readAsText(/*Blob*/ blob, [/*DOMString*/ encoding]) {
if (?encoding) {
@@ -11107,7 +10119,7 @@
/** @domName FileReaderSync.readAsDataURL */
- String readAsDataURL(Blob blob) native "FileReaderSync_readAsDataURL_Callback";
+ String readAsDataUrl(Blob blob) native "FileReaderSync_readAsDataURL_Callback";
String readAsText(/*Blob*/ blob, [/*DOMString*/ encoding]) {
if (?encoding) {
@@ -11847,22 +10859,6 @@
// WARNING: Do not edit - generated code.
-/// @domName GainNode
-class GainNode extends AudioNode {
- GainNode.internal(): super.internal();
-
-
- /** @domName GainNode.gain */
- AudioGain get gain native "GainNode_gain_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName Gamepad
class Gamepad extends NativeFieldWrapperClass1 {
Gamepad.internal();
@@ -12249,11 +11245,11 @@
/** @domName HashChangeEvent.newURL */
- String get newURL native "HashChangeEvent_newURL_Getter";
+ String get newUrl native "HashChangeEvent_newURL_Getter";
/** @domName HashChangeEvent.oldURL */
- String get oldURL native "HashChangeEvent_oldURL_Getter";
+ String get oldUrl native "HashChangeEvent_oldURL_Getter";
/** @domName HashChangeEvent.initHashChangeEvent */
@@ -12321,6 +11317,7 @@
// WARNING: Do not edit - generated code.
+/// @domName HTMLDocument
class HtmlDocument extends Document {
HtmlDocument.internal(): super.internal();
@@ -12419,6 +11416,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName XMLHttpRequest
class HttpRequest extends EventTarget {
factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
_HttpRequestFactoryProvider.createHttpRequest_get(url, onComplete);
@@ -12468,7 +11466,7 @@
/** @domName XMLHttpRequest.responseXML */
- Document get responseXML native "XMLHttpRequest_responseXML_Getter";
+ Document get responseXml native "XMLHttpRequest_responseXML_Getter";
/** @domName XMLHttpRequest.status */
@@ -13103,6 +12101,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName IDBKeyRange
class IDBKeyRange extends NativeFieldWrapperClass1 {
/**
* @domName IDBKeyRange.only
@@ -14858,11 +13857,32 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
-
-/// @domName KeyboardEvent
+/// @domName KeyboardEvent; @docsEditable true
class KeyboardEvent extends UIEvent {
+
+ factory KeyboardEvent(String type, Window view,
+ [bool canBubble = true, bool cancelable = true,
+ String keyIdentifier = null, int keyLocation = 1, bool ctrlKey = false,
+ bool altKey = false, bool shiftKey = false, bool metaKey = false,
+ bool altGraphKey = false]) {
+ final e = document.$dom_createEvent("KeyboardEvent");
+ e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+ keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
+ return e;
+ }
+
+ /** @domName KeyboardEvent.initKeyboardEvent */
+ void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+ bool altKey, bool shiftKey, bool metaKey,
+ bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
+
+ /** @domName KeyboardEvent.keyCode */
+ int get keyCode => $dom_keyCode;
+
+ /** @domName KeyboardEvent.charCode */
+ int get charCode => $dom_charCode;
KeyboardEvent.internal(): super.internal();
@@ -14879,7 +13899,7 @@
/** @domName KeyboardEvent.keyIdentifier */
- String get keyIdentifier native "KeyboardEvent_keyIdentifier_Getter";
+ String get $dom_keyIdentifier native "KeyboardEvent_keyIdentifier_Getter";
/** @domName KeyboardEvent.keyLocation */
@@ -14893,10 +13913,6 @@
/** @domName KeyboardEvent.shiftKey */
bool get shiftKey native "KeyboardEvent_shiftKey_Getter";
-
- /** @domName KeyboardEvent.initKeyboardEvent */
- void initKeyboardEvent(String type, bool canBubble, bool cancelable, LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
-
}
// 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
@@ -15329,6 +14345,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Window
class LocalWindow extends EventTarget implements Window {
/**
@@ -15635,7 +14652,7 @@
/** @domName DOMWindow.getMatchedCSSRules */
- List<CSSRule> getMatchedCSSRules(Element element, String pseudoElement) native "DOMWindow_getMatchedCSSRules_Callback";
+ List<CSSRule> getMatchedCssRules(Element element, String pseudoElement) native "DOMWindow_getMatchedCSSRules_Callback";
/** @domName DOMWindow.getSelection */
@@ -15739,7 +14756,7 @@
/** @domName DOMWindow.webkitResolveLocalFileSystemURL */
- void webkitResolveLocalFileSystemURL(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
+ void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "DOMWindow_webkitResolveLocalFileSystemURL_Callback";
}
@@ -16477,22 +15494,6 @@
// WARNING: Do not edit - generated code.
-/// @domName MediaElementAudioSourceNode
-class MediaElementAudioSourceNode extends AudioSourceNode {
- MediaElementAudioSourceNode.internal(): super.internal();
-
-
- /** @domName MediaElementAudioSourceNode.mediaElement */
- MediaElement get mediaElement native "MediaElementAudioSourceNode_mediaElement_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName MediaError
class MediaError extends NativeFieldWrapperClass1 {
MediaError.internal();
@@ -16553,7 +15554,7 @@
/** @domName MediaKeyEvent.defaultURL */
- String get defaultURL native "MediaKeyEvent_defaultURL_Getter";
+ String get defaultUrl native "MediaKeyEvent_defaultURL_Getter";
/** @domName MediaKeyEvent.errorCode */
@@ -16781,22 +15782,6 @@
// WARNING: Do not edit - generated code.
-/// @domName MediaStreamAudioSourceNode
-class MediaStreamAudioSourceNode extends AudioSourceNode {
- MediaStreamAudioSourceNode.internal(): super.internal();
-
-
- /** @domName MediaStreamAudioSourceNode.mediaStream */
- MediaStream get mediaStream native "MediaStreamAudioSourceNode_mediaStream_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName MediaStreamEvent
class MediaStreamEvent extends Event {
MediaStreamEvent.internal(): super.internal();
@@ -16975,14 +15960,6 @@
factory MenuElement() => document.$dom_createElement("menu");
MenuElement.internal(): super.internal();
-
- /** @domName HTMLMenuElement.compact */
- bool get compact native "HTMLMenuElement_compact_Getter";
-
-
- /** @domName HTMLMenuElement.compact */
- void set compact(bool value) native "HTMLMenuElement_compact_Setter";
-
}
// 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
@@ -17265,6 +16242,7 @@
// WARNING: Do not edit - generated code.
+/// @domName MouseEvent
class MouseEvent extends UIEvent {
factory MouseEvent(String type, Window view, int detail, int screenX,
int screenY, int clientX, int clientY, int button, [bool canBubble = true,
@@ -17414,6 +16392,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName MutationObserver
class MutationObserver extends NativeFieldWrapperClass1 {
factory MutationObserver(MutationCallback callback) => _MutationObserverFactoryProvider.createMutationObserver(callback);
@@ -17904,6 +16883,7 @@
Node operator[](int index) => _this.$dom_childNodes[index];
}
+/// @domName Node
class Node extends EventTarget {
_ChildNodeListLazy get nodes {
return new _ChildNodeListLazy(this);
@@ -18001,6 +16981,14 @@
Node get $dom_lastChild native "Node_lastChild_Getter";
+ /** @domName Node.localName */
+ String get $dom_localName native "Node_localName_Getter";
+
+
+ /** @domName Node.namespaceURI */
+ String get $dom_namespaceUri native "Node_namespaceURI_Getter";
+
+
/** @domName Node.nextSibling */
Node get nextNode native "Node_nextSibling_Getter";
@@ -18172,6 +17160,111 @@
// WARNING: Do not edit - generated code.
+/// @domName NodeList
+class NodeList extends NativeFieldWrapperClass1 implements List<Node> {
+ NodeList.internal();
+
+
+ /** @domName NodeList.length */
+ int get length native "NodeList_length_Getter";
+
+ Node operator[](int index) native "NodeList_item_Callback";
+
+ void operator[]=(int index, Node value) {
+ throw new UnsupportedError("Cannot assign element of immutable List.");
+ }
+ // -- start List<Node> mixins.
+ // Node is the element type.
+
+ // From Iterable<Node>:
+
+ Iterator<Node> iterator() {
+ // Note: NodeLists are not fixed size. And most probably length shouldn't
+ // be cached in both iterator _and_ forEach method. For now caching it
+ // for consistency.
+ return new FixedSizeListIterator<Node>(this);
+ }
+
+ // From Collection<Node>:
+
+ void add(Node value) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void addLast(Node value) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void addAll(Collection<Node> collection) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ bool contains(Node element) => _Collections.contains(this, element);
+
+ void forEach(void f(Node element)) => _Collections.forEach(this, f);
+
+ Collection map(f(Node element)) => _Collections.map(this, [], f);
+
+ Collection<Node> filter(bool f(Node element)) =>
+ _Collections.filter(this, <Node>[], f);
+
+ bool every(bool f(Node element)) => _Collections.every(this, f);
+
+ bool some(bool f(Node element)) => _Collections.some(this, f);
+
+ bool get isEmpty => this.length == 0;
+
+ // From List<Node>:
+
+ void sort([Comparator<Node> compare = Comparable.compare]) {
+ throw new UnsupportedError("Cannot sort immutable List.");
+ }
+
+ int indexOf(Node element, [int start = 0]) =>
+ _Lists.indexOf(this, element, start, this.length);
+
+ int lastIndexOf(Node element, [int start]) {
+ if (start == null) start = length - 1;
+ return _Lists.lastIndexOf(this, element, start);
+ }
+
+ Node get first => this[0];
+
+ Node get last => this[length - 1];
+
+ Node removeLast() {
+ throw new UnsupportedError("Cannot removeLast on immutable List.");
+ }
+
+ void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ throw new UnsupportedError("Cannot setRange on immutable List.");
+ }
+
+ void removeRange(int start, int rangeLength) {
+ throw new UnsupportedError("Cannot removeRange on immutable List.");
+ }
+
+ void insertRange(int start, int rangeLength, [Node initialValue]) {
+ throw new UnsupportedError("Cannot insertRange on immutable List.");
+ }
+
+ List<Node> getRange(int start, int rangeLength) =>
+ _Lists.getRange(this, start, rangeLength, <Node>[]);
+
+ // -- end List<Node> mixins.
+
+
+ /** @domName NodeList.item */
+ Node _item(int index) native "NodeList_item_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
/// @domName Notation
class Notation extends Node {
Notation.internal(): super.internal();
@@ -18295,7 +17388,7 @@
/** @domName NotificationCenter.createHTMLNotification */
- Notification createHTMLNotification(String url) native "NotificationCenter_createHTMLNotification_Callback";
+ Notification createHtmlNotification(String url) native "NotificationCenter_createHTMLNotification_Callback";
/** @domName NotificationCenter.createNotification */
@@ -18367,19 +17460,19 @@
/** @domName OESVertexArrayObject.bindVertexArrayOES */
- void bindVertexArrayOES(WebGLVertexArrayObjectOES arrayObject) native "OESVertexArrayObject_bindVertexArrayOES_Callback";
+ void bindVertexArray(WebGLVertexArrayObjectOES arrayObject) native "OESVertexArrayObject_bindVertexArrayOES_Callback";
/** @domName OESVertexArrayObject.createVertexArrayOES */
- WebGLVertexArrayObjectOES createVertexArrayOES() native "OESVertexArrayObject_createVertexArrayOES_Callback";
+ WebGLVertexArrayObjectOES createVertexArray() native "OESVertexArrayObject_createVertexArrayOES_Callback";
/** @domName OESVertexArrayObject.deleteVertexArrayOES */
- void deleteVertexArrayOES(WebGLVertexArrayObjectOES arrayObject) native "OESVertexArrayObject_deleteVertexArrayOES_Callback";
+ void deleteVertexArray(WebGLVertexArrayObjectOES arrayObject) native "OESVertexArrayObject_deleteVertexArrayOES_Callback";
/** @domName OESVertexArrayObject.isVertexArrayOES */
- bool isVertexArrayOES(WebGLVertexArrayObjectOES arrayObject) native "OESVertexArrayObject_isVertexArrayOES_Callback";
+ bool isVertexArray(WebGLVertexArrayObjectOES arrayObject) native "OESVertexArrayObject_isVertexArrayOES_Callback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -18601,22 +17694,6 @@
// WARNING: Do not edit - generated code.
-/// @domName OfflineAudioCompletionEvent
-class OfflineAudioCompletionEvent extends Event {
- OfflineAudioCompletionEvent.internal(): super.internal();
-
-
- /** @domName OfflineAudioCompletionEvent.renderedBuffer */
- AudioBuffer get renderedBuffer native "OfflineAudioCompletionEvent_renderedBuffer_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName HTMLOptGroupElement
class OptGroupElement extends _Element_Merged {
@@ -18723,68 +17800,6 @@
// WARNING: Do not edit - generated code.
-/// @domName OscillatorNode
-class OscillatorNode extends AudioSourceNode {
- OscillatorNode.internal(): super.internal();
-
- static const int CUSTOM = 4;
-
- static const int FINISHED_STATE = 3;
-
- static const int PLAYING_STATE = 2;
-
- static const int SAWTOOTH = 2;
-
- static const int SCHEDULED_STATE = 1;
-
- static const int SINE = 0;
-
- static const int SQUARE = 1;
-
- static const int TRIANGLE = 3;
-
- static const int UNSCHEDULED_STATE = 0;
-
-
- /** @domName OscillatorNode.detune */
- AudioParam get detune native "OscillatorNode_detune_Getter";
-
-
- /** @domName OscillatorNode.frequency */
- AudioParam get frequency native "OscillatorNode_frequency_Getter";
-
-
- /** @domName OscillatorNode.playbackState */
- int get playbackState native "OscillatorNode_playbackState_Getter";
-
-
- /** @domName OscillatorNode.type */
- int get type native "OscillatorNode_type_Getter";
-
-
- /** @domName OscillatorNode.type */
- void set type(int value) native "OscillatorNode_type_Setter";
-
-
- /** @domName OscillatorNode.setWaveTable */
- void setWaveTable(WaveTable waveTable) native "OscillatorNode_setWaveTable_Callback";
-
-
- /** @domName OscillatorNode.start */
- void start(num when) native "OscillatorNode_start_Callback";
-
-
- /** @domName OscillatorNode.stop */
- void stop(num when) native "OscillatorNode_stop_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName HTMLOutputElement
class OutputElement extends _Element_Merged {
@@ -18929,114 +17944,6 @@
// WARNING: Do not edit - generated code.
-/// @domName PannerNode
-class PannerNode extends AudioNode {
- PannerNode.internal(): super.internal();
-
- static const int EQUALPOWER = 0;
-
- static const int EXPONENTIAL_DISTANCE = 2;
-
- static const int HRTF = 1;
-
- static const int INVERSE_DISTANCE = 1;
-
- static const int LINEAR_DISTANCE = 0;
-
- static const int SOUNDFIELD = 2;
-
-
- /** @domName PannerNode.coneGain */
- AudioGain get coneGain native "PannerNode_coneGain_Getter";
-
-
- /** @domName PannerNode.coneInnerAngle */
- num get coneInnerAngle native "PannerNode_coneInnerAngle_Getter";
-
-
- /** @domName PannerNode.coneInnerAngle */
- void set coneInnerAngle(num value) native "PannerNode_coneInnerAngle_Setter";
-
-
- /** @domName PannerNode.coneOuterAngle */
- num get coneOuterAngle native "PannerNode_coneOuterAngle_Getter";
-
-
- /** @domName PannerNode.coneOuterAngle */
- void set coneOuterAngle(num value) native "PannerNode_coneOuterAngle_Setter";
-
-
- /** @domName PannerNode.coneOuterGain */
- num get coneOuterGain native "PannerNode_coneOuterGain_Getter";
-
-
- /** @domName PannerNode.coneOuterGain */
- void set coneOuterGain(num value) native "PannerNode_coneOuterGain_Setter";
-
-
- /** @domName PannerNode.distanceGain */
- AudioGain get distanceGain native "PannerNode_distanceGain_Getter";
-
-
- /** @domName PannerNode.distanceModel */
- int get distanceModel native "PannerNode_distanceModel_Getter";
-
-
- /** @domName PannerNode.distanceModel */
- void set distanceModel(int value) native "PannerNode_distanceModel_Setter";
-
-
- /** @domName PannerNode.maxDistance */
- num get maxDistance native "PannerNode_maxDistance_Getter";
-
-
- /** @domName PannerNode.maxDistance */
- void set maxDistance(num value) native "PannerNode_maxDistance_Setter";
-
-
- /** @domName PannerNode.panningModel */
- int get panningModel native "PannerNode_panningModel_Getter";
-
-
- /** @domName PannerNode.panningModel */
- void set panningModel(int value) native "PannerNode_panningModel_Setter";
-
-
- /** @domName PannerNode.refDistance */
- num get refDistance native "PannerNode_refDistance_Getter";
-
-
- /** @domName PannerNode.refDistance */
- void set refDistance(num value) native "PannerNode_refDistance_Setter";
-
-
- /** @domName PannerNode.rolloffFactor */
- num get rolloffFactor native "PannerNode_rolloffFactor_Getter";
-
-
- /** @domName PannerNode.rolloffFactor */
- void set rolloffFactor(num value) native "PannerNode_rolloffFactor_Setter";
-
-
- /** @domName PannerNode.setOrientation */
- void setOrientation(num x, num y, num z) native "PannerNode_setOrientation_Callback";
-
-
- /** @domName PannerNode.setPosition */
- void setPosition(num x, num y, num z) native "PannerNode_setPosition_Callback";
-
-
- /** @domName PannerNode.setVelocity */
- void setVelocity(num x, num y, num z) native "PannerNode_setVelocity_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName HTMLParagraphElement
class ParagraphElement extends _Element_Merged {
@@ -19389,6 +18296,7 @@
// WARNING: Do not edit - generated code.
+/// @domName WebKitPoint
class Point extends NativeFieldWrapperClass1 {
factory Point(num x, num y) => _PointFactoryProvider.createPoint(x, y);
Point.internal();
@@ -20033,7 +18941,7 @@
/// @domName RadioNodeList
-class RadioNodeList extends _NodeList {
+class RadioNodeList extends NodeList {
RadioNodeList.internal(): super.internal();
@@ -20667,32 +19575,6 @@
// WARNING: Do not edit - generated code.
-/// @domName ScriptProcessorNode
-class ScriptProcessorNode extends AudioNode implements EventTarget {
- ScriptProcessorNode.internal(): super.internal();
-
- /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
- ScriptProcessorNodeEvents get on =>
- new ScriptProcessorNodeEvents(this);
-
-
- /** @domName ScriptProcessorNode.bufferSize */
- int get bufferSize native "ScriptProcessorNode_bufferSize_Getter";
-
-}
-
-class ScriptProcessorNodeEvents extends Events {
- ScriptProcessorNodeEvents(EventTarget _ptr) : super(_ptr);
-
- EventListenerList get audioProcess => this['audioprocess'];
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName ScriptProfile
class ScriptProfile extends NativeFieldWrapperClass1 {
ScriptProfile.internal();
@@ -20723,7 +19605,7 @@
/** @domName ScriptProfileNode.callUID */
- int get callUID native "ScriptProfileNode_callUID_Getter";
+ int get callUid native "ScriptProfileNode_callUID_Getter";
/** @domName ScriptProfileNode.functionName */
@@ -20941,6 +19823,7 @@
// WARNING: Do not edit - generated code.
+/// @domName ShadowRoot
class ShadowRoot extends DocumentFragment {
factory ShadowRoot(Element host) => _ShadowRootFactoryProvider.createShadowRoot(host);
@@ -20960,11 +19843,11 @@
/** @domName ShadowRoot.innerHTML */
- String get innerHTML native "ShadowRoot_innerHTML_Getter";
+ String get innerHtml native "ShadowRoot_innerHTML_Getter";
/** @domName ShadowRoot.innerHTML */
- void set innerHTML(String value) native "ShadowRoot_innerHTML_Setter";
+ void set innerHtml(String value) native "ShadowRoot_innerHTML_Setter";
/** @domName ShadowRoot.resetStyleInheritance */
@@ -21674,6 +20557,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName Storage
class Storage extends NativeFieldWrapperClass1 implements Map<String, String> {
// TODO(nweiz): update this when maps support lazy iteration
@@ -22460,6 +21344,7 @@
// WARNING: Do not edit - generated code.
+/// @domName Text
class Text extends CharacterData {
factory Text(String data) => _TextFactoryProvider.createText(data);
Text.internal(): super.internal();
@@ -22920,7 +21805,7 @@
/** @domName TextTrackCue.getCueAsHTML */
- DocumentFragment getCueAsHTML() native "TextTrackCue_getCueAsHTML_Callback";
+ DocumentFragment getCueAsHtml() native "TextTrackCue_getCueAsHTML_Callback";
/** @domName TextTrackCue.removeEventListener */
@@ -23603,13 +22488,25 @@
// WARNING: Do not edit - generated code.
-/// @domName UIEvent
+/// @domName UIEvent; @docsEditable true
class UIEvent extends Event {
+ // In JS, canBubble and cancelable are technically required parameters to
+ // init*Event. In practice, though, if they aren't provided they simply
+ // default to false (since that's Boolean(undefined)).
+ //
+ // Contrary to JS, we default canBubble and cancelable to true, since that's
+ // what people want most of the time anyway.
+ factory UIEvent(String type, Window view, int detail,
+ [bool canBubble = true, bool cancelable = true]) {
+ final e = document.$dom_createEvent("UIEvent");
+ e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
+ return e;
+ }
UIEvent.internal(): super.internal();
/** @domName UIEvent.charCode */
- int get charCode native "UIEvent_charCode_Getter";
+ int get $dom_charCode native "UIEvent_charCode_Getter";
/** @domName UIEvent.detail */
@@ -23617,7 +22514,7 @@
/** @domName UIEvent.keyCode */
- int get keyCode native "UIEvent_keyCode_Getter";
+ int get $dom_keyCode native "UIEvent_keyCode_Getter";
/** @domName UIEvent.layerX */
@@ -23645,7 +22542,7 @@
/** @domName UIEvent.initUIEvent */
- void initUIEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail) native "UIEvent_initUIEvent_Callback";
+ void $dom_initUIEvent(String type, bool canBubble, bool cancelable, LocalWindow view, int detail) native "UIEvent_initUIEvent_Callback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -24323,26 +23220,6 @@
// WARNING: Do not edit - generated code.
-/// @domName WaveShaperNode
-class WaveShaperNode extends AudioNode {
- WaveShaperNode.internal(): super.internal();
-
-
- /** @domName WaveShaperNode.curve */
- Float32Array get curve native "WaveShaperNode_curve_Getter";
-
-
- /** @domName WaveShaperNode.curve */
- void set curve(Float32Array value) native "WaveShaperNode_curve_Setter";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName WaveTable
class WaveTable extends NativeFieldWrapperClass1 {
WaveTable.internal();
@@ -26027,6 +24904,7 @@
// WARNING: Do not edit - generated code.
+/// @domName WebSocket
class WebSocket extends EventTarget {
factory WebSocket(String url) => _WebSocketFactoryProvider.createWebSocket(url);
WebSocket.internal(): super.internal();
@@ -26045,7 +24923,7 @@
/** @domName WebSocket.URL */
- String get URL native "WebSocket_URL_Getter";
+ String get Url native "WebSocket_URL_Getter";
/** @domName WebSocket.binaryType */
@@ -26133,6 +25011,7 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName WheelEvent
class WheelEvent extends MouseEvent {
WheelEvent.internal(): super.internal();
@@ -26290,11 +25169,11 @@
/** @domName WorkerContext.webkitResolveLocalFileSystemSyncURL */
- EntrySync webkitResolveLocalFileSystemSyncURL(String url) native "WorkerContext_webkitResolveLocalFileSystemSyncURL_Callback";
+ EntrySync webkitResolveLocalFileSystemSyncUrl(String url) native "WorkerContext_webkitResolveLocalFileSystemSyncURL_Callback";
/** @domName WorkerContext.webkitResolveLocalFileSystemURL */
- void webkitResolveLocalFileSystemURL(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "WorkerContext_webkitResolveLocalFileSystemURL_Callback";
+ void webkitResolveLocalFileSystemUrl(String url, EntryCallback successCallback, [ErrorCallback errorCallback]) native "WorkerContext_webkitResolveLocalFileSystemURL_Callback";
}
@@ -26488,7 +25367,7 @@
/** @domName XPathNSResolver.lookupNamespaceURI */
- String lookupNamespaceURI(String prefix) native "XPathNSResolver_lookupNamespaceURI_Callback";
+ String lookupNamespaceUri(String prefix) native "XPathNSResolver_lookupNamespaceURI_Callback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -26618,14 +25497,6 @@
// BSD-style license that can be found in the LICENSE file.
-class _AudioElementFactoryProvider {
- static AudioElement createAudioElement([String src]) native "HTMLAudioElement_constructor_Callback";
-}
-// 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.
-
-
class _BlobFactoryProvider {
static Blob createBlob(List blobParts, [String type, String endings]) native "Blob_constructor_Callback";
}
@@ -27134,11 +26005,11 @@
/** @domName HTMLElement.innerHTML */
- String get innerHTML native "HTMLElement_innerHTML_Getter";
+ String get innerHtml native "HTMLElement_innerHTML_Getter";
/** @domName HTMLElement.innerHTML */
- void set innerHTML(String value) native "HTMLElement_innerHTML_Setter";
+ void set innerHtml(String value) native "HTMLElement_innerHTML_Setter";
/** @domName HTMLElement.isContentEditable */
@@ -27154,7 +26025,7 @@
/** @domName HTMLElement.outerHTML */
- String get outerHTML native "HTMLElement_outerHTML_Getter";
+ String get outerHtml native "HTMLElement_outerHTML_Getter";
/** @domName HTMLElement.spellcheck */
@@ -27206,7 +26077,7 @@
/** @domName HTMLElement.insertAdjacentHTML */
- void insertAdjacentHTML(String where, String html) native "HTMLElement_insertAdjacentHTML_Callback";
+ void insertAdjacentHtml(String where, String html) native "HTMLElement_insertAdjacentHTML_Callback";
/** @domName HTMLElement.insertAdjacentText */
@@ -27839,111 +26710,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
-
-
-/// @domName NodeList
-class _NodeList extends NativeFieldWrapperClass1 implements List<Node> {
- _NodeList.internal();
-
-
- /** @domName NodeList.length */
- int get length native "NodeList_length_Getter";
-
- Node operator[](int index) native "NodeList_item_Callback";
-
- void operator[]=(int index, Node value) {
- throw new UnsupportedError("Cannot assign element of immutable List.");
- }
- // -- start List<Node> mixins.
- // Node is the element type.
-
- // From Iterable<Node>:
-
- Iterator<Node> iterator() {
- // Note: NodeLists are not fixed size. And most probably length shouldn't
- // be cached in both iterator _and_ forEach method. For now caching it
- // for consistency.
- return new FixedSizeListIterator<Node>(this);
- }
-
- // From Collection<Node>:
-
- void add(Node value) {
- throw new UnsupportedError("Cannot add to immutable List.");
- }
-
- void addLast(Node value) {
- throw new UnsupportedError("Cannot add to immutable List.");
- }
-
- void addAll(Collection<Node> collection) {
- throw new UnsupportedError("Cannot add to immutable List.");
- }
-
- bool contains(Node element) => _Collections.contains(this, element);
-
- void forEach(void f(Node element)) => _Collections.forEach(this, f);
-
- Collection map(f(Node element)) => _Collections.map(this, [], f);
-
- Collection<Node> filter(bool f(Node element)) =>
- _Collections.filter(this, <Node>[], f);
-
- bool every(bool f(Node element)) => _Collections.every(this, f);
-
- bool some(bool f(Node element)) => _Collections.some(this, f);
-
- bool get isEmpty => this.length == 0;
-
- // From List<Node>:
-
- void sort([Comparator<Node> compare = Comparable.compare]) {
- throw new UnsupportedError("Cannot sort immutable List.");
- }
-
- int indexOf(Node element, [int start = 0]) =>
- _Lists.indexOf(this, element, start, this.length);
-
- int lastIndexOf(Node element, [int start]) {
- if (start == null) start = length - 1;
- return _Lists.lastIndexOf(this, element, start);
- }
-
- Node get first => this[0];
-
- Node get last => this[length - 1];
-
- Node removeLast() {
- throw new UnsupportedError("Cannot removeLast on immutable List.");
- }
-
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
- throw new UnsupportedError("Cannot setRange on immutable List.");
- }
-
- void removeRange(int start, int rangeLength) {
- throw new UnsupportedError("Cannot removeRange on immutable List.");
- }
-
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
- }
-
- List<Node> getRange(int start, int rangeLength) =>
- _Lists.getRange(this, start, rangeLength, <Node>[]);
-
- // -- end List<Node> mixins.
-
-
- /** @domName NodeList.item */
- Node _item(int index) native "NodeList_item_Callback";
-
-}
-// 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.
-
class _NotificationFactoryProvider {
static Notification createNotification(String title, [Map options]) native "Notification_constructor_Callback";
@@ -28501,6 +27267,228 @@
// BSD-style license that can be found in the LICENSE file.
+abstract class _AttributeMap implements Map<String, String> {
+
+ bool containsValue(String value) {
+ for (var v in this.values) {
+ if (value == v) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) {
+ if (!containsKey(key)) {
+ this[key] = ifAbsent();
+ }
+ return this[key];
+ }
+
+ void clear() {
+ for (var key in keys) {
+ remove(key);
+ }
+ }
+
+ void forEach(void f(String key, String value)) {
+ for (var key in keys) {
+ var value = this[key];
+ f(key, value);
+ }
+ }
+
+ Collection<String> get keys {
+ // TODO: generate a lazy collection instead.
+ var attributes = _element.$dom_attributes;
+ var keys = new List<String>();
+ for (int i = 0, len = attributes.length; i < len; i++) {
+ if (_matches(attributes[i])) {
+ keys.add(attributes[i].$dom_localName);
+ }
+ }
+ return keys;
+ }
+
+ Collection<String> get values {
+ // TODO: generate a lazy collection instead.
+ var attributes = _element.$dom_attributes;
+ var values = new List<String>();
+ for (int i = 0, len = attributes.length; i < len; i++) {
+ if (_matches(attributes[i])) {
+ values.add(attributes[i].value);
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Returns true if there is no {key, value} pair in the map.
+ */
+ bool get isEmpty {
+ return length == 0;
+ }
+
+ /**
+ * Checks to see if the node should be included in this map.
+ */
+ bool _matches(Node node);
+}
+
+/**
+ * Wrapper to expose [Element.attributes] as a typed map.
+ */
+class _ElementAttributeMap extends _AttributeMap {
+
+ final Element _element;
+
+ _ElementAttributeMap(this._element);
+
+ bool containsKey(String key) {
+ return _element.$dom_hasAttribute(key);
+ }
+
+ String operator [](String key) {
+ return _element.$dom_getAttribute(key);
+ }
+
+ void operator []=(String key, value) {
+ _element.$dom_setAttribute(key, '$value');
+ }
+
+ String remove(String key) {
+ String value = _element.$dom_getAttribute(key);
+ _element.$dom_removeAttribute(key);
+ return value;
+ }
+
+ /**
+ * The number of {key, value} pairs in the map.
+ */
+ int get length {
+ return keys.length;
+ }
+
+ bool _matches(Node node) => node.$dom_namespaceUri == null;
+}
+
+/**
+ * Wrapper to expose namespaced attributes as a typed map.
+ */
+class _NamespacedAttributeMap extends _AttributeMap {
+
+ final Element _element;
+ final String _namespace;
+
+ _NamespacedAttributeMap(this._element, this._namespace);
+
+ bool containsKey(String key) {
+ return _element.$dom_hasAttributeNS(_namespace, key);
+ }
+
+ String operator [](String key) {
+ return _element.$dom_getAttributeNS(_namespace, key);
+ }
+
+ void operator []=(String key, value) {
+ _element.$dom_setAttributeNS(_namespace, key, '$value');
+ }
+
+ String remove(String key) {
+ String value = this[key];
+ _element.$dom_removeAttributeNS(_namespace, key);
+ return value;
+ }
+
+ /**
+ * The number of {key, value} pairs in the map.
+ */
+ int get length {
+ return keys.length;
+ }
+
+ bool _matches(Node node) => node.$dom_namespaceUri == _namespace;
+}
+
+
+/**
+ * Provides a Map abstraction on top of data-* attributes, similar to the
+ * dataSet in the old DOM.
+ */
+class _DataAttributeMap implements Map<String, String> {
+
+ final Map<String, String> $dom_attributes;
+
+ _DataAttributeMap(this.$dom_attributes);
+
+ // interface Map
+
+ // TODO: Use lazy iterator when it is available on Map.
+ bool containsValue(String value) => values.some((v) => v == value);
+
+ bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
+
+ String operator [](String key) => $dom_attributes[_attr(key)];
+
+ void operator []=(String key, value) {
+ $dom_attributes[_attr(key)] = '$value';
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) =>
+ $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
+
+ String remove(String key) => $dom_attributes.remove(_attr(key));
+
+ void clear() {
+ // Needs to operate on a snapshot since we are mutating the collection.
+ for (String key in keys) {
+ remove(key);
+ }
+ }
+
+ void forEach(void f(String key, String value)) {
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ f(_strip(key), value);
+ }
+ });
+ }
+
+ Collection<String> get keys {
+ final keys = new List<String>();
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ keys.add(_strip(key));
+ }
+ });
+ return keys;
+ }
+
+ Collection<String> get values {
+ final values = new List<String>();
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ values.add(value);
+ }
+ });
+ return values;
+ }
+
+ int get length => keys.length;
+
+ // TODO: Use lazy iterator when it is available on Map.
+ bool get isEmpty => length == 0;
+
+ // Helpers.
+ String _attr(String key) => 'data-$key';
+ bool _matches(String key) => key.startsWith('data-');
+ String _strip(String key) => key.substring(5);
+}
+// 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.
+
+
/**
* An object representing the top-level context object for web scripting.
*
@@ -28530,7 +27518,7 @@
History get history;
/**
- * Indicates whether this window is closed.
+ * Indicates whether this window has been closed.
*
* print(window.closed); // 'false'
* window.close();
@@ -28583,6 +27571,34 @@
Window get top;
// Methods.
+ /**
+ * Closes the window.
+ *
+ * This method should only succeed if the [Window] object is
+ * **script-closeable** and the window calling [close] is allowed to navigate
+ * the window.
+ *
+ * A window is script-closeable if it is either a window
+ * that was opened by another window, or if it is a window with only one
+ * document in its history.
+ *
+ * A window might not be allowed to navigate, and therefore close, another
+ * window due to browser security features.
+ *
+ * var other = window.open('http://www.example.com', 'foo');
+ * // Closes other window, as it is script-closeable.
+ * other.close();
+ * print(other.closed()); // 'true'
+ *
+ * window.location('http://www.mysite.com', 'foo');
+ * // Does not close this window, as the history has changed.
+ * window.close();
+ * print(window.closed()); // 'false'
+ *
+ * See also:
+ *
+ * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
+ */
void close();
void postMessage(var message, String targetOrigin, [List messagePorts = null]);
}
@@ -28837,6 +27853,410 @@
/**
+ * Works with KeyboardEvent and KeyEvent to determine how to expose information
+ * about Key(board)Events. This class functions like an EventListenerList, and
+ * provides a consistent interface for the Dart
+ * user, despite the fact that a multitude of browsers that have varying
+ * keyboard default behavior.
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyboardEventController {
+ // This code inspired by Closure's KeyHandling library.
+ // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+
+ /**
+ * The set of keys that have been pressed down without seeing their
+ * corresponding keyup event.
+ */
+ List<KeyboardEvent> _keyDownList;
+
+ /** The set of functions that wish to be notified when a KeyEvent happens. */
+ List<Function> _callbacks;
+
+ /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
+ String _type;
+
+ /** The element we are watching for events to happen on. */
+ EventTarget _target;
+
+ // The distance to shift from upper case alphabet Roman letters to lower case.
+ int _ROMAN_ALPHABET_OFFSET = "a".charCodes[0] - "A".charCodes[0];
+
+ // Instance members referring to the internal event handlers because closures
+ // are not hashable.
+ var _keyUp, _keyDown, _keyPress;
+
+ /**
+ * An enumeration of key identifiers currently part of the W3C draft for DOM3
+ * and their mappings to keyCodes.
+ * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+ */
+ static Map<String, int> _keyIdentifier = {
+ 'Up': KeyCode.UP,
+ 'Down': KeyCode.DOWN,
+ 'Left': KeyCode.LEFT,
+ 'Right': KeyCode.RIGHT,
+ 'Enter': KeyCode.ENTER,
+ 'F1': KeyCode.F1,
+ 'F2': KeyCode.F2,
+ 'F3': KeyCode.F3,
+ 'F4': KeyCode.F4,
+ 'F5': KeyCode.F5,
+ 'F6': KeyCode.F6,
+ 'F7': KeyCode.F7,
+ 'F8': KeyCode.F8,
+ 'F9': KeyCode.F9,
+ 'F10': KeyCode.F10,
+ 'F11': KeyCode.F11,
+ 'F12': KeyCode.F12,
+ 'U+007F': KeyCode.DELETE,
+ 'Home': KeyCode.HOME,
+ 'End': KeyCode.END,
+ 'PageUp': KeyCode.PAGE_UP,
+ 'PageDown': KeyCode.PAGE_DOWN,
+ 'Insert': KeyCode.INSERT
+ };
+
+ /** Named constructor to add an onKeyPress event listener to our handler. */
+ KeyboardEventController.keypress(EventTarget target) {
+ _KeyboardEventController(target, 'keypress');
+ }
+
+ /** Named constructor to add an onKeyUp event listener to our handler. */
+ KeyboardEventController.keyup(EventTarget target) {
+ _KeyboardEventController(target, 'keyup');
+ }
+
+ /** Named constructor to add an onKeyDown event listener to our handler. */
+ KeyboardEventController.keydown(EventTarget target) {
+ _KeyboardEventController(target, 'keydown');
+ }
+
+ /**
+ * General constructor, performs basic initialization for our improved
+ * KeyboardEvent controller.
+ */
+ _KeyboardEventController(EventTarget target, String type) {
+ _callbacks = [];
+ _type = type;
+ _target = target;
+ _keyDown = processKeyDown;
+ _keyUp = processKeyUp;
+ _keyPress = processKeyPress;
+ }
+
+ /**
+ * Hook up all event listeners under the covers so we can estimate keycodes
+ * and charcodes when they are not provided.
+ */
+ void _initializeAllEventListeners() {
+ _keyDownList = [];
+ _target.on.keyDown.add(_keyDown, true);
+ _target.on.keyPress.add(_keyPress, true);
+ _target.on.keyUp.add(_keyUp, true);
+ }
+
+ /** Add a callback that wishes to be notified when a KeyEvent occurs. */
+ void add(void callback(KeyEvent)) {
+ if (_callbacks.length == 0) {
+ _initializeAllEventListeners();
+ }
+ _callbacks.add(callback);
+ }
+
+ /**
+ * Notify all callback listeners that a KeyEvent of the relevant type has
+ * occurred.
+ */
+ bool _dispatch(KeyEvent event) {
+ if (event.type == _type) {
+ // Make a copy of the listeners in case a callback gets removed while
+ // dispatching from the list.
+ List callbacksCopy = new List.from(_callbacks);
+ for(var callback in callbacksCopy) {
+ callback(event);
+ }
+ }
+ }
+
+ /** Remove the given callback from the listeners list. */
+ void remove(void callback(KeyEvent)) {
+ var index = _callbacks.indexOf(callback);
+ if (index != -1) {
+ _callbacks.removeAt(index);
+ }
+ if (_callbacks.length == 0) {
+ // If we have no listeners, don't bother keeping track of keypresses.
+ _target.on.keyDown.remove(_keyDown);
+ _target.on.keyPress.remove(_keyPress);
+ _target.on.keyUp.remove(_keyUp);
+ }
+ }
+
+ /** Determine if caps lock is one of the currently depressed keys. */
+ bool get _capsLockOn =>
+ _keyDownList.some((var element) => element.keyCode == KeyCode.CAPS_LOCK);
+
+ /**
+ * Given the previously recorded keydown key codes, see if we can determine
+ * the keycode of this keypress [event]. (Generally browsers only provide
+ * charCode information for keypress events, but with a little
+ * reverse-engineering, we can also determine the keyCode.) Returns
+ * KeyCode.UNKNOWN if the keycode could not be determined.
+ */
+ int _determineKeyCodeForKeypress(KeyboardEvent event) {
+ // Note: This function is a work in progress. We'll expand this function
+ // once we get more information about other keyboards.
+ for (var prevEvent in _keyDownList) {
+ if (prevEvent._shadowCharCode == event.charCode) {
+ return prevEvent.keyCode;
+ }
+ if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".charCodes[0]
+ && event.charCode <= "Z".charCodes[0] && event.charCode +
+ _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
+ return prevEvent.keyCode;
+ }
+ }
+ return KeyCode.UNKNOWN;
+ }
+
+ /**
+ * Given the charater code returned from a keyDown [event], try to ascertain
+ * and return the corresponding charCode for the character that was pressed.
+ * This information is not shown to the user, but used to help polyfill
+ * keypress events.
+ */
+ int _findCharCodeKeyDown(KeyboardEvent event) {
+ if (event.keyLocation == 3) { // Numpad keys.
+ switch (event.keyCode) {
+ case KeyCode.NUM_ZERO:
+ // Even though this function returns _charCodes_, for some cases the
+ // KeyCode == the charCode we want, in which case we use the keycode
+ // constant for readability.
+ return KeyCode.ZERO;
+ case KeyCode.NUM_ONE:
+ return KeyCode.ONE;
+ case KeyCode.NUM_TWO:
+ return KeyCode.TWO;
+ case KeyCode.NUM_THREE:
+ return KeyCode.THREE;
+ case KeyCode.NUM_FOUR:
+ return KeyCode.FOUR;
+ case KeyCode.NUM_FIVE:
+ return KeyCode.FIVE;
+ case KeyCode.NUM_SIX:
+ return KeyCode.SIX;
+ case KeyCode.NUM_SEVEN:
+ return KeyCode.SEVEN;
+ case KeyCode.NUM_EIGHT:
+ return KeyCode.EIGHT;
+ case KeyCode.NUM_NINE:
+ return KeyCode.NINE;
+ case KeyCode.NUM_MULTIPLY:
+ return 42; // Char code for *
+ case KeyCode.NUM_PLUS:
+ return 43; // +
+ case KeyCode.NUM_MINUS:
+ return 45; // -
+ case KeyCode.NUM_PERIOD:
+ return 46; // .
+ case KeyCode.NUM_DIVISION:
+ return 47; // /
+ }
+ } else if (event.keyCode >= 65 && event.keyCode <= 90) {
+ // Set the "char code" for key down as the lower case letter. Again, this
+ // will not show up for the user, but will be helpful in estimating
+ // keyCode locations and other information during the keyPress event.
+ return event.keyCode + _ROMAN_ALPHABET_OFFSET;
+ }
+ switch(event.keyCode) {
+ case KeyCode.SEMICOLON:
+ return KeyCode.FF_SEMICOLON;
+ case KeyCode.EQUALS:
+ return KeyCode.FF_EQUALS;
+ case KeyCode.COMMA:
+ return 44; // Ascii value for ,
+ case KeyCode.DASH:
+ return 45; // -
+ case KeyCode.PERIOD:
+ return 46; // .
+ case KeyCode.SLASH:
+ return 47; // /
+ case KeyCode.APOSTROPHE:
+ return 96; // `
+ case KeyCode.OPEN_SQUARE_BRACKET:
+ return 91; // [
+ case KeyCode.BACKSLASH:
+ return 92; // \
+ case KeyCode.CLOSE_SQUARE_BRACKET:
+ return 93; // ]
+ case KeyCode.SINGLE_QUOTE:
+ return 39; // '
+ }
+ return event.keyCode;
+ }
+
+ /**
+ * Returns true if the key fires a keypress event in the current browser.
+ */
+ bool _firesKeyPressEvent(KeyEvent event) {
+ if (!_Device.isIE && !_Device.isWebKit) {
+ return true;
+ }
+
+ if (_Device.userAgent.contains('Mac') && event.altKey) {
+ return KeyCode.isCharacterKey(event.keyCode);
+ }
+
+ // Alt but not AltGr which is represented as Alt+Ctrl.
+ if (event.altKey && !event.ctrlKey) {
+ return false;
+ }
+
+ // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
+ if (!event.shiftKey &&
+ (_keyDownList.last.keyCode == KeyCode.CTRL ||
+ _keyDownList.last.keyCode == KeyCode.ALT ||
+ _Device.userAgent.contains('Mac') &&
+ _keyDownList.last.keyCode == KeyCode.META)) {
+ return false;
+ }
+
+ // Some keys with Ctrl/Shift do not issue keypress in WebKit.
+ if (_Device.isWebKit && event.ctrlKey && event.shiftKey && (
+ event.keycode == KeyCode.BACKSLASH ||
+ event.keycode == KeyCode.OPEN_SQUARE_BRACKET ||
+ event.keycode == KeyCode.CLOSE_SQUARE_BRACKET ||
+ event.keycode == KeyCode.TILDE ||
+ event.keycode == KeyCode.SEMICOLON || event.keycode == KeyCode.DASH ||
+ event.keycode == KeyCode.EQUALS || event.keycode == KeyCode.COMMA ||
+ event.keycode == KeyCode.PERIOD || event.keycode == KeyCode.SLASH ||
+ event.keycode == KeyCode.APOSTROPHE ||
+ event.keycode == KeyCode.SINGLE_QUOTE)) {
+ return false;
+ }
+
+ switch (event.keyCode) {
+ case KeyCode.ENTER:
+ // IE9 does not fire keypress on ENTER.
+ return !_Device.isIE;
+ case KeyCode.ESC:
+ return !_Device.isWebKit;
+ }
+
+ return KeyCode.isCharacterKey(event.keyCode);
+ }
+
+ /**
+ * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
+ * Opera all use).
+ */
+ int _normalizeKeyCodes(KeyboardEvent event) {
+ // Note: This may change once we get input about non-US keyboards.
+ if (_Device.isFirefox) {
+ switch(event.keyCode) {
+ case KeyCode.FF_EQUALS:
+ return KeyCode.EQUALS;
+ case KeyCode.FF_SEMICOLON:
+ return KeyCode.SEMICOLON;
+ case KeyCode.MAC_FF_META:
+ return KeyCode.META;
+ case KeyCode.WIN_KEY_FF_LINUX:
+ return KeyCode.WIN_KEY;
+ }
+ }
+ return event.keyCode;
+ }
+
+ /** Handle keydown events. */
+ void processKeyDown(KeyboardEvent e) {
+ // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+ // before we've caught a key-up event. If the last-key was one of these
+ // we reset the state.
+ if (_keyDownList.length > 0 &&
+ (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
+ _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
+ _Device.userAgent.contains('Mac') &&
+ _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
+ _keyDownList = [];
+ }
+
+ var event = new KeyEvent(e);
+ event._shadowKeyCode = _normalizeKeyCodes(event);
+ // Technically a "keydown" event doesn't have a charCode. This is
+ // calculated nonetheless to provide us with more information in giving
+ // as much information as possible on keypress about keycode and also
+ // charCode.
+ event._shadowCharCode = _findCharCodeKeyDown(event);
+ if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
+ !_firesKeyPressEvent(event)) {
+ // Some browsers have quirks not firing keypress events where all other
+ // browsers do. This makes them more consistent.
+ processKeyPress(event);
+ }
+ _keyDownList.add(event);
+ _dispatch(event);
+ }
+
+ /** Handle keypress events. */
+ void processKeyPress(KeyboardEvent event) {
+ var e = new KeyEvent(event);
+ // IE reports the character code in the keyCode field for keypress events.
+ // There are two exceptions however, Enter and Escape.
+ if (_Device.isIE) {
+ if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
+ e._shadowCharCode = 0;
+ } else {
+ e._shadowCharCode = e.keyCode;
+ }
+ } else if (_Device.isOpera) {
+ // Opera reports the character code in the keyCode field.
+ e._shadowCharCode = KeyCode.isCharacterKey(keyCode) ? e.keyCode : 0;
+ }
+ // Now we guestimate about what the keycode is that was actually
+ // pressed, given previous keydown information.
+ e._shadowKeyCode = _determineKeyCodeForKeypress(e);
+
+ // Correct the key value for certain browser-specific quirks.
+ if (e._shadowKeyIdentifier &&
+ _keyIdentifier.contains(e._shadowKeyIdentifier)) {
+ // This is needed for Safari Windows because it currently doesn't give a
+ // keyCode/which for non printable keys.
+ e._shadowKeyCode = _keyIdentifier[keyIdentifier];
+ }
+ e._shadowAltKey = _keyDownList.some((var element) => element.altKey);
+ _dispatch(e);
+ }
+
+ /** Handle keyup events. */
+ void processKeyUp(KeyboardEvent event) {
+ var e = new KeyEvent(event);
+ KeyboardEvent toRemove = null;
+ for (var key in _keyDownList) {
+ if (key.keyCode == e.keyCode) {
+ toRemove = key;
+ }
+ }
+ if (toRemove != null) {
+ _keyDownList = _keyDownList.filter((element) => element != toRemove);
+ } else if (_keyDownList.length > 0) {
+ // This happens when we've reached some international keyboard case we
+ // haven't accounted for or we haven't correctly eliminated all browser
+ // inconsistencies. Filing bugs on when this is reached is welcome!
+ _keyDownList.removeLast();
+ }
+ _dispatch(e);
+ }
+}
+// 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.
+
+
+/**
* Defines the keycode values for keys that are returned by
* KeyboardEvent.keyCode.
*
@@ -29027,6 +28447,36 @@
static const int WIN_KEY = 224;
static const int MAC_FF_META = 224;
static const int WIN_IME = 229;
+
+ /** A sentinel value if the keycode could not be determined. */
+ static const int UNKNOWN = -1;
+
+ /**
+ * Returns true if the keyCode produces a (US keyboard) character.
+ * Note: This does not (yet) cover characters on non-US keyboards (Russian,
+ * Hebrew, etc.).
+ */
+ static bool isCharacterKey(int keyCode) {
+ if ((keyCode >= ZERO && keyCode <= NINE) ||
+ (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
+ (keyCode >= A && keyCode <= Z)) {
+ return true;
+ }
+
+ // Safari sends zero key code for non-latin characters.
+ if (_Device.isWebKit && keyCode == 0) {
+ return true;
+ }
+
+ return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
+ || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
+ keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
+ keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
+ keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
+ keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
+ keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
+ keyCode == CLOSE_SQUARE_BRACKET);
+ }
}
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -29767,7 +29217,7 @@
static DocumentFragment createDocumentFragment_html(String html) {
final fragment = new DocumentFragment();
- fragment.innerHTML = html;
+ fragment.innerHtml = html;
return fragment;
}
@@ -29775,7 +29225,7 @@
// factory DocumentFragment.xml(String xml) {
// final fragment = new DocumentFragment();
// final e = new XMLElement.tag("xml");
- // e.innerHTML = xml;
+ // e.innerHtml = xml;
//
// // Copy list first since we don't want liveness during iteration.
// final List nodes = new List.from(e.nodes);
@@ -29786,7 +29236,7 @@
static DocumentFragment createDocumentFragment_svg(String svgContent) {
final fragment = new DocumentFragment();
final e = new svg.SVGSVGElement();
- e.innerHTML = svgContent;
+ e.innerHtml = svgContent;
// Copy list first since we don't want liveness during iteration.
final List nodes = new List.from(e.nodes);
@@ -29794,19 +29244,114 @@
return fragment;
}
}
+/**
+ * A custom KeyboardEvent that attempts to eliminate cross-browser
+ * inconsistencies, and also provide both keyCode and charCode information
+ * for all key events (when such information can be determined).
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyEvent implements KeyboardEvent {
+ /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
+ KeyboardEvent _parent;
+
+ /** The "fixed" value of whether the alt key is being pressed. */
+ bool _shadowAltKey;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int _shadowCharCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int _shadowKeyCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get keyCode => _shadowKeyCode;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
+
+ /** Caculated value of whether the alt key is pressed is for this event. */
+ bool get altKey => _shadowAltKey;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get which => keyCode;
+
+ /** Accessor to the underlying keyCode value is the parent event. */
+ int get _realKeyCode => _parent.keyCode;
+
+ /** Accessor to the underlying charCode value is the parent event. */
+ int get _realCharCode => _parent.charCode;
+
+ /** Accessor to the underlying altKey value is the parent event. */
+ bool get _realAltKey => _parent.altKey;
+
+ /** Construct a KeyEvent with [parent] as event we're emulating. */
+ KeyEvent(KeyboardEvent parent) {
+ _parent = parent;
+ _shadowAltKey = _realAltKey;
+ _shadowCharCode = _realCharCode;
+ _shadowKeyCode = _realKeyCode;
+ }
+
+ /** True if the altGraphKey is pressed during this event. */
+ bool get altGraphKey => _parent.altGraphKey;
+ bool get bubbles => _parent.bubbles;
+ /** True if this event can be cancelled. */
+ bool get cancelable => _parent.cancelable;
+ bool get cancelBubble => _parent.cancelBubble;
+ set cancelBubble(bool cancel) => _parent = cancel;
+ /** Accessor to the clipboardData available for this event. */
+ Clipboard get clipboardData => _parent.clipboardData;
+ /** True if the ctrl key is pressed during this event. */
+ bool get ctrlKey => _parent.ctrlKey;
+ /** Accessor to the target this event is listening to for changes. */
+ EventTarget get currentTarget => _parent.currentTarget;
+ bool get defaultPrevented => _parent.defaultPrevented;
+ int get detail => _parent.detail;
+ int get eventPhase => _parent.eventPhase;
+ /**
+ * Accessor to the part of the keyboard that the key was pressed from (one of
+ * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
+ * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
+ */
+ int get keyLocation => _parent.keyLocation;
+ int get layerX => _parent.layerX;
+ int get layerY => _parent.layerY;
+ /** True if the Meta (or Mac command) key is pressed during this event. */
+ bool get metaKey => _parent.metaKey;
+ int get pageX => _parent.pageX;
+ int get pageY => _parent.pageY;
+ bool get returnValue => _parent.returnValue;
+ set returnValue(bool value) => _parent = value;
+ /** True if the shift key was pressed during this event. */
+ bool get shiftKey => _parent.shiftKey;
+ int get timeStamp => _parent.timeStamp;
+ /**
+ * The type of key event that occurred. One of "keydown", "keyup", or
+ * "keypress".
+ */
+ String get type => _parent.type;
+ Window get view => _parent.view;
+ void preventDefault() => _parent.preventDefault();
+ void stopImmediatePropagation() => _parent.stopImmediatePropagation();
+ void stopPropagation() => _parent.stopPropagation();
+ void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, int detail) {
+ throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
+ }
+ void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
+ bool cancelableArg) {
+ throw new UnsupportedError("Cannot initialize an Event from a KeyEvent.");
+ }
+ String get _shadowKeyIdentifier => _parent.$dom_keyIdentifier;
+}
// 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.
-class _AudioContextFactoryProvider {
- static AudioContext createAudioContext() => _createAudioContext();
- static _createAudioContext([int numberOfChannels,
- int numberOfFrames,
- int sampleRate])
- native "AudioContext_constructor_Callback";
-}
-
class _IDBKeyRangeFactoryProvider {
static IDBKeyRange createIDBKeyRange_only(/*IDBKey*/ value) =>
@@ -30774,13 +30319,13 @@
_DOMWindowCrossFrame.internal();
// Fields.
- History get history() native "DOMWindow_history_cross_frame_Getter";
- Location get location() native "DOMWindow_location_cross_frame_Getter";
- bool get closed() native "DOMWindow_closed_Getter";
- int get length() native "DOMWindow_length_Getter";
- Window get opener() native "DOMWindow_opener_Getter";
- Window get parent() native "DOMWindow_parent_Getter";
- Window get top() native "DOMWindow_top_Getter";
+ History get history native "DOMWindow_history_cross_frame_Getter";
+ Location get location native "DOMWindow_location_cross_frame_Getter";
+ bool get closed native "DOMWindow_closed_Getter";
+ int get length native "DOMWindow_length_Getter";
+ Window get opener native "DOMWindow_opener_Getter";
+ Window get parent native "DOMWindow_parent_Getter";
+ Window get top native "DOMWindow_top_Getter";
// Methods.
void close() native "DOMWindow_close_Callback";
diff --git a/sdk/lib/html/docs/html_docs.json b/sdk/lib/html/docs/html_docs.json
new file mode 100644
index 0000000..6ab4273
--- /dev/null
+++ b/sdk/lib/html/docs/html_docs.json
@@ -0,0 +1,1657 @@
+{
+"MenuElement.dart":
+ {
+ "class MenuElement extends Element implements Element native \"*HTMLMenuElement\" {":
+ [
+ "/**",
+ " * An HTML <menu> element.",
+ " *",
+ " * A <menu> element represents an unordered list of menu commands.",
+ " *",
+ " * See also:",
+ " *",
+ " * * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.",
+ " * * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.",
+ " */"
+ ]
+ },
+"RTCIceCandidateEvent.dart":
+ {
+
+ },
+"BRElement.dart":
+ {
+
+ },
+"NavigatorUserMediaError.dart":
+ {
+
+ },
+"WorkerContext.dart":
+ {
+
+ },
+"TextTrackCue.dart":
+ {
+
+ },
+"DOMParser.dart":
+ {
+
+ },
+"EntryCallback.dart":
+ {
+
+ },
+"SQLTransactionSync.dart":
+ {
+
+ },
+"ProgressElement.dart":
+ {
+
+ },
+"HtmlElement.dart":
+ {
+
+ },
+"Worker.dart":
+ {
+
+ },
+"XMLSerializer.dart":
+ {
+
+ },
+"PositionErrorCallback.dart":
+ {
+
+ },
+"MapElement.dart":
+ {
+
+ },
+"Rect.dart":
+ {
+
+ },
+"SourceElement.dart":
+ {
+
+ },
+"FileWriter.dart":
+ {
+
+ },
+"CSSMatrix.dart":
+ {
+
+ },
+"Metadata.dart":
+ {
+
+ },
+"StorageInfoUsageCallback.dart":
+ {
+
+ },
+"WebGLDebugShaders.dart":
+ {
+
+ },
+"WebGLShaderPrecisionFormat.dart":
+ {
+
+ },
+"NodeFilter.dart":
+ {
+
+ },
+"Float64Array.dart":
+ {
+
+ },
+"BodyElement.dart":
+ {
+
+ },
+"OESElementIndexUint.dart":
+ {
+
+ },
+"WebGLLoseContext.dart":
+ {
+
+ },
+"TableElement.dart":
+ {
+
+ },
+"ScriptElement.dart":
+ {
+
+ },
+"WebGLCompressedTextureS3TC.dart":
+ {
+
+ },
+"CharacterData.dart":
+ {
+
+ },
+"OESStandardDerivatives.dart":
+ {
+
+ },
+"IDBUpgradeNeededEvent.dart":
+ {
+
+ },
+"RTCIceCandidate.dart":
+ {
+
+ },
+"IDBKeyRange.dart":
+ {
+
+ },
+"XPathException.dart":
+ {
+
+ },
+"MediaError.dart":
+ {
+
+ },
+"SQLException.dart":
+ {
+
+ },
+"WorkerLocation.dart":
+ {
+
+ },
+"ClientRect.dart":
+ {
+
+ },
+"MediaController.dart":
+ {
+
+ },
+"CustomEvent.dart":
+ {
+
+ },
+"IDBVersionChangeEvent.dart":
+ {
+
+ },
+"StorageEvent.dart":
+ {
+
+ },
+"EntityReference.dart":
+ {
+
+ },
+"FileException.dart":
+ {
+
+ },
+"Notation.dart":
+ {
+
+ },
+"HTMLCollection.dart":
+ {
+
+ },
+"Int8Array.dart":
+ {
+
+ },
+"BaseFontElement.dart":
+ {
+
+ },
+"CSSPageRule.dart":
+ {
+
+ },
+"FileEntry.dart":
+ {
+
+ },
+"UListElement.dart":
+ {
+
+ },
+"HRElement.dart":
+ {
+
+ },
+"LocalHistory.dart":
+ {
+
+ },
+"WebGLRenderbuffer.dart":
+ {
+
+ },
+"StorageInfoErrorCallback.dart":
+ {
+
+ },
+"TimeRanges.dart":
+ {
+
+ },
+"CanvasRenderingContext.dart":
+ {
+
+ },
+"IDBOpenDBRequest.dart":
+ {
+
+ },
+"TableSectionElement.dart":
+ {
+
+ },
+"Point.dart":
+ {
+
+ },
+"OESTextureFloat.dart":
+ {
+
+ },
+"Uint8ClampedArray.dart":
+ {
+
+ },
+"TransitionEvent.dart":
+ {
+
+ },
+"WebGLActiveInfo.dart":
+ {
+
+ },
+"SharedWorkerContext.dart":
+ {
+
+ },
+"HttpRequestProgressEvent.dart":
+ {
+
+ },
+"Comment.dart":
+ {
+
+ },
+"BaseElement.dart":
+ {
+
+ },
+"CloseEvent.dart":
+ {
+
+ },
+"DOMPluginArray.dart":
+ {
+
+ },
+"PopStateEvent.dart":
+ {
+
+ },
+"RGBColor.dart":
+ {
+
+ },
+"DOMSettableTokenList.dart":
+ {
+
+ },
+"Geolocation.dart":
+ {
+
+ },
+"DataTransferItem.dart":
+ {
+
+ },
+"DOMError.dart":
+ {
+
+ },
+"FormData.dart":
+ {
+
+ },
+"SQLTransactionErrorCallback.dart":
+ {
+
+ },
+"OverflowEvent.dart":
+ {
+
+ },
+"AnimationEvent.dart":
+ {
+
+ },
+"FontElement.dart":
+ {
+
+ },
+"ScriptProfileNode.dart":
+ {
+
+ },
+"SpeechRecognition.dart":
+ {
+
+ },
+"WebGLContextEvent.dart":
+ {
+
+ },
+"SpeechRecognitionEvent.dart":
+ {
+
+ },
+"RadioNodeList.dart":
+ {
+
+ },
+"BatteryManager.dart":
+ {
+
+ },
+"SelectElement.dart":
+ {
+
+ },
+"EventException.dart":
+ {
+
+ },
+"DOMImplementation.dart":
+ {
+
+ },
+"WebGLFramebuffer.dart":
+ {
+
+ },
+"Navigator.dart":
+ {
+
+ },
+"WebGLShader.dart":
+ {
+
+ },
+"IceCandidate.dart":
+ {
+
+ },
+"WebSocket.dart":
+ {
+
+ },
+"RequestAnimationFrameCallback.dart":
+ {
+
+ },
+"RTCStatsElement.dart":
+ {
+
+ },
+"HeadElement.dart":
+ {
+
+ },
+"CanvasRenderingContext2D.dart":
+ {
+
+ },
+"IDBKey.dart":
+ {
+
+ },
+"ElementTraversal.dart":
+ {
+
+ },
+"Float32Array.dart":
+ {
+
+ },
+"RTCSessionDescription.dart":
+ {
+
+ },
+"DOMTokenList.dart":
+ {
+
+ },
+"RTCStatsCallback.dart":
+ {
+
+ },
+"FrameSetElement.dart":
+ {
+
+ },
+"IDBIndex.dart":
+ {
+
+ },
+"EventSource.dart":
+ {
+
+ },
+"MediaStreamAudioSourceNode.dart":
+ {
+
+ },
+"DeviceOrientationEvent.dart":
+ {
+
+ },
+"DOMFileSystem.dart":
+ {
+
+ },
+"SpeechInputResult.dart":
+ {
+
+ },
+"DataView.dart":
+ {
+
+ },
+"LocalLocation.dart":
+ {
+
+ },
+"AnchorElement.dart":
+ {
+
+ },
+"HtmlDocument.dart":
+ {
+
+ },
+"ImageData.dart":
+ {
+
+ },
+"PageTransitionEvent.dart":
+ {
+
+ },
+"AudioGain.dart":
+ {
+
+ },
+"PannerNode.dart":
+ {
+
+ },
+"UIEvent.dart":
+ {
+
+ },
+"SourceBuffer.dart":
+ {
+
+ },
+"CSSPrimitiveValue.dart":
+ {
+
+ },
+"MediaQueryList.dart":
+ {
+
+ },
+"TableCellElement.dart":
+ {
+
+ },
+"ScriptProcessorNode.dart":
+ {
+
+ },
+"ShadowRoot.dart":
+ {
+
+ },
+"MeterElement.dart":
+ {
+
+ },
+"WebKitNamedFlow.dart":
+ {
+
+ },
+"HashChangeEvent.dart":
+ {
+
+ },
+"WebGLBuffer.dart":
+ {
+
+ },
+"TouchEvent.dart":
+ {
+
+ },
+"LegendElement.dart":
+ {
+
+ },
+"CDATASection.dart":
+ {
+
+ },
+"HttpRequestUpload.dart":
+ {
+
+ },
+"Uint8Array.dart":
+ {
+
+ },
+"StyleSheet.dart":
+ {
+
+ },
+"DataTransferItemList.dart":
+ {
+
+ },
+"RTCErrorCallback.dart":
+ {
+
+ },
+"IDBDatabase.dart":
+ {
+
+ },
+"AppletElement.dart":
+ {
+
+ },
+"TextTrackList.dart":
+ {
+
+ },
+"NodeIterator.dart":
+ {
+
+ },
+"DynamicsCompressorNode.dart":
+ {
+
+ },
+"TextMetrics.dart":
+ {
+
+ },
+"Database.dart":
+ {
+
+ },
+"OfflineAudioCompletionEvent.dart":
+ {
+
+ },
+"SQLTransaction.dart":
+ {
+
+ },
+"TableRowElement.dart":
+ {
+
+ },
+"MediaStream.dart":
+ {
+
+ },
+"MetadataCallback.dart":
+ {
+
+ },
+"TreeWalker.dart":
+ {
+
+ },
+"IDBTransaction.dart":
+ {
+
+ },
+"WebGLContextAttributes.dart":
+ {
+
+ },
+"FileEntrySync.dart":
+ {
+
+ },
+"ProgressEvent.dart":
+ {
+
+ },
+"OscillatorNode.dart":
+ {
+
+ },
+"CSSKeyframesRule.dart":
+ {
+
+ },
+"ConvolverNode.dart":
+ {
+
+ },
+"MouseEvent.dart":
+ {
+
+ },
+"Notification.dart":
+ {
+
+ },
+"ChannelSplitterNode.dart":
+ {
+
+ },
+"DirectoryReaderSync.dart":
+ {
+
+ },
+"MemoryInfo.dart":
+ {
+
+ },
+"CSSCharsetRule.dart":
+ {
+
+ },
+"RTCStatsResponse.dart":
+ {
+
+ },
+"SQLError.dart":
+ {
+
+ },
+"EntriesCallback.dart":
+ {
+
+ },
+"CanvasPattern.dart":
+ {
+
+ },
+"WebGLUniformLocation.dart":
+ {
+
+ },
+"NotificationCenter.dart":
+ {
+
+ },
+"WorkerNavigator.dart":
+ {
+
+ },
+"MarqueeElement.dart":
+ {
+
+ },
+"EXTTextureFilterAnisotropic.dart":
+ {
+
+ },
+"WebGLVertexArrayObjectOES.dart":
+ {
+
+ },
+"InputElement.dart":
+ {
+
+ },
+"ImageElement.dart":
+ {
+
+ },
+"WebGLDebugRendererInfo.dart":
+ {
+
+ },
+"SpeechRecognitionError.dart":
+ {
+
+ },
+"XPathResult.dart":
+ {
+
+ },
+"ErrorEvent.dart":
+ {
+
+ },
+"FileWriterCallback.dart":
+ {
+
+ },
+"ArrayBuffer.dart":
+ {
+
+ },
+"MessagePort.dart":
+ {
+
+ },
+"CSSKeyframeRule.dart":
+ {
+
+ },
+"NavigatorUserMediaErrorCallback.dart":
+ {
+
+ },
+"TextTrackCueList.dart":
+ {
+
+ },
+"PositionError.dart":
+ {
+
+ },
+"File.dart":
+ {
+
+ },
+"LinkElement.dart":
+ {
+
+ },
+"DeviceMotionEvent.dart":
+ {
+
+ },
+"KeygenElement.dart":
+ {
+
+ },
+"VoidCallback.dart":
+ {
+
+ },
+"ShadowElement.dart":
+ {
+
+ },
+"NotificationPermissionCallback.dart":
+ {
+
+ },
+"WebKitCSSFilterValue.dart":
+ {
+
+ },
+"CompositionEvent.dart":
+ {
+
+ },
+"LocalMediaStream.dart":
+ {
+
+ },
+"RTCSessionDescriptionCallback.dart":
+ {
+
+ },
+"HeadingElement.dart":
+ {
+
+ },
+"ScriptProfile.dart":
+ {
+
+ },
+"DOMMimeType.dart":
+ {
+
+ },
+"MutationObserver.dart":
+ {
+
+ },
+"MetaElement.dart":
+ {
+
+ },
+"SpeechRecognitionResult.dart":
+ {
+
+ },
+"FrameElement.dart":
+ {
+
+ },
+"TitleElement.dart":
+ {
+
+ },
+"Uint16Array.dart":
+ {
+
+ },
+"AudioBufferCallback.dart":
+ {
+
+ },
+"IDBCursorWithValue.dart":
+ {
+
+ },
+"HttpRequest.dart":
+ {
+
+ },
+"MediaStreamTrackList.dart":
+ {
+
+ },
+"MediaStreamEvent.dart":
+ {
+
+ },
+"IFrameElement.dart":
+ {
+
+ },
+"ParagraphElement.dart":
+ {
+
+ },
+"CSSRule.dart":
+ {
+
+ },
+"QuoteElement.dart":
+ {
+
+ },
+"AudioDestinationNode.dart":
+ {
+
+ },
+"DListElement.dart":
+ {
+
+ },
+"RTCDataChannelEvent.dart":
+ {
+
+ },
+"TableCaptionElement.dart":
+ {
+
+ },
+"SpanElement.dart":
+ {
+
+ },
+"DirectoryEntry.dart":
+ {
+
+ },
+"MediaStreamTrackEvent.dart":
+ {
+
+ },
+"OutputElement.dart":
+ {
+
+ },
+"WheelEvent.dart":
+ {
+
+ },
+"SpeechGrammarList.dart":
+ {
+
+ },
+"PositionCallback.dart":
+ {
+
+ },
+"BarInfo.dart":
+ {
+
+ },
+"FileWriterSync.dart":
+ {
+
+ },
+"AudioListener.dart":
+ {
+
+ },
+"SQLStatementErrorCallback.dart":
+ {
+
+ },
+"BeforeLoadEvent.dart":
+ {
+
+ },
+"CSSMediaRule.dart":
+ {
+
+ },
+"MediaStreamTrack.dart":
+ {
+
+ },
+"XPathEvaluator.dart":
+ {
+
+ },
+"AreaElement.dart":
+ {
+
+ },
+"Node.dart":
+ {
+
+ },
+"IDBAny.dart":
+ {
+
+ },
+"BiquadFilterNode.dart":
+ {
+
+ },
+"DOMPlugin.dart":
+ {
+
+ },
+"DatabaseSync.dart":
+ {
+
+ },
+"CSSStyleSheet.dart":
+ {
+
+ },
+"DocumentType.dart":
+ {
+
+ },
+"Uint32Array.dart":
+ {
+
+ },
+"EmbedElement.dart":
+ {
+
+ },
+"Int32Array.dart":
+ {
+
+ },
+"PerformanceNavigation.dart":
+ {
+
+ },
+"MutationCallback.dart":
+ {
+
+ },
+"WebGLRenderingContext.dart":
+ {
+
+ },
+"SpeechInputEvent.dart":
+ {
+
+ },
+"IceCallback.dart":
+ {
+
+ },
+"RangeException.dart":
+ {
+
+ },
+"DirectoryReader.dart":
+ {
+
+ },
+"UnknownElement.dart":
+ {
+
+ },
+"ErrorCallback.dart":
+ {
+
+ },
+"CanvasGradient.dart":
+ {
+
+ },
+"SQLTransactionCallback.dart":
+ {
+
+ },
+"Coordinates.dart":
+ {
+
+ },
+"JavaScriptCallFrame.dart":
+ {
+
+ },
+"StyleMedia.dart":
+ {
+
+ },
+"IDBDatabaseException.dart":
+ {
+
+ },
+"ArrayBufferView.dart":
+ {
+
+ },
+"Console.dart":
+ {
+
+ },
+"CanvasElement.dart":
+ {
+
+ },
+"RTCDataChannel.dart":
+ {
+
+ },
+"Int16Array.dart":
+ {
+
+ },
+"KeyboardEvent.dart":
+ {
+
+ },
+"FileSystemCallback.dart":
+ {
+
+ },
+"StorageInfoQuotaCallback.dart":
+ {
+
+ },
+"Screen.dart":
+ {
+
+ },
+"SessionDescription.dart":
+ {
+
+ },
+"Range.dart":
+ {
+
+ },
+"VideoElement.dart":
+ {
+
+ },
+"DirectoryElement.dart":
+ {
+
+ },
+"ModElement.dart":
+ {
+
+ },
+"Animation.dart":
+ {
+
+ },
+"WebGLProgram.dart":
+ {
+
+ },
+"Gamepad.dart":
+ {
+
+ },
+"Clipboard.dart":
+ {
+
+ },
+"Storage.dart":
+ {
+
+ },
+"LocalWindow.dart":
+ {
+
+ },
+"MediaQueryListListener.dart":
+ {
+
+ },
+"TextAreaElement.dart":
+ {
+
+ },
+"DOMApplicationCache.dart":
+ {
+
+ },
+"ParamElement.dart":
+ {
+
+ },
+"HTMLOptionsCollection.dart":
+ {
+
+ },
+"MessageEvent.dart":
+ {
+
+ },
+"AbstractWorker.dart":
+ {
+
+ },
+"OListElement.dart":
+ {
+
+ },
+"FileReader.dart":
+ {
+
+ },
+"Blob.dart":
+ {
+
+ },
+"NamedNodeMap.dart":
+ {
+
+ },
+"DataListElement.dart":
+ {
+
+ },
+"CSSImportRule.dart":
+ {
+
+ },
+"AudioParam.dart":
+ {
+
+ },
+"DOMException.dart":
+ {
+
+ },
+"ObjectElement.dart":
+ {
+
+ },
+"CSSStyleRule.dart":
+ {
+
+ },
+"TouchList.dart":
+ {
+
+ },
+"MediaElementAudioSourceNode.dart":
+ {
+
+ },
+"CSSValue.dart":
+ {
+
+ },
+"Geoposition.dart":
+ {
+
+ },
+"MediaKeyEvent.dart":
+ {
+
+ },
+"MutationRecord.dart":
+ {
+
+ },
+"CSSTransformValue.dart":
+ {
+
+ },
+"FileError.dart":
+ {
+
+ },
+"Performance.dart":
+ {
+
+ },
+"DivElement.dart":
+ {
+ "class DivElement extends Element implements Element native \"*HTMLDivElement\" {":
+ [
+ "/**",
+ " * Represents an HTML <div> element.",
+ " *",
+ " * The [DivElement] is a generic container for content and does not have any",
+ " * special significance. It is functionally similar to [SpanElement].",
+ " *",
+ " * The [DivElement] is a block-level element, as opposed to [SpanElement],",
+ " * which is an inline-level element.",
+ " *",
+ " * Example usage:",
+ " *",
+ " * DivElement div = new DivElement();",
+ " * div.text = 'Here's my new DivElem",
+ " * document.body.elements.add(elem);",
+ " *",
+ " * See also:",
+ " *",
+ " * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.",
+ " * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.",
+ " * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.",
+ " */"
+ ]
+ },
+"AnalyserNode.dart":
+ {
+
+ },
+"AudioBuffer.dart":
+ {
+
+ },
+"SQLTransactionSyncCallback.dart":
+ {
+
+ },
+"StorageInfo.dart":
+ {
+
+ },
+"GainNode.dart":
+ {
+
+ },
+"TimeoutHandler.dart":
+ {
+
+ },
+"MutationEvent.dart":
+ {
+
+ },
+"SpeechRecognitionAlternative.dart":
+ {
+
+ },
+"AudioNode.dart":
+ {
+
+ },
+"SQLResultSetRowList.dart":
+ {
+
+ },
+"ContentElement.dart":
+ {
+
+ },
+"OESVertexArrayObject.dart":
+ {
+
+ },
+"TableColElement.dart":
+ {
+
+ },
+"RTCPeerConnection.dart":
+ {
+
+ },
+"Crypto.dart":
+ {
+
+ },
+"StyleElement.dart":
+ {
+
+ },
+"TrackElement.dart":
+ {
+
+ },
+"IDBVersionChangeRequest.dart":
+ {
+
+ },
+"TextEvent.dart":
+ {
+
+ },
+"ElementTimeControl.dart":
+ {
+
+ },
+"Touch.dart":
+ {
+
+ },
+"FieldSetElement.dart":
+ {
+
+ },
+"XSLTProcessor.dart":
+ {
+
+ },
+"EventTarget.dart":
+ {
+
+ },
+"Document.dart":
+ {
+
+ },
+"CSSStyleDeclaration.dart":
+ {
+
+ },
+"DocumentFragment.dart":
+ {
+
+ },
+"XPathNSResolver.dart":
+ {
+
+ },
+"DedicatedWorkerContext.dart":
+ {
+
+ },
+"IDBRequest.dart":
+ {
+
+ },
+"XPathExpression.dart":
+ {
+
+ },
+"IDBObjectStore.dart":
+ {
+
+ },
+"DelayNode.dart":
+ {
+
+ },
+"SQLResultSet.dart":
+ {
+
+ },
+"ButtonElement.dart":
+ {
+
+ },
+"ValidityState.dart":
+ {
+
+ },
+"Text.dart":
+ {
+
+ },
+"DirectoryEntrySync.dart":
+ {
+
+ },
+"Url.dart":
+ {
+
+ },
+"CSSFontFaceRule.dart":
+ {
+
+ },
+"NavigatorUserMediaSuccessCallback.dart":
+ {
+
+ },
+"OptGroupElement.dart":
+ {
+
+ },
+"Entry.dart":
+ {
+
+ },
+"IDBFactory.dart":
+ {
+
+ },
+"OptionElement.dart":
+ {
+
+ },
+"AudioContext.dart":
+ {
+
+ },
+"DetailsElement.dart":
+ {
+
+ },
+"DOMSelection.dart":
+ {
+
+ },
+"LabelElement.dart":
+ {
+
+ },
+"CSSUnknownRule.dart":
+ {
+
+ },
+"ProcessingInstruction.dart":
+ {
+
+ },
+"HTMLAllCollection.dart":
+ {
+
+ },
+"TrackEvent.dart":
+ {
+
+ },
+"SharedWorker.dart":
+ {
+
+ },
+"Element.dart":
+ {
+
+ },
+"MediaSource.dart":
+ {
+
+ },
+"MediaList.dart":
+ {
+
+ },
+"StringCallback.dart":
+ {
+
+ },
+"DOMFileSystemSync.dart":
+ {
+
+ },
+"DOMStringMap.dart":
+ {
+
+ },
+"AudioProcessingEvent.dart":
+ {
+
+ },
+"Attr.dart":
+ {
+
+ },
+"ChannelMergerNode.dart":
+ {
+
+ },
+"IDBCursor.dart":
+ {
+
+ },
+"MessageChannel.dart":
+ {
+
+ },
+"FileCallback.dart":
+ {
+
+ },
+"PerformanceTiming.dart":
+ {
+
+ },
+"SourceBufferList.dart":
+ {
+
+ },
+"AudioElement.dart":
+ {
+
+ },
+"Event.dart":
+ {
+
+ },
+"FileReaderSync.dart":
+ {
+
+ },
+"TextTrack.dart":
+ {
+
+ },
+"Counter.dart":
+ {
+
+ },
+"MediaElement.dart":
+ {
+
+ },
+"DOMMimeTypeArray.dart":
+ {
+
+ },
+"PreElement.dart":
+ {
+
+ },
+"WebGLDepthTexture.dart":
+ {
+
+ },
+"FormElement.dart":
+ {
+
+ },
+"HttpRequestException.dart":
+ {
+
+ },
+"PeerConnection00.dart":
+ {
+
+ },
+"PagePopupController.dart":
+ {
+
+ },
+"LIElement.dart":
+ {
+
+ },
+"AudioBufferSourceNode.dart":
+ {
+
+ },
+"AudioSourceNode.dart":
+ {
+
+ },
+"RTCStatsReport.dart":
+ {
+
+ },
+"SQLStatementCallback.dart":
+ {
+
+ },
+"WaveTable.dart":
+ {
+
+ },
+"DatabaseCallback.dart":
+ {
+
+ },
+"WebGLTexture.dart":
+ {
+
+ },
+"EntrySync.dart":
+ {
+
+ },
+"SpeechGrammar.dart":
+ {
+
+ },
+"WaveShaperNode.dart":
+ {
+
+ },
+"MediaKeyError.dart":
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/sdk/lib/html/docs/svg_docs.json b/sdk/lib/html/docs/svg_docs.json
new file mode 100644
index 0000000..f01683a
--- /dev/null
+++ b/sdk/lib/html/docs/svg_docs.json
@@ -0,0 +1,606 @@
+{
+"PathSegLinetoVerticalRel.dart":
+ {
+
+ },
+"DefsElement.dart":
+ {
+
+ },
+"LineElement.dart":
+ {
+
+ },
+"SwitchElement.dart":
+ {
+
+ },
+"Rect.dart":
+ {
+
+ },
+"Matrix.dart":
+ {
+
+ },
+"VKernElement.dart":
+ {
+
+ },
+"RenderingIntent.dart":
+ {
+
+ },
+"AnimatedBoolean.dart":
+ {
+
+ },
+"Angle.dart":
+ {
+
+ },
+"MissingGlyphElement.dart":
+ {
+
+ },
+"ZoomEvent.dart":
+ {
+
+ },
+"RadialGradientElement.dart":
+ {
+
+ },
+"AltGlyphDefElement.dart":
+ {
+
+ },
+"PathSegCurvetoQuadraticRel.dart":
+ {
+
+ },
+"FEPointLightElement.dart":
+ {
+
+ },
+"ScriptElement.dart":
+ {
+
+ },
+"GradientElement.dart":
+ {
+
+ },
+"FETileElement.dart":
+ {
+
+ },
+"PathSegList.dart":
+ {
+
+ },
+"AnimateTransformElement.dart":
+ {
+
+ },
+"TSpanElement.dart":
+ {
+
+ },
+"FEGaussianBlurElement.dart":
+ {
+
+ },
+"PathSegCurvetoQuadraticAbs.dart":
+ {
+
+ },
+"AnimateElement.dart":
+ {
+
+ },
+"ExternalResourcesRequired.dart":
+ {
+
+ },
+"FontFaceNameElement.dart":
+ {
+
+ },
+"UriReference.dart":
+ {
+
+ },
+"Length.dart":
+ {
+
+ },
+"FEMergeElement.dart":
+ {
+
+ },
+"Point.dart":
+ {
+
+ },
+"AnimatedTransformList.dart":
+ {
+
+ },
+"ViewSpec.dart":
+ {
+
+ },
+"Transformable.dart":
+ {
+
+ },
+"FEDisplacementMapElement.dart":
+ {
+
+ },
+"PathSegArcRel.dart":
+ {
+
+ },
+"Stylable.dart":
+ {
+
+ },
+"PathSegLinetoRel.dart":
+ {
+
+ },
+"PathSegCurvetoCubicSmoothRel.dart":
+ {
+
+ },
+"FEMorphologyElement.dart":
+ {
+
+ },
+"ElementInstance.dart":
+ {
+
+ },
+"AnimateMotionElement.dart":
+ {
+
+ },
+"AElement.dart":
+ {
+
+ },
+"FontElement.dart":
+ {
+
+ },
+"AnimatedInteger.dart":
+ {
+
+ },
+"PathElement.dart":
+ {
+
+ },
+"FEColorMatrixElement.dart":
+ {
+
+ },
+"PathSegLinetoHorizontalAbs.dart":
+ {
+
+ },
+"NumberList.dart":
+ {
+
+ },
+"RectElement.dart":
+ {
+
+ },
+"MPathElement.dart":
+ {
+
+ },
+"PathSegClosePath.dart":
+ {
+
+ },
+"FEFloodElement.dart":
+ {
+
+ },
+"FontFaceSrcElement.dart":
+ {
+
+ },
+"Number.dart":
+ {
+
+ },
+"PolylineElement.dart":
+ {
+
+ },
+"AnimatedLengthList.dart":
+ {
+
+ },
+"FECompositeElement.dart":
+ {
+
+ },
+"FontFaceFormatElement.dart":
+ {
+
+ },
+"TransformList.dart":
+ {
+
+ },
+"FEDropShadowElement.dart":
+ {
+
+ },
+"SvgSvgElement.dart":
+ {
+
+ },
+"PreserveAspectRatio.dart":
+ {
+
+ },
+"ForeignObjectElement.dart":
+ {
+
+ },
+"FESpotLightElement.dart":
+ {
+
+ },
+"DescElement.dart":
+ {
+
+ },
+"FontFaceUriElement.dart":
+ {
+
+ },
+"ImageElement.dart":
+ {
+
+ },
+"AnimatedPreserveAspectRatio.dart":
+ {
+
+ },
+"PathSegCurvetoQuadraticSmoothAbs.dart":
+ {
+
+ },
+"GElement.dart":
+ {
+
+ },
+"PathSegMovetoRel.dart":
+ {
+
+ },
+"Paint.dart":
+ {
+
+ },
+"AnimatedEnumeration.dart":
+ {
+
+ },
+"FEFuncAElement.dart":
+ {
+
+ },
+"CircleElement.dart":
+ {
+
+ },
+"SetElement.dart":
+ {
+
+ },
+"TitleElement.dart":
+ {
+
+ },
+"PatternElement.dart":
+ {
+
+ },
+"AnimatedString.dart":
+ {
+
+ },
+"FEFuncRElement.dart":
+ {
+
+ },
+"SvgDocument.dart":
+ {
+
+ },
+"FEMergeNodeElement.dart":
+ {
+
+ },
+"Exception.dart":
+ {
+
+ },
+"UseElement.dart":
+ {
+
+ },
+"PathSegLinetoVerticalAbs.dart":
+ {
+
+ },
+"FontFaceElement.dart":
+ {
+
+ },
+"PathSegCurvetoCubicRel.dart":
+ {
+
+ },
+"Color.dart":
+ {
+
+ },
+"PathSegArcAbs.dart":
+ {
+
+ },
+"FilterPrimitiveStandardAttributes.dart":
+ {
+
+ },
+"AnimationElement.dart":
+ {
+
+ },
+"AltGlyphElement.dart":
+ {
+
+ },
+"MarkerElement.dart":
+ {
+
+ },
+"FEDiffuseLightingElement.dart":
+ {
+
+ },
+"FETurbulenceElement.dart":
+ {
+
+ },
+"SvgElement.dart":
+ {
+
+ },
+"Transform.dart":
+ {
+
+ },
+"Locatable.dart":
+ {
+
+ },
+"UnitTypes.dart":
+ {
+
+ },
+"ViewElement.dart":
+ {
+
+ },
+"FEConvolveMatrixElement.dart":
+ {
+
+ },
+"FEDistantLightElement.dart":
+ {
+
+ },
+"PolygonElement.dart":
+ {
+
+ },
+"MetadataElement.dart":
+ {
+
+ },
+"ZoomAndPan.dart":
+ {
+
+ },
+"ClipPathElement.dart":
+ {
+
+ },
+"TextPositioningElement.dart":
+ {
+
+ },
+"StopElement.dart":
+ {
+
+ },
+"SymbolElement.dart":
+ {
+
+ },
+"HKernElement.dart":
+ {
+
+ },
+"GlyphRefElement.dart":
+ {
+
+ },
+"PathSegCurvetoCubicAbs.dart":
+ {
+
+ },
+"GlyphElement.dart":
+ {
+
+ },
+"MaskElement.dart":
+ {
+
+ },
+"TextContentElement.dart":
+ {
+
+ },
+"FilterElement.dart":
+ {
+
+ },
+"FEFuncGElement.dart":
+ {
+
+ },
+"EllipseElement.dart":
+ {
+
+ },
+"Tests.dart":
+ {
+
+ },
+"AnimatedLength.dart":
+ {
+
+ },
+"PathSegCurvetoQuadraticSmoothRel.dart":
+ {
+
+ },
+"StyleElement.dart":
+ {
+
+ },
+"CursorElement.dart":
+ {
+
+ },
+"FitToViewBox.dart":
+ {
+
+ },
+"TextElement.dart":
+ {
+
+ },
+"FEFuncBElement.dart":
+ {
+
+ },
+"FEOffsetElement.dart":
+ {
+
+ },
+"FEImageElement.dart":
+ {
+
+ },
+"LangSpace.dart":
+ {
+
+ },
+"FESpecularLightingElement.dart":
+ {
+
+ },
+"PointList.dart":
+ {
+
+ },
+"LinearGradientElement.dart":
+ {
+
+ },
+"PathSegMovetoAbs.dart":
+ {
+
+ },
+"AnimatedNumberList.dart":
+ {
+
+ },
+"PathSegLinetoHorizontalRel.dart":
+ {
+
+ },
+"LengthList.dart":
+ {
+
+ },
+"ComponentTransferFunctionElement.dart":
+ {
+
+ },
+"StringList.dart":
+ {
+
+ },
+"FEComponentTransferElement.dart":
+ {
+
+ },
+"PathSegCurvetoCubicSmoothAbs.dart":
+ {
+
+ },
+"PathSegLinetoAbs.dart":
+ {
+
+ },
+"AnimatedNumber.dart":
+ {
+
+ },
+"TextPathElement.dart":
+ {
+
+ },
+"AnimatedRect.dart":
+ {
+
+ },
+"AnimatedAngle.dart":
+ {
+
+ },
+"AltGlyphItemElement.dart":
+ {
+
+ },
+"TRefElement.dart":
+ {
+
+ },
+"AnimateColorElement.dart":
+ {
+
+ },
+"PathSeg.dart":
+ {
+
+ },
+"FEBlendElement.dart":
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/sdk/lib/html/scripts/dartdomgenerator.py b/sdk/lib/html/scripts/dartdomgenerator.py
index 18cba86..d15f894 100755
--- a/sdk/lib/html/scripts/dartdomgenerator.py
+++ b/sdk/lib/html/scripts/dartdomgenerator.py
@@ -25,6 +25,8 @@
_logger = logging.getLogger('dartdomgenerator')
+_libraries = ['html', 'svg', 'web_audio']
+
class GeneratorOptions(object):
def __init__(self, templates, database, type_registry, renamer):
self.templates = templates
@@ -85,6 +87,7 @@
interface_generator.Generate()
generator.Generate(webkit_database, common_database, generate_interface)
+
dart_library_emitter.EmitLibraries(auxiliary_dir)
if dart2js_output_dir:
@@ -99,7 +102,7 @@
dart_output_dir = os.path.join(dart2js_output_dir, 'dart')
dart_libraries = DartLibraries(
- template_loader, 'dart2js', dart2js_output_dir)
+ _libraries, template_loader, 'dart2js', dart2js_output_dir)
RunGenerator(dart_libraries, dart_output_dir,
template_loader, backend_factory)
@@ -118,7 +121,7 @@
dart_output_dir = os.path.join(dartium_output_dir, 'dart')
dart_libraries = DartLibraries(
- template_loader, 'dartium', dartium_output_dir)
+ _libraries, template_loader, 'dartium', dartium_output_dir)
RunGenerator(dart_libraries, dart_output_dir,
template_loader, backend_factory)
@@ -131,7 +134,7 @@
_logger.info('Flush...')
emitters.Flush()
-def GenerateSingleFile(library_path, output_dir):
+def GenerateSingleFile(library_path, output_dir, generated_output_dir=None):
library_dir = os.path.dirname(library_path)
library_filename = os.path.basename(library_path)
copy_dart_script = os.path.relpath('../../../../tools/copy_dart.py',
@@ -170,6 +173,7 @@
systems = options.systems.split(',')
output_dir = options.output_dir or os.path.join(current_dir, '../generated')
+
dart2js_output_dir = None
if 'htmldart2js' in systems:
dart2js_output_dir = os.path.join(output_dir, 'dart2js')
@@ -185,18 +189,33 @@
database = LoadDatabase(database_dir, options.use_database_cache)
GenerateFromDatabase(database, dart2js_output_dir, dartium_output_dir)
+ _logger.info('Add documentation to generated classes.')
+ html_to_json_script = os.path.relpath(
+ '../../../../tools/html_json_doc/bin/html_json_doc.dart',
+ current_dir)
+ html_output_dir = os.path.join(output_dir, 'dart2js/dart/html/')
+ svg_output_dir = os.path.join(output_dir, 'dart2js/dart/svg/')
+ html_json_path = os.path.relpath('../docs/html_docs.json')
+ svg_json_path = os.path.relpath('../docs/svg_docs.json')
+ html_command = ' '.join(['dart', html_to_json_script, '--mode=json-to-html',
+ html_output_dir, html_json_path])
+ svg_command = ' '.join(['dart', html_to_json_script, '--mode=json-to-html',
+ svg_output_dir, svg_json_path])
+ subprocess.call([html_command], shell=True)
+ subprocess.call([svg_command], shell=True)
+
if 'htmldart2js' in systems:
_logger.info('Generating dart2js single files.')
- GenerateSingleFile(os.path.join(dart2js_output_dir, 'html_dart2js.dart'),
- '../dart2js')
- GenerateSingleFile(os.path.join(dart2js_output_dir, 'svg_dart2js.dart'),
- '../../svg/dart2js')
+ for library_name in _libraries:
+ GenerateSingleFile(
+ os.path.join(dart2js_output_dir, '%s_dart2js.dart' % library_name),
+ '../../%s/dart2js' % library_name)
if 'htmldartium' in systems:
_logger.info('Generating dartium single files.')
- GenerateSingleFile(os.path.join(dartium_output_dir, 'html_dartium.dart'),
- '../dartium')
- GenerateSingleFile(os.path.join(dartium_output_dir, 'svg_dartium.dart'),
- '../../svg/dartium')
+ for library_name in _libraries:
+ GenerateSingleFile(
+ os.path.join(dartium_output_dir, '%s_dartium.dart' % library_name),
+ '../../%s/dartium' % library_name)
if __name__ == '__main__':
sys.exit(main())
diff --git a/sdk/lib/html/scripts/databasebuilder.py b/sdk/lib/html/scripts/databasebuilder.py
index d75d033..81d6c0e 100755
--- a/sdk/lib/html/scripts/databasebuilder.py
+++ b/sdk/lib/html/scripts/databasebuilder.py
@@ -74,19 +74,7 @@
except SyntaxError, e:
raise RuntimeError('Failed to load file %s: %s'
% (file_name, e))
-
-def _load_idl_file_to_queue(file_name, import_options, result_queue):
- """Loads an IDL file into a result_queue to process in the master thread"""
- try:
- result = _load_idl_file(file_name, import_options)
- result_queue.put(result, False)
- return 0
- except RuntimeError, e:
- result_queue.put(e, False)
- return 1
- except:
- result_queue.put('Unknown error loading %s' % file_name, False)
- return 1
+
class DatabaseBuilder(object):
def __init__(self, database):
@@ -429,25 +417,17 @@
def import_idl_files(self, file_paths, import_options, parallel):
if parallel:
# Parse the IDL files in parallel.
- result_queue = multiprocessing.Queue(len(file_paths))
- jobs = [ multiprocessing.Process(target=_load_idl_file_to_queue,
- args=(file_path, import_options,
- result_queue))
- for file_path in file_paths ]
+ pool = multiprocessing.Pool()
try:
- for job in jobs:
- job.start()
- for job in jobs:
- # Timeout and throw after 5 sec.
- result = result_queue.get(True, 5)
- if isinstance(result, IDLFile):
- self._process_idl_file(result, import_options)
- else:
- raise result
+ for file_path in file_paths:
+ pool.apply_async(_load_idl_file,
+ [ file_path, import_options],
+ callback = lambda idl_file:
+ self._process_idl_file(idl_file, import_options))
+ pool.close()
+ pool.join()
except:
- # Clean up child processes on error.
- for job in jobs:
- job.terminate()
+ pool.terminate()
raise
else:
# Parse the IDL files in serial.
diff --git a/sdk/lib/html/scripts/generator.py b/sdk/lib/html/scripts/generator.py
index 76b5ecf..30b0333 100644
--- a/sdk/lib/html/scripts/generator.py
+++ b/sdk/lib/html/scripts/generator.py
@@ -545,11 +545,15 @@
'SerializedScriptValue set Worker.postMessage': _serialize_SSV,
# receiving message via MessageEvent
- 'DOMObject get MessageEvent.data':
+ '* get MessageEvent.data':
Conversion('_convertNativeToDart_SerializedScriptValue',
'dynamic', 'dynamic'),
- 'DOMObject get PopStateEvent.state':
+ '* get History.state':
+ Conversion('_convertNativeToDart_SerializedScriptValue',
+ 'dynamic', 'dynamic'),
+
+ '* get PopStateEvent.state':
Conversion('_convertNativeToDart_SerializedScriptValue',
'dynamic', 'dynamic'),
@@ -577,13 +581,14 @@
def FindConversion(idl_type, direction, interface, member):
table = dart2js_conversions
return (table.get('%s %s %s.%s' % (idl_type, direction, interface, member)) or
+ table.get('* %s %s.%s' % (direction, interface, member)) or
table.get('%s %s %s.*' % (idl_type, direction, interface)) or
table.get('%s %s' % (idl_type, direction)))
return None
# ------------------------------------------------------------------------------
-# Annotations to be placed on members. The table is indexed by the IDL
+# Annotations to be placed on native members. The table is indexed by the IDL
# interface and member name, and by IDL return or field type name. Both are
# used to assemble the annotations:
#
@@ -602,8 +607,18 @@
'CanvasRenderingContext2D.webkitGetImageDataHD':
"@Creates('ImageData|=Object')",
+ # Methods returning Window can return a local window, or a cross-frame
+ # window (=Object) that needs wrapping.
+ 'DOMWindow':
+ "@Creates('LocalWindow|=Object') @Returns('LocalWindow|=Object')",
+
'DOMWindow.openDatabase': "@Creates('Database') @Creates('DatabaseSync')",
+ # Cross-frame windows are EventTargets.
+ 'EventTarget':
+ #"@Creates('Null') @Returns('EventTarget|=Object')",
+ "@Creates('EventTarget|=Object') @Returns('EventTarget|=Object')",
+
'FileReader.result': "@Creates('String|ArrayBuffer|Null')",
# Rather than have the result of an IDBRequest as a union over all possible
@@ -645,6 +660,16 @@
'MessageEvent.ports': "@Creates('=List')",
+ 'MessageEvent.data':
+ "@_annotation_Creates_SerializedScriptValue "
+ "@_annotation_Returns_SerializedScriptValue",
+ 'PopStateEvent.state':
+ "@_annotation_Creates_SerializedScriptValue "
+ "@_annotation_Returns_SerializedScriptValue",
+ 'SerializedScriptValue':
+ "@_annotation_Creates_SerializedScriptValue "
+ "@_annotation_Returns_SerializedScriptValue",
+
'SQLResultSetRowList.item': "@Creates('=Object')",
'XMLHttpRequest.response':
@@ -1096,7 +1121,7 @@
item_type='MediaStream', suppress_interface=True),
'NamedNodeMap': TypeData(clazz='Interface', item_type='Node'),
'NodeList': TypeData(clazz='Interface', item_type='Node',
- suppress_interface=True),
+ suppress_interface=False, dart_type='List<Node>'),
'SVGAnimatedLengthList': TypeData(clazz='Interface',
item_type='SVGAnimatedLength'),
'SVGAnimatedNumberList': TypeData(clazz='Interface',
diff --git a/sdk/lib/html/scripts/htmleventgenerator.py b/sdk/lib/html/scripts/htmleventgenerator.py
index c36a892..4bedc32 100644
--- a/sdk/lib/html/scripts/htmleventgenerator.py
+++ b/sdk/lib/html/scripts/htmleventgenerator.py
@@ -196,16 +196,25 @@
def ProcessInterface(self, interface, html_interface_name, custom_events,
events_implementation_emitter):
- events = set([attr for attr in interface.attributes
+ event_names = set([attr.id[2:] for attr in interface.attributes
if attr.type.id == 'EventListener'])
- if not events and interface.id not in _html_explicit_event_classes:
+
+ # Document and DocumentFragment actually derive from Element, so omit
+ # any events which are duplicated with that.
+ if interface.id == 'Document' or interface.id == 'DocumentFragment':
+ element_interface = self._database.GetInterface('Element')
+ for attr in element_interface.attributes:
+ if attr.type.id == 'EventListener' and attr.id[2:] in event_names:
+ event_names.remove(attr.id[2:])
+
+ if not event_names and interface.id not in _html_explicit_event_classes:
return None
self._event_classes.add(interface.id)
events_class_name = html_interface_name + 'Events'
parent_events_class_name = self._GetParentEventsClassName(interface)
- if not events:
+ if not event_names:
return parent_events_class_name
template_file = 'impl_%s.darttemplate' % events_class_name
@@ -222,8 +231,8 @@
SUPER='%s' % parent_events_class_name)
dom_event_names = set()
- for event in events:
- dom_name = event.id[2:]
+ for event in event_names:
+ dom_name = event
dom_name = _on_attribute_to_event_name_mapping.get(dom_name, dom_name)
dom_event_names.add(dom_name)
if html_interface_name in _html_manual_events:
@@ -239,7 +248,7 @@
implementation_events_members.Emit(
"\n"
" EventListenerList get $NAME => this['$DOM_NAME'];\n",
- NAME=html_name,
+ NAME=html_name,
DOM_NAME=dom_name)
return events_class_name
diff --git a/sdk/lib/html/scripts/htmlrenamer.py b/sdk/lib/html/scripts/htmlrenamer.py
index 2f26d06..9c43084 100644
--- a/sdk/lib/html/scripts/htmlrenamer.py
+++ b/sdk/lib/html/scripts/htmlrenamer.py
@@ -14,6 +14,7 @@
'Location': 'LocalLocation',
'SVGDocument': 'SvgDocument', # Manual to avoid name conflicts.
'SVGElement': 'SvgElement', # Manual to avoid name conflicts.
+ 'SVGException': 'SvgException', # Manual of avoid conflict with Exception.
'SVGSVGElement': 'SvgSvgElement', # Manual to avoid name conflicts.
'WebKitAnimation': 'Animation',
'WebKitAnimationEvent': 'AnimationEvent',
@@ -75,18 +76,24 @@
'Element.className',
'Element.firstElementChild',
'Element.getAttribute',
+ 'Element.getAttributeNS',
'Element.getElementsByClassName',
'Element.getElementsByTagName',
'Element.hasAttribute',
+ 'Element.hasAttributeNS',
'Element.lastElementChild',
'Element.querySelector',
'Element.querySelectorAll',
'Element.removeAttribute',
+ 'Element.removeAttributeNS',
'Element.setAttribute',
+ 'Element.setAttributeNS',
'Event.initEvent',
+ 'UIEvent.initUIEvent',
'EventTarget.addEventListener',
'EventTarget.dispatchEvent',
'EventTarget.removeEventListener',
+ 'KeyboardEvent.keyIdentifier',
'LocalWindow.getComputedStyle',
'MouseEvent.initMouseEvent',
'Node.appendChild',
@@ -94,8 +101,12 @@
'Node.childNodes',
'Node.firstChild',
'Node.lastChild',
+ "Node.localName",
+ 'Node.namespaceURI',
'Node.removeChild',
'Node.replaceChild',
+ 'UIEvent.keyCode',
+ 'UIEvent.charCode',
'ShadowRoot.getElementById',
'ShadowRoot.getElementsByClassName',
'ShadowRoot.getElementsByTagName',
@@ -112,6 +123,7 @@
# Members from the standard dom that exist in the dart:html library with
# identical functionality but with cleaner names.
_renamed_html_members = {
+ 'Document.createCDATASection': 'createCDataSection',
'Document.defaultView': 'window',
'Element.webkitMatchesSelector' : 'matchesSelector',
'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
@@ -191,16 +203,13 @@
'Document.webkitCurrentFullScreenElement',
'Document.webkitFullScreenKeyboardInputAllowed',
"DocumentType.*",
- "Element.hasAttributeNS",
- "Element.getAttributeNS",
"Element.setAttributeNode",
"Element.getAttributeNode",
"Element.removeAttributeNode",
- "Element.removeAttributeNS",
"Element.setAttributeNodeNS",
"Element.getAttributeNodeNS",
- "Element.setAttributeNS",
"Event.srcElement",
+ "EventSource.URL",
"BodyElement.text",
"AnchorElement.text",
"OptionElement.text",
@@ -249,8 +258,10 @@
"Document.version",
"Document.manifest",
"HTMLIsIndexElement.*",
+ "MenuElement.compact",
"HTMLOptionsCollection.*",
"HTMLPropertiesCollection.*",
+ "KeyboardEvent.initKeyboardEvent",
"SelectElement.remove",
"NamedNodeMap.*",
"Node.isEqualNode",
@@ -260,9 +271,7 @@
"Node.get:DOCUMENT_POSITION_FOLLOWING",
"Node.lookupNamespaceURI",
"Node.get:ELEMENT_NODE",
- "Node.get:namespaceURI",
"Node.get:DOCUMENT_FRAGMENT_NODE",
- "Node.get:localName",
"Node.isDefaultNamespace",
"Node.compareDocumentPosition",
"Node.get:baseURI",
@@ -313,6 +322,7 @@
return interface.id[len('HTML'):]
return self.DartifyTypeName(interface.id)
+
def RenameMember(self, interface_name, member_node, member, member_prefix=''):
"""
Returns the name of the member in the HTML library or None if the member is
@@ -328,10 +338,13 @@
name = self._FindMatch(interface, member, member_prefix,
_renamed_html_members)
+
target_name = _renamed_html_members[name] if name else member
if self._FindMatch(interface, member, member_prefix, _private_html_members):
if not target_name.startswith('$dom_'): # e.g. $dom_svgClassName
target_name = '$dom_' + target_name
+
+ target_name = self._DartifyMemberName(target_name)
return target_name
def _FindMatch(self, interface, member, member_prefix, candidates):
@@ -352,11 +365,20 @@
Gets the name of the library this type should live in.
This is private because this should use interfaces to resolve the library.
"""
-
if idl_type_name.startswith('SVG'):
return 'svg'
+ if 'Audio' in idl_type_name:
+ return 'web_audio'
+
+ if self._database.HasInterface(idl_type_name):
+ interface = self._database.GetInterface(idl_type_name)
+ for parent in self._database.Hierarchy(interface):
+ if parent.id == 'AudioNode':
+ return 'web_audio'
+
return 'html'
+
def DartifyTypeName(self, type_name):
"""Converts a DOM name to a Dart-friendly class name. """
library_name = self._GetLibraryName(type_name)
@@ -366,6 +388,14 @@
# Strip off the SVG prefix.
name = re.sub(r'^SVG', '', type_name)
+ return self._CamelCaseName(name)
+
+ def _DartifyMemberName(self, member_name):
+ # Strip off any OpenGL ES suffixes.
+ name = re.sub(r'OES$', '', member_name)
+ return self._CamelCaseName(name)
+
+ def _CamelCaseName(self, name):
def toLower(match):
return match.group(1) + match.group(2).lower() + match.group(3)
diff --git a/sdk/lib/html/scripts/systemhtml.py b/sdk/lib/html/scripts/systemhtml.py
index 38ad58c..345a3f1 100644
--- a/sdk/lib/html/scripts/systemhtml.py
+++ b/sdk/lib/html/scripts/systemhtml.py
@@ -202,7 +202,8 @@
_element_constructors = {
'html': _html_element_constructors,
- 'svg': _svg_element_constructors
+ 'svg': _svg_element_constructors,
+ 'web_audio': {},
}
_factory_ctr_strings = {
@@ -214,6 +215,10 @@
'provider_name': '_SvgElementFactoryProvider',
'constructor_name': 'createSvgElement_tag',
},
+ 'web_audio': {
+ 'provider_name': 'document',
+ 'constructor_name': '$dom_createElement'
+ },
}
def ElementConstructorInfos(typename, element_constructors,
@@ -507,11 +512,7 @@
return
if IsPureInterface(self._interface.id):
- self._AddInterfaceAttribute(attribute)
- return
-
- if attribute.id != html_name:
- self._AddAttributeUsingProperties(attribute, html_name, read_only)
+ self._AddInterfaceAttribute(attribute, html_name)
return
# If the attribute is shadowing, we can't generate a shadowing
@@ -532,7 +533,7 @@
' // Use implementation from $SUPER.\n'
' // final $TYPE $NAME;\n',
SUPER=super_attribute_interface,
- NAME=DartDomNameOfAttribute(attribute),
+ NAME=html_name,
TYPE=self.SecureOutputType(attribute.type.id))
return
self._members_emitter.Emit('\n // Shadowing definition.')
@@ -549,20 +550,23 @@
output_type = self.SecureOutputType(attribute.type.id)
input_type = self._NarrowInputType(attribute.type.id)
annotations = self._Annotations(attribute.type.id, attribute.id)
+ rename = self._RenamingAnnotation(attribute.id, html_name)
self.EmitAttributeDocumentation(attribute)
if not read_only:
self._members_emitter.Emit(
- '\n $ANNOTATIONS$TYPE $NAME;'
+ '\n $RENAME$ANNOTATIONS$TYPE $NAME;'
'\n',
+ RENAME=rename,
ANNOTATIONS=annotations,
- NAME=DartDomNameOfAttribute(attribute),
+ NAME=html_name,
TYPE=output_type)
else:
self._members_emitter.Emit(
- '\n $(ANNOTATIONS)final $TYPE $NAME;'
+ '\n $RENAME$(ANNOTATIONS)final $TYPE $NAME;'
'\n',
+ RENAME=rename,
ANNOTATIONS=annotations,
- NAME=DartDomNameOfAttribute(attribute),
+ NAME=html_name,
TYPE=output_type)
def _AddAttributeUsingProperties(self, attribute, html_name, read_only):
@@ -570,11 +574,11 @@
if not read_only:
self._AddRenamingSetter(attribute, html_name)
- def _AddInterfaceAttribute(self, attribute):
+ def _AddInterfaceAttribute(self, attribute, html_name):
self._members_emitter.Emit(
'\n $TYPE $NAME;'
'\n',
- NAME=DartDomNameOfAttribute(attribute),
+ NAME=html_name,
TYPE=self.SecureOutputType(attribute.type.id))
def _AddRenamingGetter(self, attr, html_name):
@@ -612,11 +616,11 @@
def _AddConvertingGetter(self, attr, html_name, conversion):
self._members_emitter.Emit(
- # TODO(sra): Use metadata to provide native name.
'\n $RETURN_TYPE get $HTML_NAME => $CONVERT(this._$(HTML_NAME));'
- '\n $NATIVE_TYPE get _$HTML_NAME =>'
- ' JS("$NATIVE_TYPE", "#.$NAME", this);'
+ "\n @JSName('$NAME')"
+ '\n $(ANNOTATIONS)final $NATIVE_TYPE _$HTML_NAME;'
'\n',
+ ANNOTATIONS=self._Annotations(attr.type.id, html_name),
CONVERT=conversion.function_name,
HTML_NAME=html_name,
NAME=attr.id,
@@ -661,32 +665,15 @@
self._AddDirectNativeOperation(info, html_name)
def _AddDirectNativeOperation(self, info, html_name):
- # Do we need a native body?
- if html_name != info.declared_name:
- return_type = self.SecureOutputType(info.type_name)
-
- operation_emitter = self._members_emitter.Emit(
- '$!SCOPE',
- MODIFIERS='static ' if info.IsStatic() else '',
- ANNOTATIONS=self._Annotations(info.type_name, info.declared_name),
- TYPE=return_type,
- HTML_NAME=html_name,
- NAME=info.declared_name,
- PARAMS=info.ParametersDeclaration(self._NarrowInputType))
-
- operation_emitter.Emit(
- '\n'
- ' $ANNOTATIONS'
- '$MODIFIERS$TYPE $(HTML_NAME)($PARAMS) native "$NAME";\n')
- else:
- self._members_emitter.Emit(
- '\n'
- ' $ANNOTATIONS$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
- MODIFIERS='static ' if info.IsStatic() else '',
- ANNOTATIONS=self._Annotations(info.type_name, info.declared_name),
- TYPE=self.SecureOutputType(info.type_name),
- NAME=info.name,
- PARAMS=info.ParametersDeclaration(self._NarrowInputType))
+ self._members_emitter.Emit(
+ '\n'
+ ' $RENAME$ANNOTATIONS$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
+ RENAME=self._RenamingAnnotation(info.declared_name, html_name),
+ ANNOTATIONS=self._Annotations(info.type_name, info.declared_name),
+ MODIFIERS='static ' if info.IsStatic() else '',
+ TYPE=self.SecureOutputType(info.type_name),
+ NAME=html_name,
+ PARAMS=info.ParametersDeclaration(self._NarrowInputType))
def _AddOperationWithConversions(self, info, html_name):
# Assert all operations have same return type.
@@ -785,13 +772,13 @@
call_emitter.Emit('$(INDENT)return $CALL;\n', CALL=call)
self._members_emitter.Emit(
- ' $MODIFIERS$ANNOTATIONS$TYPE$TARGET($PARAMS) native "$NATIVE";\n',
- MODIFIERS='static ' if info.IsStatic() else '',
+ ' $RENAME$ANNOTATIONS$MODIFIERS$TYPE$TARGET($PARAMS) native;\n',
+ RENAME=self._RenamingAnnotation(info.declared_name, target),
ANNOTATIONS=self._Annotations(info.type_name, info.declared_name),
+ MODIFIERS='static ' if info.IsStatic() else '',
TYPE=TypeOrNothing(native_return_type),
TARGET=target,
- PARAMS=', '.join(target_parameters),
- NATIVE=info.declared_name)
+ PARAMS=', '.join(target_parameters))
def GenerateChecksAndCall(operation, argument_count):
checks = []
@@ -871,8 +858,13 @@
member_name)
return member_name in _js_custom_members
- def _Annotations(self, idl_type, member_name):
- annotations = FindAnnotations(idl_type, self._interface.id, member_name)
+ def _RenamingAnnotation(self, idl_name, member_name):
+ if member_name != idl_name:
+ return "@JSName('%s')\n " % idl_name
+ return ''
+
+ def _Annotations(self, idl_type, idl_member_name):
+ annotations = FindAnnotations(idl_type, self._interface.id, idl_member_name)
if annotations:
return '%s\n ' % annotations
return_type = self.SecureOutputType(idl_type)
@@ -985,11 +977,11 @@
# ------------------------------------------------------------------------------
class DartLibraries():
- def __init__(self, template_loader, library_type, output_dir):
- self._libraries = {
- 'svg': DartLibrary('svg', template_loader, library_type, output_dir),
- 'html': DartLibrary('html', template_loader, library_type, output_dir),
- }
+ def __init__(self, libraries, template_loader, library_type, output_dir):
+ self._libraries = {}
+ for library_name in libraries:
+ self._libraries[library_name] = DartLibrary(
+ library_name, template_loader, library_type, output_dir)
def AddFile(self, basename, library_name, path):
self._libraries[library_name].AddFile(path)
diff --git a/sdk/lib/html/src/AttributeMap.dart b/sdk/lib/html/src/AttributeMap.dart
new file mode 100644
index 0000000..e5e6e26
--- /dev/null
+++ b/sdk/lib/html/src/AttributeMap.dart
@@ -0,0 +1,223 @@
+// 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.
+
+part of html;
+
+abstract class _AttributeMap implements Map<String, String> {
+
+ bool containsValue(String value) {
+ for (var v in this.values) {
+ if (value == v) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) {
+ if (!containsKey(key)) {
+ this[key] = ifAbsent();
+ }
+ return this[key];
+ }
+
+ void clear() {
+ for (var key in keys) {
+ remove(key);
+ }
+ }
+
+ void forEach(void f(String key, String value)) {
+ for (var key in keys) {
+ var value = this[key];
+ f(key, value);
+ }
+ }
+
+ Collection<String> get keys {
+ // TODO: generate a lazy collection instead.
+ var attributes = _element.$dom_attributes;
+ var keys = new List<String>();
+ for (int i = 0, len = attributes.length; i < len; i++) {
+ if (_matches(attributes[i])) {
+ keys.add(attributes[i].$dom_localName);
+ }
+ }
+ return keys;
+ }
+
+ Collection<String> get values {
+ // TODO: generate a lazy collection instead.
+ var attributes = _element.$dom_attributes;
+ var values = new List<String>();
+ for (int i = 0, len = attributes.length; i < len; i++) {
+ if (_matches(attributes[i])) {
+ values.add(attributes[i].value);
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Returns true if there is no {key, value} pair in the map.
+ */
+ bool get isEmpty {
+ return length == 0;
+ }
+
+ /**
+ * Checks to see if the node should be included in this map.
+ */
+ bool _matches(Node node);
+}
+
+/**
+ * Wrapper to expose [Element.attributes] as a typed map.
+ */
+class _ElementAttributeMap extends _AttributeMap {
+
+ final Element _element;
+
+ _ElementAttributeMap(this._element);
+
+ bool containsKey(String key) {
+ return _element.$dom_hasAttribute(key);
+ }
+
+ String operator [](String key) {
+ return _element.$dom_getAttribute(key);
+ }
+
+ void operator []=(String key, value) {
+ _element.$dom_setAttribute(key, '$value');
+ }
+
+ String remove(String key) {
+ String value = _element.$dom_getAttribute(key);
+ _element.$dom_removeAttribute(key);
+ return value;
+ }
+
+ /**
+ * The number of {key, value} pairs in the map.
+ */
+ int get length {
+ return keys.length;
+ }
+
+ bool _matches(Node node) => node.$dom_namespaceUri == null;
+}
+
+/**
+ * Wrapper to expose namespaced attributes as a typed map.
+ */
+class _NamespacedAttributeMap extends _AttributeMap {
+
+ final Element _element;
+ final String _namespace;
+
+ _NamespacedAttributeMap(this._element, this._namespace);
+
+ bool containsKey(String key) {
+ return _element.$dom_hasAttributeNS(_namespace, key);
+ }
+
+ String operator [](String key) {
+ return _element.$dom_getAttributeNS(_namespace, key);
+ }
+
+ void operator []=(String key, value) {
+ _element.$dom_setAttributeNS(_namespace, key, '$value');
+ }
+
+ String remove(String key) {
+ String value = this[key];
+ _element.$dom_removeAttributeNS(_namespace, key);
+ return value;
+ }
+
+ /**
+ * The number of {key, value} pairs in the map.
+ */
+ int get length {
+ return keys.length;
+ }
+
+ bool _matches(Node node) => node.$dom_namespaceUri == _namespace;
+}
+
+
+/**
+ * Provides a Map abstraction on top of data-* attributes, similar to the
+ * dataSet in the old DOM.
+ */
+class _DataAttributeMap implements Map<String, String> {
+
+ final Map<String, String> $dom_attributes;
+
+ _DataAttributeMap(this.$dom_attributes);
+
+ // interface Map
+
+ // TODO: Use lazy iterator when it is available on Map.
+ bool containsValue(String value) => values.some((v) => v == value);
+
+ bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
+
+ String operator [](String key) => $dom_attributes[_attr(key)];
+
+ void operator []=(String key, value) {
+ $dom_attributes[_attr(key)] = '$value';
+ }
+
+ String putIfAbsent(String key, String ifAbsent()) =>
+ $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
+
+ String remove(String key) => $dom_attributes.remove(_attr(key));
+
+ void clear() {
+ // Needs to operate on a snapshot since we are mutating the collection.
+ for (String key in keys) {
+ remove(key);
+ }
+ }
+
+ void forEach(void f(String key, String value)) {
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ f(_strip(key), value);
+ }
+ });
+ }
+
+ Collection<String> get keys {
+ final keys = new List<String>();
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ keys.add(_strip(key));
+ }
+ });
+ return keys;
+ }
+
+ Collection<String> get values {
+ final values = new List<String>();
+ $dom_attributes.forEach((String key, String value) {
+ if (_matches(key)) {
+ values.add(value);
+ }
+ });
+ return values;
+ }
+
+ int get length => keys.length;
+
+ // TODO: Use lazy iterator when it is available on Map.
+ bool get isEmpty => length == 0;
+
+ // Helpers.
+ String _attr(String key) => 'data-$key';
+ bool _matches(String key) => key.startsWith('data-');
+ String _strip(String key) => key.substring(5);
+}
diff --git a/sdk/lib/html/src/CrossFrameTypes.dart b/sdk/lib/html/src/CrossFrameTypes.dart
index b77284c..e8db94c 100644
--- a/sdk/lib/html/src/CrossFrameTypes.dart
+++ b/sdk/lib/html/src/CrossFrameTypes.dart
@@ -33,7 +33,7 @@
History get history;
/**
- * Indicates whether this window is closed.
+ * Indicates whether this window has been closed.
*
* print(window.closed); // 'false'
* window.close();
@@ -86,6 +86,34 @@
Window get top;
// Methods.
+ /**
+ * Closes the window.
+ *
+ * This method should only succeed if the [Window] object is
+ * **script-closeable** and the window calling [close] is allowed to navigate
+ * the window.
+ *
+ * A window is script-closeable if it is either a window
+ * that was opened by another window, or if it is a window with only one
+ * document in its history.
+ *
+ * A window might not be allowed to navigate, and therefore close, another
+ * window due to browser security features.
+ *
+ * var other = window.open('http://www.example.com', 'foo');
+ * // Closes other window, as it is script-closeable.
+ * other.close();
+ * print(other.closed()); // 'true'
+ *
+ * window.location('http://www.mysite.com', 'foo');
+ * // Does not close this window, as the history has changed.
+ * window.close();
+ * print(window.closed()); // 'false'
+ *
+ * See also:
+ *
+ * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
+ */
void close();
void postMessage(var message, String targetOrigin, [List messagePorts = null]);
}
diff --git a/sdk/lib/html/src/KeyCode.dart b/sdk/lib/html/src/KeyCode.dart
index 4faa53d..b2c81b3 100644
--- a/sdk/lib/html/src/KeyCode.dart
+++ b/sdk/lib/html/src/KeyCode.dart
@@ -195,4 +195,34 @@
static const int WIN_KEY = 224;
static const int MAC_FF_META = 224;
static const int WIN_IME = 229;
+
+ /** A sentinel value if the keycode could not be determined. */
+ static const int UNKNOWN = -1;
+
+ /**
+ * Returns true if the keyCode produces a (US keyboard) character.
+ * Note: This does not (yet) cover characters on non-US keyboards (Russian,
+ * Hebrew, etc.).
+ */
+ static bool isCharacterKey(int keyCode) {
+ if ((keyCode >= ZERO && keyCode <= NINE) ||
+ (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
+ (keyCode >= A && keyCode <= Z)) {
+ return true;
+ }
+
+ // Safari sends zero key code for non-latin characters.
+ if (_Device.isWebKit && keyCode == 0) {
+ return true;
+ }
+
+ return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
+ || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
+ keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
+ keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
+ keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
+ keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
+ keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
+ keyCode == CLOSE_SQUARE_BRACKET);
+ }
}
diff --git a/sdk/lib/html/src/KeyboardEventController.dart b/sdk/lib/html/src/KeyboardEventController.dart
new file mode 100644
index 0000000..34da7d5
--- /dev/null
+++ b/sdk/lib/html/src/KeyboardEventController.dart
@@ -0,0 +1,405 @@
+// 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.
+
+part of html;
+
+/**
+ * Works with KeyboardEvent and KeyEvent to determine how to expose information
+ * about Key(board)Events. This class functions like an EventListenerList, and
+ * provides a consistent interface for the Dart
+ * user, despite the fact that a multitude of browsers that have varying
+ * keyboard default behavior.
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyboardEventController {
+ // This code inspired by Closure's KeyHandling library.
+ // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+
+ /**
+ * The set of keys that have been pressed down without seeing their
+ * corresponding keyup event.
+ */
+ List<KeyboardEvent> _keyDownList;
+
+ /** The set of functions that wish to be notified when a KeyEvent happens. */
+ List<Function> _callbacks;
+
+ /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
+ String _type;
+
+ /** The element we are watching for events to happen on. */
+ EventTarget _target;
+
+ // The distance to shift from upper case alphabet Roman letters to lower case.
+ int _ROMAN_ALPHABET_OFFSET = "a".charCodes[0] - "A".charCodes[0];
+
+ // Instance members referring to the internal event handlers because closures
+ // are not hashable.
+ var _keyUp, _keyDown, _keyPress;
+
+ /**
+ * An enumeration of key identifiers currently part of the W3C draft for DOM3
+ * and their mappings to keyCodes.
+ * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+ */
+ static Map<String, int> _keyIdentifier = {
+ 'Up': KeyCode.UP,
+ 'Down': KeyCode.DOWN,
+ 'Left': KeyCode.LEFT,
+ 'Right': KeyCode.RIGHT,
+ 'Enter': KeyCode.ENTER,
+ 'F1': KeyCode.F1,
+ 'F2': KeyCode.F2,
+ 'F3': KeyCode.F3,
+ 'F4': KeyCode.F4,
+ 'F5': KeyCode.F5,
+ 'F6': KeyCode.F6,
+ 'F7': KeyCode.F7,
+ 'F8': KeyCode.F8,
+ 'F9': KeyCode.F9,
+ 'F10': KeyCode.F10,
+ 'F11': KeyCode.F11,
+ 'F12': KeyCode.F12,
+ 'U+007F': KeyCode.DELETE,
+ 'Home': KeyCode.HOME,
+ 'End': KeyCode.END,
+ 'PageUp': KeyCode.PAGE_UP,
+ 'PageDown': KeyCode.PAGE_DOWN,
+ 'Insert': KeyCode.INSERT
+ };
+
+ /** Named constructor to add an onKeyPress event listener to our handler. */
+ KeyboardEventController.keypress(EventTarget target) {
+ _KeyboardEventController(target, 'keypress');
+ }
+
+ /** Named constructor to add an onKeyUp event listener to our handler. */
+ KeyboardEventController.keyup(EventTarget target) {
+ _KeyboardEventController(target, 'keyup');
+ }
+
+ /** Named constructor to add an onKeyDown event listener to our handler. */
+ KeyboardEventController.keydown(EventTarget target) {
+ _KeyboardEventController(target, 'keydown');
+ }
+
+ /**
+ * General constructor, performs basic initialization for our improved
+ * KeyboardEvent controller.
+ */
+ _KeyboardEventController(EventTarget target, String type) {
+ _callbacks = [];
+ _type = type;
+ _target = target;
+ _keyDown = processKeyDown;
+ _keyUp = processKeyUp;
+ _keyPress = processKeyPress;
+ }
+
+ /**
+ * Hook up all event listeners under the covers so we can estimate keycodes
+ * and charcodes when they are not provided.
+ */
+ void _initializeAllEventListeners() {
+ _keyDownList = [];
+ _target.on.keyDown.add(_keyDown, true);
+ _target.on.keyPress.add(_keyPress, true);
+ _target.on.keyUp.add(_keyUp, true);
+ }
+
+ /** Add a callback that wishes to be notified when a KeyEvent occurs. */
+ void add(void callback(KeyEvent)) {
+ if (_callbacks.length == 0) {
+ _initializeAllEventListeners();
+ }
+ _callbacks.add(callback);
+ }
+
+ /**
+ * Notify all callback listeners that a KeyEvent of the relevant type has
+ * occurred.
+ */
+ bool _dispatch(KeyEvent event) {
+ if (event.type == _type) {
+ // Make a copy of the listeners in case a callback gets removed while
+ // dispatching from the list.
+ List callbacksCopy = new List.from(_callbacks);
+ for(var callback in callbacksCopy) {
+ callback(event);
+ }
+ }
+ }
+
+ /** Remove the given callback from the listeners list. */
+ void remove(void callback(KeyEvent)) {
+ var index = _callbacks.indexOf(callback);
+ if (index != -1) {
+ _callbacks.removeAt(index);
+ }
+ if (_callbacks.length == 0) {
+ // If we have no listeners, don't bother keeping track of keypresses.
+ _target.on.keyDown.remove(_keyDown);
+ _target.on.keyPress.remove(_keyPress);
+ _target.on.keyUp.remove(_keyUp);
+ }
+ }
+
+ /** Determine if caps lock is one of the currently depressed keys. */
+ bool get _capsLockOn =>
+ _keyDownList.some((var element) => element.keyCode == KeyCode.CAPS_LOCK);
+
+ /**
+ * Given the previously recorded keydown key codes, see if we can determine
+ * the keycode of this keypress [event]. (Generally browsers only provide
+ * charCode information for keypress events, but with a little
+ * reverse-engineering, we can also determine the keyCode.) Returns
+ * KeyCode.UNKNOWN if the keycode could not be determined.
+ */
+ int _determineKeyCodeForKeypress(KeyboardEvent event) {
+ // Note: This function is a work in progress. We'll expand this function
+ // once we get more information about other keyboards.
+ for (var prevEvent in _keyDownList) {
+ if (prevEvent._shadowCharCode == event.charCode) {
+ return prevEvent.keyCode;
+ }
+ if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".charCodes[0]
+ && event.charCode <= "Z".charCodes[0] && event.charCode +
+ _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
+ return prevEvent.keyCode;
+ }
+ }
+ return KeyCode.UNKNOWN;
+ }
+
+ /**
+ * Given the charater code returned from a keyDown [event], try to ascertain
+ * and return the corresponding charCode for the character that was pressed.
+ * This information is not shown to the user, but used to help polyfill
+ * keypress events.
+ */
+ int _findCharCodeKeyDown(KeyboardEvent event) {
+ if (event.keyLocation == 3) { // Numpad keys.
+ switch (event.keyCode) {
+ case KeyCode.NUM_ZERO:
+ // Even though this function returns _charCodes_, for some cases the
+ // KeyCode == the charCode we want, in which case we use the keycode
+ // constant for readability.
+ return KeyCode.ZERO;
+ case KeyCode.NUM_ONE:
+ return KeyCode.ONE;
+ case KeyCode.NUM_TWO:
+ return KeyCode.TWO;
+ case KeyCode.NUM_THREE:
+ return KeyCode.THREE;
+ case KeyCode.NUM_FOUR:
+ return KeyCode.FOUR;
+ case KeyCode.NUM_FIVE:
+ return KeyCode.FIVE;
+ case KeyCode.NUM_SIX:
+ return KeyCode.SIX;
+ case KeyCode.NUM_SEVEN:
+ return KeyCode.SEVEN;
+ case KeyCode.NUM_EIGHT:
+ return KeyCode.EIGHT;
+ case KeyCode.NUM_NINE:
+ return KeyCode.NINE;
+ case KeyCode.NUM_MULTIPLY:
+ return 42; // Char code for *
+ case KeyCode.NUM_PLUS:
+ return 43; // +
+ case KeyCode.NUM_MINUS:
+ return 45; // -
+ case KeyCode.NUM_PERIOD:
+ return 46; // .
+ case KeyCode.NUM_DIVISION:
+ return 47; // /
+ }
+ } else if (event.keyCode >= 65 && event.keyCode <= 90) {
+ // Set the "char code" for key down as the lower case letter. Again, this
+ // will not show up for the user, but will be helpful in estimating
+ // keyCode locations and other information during the keyPress event.
+ return event.keyCode + _ROMAN_ALPHABET_OFFSET;
+ }
+ switch(event.keyCode) {
+ case KeyCode.SEMICOLON:
+ return KeyCode.FF_SEMICOLON;
+ case KeyCode.EQUALS:
+ return KeyCode.FF_EQUALS;
+ case KeyCode.COMMA:
+ return 44; // Ascii value for ,
+ case KeyCode.DASH:
+ return 45; // -
+ case KeyCode.PERIOD:
+ return 46; // .
+ case KeyCode.SLASH:
+ return 47; // /
+ case KeyCode.APOSTROPHE:
+ return 96; // `
+ case KeyCode.OPEN_SQUARE_BRACKET:
+ return 91; // [
+ case KeyCode.BACKSLASH:
+ return 92; // \
+ case KeyCode.CLOSE_SQUARE_BRACKET:
+ return 93; // ]
+ case KeyCode.SINGLE_QUOTE:
+ return 39; // '
+ }
+ return event.keyCode;
+ }
+
+ /**
+ * Returns true if the key fires a keypress event in the current browser.
+ */
+ bool _firesKeyPressEvent(KeyEvent event) {
+ if (!_Device.isIE && !_Device.isWebKit) {
+ return true;
+ }
+
+ if (_Device.userAgent.contains('Mac') && event.altKey) {
+ return KeyCode.isCharacterKey(event.keyCode);
+ }
+
+ // Alt but not AltGr which is represented as Alt+Ctrl.
+ if (event.altKey && !event.ctrlKey) {
+ return false;
+ }
+
+ // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
+ if (!event.shiftKey &&
+ (_keyDownList.last.keyCode == KeyCode.CTRL ||
+ _keyDownList.last.keyCode == KeyCode.ALT ||
+ _Device.userAgent.contains('Mac') &&
+ _keyDownList.last.keyCode == KeyCode.META)) {
+ return false;
+ }
+
+ // Some keys with Ctrl/Shift do not issue keypress in WebKit.
+ if (_Device.isWebKit && event.ctrlKey && event.shiftKey && (
+ event.keycode == KeyCode.BACKSLASH ||
+ event.keycode == KeyCode.OPEN_SQUARE_BRACKET ||
+ event.keycode == KeyCode.CLOSE_SQUARE_BRACKET ||
+ event.keycode == KeyCode.TILDE ||
+ event.keycode == KeyCode.SEMICOLON || event.keycode == KeyCode.DASH ||
+ event.keycode == KeyCode.EQUALS || event.keycode == KeyCode.COMMA ||
+ event.keycode == KeyCode.PERIOD || event.keycode == KeyCode.SLASH ||
+ event.keycode == KeyCode.APOSTROPHE ||
+ event.keycode == KeyCode.SINGLE_QUOTE)) {
+ return false;
+ }
+
+ switch (event.keyCode) {
+ case KeyCode.ENTER:
+ // IE9 does not fire keypress on ENTER.
+ return !_Device.isIE;
+ case KeyCode.ESC:
+ return !_Device.isWebKit;
+ }
+
+ return KeyCode.isCharacterKey(event.keyCode);
+ }
+
+ /**
+ * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
+ * Opera all use).
+ */
+ int _normalizeKeyCodes(KeyboardEvent event) {
+ // Note: This may change once we get input about non-US keyboards.
+ if (_Device.isFirefox) {
+ switch(event.keyCode) {
+ case KeyCode.FF_EQUALS:
+ return KeyCode.EQUALS;
+ case KeyCode.FF_SEMICOLON:
+ return KeyCode.SEMICOLON;
+ case KeyCode.MAC_FF_META:
+ return KeyCode.META;
+ case KeyCode.WIN_KEY_FF_LINUX:
+ return KeyCode.WIN_KEY;
+ }
+ }
+ return event.keyCode;
+ }
+
+ /** Handle keydown events. */
+ void processKeyDown(KeyboardEvent e) {
+ // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+ // before we've caught a key-up event. If the last-key was one of these
+ // we reset the state.
+ if (_keyDownList.length > 0 &&
+ (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
+ _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
+ _Device.userAgent.contains('Mac') &&
+ _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
+ _keyDownList = [];
+ }
+
+ var event = new KeyEvent(e);
+ event._shadowKeyCode = _normalizeKeyCodes(event);
+ // Technically a "keydown" event doesn't have a charCode. This is
+ // calculated nonetheless to provide us with more information in giving
+ // as much information as possible on keypress about keycode and also
+ // charCode.
+ event._shadowCharCode = _findCharCodeKeyDown(event);
+ if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
+ !_firesKeyPressEvent(event)) {
+ // Some browsers have quirks not firing keypress events where all other
+ // browsers do. This makes them more consistent.
+ processKeyPress(event);
+ }
+ _keyDownList.add(event);
+ _dispatch(event);
+ }
+
+ /** Handle keypress events. */
+ void processKeyPress(KeyboardEvent event) {
+ var e = new KeyEvent(event);
+ // IE reports the character code in the keyCode field for keypress events.
+ // There are two exceptions however, Enter and Escape.
+ if (_Device.isIE) {
+ if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
+ e._shadowCharCode = 0;
+ } else {
+ e._shadowCharCode = e.keyCode;
+ }
+ } else if (_Device.isOpera) {
+ // Opera reports the character code in the keyCode field.
+ e._shadowCharCode = KeyCode.isCharacterKey(keyCode) ? e.keyCode : 0;
+ }
+ // Now we guestimate about what the keycode is that was actually
+ // pressed, given previous keydown information.
+ e._shadowKeyCode = _determineKeyCodeForKeypress(e);
+
+ // Correct the key value for certain browser-specific quirks.
+ if (e._shadowKeyIdentifier &&
+ _keyIdentifier.contains(e._shadowKeyIdentifier)) {
+ // This is needed for Safari Windows because it currently doesn't give a
+ // keyCode/which for non printable keys.
+ e._shadowKeyCode = _keyIdentifier[keyIdentifier];
+ }
+ e._shadowAltKey = _keyDownList.some((var element) => element.altKey);
+ _dispatch(e);
+ }
+
+ /** Handle keyup events. */
+ void processKeyUp(KeyboardEvent event) {
+ var e = new KeyEvent(event);
+ KeyboardEvent toRemove = null;
+ for (var key in _keyDownList) {
+ if (key.keyCode == e.keyCode) {
+ toRemove = key;
+ }
+ }
+ if (toRemove != null) {
+ _keyDownList = _keyDownList.filter((element) => element != toRemove);
+ } else if (_keyDownList.length > 0) {
+ // This happens when we've reached some international keyboard case we
+ // haven't accounted for or we haven't correctly eliminated all browser
+ // inconsistencies. Filing bugs on when this is reached is welcome!
+ _keyDownList.removeLast();
+ }
+ _dispatch(e);
+ }
+}
diff --git a/sdk/lib/html/src/dart2js_FactoryProviders.dart b/sdk/lib/html/src/dart2js_FactoryProviders.dart
index a28e592..09c7efa 100644
--- a/sdk/lib/html/src/dart2js_FactoryProviders.dart
+++ b/sdk/lib/html/src/dart2js_FactoryProviders.dart
@@ -4,14 +4,6 @@
part of html;
-class _AudioContextFactoryProvider {
-
- static AudioContext createAudioContext() {
- return JS('AudioContext',
- 'new (window.AudioContext || window.webkitAudioContext)()');
- }
-}
-
class _PointFactoryProvider {
static Point createPoint(num x, num y) =>
JS('Point', 'new WebKitPoint(#, #)', x, y);
diff --git a/sdk/lib/html/src/dart2js_KeyEvent.dart b/sdk/lib/html/src/dart2js_KeyEvent.dart
new file mode 100644
index 0000000..4974d51
--- /dev/null
+++ b/sdk/lib/html/src/dart2js_KeyEvent.dart
@@ -0,0 +1,103 @@
+/**
+ * A custom KeyboardEvent that attempts to eliminate cross-browser
+ * inconsistencies, and also provide both keyCode and charCode information
+ * for all key events (when such information can be determined).
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyEvent implements KeyboardEvent {
+ /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
+ KeyboardEvent _parent;
+
+ /** The "fixed" value of whether the alt key is being pressed. */
+ bool _shadowAltKey;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int _shadowCharCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int _shadowKeyCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get keyCode => _shadowKeyCode;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
+
+ /** Caculated value of whether the alt key is pressed is for this event. */
+ bool get altKey => _shadowAltKey;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get which => keyCode;
+
+ /** Accessor to the underlying keyCode value is the parent event. */
+ int get _realKeyCode => JS('int', '#.keyCode', _parent);
+
+ /** Accessor to the underlying charCode value is the parent event. */
+ int get _realCharCode => JS('int', '#.charCode', _parent);
+
+ /** Accessor to the underlying altKey value is the parent event. */
+ bool get _realAltKey => JS('int', '#.altKey', _parent);
+
+ /** Construct a KeyEvent with [parent] as event we're emulating. */
+ KeyEvent(KeyboardEvent parent) {
+ _parent = parent;
+ _shadowAltKey = _realAltKey;
+ _shadowCharCode = _realCharCode;
+ _shadowKeyCode = _realKeyCode;
+ }
+
+ /** True if the altGraphKey is pressed during this event. */
+ bool get altGraphKey => _parent.altGraphKey;
+ bool get bubbles => _parent.bubbles;
+ /** True if this event can be cancelled. */
+ bool get cancelable => _parent.cancelable;
+ bool get cancelBubble => _parent.cancelBubble;
+ set cancelBubble(bool cancel) => _parent = cancel;
+ /** Accessor to the clipboardData available for this event. */
+ Clipboard get clipboardData => _parent.clipboardData;
+ /** True if the ctrl key is pressed during this event. */
+ bool get ctrlKey => _parent.ctrlKey;
+ /** Accessor to the target this event is listening to for changes. */
+ EventTarget get currentTarget => _parent.currentTarget;
+ bool get defaultPrevented => _parent.defaultPrevented;
+ int get detail => _parent.detail;
+ int get eventPhase => _parent.eventPhase;
+ /**
+ * Accessor to the part of the keyboard that the key was pressed from (one of
+ * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
+ * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
+ */
+ int get keyLocation => _parent.keyLocation;
+ int get layerX => _parent.layerX;
+ int get layerY => _parent.layerY;
+ /** True if the Meta (or Mac command) key is pressed during this event. */
+ bool get metaKey => _parent.metaKey;
+ int get pageX => _parent.pageX;
+ int get pageY => _parent.pageY;
+ bool get returnValue => _parent.returnValue;
+ set returnValue(bool value) => _parent = value;
+ /** True if the shift key was pressed during this event. */
+ bool get shiftKey => _parent.shiftKey;
+ int get timeStamp => _parent.timeStamp;
+ /**
+ * The type of key event that occurred. One of "keydown", "keyup", or
+ * "keypress".
+ */
+ String get type => _parent.type;
+ Window get view => _parent.view;
+ void preventDefault() => _parent.preventDefault();
+ void stopImmediatePropagation() => _parent.stopImmediatePropagation();
+ void stopPropagation() => _parent.stopPropagation();
+ void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, int detail) {
+ throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
+ }
+ void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
+ bool cancelableArg) {
+ throw new UnsupportedError("Cannot initialize an Event from a KeyEvent.");
+ }
+ String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);
+}
diff --git a/sdk/lib/html/src/dartium_FactoryProviders.dart b/sdk/lib/html/src/dartium_FactoryProviders.dart
index d270c89..c0ac5b9 100644
--- a/sdk/lib/html/src/dartium_FactoryProviders.dart
+++ b/sdk/lib/html/src/dartium_FactoryProviders.dart
@@ -4,14 +4,6 @@
part of html;
-class _AudioContextFactoryProvider {
- static AudioContext createAudioContext() => _createAudioContext();
- static _createAudioContext([int numberOfChannels,
- int numberOfFrames,
- int sampleRate])
- native "AudioContext_constructor_Callback";
-}
-
class _IDBKeyRangeFactoryProvider {
static IDBKeyRange createIDBKeyRange_only(/*IDBKey*/ value) =>
diff --git a/sdk/lib/html/src/dartium_KeyEvent.dart b/sdk/lib/html/src/dartium_KeyEvent.dart
new file mode 100644
index 0000000..6ff5c5b
--- /dev/null
+++ b/sdk/lib/html/src/dartium_KeyEvent.dart
@@ -0,0 +1,103 @@
+/**
+ * A custom KeyboardEvent that attempts to eliminate cross-browser
+ * inconsistencies, and also provide both keyCode and charCode information
+ * for all key events (when such information can be determined).
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyEvent implements KeyboardEvent {
+ /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
+ KeyboardEvent _parent;
+
+ /** The "fixed" value of whether the alt key is being pressed. */
+ bool _shadowAltKey;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int _shadowCharCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int _shadowKeyCode;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get keyCode => _shadowKeyCode;
+
+ /** Caculated value of what the estimated charCode is for this event. */
+ int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
+
+ /** Caculated value of whether the alt key is pressed is for this event. */
+ bool get altKey => _shadowAltKey;
+
+ /** Caculated value of what the estimated keyCode is for this event. */
+ int get which => keyCode;
+
+ /** Accessor to the underlying keyCode value is the parent event. */
+ int get _realKeyCode => _parent.keyCode;
+
+ /** Accessor to the underlying charCode value is the parent event. */
+ int get _realCharCode => _parent.charCode;
+
+ /** Accessor to the underlying altKey value is the parent event. */
+ bool get _realAltKey => _parent.altKey;
+
+ /** Construct a KeyEvent with [parent] as event we're emulating. */
+ KeyEvent(KeyboardEvent parent) {
+ _parent = parent;
+ _shadowAltKey = _realAltKey;
+ _shadowCharCode = _realCharCode;
+ _shadowKeyCode = _realKeyCode;
+ }
+
+ /** True if the altGraphKey is pressed during this event. */
+ bool get altGraphKey => _parent.altGraphKey;
+ bool get bubbles => _parent.bubbles;
+ /** True if this event can be cancelled. */
+ bool get cancelable => _parent.cancelable;
+ bool get cancelBubble => _parent.cancelBubble;
+ set cancelBubble(bool cancel) => _parent = cancel;
+ /** Accessor to the clipboardData available for this event. */
+ Clipboard get clipboardData => _parent.clipboardData;
+ /** True if the ctrl key is pressed during this event. */
+ bool get ctrlKey => _parent.ctrlKey;
+ /** Accessor to the target this event is listening to for changes. */
+ EventTarget get currentTarget => _parent.currentTarget;
+ bool get defaultPrevented => _parent.defaultPrevented;
+ int get detail => _parent.detail;
+ int get eventPhase => _parent.eventPhase;
+ /**
+ * Accessor to the part of the keyboard that the key was pressed from (one of
+ * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
+ * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
+ */
+ int get keyLocation => _parent.keyLocation;
+ int get layerX => _parent.layerX;
+ int get layerY => _parent.layerY;
+ /** True if the Meta (or Mac command) key is pressed during this event. */
+ bool get metaKey => _parent.metaKey;
+ int get pageX => _parent.pageX;
+ int get pageY => _parent.pageY;
+ bool get returnValue => _parent.returnValue;
+ set returnValue(bool value) => _parent = value;
+ /** True if the shift key was pressed during this event. */
+ bool get shiftKey => _parent.shiftKey;
+ int get timeStamp => _parent.timeStamp;
+ /**
+ * The type of key event that occurred. One of "keydown", "keyup", or
+ * "keypress".
+ */
+ String get type => _parent.type;
+ Window get view => _parent.view;
+ void preventDefault() => _parent.preventDefault();
+ void stopImmediatePropagation() => _parent.stopImmediatePropagation();
+ void stopPropagation() => _parent.stopPropagation();
+ void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, int detail) {
+ throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
+ }
+ void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
+ bool cancelableArg) {
+ throw new UnsupportedError("Cannot initialize an Event from a KeyEvent.");
+ }
+ String get _shadowKeyIdentifier => _parent.$dom_keyIdentifier;
+}
diff --git a/sdk/lib/html/src/native_DOMImplementation.dart b/sdk/lib/html/src/native_DOMImplementation.dart
index 1d1eceb..4b8b72a 100644
--- a/sdk/lib/html/src/native_DOMImplementation.dart
+++ b/sdk/lib/html/src/native_DOMImplementation.dart
@@ -51,13 +51,13 @@
_DOMWindowCrossFrame.internal();
// Fields.
- History get history() native "DOMWindow_history_cross_frame_Getter";
- Location get location() native "DOMWindow_location_cross_frame_Getter";
- bool get closed() native "DOMWindow_closed_Getter";
- int get length() native "DOMWindow_length_Getter";
- Window get opener() native "DOMWindow_opener_Getter";
- Window get parent() native "DOMWindow_parent_Getter";
- Window get top() native "DOMWindow_top_Getter";
+ History get history native "DOMWindow_history_cross_frame_Getter";
+ Location get location native "DOMWindow_location_cross_frame_Getter";
+ bool get closed native "DOMWindow_closed_Getter";
+ int get length native "DOMWindow_length_Getter";
+ Window get opener native "DOMWindow_opener_Getter";
+ Window get parent native "DOMWindow_parent_Getter";
+ Window get top native "DOMWindow_top_Getter";
// Methods.
void close() native "DOMWindow_close_Callback";
diff --git a/sdk/lib/html/src/shared_FactoryProviders.dart b/sdk/lib/html/src/shared_FactoryProviders.dart
index 428a60d..8929121 100644
--- a/sdk/lib/html/src/shared_FactoryProviders.dart
+++ b/sdk/lib/html/src/shared_FactoryProviders.dart
@@ -55,7 +55,7 @@
static DocumentFragment createDocumentFragment_html(String html) {
final fragment = new DocumentFragment();
- fragment.innerHTML = html;
+ fragment.innerHtml = html;
return fragment;
}
@@ -63,7 +63,7 @@
// factory DocumentFragment.xml(String xml) {
// final fragment = new DocumentFragment();
// final e = new XMLElement.tag("xml");
- // e.innerHTML = xml;
+ // e.innerHtml = xml;
//
// // Copy list first since we don't want liveness during iteration.
// final List nodes = new List.from(e.nodes);
@@ -74,7 +74,7 @@
static DocumentFragment createDocumentFragment_svg(String svgContent) {
final fragment = new DocumentFragment();
final e = new svg.SVGSVGElement();
- e.innerHTML = svgContent;
+ e.innerHtml = svgContent;
// Copy list first since we don't want liveness during iteration.
final List nodes = new List.from(e.nodes);
diff --git a/sdk/lib/html/src/shared_SVGFactoryProviders.dart b/sdk/lib/html/src/shared_SVGFactoryProviders.dart
index 7a5759a..0fd92a4 100644
--- a/sdk/lib/html/src/shared_SVGFactoryProviders.dart
+++ b/sdk/lib/html/src/shared_SVGFactoryProviders.dart
@@ -22,7 +22,7 @@
parentTag = new SvgSvgElement();
}
- parentTag.innerHTML = svg;
+ parentTag.innerHtml = svg;
if (parentTag.elements.length == 1) return parentTag.elements.removeLast();
throw new ArgumentError(
diff --git a/sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate b/sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate
index b2de0d3..32c14e5 100644
--- a/sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/html_dart2js.darttemplate
@@ -9,15 +9,19 @@
import 'dart:isolate';
import 'dart:json';
+// Not actually used, but imported since dart:html can generate these objects.
import 'dart:svg' as svg;
+import 'dart:web_audio' as web_audio;
$!GENERATED_DART_FILES
+part '$AUXILIARY_DIR/AttributeMap.dart';
part '$AUXILIARY_DIR/CrossFrameTypes.dart';
part '$AUXILIARY_DIR/CssClassSet.dart';
part '$AUXILIARY_DIR/Device.dart';
part '$AUXILIARY_DIR/EventListener.dart';
part '$AUXILIARY_DIR/FilteredElementList.dart';
+part '$AUXILIARY_DIR/KeyboardEventController.dart';
part '$AUXILIARY_DIR/KeyCode.dart';
part '$AUXILIARY_DIR/KeyLocation.dart';
part '$AUXILIARY_DIR/KeyName.dart';
@@ -31,6 +35,7 @@
part '$AUXILIARY_DIR/shared_FactoryProviders.dart';
part '$AUXILIARY_DIR/dart2js_Conversions.dart';
part '$AUXILIARY_DIR/dart2js_DOMImplementation.dart';
+part '$AUXILIARY_DIR/dart2js_KeyEvent.dart';
part '$AUXILIARY_DIR/dart2js_FactoryProviders.dart';
part '$AUXILIARY_DIR/dart2js_IDBKeyRangeFactoryProvider.dart';
part '$AUXILIARY_DIR/dart2js_LocationWrapper.dart';
@@ -50,7 +55,7 @@
// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
-class HTMLElement extends Element native "*HTMLElement" {
+class _HTMLElement extends Element native "*HTMLElement" {
}
// Support for Send/ReceivePortSync.
diff --git a/sdk/lib/html/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
index fc2081d..060434c 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
// TODO(efortuna): Remove these methods when Chrome stable also uses start
diff --git a/sdk/lib/html/templates/html/dart2js/impl_Console.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_Console.darttemplate
index afa4b5b..97f1a20 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_Console.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_Console.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME
// Console is sometimes a singleton bag-of-properties without a prototype.
native "=(typeof console == 'undefined' ? {} : console)" {
diff --git a/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate
index c40b2bb..f34af4b 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_IDBDatabase.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
IDBTransaction transaction(storeName_OR_storeNames, String mode) {
@@ -42,7 +43,8 @@
return db._transaction(stores, intMode);
}
- IDBTransaction _transaction(stores, mode) native 'transaction';
+ @JSName('transaction')
+ IDBTransaction _transaction(stores, mode) native;
static bool _hasNumericMode(txn) =>
JS('bool', 'typeof(#.mode) === "number"', txn);
diff --git a/sdk/lib/html/templates/html/dart2js/impl_KeyboardEvent.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_KeyboardEvent.darttemplate
new file mode 100644
index 0000000..414cc1d
--- /dev/null
+++ b/sdk/lib/html/templates/html/dart2js/impl_KeyboardEvent.darttemplate
@@ -0,0 +1,39 @@
+// 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.
+
+
+/// @domName KeyboardEvent; @docsEditable true
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+ factory $CLASSNAME(String type, Window view,
+ [bool canBubble = true, bool cancelable = true,
+ String keyIdentifier = null, int keyLocation = 1, bool ctrlKey = false,
+ bool altKey = false, bool shiftKey = false, bool metaKey = false,
+ bool altGraphKey = false]) {
+ final e = document.$dom_createEvent("KeyboardEvent");
+ e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+ keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
+ return e;
+ }
+
+ /** @domName KeyboardEvent.initKeyboardEvent */
+ void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+ bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
+ // initKeyEvent is the call in Firefox, initKeyboardEvent for all other
+ // browsers.
+ var function = JS('dynamic', '#.initKeyboardEvent || #.initKeyEvent', this,
+ this);
+ JS('void', '#(#, #, #, #, #, #, #, #, #, #, #)', function, type,
+ canBubble, cancelable, view, keyIdentifier, keyLocation, ctrlKey,
+ altKey, shiftKey, metaKey, altGraphKey);
+ }
+
+ /** @domName KeyboardEvent.keyCode */
+ int get keyCode => $dom_keyCode;
+
+ /** @domName KeyboardEvent.charCode */
+ int get charCode => $dom_charCode;
+$!MEMBERS
+}
diff --git a/sdk/lib/html/templates/html/dart2js/impl_LocalWindow.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_LocalWindow.darttemplate
index 5542bf8..d05349c 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_LocalWindow.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_LocalWindow.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" {
Document get document => JS('Document', '#.document', this);
@@ -24,7 +25,7 @@
// API level getter and setter for Location.
// TODO: The cross domain safe wrapper can be inserted here or folded into
// _LocationWrapper.
- LocalLocation get location() {
+ LocalLocation get location {
// Firefox work-around for Location. The Firefox location object cannot be
// made to behave like a Dart object so must be wrapped.
var result = _location;
@@ -57,7 +58,8 @@
}
// Prevent compiled from thinking 'location' property is available for a Dart
// member.
- _protect_location() native 'location';
+ @JSName('location')
+ _protect_location() native;
static _isDartLocation(thing) {
// On Firefox the code that implements 'is Location' fails to find the patch
@@ -89,11 +91,11 @@
_cancelAnimationFrame(id);
}
- int _requestAnimationFrame(RequestAnimationFrameCallback callback)
- native 'requestAnimationFrame';
+ @JSName('requestAnimationFrame')
+ int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;
- void _cancelAnimationFrame(int id)
- native 'cancelAnimationFrame';
+ @JSName('cancelAnimationFrame')
+ void _cancelAnimationFrame(int id) native;
_ensureRequestAnimationFrame() {
if (JS('bool',
@@ -121,7 +123,7 @@
this);
}
- IDBFactory get indexedDB() =>
+ IDBFactory get indexedDB =>
JS('IDBFactory',
'#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
this, this, this);
diff --git a/sdk/lib/html/templates/html/dart2js/impl_MouseEvent.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_MouseEvent.darttemplate
index 4386d4c..32ad37d 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type, Window view, int detail, int screenX,
int screenY, int clientX, int clientY, int button, [bool canBubble = true,
diff --git a/sdk/lib/html/templates/html/dart2js/impl_SelectElement.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_SelectElement.darttemplate
index 10b2673..f424a19 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_SelectElement.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_SelectElement.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/sdk/lib/html/templates/html/dart2js/impl_TableElement.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_TableElement.darttemplate
index af3eed4..5f8153c 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_TableElement.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_TableElement.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
@@ -16,5 +17,6 @@
return tbody;
}
- Element _createTBody() native 'createTBody';
+ @JSName('createTBody')
+ Element _createTBody() native;
}
diff --git a/sdk/lib/html/templates/html/dart2js/impl_Url.darttemplate b/sdk/lib/html/templates/html/dart2js/impl_Url.darttemplate
index 74019c5e..beb55ec 100644
--- a/sdk/lib/html/templates/html/dart2js/impl_Url.darttemplate
+++ b/sdk/lib/html/templates/html/dart2js/impl_Url.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
static String createObjectUrl(blob_OR_source_OR_stream) =>
diff --git a/sdk/lib/html/templates/html/dart2js/web_audio_dart2js.darttemplate b/sdk/lib/html/templates/html/dart2js/web_audio_dart2js.darttemplate
new file mode 100644
index 0000000..0ab6538
--- /dev/null
+++ b/sdk/lib/html/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -0,0 +1,8 @@
+// DO NOT EDIT
+// Auto-generated dart:audio library.
+
+library web_audio;
+
+import 'dart:html';
+
+$!GENERATED_DART_FILES
diff --git a/sdk/lib/html/templates/html/dartium/html_dartium.darttemplate b/sdk/lib/html/templates/html/dartium/html_dartium.darttemplate
index b357f74..1f6b637 100644
--- a/sdk/lib/html/templates/html/dartium/html_dartium.darttemplate
+++ b/sdk/lib/html/templates/html/dartium/html_dartium.darttemplate
@@ -10,14 +10,18 @@
import 'dart:isolate';
import 'dart:json';
import 'dart:nativewrappers';
+// Not actually used, but imported since dart:html can generate these objects.
import 'dart:svg' as svg;
+import 'dart:web_audio' as web_audio;
$!GENERATED_DART_FILES
+part '$AUXILIARY_DIR/AttributeMap.dart';
part '$AUXILIARY_DIR/CrossFrameTypes.dart';
part '$AUXILIARY_DIR/CssClassSet.dart';
part '$AUXILIARY_DIR/EventListener.dart';
part '$AUXILIARY_DIR/FilteredElementList.dart';
+part '$AUXILIARY_DIR/KeyboardEventController.dart';
part '$AUXILIARY_DIR/KeyCode.dart';
part '$AUXILIARY_DIR/KeyLocation.dart';
part '$AUXILIARY_DIR/KeyName.dart';
@@ -26,6 +30,7 @@
part '$AUXILIARY_DIR/_Collections.dart';
part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
part '$AUXILIARY_DIR/shared_FactoryProviders.dart';
+part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
part '$AUXILIARY_DIR/dartium_FactoryProviders.dart';
part '$AUXILIARY_DIR/Device.dart';
part '$AUXILIARY_DIR/Isolates.dart';
diff --git a/sdk/lib/html/templates/html/dartium/impl_KeyboardEvent.darttemplate b/sdk/lib/html/templates/html/dartium/impl_KeyboardEvent.darttemplate
new file mode 100644
index 0000000..cc66b4f
--- /dev/null
+++ b/sdk/lib/html/templates/html/dartium/impl_KeyboardEvent.darttemplate
@@ -0,0 +1,32 @@
+// 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.
+
+
+/// @domName KeyboardEvent; @docsEditable true
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+ factory $CLASSNAME(String type, Window view,
+ [bool canBubble = true, bool cancelable = true,
+ String keyIdentifier = null, int keyLocation = 1, bool ctrlKey = false,
+ bool altKey = false, bool shiftKey = false, bool metaKey = false,
+ bool altGraphKey = false]) {
+ final e = document.$dom_createEvent("KeyboardEvent");
+ e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+ keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
+ return e;
+ }
+
+ /** @domName KeyboardEvent.initKeyboardEvent */
+ void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+ LocalWindow view, String keyIdentifier, int keyLocation, bool ctrlKey,
+ bool altKey, bool shiftKey, bool metaKey,
+ bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
+
+ /** @domName KeyboardEvent.keyCode */
+ int get keyCode => $dom_keyCode;
+
+ /** @domName KeyboardEvent.charCode */
+ int get charCode => $dom_charCode;
+$!MEMBERS
+}
diff --git a/sdk/lib/html/templates/html/dartium/impl_LocalWindow.darttemplate b/sdk/lib/html/templates/html/dartium/impl_LocalWindow.darttemplate
index 476d8dd..d463470 100644
--- a/sdk/lib/html/templates/html/dartium/impl_LocalWindow.darttemplate
+++ b/sdk/lib/html/templates/html/dartium/impl_LocalWindow.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
/**
diff --git a/sdk/lib/html/templates/html/dartium/impl_MouseEvent.darttemplate b/sdk/lib/html/templates/html/dartium/impl_MouseEvent.darttemplate
index 9042195..bc4e47e 100644
--- a/sdk/lib/html/templates/html/dartium/impl_MouseEvent.darttemplate
+++ b/sdk/lib/html/templates/html/dartium/impl_MouseEvent.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type, Window view, int detail, int screenX,
int screenY, int clientX, int clientY, int button, [bool canBubble = true,
diff --git a/sdk/lib/html/templates/html/dartium/web_audio_dartium.darttemplate b/sdk/lib/html/templates/html/dartium/web_audio_dartium.darttemplate
new file mode 100644
index 0000000..6496166
--- /dev/null
+++ b/sdk/lib/html/templates/html/dartium/web_audio_dartium.darttemplate
@@ -0,0 +1,9 @@
+// DO NOT EDIT
+// Auto-generated dart:audio library.
+
+library web_audio;
+
+import 'dart:html';
+import 'dart:nativewrappers';
+
+$!GENERATED_DART_FILES
diff --git a/sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate b/sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate
index b648c9c..e624fbd 100644
--- a/sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_AudioContext.darttemplate
@@ -4,8 +4,20 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
- factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.create$CLASSNAME();
+$if DART2JS
+ factory AudioContext() => JS('AudioContext',
+ 'new (window.AudioContext || window.webkitAudioContext)()');
+$else
+ factory AudioContext() => _createAudioContext();
+
+ static _createAudioContext([int numberOfChannels,
+ int numberOfFrames,
+ int sampleRate])
+ native "AudioContext_constructor_Callback";
+$endif
+
$!MEMBERS
$if DART2JS
GainNode createGain() {
diff --git a/sdk/lib/html/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/sdk/lib/html/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index 347acfc..2bd9338 100644
--- a/sdk/lib/html/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -21,6 +21,7 @@
return _cachedBrowserPrefix;
}
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.create$CLASSNAME();
factory $CLASSNAME.css(String css) =>
diff --git a/sdk/lib/html/templates/html/impl/impl_CanvasElement.darttemplate b/sdk/lib/html/templates/html/impl/impl_CanvasElement.darttemplate
index 5264681..cb5aa2a 100644
--- a/sdk/lib/html/templates/html/impl/impl_CanvasElement.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_CanvasElement.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/sdk/lib/html/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/sdk/lib/html/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
index 1466cea..eb5ad08 100644
--- a/sdk/lib/html/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/sdk/lib/html/templates/html/impl/impl_CustomEvent.darttemplate b/sdk/lib/html/templates/html/impl/impl_CustomEvent.darttemplate
index 7c84852..e302fb0 100644
--- a/sdk/lib/html/templates/html/impl/impl_CustomEvent.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_CustomEvent.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type, [bool canBubble = true, bool cancelable = true,
Object detail]) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(
diff --git a/sdk/lib/html/templates/html/impl/impl_Document.darttemplate b/sdk/lib/html/templates/html/impl/impl_Document.darttemplate
index 3e7824d..0ddb965 100644
--- a/sdk/lib/html/templates/html/impl/impl_Document.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Document.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME extends Node $NATIVESPEC
{
diff --git a/sdk/lib/html/templates/html/impl/impl_DocumentFragment.darttemplate b/sdk/lib/html/templates/html/impl/impl_DocumentFragment.darttemplate
index 2106a73..6fa79c8 100644
--- a/sdk/lib/html/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -19,6 +19,7 @@
bool get frozen => true;
}
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createDocumentFragment();
@@ -62,21 +63,21 @@
List<Element> queryAll(String selectors) =>
new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
- String get innerHTML {
+ String get innerHtml {
final e = new Element.tag("div");
e.nodes.add(this.clone(true));
- return e.innerHTML;
+ return e.innerHtml;
}
- String get outerHTML => innerHTML;
+ String get outerHtml => innerHtml;
- // TODO(nweiz): Do we want to support some variant of innerHTML for XML and/or
+ // TODO(nweiz): Do we want to support some variant of innerHtml for XML and/or
// SVG strings?
- void set innerHTML(String value) {
+ void set innerHtml(String value) {
this.nodes.clear();
final e = new Element.tag("div");
- e.innerHTML = value;
+ e.innerHtml = value;
// Copy list first since we don't want liveness during iteration.
List nodes = new List.from(e.nodes);
@@ -106,16 +107,20 @@
this._insertAdjacentNode(where, new Text(text));
}
- void insertAdjacentHTML(String where, String text) {
+ void insertAdjacentHtml(String where, String text) {
this._insertAdjacentNode(where, new DocumentFragment.html(text));
}
- void addText(String text) {
+ void append(Element element) {
+ this.children.add(element);
+ }
+
+ void appendText(String text) {
this.insertAdjacentText('beforeend', text);
}
- void addHtml(String text) {
- this.insertAdjacentHTML('beforeend', text);
+ void appendHtml(String text) {
+ this.insertAdjacentHtml('beforeend', text);
}
// If we can come up with a semi-reasonable default value for an Element
@@ -139,7 +144,7 @@
}
return null;
}
- Element get $m_lastElementChild() => elements.last;
+ Element get $m_lastElementChild => elements.last;
Element get nextElementSibling => null;
Element get previousElementSibling => null;
Element get offsetParent => null;
diff --git a/sdk/lib/html/templates/html/impl/impl_Element.darttemplate b/sdk/lib/html/templates/html/impl/impl_Element.darttemplate
index bf6e19a..bae3ab0 100644
--- a/sdk/lib/html/templates/html/impl/impl_Element.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Element.darttemplate
@@ -301,171 +301,6 @@
bool get hasNext => _index < _list.length;
}
-class _ElementAttributeMap implements Map<String, String> {
-
- final Element _element;
-
- _ElementAttributeMap(this._element);
-
- bool containsValue(String value) {
- final attributes = _element.$dom_attributes;
- for (int i = 0, len = attributes.length; i < len; i++) {
- if(value == attributes[i].value) {
- return true;
- }
- }
- return false;
- }
-
- bool containsKey(String key) {
- return _element.$dom_hasAttribute(key);
- }
-
- String operator [](String key) {
- return _element.$dom_getAttribute(key);
- }
-
- void operator []=(String key, value) {
- _element.$dom_setAttribute(key, '$value');
- }
-
- String putIfAbsent(String key, String ifAbsent()) {
- if (!containsKey(key)) {
- this[key] = ifAbsent();
- }
- return this[key];
- }
-
- String remove(String key) {
- String value = _element.$dom_getAttribute(key);
- _element.$dom_removeAttribute(key);
- return value;
- }
-
- void clear() {
- final attributes = _element.$dom_attributes;
- for (int i = attributes.length - 1; i >= 0; i--) {
- remove(attributes[i].name);
- }
- }
-
- void forEach(void f(String key, String value)) {
- final attributes = _element.$dom_attributes;
- for (int i = 0, len = attributes.length; i < len; i++) {
- final item = attributes[i];
- f(item.name, item.value);
- }
- }
-
- Collection<String> get keys {
- // TODO(jacobr): generate a lazy collection instead.
- final attributes = _element.$dom_attributes;
- final keys = new List<String>(attributes.length);
- for (int i = 0, len = attributes.length; i < len; i++) {
- keys[i] = attributes[i].name;
- }
- return keys;
- }
-
- Collection<String> get values {
- // TODO(jacobr): generate a lazy collection instead.
- final attributes = _element.$dom_attributes;
- final values = new List<String>(attributes.length);
- for (int i = 0, len = attributes.length; i < len; i++) {
- values[i] = attributes[i].value;
- }
- return values;
- }
-
- /**
- * The number of {key, value} pairs in the map.
- */
- int get length {
- return _element.$dom_attributes.length;
- }
-
- /**
- * Returns true if there is no {key, value} pair in the map.
- */
- bool get isEmpty {
- return length == 0;
- }
-}
-
-/**
- * Provides a Map abstraction on top of data-* attributes, similar to the
- * dataSet in the old DOM.
- */
-class _DataAttributeMap implements Map<String, String> {
-
- final Map<String, String> $dom_attributes;
-
- _DataAttributeMap(this.$dom_attributes);
-
- // interface Map
-
- // TODO: Use lazy iterator when it is available on Map.
- bool containsValue(String value) => values.some((v) => v == value);
-
- bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
-
- String operator [](String key) => $dom_attributes[_attr(key)];
-
- void operator []=(String key, value) {
- $dom_attributes[_attr(key)] = '$value';
- }
-
- String putIfAbsent(String key, String ifAbsent()) =>
- $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
-
- String remove(String key) => $dom_attributes.remove(_attr(key));
-
- void clear() {
- // Needs to operate on a snapshot since we are mutating the collection.
- for (String key in keys) {
- remove(key);
- }
- }
-
- void forEach(void f(String key, String value)) {
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- f(_strip(key), value);
- }
- });
- }
-
- Collection<String> get keys {
- final keys = new List<String>();
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- keys.add(_strip(key));
- }
- });
- return keys;
- }
-
- Collection<String> get values {
- final values = new List<String>();
- $dom_attributes.forEach((String key, String value) {
- if (_matches(key)) {
- values.add(value);
- }
- });
- return values;
- }
-
- int get length => keys.length;
-
- // TODO: Use lazy iterator when it is available on Map.
- bool get isEmpty => length == 0;
-
- // Helpers.
- String _attr(String key) => 'data-$key';
- bool _matches(String key) => key.startsWith('data-');
- String _strip(String key) => key.substring(5);
-}
-
class _ElementCssClassSet extends CssClassSet {
final Element _element;
@@ -491,24 +326,7 @@
}
}
-class _SimpleClientRect implements ClientRect {
- final num left;
- final num top;
- final num width;
- final num height;
- num get right => left + width;
- num get bottom => top + height;
-
- const _SimpleClientRect(this.left, this.top, this.width, this.height);
-
- bool operator ==(ClientRect other) {
- return other != null && left == other.left && top == other.top
- && width == other.width && height == other.height;
- }
-
- String toString() => "($left, $top, $width, $height)";
-}
-
+/// @domName $DOMNAME
abstract class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME.html(String html) =>
@@ -530,6 +348,14 @@
}
}
+ /**
+ * Deprecated, use innerHtml instead.
+ */
+ String get innerHTML => this.innerHtml;
+ void set innerHTML(String value) {
+ this.innerHtml = value;
+ }
+
void set elements(Collection<Element> value) {
this.children = value;
}
@@ -578,6 +404,14 @@
}
}
+ /**
+ * Gets a map for manipulating the attributes of a particular namespace.
+ * This is primarily useful for SVG attributes such as xref:link.
+ */
+ Map<String, String> getNamespacedAttributes(String namespace) {
+ return new _NamespacedAttributeMap(this, namespace);
+ }
+
/** @domName Window.getComputedStyle */
Future<CSSStyleDeclaration> get computedStyle {
// TODO(jacobr): last param should be null, see b/5045788
@@ -592,9 +426,16 @@
}
/**
+ * Adds the specified element to after the last child of this.
+ */
+ void append(Element e) {
+ this.children.add(e);
+ }
+
+ /**
* Adds the specified text as a text node after the last child of this.
*/
- void addText(String text) {
+ void appendText(String text) {
this.insertAdjacentText('beforeend', text);
}
@@ -602,8 +443,8 @@
* Parses the specified text as HTML and adds the resulting node after the
* last child of this.
*/
- void addHtml(String text) {
- this.insertAdjacentHTML('beforeend', text);
+ void appendHtml(String text) {
+ this.insertAdjacentHtml('beforeend', text);
}
// Hooks to support custom WebComponents.
@@ -651,20 +492,20 @@
}
}
- void _insertAdjacentText(String where, String text)
- native 'insertAdjacentText';
+ @JSName('insertAdjacentText')
+ void _insertAdjacentText(String where, String text) native;
/** @domName Element.insertAdjacentHTML */
- void insertAdjacentHTML(String where, String text) {
- if (JS('bool', '!!#.insertAdjacentHTML', this)) {
- _insertAdjacentHTML(where, text);
+ void insertAdjacentHtml(String where, String text) {
+ if (JS('bool', '!!#.insertAdjacentHtml', this)) {
+ _insertAdjacentHtml(where, text);
} else {
_insertAdjacentNode(where, new DocumentFragment.html(text));
}
}
- void _insertAdjacentHTML(String where, String text)
- native 'insertAdjacentHTML';
+ @JSName('insertAdjacentHTML')
+ void _insertAdjacentHTML(String where, String text) native;
/** @domName Element.insertAdjacentHTML */
Element insertAdjacentElement(String where, Element element) {
@@ -676,8 +517,8 @@
return element;
}
- void _insertAdjacentElement(String where, Element element)
- native 'insertAdjacentElement';
+ @JSName('insertAdjacentElement')
+ void _insertAdjacentElement(String where, Element element) native;
void _insertAdjacentNode(String where, Node node) {
switch (where.toLowerCase()) {
@@ -741,7 +582,7 @@
}
}
final Element temp = new Element.tag(parentTag);
- temp.innerHTML = html;
+ temp.innerHtml = html;
Element element;
if (temp.children.length == 1) {
diff --git a/sdk/lib/html/templates/html/impl/impl_Event.darttemplate b/sdk/lib/html/templates/html/impl/impl_Event.darttemplate
index deead54..c1cf096 100644
--- a/sdk/lib/html/templates/html/impl/impl_Event.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Event.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
// In JS, canBubble and cancelable are technically required parameters to
// init*Event. In practice, though, if they aren't provided they simply
diff --git a/sdk/lib/html/templates/html/impl/impl_EventTarget.darttemplate b/sdk/lib/html/templates/html/impl/impl_EventTarget.darttemplate
index da4a6c2..a602e94 100644
--- a/sdk/lib/html/templates/html/impl/impl_EventTarget.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_EventTarget.darttemplate
@@ -49,7 +49,7 @@
}
}
-
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
/** @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent */
diff --git a/sdk/lib/html/templates/html/impl/impl_HtmlDocument.darttemplate b/sdk/lib/html/templates/html/impl/impl_HtmlDocument.darttemplate
index a4b8033..918f83a 100644
--- a/sdk/lib/html/templates/html/impl/impl_HtmlDocument.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_HtmlDocument.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
/** @domName Document.body */
diff --git a/sdk/lib/html/templates/html/impl/impl_HttpRequest.darttemplate b/sdk/lib/html/templates/html/impl/impl_HttpRequest.darttemplate
index 213f434..8a834a7 100644
--- a/sdk/lib/html/templates/html/impl/impl_HttpRequest.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_HttpRequest.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME.get(String url, onComplete($CLASSNAME request)) =>
_$(CLASSNAME)FactoryProvider.create$(CLASSNAME)_get(url, onComplete);
diff --git a/sdk/lib/html/templates/html/impl/impl_IDBKeyRange.darttemplate b/sdk/lib/html/templates/html/impl/impl_IDBKeyRange.darttemplate
index 2b60eba..253134f 100644
--- a/sdk/lib/html/templates/html/impl/impl_IDBKeyRange.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_IDBKeyRange.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
/**
* @domName IDBKeyRange.only
diff --git a/sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate b/sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate
index 2bfbd2e..dda5aee 100644
--- a/sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_MutationObserver.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
void observe(Node target,
@@ -75,6 +76,7 @@
static _fixupList(list) => list; // TODO: Ensure is a JavaScript Array.
// Call native function with no conversions.
- void _call(target, options) native 'observe';
+ @JSName('observe')
+ void _call(target, options) native;
$endif
}
diff --git a/sdk/lib/html/templates/html/impl/impl_Node.darttemplate b/sdk/lib/html/templates/html/impl/impl_Node.darttemplate
index cf46de2..a2f4e0a 100644
--- a/sdk/lib/html/templates/html/impl/impl_Node.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Node.darttemplate
@@ -112,6 +112,7 @@
Node operator[](int index) => _this.$dom_childNodes[index];
}
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
_ChildNodeListLazy get nodes {
return new _ChildNodeListLazy(this);
diff --git a/sdk/lib/html/templates/html/impl/impl_Point.darttemplate b/sdk/lib/html/templates/html/impl/impl_Point.darttemplate
index 1ce9455..bfa4684 100644
--- a/sdk/lib/html/templates/html/impl/impl_Point.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Point.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(num x, num y) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(x, y);
$!MEMBERS
diff --git a/sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate b/sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate
index 50f732b..9f0649b 100644
--- a/sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_ShadowRoot.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
$if DART2JS
diff --git a/sdk/lib/html/templates/html/impl/impl_Storage.darttemplate b/sdk/lib/html/templates/html/impl/impl_Storage.darttemplate
index 47d10d6..a48e3da 100644
--- a/sdk/lib/html/templates/html/impl/impl_Storage.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Storage.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS implements Map<String, String> $NATIVESPEC {
// TODO(nweiz): update this when maps support lazy iteration
diff --git a/sdk/lib/html/templates/html/impl/impl_SvgElement.darttemplate b/sdk/lib/html/templates/html/impl/impl_SvgElement.darttemplate
index 1c15a0f..df0ed3b 100644
--- a/sdk/lib/html/templates/html/impl/impl_SvgElement.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_SvgElement.darttemplate
@@ -31,6 +31,7 @@
}
}
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME.tag(String tag) =>
_$(CLASSNAME)FactoryProvider.create$(CLASSNAME)_tag(tag);
@@ -61,25 +62,25 @@
children.addAll(value);
}
- String get outerHTML {
+ String get outerHtml {
final container = new Element.tag("div");
final SvgElement cloned = this.clone(true);
container.children.add(cloned);
- return container.innerHTML;
+ return container.innerHtml;
}
- String get innerHTML {
+ String get innerHtml {
final container = new Element.tag("div");
final SvgElement cloned = this.clone(true);
container.children.addAll(cloned.children);
- return container.innerHTML;
+ return container.innerHtml;
}
- void set innerHTML(String svg) {
+ void set innerHtml(String svg) {
final container = new Element.tag("div");
// Wrap the SVG string in <svg> so that SvgElements are created, rather than
// HTMLElements.
- container.innerHTML = '<svg version="1.1">$svg</svg>';
+ container.innerHtml = '<svg version="1.1">$svg</svg>';
this.children = container.children[0].children;
}
diff --git a/sdk/lib/html/templates/html/impl/impl_SvgSvgElement.darttemplate b/sdk/lib/html/templates/html/impl/impl_SvgSvgElement.darttemplate
index 2e00aea..cc7ba42 100644
--- a/sdk/lib/html/templates/html/impl/impl_SvgSvgElement.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_SvgSvgElement.darttemplate
@@ -4,6 +4,7 @@
part of svg;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createSvgSvgElement();
diff --git a/sdk/lib/html/templates/html/impl/impl_Text.darttemplate b/sdk/lib/html/templates/html/impl/impl_Text.darttemplate
index 6f8560f..74e385c 100644
--- a/sdk/lib/html/templates/html/impl/impl_Text.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_Text.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String data) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(data);
$!MEMBERS
diff --git a/sdk/lib/html/templates/html/impl/impl_UIEvent.darttemplate b/sdk/lib/html/templates/html/impl/impl_UIEvent.darttemplate
new file mode 100644
index 0000000..ce957c8
--- /dev/null
+++ b/sdk/lib/html/templates/html/impl/impl_UIEvent.darttemplate
@@ -0,0 +1,24 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+part of html;
+
+/// @domName $DOMNAME; @docsEditable true
+class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+ // In JS, canBubble and cancelable are technically required parameters to
+ // init*Event. In practice, though, if they aren't provided they simply
+ // default to false (since that's Boolean(undefined)).
+ //
+ // Contrary to JS, we default canBubble and cancelable to true, since that's
+ // what people want most of the time anyway.
+ factory $CLASSNAME(String type, Window view, int detail,
+ [bool canBubble = true, bool cancelable = true]) {
+ final e = document.$dom_createEvent("UIEvent");
+ e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
+ return e;
+ }
+$!MEMBERS
+}
diff --git a/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate b/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate
index 564c30f..6fb4d40 100644
--- a/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_WebSocket.darttemplate
@@ -6,6 +6,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String url) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(url);
$!MEMBERS
diff --git a/sdk/lib/html/templates/html/impl/impl_WheelEvent.darttemplate b/sdk/lib/html/templates/html/impl/impl_WheelEvent.darttemplate
index c0fad3f..d660a21 100644
--- a/sdk/lib/html/templates/html/impl/impl_WheelEvent.darttemplate
+++ b/sdk/lib/html/templates/html/impl/impl_WheelEvent.darttemplate
@@ -4,6 +4,7 @@
part of html;
+/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 85968f1..ecf7959 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -51,27 +51,55 @@
return (result == 1);
}
+ Future<int> _computeExistingIndex(List dirsToCreate) {
+ var future;
+ for (var i = 0; i < dirsToCreate.length; i++) {
+ if (future == null) {
+ future = dirsToCreate[i].exists().transform((e) => e ? i : -1);
+ } else {
+ future = future.chain((index) {
+ if (index != -1) {
+ return new Future.immediate(index);
+ }
+ return dirsToCreate[i].exists().transform((e) => e ? i : -1);
+ });
+ }
+ }
+ if (future == null) {
+ return new Future.immedidate(-1);
+ } else {
+ return future;
+ }
+ }
+
Future<Directory> createRecursively() {
if (_path is !String) {
throw new ArgumentError();
}
var path = new Path.fromNative(_path);
- var current = new Path(path.isAbsolute ? '/' : '');
- var future = null;
- for (var segment in path.segments()) {
- var next = current.append(segment);
- if (future == null) {
- future = new Directory.fromPath(current).create();
- } else {
- future = future.chain((_) => new Directory.fromPath(next).create());
+ var dirsToCreate = [];
+ var terminator = path.isAbsolute ? '/' : '';
+ while (path.toString() != terminator) {
+ dirsToCreate.add(new Directory.fromPath(path));
+ path = path.directoryPath;
+ }
+ return _computeExistingIndex(dirsToCreate).chain((index) {
+ var future;
+ for (var i = index - 1; i >= 0 ; i--) {
+ if (future == null) {
+ future = dirsToCreate[i].create();
+ } else {
+ future = future.chain((_) {
+ return dirsToCreate[i].create();
+ });
+ }
}
- current = next;
- }
- if (future == null) {
- return new Future.immediate(this);
- } else {
- return future.transform((result) => this);
- }
+ if (future == null) {
+ return new Future.immediate(this);
+ } else {
+ return future.transform((_) => this);
+ }
+ });
}
Future<Directory> create({recursive: false}) {
@@ -90,10 +118,16 @@
void createRecursivelySync() {
var path = new Path.fromNative(_path);
- var current = new Path(path.isAbsolute ? '/' : '');
- for (var segment in path.segments()) {
- current = current.append(segment);
- new Directory.fromPath(current).createSync();
+ var dirsToCreate = [];
+ var terminator = path.isAbsolute ? '/' : '';
+ while (path.toString() != terminator) {
+ var dir = new Directory.fromPath(path);
+ if (dir.existsSync()) break;
+ dirsToCreate.add(dir);
+ path = path.directoryPath;
+ }
+ for (var i = dirsToCreate.length - 1; i >= 0; i--) {
+ dirsToCreate[i].createSync();
}
}
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 7937aa0..bef2d68 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -304,6 +304,17 @@
int readByteSync();
/**
+ * Reads from a file and returns the result as a list of bytes.
+ */
+ Future<List<int>> read(int bytes);
+
+ /**
+ * Synchronously reads from a file and returns the result in a
+ * list of bytes.
+ */
+ List<int> readSync(int bytes);
+
+ /**
* Read a List<int> from the file. Returns a [:Future<int>:] that
* completes with an indication of how much was read.
*/
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 17dc2ab..0d7a548 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -65,22 +65,15 @@
_closeFile();
return;
}
- // If there is currently a _fillBuffer call waiting on readList,
+ // If there is currently a _fillBuffer call waiting on read,
// let it fill the buffer instead of us.
if (_activeFillBufferCall) return;
_activeFillBufferCall = true;
- if (_data.length != size) {
- _data = new Uint8List(size);
- // Maintain the invariant signalling that the buffer is empty.
- _position = _data.length;
- }
- var future = _openedFile.readList(_data, 0, _data.length);
- future.then((read) {
- _filePosition += read;
- if (read != _data.length) {
- _data = _data.getRange(0, read);
- }
+ var future = _openedFile.read(size);
+ future.then((data) {
+ _data = data;
_position = 0;
+ _filePosition += _data.length;
_activeFillBufferCall = false;
if (_fileLength == _filePosition) {
@@ -319,8 +312,9 @@
const int _FLUSH_REQUEST = 13;
const int _READ_BYTE_REQUEST = 14;
const int _WRITE_BYTE_REQUEST = 15;
-const int _READ_LIST_REQUEST = 16;
-const int _WRITE_LIST_REQUEST = 17;
+const int _READ_REQUEST = 16;
+const int _READ_LIST_REQUEST = 17;
+const int _WRITE_LIST_REQUEST = 18;
// Base class for _File and _RandomAccessFile with shared functions.
class _FileBase {
@@ -787,6 +781,43 @@
return result;
}
+ Future<List<int>> read(int bytes) {
+ _ensureFileService();
+ Completer<List<int>> completer = new Completer<List<int>>();
+ if (bytes is !int) {
+ // Complete asynchronously so the user has a chance to setup
+ // handlers without getting exceptions when registering the
+ // then handler.
+ new Timer(0, (t) {
+ completer.completeException(new FileIOException(
+ "Invalid arguments to read for file '$_name'"));
+ });
+ return completer.future;
+ };
+ if (closed) return _completeWithClosedException(completer);
+ List request = new List(3);
+ request[0] = _READ_REQUEST;
+ request[1] = _id;
+ request[2] = bytes;
+ return _fileService.call(request).transform((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionFromResponse(response,
+ "read failed for file '$_name'");
+ }
+ return response[1];
+ });
+ }
+
+ external static _read(int id, int bytes);
+
+ List<int> readSync(int bytes) {
+ if (bytes is !int) {
+ throw new FileIOException(
+ "Invalid arguments to readSync for file '$_name'");
+ }
+ return _read(_id, bytes);
+ }
+
Future<int> readList(List<int> buffer, int offset, int bytes) {
_ensureFileService();
Completer<int> completer = new Completer<int>();
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 2274673..5c8a2f0 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -62,11 +62,16 @@
* Start listening for HTTP requests on the specified [host] and
* [port]. If a [port] of 0 is specified the server will choose an
* ephemeral port. The optional argument [backlog] can be used to
- * specify the listen backlog for the underlying OS listen
- * setup. See [addRequestHandler] and [defaultRequestHandler] for
+ * specify the listen backlog for the underlying OS listen.
+ * The optional argument [certificate_name] is used by the HttpsServer
+ * class, which shares the same interface.
+ * See [addRequestHandler] and [defaultRequestHandler] for
* information on how incoming HTTP requests are handled.
*/
- void listen(String host, int port, {int backlog: 128});
+ void listen(String host,
+ int port,
+ {int backlog: 128,
+ String certificate_name});
/**
* Attach the HTTP server to an existing [:ServerSocket:]. If the
@@ -127,6 +132,14 @@
/**
+ * HTTPS server.
+ */
+abstract class HttpsServer implements HttpServer {
+ factory HttpsServer() => new _HttpServer.httpsServer();
+}
+
+
+/**
* Overview information of the [:HttpServer:] socket connections.
*/
class HttpConnectionsInfo {
@@ -734,6 +747,7 @@
*/
abstract class HttpClient {
static const int DEFAULT_HTTP_PORT = 80;
+ static const int DEFAULT_HTTPS_PORT = 443;
factory HttpClient() => new _HttpClient();
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index c783481..5539f3a 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -925,17 +925,40 @@
// HTTP server waiting for socket connections. The connections are
// managed by the server and as requests are received the request.
-class _HttpServer implements HttpServer {
- _HttpServer() : _connections = new Set<_HttpConnection>(),
- _handlers = new List<_RequestHandlerRegistration>(),
- _closeQueue = new _CloseQueue();
+// HTTPS connections are also supported, if the _HttpServer.httpsServer
+// constructor is used and a certificate name is provided in listen,
+// or a SecureServerSocket is provided to listenOn.
+class _HttpServer implements HttpServer, HttpsServer {
+ _HttpServer() : this._internal(isSecure: false);
- void listen(String host, int port, {int backlog: 128}) {
- listenOn(new ServerSocket(host, port, backlog));
+ _HttpServer.httpsServer() : this._internal(isSecure: true);
+
+ _HttpServer._internal({ bool isSecure: false })
+ : _secure = isSecure,
+ _connections = new Set<_HttpConnection>(),
+ _handlers = new List<_RequestHandlerRegistration>(),
+ _closeQueue = new _CloseQueue();
+
+ void listen(String host,
+ int port,
+ {int backlog: 128,
+ String certificate_name}) {
+ if (_secure) {
+ listenOn(new SecureServerSocket(host, port, backlog, certificate_name));
+ } else {
+ listenOn(new ServerSocket(host, port, backlog));
+ }
_closeServer = true;
}
void listenOn(ServerSocket serverSocket) {
+ if (_secure && serverSocket is! SecureServerSocket) {
+ throw new HttpException(
+ 'HttpsServer.listenOn was called with non-secure server socket');
+ } else if (!_secure && serverSocket is SecureServerSocket) {
+ throw new HttpException(
+ 'HttpServer.listenOn was called with a secure server socket');
+ }
void onConnection(Socket socket) {
// Accept the client connection.
_HttpConnection connection = new _HttpConnection(this);
@@ -1051,6 +1074,7 @@
ServerSocket _server; // The server listen socket.
bool _closeServer = false;
+ bool _secure;
Set<_HttpConnection> _connections; // Set of currently connected clients.
List<_RequestHandlerRegistration> _handlers;
Object _defaultHandler;
@@ -1463,18 +1487,19 @@
}
void _onError(e) {
+ // Cancel any pending data in the HTTP parser.
+ _httpParser.cancel();
if (_socketConn != null) {
_client._closeSocketConnection(_socketConn);
}
- if (_onErrorCallback != null) {
+ // Report the error.
+ if (_response != null && _response._streamErrorHandler != null) {
+ _response._streamErrorHandler(e);
+ } else if (_onErrorCallback != null) {
_onErrorCallback(e);
} else {
throw e;
}
- // Propagate the error to the streams.
- if (_response != null && _response._streamErrorHandler != null) {
- _response._streamErrorHandler(e);
- }
}
void _onResponseReceived(int statusCode,
@@ -1704,7 +1729,7 @@
HttpClientConnection _openUrl(String method,
Uri url,
[_HttpClientConnection connection]) {
- if (url.scheme != "http") {
+ if (url.scheme != "http" && url.scheme != "https") {
throw new HttpException("Unsupported URL scheme ${url.scheme}");
}
return _open(method, url, connection);
@@ -1743,8 +1768,8 @@
});
if (force) {
_activeSockets.forEach((_SocketConnection socketConn) {
- socketConn._socket.close();
socketConn._httpClientConnection._onClientShutdown();
+ socketConn._close();
});
}
if (_evictionTimer != null) _cancelEvictionTimer();
@@ -1769,7 +1794,8 @@
int port,
_ProxyConfiguration proxyConfiguration,
int proxyIndex,
- bool reusedConnection) {
+ bool reusedConnection,
+ bool secure) {
void _connectionOpened(_SocketConnection socketConn,
_HttpClientConnection connection,
@@ -1821,8 +1847,15 @@
// otherwise create a new one.
String key = _connectionKey(connectHost, connectPort);
Queue socketConnections = _openSockets[key];
+ // Remove active connections that are of the wrong type (HTTP or HTTPS).
+ while (socketConnections != null &&
+ !socketConnections.isEmpty &&
+ secure != (socketConnections.first._socket is SecureSocket)) {
+ socketConnection.removeFirst()._close();
+ }
if (socketConnections == null || socketConnections.isEmpty) {
- Socket socket = new Socket(connectHost, connectPort);
+ Socket socket = secure ? new SecureSocket(connectHost, connectPort) :
+ new Socket(connectHost, connectPort);
// Until the connection is established handle connection errors
// here as the HttpClientConnection object is not yet associated
// with the socket.
@@ -1831,7 +1864,7 @@
if (proxyIndex < proxyConfiguration.proxies.length) {
// Try the next proxy in the list.
_establishConnection(
- host, port, proxyConfiguration, proxyIndex, false);
+ host, port, proxyConfiguration, proxyIndex, false, secure);
} else {
// Report the error through the HttpClientConnection object to
// the client.
@@ -1845,7 +1878,7 @@
// the connected socket.
socket.onError = null;
_SocketConnection socketConn =
- new _SocketConnection(connectHost, connectPort, socket);
+ new _SocketConnection(connectHost, connectPort, socket);
_activeSockets.add(socketConn);
_connectionOpened(socketConn, connection, !proxy.isDirect);
};
@@ -1861,10 +1894,17 @@
}
}
+ // Find out if we want a secure socket.
+ bool is_secure = (url.scheme == "https");
+
// Find the TCP host and port.
String host = url.domain;
- int port = url.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : url.port;
-
+ int port = url.port;
+ if (port == 0) {
+ port = is_secure ?
+ HttpClient.DEFAULT_HTTPS_PORT :
+ HttpClient.DEFAULT_HTTP_PORT;
+ }
// Create a new connection object if we are not re-using an existing one.
var reusedConnection = false;
if (connection == null) {
@@ -1883,7 +1923,12 @@
}
// Establish the connection starting with the first proxy configured.
- _establishConnection(host, port, proxyConfiguration, 0, reusedConnection);
+ _establishConnection(host,
+ port,
+ proxyConfiguration,
+ 0,
+ reusedConnection,
+ is_secure);
return connection;
}
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index 1acd7eb..05db7ad 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -72,7 +72,8 @@
static const int BODY = 24;
static const int CLOSED = 25;
static const int UPGRADED = 26;
- static const int FAILURE = 27;
+ static const int CANCELED = 27;
+ static const int FAILURE = 28;
static const int FIRST_BODY_STATE = CHUNK_SIZE_STARTING_CR;
}
@@ -152,8 +153,12 @@
if (_state == _State.FAILURE) {
throw new HttpParserException("Data on failed connection");
}
+ if (_state == _State.CANCELED) {
+ throw new HttpParserException("Data on canceled connection");
+ }
while (_buffer != null &&
_index < _lastIndex &&
+ _state != _State.CANCELED &&
_state != _State.FAILURE &&
_state != _State.UPGRADED) {
int byte = _buffer[_index++];
@@ -450,6 +455,7 @@
version,
_headers);
}
+ if (_state == _State.CANCELED) continue;
_method_or_status_code.clear();
_uri_or_reason_phrase.clear();
if (!_connectionUpgrade) {
@@ -464,6 +470,7 @@
// If there is no message body get ready to process the
// next request.
_bodyEnd();
+ if (_state == _State.CANCELED) continue;
_reset();
} else if (_contentLength > 0) {
_remainingContent = _contentLength;
@@ -520,6 +527,7 @@
case _State.CHUNKED_BODY_DONE_LF:
_expect(byte, _CharCode.LF);
_bodyEnd();
+ if (_state == _State.CANCELED) continue;
_reset();
break;
@@ -538,6 +546,7 @@
}
dataReceived(data);
+ if (_state == _State.CANCELED) continue;
if (_remainingContent != null) {
_remainingContent -= data.length;
}
@@ -545,6 +554,7 @@
if (_remainingContent == 0) {
if (!_chunked) {
_bodyEnd();
+ if (_state == _State.CANCELED) continue;
_reset();
} else {
_state = _State.CHUNK_SIZE_STARTING_CR;
@@ -641,6 +651,10 @@
return null;
}
+ void cancel() {
+ _state = _State.CANCELED;
+ }
+
int get messageType => _messageType;
int get contentLength => _contentLength;
bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED;
diff --git a/sdk/lib/io/path.dart b/sdk/lib/io/path.dart
index 4061f7e..dcf492e 100644
--- a/sdk/lib/io/path.dart
+++ b/sdk/lib/io/path.dart
@@ -19,9 +19,25 @@
/**
* Creates a Path from a String that uses the native filesystem's conventions.
- * On Windows, this converts '\' to '/', and adds a '/' before a drive letter.
+ *
+ * On Windows, this converts '\' to '/' and has special handling for drive
+ * letters and shares.
+ *
+ * If the path contains a drive letter a '/' is added before the drive letter.
+ *
+ * new Path.fromNative(r'c:\a\b').toString() == '/c:/a/b'
+ *
* A path starting with '/c:/' (or any other character instead of 'c') is
* treated specially. Backwards links ('..') cannot cancel the drive letter.
+ *
+ * If the path is a share path this is recorded in the Path object and
+ * maintained in operations on the Path object.
+ *
+ * var share = new Path.fromNative(r'\\share\a\b\c');
+ * share.isWindowsShare == true
+ * share.toString() == '/share/a/b/c'
+ * share.toNativePath() == r'\\share\a\b\c'
+ * share.append('final').isWindowsShare == true
*/
factory Path.fromNative(String source) => new _Path.fromNative(source);
@@ -36,6 +52,11 @@
bool get isAbsolute;
/**
+ * Is this path a Windows share path?
+ */
+ bool get isWindowsShare;
+
+ /**
* Does this path end with a path separator?
*/
bool get hasTrailingSeparator;
diff --git a/sdk/lib/io/path_impl.dart b/sdk/lib/io/path_impl.dart
index 58e7ce3..2a661e0 100644
--- a/sdk/lib/io/path_impl.dart
+++ b/sdk/lib/io/path_impl.dart
@@ -4,31 +4,38 @@
class _Path implements Path {
final String _path;
+ final bool isWindowsShare;
- _Path(String source) : _path = source;
- _Path.fromNative(String source) : _path = _clean(source);
+ _Path(String source) : _path = source, isWindowsShare = false;
- int get hashCode => _path.hashCode;
+ _Path.fromNative(String source)
+ : _path = _clean(source), isWindowsShare = _isWindowsShare(source);
+
+ _Path._internal(String this._path, bool this.isWindowsShare);
static String _clean(String source) {
- switch (Platform.operatingSystem) {
- case 'windows':
- return _cleanWindows(source);
- default:
- return source;
- }
+ if (Platform.operatingSystem == 'windows') return _cleanWindows(source);
+ return source;
}
- static String _cleanWindows(source) {
+ static String _cleanWindows(String source) {
// Change \ to /.
var clean = source.replaceAll('\\', '/');
// Add / before intial [Drive letter]:
if (clean.length >= 2 && clean[1] == ':') {
clean = '/$clean';
}
+ if (_isWindowsShare(source)) {
+ return clean.substring(1, clean.length);
+ }
return clean;
}
+ static bool _isWindowsShare(String source) {
+ return Platform.operatingSystem == 'windows' && source.startsWith('\\\\');
+ }
+
+ int get hashCode => _path.hashCode;
bool get isEmpty => _path.isEmpty;
bool get isAbsolute => _path.startsWith('/');
bool get hasTrailingSeparator => _path.endsWith('/');
@@ -42,7 +49,8 @@
// Throws an exception if no such path exists, or the case is not
// implemented yet.
var basePath = base.toString();
- if (base.isAbsolute && _path.startsWith(basePath)) {
+ if (base.isAbsolute && _path.startsWith(basePath) &&
+ base.isWindowsShare == isWindowsShare) {
if (_path == basePath) return new Path('.');
if (base.hasTrailingSeparator) {
return new Path(_path.substring(basePath.length));
@@ -50,7 +58,8 @@
if (_path[basePath.length] == '/') {
return new Path(_path.substring(basePath.length + 1));
}
- } else if (base.isAbsolute && isAbsolute) {
+ } else if (base.isAbsolute && isAbsolute &&
+ base.isWindowsShare == isWindowsShare) {
List<String> baseSegments = base.canonicalize().segments();
List<String> pathSegments = canonicalize().segments();
int common = 0;
@@ -90,9 +99,11 @@
return further.canonicalize();
}
if (hasTrailingSeparator) {
- return new Path('$_path${further}').canonicalize();
+ var joined = new _Path._internal('$_path${further}', isWindowsShare);
+ return joined.canonicalize();
}
- return new Path('$_path/${further}').canonicalize();
+ var joined = new _Path._internal('$_path/${further}', isWindowsShare);
+ return joined.canonicalize();
}
// Note: The URI RFC names for these operations are normalize, resolve, and
@@ -182,7 +193,8 @@
segmentsToJoin.add('');
}
}
- return new Path(Strings.join(segmentsToJoin, '/'));
+ return new _Path._internal(Strings.join(segmentsToJoin, '/'),
+ isWindowsShare);
}
String toNativePath() {
@@ -195,6 +207,9 @@
nativePath = nativePath.substring(1);
}
nativePath = nativePath.replaceAll('/', '\\');
+ if (isWindowsShare) {
+ return '\\$nativePath';
+ }
return nativePath;
}
return _path;
@@ -209,11 +224,11 @@
Path append(String finalSegment) {
if (isEmpty) {
- return new Path(finalSegment);
+ return new _Path._internal(finalSegment, isWindowsShare);
} else if (hasTrailingSeparator) {
- return new Path('$_path$finalSegment');
+ return new _Path._internal('$_path$finalSegment', isWindowsShare);
} else {
- return new Path('$_path/$finalSegment');
+ return new _Path._internal('$_path/$finalSegment', isWindowsShare);
}
}
@@ -234,7 +249,8 @@
int pos = _path.lastIndexOf('/');
if (pos < 0) return new Path('');
while (pos > 0 && _path[pos - 1] == '/') --pos;
- return new Path((pos > 0) ? _path.substring(0, pos) : '/');
+ var dirPath = (pos > 0) ? _path.substring(0, pos) : '/';
+ return new _Path._internal(dirPath, isWindowsShare);
}
String get filename {
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 9efbacb..5d894d4 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -78,6 +78,7 @@
_socket.onConnect = _secureConnectHandler;
_socket.onData = _secureDataHandler;
_socket.onClosed = _secureCloseHandler;
+ _socket.onError = _secureErrorHandler;
_secureFilter.init();
_secureFilter.registerHandshakeCompleteCallback(_secureHandshakeCompleteHandler);
}
@@ -89,7 +90,7 @@
int get remotePort => _socket.remotePort;
void set onClosed(void callback()) {
- if (_inputStream != null) {
+ if (_inputStream != null && callback != null) {
throw new StreamException(
"Cannot set close handler when input stream is used");
}
@@ -101,10 +102,6 @@
}
void set onConnect(void callback()) {
- if (_outputStream != null) {
- throw new StreamException(
- "Cannot set connect handler when output stream is used");
- }
if (_status == CONNECTED || _status == CLOSED) {
throw new StreamException(
"Cannot set connect handler when already connected");
@@ -117,7 +114,7 @@
}
void set onData(void callback()) {
- if (_outputStream != null) {
+ if (_outputStream != null && callback != null) {
throw new StreamException(
"Cannot set data handler when input stream is used");
}
@@ -128,8 +125,12 @@
_socketDataHandler = callback;
}
+ void set onError(void callback(e)) {
+ _socketErrorHandler = callback;
+ }
+
void set onWrite(void callback()) {
- if (_outputStream != null) {
+ if (_outputStream != null && callback != null) {
throw new StreamException(
"Cannot set write handler when output stream is used");
}
@@ -155,9 +156,9 @@
OutputStream get outputStream {
if (_outputStream == null) {
- if (_socketConnectHandler != null || _socketWriteHandler != null) {
+ if (_socketWriteHandler != null) {
throw new StreamException(
- "Cannot get output stream when socket handlers are used");
+ "Cannot get output stream when socket write handler is used");
}
_outputStream = new _SocketOutputStream(this);
}
@@ -168,7 +169,7 @@
throw new UnimplementedError("SecureSocket.available not implemented yet");
}
- void close([bool halfClose]) {
+ void close([bool halfClose = false]) {
if (halfClose) {
_closedWrite = true;
_writeEncryptedData();
@@ -314,6 +315,35 @@
}
}
+ void _secureErrorHandler(e) {
+ _reportError(e, 'Error on underlying Socket');
+ }
+
+ void _reportError(error, String message) {
+ // TODO(whesse): Call _reportError from all internal functions that throw.
+ var e;
+ if (error is SocketIOException) {
+ e = new SocketIOException('$message (${error.message})', error.osError);
+ } else if (error is OSError) {
+ e = new SocketIOException(message, error);
+ } else {
+ e = new SocketIOException('$message (${error.toString()})', null);
+ }
+ bool reported = false;
+ if (_socketErrorHandler != null) {
+ reported = true;
+ _socketErrorHandler(e);
+ }
+ if (_inputStream != null) {
+ reported = reported || _inputStream._onSocketError(e);
+ }
+ if (_outputStream != null) {
+ reported = reported || _outputStream._onSocketError(e);
+ }
+
+ if (!reported) throw e;
+ }
+
void _secureCloseHandler() {
_socketClosedRead = true;
if (_filterReadEmpty) {
@@ -494,6 +524,7 @@
Function _socketConnectHandler;
Function _socketWriteHandler;
Function _socketDataHandler;
+ Function _socketErrorHandler;
Function _socketCloseHandler;
Timer scheduledDataEvent;
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index d018a6d..be4cb44 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -31,7 +31,7 @@
parentTag = new SvgSvgElement();
}
- parentTag.innerHTML = svg;
+ parentTag.innerHtml = svg;
if (parentTag.elements.length == 1) return parentTag.elements.removeLast();
throw new ArgumentError(
@@ -86,16 +86,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -762,16 +765,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -838,16 +844,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -902,10 +911,12 @@
void setColor(int colorType, String rgbColor, String iccColor) native;
/// @domName SVGColor.setRGBColor; @docsEditable true
- void setRGBColor(String rgbColor) native;
+ @JSName('setRGBColor')
+ void setRgbColor(String rgbColor) native;
/// @domName SVGColor.setRGBColorICCColor; @docsEditable true
- void setRGBColorICCColor(String rgbColor, String iccColor) native;
+ @JSName('setRGBColorICCColor')
+ void setRgbColorIccColor(String rgbColor, String iccColor) native;
}
// 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
@@ -1023,16 +1034,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1081,6 +1095,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1258,16 +1273,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1301,32 +1319,6 @@
// BSD-style license that can be found in the LICENSE file.
-/// @domName SVGException; @docsEditable true
-class Exception native "*SVGException" {
-
- static const int SVG_INVALID_VALUE_ERR = 1;
-
- static const int SVG_MATRIX_NOT_INVERTABLE = 2;
-
- static const int SVG_WRONG_TYPE_ERR = 0;
-
- /// @domName SVGException.code; @docsEditable true
- final int code;
-
- /// @domName SVGException.message; @docsEditable true
- final String message;
-
- /// @domName SVGException.name; @docsEditable true
- final String name;
-
- /// @domName SVGException.toString; @docsEditable true
- String toString() native;
-}
-// 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.
-
-
/// @domName SVGExternalResourcesRequired
abstract class ExternalResourcesRequired {
@@ -1380,6 +1372,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1435,6 +1428,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1474,6 +1468,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1545,6 +1540,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1625,6 +1621,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1676,6 +1673,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1737,6 +1735,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1805,6 +1804,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1841,6 +1841,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1921,6 +1922,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -1973,6 +1975,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2014,6 +2017,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2082,6 +2086,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2127,6 +2132,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2192,6 +2198,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2263,6 +2270,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2329,6 +2337,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2390,6 +2399,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2424,7 +2434,7 @@
// From SVGStylable
- AnimatedString className;
+ AnimatedString $dom_svgClassName;
CSSStyleDeclaration style;
@@ -2550,16 +2560,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2623,16 +2636,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2699,6 +2715,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2745,6 +2762,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -2819,16 +2837,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -3086,16 +3107,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -3262,6 +3286,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -3314,6 +3339,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -3606,61 +3632,80 @@
final PathSegList pathSegList;
/// @domName SVGPathElement.createSVGPathSegArcAbs; @docsEditable true
- PathSegArcAbs createSVGPathSegArcAbs(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native;
+ @JSName('createSVGPathSegArcAbs')
+ PathSegArcAbs createSvgPathSegArcAbs(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native;
/// @domName SVGPathElement.createSVGPathSegArcRel; @docsEditable true
- PathSegArcRel createSVGPathSegArcRel(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native;
+ @JSName('createSVGPathSegArcRel')
+ PathSegArcRel createSvgPathSegArcRel(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native;
/// @domName SVGPathElement.createSVGPathSegClosePath; @docsEditable true
- PathSegClosePath createSVGPathSegClosePath() native;
+ @JSName('createSVGPathSegClosePath')
+ PathSegClosePath createSvgPathSegClosePath() native;
/// @domName SVGPathElement.createSVGPathSegCurvetoCubicAbs; @docsEditable true
- PathSegCurvetoCubicAbs createSVGPathSegCurvetoCubicAbs(num x, num y, num x1, num y1, num x2, num y2) native;
+ @JSName('createSVGPathSegCurvetoCubicAbs')
+ PathSegCurvetoCubicAbs createSvgPathSegCurvetoCubicAbs(num x, num y, num x1, num y1, num x2, num y2) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoCubicRel; @docsEditable true
- PathSegCurvetoCubicRel createSVGPathSegCurvetoCubicRel(num x, num y, num x1, num y1, num x2, num y2) native;
+ @JSName('createSVGPathSegCurvetoCubicRel')
+ PathSegCurvetoCubicRel createSvgPathSegCurvetoCubicRel(num x, num y, num x1, num y1, num x2, num y2) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoCubicSmoothAbs; @docsEditable true
- PathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs(num x, num y, num x2, num y2) native;
+ @JSName('createSVGPathSegCurvetoCubicSmoothAbs')
+ PathSegCurvetoCubicSmoothAbs createSvgPathSegCurvetoCubicSmoothAbs(num x, num y, num x2, num y2) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoCubicSmoothRel; @docsEditable true
- PathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel(num x, num y, num x2, num y2) native;
+ @JSName('createSVGPathSegCurvetoCubicSmoothRel')
+ PathSegCurvetoCubicSmoothRel createSvgPathSegCurvetoCubicSmoothRel(num x, num y, num x2, num y2) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoQuadraticAbs; @docsEditable true
- PathSegCurvetoQuadraticAbs createSVGPathSegCurvetoQuadraticAbs(num x, num y, num x1, num y1) native;
+ @JSName('createSVGPathSegCurvetoQuadraticAbs')
+ PathSegCurvetoQuadraticAbs createSvgPathSegCurvetoQuadraticAbs(num x, num y, num x1, num y1) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoQuadraticRel; @docsEditable true
- PathSegCurvetoQuadraticRel createSVGPathSegCurvetoQuadraticRel(num x, num y, num x1, num y1) native;
+ @JSName('createSVGPathSegCurvetoQuadraticRel')
+ PathSegCurvetoQuadraticRel createSvgPathSegCurvetoQuadraticRel(num x, num y, num x1, num y1) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoQuadraticSmoothAbs; @docsEditable true
- PathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs(num x, num y) native;
+ @JSName('createSVGPathSegCurvetoQuadraticSmoothAbs')
+ PathSegCurvetoQuadraticSmoothAbs createSvgPathSegCurvetoQuadraticSmoothAbs(num x, num y) native;
/// @domName SVGPathElement.createSVGPathSegCurvetoQuadraticSmoothRel; @docsEditable true
- PathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel(num x, num y) native;
+ @JSName('createSVGPathSegCurvetoQuadraticSmoothRel')
+ PathSegCurvetoQuadraticSmoothRel createSvgPathSegCurvetoQuadraticSmoothRel(num x, num y) native;
/// @domName SVGPathElement.createSVGPathSegLinetoAbs; @docsEditable true
- PathSegLinetoAbs createSVGPathSegLinetoAbs(num x, num y) native;
+ @JSName('createSVGPathSegLinetoAbs')
+ PathSegLinetoAbs createSvgPathSegLinetoAbs(num x, num y) native;
/// @domName SVGPathElement.createSVGPathSegLinetoHorizontalAbs; @docsEditable true
- PathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs(num x) native;
+ @JSName('createSVGPathSegLinetoHorizontalAbs')
+ PathSegLinetoHorizontalAbs createSvgPathSegLinetoHorizontalAbs(num x) native;
/// @domName SVGPathElement.createSVGPathSegLinetoHorizontalRel; @docsEditable true
- PathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel(num x) native;
+ @JSName('createSVGPathSegLinetoHorizontalRel')
+ PathSegLinetoHorizontalRel createSvgPathSegLinetoHorizontalRel(num x) native;
/// @domName SVGPathElement.createSVGPathSegLinetoRel; @docsEditable true
- PathSegLinetoRel createSVGPathSegLinetoRel(num x, num y) native;
+ @JSName('createSVGPathSegLinetoRel')
+ PathSegLinetoRel createSvgPathSegLinetoRel(num x, num y) native;
/// @domName SVGPathElement.createSVGPathSegLinetoVerticalAbs; @docsEditable true
- PathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs(num y) native;
+ @JSName('createSVGPathSegLinetoVerticalAbs')
+ PathSegLinetoVerticalAbs createSvgPathSegLinetoVerticalAbs(num y) native;
/// @domName SVGPathElement.createSVGPathSegLinetoVerticalRel; @docsEditable true
- PathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel(num y) native;
+ @JSName('createSVGPathSegLinetoVerticalRel')
+ PathSegLinetoVerticalRel createSvgPathSegLinetoVerticalRel(num y) native;
/// @domName SVGPathElement.createSVGPathSegMovetoAbs; @docsEditable true
- PathSegMovetoAbs createSVGPathSegMovetoAbs(num x, num y) native;
+ @JSName('createSVGPathSegMovetoAbs')
+ PathSegMovetoAbs createSvgPathSegMovetoAbs(num x, num y) native;
/// @domName SVGPathElement.createSVGPathSegMovetoRel; @docsEditable true
- PathSegMovetoRel createSVGPathSegMovetoRel(num x, num y) native;
+ @JSName('createSVGPathSegMovetoRel')
+ PathSegMovetoRel createSvgPathSegMovetoRel(num x, num y) native;
/// @domName SVGPathElement.getPathSegAtLength; @docsEditable true
int getPathSegAtLength(num distance) native;
@@ -3696,16 +3741,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -4285,6 +4333,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -4320,6 +4369,7 @@
// WARNING: Do not edit - generated code.
+/// @domName SVGPoint
class Point native "*SVGPoint" {
factory Point(num x, num y) => _PointFactoryProvider.createPoint(x, y);
@@ -4406,16 +4456,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -4485,16 +4538,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -4666,16 +4722,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -4772,6 +4831,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -4906,7 +4966,7 @@
/// @domName SVGStylable
abstract class Stylable {
- AnimatedString className;
+ AnimatedString $dom_svgClassName;
CSSStyleDeclaration style;
@@ -4961,7 +5021,8 @@
final SvgSvgElement rootElement;
/// @domName SVGDocument.createEvent; @docsEditable true
- Event $dom_createEvent(String eventType) native "createEvent";
+ @JSName('createEvent')
+ Event $dom_createEvent(String eventType) native;
}
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -4995,6 +5056,7 @@
}
}
+/// @domName SVGElement
class SvgElement extends Element native "*SVGElement" {
factory SvgElement.tag(String tag) =>
_SvgElementFactoryProvider.createSvgElement_tag(tag);
@@ -5025,25 +5087,25 @@
children.addAll(value);
}
- String get outerHTML {
+ String get outerHtml {
final container = new Element.tag("div");
final SvgElement cloned = this.clone(true);
container.children.add(cloned);
- return container.innerHTML;
+ return container.innerHtml;
}
- String get innerHTML {
+ String get innerHtml {
final container = new Element.tag("div");
final SvgElement cloned = this.clone(true);
container.children.addAll(cloned.children);
- return container.innerHTML;
+ return container.innerHtml;
}
- void set innerHTML(String svg) {
+ void set innerHtml(String svg) {
final container = new Element.tag("div");
// Wrap the SVG string in <svg> so that SvgElements are created, rather than
// HTMLElements.
- container.innerHTML = '<svg version="1.1">$svg</svg>';
+ container.innerHtml = '<svg version="1.1">$svg</svg>';
this.children = container.children[0].children;
}
@@ -5058,7 +5120,8 @@
}
/// @domName SVGElement.ownerSVGElement; @docsEditable true
- final SvgSvgElement ownerSVGElement;
+ @JSName('ownerSVGElement')
+ final SvgSvgElement ownerSvgElement;
/// @domName SVGElement.viewportElement; @docsEditable true
final SvgElement viewportElement;
@@ -5072,6 +5135,33 @@
// BSD-style license that can be found in the LICENSE file.
+/// @domName SVGException; @docsEditable true
+class SvgException native "*SVGException" {
+
+ static const int SVG_INVALID_VALUE_ERR = 1;
+
+ static const int SVG_MATRIX_NOT_INVERTABLE = 2;
+
+ static const int SVG_WRONG_TYPE_ERR = 0;
+
+ /// @domName SVGException.code; @docsEditable true
+ final int code;
+
+ /// @domName SVGException.message; @docsEditable true
+ final String message;
+
+ /// @domName SVGException.name; @docsEditable true
+ final String name;
+
+ /// @domName SVGException.toString; @docsEditable true
+ String toString() native;
+}
+// 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.
+
+
+/// @domName SVGSVGElement
class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace native "*SVGSVGElement" {
factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
@@ -5131,28 +5221,36 @@
bool checkIntersection(SvgElement element, Rect rect) native;
/// @domName SVGSVGElement.createSVGAngle; @docsEditable true
- Angle createSVGAngle() native;
+ @JSName('createSVGAngle')
+ Angle createSvgAngle() native;
/// @domName SVGSVGElement.createSVGLength; @docsEditable true
- Length createSVGLength() native;
+ @JSName('createSVGLength')
+ Length createSvgLength() native;
/// @domName SVGSVGElement.createSVGMatrix; @docsEditable true
- Matrix createSVGMatrix() native;
+ @JSName('createSVGMatrix')
+ Matrix createSvgMatrix() native;
/// @domName SVGSVGElement.createSVGNumber; @docsEditable true
- Number createSVGNumber() native;
+ @JSName('createSVGNumber')
+ Number createSvgNumber() native;
/// @domName SVGSVGElement.createSVGPoint; @docsEditable true
- Point createSVGPoint() native;
+ @JSName('createSVGPoint')
+ Point createSvgPoint() native;
/// @domName SVGSVGElement.createSVGRect; @docsEditable true
- Rect createSVGRect() native;
+ @JSName('createSVGRect')
+ Rect createSvgRect() native;
/// @domName SVGSVGElement.createSVGTransform; @docsEditable true
- Transform createSVGTransform() native;
+ @JSName('createSVGTransform')
+ Transform createSvgTransform() native;
/// @domName SVGSVGElement.createSVGTransformFromMatrix; @docsEditable true
- Transform createSVGTransformFromMatrix(Matrix matrix) native;
+ @JSName('createSVGTransformFromMatrix')
+ Transform createSvgTransformFromMatrix(Matrix matrix) native;
/// @domName SVGSVGElement.deselectAll; @docsEditable true
void deselectAll() native;
@@ -5167,11 +5265,11 @@
Element getElementById(String elementId) native;
/// @domName SVGSVGElement.getEnclosureList; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> getEnclosureList(Rect rect, SvgElement referenceElement) native;
/// @domName SVGSVGElement.getIntersectionList; @docsEditable true
- @Returns('_NodeList') @Creates('_NodeList')
+ @Returns('NodeList') @Creates('NodeList')
List<Node> getIntersectionList(Rect rect, SvgElement referenceElement) native;
/// @domName SVGSVGElement.pauseAnimations; @docsEditable true
@@ -5225,16 +5323,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -5299,16 +5400,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -5370,6 +5474,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -5483,6 +5588,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -5528,10 +5634,12 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
@@ -5618,6 +5726,7 @@
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
@@ -5782,7 +5891,8 @@
Transform consolidate() native;
/// @domName SVGTransformList.createSVGTransformFromMatrix; @docsEditable true
- Transform createSVGTransformFromMatrix(Matrix matrix) native;
+ @JSName('createSVGTransformFromMatrix')
+ Transform createSvgTransformFromMatrix(Matrix matrix) native;
/// @domName SVGTransformList.getItem; @docsEditable true
Transform getItem(int index) native;
@@ -5904,16 +6014,19 @@
Rect getBBox() native;
/// @domName SVGLocatable.getCTM; @docsEditable true
- Matrix getCTM() native;
+ @JSName('getCTM')
+ Matrix getCtm() native;
/// @domName SVGLocatable.getScreenCTM; @docsEditable true
- Matrix getScreenCTM() native;
+ @JSName('getScreenCTM')
+ Matrix getScreenCtm() native;
/// @domName SVGLocatable.getTransformToElement; @docsEditable true
Matrix getTransformToElement(SvgElement element) native;
// From SVGStylable
+ // Shadowing definition.
/// @domName SVGStylable.className; @docsEditable true
AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 9a60401..490443c 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -32,7 +32,7 @@
parentTag = new SvgSvgElement();
}
- parentTag.innerHTML = svg;
+ parentTag.innerHtml = svg;
if (parentTag.elements.length == 1) return parentTag.elements.removeLast();
throw new ArgumentError(
@@ -100,11 +100,11 @@
/** @domName SVGAElement.getCTM */
- Matrix getCTM() native "SVGAElement_getCTM_Callback";
+ Matrix getCtm() native "SVGAElement_getCTM_Callback";
/** @domName SVGAElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGAElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGAElement_getScreenCTM_Callback";
/** @domName SVGAElement.getTransformToElement */
@@ -957,11 +957,11 @@
/** @domName SVGCircleElement.getCTM */
- Matrix getCTM() native "SVGCircleElement_getCTM_Callback";
+ Matrix getCtm() native "SVGCircleElement_getCTM_Callback";
/** @domName SVGCircleElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGCircleElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGCircleElement_getScreenCTM_Callback";
/** @domName SVGCircleElement.getTransformToElement */
@@ -1051,11 +1051,11 @@
/** @domName SVGClipPathElement.getCTM */
- Matrix getCTM() native "SVGClipPathElement_getCTM_Callback";
+ Matrix getCtm() native "SVGClipPathElement_getCTM_Callback";
/** @domName SVGClipPathElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGClipPathElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGClipPathElement_getScreenCTM_Callback";
/** @domName SVGClipPathElement.getTransformToElement */
@@ -1127,11 +1127,11 @@
/** @domName SVGColor.setRGBColor */
- void setRGBColor(String rgbColor) native "SVGColor_setRGBColor_Callback";
+ void setRgbColor(String rgbColor) native "SVGColor_setRGBColor_Callback";
/** @domName SVGColor.setRGBColorICCColor */
- void setRGBColorICCColor(String rgbColor, String iccColor) native "SVGColor_setRGBColorICCColor_Callback";
+ void setRgbColorIccColor(String rgbColor, String iccColor) native "SVGColor_setRGBColorICCColor_Callback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -1279,11 +1279,11 @@
/** @domName SVGDefsElement.getCTM */
- Matrix getCTM() native "SVGDefsElement_getCTM_Callback";
+ Matrix getCtm() native "SVGDefsElement_getCTM_Callback";
/** @domName SVGDefsElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGDefsElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGDefsElement_getScreenCTM_Callback";
/** @domName SVGDefsElement.getTransformToElement */
@@ -1559,11 +1559,11 @@
/** @domName SVGEllipseElement.getCTM */
- Matrix getCTM() native "SVGEllipseElement_getCTM_Callback";
+ Matrix getCtm() native "SVGEllipseElement_getCTM_Callback";
/** @domName SVGEllipseElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGEllipseElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGEllipseElement_getScreenCTM_Callback";
/** @domName SVGEllipseElement.getTransformToElement */
@@ -1609,40 +1609,6 @@
// WARNING: Do not edit - generated code.
-/// @domName SVGException
-class Exception extends NativeFieldWrapperClass1 {
- Exception.internal();
-
- static const int SVG_INVALID_VALUE_ERR = 1;
-
- static const int SVG_MATRIX_NOT_INVERTABLE = 2;
-
- static const int SVG_WRONG_TYPE_ERR = 0;
-
-
- /** @domName SVGException.code */
- int get code native "SVGException_code_Getter";
-
-
- /** @domName SVGException.message */
- String get message native "SVGException_message_Getter";
-
-
- /** @domName SVGException.name */
- String get name native "SVGException_name_Getter";
-
-
- /** @domName SVGException.toString */
- String toString() native "SVGException_toString_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
/// @domName SVGExternalResourcesRequired
class ExternalResourcesRequired extends NativeFieldWrapperClass1 {
ExternalResourcesRequired.internal();
@@ -3209,11 +3175,11 @@
/** @domName SVGForeignObjectElement.getCTM */
- Matrix getCTM() native "SVGForeignObjectElement_getCTM_Callback";
+ Matrix getCtm() native "SVGForeignObjectElement_getCTM_Callback";
/** @domName SVGForeignObjectElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGForeignObjectElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGForeignObjectElement_getScreenCTM_Callback";
/** @domName SVGForeignObjectElement.getTransformToElement */
@@ -3299,11 +3265,11 @@
/** @domName SVGGElement.getCTM */
- Matrix getCTM() native "SVGGElement_getCTM_Callback";
+ Matrix getCtm() native "SVGGElement_getCTM_Callback";
/** @domName SVGGElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGGElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGGElement_getScreenCTM_Callback";
/** @domName SVGGElement.getTransformToElement */
@@ -3565,11 +3531,11 @@
/** @domName SVGImageElement.getCTM */
- Matrix getCTM() native "SVGImageElement_getCTM_Callback";
+ Matrix getCtm() native "SVGImageElement_getCTM_Callback";
/** @domName SVGImageElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGImageElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGImageElement_getScreenCTM_Callback";
/** @domName SVGImageElement.getTransformToElement */
@@ -3902,11 +3868,11 @@
/** @domName SVGLineElement.getCTM */
- Matrix getCTM() native "SVGLineElement_getCTM_Callback";
+ Matrix getCtm() native "SVGLineElement_getCTM_Callback";
/** @domName SVGLineElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGLineElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGLineElement_getScreenCTM_Callback";
/** @domName SVGLineElement.getTransformToElement */
@@ -4000,11 +3966,11 @@
/** @domName SVGLocatable.getCTM */
- Matrix getCTM() native "SVGLocatable_getCTM_Callback";
+ Matrix getCtm() native "SVGLocatable_getCTM_Callback";
/** @domName SVGLocatable.getScreenCTM */
- Matrix getScreenCTM() native "SVGLocatable_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGLocatable_getScreenCTM_Callback";
/** @domName SVGLocatable.getTransformToElement */
@@ -4581,79 +4547,79 @@
/** @domName SVGPathElement.createSVGPathSegArcAbs */
- PathSegArcAbs createSVGPathSegArcAbs(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native "SVGPathElement_createSVGPathSegArcAbs_Callback";
+ PathSegArcAbs createSvgPathSegArcAbs(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native "SVGPathElement_createSVGPathSegArcAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegArcRel */
- PathSegArcRel createSVGPathSegArcRel(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native "SVGPathElement_createSVGPathSegArcRel_Callback";
+ PathSegArcRel createSvgPathSegArcRel(num x, num y, num r1, num r2, num angle, bool largeArcFlag, bool sweepFlag) native "SVGPathElement_createSVGPathSegArcRel_Callback";
/** @domName SVGPathElement.createSVGPathSegClosePath */
- PathSegClosePath createSVGPathSegClosePath() native "SVGPathElement_createSVGPathSegClosePath_Callback";
+ PathSegClosePath createSvgPathSegClosePath() native "SVGPathElement_createSVGPathSegClosePath_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoCubicAbs */
- PathSegCurvetoCubicAbs createSVGPathSegCurvetoCubicAbs(num x, num y, num x1, num y1, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicAbs_Callback";
+ PathSegCurvetoCubicAbs createSvgPathSegCurvetoCubicAbs(num x, num y, num x1, num y1, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoCubicRel */
- PathSegCurvetoCubicRel createSVGPathSegCurvetoCubicRel(num x, num y, num x1, num y1, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicRel_Callback";
+ PathSegCurvetoCubicRel createSvgPathSegCurvetoCubicRel(num x, num y, num x1, num y1, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicRel_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoCubicSmoothAbs */
- PathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs(num x, num y, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicSmoothAbs_Callback";
+ PathSegCurvetoCubicSmoothAbs createSvgPathSegCurvetoCubicSmoothAbs(num x, num y, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicSmoothAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoCubicSmoothRel */
- PathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel(num x, num y, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicSmoothRel_Callback";
+ PathSegCurvetoCubicSmoothRel createSvgPathSegCurvetoCubicSmoothRel(num x, num y, num x2, num y2) native "SVGPathElement_createSVGPathSegCurvetoCubicSmoothRel_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoQuadraticAbs */
- PathSegCurvetoQuadraticAbs createSVGPathSegCurvetoQuadraticAbs(num x, num y, num x1, num y1) native "SVGPathElement_createSVGPathSegCurvetoQuadraticAbs_Callback";
+ PathSegCurvetoQuadraticAbs createSvgPathSegCurvetoQuadraticAbs(num x, num y, num x1, num y1) native "SVGPathElement_createSVGPathSegCurvetoQuadraticAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoQuadraticRel */
- PathSegCurvetoQuadraticRel createSVGPathSegCurvetoQuadraticRel(num x, num y, num x1, num y1) native "SVGPathElement_createSVGPathSegCurvetoQuadraticRel_Callback";
+ PathSegCurvetoQuadraticRel createSvgPathSegCurvetoQuadraticRel(num x, num y, num x1, num y1) native "SVGPathElement_createSVGPathSegCurvetoQuadraticRel_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoQuadraticSmoothAbs */
- PathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs(num x, num y) native "SVGPathElement_createSVGPathSegCurvetoQuadraticSmoothAbs_Callback";
+ PathSegCurvetoQuadraticSmoothAbs createSvgPathSegCurvetoQuadraticSmoothAbs(num x, num y) native "SVGPathElement_createSVGPathSegCurvetoQuadraticSmoothAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegCurvetoQuadraticSmoothRel */
- PathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel(num x, num y) native "SVGPathElement_createSVGPathSegCurvetoQuadraticSmoothRel_Callback";
+ PathSegCurvetoQuadraticSmoothRel createSvgPathSegCurvetoQuadraticSmoothRel(num x, num y) native "SVGPathElement_createSVGPathSegCurvetoQuadraticSmoothRel_Callback";
/** @domName SVGPathElement.createSVGPathSegLinetoAbs */
- PathSegLinetoAbs createSVGPathSegLinetoAbs(num x, num y) native "SVGPathElement_createSVGPathSegLinetoAbs_Callback";
+ PathSegLinetoAbs createSvgPathSegLinetoAbs(num x, num y) native "SVGPathElement_createSVGPathSegLinetoAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegLinetoHorizontalAbs */
- PathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs(num x) native "SVGPathElement_createSVGPathSegLinetoHorizontalAbs_Callback";
+ PathSegLinetoHorizontalAbs createSvgPathSegLinetoHorizontalAbs(num x) native "SVGPathElement_createSVGPathSegLinetoHorizontalAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegLinetoHorizontalRel */
- PathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel(num x) native "SVGPathElement_createSVGPathSegLinetoHorizontalRel_Callback";
+ PathSegLinetoHorizontalRel createSvgPathSegLinetoHorizontalRel(num x) native "SVGPathElement_createSVGPathSegLinetoHorizontalRel_Callback";
/** @domName SVGPathElement.createSVGPathSegLinetoRel */
- PathSegLinetoRel createSVGPathSegLinetoRel(num x, num y) native "SVGPathElement_createSVGPathSegLinetoRel_Callback";
+ PathSegLinetoRel createSvgPathSegLinetoRel(num x, num y) native "SVGPathElement_createSVGPathSegLinetoRel_Callback";
/** @domName SVGPathElement.createSVGPathSegLinetoVerticalAbs */
- PathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs(num y) native "SVGPathElement_createSVGPathSegLinetoVerticalAbs_Callback";
+ PathSegLinetoVerticalAbs createSvgPathSegLinetoVerticalAbs(num y) native "SVGPathElement_createSVGPathSegLinetoVerticalAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegLinetoVerticalRel */
- PathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel(num y) native "SVGPathElement_createSVGPathSegLinetoVerticalRel_Callback";
+ PathSegLinetoVerticalRel createSvgPathSegLinetoVerticalRel(num y) native "SVGPathElement_createSVGPathSegLinetoVerticalRel_Callback";
/** @domName SVGPathElement.createSVGPathSegMovetoAbs */
- PathSegMovetoAbs createSVGPathSegMovetoAbs(num x, num y) native "SVGPathElement_createSVGPathSegMovetoAbs_Callback";
+ PathSegMovetoAbs createSvgPathSegMovetoAbs(num x, num y) native "SVGPathElement_createSVGPathSegMovetoAbs_Callback";
/** @domName SVGPathElement.createSVGPathSegMovetoRel */
- PathSegMovetoRel createSVGPathSegMovetoRel(num x, num y) native "SVGPathElement_createSVGPathSegMovetoRel_Callback";
+ PathSegMovetoRel createSvgPathSegMovetoRel(num x, num y) native "SVGPathElement_createSVGPathSegMovetoRel_Callback";
/** @domName SVGPathElement.getPathSegAtLength */
@@ -4701,11 +4667,11 @@
/** @domName SVGPathElement.getCTM */
- Matrix getCTM() native "SVGPathElement_getCTM_Callback";
+ Matrix getCtm() native "SVGPathElement_getCTM_Callback";
/** @domName SVGPathElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGPathElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGPathElement_getScreenCTM_Callback";
/** @domName SVGPathElement.getTransformToElement */
@@ -5734,6 +5700,7 @@
// WARNING: Do not edit - generated code.
+/// @domName SVGPoint
class Point extends NativeFieldWrapperClass1 {
factory Point(num x, num y) => _PointFactoryProvider.createPoint(x, y);
Point.internal();
@@ -5858,11 +5825,11 @@
/** @domName SVGPolygonElement.getCTM */
- Matrix getCTM() native "SVGPolygonElement_getCTM_Callback";
+ Matrix getCtm() native "SVGPolygonElement_getCTM_Callback";
/** @domName SVGPolygonElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGPolygonElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGPolygonElement_getScreenCTM_Callback";
/** @domName SVGPolygonElement.getTransformToElement */
@@ -5956,11 +5923,11 @@
/** @domName SVGPolylineElement.getCTM */
- Matrix getCTM() native "SVGPolylineElement_getCTM_Callback";
+ Matrix getCtm() native "SVGPolylineElement_getCTM_Callback";
/** @domName SVGPolylineElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGPolylineElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGPolylineElement_getScreenCTM_Callback";
/** @domName SVGPolylineElement.getTransformToElement */
@@ -6208,11 +6175,11 @@
/** @domName SVGRectElement.getCTM */
- Matrix getCTM() native "SVGRectElement_getCTM_Callback";
+ Matrix getCtm() native "SVGRectElement_getCTM_Callback";
/** @domName SVGRectElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGRectElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGRectElement_getScreenCTM_Callback";
/** @domName SVGRectElement.getTransformToElement */
@@ -6616,6 +6583,7 @@
}
}
+/// @domName SVGElement
class SvgElement extends Element {
factory SvgElement.tag(String tag) =>
_SvgElementFactoryProvider.createSvgElement_tag(tag);
@@ -6646,25 +6614,25 @@
children.addAll(value);
}
- String get outerHTML {
+ String get outerHtml {
final container = new Element.tag("div");
final SvgElement cloned = this.clone(true);
container.children.add(cloned);
- return container.innerHTML;
+ return container.innerHtml;
}
- String get innerHTML {
+ String get innerHtml {
final container = new Element.tag("div");
final SvgElement cloned = this.clone(true);
container.children.addAll(cloned.children);
- return container.innerHTML;
+ return container.innerHtml;
}
- void set innerHTML(String svg) {
+ void set innerHtml(String svg) {
final container = new Element.tag("div");
// Wrap the SVG string in <svg> so that SvgElements are created, rather than
// HTMLElements.
- container.innerHTML = '<svg version="1.1">$svg</svg>';
+ container.innerHtml = '<svg version="1.1">$svg</svg>';
this.children = container.children[0].children;
}
@@ -6680,7 +6648,7 @@
/** @domName SVGElement.ownerSVGElement */
- SvgSvgElement get ownerSVGElement native "SVGElement_ownerSVGElement_Getter";
+ SvgSvgElement get ownerSvgElement native "SVGElement_ownerSVGElement_Getter";
/** @domName SVGElement.viewportElement */
@@ -6699,7 +6667,42 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// WARNING: Do not edit - generated code.
+
+/// @domName SVGException
+class SvgException extends NativeFieldWrapperClass1 {
+ SvgException.internal();
+
+ static const int SVG_INVALID_VALUE_ERR = 1;
+
+ static const int SVG_MATRIX_NOT_INVERTABLE = 2;
+
+ static const int SVG_WRONG_TYPE_ERR = 0;
+
+
+ /** @domName SVGException.code */
+ int get code native "SVGException_code_Getter";
+
+
+ /** @domName SVGException.message */
+ String get message native "SVGException_message_Getter";
+
+
+ /** @domName SVGException.name */
+ String get name native "SVGException_name_Getter";
+
+
+ /** @domName SVGException.toString */
+ String toString() native "SVGException_toString_Callback";
+
+}
+// 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.
+
+
+/// @domName SVGSVGElement
class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace {
factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
@@ -6791,35 +6794,35 @@
/** @domName SVGSVGElement.createSVGAngle */
- Angle createSVGAngle() native "SVGSVGElement_createSVGAngle_Callback";
+ Angle createSvgAngle() native "SVGSVGElement_createSVGAngle_Callback";
/** @domName SVGSVGElement.createSVGLength */
- Length createSVGLength() native "SVGSVGElement_createSVGLength_Callback";
+ Length createSvgLength() native "SVGSVGElement_createSVGLength_Callback";
/** @domName SVGSVGElement.createSVGMatrix */
- Matrix createSVGMatrix() native "SVGSVGElement_createSVGMatrix_Callback";
+ Matrix createSvgMatrix() native "SVGSVGElement_createSVGMatrix_Callback";
/** @domName SVGSVGElement.createSVGNumber */
- Number createSVGNumber() native "SVGSVGElement_createSVGNumber_Callback";
+ Number createSvgNumber() native "SVGSVGElement_createSVGNumber_Callback";
/** @domName SVGSVGElement.createSVGPoint */
- Point createSVGPoint() native "SVGSVGElement_createSVGPoint_Callback";
+ Point createSvgPoint() native "SVGSVGElement_createSVGPoint_Callback";
/** @domName SVGSVGElement.createSVGRect */
- Rect createSVGRect() native "SVGSVGElement_createSVGRect_Callback";
+ Rect createSvgRect() native "SVGSVGElement_createSVGRect_Callback";
/** @domName SVGSVGElement.createSVGTransform */
- Transform createSVGTransform() native "SVGSVGElement_createSVGTransform_Callback";
+ Transform createSvgTransform() native "SVGSVGElement_createSVGTransform_Callback";
/** @domName SVGSVGElement.createSVGTransformFromMatrix */
- Transform createSVGTransformFromMatrix(Matrix matrix) native "SVGSVGElement_createSVGTransformFromMatrix_Callback";
+ Transform createSvgTransformFromMatrix(Matrix matrix) native "SVGSVGElement_createSVGTransformFromMatrix_Callback";
/** @domName SVGSVGElement.deselectAll */
@@ -6911,11 +6914,11 @@
/** @domName SVGSVGElement.getCTM */
- Matrix getCTM() native "SVGSVGElement_getCTM_Callback";
+ Matrix getCtm() native "SVGSVGElement_getCTM_Callback";
/** @domName SVGSVGElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGSVGElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGSVGElement_getScreenCTM_Callback";
/** @domName SVGSVGElement.getTransformToElement */
@@ -7005,11 +7008,11 @@
/** @domName SVGSwitchElement.getCTM */
- Matrix getCTM() native "SVGSwitchElement_getCTM_Callback";
+ Matrix getCtm() native "SVGSwitchElement_getCTM_Callback";
/** @domName SVGSwitchElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGSwitchElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGSwitchElement_getScreenCTM_Callback";
/** @domName SVGSwitchElement.getTransformToElement */
@@ -7299,11 +7302,11 @@
/** @domName SVGTextElement.getCTM */
- Matrix getCTM() native "SVGTextElement_getCTM_Callback";
+ Matrix getCtm() native "SVGTextElement_getCTM_Callback";
/** @domName SVGTextElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGTextElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGTextElement_getScreenCTM_Callback";
/** @domName SVGTextElement.getTransformToElement */
@@ -7604,7 +7607,7 @@
/** @domName SVGTransformList.createSVGTransformFromMatrix */
- Transform createSVGTransformFromMatrix(Matrix matrix) native "SVGTransformList_createSVGTransformFromMatrix_Callback";
+ Transform createSvgTransformFromMatrix(Matrix matrix) native "SVGTransformList_createSVGTransformFromMatrix_Callback";
/** @domName SVGTransformList.getItem */
@@ -7656,11 +7659,11 @@
/** @domName SVGTransformable.getCTM */
- Matrix getCTM() native "SVGTransformable_getCTM_Callback";
+ Matrix getCtm() native "SVGTransformable_getCTM_Callback";
/** @domName SVGTransformable.getScreenCTM */
- Matrix getScreenCTM() native "SVGTransformable_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGTransformable_getScreenCTM_Callback";
/** @domName SVGTransformable.getTransformToElement */
@@ -7772,11 +7775,11 @@
/** @domName SVGUseElement.getCTM */
- Matrix getCTM() native "SVGUseElement_getCTM_Callback";
+ Matrix getCtm() native "SVGUseElement_getCTM_Callback";
/** @domName SVGUseElement.getScreenCTM */
- Matrix getScreenCTM() native "SVGUseElement_getScreenCTM_Callback";
+ Matrix getScreenCtm() native "SVGUseElement_getScreenCTM_Callback";
/** @domName SVGUseElement.getTransformToElement */
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
new file mode 100644
index 0000000..4a50eba
--- /dev/null
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -0,0 +1,699 @@
+library web_audio;
+
+import 'dart:html';
+// DO NOT EDIT
+// Auto-generated dart:audio library.
+
+
+
+
+// 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.
+
+
+/// @domName AnalyserNode; @docsEditable true
+class AnalyserNode extends AudioNode native "*AnalyserNode" {
+
+ /// @domName AnalyserNode.fftSize; @docsEditable true
+ int fftSize;
+
+ /// @domName AnalyserNode.frequencyBinCount; @docsEditable true
+ final int frequencyBinCount;
+
+ /// @domName AnalyserNode.maxDecibels; @docsEditable true
+ num maxDecibels;
+
+ /// @domName AnalyserNode.minDecibels; @docsEditable true
+ num minDecibels;
+
+ /// @domName AnalyserNode.smoothingTimeConstant; @docsEditable true
+ num smoothingTimeConstant;
+
+ /// @domName AnalyserNode.getByteFrequencyData; @docsEditable true
+ void getByteFrequencyData(Uint8Array array) native;
+
+ /// @domName AnalyserNode.getByteTimeDomainData; @docsEditable true
+ void getByteTimeDomainData(Uint8Array array) native;
+
+ /// @domName AnalyserNode.getFloatFrequencyData; @docsEditable true
+ void getFloatFrequencyData(Float32Array array) native;
+}
+// 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.
+
+
+/// @domName AudioBuffer; @docsEditable true
+class AudioBuffer native "*AudioBuffer" {
+
+ /// @domName AudioBuffer.duration; @docsEditable true
+ final num duration;
+
+ /// @domName AudioBuffer.gain; @docsEditable true
+ num gain;
+
+ /// @domName AudioBuffer.length; @docsEditable true
+ final int length;
+
+ /// @domName AudioBuffer.numberOfChannels; @docsEditable true
+ final int numberOfChannels;
+
+ /// @domName AudioBuffer.sampleRate; @docsEditable true
+ final num sampleRate;
+
+ /// @domName AudioBuffer.getChannelData; @docsEditable true
+ Float32Array getChannelData(int channelIndex) native;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+typedef void AudioBufferCallback(AudioBuffer audioBuffer);
+// 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.
+
+
+/// @domName AudioBufferSourceNode
+class AudioBufferSourceNode extends AudioSourceNode native "*AudioBufferSourceNode" {
+
+ // TODO(efortuna): Remove these methods when Chrome stable also uses start
+ // instead of noteOn.
+ void start(num when, [num grainOffset, num grainDuration]) {
+ if (JS('bool', '!!#.start', this)) {
+ if (?grainDuration) {
+ JS('void', '#.start(#, #, #)', this, when, grainOffset, grainDuration);
+ } else if (?grainOffset) {
+ JS('void', '#.start(#, #)', this, when, grainOffset);
+ } else {
+ JS('void', '#.start(#)', this, when);
+ }
+ } else {
+ if (?grainDuration) {
+ JS('void', '#.noteOn(#, #, #)', this, when, grainOffset, grainDuration);
+ } else if (?grainOffset) {
+ JS('void', '#.noteOn(#, #)', this, when, grainOffset);
+ } else {
+ JS('void', '#.noteOn(#)', this, when);
+ }
+ }
+ }
+
+ void stop(num when) {
+ if (JS('bool', '!!#.stop', this)) {
+ JS('void', '#.stop(#)', this, when);
+ } else {
+ JS('void', '#.noteOff(#)', this, when);
+ }
+ }
+
+ static const int FINISHED_STATE = 3;
+
+ static const int PLAYING_STATE = 2;
+
+ static const int SCHEDULED_STATE = 1;
+
+ static const int UNSCHEDULED_STATE = 0;
+
+ /// @domName AudioBufferSourceNode.buffer; @docsEditable true
+ AudioBuffer buffer;
+
+ /// @domName AudioBufferSourceNode.gain; @docsEditable true
+ final AudioGain gain;
+
+ /// @domName AudioBufferSourceNode.loop; @docsEditable true
+ bool loop;
+
+ /// @domName AudioBufferSourceNode.loopEnd; @docsEditable true
+ num loopEnd;
+
+ /// @domName AudioBufferSourceNode.loopStart; @docsEditable true
+ num loopStart;
+
+ /// @domName AudioBufferSourceNode.playbackRate; @docsEditable true
+ final AudioParam playbackRate;
+
+ /// @domName AudioBufferSourceNode.playbackState; @docsEditable true
+ final int playbackState;
+
+}
+// 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.
+
+
+/// @domName AudioContext
+class AudioContext extends EventTarget native "*AudioContext" {
+ factory AudioContext() => JS('AudioContext',
+ 'new (window.AudioContext || window.webkitAudioContext)()');
+
+
+ /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
+ AudioContextEvents get on =>
+ new AudioContextEvents(this);
+
+ /// @domName AudioContext.activeSourceCount; @docsEditable true
+ final int activeSourceCount;
+
+ /// @domName AudioContext.currentTime; @docsEditable true
+ final num currentTime;
+
+ /// @domName AudioContext.destination; @docsEditable true
+ final AudioDestinationNode destination;
+
+ /// @domName AudioContext.listener; @docsEditable true
+ final AudioListener listener;
+
+ /// @domName AudioContext.sampleRate; @docsEditable true
+ final num sampleRate;
+
+ /// @domName AudioContext.createAnalyser; @docsEditable true
+ AnalyserNode createAnalyser() native;
+
+ /// @domName AudioContext.createBiquadFilter; @docsEditable true
+ BiquadFilterNode createBiquadFilter() native;
+
+ /// @domName AudioContext.createBuffer; @docsEditable true
+ AudioBuffer createBuffer(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, [num sampleRate]) native;
+
+ /// @domName AudioContext.createBufferSource; @docsEditable true
+ AudioBufferSourceNode createBufferSource() native;
+
+ /// @domName AudioContext.createChannelMerger; @docsEditable true
+ ChannelMergerNode createChannelMerger([int numberOfInputs]) native;
+
+ /// @domName AudioContext.createChannelSplitter; @docsEditable true
+ ChannelSplitterNode createChannelSplitter([int numberOfOutputs]) native;
+
+ /// @domName AudioContext.createConvolver; @docsEditable true
+ ConvolverNode createConvolver() native;
+
+ /// @domName AudioContext.createDelay; @docsEditable true
+ DelayNode createDelay([num maxDelayTime]) native;
+
+ /// @domName AudioContext.createDynamicsCompressor; @docsEditable true
+ DynamicsCompressorNode createDynamicsCompressor() native;
+
+ /// @domName AudioContext.createMediaElementSource; @docsEditable true
+ MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) native;
+
+ /// @domName AudioContext.createMediaStreamSource; @docsEditable true
+ MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) native;
+
+ /// @domName AudioContext.createOscillator; @docsEditable true
+ OscillatorNode createOscillator() native;
+
+ /// @domName AudioContext.createPanner; @docsEditable true
+ PannerNode createPanner() native;
+
+ /// @domName AudioContext.createWaveShaper; @docsEditable true
+ WaveShaperNode createWaveShaper() native;
+
+ /// @domName AudioContext.createWaveTable; @docsEditable true
+ WaveTable createWaveTable(Float32Array real, Float32Array imag) native;
+
+ /// @domName AudioContext.decodeAudioData; @docsEditable true
+ void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native;
+
+ /// @domName AudioContext.startRendering; @docsEditable true
+ void startRendering() native;
+
+ GainNode createGain() {
+ if (JS('bool', '#.createGain !== undefined', this)) {
+ return JS('GainNode', '#.createGain()', this);
+ } else {
+ return JS('GainNode', '#.createGainNode()', this);
+ }
+ }
+
+ ScriptProcessorNode createScriptProcessor(int bufferSize,
+ [int numberOfInputChannels, int numberOfOutputChannels]) {
+ var function = JS('dynamic', '#.createScriptProcessor || '
+ '#.createJavaScriptNode', this, this);
+ if (?numberOfOutputChannels) {
+ return JS('ScriptProcessorNode', '#.call(#, #, #, #)', function, this,
+ bufferSize, numberOfInputChannels, numberOfOutputChannels);
+ } else if (?numberOfInputChannels) {
+ return JS('ScriptProcessorNode', '#.call(#, #, #)', function, this,
+ bufferSize, numberOfInputChannels);
+ } else {
+ return JS('ScriptProcessorNode', '#.call(#, #)', function, this,
+ bufferSize);
+ }
+ }
+}
+
+class AudioContextEvents extends Events {
+ AudioContextEvents(EventTarget _ptr) : super(_ptr);
+
+ EventListenerList get complete => this['complete'];
+}
+// 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.
+
+
+/// @domName AudioDestinationNode; @docsEditable true
+class AudioDestinationNode extends AudioNode native "*AudioDestinationNode" {
+
+ /// @domName AudioDestinationNode.numberOfChannels; @docsEditable true
+ final int numberOfChannels;
+}
+// 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.
+
+
+/// @domName HTMLAudioElement; @docsEditable true
+class AudioElement extends MediaElement native "*HTMLAudioElement" {
+
+ factory AudioElement([String src]) {
+ if (!?src) {
+ return _AudioElementFactoryProvider.createAudioElement();
+ }
+ return _AudioElementFactoryProvider.createAudioElement(src);
+ }
+}
+// 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.
+
+
+/// @domName AudioGain; @docsEditable true
+class AudioGain extends AudioParam native "*AudioGain" {
+}
+// 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.
+
+
+/// @domName AudioListener; @docsEditable true
+class AudioListener native "*AudioListener" {
+
+ /// @domName AudioListener.dopplerFactor; @docsEditable true
+ num dopplerFactor;
+
+ /// @domName AudioListener.speedOfSound; @docsEditable true
+ num speedOfSound;
+
+ /// @domName AudioListener.setOrientation; @docsEditable true
+ void setOrientation(num x, num y, num z, num xUp, num yUp, num zUp) native;
+
+ /// @domName AudioListener.setPosition; @docsEditable true
+ void setPosition(num x, num y, num z) native;
+
+ /// @domName AudioListener.setVelocity; @docsEditable true
+ void setVelocity(num x, num y, num z) native;
+}
+// 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.
+
+
+/// @domName AudioNode; @docsEditable true
+class AudioNode native "*AudioNode" {
+
+ /// @domName AudioNode.context; @docsEditable true
+ final AudioContext context;
+
+ /// @domName AudioNode.numberOfInputs; @docsEditable true
+ final int numberOfInputs;
+
+ /// @domName AudioNode.numberOfOutputs; @docsEditable true
+ final int numberOfOutputs;
+
+ /// @domName AudioNode.connect; @docsEditable true
+ void connect(destination, int output, [int input]) native;
+
+ /// @domName AudioNode.disconnect; @docsEditable true
+ void disconnect(int output) native;
+}
+// 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.
+
+
+/// @domName AudioParam; @docsEditable true
+class AudioParam native "*AudioParam" {
+
+ /// @domName AudioParam.defaultValue; @docsEditable true
+ final num defaultValue;
+
+ /// @domName AudioParam.maxValue; @docsEditable true
+ final num maxValue;
+
+ /// @domName AudioParam.minValue; @docsEditable true
+ final num minValue;
+
+ /// @domName AudioParam.name; @docsEditable true
+ final String name;
+
+ /// @domName AudioParam.units; @docsEditable true
+ final int units;
+
+ /// @domName AudioParam.value; @docsEditable true
+ num value;
+
+ /// @domName AudioParam.cancelScheduledValues; @docsEditable true
+ void cancelScheduledValues(num startTime) native;
+
+ /// @domName AudioParam.exponentialRampToValueAtTime; @docsEditable true
+ void exponentialRampToValueAtTime(num value, num time) native;
+
+ /// @domName AudioParam.linearRampToValueAtTime; @docsEditable true
+ void linearRampToValueAtTime(num value, num time) native;
+
+ /// @domName AudioParam.setTargetAtTime; @docsEditable true
+ void setTargetAtTime(num target, num time, num timeConstant) native;
+
+ /// @domName AudioParam.setValueAtTime; @docsEditable true
+ void setValueAtTime(num value, num time) native;
+
+ /// @domName AudioParam.setValueCurveAtTime; @docsEditable true
+ void setValueCurveAtTime(Float32Array values, num time, num duration) native;
+}
+// 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.
+
+
+/// @domName AudioProcessingEvent; @docsEditable true
+class AudioProcessingEvent extends Event native "*AudioProcessingEvent" {
+
+ /// @domName AudioProcessingEvent.inputBuffer; @docsEditable true
+ final AudioBuffer inputBuffer;
+
+ /// @domName AudioProcessingEvent.outputBuffer; @docsEditable true
+ final AudioBuffer outputBuffer;
+}
+// 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.
+
+
+/// @domName AudioSourceNode; @docsEditable true
+class AudioSourceNode extends AudioNode native "*AudioSourceNode" {
+}
+// 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.
+
+
+/// @domName BiquadFilterNode; @docsEditable true
+class BiquadFilterNode extends AudioNode native "*BiquadFilterNode" {
+
+ static const int ALLPASS = 7;
+
+ static const int BANDPASS = 2;
+
+ static const int HIGHPASS = 1;
+
+ static const int HIGHSHELF = 4;
+
+ static const int LOWPASS = 0;
+
+ static const int LOWSHELF = 3;
+
+ static const int NOTCH = 6;
+
+ static const int PEAKING = 5;
+
+ /// @domName BiquadFilterNode.Q; @docsEditable true
+ final AudioParam Q;
+
+ /// @domName BiquadFilterNode.frequency; @docsEditable true
+ final AudioParam frequency;
+
+ /// @domName BiquadFilterNode.gain; @docsEditable true
+ final AudioParam gain;
+
+ /// @domName BiquadFilterNode.type; @docsEditable true
+ int type;
+
+ /// @domName BiquadFilterNode.getFrequencyResponse; @docsEditable true
+ void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse) native;
+}
+// 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.
+
+
+/// @domName ChannelMergerNode; @docsEditable true
+class ChannelMergerNode extends AudioNode native "*ChannelMergerNode" {
+}
+// 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.
+
+
+/// @domName ChannelSplitterNode; @docsEditable true
+class ChannelSplitterNode extends AudioNode native "*ChannelSplitterNode" {
+}
+// 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.
+
+
+/// @domName ConvolverNode; @docsEditable true
+class ConvolverNode extends AudioNode native "*ConvolverNode" {
+
+ /// @domName ConvolverNode.buffer; @docsEditable true
+ AudioBuffer buffer;
+
+ /// @domName ConvolverNode.normalize; @docsEditable true
+ bool normalize;
+}
+// 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.
+
+
+/// @domName DelayNode; @docsEditable true
+class DelayNode extends AudioNode native "*DelayNode" {
+
+ /// @domName DelayNode.delayTime; @docsEditable true
+ final AudioParam delayTime;
+}
+// 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.
+
+
+/// @domName DynamicsCompressorNode; @docsEditable true
+class DynamicsCompressorNode extends AudioNode native "*DynamicsCompressorNode" {
+
+ /// @domName DynamicsCompressorNode.attack; @docsEditable true
+ final AudioParam attack;
+
+ /// @domName DynamicsCompressorNode.knee; @docsEditable true
+ final AudioParam knee;
+
+ /// @domName DynamicsCompressorNode.ratio; @docsEditable true
+ final AudioParam ratio;
+
+ /// @domName DynamicsCompressorNode.reduction; @docsEditable true
+ final AudioParam reduction;
+
+ /// @domName DynamicsCompressorNode.release; @docsEditable true
+ final AudioParam release;
+
+ /// @domName DynamicsCompressorNode.threshold; @docsEditable true
+ final AudioParam threshold;
+}
+// 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.
+
+
+/// @domName GainNode; @docsEditable true
+class GainNode extends AudioNode native "*GainNode" {
+
+ /// @domName GainNode.gain; @docsEditable true
+ final AudioGain gain;
+}
+// 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.
+
+
+/// @domName MediaElementAudioSourceNode; @docsEditable true
+class MediaElementAudioSourceNode extends AudioSourceNode native "*MediaElementAudioSourceNode" {
+
+ /// @domName MediaElementAudioSourceNode.mediaElement; @docsEditable true
+ final MediaElement mediaElement;
+}
+// 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.
+
+
+/// @domName MediaStreamAudioSourceNode; @docsEditable true
+class MediaStreamAudioSourceNode extends AudioSourceNode native "*MediaStreamAudioSourceNode" {
+
+ /// @domName MediaStreamAudioSourceNode.mediaStream; @docsEditable true
+ final MediaStream mediaStream;
+}
+// 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.
+
+
+/// @domName OfflineAudioCompletionEvent; @docsEditable true
+class OfflineAudioCompletionEvent extends Event native "*OfflineAudioCompletionEvent" {
+
+ /// @domName OfflineAudioCompletionEvent.renderedBuffer; @docsEditable true
+ final AudioBuffer renderedBuffer;
+}
+// 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.
+
+
+/// @domName OscillatorNode; @docsEditable true
+class OscillatorNode extends AudioSourceNode native "*OscillatorNode" {
+
+ static const int CUSTOM = 4;
+
+ static const int FINISHED_STATE = 3;
+
+ static const int PLAYING_STATE = 2;
+
+ static const int SAWTOOTH = 2;
+
+ static const int SCHEDULED_STATE = 1;
+
+ static const int SINE = 0;
+
+ static const int SQUARE = 1;
+
+ static const int TRIANGLE = 3;
+
+ static const int UNSCHEDULED_STATE = 0;
+
+ /// @domName OscillatorNode.detune; @docsEditable true
+ final AudioParam detune;
+
+ /// @domName OscillatorNode.frequency; @docsEditable true
+ final AudioParam frequency;
+
+ /// @domName OscillatorNode.playbackState; @docsEditable true
+ final int playbackState;
+
+ /// @domName OscillatorNode.type; @docsEditable true
+ int type;
+
+ /// @domName OscillatorNode.setWaveTable; @docsEditable true
+ void setWaveTable(WaveTable waveTable) native;
+
+ /// @domName OscillatorNode.start; @docsEditable true
+ void start(num when) native;
+
+ /// @domName OscillatorNode.stop; @docsEditable true
+ void stop(num when) native;
+}
+// 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.
+
+
+/// @domName PannerNode; @docsEditable true
+class PannerNode extends AudioNode native "*PannerNode" {
+
+ static const int EQUALPOWER = 0;
+
+ static const int EXPONENTIAL_DISTANCE = 2;
+
+ static const int HRTF = 1;
+
+ static const int INVERSE_DISTANCE = 1;
+
+ static const int LINEAR_DISTANCE = 0;
+
+ static const int SOUNDFIELD = 2;
+
+ /// @domName PannerNode.coneGain; @docsEditable true
+ final AudioGain coneGain;
+
+ /// @domName PannerNode.coneInnerAngle; @docsEditable true
+ num coneInnerAngle;
+
+ /// @domName PannerNode.coneOuterAngle; @docsEditable true
+ num coneOuterAngle;
+
+ /// @domName PannerNode.coneOuterGain; @docsEditable true
+ num coneOuterGain;
+
+ /// @domName PannerNode.distanceGain; @docsEditable true
+ final AudioGain distanceGain;
+
+ /// @domName PannerNode.distanceModel; @docsEditable true
+ int distanceModel;
+
+ /// @domName PannerNode.maxDistance; @docsEditable true
+ num maxDistance;
+
+ /// @domName PannerNode.panningModel; @docsEditable true
+ int panningModel;
+
+ /// @domName PannerNode.refDistance; @docsEditable true
+ num refDistance;
+
+ /// @domName PannerNode.rolloffFactor; @docsEditable true
+ num rolloffFactor;
+
+ /// @domName PannerNode.setOrientation; @docsEditable true
+ void setOrientation(num x, num y, num z) native;
+
+ /// @domName PannerNode.setPosition; @docsEditable true
+ void setPosition(num x, num y, num z) native;
+
+ /// @domName PannerNode.setVelocity; @docsEditable true
+ void setVelocity(num x, num y, num z) native;
+}
+// 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.
+
+
+/// @domName ScriptProcessorNode; @docsEditable true
+class ScriptProcessorNode extends AudioNode implements EventTarget native "*ScriptProcessorNode" {
+
+ /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
+ ScriptProcessorNodeEvents get on =>
+ new ScriptProcessorNodeEvents(this);
+
+ /// @domName ScriptProcessorNode.bufferSize; @docsEditable true
+ final int bufferSize;
+}
+
+class ScriptProcessorNodeEvents extends Events {
+ ScriptProcessorNodeEvents(EventTarget _ptr) : super(_ptr);
+
+ EventListenerList get audioProcess => this['audioprocess'];
+}
+// 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.
+
+
+/// @domName WaveShaperNode; @docsEditable true
+class WaveShaperNode extends AudioNode native "*WaveShaperNode" {
+
+ /// @domName WaveShaperNode.curve; @docsEditable true
+ Float32Array curve;
+}
+// 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.
+
+
+class _AudioElementFactoryProvider {
+ static AudioElement createAudioElement([String src = null]) {
+ if (src == null) return JS('AudioElement', 'new Audio()');
+ return JS('AudioElement', 'new Audio(#)', src);
+ }
+}
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
new file mode 100644
index 0000000..908a772
--- /dev/null
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -0,0 +1,1069 @@
+library web_audio;
+
+import 'dart:html';
+import 'dart:nativewrappers';
+// DO NOT EDIT
+// Auto-generated dart:audio library.
+
+
+
+
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AnalyserNode
+class AnalyserNode extends AudioNode {
+ AnalyserNode.internal(): super.internal();
+
+
+ /** @domName AnalyserNode.fftSize */
+ int get fftSize native "AnalyserNode_fftSize_Getter";
+
+
+ /** @domName AnalyserNode.fftSize */
+ void set fftSize(int value) native "AnalyserNode_fftSize_Setter";
+
+
+ /** @domName AnalyserNode.frequencyBinCount */
+ int get frequencyBinCount native "AnalyserNode_frequencyBinCount_Getter";
+
+
+ /** @domName AnalyserNode.maxDecibels */
+ num get maxDecibels native "AnalyserNode_maxDecibels_Getter";
+
+
+ /** @domName AnalyserNode.maxDecibels */
+ void set maxDecibels(num value) native "AnalyserNode_maxDecibels_Setter";
+
+
+ /** @domName AnalyserNode.minDecibels */
+ num get minDecibels native "AnalyserNode_minDecibels_Getter";
+
+
+ /** @domName AnalyserNode.minDecibels */
+ void set minDecibels(num value) native "AnalyserNode_minDecibels_Setter";
+
+
+ /** @domName AnalyserNode.smoothingTimeConstant */
+ num get smoothingTimeConstant native "AnalyserNode_smoothingTimeConstant_Getter";
+
+
+ /** @domName AnalyserNode.smoothingTimeConstant */
+ void set smoothingTimeConstant(num value) native "AnalyserNode_smoothingTimeConstant_Setter";
+
+
+ /** @domName AnalyserNode.getByteFrequencyData */
+ void getByteFrequencyData(Uint8Array array) native "AnalyserNode_getByteFrequencyData_Callback";
+
+
+ /** @domName AnalyserNode.getByteTimeDomainData */
+ void getByteTimeDomainData(Uint8Array array) native "AnalyserNode_getByteTimeDomainData_Callback";
+
+
+ /** @domName AnalyserNode.getFloatFrequencyData */
+ void getFloatFrequencyData(Float32Array array) native "AnalyserNode_getFloatFrequencyData_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioBuffer
+class AudioBuffer extends NativeFieldWrapperClass1 {
+ AudioBuffer.internal();
+
+
+ /** @domName AudioBuffer.duration */
+ num get duration native "AudioBuffer_duration_Getter";
+
+
+ /** @domName AudioBuffer.gain */
+ num get gain native "AudioBuffer_gain_Getter";
+
+
+ /** @domName AudioBuffer.gain */
+ void set gain(num value) native "AudioBuffer_gain_Setter";
+
+
+ /** @domName AudioBuffer.length */
+ int get length native "AudioBuffer_length_Getter";
+
+
+ /** @domName AudioBuffer.numberOfChannels */
+ int get numberOfChannels native "AudioBuffer_numberOfChannels_Getter";
+
+
+ /** @domName AudioBuffer.sampleRate */
+ num get sampleRate native "AudioBuffer_sampleRate_Getter";
+
+
+ /** @domName AudioBuffer.getChannelData */
+ Float32Array getChannelData(int channelIndex) native "AudioBuffer_getChannelData_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+typedef void AudioBufferCallback(AudioBuffer audioBuffer);
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioBufferSourceNode
+class AudioBufferSourceNode extends AudioSourceNode {
+ AudioBufferSourceNode.internal(): super.internal();
+
+ static const int FINISHED_STATE = 3;
+
+ static const int PLAYING_STATE = 2;
+
+ static const int SCHEDULED_STATE = 1;
+
+ static const int UNSCHEDULED_STATE = 0;
+
+
+ /** @domName AudioBufferSourceNode.buffer */
+ AudioBuffer get buffer native "AudioBufferSourceNode_buffer_Getter";
+
+
+ /** @domName AudioBufferSourceNode.buffer */
+ void set buffer(AudioBuffer value) native "AudioBufferSourceNode_buffer_Setter";
+
+
+ /** @domName AudioBufferSourceNode.gain */
+ AudioGain get gain native "AudioBufferSourceNode_gain_Getter";
+
+
+ /** @domName AudioBufferSourceNode.loop */
+ bool get loop native "AudioBufferSourceNode_loop_Getter";
+
+
+ /** @domName AudioBufferSourceNode.loop */
+ void set loop(bool value) native "AudioBufferSourceNode_loop_Setter";
+
+
+ /** @domName AudioBufferSourceNode.loopEnd */
+ num get loopEnd native "AudioBufferSourceNode_loopEnd_Getter";
+
+
+ /** @domName AudioBufferSourceNode.loopEnd */
+ void set loopEnd(num value) native "AudioBufferSourceNode_loopEnd_Setter";
+
+
+ /** @domName AudioBufferSourceNode.loopStart */
+ num get loopStart native "AudioBufferSourceNode_loopStart_Getter";
+
+
+ /** @domName AudioBufferSourceNode.loopStart */
+ void set loopStart(num value) native "AudioBufferSourceNode_loopStart_Setter";
+
+
+ /** @domName AudioBufferSourceNode.playbackRate */
+ AudioParam get playbackRate native "AudioBufferSourceNode_playbackRate_Getter";
+
+
+ /** @domName AudioBufferSourceNode.playbackState */
+ int get playbackState native "AudioBufferSourceNode_playbackState_Getter";
+
+ void start(/*double*/ when, [/*double*/ grainOffset, /*double*/ grainDuration]) {
+ if ((when is num || when == null) && !?grainOffset && !?grainDuration) {
+ _start_1(when);
+ return;
+ }
+ if ((when is num || when == null) && (grainOffset is num || grainOffset == null) && (grainDuration is num || grainDuration == null)) {
+ _start_2(when, grainOffset, grainDuration);
+ return;
+ }
+ throw "Incorrect number or type of arguments";
+ }
+
+
+ /** @domName AudioBufferSourceNode.start_1 */
+ void _start_1(when) native "AudioBufferSourceNode_start_1_Callback";
+
+
+ /** @domName AudioBufferSourceNode.start_2 */
+ void _start_2(when, grainOffset, grainDuration) native "AudioBufferSourceNode_start_2_Callback";
+
+
+ /** @domName AudioBufferSourceNode.stop */
+ void stop(num when) native "AudioBufferSourceNode_stop_Callback";
+
+}
+// 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.
+
+
+/// @domName AudioContext
+class AudioContext extends EventTarget {
+ factory AudioContext() => _createAudioContext();
+
+ static _createAudioContext([int numberOfChannels,
+ int numberOfFrames,
+ int sampleRate])
+ native "AudioContext_constructor_Callback";
+
+ AudioContext.internal(): super.internal();
+
+ /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
+ AudioContextEvents get on =>
+ new AudioContextEvents(this);
+
+
+ /** @domName AudioContext.activeSourceCount */
+ int get activeSourceCount native "AudioContext_activeSourceCount_Getter";
+
+
+ /** @domName AudioContext.currentTime */
+ num get currentTime native "AudioContext_currentTime_Getter";
+
+
+ /** @domName AudioContext.destination */
+ AudioDestinationNode get destination native "AudioContext_destination_Getter";
+
+
+ /** @domName AudioContext.listener */
+ AudioListener get listener native "AudioContext_listener_Getter";
+
+
+ /** @domName AudioContext.sampleRate */
+ num get sampleRate native "AudioContext_sampleRate_Getter";
+
+
+ /** @domName AudioContext.createAnalyser */
+ AnalyserNode createAnalyser() native "AudioContext_createAnalyser_Callback";
+
+
+ /** @domName AudioContext.createBiquadFilter */
+ BiquadFilterNode createBiquadFilter() native "AudioContext_createBiquadFilter_Callback";
+
+ AudioBuffer createBuffer(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, [/*float*/ sampleRate]) {
+ if ((buffer_OR_numberOfChannels is int || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is int || mixToMono_OR_numberOfFrames == null) && (sampleRate is num || sampleRate == null)) {
+ return _createBuffer_1(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, sampleRate);
+ }
+ if ((buffer_OR_numberOfChannels is ArrayBuffer || buffer_OR_numberOfChannels == null) && (mixToMono_OR_numberOfFrames is bool || mixToMono_OR_numberOfFrames == null) && !?sampleRate) {
+ return _createBuffer_2(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames);
+ }
+ throw "Incorrect number or type of arguments";
+ }
+
+
+ /** @domName AudioContext.createBuffer_1 */
+ AudioBuffer _createBuffer_1(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames, sampleRate) native "AudioContext_createBuffer_1_Callback";
+
+
+ /** @domName AudioContext.createBuffer_2 */
+ AudioBuffer _createBuffer_2(buffer_OR_numberOfChannels, mixToMono_OR_numberOfFrames) native "AudioContext_createBuffer_2_Callback";
+
+
+ /** @domName AudioContext.createBufferSource */
+ AudioBufferSourceNode createBufferSource() native "AudioContext_createBufferSource_Callback";
+
+ ChannelMergerNode createChannelMerger([/*unsigned long*/ numberOfInputs]) {
+ if (?numberOfInputs) {
+ return _createChannelMerger_1(numberOfInputs);
+ }
+ return _createChannelMerger_2();
+ }
+
+
+ /** @domName AudioContext.createChannelMerger_1 */
+ ChannelMergerNode _createChannelMerger_1(numberOfInputs) native "AudioContext_createChannelMerger_1_Callback";
+
+
+ /** @domName AudioContext.createChannelMerger_2 */
+ ChannelMergerNode _createChannelMerger_2() native "AudioContext_createChannelMerger_2_Callback";
+
+ ChannelSplitterNode createChannelSplitter([/*unsigned long*/ numberOfOutputs]) {
+ if (?numberOfOutputs) {
+ return _createChannelSplitter_1(numberOfOutputs);
+ }
+ return _createChannelSplitter_2();
+ }
+
+
+ /** @domName AudioContext.createChannelSplitter_1 */
+ ChannelSplitterNode _createChannelSplitter_1(numberOfOutputs) native "AudioContext_createChannelSplitter_1_Callback";
+
+
+ /** @domName AudioContext.createChannelSplitter_2 */
+ ChannelSplitterNode _createChannelSplitter_2() native "AudioContext_createChannelSplitter_2_Callback";
+
+
+ /** @domName AudioContext.createConvolver */
+ ConvolverNode createConvolver() native "AudioContext_createConvolver_Callback";
+
+ DelayNode createDelay([/*double*/ maxDelayTime]) {
+ if (?maxDelayTime) {
+ return _createDelay_1(maxDelayTime);
+ }
+ return _createDelay_2();
+ }
+
+
+ /** @domName AudioContext.createDelay_1 */
+ DelayNode _createDelay_1(maxDelayTime) native "AudioContext_createDelay_1_Callback";
+
+
+ /** @domName AudioContext.createDelay_2 */
+ DelayNode _createDelay_2() native "AudioContext_createDelay_2_Callback";
+
+
+ /** @domName AudioContext.createDynamicsCompressor */
+ DynamicsCompressorNode createDynamicsCompressor() native "AudioContext_createDynamicsCompressor_Callback";
+
+
+ /** @domName AudioContext.createGain */
+ GainNode createGain() native "AudioContext_createGain_Callback";
+
+
+ /** @domName AudioContext.createMediaElementSource */
+ MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) native "AudioContext_createMediaElementSource_Callback";
+
+
+ /** @domName AudioContext.createMediaStreamSource */
+ MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) native "AudioContext_createMediaStreamSource_Callback";
+
+
+ /** @domName AudioContext.createOscillator */
+ OscillatorNode createOscillator() native "AudioContext_createOscillator_Callback";
+
+
+ /** @domName AudioContext.createPanner */
+ PannerNode createPanner() native "AudioContext_createPanner_Callback";
+
+ ScriptProcessorNode createScriptProcessor(/*unsigned long*/ bufferSize, [/*unsigned long*/ numberOfInputChannels, /*unsigned long*/ numberOfOutputChannels]) {
+ if (?numberOfOutputChannels) {
+ return _createScriptProcessor_1(bufferSize, numberOfInputChannels, numberOfOutputChannels);
+ }
+ if (?numberOfInputChannels) {
+ return _createScriptProcessor_2(bufferSize, numberOfInputChannels);
+ }
+ return _createScriptProcessor_3(bufferSize);
+ }
+
+
+ /** @domName AudioContext.createScriptProcessor_1 */
+ ScriptProcessorNode _createScriptProcessor_1(bufferSize, numberOfInputChannels, numberOfOutputChannels) native "AudioContext_createScriptProcessor_1_Callback";
+
+
+ /** @domName AudioContext.createScriptProcessor_2 */
+ ScriptProcessorNode _createScriptProcessor_2(bufferSize, numberOfInputChannels) native "AudioContext_createScriptProcessor_2_Callback";
+
+
+ /** @domName AudioContext.createScriptProcessor_3 */
+ ScriptProcessorNode _createScriptProcessor_3(bufferSize) native "AudioContext_createScriptProcessor_3_Callback";
+
+
+ /** @domName AudioContext.createWaveShaper */
+ WaveShaperNode createWaveShaper() native "AudioContext_createWaveShaper_Callback";
+
+
+ /** @domName AudioContext.createWaveTable */
+ WaveTable createWaveTable(Float32Array real, Float32Array imag) native "AudioContext_createWaveTable_Callback";
+
+
+ /** @domName AudioContext.decodeAudioData */
+ void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) native "AudioContext_decodeAudioData_Callback";
+
+
+ /** @domName AudioContext.startRendering */
+ void startRendering() native "AudioContext_startRendering_Callback";
+
+}
+
+class AudioContextEvents extends Events {
+ AudioContextEvents(EventTarget _ptr) : super(_ptr);
+
+ EventListenerList get complete => this['complete'];
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioDestinationNode
+class AudioDestinationNode extends AudioNode {
+ AudioDestinationNode.internal(): super.internal();
+
+
+ /** @domName AudioDestinationNode.numberOfChannels */
+ int get numberOfChannels native "AudioDestinationNode_numberOfChannels_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName HTMLAudioElement
+class AudioElement extends MediaElement {
+
+ factory AudioElement([String src]) {
+ if (!?src) {
+ return _AudioElementFactoryProvider.createAudioElement();
+ }
+ return _AudioElementFactoryProvider.createAudioElement(src);
+ }
+ AudioElement.internal(): super.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioGain
+class AudioGain extends AudioParam {
+ AudioGain.internal(): super.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioListener
+class AudioListener extends NativeFieldWrapperClass1 {
+ AudioListener.internal();
+
+
+ /** @domName AudioListener.dopplerFactor */
+ num get dopplerFactor native "AudioListener_dopplerFactor_Getter";
+
+
+ /** @domName AudioListener.dopplerFactor */
+ void set dopplerFactor(num value) native "AudioListener_dopplerFactor_Setter";
+
+
+ /** @domName AudioListener.speedOfSound */
+ num get speedOfSound native "AudioListener_speedOfSound_Getter";
+
+
+ /** @domName AudioListener.speedOfSound */
+ void set speedOfSound(num value) native "AudioListener_speedOfSound_Setter";
+
+
+ /** @domName AudioListener.setOrientation */
+ void setOrientation(num x, num y, num z, num xUp, num yUp, num zUp) native "AudioListener_setOrientation_Callback";
+
+
+ /** @domName AudioListener.setPosition */
+ void setPosition(num x, num y, num z) native "AudioListener_setPosition_Callback";
+
+
+ /** @domName AudioListener.setVelocity */
+ void setVelocity(num x, num y, num z) native "AudioListener_setVelocity_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioNode
+class AudioNode extends NativeFieldWrapperClass1 {
+ AudioNode.internal();
+
+
+ /** @domName AudioNode.context */
+ AudioContext get context native "AudioNode_context_Getter";
+
+
+ /** @domName AudioNode.numberOfInputs */
+ int get numberOfInputs native "AudioNode_numberOfInputs_Getter";
+
+
+ /** @domName AudioNode.numberOfOutputs */
+ int get numberOfOutputs native "AudioNode_numberOfOutputs_Getter";
+
+ void connect(destination, /*unsigned long*/ output, [/*unsigned long*/ input]) {
+ if ((destination is AudioNode || destination == null) && (output is int || output == null) && (input is int || input == null)) {
+ _connect_1(destination, output, input);
+ return;
+ }
+ if ((destination is AudioParam || destination == null) && (output is int || output == null) && !?input) {
+ _connect_2(destination, output);
+ return;
+ }
+ throw "Incorrect number or type of arguments";
+ }
+
+
+ /** @domName AudioNode.connect_1 */
+ void _connect_1(destination, output, input) native "AudioNode_connect_1_Callback";
+
+
+ /** @domName AudioNode.connect_2 */
+ void _connect_2(destination, output) native "AudioNode_connect_2_Callback";
+
+
+ /** @domName AudioNode.disconnect */
+ void disconnect(int output) native "AudioNode_disconnect_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioParam
+class AudioParam extends NativeFieldWrapperClass1 {
+ AudioParam.internal();
+
+
+ /** @domName AudioParam.defaultValue */
+ num get defaultValue native "AudioParam_defaultValue_Getter";
+
+
+ /** @domName AudioParam.maxValue */
+ num get maxValue native "AudioParam_maxValue_Getter";
+
+
+ /** @domName AudioParam.minValue */
+ num get minValue native "AudioParam_minValue_Getter";
+
+
+ /** @domName AudioParam.name */
+ String get name native "AudioParam_name_Getter";
+
+
+ /** @domName AudioParam.units */
+ int get units native "AudioParam_units_Getter";
+
+
+ /** @domName AudioParam.value */
+ num get value native "AudioParam_value_Getter";
+
+
+ /** @domName AudioParam.value */
+ void set value(num value) native "AudioParam_value_Setter";
+
+
+ /** @domName AudioParam.cancelScheduledValues */
+ void cancelScheduledValues(num startTime) native "AudioParam_cancelScheduledValues_Callback";
+
+
+ /** @domName AudioParam.exponentialRampToValueAtTime */
+ void exponentialRampToValueAtTime(num value, num time) native "AudioParam_exponentialRampToValueAtTime_Callback";
+
+
+ /** @domName AudioParam.linearRampToValueAtTime */
+ void linearRampToValueAtTime(num value, num time) native "AudioParam_linearRampToValueAtTime_Callback";
+
+
+ /** @domName AudioParam.setTargetAtTime */
+ void setTargetAtTime(num target, num time, num timeConstant) native "AudioParam_setTargetAtTime_Callback";
+
+
+ /** @domName AudioParam.setValueAtTime */
+ void setValueAtTime(num value, num time) native "AudioParam_setValueAtTime_Callback";
+
+
+ /** @domName AudioParam.setValueCurveAtTime */
+ void setValueCurveAtTime(Float32Array values, num time, num duration) native "AudioParam_setValueCurveAtTime_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioProcessingEvent
+class AudioProcessingEvent extends Event {
+ AudioProcessingEvent.internal(): super.internal();
+
+
+ /** @domName AudioProcessingEvent.inputBuffer */
+ AudioBuffer get inputBuffer native "AudioProcessingEvent_inputBuffer_Getter";
+
+
+ /** @domName AudioProcessingEvent.outputBuffer */
+ AudioBuffer get outputBuffer native "AudioProcessingEvent_outputBuffer_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName AudioSourceNode
+class AudioSourceNode extends AudioNode {
+ AudioSourceNode.internal(): super.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName BiquadFilterNode
+class BiquadFilterNode extends AudioNode {
+ BiquadFilterNode.internal(): super.internal();
+
+ static const int ALLPASS = 7;
+
+ static const int BANDPASS = 2;
+
+ static const int HIGHPASS = 1;
+
+ static const int HIGHSHELF = 4;
+
+ static const int LOWPASS = 0;
+
+ static const int LOWSHELF = 3;
+
+ static const int NOTCH = 6;
+
+ static const int PEAKING = 5;
+
+
+ /** @domName BiquadFilterNode.Q */
+ AudioParam get Q native "BiquadFilterNode_Q_Getter";
+
+
+ /** @domName BiquadFilterNode.frequency */
+ AudioParam get frequency native "BiquadFilterNode_frequency_Getter";
+
+
+ /** @domName BiquadFilterNode.gain */
+ AudioParam get gain native "BiquadFilterNode_gain_Getter";
+
+
+ /** @domName BiquadFilterNode.type */
+ int get type native "BiquadFilterNode_type_Getter";
+
+
+ /** @domName BiquadFilterNode.type */
+ void set type(int value) native "BiquadFilterNode_type_Setter";
+
+
+ /** @domName BiquadFilterNode.getFrequencyResponse */
+ void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse) native "BiquadFilterNode_getFrequencyResponse_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName ChannelMergerNode
+class ChannelMergerNode extends AudioNode {
+ ChannelMergerNode.internal(): super.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName ChannelSplitterNode
+class ChannelSplitterNode extends AudioNode {
+ ChannelSplitterNode.internal(): super.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName ConvolverNode
+class ConvolverNode extends AudioNode {
+ ConvolverNode.internal(): super.internal();
+
+
+ /** @domName ConvolverNode.buffer */
+ AudioBuffer get buffer native "ConvolverNode_buffer_Getter";
+
+
+ /** @domName ConvolverNode.buffer */
+ void set buffer(AudioBuffer value) native "ConvolverNode_buffer_Setter";
+
+
+ /** @domName ConvolverNode.normalize */
+ bool get normalize native "ConvolverNode_normalize_Getter";
+
+
+ /** @domName ConvolverNode.normalize */
+ void set normalize(bool value) native "ConvolverNode_normalize_Setter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName DelayNode
+class DelayNode extends AudioNode {
+ DelayNode.internal(): super.internal();
+
+
+ /** @domName DelayNode.delayTime */
+ AudioParam get delayTime native "DelayNode_delayTime_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName DynamicsCompressorNode
+class DynamicsCompressorNode extends AudioNode {
+ DynamicsCompressorNode.internal(): super.internal();
+
+
+ /** @domName DynamicsCompressorNode.attack */
+ AudioParam get attack native "DynamicsCompressorNode_attack_Getter";
+
+
+ /** @domName DynamicsCompressorNode.knee */
+ AudioParam get knee native "DynamicsCompressorNode_knee_Getter";
+
+
+ /** @domName DynamicsCompressorNode.ratio */
+ AudioParam get ratio native "DynamicsCompressorNode_ratio_Getter";
+
+
+ /** @domName DynamicsCompressorNode.reduction */
+ AudioParam get reduction native "DynamicsCompressorNode_reduction_Getter";
+
+
+ /** @domName DynamicsCompressorNode.release */
+ AudioParam get release native "DynamicsCompressorNode_release_Getter";
+
+
+ /** @domName DynamicsCompressorNode.threshold */
+ AudioParam get threshold native "DynamicsCompressorNode_threshold_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName GainNode
+class GainNode extends AudioNode {
+ GainNode.internal(): super.internal();
+
+
+ /** @domName GainNode.gain */
+ AudioGain get gain native "GainNode_gain_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName MediaElementAudioSourceNode
+class MediaElementAudioSourceNode extends AudioSourceNode {
+ MediaElementAudioSourceNode.internal(): super.internal();
+
+
+ /** @domName MediaElementAudioSourceNode.mediaElement */
+ MediaElement get mediaElement native "MediaElementAudioSourceNode_mediaElement_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName MediaStreamAudioSourceNode
+class MediaStreamAudioSourceNode extends AudioSourceNode {
+ MediaStreamAudioSourceNode.internal(): super.internal();
+
+
+ /** @domName MediaStreamAudioSourceNode.mediaStream */
+ MediaStream get mediaStream native "MediaStreamAudioSourceNode_mediaStream_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName OfflineAudioCompletionEvent
+class OfflineAudioCompletionEvent extends Event {
+ OfflineAudioCompletionEvent.internal(): super.internal();
+
+
+ /** @domName OfflineAudioCompletionEvent.renderedBuffer */
+ AudioBuffer get renderedBuffer native "OfflineAudioCompletionEvent_renderedBuffer_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName OscillatorNode
+class OscillatorNode extends AudioSourceNode {
+ OscillatorNode.internal(): super.internal();
+
+ static const int CUSTOM = 4;
+
+ static const int FINISHED_STATE = 3;
+
+ static const int PLAYING_STATE = 2;
+
+ static const int SAWTOOTH = 2;
+
+ static const int SCHEDULED_STATE = 1;
+
+ static const int SINE = 0;
+
+ static const int SQUARE = 1;
+
+ static const int TRIANGLE = 3;
+
+ static const int UNSCHEDULED_STATE = 0;
+
+
+ /** @domName OscillatorNode.detune */
+ AudioParam get detune native "OscillatorNode_detune_Getter";
+
+
+ /** @domName OscillatorNode.frequency */
+ AudioParam get frequency native "OscillatorNode_frequency_Getter";
+
+
+ /** @domName OscillatorNode.playbackState */
+ int get playbackState native "OscillatorNode_playbackState_Getter";
+
+
+ /** @domName OscillatorNode.type */
+ int get type native "OscillatorNode_type_Getter";
+
+
+ /** @domName OscillatorNode.type */
+ void set type(int value) native "OscillatorNode_type_Setter";
+
+
+ /** @domName OscillatorNode.setWaveTable */
+ void setWaveTable(WaveTable waveTable) native "OscillatorNode_setWaveTable_Callback";
+
+
+ /** @domName OscillatorNode.start */
+ void start(num when) native "OscillatorNode_start_Callback";
+
+
+ /** @domName OscillatorNode.stop */
+ void stop(num when) native "OscillatorNode_stop_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName PannerNode
+class PannerNode extends AudioNode {
+ PannerNode.internal(): super.internal();
+
+ static const int EQUALPOWER = 0;
+
+ static const int EXPONENTIAL_DISTANCE = 2;
+
+ static const int HRTF = 1;
+
+ static const int INVERSE_DISTANCE = 1;
+
+ static const int LINEAR_DISTANCE = 0;
+
+ static const int SOUNDFIELD = 2;
+
+
+ /** @domName PannerNode.coneGain */
+ AudioGain get coneGain native "PannerNode_coneGain_Getter";
+
+
+ /** @domName PannerNode.coneInnerAngle */
+ num get coneInnerAngle native "PannerNode_coneInnerAngle_Getter";
+
+
+ /** @domName PannerNode.coneInnerAngle */
+ void set coneInnerAngle(num value) native "PannerNode_coneInnerAngle_Setter";
+
+
+ /** @domName PannerNode.coneOuterAngle */
+ num get coneOuterAngle native "PannerNode_coneOuterAngle_Getter";
+
+
+ /** @domName PannerNode.coneOuterAngle */
+ void set coneOuterAngle(num value) native "PannerNode_coneOuterAngle_Setter";
+
+
+ /** @domName PannerNode.coneOuterGain */
+ num get coneOuterGain native "PannerNode_coneOuterGain_Getter";
+
+
+ /** @domName PannerNode.coneOuterGain */
+ void set coneOuterGain(num value) native "PannerNode_coneOuterGain_Setter";
+
+
+ /** @domName PannerNode.distanceGain */
+ AudioGain get distanceGain native "PannerNode_distanceGain_Getter";
+
+
+ /** @domName PannerNode.distanceModel */
+ int get distanceModel native "PannerNode_distanceModel_Getter";
+
+
+ /** @domName PannerNode.distanceModel */
+ void set distanceModel(int value) native "PannerNode_distanceModel_Setter";
+
+
+ /** @domName PannerNode.maxDistance */
+ num get maxDistance native "PannerNode_maxDistance_Getter";
+
+
+ /** @domName PannerNode.maxDistance */
+ void set maxDistance(num value) native "PannerNode_maxDistance_Setter";
+
+
+ /** @domName PannerNode.panningModel */
+ int get panningModel native "PannerNode_panningModel_Getter";
+
+
+ /** @domName PannerNode.panningModel */
+ void set panningModel(int value) native "PannerNode_panningModel_Setter";
+
+
+ /** @domName PannerNode.refDistance */
+ num get refDistance native "PannerNode_refDistance_Getter";
+
+
+ /** @domName PannerNode.refDistance */
+ void set refDistance(num value) native "PannerNode_refDistance_Setter";
+
+
+ /** @domName PannerNode.rolloffFactor */
+ num get rolloffFactor native "PannerNode_rolloffFactor_Getter";
+
+
+ /** @domName PannerNode.rolloffFactor */
+ void set rolloffFactor(num value) native "PannerNode_rolloffFactor_Setter";
+
+
+ /** @domName PannerNode.setOrientation */
+ void setOrientation(num x, num y, num z) native "PannerNode_setOrientation_Callback";
+
+
+ /** @domName PannerNode.setPosition */
+ void setPosition(num x, num y, num z) native "PannerNode_setPosition_Callback";
+
+
+ /** @domName PannerNode.setVelocity */
+ void setVelocity(num x, num y, num z) native "PannerNode_setVelocity_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName ScriptProcessorNode
+class ScriptProcessorNode extends AudioNode implements EventTarget {
+ ScriptProcessorNode.internal(): super.internal();
+
+ /// @domName EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent; @docsEditable true
+ ScriptProcessorNodeEvents get on =>
+ new ScriptProcessorNodeEvents(this);
+
+
+ /** @domName ScriptProcessorNode.bufferSize */
+ int get bufferSize native "ScriptProcessorNode_bufferSize_Getter";
+
+}
+
+class ScriptProcessorNodeEvents extends Events {
+ ScriptProcessorNodeEvents(EventTarget _ptr) : super(_ptr);
+
+ EventListenerList get audioProcess => this['audioprocess'];
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+/// @domName WaveShaperNode
+class WaveShaperNode extends AudioNode {
+ WaveShaperNode.internal(): super.internal();
+
+
+ /** @domName WaveShaperNode.curve */
+ Float32Array get curve native "WaveShaperNode_curve_Getter";
+
+
+ /** @domName WaveShaperNode.curve */
+ void set curve(Float32Array value) native "WaveShaperNode_curve_Setter";
+
+}
+// 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.
+
+
+class _AudioElementFactoryProvider {
+ static AudioElement createAudioElement([String src]) native "HTMLAudioElement_constructor_Callback";
+}
diff --git a/tests/co19/co19-compiler.status b/tests/co19/co19-compiler.status
index b076d5c..a4a880f 100644
--- a/tests/co19/co19-compiler.status
+++ b/tests/co19/co19-compiler.status
@@ -3,13 +3,6 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dartc ]
-Language/03_Overview/1_Scoping_A02_t05: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/1_Scoping_A02_t06: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/2_Privacy_A01_t05: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/2_Privacy_A01_t09: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/2_Privacy_A01_t10: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/2_Privacy_A01_t19: Fail # TODO(analyzer-team): Please triage this failure.
-Language/03_Overview/2_Privacy_A01_t20: Fail # TODO(analyzer-team): Please triage this failure.
Language/05_Variables/05_Variables_A05_t11: Fail # TODO(analyzer-team): Please triage this failure.
Language/05_Variables/05_Variables_A05_t12: Fail # TODO(analyzer-team): Please triage this failure.
Language/05_Variables/05_Variables_A05_t13: Fail # TODO(analyzer-team): Please triage this failure.
@@ -18,23 +11,16 @@
Language/05_Variables/05_Variables_A06_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/05_Variables/05_Variables_A11_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # TODO(analyzer-team): Please triage this failure.
-Language/06_Functions/1_Function_Declaration_A02_t03: Fail # TODO(analyzer-team): Please triage this failure.
-Language/06_Functions/1_Function_Declaration_A03_t03: Fail # TODO(analyzer-team): Please triage this failure.
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t10: Fail # TODO(analyzer-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t01: Fail # TODO(analyzer-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t02: Fail # TODO(analyzer-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t02: Fail # TODO(analyzer-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t04: Fail # TODO(analyzer-team): Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(analyzer-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t03: Fail # TODO(analyzer-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t05: Fail # TODO(analyzer-team): Please triage this failure.
Language/08_Interfaces/5_Superinterfaces_A01_t02: Fail # TODO(analyzer-team): Please triage this failure.
-Language/09_Generics/09_Generics_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
-Language/09_Generics/09_Generics_A05_t02: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/01_Constants_A03_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/01_Constants_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/01_Constants_A14_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/01_Constants_A20_t03: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/08_Throw_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
-Language/11_Expressions/11_Instance_Creation/1_New_A02_t07: Fail # TODO(analyzer-team): Please triage this failure.
-Language/11_Expressions/11_Instance_Creation/1_New_A06_t06: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/11_Instance_Creation/2_Const_A10_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/18_Assignment_A05_t05: Fail # TODO(analyzer-team): Please triage this failure.
Language/11_Expressions/31_Type_Test_A01_t02: Fail # TODO(analyzer-team): Please triage this failure.
@@ -45,6 +31,9 @@
Language/12_Statements/03_Variable_Declaration_A01_t16: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/06_For_A01_t11: Fail # TODO(analyzer-team): Please triage this failure.
Language/12_Statements/09_Switch_A02_t03: Fail # TODO(analyzer-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t01: Fail # TODO(analyzer-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t02: Fail # TODO(analyzer-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t03: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t29: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/2_Exports_A05_t01: Fail # TODO(analyzer-team): Please triage this failure.
@@ -52,6 +41,10 @@
Language/13_Libraries_and_Scripts/4_Scripts_A01_t23: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t01: Fail # TODO(analyzer-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # TODO(analyzer-team): Please triage this failure.
+Language/14_Types/5_Function_Types_A04_t01: Fail # TODO(analyzer-team): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t09: Fail # TODO(analyzer-team): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t11: Fail # TODO(analyzer-team): Please triage this failure.
+
# co19 issue 320
Language/13_Libraries_and_Scripts/1_Imports_A02_t12: Fail, OK
@@ -59,18 +52,8 @@
Language/13_Libraries_and_Scripts/1_Imports_A02_t18: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t19: Fail, OK
-
-# co19 issue 330
-# was issue 6824
-Language/13_Libraries_and_Scripts/2_Exports_A04_t05: Fail
-Language/13_Libraries_and_Scripts/2_Exports_A04_t06: Fail
-
-
# co19 issue 327
-Language/03_Overview/1_Scoping_A02_t17: Fail, OK
Language/03_Overview/1_Scoping_A02_t32: Fail, OK
-Language/12_Statements/03_Variable_Declaration_A01_t10: Fail, OK
-Language/12_Statements/03_Variable_Declaration_A01_t17: Fail, OK
Language/03_Overview/2_Privacy_A01_t08: pass # http://dartbug.com/5179
Language/03_Overview/2_Privacy_A01_t11: pass # http://dartbug.com/5179
@@ -110,19 +93,11 @@
Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t01: pass # http://dartbug.com/5179
# co19 issue 298
-Language/03_Overview/2_Privacy_A01_t07: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t16: Fail, OK
Language/13_Libraries_and_Scripts/1_Imports_A02_t17: Fail, OK
-Language/07_Classes/6_Constructors/2_Factories_A03_t01: Fail, OK # co19 issue 307
-
-# co19 issue 329
-Language/13_Libraries_and_Scripts/4_Scripts_A01_t20: Fail
-
-Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t03: Fail, OK # contains syntax error
Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t04: Fail, OK # contains syntax error
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t02: Fail, OK # deprecated parameter syntax
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail # Issue 5294
# The following tests use NoSuchMethodException instead of NoSuchMethodError.
Language/06_Functions/4_External_Functions_A01_t01: Fail, OK # co19 issue 195
@@ -140,7 +115,6 @@
Language/11_Expressions/01_Constants_A16_t02: Fail # Issue 1473
Language/11_Expressions/01_Constants_A16_t03: Fail # Issue 1473
Language/11_Expressions/01_Constants_A17_t03: Fail # Issue 1473
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail # Issue 3524
Language/11_Expressions/22_Equality_A01_t19: Fail # language change 3368
Language/11_Expressions/22_Equality_A01_t20: Fail # language change 3368
Language/11_Expressions/22_Equality_A02_t03: Fail, OK # co19 issue 169
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 1614758..b0ef1f2 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -3,6 +3,25 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2dart ]
+Language/03_Overview/1_Scoping_A02_t32: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t01: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t02: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t03: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t04: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t05: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/11_Expressions/11_Instance_Creation/2_Const_A03_t01: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/12_Statements/03_Variable_Declaration_A04_t07: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/12_Statements/09_Switch_A04_t01: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t01: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t02: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t03: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/13_Libraries_and_Scripts/4_Scripts_A01_t20: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/14_Types/5_Function_Types_A04_t01: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t09: Fail # TODO(dart2dart-team): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t11: Fail # TODO(dart2dart-team): Please triage this failure.
+
+
# Calling unresolved class constructor:
Language/03_Overview/2_Privacy_A01_t19: Fail
Language/03_Overview/2_Privacy_A01_t20: Fail
@@ -57,10 +76,6 @@
Language/06_Functions/06_Functions_A01_t22: Fail # inherited from VM
Language/06_Functions/06_Functions_A01_t31: Fail # http://dartbug.com/5519
Language/06_Functions/1_Function_Declaration_A01_t01: Fail # http://dartbug.com/5519
-Language/06_Functions/1_Function_Declaration_A02_t02: Fail # http://dartbug.com/5519
-Language/06_Functions/1_Function_Declaration_A02_t03: Fail # inherited from VM
-Language/06_Functions/1_Function_Declaration_A03_t02: Fail # http://dartbug.com/5519
-Language/06_Functions/1_Function_Declaration_A03_t03: Fail # inherited from VM
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t03: Fail # http://dartbug.com/5519
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # http://dartbug.com/5519
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t05: Fail # http://dartbug.com/5519
@@ -128,7 +143,6 @@
Language/07_Classes/1_Instance_Methods_A02_t05: Fail # http://dartbug.com/5519
Language/07_Classes/1_Instance_Methods_A06_t01: Fail # Inherited from dart2js
Language/07_Classes/1_Instance_Methods_A06_t02: Fail # Inherited from dart2js
-Language/07_Classes/1_Instance_Methods_A07_t01: Fail # Inherited from dart2js
Language/07_Classes/2_Getters_A01_t03: Fail # inherited from VM
Language/07_Classes/2_Getters_A01_t04: Fail # http://dartbug.com/5519
Language/07_Classes/2_Getters_A01_t05: Fail # inherited from VM
@@ -158,13 +172,7 @@
Language/07_Classes/6_Constructors/1_Generative_Constructors_A16_t07: Fail # http://dartbug.com/6242
Language/07_Classes/6_Constructors/1_Generative_Constructors_A21_t01: Fail # http://dartbug.com/5519
Language/07_Classes/6_Constructors/2_Factories_A01_t05: Fail # Inherited from dartjs
-Language/07_Classes/6_Constructors/2_Factories_A05_t01: Fail # Inherited from dart2js
-Language/07_Classes/6_Constructors/2_Factories_A05_t02: Fail # Inherited from dart2js
-Language/07_Classes/6_Constructors/2_Factories_A05_t03: Fail # Inherited from dart2js
-Language/07_Classes/6_Constructors/2_Factories_A05_t04: Fail # Inherited from dart2js
Language/07_Classes/6_Constructors/2_Factories_A07_t01: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A02_t01: Fail # http://dartbug.com/5519
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A02_t03: Fail # http://dartbug.com/5519
Language/07_Classes/6_Constructors/3_Constant_Constructors_A03_t01: Fail # http://dartbug.com/5519
Language/07_Classes/6_Constructors/3_Constant_Constructors_A03_t02: Fail # http://dartbug.com/5519
Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t01: Fail # inherited from VM
@@ -257,7 +265,6 @@
Language/11_Expressions/11_Instance_Creation/1_New_A03_t01: Fail # http://dartbug.com/6895
Language/11_Expressions/11_Instance_Creation/1_New_A03_t02: Fail # http://dartbug.com/6895
Language/11_Expressions/11_Instance_Creation/1_New_A04_t01: Fail # http://dartbug.com/6895
-Language/11_Expressions/11_Instance_Creation/1_New_A04_t02: Fail # http://dartbug.com/6895
Language/11_Expressions/11_Instance_Creation/1_New_A09_t09: Fail # inherited from VM
Language/11_Expressions/11_Instance_Creation/2_Const_A01_t02: Fail # http://dartbug.com/5519
Language/11_Expressions/11_Instance_Creation/2_Const_A06_t01: Fail # http://dartbug.com/5519
@@ -361,12 +368,8 @@
Language/13_Libraries_and_Scripts/1_Imports_A02_t14: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/1_Imports_A02_t16: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/1_Imports_A02_t17: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/1_Imports_A02_t18: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/1_Imports_A02_t28: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/1_Imports_A03_t31: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/1_Imports_A05_t01: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/2_Exports_A04_t05: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/2_Exports_A04_t06: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/3_Parts_A03_t02: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/4_Scripts_A01_t21: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/4_Scripts_A01_t22: Fail # Inherited from dart2js
@@ -374,11 +377,7 @@
Language/13_Libraries_and_Scripts/4_Scripts_A03_t01: Fail # http://dartbug.com/5519
Language/13_Libraries_and_Scripts/4_Scripts_A03_t03: Fail # http://dartbug.com/5519
Language/13_Libraries_and_Scripts/5_URIs_A01_t01: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/5_URIs_A01_t04: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/5_URIs_A01_t05: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/5_URIs_A01_t11: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/5_URIs_A01_t14: Fail # Inherited from dart2js
-Language/13_Libraries_and_Scripts/5_URIs_A01_t15: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/5_URIs_A01_t24: Fail # Inherited from dart2js
Language/13_Libraries_and_Scripts/5_URIs_A01_t25: Fail # Inherited from dart2js
@@ -400,8 +399,6 @@
LibTest/core/Date/Date.fromString_A03_t01: Fail, OK # Issue co19 - 121
LibTest/core/Date/toString_A02_t01: Fail, OK # inherited from VM
LibTest/core/Date/year_A01_t01: Fail, OK # inherited from VM
-LibTest/core/Future/chain_A03_t01: Fail, OK # co19 issue 328
-LibTest/core/Future/transform_A03_t01: Fail, OK # co19 issue 328
LibTest/core/LinkedHashMap/LinkedHashMap_class_A01_t01: Fail, OK # co19 issue 293
LibTest/core/Map/getKeys_A01_t01: Fail, OK # co19 issue 293
LibTest/core/Map/getKeys_A01_t02: Fail, OK # co19 issue 293
@@ -431,8 +428,8 @@
LibTest/core/int/operator_left_shift_A01_t02: Fail, OK # co19 issue 129
LibTest/core/int/toRadixString_A01_t01: Fail # inherited from VM
LibTest/isolate/ReceivePort/receive_A01_t02: Fail, OK # co19 issue 276
-LibTest/isolate/SendPort/send_A02_t02: Fail, OK # co19 issue 293
-LibTest/isolate/SendPort/send_A02_t03: Fail, OK # co19 issue 293
+LibTest/isolate/SendPort/send_A02_t02: Fail, Timeout, OK # co19 issue 293
+LibTest/isolate/SendPort/send_A02_t03: Fail, Timeout, OK # co19 issue 293
LibTest/isolate/SendPort/send_A02_t04: Fail, OK # co19 issue 293
LibTest/isolate/isolate_api/port_A01_t01: Skip # Times out.
LibTest/isolate/isolate_api/spawnUri_A01_t01: Fail, OK # Problems with the test: encoded file name
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index b878b65..42c838e 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -4,6 +4,10 @@
# Crashes first, please. Then untriaged bugs. There is a section below
# for co19 bugs.
+[ $compiler == dart2js && $host_checked ]
+Language/13_Libraries_and_Scripts/5_URIs_A01_t15: Crash # Issue 6931
+Language/13_Libraries_and_Scripts/5_URIs_A01_t14: Crash # Issue 6931
+
[ $compiler == dart2js ]
Language/03_Overview/1_Scoping_A02_t05: Fail # TODO(ahe): Please triage this failure.
Language/03_Overview/1_Scoping_A02_t06: Fail # TODO(ahe): Please triage this failure.
@@ -35,11 +39,12 @@
Language/07_Classes/07_Classes_A03_t07: Fail # TODO(ahe): Please triage this failure.
Language/07_Classes/1_Instance_Methods_A06_t01: Fail # TODO(ahe): Please triage this failure.
Language/07_Classes/1_Instance_Methods_A06_t02: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/1_Instance_Methods_A07_t01: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t01: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t02: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t03: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t04: Fail # TODO(ahe): Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(ahe): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t01: Fail # TODO(ahe): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t02: Fail # TODO(ahe): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t03: Fail # TODO(ahe): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t04: Fail # TODO(ahe): Please triage this failure.
+Language/07_Classes/6_Constructors/2_Factories_A02_t05: Fail # TODO(ahe): Please triage this failure.
Language/07_Classes/6_Constructors/2_Factories_A07_t01: Fail # TODO(ahe): Please triage this failure.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: Fail # TODO(ahe): Please triage this failure.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: Fail # TODO(ahe): Please triage this failure.
@@ -63,6 +68,7 @@
Language/11_Expressions/11_Instance_Creation/1_New_A02_t06: Fail # TODO(ahe): Please triage this failure.
Language/11_Expressions/11_Instance_Creation/1_New_A02_t07: Fail # TODO(ahe): Please triage this failure.
Language/11_Expressions/11_Instance_Creation/2_Const_A01_t02: Fail # TODO(ahe): Please triage this failure.
+Language/11_Expressions/11_Instance_Creation/2_Const_A03_t01: Fail # TODO(ahe): Please triage this failure.
Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail # TODO(ahe): Please triage this failure.
Language/11_Expressions/18_Assignment_A05_t02: Fail # TODO(ahe): Please triage this failure.
Language/11_Expressions/18_Assignment_A05_t04: Fail # TODO(ahe): Please triage this failure.
@@ -105,6 +111,7 @@
Language/12_Statements/03_Variable_Declaration_A04_t04: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/03_Variable_Declaration_A04_t05: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/03_Variable_Declaration_A04_t06: Fail # TODO(ahe): Please triage this failure.
+Language/12_Statements/03_Variable_Declaration_A04_t07: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/04_Local_Function_Declaration_A01_t01: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/04_Local_Function_Declaration_A02_t02: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/06_For_A01_t11: Fail # TODO(ahe): Please triage this failure.
@@ -114,7 +121,11 @@
Language/12_Statements/09_Switch_A02_t03: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/09_Switch_A03_t01: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/09_Switch_A03_t02: Fail # TODO(ahe): Please triage this failure.
+Language/12_Statements/09_Switch_A04_t01: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/09_Switch_A06_t02: Fail # TODO(ahe): Please triage this failure.
+Language/12_Statements/10_Try_A03_t01: Fail # TODO(ahe): Please triage this failure.
+Language/12_Statements/10_Try_A03_t02: Fail # TODO(ahe): Please triage this failure.
+Language/12_Statements/10_Try_A03_t03: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/10_Try_A06_t01: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/10_Try_A07_t03: Fail # TODO(ahe): Please triage this failure.
Language/12_Statements/11_Return_A05_t01: Fail # TODO(ahe): Please triage this failure.
@@ -126,25 +137,19 @@
Language/13_Libraries_and_Scripts/1_Imports_A02_t14: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t16: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t17: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/1_Imports_A02_t18: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t19: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t27: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A02_t28: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/1_Imports_A03_t31: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A03_t51: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A05_t01: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Exports_A04_t05: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Exports_A04_t06: Fail # TODO(ahe): Please triage this failure.
+Language/13_Libraries_and_Scripts/2_Exports_A06_t02: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/3_Parts_A03_t02: Fail # TODO(ahe): Please triage this failure.
+Language/13_Libraries_and_Scripts/4_Scripts_A01_t20: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/4_Scripts_A01_t21: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/4_Scripts_A01_t22: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/4_Scripts_A01_t23: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t01: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/5_URIs_A01_t04: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/5_URIs_A01_t05: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t11: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/5_URIs_A01_t14: Fail # TODO(ahe): Please triage this failure.
-Language/13_Libraries_and_Scripts/5_URIs_A01_t15: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t24: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t25: Fail # TODO(ahe): Please triage this failure.
@@ -174,8 +179,11 @@
Language/14_Types/5_Function_Types_A03_t11: Fail # TODO(ahe): Please triage this failure.
Language/14_Types/5_Function_Types_A03_t12: Fail # TODO(ahe): Please triage this failure.
Language/14_Types/5_Function_Types_A03_t13: Fail # TODO(ahe): Please triage this failure.
+Language/14_Types/5_Function_Types_A04_t01: Fail # TODO(ahe): Please triage this failure.
Language/14_Types/5_Function_Types_A06_t01: Fail # TODO(ahe): Please triage this failure.
Language/15_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: Fail # TODO(ahe): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t09: Fail # TODO(ahe): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t11: Fail # TODO(ahe): Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A01_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A02_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A06_t01: Fail # TODO(ahe): Please triage this failure.
@@ -184,7 +192,6 @@
LibTest/core/double/parse_A01_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/isolate/ReceivePort/receive_A01_t02: Fail # TODO(ahe): Please triage this failure.
LibTest/math/Random/nextDouble_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/math/exp_A01_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/math/pow_A01_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/math/pow_A11_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/math/pow_A13_t01: Fail # TODO(ahe): Please triage this failure.
@@ -194,6 +201,8 @@
# Partially implemented rediriecting constructors makes this fail.
Language/07_Classes/6_Constructors/2_Factories_A01_t05: Fail
+[ $compiler == dart2js && ($system == linux || $system == macos)]
+LibTest/math/exp_A01_t01: Fail # TODO(ahe): Please triage this failure.
[ $compiler == dart2js && $unchecked ]
LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: Fail # TODO(ahe): Please triage this failure.
@@ -246,6 +255,7 @@
Language/12_Statements/09_Switch_A05_t01: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A03_t06: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A03_t26: Fail # TODO(ahe): Please triage this failure.
+Language/13_Libraries_and_Scripts/1_Imports_A03_t31: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A03_t46: Fail # TODO(ahe): Please triage this failure.
Language/13_Libraries_and_Scripts/1_Imports_A03_t66: Fail # TODO(ahe): Please triage this failure.
Language/14_Types/4_Interface_Types_A08_t03: Fail # TODO(ahe): Please triage this failure.
@@ -318,9 +328,6 @@
Language/09_Generics/09_Generics_A05_t01: Fail # co19 issue 297
-[ $compiler == dart2js && $system == windows && $jscl ]
-LibTest/core/double/operator_remainder_A01_t04: Fail
-
[ $compiler == dart2js ]
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # TODO(ahe): Enforce optional parameter semantics.
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t01: Fail # http://dartbug.com/5026
@@ -385,8 +392,6 @@
Language/11_Expressions/22_Equality_A01_t01: Fail, OK # Function declaration takes precedence over function expression.
Language/11_Expressions/28_Postfix_Expressions_A01_t01: Fail, OK # A map literal cannot start an expression statement.
-Language/06_Functions/1_Function_Declaration_A02_t03: Fail, OK # co19 issue 210
-Language/06_Functions/1_Function_Declaration_A03_t03: Fail, OK # co19 issue 210
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t14: Fail, OK # co19 issue 210
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t15: Fail, OK # co19 issue 210
Language/11_Expressions/05_Strings/1_String_Interpolation_A01_t09: Fail, OK # co19 issue 210
@@ -403,8 +408,6 @@
Language/03_Overview/2_Privacy_A01_t11: Pass, OK # co19 issue 316
Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t01: Pass, OK # co19 issue 316
-LibTest/core/Future/chain_A03_t01: Fail, OK # co19 issue 328
-LibTest/core/Future/transform_A03_t01: Fail, OK # co19 issue 328
[ $compiler == dart2js && $jscl ]
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail, Pass # issue 3333
@@ -501,8 +504,6 @@
Language/05_Variables/05_Variables_A05_t01: Fail # Checks that a compile-time error occurs if a constant variable is not initialized.
Language/06_Functions/06_Functions_A01_t31: Fail # Checks that functions can't be declared as static inside of a function body.
Language/06_Functions/1_Function_Declaration_A01_t01: Fail # Checks that it is a compile-time error to preface library function with 'static'.
-Language/06_Functions/1_Function_Declaration_A02_t02: Fail # Checks that 'id' is not assignable since its declaration is equivalent to a final variable declaration.
-Language/06_Functions/1_Function_Declaration_A03_t02: Fail # Checks that 'id' is not assignable since its declaration is equivalent to the final variable declaration.
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t03: Fail # Checks that a required parameter can be constant. Reassigning it should produce a compile-time error.
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # Checks that static variable declaration can't be a required formal parameter
Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t05: Fail # Checks that reassigning a final required parameter produces a compile-time error.
@@ -554,8 +555,6 @@
Language/07_Classes/6_Constructors/1_Generative_Constructors_A03_t05: Fail # Checks that redirecting constructor can not have initializing formals.
Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Fail # Checks that error is produced if a final variable is not initialized in one of the specified ways.
Language/07_Classes/6_Constructors/1_Generative_Constructors_A21_t01: Fail # Checks that a compile-time error occur if k’s initializer list contains an initializer for a final variable whose declaration includes an initialization expression.
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A02_t01: Fail # Checks that it is a compile-time error when a constant constructor declaration has a body.
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A02_t03: Fail # Checks that it is a compile-time error if a named constant constructor has a body.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A03_t01: Fail # Checks that a compile-time error is produced when a class with constant constructor also declares a non-final instance variable.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A03_t02: Fail # Checks that compile-time error is produced when a class with constant constructor inherits a non-final instance variable.
Language/07_Classes/6_Constructors_A01_t01: Fail # Checks that a compile-error is produced when a constructor's id coincides with the name of a field in the same class.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 60702b9..95a04a4 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -3,19 +3,11 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == none && $runtime == vm ]
-Language/13_Libraries_and_Scripts/1_Imports_A02_t21: Crash # TODO(vm-team): Please triage this crash.
-Language/13_Libraries_and_Scripts/1_Imports_A02_t22: Crash # TODO(vm-team): Please triage this crash.
+Language/13_Libraries_and_Scripts/1_Imports_A02_t21: Crash # Dart issue 6060
+Language/13_Libraries_and_Scripts/1_Imports_A02_t22: Crash # Dart issue 6060
-Language/05_Variables/05_Variables_A05_t04: Fail # TODO(vm-team): Please triage this failure.
-Language/05_Variables/05_Variables_A05_t11: Fail # TODO(vm-team): Please triage this failure.
-Language/05_Variables/05_Variables_A05_t13: Fail # TODO(vm-team): Please triage this failure.
-Language/05_Variables/05_Variables_A05_t14: Fail # TODO(vm-team): Please triage this failure.
-Language/05_Variables/05_Variables_A05_t15: Fail # TODO(vm-team): Please triage this failure.
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # TODO(vm-team): Please triage this failure.
-Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # TODO(vm-team): Please triage this failure.
+Language/03_Overview/1_Scoping_A02_t32: Fail # TODO(vm-team): Please triage this failure.
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A01_t10: Fail # TODO(vm-team): Please triage this failure.
-Language/07_Classes/2_Getters_A01_t03: Fail # Expects compile-time error when getter has empty parameter list.
-Language/07_Classes/2_Getters_A01_t05: Fail # Expects compile-time error when getter has empty parameter list.
Language/07_Classes/3_Setters_A04_t01: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/3_Setters_A04_t04: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/3_Setters_A04_t05: Fail # TODO(vm-team): Please triage this failure.
@@ -25,9 +17,7 @@
Language/07_Classes/4_Abstract_Instance_Members_A03_t05: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/4_Abstract_Instance_Members_A04_t05: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/4_Abstract_Instance_Members_A04_t06: Fail # TODO(vm-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t01: Fail # TODO(vm-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t03: Fail # TODO(vm-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A05_t04: Fail # TODO(vm-team): Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t01: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t02: Fail # TODO(vm-team): Please triage this failure.
Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t03: Fail # TODO(vm-team): Please triage this failure.
@@ -123,6 +113,7 @@
Language/11_Expressions/30_Identifier_Reference_A08_t02: Fail # TODO(vm-team): Please triage this failure.
Language/11_Expressions/31_Type_Test_A01_t02: Fail # TODO(vm-team): Please triage this failure.
Language/11_Expressions/31_Type_Test_A01_t04: Fail # TODO(vm-team): Please triage this failure.
+Language/12_Statements/03_Variable_Declaration_A04_t07: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/04_Local_Function_Declaration_A02_t02: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/06_For_A01_t11: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/09_Switch_A01_t02: Fail # TODO(vm-team): Please triage this failure.
@@ -131,7 +122,11 @@
Language/12_Statements/09_Switch_A02_t03: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/09_Switch_A03_t01: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/09_Switch_A03_t02: Fail # TODO(vm-team): Please triage this failure.
+Language/12_Statements/09_Switch_A04_t01: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/09_Switch_A06_t02: Fail # TODO(vm-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t01: Fail # TODO(vm-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t02: Fail # TODO(vm-team): Please triage this failure.
+Language/12_Statements/10_Try_A03_t03: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/10_Try_A11_t01: Fail # TODO(vm-team): Please triage this failure.
Language/12_Statements/12_Labels_A01_t03: Fail # TODO(vm-team): Please triage this failure.
Language/13_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t04: Fail # TODO(vm-team): Please triage this failure.
@@ -139,13 +134,17 @@
Language/13_Libraries_and_Scripts/1_Imports_A05_t01: Fail # TODO(vm-team): Please triage this failure.
Language/13_Libraries_and_Scripts/2_Exports_A04_t02: Fail # TODO(vm-team): Please triage this failure.
Language/13_Libraries_and_Scripts/2_Exports_A04_t03: Fail # TODO(vm-team): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Exports_A04_t05: Fail # TODO(vm-team): Please triage this failure.
-Language/13_Libraries_and_Scripts/2_Exports_A04_t06: Fail # TODO(vm-team): Please triage this failure.
-Language/13_Libraries_and_Scripts/4_Scripts_A01_t20: Fail # TODO(vm-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t01: Fail # TODO(vm-team): Please triage this failure.
+Language/13_Libraries_and_Scripts/5_URIs_A01_t04: Fail # TODO(vm-team): Please triage this failure.
+Language/13_Libraries_and_Scripts/5_URIs_A01_t05: Fail # TODO(vm-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t11: Fail # TODO(vm-team): Please triage this failure.
+Language/13_Libraries_and_Scripts/5_URIs_A01_t14: Fail # TODO(vm-team): Please triage this failure.
+Language/13_Libraries_and_Scripts/5_URIs_A01_t15: Fail # TODO(vm-team): Please triage this failure.
Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # TODO(vm-team): Please triage this failure.
+Language/14_Types/5_Function_Types_A04_t01: Fail # TODO(vm-team): Please triage this failure.
Language/14_Types/5_Function_Types_A06_t01: Fail # TODO(vm-team): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t09: Fail # TODO(vm-team): Please triage this failure.
+Language/15_Reference/1_Lexical_Rules_A01_t11: Fail # TODO(vm-team): Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A01_t01: Fail # TODO(vm-team): Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A02_t01: Fail # TODO(vm-team): Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A06_t01: Fail # TODO(vm-team): Please triage this failure.
@@ -158,10 +157,16 @@
LibTest/math/pow_A13_t01: Fail # TODO(vm-team): Please triage this failure.
LibTest/math/sin_A01_t01: Fail # TODO(vm-team): Please triage this failure.
+Language/05_Variables/05_Variables_A05_t04: Fail # Dart issue 5881
+Language/05_Variables/05_Variables_A05_t11: Fail # Dart issue 5885
+Language/05_Variables/05_Variables_A05_t13: Fail # Dart issue 5885
+Language/05_Variables/05_Variables_A05_t14: Fail # Dart issue 5885
+Language/05_Variables/05_Variables_A05_t15: Fail # Dart issue 5885
+Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Dart issue 5802
+Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Dart issue 5894
+
LibTest/isolate/isolate_api/port_A01_t01: Skip # Times out.
-Language/06_Functions/1_Function_Declaration_A02_t03: Fail # issue 6058
-Language/06_Functions/1_Function_Declaration_A03_t03: Fail # issue 6058
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t01: Fail # issue 6085
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t02: Fail # issue 6085
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # issue 6085
@@ -169,17 +174,12 @@
[ $compiler == none && $runtime == vm && $checked ]
Language/12_Statements/09_Switch_A05_t01: Fail # TODO(vm-team): Please triage this failure.
-Language/14_Types/5_Function_Types_A03_t12: Fail # TODO(vm-team): Please triage this failure.
Language/11_Expressions/11_Instance_Creation_A05_t02: Fail # co19 issue 234
[ $compiler == none && $runtime == vm && $unchecked ]
-Language/13_Libraries_and_Scripts/1_Imports_A03_t31: Fail # TODO(vm-team): Please triage this failure.
LibTest/core/Date/Date.fromMillisecondsSinceEpoch_A03_t01: Fail # TODO(vm-team): Please triage this failure.
-Language/11_Expressions/11_Instance_Creation/2_Const_A03_t01: Fail, OK # co19 issue 282
-Language/11_Expressions/11_Instance_Creation/2_Const_A03_t02: Fail, OK # co19 issue 282
-
[ $compiler == none && $runtime == vm ]
# Not properly reporting exception in initializer expressions
Language/11_Expressions/01_Constants_A16_t01: Fail
@@ -226,12 +226,8 @@
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail
-# New failures
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail
-LibTest/core/Future/chain_A03_t01: Fail, OK # co19 issue 328
-LibTest/core/Future/transform_A03_t01: Fail, OK # co19 issue 328
-
[ $compiler == none && $runtime == vm ]
LibTest/core/Date/Date.fromString_A03_t01: Fail # Issue co19 - 121
LibTest/core/Match/operator_subscript_A01_t01: Fail
@@ -262,15 +258,6 @@
[ $compiler == none && $runtime == vm && $arch == x64 && $mode == debug ]
LibTest/core/Map/Map_class_A01_t04: Skip # Timeout
-[ $compiler == none && $runtime == vm && $system == windows ]
-LibTest/math/atan2_A01_t03: Fail # http://dartbug.com/5407
-LibTest/core/double/operator_remainder_A01_t04: Fail # http://dartbug.com/5407
-LibTest/core/double/remainder_A01_t04: Fail # http://dartbug.com/5407
-LibTest/core/double/round_A01_t01: Fail # http://dartbug.com/5407
-LibTest/core/int/operator_remainder_A01_t02: Fail # TODO(vm-team): Please triage this failure.
-LibTest/core/int/remainder_A01_t02: Fail # TODO(vm-team): Please triage this failure.
-
-
[ $compiler == none && $runtime == vm ]
# The following tests use the deprecated Date interface.
@@ -278,8 +265,8 @@
LibTest/core/Date/toString_A02_t01: Fail, OK
LibTest/core/Date/year_A01_t01: Fail, OK
-LibTest/isolate/SendPort/send_A02_t02: Fail, OK # co19 issue 293
-LibTest/isolate/SendPort/send_A02_t03: Fail, OK # co19 issue 293
+LibTest/isolate/SendPort/send_A02_t02: Skip # co19 issue 293
+LibTest/isolate/SendPort/send_A02_t03: Skip # co19 issue 293
LibTest/isolate/SendPort/send_A02_t04: Fail, OK # co19 issue 293
LibTest/core/LinkedHashMap/LinkedHashMap_class_A01_t01: Fail, OK # co19 issue 293
LibTest/core/Map/getKeys_A01_t01: Fail, OK # co19 issue 293
diff --git a/tests/compiler/dart2js/class_codegen_test.dart b/tests/compiler/dart2js/class_codegen_test.dart
index 51b2d07..0aba4ec 100644
--- a/tests/compiler/dart2js/class_codegen_test.dart
+++ b/tests/compiler/dart2js/class_codegen_test.dart
@@ -64,14 +64,14 @@
twoClasses() {
String generated = compileAll(TEST_ONE);
- Expect.isTrue(generated.contains('\$.A = {\n "super": "Object"'));
- Expect.isTrue(generated.contains('\$.B = {\n "super": "Object"'));
+ Expect.isTrue(generated.contains('\$.A = {"":"Object;"'));
+ Expect.isTrue(generated.contains('\$.B = {"":"Object;"'));
}
subClass() {
checkOutput(String generated) {
- Expect.isTrue(generated.contains('\$.A = {\n "super": "Object"'));
- Expect.isTrue(generated.contains('\$.B = {\n "super": "A"'));
+ Expect.isTrue(generated.contains('\$.A = {"":"Object;"'));
+ Expect.isTrue(generated.contains('\$.B = {"":"A;"'));
}
checkOutput(compileAll(TEST_TWO));
@@ -81,8 +81,7 @@
fieldTest() {
String generated = compileAll(TEST_FOUR);
Expect.isTrue(generated.contains(r"""
-$.B = {"": ["y", "z", "x"],
- "super": "A"
+$.B = {"":"A;y,z,x"
}"""));
}
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index a8db3d5..9b9a1ba 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -111,6 +111,14 @@
}
/**
+ * Checks that the inferred type of the node corresponding to the last
+ * occurence of [: variable; :] in the program is the unknown concrete type.
+ */
+ void checkNodeHasUnknownType(String variable) {
+ return Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnkown());
+ }
+
+ /**
* Checks that [: className#fieldName :]'s inferred type is the concrete type
* made of [baseTypes].
*/
@@ -120,11 +128,26 @@
concreteFrom(baseTypes),
inferrer.inferredFieldTypes[findField(className, fieldName)]);
}
+
+ /**
+ * Checks that [: className#fieldName :]'s inferred type is the unknown
+ * concrete type.
+ */
+ void checkFieldHasUknownType(String className, String fieldName) {
+ return Expect.isTrue(
+ inferrer.inferredFieldTypes[findField(className, fieldName)]
+ .isUnkown());
+ }
}
const String CORELIB = r'''
print(var obj) {}
- abstract class num { operator +(x); operator *(x); operator -(x); }
+ abstract class num {
+ operator +(x);
+ operator *(x);
+ operator -(x);
+ operator ==(x);
+ }
abstract class int extends num { }
abstract class double extends num { }
class bool {}
@@ -144,10 +167,22 @@
MockCompiler compiler = new MockCompiler(coreSource: CORELIB,
enableConcreteTypeInference: true);
compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code);
+ compiler.typesTask.concreteTypesInferrer.testMode = true;
compiler.runCompiler(uri);
return new AnalysisResult(compiler);
}
+testDynamicBackDoor() {
+ final String source = r"""
+ main () {
+ var x = "__dynamic_for_test";
+ x;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasUnknownType('x');
+}
+
testLiterals() {
final String source = r"""
main() {
@@ -267,6 +302,15 @@
result.checkNodeHasType('bar', [result.int]);
}
+testToplevelVariable() {
+ final String source = r"""
+ final top = 'abc';
+ main() { var foo = top; foo; }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('foo', [result.string]);
+}
+
testNonRecusiveFunction() {
final String source = r"""
f(x, y) => true ? x : y;
@@ -298,6 +342,49 @@
result.checkNodeHasType('foo', [result.int, result.string]);
}
+testSimpleSend() {
+ final String source = r"""
+ class A {
+ f(x) => x;
+ }
+ class B {
+ f(x) => 'abc';
+ }
+ class C {
+ f(x) => 3.14;
+ }
+ class D {
+ var f; // we check that this field is ignored in calls to dynamic.f()
+ D(this.f);
+ }
+ main() {
+ new B(); new D(42); // we instantiate B and D but not C
+ var foo = new A().f(42);
+ var bar = "__dynamic_for_test".f(42);
+ foo; bar;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('foo', [result.int]);
+ result.checkNodeHasType('bar', [result.int, result.string]);
+}
+
+testSendToClosureField() {
+ final String source = r"""
+ f(x) => x;
+ class A {
+ var g;
+ A(this.g);
+ }
+ main() {
+ var foo = new A(f).g(42);
+ foo;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('foo', [result.int]);
+}
+
testSendToThis1() {
final String source = r"""
class A {
@@ -356,18 +443,27 @@
get y => x;
get z => y;
}
+ class B {
+ var x;
+ B(this.x);
+ }
main() {
var a = new A(42);
+ var b = new B('abc');
var foo = a.x;
var bar = a.y;
var baz = a.z;
- foo; bar; baz;
+ var qux = null.x;
+ var quux = "__dynamic_for_test".x;
+ foo; bar; baz; qux; quux;
}
""";
AnalysisResult result = analyze(source);
result.checkNodeHasType('foo', [result.int]);
result.checkNodeHasType('bar', [result.int]);
result.checkNodeHasType('baz', [result.int]);
+ result.checkNodeHasType('qux', []);
+ result.checkNodeHasType('quux', [result.int, result.string]);
}
testSetters() {
@@ -379,15 +475,34 @@
set y(a) { x = a; z = a; }
set z(a) { w = a; }
}
+ class B {
+ var x;
+ B(this.x);
+ }
main() {
var a = new A(42, 42);
+ var b = new B(42);
a.x = 'abc';
a.y = true;
+ null.x = 42; // should be ignored
+ "__dynamic_for_test".x = null;
+ "__dynamic_for_test".y = 3.14;
}
""";
AnalysisResult result = analyze(source);
- result.checkFieldHasType('A', 'x', [result.int, result.string, result.bool]);
- result.checkFieldHasType('A', 'w', [result.int, result.bool]);
+ result.checkFieldHasType('B', 'x',
+ [result.int, // new B(42)
+ result.nullType]); // dynamic.x = null
+ result.checkFieldHasType('A', 'x',
+ [result.int, // new A(42, ...)
+ result.string, // a.x = 'abc'
+ result.bool, // a.y = true
+ result.nullType, // dynamic.x = null
+ result.double]); // dynamic.y = 3.14
+ result.checkFieldHasType('A', 'w',
+ [result.int, // new A(..., 42)
+ result.bool, // a.y = true
+ result.double]); // dynamic.y = double
}
testNamedParameters() {
@@ -527,25 +642,55 @@
result.checkNodeHasType('y', [result.string]);
}
+testSetIndexOperator() {
+ final String source = r"""
+ class A {
+ var witness1;
+ var witness2;
+ operator []=(i, x) { witness1 = i; witness2 = x; }
+ }
+ main() {
+ var x = new A()[42] = "abc";
+ x;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('x', [result.string]);
+ // TODO(polux): the two following results should be [:[null, string:], see
+ // testFieldInitialization().
+ result.checkFieldHasType('A', 'witness1', [result.int]);
+ result.checkFieldHasType('A', 'witness2', [result.string]);
+}
+
testCompoundOperators1() {
final String source = r"""
class A {
operator +(x) => "foo";
}
main() {
- var x1 = 1; x1++;
- var x2 = 1; ++x2;
- var x3 = new A(); x3++;
- var x4 = new A(); ++x4;
+ var x1 = 1;
+ x1++;
+ var x2 = 1;
+ ++x2;
+ var x3 = 1;
+ x3 += 42;
+ var x4 = new A();
+ x4++;
+ var x5 = new A();
+ ++x5;
+ var x6 = new A();
+ x6 += true;
- x1; x2; x3; x4;
+ x1; x2; x3; x4; x5; x6;
}
""";
AnalysisResult result = analyze(source);
result.checkNodeHasType('x1', [result.int]);
result.checkNodeHasType('x2', [result.int]);
- result.checkNodeHasType('x3', [result.string]);
+ result.checkNodeHasType('x3', [result.int]);
result.checkNodeHasType('x4', [result.string]);
+ result.checkNodeHasType('x5', [result.string]);
+ result.checkNodeHasType('x6', [result.string]);
}
@@ -553,24 +698,58 @@
final String source = r"""
class A {
var xx;
+ var yy;
var witness1;
var witness2;
+ var witness3;
+ var witness4;
- A(this.xx);
+ A(this.xx, this.yy);
get x { witness1 = "foo"; return xx; }
- set x(y) { witness2 = "foo"; xx = y; }
+ set x(a) { witness2 = "foo"; xx = a; }
+ get y { witness3 = "foo"; return yy; }
+ set y(a) { witness4 = "foo"; yy = a; }
}
main () {
- var a = new A(1);
+ var a = new A(1, 1);
a.x++;
+ a.y++;
}
""";
AnalysisResult result = analyze(source);
result.checkFieldHasType('A', 'xx', [result.int]);
- // TODO(polux): the two following results should be {null, string}, see
- // fieldInitialization().
+ result.checkFieldHasType('A', 'yy', [result.int]);
+ // TODO(polux): the four following results should be [:[null, string]:], see
+ // testFieldInitialization().
result.checkFieldHasType('A', 'witness1', [result.string]);
result.checkFieldHasType('A', 'witness2', [result.string]);
+ result.checkFieldHasType('A', 'witness3', [result.string]);
+ result.checkFieldHasType('A', 'witness4', [result.string]);
+}
+
+testInequality() {
+ final String source = r"""
+ class A {
+ var witness;
+ operator ==(x) { witness = "foo"; return "abc"; }
+ }
+ class B {
+ operator ==(x) { throw "error"; }
+ }
+ main() {
+ var foo = 1 != 2;
+ var bar = new A() != 2;
+ var baz = new B() != 2;
+ foo; bar; baz;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('foo', [result.bool]);
+ result.checkNodeHasType('bar', [result.bool]);
+ result.checkNodeHasType('baz', []);
+ // TODO(polux): the following result should be [:[null, string]:], see
+ // fieldInitialization().
+ result.checkFieldHasType('A', 'witness', [result.string]);
}
testFieldInitialization() {
@@ -588,7 +767,43 @@
result.checkFieldHasType('A', 'y', [result.int]);
}
+testSendWithWrongArity() {
+ final String source = r"""
+ f(x) { }
+ class A { g(x) { } }
+ main () {
+ var x = f();
+ var y = f(1, 2);
+ var z = new A().g();
+ var w = new A().g(1, 2);
+ x; y; z; w;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('x', []);
+ result.checkNodeHasType('y', []);
+ result.checkNodeHasType('z', []);
+ result.checkNodeHasType('w', []);
+}
+
+testDynamicIsAbsorbing() {
+ final String source = r"""
+ main () {
+ var x = 1;
+ if (true) {
+ x = "__dynamic_for_test";
+ } else {
+ x = 42;
+ }
+ x;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasUnknownType('x');
+}
+
void main() {
+ testDynamicBackDoor();
testLiterals();
testRedefinition();
testIfThenElse();
@@ -596,9 +811,12 @@
testWhile();
testFor1();
testFor2();
+ // testToplevelVariable(); // toplevel variables are not yet supported
testNonRecusiveFunction();
testRecusiveFunction();
testMutuallyRecusiveFunction();
+ testSimpleSend();
+ // testSendToClosureField(); // closures are not yet supported
testSendToThis1();
testSendToThis2();
testConstructor();
@@ -613,5 +831,9 @@
testOperators();
testCompoundOperators1();
testCompoundOperators2();
+ testSetIndexOperator();
+ testInequality();
// testFieldInitialization(); // TODO(polux)
+ testSendWithWrongArity();
+ testDynamicIsAbsorbing();
}
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 42b0300..8fa9030 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -45,7 +45,8 @@
abstract class JavaScriptIndexingBehavior {}
class JSInvocationMirror {}
S() {}
- assertHelper(a){}''';
+ assertHelper(a){}
+ throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) {}''';
const String DEFAULT_INTERCEPTORSLIB = r'''
class JSArray {
@@ -54,6 +55,10 @@
class JSString {
var length;
}
+ class JSNumber {
+ }
+ class ObjectInterceptor {
+ }
getInterceptor(x) {}''';
const String DEFAULT_CORELIB = r'''
diff --git a/tests/compiler/dart2js/no_constructor_body_test.dart b/tests/compiler/dart2js/no_constructor_body_test.dart
index 2193286..80cbeb2 100644
--- a/tests/compiler/dart2js/no_constructor_body_test.dart
+++ b/tests/compiler/dart2js/no_constructor_body_test.dart
@@ -18,5 +18,5 @@
main() {
String generated = compileAll(TEST);
Expect.isTrue(
- generated.contains('\$.A = {\n "super": "Object"\n}'));
+ generated.contains('\$.A = {"":"Object;"\n}'));
}
diff --git a/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart b/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart
index 67fa8fc..c1a2e3b 100644
--- a/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart
+++ b/tests/compiler/dart2js/no_duplicate_constructor_body_test.dart
@@ -16,7 +16,7 @@
main() {
String generated = compileAll(CODE);
- RegExp regexp = new RegExp(r'\$.A = {\n "super"');
+ RegExp regexp = new RegExp(r'\$.A = {"":"[A-za-z]+;"');
Iterator<Match> matches = regexp.allMatches(generated).iterator();
checkNumberOfMatches(matches, 1);
}
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index ed2af77..9946eca 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -85,8 +85,9 @@
return unit.localMembers;
}
-NodeList fullParseUnit(String source) {
- return parseBodyCode(source, (parser, tokens) => parser.parseUnit(tokens));
+NodeList fullParseUnit(String source, {DiagnosticListener diagnosticHandler}) {
+ return parseBodyCode(source, (parser, tokens) => parser.parseUnit(tokens),
+ diagnosticHandler: diagnosticHandler);
}
// TODO(ahe): We define this method to avoid having to import
diff --git a/tests/compiler/dart2js/parser_test.dart b/tests/compiler/dart2js/parser_test.dart
index 2bb1b49..bb78175 100644
--- a/tests/compiler/dart2js/parser_test.dart
+++ b/tests/compiler/dart2js/parser_test.dart
@@ -293,6 +293,18 @@
Expect.throws(parse, check);
}
+void testMissingCloseBraceInClass() {
+ final String source = 'class Foo {'; // Missing close '}'.
+ parse() {
+ fullParseUnit(source, diagnosticHandler: new Collector());
+ }
+ check(Collector c) {
+ Expect.equals(EOF_TOKEN, c.token);
+ return true;
+ }
+ Expect.throws(parse, check);
+}
+
void main() {
testGenericTypes();
// TODO(ahe): Enable this test when we handle library prefixes.
@@ -308,4 +320,5 @@
testPostfix();
testOperatorParse();
testMissingCloseParen();
+ testMissingCloseBraceInClass();
}
diff --git a/tests/compiler/dart2js/value_range_test.dart b/tests/compiler/dart2js/value_range_test.dart
index 177eae5..45b6328 100644
--- a/tests/compiler/dart2js/value_range_test.dart
+++ b/tests/compiler/dart2js/value_range_test.dart
@@ -64,7 +64,7 @@
return a.removeLast();
}
""",
-REMOVED, // TODO(6829): Put it back to KEPT
+KEPT,
"""
main() {
diff --git a/tests/compiler/dart2js_native/native_field_name_test.dart b/tests/compiler/dart2js_native/native_field_name_test.dart
new file mode 100644
index 0000000..d479d82
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_field_name_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that native fields are not incorrectly renamed.
+
+class A native "*A" {
+ int myLongPropertyName;
+ int getValue;
+
+ int method(int z) => myLongPropertyName;
+}
+
+
+// This code is inside the setup function, so the function names are not
+// accessible, but the makeA variable is global through the magic of JS scoping.
+// The contents of this are of course not analyzable by the compiler.
+void setup() native r"""
+function getter() {
+ return ++this.getValue;
+}
+
+function setter(x) {
+ this.getValue += 10;
+}
+
+function A(){
+ var a = Object.create(
+ { constructor: { name: 'A'}},
+ { myLongPropertyName: { get: getter,
+ set: setter,
+ configurable: false,
+ writeable: false
+ }
+ });
+ a.getValue = 0;
+ return a;
+}
+
+makeA = function(){return new A;};
+""";
+
+A makeA() native { return new A(); }
+
+main() {
+ setup();
+ var a = makeA();
+ a.myLongPropertyName = 21;
+ int gotten = a.myLongPropertyName;
+ Expect.equals(11, gotten);
+
+ var a2 = makeA();
+ if (a2 is A) {
+ // Inside this 'if' the compiler knows that a2 is an A, so it is tempted
+ // to access myLongPropertyName directly, using its minified name. But
+ // renaming of native properties can only work using getters and setters
+ // that access the original name.
+ a2.myLongPropertyName = 21;
+ int gotten = a2.myLongPropertyName;
+ Expect.equals(11, gotten);
+ }
+}
+
diff --git a/tests/compiler/dart2js_native/native_field_rename_1_frog_test.dart b/tests/compiler/dart2js_native/native_field_rename_1_frog_test.dart
index 112854f..317ce35 100644
--- a/tests/compiler/dart2js_native/native_field_rename_1_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_field_rename_1_frog_test.dart
@@ -18,10 +18,12 @@
}
class X native "*X" {
- int native_key_method() native 'key';
+ @JSName('key')
+ int native_key_method() native;
// This should cause B.key to be renamed, but not A.key.
- int key() native 'key';
+ @JSName('key')
+ int key() native;
}
A makeA() native;
diff --git a/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart b/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart
index c6ae9c7..edbc3b3 100644
--- a/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart
@@ -22,9 +22,11 @@
}
class X native "*X" {
- int native_key_method() native 'key';
+ @JSName('key')
+ int native_key_method() native;
// This should cause B.key to be renamed, but not A.key.
- int key() native 'key';
+ @JSName('key')
+ int key() native;
}
A makeA() native;
diff --git a/tests/compiler/dart2js_native/native_method_rename1_frog_test.dart b/tests/compiler/dart2js_native/native_method_rename1_frog_test.dart
index 820763e..a4add4c 100644
--- a/tests/compiler/dart2js_native/native_method_rename1_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_method_rename1_frog_test.dart
@@ -5,9 +5,14 @@
// Test the feature where the native string declares the native method's name.
class A native "*A" {
- int foo() native 'fooA';
- int bar() native 'barA';
- int baz() native 'bazA';
+ @JSName('fooA')
+ int foo() native;
+
+ @JSName('barA')
+ int bar() native;
+
+ @JSName('bazA')
+ int baz() native;
}
A makeA() native;
diff --git a/tests/compiler/dart2js_native/native_method_rename2_frog_test.dart b/tests/compiler/dart2js_native/native_method_rename2_frog_test.dart
index f3d4bff..c030c7e 100644
--- a/tests/compiler/dart2js_native/native_method_rename2_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_method_rename2_frog_test.dart
@@ -5,11 +5,13 @@
// Test the feature where the native string declares the native method's name.
class A native "*A" {
- int foo() native 'fooA';
+ @JSName('fooA')
+ int foo() native;
}
class B extends A native "*B" {
- int foo() native 'fooB';
+ @JSName('fooB')
+ int foo() native;
}
makeA() native;
diff --git a/tests/compiler/dart2js_native/native_method_rename3_frog_test.dart b/tests/compiler/dart2js_native/native_method_rename3_frog_test.dart
index d1ec6aa..88fc641 100644
--- a/tests/compiler/dart2js_native/native_method_rename3_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_method_rename3_frog_test.dart
@@ -6,11 +6,13 @@
// #3. The name does not get
class A native "*A" {
- int foo() native 'fooA';
+ @JSName('fooA')
+ int foo() native;
}
class B extends A native "*B" {
- int foo() native 'fooB';
+ @JSName('fooB')
+ int foo() native;
int fooA() => 333;
}
diff --git a/tests/corelib/futures_test.dart b/tests/corelib/futures_test.dart
index e5daa1d..70a54bf 100644
--- a/tests/corelib/futures_test.dart
+++ b/tests/corelib/futures_test.dart
@@ -27,18 +27,47 @@
return Futures.wait(futures);
}
+Future testForEachEmpty() {
+ return Futures.forEach([], (_) {
+ throw 'should not be called';
+ });
+}
+
+Future testForEach() {
+ var seen = <int>[];
+ return Futures.forEach([1, 2, 3, 4, 5], (n) {
+ seen.add(n);
+ return new Future.immediate(null);
+ }).transform((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
+}
+
+Future testForEachWithException() {
+ var seen = <int>[];
+ return Futures.forEach([1, 2, 3, 4, 5], (n) {
+ if (n == 4) throw 'correct exception';
+ seen.add(n);
+ return new Future.immediate(null);
+ }).transform((_) {
+ throw 'incorrect exception';
+ }).transformException((e) {
+ Expect.equals('correct exception', e);
+ });
+}
+
main() {
List<Future> futures = new List<Future>();
futures.add(testWaitEmpty());
futures.add(testCompleteAfterWait());
futures.add(testCompleteBeforeWait());
+ futures.add(testForEachEmpty());
+ futures.add(testForEach());
// Use a receive port for blocking the test.
// Note that if the test fails, the program will not end.
ReceivePort port = new ReceivePort();
Futures.wait(futures).then((List list) {
- Expect.equals(3, list.length);
+ Expect.equals(5, list.length);
port.close();
});
}
diff --git a/tests/html/audiobuffersourcenode_test.dart b/tests/html/audiobuffersourcenode_test.dart
index 54d0b6a..3e19ba6 100644
--- a/tests/html/audiobuffersourcenode_test.dart
+++ b/tests/html/audiobuffersourcenode_test.dart
@@ -1,7 +1,7 @@
library AudioBufferSourceNodeTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
+import 'dart:web_audio';
main() {
diff --git a/tests/html/audiocontext_test.dart b/tests/html/audiocontext_test.dart
index 8e78436..6236753 100644
--- a/tests/html/audiocontext_test.dart
+++ b/tests/html/audiocontext_test.dart
@@ -2,6 +2,7 @@
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:html';
+import 'dart:web_audio';
main() {
diff --git a/tests/html/audioelement_test.dart b/tests/html/audioelement_test.dart
index 0b518e0..bf66654 100644
--- a/tests/html/audioelement_test.dart
+++ b/tests/html/audioelement_test.dart
@@ -1,7 +1,7 @@
library AudioElementTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
+import 'dart:web_audio';
main() {
useHtmlConfiguration();
diff --git a/tests/html/client_rect_test.dart b/tests/html/client_rect_test.dart
index 4086a0d..2363bfc 100644
--- a/tests/html/client_rect_test.dart
+++ b/tests/html/client_rect_test.dart
@@ -10,7 +10,7 @@
insertTestDiv() {
var element = new Element.tag('div');
- element.innerHTML = r'''
+ element.innerHtml = r'''
A large block of text should go here. Click this
block of text multiple times to see each line
highlight with every click of the mouse button.
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index 1383561..d2783f4 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -25,7 +25,7 @@
expect(style, hasLength(0));
// These assertions throw a UnimplementedError in dartium:
// expect(style.parentRule, isNull);
- // expect(style.getPropertyCSSValue('color'), isNull);
+ // expect(style.getPropertyCssValue('color'), isNull);
// expect(style.getPropertyShorthand('color'), isNull);
});
diff --git a/tests/html/datalistelement_test.dart b/tests/html/datalistelement_test.dart
index e6022cb..7b41aad 100644
--- a/tests/html/datalistelement_test.dart
+++ b/tests/html/datalistelement_test.dart
@@ -18,7 +18,7 @@
setUp(() {
div = new DivElement();
document.body.nodes.add(div);
- div.innerHTML = """
+ div.innerHtml = """
<input id="input" list="browsers" />
<datalist id="browsers">
<option value="Chrome">
diff --git a/tests/html/documentfragment_test.dart b/tests/html/documentfragment_test.dart
index cd47c38..63d4e23 100644
--- a/tests/html/documentfragment_test.dart
+++ b/tests/html/documentfragment_test.dart
@@ -45,7 +45,7 @@
expect(style.length, isZero);
// TODO(jacobr): these checks throw UnimplementedErrors in dartium.
// expect(style.parentRule, isNull);
- // expect(style.getPropertyCSSValue('color'), isNull);
+ // expect(style.getPropertyCssValue('color'), isNull);
// expect(style.getPropertyShorthand('color'), isNull);
// expect(style.isPropertyImplicit('color'), isFalse);
@@ -182,18 +182,18 @@
});
});
- test('setting innerHTML works', () {
+ test('setting innerHtml works', () {
var fragment = new DocumentFragment();
fragment.nodes.add(new Text("foo"));
- fragment.innerHTML = "<a>bar</a>baz";
+ fragment.innerHtml = "<a>bar</a>baz";
expect(_nodeStrings(fragment.nodes), equals(["A", "baz"]));
});
- test('getting innerHTML works', () {
+ test('getting innerHtml works', () {
var fragment = new DocumentFragment();
fragment.nodes.addAll([new Text("foo"), new Element.html("<A>bar</A>")]);
- expect(fragment.innerHTML, "foo<a>bar</a>");
- expect(fragment.outerHTML, "foo<a>bar</a>");
+ expect(fragment.innerHtml, "foo<a>bar</a>");
+ expect(fragment.outerHtml, "foo<a>bar</a>");
});
group('insertAdjacentElement', () {
@@ -203,28 +203,28 @@
var fragment = getFragment();
expect(fragment.insertAdjacentElement("beforeBegin",
new Element.tag("b")), isNull);
- expect(fragment.innerHTML, "<a>foo</a>");
+ expect(fragment.innerHtml, "<a>foo</a>");
});
test('afterEnd does nothing', () {
var fragment = getFragment();
expect(fragment.insertAdjacentElement("afterEnd",
new Element.tag("b")), isNull);
- expect(fragment.innerHTML, "<a>foo</a>");
+ expect(fragment.innerHtml, "<a>foo</a>");
});
test('afterBegin inserts the element', () {
var fragment = getFragment();
var el = new Element.tag("b");
expect(fragment.insertAdjacentElement("afterBegin", el), equals(el));
- expect(fragment.innerHTML, "<b></b><a>foo</a>");
+ expect(fragment.innerHtml, "<b></b><a>foo</a>");
});
test('beforeEnd inserts the element', () {
var fragment = getFragment();
var el = new Element.tag("b");
expect(fragment.insertAdjacentElement("beforeEnd", el), equals(el));
- expect(fragment.innerHTML, "<a>foo</a><b></b>");
+ expect(fragment.innerHtml, "<a>foo</a><b></b>");
});
});
@@ -234,53 +234,53 @@
test('beforeBegin does nothing', () {
var fragment = getFragment();
fragment.insertAdjacentText("beforeBegin", "foo");
- expect(fragment.innerHTML, "<a>foo</a>");
+ expect(fragment.innerHtml, "<a>foo</a>");
});
test('afterEnd does nothing', () {
var fragment = getFragment();
fragment.insertAdjacentText("afterEnd", "foo");
- expect(fragment.innerHTML, "<a>foo</a>");
+ expect(fragment.innerHtml, "<a>foo</a>");
});
test('afterBegin inserts the text', () {
var fragment = getFragment();
fragment.insertAdjacentText("afterBegin", "foo");
- expect(fragment.innerHTML, "foo<a>foo</a>");
+ expect(fragment.innerHtml, "foo<a>foo</a>");
});
test('beforeEnd inserts the text', () {
var fragment = getFragment();
fragment.insertAdjacentText("beforeEnd", "foo");
- expect(fragment.innerHTML, "<a>foo</a>foo");
+ expect(fragment.innerHtml, "<a>foo</a>foo");
});
});
- group('insertAdjacentHTML', () {
+ group('insertAdjacentHtml', () {
getFragment() => new DocumentFragment.html("<a>foo</a>");
test('beforeBegin does nothing', () {
var fragment = getFragment();
- fragment.insertAdjacentHTML("beforeBegin", "foo<br>");
- expect(fragment.innerHTML, "<a>foo</a>");
+ fragment.insertAdjacentHtml("beforeBegin", "foo<br>");
+ expect(fragment.innerHtml, "<a>foo</a>");
});
test('afterEnd does nothing', () {
var fragment = getFragment();
- fragment.insertAdjacentHTML("afterEnd", "<br>foo");
- expect(fragment.innerHTML, "<a>foo</a>");
+ fragment.insertAdjacentHtml("afterEnd", "<br>foo");
+ expect(fragment.innerHtml, "<a>foo</a>");
});
test('afterBegin inserts the HTML', () {
var fragment = getFragment();
- fragment.insertAdjacentHTML("afterBegin", "foo<br>");
- expect(fragment.innerHTML, "foo<br><a>foo</a>");
+ fragment.insertAdjacentHtml("afterBegin", "foo<br>");
+ expect(fragment.innerHtml, "foo<br><a>foo</a>");
});
test('beforeEnd inserts the HTML', () {
var fragment = getFragment();
- fragment.insertAdjacentHTML("beforeEnd", "<br>foo");
- expect(fragment.innerHTML, "<a>foo</a><br>foo");
+ fragment.insertAdjacentHtml("beforeEnd", "<br>foo");
+ expect(fragment.innerHtml, "<a>foo</a><br>foo");
});
});
diff --git a/tests/html/element_add_test.dart b/tests/html/element_add_test.dart
index ef911fdd..ece267d 100644
--- a/tests/html/element_add_test.dart
+++ b/tests/html/element_add_test.dart
@@ -18,15 +18,15 @@
void expectNoSuchMethod(void fn()) =>
expect(fn, throwsNoSuchMethodError);
- group('addHtml', () {
+ group('append', () {
test('htmlelement', () {
var el = new DivElement();
- el.addHtml('<span></span>');
+ el.append(new SpanElement());
expect(el.children.length, equals(1));
var span = el.children[0];
expect(span, isSpanElement);
- el.addHtml('<div></div>');
+ el.append(new DivElement());
expect(el.children.length, equals(2));
// Validate that the first item is still first.
expect(el.children[0], equals(span));
@@ -35,16 +35,39 @@
test('documentFragment', () {
var fragment = new DocumentFragment();
- fragment.addHtml('<span>something</span>');
+ fragment.append(new SpanElement());
expect(fragment.children.length, equals(1));
expect(fragment.children[0], isSpanElement);
});
});
- group('addText', () {
+ group('appendHtml', () {
test('htmlelement', () {
var el = new DivElement();
- el.addText('foo');
+ el.appendHtml('<span></span>');
+ expect(el.children.length, equals(1));
+ var span = el.children[0];
+ expect(span, isSpanElement);
+
+ el.appendHtml('<div></div>');
+ expect(el.children.length, equals(2));
+ // Validate that the first item is still first.
+ expect(el.children[0], equals(span));
+ expect(el.children[1], isDivElement);
+ });
+
+ test('documentFragment', () {
+ var fragment = new DocumentFragment();
+ fragment.appendHtml('<span>something</span>');
+ expect(fragment.children.length, equals(1));
+ expect(fragment.children[0], isSpanElement);
+ });
+ });
+
+ group('appendText', () {
+ test('htmlelement', () {
+ var el = new DivElement();
+ el.appendText('foo');
// No children were created.
expect(el.children.length, equals(0));
// One text node was added.
@@ -53,7 +76,7 @@
test('documentFragment', () {
var fragment = new DocumentFragment();
- fragment.addText('foo');
+ fragment.appendText('foo');
// No children were created.
expect(fragment.children.length, equals(0));
// One text node was added.
@@ -111,13 +134,13 @@
});
});
- group('insertAdjacentHTML', () {
+ group('insertAdjacentHtml', () {
test('beforebegin', () {
var parent = new DivElement();
var child = new DivElement();
parent.children.add(child);
- child.insertAdjacentHTML('beforebegin', '<span></span>');
+ child.insertAdjacentHtml('beforebegin', '<span></span>');
expect(parent.children.length, 2);
expect(parent.children[0], isSpanElement);
@@ -128,7 +151,7 @@
var child = new DivElement();
parent.children.add(child);
- child.insertAdjacentHTML('afterend', '<span></span>');
+ child.insertAdjacentHtml('afterend', '<span></span>');
expect(parent.children.length, 2);
expect(parent.children[1], isSpanElement);
@@ -139,7 +162,7 @@
var child = new DivElement();
parent.children.add(child);
- parent.insertAdjacentHTML('afterbegin', '<span></span>');
+ parent.insertAdjacentHtml('afterbegin', '<span></span>');
expect(parent.children.length, 2);
expect(parent.children[0], isSpanElement);
@@ -150,7 +173,7 @@
var child = new DivElement();
parent.children.add(child);
- parent.insertAdjacentHTML('beforeend', '<span></span>');
+ parent.insertAdjacentHtml('beforeend', '<span></span>');
expect(parent.children.length, 2);
expect(parent.children[1], isSpanElement);
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index ab0be3b..2ef18cc 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -21,7 +21,7 @@
Set<String> makeClassSet() => makeElementWithClasses().classes;
Set<String> extractClasses(Element el) {
- final match = new RegExp('class="([^"]+)"').firstMatch(el.outerHTML);
+ final match = new RegExp('class="([^"]+)"').firstMatch(el.outerHtml);
return new Set.from(match[1].split(' '));
}
@@ -45,7 +45,7 @@
});
test('toString', () {
- expect(makeClassSet().toString().split(' '),
+ expect(makeClassSet().toString().split(' '),
unorderedEquals(['foo', 'bar', 'baz']));
expect(makeElement().classes.toString(), '');
});
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 2a5d460..6825c91 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -464,6 +464,34 @@
attributes['style'] = 'width: 300px;';
expect(attributes.length, 5);
});
+
+ test('namespaces', () {
+ var element = new svg.SvgElement.svg(
+ '''<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <image xlink:href="foo" data-foo="bar"/>
+ </svg>''').elements[0];
+
+ var attributes = element.attributes;
+ expect(attributes.length, 1);
+ expect(attributes['data-foo'], 'bar');
+
+ var xlinkAttrs =
+ element.getNamespacedAttributes('http://www.w3.org/1999/xlink');
+ expect(xlinkAttrs.length, 1);
+ expect(xlinkAttrs['href'], 'foo');
+
+ xlinkAttrs.remove('href');
+ expect(xlinkAttrs.length, 0);
+
+ xlinkAttrs['href'] = 'bar';
+ expect(xlinkAttrs['href'], 'bar');
+
+ var randomAttrs = element.getNamespacedAttributes('http://example.com');
+ expect(randomAttrs.length, 0);
+ randomAttrs['href'] = 'bar';
+ expect(randomAttrs.length, 1);
+ });
});
group('children', () {
diff --git a/tests/html/event_test.dart b/tests/html/event_test.dart
index e676fb4..c4c4609 100644
--- a/tests/html/event_test.dart
+++ b/tests/html/event_test.dart
@@ -90,8 +90,8 @@
eventTest('HashChangeEvent',
() => new HashChangeEvent('foo', 'http://old.url', 'http://new.url'),
(ev) {
- expect(ev.oldURL, equals('http//old.url'));
- expect(ev.newURL, equals('http://new.url'));
+ expect(ev.oldUrl, equals('http//old.url'));
+ expect(ev.newUrl, equals('http://new.url'));
});
eventTest('KeyboardEvent',
diff --git a/tests/html/form_element_test.dart b/tests/html/form_element_test.dart
index 9539387..b7d030c 100644
--- a/tests/html/form_element_test.dart
+++ b/tests/html/form_element_test.dart
@@ -21,11 +21,11 @@
test('checkValidityTest', () {
var form = new FormElement();
- form.innerHTML = '<label>Google: <input type="search" name="q"></label> '
+ form.innerHtml = '<label>Google: <input type="search" name="q"></label> '
'<input type="submit" value="Search...">';
expect(form.checkValidity(), isTrue);
// TODO(efortuna): Issue 4832.
- form.innerHTML = '<input type="email" value="notemail" blaber="test"'
+ form.innerHtml = '<input type="email" value="notemail" blaber="test"'
' required>';
expect(form.checkValidity(), isFalse);
});
@@ -36,47 +36,47 @@
form.acceptCharset = charset;
expect(form.acceptCharset, charset);
});
-
+
test('actionTest', () {
var action = 'http://dartlang.org/';
form.action = action;
expect(form.action, action);
});
-
+
test('autocompleteTest', () {
var auto = 'on';
form.autocomplete = auto;
expect(form.autocomplete, auto);
});
-
+
test('encodingAndEnctypeTest', () {
expect(form.enctype, form.encoding);
});
-
+
test('lengthTest', () {
expect(form.length, 0);
- form.innerHTML = '<label>Google: <input type="search" name="q"></label> '
+ form.innerHtml = '<label>Google: <input type="search" name="q"></label> '
'<input type="submit" value="Search...">';
expect(form.length, 2);
});
-
+
test('methodTest', () {
var method = 'post';
form.method = method;
expect(form.method, method);
});
-
+
test('nameTest', () {
var name = 'aname';
form.name = name;
expect(form.name, name);
});
-
+
test('noValidateTest', () {
form.noValidate = true;
expect(form.noValidate, true);
});
-
+
test('targetTest', () {
var target = 'target';
form.target = target;
diff --git a/tests/html/html.status b/tests/html/html.status
index 49e137f..17d95df 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -33,7 +33,6 @@
audioelement_test: Fail # Issue 4517
blob_constructor_test: Fail # Issue 4517
css_test: Fail # Issue 4517
-htmlaudioelement_test: Fail # Issue 4517
form_data_test: Fail # Possibly Issue 4517
fileapi_test: Fail # Possibly Issue 4517
websql_test: Pass, Fail # Possibly Issue 4517
@@ -76,7 +75,6 @@
indexeddb_4_test: Fail
inner_frame_test: Skip
isolates_test: Skip
-js_interop_2_test: Fail
localstorage_test: Fail
measurement_test: Fail, Pass
messageevent_test: Fail
@@ -85,8 +83,8 @@
storage_test: Fail, Pass
svgelement_test/additionalConstructors: Fail
svgelement_test/elementset: Fail
-svgelement_test/innerHTML: Fail
-svgelement_test/outerHTML: Fail
+svgelement_test/innerHtml: Fail
+svgelement_test/outerHtml: Fail
svgelement2_test: Fail
svg_3_test: Fail
typed_arrays_1_test: Fail
@@ -134,7 +132,6 @@
indexeddb_2_test: Fail
indexeddb_3_test: Fail
indexeddb_4_test: Fail
-js_interop_2_test: Fail
messageevent_test: Fail
mutationobserver_test: Fail
postmessage_structured_test: Skip # BUG(5685): times out.
@@ -146,8 +143,8 @@
svgelement_test/additionalConstructors: Fail
svgelement_test/elementset: Fail
element_test/eventListening: Fail
-svgelement_test/innerHTML: Fail
-svgelement_test/outerHTML: Fail
+svgelement_test/innerHtml: Fail
+svgelement_test/outerHtml: Fail
svgelement2_test: Fail
url_test: Fail # IE9 does not support createObjectURL (it is supported in IE10)
websocket_test: Fail
@@ -201,8 +198,8 @@
svgelement_test/additionalConstructors: Fail
svgelement_test/elementget: Fail
svgelement_test/elementset: Fail
-svgelement_test/innerHTML: Crash, Fail
-svgelement_test/outerHTML: Fail
+svgelement_test/innerHtml: Crash, Fail
+svgelement_test/outerHtml: Fail
svgelement_test/svg: Fail
url_test: Fail
diff --git a/tests/html/htmlaudioelement_test.dart b/tests/html/htmlaudioelement_test.dart
deleted file mode 100644
index b3bcc08..0000000
--- a/tests/html/htmlaudioelement_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-library AudioElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-
-main() {
-
- useHtmlConfiguration();
-
- var isAudioElement =
- predicate((x) => x is AudioElement, 'is an AudioElement');
-
- test('constructorTest1', () {
- var audio = new AudioElement(); // would be new Audio() in JS
- expect(audio, isNotNull);
- expect(audio, isAudioElement);
- });
-
- test('constructorTest2', () {
- var audio = new AudioElement('hahaURL');
- expect(audio, isNotNull);
- expect(audio, isAudioElement);
- expect(audio.src.indexOf('hahaURL'), greaterThanOrEqualTo(0));
- });
-}
diff --git a/tests/html/htmlcollection_test.dart b/tests/html/htmlcollection_test.dart
index ad993ff..cf7f184 100644
--- a/tests/html/htmlcollection_test.dart
+++ b/tests/html/htmlcollection_test.dart
@@ -7,7 +7,7 @@
main() {
Element insertTestDiv() {
Element element = new Element.tag('div');
- element.innerHTML = r"""
+ element.innerHtml = r"""
<div id='allChecked'>
<input type="checkbox" name="c1" value="1" checked="yes">
<input type="checkbox" name="c2" value="2" checked="yes">
diff --git a/tests/html/htmlelement_test.dart b/tests/html/htmlelement_test.dart
index b7964c2..f9455df 100644
--- a/tests/html/htmlelement_test.dart
+++ b/tests/html/htmlelement_test.dart
@@ -8,11 +8,11 @@
test('InnerHTML', () {
Element element = new Element.tag('div');
element.id = 'test';
- element.innerHTML = 'Hello World';
+ element.innerHtml = 'Hello World';
document.body.nodes.add(element);
element = document.query('#test');
- expect(element.innerHTML, 'Hello World');
+ expect(element.innerHtml, 'Hello World');
element.remove();
});
test('HTMLTable', () {
@@ -68,7 +68,7 @@
expect(keys, unorderedEquals(['foo', 'bar']));
expect(values, unorderedEquals(['foo-value', 'bar-value']));
- expect(new List<String>.from(div.dataAttributes.keys),
+ expect(new List<String>.from(div.dataAttributes.keys),
unorderedEquals(['foo', 'bar']));
expect(new List<String>.from(div.dataAttributes.values),
unorderedEquals(['foo-value', 'bar-value']));
diff --git a/tests/html/instance_of_test.dart b/tests/html/instance_of_test.dart
index 0643507..dd4355b 100644
--- a/tests/html/instance_of_test.dart
+++ b/tests/html/instance_of_test.dart
@@ -43,8 +43,8 @@
// expect(context, isNot(isCanvasPixelArray));
// FIXME(b/5286633): Interface injection type check workaround.
- var image = context.createImageData(canvas.width as Dynamic,
- canvas.height as Dynamic);
+ var image = context.createImageData(canvas.width as dynamic,
+ canvas.height as dynamic);
expect(image, isNot(isCanvasRenderingContext));
expect(image, isNot(isCanvasRenderingContext2D));
expect(image, isNot(isElement));
diff --git a/tests/html/js_interop_1_test.dart b/tests/html/js_interop_1_test.dart
index 610d873..168294f 100644
--- a/tests/html/js_interop_1_test.dart
+++ b/tests/html/js_interop_1_test.dart
@@ -11,7 +11,7 @@
injectSource(code) {
final script = new ScriptElement();
script.type = 'text/javascript';
- script.innerHTML = code;
+ script.innerHtml = code;
document.body.nodes.add(script);
}
diff --git a/tests/html/js_interop_2_test.dart b/tests/html/js_interop_2_test.dart
index 0f03f54..7f7550a 100644
--- a/tests/html/js_interop_2_test.dart
+++ b/tests/html/js_interop_2_test.dart
@@ -11,7 +11,7 @@
injectSource(code) {
final script = new ScriptElement();
script.type = 'text/javascript';
- script.innerHTML = code;
+ script.innerHtml = code;
document.body.nodes.add(script);
}
diff --git a/tests/html/js_interop_3_test.dart b/tests/html/js_interop_3_test.dart
index 844dd11..142c4d9 100644
--- a/tests/html/js_interop_3_test.dart
+++ b/tests/html/js_interop_3_test.dart
@@ -11,7 +11,7 @@
injectSource(code) {
final script = new ScriptElement();
script.type = 'text/javascript';
- script.innerHTML = code;
+ script.innerHtml = code;
document.body.nodes.add(script);
}
diff --git a/tests/html/keyboard_event_test.dart b/tests/html/keyboard_event_test.dart
new file mode 100644
index 0000000..4f32f2d
--- /dev/null
+++ b/tests/html/keyboard_event_test.dart
@@ -0,0 +1,30 @@
+library KeyboardEventTest;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:html';
+
+// Test that we are correctly determining keyCode and charCode uniformly across
+// browsers.
+
+main() {
+
+ useHtmlConfiguration();
+
+ keydownHandlerTest(KeyEvent e) {
+ expect(e.charCode, 0);
+ }
+
+ test('keys', () {
+ // This test currently is pretty much a no-op because we
+ // can't (right now) construct KeyboardEvents with specific keycode/charcode
+ // values (a KeyboardEvent can be "init"-ed but not all the information can
+ // be programmatically populated. It exists as an example for how to use
+ // KeyboardEventController more than anything else.
+ var controller = new KeyboardEventController.keydown(document.window);
+ var func = keydownHandlerTest;
+ controller.add(func);
+ document.window.on.keyDown.add((e) => print('regular listener'), false);
+ });
+}
+
+
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index f3999c3..8581dc2 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -12,7 +12,7 @@
injectSource(code) {
final script = new ScriptElement();
script.type = 'text/javascript';
- script.innerHTML = code;
+ script.innerHtml = code;
document.body.nodes.add(script);
}
diff --git a/tests/html/svg_1_test.dart b/tests/html/svg_1_test.dart
index a6bfc44..d5033c4 100644
--- a/tests/html/svg_1_test.dart
+++ b/tests/html/svg_1_test.dart
@@ -14,7 +14,7 @@
test('simpleRect', () {
var div = new Element.tag('div');
document.body.nodes.add(div);
- div.innerHTML = r'''
+ div.innerHtml = r'''
<svg id='svg1' width='200' height='100'>
<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
</svg>
diff --git a/tests/html/svg_2_test.dart b/tests/html/svg_2_test.dart
index 2b12818..89f4fe2 100644
--- a/tests/html/svg_2_test.dart
+++ b/tests/html/svg_2_test.dart
@@ -11,7 +11,7 @@
insertTestDiv() {
var element = new Element.tag('div');
- element.innerHTML = r'''
+ element.innerHtml = r'''
<svg id='svg1' width='200' height='100'>
<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
</svg>
diff --git a/tests/html/svg_3_test.dart b/tests/html/svg_3_test.dart
index d5a4e4f..b076ed6 100644
--- a/tests/html/svg_3_test.dart
+++ b/tests/html/svg_3_test.dart
@@ -27,7 +27,7 @@
insertTestDiv() {
var element = new Element.tag('div');
- element.innerHTML = r'''
+ element.innerHtml = r'''
<svg id='svg1' width='200' height='100'>
<rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
</svg>
@@ -105,10 +105,10 @@
var bbox = e.getBBox();
expect(bbox, isSvgRect);
- var ctm = e.getCTM();
+ var ctm = e.getCtm();
expect(ctm, isSvgMatrix);
- var sctm = e.getScreenCTM();
+ var sctm = e.getScreenCtm();
expect(sctm, isSvgMatrix);
var xf2e = e.getTransformToElement(e);
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index e41c35614..21f8205 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -44,8 +44,8 @@
</svg>""";
final el = new svg.SvgElement.svg(svgContent);
expect(el, isSvgSvgElement);
- expect(el.innerHTML, "<circle></circle><path></path>");
- expect(el.outerHTML, svgContent);
+ expect(el.innerHtml, "<circle></circle><path></path>");
+ expect(el.outerHtml, svgContent);
});
test('has no parent', () =>
@@ -149,29 +149,29 @@
testConstructor('view', (e) => e is svg.ViewElement);
});
- group('outerHTML', () {
- test('outerHTML', () {
+ group('outerHtml', () {
+ test('outerHtml', () {
final el = new svg.SvgSvgElement();
el.children.add(new svg.CircleElement());
el.children.add(new svg.PathElement());
- expect(el.outerHTML,
+ expect(el.outerHtml,
'<svg version="1.1"><circle></circle><path></path></svg>');
});
});
- group('innerHTML', () {
+ group('innerHtml', () {
test('get', () {
final el = new svg.SvgSvgElement();
el.children.add(new svg.CircleElement());
el.children.add(new svg.PathElement());
- expect(el.innerHTML, '<circle></circle><path></path>');
+ expect(el.innerHtml, '<circle></circle><path></path>');
});
test('set', () {
final el = new svg.SvgSvgElement();
el.children.add(new svg.CircleElement());
el.children.add(new svg.PathElement());
- el.innerHTML = '<rect></rect><a></a>';
+ el.innerHtml = '<rect></rect><a></a>';
expect(_nodeStrings(el.children), ["rect", "a"]);
});
});
@@ -192,7 +192,7 @@
test('set', () {
final el = new svg.SvgSvgElement();
el.children = [new svg.SvgElement.tag("circle"), new svg.SvgElement.tag("path")];
- expect(el.innerHTML, '<circle></circle><path></path>');
+ expect(el.innerHtml, '<circle></circle><path></path>');
});
});
diff --git a/tests/html/url_test.dart b/tests/html/url_test.dart
index 4b784ca..c52b7c6 100644
--- a/tests/html/url_test.dart
+++ b/tests/html/url_test.dart
@@ -19,7 +19,7 @@
context.fillStyle = 'red';
context.fillRect(0, 0, canvas.width, canvas.height);
- var dataUri = canvas.toDataURL('image/png');
+ var dataUri = canvas.toDataUrl('image/png');
var byteString = window.atob(dataUri.split(',')[1]);
var mimeString = dataUri.split(',')[0].split(':')[1].split(';')[0];
diff --git a/tests/html/window_open_test.dart b/tests/html/window_open_test.dart
index 664953f..8fbe664 100644
--- a/tests/html/window_open_test.dart
+++ b/tests/html/window_open_test.dart
@@ -7,7 +7,7 @@
useHtmlConfiguration();
evaluateJavaScript(code) {
final scriptTag = new Element.tag('script');
- scriptTag.innerHTML = code;
+ scriptTag.innerHtml = code;
document.body.nodes.add(scriptTag);
}
evaluateJavaScript('(testRunner || layoutTestController).setCanOpenWindows()');
diff --git a/tests/html/xmldocument_test.dart b/tests/html/xmldocument_test.dart
index 53c3bc4..35666e6 100644
--- a/tests/html/xmldocument_test.dart
+++ b/tests/html/xmldocument_test.dart
@@ -47,7 +47,7 @@
test('overwrites nodes when set', () {
final doc = new XMLDocument.xml("<xml>1<a/><b/>2<c/>3<d/></xml>");
doc.children = [new XMLElement.tag('x'), new XMLElement.tag('y')];
- expect(doc.outerHTML, "<xml><x></x><y></y></xml>");
+ expect(doc.outerHtml, "<xml><x></x><y></y></xml>");
});
});
@@ -58,7 +58,7 @@
Set<String> makeClassSet() => makeDocumentWithClasses().classes;
Set<String> extractClasses(Document doc) {
- final match = new RegExp('class="([^"]+)"').firstMatch(doc.outerHTML);
+ final match = new RegExp('class="([^"]+)"').firstMatch(doc.outerHtml);
return new Set.from(match[1].split(' '));
}
@@ -398,9 +398,9 @@
});
});
- test('set innerHTML', () {
+ test('set innerHtml', () {
final doc = makeDocument();
- doc.innerHTML = "<foo>Bar<baz/></foo>";
+ doc.innerHtml = "<foo>Bar<baz/></foo>";
expect(doc.nodes.length, 1);
final node = doc.nodes[0];
expect(node, isXMLElement);
@@ -409,13 +409,13 @@
expect(node.nodes[1].tagName, 'baz');
});
- test('get innerHTML/outerHTML', () {
+ test('get innerHtml/outerHtml', () {
final doc = makeDocument();
- expect(doc.innerHTML, "<foo></foo><bar></bar>");
+ expect(doc.innerHtml, "<foo></foo><bar></bar>");
doc.nodes.clear();
doc.nodes.addAll([new Text("foo"), new XMLElement.xml("<a>bar</a>")]);
- expect(doc.innertHTML, "foo<a>bar</a>");
- expect(doc.outerHTML, "<xml>foo<a>bar</a></xml>");
+ expect(doc.innerHtml, "foo<a>bar</a>");
+ expect(doc.outerHtml, "<xml>foo<a>bar</a></xml>");
});
test('query', () {
@@ -447,28 +447,28 @@
final doc = getDoc();
expect(doc.insertAdjacentElement("beforeBegin", new XMLElement.tag("b")),
isNull);
- expect(doc.innerHTML, "<a>foo</a>");
+ expect(doc.innerHtml, "<a>foo</a>");
});
test('afterEnd does nothing', () {
final doc = getDoc();
expect(doc.insertAdjacentElement("afterEnd", new XMLElement.tag("b")),
isNull);
- expect(doc.innerHTML, "<a>foo</a>");
+ expect(doc.innerHtml, "<a>foo</a>");
});
test('afterBegin inserts the element', () {
final doc = getDoc();
final el = new XMLElement.tag("b");
expect(doc.insertAdjacentElement("afterBegin", el), el);
- expect(doc.innerHTML, "<b></b><a>foo</a>");
+ expect(doc.innerHtml, "<b></b><a>foo</a>");
});
test('beforeEnd inserts the element', () {
final doc = getDoc();
final el = new XMLElement.tag("b");
expect(doc.insertAdjacentElement("beforeEnd", el), el);
- expect(doc.innerHTML, "<a>foo</a><b></b>");
+ expect(doc.innerHtml, "<a>foo</a><b></b>");
});
});
@@ -478,53 +478,53 @@
test('beforeBegin does nothing', () {
final doc = getDoc();
doc.insertAdjacentText("beforeBegin", "foo");
- expect(doc.innerHTML, "<a>foo</a>");
+ expect(doc.innerHtml, "<a>foo</a>");
});
test('afterEnd does nothing', () {
final doc = getDoc();
doc.insertAdjacentText("afterEnd", "foo");
- expect(doc.innerHTML, "<a>foo</a>");
+ expect(doc.innerHtml, "<a>foo</a>");
});
test('afterBegin inserts the text', () {
final doc = getDoc();
doc.insertAdjacentText("afterBegin", "foo");
- expect(doc.innerHTML, "foo<a>foo</a>");
+ expect(doc.innerHtml, "foo<a>foo</a>");
});
test('beforeEnd inserts the text', () {
final doc = getDoc();
doc.insertAdjacentText("beforeEnd", "foo");
- expect(doc.innerHTML, "<a>foo</a>foo");
+ expect(doc.innerHtml, "<a>foo</a>foo");
});
});
- group('insertAdjacentHTML', () {
+ group('insertAdjacentHtml', () {
getDoc() => new XMLDocument.xml("<xml><a>foo</a></xml>");
test('beforeBegin does nothing', () {
final doc = getDoc();
- doc.insertAdjacentHTML("beforeBegin", "foo<b/>");
- expect(doc.innerHTML, "<a>foo</a>");
+ doc.insertAdjacentHtml("beforeBegin", "foo<b/>");
+ expect(doc.innerHtml, "<a>foo</a>");
});
test('afterEnd does nothing', () {
final doc = getDoc();
- doc.insertAdjacentHTML("afterEnd", "<b/>foo");
- expect(doc.innerHTML, "<a>foo</a>");
+ doc.insertAdjacentHtml("afterEnd", "<b/>foo");
+ expect(doc.innerHtml, "<a>foo</a>");
});
test('afterBegin inserts the HTML', () {
final doc = getDoc();
- doc.insertAdjacentHTML("afterBegin", "foo<b/>");
- expect(doc.innerHTML, "foo<b></b><a>foo</a>");
+ doc.insertAdjacentHtml("afterBegin", "foo<b/>");
+ expect(doc.innerHtml, "foo<b></b><a>foo</a>");
});
test('beforeEnd inserts the HTML', () {
final doc = getDoc();
- doc.insertAdjacentHTML("beforeEnd", "<b/>foo");
- expect(doc.innerHTML, "<a>foo</a><b></b>foo");
+ doc.insertAdjacentHtml("beforeEnd", "<b/>foo");
+ expect(doc.innerHtml, "<a>foo</a><b></b>foo");
});
});
diff --git a/tests/html/xmlelement_test.dart b/tests/html/xmlelement_test.dart
index 1436b18..94cfb1a 100644
--- a/tests/html/xmlelement_test.dart
+++ b/tests/html/xmlelement_test.dart
@@ -63,7 +63,7 @@
test('overwrites nodes when set', () {
final el = new XMLElement.xml("<xml>1<a/><b/>2<c/>3<d/></xml>");
el.children = [new XMLElement.tag('x'), new XMLElement.tag('y')];
- expect(el.outerHTML, "<xml><x></x><y></y></xml>");
+ expect(el.outerHtml, "<xml><x></x><y></y></xml>");
});
});
@@ -388,9 +388,9 @@
});
});
- test('set innerHTML', () {
+ test('set innerHtml', () {
final el = makeElement();
- el.innerHTML = "<foo>Bar<baz/></foo>";
+ el.innerHtml = "<foo>Bar<baz/></foo>";
expect(el.nodes.length, 1);
final node = el.nodes[0];
expect(node, isXMLElement);
@@ -399,13 +399,13 @@
expect(node.nodes[1].tagName, 'baz');
});
- test('get innerHTML/outerHTML', () {
+ test('get innerHtml/outerHtml', () {
final el = makeElement();
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
el.nodes.clear();
el.nodes.addAll([new Text("foo"), new XMLElement.xml("<a>bar</a>")]);
- expect(el.innerHTML, "foo<a>bar</a>");
- expect(el.outerHTML, "<xml>foo<a>bar</a></xml>");
+ expect(el.innerHtml, "foo<a>bar</a>");
+ expect(el.outerHtml, "<xml>foo<a>bar</a></xml>");
});
test('query', () {
@@ -435,22 +435,22 @@
final el = makeElement();
expect(el.insertAdjacentElement("beforeBegin", new XMLElement.tag("b")),
isNull);
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
});
test('afterEnd with no parent does nothing', () {
final el = makeElement();
expect(
el.insertAdjacentElement("afterEnd", new XMLElement.tag("b")), isNull);
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
});
test('beforeBegin with parent inserts the element', () {
final el = makeElementWithParent();
final newEl = new XMLElement.tag("b");
expect(el.insertAdjacentElement("beforeBegin", newEl), newEl);
- expect(el.innerHTML, "<foo></foo><bar></bar>");
- expect(el.parent.innerHTML,
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
+ expect(el.parent.innerHtml,
"<before></before><b></b><xml><foo></foo><bar></bar>"
"</xml><after></after>");
});
@@ -459,8 +459,8 @@
final el = makeElementWithParent();
final newEl = new XMLElement.tag("b");
expect(el.insertAdjacentElement("afterEnd", newEl), newEl);
- expect(el.innerHTML, "<foo></foo><bar></bar>");
- expect(el.parent.innerHTML,
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
+ expect(el.parent.innerHtml,
"<before></before><xml><foo></foo><bar></bar></xml><b>"
"</b><after></after>");
});
@@ -469,14 +469,14 @@
final el = makeElement();
final newEl = new XMLElement.tag("b");
expect(el.insertAdjacentElement("afterBegin", newEl), newEl);
- expect(el.innerHTML, "<b></b><foo></foo><bar></bar>");
+ expect(el.innerHtml, "<b></b><foo></foo><bar></bar>");
});
test('beforeEnd inserts the element', () {
final el = makeElement();
final newEl = new XMLElement.tag("b");
expect(el.insertAdjacentElement("beforeEnd", newEl), newEl);
- expect(el.innerHTML, "<foo></foo><bar></bar><b></b>");
+ expect(el.innerHtml, "<foo></foo><bar></bar><b></b>");
});
});
@@ -484,20 +484,20 @@
test('beforeBegin with no parent does nothing', () {
final el = makeElement();
el.insertAdjacentText("beforeBegin", "foo");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
});
test('afterEnd with no parent does nothing', () {
final el = makeElement();
el.insertAdjacentText("afterEnd", "foo");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
});
test('beforeBegin with parent inserts the text', () {
final el = makeElementWithParent();
el.insertAdjacentText("beforeBegin", "foo");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
- expect(el.parent.innerHTML,
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
+ expect(el.parent.innerHtml,
"<before></before>foo<xml><foo></foo><bar></bar></xml>"
"<after></after>");
});
@@ -505,8 +505,8 @@
test('afterEnd with parent inserts the text', () {
final el = makeElementWithParent();
el.insertAdjacentText("afterEnd", "foo");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
- expect(el.parent.innerHTML,
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
+ expect(el.parent.innerHtml,
"<before></before><xml><foo></foo><bar></bar></xml>foo"
"<after></after>");
});
@@ -514,57 +514,57 @@
test('afterBegin inserts the text', () {
final el = makeElement();
el.insertAdjacentText("afterBegin", "foo");
- expect(el.innerHTML, "foo<foo></foo><bar></bar>");
+ expect(el.innerHtml, "foo<foo></foo><bar></bar>");
});
test('beforeEnd inserts the text', () {
final el = makeElement();
el.insertAdjacentText("beforeEnd", "foo");
- expect(el.innerHTML, "<foo></foo><bar></bar>foo");
+ expect(el.innerHtml, "<foo></foo><bar></bar>foo");
});
});
- group('insertAdjacentHTML', () {
+ group('insertAdjacentHtml', () {
test('beforeBegin with no parent does nothing', () {
final el = makeElement();
- el.insertAdjacentHTML("beforeBegin", "foo<b/>");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ el.insertAdjacentHtml("beforeBegin", "foo<b/>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
});
test('afterEnd with no parent does nothing', () {
final el = makeElement();
- el.insertAdjacentHTML("afterEnd", "<b/>foo");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
+ el.insertAdjacentHtml("afterEnd", "<b/>foo");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
});
test('beforeBegin with parent inserts the HTML', () {
final el = makeElementWithParent();
- el.insertAdjacentHTML("beforeBegin", "foo<b/>");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
- expect(el.parent.innerHTML,
+ el.insertAdjacentHtml("beforeBegin", "foo<b/>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
+ expect(el.parent.innerHtml,
"<before></before>foo<b></b><xml><foo></foo><bar></bar>"
"</xml><after></after>");
});
test('afterEnd with parent inserts the HTML', () {
final el = makeElementWithParent();
- el.insertAdjacentHTML("afterEnd", "foo<b/>");
- expect(el.innerHTML, "<foo></foo><bar></bar>");
- expect(el.parent.innerHTML,
+ el.insertAdjacentHtml("afterEnd", "foo<b/>");
+ expect(el.innerHtml, "<foo></foo><bar></bar>");
+ expect(el.parent.innerHtml,
"<before></before><xml><foo></foo><bar></bar></xml>foo"
"<b></b><after></after>");
});
test('afterBegin inserts the HTML', () {
final el = makeElement();
- el.insertAdjacentHTML("afterBegin", "foo<b/>");
- expect(el.innerHTML, "foo<b></b><foo></foo><bar></bar>");
+ el.insertAdjacentHtml("afterBegin", "foo<b/>");
+ expect(el.innerHtml, "foo<b></b><foo></foo><bar></bar>");
});
test('beforeEnd inserts the HTML', () {
final el = makeElement();
- el.insertAdjacentHTML("beforeEnd", "<b/>foo");
- expect(el.innerHTML, "<foo></foo><bar></bar><b></b>foo");
+ el.insertAdjacentHtml("beforeEnd", "<b/>foo");
+ expect(el.innerHtml, "<foo></foo><bar></bar><b></b>foo");
});
});
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 5d7fc3e..e176844 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -4,22 +4,26 @@
[ $runtime == vm ]
isolate2_negative_test: Skip # Need to resolve correct behaviour.
+isolate3_negative_test: Skip # test depends on isolate error exiting process.
serialization_test: Skip # tests dart2js-specific serialization code
spawn_uri_test: Fail, OK # test uses a ".js" suffix that is bogus on vm.
compute_this_script_browser_test: Skip # browser specific test
timer_not_available_test: Fail, OK # only meant to test when there is no way to
# implement timer (currently only in d8)
timer_isolate_test: Skip # See Issue 4997
+unresolved_ports_negative_test: Skip # See Issue 6839
[ $compiler == none && $runtime == drt ]
+isolate2_negative_test: Skip # Inherited from VM.
+isolate3_negative_test: Skip # Inherited from VM.
serialization_test: Skip # tests dart2js-specific serialization code
spawn_uri_test: Skip # uses a .js extension (not for dartium)
spawn_uri_negative_test: Skip # ditto
spawn_uri_vm_test: Skip # not implemented in dartium yet.
spawn_uri_vm_negative_test: Skip
-timer_isolate_test: Pass, Fail # See Issue 4997
-timer_not_available_test: Fail, OK # only meant to test when there is no way to
- # implement timer (currently only in d8)
+timer_isolate_test: Skip # See Issue 4997
+timer_not_available_test: Skip # only meant to test when there is no way to
+ # implement timer (currently only in d8)
[ $compiler == dartc ]
serialization_test: Skip # tests dart2js-specific serialization code
@@ -68,7 +72,7 @@
[ $runtime == opera ]
multiple_timer_test: Pass, Fail
isolate2_negative_test: Skip # Timeout.
-unresolved_ports_negative_test: Skip # Timeout.
+unresolved_ports_negative_test: Skip # See Issue 6839
[ $runtime == opera && $system == windows]
# TODO(efortuna): Investigate.
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_abstract.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_abstract.dart
index 671dbb5..01018c2 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_abstract.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library abstract;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_as.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_as.dart
index 671dbb5..96ce332 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_as.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library as;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_dynamic.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_dynamic.dart
index 671dbb5..a112109 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_dynamic.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library dynamic;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_export.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_export.dart
index 671dbb5..0349001 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_export.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library export;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_external.dart
similarity index 68%
rename from sdk/lib/html/templates/interface.darttemplate
rename to tests/language/built_in_identifier_prefix_library_external.dart
index 671dbb5..f4b90cb 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_external.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library external;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_factory.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_factory.dart
index 671dbb5..22edf72 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_factory.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library factory;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_get.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_get.dart
index 671dbb5..73b2232 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_get.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library get;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_implements.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_implements.dart
index 671dbb5..f492b55 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_implements.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library implements;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_import.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_import.dart
index 671dbb5..c06338a0 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_import.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library import;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_library.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_library.dart
index 671dbb5..b77ed20 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_library.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library library;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_operator.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_operator.dart
index 671dbb5..8c43373 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_operator.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library operator;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_part.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_part.dart
index 671dbb5..04276aa 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_part.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library part;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_set.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_set.dart
index 671dbb5..2533ed4 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_set.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library set;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_static.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_static.dart
index 671dbb5..7b21503 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_static.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library static;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/built_in_identifier_prefix_library_typedef.dart
similarity index 68%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/built_in_identifier_prefix_library_typedef.dart
index 671dbb5..88ee7c1 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/built_in_identifier_prefix_library_typedef.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+library typedef;
-part of html;
+class A {
+}
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class B<T> {
+}
+
+class C<T, S> {
+}
diff --git a/tests/language/built_in_identifier_prefix_test.dart b/tests/language/built_in_identifier_prefix_test.dart
new file mode 100644
index 0000000..cb08c87
--- /dev/null
+++ b/tests/language/built_in_identifier_prefix_test.dart
@@ -0,0 +1,215 @@
+// 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.
+
+// Test that built-in identifiers can be used as library prefixes.
+
+// From The Dart Programming Language Specification, section 11.30
+// "Identifier Reference":
+//
+// "A built-in identifier is one of the identifiers produced by the
+// production BUILT IN IDENTIFIER. It is a compile-time error if a
+// built-in identifier is used as the declared name of a class, type
+// parameter or type alias. It is a compile-time error to use a
+// built-in identifier other than dynamic as a type annotation."
+//
+// Observation: it is not illegal to use a built-in identifier as a library
+// prefix.
+//
+// Observation: it is not legal to use a built-in identifer as a type
+// annotation. A type annotation is not fully defined in the
+// specification, so we assume this means that the grammar production
+// "type" cannot match a built-in identifier. Unfortunately, this
+// doesn't prevent us from using built-in identifiers *in* type
+// annotations. For example, "final abstract foo;" is illegal as
+// "abstract" is used as a type annotation. However, "final
+// abstract<dynamic> foo;" is not illegal because "abstract" is used
+// as a typeName.
+
+import 'built_in_identifier_prefix_library_abstract.dart' as abstract;
+import 'built_in_identifier_prefix_library_as.dart' as as;
+import 'built_in_identifier_prefix_library_dynamic.dart' as dynamic;
+import 'built_in_identifier_prefix_library_export.dart' as export;
+import 'built_in_identifier_prefix_library_external.dart' as external;
+import 'built_in_identifier_prefix_library_factory.dart' as factory;
+import 'built_in_identifier_prefix_library_get.dart' as get;
+import 'built_in_identifier_prefix_library_implements.dart' as implements;
+import 'built_in_identifier_prefix_library_import.dart' as import;
+import 'built_in_identifier_prefix_library_library.dart' as library;
+import 'built_in_identifier_prefix_library_operator.dart' as operator;
+import 'built_in_identifier_prefix_library_part.dart' as part;
+import 'built_in_identifier_prefix_library_set.dart' as set;
+import 'built_in_identifier_prefix_library_static.dart' as static;
+import 'built_in_identifier_prefix_library_typedef.dart' as typedef;
+
+abstract.A _abstract = new abstract.A();
+as.A _as = new as.A();
+dynamic.A _dynamic = new dynamic.A();
+export.A _export = new export.A();
+external.A _external = new external.A();
+factory.A _factory = new factory.A();
+get.A _get = new get.A();
+implements.A _implements = new implements.A();
+import.A _import = new import.A();
+library.A _library = new library.A();
+operator.A _operator = new operator.A();
+part.A _part = new part.A();
+set.A _set = new set.A();
+static.A _static = new static.A();
+typedef.A _typedef = new typedef.A();
+
+abstract<dynamic> generic_abstract = new abstract.A();
+as<dynamic> generic_as = new as.A();
+dynamic<dynamic> generic_dynamic = new dynamic.A();
+export<dynamic> generic_export = new export.A();
+external<dynamic> generic_external = new external.A();
+factory<dynamic> generic_factory = new factory.A();
+get<dynamic> generic_get = new get.A();
+implements<dynamic> generic_implements = new implements.A();
+import<dynamic> generic_import = new import.A();
+library<dynamic> generic_library = new library.A();
+operator<dynamic> generic_operator = new operator.A();
+part<dynamic> generic_part = new part.A();
+set<dynamic> generic_set = new set.A();
+static<dynamic> generic_static = new static.A();
+typedef<dynamic> generic_typedef = new typedef.A();
+
+abstract.B<dynamic> dynamic_B_abstract = new abstract.B();
+as.B<dynamic> dynamic_B_as = new as.B();
+dynamic.B<dynamic> dynamic_B_dynamic = new dynamic.B();
+export.B<dynamic> dynamic_B_export = new export.B();
+external.B<dynamic> dynamic_B_external = new external.B();
+factory.B<dynamic> dynamic_B_factory = new factory.B();
+get.B<dynamic> dynamic_B_get = new get.B();
+implements.B<dynamic> dynamic_B_implements = new implements.B();
+import.B<dynamic> dynamic_B_import = new import.B();
+library.B<dynamic> dynamic_B_library = new library.B();
+operator.B<dynamic> dynamic_B_operator = new operator.B();
+part.B<dynamic> dynamic_B_part = new part.B();
+set.B<dynamic> dynamic_B_set = new set.B();
+static.B<dynamic> dynamic_B_static = new static.B();
+typedef.B<dynamic> dynamic_B_typedef = new typedef.B();
+
+abstract.B<abstract<dynamic>> parameterized_B_abstract = new abstract.B();
+as.B<as<dynamic>> parameterized_B_as = new as.B();
+dynamic.B<dynamic<dynamic>> parameterized_B_dynamic = new dynamic.B();
+export.B<export<dynamic>> parameterized_B_export = new export.B();
+external.B<external<dynamic>> parameterized_B_external = new external.B();
+factory.B<factory<dynamic>> parameterized_B_factory = new factory.B();
+get.B<get<dynamic>> parameterized_B_get = new get.B();
+implements.B<implements<dynamic>> parameterized_B_implements =
+ new implements.B();
+import.B<import<dynamic>> parameterized_B_import = new import.B();
+library.B<library<dynamic>> parameterized_B_library = new library.B();
+operator.B<operator<dynamic>> parameterized_B_operator = new operator.B();
+part.B<part<dynamic>> parameterized_B_part = new part.B();
+set.B<set<dynamic>> parameterized_B_set = new set.B();
+static.B<static<dynamic>> parameterized_B_static = new static.B();
+typedef.B<typedef<dynamic>> parameterized_B_typedef = new typedef.B();
+
+class UseA {
+ abstract.A abstract = new abstract.A();
+ as.A as = new as.A();
+ dynamic.A dynamic = new dynamic.A();
+ export.A export = new export.A();
+ external.A external = new external.A();
+ factory.A factory = new factory.A();
+ get.A get = new get.A();
+ implements.A implements = new implements.A();
+ import.A import = new import.A();
+ library.A library = new library.A();
+ operator.A operator = new operator.A();
+ part.A part = new part.A();
+ set.A set = new set.A();
+ static.A static = new static.A();
+ typedef.A typedef = new typedef.A();
+}
+
+main() {
+ bool assertionsEnabled = false;
+ assert(assertionsEnabled = true);
+
+ Expect.isTrue(_abstract is abstract.A);
+ Expect.isTrue(_as is as.A);
+ Expect.isTrue(_dynamic is dynamic.A);
+ Expect.isTrue(_export is export.A);
+ Expect.isTrue(_external is external.A);
+ Expect.isTrue(_factory is factory.A);
+ Expect.isTrue(_get is get.A);
+ Expect.isTrue(_implements is implements.A);
+ Expect.isTrue(_import is import.A);
+ Expect.isTrue(_library is library.A);
+ Expect.isTrue(_operator is operator.A);
+ Expect.isTrue(_part is part.A);
+ Expect.isTrue(_set is set.A);
+ Expect.isTrue(_static is static.A);
+ Expect.isTrue(_typedef is typedef.A);
+
+ Expect.isTrue(dynamic_B_abstract is abstract.B);
+ Expect.isTrue(dynamic_B_as is as.B);
+ Expect.isTrue(dynamic_B_dynamic is dynamic.B);
+ Expect.isTrue(dynamic_B_export is export.B);
+ Expect.isTrue(dynamic_B_external is external.B);
+ Expect.isTrue(dynamic_B_factory is factory.B);
+ Expect.isTrue(dynamic_B_get is get.B);
+ Expect.isTrue(dynamic_B_implements is implements.B);
+ Expect.isTrue(dynamic_B_import is import.B);
+ Expect.isTrue(dynamic_B_library is library.B);
+ Expect.isTrue(dynamic_B_operator is operator.B);
+ Expect.isTrue(dynamic_B_part is part.B);
+ Expect.isTrue(dynamic_B_set is set.B);
+ Expect.isTrue(dynamic_B_static is static.B);
+ Expect.isTrue(dynamic_B_typedef is typedef.B);
+
+ var x = new UseA();
+ Expect.isTrue(x.abstract is abstract.A);
+ Expect.isTrue(x.as is as.A);
+ Expect.isTrue(x.dynamic is dynamic.A);
+ Expect.isTrue(x.export is export.A);
+ Expect.isTrue(x.external is external.A);
+ Expect.isTrue(x.factory is factory.A);
+ Expect.isTrue(x.get is get.A);
+ Expect.isTrue(x.implements is implements.A);
+ Expect.isTrue(x.import is import.A);
+ Expect.isTrue(x.library is library.A);
+ Expect.isTrue(x.operator is operator.A);
+ Expect.isTrue(x.part is part.A);
+ Expect.isTrue(x.set is set.A);
+ Expect.isTrue(x.static is static.A);
+ Expect.isTrue(x.typedef is typedef.A);
+
+ // Most of the following variables have malformed type annotations.
+ if (assertionsEnabled) return;
+
+ Expect.isTrue(generic_abstract is abstract.A);
+ Expect.isTrue(generic_as is as.A);
+ Expect.isTrue(generic_dynamic is dynamic.A);
+ Expect.isTrue(generic_export is export.A);
+ Expect.isTrue(generic_external is external.A);
+ Expect.isTrue(generic_factory is factory.A);
+ Expect.isTrue(generic_get is get.A);
+ Expect.isTrue(generic_implements is implements.A);
+ Expect.isTrue(generic_import is import.A);
+ Expect.isTrue(generic_library is library.A);
+ Expect.isTrue(generic_operator is operator.A);
+ Expect.isTrue(generic_part is part.A);
+ Expect.isTrue(generic_set is set.A);
+ Expect.isTrue(generic_static is static.A);
+ Expect.isTrue(generic_typedef is typedef.A);
+
+ Expect.isTrue(parameterized_B_abstract is abstract.B);
+ Expect.isTrue(parameterized_B_as is as.B);
+ Expect.isTrue(parameterized_B_dynamic is dynamic.B);
+ Expect.isTrue(parameterized_B_export is export.B);
+ Expect.isTrue(parameterized_B_external is external.B);
+ Expect.isTrue(parameterized_B_factory is factory.B);
+ Expect.isTrue(parameterized_B_get is get.B);
+ Expect.isTrue(parameterized_B_implements is implements.B);
+ Expect.isTrue(parameterized_B_import is import.B);
+ Expect.isTrue(parameterized_B_library is library.B);
+ Expect.isTrue(parameterized_B_operator is operator.B);
+ Expect.isTrue(parameterized_B_part is part.B);
+ Expect.isTrue(parameterized_B_set is set.B);
+ Expect.isTrue(parameterized_B_static is static.B);
+ Expect.isTrue(parameterized_B_typedef is typedef.B);
+}
diff --git a/sdk/lib/html/templates/interface.darttemplate b/tests/language/class_syntax_test.dart
similarity index 64%
copy from sdk/lib/html/templates/interface.darttemplate
copy to tests/language/class_syntax_test.dart
index 671dbb5..f14822d 100644
--- a/sdk/lib/html/templates/interface.darttemplate
+++ b/tests/language/class_syntax_test.dart
@@ -2,9 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// WARNING: Do not edit - generated code.
+main() {
+ new ClassSyntaxTest();
+}
-part of html;
-
-abstract class $ID$EXTENDS {
-$!MEMBERS}
+class ClassSyntaxTest {
+ /* /// 01: compile-time error
+}
+*/ /// 01: continued
diff --git a/tests/language/const_factory_redirection_test.dart b/tests/language/const_factory_redirection_test.dart
index 95c0690..01390a8 100644
--- a/tests/language/const_factory_redirection_test.dart
+++ b/tests/language/const_factory_redirection_test.dart
@@ -12,12 +12,15 @@
class D implements C {
final int i;
const D(this.i);
+ m() => 'called m';
}
main() {
const C c = const C(42);
D d = c;
Expect.equals(42, d.i);
+ Expect.equals('called m', d.m());
d = new C(42);
Expect.equals(42, d.i);
+ Expect.equals('called m', d.m());
}
diff --git a/tests/language/interceptor2_test.dart b/tests/language/interceptor2_test.dart
new file mode 100644
index 0000000..3cff1be
--- /dev/null
+++ b/tests/language/interceptor2_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Regression test for issue http://dartbug.com/6903: dart2js used to
+// not generate an interceptor forwarder when a getter call and a
+// method call on an intercepted method were both used.
+
+class A { get iterator => () => 499; }
+
+main() {
+ var a = [new A(), [1, 1]];
+ Expect.equals(499, a[0].iterator());
+ Expect.equals(499, (a[0].iterator)());
+ for (var i in a[1]) {
+ Expect.equals(1, i);
+ }
+}
diff --git a/tests/language/interceptor3_test.dart b/tests/language/interceptor3_test.dart
new file mode 100644
index 0000000..ec9cc6d
--- /dev/null
+++ b/tests/language/interceptor3_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that code motion in the presence of interceptors work in dart2js.
+
+main() {
+ var a = [2, '2'];
+ var b = a[1];
+ if (a[0] == 2 && b is String) {
+ Expect.isTrue(b.contains('2'));
+ } else {
+ b.isEven();
+ }
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 1cf55b7..f7c3283 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -16,6 +16,7 @@
# 3) Update the language/src directory with the updated test.
[ $compiler == none ]
+built_in_identifier_prefix_test: Fail # http://dartbug.com/6970
library_juxtaposition_test: Fail # Issue 6877
part_test: Fail
part2_test: Fail
@@ -57,6 +58,155 @@
duplicate_export_negative_test: Fail # issue 6134
invocation_mirror_indirect_test: Fail # Issue 3326
+# Test issue 6324
+generic_instanceof3_test: Fail, OK
+interface_factory_test: Fail, OK
+factory4_test: Fail, OK
+list_literal_syntax_test/none: Fail, OK
+default_class_implicit_constructor_test: Fail, OK
+interface_factory_constructor_negative_test: Pass, OK
+implied_interface_test: Fail, OK
+throw2_test: Fail, OK
+class_override_negative_test: Pass, OK
+default_implementation2_test: Fail, OK
+implicit_this_test/none: Fail, OK
+implicit_this_test/01: Fail, OK
+implicit_this_test/04: Fail, OK
+interface_factory3_negative_test: Pass, OK
+factory_implementation_test: Fail, OK
+interface_factory_multi_test: Fail, OK
+interface_function_type_alias2_negative_test: Pass, OK
+throw1_test: Fail, OK
+factory2_negative_test: Pass, OK
+named_parameters_test/none: Fail, OK
+prefix14_test: Fail, OK
+prefix15_test: Fail, OK
+prefix16_test: Fail, OK
+prefix17_test: Fail, OK
+prefix22_test: Fail, OK
+prefix23_test: Fail, OK
+type_checks_in_factory_method_test: Fail, OK
+interface_static_method_negative_test: Pass, OK
+method_override2_test/none: Fail, OK
+interface_injection1_negative_test: Pass, OK
+extend_type_parameter2_negative_test: Pass, OK
+generic_syntax_test: Fail, OK
+is_operator_test: Fail, OK
+dynamic_test: Fail, OK
+generic_deep_test: Fail, OK
+default_factory2_test: Fail, OK
+default_implementation_test: Fail, OK
+non_parameterized_factory2_test: Fail, OK
+interface_function_type_alias1_negative_test: Pass, OK
+default_factory3_test: Fail, OK
+interface_inherit_field_test: Fail, OK
+class_test: Fail, OK
+interface2_negative_test: Pass, OK
+instanceof_test: Fail, OK
+default_interface1_negative_test: Pass, OK
+default_factory_test: Fail, OK
+default_factory_library_test: Fail, OK
+duplicate_implements_test/none: Fail, OK
+syntax_test/none: Fail, OK
+type_variable_scope_test: Fail, OK
+cyclic_type_variable_test: Fail, OK
+interface_function_type_alias3_negative_test: Pass, OK
+compile_time_constant_h_test: Fail, OK
+try_catch3_test: Fail, OK
+ct_const_test: Fail, OK
+factory_negative_test: Pass, OK
+instanceof2_test: Fail, OK
+interface_constants_test: Fail, OK
+interface_test: Fail, OK
+library_same_name_used_test: Fail, OK
+pseudo_kw_illegal_test/09: Fail, OK
+interface_injection2_negative_test: Pass, OK
+factory2_test: Fail, OK
+non_parameterized_factory_test: Fail, OK
+try_catch2_test: Fail, OK
+factory3_negative_test: Pass, OK
+class_extends_negative_test: Pass, OK
+interface_static_non_final_fields_negative_test: Pass, OK
+interface_cycle_negative_test: Pass, OK
+factory3_test: Fail, OK
+interface_factory1_negative_test: Pass, OK
+factory5_test: Fail, OK
+interface_factory2_negative_test: Pass, OK
+class_test: Fail, OK
+interface_test/none: Fail, OK
+interface_test/00: Fail, OK
+compile_time_constant_h_test: Fail, OK
+const_constructor_syntax_test/none: Fail, OK
+default_class_implicit_constructor_test: Fail, OK
+named_parameters_test/none: Fail, OK
+type_checks_in_factory_method_test: Fail, OK
+default_factory2_test/none: Fail, OK
+default_factory3_test: Fail, OK
+default_factory_library_test: Fail, OK
+default_implementation2_test: Fail, OK
+default_factory_test: Fail, OK
+default_implementation_test: Fail, OK
+factory2_test: Fail, OK
+factory3_test: Fail, OK
+factory5_test/none: Fail, OK
+factory5_test/00: Fail, OK
+factory4_test: Fail, OK
+factory_implementation_test: Fail, OK
+interface_factory_test: Fail, OK
+interface_factory_multi_test: Fail, OK
+type_variable_bounds_test/none: Fail, OK
+type_variable_bounds_test/00: Fail, OK
+type_variable_bounds_test/03: Fail, OK
+type_variable_bounds_test/06: Fail, OK
+type_variable_bounds_test/09: Fail, OK
+type_variable_bounds_test/10: Fail, OK
+non_parameterized_factory2_test: Fail, OK
+non_parameterized_factory_test: Fail, OK
+default_factory_test: Fail, OK
+default_factory_library_test: Fail, OK
+default_factory_test: Fail, OK
+type_variable_scope_test/none: Fail, OK
+
+[ $compiler == none && $unchecked ]
+# Test issue 6324 (continued)
+default_factory2_test/01: Fail, OK
+type_variable_bounds_test/01: Fail, OK
+type_variable_bounds_test/02: Fail, OK
+type_variable_bounds_test/04: Fail, OK
+type_variable_bounds_test/05: Fail, OK
+type_variable_bounds_test/07: Fail, OK
+type_variable_bounds2_test: Fail, OK
+type_variable_scope_test/00: Fail, OK
+type_variable_scope_test/01: Fail, OK
+type_variable_scope_test/02: Fail, OK
+type_variable_scope_test/03: Fail, OK
+type_variable_scope_test/04: Fail, OK
+type_variable_scope_test/05: Fail, OK
+
+[ $compiler == none && $checked ]
+# Test issue 6324 (continued)
+# Pass for the wrong reason: no distinction between compile-time error and dynamic error
+default_factory2_test/01: Pass
+type_variable_bounds_test/01: Pass
+type_variable_bounds_test/02: Pass
+type_variable_bounds_test/04: Pass
+type_variable_bounds_test/05: Pass
+type_variable_bounds_test/07: Pass
+type_variable_bounds2_test/none: Fail, OK
+type_variable_bounds2_test/00: Pass
+type_variable_bounds2_test/01: Fail, OK
+type_variable_bounds2_test/02: Pass
+type_variable_bounds2_test/03: Pass
+type_variable_bounds2_test/04: Fail, OK
+type_variable_bounds2_test/05: Pass
+type_variable_bounds2_test/06: Pass
+type_variable_scope_test/00: Pass
+type_variable_scope_test/01: Pass
+type_variable_scope_test/02: Pass
+type_variable_scope_test/03: Pass
+type_variable_scope_test/04: Pass
+type_variable_scope_test/05: Pass
+
[ $compiler == none && ($system == macos || $system == linux) && $arch == ia32 && $checked ]
gc_test: Skip # Issue 1487, flaky.
@@ -82,6 +232,7 @@
compile_time_constant_checked3_test/06: Fail, OK
[ $compiler == dartc ]
+built_in_identifier_prefix_test: Fail # http://dartbug.com/6971
library_juxtaposition_test: Fail # Issue 6881
new_expression_type_args_test/0*: Fail # Wrongly reports compile-time error.
redirecting_factory_infinite_steps_test/01: Fail # http://dartbug.com/6560
@@ -176,12 +327,10 @@
type_variable_bounds_test/00: Fail # issue 3079
# test issue 5291
-type_parameter_test/none: Fail, OK
type_parameter_test/01: Fail, OK
type_parameter_test/02: Fail, OK
type_parameter_test/03: Fail, OK
type_parameter_test/04: Fail, OK
-type_variable_scope2_test: Fail, OK
# test issue 5337
@@ -222,6 +371,7 @@
cyclic_type_variable_test/04: Fail, OK
default_class_implicit_constructor_test: Fail, OK
default_factory2_test/none: Fail, OK
+default_factory2_test/none: Fail, OK
default_factory2_test/01: Fail, OK
default_factory3_test: Fail, OK
default_factory_library_test: Fail, OK
@@ -346,6 +496,10 @@
# test issue 6871
block_scope_test: Fail, OK
+# test issue 7021
+instantiate_type_variable_negative_test: Fail
+type_variable_static_context_negative_test: Fail
+
#
# Add new dartc annotations above in alphabetical order
@@ -391,6 +545,7 @@
*: Skip
[ $compiler == dart2dart ]
+built_in_identifier_prefix_test: Fail # Inherited from dart2js.
factory_redirection2_test/01: Fail # Inherited from dart2js.
const_factory_redirection_test: Fail # http://dartbug.com/6894
@@ -418,6 +573,53 @@
# factory2_negative_test: Fail
# factory3_negative_test: Fail
# factory_negative_test: Fail
+ct_const_test: Fail, OK
+cyclic_type_variable_test/01: Fail, OK
+cyclic_type_variable_test/02: Fail, OK
+cyclic_type_variable_test/03: Fail, OK
+cyclic_type_variable_test/04: Fail, OK
+cyclic_type_variable_test/none: Fail, OK
+dynamic_test: Fail, OK
+generic_deep_test: Fail, OK
+generic_instanceof3_test: Fail, OK
+generic_syntax_test: Fail, OK
+implicit_this_test/01: Fail, OK
+implicit_this_test/04: Fail, OK
+implicit_this_test/none: Fail, OK
+implied_interface_test: Fail, OK
+instanceof2_test: Fail, OK
+instanceof_test: Fail, OK
+interface_constants_test: Fail, OK
+interface_inherit_field_test: Fail, OK
+is_operator_test: Fail, OK
+library_same_name_used_test: Fail, OK
+method_override2_test/none: Fail, OK
+prefix14_test: Fail, OK
+prefix15_test: Fail, OK
+syntax_test/none: Fail, OK
+throw1_test: Fail, OK
+throw2_test: Fail, OK
+try_catch2_test: Fail, OK
+try_catch3_test: Fail, OK
+type_variable_bounds2_test/00: Fail, OK
+type_variable_bounds2_test/01: Fail, OK
+type_variable_bounds2_test/02: Fail, OK
+type_variable_bounds2_test/03: Fail, OK
+type_variable_bounds2_test/04: Fail, OK
+type_variable_bounds2_test/05: Fail, OK
+type_variable_bounds2_test/06: Fail, OK
+type_variable_bounds2_test/none: Fail, OK
+default_class_implicit_constructor_test: Fail, OK
+default_implementation2_test:Fail, OK
+named_parameters_test/none: Fail, OK
+type_checks_in_factory_method_test: Fail, OK
+default_factory2_test/01: Fail, OK
+default_implementation_test: Fail, OK
+default_factory3_test: Fail, OK
+class_test: Fail, OK
+compile_time_constant_h_test: Fail, OK
+interface_test/00: Fail, OK
+default_implementation2_test: Fail, OK
default_factory_test: Fail
factory2_test: Fail
factory3_test: Fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 572215f..b7d3a74 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -2,6 +2,9 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
+[ $compiler == dart2js && $host_checked && $checked]
+new_expression_type_args_test/02: Crash # Issue 6931
+
[ $compiler == dart2js || $compiler == dart2dart ]
class_literal_test/01: Fail # Class literals are expression now; delete this test.
class_literal_test/02: Fail # Class literals are expression now; delete this test.
@@ -82,6 +85,7 @@
compile_time_constant_checked3_test/06: Fail, OK
[ $compiler == dart2js ]
+built_in_identifier_prefix_test: Fail # http://dartbug.com/6972
number_identity2_test: Fail # identity of NaN
factory_redirection2_test/01: Fail # http://dartbug.com/6791
new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
diff --git a/tests/language/load_to_load_forwarding_test.dart b/tests/language/load_to_load_forwarding_test.dart
new file mode 100644
index 0000000..5738263
--- /dev/null
+++ b/tests/language/load_to_load_forwarding_test.dart
@@ -0,0 +1,42 @@
+// 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.
+// Test correctness of side effects tracking used by load to load forwarding.
+
+class A {
+ var x, y;
+ A(this.x, this.y);
+}
+
+foo(a) {
+ var value1 = a.x;
+ var value2 = a.y;
+ for (var j = 1; j < 4; j++) {
+ value1 |= a.x << (j * 8);
+ a.y += 1;
+ a.x += 1;
+ value2 |= a.y << (j * 8);
+ }
+ return [value1, value2];
+}
+
+bar(a, mode) {
+ var value1 = a.x;
+ var value2 = a.y;
+ for (var j = 1; j < 4; j++) {
+ value1 |= a.x << (j * 8);
+ a.y += 1;
+ if (mode) a.x += 1;
+ a.x += 1;
+ value2 |= a.y << (j * 8);
+ }
+ return [value1, value2];
+}
+
+main() {
+ for (var i = 0; i < 2000; i++) {
+ Expect.listEquals([0x02010000, 0x03020100], foo(new A(0, 0)));
+ Expect.listEquals([0x02010000, 0x03020100], bar(new A(0, 0), false));
+ Expect.listEquals([0x04020000, 0x03020100], bar(new A(0, 0), true));
+ }
+}
\ No newline at end of file
diff --git a/tests/standalone/io/http_content_length_test.dart b/tests/standalone/io/http_content_length_test.dart
index 47ef941..5a082f2 100644
--- a/tests/standalone/io/http_content_length_test.dart
+++ b/tests/standalone/io/http_content_length_test.dart
@@ -37,10 +37,9 @@
conn.onResponse = (HttpClientResponse response) {
Expect.equals("0", response.headers.value('content-length'));
Expect.equals(0, response.contentLength);
- count++;
response.inputStream.onData = response.inputStream.read;
response.inputStream.onClosed = () {
- if (count == totalConnections) {
+ if (++count == totalConnections) {
client.shutdown();
server.close();
}
@@ -84,10 +83,9 @@
conn.onResponse = (HttpClientResponse response) {
Expect.equals("2", response.headers.value('content-length'));
Expect.equals(2, response.contentLength);
- count++;
response.inputStream.onData = response.inputStream.read;
response.inputStream.onClosed = () {
- if (count == totalConnections) {
+ if (++count == totalConnections) {
client.shutdown();
server.close();
}
diff --git a/tests/standalone/io/https_client_test.dart b/tests/standalone/io/https_client_test.dart
new file mode 100644
index 0000000..d639426
--- /dev/null
+++ b/tests/standalone/io/https_client_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "dart:uri";
+import "dart:isolate";
+
+
+int testGoogleUrlCount = 0;
+void testGoogleUrl() {
+ HttpClient client = new HttpClient();
+
+ void testUrl(String url) {
+ var requestUri = new Uri.fromString(url);
+ var conn = client.getUrl(requestUri);
+
+ conn.onRequest = (HttpClientRequest request) {
+ request.outputStream.close();
+ };
+ conn.onResponse = (HttpClientResponse response) {
+ testGoogleUrlCount++;
+ Expect.isTrue(response.statusCode < 500);
+ if (requestUri.path.length == 0) {
+ Expect.isTrue(response.statusCode != 404);
+ }
+ response.inputStream.onData = () {
+ response.inputStream.read();
+ };
+ response.inputStream.onClosed = () {
+ if (testGoogleUrlCount == 4) client.shutdown();
+ };
+ };
+ conn.onError = (error) => Expect.fail("Unexpected IO error $error");
+ }
+
+ testUrl('https://www.google.dk');
+ testUrl('https://www.google.dk');
+ testUrl('https://www.google.dk/#q=foo');
+ testUrl('https://www.google.dk/#hl=da&q=foo');
+}
+
+void testBadHostName() {
+ HttpClient client = new HttpClient();
+ HttpClientConnection connection = client.getUrl(
+ new Uri.fromString("https://some.bad.host.name.7654321/"));
+ connection.onRequest = (HttpClientRequest request) {
+ Expect.fail("Should not open a request on bad hostname");
+ };
+ ReceivePort port = new ReceivePort();
+ connection.onError = (Exception error) {
+ port.close(); // We expect onError to be called, due to bad host name.
+ };
+}
+
+void InitializeSSL() {
+ var testPkcertDatabase =
+ new Path.fromNative(new Options().script).directoryPath.append('pkcert/');
+ SecureSocket.setCertificateDatabase(testPkcertDatabase.toNativePath());
+}
+
+void main() {
+ InitializeSSL();
+ testGoogleUrl();
+ testBadHostName();
+}
diff --git a/tests/standalone/io/https_server_test.dart b/tests/standalone/io/https_server_test.dart
new file mode 100644
index 0000000..8eb639f
--- /dev/null
+++ b/tests/standalone/io/https_server_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "dart:uri";
+import "dart:isolate";
+
+const SERVER_ADDRESS = "127.0.0.1";
+const HOST_NAME = "localhost";
+
+void testListenOn() {
+ void test(void onDone()) {
+ HttpsServer server = new HttpsServer();
+ Expect.throws(() => server.port);
+
+ ReceivePort serverPort = new ReceivePort();
+ server.defaultRequestHandler =
+ (HttpRequest request, HttpResponse response) {
+ request.inputStream.onClosed = () {
+ response.outputStream.close();
+ serverPort.close();
+ };
+ };
+
+ server.onError = (Exception e) {
+ Expect.fail("Unexpected error in Https Server: $e");
+ };
+
+ server.listen(SERVER_ADDRESS,
+ 0,
+ backlog: 5,
+ certificate_name: 'CN=$HOST_NAME');
+
+ HttpClient client = new HttpClient();
+ HttpClientConnection conn =
+ client.getUrl(new Uri.fromString("https://$HOST_NAME:${server.port}/"));
+ conn.onRequest = (HttpClientRequest request) {
+ request.outputStream.close();
+ };
+ ReceivePort clientPort = new ReceivePort();
+ conn.onResponse = (HttpClientResponse response) {
+ response.inputStream.onClosed = () {
+ client.shutdown();
+ clientPort.close();
+ server.close();
+ Expect.throws(() => server.port);
+ onDone();
+ };
+ };
+ conn.onError = (Exception e) {
+ Expect.fail("Unexpected error in Https Client: $e");
+ };
+ };
+
+ // Test two connection after each other.
+ test(() {
+ test(() {
+ });
+ });
+}
+
+void InitializeSSL() {
+ var testPkcertDatabase =
+ new Path.fromNative(new Options().script).directoryPath.append('pkcert/');
+ SecureSocket.setCertificateDatabase(testPkcertDatabase.toNativePath(),
+ 'dartdart');
+}
+
+void main() {
+ InitializeSSL();
+ testListenOn();
+}
diff --git a/tests/standalone/io/path_test.dart b/tests/standalone/io/path_test.dart
index a2b39a6..fbc2ce9 100644
--- a/tests/standalone/io/path_test.dart
+++ b/tests/standalone/io/path_test.dart
@@ -11,6 +11,7 @@
testCanonicalize();
testJoinAppend();
testRelativeTo();
+ testWindowsShare();
}
void testBaseFunctions() {
@@ -194,3 +195,36 @@
Expect.throws(() =>
new Path('a/b').relativeTo(new Path('../../d')));
}
+
+// Test that Windows share information is maintain through
+// Path operations.
+void testWindowsShare() {
+ // Windows share information only makes sense on Windows.
+ if (Platform.operatingSystem != 'windows') return;
+ var path = new Path.fromNative(r'\\share\a\b\..\c');
+ Expect.isTrue(path.isAbsolute);
+ Expect.isTrue(path.isWindowsShare);
+ Expect.isFalse(path.hasTrailingSeparator);
+ var canonical = path.canonicalize();
+ Expect.isTrue(canonical.isAbsolute);
+ Expect.isTrue(canonical.isWindowsShare);
+ Expect.isFalse(path.isCanonical);
+ Expect.isTrue(canonical.isCanonical);
+ var joined = canonical.join(new Path('d/e/f'));
+ Expect.isTrue(joined.isAbsolute);
+ Expect.isTrue(joined.isWindowsShare);
+ var relativeTo = joined.relativeTo(canonical);
+ Expect.isFalse(relativeTo.isAbsolute);
+ Expect.isFalse(relativeTo.isWindowsShare);
+ var nonShare = new Path('/share/a/c/d/e');
+ Expect.throws(() => nonShare.relativeTo(canonical));
+ Expect.isTrue(canonical.toString().startsWith('/share/a'));
+ Expect.isTrue(canonical.toNativePath().startsWith(r'\\share\a'));
+ Expect.listEquals(['share', 'a', 'c'], canonical.segments());
+ var appended = canonical.append('d');
+ Expect.isTrue(appended.isAbsolute);
+ Expect.isTrue(appended.isWindowsShare);
+ var directoryPath = canonical.directoryPath;
+ Expect.isTrue(directoryPath.isAbsolute);
+ Expect.isTrue(directoryPath.isWindowsShare);
+}
diff --git a/tests/standalone/package/package_isolate_test.dart b/tests/standalone/package/package_isolate_test.dart
index 7f4bc61..fad10c8 100644
--- a/tests/standalone/package/package_isolate_test.dart
+++ b/tests/standalone/package/package_isolate_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// PackageRoot=tests/standalone/package/packages/
+// PackageRoot=packages/
library package_isolate_test;
import 'package:shared.dart' as shared;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index d64d1e6..f4bccf8 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -43,6 +43,7 @@
[ $runtime == vm && $system == windows ]
io/file_system_links_test: Skip # No links on Windows.
io/secure_server_stream_test: Pass, Crash, Timeout # Issue 6893
+io/secure_server_test: Pass, Crash, Fail, Timeout # Issue 6893
[ $compiler == none && $runtime == drt ]
io/*: Skip # Don't run tests using dart:io in the browser
@@ -67,7 +68,7 @@
typed_array_test: Skip # This is a VM test
float_array_test: Skip # This is a VM test
int_array_test: Skip # This is a VM test
-medium_integer_test: Fail, OK # cannot resolve type Mint
+medium_integer_test: Fail, OK # Test fails with JS number semantics: issue 1533.
io/process_exit_negative_test: Fail, OK # relies on a static error that is a warning now.
package/package_isolate_test: Skip # spawnUri does not work in dart2js. See issue 3051
@@ -81,6 +82,7 @@
[ $compiler == dart2js && $runtime == none ]
io/options_test: Fail
+medium_integer_test: Pass # The test only fails at runtime, not at compilation.
[ $compiler == dart2js && $browser ]
*: Skip
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index f7096f1..af4c06a 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -34,6 +34,9 @@
eqNullB(a) {}""";
} else if (uri.path.endsWith('_patch.dart')) {
source = '';
+ } else if (uri.path.endsWith('interceptors.dart')) {
+ source = """class ObjectInterceptor {}
+ var getInterceptor;""";
} else if (uri.path.endsWith('js_helper.dart')) {
source = 'library jshelper; class JSInvocationMirror {}';
} else {
diff --git a/tools/VERSION b/tools/VERSION
index 9b6bee7..84b242a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 2
-BUILD 6
+BUILD 7
PATCH 0
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 5793e3e..d8396602 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -59,6 +59,8 @@
import tempfile
import utils
+HOST_OS = utils.GuessOS()
+
# TODO(dgrove): Only import modules following Google style guide.
from os.path import basename, dirname, join, realpath, exists, isdir
@@ -85,15 +87,14 @@
# TODO(zundel): this excludes the analyzer from the sdk build until builders
# have all prerequisite software installed. Also update dart.gyp.
def ShouldCopyAnalyzer():
- os = utils.GuessOS()
- return os == 'linux' or os == 'macos'
+ return HOST_OS == 'linux' or HOST_OS == 'macos'
def CopyShellScript(src_file, dest_dir):
'''Copies a shell/batch script to the given destination directory. Handles
using the appropriate platform-specific file extension.'''
file_extension = ''
- if utils.GuessOS() == 'win32':
+ if HOST_OS == 'win32':
file_extension = '.bat'
src = src_file + file_extension
@@ -149,7 +150,7 @@
build_dir = os.path.dirname(argv[1])
dart_file_extension = ''
analyzer_file_extension = ''
- if utils.GuessOS() == 'win32':
+ if HOST_OS == 'win32':
dart_file_extension = '.exe'
analyzer_file_extension = '.bat' # TODO(zundel): test on Windows
dart_import_lib_src = join(HOME, build_dir, 'dart.lib')
@@ -159,8 +160,11 @@
dart_dest_binary = join(BIN, 'dart' + dart_file_extension)
copyfile(dart_src_binary, dart_dest_binary)
copymode(dart_src_binary, dart_dest_binary)
- if utils.GuessOS() != 'win32':
+ # Strip the binaries on platforms where that is supported.
+ if HOST_OS == 'linux':
subprocess.call(['strip', dart_dest_binary])
+ elif HOST_OS == 'macos':
+ subprocess.call(['strip', '-x', dart_dest_binary])
if ShouldCopyAnalyzer():
# Copy analyzer into sdk/bin
@@ -201,7 +205,8 @@
for library in ['_internal', 'collection', 'core', 'crypto', 'io', 'isolate',
join('html', 'dart2js'), join('html', 'dartium'), 'json',
'math', 'mirrors', 'scalarlist', join('svg', 'dart2js'),
- join('svg', 'dartium'), 'uri', 'utf']:
+ join('svg', 'dartium'), 'uri', 'utf',
+ join('web_audio', 'dart2js'), join('web_audio', 'dartium')]:
copytree(join(HOME, 'sdk', 'lib', library), join(LIB, library),
ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh'))
@@ -211,11 +216,11 @@
os.makedirs(PKG)
#
- # Create and populate pkg/{args, intl, logging, meta, unittest}
+ # Create and populate pkg/{args, intl, logging, meta, unittest, ...}
#
- for library in ['args', 'htmlescape', 'intl', 'logging',
- 'meta', 'unittest']:
+ for library in ['args', 'htmlescape', 'http', 'intl', 'logging',
+ 'meta', 'oauth2', 'unittest']:
copytree(join(HOME, 'pkg', library), join(PKG, library),
ignore=ignore_patterns('*.svn', 'doc', 'docs',
'*.py', '*.gypi', '*.sh'))
@@ -249,21 +254,21 @@
ignore=ignore_patterns('.svn', 'sdk'))
# Copy in 7zip for Windows.
- if utils.GuessOS() == 'win32':
+ if HOST_OS == 'win32':
copytree(join(HOME, 'third_party', '7zip'),
join(join(UTIL, 'pub'), '7zip'),
ignore=ignore_patterns('.svn'))
- ReplaceInFiles([
- join(UTIL, 'pub', 'io.dart'),
- ], [
- ("var pathTo7zip = '../../third_party/7zip/7za.exe';",
- "var pathTo7zip = '7zip/7za.exe';"),
- ])
+ ReplaceInFiles([
+ join(UTIL, 'pub', 'io.dart'),
+ ], [
+ ("../../third_party/7zip/7za.exe",
+ "7zip/7za.exe"),
+ ])
# Copy in cURL on all operating systems, since we need the certificates file
# even outside Windows. Leave out the EXE on non-Windows systems, though.
- curl_ignore_patterns = ignore_patterns('.svn') if utils.GuessOS() == 'win32' \
+ curl_ignore_patterns = ignore_patterns('.svn') if HOST_OS == 'win32' \
else ignore_patterns('.svn', '*.exe')
copytree(join(HOME, 'third_party', 'curl'),
join(join(UTIL, 'pub'), 'curl'),
@@ -272,10 +277,10 @@
ReplaceInFiles([
join(UTIL, 'pub', 'curl_client.dart'),
], [
- ("var pathToCurl = '../../third_party/curl/curl.exe';",
- "var pathToCurl = 'curl/curl.exe';"),
- ("var pathToCertificates = '../../third_party/curl/ca-certificates.crt';",
- "var pathToCertificates = 'curl/ca-certificates.crt';"),
+ ("../../third_party/curl/curl.exe",
+ "curl/curl.exe"),
+ ("../../third_party/curl/ca-certificates.crt",
+ "curl/ca-certificates.crt"),
])
version = utils.GetVersion()
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index e51516f..3c2f643 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -526,7 +526,7 @@
}
-void main() {
+void debuggerMain() {
outstandingCommands = new Map<int, Completer>();
vmSock = new Socket("127.0.0.1", 5858);
vmStream = vmSock.outputStream;
@@ -548,3 +548,26 @@
quitShell();
};
}
+
+void main() {
+ Options options = new Options();
+ List<String> arguments = options.arguments;
+ if (arguments.length > 0) {
+ arguments = <String>['--debug', '--verbose_debug']..addAll(arguments);
+ Process.start(options.executable, arguments).then((Process process) {
+ process.onExit = (int exitCode) {
+ print('${Strings.join(arguments, " ")} exited with $exitCode');
+ };
+ process.stdin.close();
+ // Redirecting both stdout and stderr of the child process to
+ // stdout. This should help users keep track of which errors
+ // are coming from the debugger, and which errors are coming
+ // from the process being debugged.
+ process.stderr.pipe(stdout);
+ process.stdout.pipe(stdout);
+ debuggerMain();
+ });
+ } else {
+ debuggerMain();
+ }
+}
diff --git a/tools/gyp/configurations_android.gypi b/tools/gyp/configurations_android.gypi
index fc393cf..f7d9da9 100644
--- a/tools/gyp/configurations_android.gypi
+++ b/tools/gyp/configurations_android.gypi
@@ -40,7 +40,15 @@
'ANDROID',
],
'configurations': {
- 'Release': {
+ 'Dart_Debug': {
+ 'defines': [
+ 'DEBUG',
+ ],
+ },
+ 'Dart_Release': {
+ 'defines': [
+ 'NDEBUG',
+ ],
'cflags!': [
'-O2',
'-Os',
@@ -51,7 +59,7 @@
'-fomit-frame-pointer',
'-O3',
],
- }, # Release
+ },
}, # configurations
'cflags': [ '-Wno-abi', '-Wall', '-W', '-Wno-unused-parameter',
'-Wnon-virtual-dtor', '-fno-rtti', '-fno-exceptions', ],
diff --git a/tools/html_json_doc/bin/html_json_doc.dart b/tools/html_json_doc/bin/html_json_doc.dart
new file mode 100644
index 0000000..7c5b726
--- /dev/null
+++ b/tools/html_json_doc/bin/html_json_doc.dart
@@ -0,0 +1,69 @@
+// 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.
+
+/**
+ * TODO(amouravski): Document stuff here.
+ */
+
+import 'dart:io';
+
+import '../lib/html_to_json.dart' as html_to_json;
+import '../lib/json_to_html.dart' as json_to_html;
+import '../../../pkg/args/lib/args.dart';
+
+// Need this because ArgParser.getUsage doesn't show command invocation.
+const USAGE = 'Usage htmlJsonDoc [options] --mode=<mode> <HTML.dart directory> '
+ '<json path>\n[options] include:';
+final argParser = new ArgParser();
+
+main() {
+ final args = new Options().arguments;
+
+ if (args.isEmpty) {
+ printUsage('No arguments provided.');
+ return;
+ }
+
+ var mode;
+ argParser.addOption('mode', abbr: 'm',
+ help: '(Required) Convert from HTML docs to JSON or vice versa.',
+ allowed: ['html-to-json', 'json-to-html'], allowedHelp: {
+ 'html-to-json': 'Processes all HTML .dart files at given\n'
+ 'location and outputs JSON.',
+ 'json-to-html': 'Takes JSON file at location and inserts docs into\n'
+ 'HTML .dart files.'},
+ callback: (m) => mode = m
+ );
+
+ final argResults = argParser.parse(args);
+
+ if (mode == null) {
+ printUsage('Mode is a required option.');
+ return;
+ } else if (argResults.rest.length < 2) {
+ printUsage('Insufficient arguments.');
+ return;
+ }
+
+ var htmlPath = new Path.fromNative(argResults.rest[0]);
+ var jsonPath = new Path.fromNative(argResults.rest[1]);
+
+ var convertFuture;
+ if (mode == 'html-to-json') {
+ convertFuture = html_to_json.convert(htmlPath, jsonPath);
+ } else {
+ convertFuture = json_to_html.convert(htmlPath, jsonPath);
+ }
+
+ convertFuture.then((anyErrors) {
+ print('Completed ${anyErrors ? "with" : "without"} errors.');
+ });
+}
+
+/// Prints the usage of the tool. [message] is printed if provided.
+void printUsage([String message]) {
+ print(message);
+ print(USAGE);
+ print(argParser.getUsage());
+}
\ No newline at end of file
diff --git a/tools/html_json_doc/lib/html_to_json.dart b/tools/html_json_doc/lib/html_to_json.dart
new file mode 100644
index 0000000..ddfb5eb
--- /dev/null
+++ b/tools/html_json_doc/lib/html_to_json.dart
@@ -0,0 +1,314 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Library for extracting the documentation comments from files generated by
+ * the HTML library. The comments are stored in a JSON file.
+ *
+ * Comments must be in either the block style with leading *s:
+ *
+ * /**
+ * * Comment here.
+ * */
+ *
+ * Or the triple-slash style:
+ *
+ * /// Docs go here.
+ * /// And here.
+ *
+ * Each member that is to be documented should be preceeded by a meta-comment
+ * containing the string `@docsEditable` such as:
+ *
+ * /// @docsEditable
+ */
+library html_to_json;
+
+import 'dart:json';
+import 'dart:io';
+
+
+/// True if any errors were triggered through the conversion.
+bool _anyErrors = false;
+
+
+/**
+ * Convert files on [htmlPath] and write JSON to [jsonPath].
+ */
+Future<bool> convert(Path htmlPath, Path jsonPath) {
+ var completer = new Completer();
+
+ // TODO(amouravski): make this transform once I know what I want this file to
+ // return.
+ _convertFiles(htmlPath).then((convertedJson) {
+ final jsonFile = new File.fromPath(jsonPath);
+ var writeJson = convertedJson;
+
+ if (jsonFile.existsSync()) {
+ writeJson = _mergeJsonAndFile(convertedJson, jsonFile);
+ }
+
+ var outputStream = jsonFile.openOutputStream();
+ outputStream.writeString(prettyPrintJson(writeJson));
+
+ outputStream.onNoPendingWrites = () {
+ completer.complete(_anyErrors);
+ };
+
+ outputStream.onClosed = () {
+ completer.complete(_anyErrors);
+ };
+
+ outputStream.onError = completer.completeException;
+ });
+
+ return completer.future;
+}
+
+
+/**
+ * Convert all files on [htmlPath].
+ *
+ * Returns a future that completes to the converted JSON object.
+ */
+Future<Object> _convertFiles(Path htmlPath) {
+ var completer = new Completer();
+
+ List<Future> fileFutures = [];
+
+ // Get a list of all HTML dart files.
+ // TODO(amouravski): discriminate .dart files.
+ final htmlDir = new Directory.fromPath(htmlPath);
+ final lister = htmlDir.list(recursive: false);
+
+ lister.onFile = (String path) {
+ final name = new Path.fromNative(path).filename;
+
+ // Ignore private classes.
+ if (name.startsWith('_')) return;
+
+ // Ignore non-dart files.
+ if (!name.endsWith('.dart')) return;
+
+ File file = new File(path);
+
+ // TODO(amouravski): Handle missing file.
+ if (!file.existsSync()) {
+ print('ERROR: cannot find file $path');
+ _anyErrors = true;
+ return;
+ }
+
+ fileFutures.add(_convertFile(file));
+ };
+
+
+ // Combine all JSON objects
+ lister.onDone = (_) {
+ Futures.wait(fileFutures).then((jsonList) {
+ var convertedJson = {};
+ jsonList.forEach((json) {
+ final k = json.keys[0];
+ convertedJson.putIfAbsent(k, () => json[k]);
+ });
+ completer.complete(convertedJson);
+ });
+ };
+
+ // TODO(amouravski): add more error handling.
+
+ return completer.future;
+}
+
+
+/**
+ * Convert a single file to JSON docs.
+ *
+ * Returns a map with one entry whose key is the file name and whose value is
+ * the list of comment lines.
+ */
+Future<Map> _convertFile(File file) {
+ var completer = new Completer();
+
+ var comments = {};
+
+ // Find all /// @docsEditable annotations.
+ InputStream file_stream = file.openInputStream();
+ StringInputStream inputLines = new StringInputStream(file_stream);
+
+ // TODO(amouravski): Re-write as file.readAsLine().thin((lines) {...}
+ inputLines.onLine = () {
+ var comment = <String>[];
+
+ var docCommentFound = false;
+ String line;
+ while ((line = inputLines.readLine()) != null) {
+ var trimmedLine = line.trim();
+
+ // Sentinel found. Process the comment block.
+ if (trimmedLine.startsWith('///') &&
+ trimmedLine.contains('@docsEditable')) {
+ if (docCommentFound == true) {
+ var nextLine = inputLines.readLine();
+
+ if (nextLine == null) return false;
+
+ var lineObject = {};
+
+ if (comments[nextLine] != null) {
+ print('WARNING: duplicate line ${nextLine} found in'
+ '${new Path(file.fullPathSync()).filename}');
+ }
+ comments.putIfAbsent(nextLine, () => comment);
+ }
+
+ // Reset.
+ docCommentFound = false;
+ comment = <String>[];
+ } else if ( // Start a comment block.
+ trimmedLine.startsWith('/**') ||
+ trimmedLine.startsWith('///')) {
+ docCommentFound = true;
+ comment.add(line);
+ } else if (docCommentFound &&
+ // TODO(amouravski): This will barf on:
+ // /// blah
+ // *
+ (trimmedLine.startsWith('*') || trimmedLine.startsWith('///'))) {
+ comment.add(line);
+ } else {
+ // Reset if we're not in a comment.
+ docCommentFound = false;
+ comment = <String>[];
+ }
+ }
+ };
+
+ inputLines.onClosed = () {
+ var jsonObject = {};
+ jsonObject[new Path(file.fullPathSync()).filename] = comments;
+ completer.complete(jsonObject);
+ };
+
+ // TODO(amouravski): better error handling.
+
+ return completer.future;
+}
+
+
+/**
+ * Merge the new JSON object and the existing file.
+ */
+Object _mergeJsonAndFile(Object json, File file) {
+ var completer = new Completer();
+
+ var fileJson = {};
+ var jsonRead = file.readAsStringSync();
+
+ if (jsonRead == '') {
+ print('WARNING: no data read from '
+ '${new Path(file.fullPathSync()).filename}');
+ _anyErrors = true;
+ } else {
+ fileJson = JSON.parse(jsonRead);
+ }
+ return _mergeJson(json, fileJson);
+}
+
+
+/**
+ * Merge two JSON objects, such that the returned JSON object is the
+ * union of both.
+ *
+ * Each JSON must be a map, with each value being a map.
+ */
+Object _mergeJson(Object json1, Object json2) {
+ if (json1 is Map && json2 is Map) {
+ // Then check if [json2] contains any key form [json1], in which case
+ // add all of the values from [json2] to the values of [json1].
+ json2.forEach((k, v) {
+ if (json1.containsKey(k)) {
+ v.forEach((vk, vv) {
+ if (json1[k].containsKey(vk) &&
+ !_listsEqual(json1[k][vk],vv)) {
+ // Assume that json1 is more current and take its data as opposed
+ // to json2's.
+ // TODO(amouravski): add better warning message and only if there's
+ // a conflict.
+ print('INFO: duplicate keys.');
+ _anyErrors = false;
+ } else {
+ json1[k].putIfAbsent(vk, () => vv);
+ }
+ });
+ } else {
+ json1.putIfAbsent(k, () => v);
+ }
+ });
+ } else {
+ throw new ArgumentError('JSON objects must both be Maps');
+ }
+
+ // TODO(amouravski): more error handling.
+
+ return json1;
+}
+
+
+/**
+ * Tests for equality between two lists.
+ *
+ * This checks the first level of depth, so does not work for nested lists.
+ */
+bool _listsEqual(List list1, List list2) {
+ return list1.every((e) => list2.contains(e)) &&
+ list2.every((e) => list1.contains(e));
+}
+
+
+/**
+ * Print JSON in a much nicer format.
+ *
+ * For example:
+ *
+ * {"foo":["bar","baz"],"boo":{"far:"faz"}}
+ *
+ * becomes:
+ *
+ * {
+ * "foo":
+ * [
+ * "bar",
+ * "baz"
+ * ],
+ * "boo":
+ * {
+ * "far":
+ * "faz"
+ * }
+ * }
+ */
+String prettyPrintJson(Object json, [String indentation = '']) {
+ var output;
+
+ if (json is List) {
+ var recursiveOutput =
+ Strings.join(json.map((e) =>
+ prettyPrintJson(e, '$indentation ')), ',\n');
+ output = '$indentation[\n'
+ '$recursiveOutput'
+ '\n$indentation]';
+ } else if (json is Map) {
+ // TODO(amouravski): No newline after :
+ var mapList = json.keys.map((key) =>
+ '$indentation${JSON.stringify(key)}:\n'
+ '${prettyPrintJson(json[key], '$indentation ')}');
+ var recursiveOutput = Strings.join(mapList, ',\n');
+ output = '$indentation{\n'
+ '$recursiveOutput'
+ '\n$indentation}';
+ } else {
+ output = '$indentation${JSON.stringify(json)}';
+ }
+ return output;
+}
\ No newline at end of file
diff --git a/tools/html_json_doc/lib/json_to_html.dart b/tools/html_json_doc/lib/json_to_html.dart
new file mode 100644
index 0000000..d25aa4d
--- /dev/null
+++ b/tools/html_json_doc/lib/json_to_html.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Library for taking a JSON file and putting the comments located within into
+ * the HTML files the comments are associated with.
+ *
+ * The format of the JSON file is:
+ *
+ * {
+ * "$filename":
+ * {
+ * "$lineInHtml":
+ * [
+ * "lines of comment",
+ * "here"
+ * ]
+ * },
+ * ...
+ * }
+ */
+library json_to_html;
+
+import 'dart:json';
+import 'dart:io';
+
+
+/// True if any errors were triggered through the conversion.
+bool _anyErrors = false;
+
+
+/**
+ * Take comments from [jsonPath] and apply them to all the files found in
+ * [htmlPath]. This will overwrite the files in htmlPath.
+ */
+Future<bool> convert(Path htmlPath, Path jsonPath) {
+ final completer = new Completer();
+
+ final jsonFile = new File.fromPath(jsonPath);
+ final htmlDir = new Directory.fromPath(htmlPath);
+
+ if (!jsonFile.existsSync()) {
+ print("ERROR: No JSON file found at: ${jsonPath}");
+ _anyErrors = true;
+ completer.complete(false);
+ } else if (!htmlDir.existsSync()) {
+ print("ERROR: No HTML directory found at: ${htmlPath}");
+ _anyErrors = true;
+ completer.complete(false);
+ }
+
+
+ var fileJson = {};
+ var jsonRead = jsonFile.readAsStringSync();
+
+ if (jsonRead == '') {
+ print('WARNING: no data read from ${jsonPath.filename}');
+ _anyErrors = true;
+ completer.complete(false);
+ } else {
+ fileJson = JSON.parse(jsonRead);
+ }
+
+ // TODO(amouravski): Refactor to not duplicate code here and in html-to-json.
+ // Find html files. (lister)
+ final lister = htmlDir.list(recursive: false);
+
+ lister.onFile = (String path) {
+ final name = new Path.fromNative(path).filename;
+
+ // Ignore private classes.
+ if (name.startsWith('_')) return;
+
+ // Ignore non-dart files.
+ if (!name.endsWith('.dart')) return;
+
+ File file = new File(path);
+
+ // TODO(amouravski): Handle missing file.
+ if (!file.existsSync()) {
+ print('ERROR: cannot find file: $path');
+ _anyErrors = true;
+ return;
+ }
+
+ if (!fileJson.containsKey(name)) {
+ print('WARNING: file found that is not in JSON: $path');
+ _anyErrors = true;
+ return;
+ }
+
+ var comments = fileJson[name];
+
+ _convertFile(file, comments);
+
+ fileJson.remove(name);
+ };
+
+ lister.onDone = (_) {
+
+ fileJson.forEach((key, _) {
+ print('WARNING: the following filename was found in the JSON but not in '
+ '${htmlDir.path}:\n"$key"');
+ _anyErrors = true;
+ });
+
+ completer.complete(_anyErrors);
+ };
+
+ return completer.future;
+}
+
+
+/**
+ * Inserts the comments from JSON into a single file.
+ */
+void _convertFile(File file, Map<String, List<String>> comments) {
+ var fileLines = file.readAsLinesSync();
+
+ var unusedComments = {};
+
+ comments.forEach((key, comments) {
+ var index = fileLines.indexOf(key);
+ // If the key is found in any line past the first one.
+ if (index > 0 && fileLines[index - 1].trim().startsWith('///') &&
+ fileLines[index - 1].contains('@docsEditable')) {
+
+ // Add comments.
+ fileLines.insertRange(index - 1, comments.length);
+ fileLines.setRange(index - 1, comments.length, comments);
+ } else {
+ unusedComments.putIfAbsent(key, () => comments);
+ }
+ });
+
+ unusedComments.forEach((String key, _) {
+ print('WARNING: the following key was found in the JSON but not in '
+ '${new Path(file.fullPathSync()).filename}:\n"$key"');
+ _anyErrors = true;
+ });
+
+ // TODO(amouravski): file.writeAsStringSync('${Strings.join(fileLines, '\n')}\n');
+ var outputStream = file.openOutputStream();
+ outputStream.writeString(Strings.join(fileLines, '\n'));
+ outputStream.writeString('\n');
+
+ outputStream.onNoPendingWrites = () {
+ outputStream.close();
+ };
+}
diff --git a/tools/html_json_doc/test/html_json_doc_test.dart b/tools/html_json_doc/test/html_json_doc_test.dart
new file mode 100644
index 0000000..4d721dc
--- /dev/null
+++ b/tools/html_json_doc/test/html_json_doc_test.dart
@@ -0,0 +1,103 @@
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../lib/html_to_json.dart' as html_to_json;
+import '../lib/json_to_html.dart' as json_to_html;
+import 'dart:json';
+import 'dart:io';
+
+void main() {
+ var scriptPath = new Path(new Options().script).directoryPath.toString();
+
+ test('HTML Doc to JSON', () {
+ var htmlPath = new Path('$scriptPath/test_data/html_to_json');
+ var jsonPath = new Path('$scriptPath/test_output/html_to_json_test.json');
+
+ var convertFuture = html_to_json.convert(htmlPath, jsonPath);
+
+ convertFuture.then(expectAsync1((anyErrors) {
+ var output = new File.fromPath(jsonPath);
+
+ var goldenFile = new File(
+ '$scriptPath/test_data/html_to_json/'
+ 'html_to_json_test_golden_output.json');
+
+ expect(anyErrors, false, reason:'The conversion completed with errors.');
+ expect(output.readAsStringSync(), goldenFile.readAsStringSync());
+ }));
+ });
+
+ test('JSON to HTML Doc', () {
+ var preHtmlPath = new Path('$scriptPath/test_data/json_to_html');
+ var goldenHtmlPath = new Path('$scriptPath/test_data/html_to_json');
+ var htmlPath = new Path('$scriptPath/test_output');
+ var jsonPath = new Path('$scriptPath/test_output/html_to_json_test.json');
+
+ var copyFuture = _copyFiles(preHtmlPath, htmlPath);
+
+ copyFuture.then(expectAsync1((_) {
+ var convertFuture = json_to_html.convert(htmlPath, jsonPath);
+
+ convertFuture.then((anyErrors) {
+ expect(anyErrors, false,
+ reason:'The conversion completed with errors.');
+
+ _compareFilesInDirectories(goldenHtmlPath, htmlPath);
+
+ });
+ }));
+ });
+}
+
+void _compareFilesInDirectories(Path path1, Path path2) {
+ final dir1 = new Directory.fromPath(path1);
+ final dir2 = new Directory.fromPath(path2);
+ final lister1 = dir1.list(recursive: false);
+ final lister2 = dir2.list(recursive: false);
+
+ // True once one of the listers is finished.
+ var oneFinished = false;
+
+ var list1 = <String, File>{};
+
+ lister1.onFile = (String path) {
+ if (path.endsWith('.dart')) {
+ list1.putIfAbsent(new Path(path).filename, () => new File(path));
+ }
+ };
+
+ lister1.onDone = (_) {
+ lister2.onFile = (String path) {
+ if (path.endsWith('.dart')) {
+ expect(list1[new Path(path).filename].readAsStringSync(),
+ new File(path).readAsStringSync());
+ }
+ };
+ };
+}
+
+Future _copyFiles(Path fromDir, Path toDir) {
+ // First copy the files into a new place to keep the old files.
+ final completer = new Completer();
+ final htmlDir = new Directory.fromPath(fromDir);
+ final lister = htmlDir.list(recursive: false);
+
+ lister.onFile = (String path) {
+ final name = new Path.fromNative(path).filename;
+
+ // Ignore private classes.
+ if (name.startsWith('_')) return;
+
+ // Ignore non-dart files.
+ if (!name.endsWith('.dart')) return;
+
+ File file = new File(path);
+ File newFile = new File.fromPath(toDir.append(name));
+
+ var outputStream = newFile.openOutputStream();
+ outputStream.writeString(file.readAsStringSync());
+ };
+
+ lister.onDone = (_) {
+ completer.complete(null);
+ };
+ return completer.future;
+}
\ No newline at end of file
diff --git a/tools/html_json_doc/test/test_data/html_to_json/html_to_json_test_golden_output.json b/tools/html_json_doc/test/test_data/html_to_json/html_to_json_test_golden_output.json
new file mode 100644
index 0000000..8495eed
--- /dev/null
+++ b/tools/html_json_doc/test/test_data/html_to_json/html_to_json_test_golden_output.json
@@ -0,0 +1,79 @@
+{
+"test_html_input2.dart":
+ {
+ "class InputTestCase1 {":
+ [
+ "/**",
+ " * This is a multi-line dartdoc comment.",
+ " * This is one line.",
+ " * And it keeps going to this line, too.",
+ " */"
+ ],
+ "class InputTestCase2 extends InputTestCase1 {":
+ [
+ "/// This is a single line dartdoc comment."
+ ],
+ "class InputTestCase3 extends InputTestCase2 {":
+ [
+ "/// This is a multi-line dartdoc comment.",
+ "/// It happens to use multiple single line dartdoc comments."
+ ],
+ " var InputTestCase8;":
+ [
+ " /**",
+ " * This is a multi-line comment on a member.",
+ " */"
+ ],
+ " var InputTestCase9;":
+ [
+ " /// This is a single line dartdoc comment on a member."
+ ],
+ " var InputTestCase10;":
+ [
+ " /// This is a multi-line dartdoc comment on a member.",
+ " /// It is split over two lines."
+ ]
+ },
+"test_html_input.dart":
+ {
+ "library testInput;":
+ [
+ "/**",
+ " * YES. This is a library level dartdoc comment.",
+ " * This should show up correctly in the JSON.",
+ " */"
+ ],
+ "class InputTestCase1 {":
+ [
+ "/**",
+ " * YES. This is a multi-line dartdoc comment.",
+ " * This is one line.",
+ " * And it keeps going to this line, too.",
+ " */"
+ ],
+ "class InputTestCase2 extends InputTestCase1 {":
+ [
+ "/// YES. This is a single line dartdoc comment."
+ ],
+ "class InputTestCase3 extends InputTestCase2 {":
+ [
+ "/// YES. This is a multi-line dartdoc comment.",
+ "/// It happens to use multiple single line dartdoc comments."
+ ],
+ " var InputTestCase8;":
+ [
+ " /**",
+ " * YES. This is a multi-line comment on a member.",
+ " */"
+ ],
+ " var InputTestCase9;":
+ [
+ " /// YES. This is a single line dartdoc comment on a member."
+ ],
+ " var InputTestCase10;":
+ [
+ " /// YES. This is a multi-line dartdoc comment on a member.",
+ " /// It is split over two lines."
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tools/html_json_doc/test/test_data/html_to_json/test_html_input.dart b/tools/html_json_doc/test/test_data/html_to_json/test_html_input.dart
new file mode 100644
index 0000000..291d0dd
--- /dev/null
+++ b/tools/html_json_doc/test/test_data/html_to_json/test_html_input.dart
@@ -0,0 +1,80 @@
+/**
+ * YES. This is a library level dartdoc comment.
+ * This should show up correctly in the JSON.
+ */
+/// @docsEditable
+library testInput;
+
+/**
+ * YES. This is a multi-line dartdoc comment.
+ * This is one line.
+ * And it keeps going to this line, too.
+ */
+/// @docsEditable
+class InputTestCase1 {
+
+}
+
+/// YES. This is a single line dartdoc comment.
+/// @docsEditable
+class InputTestCase2 extends InputTestCase1 {
+
+}
+
+/// YES. This is a multi-line dartdoc comment.
+/// It happens to use multiple single line dartdoc comments.
+/// @docsEditable
+class InputTestCase3 extends InputTestCase2 {
+
+}
+
+/*
+ * NO. This is not a dartdoc comment and should not be picked up.
+ * The output of this comment should be nothing.
+ */
+/// @docsEditable
+class InputTestCase4 {
+
+}
+
+/**
+ * NO. This multi-line dartdoc comment doesn't have the /// @docsEditable stuff.
+ * This comment should not show up in the JSON.
+ * Note that the /// @docsEditable in this line and the one above are ignored.
+ */
+class InputTestCase5 {
+
+}
+
+/// NO. This is a single line dartdoc comment that is ignored.
+class InputTestCase6 {
+
+}
+
+/// NO. This is a multi-line dartdoc comment that is ignored.
+/// It is made of multiple single line dartdoc comments.
+class InputTestCase7 {
+
+ /**
+ * YES. This is a multi-line comment on a member.
+ */
+ /// @docsEditable
+ var InputTestCase8;
+
+ /// YES. This is a single line dartdoc comment on a member.
+ /// @docsEditable
+ var InputTestCase9;
+
+ /// YES. This is a multi-line dartdoc comment on a member.
+ /// It is split over two lines.
+ /// @docsEditable
+ var InputTestCase10;
+
+ /**
+ * NO.This multi-line comment on a member is ignored.
+ */
+ var InputTestCase11;
+
+ /// NO. This single line dartdoc comment on a member is ignored.
+ var InputTestCase12;
+}
diff --git a/tools/html_json_doc/test/test_data/html_to_json/test_html_input2.dart b/tools/html_json_doc/test/test_data/html_to_json/test_html_input2.dart
new file mode 100644
index 0000000..1f9615b
--- /dev/null
+++ b/tools/html_json_doc/test/test_data/html_to_json/test_html_input2.dart
@@ -0,0 +1,79 @@
+/**
+ * This is a library level dartdoc comment.
+ * This should be ignored.
+ */
+library testInput2;
+
+/**
+ * This is a multi-line dartdoc comment.
+ * This is one line.
+ * And it keeps going to this line, too.
+ */
+/// @docsEditable
+class InputTestCase1 {
+
+}
+
+/// This is a single line dartdoc comment.
+/// @docsEditable
+class InputTestCase2 extends InputTestCase1 {
+
+}
+
+/// This is a multi-line dartdoc comment.
+/// It happens to use multiple single line dartdoc comments.
+/// @docsEditable
+class InputTestCase3 extends InputTestCase2 {
+
+}
+
+/*
+ * This is not a dartdoc comment and should not be picked up.
+ * The output of this comment should be nothing.
+ */
+/// @docsEditable
+class InputTestCase4 {
+
+}
+
+/**
+ * This multi-line dartdoc comment doesn't have the /// @docsEditable stuff.
+ * This comment should not show up in the JSON.
+ * Note that the /// @docsEditable in this line and the one above are ignored.
+ */
+class InputTestCase5 {
+
+}
+
+/// This is a single line dartdoc comment that is ignored.
+class InputTestCase6 {
+
+}
+
+/// This is a multi-line dartdoc comment that is ignored.
+/// It is made of multiple single line dartdoc comments.
+class InputTestCase7 {
+
+ /**
+ * This is a multi-line comment on a member.
+ */
+ /// @docsEditable
+ var InputTestCase8;
+
+ /// This is a single line dartdoc comment on a member.
+ /// @docsEditable
+ var InputTestCase9;
+
+ /// This is a multi-line dartdoc comment on a member.
+ /// It is split over two lines.
+ /// @docsEditable
+ var InputTestCase10;
+
+ /**
+ * This multi-line comment on a member is ignored.
+ */
+ var InputTestCase11;
+
+ /// This single line dartdoc comment on a member is ignored.
+ var InputTestCase12;
+}
diff --git a/tools/html_json_doc/test/test_data/json_to_html/test_html_input.dart b/tools/html_json_doc/test/test_data/json_to_html/test_html_input.dart
new file mode 100644
index 0000000..70b6041
--- /dev/null
+++ b/tools/html_json_doc/test/test_data/json_to_html/test_html_input.dart
@@ -0,0 +1,62 @@
+/// @docsEditable
+library testInput;
+
+/// @docsEditable
+class InputTestCase1 {
+
+}
+
+/// @docsEditable
+class InputTestCase2 extends InputTestCase1 {
+
+}
+
+/// @docsEditable
+class InputTestCase3 extends InputTestCase2 {
+
+}
+
+/*
+ * NO. This is not a dartdoc comment and should not be picked up.
+ * The output of this comment should be nothing.
+ */
+/// @docsEditable
+class InputTestCase4 {
+
+}
+
+/**
+ * NO. This multi-line dartdoc comment doesn't have the /// @docsEditable stuff.
+ * This comment should not show up in the JSON.
+ * Note that the /// @docsEditable in this line and the one above are ignored.
+ */
+class InputTestCase5 {
+
+}
+
+/// NO. This is a single line dartdoc comment that is ignored.
+class InputTestCase6 {
+
+}
+
+/// NO. This is a multi-line dartdoc comment that is ignored.
+/// It is made of multiple single line dartdoc comments.
+class InputTestCase7 {
+
+ /// @docsEditable
+ var InputTestCase8;
+
+ /// @docsEditable
+ var InputTestCase9;
+
+ /// @docsEditable
+ var InputTestCase10;
+
+ /**
+ * NO.This multi-line comment on a member is ignored.
+ */
+ var InputTestCase11;
+
+ /// NO. This single line dartdoc comment on a member is ignored.
+ var InputTestCase12;
+}
diff --git a/tools/html_json_doc/test/test_data/json_to_html/test_html_input2.dart b/tools/html_json_doc/test/test_data/json_to_html/test_html_input2.dart
new file mode 100644
index 0000000..a6b286d
--- /dev/null
+++ b/tools/html_json_doc/test/test_data/json_to_html/test_html_input2.dart
@@ -0,0 +1,65 @@
+/**
+ * This is a library level dartdoc comment.
+ * This should be ignored.
+ */
+library testInput2;
+
+/// @docsEditable
+class InputTestCase1 {
+
+}
+
+/// @docsEditable
+class InputTestCase2 extends InputTestCase1 {
+
+}
+
+/// @docsEditable
+class InputTestCase3 extends InputTestCase2 {
+
+}
+
+/*
+ * This is not a dartdoc comment and should not be picked up.
+ * The output of this comment should be nothing.
+ */
+/// @docsEditable
+class InputTestCase4 {
+
+}
+
+/**
+ * This multi-line dartdoc comment doesn't have the /// @docsEditable stuff.
+ * This comment should not show up in the JSON.
+ * Note that the /// @docsEditable in this line and the one above are ignored.
+ */
+class InputTestCase5 {
+
+}
+
+/// This is a single line dartdoc comment that is ignored.
+class InputTestCase6 {
+
+}
+
+/// This is a multi-line dartdoc comment that is ignored.
+/// It is made of multiple single line dartdoc comments.
+class InputTestCase7 {
+
+ /// @docsEditable
+ var InputTestCase8;
+
+ /// @docsEditable
+ var InputTestCase9;
+
+ /// @docsEditable
+ var InputTestCase10;
+
+ /**
+ * This multi-line comment on a member is ignored.
+ */
+ var InputTestCase11;
+
+ /// This single line dartdoc comment on a member is ignored.
+ var InputTestCase12;
+}
diff --git a/tools/html_json_doc/test/test_output/html_to_json_test.json b/tools/html_json_doc/test/test_output/html_to_json_test.json
new file mode 100644
index 0000000..8495eed
--- /dev/null
+++ b/tools/html_json_doc/test/test_output/html_to_json_test.json
@@ -0,0 +1,79 @@
+{
+"test_html_input2.dart":
+ {
+ "class InputTestCase1 {":
+ [
+ "/**",
+ " * This is a multi-line dartdoc comment.",
+ " * This is one line.",
+ " * And it keeps going to this line, too.",
+ " */"
+ ],
+ "class InputTestCase2 extends InputTestCase1 {":
+ [
+ "/// This is a single line dartdoc comment."
+ ],
+ "class InputTestCase3 extends InputTestCase2 {":
+ [
+ "/// This is a multi-line dartdoc comment.",
+ "/// It happens to use multiple single line dartdoc comments."
+ ],
+ " var InputTestCase8;":
+ [
+ " /**",
+ " * This is a multi-line comment on a member.",
+ " */"
+ ],
+ " var InputTestCase9;":
+ [
+ " /// This is a single line dartdoc comment on a member."
+ ],
+ " var InputTestCase10;":
+ [
+ " /// This is a multi-line dartdoc comment on a member.",
+ " /// It is split over two lines."
+ ]
+ },
+"test_html_input.dart":
+ {
+ "library testInput;":
+ [
+ "/**",
+ " * YES. This is a library level dartdoc comment.",
+ " * This should show up correctly in the JSON.",
+ " */"
+ ],
+ "class InputTestCase1 {":
+ [
+ "/**",
+ " * YES. This is a multi-line dartdoc comment.",
+ " * This is one line.",
+ " * And it keeps going to this line, too.",
+ " */"
+ ],
+ "class InputTestCase2 extends InputTestCase1 {":
+ [
+ "/// YES. This is a single line dartdoc comment."
+ ],
+ "class InputTestCase3 extends InputTestCase2 {":
+ [
+ "/// YES. This is a multi-line dartdoc comment.",
+ "/// It happens to use multiple single line dartdoc comments."
+ ],
+ " var InputTestCase8;":
+ [
+ " /**",
+ " * YES. This is a multi-line comment on a member.",
+ " */"
+ ],
+ " var InputTestCase9;":
+ [
+ " /// YES. This is a single line dartdoc comment on a member."
+ ],
+ " var InputTestCase10;":
+ [
+ " /// YES. This is a multi-line dartdoc comment on a member.",
+ " /// It is split over two lines."
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tools/html_json_doc/test/test_output/test_html_input.dart b/tools/html_json_doc/test/test_output/test_html_input.dart
new file mode 100644
index 0000000..291d0dd
--- /dev/null
+++ b/tools/html_json_doc/test/test_output/test_html_input.dart
@@ -0,0 +1,80 @@
+/**
+ * YES. This is a library level dartdoc comment.
+ * This should show up correctly in the JSON.
+ */
+/// @docsEditable
+library testInput;
+
+/**
+ * YES. This is a multi-line dartdoc comment.
+ * This is one line.
+ * And it keeps going to this line, too.
+ */
+/// @docsEditable
+class InputTestCase1 {
+
+}
+
+/// YES. This is a single line dartdoc comment.
+/// @docsEditable
+class InputTestCase2 extends InputTestCase1 {
+
+}
+
+/// YES. This is a multi-line dartdoc comment.
+/// It happens to use multiple single line dartdoc comments.
+/// @docsEditable
+class InputTestCase3 extends InputTestCase2 {
+
+}
+
+/*
+ * NO. This is not a dartdoc comment and should not be picked up.
+ * The output of this comment should be nothing.
+ */
+/// @docsEditable
+class InputTestCase4 {
+
+}
+
+/**
+ * NO. This multi-line dartdoc comment doesn't have the /// @docsEditable stuff.
+ * This comment should not show up in the JSON.
+ * Note that the /// @docsEditable in this line and the one above are ignored.
+ */
+class InputTestCase5 {
+
+}
+
+/// NO. This is a single line dartdoc comment that is ignored.
+class InputTestCase6 {
+
+}
+
+/// NO. This is a multi-line dartdoc comment that is ignored.
+/// It is made of multiple single line dartdoc comments.
+class InputTestCase7 {
+
+ /**
+ * YES. This is a multi-line comment on a member.
+ */
+ /// @docsEditable
+ var InputTestCase8;
+
+ /// YES. This is a single line dartdoc comment on a member.
+ /// @docsEditable
+ var InputTestCase9;
+
+ /// YES. This is a multi-line dartdoc comment on a member.
+ /// It is split over two lines.
+ /// @docsEditable
+ var InputTestCase10;
+
+ /**
+ * NO.This multi-line comment on a member is ignored.
+ */
+ var InputTestCase11;
+
+ /// NO. This single line dartdoc comment on a member is ignored.
+ var InputTestCase12;
+}
diff --git a/tools/html_json_doc/test/test_output/test_html_input2.dart b/tools/html_json_doc/test/test_output/test_html_input2.dart
new file mode 100644
index 0000000..1f9615b
--- /dev/null
+++ b/tools/html_json_doc/test/test_output/test_html_input2.dart
@@ -0,0 +1,79 @@
+/**
+ * This is a library level dartdoc comment.
+ * This should be ignored.
+ */
+library testInput2;
+
+/**
+ * This is a multi-line dartdoc comment.
+ * This is one line.
+ * And it keeps going to this line, too.
+ */
+/// @docsEditable
+class InputTestCase1 {
+
+}
+
+/// This is a single line dartdoc comment.
+/// @docsEditable
+class InputTestCase2 extends InputTestCase1 {
+
+}
+
+/// This is a multi-line dartdoc comment.
+/// It happens to use multiple single line dartdoc comments.
+/// @docsEditable
+class InputTestCase3 extends InputTestCase2 {
+
+}
+
+/*
+ * This is not a dartdoc comment and should not be picked up.
+ * The output of this comment should be nothing.
+ */
+/// @docsEditable
+class InputTestCase4 {
+
+}
+
+/**
+ * This multi-line dartdoc comment doesn't have the /// @docsEditable stuff.
+ * This comment should not show up in the JSON.
+ * Note that the /// @docsEditable in this line and the one above are ignored.
+ */
+class InputTestCase5 {
+
+}
+
+/// This is a single line dartdoc comment that is ignored.
+class InputTestCase6 {
+
+}
+
+/// This is a multi-line dartdoc comment that is ignored.
+/// It is made of multiple single line dartdoc comments.
+class InputTestCase7 {
+
+ /**
+ * This is a multi-line comment on a member.
+ */
+ /// @docsEditable
+ var InputTestCase8;
+
+ /// This is a single line dartdoc comment on a member.
+ /// @docsEditable
+ var InputTestCase9;
+
+ /// This is a multi-line dartdoc comment on a member.
+ /// It is split over two lines.
+ /// @docsEditable
+ var InputTestCase10;
+
+ /**
+ * This multi-line comment on a member is ignored.
+ */
+ var InputTestCase11;
+
+ /// This single line dartdoc comment on a member is ignored.
+ var InputTestCase12;
+}
diff --git a/tools/make_links.py b/tools/make_links.py
index 3f54004..e47d02f 100644
--- a/tools/make_links.py
+++ b/tools/make_links.py
@@ -50,12 +50,14 @@
def main(argv):
target = os.path.relpath(argv[1])
+ if not os.path.exists(target):
+ os.makedirs(target)
for source in argv[2:]:
- # Assume the source directory is named ".../TARGET_NAME/lib".
+ # Assume the source directory is named ".../NAME/lib".
(name, lib) = os.path.split(source)
if lib != 'lib':
name = source
- # Remove any addtional path components preceding TARGET_NAME.
+ # Remove any addtional path components preceding NAME.
(path, name) = os.path.split(name)
if utils.GuessOS() == 'win32':
source = os.path.relpath(source)
diff --git a/tools/publish_pkg.py b/tools/publish_pkg.py
new file mode 100755
index 0000000..91ac8db
--- /dev/null
+++ b/tools/publish_pkg.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+# Script to push a package to pub.
+#
+# Usage: publish_pkg.py pkg_dir
+#
+# "pub" must be in PATH.
+
+
+import os
+import os.path
+import re
+import shutil
+import sys
+import subprocess
+import tempfile
+
+def ReplaceInFiles(paths, subs):
+ '''Reads a series of files, applies a series of substitutions to each, and
+ saves them back out. subs should be a list of (pattern, replace) tuples.'''
+ for path in paths:
+ contents = open(path).read()
+ for pattern, replace in subs:
+ contents = re.sub(pattern, replace, contents)
+
+ dest = open(path, 'w')
+ dest.write(contents)
+ dest.close()
+
+
+def ReadVersion(file, field):
+ for line in open(file).read().split('\n'):
+ [k, v] = re.split('\s+', line)
+ if field == k:
+ return int(v)
+
+def Main(argv):
+ HOME = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+
+ versionFile = os.path.join(HOME, 'tools', 'VERSION')
+ major = ReadVersion(versionFile, 'MAJOR')
+ minor = ReadVersion(versionFile, 'MINOR')
+ build = ReadVersion(versionFile, 'BUILD')
+ patch = ReadVersion(versionFile, 'PATCH')
+
+ # bleeding_edge has a fixed version number of 0.1.x.y . Don't allow users
+ # to publish packages from bleeding_edge.
+ if major == 0 and minor <= 1:
+ print 'Error: Do not run this script from a bleeding_edge checkout.'
+ return -1
+
+ version = '%d.%d.%d+%d' % (major, minor, build, patch)
+
+ tmpDir = tempfile.mkdtemp()
+ pkgName = argv[1].split('/').pop()
+
+ pubspec = os.path.join(tmpDir, pkgName, 'pubspec.yaml')
+
+ if os.path.exists(os.path.join(HOME, argv[1], 'pubspec.yaml')):
+ #
+ # If pubspec.yaml exists, add the SDK's version number if
+ # no version number is present.
+ #
+ shutil.copytree(os.path.join(HOME, argv[1]),
+ os.path.join(tmpDir, pkgName))
+ with open(pubspec) as pubspecFile:
+ lines = pubspecFile.readlines()
+ with open(pubspec, 'w') as pubspecFile:
+ foundVersion = False
+ inDependencies = False
+ for line in lines:
+ if line.startswith('dependencies:'):
+ inDependencies = True
+ elif line[0].isalpha():
+ inDependencies = False
+ if line.startswith('version:'):
+ foundVersion = True
+ if inDependencies:
+ #
+ # Within dependencies, don't print line that start with " sdk:"
+ # and strip out "{ sdk: package_name }".
+ #
+ if not line.startswith(' sdk:'):
+ line = re.sub(r'{(\s*)sdk:(\s+)([a-z0-9_]+)(\s*)}', '', line)
+ pubspecFile.write(line)
+ else:
+ pubspecFile.write(line)
+ if not foundVersion:
+ pubspecFile.write('\nversion: ' + version + '\n')
+ else:
+ #
+ # If there's a lib/ directory in the package, copy the package.
+ # Otherwise, move the package's contents to lib/.
+ #
+ if os.path.exists(os.path.join(HOME, argv[1], 'lib')):
+ shutil.copytree(os.path.join(HOME, argv[1]),
+ os.path.join(tmpDir, pkgName))
+ else:
+ os.makedirs(os.path.join(tmpDir, pkgName))
+ shutil.copytree(os.path.join(HOME, argv[1]),
+ os.path.join(tmpDir, pkgName, 'lib'))
+
+ # Create pubspec.yaml .
+ with open(pubspec, 'w') as pubspecFile:
+ pubspecFile.write('name: ' + pkgName + '_unsupported\n')
+ pubspecFile.write('version: ' + version + '\n')
+ pubspecFile.write("description: >\n")
+ pubspecFile.write(' A completely unsupported clone of Dart SDK library\n')
+ pubspecFile.write(' ' + argv[1] + ' . This package will change in\n')
+ pubspecFile.write(' unpredictable/incompatible ways without warning.\n')
+ pubspecFile.write('dependencies:\n')
+
+ # Replace '../*/pkg' imports and parts.
+ for root, dirs, files in os.walk(os.path.join(tmpDir, pkgName)):
+ for name in files:
+ if name.endswith('.dart'):
+ ReplaceInFiles([os.path.join(root, name)],
+ [(r'(import|part)(\s+)(\'|")(\.\./)+pkg/', r'\1\2\3package:')])
+
+ print 'publishing version ' + version + ' of ' + argv[1] + ' to pub.\n'
+ subprocess.call(['pub', 'publish'], cwd=os.path.join(tmpDir, pkgName))
+ shutil.rmtree(tmpDir)
+
+if __name__ == '__main__':
+ sys.exit(Main(sys.argv))
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 0adda23..9c6de09 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -35,7 +35,8 @@
const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk', '--checked']];
void main() {
- File scriptFile = new File(new Options().script);
+ Options options = new Options();
+ File scriptFile = new File(options.script);
Path scriptPath =
new Path.fromNative(scriptFile.fullPathSync())
.directoryPath.directoryPath.directoryPath.append('test.dart');
@@ -46,6 +47,7 @@
for (var commandLine in COMMAND_LINES) {
List arguments = <String>[];
arguments.addAll(COMMON_ARGUMENTS);
+ arguments.addAll(options.arguments);
arguments.addAll(commandLine);
arguments.add('co19');
configurations.addAll(optionsParser.parse(arguments));
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 8a3a2a6..fc9adac 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -12,7 +12,7 @@
List<String> defaultTestSelectors =
const ['dartc', 'samples', 'standalone', 'corelib', 'co19', 'language',
'isolate', 'vm', 'html', 'json', 'benchmark_smoke',
- 'utils', 'pub', 'lib', 'pkg'];
+ 'utils', 'lib', 'pkg'];
/**
* Specification of a single test option.
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 30f5259..4c7498d 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -785,8 +785,13 @@
void processExitHandler(int returnCode) {
commandCompleteHandler(command, returnCode);
}
-
- Future processFuture = Process.start(command.executable, command.arguments);
+ ProcessOptions options = new ProcessOptions();
+ options.environment = new Map<String, String>.from(Platform.environment);
+ options.environment['DART_CONFIGURATION'] =
+ TestUtils.configurationDir(testCase.configuration);
+ Future processFuture = Process.start(command.executable,
+ command.arguments,
+ options);
processFuture.then((Process p) {
process = p;
process.onExit = processExitHandler;
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 4ce2287..841c13a 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -115,7 +115,29 @@
if (configuration['compiler'] == 'none') {
return null; // No separate compiler for dartium tests.
}
- var name = '$buildDir/${compilerName}';
+ var name;
+ switch (configuration['compiler']) {
+ case 'dartc':
+ name = '$buildDir/$executableName';
+ case 'dart2js':
+ case 'dart2dart':
+ var prefix = 'sdk/bin/';
+ String suffix = getExecutableSuffix(configuration['compiler']);
+ if (configuration['host_checked']) {
+ // The script dart2js_developer is not included in the
+ // shipped SDK, that is the script is not installed in
+ // "$buildDir/dart-sdk/bin/"
+ name = '$prefix/dart2js_developer$suffix';
+ } else {
+ if (configuration['use_sdk']) {
+ prefix = '$buildDir/dart-sdk/bin/';
+ }
+ name = '${prefix}dart2js$suffix';
+ }
+ break;
+ default:
+ throw "Unknown compiler for: ${configuration['compiler']}";
+ }
if (!(new File(name)).existsSync() && !configuration['list']) {
throw "Executable '$name' does not exist";
}
@@ -123,21 +145,6 @@
}
/**
- * The name of the compiler for this suite's configuration. Throws an error
- * if the configuration does not use a compiler.
- */
- String get compilerName {
- switch (configuration['compiler']) {
- case 'dartc':
- case 'dart2js':
- case 'dart2dart':
- return executableName;
- default:
- throw "Unknown compiler for: ${configuration['compiler']}";
- }
- }
-
- /**
* The file name of the executable used to run this suite's tests.
*/
String get executableName {
@@ -147,19 +154,6 @@
return 'dart$suffix';
case 'dartc':
return 'analyzer/bin/dart_analyzer$suffix';
- case 'dart2js':
- case 'dart2dart':
- var prefix = '';
- if (configuration['use_sdk']) {
- prefix = 'dart-sdk/bin/';
- }
- if (configuration['host_checked']) {
- // The script dart2js_developer is not in the SDK.
- return 'dart2js_developer$suffix';
- } else {
- return '${prefix}dart2js$suffix';
- }
- break;
default:
throw "Unknown executable for: ${configuration['compiler']}";
}
@@ -695,7 +689,7 @@
args = new List.from(args);
String tempDir = createOutputDirectory(info.filePath, '');
args.add('--out=$tempDir/out.js');
- List<Command> commands = <Command>[new Command(dartShellFileName, args)];
+ List<Command> commands = <Command>[new Command(compilerPath, args)];
if (info.hasCompileError) {
// Do not attempt to run the compiled result. A compilation
// error should be reported by the compilation command.
@@ -712,7 +706,7 @@
String tempDir = createOutputDirectory(info.filePath, '');
compilerArguments.add('--out=$tempDir/out.dart');
List<Command> commands =
- <Command>[new Command(dartShellFileName, compilerArguments)];
+ <Command>[new Command(compilerPath, compilerArguments)];
if (info.hasCompileError) {
// Do not attempt to run the compiled result. A compilation
// error should be reported by the compilation command.
@@ -1028,10 +1022,16 @@
// Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName',
// including any intermediate directories that don't exist.
+ // If the tests are run in checked or minified mode we add that to the
+ // '$compile-$runtime' directory name.
+ var checked = configuration['checked'] ? '-checked' : '';
+ var minified = configuration['minified'] ? '-minified' : '';
+ var dirName = "${configuration['compiler']}-${configuration['runtime']}"
+ "$checked$minified";
var generatedTestPath = Strings.join([
buildDir,
'generated_tests',
- "${configuration['compiler']}-${configuration['runtime']}",
+ dirName,
testUniqueName
], '/');
@@ -1262,6 +1262,10 @@
'More than one "// PackageRoot=" line in test $filePath');
}
packageRoot = match[1];
+ if (packageRoot != 'none') {
+ // PackageRoot=none means that no package-root option should be given.
+ packageRoot = '${filePath.directoryPath.join(new Path(packageRoot))}';
+ }
}
matches = staticCleanRegExp.allMatches(contents);
@@ -1610,9 +1614,13 @@
} else if (system == 'windows') {
outputDir = 'build/';
}
+ return "$outputDir${configurationDir(configuration)}";
+ }
+
+ static String configurationDir(Map configuration) {
var mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
var arch = configuration['arch'].toUpperCase();
- return "$outputDir$mode$arch";
+ return '$mode$arch';
}
}
diff --git a/utils/apidoc/.gitignore b/utils/apidoc/.gitignore
index 7d4ce82..adaa849 100644
--- a/utils/apidoc/.gitignore
+++ b/utils/apidoc/.gitignore
@@ -1,9 +1,22 @@
-/apidoc.Makefile
-/apidoc.xcodeproj
-/api_docs.target.mk
-/api_docs.vcxproj.filters
-/api_docs.vcproj
+/Makefile
+/out
+/runtime
+/xcodebuild
+/*.Makefile
+/*.sln
+/*.target.mk
+/*.vcproj
+/*.vcxproj
+/*.vcxproj.filters
+/*.vcxproj.user
+/*.xcodeproj
/Debug
-/api_docs.vcxproj.user
-/apidoc.sln
+/DebugARM
/DebugIA32
+/DebugSIMARM
+/DebugX64
+/Release
+/ReleaseARM
+/ReleaseIA32
+/ReleaseSIMARM
+/ReleaseX64
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index c029b94..ab17574 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -32,7 +32,7 @@
'<(PRODUCT_DIR)/dart2js',
'<(PRODUCT_DIR)/dart2js.bat',
'<!@(["python", "../../tools/list_files.py", "\\.(css|ico|js|json|png|sh|txt|yaml|py)$", ".", "../../sdk/lib/_internal/dartdoc"])',
- '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../lib", "../../runtime/lib", "../../runtime/bin", "../../sdk/lib/_internal/dartdoc"])',
+ '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../sdk/lib", "../../runtime/lib", "../../runtime/bin"])',
],
'outputs': [
'<(PRODUCT_DIR)/api_docs/index.html',
diff --git a/utils/apidoc/html_diff.dart b/utils/apidoc/html_diff.dart
index cc37f9f..f39cb12 100644
--- a/utils/apidoc/html_diff.dart
+++ b/utils/apidoc/html_diff.dart
@@ -18,8 +18,14 @@
// TODO(amouravski): There is currently magic that looks at dart:* libraries
// rather than the declared library names. This changed due to recent syntax
// changes. We should only need to look at the library 'html'.
-const List<String> HTML_LIBRARY_NAMES = const ['dart:html', 'dart:svg'];
-const List<String> HTML_DECLARED_NAMES = const ['html', 'svg'];
+const List<String> HTML_LIBRARY_NAMES = const [
+ 'dart:html',
+ 'dart:svg',
+ 'dart:web_audio'];
+const List<String> HTML_DECLARED_NAMES = const [
+ 'html',
+ 'svg',
+ 'web_audio'];
/**
* A class for computing a many-to-many mapping between the types and
diff --git a/utils/compiler/.gitignore b/utils/compiler/.gitignore
index a2b2950..cfb192d 100644
--- a/utils/compiler/.gitignore
+++ b/utils/compiler/.gitignore
@@ -1,8 +1,14 @@
-/compiler.Makefile
-/compiler.xcodeproj
-/dart2js.target.mk
+/Makefile
/out
/xcodebuild
+/*.Makefile
+/*.sln
+/*.target.mk
+/*.vcproj
+/*.vcxproj
+/*.vcxproj.filters
+/*.vcxproj.user
+/*.xcodeproj
/Debug
/DebugARM
/DebugIA32
@@ -13,9 +19,3 @@
/ReleaseIA32
/ReleaseSIMARM
/ReleaseX64
-/api_docs.vcxproj
-/dart2js.vcxproj.user
-/dart2js.vcxproj
-/compiler.sln
-/dart2js.vcxproj.filters
-/dart2js.vcproj
diff --git a/utils/compiler/build_helper.dart b/utils/compiler/build_helper.dart
index fa2ec0c..79bfb63 100644
--- a/utils/compiler/build_helper.dart
+++ b/utils/compiler/build_helper.dart
@@ -94,12 +94,12 @@
// Tell the VM to grow the heap more aggressively. This should only
// be necessary temporarily until the VM is better at detecting how
// applications use memory.
- // TODO(ahe): Remove this option.
- options = ' --heap_growth_rate=32$options';
+ // TODO(ahe): Remove this option (http://dartbug.com/6495).
+ options = ' --heap_growth_rate=512$options';
// Tell the VM to don't bother inlining methods. So far it isn't
// paying off but the VM team is working on fixing that.
- // TODO(ahe): Remove this option.
+ // TODO(ahe): Remove this option (http://dartbug.com/6495).
options = ' --no_use_inlining$options';
return [
@@ -143,8 +143,12 @@
if %SCRIPTPATH:~-1%==\ set SCRIPTPATH=%SCRIPTPATH:~0,-1%
set arguments=%*
-set SNAPSHOTNAME=%SCRIPTPATH%dart2js.snapshot
-if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+set SNAPSHOT=
+set SNAPSHOTNAME=%SCRIPTPATH%${pathWin}.snapshot
+if exist %SNAPSHOTNAME% (
+ echo Using snapshot "%SNAPSHOTNAME%" 1>&2
+ set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+)
"%SCRIPTPATH%\dart.exe"$options %SNAPSHOT% "%SCRIPTPATH%$pathWin" %arguments%
'''.replaceAll('\n', '\r\n')];
diff --git a/utils/compiler/compiler.gyp b/utils/compiler/compiler.gyp
index 2dee58f..bcba6cc 100644
--- a/utils/compiler/compiler.gyp
+++ b/utils/compiler/compiler.gyp
@@ -57,10 +57,6 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)',
-
- # TODO(ahe): Remove option when http://dartbug.com/5989 is fixed.
- '--optimization_counter_threshold=-1',
-
# Note: we don't store the snapshot in the location where
# the dart2js script is looking for it. The motivation
# for that is to support an incremental development model
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
new file mode 100644
index 0000000..7563bb1
--- /dev/null
+++ b/utils/pub/command_lish.dart
@@ -0,0 +1,167 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library command_lish;
+
+import 'dart:io';
+import 'dart:json';
+import 'dart:uri';
+
+import '../../pkg/args/lib/args.dart';
+import '../../pkg/http/lib/http.dart' as http;
+import 'pub.dart';
+import 'io.dart';
+import 'git.dart' as git;
+import 'oauth2.dart' as oauth2;
+
+// TODO(nweiz): Make "publish" the primary name for this command. See issue
+// 6949.
+/// Handles the `lish` and `publish` pub commands.
+class LishCommand extends PubCommand {
+ final description = "publish the current package to pub.dartlang.org";
+ final usage = "pub publish [options]";
+ final aliases = const ["lish", "lush"];
+
+ ArgParser get commandParser {
+ var parser = new ArgParser();
+ parser.addOption('server', defaultsTo: 'http://pub.dartlang.org',
+ help: 'The package server to which to upload this package');
+ return parser;
+ }
+
+ /// The URL of the server to which to upload the package.
+ Uri get server => new Uri.fromString(commandOptions['server']);
+
+ Future onRun() {
+ var cloudStorageUrl;
+ return oauth2.withClient(cache, (client) {
+ // TODO(nweiz): Better error-handling. There are a few cases we need to
+ // handle better:
+ //
+ // * The server can tell us we need new credentials (a 401 error). The
+ // oauth2 package should throw an AuthorizationException in this case
+ // (contingent on issue 6813 and 6275). We should have the user
+ // re-authorize the client, then restart the command. We should also do
+ // this in case of an ExpirationException. See issue 6950.
+ //
+ // * Cloud Storage can provide an XML-formatted error. We should report
+ // that error and exit.
+ return Futures.wait([
+ client.get(server.resolve("/packages/versions/new.json")),
+ _filesToPublish.transform((files) {
+ return createTarGz(files, baseDir: entrypoint.root.dir);
+ }).chain(consumeInputStream)
+ ]).chain((results) {
+ var response = results[0];
+ var packageBytes = results[1];
+ var parameters = _parseJson(response);
+
+ var url = _expectField(parameters, 'url', response);
+ if (url is! String) _invalidServerResponse(response);
+ cloudStorageUrl = new Uri.fromString(url);
+ var request = new http.MultipartRequest('POST', cloudStorageUrl);
+
+ var fields = _expectField(parameters, 'fields', response);
+ if (fields is! Map) _invalidServerResponse(response);
+ fields.forEach((key, value) {
+ if (value is! String) _invalidServerResponse(response);
+ request.fields[key] = value;
+ });
+
+ request.followRedirects = false;
+ request.files.add(new http.MultipartFile.fromBytes(
+ 'file', packageBytes, filename: 'package.tar.gz'));
+ return client.send(request);
+ }).chain(http.Response.fromStream).transform((response) {
+ var location = response.headers['location'];
+ if (location == null) throw new PubHttpException(response);
+ return location;
+ }).chain((location) => client.get(location)).transform((response) {
+ var parsed = _parseJson(response);
+ if (parsed['success'] is! Map ||
+ !parsed['success'].containsKey('message') ||
+ parsed['success']['message'] is! String) {
+ _invalidServerResponse(response);
+ }
+ print(parsed['success']['message']);
+ });
+ }).transformException((e) {
+ if (e is PubHttpException) {
+ var url = e.response.request.url;
+ if (url.toString() == cloudStorageUrl.toString()) {
+ // TODO(nweiz): the response may have XML-formatted information about
+ // the error. Try to parse that out once we have an easily-accessible
+ // XML parser.
+ throw 'Failed to upload the package.';
+ } else if (url.origin == server.origin) {
+ var errorMap = _parseJson(e.response);
+ if (errorMap['error'] is! Map ||
+ !errorMap['error'].containsKey('message') ||
+ errorMap['error']['message'] is! String) {
+ _invalidServerResponse(e.response);
+ }
+ throw errorMap['error']['message'];
+ }
+ }
+
+ if (e is! oauth2.ExpirationException) throw e;
+
+ printError("Pub's authorization to upload packages has expired and can't "
+ "be automatically refreshed.");
+ return onRun();
+ });
+ }
+
+ /// Returns a list of files that should be included in the published package.
+ /// If this is a Git repository, this will respect .gitignore; otherwise, it
+ /// will return all non-hidden files.
+ Future<List<String>> get _filesToPublish {
+ var rootDir = entrypoint.root.dir;
+ return Futures.wait([
+ dirExists(join(rootDir, '.git')),
+ git.isInstalled
+ ]).chain((results) {
+ if (results[0] && results[1]) {
+ // List all files that aren't gitignored, including those not checked in
+ // to Git.
+ return git.run(["ls-files", "--cached", "--others"]);
+ }
+
+ return listDir(rootDir, recursive: true).chain((entries) {
+ return Futures.wait(entries.map((entry) {
+ return fileExists(entry).transform((isFile) => isFile ? entry : null);
+ }));
+ });
+ }).transform((files) => files.filter((file) {
+ return file != null && basename(file) != 'packages';
+ }));
+ }
+
+ /// Parses a response body, assuming it's JSON-formatted. Throws a
+ /// user-friendly error if the response body is invalid JSON, or if it's not a
+ /// map.
+ Map _parseJson(http.Response response) {
+ var value;
+ try {
+ value = JSON.parse(response.body);
+ } catch (e) {
+ // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
+ _invalidServerResponse(response);
+ }
+ if (value is! Map) _invalidServerResponse(response);
+ return value;
+ }
+
+ /// Returns the value associated with [key] in [map]. Throws a user-friendly
+ /// error if [map] doens't contain [key].
+ _expectField(Map map, String key, http.Response response) {
+ if (map.containsKey(key)) return map[key];
+ _invalidServerResponse(response);
+ }
+
+ /// Throws an error describing an invalid response from the server.
+ void _invalidServerResponse(http.Response response) {
+ throw 'Invalid server response:\n${response.body}';
+ }
+}
diff --git a/utils/pub/curl_client.dart b/utils/pub/curl_client.dart
index 20a1027..e1afc2d 100644
--- a/utils/pub/curl_client.dart
+++ b/utils/pub/curl_client.dart
@@ -45,7 +45,7 @@
return _waitForHeaders(process, expectBody: request.method != "HEAD");
}).chain((_) => new File(headerFile).readAsLines())
- .transform((lines) => _buildResponse(process, lines));
+ .transform((lines) => _buildResponse(request, process, lines));
});
}
@@ -105,12 +105,17 @@
/// receiving the response headers. [expectBody] indicates that the server is
/// expected to send a response body (which is not the case for HEAD
/// requests).
+ ///
+ /// Curl prints the headers to a file and then prints the body to stdout. So,
+ /// in theory, we could read the headers as soon as we see anything appear
+ /// in stdout. However, that seems to be too early to successfully read the
+ /// file (at least on Mac). Instead, this just waits until the entire process
+ /// has completed.
Future _waitForHeaders(Process process, {bool expectBody}) {
- var exitCompleter = new Completer<int>();
- var exitFuture = exitCompleter.future;
+ var completer = new Completer();
process.onExit = (exitCode) {
if (exitCode == 0) {
- exitCompleter.complete(0);
+ completer.complete(null);
return;
}
@@ -122,7 +127,7 @@
} else {
throw new HttpException(message);
}
- }), exitCompleter);
+ }), completer);
};
// If there's not going to be a response body (e.g. for HEAD requests), curl
@@ -131,38 +136,17 @@
if (!expectBody) {
return Futures.wait([
consumeInputStream(process.stdout),
- exitFuture
+ completer.future
]);
}
- var completer = new Completer();
- resetCallbacks() {
- process.stdout.onData = null;
- process.stdout.onError = null;
- process.stdout.onClosed = null;
- }
- process.stdout.onData = () {
- // TODO(nweiz): If an error happens after the body data starts being
- // received, it should be piped through Response.stream once issue
- // 3657 is fixed.
- exitFuture.handleException((e) => true);
- resetCallbacks();
- completer.complete(null);
- };
- process.stdout.onError = (e) {
- resetCallbacks();
- completer.completeException(e);
- };
- process.stdout.onClosed = () {
- resetCallbacks();
- chainToCompleter(exitFuture, completer);
- };
return completer.future;
}
/// Returns a [http.StreamedResponse] from the response data printed by the
/// `curl` [process]. [lines] are the headers that `curl` wrote to a file.
- http.StreamedResponse _buildResponse(Process process, List<String> lines) {
+ http.StreamedResponse _buildResponse(
+ http.BaseRequest request, Process process, List<String> lines) {
// When curl follows redirects, it prints the redirect headers as well as
// the headers of the final request. Each block is separated by a blank
// line. We just care about the last block. There is one trailing empty
@@ -192,6 +176,7 @@
}
return new http.StreamedResponse(responseStream, status, contentLength,
+ request: request,
headers: headers,
isRedirect: isRedirect,
reasonPhrase: reasonPhrase);
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index 07ea60f..8315acd 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -8,6 +8,8 @@
import 'dart:json';
import 'dart:uri';
+// TODO(nweiz): Make this import better.
+import '../../pkg/http/lib/http.dart' as http;
import 'io.dart';
import 'package.dart';
import 'pubspec.dart';
@@ -37,7 +39,7 @@
var parsed = _parseDescription(description);
var fullUrl = "${parsed.last}/packages/${parsed.first}.json";
- return httpGetString(fullUrl).transform((body) {
+ return httpClient.read(fullUrl).transform((body) {
var doc = JSON.parse(body);
return doc['versions'].map((version) => new Version.parse(version));
}).transformException((ex) {
@@ -54,7 +56,7 @@
var fullUrl = "${parsed.last}/packages/${parsed.first}/versions/"
"${id.version}.yaml";
- return httpGetString(fullUrl).transform((yaml) {
+ return httpClient.read(fullUrl).transform((yaml) {
return new Pubspec.parse(yaml, systemCache.sources);
}).transformException((ex) {
_throwFriendlyError(ex, id, parsed.last);
@@ -75,11 +77,14 @@
// Download and extract the archive to a temp directory.
var tempDir;
- return Futures.wait([httpGet(fullUrl),
- systemCache.createTempDir()]).chain((args) {
+ return Futures.wait([
+ httpClient.send(new http.Request("GET", new Uri.fromString(fullUrl)))
+ .transform((response) => response.stream),
+ systemCache.createTempDir()
+ ]).chain((args) {
tempDir = args[1];
return timeout(extractTarGz(args[0], tempDir), HTTP_TIMEOUT,
- 'Timed out while fetching URL "$fullUrl".');
+ 'fetching URL "$fullUrl"');
}).chain((_) {
// Now that the install has succeeded, move it to the real location in
// the cache. This ensures that we don't leave half-busted ghost
@@ -123,7 +128,7 @@
/// this tries to translate into a more user friendly error message. Always
/// throws an error, either the original one or a better one.
void _throwFriendlyError(ex, package, url) {
- if (ex is PubHttpException && ex.statusCode == 404) {
+ if (ex is PubHttpException && ex.response.statusCode == 404) {
throw 'Could not find package "$package" at $url.';
}
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index ed5dee6..0c6903f 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -11,7 +11,10 @@
import 'dart:isolate';
import 'dart:uri';
+// TODO(nweiz): Make this import better.
+import '../../pkg/http/lib/http.dart' as http;
import 'utils.dart';
+import 'curl_client.dart';
bool _isGitInstalledCache;
@@ -31,13 +34,14 @@
stderr.writeString('\n');
}
+
/**
* Joins a number of path string parts into a single path. Handles
* platform-specific path separators. Parts can be [String], [Directory], or
* [File] objects.
*/
String join(part1, [part2, part3, part4]) {
- final parts = _getPath(part1).replaceAll('\\', '/').split('/');
+ final parts = _sanitizePath(part1).split('/');
for (final part in [part2, part3, part4]) {
if (part == null) continue;
@@ -65,7 +69,7 @@
// TODO(rnystrom): Copied from file_system (so that we don't have to add
// file_system to the SDK). Should unify.
String basename(file) {
- file = _getPath(file).replaceAll('\\', '/');
+ file = _sanitizePath(file);
int lastSlash = file.lastIndexOf('/', file.length);
if (lastSlash == -1) {
@@ -82,7 +86,7 @@
// TODO(nweiz): Copied from file_system (so that we don't have to add
// file_system to the SDK). Should unify.
String dirname(file) {
- file = _getPath(file).replaceAll('\\', '/');
+ file = _sanitizePath(file);
int lastSlash = file.lastIndexOf('/', file.length);
if (lastSlash == -1) {
@@ -92,6 +96,11 @@
}
}
+/// Returns whether or not [entry] is nested somewhere within [dir]. This just
+/// performs a path comparison; it doesn't look at the actual filesystem.
+bool isBeneath(entry, dir) =>
+ _sanitizePath(entry).startsWith('${_sanitizePath(dir)}/');
+
/**
* Asynchronously determines if [path], which can be a [String] file path, a
* [File], or a [Directory] exists on the file system. Returns a [Future] that
@@ -157,8 +166,16 @@
completer.complete(file);
};
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
completeError(error) {
- if (!completer.isComplete) completer.completeException(error);
+ if (!completer.isComplete) completer.completeException(error, stackTrace);
}
stream.onError = completeError;
@@ -228,12 +245,11 @@
/**
* Asynchronously lists the contents of [dir], which can be a [String] directory
* path or a [Directory]. If [recursive] is `true`, lists subdirectory contents
- * (defaults to `false`). If [includeSpecialFiles] is `true`, includes
- * hidden `.DS_Store` files (defaults to `false`, other hidden files may be
- * omitted later).
+ * (defaults to `false`). If [includeHiddenFiles] is `true`, includes files
+ * beginning with `.` (defaults to `false`).
*/
Future<List<String>> listDir(dir,
- [bool recursive = false, bool includeSpecialFiles = false]) {
+ {bool recursive: false, bool includeHiddenFiles: false}) {
final completer = new Completer<List<String>>();
final contents = <String>[];
@@ -246,12 +262,18 @@
if (done) completer.complete(contents);
};
- lister.onError = (error) => completer.completeException(error);
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
+ lister.onError = (error) => completer.completeException(error, stackTrace);
lister.onDir = (file) => contents.add(file);
lister.onFile = (file) {
- if (!includeSpecialFiles) {
- if (basename(file) == '.DS_Store') return;
- }
+ if (!includeHiddenFiles && basename(file).startsWith('.')) return;
contents.add(file);
};
@@ -368,8 +390,60 @@
/// Resolves [path] relative to the location of pub.dart.
String relativeToPub(String path) {
var scriptPath = new File(new Options().script).fullPathSync();
- var scriptDir = new Path.fromNative(scriptPath).directoryPath;
- return scriptDir.append(path).canonicalize().toNativePath();
+
+ // Walk up until we hit the "util(s)" directory. This lets us figure out where
+ // we are if this function is called from pub.dart, or one of the tests,
+ // which also live under "utils", or from the SDK where pub is in "util".
+ var utilDir = new Path.fromNative(scriptPath).directoryPath;
+ while (utilDir.filename != 'utils' && utilDir.filename != 'util') {
+ if (utilDir.filename == '') throw 'Could not find path to pub.';
+ utilDir = utilDir.directoryPath;
+ }
+
+ return utilDir.append('pub').append(path).canonicalize().toNativePath();
+}
+
+/// A StringInputStream reading from stdin.
+final _stringStdin = new StringInputStream(stdin);
+
+/// Returns a single line read from a [StringInputStream]. By default, reads
+/// from stdin.
+///
+/// A [StringInputStream] passed to this should have no callbacks registered.
+Future<String> readLine([StringInputStream stream]) {
+ if (stream == null) stream = _stringStdin;
+ if (stream.closed) return new Future.immediate('');
+ void removeCallbacks() {
+ stream.onClosed = null;
+ stream.onLine = null;
+ stream.onError = null;
+ }
+
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
+ var completer = new Completer();
+ stream.onClosed = () {
+ removeCallbacks();
+ completer.complete('');
+ };
+
+ stream.onLine = () {
+ removeCallbacks();
+ completer.complete(stream.readLine());
+ };
+
+ stream.onError = (e) {
+ removeCallbacks();
+ completer.completeException(e, stackTrace);
+ };
+
+ return completer.future;
}
// TODO(nweiz): make this configurable
@@ -379,106 +453,149 @@
*/
final HTTP_TIMEOUT = 30 * 1000;
-/**
- * Opens an input stream for a HTTP GET request to [uri], which may be a
- * [String] or [Uri].
- *
- * Callers should be sure to use [timeout] to make sure that the HTTP request
- * doesn't last indefinitely
- */
-Future<InputStream> httpGet(uri) {
- // TODO(nweiz): This could return an InputStream synchronously if issue 3657
- // were fixed and errors could be propagated through it. Then we could also
- // automatically attach a timeout to that stream.
- uri = _getUri(uri);
+/// An HTTP client that transforms 40* errors and socket exceptions into more
+/// user-friendly error messages.
+class PubHttpClient extends http.BaseClient {
+ final http.Client _inner;
- var completer = new Completer<InputStream>();
- var client = new HttpClient();
- var connection = client.getUrl(uri);
+ PubHttpClient([http.Client inner])
+ : _inner = inner == null ? new http.Client() : inner;
- connection.onError = (e) {
- // Show a friendly error if the URL couldn't be resolved.
- if (e is SocketIOException &&
- e.osError != null &&
- (e.osError.errorCode == 8 ||
- e.osError.errorCode == -2 ||
- e.osError.errorCode == -5 ||
- e.osError.errorCode == 11004)) {
- e = 'Could not resolve URL "${uri.origin}".';
+ Future<http.StreamedResponse> send(http.BaseRequest request) {
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw null;
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
}
- client.shutdown();
- completer.completeException(e);
- };
+ // TODO(nweiz): Ideally the timeout would extend to reading from the
+ // response input stream, but until issue 3657 is fixed that's not feasible.
+ return timeout(_inner.send(request).chain((streamedResponse) {
+ if (streamedResponse.statusCode < 400) {
+ return new Future.immediate(streamedResponse);
+ }
- connection.onResponse = (response) {
- if (response.statusCode >= 400) {
- client.shutdown();
- completer.completeException(
- new PubHttpException(response.statusCode, response.reasonPhrase));
- return;
- }
-
- completer.complete(response.inputStream);
- };
-
- return completer.future;
+ return http.Response.fromStream(streamedResponse).transform((response) {
+ throw new PubHttpException(response);
+ });
+ }).transformException((e) {
+ if (e is SocketIOException &&
+ e.osError != null &&
+ (e.osError.errorCode == 8 ||
+ e.osError.errorCode == -2 ||
+ e.osError.errorCode == -5 ||
+ e.osError.errorCode == 11004)) {
+ throw 'Could not resolve URL "${request.url.origin}".';
+ }
+ throw e;
+ }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
+ }
}
-/**
- * Opens an input stream for a HTTP GET request to [uri], which may be a
- * [String] or [Uri]. Completes with the result of the request as a String.
- */
-Future<String> httpGetString(uri) {
- var future = httpGet(uri).chain((stream) => consumeInputStream(stream))
- .transform((bytes) => new String.fromCharCodes(bytes));
- return timeout(future, HTTP_TIMEOUT, 'Timed out while fetching URL "$uri".');
-}
+/// The HTTP client to use for all HTTP requests.
+final httpClient = new PubHttpClient();
+
+final curlClient = new PubHttpClient(new CurlClient());
/**
* Takes all input from [source] and writes it to [sink].
*
- * [onClosed] is called when [source] is closed.
+ * Returns a future that completes when [source] is closed.
*/
-void pipeInputToInput(InputStream source, ListInputStream sink,
- [void onClosed()]) {
+Future pipeInputToInput(InputStream source, ListInputStream sink) {
+ var completer = new Completer();
source.onClosed = () {
sink.markEndOfStream();
- if (onClosed != null) onClosed();
+ completer.complete(null);
};
source.onData = () => sink.write(source.read());
// TODO(nweiz): propagate this error to the sink. See issue 3657.
source.onError = (e) { throw e; };
+ return completer.future;
}
/**
* Buffers all input from an InputStream and returns it as a future.
*/
Future<List<int>> consumeInputStream(InputStream stream) {
+ if (stream.closed) return new Future.immediate(<int>[]);
+
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
var completer = new Completer<List<int>>();
var buffer = <int>[];
stream.onClosed = () => completer.complete(buffer);
stream.onData = () => buffer.addAll(stream.read());
- stream.onError = (e) => completer.completeException(e);
+ stream.onError = (e) => completer.completeException(e, stackTrace);
+ return completer.future;
+}
+
+/// Buffers all input from a StringInputStream and returns it as a future.
+Future<String> consumeStringInputStream(StringInputStream stream) {
+ if (stream.closed) return new Future.immediate('');
+
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
+ var completer = new Completer<String>();
+ var buffer = new StringBuffer();
+ stream.onClosed = () => completer.complete(buffer.toString());
+ stream.onData = () => buffer.add(stream.read());
+ stream.onError = (e) => completer.completeException(e, stackTrace);
return completer.future;
}
/// Spawns and runs the process located at [executable], passing in [args].
-/// Returns a [Future] that will complete the results of the process after it
-/// has ended.
+/// Returns a [Future] that will complete with the results of the process after
+/// it has ended.
///
/// The spawned process will inherit its parent's environment variables. If
/// [environment] is provided, that will be used to augment (not replace) the
/// the inherited variables.
-///
-/// If [pipeStdout] and/or [pipeStderr] are set, all output from the
-/// subprocess's output streams are sent to the parent process's output streams.
-/// Output from piped streams won't be available in the result object.
Future<PubProcessResult> runProcess(String executable, List<String> args,
- {workingDir, Map<String, String> environment, bool pipeStdout: false,
- bool pipeStderr: false}) {
- int exitCode;
+ {workingDir, Map<String, String> environment}) {
+ return _doProcess(Process.run, executable, args, workingDir, environment)
+ .transform((result) {
+ // TODO(rnystrom): Remove this and change to returning one string.
+ List<String> toLines(String output) {
+ var lines = output.split(NEWLINE_PATTERN);
+ if (!lines.isEmpty && lines.last == "") lines.removeLast();
+ return lines;
+ }
+ return new PubProcessResult(toLines(result.stdout),
+ toLines(result.stderr),
+ result.exitCode);
+ });
+}
+/// Spawns the process located at [executable], passing in [args]. Returns a
+/// [Future] that will complete with the [Process] once it's been started.
+///
+/// The spawned process will inherit its parent's environment variables. If
+/// [environment] is provided, that will be used to augment (not replace) the
+/// the inherited variables.
+Future<Process> startProcess(String executable, List<String> args,
+ {workingDir, Map<String, String> environment}) =>
+ _doProcess(Process.start, executable, args, workingDir, environment);
+
+/// Calls [fn] with appropriately modified arguments. [fn] should have the same
+/// signature as [Process.start], except that the returned [Future] may have a
+/// type other than [Process].
+Future _doProcess(Function fn, String executable, List<String> args, workingDir,
+ Map<String, String> environment) {
// TODO(rnystrom): Should dart:io just handle this?
// Spawning a process on Windows will not look for the executable in the
// system path. So, if executable looks like it needs that (i.e. it doesn't
@@ -499,39 +616,55 @@
environment.forEach((key, value) => options.environment[key] = value);
}
- var future = Process.run(executable, args, options);
- return future.transform((result) {
- // TODO(rnystrom): Remove this and change to returning one string.
- List<String> toLines(String output) {
- var lines = output.split(NEWLINE_PATTERN);
- if (!lines.isEmpty && lines.last == "") lines.removeLast();
- return lines;
- }
- return new PubProcessResult(toLines(result.stdout),
- toLines(result.stderr),
- result.exitCode);
- });
+ return fn(executable, args, options);
+}
+
+/// Closes [response] while ignoring the body of [request]. Returns a Future
+/// that completes once the response is closed.
+///
+/// Due to issue 6984, it's necessary to drain the request body before closing
+/// the response.
+Future closeHttpResponse(HttpRequest request, HttpResponse response) {
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
+ var completer = new Completer();
+ request.inputStream.onError = (e) =>
+ completer.completeException(e, stackTrace);
+ request.inputStream.onData = request.inputStream.read;
+ request.inputStream.onClosed = () {
+ response.outputStream.close();
+ completer.complete(null);
+ };
+ return completer.future;
}
/**
* Wraps [input] to provide a timeout. If [input] completes before
* [milliseconds] have passed, then the return value completes in the same way.
* However, if [milliseconds] pass before [input] has completed, it completes
- * with a [TimeoutException] with [message].
+ * with a [TimeoutException] with [description] (which should be a fragment
+ * describing the action that timed out).
*
* Note that timing out will not cancel the asynchronous operation behind
* [input].
*/
-Future timeout(Future input, int milliseconds, String message) {
+Future timeout(Future input, int milliseconds, String description) {
var completer = new Completer();
var timer = new Timer(milliseconds, (_) {
if (completer.future.isComplete) return;
- completer.completeException(new TimeoutException(message));
+ completer.completeException(new TimeoutException(
+ 'Timed out while $description.'));
});
input.handleException((e) {
if (completer.future.isComplete) return false;
timer.cancel();
- completer.completeException(e);
+ completer.completeException(e, input.stackTrace);
return true;
});
input.then((value) {
@@ -547,7 +680,7 @@
/// will be deleted.
Future withTempDir(Future fn(String path)) {
var tempDir;
- var future = new Directory('').createTemp().chain((dir) {
+ var future = createTempDir().chain((dir) {
tempDir = dir;
return fn(tempDir.path);
});
@@ -638,7 +771,7 @@
process.stderr.pipe(stderr, close: false);
});
processFuture.handleException((error) {
- completer.completeException(error);
+ completer.completeException(error, processFuture.stackTrace);
return true;
});
@@ -660,6 +793,7 @@
var tempDir;
+ // TODO(rnystrom): Use withTempDir().
return createTempDir().chain((temp) {
// Write the archive to a temp file.
tempDir = temp;
@@ -704,16 +838,76 @@
}).transform((_) => true);
}
+/// Create a .tar.gz archive from a list of entries. Each entry can be a
+/// [String], [Directory], or [File] object. The root of the archive is
+/// considered to be [baseDir], which defaults to the current working directory.
+/// Returns an [InputStream] that will emit the contents of the archive.
+InputStream createTarGz(List contents, {baseDir}) {
+ // TODO(nweiz): Propagate errors to the returned stream (including non-zero
+ // exit codes). See issue 3657.
+ var stream = new ListInputStream();
+
+ if (baseDir == null) baseDir = currentWorkingDir;
+ baseDir = getFullPath(baseDir);
+ contents = contents.map((entry) {
+ entry = getFullPath(entry);
+ if (!isBeneath(entry, baseDir)) {
+ throw 'Entry $entry is not inside $baseDir.';
+ }
+ return new Path.fromNative(entry).relativeTo(new Path.fromNative(baseDir))
+ .toNativePath();
+ });
+
+ if (Platform.operatingSystem != "windows") {
+ var args = ["--create", "--gzip", "--directory", baseDir];
+ args.addAll(contents.map(_getPath));
+ // TODO(nweiz): It's possible that enough command-line arguments will make
+ // the process choke, so at some point we should save the arguments to a
+ // file and pass them in via --files-from for tar and -i@filename for 7zip.
+ startProcess("tar", args).then((process) {
+ pipeInputToInput(process.stdout, stream);
+ process.stderr.pipe(stderr, close: false);
+ });
+ return stream;
+ }
+
+ withTempDir((tempDir) {
+ // Create the tar file.
+ var tarFile = join(tempDir, "intermediate.tar");
+ var args = ["a", "-w$baseDir", tarFile];
+ args.addAll(contents.map((entry) => '-i!"$entry"'));
+
+ // Note: This line of code gets munged by create_sdk.py to be the correct
+ // relative path to 7zip in the SDK.
+ var pathTo7zip = '../../third_party/7zip/7za.exe';
+ var command = relativeToPub(pathTo7zip);
+
+ // We're passing 'baseDir' both as '-w' and setting it as the working
+ // directory explicitly here intentionally. The former ensures that the
+ // files added to the archive have the correct relative path in the archive.
+ // The latter enables relative paths in the "-i" args to be resolved.
+ return runProcess(command, args, workingDir: baseDir).chain((_) {
+ // GZIP it. 7zip doesn't support doing both as a single operation. Send
+ // the output to stdout.
+ args = ["a", "unused", "-tgzip", "-so", tarFile];
+ return startProcess(command, args);
+ }).chain((process) {
+ process.stderr.pipe(stderr, close: false);
+ return pipeInputToInput(process.stdout, stream);
+ });
+ });
+ return stream;
+}
+
/**
* Exception thrown when an HTTP operation fails.
*/
class PubHttpException implements Exception {
- final int statusCode;
- final String reason;
+ final http.Response response;
- const PubHttpException(this.statusCode, this.reason);
+ const PubHttpException(this.response);
- String toString() => 'HTTP error $statusCode: $reason';
+ String toString() => 'HTTP error ${response.statusCode}: ${response.reason}';
}
/**
@@ -752,6 +946,16 @@
throw 'Entry $entry is not a supported type.';
}
+/// Gets the path string for [entry] as in [_getPath], but normalizes
+/// backslashes to forward slashes on Windows.
+String _sanitizePath(entry) {
+ entry = _getPath(entry);
+ if (Platform.operatingSystem == 'windows') {
+ entry = entry.replaceAll('\\', '/');
+ }
+ return entry;
+}
+
/**
* Gets a [Directory] for [entry], which can either already be one, or be a
* [String].
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
new file mode 100644
index 0000000..7cc5c85
--- /dev/null
+++ b/utils/pub/oauth2.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library oauth2;
+
+import 'dart:io';
+import 'dart:uri';
+
+// TODO(nweiz): Make this a "package:" URL, or something nicer than this.
+import '../../pkg/oauth2/lib/oauth2.dart';
+import 'io.dart';
+import 'system_cache.dart';
+import 'utils.dart';
+
+export '../../pkg/oauth2/lib/oauth2.dart';
+
+/// The pub client's OAuth2 identifier.
+final _identifier = '818368855108-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.'
+ 'googleusercontent.com';
+
+/// The pub client's OAuth2 secret. This isn't actually meant to be kept a
+/// secret.
+final _secret = 'SWeqj8seoJW0w7_CpEPFLX0K';
+
+/// The URL to which the user will be directed to authorize the pub client to
+/// get an OAuth2 access token.
+///
+/// `access_type=offline` and `approval_prompt=force` ensures that we always get
+/// a refresh token from the server. See the [Google OAuth2 documentation][].
+///
+/// [Google OAuth2 documentation]: https://developers.google.com/accounts/docs/OAuth2WebServer#offline
+final _authorizationEndpoint = new Uri.fromString(
+ 'https://accounts.google.com/o/oauth2/auth?access_type=offline'
+ '&approval_prompt=force');
+
+/// The URL from which the pub client will request an access token once it's
+/// been authorized by the user.
+final _tokenEndpoint = new Uri.fromString(
+ 'https://accounts.google.com/o/oauth2/token');
+
+/// The OAuth2 scopes that the pub client needs. Currently the client only needs
+/// the user's email so that the server can verify their identity.
+final _scopes = ['https://www.googleapis.com/auth/userinfo.email'];
+
+/// An in-memory cache of the user's OAuth2 credentials. This should always be
+/// the same as the credentials file stored in the system cache.
+Credentials _credentials;
+
+/// Asynchronously passes an OAuth2 [Client] to [fn], and closes the client when
+/// the [Future] returned by [fn] completes.
+///
+/// This takes care of loading and saving the client's credentials, as well as
+/// prompting the user for their authorization.
+Future withClient(SystemCache cache, Future fn(Client client)) {
+ return _getClient(cache).chain((client) {
+ var completer = new Completer();
+ var future = fn(client);
+ future.onComplete((_) {
+ try {
+ client.close();
+ // Be sure to save the credentials even when an error happens. Also be
+ // sure to pipe the exception from `future` to `completer`.
+ chainToCompleter(
+ _saveCredentials(cache, client.credentials).chain((_) => future),
+ completer);
+ } catch (e, stackTrace) {
+ // onComplete will drop exceptions on the floor. We want to ensure that
+ // any programming errors here don't go un-noticed. See issue 4127.
+ completer.completeException(e, stackTrace);
+ }
+ });
+ return completer.future;
+ });
+}
+
+/// Gets a new OAuth2 client. If saved credentials are available, those are
+/// used; otherwise, the user is prompted to authorize the pub client.
+Future<Client> _getClient(SystemCache cache) {
+ return _loadCredentials(cache).chain((credentials) {
+ if (credentials == null) return _authorize();
+ return new Future.immediate(new Client(
+ _identifier, _secret, credentials, httpClient: curlClient));
+ }).chain((client) {
+ return _saveCredentials(cache, client.credentials).transform((_) => client);
+ });
+}
+
+/// Loads the user's OAuth2 credentials from the in-memory cache or the
+/// filesystem if possible. If the credentials can't be loaded for any reason,
+/// the returned [Future] will complete to null.
+Future<Credentials> _loadCredentials(SystemCache cache) {
+ if (_credentials != null) return new Future.immediate(_credentials);
+ return fileExists(_credentialsFile(cache)).chain((credentialsExist) {
+ if (!credentialsExist) return new Future.immediate(null);
+
+ return readTextFile(_credentialsFile(cache)).transform((credentialsJson) {
+ var credentials = new Credentials.fromJson(credentialsJson);
+ if (credentials.isExpired && !credentials.canRefresh) {
+ printError("Pub's authorization to upload packages has expired and "
+ "can't be automatically refreshed.");
+ return null; // null means re-authorize
+ }
+
+ return credentials;
+ });
+ }).transformException((e) {
+ printError('Warning: could not load the saved OAuth2 credentials:'
+ ' $e\n'
+ 'Obtaining new credentials...');
+ return null; // null means re-authorize
+ });
+}
+
+/// Save the user's OAuth2 credentials to the in-memory cache and the
+/// filesystem.
+Future _saveCredentials(SystemCache cache, Credentials credentials) {
+ _credentials = credentials;
+ var credentialsFile = _credentialsFile(cache);
+ return ensureDir(dirname(credentialsFile)).chain((_) =>
+ writeTextFile(credentialsFile, credentials.toJson()));
+}
+
+/// The path to the file in which the user's OAuth2 credentials are stored.
+String _credentialsFile(SystemCache cache) =>
+ join(cache.rootDir, 'credentials.json');
+
+/// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2.
+/// Returns a Future that will complete to a fully-authorized [Client].
+Future<Client> _authorize() {
+ // Allow the tests to inject their own token endpoint URL.
+ var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
+ if (tokenEndpoint != null) {
+ tokenEndpoint = new Uri.fromString(tokenEndpoint);
+ } else {
+ tokenEndpoint = _tokenEndpoint;
+ }
+
+ var grant = new AuthorizationCodeGrant(
+ _identifier,
+ _secret,
+ _authorizationEndpoint,
+ tokenEndpoint,
+ httpClient: curlClient);
+
+ // Spin up a one-shot HTTP server to receive the authorization code from the
+ // Google OAuth2 server via redirect. This server will close itself as soon as
+ // the code is received.
+ var completer = new Completer();
+ var server = new HttpServer();
+ server.addRequestHandler((request) => request.path == "/",
+ (request, response) {
+ chainToCompleter(new Future.immediate(null).chain((_) {
+ print('Authorization received, processing...');
+ var queryString = request.queryString;
+ if (queryString == null) queryString = '';
+ response.statusCode = 302;
+ response.headers.set('location', 'http://pub.dartlang.org/authorized');
+ return Futures.wait([
+ closeHttpResponse(request, response),
+ grant.handleAuthorizationResponse(queryToMap(queryString))
+ ]);
+ }).transform((results) {
+ server.close();
+ return results[1];
+ }), completer);
+ });
+ server.listen('127.0.0.1', 0);
+
+ var authUrl = grant.getAuthorizationUrl(
+ new Uri.fromString('http://localhost:${server.port}'), scopes: _scopes);
+
+ print('Pub needs your authorization to upload packages on your behalf.\n'
+ 'In a web browser, go to $authUrl\n'
+ 'Then click "Allow access".\n\n'
+ 'Waiting for your authorization...');
+
+ return completer.future.transform((client) {
+ print('Successfully authorized.\n');
+ return client;
+ });
+}
\ No newline at end of file
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index 4c2f77e..9bb12ee 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -13,6 +13,7 @@
import 'io.dart';
import 'command_help.dart';
import 'command_install.dart';
+import 'command_lish.dart';
import 'command_update.dart';
import 'command_version.dart';
import 'entrypoint.dart';
@@ -33,12 +34,21 @@
/**
* The commands that Pub understands.
*/
-Map<String, PubCommand> get pubCommands => {
- 'help': new HelpCommand(),
- 'install': new InstallCommand(),
- 'update': new UpdateCommand(),
- 'version': new VersionCommand()
-};
+Map<String, PubCommand> get pubCommands {
+ var commands = {
+ 'help': new HelpCommand(),
+ 'install': new InstallCommand(),
+ 'publish': new LishCommand(),
+ 'update': new UpdateCommand(),
+ 'version': new VersionCommand()
+ };
+ for (var command in commands.values) {
+ for (var alias in command.aliases) {
+ commands[alias] = command;
+ }
+ }
+ return commands;
+}
/**
* The parser for arguments that are global to Pub rather than specific to a
@@ -124,6 +134,8 @@
int length = 0;
var names = <String>[];
for (var command in pubCommands.keys) {
+ // Hide aliases.
+ if (pubCommands[command].aliases.indexOf(command) >= 0) continue;
length = max(length, command.length);
names.add(command);
}
@@ -162,7 +174,11 @@
/// Whether or not this command requires [entrypoint] to be defined. If false,
/// Pub won't look for a pubspec and [entrypoint] will be null when the
/// command runs.
- bool get requiresEntrypoint => true;
+ final requiresEntrypoint = true;
+
+ /// Alternate names for this command. These names won't be used in the
+ /// documentation, but they will work when invoked on the command line.
+ final aliases = const <String>[];
/**
* Override this to define command-specific options. The results will be made
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 4097885..d9932b8 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -9,6 +9,7 @@
import 'dart:crypto';
import 'dart:isolate';
+import 'dart:uri';
/** A pair of values. */
class Pair<E, F> {
@@ -122,11 +123,11 @@
CryptoUtils.bytesToHex(new SHA1().update(source.charCodes).digest());
/**
- * Returns a [Future] that completes in [milliSeconds].
+ * Returns a [Future] that completes in [milliseconds].
*/
-Future sleep(int milliSeconds) {
+Future sleep(int milliseconds) {
var completer = new Completer();
- new Timer(milliSeconds, completer.complete);
+ new Timer(milliseconds, completer.complete);
return completer.future;
}
@@ -134,12 +135,15 @@
/// to [completer].
void chainToCompleter(Future future, Completer completer) {
future.handleException((e) {
- completer.completeException(e);
+ completer.completeException(e, future.stackTrace);
return true;
});
future.then(completer.complete);
}
+// TODO(nweiz): unify the following functions with the utility functions in
+// pkg/http.
+
/// Like [String.split], but only splits on the first occurrence of the pattern.
/// This will always return an array of two elements or fewer.
List<String> split1(String toSplit, String pattern) {
@@ -150,3 +154,49 @@
return [toSplit.substring(0, index),
toSplit.substring(index + pattern.length)];
}
+
+/// Adds additional query parameters to [url], overwriting the original
+/// parameters if a name conflict occurs.
+Uri addQueryParameters(Uri url, Map<String, String> parameters) {
+ var queryMap = queryToMap(url.query);
+ mapAddAll(queryMap, parameters);
+ return url.resolve("?${mapToQuery(queryMap)}");
+}
+
+/// Convert a URL query string (or `application/x-www-form-urlencoded` body)
+/// into a [Map] from parameter names to values.
+Map<String, String> queryToMap(String queryList) {
+ var map = <String>{};
+ for (var pair in queryList.split("&")) {
+ var split = split1(pair, "=");
+ if (split.isEmpty) continue;
+ var key = urlDecode(split[0]);
+ var value = split.length > 1 ? urlDecode(split[1]) : "";
+ map[key] = value;
+ }
+ return map;
+}
+
+/// Convert a [Map] from parameter names to values to a URL query string.
+String mapToQuery(Map<String, String> map) {
+ var pairs = <List<String>>[];
+ map.forEach((key, value) {
+ key = encodeUriComponent(key);
+ value = (value == null || value.isEmpty) ? null : encodeUriComponent(value);
+ pairs.add([key, value]);
+ });
+ return Strings.join(pairs.map((pair) {
+ if (pair[1] == null) return pair[0];
+ return "${pair[0]}=${pair[1]}";
+ }), "&");
+}
+
+/// Add all key/value pairs from [source] to [destination], overwriting any
+/// pre-existing values.
+void mapAddAll(Map destination, Map source) =>
+ source.forEach((key, value) => destination[key] = value);
+
+/// Decodes a URL-encoded string. Unlike [decodeUriComponent], this includes
+/// replacing `+` with ` `.
+String urlDecode(String encoded) =>
+ decodeUriComponent(encoded.replaceAll("+", " "));
diff --git a/utils/pub/version.dart b/utils/pub/version.dart
index b6e8e8f..50174cc 100644
--- a/utils/pub/version.dart
+++ b/utils/pub/version.dart
@@ -197,11 +197,11 @@
* version that is "2.0.0" or greater. Version objects themselves implement
* this to match a specific version.
*/
-interface VersionConstraint default _VersionConstraintFactory {
+abstract class VersionConstraint {
/**
* A [VersionConstraint] that allows no versions: i.e. the empty set.
*/
- VersionConstraint.empty();
+ factory VersionConstraint.empty() => const _EmptyVersion();
/**
* Parses a version constraint. This string is a space-separated series of
@@ -218,7 +218,19 @@
* <=5.1.4
* >2.0.4 <=2.4.6
*/
- VersionConstraint.parse(String text);
+ factory VersionConstraint.parse(String text) {
+ if (text.trim() == '') {
+ throw new FormatException('Cannot parse an empty string.');
+ }
+
+ // Split it into space-separated parts.
+ var constraints = <VersionConstraint>[];
+ for (var part in text.split(' ')) {
+ constraints.add(_parseSingleConstraint(part));
+ }
+
+ return new VersionConstraint.intersection(constraints);
+ }
/**
* Creates a new version constraint that is the intersection of [constraints].
@@ -226,7 +238,14 @@
* constraints is empty, then it returns a VersionConstraint that allows all
* versions.
*/
- VersionConstraint.intersect(Collection<VersionConstraint> constraints);
+ factory VersionConstraint.intersection(
+ Collection<VersionConstraint> constraints) {
+ var constraint = new VersionRange();
+ for (var other in constraints) {
+ constraint = constraint.intersect(other);
+ }
+ return constraint;
+ }
/**
* Returns `true` if this constraint allows no versions.
@@ -243,6 +262,32 @@
* both this and [other].
*/
VersionConstraint intersect(VersionConstraint other);
+
+ static VersionConstraint _parseSingleConstraint(String text) {
+ if (text == 'any') {
+ return new VersionRange();
+ }
+
+ // TODO(rnystrom): Consider other syntaxes for version constraints. This
+ // one is whitespace sensitive (you can't do "< 1.2.3") and "<" is
+ // unfortunately meaningful in YAML, requiring it to be quoted in a
+ // pubspec.
+ // See if it's a comparison operator followed by a version, like ">1.2.3".
+ var match = new RegExp(r"^([<>]=?)?(.*)$").firstMatch(text);
+ if (match != null) {
+ var comparison = match[1];
+ var version = new Version.parse(match[2]);
+ switch (match[1]) {
+ case '<=': return new VersionRange(max: version, includeMax: true);
+ case '<': return new VersionRange(max: version, includeMax: false);
+ case '>=': return new VersionRange(min: version, includeMin: true);
+ case '>': return new VersionRange(min: version, includeMin: false);
+ }
+ }
+
+ // Otherwise, it must be an explicit version.
+ return new Version.parse(text);
+ }
}
/**
@@ -374,56 +419,3 @@
VersionConstraint intersect(VersionConstraint other) => this;
String toString() => '<empty>';
}
-
-class _VersionConstraintFactory {
- factory VersionConstraint.empty() => const _EmptyVersion();
-
- factory VersionConstraint.parse(String text) {
- if (text.trim() == '') {
- throw new FormatException('Cannot parse an empty string.');
- }
-
- // Split it into space-separated parts.
- var constraints = <VersionConstraint>[];
- for (var part in text.split(' ')) {
- constraints.add(parseSingleConstraint(part));
- }
-
- return new VersionConstraint.intersect(constraints);
- }
-
- factory VersionConstraint.intersect(
- Collection<VersionConstraint> constraints) {
- var constraint = new VersionRange();
- for (var other in constraints) {
- constraint = constraint.intersect(other);
- }
- return constraint;
- }
-
- static VersionConstraint parseSingleConstraint(String text) {
- if (text == 'any') {
- return new VersionRange();
- }
-
- // TODO(rnystrom): Consider other syntaxes for version constraints. This
- // one is whitespace sensitive (you can't do "< 1.2.3") and "<" is
- // unfortunately meaningful in YAML, requiring it to be quoted in a
- // pubspec.
- // See if it's a comparison operator followed by a version, like ">1.2.3".
- var match = new RegExp(r"^([<>]=?)?(.*)$").firstMatch(text);
- if (match != null) {
- var comparison = match[1];
- var version = new Version.parse(match[2]);
- switch (match[1]) {
- case '<=': return new VersionRange(max: version, includeMax: true);
- case '<': return new VersionRange(max: version, includeMax: false);
- case '>=': return new VersionRange(min: version, includeMin: true);
- case '>': return new VersionRange(min: version, includeMin: false);
- }
- }
-
- // Otherwise, it must be an explicit version.
- return new Version.parse(text);
- }
-}
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 0b1a46b..e0cf2be 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -557,7 +557,7 @@
*/
VersionConstraint get constraint {
if (_refs.isEmpty) return null;
- return new VersionConstraint.intersect(
+ return new VersionConstraint.intersection(
_refs.values.map((ref) => ref.constraint));
}
diff --git a/utils/pub/yaml/model.dart b/utils/pub/yaml/model.dart
index f709536..2ba1416 100644
--- a/utils/pub/yaml/model.dart
+++ b/utils/pub/yaml/model.dart
@@ -50,7 +50,7 @@
}
/** The abstract class for YAML nodes. */
-class _Node {
+abstract class _Node {
/** Every YAML node has a tag that describes its type. */
_Tag tag;
@@ -66,7 +66,7 @@
int get hashCode => _hashCode([tag, anchor]);
- abstract visit(_Visitor v);
+ visit(_Visitor v);
}
/** A sequence node represents an ordered list of nodes. */
diff --git a/utils/tests/pub/oauth2_test.dart b/utils/tests/pub/oauth2_test.dart
new file mode 100644
index 0000000..e739a96
--- /dev/null
+++ b/utils/tests/pub/oauth2_test.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library oauth2_test;
+
+import 'dart:io';
+import 'dart:json';
+import 'dart:uri';
+
+import 'test_pub.dart';
+import '../../../pkg/http/lib/http.dart' as http;
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../pub/io.dart';
+import '../../pub/utils.dart';
+
+main() {
+ setUp(() => dir(appPath, [libPubspec("test_pkg", "1.0.0")]).scheduleCreate());
+
+ test('with no credentials.json, authenticates and saves credentials.json',
+ () {
+ var server = new ScheduledServer();
+ var pub = startPubLish(server);
+ authorizePub(pub, server);
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ expect(request.headers.value('authorization'),
+ equals('Bearer access token'));
+
+ return closeHttpResponse(request, response);
+ });
+
+ pub.kill();
+
+ credentialsFile(server, 'access token').scheduleValidate();
+
+ run();
+ });
+
+ test('with a pre-existing credentials.json does not authenticate', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ expect(request.headers.value('authorization'),
+ equals('Bearer access token'));
+
+ return closeHttpResponse(request, response);
+ });
+
+ pub.kill();
+
+ run();
+ });
+
+ test('with an expired credentials.json, refreshes and saves the refreshed '
+ 'access token to credentials.json', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token',
+ refreshToken: 'refresh token',
+ expiration: new Date.now().subtract(new Duration(hours: 1)))
+ .scheduleCreate();
+
+ var pub = startPubLish(server);
+
+ server.handle('POST', '/token', (request, response) {
+ return consumeInputStream(request.inputStream).transform((bytes) {
+ var body = new String.fromCharCodes(bytes);
+ expect(body, matches(
+ new RegExp(r'(^|&)refresh_token=refresh%20token(&|$)')));
+
+ response.headers.contentType = new ContentType("application", "json");
+ response.outputStream.writeString(JSON.stringify({
+ "access_token": "new access token",
+ "token_type": "bearer"
+ }));
+ response.outputStream.close();
+ });
+ });
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ expect(request.headers.value('authorization'),
+ equals('Bearer new access token'));
+
+ return closeHttpResponse(request, response);
+ });
+
+ pub.shouldExit();
+
+ credentialsFile(server, 'new access token', refreshToken: 'refresh token')
+ .scheduleValidate();
+
+ run();
+ });
+
+ test('with an expired credentials.json without a refresh token, '
+ 'authenticates again and saves credentials.json', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token',
+ expiration: new Date.now().subtract(new Duration(hours: 1)))
+ .scheduleCreate();
+
+ var pub = startPubLish(server);
+
+ expectLater(pub.nextErrLine(), equals("Pub's authorization to upload "
+ "packages has expired and can't be automatically refreshed."));
+ authorizePub(pub, server, "new access token");
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ expect(request.headers.value('authorization'),
+ equals('Bearer new access token'));
+
+ return closeHttpResponse(request, response);
+ });
+
+ pub.kill();
+
+ credentialsFile(server, 'new access token').scheduleValidate();
+
+ run();
+ });
+
+ test('with a malformed credentials.json, authenticates again and saves '
+ 'credentials.json', () {
+ var server = new ScheduledServer();
+ dir(cachePath, [
+ file('credentials.json', '{bad json')
+ ]).scheduleCreate();
+
+ var pub = startPubLish(server);
+ authorizePub(pub, server, "new access token");
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ expect(request.headers.value('authorization'),
+ equals('Bearer new access token'));
+
+ return closeHttpResponse(request, response);
+ });
+
+ pub.kill();
+
+ credentialsFile(server, 'new access token').scheduleValidate();
+
+ run();
+ });
+}
+
+void authorizePub(ScheduledProcess pub, ScheduledServer server,
+ [String accessToken="access token"]) {
+ expectLater(pub.nextLine(), equals('Pub needs your '
+ 'authorization to upload packages on your behalf.'));
+
+ expectLater(pub.nextLine().chain((line) {
+ var match = new RegExp(r'[?&]redirect_uri=([0-9a-zA-Z%+-]+)[$&]')
+ .firstMatch(line);
+ expect(match, isNotNull);
+
+ var redirectUrl = new Uri.fromString(decodeUriComponent(match.group(1)));
+ redirectUrl = addQueryParameters(redirectUrl, {'code': 'access code'});
+ return (new http.Request('GET', redirectUrl)..followRedirects = false)
+ .send();
+ }).transform((response) {
+ expect(response.headers['location'],
+ equals(['http://pub.dartlang.org/authorized']));
+ }), anything);
+
+ handleAccessTokenRequest(server, accessToken);
+}
+
+void handleAccessTokenRequest(ScheduledServer server, String accessToken) {
+ server.handle('POST', '/token', (request, response) {
+ return consumeInputStream(request.inputStream).transform((bytes) {
+ var body = new String.fromCharCodes(bytes);
+ expect(body, matches(new RegExp(r'(^|&)code=access%20code(&|$)')));
+
+ response.headers.contentType = new ContentType("application", "json");
+ response.outputStream.writeString(JSON.stringify({
+ "access_token": accessToken,
+ "token_type": "bearer"
+ }));
+ response.outputStream.close();
+ });
+ });
+}
diff --git a/utils/tests/pub/pub.status b/utils/tests/pub/pub.status
index 03af2a0..5197714 100644
--- a/utils/tests/pub/pub.status
+++ b/utils/tests/pub/pub.status
@@ -10,8 +10,11 @@
[ $runtime == drt || $runtime == dartium || $runtime == opera]
*: Skip
-# Git on Windows is embarrassingly slow.
-# TODO(rnystrom): Get them fast enough to reliably not time out (#5271).
+# TODO(nweiz): Figure out why this is failing.
[ $system == windows ]
-install/git/*: Slow, Pass, Timeout
-update/git/*: Slow, Pass, Timeout
+pub_lish_test: Fail
+
+# TODO(nweiz): The "pub lish" and oauth2 tests often fail mysteriously on
+# Windows. See issues 7015 and 7016.
+oauth2_test: Skip
+curl_client_test: Skip
diff --git a/utils/tests/pub/pub_lish_test.dart b/utils/tests/pub/pub_lish_test.dart
new file mode 100644
index 0000000..aa67161
--- /dev/null
+++ b/utils/tests/pub/pub_lish_test.dart
@@ -0,0 +1,326 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_lish_test;
+
+import 'dart:io';
+import 'dart:json';
+
+import 'test_pub.dart';
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../pub/io.dart';
+
+void handleUploadForm(ScheduledServer server, [Map body]) {
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ return server.url.chain((url) {
+ expect(request.headers.value('authorization'),
+ equals('Bearer access token'));
+
+ if (body == null) {
+ body = {
+ 'url': url.resolve('/upload').toString(),
+ 'fields': {
+ 'field1': 'value1',
+ 'field2': 'value2'
+ }
+ };
+ }
+
+ response.headers.contentType = new ContentType("application", "json");
+ response.outputStream.writeString(JSON.stringify(body));
+ return closeHttpResponse(request, response);
+ });
+ });
+}
+
+void handleUpload(ScheduledServer server) {
+ server.handle('POST', '/upload', (request, response) {
+ // TODO(nweiz): Once a multipart/form-data parser in Dart exists, validate
+ // that the request body is correctly formatted. See issue 6952.
+ return server.url.chain((url) {
+ response.statusCode = 302;
+ response.headers.set('location', url.resolve('/create').toString());
+ return closeHttpResponse(request, response);
+ });
+ });
+}
+
+main() {
+ setUp(() => dir(appPath, [libPubspec("test_pkg", "1.0.0")]).scheduleCreate());
+
+ test('archives and uploads a package', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+ handleUpload(server);
+
+ server.handle('GET', '/create', (request, response) {
+ response.outputStream.writeString(JSON.stringify({
+ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
+ }));
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextLine(), equals('Package test_pkg 1.0.0 uploaded!'));
+ pub.shouldExit(0);
+
+ run();
+ });
+
+ // TODO(nweiz): Once a multipart/form-data parser in Dart exists, we should
+ // test that "pub lish" chooses the correct files to publish.
+
+ // TODO(nweiz): Once issue 6813 is fixed, test that OAuth2 authentication
+ // errors cause the client to try re-authenticating.
+
+ test('upload form provides an error', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ response.statusCode = 400;
+ response.outputStream.writeString(JSON.stringify({
+ 'error': {'message': 'your request sucked'}
+ }));
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('your request sucked'));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('upload form provides invalid JSON', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ server.handle('GET', '/packages/versions/new.json', (request, response) {
+ response.outputStream.writeString('{not json');
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals('{not json'));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('upload form is missing url', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ var body = {
+ 'fields': {
+ 'field1': 'value1',
+ 'field2': 'value2'
+ }
+ };
+
+ handleUploadForm(server, body);
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('upload form url is not a string', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ var body = {
+ 'url': 12,
+ 'fields': {
+ 'field1': 'value1',
+ 'field2': 'value2'
+ }
+ };
+
+ handleUploadForm(server, body);
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('upload form is missing fields', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ var body = {'url': 'http://example.com/upload'};
+ handleUploadForm(server, body);
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('upload form fields is not a map', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ var body = {'url': 'http://example.com/upload', 'fields': 12};
+ handleUploadForm(server, body);
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('upload form fields has a non-string value', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+
+ var body = {
+ 'url': 'http://example.com/upload',
+ 'fields': {'field': 12}
+ };
+ handleUploadForm(server, body);
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('cloud storage upload provides an error', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+
+ server.handle('POST', '/upload', (request, response) {
+ // TODO(rnystrom): HTTP requires that you don't start sending a response
+ // until the request has been completely sent, but dart:io doesn't
+ // ensure that (#7044). Workaround it by manually consuming the entire
+ // input stream before we start responding. If we don't do this, curl
+ // will choke on this on Mac and Windows.
+ return consumeInputStream(request.inputStream).transform((_) {
+ response.statusCode = 400;
+ response.headers.contentType = new ContentType('application', 'xml');
+ response.outputStream.writeString('<Error><Message>Your request sucked.'
+ '</Message></Error>');
+ response.outputStream.close();
+ });
+ });
+
+ // TODO(nweiz): This should use the server's error message once the client
+ // can parse the XML.
+ expectLater(pub.nextErrLine(), equals('Failed to upload the package.'));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test("cloud storage upload doesn't redirect", () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+
+ server.handle('POST', '/upload', (request, response) {
+ // don't set the location header
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('Failed to upload the package.'));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('package creation provides an error', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+ handleUpload(server);
+
+ server.handle('GET', '/create', (request, response) {
+ response.statusCode = 400;
+ response.outputStream.writeString(JSON.stringify({
+ 'error': {'message': 'Your package was too boring.'}
+ }));
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('Your package was too boring.'));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('package creation provides invalid JSON', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+ handleUpload(server);
+
+ server.handle('GET', '/create', (request, response) {
+ response.outputStream.writeString('{not json');
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals('{not json'));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('package creation provides a malformed error', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+ handleUpload(server);
+
+ var body = {'error': 'Your package was too boring.'};
+ server.handle('GET', '/create', (request, response) {
+ response.statusCode = 400;
+ response.outputStream.writeString(JSON.stringify(body));
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+
+ test('package creation provides a malformed success', () {
+ var server = new ScheduledServer();
+ credentialsFile(server, 'access token').scheduleCreate();
+ var pub = startPubLish(server);
+ handleUploadForm(server);
+ handleUpload(server);
+
+ var body = {'success': 'Your package was awesome.'};
+ server.handle('GET', '/create', (request, response) {
+ response.outputStream.writeString(JSON.stringify(body));
+ return closeHttpResponse(request, response);
+ });
+
+ expectLater(pub.nextErrLine(), equals('Invalid server response:'));
+ expectLater(pub.nextErrLine(), equals(JSON.stringify(body)));
+ pub.shouldExit(1);
+
+ run();
+ });
+}
diff --git a/utils/tests/pub/pub_test.dart b/utils/tests/pub/pub_test.dart
index bc18d9d..aa5454a 100644
--- a/utils/tests/pub/pub_test.dart
+++ b/utils/tests/pub/pub_test.dart
@@ -22,6 +22,7 @@
Available commands:
help display help information for Pub
install install the current package's dependencies
+ publish publish the current package to pub.dartlang.org
update update the current package's dependencies to the latest versions
version print Pub version
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 3b6a612..ef6cd7f 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -16,6 +16,7 @@
import 'dart:math';
import 'dart:uri';
+import '../../../pkg/oauth2/lib/oauth2.dart' as oauth2;
import '../../../pkg/unittest/lib/unittest.dart';
import '../../lib/file_system.dart' as fs;
import '../../pub/git_source.dart';
@@ -104,7 +105,7 @@
} catch (e) {
response.statusCode = 404;
response.contentLength = 0;
- response.outputStream.close();
+ closeHttpResponse(request, response);
return;
}
@@ -113,14 +114,14 @@
response.statusCode = 200;
response.contentLength = data.length;
response.outputStream.write(data);
- response.outputStream.close();
+ closeHttpResponse(request, response);
});
future.handleException((e) {
print("Exception while handling ${request.uri}: $e");
response.statusCode = 500;
response.reasonPhrase = e.message;
- response.outputStream.close();
+ closeHttpResponse(request, response);
});
};
_server.listen("127.0.0.1", 0);
@@ -364,6 +365,26 @@
]);
}
+/// Describes the file in the system cache that contains the client's OAuth2
+/// credentials. The URL "/token" on [server] will be used as the token
+/// endpoint for refreshing the access token.
+Descriptor credentialsFile(
+ ScheduledServer server,
+ String accessToken,
+ {String refreshToken,
+ Date expiration}) {
+ return async(server.url.transform((url) {
+ return dir(cachePath, [
+ file('credentials.json', new oauth2.Credentials(
+ accessToken,
+ refreshToken,
+ url.resolve('/token'),
+ ['https://www.googleapis.com/auth/userinfo.email'],
+ expiration).toJson())
+ ]);
+ }));
+}
+
/**
* Describes the application directory, containing only a pubspec specifying the
* given [dependencies].
@@ -460,6 +481,10 @@
*/
List<_ScheduledEvent> _scheduledCleanup;
+/// The list of events that are scheduled to run after the test case only if it
+/// failed.
+List<_ScheduledEvent> _scheduledOnException;
+
/**
* Set to true when the current batch of scheduled events should be aborted.
*/
@@ -477,6 +502,8 @@
Future cleanup() {
return _runScheduled(createdSandboxDir, _scheduledCleanup).chain((_) {
_scheduled = null;
+ _scheduledCleanup = null;
+ _scheduledOnException = null;
if (createdSandboxDir != null) return deleteDir(createdSandboxDir);
return new Future.immediate(null);
});
@@ -491,7 +518,15 @@
// If an error occurs during testing, delete the sandbox, throw the error so
// that the test framework sees it, then finally call asyncDone so that the
// test framework knows we're done doing asynchronous stuff.
- cleanup().then((_) => registerException(error, future.stackTrace));
+ var future = _runScheduled(createdSandboxDir, _scheduledOnException)
+ .chain((_) => cleanup());
+ future.handleException((e) {
+ print("Exception while cleaning up: $e");
+ print(future.stackTrace);
+ registerException(error, future.stackTrace);
+ return true;
+ });
+ future.then((_) => registerException(error, future.stackTrace));
return true;
});
@@ -513,36 +548,10 @@
* validates that its results match [output], [error], and [exitCode].
*/
void schedulePub({List<String> args, Pattern output, Pattern error,
- int exitCode: 0}) {
+ Future<Uri> tokenEndpoint, int exitCode: 0}) {
_schedule((sandboxDir) {
- String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
-
- return ensureDir(pathInSandbox(appPath)).chain((_) {
- // Find a Dart executable we can use to spawn. Use the same one that was
- // used to run this script itself.
- var dartBin = new Options().executable;
-
- // If the executable looks like a path, get its full path. That way we
- // can still find it when we spawn it with a different working directory.
- if (dartBin.contains(Platform.pathSeparator)) {
- dartBin = new File(dartBin).fullPathSync();
- }
-
- // Find the main pub entrypoint.
- var pubPath = fs.joinPaths(testDirectory, '../../pub/pub.dart');
-
- var dartArgs =
- ['--enable-type-checks', '--enable-asserts', pubPath, '--trace'];
- dartArgs.addAll(args);
-
- var environment = {
- 'PUB_CACHE': pathInSandbox(cachePath),
- 'DART_SDK': pathInSandbox(sdkPath)
- };
-
- return runProcess(dartBin, dartArgs, workingDir: pathInSandbox(appPath),
- environment: environment);
- }).transform((result) {
+ return _doPub(runProcess, sandboxDir, args, tokenEndpoint)
+ .transform((result) {
var failures = [];
_validateOutput(failures, 'stdout', output, result.stdout);
@@ -578,6 +587,66 @@
run();
}
+/// Starts a Pub process and returns a [ScheduledProcess] that supports
+/// interaction with that process.
+ScheduledProcess startPub({List<String> args}) {
+ var process = _scheduleValue((sandboxDir) =>
+ _doPub(startProcess, sandboxDir, args));
+ return new ScheduledProcess("pub", process);
+}
+
+/// Like [startPub], but runs `pub lish` in particular with [server] used both
+/// as the OAuth2 server (with "/token" as the token endpoint) and as the
+/// package server.
+ScheduledProcess startPubLish(ScheduledServer server, {List<String> args}) {
+ var process = _scheduleValue((sandboxDir) {
+ return server.url.chain((url) {
+ var tokenEndpoint = url.resolve('/token');
+ if (args == null) args = [];
+ args = flatten(['lish', '--server', url.toString(), args]);
+ return _doPub(startProcess, sandboxDir, args, tokenEndpoint);
+ });
+ });
+ return new ScheduledProcess("pub lish", process);
+}
+
+/// Calls [fn] with appropriately modified arguments to run a pub process. [fn]
+/// should have the same signature as [startProcess], except that the returned
+/// [Future] may have a type other than [Process].
+Future _doPub(Function fn, sandboxDir, List<String> args, Uri tokenEndpoint) {
+ String pathInSandbox(path) => join(getFullPath(sandboxDir), path);
+
+ return ensureDir(pathInSandbox(appPath)).chain((_) {
+ // Find a Dart executable we can use to spawn. Use the same one that was
+ // used to run this script itself.
+ var dartBin = new Options().executable;
+
+ // If the executable looks like a path, get its full path. That way we
+ // can still find it when we spawn it with a different working directory.
+ if (dartBin.contains(Platform.pathSeparator)) {
+ dartBin = new File(dartBin).fullPathSync();
+ }
+
+ // Find the main pub entrypoint.
+ var pubPath = fs.joinPaths(testDirectory, '../../pub/pub.dart');
+
+ var dartArgs =
+ ['--enable-type-checks', '--enable-asserts', pubPath, '--trace'];
+ dartArgs.addAll(args);
+
+ var environment = {
+ 'PUB_CACHE': pathInSandbox(cachePath),
+ 'DART_SDK': pathInSandbox(sdkPath)
+ };
+ if (tokenEndpoint != null) {
+ environment['_PUB_TEST_TOKEN_ENDPOINT'] = tokenEndpoint.toString();
+ }
+
+ return fn(dartBin, dartArgs, workingDir: pathInSandbox(appPath),
+ environment: environment);
+ });
+}
+
/**
* Skips the current test if Git is not installed. This validates that the
* current test is running on a buildbot in which case we expect git to be
@@ -598,9 +667,7 @@
});
}
-Future<Directory> _setUpSandbox() {
- return createTempDir();
-}
+Future<Directory> _setUpSandbox() => createTempDir();
Future _runScheduled(Directory parentDir, List<_ScheduledEvent> scheduled) {
if (scheduled == null) return new Future.immediate(null);
@@ -781,6 +848,14 @@
});
}
+ // TODO(nweiz): remove this when issue 4061 is fixed.
+ var stackTrace;
+ try {
+ throw "";
+ } catch (_, localStackTrace) {
+ stackTrace = localStackTrace;
+ }
+
return listDir(dir).chain((files) {
var matches = files.filter((file) => endsWithPattern(file, name));
if (matches.length == 0) {
@@ -803,7 +878,8 @@
for (var failure in failures) {
error.add(" ").add(failure).add("\n");
}
- completer.completeException(new ExpectException(error.toString()));
+ completer.completeException(
+ new ExpectException(error.toString()), stackTrace);
}
for (var match in matches) {
@@ -1019,16 +1095,11 @@
* to by [ref] at the current point in the scheduled test run.
*/
Future<String> revParse(String ref) {
- var completer = new Completer<String>();
- _schedule((parentDir) {
+ return _scheduleValue((parentDir) {
return super.create(parentDir).chain((rootDir) {
return _runGit(['rev-parse', ref], rootDir);
- }).transform((output) {
- completer.complete(output[0]);
- return null;
- });
+ }).transform((output) => output[0]);
});
- return completer.future;
}
/// Schedule a Git command to run in this repository.
@@ -1090,41 +1161,17 @@
* compresses them, and saves the result to [parentDir].
*/
Future<File> create(parentDir) {
+ // TODO(rnystrom): Use withTempDir().
var tempDir;
- return parentDir.createTemp().chain((_tempDir) {
+ return createTempDir().chain((_tempDir) {
tempDir = _tempDir;
return Futures.wait(contents.map((child) => child.create(tempDir)));
- }).chain((_) {
- if (Platform.operatingSystem != "windows") {
- var args = ["--directory", tempDir.path, "--create", "--gzip",
- "--file", join(parentDir, _stringName)];
- args.addAll(contents.map((child) => child.name));
- return runProcess("tar", args);
- } else {
- // Create the tar file.
- var tarFile = join(tempDir, _stringName.replaceAll("tar.gz", "tar"));
- var args = ["a", tarFile];
- args.addAll(contents.map(
- (child) => '-i!"${join(tempDir, child.name)}"'));
-
- // Find 7zip.
- var command = fs.joinPaths(testDirectory,
- '../../../third_party/7zip/7za.exe');
-
- return runProcess(command, args).chain((_) {
- // GZIP it. 7zip doesn't support doing both as a single operation.
- args = ["a", join(parentDir, _stringName), tarFile];
- return runProcess(command, args);
- });
- }
- }).chain((result) {
- if (!result.success) {
- throw "Failed to create tar file $name.\n"
- "STDERR: ${Strings.join(result.stderr, "\n")}";
- }
- return deleteDir(tempDir);
- }).transform((_) {
- return new File(join(parentDir, _stringName));
+ }).chain((createdContents) {
+ return consumeInputStream(createTarGz(createdContents, baseDir: tempDir));
+ }).chain((bytes) {
+ return new File(join(parentDir, _stringName)).writeAsBytes(bytes);
+ }).chain((file) {
+ return deleteDir(tempDir).transform((_) => file);
});
}
@@ -1150,15 +1197,16 @@
var sinkStream = new ListInputStream();
var tempDir;
+ // TODO(rnystrom): Use withTempDir() here.
// TODO(nweiz): propagate any errors to the return value. See issue 3657.
createTempDir().chain((_tempDir) {
tempDir = _tempDir;
return create(tempDir);
}).then((tar) {
var sourceStream = tar.openInputStream();
- pipeInputToInput(sourceStream,
- sinkStream,
- () => tempDir.delete(recursive: true));
+ pipeInputToInput(sourceStream, sinkStream).then((_) {
+ tempDir.delete(recursive: true);
+ });
});
return sinkStream;
}
@@ -1189,6 +1237,240 @@
}
}
+/// A class representing a [Process] that is scheduled to run in the course of
+/// the test. This class allows actions on the process to be scheduled
+/// 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.
+///
+/// If the test fails, this will automatically print out any remaining stdout
+/// and stderr from the process to aid debugging.
+class ScheduledProcess {
+ /// The name of the process. Used for error reporting.
+ final String name;
+
+ /// The process that's scheduled to run.
+ final Future<Process> _process;
+
+ /// A [StringInputStream] wrapping the stdout of the process that's scheduled
+ /// to run.
+ final Future<StringInputStream> _stdout;
+
+ /// A [StringInputStream] wrapping the stderr of the process that's scheduled
+ /// to run.
+ final Future<StringInputStream> _stderr;
+
+ /// The exit code of the process that's scheduled to run. This will naturally
+ /// only complete once the process has terminated.
+ Future<int> get _exitCode => _exitCodeCompleter.future;
+
+ /// The completer for [_exitCode].
+ final Completer<int> _exitCodeCompleter = new Completer();
+
+ /// Whether the user has scheduled the end of this process by calling either
+ /// [shouldExit] or [kill].
+ bool _endScheduled = false;
+
+ /// Whether the process is expected to terminate at this point.
+ bool _endExpected = false;
+
+ /// Wraps a [Process] [Future] in a scheduled process.
+ ScheduledProcess(this.name, Future<Process> process)
+ : _process = process,
+ _stdout = process.transform((p) => new StringInputStream(p.stdout)),
+ _stderr = process.transform((p) => new StringInputStream(p.stderr)) {
+
+ _schedule((_) {
+ if (!_endScheduled) {
+ throw new StateError("Scheduled process $name must have shouldExit() "
+ "or kill() called before the test is run.");
+ }
+
+ return _process.transform((p) {
+ p.onExit = (c) {
+ if (_endExpected) {
+ _exitCodeCompleter.complete(c);
+ return;
+ }
+
+ // Sleep for half a second in case _endExpected is set in the next
+ // scheduled event.
+ sleep(500).then((_) {
+ if (_endExpected) {
+ _exitCodeCompleter.complete(c);
+ return;
+ }
+
+ _printStreams().then((_) {
+ registerException(new ExpectException("Process $name ended "
+ "earlier than scheduled with exit code $c"));
+ });
+ });
+ };
+ });
+ });
+
+ _scheduleOnException((_) {
+ if (!_process.hasValue) return;
+
+ if (!_exitCode.hasValue) {
+ print("\nKilling process $name prematurely.");
+ _endExpected = true;
+ _process.value.kill();
+ }
+
+ return _printStreams();
+ });
+
+ _scheduleCleanup((_) {
+ if (!_process.hasValue) return;
+ // Ensure that the process is dead and we aren't waiting on any IO.
+ var process = _process.value;
+ process.kill();
+ process.stdout.close();
+ process.stderr.close();
+ });
+ }
+
+ /// Reads the next line of stdout from the process.
+ Future<String> nextLine() {
+ return _scheduleValue((_) {
+ return timeout(_stdout.chain(readLine), 5000,
+ "waiting for the next stdout line from process $name");
+ });
+ }
+
+ /// Reads the next line of stderr from the process.
+ Future<String> nextErrLine() {
+ return _scheduleValue((_) {
+ return timeout(_stderr.chain(readLine), 5000,
+ "waiting for the next stderr line from process $name");
+ });
+ }
+
+ /// Writes [line] to the process as stdin.
+ void writeLine(String line) {
+ _schedule((_) => _process.transform((p) => p.stdin.writeString('$line\n')));
+ }
+
+ /// Kills the process, and waits until it's dead.
+ void kill() {
+ _endScheduled = true;
+ _schedule((_) {
+ _endExpected = true;
+ return _process.chain((p) {
+ p.kill();
+ return timeout(_exitCode, 5000, "waiting for process $name to die");
+ });
+ });
+ }
+
+ /// Waits for the process to exit, and verifies that the exit code matches
+ /// [expectedExitCode] (if given).
+ void shouldExit([int expectedExitCode]) {
+ _endScheduled = true;
+ _schedule((_) {
+ _endExpected = true;
+ return timeout(_exitCode, 5000, "waiting for process $name to exit")
+ .transform((exitCode) {
+ if (expectedExitCode != null) {
+ expect(exitCode, equals(expectedExitCode));
+ }
+ });
+ });
+ }
+
+ /// Prints the remaining data in the process's stdout and stderr streams.
+ /// Prints nothing if the straems are empty.
+ Future _printStreams() {
+ Future printStream(String streamName, StringInputStream stream) {
+ return consumeStringInputStream(stream).transform((output) {
+ if (output.isEmpty) return;
+
+ print('\nProcess $name $streamName:');
+ for (var line in output.trim().split("\n")) {
+ print('| $line');
+ }
+ return;
+ });
+ }
+
+ return printStream('stdout', _stdout.value)
+ .chain((_) => printStream('stderr', _stderr.value));
+ }
+}
+
+/// A class representing an [HttpServer] that's scheduled to run in the course
+/// of the test. This class allows the server's request handling to be scheduled
+/// synchronously. All operations on this class are scheduled.
+class ScheduledServer {
+ /// The wrapped server.
+ final Future<HttpServer> _server;
+
+ /// The queue of handlers to run for upcoming requests.
+ final _handlers = new Queue<Future>();
+
+ ScheduledServer._(this._server);
+
+ /// Creates a new server listening on an automatically-allocated port on
+ /// localhost.
+ factory ScheduledServer() {
+ var scheduledServer;
+ scheduledServer = new ScheduledServer._(_scheduleValue((_) {
+ var server = new HttpServer();
+ server.defaultRequestHandler = scheduledServer._awaitHandle;
+ server.listen("127.0.0.1", 0);
+ _scheduleCleanup((_) => server.close());
+ return new Future.immediate(server);
+ }));
+ return scheduledServer;
+ }
+
+ /// The port on which the server is listening.
+ Future<int> get port => _server.transform((s) => s.port);
+
+ /// The base URL of the server, including its port.
+ Future<Uri> get url =>
+ port.transform((p) => new Uri.fromString("http://localhost:$p"));
+
+ /// Assert that the next request has the given [method] and [path], and pass
+ /// it to [handler] to handle. If [handler] returns a [Future], wait until
+ /// it's completed to continue the schedule.
+ void handle(String method, String path,
+ Future handler(HttpRequest request, HttpResponse response)) {
+ var handlerCompleter = new Completer<Function>();
+ _scheduleValue((_) {
+ var requestCompleteCompleter = new Completer();
+ handlerCompleter.complete((request, response) {
+ expect(request.method, equals(method));
+ expect(request.path, equals(path));
+
+ var future = handler(request, response);
+ if (future == null) future = new Future.immediate(null);
+ chainToCompleter(future, requestCompleteCompleter);
+ });
+ return timeout(requestCompleteCompleter.future,
+ 5000, "waiting for $method $path");
+ });
+ _handlers.add(handlerCompleter.future);
+ }
+
+ /// Raises an error complaining of an unexpected request.
+ void _awaitHandle(HttpRequest request, HttpResponse response) {
+ var future = timeout(new Future.immediate(null).chain((_) {
+ var handlerFuture = _handlers.removeFirst();
+ if (handlerFuture == null) {
+ fail('Unexpected ${request.method} request to ${request.path}.');
+ }
+ return handlerFuture;
+ }).transform((handler) {
+ handler(request, response);
+ }), 5000, "waiting for a handler for ${request.method} ${request.path}");
+ expect(future, completes);
+ }
+}
+
/**
* Takes a simple data structure (composed of [Map]s, [List]s, scalar objects,
* and [Future]s) and recursively resolves all the [Future]s contained within.
@@ -1222,11 +1504,43 @@
_scheduled.add(event);
}
-/**
- * Schedules a callback to be called after Pub is run with [runPub], even if it
- * fails.
- */
+/// Like [_schedule], but pipes the return value of [event] to a returned
+/// [Future].
+Future _scheduleValue(_ScheduledEvent event) {
+ var completer = new Completer();
+ _schedule((parentDir) {
+ chainToCompleter(event(parentDir), completer);
+ return completer.future;
+ });
+ return completer.future;
+}
+
+/// Schedules a callback to be called after the test case has completed, even if
+/// it failed.
void _scheduleCleanup(_ScheduledEvent event) {
if (_scheduledCleanup == null) _scheduledCleanup = [];
_scheduledCleanup.add(event);
}
+
+/// Schedules a callback to be called after the test case has completed, but
+/// only if it failed.
+void _scheduleOnException(_ScheduledEvent event) {
+ if (_scheduledOnException == null) _scheduledOnException = [];
+ _scheduledOnException.add(event);
+}
+
+/// Like [expect], but for [Future]s that complete as part of the scheduled
+/// test. This is necessary to ensure that the exception thrown by the
+/// expectation failing is handled by the scheduler.
+///
+/// Note that [matcher] matches against the completed value of [actual], so
+/// calling [completion] is unnecessary.
+void expectLater(Future actual, matcher, {String reason,
+ FailureHandler failureHandler, bool verbose: false}) {
+ _schedule((_) {
+ return actual.transform((value) {
+ expect(value, matcher, reason: reason, failureHandler: failureHandler,
+ verbose: false);
+ });
+ });
+}