Version 0.3.3.0
svn merge -r 17651:17990 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 18009 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@18016 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/compiler/eclipse.workspace/dartc/.gitignore b/compiler/eclipse.workspace/dartc/.gitignore
new file mode 100644
index 0000000..1f57b97
--- /dev/null
+++ b/compiler/eclipse.workspace/dartc/.gitignore
@@ -0,0 +1 @@
+/output
diff --git a/compiler/eclipse.workspace/tests/.gitignore b/compiler/eclipse.workspace/tests/.gitignore
new file mode 100644
index 0000000..4ab5c99
--- /dev/null
+++ b/compiler/eclipse.workspace/tests/.gitignore
@@ -0,0 +1,2 @@
+/output
+/.settings
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index f85ccd5..9a4cbf1 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -372,6 +372,7 @@
}
onError(errorTarget, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getName());
}
+ checkMixinObjectIsSupertype(cls.getMixins());
checkMixinNoConstructors(cls.getMixins());
checkMixinNoSuperInvocations(cls.getMixins());
return classElement;
@@ -490,6 +491,7 @@
}
// check mixins
+ checkMixinObjectIsSupertype(cls.getMixins());
checkMixinNoConstructors(cls.getMixins());
checkMixinNoSuperInvocations(cls.getMixins());
@@ -517,7 +519,27 @@
}
/**
- * Checks that the types of the given mixin type node don't have super invocations.
+ * Checks that the types of the given mixin type nodes se subtypes of Object.
+ */
+ private void checkMixinObjectIsSupertype(List<DartTypeNode> mixins) {
+ for (DartTypeNode mixNode : mixins) {
+ if (mixNode.getType() instanceof InterfaceType) {
+ InterfaceType mixType = (InterfaceType) mixNode.getType();
+ ClassElement mixElement = mixType.getElement();
+ if (!mixElement.getMixins().isEmpty()) {
+ topLevelContext.onError(mixNode, ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS);
+ continue;
+ }
+ if (!Objects.equal(mixElement.getSupertype(), typeProvider.getObjectType())) {
+ topLevelContext.onError(mixNode, ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS);
+ continue;
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks that the types of the given mixin type nodes don't have super invocations.
*/
private void checkMixinNoSuperInvocations(List<DartTypeNode> mixins) {
for (DartTypeNode mixNode : mixins) {
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
index 093334d..1087830 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
@@ -33,6 +33,7 @@
CANNOT_HIDE_IMPORT_PREFIX("Cannot hide import prefix '%s'"),
CANNOT_INIT_STATIC_FIELD_IN_INITIALIZER("Cannot initialize a static field in an initializer list"),
CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR("Cannot use class with constructor as a mixin."),
+ CANNOT_MIXIN_CLASS_WITH_MIXINS("Cannot use class with mixins as a mixin."),
CANNOT_MIXIN_CLASS_WITH_SUPER("Cannot use class with super invocation as a mixin."),
CANNOT_OVERRIDE_INSTANCE_MEMBER("static member cannot override instance member %s of %s"),
CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS(
diff --git a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
index 6f13767..ed9505e 100644
--- a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
@@ -177,10 +177,6 @@
topLevelContext.onError(mixNode, ResolverErrorCode.SUPER_CLASS_IN_WITH);
continue;
}
- if (!Objects.equal(mixType.getElement().getSupertype(), typeProvider.getObjectType())) {
- topLevelContext.onError(mixNode, ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS);
- continue;
- }
seenMixin.add(mixType);
// OK, add
Elements.addMixin(classElement, mixType);
diff --git a/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
index 7467104..f439eef 100644
--- a/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
+++ b/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
@@ -4,6 +4,7 @@
package com.google.dart.compiler.type;
+import com.google.common.collect.Lists;
import com.google.dart.compiler.resolver.ClassElement;
import com.google.dart.compiler.resolver.DynamicElement;
import com.google.dart.compiler.resolver.Element;
@@ -144,7 +145,7 @@
}
@Override
- public Member lookupSubTypeMember(String name) {
- return null;
+ public List<Member> lookupSubTypeMembers(String name) {
+ return Lists.newArrayList();
}
}
diff --git a/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java b/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
index d8a6be2..fb6b481 100644
--- a/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
+++ b/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
@@ -154,7 +154,7 @@
// OK, we know more specific return type
Type tagType = tagTypeElement.getType();
if (tagType != null) {
- return tagType;
+ return Types.makeInferred(tagType, TypeQuality.INFERRED_EXACT);
}
}
// no guess
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceType.java b/compiler/java/com/google/dart/compiler/type/InterfaceType.java
index 99b7c9d..2f76916 100644
--- a/compiler/java/com/google/dart/compiler/type/InterfaceType.java
+++ b/compiler/java/com/google/dart/compiler/type/InterfaceType.java
@@ -35,11 +35,12 @@
void registerSubClass(ClassElement subClass);
void unregisterSubClass(ClassElement subClass);
+
/**
- * @return the unique {@link Member} with given name, defined in one of the subtypes. May be
- * <code>null</code> if not found or not unique.
+ * @return the {@link Member}s with given name, defined in one of the subtypes. May be empty, but
+ * not <code>null</code>.
*/
- Member lookupSubTypeMember(String name);
+ List<Member> lookupSubTypeMembers(String name);
interface Member {
InterfaceType getHolder();
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
index 5bb25bf3..d1dad43 100644
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
+++ b/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
@@ -4,6 +4,7 @@
package com.google.dart.compiler.type;
+import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.dart.compiler.resolver.ClassElement;
import com.google.dart.compiler.resolver.Element;
@@ -255,33 +256,24 @@
}
@Override
- public Member lookupSubTypeMember(String name) {
- Member foundMember = null;
- for (ClassElement subClass : subClasses.keySet()) {
- // find one or more members in subClass elements
- {
- Element element = subClass.lookupLocalElement(name);
- if (element != null) {
- if (foundMember != null) {
- return null;
- }
- foundMember = new MemberImplementation(this, element);
- continue;
- }
- }
- // try to find deeper
- InterfaceType type = subClass.getType();
- if (type != null) {
- Member member = type.lookupSubTypeMember(name);
- if (member != null) {
- if (foundMember != null) {
- return null;
- }
- foundMember = member;
- }
+ public List<Member> lookupSubTypeMembers(String name) {
+ List<Member> members = Lists.newArrayList();
+ fillSubTypeMember(members, name);
+ return members;
+ }
+
+ private void fillSubTypeMember(List<Member> members, String name) {
+ {
+ Member member = lookupMember(name);
+ if (member != null) {
+ members.add(member);
}
}
- // may be found
- return foundMember;
+ for (ClassElement subClass : subClasses.keySet()) {
+ InterfaceType type = subClass.getType();
+ if (type instanceof InterfaceTypeImplementation) {
+ ((InterfaceTypeImplementation)type).fillSubTypeMember(members, name);
+ }
+ }
}
}
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
index b17a4d3..50f0006 100644
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
+++ b/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
@@ -5,6 +5,7 @@
package com.google.dart.compiler.type;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import com.google.dart.compiler.resolver.ClassElement;
import com.google.dart.compiler.resolver.ClassElementUnion;
@@ -105,8 +106,8 @@
}
@Override
- public Member lookupSubTypeMember(String name) {
- return null;
+ public List<Member> lookupSubTypeMembers(String name) {
+ return Lists.newArrayList();
}
public List<InterfaceType> getTypes() {
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index cd9238e..a2d1272 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -656,16 +656,21 @@
member = itype.lookupMember("setter " + methodName);
}
// is "receiver" is inferred, attempt to find member in one of the subtypes
+ boolean hasMemberInSubClasses = false;
if (member == null) {
if (TypeQuality.of(receiver) == TypeQuality.INFERRED && receiver instanceof InterfaceType) {
- member = ((InterfaceType) receiver).lookupSubTypeMember(methodName);
+ List<Member> subMembers = ((InterfaceType) receiver).lookupSubTypeMembers(methodName);
+ hasMemberInSubClasses = !subMembers.isEmpty();
+ if (subMembers.size() == 1) {
+ member = subMembers.get(0);
+ }
}
}
// report problem
if (member == null && problemTarget != null) {
if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(itype)) {
- if (typeChecksForInferredTypes && !isTooGenericInferredType(receiver)
- || !TypeQuality.isInferred(receiver)) {
+ if (typeChecksForInferredTypes && !hasMemberInSubClasses
+ && !isTooGenericInferredType(receiver) || !TypeQuality.isInferred(receiver)) {
ErrorCode code = TypeQuality.isInferred(receiver)
? TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED
: TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED;
@@ -2396,16 +2401,21 @@
}
}
// is "receiver" is inferred, attempt to find member in one of the subtypes
+ boolean hasMemberInSubClasses = false;
if (member == null) {
if (TypeQuality.of(receiver) == TypeQuality.INFERRED && receiver instanceof InterfaceType) {
- member = ((InterfaceType) receiver).lookupSubTypeMember(name);
+ List<Member> subMembers = ((InterfaceType) receiver).lookupSubTypeMembers(name);
+ hasMemberInSubClasses = !subMembers.isEmpty();
+ if (subMembers.size() == 1) {
+ member = subMembers.get(0);
+ }
}
}
// report "not a member"
if (member == null) {
if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(cls)) {
- if (typeChecksForInferredTypes && !isTooGenericInferredType(receiver)
- || !TypeQuality.isInferred(receiver)) {
+ if (typeChecksForInferredTypes && !hasMemberInSubClasses
+ && !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);
@@ -2448,7 +2458,10 @@
{
getterMember = cls.lookupMember(name);
if (getterMember == null && TypeQuality.of(cls) == TypeQuality.INFERRED) {
- getterMember = cls.lookupSubTypeMember(name);
+ List<Member> members = cls.lookupSubTypeMembers(name);
+ if (members.size() == 1) {
+ getterMember = members.get(0);
+ }
}
}
{
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index f058ab1..ebf9907 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -5956,7 +5956,8 @@
" });",
"}",
"");
- assertErrors(result.getErrors(), errEx(TypeErrorCode.NOT_A_MEMBER_OF_INFERRED, 16, 11, 7));
+ // don't report error, because there IS member, we just don't know which one
+ assertErrors(result.getErrors());
}
/**
@@ -6479,5 +6480,15 @@
result.getErrors(),
errEx(TypeErrorCode.NOT_A_MEMBER_OF, 13, 5, 2));
}
+
+ public void test_mixin_disallowMixinApplication_asMixin() throws Exception {
+ AnalyzeLibraryResult result = analyzeLibrary(
+ "// filler filler filler filler filler filler filler filler filler filler",
+ "typedef M = Object with M;",
+ "");
+ assertErrors(
+ result.getErrors(),
+ errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS, 2, 25, 1));
+ }
}
diff --git a/pkg/analyzer-experimental/README b/pkg/analyzer-experimental/README
new file mode 100644
index 0000000..c8db3be
--- /dev/null
+++ b/pkg/analyzer-experimental/README
@@ -0,0 +1,20 @@
+This code is part of an experimental port of the Editor's analysis engine from
+Java to Dart. While we will continue to support the Java version of the analysis
+engine and the services built on it, we also intend to provide the same services
+to Dart-based applications. This is very early code and we expect it to change,
+possibly in significant ways. While we are eager to see other people make use
+of the analysis engine, we also want to be clear, in case you are interested in
+doing so, that the current API's should in no way be considered to be stable.
+
+In particular, this code was automatically translated from the Java
+implementation. The Java implementation that was translated is still under
+development and will continue to change over time. The translator that was used
+is still under development and the output produced by the translator will change
+over time. Therefore, the API presented by this code will change. In addition,
+any edits made to this code will be overwritten the next time we re-generate
+this code.
+
+If you are interested in using this code, despite the disclaimer above,
+fantastic! Please let the editor team know so that we can get a sense of the
+interest in it. Also, feel free to ask questions and make requests for
+additional functionality.
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/bin/analyzer.dart b/pkg/analyzer-experimental/bin/analyzer.dart
index 6ccf8ab..da405db 100644
--- a/pkg/analyzer-experimental/bin/analyzer.dart
+++ b/pkg/analyzer-experimental/bin/analyzer.dart
@@ -36,7 +36,7 @@
*/
Future<AnalysisResult> run(List<String> args) {
- var options = CommandLineOptions.parse(args);
+ var options = new CommandLineOptions.parse(args);
if (options == null) {
return new Future.immediate(new AnalysisResult.forFailure());
}
diff --git a/pkg/analyzer-experimental/lib/options.dart b/pkg/analyzer-experimental/lib/options.dart
index c480a34..b426129 100644
--- a/pkg/analyzer-experimental/lib/options.dart
+++ b/pkg/analyzer-experimental/lib/options.dart
@@ -163,6 +163,10 @@
return args;
}
+ //TODO(pquitslund): replace w/ the following once library skew issues are sorted out
+ //return args.where((arg) => !arg.startsWith('--') ||
+ // _knownFlags.contains(arg.substring(2)));
+
// Filter all unrecognized flags and options.
var filtered = <String>[];
for (var i=0; i < args.length; ++i) {
diff --git a/pkg/http/lib/src/base_request.dart b/pkg/http/lib/src/base_request.dart
index 943f1f6..ffff471 100644
--- a/pkg/http/lib/src/base_request.dart
+++ b/pkg/http/lib/src/base_request.dart
@@ -82,7 +82,7 @@
/// Creates a new HTTP request.
BaseRequest(this.method, this.url)
- : headers = {};
+ : headers = <String, String>{};
/// Finalizes the HTTP request in preparation for it being sent. This freezes
/// all mutable fields and returns a single-subscription [ByteStream] that
diff --git a/pkg/http/lib/src/io_client.dart b/pkg/http/lib/src/io_client.dart
index 1a432d6..47fb1f0 100644
--- a/pkg/http/lib/src/io_client.dart
+++ b/pkg/http/lib/src/io_client.dart
@@ -57,7 +57,9 @@
connection.onResponse = (response) {
var headers = {};
- response.headers.forEach((key, value) => headers[key] = value);
+ response.headers.forEach((key, values) {
+ headers[key] = values.join(',');
+ });
if (completed) return;
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index e1b952e..c61733e 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -38,7 +38,7 @@
var pairs = <List<String>>[];
map.forEach((key, value) =>
pairs.add([encodeUriComponent(key), encodeUriComponent(value)]));
- return Strings.join(pairs.mappedBy((pair) => "${pair[0]}=${pair[1]}"), "&");
+ return Strings.join(pairs.map((pair) => "${pair[0]}=${pair[1]}"), "&");
}
/// Adds all key/value pairs from [source] to [destination], overwriting any
diff --git a/pkg/http/test/client_test.dart b/pkg/http/test/client_test.dart
index e29cef5..fd056c9 100644
--- a/pkg/http/test/client_test.dart
+++ b/pkg/http/test/client_test.dart
@@ -25,6 +25,11 @@
expect(client.send(request).then((response) {
expect(response.request, equals(request));
expect(response.statusCode, equals(200));
+ expect(response.headers['single'], equals('value'));
+ // dart:io internally normalizes outgoing headers so that they never have
+ // multiple headers with the same name, so there's no way to test whether
+ // we handle that case correctly.
+
return response.stream.bytesToString();
}).whenComplete(client.close), completion(parse(equals({
'method': 'POST',
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index 5fc267e..10067d2 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -55,6 +55,7 @@
consumeInputStream(request.inputStream).then((requestBodyBytes) {
response.statusCode = 200;
response.headers.contentType = new ContentType("application", "json");
+ response.headers.set('single', 'value');
var requestBody;
if (requestBodyBytes.isEmpty) {
@@ -138,19 +139,6 @@
}
}
-// TODO(nweiz): remove this once it's built in to unittest (issue 7922).
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
- const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
- const _StateError() : super("StateError");
- bool matches(item, MatchState matchState) => item is StateError;
-}
-
/// A matcher for HttpExceptions.
const isHttpException = const _HttpException();
diff --git a/pkg/intl/lib/intl_standalone.dart b/pkg/intl/lib/intl_standalone.dart
index fc22cf9..e40126f 100644
--- a/pkg/intl/lib/intl_standalone.dart
+++ b/pkg/intl/lib/intl_standalone.dart
@@ -35,12 +35,10 @@
Future<String> findSystemLocale() {
// On *nix systems we expect this is an environment variable, which is the
// easiest thing to check. On a Mac the environment variable may be present
- // so always check it first.
+ // so always check it first. We have no mechanism for this right now on
+ // Windows, so it will just fail.
String baseLocale = _checkEnvironmentVariable();
if (baseLocale != null) return _setLocale(baseLocale);
- if (Platform.operatingSystem == 'windows') {
- return _getWindowsSystemInfo();
- }
if (Platform.operatingSystem == 'macos') {
return _getAppleDefaults();
}
@@ -49,12 +47,6 @@
}
/**
- * Regular expression to match the expected output of systeminfo on
- * Windows. e.g. System Locale:<tab>en_US;English (United States)
- */
-RegExp sysInfoRegex = new RegExp(r"System Locale:\s+((\w\w;)|(\w\w-\w+;))");
-
-/**
* Regular expression to match the expected output of reading the defaults
* database for AppleLanguages on Mac systems.
* e.g. {
@@ -86,15 +78,6 @@
}
/**
- * Run the "systemlocale" command and return the output in a future.
- */
-Future _getWindowsSystemInfo() {
- var p = Process.run('systeminfo', []);
- var myResult = p.then((result) => _checkResult(result, sysInfoRegex));
- return myResult;
-}
-
-/**
* Given [result], find its text and extract the locale from it using
* [regex], and set it as the system locale. If the process didn't run correctly
* then don't set the variable and return a future that completes with null.
diff --git a/pkg/intl/lib/src/http_request_data_reader.dart b/pkg/intl/lib/src/http_request_data_reader.dart
index 6cf14c7..530dce6 100644
--- a/pkg/intl/lib/src/http_request_data_reader.dart
+++ b/pkg/intl/lib/src/http_request_data_reader.dart
@@ -19,12 +19,5 @@
String url;
HTTPRequestDataReader(this.url);
- Future read(String locale) {
- var completer = new Completer();
- var source = '$url$locale.json';
- var request = new HttpRequest.get(
- source,
- (req) => completer.complete(req.responseText));
- return completer.future;
- }
+ Future read(String locale) => HttpRequest.getString('$url$locale.json');
}
diff --git a/pkg/intl/test/date_time_format_http_request_test.dart b/pkg/intl/test/date_time_format_http_request_test.dart
index e74448d..139cf6d 100644
--- a/pkg/intl/test/date_time_format_http_request_test.dart
+++ b/pkg/intl/test/date_time_format_http_request_test.dart
@@ -30,7 +30,7 @@
void runEverything(_) {
// Initialize all locales and wait for them to finish before running tests.
var futures = DateFormat.allLocalesWithSymbols()
- .mappedBy((locale) => initializeDateFormatting(locale, url))
+ .map((locale) => initializeDateFormatting(locale, url))
.toList();
Future.wait(futures).then(expectAsync1((_) {
runDateTests(smallSetOfLocales());
diff --git a/pkg/intl/test/date_time_format_local_test_stub.dart b/pkg/intl/test/date_time_format_local_test_stub.dart
index cd938c8..1b9bfc2 100644
--- a/pkg/intl/test/date_time_format_local_test_stub.dart
+++ b/pkg/intl/test/date_time_format_local_test_stub.dart
@@ -26,7 +26,7 @@
void runEverything(Function getSubset) {
// Initialize all locales and wait for them to finish before running tests.
var futures = DateFormat.allLocalesWithSymbols()
- .mappedBy((locale) => initializeDateFormatting(locale, null))
+ .map((locale) => initializeDateFormatting(locale, null))
.toList();
Future.wait(futures).then((results) => runDateTests(getSubset()));
}
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index 94f9bcf..fce9e6e 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -218,12 +218,12 @@
var date_format = new DateFormat("d");
expect(
date_format.parsePattern("hh:mm:ss")
- .mappedBy((x) => x.pattern)
+ .map((x) => x.pattern)
.toList(),
orderedEquals(["hh",":", "mm",":","ss"]));
expect(
date_format.parsePattern("hh:mm:ss")
- .mappedBy((x) => x.pattern)
+ .map((x) => x.pattern)
.toList(),
orderedEquals(["hh",":", "mm",":","ss"]));
});
diff --git a/pkg/intl/test/find_default_locale_standalone_test.dart b/pkg/intl/test/find_default_locale_standalone_test.dart
index 50167c6..80bb454 100644
--- a/pkg/intl/test/find_default_locale_standalone_test.dart
+++ b/pkg/intl/test/find_default_locale_standalone_test.dart
@@ -7,22 +7,18 @@
import 'package:intl/intl.dart';
import 'package:intl/intl_standalone.dart';
import 'package:unittest/unittest.dart';
+import 'dart:io';
main() {
test("Find system locale standalone", () {
// TODO (alanknight): This only verifies that we found some locale. We
// should find a way to force the system locale before the test is run
// and then verify that it's actually the correct value.
+ // We have no way of getting this reliably for Windows, so it will fail.
Intl.systemLocale = "xx_YY";
var callback = expectAsync1(verifyLocale);
findSystemLocale().then(callback);
});
-
- test("Test windows regex", () {
- expect(sysInfoRegex.hasMatch("System Locale: en-US;blah blah"), isTrue);
- expect(sysInfoRegex.hasMatch("System Locale: ru;sdfadsf"), isTrue);
- expect(sysInfoRegex.hasMatch("System Locale: ru;"), isTrue);
- });
}
verifyLocale(_) {
diff --git a/pkg/oauth2/lib/src/utils.dart b/pkg/oauth2/lib/src/utils.dart
index 85a9f67..bcff589 100644
--- a/pkg/oauth2/lib/src/utils.dart
+++ b/pkg/oauth2/lib/src/utils.dart
@@ -39,7 +39,7 @@
value = (value == null || value.isEmpty) ? null : encodeUriComponent(value);
pairs.add([key, value]);
});
- return Strings.join(pairs.mappedBy((pair) {
+ return Strings.join(pairs.map((pair) {
if (pair[1] == null) return pair[0];
return "${pair[0]}=${pair[1]}";
}), "&");
diff --git a/pkg/oauth2/test/utils.dart b/pkg/oauth2/test/utils.dart
index 2b6c1a7..0935658 100644
--- a/pkg/oauth2/test/utils.dart
+++ b/pkg/oauth2/test/utils.dart
@@ -45,19 +45,6 @@
}
}
-// TODO(nweiz): remove this once it's built in to unittest
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
- const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
- const _StateError() : super("StateError");
- bool matches(item, MatchState matchState) => item is StateError;
-}
-
/// A matcher for AuthorizationExceptions.
const isAuthorizationException = const _AuthorizationException();
diff --git a/pkg/path/lib/path.dart b/pkg/path/lib/path.dart
index 854d4da..3bd2332 100644
--- a/pkg/path/lib/path.dart
+++ b/pkg/path/lib/path.dart
@@ -179,7 +179,7 @@
var message = new StringBuffer();
message.add("$method(");
message.add(args.take(numArgs)
- .mappedBy((arg) => arg == null ? "null" : '"$arg"')
+ .map((arg) => arg == null ? "null" : '"$arg"')
.join(", "));
message.add("): part ${i - 1} was null, but part $i was not.");
throw new ArgumentError(message.toString());
diff --git a/pkg/pkg.status b/pkg/pkg.status
index bc2bd16..e621a2b 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -37,8 +37,8 @@
intl/test/find_default_locale_browser_test: Skip
intl/test/date_time_format_http_request_test: Skip
-[ $runtime == vm && $system == windows ]
-intl/test/find_default_locale_standalone_test: Pass, Fail # Issue 7722
+[ $runtime == vm && $system == windows ]
+intl/test/find_default_locale_standalone_test: Fail # Issue 8110
# Skip http request tests on Dartium while resolving an odd
# error there that causes the tests to timeout.
diff --git a/pkg/serialization/lib/serialization.dart b/pkg/serialization/lib/serialization.dart
index 8a95659..3f2146d 100644
--- a/pkg/serialization/lib/serialization.dart
+++ b/pkg/serialization/lib/serialization.dart
@@ -183,7 +183,7 @@
import 'src/serialization_helpers.dart';
import 'dart:async';
import 'dart:json' as json;
-import 'dart:collection' show Queue;
+import 'dart:collection';
part 'src/reader_writer.dart';
part 'src/serialization_rule.dart';
@@ -311,6 +311,7 @@
// Both these rules apply to lists, so unless otherwise indicated,
// it will always find the first one.
addRule(new ListRuleEssential());
+ addRule(new MapRule());
}
/**
@@ -426,6 +427,7 @@
var meta = new Serialization()
..selfDescribing = false
..addRuleFor(new ListRule())
+ ..addRuleFor(new MapRule())
..addRuleFor(new PrimitiveRule())
..addRuleFor(new ListRuleEssential())
..addRuleFor(basicRule,
@@ -463,4 +465,5 @@
class SerializationException implements Exception {
final String message;
const SerializationException([this.message]);
+ toString() => "SerializationException($message)";
}
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index adbd9ea..d8f1ebe 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -137,9 +137,25 @@
createStateHolder() =>
useMaps ? new _MapWrapper(fields.contents) : new List(fields.length);
- /** Wrap the state if it's passed in as a map. */
- makeIndexableByNumber(state) =>
- (state is Map) ? new _MapWrapper.fromMap(state, fields.contents) : state;
+ /**
+ * Wrap the state if it's passed in as a map, and if the keys are references,
+ * resolve them to the strings we expect. We leave the previous keys in there
+ * as well, as they shouldn't be harmful, and it costs more to remove them.
+ */
+ makeIndexableByNumber(state) {
+ if (!(state is Map)) return state;
+ // TODO(alanknight): This is quite inefficient, and we do it twice per
+ // instance. If the keys are references, we need to turn them into strings
+ // before we can look at indexing them by field position. It's also eager,
+ // but we know our keys are always primitives, so we don't have to worry
+ // about their instances not having been created yet.
+ var newState = new Map();
+ for (var each in state.keys) {
+ var newKey = (each is Reference) ? each.inflated() : each;
+ newState[newKey] = state[each];
+ }
+ return new _MapWrapper.fromMap(newState, fields.contents);
+ }
/**
* Extract the state from [object] using an instanceMirror and the field
@@ -152,12 +168,27 @@
keysAndValues(fields).forEach(
(index, field) {
var value = _value(mirror, field);
+ callback(field.name);
callback(checkForEssentialLists(index, value));
result[index] = value;
});
return _unwrap(result);
}
+ flatten(state, Writer writer) {
+ if (state is List) {
+ keysAndValues(state).forEach((index, value) {
+ state[index] = writer._referenceFor(value);
+ });
+ } else {
+ var newState = new Map();
+ keysAndValues(state).forEach((key, value) {
+ newState[writer._referenceFor(key)] = writer._referenceFor(value);
+ });
+ return newState;
+ }
+ }
+
/**
* If the value is a List, and the field is a constructor field or
* otherwise specially designated, we wrap it in something that indicates
@@ -219,8 +250,12 @@
fields.figureOutFields();
}
+ bool get hasVariableLengthEntries => false;
+
+ int get dataLength => fields.length;
+
/**
- * Extract the value of the field [fieldName] from the object reflected
+ * Extract the value of [field] from the object reflected
* by [mirror].
*/
// TODO(alanknight): The framework should be resilient if there are fields
@@ -498,13 +533,13 @@
List get constructorFields => _constructorFields;
List constructorFieldNames() =>
- constructorFields.mappedBy((x) => x.name).toList();
+ constructorFields.map((x) => x.name).toList();
List constructorFieldIndices() =>
- constructorFields.mappedBy((x) => x.index).toList();
+ constructorFields.map((x) => x.index).toList();
List regularFields() => contents.where((x) => !x.usedInConstructor).toList();
- List regularFieldNames() => regularFields().mappedBy((x) => x.name).toList();
+ List regularFieldNames() => regularFields().map((x) => x.name).toList();
List regularFieldIndices() =>
- regularFields().mappedBy((x) => x.index).toList();
+ regularFields().map((x) => x.index).toList();
/**
* If we weren't given any non-constructor fields to use, figure out what
@@ -514,7 +549,7 @@
*/
void figureOutFields() {
Iterable names(Iterable<DeclarationMirror> mirrors) =>
- mirrors.mappedBy((each) => each.simpleName);
+ mirrors.map((each) => each.simpleName).toList();
if (!_shouldFigureOutFields || !regularFields().isEmpty) return;
var fields = publicFields(mirror);
@@ -528,6 +563,8 @@
addAllNotExplicitlyExcluded(names(gettersWithSetters));
addAllNotExplicitlyExcluded(names(gettersThatMatchConstructor));
}
+
+ toString() => "FieldList($contents)";
}
/**
@@ -569,10 +606,9 @@
*/
constructFrom(state, Reader r) {
// TODO(alanknight): Handle named parameters
- Collection inflated = fieldNumbers.mappedBy(
- (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x))
- .toList();
- var result = type.newInstance(name, inflated);
+ Iterable inflated = fieldNumbers.map(
+ (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x));
+ var result = type.newInstance(name, inflated.toList());
return deprecatedFutureValue(result);
}
}
@@ -582,12 +618,13 @@
* from the index into a field name and then looks it up in the map.
*/
class _MapWrapper {
- Map<String, dynamic> _map = new Map<String, dynamic>();
+ final _map;
List fieldList;
- _MapWrapper(this.fieldList);
+ _MapWrapper(this.fieldList) : _map = new Map();
_MapWrapper.fromMap(this._map, this.fieldList);
operator [](key) => _map[fieldList[key].name];
+
operator []=(key, value) { _map[fieldList[key].name] = value; }
get length => _map.length;
diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart
index 4ab20d4..c1d122e 100644
--- a/pkg/serialization/lib/src/format.dart
+++ b/pkg/serialization/lib/src/format.dart
@@ -95,6 +95,11 @@
*/
final bool storeRoundTripInfo;
+ /**
+ * If we store the rule numbers, what key should we use to store them.
+ */
+ String ruleIdentifier = "__rule";
+
SimpleJsonFormat({this.storeRoundTripInfo : false});
/**
@@ -129,7 +134,7 @@
if (storeRoundTripInfo) ruleData[i].add(rule.number);
} else if (each is Map) {
jsonifyEntry(each, w);
- if (storeRoundTripInfo) each["__rule"] = rule.number;
+ if (storeRoundTripInfo) each[ruleIdentifier] = rule.number;
}
}
}
@@ -156,8 +161,7 @@
var result = {};
result["rules"] = null;
var ruleData =
- new List(r.serialization.rules.length).mappedBy((x) => []).toList();
- var rootRule = data["__rule"];
+ new List(r.serialization.rules.length).map((x) => []).toList();
var top = recursivelyFixUp(data, r, ruleData);
result["data"] = ruleData;
result["roots"] = [top];
@@ -172,12 +176,17 @@
result[r._primitiveRule().number].add(data);
return data;
}
- var ruleNumber =
- (data is List) ? data.removeLast() : data.remove("__rule");
- var newData = values(data).mappedBy(
- (x) => recursivelyFixUp(x, r, result));
+ var ruleNumber;
+ if (data is List) {
+ ruleNumber = data.removeLast();
+ } else if (data is Map) {
+ ruleNumber = data.remove(ruleIdentifier);
+ } else {
+ throw new SerializationException("Invalid data format");
+ }
+ var newData = mapValues(data, (x) => recursivelyFixUp(x, r, result));
result[ruleNumber].add(newData);
- return new Reference(this, ruleNumber, result[ruleNumber].length - 1);
+ return new Reference(r, ruleNumber, result[ruleNumber].length - 1);
}
}
@@ -225,12 +234,14 @@
void writeStateInto(SerializationRule rule, List ruleData, List target) {
if (!ruleData.isEmpty) {
var sample = ruleData.first;
- if (sample is List) {
+ if (rule.storesStateAsLists || sample is List) {
writeLists(rule, ruleData, target);
- } else if (sample is Map) {
+ } else if (rule.storesStateAsMaps || sample is Map) {
writeMaps(rule, ruleData, target);
- } else {
+ } else if (rule.storesStateAsPrimitives || isPrimitive(sample)) {
writeObjects(ruleData, target);
+ } else {
+ throw new SerializationException("Invalid data format");
}
} else {
// If there is no data, write a zero for the length.
@@ -271,13 +282,8 @@
if (rule.hasVariableLengthEntries) {
target.add(eachEntry.length);
}
- // We take advantage of this being only a semi-flat format, and expecting
- // that the keys here are field names, i.e. strings. So we write
- // the keys as literals and the values as references. This duplicates the
- // keys, so is quite inefficient. But generating maps rather than lists is
- // not very efficient in the first place.
eachEntry.forEach((key, value) {
- target.add(key);
+ writeReference(key, target);
writeReference(value, target);
});
}
@@ -289,6 +295,9 @@
*/
writeObjects(List entries, List target) {
target.add(STORED_AS_PRIMITIVE);
+ for (var each in entries) {
+ if (!isPrimitive(each)) throw new SerializationException("Invalid data");
+ }
target.addAll(entries);
}
@@ -312,6 +321,9 @@
* format.
*/
Map<String, dynamic> read(List rawInput, Reader r) {
+ // TODO(alanknight): It's annoying to have to pass the reader around so
+ // much, consider having the format be specific to a particular
+ // serialization operation along with the reader and having it as a field.
var input = {};
input["rules"] = rawInput[0];
r.readRules(input["rules"]);
@@ -320,14 +332,14 @@
var stream = flatData.iterator;
var tempData = new List(r.rules.length);
for (var eachRule in r.rules) {
- tempData[eachRule.number] = readRuleDataFrom(stream, eachRule);
+ tempData[eachRule.number] = readRuleDataFrom(stream, eachRule, r);
}
input["data"] = tempData;
var roots = [];
var rootsAsInts = rawInput[2].iterator;
do {
- roots.add(nextReferenceFrom(rootsAsInts));
+ roots.add(nextReferenceFrom(rootsAsInts, r));
} while (rootsAsInts.current != null);
input["roots"] = roots;
@@ -337,14 +349,14 @@
/**
* Read the data for [rule] from [input] and return it.
*/
- readRuleDataFrom(Iterator input, SerializationRule rule) {
+ readRuleDataFrom(Iterator input, SerializationRule rule, Reader r) {
var numberOfEntries = _next(input);
var entryType = _next(input);
if (entryType == STORED_AS_LIST) {
- return readLists(input, rule, numberOfEntries);
+ return readLists(input, rule, numberOfEntries, r);
}
if (entryType == STORED_AS_MAP) {
- return readMaps(input, rule, numberOfEntries);
+ return readMaps(input, rule, numberOfEntries, r);
}
if (entryType == STORED_AS_PRIMITIVE) {
return readPrimitives(input, rule, numberOfEntries);
@@ -360,7 +372,7 @@
* Read data for [rule] from [input] with [length] number of entries,
* creating lists from the results.
*/
- readLists(Iterator input, SerializationRule rule, int length) {
+ readLists(Iterator input, SerializationRule rule, int length, Reader r) {
var ruleData = [];
for (var i = 0; i < length; i++) {
var subLength =
@@ -368,7 +380,7 @@
var subList = [];
ruleData.add(subList);
for (var j = 0; j < subLength; j++) {
- subList.add(nextReferenceFrom(input));
+ subList.add(nextReferenceFrom(input, r));
}
}
return ruleData;
@@ -378,15 +390,17 @@
* Read data for [rule] from [input] with [length] number of entries,
* creating maps from the results.
*/
- readMaps(Iterator input, SerializationRule rule, int length) {
+ readMaps(Iterator input, SerializationRule rule, int length, Reader r) {
var ruleData = [];
for (var i = 0; i < length; i++) {
var subLength =
rule.hasVariableLengthEntries ? _next(input) : rule.dataLength;
- var map = {};
+ var map = new Map();
ruleData.add(map);
for (var j = 0; j < subLength; j++) {
- map[_next(input)] = nextReferenceFrom(input);
+ var key = nextReferenceFrom(input, r);
+ var value = nextReferenceFrom(input, r);
+ map[key] = value;
}
}
return ruleData;
@@ -405,13 +419,13 @@
}
/** Read the next Reference from the input. */
- nextReferenceFrom(Iterator input) {
+ nextReferenceFrom(Iterator input, Reader r) {
var a = _next(input);
var b = _next(input);
if (a == null) {
return null;
} else {
- return new Reference(this, a, b);
+ return new Reference(r, a, b);
}
}
@@ -420,4 +434,4 @@
input.moveNext();
return input.current;
}
-}
\ No newline at end of file
+}
diff --git a/pkg/serialization/lib/src/reader_writer.dart b/pkg/serialization/lib/src/reader_writer.dart
index 87535ce..146255d 100644
--- a/pkg/serialization/lib/src/reader_writer.dart
+++ b/pkg/serialization/lib/src/reader_writer.dart
@@ -13,7 +13,7 @@
// that isn't necessary, e.g. detecting cycles and maintaining references.
// Consider having an abstract superclass with the basic functionality and
// simple serialization subclasses where we know there aren't cycles.
-class Writer {
+class Writer implements ReaderOrWriter {
/**
* The [serialization] holds onto the rules that define how objects
* are serialized.
@@ -88,8 +88,13 @@
for (var eachRule in rules) {
_growStates(eachRule);
var index = eachRule.number;
- for (var eachState in states[index]) {
- eachRule.flatten(eachState, this);
+ var statesForThisRule = states[index];
+ for (var i = 0; i < statesForThisRule.length; i++) {
+ var eachState = statesForThisRule[i];
+ var newState = eachRule.flatten(eachState, this);
+ if (newState != null) {
+ statesForThisRule[i] = newState;
+ }
}
}
}
@@ -192,15 +197,18 @@
* Return a list of [Reference] objects pointing to our roots. This will be
* stored in the output under "roots" in the default format.
*/
- _rootReferences() => trace.roots.mappedBy(_referenceFor).toList();
+ _rootReferences() => trace.roots.map(_referenceFor).toList();
/**
* Given an object, return a reference for it if one exists. If there's
- * no reference, return null. Once we have finished the tracing step, all
- * objects that should have a reference (roughly speaking, non-primitives)
- * can be relied on to have a reference.
+ * no reference, return the object itself. Once we have finished the tracing
+ * step, all objects that should have a reference (roughly speaking,
+ * non-primitives) can be relied on to have a reference.
*/
- _referenceFor(object) => references[object];
+ _referenceFor(object) {
+ var result = references[object];
+ return (result == null) ? object : result;
+ }
/**
* Return true if the [namedObjects] collection has a reference to [object].
@@ -217,13 +225,32 @@
// For debugging/testing purposes. Find what state a reference points to.
stateForReference(Reference r) => states[r.ruleNumber][r.objectNumber];
+
+ /** Return the state pointed to by [reference]. */
+ resolveReference(reference) => stateForReference(reference);
+}
+
+/**
+ * An abstract class for Reader and Writer, which primarily exists so we can
+ * type things that will refer to one or the other, depending on which
+ * operation we're doing.
+ */
+abstract class ReaderOrWriter {
+ /** Return the list of serialization rules we are using.*/
+ List<SerializationRule> get rules;
+
+ /**
+ * Return the object, or state, that ref points to, depending on which
+ * we're generating.
+ */
+ resolveReference(Reference ref);
}
/**
* The main class responsible for reading. It holds
* onto the necessary state and to the objects that have been inflated.
*/
-class Reader {
+class Reader implements ReaderOrWriter {
/**
* The serialization that specifies how we read. Note that in contrast
@@ -304,7 +331,7 @@
// When we set the data, initialize the object storage to a matching size.
void set data(List<List> newData) {
_data = newData;
- objects = _data.mappedBy((x) => new List(x.length)).toList();
+ objects = _data.map((x) => new List(x.length)).toList();
}
/**
@@ -388,6 +415,9 @@
});
}
+ /** Return the object pointed to by [reference]. */
+ resolveReference(reference) => inflateReference(reference);
+
/**
* Given [reference], return what we have stored as an object for it. Note
* that, depending on the current state, this might be null or a Sentinel.
@@ -518,13 +548,27 @@
*/
class Reference {
/** The [Reader] or [Writer] that owns this reference. */
- final parent;
+ final ReaderOrWriter parent;
/** The position of the rule that controls this reference in [parent]. */
final int ruleNumber;
/** The index of the referred-to object in the storage of [parent] */
final int objectNumber;
- const Reference(this.parent, this.ruleNumber, this.objectNumber);
+ Reference(this.parent, this.ruleNumber, this.objectNumber) {
+ if (ruleNumber == null || objectNumber == null) {
+ throw new SerializationException("Invalid Reference");
+ }
+ if (parent.rules.length < ruleNumber) {
+ throw new SerializationException("Invalid Reference");
+ }
+ }
+
+ /**
+ * Return the thing this reference points to. Assumes that we have a valid
+ * parent and that it is a Reader, as inflating is not meaningful when
+ * writing.
+ */
+ inflated() => parent.resolveReference(this);
/**
* Convert the reference to a map in JSON format. This is specific to the
@@ -545,7 +589,7 @@
list.add(objectNumber);
}
- toString() => "Reference $ruleNumber, $objectNumber";
+ toString() => "Reference($ruleNumber, $objectNumber)";
}
/**
diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
index a995473..9568c24 100644
--- a/pkg/serialization/lib/src/serialization_helpers.dart
+++ b/pkg/serialization/lib/src/serialization_helpers.dart
@@ -77,7 +77,7 @@
* [collection] is a List, it will be the same as the map() method if the
* [key] parameter wasn't passed.
*/
- mappedBy(Function f) {
+ map(Function f) {
var result = copyEmpty();
forEach((key, value) {
result[key] = f(key, value);
@@ -131,9 +131,9 @@
}
mapValues(x, f) {
- if (x is Set) return x.mappedBy(f).toSet();
- if (x is Iterable) return x.mappedBy(f).toList();
- if (x is Map) return new ListLikeIterable(x).mappedBy(f);
+ if (x is Set) return x.map(f).toSet();
+ if (x is Iterable) return x.map(f).toList();
+ if (x is Map) return new ListLikeIterable(x).map(f);
throw new ArgumentError("Invalid argument");
}
@@ -158,7 +158,7 @@
* [collection] is a List, it will be the same as if map() had been called
* directly on [collection].
*/
- mappedBy(Function f) {
+ map(Function f) {
var result = new Map();
collection.forEach((key, value) => result[key] = f(value));
return result;
@@ -251,4 +251,4 @@
// Note that this is doing an equality comparison.
bool containsValue(x) => values.contains(x);
-}
\ No newline at end of file
+}
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index b040796..5c397b0 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -28,7 +28,7 @@
* be identified within it by number.
*/
void set number(x) {
- if (_number != null) throw
+ if (_number != null && _number != x) throw
new SerializationException("Rule numbers cannot be changed, once set");
_number = x;
}
@@ -48,23 +48,32 @@
extractState(object, void f(value));
/**
+ * Allows rules to tell us how they expect to store their state. If this
+ * isn't specified we can also just look at the data to tell.
+ */
+ bool get storesStateAsLists => false;
+ bool get storesStateAsMaps => false;
+ bool get storesStateAsPrimitives => false;
+
+ /**
* Given the variables representing the state of an object, flatten it
* by turning object pointers into Reference objects where needed. This
* destructively modifies the state object.
*
* This has a default implementation which assumes that object is indexable,
* so either conforms to Map or List. Subclasses may override to do something
- * different.
+ * different, including returning a new state object to be used in place
+ * of the original.
*/
// This has to be a separate operation from extracting, because we extract
// as we are traversing the objects, so we don't yet have the objects to
// generate references for them. It might be possible to avoid that by
// doing a depth-first rather than breadth-first traversal, but I'm not
// sure it's worth it.
- void flatten(state, Writer writer) {
+ flatten(state, Writer writer) {
keysAndValues(state).forEach((key, value) {
var reference = writer._referenceFor(value);
- state[key] = (reference == null) ? value : reference;
+ state[key] = reference;
});
}
@@ -131,7 +140,7 @@
appliesTo(object, Writer w) => object is List;
- state(List list) => new List.from(list);
+ bool get storesStateAsLists => true;
List extractState(List list, f) {
var result = new List();
@@ -180,6 +189,84 @@
}
/**
+ * This rule handles things that implement Map. It will recreate them as
+ * whatever the default implemenation of Map is on the target platform. If a
+ * map has string keys it will attempt to retain it as a map for JSON formats,
+ * otherwise it will store it as a list of references to keys and values.
+ */
+class MapRule extends SerializationRule {
+
+ appliesTo(object, Writer w) => object is Map;
+
+ bool get storesStateAsMaps => true;
+
+ extractState(Map map, f) {
+ // Note that we make a copy here because flattening may be destructive.
+ var newMap = new Map.from(map);
+ newMap.forEach((key, value) {
+ f(key);
+ f(value);
+ });
+ return newMap;
+ }
+
+ /**
+ * Change the keys and values of [state] into references in [writer].
+ * If [state] is a map whose keys are all strings then we leave the keys
+ * as is so that JSON formats will be more readable. If the keys are
+ * arbitrary then we need to turn them into references and replace the
+ * state with a new Map whose keys are the references.
+ */
+ flatten(Map state, Writer writer) {
+ bool keysAreAllStrings = state.keys.every((x) => x is String);
+ if (keysAreAllStrings) {
+ keysAndValues(state).forEach(
+ (key, value) => state[key] = writer._referenceFor(value));
+ return state;
+ } else {
+ var newState = [];
+ keysAndValues(state).forEach((key, value) {
+ newState.add(writer._referenceFor(key));
+ newState.add(writer._referenceFor(value));
+ });
+ return newState;
+ }
+ }
+
+ inflateEssential(state, Reader r) => new Map();
+
+ // For a map, we consider all of its state non-essential and add it
+ // after creation.
+ inflateNonEssential(state, Map newMap, Reader r) {
+ if (state is List) {
+ inflateNonEssentialFromList(state, newMap, r);
+ } else {
+ inflateNonEssentialFromMap(state, newMap, r);
+ }
+ }
+
+ void inflateNonEssentialFromList(List state, Map newMap, Reader r) {
+ var key;
+ for (var each in state) {
+ if (key == null) {
+ key = each;
+ } else {
+ newMap[r.inflateReference(key)] = r.inflateReference(each);
+ key = null;
+ }
+ }
+ }
+
+ void inflateNonEssentialFromMap(Map state, Map newMap, Reader r) {
+ state.forEach((key, value) {
+ newMap[r.inflateReference(key)] = r.inflateReference(value);
+ });
+ }
+
+ bool get hasVariableLengthEntries => true;
+}
+
+/**
* This rule handles primitive types, defined as those that we can normally
* represent directly in the output format. We hard-code that to mean
* num, String, and bool.
@@ -189,10 +276,12 @@
return isPrimitive(object);
}
extractState(object, Function f) => object;
- void flatten(object, Writer writer) {}
+ flatten(object, Writer writer) {}
inflateEssential(state, Reader r) => state;
inflateNonEssential(object, _, Reader r) {}
+ bool get storesStateAsPrimitives => true;
+
/**
* Indicate whether we should save pointers to this object as references
* or store the object directly. For primitives this depends on the format,
@@ -274,7 +363,7 @@
// reference to that. But that requires adding the Writer as a parameter to
// extractState, and I'm reluctant to add yet another parameter until
// proven necessary.
- void flatten(state, Writer writer) {
+ flatten(state, Writer writer) {
state[0] = nameFor(state.first, writer);
}
@@ -390,7 +479,7 @@
// These operations will work, but may be expensive, and are probably
// best avoided.
- get _inflated => keysAndValues(_raw).mappedBy(_reader.inflateReference);
+ get _inflated => keysAndValues(_raw).map(_reader.inflateReference);
bool containsValue(x) => _inflated.containsValue(x);
Iterable get values => _inflated.values;
void forEach(f) => _inflated.forEach(f);
@@ -429,7 +518,7 @@
// These operations, and other inherited methods that iterate over the whole
// list will work, but may be expensive, and are probably
// best avoided.
- List get _inflated => _raw.mappedBy(_reader.inflateReference);
+ List get _inflated => _raw.map(_reader.inflateReference);
Iterator get iterator => _inflated.iterator;
indexOf(x, [pos = 0]) => _inflated.toList().indexOf(x);
lastIndexOf(x, [pos]) => _inflated.toList().lastIndexOf(x);
@@ -445,8 +534,8 @@
sort([f]) => _throw();
clear() => _throw();
removeAt(x) => _throw();
- removeLast() => _throw();
remove(x) => _throw();
+ removeLast() => _throw();
removeAll(x) => _throw();
retainAll(x) => _throw();
removeMatching(x) => _throw();
@@ -455,6 +544,6 @@
setRange(x, y, z, [a]) => _throw();
removeRange(x, y) => _throw();
insertRange(x, y, [z]) => _throw();
+ get reversed => _throw();
void set length(x) => _throw();
- List get reversed => _throw();
}
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 73e2e13..f4713a2 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -47,15 +47,19 @@
// actually writing.
var w = new Writer(s);
w.write(p1);
- var flatPerson = w.states[3].first;
+ var personRule = s.rules.firstMatching(
+ (x) => x is BasicRule && x.type == reflect(p1).type);
+ var flatPerson = w.states[personRule.number].first;
var primStates = w.states.first;
expect(primStates.isEmpty, true);
expect(flatPerson["name"], "Alice");
var ref = flatPerson["address"];
expect(ref is Reference, true);
- expect(ref.ruleNumber, 4);
+ var addressRule = s.rules.firstMatching(
+ (x) => x is BasicRule && x.type == reflect(a1).type);
+ expect(ref.ruleNumber, addressRule.number);
expect(ref.objectNumber, 0);
- expect(w.states[4].first['street'], 'N 34th');
+ expect(w.states[addressRule.number].first['street'], 'N 34th');
});
test('exclude fields', () {
@@ -206,9 +210,11 @@
var w = new Writer(s);
w.trace = new Trace(w);
w.write(n1);
- expect(w.states.length, 4); // prims, lists, essential lists, basic
+ expect(w.states.length, 5); // prims, lists, essential lists, basic
var children = 0, name = 1, parent = 2;
- List rootNode = w.states[3].where((x) => x[name] == "1").toList();
+ var nodeRule = s.rules.firstMatching((x) => x is BasicRule);
+ List rootNode = w.states[nodeRule.number].where(
+ (x) => x[name] == "1").toList();
rootNode = rootNode.first;
expect(rootNode[parent], isNull);
var list = w.states[1].first;
@@ -372,6 +378,25 @@
expect(a2.city, "Seattle");
});
+ test("Straight JSON format, root is a Map", () {
+ // Note that we can't use the usual round-trip test because it has cycles.
+ var p1 = new Person()..name = 'Alice'..address = a1;
+ // Use maps for one rule, lists for the other.
+ var s = new Serialization()
+ ..addRuleFor(a1)
+ ..addRuleFor(p1).configureForMaps();
+ var format = new SimpleJsonFormat(storeRoundTripInfo: true);
+ var writer = s.newWriter(format);
+ var out = writer.write({"stuff" : p1});
+ var reader = s.newReader(format);
+ var p2 = reader.read(out)["stuff"];
+ expect(p2.name, "Alice");
+ var a2 = p2.address;
+ expect(a2.street, "N 34th");
+ expect(a2.city, "Seattle");
+ });
+
+
test("Straight JSON format, round-trip with named objects", () {
// Note that we can't use the usual round-trip test because it has cycles.
var p1 = new Person()..name = 'Alice'..address = a1;
@@ -389,6 +414,54 @@
var a2 = p2.address;
expect(a2, 12);
});
+
+ test("Maps", () {
+ var s = new Serialization()..selfDescribing = false;
+ var p1 = new Person()..name = 'Alice'..address = a1;
+ var data = new Map();
+ data["simple data"] = 1;
+ data[p1] = a1;
+ data[a1] = p1;
+ var formats = [new SimpleFlatFormat(), new SimpleMapFormat(),
+ new SimpleJsonFormat(storeRoundTripInfo: true)];
+ for (var eachFormat in formats) {
+ var output = s.write(data, eachFormat);
+ var reader = s.newReader(eachFormat);
+ var input = reader.read(output);
+ expect(input["simple data"], data["simple data"]);
+ var p2 = input.keys.firstMatching((x) => x is Person);
+ var a2 = input.keys.firstMatching((x) => x is Address);
+ if (eachFormat is SimpleJsonFormat) {
+ // JSON doesn't handle cycles, so these won't be identical.
+ expect(input[p2] is Address, isTrue);
+ expect(input[a2] is Person, isTrue);
+ var a3 = input[p2];
+ expect(a3.city, a2.city);
+ expect(a3.state, a2.state);
+ expect(a3.state, a2.state);
+ var p3 = input[a2];
+ expect(p3.name, p2.name);
+ expect(p3.rank, p2.rank);
+ expect(p3.address.city, a2.city);
+ } else {
+ expect(input[p2], same(a2));
+ expect(input[a2], same(p2));
+ }
+ }
+ });
+
+ test("Map with string keys stays that way", () {
+ var s = new Serialization()..addRuleFor(new Person());
+ var data = {"abc" : 1, "def" : "ghi"};
+ data["person"] = new Person()..name = "Foo";
+ var output = s.write(data, new SimpleMapFormat());
+ var mapRule = s.rules.firstMatching((x) => x is MapRule);
+ var map = json.parse(output)["data"][mapRule.number][0];
+ expect(map is Map, isTrue);
+ expect(map["abc"], 1);
+ expect(map["def"], "ghi");
+ expect(new Reader(s).asReference(map["person"]) is Reference, isTrue);
+ });
}
/******************************************************************************
@@ -413,10 +486,11 @@
'constructorName',
'constructorFields', 'regularFields', []],
fields: [])
- ..addRuleFor(new Serialization()).setFieldWith('rules',
- (InstanceMirror s, List rules) {
+ ..addRuleFor(new Serialization(), constructor: "blank")
+ .setFieldWith('rules',
+ (InstanceMirror s, List rules) {
rules.forEach((x) => s.reflectee.addRule(x));
- })
+ })
..addRule(new NamedObjectRule())
..addRule(new MirrorRule());
return meta;
@@ -441,7 +515,12 @@
var reader = new Reader(aSerialization);
// We're not sure which rule needs the sample data, so put it everywhere
// and trust that the extra will just be ignored.
- reader.data = [[sampleData], [sampleData], [sampleData], [sampleData]];
+ var fillValue = [sampleData];
+ var data = [];
+ for (int i = 0; i < 10; i++) {
+ data.add(fillValue);
+ }
+ reader.data = data;
return reader;
}
@@ -562,7 +641,7 @@
/** Extract the state from [object] using the rules in [s] and return it. */
states(object, Serialization s) {
var rules = s.rulesFor(object, null);
- return rules.mappedBy((x) => x.extractState(object, doNothing)).toList();
+ return rules.map((x) => x.extractState(object, doNothing)).toList();
}
/** A hard-coded rule for serializing Node instances. */
diff --git a/pkg/unittest/lib/compact_vm_config.dart b/pkg/unittest/lib/compact_vm_config.dart
index cb21d4d..6b46a65 100644
--- a/pkg/unittest/lib/compact_vm_config.dart
+++ b/pkg/unittest/lib/compact_vm_config.dart
@@ -58,7 +58,7 @@
}
String _indent(String str) {
- return str.split("\n").mappedBy((line) => " $line").join("\n");
+ return str.split("\n").map((line) => " $line").join("\n");
}
void onSummary(int passed, int failed, int errors, List<TestCase> results,
diff --git a/pkg/unittest/lib/html_config.dart b/pkg/unittest/lib/html_config.dart
index a4a1f9f..d4c9cdb 100644
--- a/pkg/unittest/lib/html_config.dart
+++ b/pkg/unittest/lib/html_config.dart
@@ -7,6 +7,7 @@
*/
library unittest_html_config;
+import 'dart:async';
import 'dart:html';
import 'unittest.dart';
@@ -89,32 +90,28 @@
final bool _isLayoutTest;
HtmlConfiguration(this._isLayoutTest);
- // TODO(rnystrom): Get rid of this if we get canonical closures for methods.
- EventListener _onErrorClosure;
- EventListener _onMessageClosure;
+ StreamSubscription<Event> _onErrorSubscription;
+ StreamSubscription<Event> _onMessageSubscription;
void _installHandlers() {
- if (_onErrorClosure == null) {
- _onErrorClosure =
- (e) => handleExternalError(e, '(DOM callback has errors)');
- // Listen for uncaught errors.
- window.on.error.add(_onErrorClosure);
+ if (_onErrorSubscription == null) {
+ _onErrorSubscription = window.onError.listen(
+ (e) => handleExternalError(e, '(DOM callback has errors)'));
}
- if (_onMessageClosure == null) {
- _onMessageClosure = (e) => processMessage(e);
- // Listen for errors from JS.
- window.on.message.add(_onMessageClosure);
+ if (_onMessageSubscription == null) {
+ _onMessageSubscription = window.onMessage.listen(
+ (e) => processMessage(e));
}
}
void _uninstallHandlers() {
- if (_onErrorClosure != null) {
- window.on.error.remove(_onErrorClosure);
- _onErrorClosure = null;
+ if (_onErrorSubscription != null) {
+ _onErrorSubscription.cancel();
+ _onErrorSubscription = null;
}
- if (_onMessageClosure != null) {
- window.on.message.remove(_onMessageClosure);
- _onMessageClosure = null;
+ if (_onMessageSubscription != null) {
+ _onMessageSubscription.cancel();
+ _onMessageSubscription = null;
}
}
diff --git a/pkg/unittest/lib/html_individual_config.dart b/pkg/unittest/lib/html_individual_config.dart
index 2de4ed2..f722a6d 100644
--- a/pkg/unittest/lib/html_individual_config.dart
+++ b/pkg/unittest/lib/html_individual_config.dart
@@ -24,11 +24,15 @@
HtmlIndividualConfiguration(isLayoutTest): super(isLayoutTest);
void onStart() {
- var testGroupName = window.location.hash;
+ var testGroupName = window.location.search;
if (testGroupName != '') {
try {
- testGroupName = testGroupName.substring(1); // cut off the #
- unittest.filterTests('^$testGroupName');
+ for (var parameter in testGroupName.substring(1).split('&')) {
+ if (parameter.startsWith('group=')) {
+ testGroupName = parameter.split('=')[1];
+ }
+ }
+ unittest.filterTests('^$testGroupName${unittest.groupSep}');
} catch (e) {
print('tried to match "$testGroupName"');
print('NO_SUCH_TEST');
diff --git a/pkg/unittest/lib/src/config.dart b/pkg/unittest/lib/src/config.dart
index c77019b..73de212 100644
--- a/pkg/unittest/lib/src/config.dart
+++ b/pkg/unittest/lib/src/config.dart
@@ -146,7 +146,7 @@
// TODO(nweiz): Use this simpler code once issue 2980 is fixed.
// return str.replaceAll(new RegExp("^", multiLine: true), " ");
- return Strings.join(str.split("\n").mappedBy((line) => " $line"), "\n");
+ return Strings.join(str.split("\n").map((line) => " $line"), "\n");
}
/** Handle errors that happen outside the tests. */
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index fbf1465..489fecd 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -504,6 +504,19 @@
bool matches(item, MatchState matchState) => item is UnsupportedError;
}
+/** A matcher for StateErrors. */
+const isStateError = const _StateError();
+
+/** A matcher for functions that throw StateError. */
+const Matcher throwsStateError =
+ const Throws(isStateError);
+
+class _StateError extends TypeMatcher {
+ const _StateError() : super("StateError");
+ bool matches(item, MatchState matchState) => item is StateError;
+}
+
+
/** A matcher for Map types. */
const isMap = const _IsMap();
diff --git a/pkg/yaml/README.md b/pkg/yaml/README.md
new file mode 100644
index 0000000..ad7678f
--- /dev/null
+++ b/pkg/yaml/README.md
@@ -0,0 +1,24 @@
+A parser for [YAML](http://www.yaml.org/).
+
+Use `loadYaml` to load a single document, or `loadYamlStream` to load a
+stream of documents. For example:
+
+ import 'package:yaml/yaml.dart';
+ main() {
+ var doc = loadYaml("YAML: YAML Ain't Markup Language");
+ print(doc['YAML']);
+ }
+
+This library currently doesn't support dumping to YAML. You should use
+`stringify` from `dart:json` instead:
+
+ import 'dart:json' as json;
+ import 'package:yaml/yaml.dart';
+ main() {
+ var doc = loadYaml("YAML: YAML Ain't Markup Language");
+ print(json.stringify(doc));
+ }
+
+The source code for this package is at <http://code.google.com/p/dart>.
+Please file issues at <http://dartbug.com>. Other questions or comments can be
+directed to the Dart mailing list at <mailto:misc@dartlang.org>.
diff --git a/utils/pub/yaml/composer.dart b/pkg/yaml/lib/composer.dart
similarity index 100%
rename from utils/pub/yaml/composer.dart
rename to pkg/yaml/lib/composer.dart
diff --git a/utils/pub/yaml/constructor.dart b/pkg/yaml/lib/constructor.dart
similarity index 100%
rename from utils/pub/yaml/constructor.dart
rename to pkg/yaml/lib/constructor.dart
diff --git a/utils/pub/yaml/deep_equals.dart b/pkg/yaml/lib/deep_equals.dart
similarity index 100%
rename from utils/pub/yaml/deep_equals.dart
rename to pkg/yaml/lib/deep_equals.dart
diff --git a/utils/pub/yaml/model.dart b/pkg/yaml/lib/model.dart
similarity index 97%
rename from utils/pub/yaml/model.dart
rename to pkg/yaml/lib/model.dart
index 8c111af..7a609b9 100644
--- a/utils/pub/yaml/model.dart
+++ b/pkg/yaml/lib/model.dart
@@ -91,7 +91,7 @@
}
String toString() =>
- '$tag [${Strings.join(content.mappedBy((e) => '$e'), ', ')}]';
+ '$tag [${Strings.join(content.map((e) => '$e'), ', ')}]';
int get hashCode => super.hashCode ^ _hashCode(content);
@@ -150,7 +150,7 @@
// TODO(nweiz): This could be faster if we used a RegExp to check for
// special characters and short-circuited if they didn't exist.
- var escapedValue = value.charCodes.mappedBy((c) {
+ var escapedValue = value.charCodes.map((c) {
switch (c) {
case _Parser.TAB: return "\\t";
case _Parser.LF: return "\\n";
@@ -223,7 +223,7 @@
String toString() {
var strContent = content.keys
- .mappedBy((k) => '${k}: ${content[k]}')
+ .map((k) => '${k}: ${content[k]}')
.join(', ');
return '$tag {$strContent}';
}
diff --git a/utils/pub/yaml/parser.dart b/pkg/yaml/lib/parser.dart
similarity index 100%
rename from utils/pub/yaml/parser.dart
rename to pkg/yaml/lib/parser.dart
diff --git a/utils/pub/yaml/visitor.dart b/pkg/yaml/lib/visitor.dart
similarity index 92%
rename from utils/pub/yaml/visitor.dart
rename to pkg/yaml/lib/visitor.dart
index b5c14c9..42dbb22 100644
--- a/utils/pub/yaml/visitor.dart
+++ b/pkg/yaml/lib/visitor.dart
@@ -14,7 +14,7 @@
/// Visits each node in [seq] and returns a list of the results.
visitSequence(_SequenceNode seq)
- => seq.content.mappedBy((e) => e.visit(this)).toList();
+ => seq.content.map((e) => e.visit(this)).toList();
/// Visits each key and value in [map] and returns a map of the results.
visitMapping(_MappingNode map) {
diff --git a/utils/pub/yaml/yaml.dart b/pkg/yaml/lib/yaml.dart
similarity index 69%
rename from utils/pub/yaml/yaml.dart
rename to pkg/yaml/lib/yaml.dart
index a73736d..e905e76 100644
--- a/utils/pub/yaml/yaml.dart
+++ b/pkg/yaml/lib/yaml.dart
@@ -2,6 +2,26 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+/// A parser for [YAML](http://www.yaml.org/).
+///
+/// Use [loadYaml] to load a single document, or [loadYamlStream] to load a
+/// stream of documents. For example:
+///
+/// import 'package:yaml/yaml.dart';
+/// main() {
+/// var doc = loadYaml("YAML: YAML Ain't Markup Language");
+/// print(doc['YAML']);
+/// }
+///
+/// This library currently doesn't support dumping to YAML. You should use
+/// `stringify` from `dart:json` instead:
+///
+/// import 'dart:json' as json;
+/// import 'package:yaml/yaml.dart';
+/// main() {
+/// var doc = loadYaml("YAML: YAML Ain't Markup Language");
+/// print(json.stringify(doc));
+/// }
library yaml;
import 'dart:math' as Math;
@@ -40,8 +60,8 @@
/// are YamlMaps. These have a few small behavioral differences from the default
/// Map implementation; for details, see the YamlMap class.
List loadYamlStream(String yaml) {
- return new _Parser(yaml).l_yamlStream().mappedBy((doc) =>
- new _Constructor(new _Composer(doc).compose()).construct())
+ return new _Parser(yaml).l_yamlStream()
+ .map((doc) => new _Constructor(new _Composer(doc).compose()).construct())
.toList();
}
diff --git a/utils/pub/yaml/yaml_map.dart b/pkg/yaml/lib/yaml_map.dart
similarity index 97%
rename from utils/pub/yaml/yaml_map.dart
rename to pkg/yaml/lib/yaml_map.dart
index 65dd119..cbf18e5 100644
--- a/utils/pub/yaml/yaml_map.dart
+++ b/pkg/yaml/lib/yaml_map.dart
@@ -29,7 +29,7 @@
void clear() => _map.clear();
void forEach(void f(key, value)) =>
_map.forEach((k, v) => f(_unwrapKey(k), v));
- Iterable get keys => _map.keys.mappedBy(_unwrapKey);
+ Iterable get keys => _map.keys.map(_unwrapKey);
Iterable get values => _map.values;
int get length => _map.length;
bool get isEmpty => _map.isEmpty;
diff --git a/pkg/yaml/pubspec.yaml b/pkg/yaml/pubspec.yaml
new file mode 100644
index 0000000..7c944d2
--- /dev/null
+++ b/pkg/yaml/pubspec.yaml
@@ -0,0 +1,7 @@
+name: yaml
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: A parser for YAML.
+dependencies:
+ unittest:
+ sdk: unittest
diff --git a/utils/tests/pub/yaml_test.dart b/pkg/yaml/test/yaml_test.dart
similarity index 99%
rename from utils/tests/pub/yaml_test.dart
rename to pkg/yaml/test/yaml_test.dart
index 50c0214..b939b67 100644
--- a/utils/tests/pub/yaml_test.dart
+++ b/pkg/yaml/test/yaml_test.dart
@@ -4,9 +4,11 @@
library yaml_test;
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../pub/yaml/yaml.dart';
-import '../../pub/yaml/deep_equals.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/yaml.dart';
+import 'package:yaml/deep_equals.dart';
+// TODO(jmesserly): we should not be reaching outside the YAML package
+// The http package has a similar problem.
import '../../../tests/utils/test_utils.dart';
/// Constructs a new yaml.YamlMap, optionally from a normal Map.
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 5269d6d..7eac81a 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -664,10 +664,9 @@
}
-Dart_CObject* CObject::NewExternalUint8Array(int64_t length,
- uint8_t* data,
- void* peer,
- Dart_PeerFinalizer callback) {
+Dart_CObject* CObject::NewExternalUint8Array(
+ int64_t length, uint8_t* data, void* peer,
+ Dart_WeakPersistentHandleFinalizer callback) {
Dart_CObject* cobject = New(Dart_CObject::kExternalUint8Array);
cobject->value.as_external_byte_array.length = length;
cobject->value.as_external_byte_array.data = data;
@@ -679,14 +678,14 @@
Dart_CObject* CObject::NewIOBuffer(int64_t length) {
uint8_t* data = IOBuffer::Allocate(length);
- return NewExternalUint8Array(length, data, data, IOBuffer::Free);
+ return NewExternalUint8Array(length, data, data, IOBuffer::Finalizer);
}
void CObject::FreeIOBufferData(Dart_CObject* cobject) {
ASSERT(cobject->type == Dart_CObject::kExternalUint8Array);
cobject->value.as_external_byte_array.callback(
- cobject->value.as_external_byte_array.peer);
+ NULL, cobject->value.as_external_byte_array.peer);
cobject->value.as_external_byte_array.data = NULL;
}
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index ce9f3f4..03c9477 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -228,10 +228,9 @@
static Dart_CObject* NewString(const char* str);
static Dart_CObject* NewArray(int length);
static Dart_CObject* NewUint8Array(int length);
- static Dart_CObject* NewExternalUint8Array(int64_t length,
- uint8_t* data,
- void* peer,
- Dart_PeerFinalizer callback);
+ static Dart_CObject* NewExternalUint8Array(
+ int64_t length, uint8_t* data, void* peer,
+ Dart_WeakPersistentHandleFinalizer callback);
static Dart_CObject* NewIOBuffer(int64_t length);
static void FreeIOBufferData(Dart_CObject* object);
@@ -412,7 +411,7 @@
}
uint8_t* Data() const { return cobject_->value.as_external_byte_array.data; }
void* Peer() const { return cobject_->value.as_external_byte_array.peer; }
- Dart_PeerFinalizer Callback() const {
+ Dart_WeakPersistentHandleFinalizer Callback() const {
return cobject_->value.as_external_byte_array.callback;
}
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index c0ca3de..f5e53ee 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -31,7 +31,6 @@
// Global state that indicates whether a snapshot is to be created and
// if so which file to write the snapshot into.
static const char* snapshot_filename = NULL;
-static bool script_snapshot = false;
static const char* package_root = NULL;
static uint8_t* snapshot_buffer = NULL;
@@ -66,13 +65,6 @@
static bool ProcessSnapshotOption(const char* option) {
const char* name = ProcessOption(option, "--snapshot=");
if (name != NULL) {
- script_snapshot = false;
- snapshot_filename = name;
- return true;
- }
- name = ProcessOption(option, "--script_snapshot=");
- if (name != NULL) {
- script_snapshot = true;
snapshot_filename = name;
return true;
}
@@ -367,14 +359,12 @@
"Usage:\n"
"\n"
" gen_snapshot [<vm-flags>] [<options>] \\\n"
-" {--script_snapshot=<out-file> | --snapshot=<out-file>} \\\n"
-" [<dart-script-file>]\n"
+" --snapshot=<out-file> [<dart-script-file>]\n"
"\n"
" Writes a snapshot of <dart-script-file> to <out-file>. If no\n"
" <dart-script-file> is passed, a generic snapshot of all the corelibs is\n"
-" created. One of the following is required:\n"
+" created. It is required to specify an output file name:\n"
"\n"
-" --script_snapshot=<file> Generates a script snapshot.\n"
" --snapshot=<file> Generates a complete snapshot. Uses the url\n"
" mapping specified on the command line to load\n"
" the libraries.\n"
@@ -401,19 +391,13 @@
}
-static void CreateAndWriteSnapshot(bool script_snapshot) {
+static void CreateAndWriteSnapshot() {
Dart_Handle result;
uint8_t* buffer = NULL;
intptr_t size = 0;
// First create a snapshot.
- if (script_snapshot) {
- // Script snapshot specified so create a script snapshot.
- result = Dart_CreateScriptSnapshot(&buffer, &size);
- } else {
- // Create a full snapshot.
- result = Dart_CreateSnapshot(&buffer, &size);
- }
+ result = Dart_CreateSnapshot(&buffer, &size);
CHECK_RESULT(result);
// Now write the snapshot out to specified file and exit.
@@ -505,103 +489,49 @@
ASSERT(snapshot_filename != NULL);
// Load up the script before a snapshot is created.
if (app_script_name != NULL) {
- if (!script_snapshot) {
- // This is the case of a custom embedder (e.g: dartium) trying to
- // create a full snapshot. The current isolate is set up so that we can
- // invoke the dart uri resolution code like _resolveURI. App script is
- // loaded into a separate isolate.
+ // This is the case of a custom embedder (e.g: dartium) trying to
+ // create a full snapshot. The current isolate is set up so that we can
+ // invoke the dart uri resolution code like _resolveURI. App script is
+ // loaded into a separate isolate.
- SetupForUriResolution();
+ SetupForUriResolution();
- // Get handle to builtin library.
- Dart_Handle builtin_lib =
- Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
- CHECK_RESULT(builtin_lib);
+ // Get handle to builtin library.
+ Dart_Handle builtin_lib =
+ Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+ CHECK_RESULT(builtin_lib);
- // Prepare for script loading by setting up the 'print' and 'timer'
- // closures and setting up 'package root' for URI resolution.
- result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
- CHECK_RESULT(result);
- Dart_ExitScope();
+ // Prepare for script loading by setting up the 'print' and 'timer'
+ // closures and setting up 'package root' for URI resolution.
+ result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
+ CHECK_RESULT(result);
+ Dart_ExitScope();
- UriResolverIsolateScope::isolate = isolate;
+ UriResolverIsolateScope::isolate = isolate;
- // Now we create an isolate into which we load all the code that needs to
- // be in the snapshot.
- if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error) == NULL) {
- fprintf(stderr, "%s", error);
- free(error);
- exit(255);
- }
- Dart_EnterScope();
-
- // Set up the library tag handler in such a manner that it will use the
- // URL mapping specified on the command line to load the libraries.
- result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
- CHECK_RESULT(result);
- // Load the specified script.
- library = LoadSnapshotCreationScript(app_script_name);
- VerifyLoaded(library);
- CreateAndWriteSnapshot(false);
-
- Dart_EnterIsolate(UriResolverIsolateScope::isolate);
- Dart_ShutdownIsolate();
- } else {
- // This is the case where we want to create a script snapshot of
- // the specified script. There will be no URL mapping specified for
- // this case, use the generic library tag handler.
-
- // First setup and create a generic full snapshot.
- SetupForGenericSnapshotCreation();
- uint8_t* buffer = NULL;
- intptr_t size = 0;
- result = Dart_CreateSnapshot(&buffer, &size);
- CHECK_RESULT(result);
-
- // Save the snapshot buffer as we are about to shutdown the isolate.
- snapshot_buffer = reinterpret_cast<uint8_t*>(malloc(size));
- ASSERT(snapshot_buffer != NULL);
- memmove(snapshot_buffer, buffer, size);
-
- // Shutdown the isolate.
- Dart_ExitScope();
- Dart_ShutdownIsolate();
-
- // Now load the specified script and create a script snapshot.
- if (Dart_CreateIsolate(
- NULL, NULL, snapshot_buffer, NULL, &error) == NULL) {
- Log::PrintErr("%s", error);
- free(error);
- free(snapshot_buffer);
- exit(255);
- }
- Dart_EnterScope();
-
- // Setup generic library tag handler.
- result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
- CHECK_RESULT(result);
-
- // Get handle to builtin library.
- Dart_Handle builtin_lib =
- Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
- CHECK_RESULT(builtin_lib);
-
- // Prepare for script loading by setting up the 'print' and 'timer'
- // closures and setting up 'package root' for URI resolution.
- result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
- CHECK_RESULT(result);
-
- // Load specified script.
- library = DartUtils::LoadScript(app_script_name, builtin_lib);
-
- // Now create and write snapshot of script.
- CreateAndWriteSnapshot(true);
-
- free(snapshot_buffer);
+ // Now we create an isolate into which we load all the code that needs to
+ // be in the snapshot.
+ if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error) == NULL) {
+ fprintf(stderr, "%s", error);
+ free(error);
+ exit(255);
}
+ Dart_EnterScope();
+
+ // Set up the library tag handler in such a manner that it will use the
+ // URL mapping specified on the command line to load the libraries.
+ result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
+ CHECK_RESULT(result);
+ // Load the specified script.
+ library = LoadSnapshotCreationScript(app_script_name);
+ VerifyLoaded(library);
+ CreateAndWriteSnapshot();
+
+ Dart_EnterIsolate(UriResolverIsolateScope::isolate);
+ Dart_ShutdownIsolate();
} else {
SetupForGenericSnapshotCreation();
- CreateAndWriteSnapshot(false);
+ CreateAndWriteSnapshot();
}
return 0;
}
diff --git a/runtime/bin/io_buffer.cc b/runtime/bin/io_buffer.cc
index a07559d..5f40478 100644
--- a/runtime/bin/io_buffer.cc
+++ b/runtime/bin/io_buffer.cc
@@ -6,7 +6,8 @@
Dart_Handle IOBuffer::Allocate(intptr_t size, uint8_t **buffer) {
uint8_t* data = Allocate(size);
- Dart_Handle result = Dart_NewExternalByteArray(data, size, data, Free);
+ Dart_Handle result = Dart_NewExternalByteArray(data, size,
+ data, IOBuffer::Finalizer);
if (Dart_IsError(result)) {
Free(data);
Dart_PropagateError(result);
diff --git a/runtime/bin/io_buffer.h b/runtime/bin/io_buffer.h
index 69a5c09..0c73164 100644
--- a/runtime/bin/io_buffer.h
+++ b/runtime/bin/io_buffer.h
@@ -2,8 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-#ifndef IO_BUFFER_H_
-#define IO_BUFFER_H_
+#ifndef BIN_IO_BUFFER_H_
+#define BIN_IO_BUFFER_H_
#include "platform/globals.h"
@@ -24,9 +24,17 @@
delete[] reinterpret_cast<uint8_t*>(buffer);
}
+ // Function for finalizing external byte arrays used as IO buffers.
+ static void Finalizer(Dart_Handle handle, void* buffer) {
+ Free(buffer);
+ if (handle != NULL) {
+ Dart_DeletePersistentHandle(handle);
+ }
+ }
+
private:
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(IOBuffer);
};
-#endif // IO_BUFFER_H_
+#endif // BIN_IO_BUFFER_H_
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 1adb208..6d263ef 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -29,6 +29,7 @@
// Global state that stores a pointer to the application script snapshot.
static bool use_script_snapshot = false;
+static bool generate_script_snapshot = false;
static File* snapshot_file = NULL;
@@ -144,10 +145,45 @@
}
-static bool ProcessScriptSnapshotOption(const char* filename) {
+static bool ProcessUseScriptSnapshotOption(const char* filename) {
if (filename != NULL && strlen(filename) != 0) {
use_script_snapshot = true;
+ if (generate_script_snapshot) {
+ Log::PrintErr("Incompatible options specified --generate-script-snapshot "
+ "and --use-script-snapshot\n");
+ return false;
+ }
snapshot_file = File::Open(filename, File::kRead);
+ if (snapshot_file == NULL) {
+ Log::PrintErr("Unable to open file %s for reading the snapshot\n",
+ filename);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+static bool ProcessGenScriptSnapshotOption(const char* filename) {
+ if (filename != NULL && strlen(filename) != 0) {
+ // Ensure that are already running using a full snapshot.
+ if (snapshot_buffer == NULL) {
+ Log::PrintErr("Script snapshots cannot be generated in this version of"
+ " dart\n");
+ return false;
+ }
+ if (use_script_snapshot) {
+ Log::PrintErr("Incompatible options specified --use-script-snapshot "
+ "and --generate-script-snapshot\n");
+ return false;
+ }
+ snapshot_file = File::Open(filename, File::kWriteTruncate);
+ if (snapshot_file == NULL) {
+ Log::PrintErr("Unable to open file %s for writing the snapshot\n",
+ filename);
+ return false;
+ }
+ generate_script_snapshot = true;
}
return true;
}
@@ -169,7 +205,8 @@
{ "--break_at=", ProcessBreakpointOption },
{ "--compile_all", ProcessCompileAllOption },
{ "--debug", ProcessDebugOption },
- { "--use_script_snapshot=", ProcessScriptSnapshotOption },
+ { "--use-script-snapshot=", ProcessUseScriptSnapshotOption },
+ { "--generate-script-snapshot=", ProcessGenScriptSnapshotOption },
{ NULL, NULL }
};
@@ -507,9 +544,12 @@
" url:<line_num> e.g. test.dart:10\n"
" [<class_name>.]<function_name> e.g. B.foo\n"
"\n"
-"--use_script_snapshot=<file_name>\n"
+"--use-script-snapshot=<file_name>\n"
" executes Dart script present in the specified snapshot file\n"
"\n"
+"--generate-script-snapshot=<file_name>\n"
+" loads Dart script and generates a snapshot in the specified file\n"
+"\n"
"The following options are only used for VM development and may\n"
"be changed in any future version:\n");
const char* print_flags = "--print_flags";
@@ -673,46 +713,65 @@
Dart_EnterScope();
- if (has_compile_all) {
- result = Dart_CompileAll();
+ if (generate_script_snapshot) {
+ // First create a snapshot.
+ Dart_Handle result;
+ uint8_t* buffer = NULL;
+ intptr_t size = 0;
+ result = Dart_CreateScriptSnapshot(&buffer, &size);
+ if (Dart_IsError(result)) {
+ Log::PrintErr("%s\n", Dart_GetError(result));
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+ return kErrorExitCode; // Indicates we encountered an error.
+ }
+
+ // Now write the snapshot out to specified file.
+ bool bytes_written = snapshot_file->WriteFully(buffer, size);
+ ASSERT(bytes_written);
+ delete snapshot_file;
+ } else {
+ if (has_compile_all) {
+ result = Dart_CompileAll();
+ if (Dart_IsError(result)) {
+ return ErrorExit("%s\n", Dart_GetError(result));
+ }
+ }
+
+ // Create a dart options object that can be accessed from dart code.
+ Dart_Handle options_result =
+ SetupRuntimeOptions(&dart_options, executable_name, script_name);
+ if (Dart_IsError(options_result)) {
+ return ErrorExit("%s\n", Dart_GetError(options_result));
+ }
+ // Lookup the library of the root script.
+ Dart_Handle library = Dart_RootLibrary();
+ if (Dart_IsNull(library)) {
+ return ErrorExit("Unable to find root library for '%s'\n",
+ script_name);
+ }
+ // Set debug breakpoint if specified on the command line.
+ if (breakpoint_at != NULL) {
+ result = SetBreakpoint(breakpoint_at, library);
+ if (Dart_IsError(result)) {
+ return ErrorExit("Error setting breakpoint at '%s': %s\n",
+ breakpoint_at,
+ Dart_GetError(result));
+ }
+ }
+
+ // Lookup and invoke the top level main function.
+ result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
if (Dart_IsError(result)) {
return ErrorExit("%s\n", Dart_GetError(result));
}
- }
-
- // Create a dart options object that can be accessed from dart code.
- Dart_Handle options_result =
- SetupRuntimeOptions(&dart_options, executable_name, script_name);
- if (Dart_IsError(options_result)) {
- return ErrorExit("%s\n", Dart_GetError(options_result));
- }
- // Lookup the library of the root script.
- Dart_Handle library = Dart_RootLibrary();
- if (Dart_IsNull(library)) {
- return ErrorExit("Unable to find root library for '%s'\n",
- script_name);
- }
- // Set debug breakpoint if specified on the command line.
- if (breakpoint_at != NULL) {
- result = SetBreakpoint(breakpoint_at, library);
+ // Keep handling messages until the last active receive port is closed.
+ result = Dart_RunLoop();
if (Dart_IsError(result)) {
- return ErrorExit("Error setting breakpoint at '%s': %s\n",
- breakpoint_at,
- Dart_GetError(result));
+ return ErrorExit("%s\n", Dart_GetError(result));
}
}
- // Lookup and invoke the top level main function.
- result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
- if (Dart_IsError(result)) {
- return ErrorExit("%s\n", Dart_GetError(result));
- }
- // Keep handling messages until the last active receive port is closed.
- result = Dart_RunLoop();
- if (Dart_IsError(result)) {
- return ErrorExit("%s\n", Dart_GetError(result));
- }
-
Dart_ExitScope();
// Shutdown the isolate.
Dart_ShutdownIsolate();
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 1285f13..dfde8f3 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -186,6 +186,7 @@
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
+ buffer = static_cast<void*>((static_cast<uint8_t*>(buffer) + offset));
bytes_written = Socket::Write(socket, buffer, length);
if (bytes_written > 0) total_bytes_written = bytes_written;
} else {
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 2966135..2e53b34 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -958,7 +958,7 @@
int length;
uint8_t* data;
void* peer;
- Dart_PeerFinalizer callback;
+ Dart_WeakPersistentHandleFinalizer callback;
} as_external_byte_array;
} value;
} Dart_CObject;
@@ -1631,7 +1631,22 @@
uint8_t* native_array,
intptr_t length);
-// --- Byte Arrays ---
+// --- Scalar Lists ---
+
+typedef enum {
+ kByteArray = 0,
+ kInt8,
+ kUint8,
+ kUint8Clamped,
+ kInt16,
+ kUint16,
+ kInt32,
+ kUint32,
+ kInt64,
+ kUint64,
+ kFloat32,
+ kFloat64
+} Dart_Scalar_Type;
/**
* Is this object a ByteArray?
@@ -1664,12 +1679,15 @@
* \param peer An external pointer to associate with this byte array.
*
* \return The ByteArray object if no error occurs. Otherwise returns
- * an error handle.
+ * an error handle. The ByteArray object is returned in a
+ * WeakPersistentHandle which needs to be deleted in the specified callback
+ * using Dart_DeletePersistentHandle.
*/
-DART_EXPORT Dart_Handle Dart_NewExternalByteArray(uint8_t* data,
- intptr_t length,
- void* peer,
- Dart_PeerFinalizer callback);
+DART_EXPORT Dart_Handle Dart_NewExternalByteArray(
+ uint8_t* data,
+ intptr_t length,
+ void* peer,
+ Dart_WeakPersistentHandleFinalizer callback);
/**
* Returns a clamped ByteArray which references an external array of
@@ -1683,13 +1701,15 @@
* \param peer An external pointer to associate with this byte array.
*
* \return The clamped ByteArray object if no error occurs. Otherwise returns
- * an error handle.
+ * an error handle. The clamped ByteArray object is returned in a
+ * WeakPersistentHandle which needs to be deleted in the specified callback
+ * using Dart_DeletePersistentHandle.
*/
DART_EXPORT Dart_Handle Dart_NewExternalClampedByteArray(
uint8_t* data,
intptr_t length,
void* peer,
- Dart_PeerFinalizer callback);
+ Dart_WeakPersistentHandleFinalizer callback);
/**
* Retrieves the data pointer associated with an external ByteArray.
@@ -1704,304 +1724,38 @@
void** peer);
/**
- * Gets an int8_t at some byte offset in a ByteArray.
+ * Acquires access to the internal data address of a scalar list object.
*
- * If the byte offset is out of bounds, an error occurs.
+ * \param array The scalar list object whose internal data address is to
+ * be accessed.
+ * \param type The scalar type of the object is returned here.
+ * \param data The internal data address is returned here.
+ * \param len Size of the byte array is returned here.
*
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int8_t.
+ * Note: When the internal address of the object is acquired any calls to a
+ * Dart API function that could potentially allocate an object or run
+ * any Dart code will return an error.
*
- * \return A valid handle if no error occurs during the operation.
+ * \return Success if the internal data address is acquired successfully.
+ * Otherwise, returns an error handle.
*/
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt8At(Dart_Handle array,
- intptr_t offset,
- int8_t* value);
+DART_EXPORT Dart_Handle Dart_ScalarListAcquireData(Dart_Handle array,
+ Dart_Scalar_Type* type,
+ void** data,
+ intptr_t* len);
/**
- * Sets an int8_t at some byte offset in a ByteArray.
+ * Releases access to the internal data address that was acquired earlier using
+ * Dart_ByteArrayAcquireData.
*
- * If the byte offset is out of bounds, an error occurs.
+ * \param array The scalar list object whose internal data address is to be
+ * released.
*
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int8_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
+ * \return Success if the internal data address is released successfully.
+ * Otherwise, returns an error handle.
*/
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt8At(Dart_Handle array,
- intptr_t offset,
- int8_t value);
+DART_EXPORT Dart_Handle Dart_ScalarListReleaseData(Dart_Handle array);
-/**
- * Gets a uint8_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint8_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint8At(Dart_Handle array,
- intptr_t offset,
- uint8_t* value);
-
-/**
- * Sets a uint8_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint8_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint8At(Dart_Handle array,
- intptr_t offset,
- uint8_t value);
-
-/**
- * Gets an int16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int16_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt16At(Dart_Handle array,
- intptr_t offset,
- int16_t* value);
-
-/**
- * Sets an int16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int16_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt16At(Dart_Handle array,
- intptr_t offset,
- int16_t value);
-
-/**
- * Gets a uint16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint16_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint16At(Dart_Handle array,
- intptr_t offset,
- uint16_t* value);
-
-/**
- * Sets a uint16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint16_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint16At(Dart_Handle array,
- intptr_t offset,
- uint16_t value);
-
-/**
- * Gets an int32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int32_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt32At(Dart_Handle array,
- intptr_t offset,
- int32_t* value);
-
-/**
- * Sets an int32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int32_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt32At(Dart_Handle array,
- intptr_t offset,
- int32_t value);
-
-/**
- * Gets a uint32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint32_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint32At(Dart_Handle array,
- intptr_t offset,
- uint32_t* value);
-
-/**
- * Sets a uint32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint32_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint32At(Dart_Handle array,
- intptr_t offset,
- uint32_t value);
-
-/**
- * Gets an int64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int64_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt64At(Dart_Handle array,
- intptr_t offset,
- int64_t* value);
-
-/**
- * Sets an int64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int64_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt64At(Dart_Handle array,
- intptr_t offset,
- int64_t value);
-
-/**
- * Gets a uint64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint64_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint64At(Dart_Handle array,
- intptr_t offset,
- uint64_t* value);
-
-/**
- * Sets a uint64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint64_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint64At(Dart_Handle array,
- intptr_t offset,
- uint64_t value);
-
-/**
- * Gets a float at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the float.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat32At(Dart_Handle array,
- intptr_t offset,
- float* value);
-
-/**
- * Sets a float at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The float to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat32At(Dart_Handle array,
- intptr_t offset,
- float value);
-
-/**
- * Gets a double from some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the double.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat64At(Dart_Handle array,
- intptr_t offset,
- double* value);
-
-/**
- * Sets a double at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The double to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat64At(Dart_Handle array,
- intptr_t offset,
- double value);
// --- Closures ---
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index e7c4bee..f72191d 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -34,6 +34,7 @@
"Cannot remove element of a non-extendable array");
}
+ // Collection interface.
void removeAll(Iterable elements) {
throw new UnsupportedError(
"Cannot remove element of a non-extendable array");
@@ -54,6 +55,7 @@
"Cannot remove element of a non-extendable array");
}
+ // List interface.
void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
if (length < 0) {
throw new ArgumentError("negative length $length");
@@ -84,7 +86,7 @@
return list;
}
- // Collection interface.
+ // Iterable interface.
bool contains(E element) {
return IterableMixinWorkaround.contains(this, element);
@@ -98,8 +100,12 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(E element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(E element)) {
- return IterableMixinWorkaround.mappedByList(this, f);
+ IterableMixinWorkaround.mappedByList(this, f);
}
reduce(initialValue, combine(previousValue, E element)) {
@@ -110,7 +116,7 @@
return IterableMixinWorkaround.where(this, f);
}
- List<E> take(int n) {
+ Iterable<E> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -118,7 +124,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<E> skip(int n) {
+ Iterable<E> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -324,6 +330,10 @@
IterableMixinWorkaround.forEach(this, f);
}
+ Iterable map(f(E element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(E element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -340,7 +350,7 @@
return IterableMixinWorkaround.where(this, f);
}
- List<E> take(int n) {
+ Iterable<E> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -348,7 +358,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<E> skip(int n) {
+ Iterable<E> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index 109d951..da5bf73 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -27,21 +27,6 @@
return result;
}
- /* patch */ factory List.filled(int length, E fill) {
- if ((length is! int) || (length < 0)) {
- _throwArgumentError(length);
- }
- _GrowableObjectArray<E> result =
- new _GrowableObjectArray<E>.withCapacity(length < 4 ? 4 : length);
- result.length = length;
- if (fill != null) {
- for (int i = 0; i < length; i++) {
- result[i] = fill;
- }
- }
- return result;
- }
-
// Factory constructing a mutable List from a parser generated List literal.
// [elements] contains elements that are already type checked.
factory List._fromLiteral(List elements) {
diff --git a/runtime/lib/byte_array.cc b/runtime/lib/byte_array.cc
index 361c883..a96d211 100644
--- a/runtime/lib/byte_array.cc
+++ b/runtime/lib/byte_array.cc
@@ -4,6 +4,8 @@
#include "vm/bootstrap_natives.h"
+#include "include/dart_api.h"
+
#include "vm/bigint_operations.h"
#include "vm/exceptions.h"
#include "vm/native_entry.h"
@@ -292,6 +294,12 @@
}
+static void PeerFinalizer(Dart_Handle handle, void* peer) {
+ Dart_DeletePersistentHandle(handle);
+ OS::AlignedFree(peer);
+}
+
+
// Int8Array
DEFINE_NATIVE_ENTRY(Int8Array_new, 1) {
@@ -303,16 +311,15 @@
DEFINE_NATIVE_ENTRY(Int8List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Int8Array::kMaxElements);
- int8_t* bytes = OS::AllocateAlignedArray<int8_t>(
- len,
- ExternalByteArrayData<int8_t>::kAlignment);
- return ExternalInt8Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ int8_t* bytes = OS::AllocateAlignedArray<int8_t>(len, kAlignment);
+ const ExternalInt8Array& obj =
+ ExternalInt8Array::Handle(ExternalInt8Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -337,16 +344,15 @@
DEFINE_NATIVE_ENTRY(Uint8List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Uint8Array::kMaxElements);
- uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(
- len,
- ExternalByteArrayData<uint8_t>::kAlignment);
- return ExternalUint8Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(len, kAlignment);
+ const ExternalUint8Array& obj =
+ ExternalUint8Array::Handle(ExternalUint8Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -371,16 +377,15 @@
DEFINE_NATIVE_ENTRY(Uint8ClampedList_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Uint8ClampedArray::kMaxElements);
- uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(
- len,
- ExternalByteArrayData<uint8_t>::kAlignment);
- return ExternalUint8ClampedArray::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(len, kAlignment);
+ const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle(
+ ExternalUint8ClampedArray::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -405,16 +410,15 @@
DEFINE_NATIVE_ENTRY(Int16List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Int16Array::kMaxElements);
- int16_t* bytes = OS::AllocateAlignedArray<int16_t>(
- len,
- ExternalByteArrayData<int16_t>::kAlignment);
- return ExternalInt16Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ int16_t* bytes = OS::AllocateAlignedArray<int16_t>(len, kAlignment);
+ const ExternalInt16Array& obj =
+ ExternalInt16Array::Handle(ExternalInt16Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -439,16 +443,15 @@
DEFINE_NATIVE_ENTRY(Uint16List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Uint16Array::kMaxElements);
- uint16_t* bytes = OS::AllocateAlignedArray<uint16_t>(
- len,
- ExternalByteArrayData<uint16_t>::kAlignment);
- return ExternalUint16Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ uint16_t* bytes = OS::AllocateAlignedArray<uint16_t>(len, kAlignment);
+ const ExternalUint16Array& obj =
+ ExternalUint16Array::Handle(ExternalUint16Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -473,16 +476,15 @@
DEFINE_NATIVE_ENTRY(Int32List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Int32Array::kMaxElements);
- int32_t* bytes = OS::AllocateAlignedArray<int32_t>(
- len,
- ExternalByteArrayData<int32_t>::kAlignment);
- return ExternalInt32Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ int32_t* bytes = OS::AllocateAlignedArray<int32_t>(len, kAlignment);
+ const ExternalInt32Array& obj =
+ ExternalInt32Array::Handle(ExternalInt32Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -507,16 +509,15 @@
DEFINE_NATIVE_ENTRY(Uint32List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Uint32Array::kMaxElements);
- uint32_t* bytes = OS::AllocateAlignedArray<uint32_t>(
- len,
- ExternalByteArrayData<uint32_t>::kAlignment);
- return ExternalUint32Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ uint32_t* bytes = OS::AllocateAlignedArray<uint32_t>(len, kAlignment);
+ const ExternalUint32Array& obj =
+ ExternalUint32Array::Handle(ExternalUint32Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -541,16 +542,15 @@
DEFINE_NATIVE_ENTRY(Int64List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Int64Array::kMaxElements);
- int64_t* bytes = OS::AllocateAlignedArray<int64_t>(
- len,
- ExternalByteArrayData<int64_t>::kAlignment);
- return ExternalInt64Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ int64_t* bytes = OS::AllocateAlignedArray<int64_t>(len, kAlignment);
+ const ExternalInt64Array& obj =
+ ExternalInt64Array::Handle(ExternalInt64Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -575,16 +575,15 @@
DEFINE_NATIVE_ENTRY(Uint64List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Uint64Array::kMaxElements);
- uint64_t* bytes = OS::AllocateAlignedArray<uint64_t>(
- len,
- ExternalByteArrayData<uint64_t>::kAlignment);
- return ExternalUint64Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ uint64_t* bytes = OS::AllocateAlignedArray<uint64_t>(len, kAlignment);
+ const ExternalUint64Array& obj =
+ ExternalUint64Array::Handle(ExternalUint64Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -609,16 +608,15 @@
DEFINE_NATIVE_ENTRY(Float32List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Float32Array::kMaxElements);
- float* bytes = OS::AllocateAlignedArray<float>(
- len,
- ExternalByteArrayData<float>::kAlignment);
- return ExternalFloat32Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ float* bytes = OS::AllocateAlignedArray<float>(len, kAlignment);
+ const ExternalFloat32Array& obj =
+ ExternalFloat32Array::Handle(ExternalFloat32Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
@@ -643,16 +641,15 @@
DEFINE_NATIVE_ENTRY(Float64List_newTransferable, 1) {
+ const int kAlignment = 16;
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
intptr_t len = length.Value();
LengthCheck(len, Float64Array::kMaxElements);
- double* bytes = OS::AllocateAlignedArray<double>(
- len,
- ExternalByteArrayData<double>::kAlignment);
- return ExternalFloat64Array::New(bytes,
- len,
- bytes,
- OS::AlignedFree);
+ double* bytes = OS::AllocateAlignedArray<double>(len, kAlignment);
+ const ExternalFloat64Array& obj =
+ ExternalFloat64Array::Handle(ExternalFloat64Array::New(bytes, len));
+ obj.AddFinalizer(bytes, PeerFinalizer);
+ return obj.raw();
}
diff --git a/runtime/lib/byte_array.dart b/runtime/lib/byte_array.dart
index 9794eba4c..74e2c3a 100644
--- a/runtime/lib/byte_array.dart
+++ b/runtime/lib/byte_array.dart
@@ -229,6 +229,10 @@
}
}
+ Iterable map(f(int element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(int element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -246,7 +250,7 @@
return IterableMixinWorkaround.where(this, f);
}
- List<int> take(int n) {
+ Iterable<int> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -254,7 +258,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) {
+ Iterable<int> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 7067658..2d3c5f8 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -7,6 +7,7 @@
#include "vm/bootstrap_natives.h"
#include "vm/bigint_operations.h"
+#include "vm/code_generator.h" // DartModulo.
#include "vm/double_conversion.h"
#include "vm/exceptions.h"
#include "vm/native_entry.h"
@@ -103,19 +104,7 @@
double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
double right = right_object.value();
-
- 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;
- } else if (remainder < 0) {
- if (right < 0) {
- remainder -= right;
- } else {
- remainder += right;
- }
- }
- return Double::New(remainder);
+ return Double::New(DartModulo(left, right));
}
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 39e35fd..cd31864 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -242,6 +242,10 @@
return buffer.toString();
}
+ Iterable map(f(T element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(T element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -254,7 +258,7 @@
return IterableMixinWorkaround.where(this, f);
}
- List<T> take(int n) {
+ Iterable<T> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -262,7 +266,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<T> skip(int n) {
+ Iterable<T> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
diff --git a/runtime/tests/vm/dart/optimized_stacktrace_test.dart b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
new file mode 100644
index 0000000..c3e24ba
--- /dev/null
+++ b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test correct source positions in stack trace with optimized functions.
+
+// (1) Test normal exception.
+foo(x) => bar(x);
+
+bar(x) {
+ if (x == null) throw 42; // throw at position 11:18
+ return x + 1;
+}
+
+test1() {
+ // First unoptimized.
+ try {
+ foo(null);
+ Expect.fail("Unreachable");
+ } catch (e, stacktrace) {
+ String s = stacktrace.toString();
+ Expect.equals(-1, s.indexOf("-1:-1"));
+ Expect.notEquals(-1, s.indexOf("11:18"));
+ }
+
+ // Optimized.
+ for (var i=0; i<10000; i++) foo(42);
+ try {
+ foo(null);
+ Expect.fail("Unreachable");
+ } catch (e, stacktrace) {
+ String s = stacktrace.toString();
+ Expect.equals(-1, s.indexOf("-1:-1"));
+ Expect.notEquals(-1, s.indexOf("11:18"));
+ }
+}
+
+
+// (2) Test checked mode exceptions.
+maximus(x) => moritz(x);
+
+moritz(x) {
+ if (x == 333) return 42 ? 0 : 1; // Throws in checked mode.
+ if (x == 777) {
+ bool b = x; // Throws in checked mode.
+ return b;
+ }
+
+ return x + 1;
+}
+
+test2() {
+ for (var i=0; i<100000; i++) maximus(42);
+ try {
+ maximus(333);
+ } catch (e, stacktrace) {
+ String s = stacktrace.toString();
+ print(s);
+ Expect.notEquals(-1, s.indexOf("maximus"));
+ Expect.notEquals(-1, s.indexOf("moritz"));
+ Expect.equals(-1, s.indexOf("-1:-1"));
+ }
+
+ try {
+ maximus(777);
+ } catch (e, stacktrace) {
+ String s = stacktrace.toString();
+ print(s);
+ Expect.notEquals(-1, s.indexOf("maximus"));
+ Expect.notEquals(-1, s.indexOf("moritz"));
+ Expect.equals(-1, s.indexOf("-1:-1"));
+ }
+}
+
+main() {
+ test1();
+ test2();
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index c88b455..c944645 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -34,6 +34,10 @@
dart/byte_array_test: Skip # compilers not aware of byte arrays
dart/isolate_unhandled*: Skip
+[ $compiler == dart2js ]
+# The source positions do not match with dart2js.
+dart/optimized_stacktrace_test: Fail
+
[ $compiler == dart2js && $minified ]
# Methods in stack traces are renamed.
dart/inline_stack_frame_test: Fail # Issue 7953.
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index 261fdaf..64a7716 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -13,6 +13,10 @@
namespace dart {
+DEFINE_FLAG(bool, code_comments, false,
+ "Include comments into code and disassembly");
+
+
static uword NewContents(intptr_t capacity) {
Zone* zone = Isolate::Current()->current_zone();
uword result = zone->AllocUnsafe(capacity);
@@ -185,4 +189,31 @@
Stop(buffer);
}
+
+void Assembler::Comment(const char* format, ...) {
+ if (FLAG_code_comments) {
+ char buffer[1024];
+
+ va_list args;
+ va_start(args, format);
+ OS::VSNPrint(buffer, sizeof(buffer), format, args);
+ va_end(args);
+
+ comments_.Add(new CodeComment(buffer_.GetPosition(),
+ String::Handle(String::New(buffer))));
+ }
+}
+
+
+const Code::Comments& Assembler::GetCodeComments() const {
+ Code::Comments& comments = Code::Comments::New(comments_.length());
+
+ for (intptr_t i = 0; i < comments_.length(); i++) {
+ comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
+ comments.SetCommentAt(i, comments_[i]->comment());
+ }
+
+ return comments;
+}
+
} // namespace dart
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 4a64fc3..817a58f 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -10,8 +10,1489 @@
namespace dart {
DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
- "Include comments into code and disassembly");
+
+
+// Instruction encoding bits.
+enum {
+ H = 1 << 5, // halfword (or byte)
+ L = 1 << 20, // load (or store)
+ S = 1 << 20, // set condition code (or leave unchanged)
+ W = 1 << 21, // writeback base register (or leave unchanged)
+ A = 1 << 21, // accumulate in multiply instruction (or not)
+ B = 1 << 22, // unsigned byte (or word)
+ N = 1 << 22, // long (or short)
+ U = 1 << 23, // positive (or negative) offset/index
+ P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing)
+ I = 1 << 25, // immediate shifter operand (or not)
+
+ B0 = 1,
+ B1 = 1 << 1,
+ B2 = 1 << 2,
+ B3 = 1 << 3,
+ B4 = 1 << 4,
+ B5 = 1 << 5,
+ B6 = 1 << 6,
+ B7 = 1 << 7,
+ B8 = 1 << 8,
+ B9 = 1 << 9,
+ B10 = 1 << 10,
+ B11 = 1 << 11,
+ B12 = 1 << 12,
+ B16 = 1 << 16,
+ B17 = 1 << 17,
+ B18 = 1 << 18,
+ B19 = 1 << 19,
+ B20 = 1 << 20,
+ B21 = 1 << 21,
+ B22 = 1 << 22,
+ B23 = 1 << 23,
+ B24 = 1 << 24,
+ B25 = 1 << 25,
+ B26 = 1 << 26,
+ B27 = 1 << 27,
+
+ // ldrex/strex register field encodings.
+ kLdExRnShift = 16,
+ kLdExRtShift = 12,
+ kStrExRnShift = 16,
+ kStrExRdShift = 12,
+ kStrExRtShift = 0,
+};
+
+
+uint32_t Address::encoding3() const {
+ const uint32_t offset_mask = (1 << 12) - 1;
+ uint32_t offset = encoding_ & offset_mask;
+ ASSERT(offset < 256);
+ return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
+}
+
+
+uint32_t Address::vencoding() const {
+ const uint32_t offset_mask = (1 << 12) - 1;
+ uint32_t offset = encoding_ & offset_mask;
+ ASSERT(offset < (1 << 10)); // In the range 0 to +1020.
+ ASSERT(Utils::Utils::IsAligned(offset, 2)); // Multiple of 4.
+ int mode = encoding_ & ((8|4|1) << 21);
+ ASSERT((mode == Offset) || (mode == NegOffset));
+ uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
+ if (mode == Offset) {
+ vencoding |= 1 << 23;
+ }
+ return vencoding;
+}
+
+
+void Assembler::Emit(int32_t value) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ buffer_.Emit<int32_t>(value);
+}
+
+
+void Assembler::EmitType01(Condition cond,
+ int type,
+ Opcode opcode,
+ int set_cc,
+ Register rn,
+ Register rd,
+ ShifterOperand so) {
+ ASSERT(rd != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+ type << kTypeShift |
+ static_cast<int32_t>(opcode) << kOpcodeShift |
+ set_cc << kSShift |
+ static_cast<int32_t>(rn) << kRnShift |
+ static_cast<int32_t>(rd) << kRdShift |
+ so.encoding();
+ Emit(encoding);
+}
+
+
+void Assembler::EmitType5(Condition cond, int offset, bool link) {
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+ 5 << kTypeShift |
+ (link ? 1 : 0) << kLinkShift;
+ Emit(Assembler::EncodeBranchOffset(offset, encoding));
+}
+
+
+void Assembler::EmitMemOp(Condition cond,
+ bool load,
+ bool byte,
+ Register rd,
+ Address ad) {
+ ASSERT(rd != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B26 |
+ (load ? L : 0) |
+ (byte ? B : 0) |
+ (static_cast<int32_t>(rd) << kRdShift) |
+ ad.encoding();
+ Emit(encoding);
+}
+
+
+void Assembler::EmitMemOpAddressMode3(Condition cond,
+ int32_t mode,
+ Register rd,
+ Address ad) {
+ ASSERT(rd != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B22 |
+ mode |
+ (static_cast<int32_t>(rd) << kRdShift) |
+ ad.encoding3();
+ Emit(encoding);
+}
+
+
+void Assembler::EmitMultiMemOp(Condition cond,
+ BlockAddressMode am,
+ bool load,
+ Register base,
+ RegList regs) {
+ ASSERT(base != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 |
+ am |
+ (load ? L : 0) |
+ (static_cast<int32_t>(base) << kRnShift) |
+ regs;
+ Emit(encoding);
+}
+
+
+void Assembler::EmitShiftImmediate(Condition cond,
+ Shift opcode,
+ Register rd,
+ Register rm,
+ ShifterOperand so) {
+ ASSERT(cond != kNoCondition);
+ ASSERT(so.type() == 1);
+ int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+ static_cast<int32_t>(MOV) << kOpcodeShift |
+ static_cast<int32_t>(rd) << kRdShift |
+ so.encoding() << kShiftImmShift |
+ static_cast<int32_t>(opcode) << kShiftShift |
+ static_cast<int32_t>(rm);
+ Emit(encoding);
+}
+
+
+void Assembler::EmitShiftRegister(Condition cond,
+ Shift opcode,
+ Register rd,
+ Register rm,
+ ShifterOperand so) {
+ ASSERT(cond != kNoCondition);
+ ASSERT(so.type() == 0);
+ int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+ static_cast<int32_t>(MOV) << kOpcodeShift |
+ static_cast<int32_t>(rd) << kRdShift |
+ so.encoding() << kShiftRegisterShift |
+ static_cast<int32_t>(opcode) << kShiftShift |
+ B4 |
+ static_cast<int32_t>(rm);
+ Emit(encoding);
+}
+
+
+void Assembler::EmitBranch(Condition cond, Label* label, bool link) {
+ if (label->IsBound()) {
+ EmitType5(cond, label->Position() - buffer_.Size(), link);
+ } else {
+ int position = buffer_.Size();
+ // Use the offset field of the branch instruction for linking the sites.
+ EmitType5(cond, label->position_, link);
+ label->LinkTo(position);
+ }
+}
+
+
+void Assembler::and_(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), AND, 0, rn, rd, so);
+}
+
+
+void Assembler::eor(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
+}
+
+
+void Assembler::sub(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
+}
+
+void Assembler::rsb(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
+}
+
+void Assembler::rsbs(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
+}
+
+
+void Assembler::add(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
+}
+
+
+void Assembler::adds(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
+}
+
+
+void Assembler::subs(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
+}
+
+
+void Assembler::adc(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
+}
+
+
+void Assembler::sbc(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
+}
+
+
+void Assembler::rsc(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
+}
+
+
+void Assembler::tst(Register rn, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), TST, 1, rn, R0, so);
+}
+
+
+void Assembler::teq(Register rn, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
+}
+
+
+void Assembler::cmp(Register rn, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
+}
+
+
+void Assembler::cmn(Register rn, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
+}
+
+
+void Assembler::orr(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
+}
+
+
+void Assembler::orrs(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
+}
+
+
+void Assembler::mov(Register rd, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
+}
+
+
+void Assembler::movs(Register rd, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
+}
+
+
+void Assembler::bic(Register rd, Register rn, ShifterOperand so,
+ Condition cond) {
+ EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
+}
+
+
+void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
+}
+
+
+void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) {
+ EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
+}
+
+
+void Assembler::clz(Register rd, Register rm, Condition cond) {
+ ASSERT(rd != kNoRegister);
+ ASSERT(rm != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ ASSERT(rd != PC);
+ ASSERT(rm != PC);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B24 | B22 | B21 | (0xf << 16) |
+ (static_cast<int32_t>(rd) << kRdShift) |
+ (0xf << 8) | B4 | static_cast<int32_t>(rm);
+ Emit(encoding);
+}
+
+
+void Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+ B25 | B24 | ((imm16 >> 12) << 16) |
+ static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
+ Emit(encoding);
+}
+
+
+void Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+ B25 | B24 | B22 | ((imm16 >> 12) << 16) |
+ static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
+ Emit(encoding);
+}
+
+
+void Assembler::EmitMulOp(Condition cond, int32_t opcode,
+ Register rd, Register rn,
+ Register rm, Register rs) {
+ ASSERT(rd != kNoRegister);
+ ASSERT(rn != kNoRegister);
+ ASSERT(rm != kNoRegister);
+ ASSERT(rs != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = opcode |
+ (static_cast<int32_t>(cond) << kConditionShift) |
+ (static_cast<int32_t>(rn) << kRnShift) |
+ (static_cast<int32_t>(rd) << kRdShift) |
+ (static_cast<int32_t>(rs) << kRsShift) |
+ B7 | B4 |
+ (static_cast<int32_t>(rm) << kRmShift);
+ Emit(encoding);
+}
+
+
+void Assembler::mul(Register rd, Register rn,
+ Register rm, Condition cond) {
+ // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
+ EmitMulOp(cond, 0, R0, rd, rn, rm);
+}
+
+
+void Assembler::mla(Register rd, Register rn,
+ Register rm, Register ra, Condition cond) {
+ // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
+ EmitMulOp(cond, B21, ra, rd, rn, rm);
+}
+
+
+void Assembler::mls(Register rd, Register rn,
+ Register rm, Register ra, Condition cond) {
+ // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
+ EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
+}
+
+
+void Assembler::umull(Register rd_lo, Register rd_hi,
+ Register rn, Register rm, Condition cond) {
+ // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
+ EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
+}
+
+
+void Assembler::ldr(Register rd, Address ad, Condition cond) {
+ EmitMemOp(cond, true, false, rd, ad);
+}
+
+
+void Assembler::str(Register rd, Address ad, Condition cond) {
+ EmitMemOp(cond, false, false, rd, ad);
+}
+
+
+void Assembler::ldrb(Register rd, Address ad, Condition cond) {
+ EmitMemOp(cond, true, true, rd, ad);
+}
+
+
+void Assembler::strb(Register rd, Address ad, Condition cond) {
+ EmitMemOp(cond, false, true, rd, ad);
+}
+
+
+void Assembler::ldrh(Register rd, Address ad, Condition cond) {
+ EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
+}
+
+
+void Assembler::strh(Register rd, Address ad, Condition cond) {
+ EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
+}
+
+
+void Assembler::ldrsb(Register rd, Address ad, Condition cond) {
+ EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
+}
+
+
+void Assembler::ldrsh(Register rd, Address ad, Condition cond) {
+ EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
+}
+
+
+void Assembler::ldrd(Register rd, Address ad, Condition cond) {
+ ASSERT((rd % 2) == 0);
+ EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
+}
+
+
+void Assembler::strd(Register rd, Address ad, Condition cond) {
+ ASSERT((rd % 2) == 0);
+ EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
+}
+
+
+void Assembler::ldm(BlockAddressMode am, Register base, RegList regs,
+ Condition cond) {
+ EmitMultiMemOp(cond, am, true, base, regs);
+}
+
+
+void Assembler::stm(BlockAddressMode am, Register base, RegList regs,
+ Condition cond) {
+ EmitMultiMemOp(cond, am, false, base, regs);
+}
+
+
+void Assembler::ldrex(Register rt, Register rn, Condition cond) {
+ ASSERT(rn != kNoRegister);
+ ASSERT(rt != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B24 |
+ B23 |
+ L |
+ (static_cast<int32_t>(rn) << kLdExRnShift) |
+ (static_cast<int32_t>(rt) << kLdExRtShift) |
+ B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
+ Emit(encoding);
+}
+
+
+void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
+ ASSERT(rn != kNoRegister);
+ ASSERT(rd != kNoRegister);
+ ASSERT(rt != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B24 |
+ B23 |
+ (static_cast<int32_t>(rn) << kStrExRnShift) |
+ (static_cast<int32_t>(rd) << kStrExRdShift) |
+ B11 | B10 | B9 | B8 | B7 | B4 |
+ (static_cast<int32_t>(rt) << kStrExRtShift);
+ Emit(encoding);
+}
+
+
+void Assembler::clrex() {
+ int32_t encoding = (kSpecialCondition << kConditionShift) |
+ B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
+ Emit(encoding);
+}
+
+
+void Assembler::nop(Condition cond) {
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B25 | B24 | B21 | (0xf << 12);
+ Emit(encoding);
+}
+
+
+void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
+ ASSERT(sn != kNoSRegister);
+ ASSERT(rt != kNoRegister);
+ ASSERT(rt != SP);
+ ASSERT(rt != PC);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 |
+ ((static_cast<int32_t>(sn) >> 1)*B16) |
+ (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+ ((static_cast<int32_t>(sn) & 1)*B7) | B4;
+ Emit(encoding);
+}
+
+
+void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
+ ASSERT(sn != kNoSRegister);
+ ASSERT(rt != kNoRegister);
+ ASSERT(rt != SP);
+ ASSERT(rt != PC);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 | B20 |
+ ((static_cast<int32_t>(sn) >> 1)*B16) |
+ (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+ ((static_cast<int32_t>(sn) & 1)*B7) | B4;
+ Emit(encoding);
+}
+
+
+void Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
+ Condition cond) {
+ ASSERT(sm != kNoSRegister);
+ ASSERT(sm != S31);
+ ASSERT(rt != kNoRegister);
+ ASSERT(rt != SP);
+ ASSERT(rt != PC);
+ ASSERT(rt2 != kNoRegister);
+ ASSERT(rt2 != SP);
+ ASSERT(rt2 != PC);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B22 |
+ (static_cast<int32_t>(rt2)*B16) |
+ (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+ ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
+ (static_cast<int32_t>(sm) >> 1);
+ Emit(encoding);
+}
+
+
+void Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
+ Condition cond) {
+ ASSERT(sm != kNoSRegister);
+ ASSERT(sm != S31);
+ ASSERT(rt != kNoRegister);
+ ASSERT(rt != SP);
+ ASSERT(rt != PC);
+ ASSERT(rt2 != kNoRegister);
+ ASSERT(rt2 != SP);
+ ASSERT(rt2 != PC);
+ ASSERT(rt != rt2);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B22 | B20 |
+ (static_cast<int32_t>(rt2)*B16) |
+ (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+ ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
+ (static_cast<int32_t>(sm) >> 1);
+ Emit(encoding);
+}
+
+
+void Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
+ Condition cond) {
+ ASSERT(dm != kNoDRegister);
+ ASSERT(rt != kNoRegister);
+ ASSERT(rt != SP);
+ ASSERT(rt != PC);
+ ASSERT(rt2 != kNoRegister);
+ ASSERT(rt2 != SP);
+ ASSERT(rt2 != PC);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B22 |
+ (static_cast<int32_t>(rt2)*B16) |
+ (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
+ ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
+ (static_cast<int32_t>(dm) & 0xf);
+ Emit(encoding);
+}
+
+
+void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
+ Condition cond) {
+ ASSERT(dm != kNoDRegister);
+ ASSERT(rt != kNoRegister);
+ ASSERT(rt != SP);
+ ASSERT(rt != PC);
+ ASSERT(rt2 != kNoRegister);
+ ASSERT(rt2 != SP);
+ ASSERT(rt2 != PC);
+ ASSERT(rt != rt2);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B22 | B20 |
+ (static_cast<int32_t>(rt2)*B16) |
+ (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
+ ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
+ (static_cast<int32_t>(dm) & 0xf);
+ Emit(encoding);
+}
+
+
+void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
+ ASSERT(sd != kNoSRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B24 | B20 |
+ ((static_cast<int32_t>(sd) & 1)*B22) |
+ ((static_cast<int32_t>(sd) >> 1)*B12) |
+ B11 | B9 | ad.vencoding();
+ Emit(encoding);
+}
+
+
+void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
+ ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
+ ASSERT(sd != kNoSRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B24 |
+ ((static_cast<int32_t>(sd) & 1)*B22) |
+ ((static_cast<int32_t>(sd) >> 1)*B12) |
+ B11 | B9 | ad.vencoding();
+ Emit(encoding);
+}
+
+
+void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
+ ASSERT(dd != kNoDRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B24 | B20 |
+ ((static_cast<int32_t>(dd) >> 4)*B22) |
+ ((static_cast<int32_t>(dd) & 0xf)*B12) |
+ B11 | B9 | B8 | ad.vencoding();
+ Emit(encoding);
+}
+
+
+void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
+ ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
+ ASSERT(dd != kNoDRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B24 |
+ ((static_cast<int32_t>(dd) >> 4)*B22) |
+ ((static_cast<int32_t>(dd) & 0xf)*B12) |
+ B11 | B9 | B8 | ad.vencoding();
+ Emit(encoding);
+}
+
+
+void Assembler::EmitVFPsss(Condition cond, int32_t opcode,
+ SRegister sd, SRegister sn, SRegister sm) {
+ ASSERT(sd != kNoSRegister);
+ ASSERT(sn != kNoSRegister);
+ ASSERT(sm != kNoSRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 | B11 | B9 | opcode |
+ ((static_cast<int32_t>(sd) & 1)*B22) |
+ ((static_cast<int32_t>(sn) >> 1)*B16) |
+ ((static_cast<int32_t>(sd) >> 1)*B12) |
+ ((static_cast<int32_t>(sn) & 1)*B7) |
+ ((static_cast<int32_t>(sm) & 1)*B5) |
+ (static_cast<int32_t>(sm) >> 1);
+ Emit(encoding);
+}
+
+
+void Assembler::EmitVFPddd(Condition cond, int32_t opcode,
+ DRegister dd, DRegister dn, DRegister dm) {
+ ASSERT(dd != kNoDRegister);
+ ASSERT(dn != kNoDRegister);
+ ASSERT(dm != kNoDRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 | B11 | B9 | B8 | opcode |
+ ((static_cast<int32_t>(dd) >> 4)*B22) |
+ ((static_cast<int32_t>(dn) & 0xf)*B16) |
+ ((static_cast<int32_t>(dd) & 0xf)*B12) |
+ ((static_cast<int32_t>(dn) >> 4)*B7) |
+ ((static_cast<int32_t>(dm) >> 4)*B5) |
+ (static_cast<int32_t>(dm) & 0xf);
+ Emit(encoding);
+}
+
+
+void Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
+ EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
+}
+
+
+bool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
+ uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
+ if (((imm32 & ((1 << 19) - 1)) == 0) &&
+ ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
+ (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
+ uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
+ ((imm32 >> 19) & ((1 << 6) -1));
+ EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
+ sd, S0, S0);
+ return true;
+ }
+ return false;
+}
+
+
+bool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
+ uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
+ if (((imm64 & ((1LL << 48) - 1)) == 0) &&
+ ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
+ (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
+ uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
+ ((imm64 >> 48) & ((1 << 6) -1));
+ EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
+ dd, D0, D0);
+ return true;
+ }
+ return false;
+}
+
+
+void Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
+ Condition cond) {
+ EmitVFPsss(cond, B21 | B20, sd, sn, sm);
+}
+
+
+void Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
+ Condition cond) {
+ EmitVFPddd(cond, B21 | B20, dd, dn, dm);
+}
+
+
+void Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
+ Condition cond) {
+ EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
+}
+
+
+void Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
+ Condition cond) {
+ EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
+}
+
+
+void Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
+ Condition cond) {
+ EmitVFPsss(cond, B21, sd, sn, sm);
+}
+
+
+void Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
+ Condition cond) {
+ EmitVFPddd(cond, B21, dd, dn, dm);
+}
+
+
+void Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
+ Condition cond) {
+ EmitVFPsss(cond, 0, sd, sn, sm);
+}
+
+
+void Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
+ Condition cond) {
+ EmitVFPddd(cond, 0, dd, dn, dm);
+}
+
+
+void Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
+ Condition cond) {
+ EmitVFPsss(cond, B6, sd, sn, sm);
+}
+
+
+void Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
+ Condition cond) {
+ EmitVFPddd(cond, B6, dd, dn, dm);
+}
+
+
+void Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
+ Condition cond) {
+ EmitVFPsss(cond, B23, sd, sn, sm);
+}
+
+
+void Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
+ Condition cond) {
+ EmitVFPddd(cond, B23, dd, dn, dm);
+}
+
+
+void Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
+ EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
+}
+
+
+void Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
+ EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
+}
+
+
+void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
+}
+
+void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
+ EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
+}
+
+
+void Assembler::EmitVFPsd(Condition cond, int32_t opcode,
+ SRegister sd, DRegister dm) {
+ ASSERT(sd != kNoSRegister);
+ ASSERT(dm != kNoDRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 | B11 | B9 | opcode |
+ ((static_cast<int32_t>(sd) & 1)*B22) |
+ ((static_cast<int32_t>(sd) >> 1)*B12) |
+ ((static_cast<int32_t>(dm) >> 4)*B5) |
+ (static_cast<int32_t>(dm) & 0xf);
+ Emit(encoding);
+}
+
+
+void Assembler::EmitVFPds(Condition cond, int32_t opcode,
+ DRegister dd, SRegister sm) {
+ ASSERT(dd != kNoDRegister);
+ ASSERT(sm != kNoSRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 | B11 | B9 | opcode |
+ ((static_cast<int32_t>(dd) >> 4)*B22) |
+ ((static_cast<int32_t>(dd) & 0xf)*B12) |
+ ((static_cast<int32_t>(sm) & 1)*B5) |
+ (static_cast<int32_t>(sm) >> 1);
+ Emit(encoding);
+}
+
+
+void Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
+ EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
+}
+
+
+void Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
+ EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
+}
+
+
+void Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
+ EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
+}
+
+
+void Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
+ EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
+}
+
+
+void Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
+ EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
+}
+
+
+void Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
+ EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
+}
+
+
+void Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
+ EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
+}
+
+
+void Assembler::vcmpsz(SRegister sd, Condition cond) {
+ EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
+}
+
+
+void Assembler::vcmpdz(DRegister dd, Condition cond) {
+ EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
+}
+
+
+void Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
+ (static_cast<int32_t>(PC)*B12) |
+ B11 | B9 | B4;
+ Emit(encoding);
+}
+
+
+void Assembler::svc(uint32_t imm24) {
+ ASSERT(imm24 < (1 << 24));
+ int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
+ Emit(encoding);
+}
+
+
+void Assembler::bkpt(uint16_t imm16) {
+ int32_t encoding = (AL << kConditionShift) | B24 | B21 |
+ ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
+ Emit(encoding);
+}
+
+
+void Assembler::b(Label* label, Condition cond) {
+ EmitBranch(cond, label, false);
+}
+
+
+void Assembler::bl(Label* label, Condition cond) {
+ EmitBranch(cond, label, true);
+}
+
+
+void Assembler::blx(Register rm, Condition cond) {
+ ASSERT(rm != kNoRegister);
+ ASSERT(cond != kNoCondition);
+ int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+ B24 | B21 | (0xfff << 8) | B5 | B4 |
+ (static_cast<int32_t>(rm) << kRmShift);
+ Emit(encoding);
+}
+
+
+void Assembler::MarkExceptionHandler(Label* label) {
+ EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
+ Label l;
+ b(&l);
+ EmitBranch(AL, label, false);
+ Bind(&l);
+}
+
+
+void Assembler::LoadObject(Register rd, const Object& object) {
+ UNIMPLEMENTED();
+}
+
+
+void Assembler::Bind(Label* label) {
+ ASSERT(!label->IsBound());
+ int bound_pc = buffer_.Size();
+ while (label->IsLinked()) {
+ int32_t position = label->Position();
+ int32_t next = buffer_.Load<int32_t>(position);
+ int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next);
+ buffer_.Store<int32_t>(position, encoded);
+ label->position_ = Assembler::DecodeBranchOffset(next);
+ }
+ label->BindTo(bound_pc);
+}
+
+
+bool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
+ switch (type) {
+ case kLoadSignedByte:
+ case kLoadSignedHalfword:
+ case kLoadUnsignedHalfword:
+ case kLoadWordPair:
+ return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3.
+ case kLoadUnsignedByte:
+ case kLoadWord:
+ return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2.
+ case kLoadSWord:
+ case kLoadDWord:
+ return Utils::IsAbsoluteUint(10, offset); // VFP addressing mode.
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+
+bool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
+ switch (type) {
+ case kStoreHalfword:
+ case kStoreWordPair:
+ return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3.
+ case kStoreByte:
+ case kStoreWord:
+ return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2.
+ case kStoreSWord:
+ case kStoreDWord:
+ return Utils::IsAbsoluteUint(10, offset); // VFP addressing mode.
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+
+void Assembler::Push(Register rd, Condition cond) {
+ str(rd, Address(SP, -kWordSize, Address::PreIndex), cond);
+}
+
+
+void Assembler::Pop(Register rd, Condition cond) {
+ ldr(rd, Address(SP, kWordSize, Address::PostIndex), cond);
+}
+
+
+void Assembler::PushList(RegList regs, Condition cond) {
+ stm(DB_W, SP, regs, cond);
+}
+
+
+void Assembler::PopList(RegList regs, Condition cond) {
+ ldm(IA_W, SP, regs, cond);
+}
+
+
+void Assembler::Mov(Register rd, Register rm, Condition cond) {
+ if (rd != rm) {
+ mov(rd, ShifterOperand(rm), cond);
+ }
+}
+
+
+void Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
+ Condition cond) {
+ ASSERT(shift_imm != 0); // Do not use Lsl if no shift is wanted.
+ mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
+}
+
+
+void Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
+ Condition cond) {
+ ASSERT(shift_imm != 0); // Do not use Lsr if no shift is wanted.
+ if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
+ mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
+}
+
+
+void Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
+ Condition cond) {
+ ASSERT(shift_imm != 0); // Do not use Asr if no shift is wanted.
+ if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax.
+ mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
+}
+
+
+void Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
+ Condition cond) {
+ ASSERT(shift_imm != 0); // Use Rrx instruction.
+ mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
+}
+
+
+void Assembler::Rrx(Register rd, Register rm, Condition cond) {
+ mov(rd, ShifterOperand(rm, ROR, 0), cond);
+}
+
+
+void Assembler::Branch(const ExternalLabel* label) {
+ // TODO(regis): Revisit this code sequence.
+ LoadImmediate(IP, label->address()); // Target address is never patched.
+ mov(PC, ShifterOperand(IP));
+}
+
+
+void Assembler::BranchLink(const ExternalLabel* label) {
+ // TODO(regis): Revisit this code sequence.
+ // Make sure that CodePatcher is able to patch this code sequence.
+ // For added code robustness, use 'blx lr' in a patchable sequence and
+ // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
+ ldr(LR, Address(PC));
+ Label skip;
+ b(&skip);
+ Emit(label->address()); // May get patched.
+ Bind(&skip);
+ blx(LR); // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) {
+ // TODO(regis): Revisit this code sequence.
+ LoadImmediate(IP, label->address()); // Target address is never patched.
+ str(PC, ad);
+ blx(IP); // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::BranchLinkOffset(Register base, int offset) {
+ ASSERT(base != PC);
+ ASSERT(base != IP);
+ if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
+ ldr(IP, Address(base, offset));
+ } else {
+ int offset_hi = offset & ~kOffset12Mask;
+ int offset_lo = offset & kOffset12Mask;
+ ShifterOperand offset_hi_op;
+ if (ShifterOperand::CanHold(offset_hi, &offset_hi_op)) {
+ add(IP, base, offset_hi_op);
+ ldr(IP, Address(IP, offset_lo));
+ } else {
+ LoadImmediate(IP, offset_hi);
+ add(IP, IP, ShifterOperand(base));
+ ldr(IP, Address(IP, offset_lo));
+ }
+ }
+ blx(IP); // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
+ ShifterOperand shifter_op;
+ if (ShifterOperand::CanHold(value, &shifter_op)) {
+ mov(rd, shifter_op, cond);
+ } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
+ mvn(rd, shifter_op, cond);
+ } else {
+ movw(rd, Utils::Low16Bits(value), cond);
+ uint16_t value_high = Utils::High16Bits(value);
+ if (value_high != 0) {
+ movt(rd, value_high, cond);
+ }
+ }
+}
+
+
+void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) {
+ if (!vmovs(sd, value, cond)) {
+ LoadImmediate(IP, bit_cast<int32_t, float>(value), cond);
+ vmovsr(sd, IP, cond);
+ }
+}
+
+
+void Assembler::LoadDImmediate(DRegister dd,
+ double value,
+ Register scratch,
+ Condition cond) {
+ // TODO(regis): Revisit this code sequence.
+ ASSERT(scratch != PC);
+ ASSERT(scratch != IP);
+ if (!vmovd(dd, value, cond)) {
+ // A scratch register and IP are needed to load an arbitrary double.
+ ASSERT(scratch != kNoRegister);
+ int64_t imm64 = bit_cast<int64_t, double>(value);
+ LoadImmediate(IP, Utils::Low32Bits(imm64), cond);
+ LoadImmediate(scratch, Utils::High32Bits(imm64), cond);
+ vmovdrr(dd, IP, scratch, cond);
+ }
+}
+
+
+void Assembler::LoadFromOffset(LoadOperandType type,
+ Register reg,
+ Register base,
+ int32_t offset,
+ Condition cond) {
+ if (!Address::CanHoldLoadOffset(type, offset)) {
+ ASSERT(base != IP);
+ LoadImmediate(IP, offset, cond);
+ add(IP, IP, ShifterOperand(base), cond);
+ base = IP;
+ offset = 0;
+ }
+ ASSERT(Address::CanHoldLoadOffset(type, offset));
+ switch (type) {
+ case kLoadSignedByte:
+ ldrsb(reg, Address(base, offset), cond);
+ break;
+ case kLoadUnsignedByte:
+ ldrb(reg, Address(base, offset), cond);
+ break;
+ case kLoadSignedHalfword:
+ ldrsh(reg, Address(base, offset), cond);
+ break;
+ case kLoadUnsignedHalfword:
+ ldrh(reg, Address(base, offset), cond);
+ break;
+ case kLoadWord:
+ ldr(reg, Address(base, offset), cond);
+ break;
+ case kLoadWordPair:
+ ldrd(reg, Address(base, offset), cond);
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+
+void Assembler::StoreToOffset(StoreOperandType type,
+ Register reg,
+ Register base,
+ int32_t offset,
+ Condition cond) {
+ if (!Address::CanHoldStoreOffset(type, offset)) {
+ ASSERT(reg != IP);
+ ASSERT(base != IP);
+ LoadImmediate(IP, offset, cond);
+ add(IP, IP, ShifterOperand(base), cond);
+ base = IP;
+ offset = 0;
+ }
+ ASSERT(Address::CanHoldStoreOffset(type, offset));
+ switch (type) {
+ case kStoreByte:
+ strb(reg, Address(base, offset), cond);
+ break;
+ case kStoreHalfword:
+ strh(reg, Address(base, offset), cond);
+ break;
+ case kStoreWord:
+ str(reg, Address(base, offset), cond);
+ break;
+ case kStoreWordPair:
+ strd(reg, Address(base, offset), cond);
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+
+void Assembler::LoadSFromOffset(SRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond) {
+ if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) {
+ ASSERT(base != IP);
+ LoadImmediate(IP, offset, cond);
+ add(IP, IP, ShifterOperand(base), cond);
+ base = IP;
+ offset = 0;
+ }
+ ASSERT(Address::CanHoldLoadOffset(kLoadSWord, offset));
+ vldrs(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::StoreSToOffset(SRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond) {
+ if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) {
+ ASSERT(base != IP);
+ LoadImmediate(IP, offset, cond);
+ add(IP, IP, ShifterOperand(base), cond);
+ base = IP;
+ offset = 0;
+ }
+ ASSERT(Address::CanHoldStoreOffset(kStoreSWord, offset));
+ vstrs(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::LoadDFromOffset(DRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond) {
+ if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) {
+ ASSERT(base != IP);
+ LoadImmediate(IP, offset, cond);
+ add(IP, IP, ShifterOperand(base), cond);
+ base = IP;
+ offset = 0;
+ }
+ ASSERT(Address::CanHoldLoadOffset(kLoadDWord, offset));
+ vldrd(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::StoreDToOffset(DRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond) {
+ if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) {
+ ASSERT(base != IP);
+ LoadImmediate(IP, offset, cond);
+ add(IP, IP, ShifterOperand(base), cond);
+ base = IP;
+ offset = 0;
+ }
+ ASSERT(Address::CanHoldStoreOffset(kStoreDWord, offset));
+ vstrd(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
+ AddConstant(rd, rd, value, cond);
+}
+
+
+void Assembler::AddConstant(Register rd, Register rn, int32_t value,
+ Condition cond) {
+ if (value == 0) {
+ if (rd != rn) {
+ mov(rd, ShifterOperand(rn), cond);
+ }
+ return;
+ }
+ // We prefer to select the shorter code sequence rather than selecting add for
+ // positive values and sub for negatives ones, which would slightly improve
+ // the readability of generated code for some constants.
+ ShifterOperand shifter_op;
+ if (ShifterOperand::CanHold(value, &shifter_op)) {
+ add(rd, rn, shifter_op, cond);
+ } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
+ sub(rd, rn, shifter_op, cond);
+ } else {
+ ASSERT(rn != IP);
+ if (ShifterOperand::CanHold(~value, &shifter_op)) {
+ mvn(IP, shifter_op, cond);
+ add(rd, rn, ShifterOperand(IP), cond);
+ } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
+ mvn(IP, shifter_op, cond);
+ sub(rd, rn, ShifterOperand(IP), cond);
+ } else {
+ movw(IP, Utils::Low16Bits(value), cond);
+ uint16_t value_high = Utils::High16Bits(value);
+ if (value_high != 0) {
+ movt(IP, value_high, cond);
+ }
+ add(rd, rn, ShifterOperand(IP), cond);
+ }
+ }
+}
+
+
+void Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
+ Condition cond) {
+ ShifterOperand shifter_op;
+ if (ShifterOperand::CanHold(value, &shifter_op)) {
+ adds(rd, rn, shifter_op, cond);
+ } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
+ subs(rd, rn, shifter_op, cond);
+ } else {
+ ASSERT(rn != IP);
+ if (ShifterOperand::CanHold(~value, &shifter_op)) {
+ mvn(IP, shifter_op, cond);
+ adds(rd, rn, ShifterOperand(IP), cond);
+ } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
+ mvn(IP, shifter_op, cond);
+ subs(rd, rn, ShifterOperand(IP), cond);
+ } else {
+ movw(IP, Utils::Low16Bits(value), cond);
+ uint16_t value_high = Utils::High16Bits(value);
+ if (value_high != 0) {
+ movt(IP, value_high, cond);
+ }
+ adds(rd, rn, ShifterOperand(IP), cond);
+ }
+ }
+}
+
+
+void Assembler::AddConstantWithCarry(Register rd, Register rn, int32_t value,
+ Condition cond) {
+ ShifterOperand shifter_op;
+ if (ShifterOperand::CanHold(value, &shifter_op)) {
+ adc(rd, rn, shifter_op, cond);
+ } else if (ShifterOperand::CanHold(-value - 1, &shifter_op)) {
+ sbc(rd, rn, shifter_op, cond);
+ } else {
+ ASSERT(rn != IP);
+ if (ShifterOperand::CanHold(~value, &shifter_op)) {
+ mvn(IP, shifter_op, cond);
+ adc(rd, rn, ShifterOperand(IP), cond);
+ } else if (ShifterOperand::CanHold(~(-value - 1), &shifter_op)) {
+ mvn(IP, shifter_op, cond);
+ sbc(rd, rn, ShifterOperand(IP), cond);
+ } else {
+ movw(IP, Utils::Low16Bits(value), cond);
+ uint16_t value_high = Utils::High16Bits(value);
+ if (value_high != 0) {
+ movt(IP, value_high, cond);
+ }
+ adc(rd, rn, ShifterOperand(IP), cond);
+ }
+ }
+}
+
+
+void Assembler::Stop(const char* message) {
+ if (FLAG_print_stop_message) {
+ UNIMPLEMENTED(); // Emit call to StubCode::PrintStopMessage().
+ }
+ // Emit the message address before the svc instruction, so that we can
+ // 'unstop' and continue execution in the simulator or jump to the next
+ // instruction in gdb.
+ Label stop;
+ b(&stop);
+ Emit(reinterpret_cast<int32_t>(message));
+ Bind(&stop);
+ svc(kStopMessageSvcCode);
+}
+
+
+int32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) {
+ // The offset is off by 8 due to the way the ARM CPUs read PC.
+ offset -= 8;
+ ASSERT(Utils::IsAligned(offset, 4));
+ ASSERT(Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset));
+
+ // Properly preserve only the bits supported in the instruction.
+ offset >>= 2;
+ offset &= kBranchOffsetMask;
+ return (inst & ~kBranchOffsetMask) | offset;
+}
+
+
+int Assembler::DecodeBranchOffset(int32_t inst) {
+ // Sign-extend, left-shift by 2, then add 8.
+ return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
+}
} // namespace dart
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 0661a8a..b998894e 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -10,55 +10,11 @@
#endif
#include "platform/assert.h"
+#include "platform/utils.h"
#include "vm/constants_arm.h"
namespace dart {
-class Operand : public ValueObject {
- public:
- Operand(const Operand& other) : ValueObject() {
- UNIMPLEMENTED();
- }
-
- Operand& operator=(const Operand& other) {
- UNIMPLEMENTED();
- return *this;
- }
-
- protected:
- Operand() { } // Needed by subclass Address.
-};
-
-
-class Address : public Operand {
- public:
- Address(Register base, int32_t disp) {
- UNIMPLEMENTED();
- }
-
- Address(const Address& other) : Operand(other) { }
-
- Address& operator=(const Address& other) {
- Operand::operator=(other);
- return *this;
- }
-};
-
-
-class FieldAddress : public Address {
- public:
- FieldAddress(Register base, int32_t disp)
- : Address(base, disp - kHeapObjectTag) { }
-
- FieldAddress(const FieldAddress& other) : Address(other) { }
-
- FieldAddress& operator=(const FieldAddress& other) {
- Address::operator=(other);
- return *this;
- }
-};
-
-
class Label : public ValueObject {
public:
Label() : position_(0) { }
@@ -113,38 +69,219 @@
};
+// Encodes Addressing Mode 1 - Data-processing operands.
+class ShifterOperand : public ValueObject {
+ public:
+ // Data-processing operands - Uninitialized.
+ ShifterOperand() : type_(-1) { }
+
+ // Data-processing operands - Copy constructor.
+ ShifterOperand(const ShifterOperand& other)
+ : ValueObject(), type_(other.type_), encoding_(other.encoding_) { }
+
+ // Data-processing operands - Assignment operator.
+ ShifterOperand& operator=(const ShifterOperand& other) {
+ type_ = other.type_;
+ encoding_ = other.encoding_;
+ return *this;
+ }
+
+ // Data-processing operands - Immediate.
+ explicit ShifterOperand(uint32_t immediate) {
+ ASSERT(immediate < (1 << kImmed8Bits));
+ type_ = 1;
+ encoding_ = immediate;
+ }
+
+ // Data-processing operands - Rotated immediate.
+ ShifterOperand(uint32_t rotate, uint32_t immed8) {
+ ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
+ type_ = 1;
+ encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
+ }
+
+ // Data-processing operands - Register.
+ explicit ShifterOperand(Register rm) {
+ type_ = 0;
+ encoding_ = static_cast<uint32_t>(rm);
+ }
+
+ // Data-processing operands - Logical shift/rotate by immediate.
+ ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) {
+ ASSERT(shift_imm < (1 << kShiftImmBits));
+ type_ = 0;
+ encoding_ = shift_imm << kShiftImmShift |
+ static_cast<uint32_t>(shift) << kShiftShift |
+ static_cast<uint32_t>(rm);
+ }
+
+ // Data-processing operands - Logical shift/rotate by register.
+ ShifterOperand(Register rm, Shift shift, Register rs) {
+ type_ = 0;
+ encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift |
+ static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) |
+ static_cast<uint32_t>(rm);
+ }
+
+ static bool CanHold(uint32_t immediate, ShifterOperand* shifter_op) {
+ // Avoid the more expensive test for frequent small immediate values.
+ if (immediate < (1 << kImmed8Bits)) {
+ shifter_op->type_ = 1;
+ shifter_op->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
+ return true;
+ }
+ // Note that immediate must be unsigned for the test to work correctly.
+ for (int rot = 0; rot < 16; rot++) {
+ uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot));
+ if (imm8 < (1 << kImmed8Bits)) {
+ shifter_op->type_ = 1;
+ shifter_op->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ bool is_valid() const { return (type_ == 0) || (type_ == 1); }
+
+ uint32_t type() const {
+ ASSERT(is_valid());
+ return type_;
+ }
+
+ uint32_t encoding() const {
+ ASSERT(is_valid());
+ return encoding_;
+ }
+
+ uint32_t type_; // Encodes the type field (bits 27-25) in the instruction.
+ uint32_t encoding_;
+
+ friend class Assembler;
+};
+
+
+enum LoadOperandType {
+ kLoadSignedByte,
+ kLoadUnsignedByte,
+ kLoadSignedHalfword,
+ kLoadUnsignedHalfword,
+ kLoadWord,
+ kLoadWordPair,
+ kLoadSWord,
+ kLoadDWord
+};
+
+
+enum StoreOperandType {
+ kStoreByte,
+ kStoreHalfword,
+ kStoreWord,
+ kStoreWordPair,
+ kStoreSWord,
+ kStoreDWord
+};
+
+
+// Load/store multiple addressing mode.
+enum BlockAddressMode {
+ // bit encoding P U W
+ DA = (0|0|0) << 21, // decrement after
+ IA = (0|4|0) << 21, // increment after
+ DB = (8|0|0) << 21, // decrement before
+ IB = (8|4|0) << 21, // increment before
+ DA_W = (0|0|1) << 21, // decrement after with writeback to base
+ IA_W = (0|4|1) << 21, // increment after with writeback to base
+ DB_W = (8|0|1) << 21, // decrement before with writeback to base
+ IB_W = (8|4|1) << 21 // increment before with writeback to base
+};
+
+
+class Address : public ValueObject {
+ public:
+ // Memory operand addressing mode
+ enum Mode {
+ // bit encoding P U W
+ Offset = (8|4|0) << 21, // offset (w/o writeback to base)
+ PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback
+ PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback
+ NegOffset = (8|0|0) << 21, // negative offset (w/o writeback to base)
+ NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback
+ NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback
+ };
+
+ Address(const Address& other) : ValueObject(), encoding_(other.encoding_) { }
+
+ Address& operator=(const Address& other) {
+ encoding_ = other.encoding_;
+ return *this;
+ }
+
+ explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
+ ASSERT(Utils::IsAbsoluteUint(12, offset));
+ if (offset < 0) {
+ encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign.
+ } else {
+ encoding_ = am | offset;
+ }
+ encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
+ }
+
+ static bool CanHoldLoadOffset(LoadOperandType type, int offset);
+ static bool CanHoldStoreOffset(StoreOperandType type, int offset);
+
+ private:
+ uint32_t encoding() const { return encoding_; }
+
+ // Encoding for addressing mode 3.
+ uint32_t encoding3() const;
+
+ // Encoding for vfp load/store addressing.
+ uint32_t vencoding() const;
+
+ uint32_t encoding_;
+
+ friend class Assembler;
+};
+
+
+class FieldAddress : public Address {
+ public:
+ FieldAddress(Register base, int32_t disp)
+ : Address(base, disp - kHeapObjectTag) { }
+
+ FieldAddress(const FieldAddress& other) : Address(other) { }
+
+ FieldAddress& operator=(const FieldAddress& other) {
+ Address::operator=(other);
+ return *this;
+ }
+};
+
+
class Assembler : public ValueObject {
public:
- Assembler() { UNIMPLEMENTED(); }
+ Assembler() : buffer_(), prologue_offset_(-1), comments_() { }
~Assembler() { }
- void PopRegister(Register r) {
- UNIMPLEMENTED();
- }
+ void PopRegister(Register r) { Pop(r); }
- void Bind(Label* label) {
- UNIMPLEMENTED();
- }
+ void Bind(Label* label);
// Misc. functionality
- int CodeSize() const {
- UNIMPLEMENTED();
- return 0;
- }
- int prologue_offset() const {
- UNIMPLEMENTED();
- return 0;
- }
+ int CodeSize() const { return buffer_.Size(); }
+ int prologue_offset() const { return prologue_offset_; }
const ZoneGrowableArray<int>& GetPointerOffsets() const {
- UNIMPLEMENTED();
- return *pointer_offsets_;
+ return buffer_.pointer_offsets();
}
+
void FinalizeInstructions(const MemoryRegion& region) {
- UNIMPLEMENTED();
+ buffer_.FinalizeInstructions(region);
}
// Debugging and bringup support.
- void Stop(const char* message) { UNIMPLEMENTED(); }
+ void Stop(const char* message);
void Unimplemented(const char* message);
void Untested(const char* message);
void Unreachable(const char* message);
@@ -153,14 +290,9 @@
UNIMPLEMENTED();
}
- void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
- UNIMPLEMENTED();
- }
+ void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
- const Code::Comments& GetCodeComments() const {
- UNIMPLEMENTED();
- return Code::Comments::New(0);
- }
+ const Code::Comments& GetCodeComments() const;
static const char* RegisterName(Register reg) {
UNIMPLEMENTED();
@@ -172,8 +304,327 @@
return NULL;
}
+ // Data-processing instructions.
+ void and_(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void eor(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void sub(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+ void subs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void rsb(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+ void rsbs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void add(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void adds(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void adc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void sbc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void rsc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void tst(Register rn, ShifterOperand so, Condition cond = AL);
+
+ void teq(Register rn, ShifterOperand so, Condition cond = AL);
+
+ void cmp(Register rn, ShifterOperand so, Condition cond = AL);
+
+ void cmn(Register rn, ShifterOperand so, Condition cond = AL);
+
+ void orr(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+ void orrs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void mov(Register rd, ShifterOperand so, Condition cond = AL);
+ void movs(Register rd, ShifterOperand so, Condition cond = AL);
+
+ void bic(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+ void mvn(Register rd, ShifterOperand so, Condition cond = AL);
+ void mvns(Register rd, ShifterOperand so, Condition cond = AL);
+
+ // Miscellaneous data-processing instructions.
+ void clz(Register rd, Register rm, Condition cond = AL);
+ void movw(Register rd, uint16_t imm16, Condition cond = AL);
+ void movt(Register rd, uint16_t imm16, Condition cond = AL);
+
+ // Multiply instructions.
+ void mul(Register rd, Register rn, Register rm, Condition cond = AL);
+ void mla(Register rd, Register rn, Register rm, Register ra,
+ Condition cond = AL);
+ void mls(Register rd, Register rn, Register rm, Register ra,
+ Condition cond = AL);
+ void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
+ Condition cond = AL);
+
+ // Load/store instructions.
+ void ldr(Register rd, Address ad, Condition cond = AL);
+ void str(Register rd, Address ad, Condition cond = AL);
+
+ void ldrb(Register rd, Address ad, Condition cond = AL);
+ void strb(Register rd, Address ad, Condition cond = AL);
+
+ void ldrh(Register rd, Address ad, Condition cond = AL);
+ void strh(Register rd, Address ad, Condition cond = AL);
+
+ void ldrsb(Register rd, Address ad, Condition cond = AL);
+ void ldrsh(Register rd, Address ad, Condition cond = AL);
+
+ void ldrd(Register rd, Address ad, Condition cond = AL);
+ void strd(Register rd, Address ad, Condition cond = AL);
+
+ void ldm(BlockAddressMode am, Register base,
+ RegList regs, Condition cond = AL);
+ void stm(BlockAddressMode am, Register base,
+ RegList regs, Condition cond = AL);
+
+ void ldrex(Register rd, Register rn, Condition cond = AL);
+ void strex(Register rd, Register rt, Register rn, Condition cond = AL);
+
+ // Miscellaneous instructions.
+ void clrex();
+ void nop(Condition cond = AL);
+
+ // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
+ void bkpt(uint16_t imm16);
+ void svc(uint32_t imm24);
+
+ // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
+ void vmovsr(SRegister sn, Register rt, Condition cond = AL);
+ void vmovrs(Register rt, SRegister sn, Condition cond = AL);
+ void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
+ void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
+ void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
+ void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
+ void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
+ void vmovd(DRegister dd, DRegister dm, Condition cond = AL);
+
+ // Returns false if the immediate cannot be encoded.
+ bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
+ bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
+
+ void vldrs(SRegister sd, Address ad, Condition cond = AL);
+ void vstrs(SRegister sd, Address ad, Condition cond = AL);
+ void vldrd(DRegister dd, Address ad, Condition cond = AL);
+ void vstrd(DRegister dd, Address ad, Condition cond = AL);
+
+ void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+ void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+ void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+ void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+ void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+ void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+ void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+ void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+ void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+ void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+ void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+ void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+
+ void vabss(SRegister sd, SRegister sm, Condition cond = AL);
+ void vabsd(DRegister dd, DRegister dm, Condition cond = AL);
+ void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
+ void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
+ void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
+ void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);
+
+ void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
+ void vcvtds(DRegister dd, SRegister sm, Condition cond = AL);
+ void vcvtis(SRegister sd, SRegister sm, Condition cond = AL);
+ void vcvtid(SRegister sd, DRegister dm, Condition cond = AL);
+ void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL);
+ void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL);
+ void vcvtus(SRegister sd, SRegister sm, Condition cond = AL);
+ void vcvtud(SRegister sd, DRegister dm, Condition cond = AL);
+ void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL);
+ void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL);
+
+ void vcmps(SRegister sd, SRegister sm, Condition cond = AL);
+ void vcmpd(DRegister dd, DRegister dm, Condition cond = AL);
+ void vcmpsz(SRegister sd, Condition cond = AL);
+ void vcmpdz(DRegister dd, Condition cond = AL);
+ void vmstat(Condition cond = AL); // VMRS APSR_nzcv, FPSCR
+
+ // Branch instructions.
+ void b(Label* label, Condition cond = AL);
+ void bl(Label* label, Condition cond = AL);
+ void blx(Register rm, Condition cond = AL);
+
+ // Macros.
+ // Branch to an entry address that can be patched at runtime.
+ void Branch(const ExternalLabel* label);
+ void BranchLink(const ExternalLabel* label);
+
+ // Branch to entry after setting LR and storing LR at ad.
+ void BranchLinkStore(const ExternalLabel* label, Address ad);
+
+ // Branch to [base + offset] after setting LR.
+ void BranchLinkOffset(Register base, int offset);
+
+ // Add signed constant value to rd. May clobber IP.
+ void AddConstant(Register rd, int32_t value, Condition cond = AL);
+ void AddConstant(Register rd, Register rn, int32_t value,
+ Condition cond = AL);
+ void AddConstantSetFlags(Register rd, Register rn, int32_t value,
+ Condition cond = AL);
+ void AddConstantWithCarry(Register rd, Register rn, int32_t value,
+ Condition cond = AL);
+
+ // Load and Store. May clobber IP.
+ void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
+ void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
+ void LoadDImmediate(DRegister dd, double value,
+ Register scratch, Condition cond = AL);
+ void MarkExceptionHandler(Label* label);
+ void LoadObject(Register rd, const Object& object);
+ void LoadFromOffset(LoadOperandType type,
+ Register reg,
+ Register base,
+ int32_t offset,
+ Condition cond = AL);
+ void StoreToOffset(StoreOperandType type,
+ Register reg,
+ Register base,
+ int32_t offset,
+ Condition cond = AL);
+ void LoadSFromOffset(SRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond = AL);
+ void StoreSToOffset(SRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond = AL);
+ void LoadDFromOffset(DRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond = AL);
+ void StoreDToOffset(DRegister reg,
+ Register base,
+ int32_t offset,
+ Condition cond = AL);
+
+ void Push(Register rd, Condition cond = AL);
+ void Pop(Register rd, Condition cond = AL);
+
+ void PushList(RegList regs, Condition cond = AL);
+ void PopList(RegList regs, Condition cond = AL);
+
+ void Mov(Register rd, Register rm, Condition cond = AL);
+
+ // Convenience shift instructions. Use mov instruction with shifter operand
+ // for variants setting the status flags or using a register shift count.
+ void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+ void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+ void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+ void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+ void Rrx(Register rd, Register rm, Condition cond = AL);
+
+ // Emit data (e.g encoded instruction or immediate) in instruction stream.
+ void Emit(int32_t value);
+
private:
+ AssemblerBuffer buffer_;
ZoneGrowableArray<int>* pointer_offsets_;
+ int prologue_offset_;
+
+ class CodeComment : public ZoneAllocated {
+ public:
+ CodeComment(intptr_t pc_offset, const String& comment)
+ : pc_offset_(pc_offset), comment_(comment) { }
+
+ intptr_t pc_offset() const { return pc_offset_; }
+ const String& comment() const { return comment_; }
+
+ private:
+ intptr_t pc_offset_;
+ const String& comment_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeComment);
+ };
+
+ GrowableArray<CodeComment*> comments_;
+
+ void EmitType01(Condition cond,
+ int type,
+ Opcode opcode,
+ int set_cc,
+ Register rn,
+ Register rd,
+ ShifterOperand so);
+
+ void EmitType5(Condition cond, int offset, bool link);
+
+ void EmitMemOp(Condition cond,
+ bool load,
+ bool byte,
+ Register rd,
+ Address ad);
+
+ void EmitMemOpAddressMode3(Condition cond,
+ int32_t mode,
+ Register rd,
+ Address ad);
+
+ void EmitMultiMemOp(Condition cond,
+ BlockAddressMode am,
+ bool load,
+ Register base,
+ RegList regs);
+
+ void EmitShiftImmediate(Condition cond,
+ Shift opcode,
+ Register rd,
+ Register rm,
+ ShifterOperand so);
+
+ void EmitShiftRegister(Condition cond,
+ Shift opcode,
+ Register rd,
+ Register rm,
+ ShifterOperand so);
+
+ void EmitMulOp(Condition cond,
+ int32_t opcode,
+ Register rd,
+ Register rn,
+ Register rm,
+ Register rs);
+
+ void EmitVFPsss(Condition cond,
+ int32_t opcode,
+ SRegister sd,
+ SRegister sn,
+ SRegister sm);
+
+ void EmitVFPddd(Condition cond,
+ int32_t opcode,
+ DRegister dd,
+ DRegister dn,
+ DRegister dm);
+
+ void EmitVFPsd(Condition cond,
+ int32_t opcode,
+ SRegister sd,
+ DRegister dm);
+
+ void EmitVFPds(Condition cond,
+ int32_t opcode,
+ DRegister dd,
+ SRegister sm);
+
+ void EmitBranch(Condition cond, Label* label, bool link);
+ static int32_t EncodeBranchOffset(int offset, int32_t inst);
+ static int DecodeBranchOffset(int32_t inst);
+ int32_t EncodeTstOffset(int offset, int32_t inst);
+ int DecodeTstOffset(int32_t inst);
+
+ // Returns whether or not the given register is used for passing parameters.
+ static int RegisterCompare(const Register* reg1, const Register* reg2) {
+ return *reg1 - *reg2;
+ }
+
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(Assembler);
};
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index ec581e9..1e23316 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -16,8 +16,6 @@
namespace dart {
DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
- "Include comments into code and disassembly");
DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
@@ -2052,33 +2050,6 @@
}
-void Assembler::Comment(const char* format, ...) {
- if (FLAG_code_comments) {
- char buffer[1024];
-
- va_list args;
- va_start(args, format);
- OS::VSNPrint(buffer, sizeof(buffer), format, args);
- va_end(args);
-
- comments_.Add(new CodeComment(buffer_.GetPosition(),
- String::Handle(String::New(buffer))));
- }
-}
-
-
-const Code::Comments& Assembler::GetCodeComments() const {
- Code::Comments& comments = Code::Comments::New(comments_.length());
-
- for (intptr_t i = 0; i < comments_.length(); i++) {
- comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
- comments.SetCommentAt(i, comments_[i]->comment());
- }
-
- return comments;
-}
-
-
static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
};
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 6885019..d6db404 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -10,8 +10,6 @@
namespace dart {
DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
- "Include comments into code and disassembly");
} // namespace dart
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index f2a0f34..9ad8b88 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -153,14 +153,9 @@
UNIMPLEMENTED();
}
- void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
- UNIMPLEMENTED();
- }
+ void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
- const Code::Comments& GetCodeComments() const {
- UNIMPLEMENTED();
- return Code::Comments::New(0);
- }
+ const Code::Comments& GetCodeComments() const;
static const char* RegisterName(Register reg) {
UNIMPLEMENTED();
@@ -173,7 +168,27 @@
}
private:
+ AssemblerBuffer buffer_;
ZoneGrowableArray<int>* pointer_offsets_;
+ int prologue_offset_;
+
+ class CodeComment : public ZoneAllocated {
+ public:
+ CodeComment(intptr_t pc_offset, const String& comment)
+ : pc_offset_(pc_offset), comment_(comment) { }
+
+ intptr_t pc_offset() const { return pc_offset_; }
+ const String& comment() const { return comment_; }
+
+ private:
+ intptr_t pc_offset_;
+ const String& comment_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeComment);
+ };
+
+ GrowableArray<CodeComment*> comments_;
+
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(Assembler);
};
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 9e5dcbb..1b270aa 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -14,8 +14,6 @@
namespace dart {
DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
- "Include comments into code and disassembly");
DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
@@ -2139,33 +2137,6 @@
}
-void Assembler::Comment(const char* format, ...) {
- if (FLAG_code_comments) {
- char buffer[1024];
-
- va_list args;
- va_start(args, format);
- OS::VSNPrint(buffer, sizeof(buffer), format, args);
- va_end(args);
-
- comments_.Add(new CodeComment(buffer_.GetPosition(),
- String::Handle(String::New(buffer))));
- }
-}
-
-
-const Code::Comments& Assembler::GetCodeComments() const {
- Code::Comments& comments = Code::Comments::New(comments_.length());
-
- for (intptr_t i = 0; i < comments_.length(); i++) {
- comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
- comments.SetCommentAt(i, comments_[i]->comment());
- }
-
- return comments;
-}
-
-
static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index f52c1b0..687054f 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -80,6 +80,20 @@
#endif
}
+ int32_t no_callback_scope_depth() const {
+ return no_callback_scope_depth_;
+ }
+
+ void IncrementNoCallbackScopeDepth() {
+ ASSERT(no_callback_scope_depth_ < INT_MAX);
+ no_callback_scope_depth_ += 1;
+ }
+
+ void DecrementNoCallbackScopeDepth() {
+ ASSERT(no_callback_scope_depth_ > 0);
+ no_callback_scope_depth_ -= 1;
+ }
+
#if defined(DEBUG)
static void AssertCurrent(BaseIsolate* isolate);
#endif
@@ -87,14 +101,13 @@
protected:
BaseIsolate()
: top_resource_(NULL),
-#if defined(DEBUG)
current_zone_(NULL),
+#if defined(DEBUG)
top_handle_scope_(NULL),
no_handle_scope_depth_(0),
- no_gc_scope_depth_(0)
-#else
- current_zone_(NULL)
+ no_gc_scope_depth_(0),
#endif
+ no_callback_scope_depth_(0)
{}
~BaseIsolate() {
@@ -108,6 +121,7 @@
int32_t no_handle_scope_depth_;
int32_t no_gc_scope_depth_;
#endif
+ int32_t no_callback_scope_depth_;
DISALLOW_COPY_AND_ASSIGN(BaseIsolate);
};
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index c18860d..08ff160 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1717,4 +1717,20 @@
}
END_LEAF_RUNTIME_ENTRY
+
+double DartModulo(double left, double 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;
+ } else if (remainder < 0.0) {
+ if (right < 0) {
+ remainder -= right;
+ } else {
+ remainder += right;
+ }
+ }
+ return remainder;
+}
+
} // namespace dart
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 7bf4e99..7946dc2 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -73,6 +73,8 @@
V(CheckArrayBound) \
V(AtCall) \
V(DoubleToSmi) \
+ V(Int32Load) \
+ V(Uint32Load) \
V(NumReasons) \
enum DeoptReasonId {
@@ -93,6 +95,8 @@
void DeoptimizeAll();
void DeoptimizeIfOwner(const GrowableArray<intptr_t>& classes);
+double DartModulo(double a, double b);
+
} // namespace dart
#endif // VM_CODE_GENERATOR_H_
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index aca46da..4d477db 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -133,7 +133,8 @@
// Register aliases.
const Register TMP = kNoRegister; // No scratch register used by assembler.
-const Register CTX = R9; // Caches current context in generated code.
+const Register CTX = R9; // Caches current context in generated code.
+const Register CP = R10; // Caches constant pool base in generated code.
const Register SPREG = SP;
const Register FPREG = FP;
@@ -143,6 +144,17 @@
const Register kExceptionObjectReg = R0; // Unimplemented.
+// List of registers used in load/store multiple.
+typedef uint16_t RegList;
+const RegList kAllCoreRegistersList = 0xFFFF;
+
+
+// C++ ABI call registers
+const int kAbiRegisterCount = 4;
+const Register kAbiRegisters[kAbiRegisterCount] = { R0, R1, R2, R3 };
+const RegList kAbiRegisterList = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3);
+
+
// Values for the condition field as defined in section A3.2.
enum Condition {
kNoCondition = -1,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 95d3f0c..ed4fd7b 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -192,7 +192,8 @@
Dart_Handle Api::NewError(const char* format, ...) {
Isolate* isolate = Isolate::Current();
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
va_list args;
va_start(args, format);
@@ -210,6 +211,23 @@
}
+void Api::SetupCallbackError(Isolate* isolate) {
+ ASSERT(isolate != NULL);
+ ApiState* state = isolate->api_state();
+ ASSERT(state != NULL);
+ state->SetupCallbackError();
+}
+
+
+Dart_Handle Api::CallbackError(Isolate* isolate) {
+ ASSERT(isolate != NULL);
+ ApiState* state = isolate->api_state();
+ ASSERT(state != NULL);
+ PersistentHandle* callback_error_handle = state->CallbackError();
+ return reinterpret_cast<Dart_Handle>(callback_error_handle);
+}
+
+
Dart_Handle Api::Null(Isolate* isolate) {
ASSERT(isolate != NULL);
ApiState* state = isolate->api_state();
@@ -396,6 +414,7 @@
DART_EXPORT Dart_Handle Dart_Error(const char* format, ...) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
va_list args;
va_start(args, format);
@@ -418,6 +437,7 @@
DART_EXPORT Dart_Handle Dart_NewApiError(const char* format, ...) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
va_list args;
va_start(args, format);
@@ -438,6 +458,8 @@
DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
+
const Instance& obj = Api::UnwrapInstanceHandle(isolate, exception);
if (obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, exception, Instance);
@@ -501,9 +523,11 @@
if (obj.IsString()) {
return Api::NewHandle(isolate, obj.raw());
} else if (obj.IsInstance()) {
+ CHECK_CALLBACK_STATE(isolate);
const Instance& receiver = Instance::Cast(obj);
return Api::NewHandle(isolate, DartLibraryCalls::ToString(receiver));
} else {
+ CHECK_CALLBACK_STATE(isolate);
// This is a VM internal object. Call the C++ method of printing.
return Api::NewHandle(isolate, String::New(obj.ToCString()));
}
@@ -520,8 +544,7 @@
DART_EXPORT Dart_Handle Dart_NewPersistentHandle(Dart_Handle object) {
Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
const Object& old_ref = Object::Handle(isolate, Api::UnwrapHandle(object));
@@ -550,8 +573,7 @@
void* peer,
Dart_WeakPersistentHandleFinalizer callback) {
Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
return AllocateFinalizableHandle(isolate,
@@ -567,8 +589,7 @@
void* peer,
Dart_WeakPersistentHandleFinalizer callback) {
Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
return AllocateFinalizableHandle(isolate,
@@ -810,7 +831,7 @@
free(isolate_name);
{
StackZone zone(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ HANDLESCOPE(isolate);
const Error& error_obj =
Error::Handle(isolate,
Dart::InitializeIsolate(snapshot, callback_data));
@@ -964,6 +985,7 @@
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
Monitor monitor;
MonitorLocker ml(&monitor);
{
@@ -1046,8 +1068,7 @@
DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
const Object& object = Object::Handle(isolate, Api::UnwrapHandle(handle));
uint8_t* data = NULL;
MessageWriter writer(&data, &allocator);
@@ -1093,6 +1114,7 @@
DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
}
@@ -1100,6 +1122,8 @@
DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
+
Library& isolate_lib = Library::Handle(isolate, Library::IsolateLibrary());
ASSERT(!isolate_lib.IsNull());
const String& class_name = String::Handle(
@@ -1138,7 +1162,7 @@
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(),
- reinterpret_cast<uword>(&state));
+ isolate->top_exit_frame_info());
ASSERT(new_scope != NULL);
state->set_top_scope(new_scope); // New scope is now the top scope.
}
@@ -1191,6 +1215,7 @@
bool* value) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
const Instance& expected =
Instance::CheckedHandle(isolate, Api::UnwrapHandle(obj1));
const Instance& actual =
@@ -1235,6 +1260,7 @@
return Api::NewError("%s", msg);
}
if (obj.IsInstance()) {
+ CHECK_CALLBACK_STATE(isolate);
const Type& type = Type::Handle(isolate,
Type::NewNonParameterizedType(cls));
Error& malformed_type_error = Error::Handle(isolate);
@@ -1299,7 +1325,7 @@
return Api::Success(isolate);
}
// Slow path for Mints and Bigints.
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
if (int_obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1320,7 +1346,7 @@
return Api::Success(isolate);
}
// Slow path for Mints and Bigints.
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
if (int_obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1344,7 +1370,8 @@
return Api::NewHandle(isolate, Smi::New(static_cast<intptr_t>(value)));
}
// Slow path for Mints and Bigints.
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, Integer::New(value));
}
@@ -1352,6 +1379,7 @@
DART_EXPORT Dart_Handle Dart_NewIntegerFromHexCString(const char* str) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
const String& str_obj = String::Handle(isolate, String::New(str));
return Api::NewHandle(isolate, Integer::New(str_obj));
}
@@ -1367,7 +1395,7 @@
return Api::Success(isolate);
}
// Slow path for Mints and Bigints.
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
if (int_obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1401,7 +1429,7 @@
}
}
// Slow path for Mints and Bigints.
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
if (int_obj.IsNull()) {
RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1500,6 +1528,7 @@
DART_EXPORT Dart_Handle Dart_NewDouble(double value) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, Double::New(value));
}
@@ -1548,6 +1577,7 @@
if (str == NULL) {
RETURN_NULL_ERROR(str);
}
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, String::New(str));
}
@@ -1564,6 +1594,7 @@
return Api::NewError("%s expects argument 'str' to be valid UTF-8.",
CURRENT_FUNC);
}
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, String::FromUTF8(utf8_array, length));
}
@@ -1576,6 +1607,7 @@
RETURN_NULL_ERROR(utf16_array);
}
CHECK_LENGTH(length, String::kMaxElements);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, String::FromUTF16(utf16_array, length));
}
@@ -1588,6 +1620,7 @@
RETURN_NULL_ERROR(utf32_array);
}
CHECK_LENGTH(length, String::kMaxElements);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length));
}
@@ -1630,6 +1663,7 @@
RETURN_NULL_ERROR(latin1_array);
}
CHECK_LENGTH(length, String::kMaxElements);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate,
String::NewExternal(latin1_array, length, peer, cback));
}
@@ -1645,6 +1679,7 @@
RETURN_NULL_ERROR(utf16_array);
}
CHECK_LENGTH(length, String::kMaxElements);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate,
String::NewExternal(utf16_array, length, peer, cback));
}
@@ -1853,6 +1888,7 @@
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
CHECK_LENGTH(length, Array::kMaxElements);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, Array::New(length));
}
@@ -1881,6 +1917,8 @@
if (obj.IsGrowableObjectArray()) {
GET_LIST_LENGTH(isolate, GrowableObjectArray, obj, len);
}
+ CHECK_CALLBACK_STATE(isolate);
+
// Now check and handle a dart object that implements the List interface.
const Instance& instance =
Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -1948,6 +1986,8 @@
} else if (obj.IsError()) {
return list;
} else {
+ CHECK_CALLBACK_STATE(isolate);
+
// Check and handle a dart object that implements the List interface.
const Instance& instance =
Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -1989,16 +2029,17 @@
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list));
- if (obj.IsArray()) {
- if (obj.IsImmutableArray()) {
- return Api::NewError("Cannot modify immutable array");
- }
+ // If the list is immutable we call into Dart for the indexed setter to
+ // get the unsupported operation exception as the result.
+ if (obj.IsArray() && !obj.IsImmutableArray()) {
SET_LIST_ELEMENT(isolate, Array, obj, index, value);
} else if (obj.IsGrowableObjectArray()) {
SET_LIST_ELEMENT(isolate, GrowableObjectArray, obj, index, value);
} else if (obj.IsError()) {
return list;
} else {
+ CHECK_CALLBACK_STATE(isolate);
+
// Check and handle a dart object that implements the List interface.
const Instance& instance =
Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -2085,6 +2126,8 @@
} else if (obj.IsError()) {
return list;
} else {
+ CHECK_CALLBACK_STATE(isolate);
+
// Check and handle a dart object that implements the List interface.
const Instance& instance =
Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -2153,10 +2196,9 @@
return Api::Success(isolate);
}
return Api::NewError("Invalid length passed in to set list elements");
- } else if (obj.IsArray()) {
- if (obj.IsImmutableArray()) {
- return Api::NewError("Cannot modify immutable array");
- }
+ } else if (obj.IsArray() && !obj.IsImmutableArray()) {
+ // If the list is immutable we call into Dart for the indexed setter to
+ // get the unsupported operation exception as the result.
SET_LIST_ELEMENT_AS_BYTES(isolate,
Array,
obj,
@@ -2173,7 +2215,9 @@
} else if (obj.IsError()) {
return list;
} else {
- // Check and handle a dart object that implements the List interface.
+ CHECK_CALLBACK_STATE(isolate);
+
+ // Check and handle a dart object that implements the List interface.
const Instance& instance =
Instance::Handle(isolate, GetListInstance(isolate, obj));
if (!instance.IsNull()) {
@@ -2225,22 +2269,26 @@
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
CHECK_LENGTH(length, Uint8Array::kMaxElements);
+ CHECK_CALLBACK_STATE(isolate);
return Api::NewHandle(isolate, Uint8Array::New(length));
}
-DART_EXPORT Dart_Handle Dart_NewExternalByteArray(uint8_t* data,
- intptr_t length,
- void* peer,
- Dart_PeerFinalizer callback) {
+DART_EXPORT Dart_Handle Dart_NewExternalByteArray(
+ uint8_t* data,
+ intptr_t length,
+ void* peer,
+ Dart_WeakPersistentHandleFinalizer callback) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
if (data == NULL && length != 0) {
RETURN_NULL_ERROR(data);
}
CHECK_LENGTH(length, ExternalUint8Array::kMaxElements);
- return Api::NewHandle(
- isolate, ExternalUint8Array::New(data, length, peer, callback));
+ CHECK_CALLBACK_STATE(isolate);
+ const ExternalUint8Array& obj = ExternalUint8Array::Handle(
+ ExternalUint8Array::New(data, length));
+ return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback));
}
@@ -2248,15 +2296,17 @@
uint8_t* data,
intptr_t length,
void* peer,
- Dart_PeerFinalizer callback) {
+ Dart_WeakPersistentHandleFinalizer callback) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
if (data == NULL && length != 0) {
RETURN_NULL_ERROR(data);
}
CHECK_LENGTH(length, ExternalUint8ClampedArray::kMaxElements);
- return Api::NewHandle(
- isolate, ExternalUint8ClampedArray::New(data, length, peer, callback));
+ CHECK_CALLBACK_STATE(isolate);
+ const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle(
+ ExternalUint8ClampedArray::New(data, length));
+ return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback));
}
@@ -2294,182 +2344,46 @@
}
-template<typename T>
-Dart_Handle ByteArrayGetAt(T* value, Dart_Handle array, intptr_t offset) {
+DART_EXPORT Dart_Handle Dart_ScalarListAcquireData(Dart_Handle array,
+ Dart_Scalar_Type* type,
+ void** data,
+ intptr_t* len) {
Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
- const ByteArray& array_obj = Api::UnwrapByteArrayHandle(isolate, array);
- if (array_obj.IsNull()) {
- RETURN_TYPE_ERROR(isolate, array, ByteArray);
+ DARTSCOPE(isolate);
+ if (!RawObject::IsByteArrayClassId(Api::ClassId(array))) {
+ RETURN_TYPE_ERROR(isolate, array, 'scalar list');
}
- intptr_t length = sizeof(T);
- if (!Utils::RangeCheck(offset, length, array_obj.ByteLength())) {
- return Api::NewError("Invalid index passed in to get byte array element");
+ if (type == NULL) {
+ RETURN_NULL_ERROR(type);
}
- uint8_t* dst = reinterpret_cast<uint8_t*>(value);
- ByteArray::Copy(dst, array_obj, offset, length);
+ if (data == NULL) {
+ RETURN_NULL_ERROR(data);
+ }
+ if (len == NULL) {
+ RETURN_NULL_ERROR(len);
+ }
+ isolate->IncrementNoGCScopeDepth();
+ START_NO_CALLBACK_SCOPE(isolate);
+
+ UNIMPLEMENTED();
return Api::Success(isolate);
}
-template<typename T>
-Dart_Handle ByteArraySetAt(Dart_Handle array, intptr_t offset, T value) {
+DART_EXPORT Dart_Handle Dart_ScalarListReleaseData(Dart_Handle array) {
Isolate* isolate = Isolate::Current();
- CHECK_ISOLATE(isolate);
- const ByteArray& array_obj = Api::UnwrapByteArrayHandle(isolate, array);
- if (array_obj.IsNull()) {
- RETURN_TYPE_ERROR(isolate, array, ByteArray);
+ DARTSCOPE(isolate);
+ if (!RawObject::IsByteArrayClassId(Api::ClassId(array))) {
+ RETURN_TYPE_ERROR(isolate, array, 'scalar list');
}
- intptr_t length = sizeof(T);
- if (!Utils::RangeCheck(offset, length, array_obj.ByteLength())) {
- return Api::NewError("Invalid index passed in to get byte array element");
- }
- const uint8_t* src = reinterpret_cast<uint8_t*>(&value);
- ByteArray::Copy(array_obj, offset, src, length);
+
+ UNIMPLEMENTED();
+ isolate->DecrementNoGCScopeDepth();
+ END_NO_CALLBACK_SCOPE(isolate);
return Api::Success(isolate);
}
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt8At(Dart_Handle array,
- intptr_t byte_offset,
- int8_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt8At(Dart_Handle array,
- intptr_t byte_offset,
- int8_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint8At(Dart_Handle array,
- intptr_t byte_offset,
- uint8_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint8At(Dart_Handle array,
- intptr_t byte_offset,
- uint8_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt16At(Dart_Handle array,
- intptr_t byte_offset,
- int16_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt16At(Dart_Handle array,
- intptr_t byte_offset,
- int16_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint16At(Dart_Handle array,
- intptr_t byte_offset,
- uint16_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint16At(Dart_Handle array,
- intptr_t byte_offset,
- uint16_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt32At(Dart_Handle array,
- intptr_t byte_offset,
- int32_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt32At(Dart_Handle array,
- intptr_t byte_offset,
- int32_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint32At(Dart_Handle array,
- intptr_t byte_offset,
- uint32_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint32At(Dart_Handle array,
- intptr_t byte_offset,
- uint32_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt64At(Dart_Handle array,
- intptr_t byte_offset,
- int64_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt64At(Dart_Handle array,
- intptr_t byte_offset,
- int64_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint64At(Dart_Handle array,
- intptr_t byte_offset,
- uint64_t* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint64At(Dart_Handle array,
- intptr_t byte_offset,
- uint64_t value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat32At(Dart_Handle array,
- intptr_t byte_offset,
- float* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat32At(Dart_Handle array,
- intptr_t byte_offset,
- float value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat64At(Dart_Handle array,
- intptr_t byte_offset,
- double* value) {
- return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat64At(Dart_Handle array,
- intptr_t byte_offset,
- double value) {
- return ByteArraySetAt(array, byte_offset, value);
-}
-
-
// --- Closures ---
@@ -2503,6 +2417,7 @@
Dart_Handle* arguments) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) {
RETURN_TYPE_ERROR(isolate, closure, Instance);
@@ -3351,6 +3266,7 @@
Dart_Handle* arguments) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
Object& result = Object::Handle(isolate);
if (number_of_arguments < 0) {
@@ -3365,6 +3281,7 @@
if (cls.IsNull()) {
RETURN_TYPE_ERROR(isolate, clazz, Class);
}
+
String& base_constructor_name = String::Handle();
base_constructor_name = cls.Name();
@@ -3451,6 +3368,7 @@
Dart_Handle* arguments) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
const String& function_name = Api::UnwrapStringHandle(isolate, name);
if (function_name.IsNull()) {
@@ -3594,6 +3512,7 @@
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
const String& field_name = Api::UnwrapStringHandle(isolate, name);
if (field_name.IsNull()) {
@@ -3708,6 +3627,7 @@
Dart_Handle value) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
const String& field_name = Api::UnwrapStringHandle(isolate, name);
if (field_name.IsNull()) {
@@ -3861,6 +3781,7 @@
return Api::NewError(
"Negative field_count passed to Dart_CreateNativeWrapperClass");
}
+ CHECK_CALLBACK_STATE(isolate);
String& cls_symbol = String::Handle(isolate, Symbols::New(cls_name));
const Class& cls = Class::Handle(
@@ -3931,6 +3852,7 @@
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
{
const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception);
if (excp.IsNull()) {
@@ -3942,6 +3864,7 @@
// throw an exception here.
return Api::NewError("No Dart frames on stack, cannot throw exception");
}
+
// Unwind all the API scopes till the exit frame before throwing an
// exception.
ApiState* state = isolate->api_state();
@@ -3963,6 +3886,7 @@
Dart_Handle stacktrace) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ CHECK_CALLBACK_STATE(isolate);
{
const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception);
if (excp.IsNull()) {
@@ -3978,6 +3902,7 @@
// throw an exception here.
return Api::NewError("No Dart frames on stack, cannot throw exception");
}
+
// Unwind all the API scopes till the exit frame before throwing an
// exception.
ApiState* state = isolate->api_state();
@@ -4094,6 +4019,8 @@
return Api::NewError("%s: A script has already been loaded from '%s'.",
CURRENT_FUNC, library_url.ToCString());
}
+ CHECK_CALLBACK_STATE(isolate);
+
library = Library::New(url_str);
library.set_debuggable(true);
library.Register();
@@ -4137,6 +4064,7 @@
return Api::NewError("%s: argument 'col_offset' must be positive number",
CURRENT_FUNC);
}
+ CHECK_CALLBACK_STATE(isolate);
library = Library::New(url_str);
library.set_debuggable(true);
@@ -4171,6 +4099,8 @@
return Api::NewError("%s: A script has already been loaded from '%s'.",
CURRENT_FUNC, library_url.ToCString());
}
+ CHECK_CALLBACK_STATE(isolate);
+
SnapshotReader reader(snapshot->content(),
snapshot->length(),
snapshot->kind(),
@@ -4215,6 +4145,7 @@
if (msg != NULL) {
return Api::NewError("%s", msg);
}
+ CHECK_CALLBACK_STATE(isolate);
CompileAll(isolate, &result);
return result;
}
@@ -4338,6 +4269,8 @@
if (source_str.IsNull()) {
RETURN_TYPE_ERROR(isolate, source, String);
}
+ CHECK_CALLBACK_STATE(isolate);
+
Library& library = Library::Handle(isolate, Library::LookupLibrary(url_str));
if (library.IsNull()) {
library = Library::New(url_str);
@@ -4390,6 +4323,8 @@
if (prefix_vm.IsNull()) {
RETURN_TYPE_ERROR(isolate, prefix, String);
}
+ CHECK_CALLBACK_STATE(isolate);
+
const String& prefix_symbol =
String::Handle(isolate, Symbols::New(prefix_vm));
const Namespace& import_ns = Namespace::Handle(
@@ -4428,6 +4363,8 @@
if (source_str.IsNull()) {
RETURN_TYPE_ERROR(isolate, source, String);
}
+ CHECK_CALLBACK_STATE(isolate);
+
const Script& script = Script::Handle(
isolate, Script::New(url_str, source_str, RawScript::kSourceTag));
Dart_Handle result;
@@ -4454,6 +4391,8 @@
if (source_str.IsNull()) {
RETURN_TYPE_ERROR(isolate, patch_source, String);
}
+ CHECK_CALLBACK_STATE(isolate);
+
const Script& script = Script::Handle(
isolate, Script::New(url_str, source_str, RawScript::kPatchTag));
Dart_Handle result;
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 674b643c..2b574f6 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -52,11 +52,6 @@
} \
} while (0)
-#define DARTSCOPE_NOCHECKS(isolate) \
- Isolate* __temp_isolate__ = (isolate); \
- ASSERT(__temp_isolate__ != NULL); \
- HANDLESCOPE(__temp_isolate__);
-
#define DARTSCOPE(isolate) \
Isolate* __temp_isolate__ = (isolate); \
CHECK_ISOLATE_SCOPE(__temp_isolate__); \
@@ -109,6 +104,16 @@
// Gets the handle used to designate successful return.
static Dart_Handle Success(Isolate* isolate);
+ // Sets up the callback error object after initializing an Isolate. This
+ // object is pre-created because we will not be able to allocate this
+ // object when the error actually occurs. When the error occurs there will
+ // be outstanding acquires to internal data pointers making it unsafe to
+ // allocate objects on the dart heap.
+ static void SetupCallbackError(Isolate* isolate);
+
+ // Gets the handle which holds the pre-created callback error object.
+ static Dart_Handle CallbackError(Isolate* isolate);
+
// Returns true if the handle holds a Smi.
static bool IsSmi(Dart_Handle handle) {
// TODO(turnidge): Assumes RawObject* is at offset zero. Fix.
@@ -175,6 +180,19 @@
DISALLOW_COPY_AND_ASSIGN(IsolateSaver);
};
+// Start a scope in which no Dart API call backs are allowed.
+#define START_NO_CALLBACK_SCOPE(isolate) \
+ isolate->IncrementNoCallbackScopeDepth()
+
+// End a no Dart API call backs Scope.
+#define END_NO_CALLBACK_SCOPE(isolate) \
+ isolate->DecrementNoCallbackScopeDepth()
+
+#define CHECK_CALLBACK_STATE(isolate) \
+ if (isolate->no_callback_scope_depth() != 0) { \
+ return reinterpret_cast<Dart_Handle>(Api::CallbackError(isolate)); \
+ } \
+
} // namespace dart.
#endif // VM_DART_API_IMPL_H_
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 625d603..df08036 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -204,7 +204,7 @@
// Non-instance objects.
{
Isolate* isolate = Isolate::Current();
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
Dart_Handle class1 = Api::NewHandle(isolate, Object::null_class());
Dart_Handle class2 = Api::NewHandle(isolate, Object::class_class());
@@ -695,6 +695,10 @@
" a.add(20);"
" a.add(30);"
" return a;"
+ "}"
+ ""
+ "List immutable() {"
+ " return const [0, 1, 2];"
"}";
Dart_Handle result;
@@ -706,71 +710,71 @@
EXPECT_VALID(result);
// First ensure that the returned object is an array.
- Dart_Handle ListAccessTestObj = result;
+ Dart_Handle list_access_test_obj = result;
- EXPECT(Dart_IsList(ListAccessTestObj));
+ EXPECT(Dart_IsList(list_access_test_obj));
// Get length of array object.
intptr_t len = 0;
- result = Dart_ListLength(ListAccessTestObj, &len);
+ result = Dart_ListLength(list_access_test_obj, &len);
EXPECT_VALID(result);
EXPECT_EQ(3, len);
// Access elements in the array.
int64_t value;
- result = Dart_ListGetAt(ListAccessTestObj, 0);
+ result = Dart_ListGetAt(list_access_test_obj, 0);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(10, value);
- result = Dart_ListGetAt(ListAccessTestObj, 1);
+ result = Dart_ListGetAt(list_access_test_obj, 1);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(20, value);
- result = Dart_ListGetAt(ListAccessTestObj, 2);
+ result = Dart_ListGetAt(list_access_test_obj, 2);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(30, value);
// Set some elements in the array.
- result = Dart_ListSetAt(ListAccessTestObj, 0, Dart_NewInteger(0));
+ result = Dart_ListSetAt(list_access_test_obj, 0, Dart_NewInteger(0));
EXPECT_VALID(result);
- result = Dart_ListSetAt(ListAccessTestObj, 1, Dart_NewInteger(1));
+ result = Dart_ListSetAt(list_access_test_obj, 1, Dart_NewInteger(1));
EXPECT_VALID(result);
- result = Dart_ListSetAt(ListAccessTestObj, 2, Dart_NewInteger(2));
+ result = Dart_ListSetAt(list_access_test_obj, 2, Dart_NewInteger(2));
EXPECT_VALID(result);
// Get length of array object.
- result = Dart_ListLength(ListAccessTestObj, &len);
+ result = Dart_ListLength(list_access_test_obj, &len);
EXPECT_VALID(result);
EXPECT_EQ(3, len);
// Now try and access these elements in the array.
- result = Dart_ListGetAt(ListAccessTestObj, 0);
+ result = Dart_ListGetAt(list_access_test_obj, 0);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(0, value);
- result = Dart_ListGetAt(ListAccessTestObj, 1);
+ result = Dart_ListGetAt(list_access_test_obj, 1);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(1, value);
- result = Dart_ListGetAt(ListAccessTestObj, 2);
+ result = Dart_ListGetAt(list_access_test_obj, 2);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(2, value);
uint8_t native_array[3];
- result = Dart_ListGetAsBytes(ListAccessTestObj, 0, native_array, 3);
+ result = Dart_ListGetAsBytes(list_access_test_obj, 0, native_array, 3);
EXPECT_VALID(result);
EXPECT_EQ(0, native_array[0]);
EXPECT_EQ(1, native_array[1]);
@@ -779,22 +783,36 @@
native_array[0] = 10;
native_array[1] = 20;
native_array[2] = 30;
- result = Dart_ListSetAsBytes(ListAccessTestObj, 0, native_array, 3);
+ result = Dart_ListSetAsBytes(list_access_test_obj, 0, native_array, 3);
EXPECT_VALID(result);
- result = Dart_ListGetAsBytes(ListAccessTestObj, 0, native_array, 3);
+ result = Dart_ListGetAsBytes(list_access_test_obj, 0, native_array, 3);
EXPECT_VALID(result);
EXPECT_EQ(10, native_array[0]);
EXPECT_EQ(20, native_array[1]);
EXPECT_EQ(30, native_array[2]);
- result = Dart_ListGetAt(ListAccessTestObj, 2);
+ result = Dart_ListGetAt(list_access_test_obj, 2);
EXPECT_VALID(result);
result = Dart_IntegerToInt64(result, &value);
EXPECT_VALID(result);
EXPECT_EQ(30, value);
// Check if we get an exception when accessing beyond limit.
- result = Dart_ListGetAt(ListAccessTestObj, 4);
+ result = Dart_ListGetAt(list_access_test_obj, 4);
EXPECT(Dart_IsError(result));
+
+ // Check that we get an exception (and not a fatal error) when
+ // calling ListSetAt and ListSetAsBytes with an immutable list.
+ list_access_test_obj = Dart_Invoke(lib, NewString("immutable"), 0, NULL);
+ EXPECT_VALID(list_access_test_obj);
+ EXPECT(Dart_IsList(list_access_test_obj));
+
+ result = Dart_ListSetAsBytes(list_access_test_obj, 0, native_array, 3);
+ EXPECT(Dart_IsError(result));
+ EXPECT(Dart_IsUnhandledExceptionError(result));
+
+ result = Dart_ListSetAt(list_access_test_obj, 0, Dart_NewInteger(42));
+ EXPECT(Dart_IsError(result));
+ EXPECT(Dart_IsUnhandledExceptionError(result));
}
@@ -812,13 +830,9 @@
result = Dart_ListSetAt(byte_array1, -1, Dart_NewInteger(1));
EXPECT(Dart_IsError(result));
- result = Dart_ByteArraySetUint8At(byte_array1, -1, 1);
- EXPECT(Dart_IsError(result));
result = Dart_ListSetAt(byte_array1, 10, Dart_NewInteger(1));
EXPECT(Dart_IsError(result));
- result = Dart_ByteArraySetUint8At(byte_array1, 10, 1);
- EXPECT(Dart_IsError(result));
// Set through the List API.
for (intptr_t i = 0; i < 10; ++i) {
@@ -831,27 +845,6 @@
int64_t int64_t_value = -1;
EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
EXPECT_EQ(i + 1, int64_t_value);
- // Get through the ByteArray API.
- uint8_t uint8_t_value = 0xFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
- EXPECT_EQ(i + 1, uint8_t_value);
- }
-
- // Set through the ByteArray API.
- for (intptr_t i = 0; i < 10; ++i) {
- EXPECT_VALID(Dart_ByteArraySetUint8At(byte_array1, i, i + 2));
- }
- for (intptr_t i = 0; i < 10; ++i) {
- // Get through the List API.
- Dart_Handle integer_obj = Dart_ListGetAt(byte_array1, i);
- EXPECT_VALID(integer_obj);
- int64_t int64_t_value = -1;
- EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
- EXPECT_EQ(i + 2, int64_t_value);
- // Get through the ByteArray API.
- uint8_t uint8_t_value = 0xFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
- EXPECT_EQ(i + 2, uint8_t_value);
}
Dart_Handle byte_array2 = Dart_NewByteArray(10);
@@ -861,6 +854,8 @@
// Set through the List API.
for (intptr_t i = 0; i < 10; ++i) {
+ result = Dart_ListSetAt(byte_array1, i, Dart_NewInteger(i + 2));
+ EXPECT_VALID(result);
result = Dart_ListSetAt(byte_array2, i, Dart_NewInteger(i + 2));
EXPECT_VALID(result);
}
@@ -871,57 +866,9 @@
is_equal = false;
Dart_ObjectEquals(e1, e2, &is_equal);
EXPECT(is_equal);
- // Get through the ByteArray API.
- uint8_t v1 = 0xFF;
- uint8_t v2 = 0XFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &v1));
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array2, i, &v2));
- EXPECT_NE(v1, 0xFF);
- EXPECT_NE(v2, 0xFF);
- EXPECT_EQ(v1, v2);
- }
-
- byte_array2 = Dart_NewByteArray(10);
- is_equal = false;
- Dart_ObjectEquals(byte_array1, byte_array2, &is_equal);
- EXPECT(!is_equal);
-
- // Set through the ByteArray API.
- for (intptr_t i = 0; i < 10; ++i) {
- result = Dart_ByteArraySetUint8At(byte_array2, i, i + 2);
- EXPECT_VALID(result);
- }
- for (intptr_t i = 0; i < 10; ++i) {
- // Get through the List API.
- Dart_Handle e1 = Dart_ListGetAt(byte_array1, i);
- Dart_Handle e2 = Dart_ListGetAt(byte_array2, i);
- is_equal = false;
- Dart_ObjectEquals(e1, e2, &is_equal);
- EXPECT(is_equal);
- // Get through the ByteArray API.
- uint8_t v1 = 0xFF;
- uint8_t v2 = 0XFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &v1));
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array2, i, &v2));
- EXPECT_NE(v1, 0xFF);
- EXPECT_NE(v2, 0xFF);
- EXPECT_EQ(v1, v2);
}
uint8_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
- result = Dart_ListSetAsBytes(byte_array1, 0, data, 10);
- EXPECT_VALID(result);
- for (intptr_t i = 0; i < 10; ++i) {
- Dart_Handle integer_obj = Dart_ListGetAt(byte_array1, i);
- EXPECT_VALID(integer_obj);
- int64_t int64_t_value = -1;
- EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
- EXPECT_EQ(i, int64_t_value);
- uint8_t uint8_t_value = 0xFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
- EXPECT_EQ(i, uint8_t_value);
- }
-
for (intptr_t i = 0; i < 10; ++i) {
EXPECT_VALID(Dart_ListSetAt(byte_array1, i, Dart_NewInteger(10 - i)));
}
@@ -932,160 +879,40 @@
int64_t int64_t_value = -1;
EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
EXPECT_EQ(10 - i, int64_t_value);
- uint8_t uint8_t_value = 0xFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
- EXPECT_EQ(10 - i, uint8_t_value);
- }
-
- for (intptr_t i = 0; i < 10; ++i) {
- EXPECT_VALID(Dart_ByteArraySetUint8At(byte_array1, i, 10 + i));
- }
- Dart_ListGetAsBytes(byte_array1, 0, data, 10);
- for (intptr_t i = 0; i < 10; ++i) {
- Dart_Handle integer_obj = Dart_ListGetAt(byte_array1, i);
- EXPECT_VALID(integer_obj);
- int64_t int64_t_value = -1;
- EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
- EXPECT_EQ(10 + i, int64_t_value);
- uint8_t uint8_t_value = 0xFF;
- EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
- EXPECT_EQ(10 + i, uint8_t_value);
}
}
-TEST_CASE(ByteArrayAlignedMultiByteAccess) {
- intptr_t length = 16;
- Dart_Handle byte_array = Dart_NewByteArray(length);
- intptr_t api_length = 0;
- EXPECT_VALID(Dart_ListLength(byte_array, &api_length));
- EXPECT_EQ(length, api_length);
+TEST_CASE(ScalarListDirectAccess) {
+ Dart_Handle str = Dart_NewStringFromCString("junk");
+ Dart_Handle byte_array = Dart_NewByteArray(10);
+ EXPECT_VALID(byte_array);
+ Dart_Handle result;
+ result = Dart_ScalarListAcquireData(byte_array, NULL, NULL, NULL);
+ EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'type'"
+ " to be non-null.");
+ Dart_Scalar_Type type;
+ result = Dart_ScalarListAcquireData(byte_array, &type, NULL, NULL);
+ EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'data'"
+ " to be non-null.");
+ void* data;
+ result = Dart_ScalarListAcquireData(byte_array, &type, &data, NULL);
+ EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'len'"
+ " to be non-null.");
+ intptr_t len;
+ result = Dart_ScalarListAcquireData(Dart_Null(), &type, &data, &len);
+ EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'array'"
+ " to be non-null.");
+ result = Dart_ScalarListAcquireData(str, &type, &data, &len);
+ EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'array'"
+ " to be of type 'scalar list'.");
- // 4-byte aligned sets.
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 0, FLT_MIN));
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 4, FLT_MAX));
-
- float float_value = 0.0f;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 0, &float_value));
- EXPECT_EQ(FLT_MIN, float_value);
-
- float_value = 0.0f;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 4, &float_value));
- EXPECT_EQ(FLT_MAX, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 0, 0.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 0, &float_value));
- EXPECT_EQ(0.0f, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 4, 1.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 4, &float_value));
- EXPECT_EQ(1.0f, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 0, -1.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 0, &float_value));
- EXPECT_EQ(-1.0f, float_value);
-
- // 8-byte aligned sets.
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 0, DBL_MIN));
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 8, DBL_MAX));
-
- double double_value = 0.0;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 0, &double_value));
- EXPECT_EQ(DBL_MIN, double_value);
-
- double_value = 0.0;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 8, &double_value));
- EXPECT_EQ(DBL_MAX, double_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 0, 0.0));
- double_value = DBL_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 0, &double_value));
- EXPECT_EQ(0.0, double_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 8, 1.0));
- double_value = DBL_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 8, &double_value));
- EXPECT_EQ(1.0, double_value);
-}
-
-
-TEST_CASE(ByteArrayMisalignedMultiByteAccess) {
- intptr_t length = 17;
- Dart_Handle byte_array = Dart_NewByteArray(length);
- intptr_t api_length = 0;
- EXPECT_VALID(Dart_ListLength(byte_array, &api_length));
- EXPECT_EQ(length, api_length);
-
- // 4-byte misaligned sets.
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 1, FLT_MIN));
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 5, FLT_MAX));
-
- float float_value = 0.0f;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 1, &float_value));
- EXPECT_EQ(FLT_MIN, float_value);
-
- float_value = 0.0f;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 5, &float_value));
- EXPECT_EQ(FLT_MAX, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 1, 0.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 1, &float_value));
- EXPECT_EQ(0.0f, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 5, -0.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 5, &float_value));
- EXPECT_EQ(-0.0f, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 5, 1.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 5, &float_value));
- EXPECT_EQ(1.0f, float_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 1, -1.0f));
- float_value = FLT_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 1, &float_value));
- EXPECT_EQ(-1.0f, float_value);
-
- // 8-byte misaligned sets.
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 1, DBL_MIN));
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 9, DBL_MAX));
-
- double double_value = 0.0;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 1, &double_value));
- EXPECT_EQ(DBL_MIN, double_value);
-
- double_value = 0.0;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 9, &double_value));
- EXPECT_EQ(DBL_MAX, double_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 1, 0.0));
- double_value = DBL_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 1, &double_value));
- EXPECT_EQ(0.0, double_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 9, -0.0));
- double_value = DBL_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 9, &double_value));
- EXPECT_EQ(-0.0, double_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 9, 1.0));
- double_value = DBL_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 9, &double_value));
- EXPECT_EQ(1.0, double_value);
-
- EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 1, -1.0));
- double_value = DBL_MAX;
- EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 1, &double_value));
- EXPECT_EQ(-1.0, double_value);
+ result = Dart_ScalarListReleaseData(Dart_Null());
+ EXPECT_ERROR(result, "Dart_ScalarListReleaseData expects argument 'array'"
+ " to be non-null.");
+ result = Dart_ScalarListReleaseData(str);
+ EXPECT_ERROR(result, "Dart_ScalarListReleaseData expects argument 'array'"
+ " to be of type 'scalar list'.");
}
@@ -1199,8 +1026,8 @@
}
-
-static void ExternalByteArrayCallbackFinalizer(void* peer) {
+static void ExternalByteArrayCallbackFinalizer(Dart_Handle handle, void* peer) {
+ Dart_DeletePersistentHandle(handle);
*static_cast<int*>(peer) = 42;
}
@@ -1244,7 +1071,7 @@
Dart_EnterScope();
{
EXPECT(state->top_scope() != NULL);
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
const String& str1 = String::Handle(String::New("Test String"));
Dart_Handle ref = Api::NewHandle(isolate, str1.raw());
String& str2 = String::Handle();
@@ -1269,7 +1096,7 @@
Dart_Handle handles[2000];
Dart_EnterScope();
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
Dart_Handle ref1 = Api::NewHandle(isolate, String::New(kTestString1));
for (int i = 0; i < 1000; i++) {
handles[i] = Dart_NewPersistentHandle(ref1);
@@ -1294,7 +1121,7 @@
Dart_ExitScope();
{
StackZone zone(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ HANDLESCOPE(isolate);
for (int i = 0; i < 500; i++) {
String& str = String::Handle();
str ^= Api::UnwrapHandle(handles[i]);
@@ -2245,7 +2072,7 @@
Dart_Handle handles[300];
{
StackZone zone(isolate);
- DARTSCOPE_NOCHECKS(isolate);
+ HANDLESCOPE(isolate);
Smi& val = Smi::Handle();
// Start a new scope and allocate some local handles.
@@ -2905,7 +2732,7 @@
// Invoke a function which returns an object of type NativeFields.
result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
EXPECT_VALID(result);
- DARTSCOPE_NOCHECKS(Isolate::Current());
+ DARTSCOPE(Isolate::Current());
Instance& obj = Instance::Handle();
obj ^= Api::UnwrapHandle(result);
const Class& cls = Class::Handle(obj.clazz());
@@ -2974,7 +2801,7 @@
// Invoke a function which returns an object of type NativeFields.
result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
EXPECT_VALID(result);
- DARTSCOPE_NOCHECKS(Isolate::Current());
+ DARTSCOPE(Isolate::Current());
Instance& obj = Instance::Handle();
obj ^= Api::UnwrapHandle(result);
const Class& cls = Class::Handle(obj.clazz());
@@ -3229,7 +3056,7 @@
" return () {};\n"
"}\n";
Dart_Handle result;
- DARTSCOPE_NOCHECKS(Isolate::Current());
+ DARTSCOPE(Isolate::Current());
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -3305,7 +3132,7 @@
" });\n"
"}\n";
- DARTSCOPE_NOCHECKS(Isolate::Current());
+ DARTSCOPE(Isolate::Current());
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -3888,7 +3715,7 @@
Dart_Handle result;
Dart_Handle owner;
Dart_Handle defining_function;
- DARTSCOPE_NOCHECKS(Isolate::Current());
+ DARTSCOPE(Isolate::Current());
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -4056,7 +3883,7 @@
" return InvokeClosure.method2(10);\n"
"}\n";
Dart_Handle result;
- DARTSCOPE_NOCHECKS(Isolate::Current());
+ DARTSCOPE(Isolate::Current());
// Create a test library and Load up a test script in it.
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -6919,7 +6746,7 @@
Isolate* isolate = Isolate::Current();
Dart_EnterScope();
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
Dart_Handle str = NewString("a string");
EXPECT_VALID(str);
EXPECT(Dart_IsString(str));
@@ -6992,7 +6819,7 @@
Isolate* isolate = Isolate::Current();
Dart_EnterScope();
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
Dart_Handle s1 = NewString("s1");
EXPECT_VALID(s1);
EXPECT(Dart_IsString(s1));
@@ -7076,7 +6903,7 @@
isolate->heap()->CollectGarbage(Heap::kNew);
isolate->heap()->CollectGarbage(Heap::kNew);
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
String& handle = String::Handle();
handle ^= Api::UnwrapHandle(str);
EXPECT(handle.IsOld());
@@ -7129,7 +6956,7 @@
Isolate* isolate = Isolate::Current();
Dart_EnterScope();
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
Dart_Handle str = Api::NewHandle(isolate, String::New("str", Heap::kOld));
EXPECT_VALID(str);
EXPECT(Dart_IsString(str));
@@ -7205,7 +7032,7 @@
Isolate* isolate = Isolate::Current();
Dart_EnterScope();
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
Dart_Handle s1 = Api::NewHandle(isolate, String::New("s1", Heap::kOld));
EXPECT_VALID(s1);
EXPECT(Dart_IsString(s1));
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index b306b96..61a9fc6 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -870,7 +870,7 @@
int length = object->value.as_external_byte_array.length;
uint8_t* data = object->value.as_external_byte_array.data;
void* peer = object->value.as_external_byte_array.peer;
- Dart_PeerFinalizer callback =
+ Dart_WeakPersistentHandleFinalizer callback =
object->value.as_external_byte_array.callback;
WriteSmi(length);
WriteIntptrValue(reinterpret_cast<intptr_t>(data));
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index debb26a..57e62c0 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -526,7 +526,8 @@
class ApiState {
public:
ApiState() : top_scope_(NULL), delayed_weak_reference_sets_(NULL),
- null_(NULL), true_(NULL), false_(NULL) { }
+ null_(NULL), true_(NULL), false_(NULL),
+ callback_error_(NULL) {}
~ApiState() {
while (top_scope_ != NULL) {
ApiLocalScope* scope = top_scope_;
@@ -569,7 +570,9 @@
}
void UnwindScopes(uword sp) {
- while (top_scope_ != NULL && top_scope_->stack_marker() < sp) {
+ while (top_scope_ != NULL &&
+ top_scope_->stack_marker() != 0 &&
+ top_scope_->stack_marker() <= sp) {
ApiLocalScope* scope = top_scope_;
top_scope_ = top_scope_->previous();
delete scope;
@@ -675,6 +678,19 @@
return false_;
}
+ void SetupCallbackError() {
+ ASSERT(callback_error_ == NULL);
+ callback_error_ = persistent_handles().AllocateHandle();
+ callback_error_->set_raw(
+ String::New("Internal Dart data pointers have been acquired, "
+ "please release them using Dart_ByteArrayReleaseData."));
+ }
+
+ PersistentHandle* CallbackError() const {
+ ASSERT(callback_error_ != NULL);
+ return callback_error_;
+ }
+
void DelayWeakReferenceSet(WeakReferenceSet* reference_set) {
WeakReferenceSet::Push(reference_set, &delayed_weak_reference_sets_);
}
@@ -690,6 +706,7 @@
PersistentHandle* null_;
PersistentHandle* true_;
PersistentHandle* false_;
+ PersistentHandle* callback_error_;
DISALLOW_COPY_AND_ASSIGN(ApiState);
};
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 47cb5b7..e4924c8 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -46,6 +46,7 @@
ASSERT(context.isolate() == Isolate::Current());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
+ ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
return entrypoint(code.EntryPoint(),
arguments_descriptor,
arguments,
@@ -82,6 +83,7 @@
ASSERT(context.isolate() == Isolate::Current());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
+ ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
return entrypoint(code.EntryPoint(),
arguments_descriptor,
arguments,
@@ -127,6 +129,7 @@
ASSERT(context.isolate() == Isolate::Current());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
+ ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
return entrypoint(code.EntryPoint(),
arguments_descriptor,
arguments,
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 37d6e23..035cc65 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -210,12 +210,8 @@
*to_addr = continue_at_pc;
}
- static void GetEncodedValues(intptr_t from_index,
- intptr_t* object_table_index,
- intptr_t* deopt_id) {
- *object_table_index = ObjectTableIndex::decode(from_index);
- *deopt_id = DeoptId::decode(from_index);
- }
+ intptr_t object_table_index() const { return object_table_index_; }
+ intptr_t deopt_id() const { return deopt_id_; }
private:
static const intptr_t kFieldWidth = kBitsPerWord / 2;
@@ -548,7 +544,7 @@
}
void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
- // The deoptimization info is uncompresses by translating away suffixes
+ // The deoptimization info is uncompressed by translating away suffixes
// before executing the instructions.
UNREACHABLE();
}
@@ -575,19 +571,17 @@
}
-uword DeoptInstr::GetRetAfterAddress(intptr_t from_index,
+uword DeoptInstr::GetRetAfterAddress(DeoptInstr* instr,
const Array& object_table,
Function* func) {
+ ASSERT(instr->kind() == kRetAfterAddress);
+ DeoptRetAfterAddressInstr* ret_after_instr =
+ static_cast<DeoptRetAfterAddressInstr*>(instr);
ASSERT(!object_table.IsNull());
ASSERT(func != NULL);
- intptr_t object_table_index;
- intptr_t deopt_id;
- DeoptRetAfterAddressInstr::GetEncodedValues(from_index,
- &object_table_index,
- &deopt_id);
- *func ^= object_table.At(object_table_index);
+ *func ^= object_table.At(ret_after_instr->object_table_index());
const Code& code = Code::Handle(func->unoptimized_code());
- return code.GetDeoptAfterPcAtDeoptId(deopt_id);
+ return code.GetDeoptAfterPcAtDeoptId(ret_after_instr->deopt_id());
}
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 74a919a..134d33d 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -115,6 +115,8 @@
virtual void Execute(DeoptimizationContext* deopt_context,
intptr_t to_index) = 0;
+ virtual DeoptInstr::Kind kind() const = 0;
+
bool Equals(const DeoptInstr& other) const {
return (kind() == other.kind()) && (from_index() == other.from_index());
}
@@ -125,12 +127,11 @@
// Get the function and return address which is encoded in this
// kRetAfterAddress deopt instruction.
- static uword GetRetAfterAddress(intptr_t deopt_from_index,
+ static uword GetRetAfterAddress(DeoptInstr* instr,
const Array& object_table,
Function* func);
protected:
- virtual DeoptInstr::Kind kind() const = 0;
virtual intptr_t from_index() const = 0;
friend class DeoptInfoBuilder;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 167b74b..98f2d04 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -55,17 +55,15 @@
if (code.is_optimized()) {
// For optimized frames, extract all the inlined functions if any
// into the stack trace.
- InlinedFunctionsInDartFrameIterator optimized_frames(frame);
- while (true) {
- uword pc = 0;
- func = optimized_frames.GetNextFunction(&pc);
- if (func.IsNull()) {
- break;
- }
+ for (InlinedFunctionsIterator it(frame); !it.Done(); it.Advance()) {
+ func = it.function();
+ code = it.code();
+ uword pc = it.pc();
ASSERT(pc != 0);
- code = func.unoptimized_code();
- offset = Smi::New(pc - code.EntryPoint());
+ ASSERT(code.EntryPoint() <= pc);
+ ASSERT(pc < (code.EntryPoint() + code.Size()));
if (ShouldShowFunction(func)) {
+ offset = Smi::New(pc - code.EntryPoint());
func_list.Add(func);
code_list.Add(code);
pc_offset_list.Add(offset);
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index e2e114e..2ea9813 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -107,15 +107,15 @@
Value* use = instr->InputAt(i);
use->set_instruction(NULL);
use->set_use_index(-1);
+ use->set_previous_use(NULL);
use->set_next_use(NULL);
}
- if (instr->env() != NULL) {
- for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
- Value* use = it.CurrentValue();
- use->set_instruction(NULL);
- use->set_use_index(-1);
- use->set_next_use(NULL);
- }
+ for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
+ Value* use = it.CurrentValue();
+ use->set_instruction(NULL);
+ use->set_use_index(-1);
+ use->set_previous_use(NULL);
+ use->set_next_use(NULL);
}
}
@@ -164,18 +164,25 @@
}
Definition* defn = instr->AsDefinition();
if (defn != NULL) {
- for (Value* use = defn->input_use_list();
- use != NULL;
- use = use->next_use()) {
- ASSERT(defn == use->definition());
- ASSERT(use == use->instruction()->InputAt(use->use_index()));
+ Value* prev = NULL;
+ Value* curr = defn->input_use_list();
+ while (curr != NULL) {
+ ASSERT(prev == curr->previous_use());
+ ASSERT(defn == curr->definition());
+ ASSERT(curr == curr->instruction()->InputAt(curr->use_index()));
+ prev = curr;
+ curr = curr->next_use();
}
- for (Value* use = defn->env_use_list();
- use != NULL;
- use = use->next_use()) {
- ASSERT(defn == use->definition());
- ASSERT(use ==
- use->instruction()->env()->ValueAtUseIndex(use->use_index()));
+
+ prev = NULL;
+ curr = defn->env_use_list();
+ while (curr != NULL) {
+ ASSERT(prev == curr->previous_use());
+ ASSERT(defn == curr->definition());
+ ASSERT(curr ==
+ curr->instruction()->env()->ValueAtUseIndex(curr->use_index()));
+ prev = curr;
+ curr = curr->next_use();
}
}
}
@@ -220,6 +227,7 @@
Value* use = instr->InputAt(i);
ASSERT(use->instruction() == NULL);
ASSERT(use->use_index() == -1);
+ ASSERT(use->previous_use() == NULL);
ASSERT(use->next_use() == NULL);
DEBUG_ASSERT(!FLAG_verify_compiler ||
(0 == MembershipCount(use, use->definition()->input_use_list())));
@@ -238,6 +246,7 @@
Value* use = it.CurrentValue();
ASSERT(use->instruction() == NULL);
ASSERT(use->use_index() == -1);
+ ASSERT(use->previous_use() == NULL);
ASSERT(use->next_use() == NULL);
DEBUG_ASSERT(!FLAG_verify_compiler ||
(0 == MembershipCount(use, use->definition()->env_use_list())));
@@ -282,6 +291,7 @@
Value* use = phi->InputAt(pred_index);
ASSERT(use->instruction() == NULL);
ASSERT(use->use_index() == -1);
+ ASSERT(use->previous_use() == NULL);
ASSERT(use->next_use() == NULL);
DEBUG_ASSERT(!FLAG_verify_compiler ||
(0 == MembershipCount(use, use->definition()->input_use_list())));
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 9d04729..88c7c9e 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1786,6 +1786,34 @@
}
+static intptr_t GetResultCidOfNative(const Function& function) {
+ const Class& function_class = Class::Handle(function.Owner());
+ if (function_class.library() == Library::ScalarlistLibrary()) {
+ const String& function_name = String::Handle(function.name());
+ if (!String::EqualsIgnoringPrivateKey(function_name, Symbols::_New())) {
+ return kDynamicCid;
+ }
+ switch (function_class.id()) {
+ case kInt8ArrayCid:
+ case kUint8ArrayCid:
+ case kUint8ClampedArrayCid:
+ case kInt16ArrayCid:
+ case kUint16ArrayCid:
+ case kInt32ArrayCid:
+ case kUint32ArrayCid:
+ case kInt64ArrayCid:
+ case kUint64ArrayCid:
+ case kFloat32ArrayCid:
+ case kFloat64ArrayCid:
+ return function_class.id();
+ default:
+ return kDynamicCid; // Unknown.
+ }
+ }
+ return kDynamicCid;
+}
+
+
// <Expression> ::= StaticCall { function: Function
// arguments: <ArgumentList> }
void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
@@ -1821,6 +1849,10 @@
node->function(),
node->arguments()->names(),
arguments);
+ if (node->function().is_native()) {
+ const intptr_t result_cid = GetResultCidOfNative(node->function());
+ call->set_result_cid(result_cid);
+ }
ReturnDefinition(call);
}
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index a55ae09..11349ad 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -152,7 +152,8 @@
may_reoptimize_(false),
double_class_(Class::ZoneHandle(
Isolate::Current()->object_store()->double_class())),
- parallel_move_resolver_(this) {
+ parallel_move_resolver_(this),
+ pending_deoptimization_env_(NULL) {
ASSERT(assembler != NULL);
}
@@ -224,8 +225,10 @@
} else {
ASSERT(instr->locs() != NULL);
EmitInstructionPrologue(instr);
+ ASSERT(pending_deoptimization_env_ == NULL);
pending_deoptimization_env_ = instr->env();
instr->EmitNativeCode(this);
+ pending_deoptimization_env_ = NULL;
EmitInstructionEpilogue(instr);
}
}
@@ -535,7 +538,7 @@
return;
}
// Emit IC call that will count and thus may need reoptimization at
- // return instruction.
+ // function entry.
ASSERT(!is_optimizing() || may_reoptimize());
switch (ic_data.num_args_tested()) {
case 1:
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 3bed948..eb7181f 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -220,6 +220,7 @@
bool TryIntrinsify();
void GenerateCallRuntime(intptr_t token_pos,
+ intptr_t deopt_id,
const RuntimeEntry& entry,
LocationSummary* locs);
@@ -235,11 +236,13 @@
LocationSummary* locs);
void GenerateAssertAssignable(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& dst_type,
const String& dst_name,
LocationSummary* locs);
void GenerateInstanceOf(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& type,
bool negate_result,
LocationSummary* locs);
@@ -394,6 +397,8 @@
Register index);
private:
+ friend class CheckStackOverflowSlowPath; // For pending_deoptimization_env_.
+
void EmitFrameEntry();
void AddStaticCallTarget(const Function& function);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 3bd8df5..38b9901 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -110,6 +110,7 @@
void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& type,
bool negate_result,
LocationSummary* locs) {
@@ -118,6 +119,7 @@
void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& dst_type,
const String& dst_name,
LocationSummary* locs) {
@@ -178,6 +180,7 @@
void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+ intptr_t deopt_id,
const RuntimeEntry& entry,
LocationSummary* locs) {
UNIMPLEMENTED();
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index a8d383d..102f205 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -459,6 +459,7 @@
// Returns:
// - true or false in EAX.
void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& type,
bool negate_result,
LocationSummary* locs) {
@@ -501,7 +502,7 @@
__ pushl(EDX); // Instantiator type arguments.
__ LoadObject(EAX, test_cache);
__ pushl(EAX);
- GenerateCallRuntime(token_pos, kInstanceofRuntimeEntry, locs);
+ GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// instanceof runtime call will be left as the result of the operation.
__ Drop(5);
@@ -541,6 +542,7 @@
// Performance notes: positive checks must be quick, negative checks can be slow
// as they throw an exception.
void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& dst_type,
const String& dst_name,
LocationSummary* locs) {
@@ -569,6 +571,7 @@
__ PushObject(dst_name); // Push the name of the destination.
__ PushObject(error_message);
GenerateCallRuntime(token_pos,
+ deopt_id,
kMalformedTypeErrorRuntimeEntry,
locs);
// We should never return here.
@@ -596,7 +599,7 @@
__ PushObject(dst_name); // Push the name of the destination.
__ LoadObject(EAX, test_cache);
__ pushl(EAX);
- GenerateCallRuntime(token_pos, kTypeCheckRuntimeEntry, locs);
+ GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// type check runtime call is the checked value.
__ Drop(6);
@@ -1091,11 +1094,25 @@
void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+ intptr_t deopt_id,
const RuntimeEntry& entry,
LocationSummary* locs) {
__ CallRuntime(entry);
- AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
+ AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
RecordSafepoint(locs);
+ if (deopt_id != Isolate::kNoDeoptId) {
+ // Marks either the continuation point in unoptimized code or the
+ // deoptimization point in optimized code, after call.
+ if (is_optimizing()) {
+ AddDeoptIndexAtCall(deopt_id, token_pos);
+ } else {
+ // Add deoptimization continuation point after the call and before the
+ // arguments are removed.
+ AddCurrentDescriptor(PcDescriptors::kDeoptAfter,
+ deopt_id,
+ token_pos);
+ }
+ }
}
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index c6243bc..6ff3a8c 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -110,6 +110,7 @@
void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& type,
bool negate_result,
LocationSummary* locs) {
@@ -118,6 +119,7 @@
void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& dst_type,
const String& dst_name,
LocationSummary* locs) {
@@ -178,6 +180,7 @@
void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+ intptr_t deopt_id,
const RuntimeEntry& entry,
LocationSummary* locs) {
UNIMPLEMENTED();
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 1abf729..4e1b9aa 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -459,6 +459,7 @@
// Returns:
// - true or false in RAX.
void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& type,
bool negate_result,
LocationSummary* locs) {
@@ -501,7 +502,7 @@
__ pushq(RDX); // Instantiator type arguments.
__ LoadObject(RAX, test_cache);
__ pushq(RAX);
- GenerateCallRuntime(token_pos, kInstanceofRuntimeEntry, locs);
+ GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// instanceof runtime call will be left as the result of the operation.
__ Drop(5);
@@ -541,6 +542,7 @@
// Performance notes: positive checks must be quick, negative checks can be slow
// as they throw an exception.
void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+ intptr_t deopt_id,
const AbstractType& dst_type,
const String& dst_name,
LocationSummary* locs) {
@@ -569,6 +571,7 @@
__ PushObject(dst_name); // Push the name of the destination.
__ PushObject(error_message);
GenerateCallRuntime(token_pos,
+ deopt_id,
kMalformedTypeErrorRuntimeEntry,
locs);
// We should never return here.
@@ -596,7 +599,7 @@
__ PushObject(dst_name); // Push the name of the destination.
__ LoadObject(RAX, test_cache);
__ pushq(RAX);
- GenerateCallRuntime(token_pos, kTypeCheckRuntimeEntry, locs);
+ GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
// Pop the parameters supplied to the runtime entry. The result of the
// type check runtime call is the checked value.
__ Drop(6);
@@ -1095,11 +1098,25 @@
void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+ intptr_t deopt_id,
const RuntimeEntry& entry,
LocationSummary* locs) {
__ CallRuntime(entry);
- AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
+ AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
RecordSafepoint(locs);
+ if (deopt_id != Isolate::kNoDeoptId) {
+ // Marks either the continuation point in unoptimized code or the
+ // deoptimization point in optimized code, after call.
+ if (is_optimizing()) {
+ AddDeoptIndexAtCall(deopt_id, token_pos);
+ } else {
+ // Add deoptimization continuation point after the call and before the
+ // arguments are removed.
+ AddCurrentDescriptor(PcDescriptors::kDeoptAfter,
+ deopt_id,
+ token_pos);
+ }
+ }
}
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 29ff1e1..3a2d5df 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -551,9 +551,19 @@
}
}
if (!skip_check) {
- // Insert array bounds check.
+ // Insert array length load and bounds check.
+ const bool is_immutable = (class_id != kGrowableObjectArrayCid);
+ LoadFieldInstr* length = new LoadFieldInstr(
+ (*array)->Copy(),
+ CheckArrayBoundInstr::LengthOffsetFor(class_id),
+ Type::ZoneHandle(Type::SmiType()),
+ is_immutable);
+ length->set_result_cid(kSmiCid);
+ length->set_recognized_kind(
+ LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
+ InsertBefore(call, length, NULL, Definition::kValue);
InsertBefore(call,
- new CheckArrayBoundInstr((*array)->Copy(),
+ new CheckArrayBoundInstr(new Value(length),
(*index)->Copy(),
class_id,
call),
@@ -690,7 +700,11 @@
type_args,
value_type,
Symbols::Value());
- InsertBefore(call, assert_value, NULL, Definition::kValue);
+ // Newly inserted instructions that can deoptimize or throw an exception
+ // must have a deoptimization id that is valid for lookup in the unoptimized
+ // code.
+ assert_value->deopt_id_ = call->deopt_id();
+ InsertBefore(call, assert_value, call->env(), Definition::kValue);
}
Value* array = NULL;
@@ -729,6 +743,8 @@
bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
const intptr_t class_id = ReceiverClassId(call);
+ // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt.
+ intptr_t deopt_id = Isolate::kNoDeoptId;
switch (class_id) {
case kArrayCid:
case kImmutableArrayCid:
@@ -749,6 +765,14 @@
if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
return false;
}
+ {
+ // Set deopt_id if we can optimistically assume that the result is Smi.
+ // Assume mixed Mint/Smi if this instruction caused deoptimization once.
+ ASSERT(call->HasICData());
+ const ICData& ic_data = *call->ic_data();
+ deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ?
+ call->deopt_id() : Isolate::kNoDeoptId;
+ }
break;
default:
return false;
@@ -756,7 +780,8 @@
Value* array = NULL;
Value* index = NULL;
intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index);
- Definition* array_op = new LoadIndexedInstr(array, index, array_cid);
+ Definition* array_op =
+ new LoadIndexedInstr(array, index, array_cid, deopt_id);
call->ReplaceWith(array_op, current_iterator());
RemovePushArguments(call);
return true;
@@ -960,6 +985,13 @@
new CheckSmiInstr(right->Copy(), call->deopt_id()),
call->env(),
Definition::kEffect);
+ if (left->BindsToConstant() &&
+ ((op_kind == Token::kADD) || (op_kind == Token::kMUL))) {
+ // Constant should be on the right side.
+ Value* temp = left;
+ left = right;
+ right = temp;
+ }
BinarySmiOpInstr* bin_op = new BinarySmiOpInstr(op_kind, call, left, right);
call->ReplaceWith(bin_op, current_iterator());
RemovePushArguments(call);
@@ -1277,15 +1309,24 @@
}
if (!skip_check) {
// Insert bounds check.
+ const bool is_immutable = true;
+ LoadFieldInstr* length = new LoadFieldInstr(
+ str->Copy(),
+ CheckArrayBoundInstr::LengthOffsetFor(cid),
+ Type::ZoneHandle(Type::SmiType()),
+ is_immutable);
+ length->set_result_cid(kSmiCid);
+ length->set_recognized_kind(MethodRecognizer::kStringBaseLength);
+ InsertBefore(call, length, NULL, Definition::kValue);
InsertBefore(call,
- new CheckArrayBoundInstr(str->Copy(),
+ new CheckArrayBoundInstr(new Value(length),
index->Copy(),
cid,
call),
call->env(),
Definition::kEffect);
}
- return new LoadIndexedInstr(str, index, cid);
+ return new LoadIndexedInstr(str, index, cid, Isolate::kNoDeoptId);
}
@@ -2023,7 +2064,6 @@
void ConstrainValueAfterBranch(Definition* defn, Value* use);
void ConstrainValueAfterCheckArrayBound(Definition* defn,
CheckArrayBoundInstr* check);
- Definition* LoadArrayLength(CheckArrayBoundInstr* check);
// Replace uses of the definition def that are dominated by instruction dom
// with uses of other definition.
@@ -2083,53 +2123,6 @@
GrowableArray<Definition*> worklist_;
BitVector* marked_defns_;
- class ArrayLengthData : public ValueObject {
- public:
- ArrayLengthData(Definition* array, Definition* array_length)
- : array_(array), array_length_(array_length) { }
-
- ArrayLengthData(const ArrayLengthData& other)
- : ValueObject(),
- array_(other.array_),
- array_length_(other.array_length_) { }
-
- ArrayLengthData& operator=(const ArrayLengthData& other) {
- array_ = other.array_;
- array_length_ = other.array_length_;
- return *this;
- }
-
- Definition* array() const { return array_; }
- Definition* array_length() const { return array_length_; }
-
- typedef Definition* Value;
- typedef Definition* Key;
- typedef class ArrayLengthData Pair;
-
- // KeyValueTrait members.
- static Key KeyOf(const ArrayLengthData& data) {
- return data.array();
- }
-
- static Value ValueOf(const ArrayLengthData& data) {
- return data.array_length();
- }
-
- static inline intptr_t Hashcode(Key key) {
- return reinterpret_cast<intptr_t>(key);
- }
-
- static inline bool IsKeyEqual(const ArrayLengthData& kv, Key key) {
- return kv.array() == key;
- }
-
- private:
- Definition* array_;
- Definition* array_length_;
- };
-
- DirectChainedHashMap<ArrayLengthData> array_lengths_;
-
DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
};
@@ -2207,29 +2200,19 @@
Instruction* dom,
Definition* other) {
Value* next_use = NULL;
- Value* prev_use = NULL;
for (Value* use = def->input_use_list();
use != NULL;
use = next_use) {
next_use = use->next_use();
// Skip dead phis.
- if (use->instruction()->IsPhi() &&
- !use->instruction()->AsPhi()->is_alive()) {
- prev_use = use;
- continue;
- }
+ PhiInstr* phi = use->instruction()->AsPhi();
+ if ((phi != NULL) && !phi->is_alive()) continue;
if (IsDominatedUse(dom, use)) {
- if (prev_use != NULL) {
- prev_use->set_next_use(next_use);
- } else {
- def->set_input_use_list(next_use);
- }
+ use->RemoveFromInputUseList();
use->set_definition(other);
use->AddToInputUseList();
- } else {
- prev_use = use;
}
}
}
@@ -2373,47 +2356,13 @@
}
-Definition* RangeAnalysis::LoadArrayLength(CheckArrayBoundInstr* check) {
- Definition* array = check->array()->definition();
-
- Definition* length = array_lengths_.Lookup(array);
- if (length != NULL) return length;
-
- StaticCallInstr* allocation = array->AsStaticCall();
- if ((allocation != NULL) &&
- allocation->is_known_constructor() &&
- (allocation->ResultCid() == kArrayCid)) {
- // For fixed length arrays check if array is the result of a constructor
- // call. In this case we can use the length passed to the constructor
- // instead of loading it from array itself.
- length = allocation->ArgumentAt(1)->value()->definition();
- } else {
- // Load length from the array. Do not insert instruction into the graph.
- // It will only be used in range boundaries.
- LoadFieldInstr* length_load = new LoadFieldInstr(
- check->array()->Copy(),
- CheckArrayBoundInstr::LengthOffsetFor(check->array_type()),
- Type::ZoneHandle(Type::SmiType()),
- true); // Immutable.
- length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
- length_load->set_result_cid(kSmiCid);
- length_load->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
- length = length_load;
- }
-
- ASSERT(length != NULL);
- array_lengths_.Insert(ArrayLengthData(array, length));
- return length;
-}
-
-
void RangeAnalysis::ConstrainValueAfterCheckArrayBound(
Definition* defn, CheckArrayBoundInstr* check) {
if (!CheckArrayBoundInstr::IsFixedLengthArrayType(check->array_type())) {
return;
}
- Definition* length = LoadArrayLength(check);
+ Definition* length = check->length()->definition();
Range* constraint_range = new Range(
RangeBoundary::FromConstant(0),
@@ -2610,7 +2559,7 @@
current->IsCheckArrayBound()) {
CheckArrayBoundInstr* check = current->AsCheckArrayBound();
RangeBoundary array_length =
- RangeBoundary::FromDefinition(LoadArrayLength(check));
+ RangeBoundary::FromDefinition(check->length()->definition());
if (check->IsRedundant(array_length)) it.RemoveCurrentFromGraph();
}
}
@@ -4200,9 +4149,25 @@
instr->value()->definition()->AsCreateArray()->ArgumentCount();
const Object& result = Smi::ZoneHandle(Smi::New(length));
SetValue(instr, result);
- } else {
- SetValue(instr, non_constant_);
+ return;
}
+
+ if (instr->IsImmutableLengthLoad()) {
+ ConstantInstr* constant = instr->value()->definition()->AsConstant();
+ if (constant != NULL) {
+ if (constant->value().IsString()) {
+ SetValue(instr, Smi::ZoneHandle(
+ Smi::New(String::Cast(constant->value()).Length())));
+ return;
+ }
+ if (constant->value().IsArray()) {
+ SetValue(instr, Smi::ZoneHandle(
+ Smi::New(Array::Cast(constant->value()).Length())));
+ return;
+ }
+ }
+ }
+ SetValue(instr, non_constant_);
}
@@ -4523,13 +4488,9 @@
// Replace constant-valued instructions without observable side
// effects. Do this for smis only to avoid having to copy other
// objects into the heap's old generation.
- //
- // TODO(kmillikin): Extend this to handle booleans, other number
- // types, etc.
if ((defn != NULL) &&
- (defn->constant_value().IsSmi() ||
- defn->constant_value().IsNull() ||
- defn->constant_value().IsTypeArguments()) &&
+ IsConstant(defn->constant_value()) &&
+ (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) &&
!defn->IsConstant() &&
!defn->IsPushArgument() &&
!defn->IsStoreIndexed() &&
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 41d3091..7cf859f 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -158,7 +158,8 @@
RecordAfterGC();
PrintStats();
if (new_space_->HadPromotionFailure()) {
- CollectGarbage(kOld, api_callbacks);
+ // Old collections should call the API callbacks.
+ CollectGarbage(kOld, kInvokeApiCallbacks);
}
break;
}
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index c7f87b1..d5284b7 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -627,47 +627,57 @@
void Value::AddToInputUseList() {
- set_next_use(definition()->input_use_list());
+ Value* next = definition()->input_use_list();
definition()->set_input_use_list(this);
+ set_next_use(next);
+ set_previous_use(NULL);
+ if (next != NULL) next->set_previous_use(this);
}
void Value::AddToEnvUseList() {
- set_next_use(definition()->env_use_list());
+ Value* next = definition()->env_use_list();
definition()->set_env_use_list(this);
+ set_next_use(next);
+ set_previous_use(NULL);
+ if (next != NULL) next->set_previous_use(this);
}
void Value::RemoveFromInputUseList() {
- if (definition_->input_use_list() == this) {
- definition_->set_input_use_list(next_use_);
- return;
+ Value* previous = previous_use();
+ Value* next = next_use();
+ if (previous == NULL) {
+ definition()->set_input_use_list(next);
+ } else {
+ previous->set_next_use(next);
}
-
- Value* prev = definition_->input_use_list();
- while (prev->next_use_ != this) {
- prev = prev->next_use_;
- }
- prev->next_use_ = next_use_;
- definition_ = NULL;
+ if (next != NULL) next->set_previous_use(previous);
+ set_definition(NULL);
}
void Definition::ReplaceUsesWith(Definition* other) {
ASSERT(other != NULL);
ASSERT(this != other);
- while (input_use_list_ != NULL) {
- Value* current = input_use_list_;
- input_use_list_ = input_use_list_->next_use();
+ Value* next = input_use_list();
+ while (next != NULL) {
+ Value* current = next;
+ next = current->next_use();
current->set_definition(other);
current->AddToInputUseList();
}
- while (env_use_list_ != NULL) {
- Value* current = env_use_list_;
- env_use_list_ = env_use_list_->next_use();
+
+ next = env_use_list();
+ while (next != NULL) {
+ Value* current = next;
+ next = current->next_use();
current->set_definition(other);
current->AddToEnvUseList();
}
+
+ set_input_use_list(NULL);
+ set_env_use_list(NULL);
}
@@ -1654,6 +1664,64 @@
}
+bool LoadFieldInstr::IsImmutableLengthLoad() const {
+ switch (recognized_kind()) {
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength:
+ case MethodRecognizer::kByteArrayBaseLength:
+ case MethodRecognizer::kStringBaseLength:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+MethodRecognizer::Kind LoadFieldInstr::RecognizedKindFromArrayCid(
+ intptr_t cid) {
+ switch (cid) {
+ case kArrayCid:
+ return MethodRecognizer::kObjectArrayLength;
+ case kImmutableArrayCid:
+ return MethodRecognizer::kImmutableArrayLength;
+ case kGrowableObjectArrayCid:
+ return MethodRecognizer::kGrowableArrayLength;
+ case kInt8ArrayCid:
+ case kUint8ArrayCid:
+ case kUint8ClampedArrayCid:
+ case kExternalUint8ArrayCid:
+ case kInt16ArrayCid:
+ case kUint16ArrayCid:
+ case kInt32ArrayCid:
+ case kUint32ArrayCid:
+ case kInt64ArrayCid:
+ case kUint64ArrayCid:
+ case kFloat32ArrayCid:
+ case kFloat64ArrayCid:
+ return MethodRecognizer::kByteArrayBaseLength;
+ default:
+ UNREACHABLE();
+ return MethodRecognizer::kUnknown;
+ }
+}
+
+
+Definition* LoadFieldInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
+ if (!IsImmutableLengthLoad()) return this;
+
+ // For fixed length arrays if the array is the result of a known constructor
+ // call we can replace the length load with the length argument passed to
+ // the constructor.
+ StaticCallInstr* call = value()->definition()->AsStaticCall();
+ if (call != NULL &&
+ call->is_known_constructor() &&
+ call->ResultCid() == kArrayCid) {
+ return call->ArgumentAt(1)->value()->definition();
+ }
+ return this;
+}
+
+
Definition* AssertBooleanInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
const intptr_t value_cid = value()->ResultCid();
return (value_cid == kBoolCid) ? value()->definition() : this;
@@ -2010,6 +2078,7 @@
void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
if (!is_eliminated()) {
compiler->GenerateAssertAssignable(token_pos(),
+ deopt_id(),
dst_type(),
dst_name(),
locs());
@@ -2123,7 +2192,10 @@
static bool AreEqualDefinitions(Definition* a, Definition* b) {
a = UnwrapConstraint(a);
b = UnwrapConstraint(b);
- return (a == b) || (!a->AffectedBySideEffect() && a->Equals(b));
+ return (a == b) ||
+ (!a->AffectedBySideEffect() &&
+ !b->AffectedBySideEffect() &&
+ a->Equals(b));
}
@@ -2497,9 +2569,7 @@
static bool IsArrayLength(Definition* defn) {
LoadFieldInstr* load = defn->AsLoadField();
- return (load != NULL) &&
- ((load->recognized_kind() == MethodRecognizer::kObjectArrayLength) ||
- (load->recognized_kind() == MethodRecognizer::kImmutableArrayLength));
+ return (load != NULL) && load->IsImmutableLengthLoad();
}
@@ -2718,8 +2788,8 @@
static_cast<BinaryMathCFunction>(&pow)), 0, true);
extern const RuntimeEntry kModRuntimeEntry(
- "libc_fmod", reinterpret_cast<RuntimeFunction>(
- static_cast<BinaryMathCFunction>(&fmod)), 0, true);
+ "DartModulo", reinterpret_cast<RuntimeFunction>(
+ static_cast<BinaryMathCFunction>(&DartModulo)), 0, true);
extern const RuntimeEntry kFloorRuntimeEntry(
"libc_floor", reinterpret_cast<RuntimeFunction>(
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index c00b43c..d2ae0d0 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -73,6 +73,7 @@
public:
explicit Value(Definition* definition)
: definition_(definition),
+ previous_use_(NULL),
next_use_(NULL),
instruction_(NULL),
use_index_(-1),
@@ -81,6 +82,9 @@
Definition* definition() const { return definition_; }
void set_definition(Definition* definition) { definition_ = definition; }
+ Value* previous_use() const { return previous_use_; }
+ void set_previous_use(Value* previous) { previous_use_ = previous; }
+
Value* next_use() const { return next_use_; }
void set_next_use(Value* next) { next_use_ = next; }
@@ -133,6 +137,7 @@
private:
Definition* definition_;
+ Value* previous_use_;
Value* next_use_;
Instruction* instruction_;
intptr_t use_index_;
@@ -519,6 +524,8 @@
friend class DoubleToSmiInstr;
friend class DoubleToDoubleInstr;
friend class InvokeMathCFunctionInstr;
+ friend class FlowGraphOptimizer;
+ friend class LoadIndexedInstr;
intptr_t deopt_id_;
intptr_t lifetime_position_; // Position used by register allocator.
@@ -1407,7 +1414,7 @@
intptr_t token_pos() const { return token_pos_; }
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return true; }
@@ -1428,7 +1435,7 @@
intptr_t token_pos() const { return token_pos_; }
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return true; }
@@ -1905,7 +1912,7 @@
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return false; }
@@ -1952,7 +1959,7 @@
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return false; }
@@ -1994,7 +2001,7 @@
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return true; }
@@ -2224,7 +2231,9 @@
inline bool BranchInstr::CanDeoptimize() const {
- return comparison()->CanDeoptimize();
+ // Branches need a deoptimization info in checked mode if they
+ // can throw a type check error.
+ return comparison()->CanDeoptimize() || is_checked();
}
@@ -2692,12 +2701,16 @@
class LoadIndexedInstr : public TemplateDefinition<2> {
public:
- LoadIndexedInstr(Value* array, Value* index, intptr_t class_id)
+ LoadIndexedInstr(Value* array,
+ Value* index,
+ intptr_t class_id,
+ intptr_t deopt_id)
: class_id_(class_id) {
ASSERT(array != NULL);
ASSERT(index != NULL);
inputs_[0] = array;
inputs_[1] = index;
+ deopt_id_ = deopt_id;
}
DECLARE_INSTRUCTION(LoadIndexed)
@@ -2707,7 +2720,9 @@
Value* index() const { return inputs_[1]; }
intptr_t class_id() const { return class_id_; }
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const {
+ return deopt_id_ != Isolate::kNoDeoptId;
+ }
virtual bool HasSideEffect() const { return false; }
@@ -2872,7 +2887,7 @@
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return true; }
@@ -2949,7 +2964,7 @@
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return true; }
@@ -3093,6 +3108,12 @@
return recognized_kind_;
}
+ bool IsImmutableLengthLoad() const;
+
+ virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
+
+ static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid);
+
private:
const intptr_t offset_in_bytes_;
const AbstractType& type_;
@@ -3166,7 +3187,7 @@
virtual void PrintOperandsTo(BufferFormatter* f) const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return true; }
@@ -3315,7 +3336,7 @@
DECLARE_INSTRUCTION(CloneContext)
virtual RawAbstractType* CompileType() const;
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return false; }
@@ -3915,7 +3936,7 @@
virtual intptr_t ArgumentCount() const { return 0; }
- virtual bool CanDeoptimize() const { return false; }
+ virtual bool CanDeoptimize() const { return true; }
virtual bool HasSideEffect() const { return false; }
@@ -4193,14 +4214,14 @@
class CheckArrayBoundInstr : public TemplateInstruction<2> {
public:
- CheckArrayBoundInstr(Value* array,
+ CheckArrayBoundInstr(Value* length,
Value* index,
intptr_t array_type,
InstanceCallInstr* instance_call)
: array_type_(array_type) {
- ASSERT(array != NULL);
+ ASSERT(length != NULL);
ASSERT(index != NULL);
- inputs_[0] = array;
+ inputs_[0] = length;
inputs_[1] = index;
deopt_id_ = instance_call->deopt_id();
}
@@ -4218,7 +4239,7 @@
virtual bool AffectedBySideEffect() const { return false; }
- Value* array() const { return inputs_[0]; }
+ Value* length() const { return inputs_[0]; }
Value* index() const { return inputs_[1]; }
intptr_t array_type() const { return array_type_; }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index ca21720..62d423d 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -185,6 +185,7 @@
static void EmitAssertBoolean(Register reg,
intptr_t token_pos,
+ intptr_t deopt_id,
LocationSummary* locs,
FlowGraphCompiler* compiler) {
// Check that the type of the value is allowed in conditional context.
@@ -198,6 +199,7 @@
__ pushl(reg); // Push the source object.
compiler->GenerateCallRuntime(token_pos,
+ deopt_id,
kConditionTypeErrorRuntimeEntry,
locs);
// We should never return here.
@@ -211,7 +213,7 @@
Register result = locs()->out().reg();
if (!is_eliminated()) {
- EmitAssertBoolean(obj, token_pos(), locs(), compiler);
+ EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
}
ASSERT(obj == result);
}
@@ -238,6 +240,7 @@
__ PushObject(formal_parameter_name());
__ pushl(saved_args_desc);
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kArgumentDefinitionTestRuntimeEntry,
locs());
__ Drop(3);
@@ -498,7 +501,7 @@
}
} else {
if (branch->is_checked()) {
- EmitAssertBoolean(EAX, token_pos, locs, compiler);
+ EmitAssertBoolean(EAX, token_pos, deopt_id, locs, compiler);
}
__ CompareObject(EAX, Bool::True());
branch->EmitBranchOnCondition(compiler, cond);
@@ -869,7 +872,7 @@
locs(),
*ic_data());
if (branch->is_checked()) {
- EmitAssertBoolean(EAX, token_pos(), locs(), compiler);
+ EmitAssertBoolean(EAX, token_pos(), deopt_id(), locs(), compiler);
}
Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
__ CompareObject(EAX, Bool::True());
@@ -1110,8 +1113,10 @@
return kSmiCid;
case kInt32ArrayCid:
case kUint32ArrayCid:
- // Result can be smi or mint when boxed.
- return kDynamicCid;
+ // Result can be Smi or Mint when boxed.
+ // Instruction can deoptimize if we optimistically assumed that the result
+ // fits into Smi.
+ return CanDeoptimize() ? kSmiCid : kDynamicCid;
default:
UNIMPLEMENTED();
return kDynamicCid;
@@ -1134,7 +1139,9 @@
return kTagged;
case kInt32ArrayCid:
case kUint32ArrayCid:
- return kUnboxedMint;
+ // Instruction can deoptimize if we optimistically assumed that the result
+ // fits into Smi.
+ return CanDeoptimize() ? kTagged : kUnboxedMint;
case kFloat32ArrayCid :
case kFloat64ArrayCid :
return kUnboxedDouble;
@@ -1181,9 +1188,7 @@
__ SmiUntag(index.reg());
}
__ movl(result,
- FieldAddress(array, ExternalUint8Array::external_data_offset()));
- __ movl(result,
- Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
+ FieldAddress(array, ExternalUint8Array::data_offset()));
__ movzxb(result, element_address);
__ SmiTag(result);
if (index.IsRegister()) {
@@ -1250,6 +1255,24 @@
__ movzxw(result, element_address);
__ SmiTag(result);
break;
+ case kInt32ArrayCid: {
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
+ __ movl(result, element_address);
+ // Verify that the signed value in 'result' can fit inside a Smi.
+ __ cmpl(result, Immediate(0xC0000000));
+ __ j(NEGATIVE, deopt);
+ __ SmiTag(result);
+ }
+ break;
+ case kUint32ArrayCid: {
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
+ __ movl(result, element_address);
+ // Verify that the unsigned value in 'result' can fit inside a Smi.
+ __ testl(result, Immediate(0xC0000000));
+ __ j(NOT_ZERO, deopt);
+ __ SmiTag(result);
+ }
+ break;
default:
ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
__ movl(result, element_address);
@@ -1523,6 +1546,7 @@
ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
compiler->GenerateInstanceOf(token_pos(),
+ deopt_id(),
type(),
negate_result(),
locs());
@@ -1585,6 +1609,7 @@
__ pushl(type_arguments);
__ pushl(instantiator_type_arguments);
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kAllocateObjectWithBoundsCheckRuntimeEntry,
locs());
// Pop instantiator type arguments, type arguments, and class.
@@ -1660,6 +1685,7 @@
__ PushObject(type_arguments());
__ pushl(instantiator_reg); // Push instantiator type arguments.
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kInstantiateTypeArgumentsRuntimeEntry,
locs());
__ Drop(2); // Drop instantiator and uninstantiated type arguments.
@@ -1838,6 +1864,7 @@
__ PushObject(Object::ZoneHandle()); // Make room for the result.
__ pushl(context_value);
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kCloneContextRuntimeEntry,
locs());
__ popl(result); // Remove argument.
@@ -1892,9 +1919,15 @@
__ Comment("CheckStackOverflowSlowPath");
__ Bind(entry_label());
compiler->SaveLiveRegisters(instruction_->locs());
+ // pending_deoptimization_env_ is needed to generate a runtime call that
+ // may throw an exception.
+ ASSERT(compiler->pending_deoptimization_env_ == NULL);
+ compiler->pending_deoptimization_env_ = instruction_->env();
compiler->GenerateCallRuntime(instruction_->token_pos(),
+ instruction_->deopt_id(),
kStackOverflowRuntimeEntry,
instruction_->locs());
+ compiler->pending_deoptimization_env_ = NULL;
compiler->RestoreLiveRegisters(instruction_->locs());
__ jmp(exit_label());
}
@@ -2679,7 +2712,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrSmiConstant(array()));
+ locs->set_in(0, Location::RegisterOrSmiConstant(length()));
locs->set_in(1, Location::RegisterOrSmiConstant(index()));
return locs;
}
@@ -2695,29 +2728,24 @@
return;
}
- intptr_t length_offset = LengthOffsetFor(array_type());
if (locs()->in(1).IsConstant()) {
- Register receiver = locs()->in(0).reg();
+ Register length = locs()->in(0).reg();
const Object& constant = locs()->in(1).constant();
ASSERT(constant.IsSmi());
const int32_t imm =
reinterpret_cast<int32_t>(constant.raw());
- __ cmpl(FieldAddress(receiver, length_offset), Immediate(imm));
+ __ cmpl(length, Immediate(imm));
__ j(BELOW_EQUAL, deopt);
} else if (locs()->in(0).IsConstant()) {
- ASSERT(locs()->in(0).constant().IsArray() ||
- locs()->in(0).constant().IsString());
- intptr_t length = locs()->in(0).constant().IsArray()
- ? Array::Cast(locs()->in(0).constant()).Length()
- : String::Cast(locs()->in(0).constant()).Length();
+ ASSERT(locs()->in(0).constant().IsSmi());
+ const Smi& smi_const = Smi::Cast(locs()->in(0).constant());
Register index = locs()->in(1).reg();
- __ cmpl(index,
- Immediate(reinterpret_cast<int32_t>(Smi::New(length))));
+ __ cmpl(index, Immediate(reinterpret_cast<int32_t>(smi_const.raw())));
__ j(ABOVE_EQUAL, deopt);
} else {
- Register receiver = locs()->in(0).reg();
+ Register length = locs()->in(0).reg();
Register index = locs()->in(1).reg();
- __ cmpl(index, FieldAddress(receiver, length_offset));
+ __ cmpl(index, length);
__ j(ABOVE_EQUAL, deopt);
}
}
@@ -3030,6 +3058,7 @@
void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kThrowRuntimeEntry,
locs());
__ int3();
@@ -3043,6 +3072,7 @@
void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kReThrowRuntimeEntry,
locs());
__ int3();
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 14fbd2a..59b9855 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -192,6 +192,7 @@
static void EmitAssertBoolean(Register reg,
intptr_t token_pos,
+ intptr_t deopt_id,
LocationSummary* locs,
FlowGraphCompiler* compiler) {
// Check that the type of the value is allowed in conditional context.
@@ -205,6 +206,7 @@
__ pushq(reg); // Push the source object.
compiler->GenerateCallRuntime(token_pos,
+ deopt_id,
kConditionTypeErrorRuntimeEntry,
locs);
// We should never return here.
@@ -218,7 +220,7 @@
Register result = locs()->out().reg();
if (!is_eliminated()) {
- EmitAssertBoolean(obj, token_pos(), locs(), compiler);
+ EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
}
ASSERT(obj == result);
}
@@ -245,6 +247,7 @@
__ PushObject(formal_parameter_name());
__ pushq(saved_args_desc);
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kArgumentDefinitionTestRuntimeEntry,
locs());
__ Drop(3);
@@ -496,7 +499,7 @@
}
} else {
if (branch->is_checked()) {
- EmitAssertBoolean(RAX, token_pos, locs, compiler);
+ EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler);
}
__ CompareObject(RAX, Bool::True());
branch->EmitBranchOnCondition(compiler, cond);
@@ -751,7 +754,7 @@
locs(),
*ic_data());
if (branch->is_checked()) {
- EmitAssertBoolean(RAX, token_pos(), locs(), compiler);
+ EmitAssertBoolean(RAX, token_pos(), deopt_id(), locs(), compiler);
}
Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
__ CompareObject(RAX, Bool::True());
@@ -1042,9 +1045,7 @@
__ SmiUntag(index.reg());
}
__ movq(result,
- FieldAddress(array, ExternalUint8Array::external_data_offset()));
- __ movq(result,
- Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
+ FieldAddress(array, ExternalUint8Array::data_offset()));
__ movzxb(result, element_address);
__ SmiTag(result);
if (index.IsRegister()) {
@@ -1382,6 +1383,7 @@
ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
compiler->GenerateInstanceOf(token_pos(),
+ deopt_id(),
type(),
negate_result(),
locs());
@@ -1444,6 +1446,7 @@
__ pushq(type_arguments);
__ pushq(instantiator_type_arguments);
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kAllocateObjectWithBoundsCheckRuntimeEntry,
locs());
// Pop instantiator type arguments, type arguments, and class.
@@ -1516,6 +1519,7 @@
__ PushObject(type_arguments());
__ pushq(instantiator_reg); // Push instantiator type arguments.
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kInstantiateTypeArgumentsRuntimeEntry,
locs());
__ Drop(2); // Drop instantiator and uninstantiated type arguments.
@@ -1690,6 +1694,7 @@
__ PushObject(Object::ZoneHandle()); // Make room for the result.
__ pushq(context_value);
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kCloneContextRuntimeEntry,
locs());
__ popq(result); // Remove argument.
@@ -1745,9 +1750,15 @@
__ Comment("CheckStackOverflowSlowPath");
__ Bind(entry_label());
compiler->SaveLiveRegisters(instruction_->locs());
+ // pending_deoptimization_env_ is needed to generate a runtime call that
+ // may throw an exception.
+ ASSERT(compiler->pending_deoptimization_env_ == NULL);
+ compiler->pending_deoptimization_env_ = instruction_->env();
compiler->GenerateCallRuntime(instruction_->token_pos(),
+ instruction_->deopt_id(),
kStackOverflowRuntimeEntry,
instruction_->locs());
+ compiler->pending_deoptimization_env_ = NULL;
compiler->RestoreLiveRegisters(instruction_->locs());
__ jmp(exit_label());
}
@@ -2571,7 +2582,7 @@
const intptr_t kNumTemps = 0;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrSmiConstant(array()));
+ locs->set_in(0, Location::RegisterOrSmiConstant(length()));
locs->set_in(1, Location::RegisterOrSmiConstant(index()));
return locs;
}
@@ -2587,30 +2598,24 @@
return;
}
-
- intptr_t length_offset = LengthOffsetFor(array_type());
if (locs()->in(1).IsConstant()) {
- Register receiver = locs()->in(0).reg();
+ Register length = locs()->in(0).reg();
const Object& constant = locs()->in(1).constant();
ASSERT(constant.IsSmi());
const int64_t imm =
reinterpret_cast<int64_t>(constant.raw());
- __ cmpq(FieldAddress(receiver, length_offset), Immediate(imm));
+ __ cmpq(length, Immediate(imm));
__ j(BELOW_EQUAL, deopt);
} else if (locs()->in(0).IsConstant()) {
- ASSERT(locs()->in(0).constant().IsArray() ||
- locs()->in(0).constant().IsString());
- intptr_t length = locs()->in(0).constant().IsArray()
- ? Array::Cast(locs()->in(0).constant()).Length()
- : String::Cast(locs()->in(0).constant()).Length();
+ ASSERT(locs()->in(0).constant().IsSmi());
+ const Smi& smi_const = Smi::Cast(locs()->in(0).constant());
Register index = locs()->in(1).reg();
- __ cmpq(index,
- Immediate(reinterpret_cast<int64_t>(Smi::New(length))));
+ __ cmpq(index, Immediate(reinterpret_cast<int64_t>(smi_const.raw())));
__ j(ABOVE_EQUAL, deopt);
} else {
- Register receiver = locs()->in(0).reg();
+ Register length = locs()->in(0).reg();
Register index = locs()->in(1).reg();
- __ cmpq(index, FieldAddress(receiver, length_offset));
+ __ cmpq(index, length);
__ j(ABOVE_EQUAL, deopt);
}
}
@@ -2678,6 +2683,7 @@
void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kThrowRuntimeEntry,
locs());
__ int3();
@@ -2691,6 +2697,7 @@
void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
compiler->GenerateCallRuntime(token_pos(),
+ deopt_id(),
kReThrowRuntimeEntry,
locs());
__ int3();
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 9231d26..a82f317 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -95,6 +95,7 @@
V(_Int16Array, [], Int16Array_getIndexed, 870098766) \
V(_Int16Array, _new, Int16Array_new, 903723993) \
V(_Uint16Array, [], Uint16Array_getIndexed, 1019828411) \
+ V(_Uint16Array, []=, Uint16Array_setIndexed, 1457955615) \
V(_Uint16Array, _new, Uint16Array_new, 133542762) \
V(_Int32Array, [], Int32Array_getIndexed, 1999321436) \
V(_Int32Array, _new, Int32Array_new, 8218286) \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index de3defe..5de8051 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -94,6 +94,11 @@
}
+bool Intrinsifier::Int8Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -104,6 +109,11 @@
}
+bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -114,36 +124,76 @@
}
+bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Int16Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+ return false;
+}
+
+
+bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Int32Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Int64Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -154,6 +204,11 @@
}
+bool Intrinsifier::Float32Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -164,6 +219,11 @@
}
+bool Intrinsifier::Float64Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
return false;
}
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index fe89c8c..114a1b2 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -468,13 +468,11 @@
}
-// Places the address of the ByteArray in EAX.
-// Places the Smi index in EBX.
-// Tests if EBX contains an Smi, jumps to label fall_through if false.
-// Tests if index in EBX is within bounds, jumps to label fall_through if not.
-// Leaves the index as an Smi in EBX.
-// Leaves the ByteArray address in EAX.
-static void TestByteArrayIndex(Assembler* assembler, Label* fall_through) {
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in EBX, array in EAX.
+// This should be used only on getIndexed intrinsics.
+static void TestByteArrayGetIndex(Assembler* assembler, Label* fall_through) {
__ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array.
__ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
__ testl(EBX, Immediate(kSmiTagMask));
@@ -486,7 +484,9 @@
}
-// Operates in the same manner as TestByteArrayIndex.
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in EBX, array in EAX.
// This should be used only for setIndexed intrinsics.
static void TestByteArraySetIndex(Assembler* assembler, Label* fall_through) {
__ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array.
@@ -502,7 +502,9 @@
bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
__ movsxb(EAX, FieldAddress(EAX,
EBX,
@@ -517,12 +519,9 @@
bool Intrinsifier::Int8Array_setIndexed(Assembler* assembler) {
Label fall_through;
- // Verify that the array index is valid.
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted by 1.
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
// Free EBX for the value since we want a byte register.
__ movl(EDI, EBX);
@@ -638,7 +637,9 @@
bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
__ movzxb(EAX, FieldAddress(EAX,
EBX,
@@ -653,12 +654,9 @@
bool Intrinsifier::Uint8Array_setIndexed(Assembler* assembler) {
Label fall_through;
- // Verify that the array index is valid.
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted by 1.
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
// Free EBX for the value since we want a byte register.
__ movl(EDI, EBX);
@@ -684,7 +682,9 @@
bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
__ movzxb(EAX, FieldAddress(EAX,
EBX,
@@ -699,12 +699,9 @@
bool Intrinsifier::Uint8ClampedArray_setIndexed(Assembler* assembler) {
Label fall_through, store_value, load_0xff;
- // Verify that the array index is valid.
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted by 1.
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
// Free EBX for the value since we need a byte register.
__ leal(EAX, FieldAddress(EAX, EBX, TIMES_1,
@@ -739,7 +736,9 @@
bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ movsxw(EAX, FieldAddress(EAX,
EBX,
TIMES_1,
@@ -759,7 +758,9 @@
bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ movzxw(EAX, FieldAddress(EAX,
EBX,
TIMES_1,
@@ -771,6 +772,23 @@
}
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+ Label fall_through;
+ TestByteArraySetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
+ __ movl(EDI, Address(ESP, + 1 * kWordSize));
+ __ SmiUntag(EDI);
+ // EDI: undtagged value.
+ __ testl(EDI, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+ __ movw(FieldAddress(EAX, EBX, TIMES_1, Uint16Array::data_offset()), EDI);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
+
bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
return false;
@@ -779,12 +797,9 @@
bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
- // After TestByteArrayIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted left by 1.
- // This shift means we only multiply the index by 2 not 4 (sizeof Int32).
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ movl(EAX, FieldAddress(EAX,
EBX,
TIMES_2,
@@ -807,17 +822,14 @@
bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
- // After TestByteArrayIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted left by 1.
- // This shift means we only multiply the index by 2 not 4 (sizeof Uint32).
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ movl(EAX, FieldAddress(EAX,
EBX,
TIMES_2,
Uint32Array::data_offset()));
- // Verify that the unsigned value in EAX can be stored in a Smi.
+ // Verify that the unsigned value in EAX can be stored in a Smi.
__ testl(EAX, Immediate(0xC0000000));
__ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Won't fit Smi.
__ SmiTag(EAX);
@@ -857,12 +869,9 @@
bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
- // After TestByteArrayIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted left by 1.
- // This shift means we only multiply the index by 2 not 4 (sizeof float).
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
// Load single precision float into XMM7.
__ movss(XMM7, FieldAddress(EAX, EBX, TIMES_2,
Float32Array::data_offset()));
@@ -895,11 +904,8 @@
// Load double value into XMM7.
__ movsd(XMM7, FieldAddress(EAX, Double::value_offset()));
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted by 1.
- // This shift means we only multiply the index by 2 not 4 (sizeof float).
+ // EBX: index as Smi.
+ // EAX: array.
// Convert from double precision float to single precision float.
__ cvtsd2ss(XMM7, XMM7);
// Store into array.
@@ -919,12 +925,9 @@
bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
- // After TestByteArrayIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted left by 1.
- // This shift means we only multiply the index by 4 not 8 (sizeof double).
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
// Load double precision float into XMM7.
__ movsd(XMM7, FieldAddress(EAX, EBX, TIMES_4,
Float64Array::data_offset()));
@@ -954,12 +957,8 @@
// Load double value into XMM7.
__ movsd(XMM7, FieldAddress(EAX, Double::value_offset()));
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * EAX has the base address of the byte array.
- // * EBX has the index into the array.
- // EBX contains the SMI index which is shifted by 1.
- // This shift means we only multiply the index by 4 not 8 (sizeof float).
- // Store into array.
+ // EBX: index as Smi.
+ // EAX: array.
__ movsd(FieldAddress(EAX, EBX, TIMES_4, Float64Array::data_offset()), XMM7);
__ ret();
__ Bind(&fall_through);
@@ -975,10 +974,11 @@
bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // EBX: index as Smi.
+ // EAX: array.
__ SmiUntag(EBX);
- __ movl(EAX, FieldAddress(EAX, ExternalUint8Array::external_data_offset()));
- __ movl(EAX, Address(EAX, ExternalByteArrayData<uint8_t>::data_offset()));
+ __ movl(EAX, FieldAddress(EAX, ExternalUint8Array::data_offset()));
__ movzxb(EAX, Address(EAX, EBX, TIMES_1, 0));
__ SmiTag(EAX);
__ ret();
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index bd4d751..e71febb 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -94,6 +94,11 @@
}
+bool Intrinsifier::Int8Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -104,6 +109,11 @@
}
+bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -114,36 +124,76 @@
}
+bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Int16Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+ return false;
+}
+
+
+bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Int32Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Int64Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
return false;
}
+bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -154,6 +204,11 @@
}
+bool Intrinsifier::Float32Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
return false;
}
@@ -164,6 +219,11 @@
}
+bool Intrinsifier::Float64Array_new(Assembler* assembler) {
+ return false;
+}
+
+
bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
return false;
}
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index df97b4e..cd1d7d2 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -423,13 +423,12 @@
}
-// Places the address of the ByteArray in RAX.
-// Places the Smi index in R12.
-// Tests if R12 contains an Smi, jumps to label fall_through if false.
-// Tests if index in R12 is within bounds, jumps to label fall_through if not.
-// Leaves the index as an Smi in R12.
-// Leaves the ByteArray address in RAX.
-void TestByteArrayIndex(Assembler* assembler, Label* fall_through) {
+
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in R12, array in RAX.
+// This should be used only on getIndexed intrinsics.
+void TestByteArrayGetIndex(Assembler* assembler, Label* fall_through) {
__ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array.
__ movq(R12, Address(RSP, + 1 * kWordSize)); // Index.
__ testq(R12, Immediate(kSmiTagMask));
@@ -441,7 +440,9 @@
}
-// Operates in the same manner as TestByteArrayIndex.
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in R12, array in RAX.
// This should be used only for setIndexed intrinsics.
static void TestByteArraySetIndex(Assembler* assembler, Label* fall_through) {
__ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array.
@@ -457,7 +458,9 @@
bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
__ movsxb(RAX, FieldAddress(RAX,
R12,
@@ -472,12 +475,9 @@
bool Intrinsifier::Int8Array_setIndexed(Assembler* assembler) {
Label fall_through;
- // Verify that the array index is valid.
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted by 1.
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
__ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
__ testq(RDI, Immediate(kSmiTagMask));
@@ -596,7 +596,9 @@
bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
__ movzxb(RAX, FieldAddress(RAX,
R12,
@@ -611,12 +613,9 @@
bool Intrinsifier::Uint8Array_setIndexed(Assembler* assembler) {
Label fall_through;
- // Verify that the array index is valid.
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted by 1.
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
__ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
__ testq(RDI, Immediate(kSmiTagMask));
@@ -640,7 +639,9 @@
bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
__ movzxb(RAX, FieldAddress(RAX,
R12,
@@ -655,12 +656,9 @@
bool Intrinsifier::Uint8ClampedArray_setIndexed(Assembler* assembler) {
Label fall_through, store_value, load_0xff;
- // Verify that the array index is valid.
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted by 1.
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
__ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
__ testq(RDI, Immediate(kSmiTagMask));
@@ -692,7 +690,9 @@
bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ movsxw(RAX, FieldAddress(RAX,
R12,
TIMES_1,
@@ -712,7 +712,9 @@
bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ movzxw(RAX, FieldAddress(RAX,
R12,
TIMES_1,
@@ -724,6 +726,23 @@
}
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+ Label fall_through;
+ TestByteArraySetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
+ __ movq(RDI, Address(RSP, + 1 * kWordSize));
+ __ SmiUntag(RDI);
+ // RDI: untagged value.
+ __ testl(RDI, Immediate(kSmiTagMask));
+ __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+ __ movw(FieldAddress(RAX, R12, TIMES_1, Uint16Array::data_offset()), RDI);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
+
bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
return false;
@@ -732,7 +751,9 @@
bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ movsxl(RAX, FieldAddress(RAX,
R12,
TIMES_2,
@@ -752,7 +773,9 @@
bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ movl(RAX, FieldAddress(RAX,
R12,
TIMES_2,
@@ -772,7 +795,9 @@
bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ movq(RAX, FieldAddress(RAX,
R12,
TIMES_4,
@@ -799,7 +824,9 @@
bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ movq(RAX, FieldAddress(RAX,
R12,
TIMES_4,
@@ -825,12 +852,9 @@
bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
- // After TestByteArrayIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted left by 1.
- // This shift means we only multiply the index by 2 not 4 (sizeof float).
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
// Load single precision float into XMM7.
__ movss(XMM7, FieldAddress(RAX, R12, TIMES_2,
Float32Array::data_offset()));
@@ -854,11 +878,8 @@
bool Intrinsifier::Float32Array_setIndexed(Assembler* assembler) {
Label fall_through;
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted by 1.
- // This shift means we only multiply the index by 2 not 4 (sizeof float).
+ // R12: index as Smi.
+ // RAX: array.
__ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
// If RDX is not an instance of double, jump to fall through.
__ testq(RDX, Immediate(kSmiTagMask));
@@ -886,12 +907,9 @@
bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
- // After TestByteArrayIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted left by 1.
- // This shift means we only multiply the index by 4 not 8 (sizeof double).
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
// Load double precision float into XMM7.
__ movsd(XMM7, FieldAddress(RAX, R12, TIMES_4,
Float64Array::data_offset()));
@@ -913,11 +931,8 @@
bool Intrinsifier::Float64Array_setIndexed(Assembler* assembler) {
Label fall_through;
TestByteArraySetIndex(assembler, &fall_through);
- // After TestByteArraySetIndex:
- // * RAX has the base address of the byte array.
- // * R12 has the index into the array.
- // R12 contains the SMI index which is shifted by 1.
- // This shift means we only multiply the index by 4 not 8 (sizeof double).
+ // R12: index as Smi.
+ // RAX: array.
__ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
// If RDX is not an instance of double, jump to fall through.
__ testq(RDX, Immediate(kSmiTagMask));
@@ -942,10 +957,11 @@
bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
Label fall_through;
- TestByteArrayIndex(assembler, &fall_through);
+ TestByteArrayGetIndex(assembler, &fall_through);
+ // R12: index as Smi.
+ // RAX: array.
__ SmiUntag(R12);
- __ movq(RAX, FieldAddress(RAX, ExternalUint8Array::external_data_offset()));
- __ movq(RAX, Address(RAX, ExternalByteArrayData<uint8_t>::data_offset()));
+ __ movq(RAX, FieldAddress(RAX, ExternalUint8Array::data_offset()));
__ movzxb(RAX, Address(RAX, R12, TIMES_1, 0));
__ SmiTag(RAX);
__ ret();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 93d2cfe..ec3cb20 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -273,6 +273,16 @@
}
+static void DeleteWeakPersistentHandle(Dart_Handle handle) {
+ ApiState* state = Isolate::Current()->api_state();
+ ASSERT(state != NULL);
+ FinalizablePersistentHandle* weak_ref =
+ reinterpret_cast<FinalizablePersistentHandle*>(handle);
+ ASSERT(state->IsValidWeakPersistentHandle(handle));
+ state->weak_persistent_handles().FreeHandle(weak_ref);
+}
+
+
void Object::InitOnce() {
// TODO(iposva): NoGCScope needs to be added here.
ASSERT(class_class() == null_);
@@ -1281,6 +1291,7 @@
Heap::Space space) {
ASSERT(Utils::IsAligned(size, kObjectAlignment));
Isolate* isolate = Isolate::Current();
+ ASSERT(isolate->no_callback_scope_depth() == 0);
Heap* heap = isolate->heap();
uword address = heap->Allocate(size, space);
@@ -1300,14 +1311,15 @@
}
-class StoreBufferObjectPointerVisitor : public ObjectPointerVisitor {
+class StoreBufferUpdateVisitor : public ObjectPointerVisitor {
public:
- explicit StoreBufferObjectPointerVisitor(Isolate* isolate) :
- ObjectPointerVisitor(isolate) {
- }
+ explicit StoreBufferUpdateVisitor(Isolate* isolate) :
+ ObjectPointerVisitor(isolate) { }
+
void VisitPointers(RawObject** first, RawObject** last) {
for (RawObject** curr = first; curr <= last; ++curr) {
- if ((*curr)->IsNewObject()) {
+ RawObject* raw_obj = *curr;
+ if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
uword ptr = reinterpret_cast<uword>(curr);
isolate()->store_buffer()->AddPointer(ptr);
}
@@ -1315,7 +1327,7 @@
}
private:
- DISALLOW_COPY_AND_ASSIGN(StoreBufferObjectPointerVisitor);
+ DISALLOW_COPY_AND_ASSIGN(StoreBufferUpdateVisitor);
};
@@ -1337,7 +1349,7 @@
NoGCScope no_gc;
memmove(raw_obj->ptr(), src.raw()->ptr(), size);
if (space == Heap::kOld) {
- StoreBufferObjectPointerVisitor visitor(Isolate::Current());
+ StoreBufferUpdateVisitor visitor(Isolate::Current());
raw_obj->VisitPointers(&visitor);
}
return raw_obj;
@@ -4748,9 +4760,10 @@
}
-void TokenStream::DataFinalizer(void *peer) {
+void TokenStream::DataFinalizer(Dart_Handle handle, void *peer) {
ASSERT(peer != NULL);
::free(peer);
+ DeleteWeakPersistentHandle(handle);
}
@@ -4966,7 +4979,8 @@
uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len));
ASSERT(data != NULL);
const ExternalUint8Array& stream = ExternalUint8Array::Handle(
- ExternalUint8Array::New(data, len, data, DataFinalizer, Heap::kOld));
+ ExternalUint8Array::New(data, len, Heap::kOld));
+ stream.AddFinalizer(data, DataFinalizer);
const TokenStream& result = TokenStream::Handle(TokenStream::New());
result.SetStream(stream);
return result.raw();
@@ -5139,11 +5153,8 @@
// Create and setup the token stream object.
const ExternalUint8Array& stream = ExternalUint8Array::Handle(
- ExternalUint8Array::New(data.GetStream(),
- data.Length(),
- data.GetStream(),
- DataFinalizer,
- Heap::kOld));
+ ExternalUint8Array::New(data.GetStream(), data.Length(), Heap::kOld));
+ stream.AddFinalizer(data.GetStream(), DataFinalizer);
const TokenStream& result = TokenStream::Handle(New());
result.SetPrivateKey(private_key);
{
@@ -9316,14 +9327,28 @@
RawClass* Type::type_class() const {
ASSERT(HasResolvedTypeClass());
+#ifdef DEBUG
+ Class& type_class = Class::Handle();
+ type_class ^= raw_ptr()->type_class_;
+ return type_class.raw();
+#else
return reinterpret_cast<RawClass*>(raw_ptr()->type_class_);
+#endif
}
RawUnresolvedClass* Type::unresolved_class() const {
+ ASSERT(!HasResolvedTypeClass());
+#ifdef DEBUG
+ UnresolvedClass& unresolved_class = UnresolvedClass::Handle();
+ unresolved_class ^= raw_ptr()->type_class_;
+ ASSERT(!unresolved_class.IsNull());
+ return unresolved_class.raw();
+#else
ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull());
ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass());
return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_);
+#endif
}
@@ -10987,10 +11012,12 @@
}
-static void AddFinalizer(const Object& referent,
- void* peer,
- Dart_WeakPersistentHandleFinalizer callback) {
- ASSERT(callback != NULL);
+static FinalizablePersistentHandle* AddFinalizer(
+ const Object& referent,
+ void* peer,
+ Dart_WeakPersistentHandleFinalizer callback) {
+ ASSERT((callback != NULL && peer != NULL) ||
+ (callback == NULL && peer == NULL));
ApiState* state = Isolate::Current()->api_state();
ASSERT(state != NULL);
FinalizablePersistentHandle* weak_ref =
@@ -10998,6 +11025,7 @@
weak_ref->set_raw(referent);
weak_ref->set_peer(peer);
weak_ref->set_callback(callback);
+ return weak_ref;
}
@@ -11601,16 +11629,6 @@
}
-static void DeleteWeakPersistentHandle(Dart_Handle handle) {
- ApiState* state = Isolate::Current()->api_state();
- ASSERT(state != NULL);
- FinalizablePersistentHandle* weak_ref =
- reinterpret_cast<FinalizablePersistentHandle*>(handle);
- ASSERT(state->IsValidWeakPersistentHandle(handle));
- state->weak_persistent_handles().FreeHandle(weak_ref);
-}
-
-
void ExternalOneByteString::Finalize(Dart_Handle handle, void* peer) {
delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer);
DeleteWeakPersistentHandle(handle);
@@ -11966,19 +11984,10 @@
}
-template<typename T>
-static void ExternalByteArrayFinalize(Dart_Handle handle, void* peer) {
- delete reinterpret_cast<ExternalByteArrayData<T>*>(peer);
- DeleteWeakPersistentHandle(handle);
-}
-
-
template<typename HandleT, typename RawT, typename ElementT>
RawT* ByteArray::NewExternalImpl(intptr_t class_id,
ElementT* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
if (len < 0 || len > HandleT::kMaxElements) {
// This should be caught before we reach here.
@@ -11986,16 +11995,13 @@
len);
}
HandleT& result = HandleT::Handle();
- ExternalByteArrayData<ElementT>* external_data =
- new ExternalByteArrayData<ElementT>(data, peer, callback);
{
RawObject* raw = Object::Allocate(class_id, HandleT::InstanceSize(), space);
NoGCScope no_gc;
result ^= raw;
result.SetLength(len);
- result.SetExternalData(external_data);
+ result.SetData(data);
}
- AddFinalizer(result, external_data, ExternalByteArrayFinalize<ElementT>);
return result.raw();
}
@@ -12007,6 +12013,14 @@
}
+FinalizablePersistentHandle* ByteArray::AddFinalizer(
+ void* peer,
+ Dart_WeakPersistentHandleFinalizer callback) const {
+ SetPeer(peer);
+ return dart::AddFinalizer(*this, peer, callback);
+}
+
+
uint8_t* ByteArray::ByteAddr(intptr_t byte_offset) const {
// ByteArray is an abstract class.
UNREACHABLE();
@@ -12302,13 +12316,11 @@
RawExternalInt8Array* ExternalInt8Array::New(int8_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_int8_array_class() !=
Class::null());
- return NewExternalImpl<ExternalInt8Array, RawExternalInt8Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalInt8Array,
+ RawExternalInt8Array>(kClassId, data, len, space);
}
@@ -12319,13 +12331,11 @@
RawExternalUint8Array* ExternalUint8Array::New(uint8_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_uint8_array_class() !=
Class::null());
- return NewExternalImpl<ExternalUint8Array, RawExternalUint8Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalUint8Array,
+ RawExternalUint8Array>(kClassId, data, len, space);
}
@@ -12337,14 +12347,13 @@
RawExternalUint8ClampedArray* ExternalUint8ClampedArray::New(
uint8_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->
- object_store()->external_uint8_clamped_array_class() !=
+ object_store()->external_uint8_clamped_array_class() !=
Class::null());
return NewExternalImpl<ExternalUint8ClampedArray,
- RawExternalUint8ClampedArray>(kClassId, data, len, peer, callback, space);
+ RawExternalUint8ClampedArray>(kClassId, data,
+ len, space);
}
@@ -12355,13 +12364,11 @@
RawExternalInt16Array* ExternalInt16Array::New(int16_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_int16_array_class() !=
Class::null());
- return NewExternalImpl<ExternalInt16Array, RawExternalInt16Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalInt16Array,
+ RawExternalInt16Array>(kClassId, data, len, space);
}
@@ -12372,13 +12379,11 @@
RawExternalUint16Array* ExternalUint16Array::New(uint16_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_uint16_array_class() !=
Class::null());
- return NewExternalImpl<ExternalUint16Array, RawExternalUint16Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalUint16Array,
+ RawExternalUint16Array>(kClassId, data, len, space);
}
@@ -12389,13 +12394,11 @@
RawExternalInt32Array* ExternalInt32Array::New(int32_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_int32_array_class() !=
Class::null());
- return NewExternalImpl<ExternalInt32Array, RawExternalInt32Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalInt32Array,
+ RawExternalInt32Array>(kClassId, data, len, space);
}
@@ -12406,13 +12409,11 @@
RawExternalUint32Array* ExternalUint32Array::New(uint32_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_uint32_array_class() !=
Class::null());
- return NewExternalImpl<ExternalUint32Array, RawExternalUint32Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalUint32Array,
+ RawExternalUint32Array>(kClassId, data, len, space);
}
@@ -12423,13 +12424,11 @@
RawExternalInt64Array* ExternalInt64Array::New(int64_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_int64_array_class() !=
Class::null());
- return NewExternalImpl<ExternalInt64Array, RawExternalInt64Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalInt64Array,
+ RawExternalInt64Array>(kClassId, data, len, space);
}
@@ -12440,13 +12439,11 @@
RawExternalUint64Array* ExternalUint64Array::New(uint64_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_uint64_array_class() !=
Class::null());
- return NewExternalImpl<ExternalUint64Array, RawExternalUint64Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalUint64Array,
+ RawExternalUint64Array>(kClassId, data, len, space);
}
@@ -12457,13 +12454,11 @@
RawExternalFloat32Array* ExternalFloat32Array::New(float* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_float32_array_class() !=
Class::null());
- return NewExternalImpl<ExternalFloat32Array, RawExternalFloat32Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalFloat32Array,
+ RawExternalFloat32Array>(kClassId, data, len, space);
}
@@ -12474,13 +12469,11 @@
RawExternalFloat64Array* ExternalFloat64Array::New(double* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space) {
ASSERT(Isolate::Current()->object_store()->external_float64_array_class() !=
Class::null());
- return NewExternalImpl<ExternalFloat64Array, RawExternalFloat64Array>(
- kClassId, data, len, peer, callback, space);
+ return NewExternalImpl<ExternalFloat64Array,
+ RawExternalFloat64Array>(kClassId, data, len, space);
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 548a0c4..81a4f97 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -30,6 +30,7 @@
class Closure;
class Code;
class DeoptInstr;
+class FinalizablePersistentHandle;
class LocalScope;
class Symbols;
@@ -1076,7 +1077,7 @@
RawAbstractType** TypeAddr(intptr_t index) const;
void SetLength(intptr_t value) const;
- HEAP_OBJECT_IMPLEMENTATION(TypeArguments, AbstractTypeArguments);
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, AbstractTypeArguments);
friend class Class;
};
@@ -1131,7 +1132,8 @@
const AbstractTypeArguments& value) const;
static RawInstantiatedTypeArguments* New();
- HEAP_OBJECT_IMPLEMENTATION(InstantiatedTypeArguments, AbstractTypeArguments);
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(InstantiatedTypeArguments,
+ AbstractTypeArguments);
friend class Class;
};
@@ -1894,7 +1896,7 @@
void SetPrivateKey(const String& value) const;
static RawTokenStream* New();
- static void DataFinalizer(void *peer);
+ static void DataFinalizer(Dart_Handle handle, void *peer);
FINAL_HEAP_OBJECT_IMPLEMENTATION(TokenStream, Object);
friend class Class;
@@ -3558,7 +3560,7 @@
static RawType* New(Heap::Space space = Heap::kOld);
- HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
friend class Class;
};
@@ -3618,7 +3620,7 @@
void set_type_state(int8_t state) const;
static RawTypeParameter* New();
- HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
friend class Class;
};
@@ -4749,6 +4751,11 @@
virtual intptr_t ByteLength() const;
+ virtual void* GetPeer() const { return NULL; }
+
+ FinalizablePersistentHandle* AddFinalizer(
+ void* peer, Dart_WeakPersistentHandleFinalizer callback) const;
+
static void Copy(void* dst,
const ByteArray& src,
intptr_t src_offset,
@@ -4767,6 +4774,7 @@
protected:
virtual uint8_t* ByteAddr(intptr_t byte_offset) const;
+ virtual void SetPeer(void* peer) const { }
template<typename HandleT, typename RawT>
static RawT* NewImpl(intptr_t class_id,
@@ -4783,8 +4791,6 @@
static RawT* NewExternalImpl(intptr_t class_id,
ElementT* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space);
template<typename HandleT, typename RawT, typename ElementT>
@@ -5384,20 +5390,20 @@
int8_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int8_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ int8_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 1;
@@ -5410,22 +5416,27 @@
return RoundedAllocationSize(sizeof(RawExternalInt8Array));
}
+ static intptr_t data_offset() {
+ return OFFSET_OF(RawExternalInt8Array, data_);
+ }
+
static RawExternalInt8Array* New(int8_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<int8_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(int8_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt8Array, ByteArray);
@@ -5442,20 +5453,20 @@
uint8_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, uint8_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ uint8_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 1;
@@ -5468,26 +5479,28 @@
return RoundedAllocationSize(sizeof(RawExternalUint8Array));
}
- static intptr_t external_data_offset() {
- return OFFSET_OF(RawExternalUint8Array, external_data_);
+ static intptr_t data_offset() {
+ return OFFSET_OF(RawExternalUint8Array, data_);
}
static RawExternalUint8Array* New(uint8_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<uint8_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(uint8_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
HEAP_OBJECT_IMPLEMENTATION(ExternalUint8Array, ByteArray);
@@ -5501,8 +5514,6 @@
public:
static RawExternalUint8ClampedArray* New(uint8_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
@@ -5520,20 +5531,20 @@
int16_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int16_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ int16_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 2;
@@ -5548,20 +5559,21 @@
static RawExternalInt16Array* New(int16_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<int16_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(int16_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt16Array, ByteArray);
@@ -5578,20 +5590,20 @@
int16_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int16_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ uint16_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 2;
@@ -5606,20 +5618,21 @@
static RawExternalUint16Array* New(uint16_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<uint16_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(uint16_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalUint16Array, ByteArray);
@@ -5636,20 +5649,20 @@
int32_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int32_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ int32_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 4;
@@ -5664,20 +5677,21 @@
static RawExternalInt32Array* New(int32_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<int32_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(int32_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt32Array, ByteArray);
@@ -5694,20 +5708,20 @@
int32_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int32_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ uint32_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 4;
@@ -5722,20 +5736,21 @@
static RawExternalUint32Array* New(uint32_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<uint32_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(uint32_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalUint32Array, ByteArray);
@@ -5752,20 +5767,20 @@
int64_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int64_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ int64_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 8;
@@ -5780,20 +5795,21 @@
static RawExternalInt64Array* New(int64_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<int64_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(int64_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt64Array, ByteArray);
@@ -5810,20 +5826,20 @@
int64_t At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, int64_t value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ uint64_t* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 8;
@@ -5838,20 +5854,21 @@
static RawExternalUint64Array* New(uint64_t* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<uint64_t>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(uint64_t* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalUint64Array, ByteArray);
@@ -5868,20 +5885,20 @@
float At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, float value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ float* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 4;
@@ -5896,20 +5913,21 @@
static RawExternalFloat32Array* New(float* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<float>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(float* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat32Array, ByteArray);
@@ -5926,20 +5944,20 @@
double At(intptr_t index) const {
ASSERT((index >= 0) && (index < Length()));
- return raw_ptr()->external_data_->data()[index];
+ return raw_ptr()->data_[index];
}
void SetAt(intptr_t index, double value) const {
ASSERT((index >= 0) && (index < Length()));
- raw_ptr()->external_data_->data()[index] = value;
+ raw_ptr()->data_[index] = value;
}
- void* GetData() const {
- return raw_ptr()->external_data_->data();
+ double* GetData() const {
+ return raw_ptr()->data_;
}
void* GetPeer() const {
- return raw_ptr()->external_data_->peer();
+ return raw_ptr()->peer_;
}
static const intptr_t kBytesPerElement = 8;
@@ -5954,20 +5972,21 @@
static RawExternalFloat64Array* New(double* data,
intptr_t len,
- void* peer,
- Dart_PeerFinalizer callback,
Heap::Space space = Heap::kNew);
private:
uint8_t* ByteAddr(intptr_t byte_offset) const {
ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
- uint8_t* data =
- reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+ uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
return data + byte_offset;
}
- void SetExternalData(ExternalByteArrayData<double>* data) {
- raw_ptr()->external_data_ = data;
+ void SetData(double* data) const {
+ raw_ptr()->data_ = data;
+ }
+
+ void SetPeer(void* peer) const {
+ raw_ptr()->peer_ = peer;
}
FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat64Array, ByteArray);
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 04b4299..a2d6686 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1905,19 +1905,19 @@
const ExternalInt8Array& int8_array =
ExternalInt8Array::Handle(
ExternalInt8Array::New(reinterpret_cast<int8_t*>(data),
- data_length, NULL, NULL));
+ data_length));
EXPECT(!int8_array.IsNull());
EXPECT_EQ(data_length, int8_array.Length());
const ExternalUint8Array& uint8_array =
ExternalUint8Array::Handle(
- ExternalUint8Array::New(data, data_length, NULL, NULL));
+ ExternalUint8Array::New(data, data_length));
EXPECT(!uint8_array.IsNull());
EXPECT_EQ(data_length, uint8_array.Length());
const ExternalUint8ClampedArray& uint8_clamped_array =
ExternalUint8ClampedArray::Handle(
- ExternalUint8ClampedArray::New(data, data_length, NULL, NULL));
+ ExternalUint8ClampedArray::New(data, data_length));
EXPECT(!uint8_clamped_array.IsNull());
EXPECT_EQ(data_length, uint8_clamped_array.Length());
@@ -2090,7 +2090,7 @@
const ExternalUint8Array& external =
ExternalUint8Array::Handle(
- ExternalUint8Array::New(data, ARRAY_SIZE(data), NULL, NULL));
+ ExternalUint8Array::New(data, ARRAY_SIZE(data)));
EXPECT(!external.IsNull());
EXPECT_EQ(4, external.Length());
EXPECT_EQ(0, external.At(0));
@@ -2150,7 +2150,7 @@
const ExternalUint8ClampedArray& external =
ExternalUint8ClampedArray::Handle(
- ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data), NULL, NULL));
+ ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data)));
EXPECT(!external.IsNull());
EXPECT_EQ(4, external.Length());
EXPECT_EQ(0, external.At(0));
@@ -2217,7 +2217,7 @@
const ExternalUint8Array& external =
ExternalUint8Array::Handle(
- ExternalUint8Array::New(data, ARRAY_SIZE(data), NULL, NULL));
+ ExternalUint8Array::New(data, ARRAY_SIZE(data)));
EXPECT(!external.IsNull());
EXPECT_EQ(4, external.Length());
EXPECT_EQ(4, external.At(0));
@@ -2298,7 +2298,7 @@
const ExternalUint8ClampedArray& external =
ExternalUint8ClampedArray::Handle(
- ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data), NULL, NULL));
+ ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data)));
EXPECT(!external.IsNull());
EXPECT_EQ(4, external.Length());
EXPECT_EQ(4, external.At(0));
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 078e07e..3478c5a 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -253,10 +253,12 @@
}
bool IsNewObject() const {
+ ASSERT(IsHeapObject());
uword addr = reinterpret_cast<uword>(this);
return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
}
bool IsOldObject() const {
+ ASSERT(IsHeapObject());
uword addr = reinterpret_cast<uword>(this);
return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
}
@@ -1401,53 +1403,23 @@
};
-template<typename T>
-class ExternalByteArrayData {
- public:
- static const int kAlignment = 16;
-
- ExternalByteArrayData(T* data,
- void* peer,
- Dart_PeerFinalizer callback) :
- data_(data), peer_(peer), callback_(callback) {
- }
- ~ExternalByteArrayData() {
- if (callback_ != NULL) (*callback_)(peer_);
- }
-
- T* data() {
- return data_;
- }
- void* peer() {
- return peer_;
- }
-
- static intptr_t data_offset() {
- return OFFSET_OF(ExternalByteArrayData<T>, data_);
- }
-
- private:
- T* data_;
- void* peer_;
- Dart_PeerFinalizer callback_;
-};
-
-
class RawExternalInt8Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt8Array);
- ExternalByteArrayData<int8_t>* external_data_;
+ int8_t* data_;
+ void* peer_;
};
class RawExternalUint8Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint8Array);
- protected:
- ExternalByteArrayData<uint8_t>* external_data_;
+ uint8_t* data_;
+ void* peer_;
friend class TokenStream;
friend class RawTokenStream;
+ friend class RawExternalUint8ClampedArray;
};
@@ -1459,56 +1431,64 @@
class RawExternalInt16Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt16Array);
- ExternalByteArrayData<int16_t>* external_data_;
+ int16_t* data_;
+ void* peer_;
};
class RawExternalUint16Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint16Array);
- ExternalByteArrayData<uint16_t>* external_data_;
+ uint16_t* data_;
+ void* peer_;
};
class RawExternalInt32Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt32Array);
- ExternalByteArrayData<int32_t>* external_data_;
+ int32_t* data_;
+ void* peer_;
};
class RawExternalUint32Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint32Array);
- ExternalByteArrayData<uint32_t>* external_data_;
+ uint32_t* data_;
+ void* peer_;
};
class RawExternalInt64Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt64Array);
- ExternalByteArrayData<int64_t>* external_data_;
+ int64_t* data_;
+ void* peer_;
};
class RawExternalUint64Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint64Array);
- ExternalByteArrayData<uint64_t>* external_data_;
+ uint64_t* data_;
+ void* peer_;
};
class RawExternalFloat32Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat32Array);
- ExternalByteArrayData<float>* external_data_;
+ float* data_;
+ void* peer_;
};
class RawExternalFloat64Array : public RawByteArray {
RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat64Array);
- ExternalByteArrayData<double>* external_data_;
+ double* data_;
+ void* peer_;
};
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 7011f4b..8895007 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -767,7 +767,7 @@
if (kind == Snapshot::kScript) {
NoGCScope no_gc;
RawExternalUint8Array* stream = token_stream.GetStream();
- reader->ReadBytes(stream->ptr()->external_data_->data(), len);
+ reader->ReadBytes(stream->ptr()->data_, len);
}
// Read in the literal/identifier token array.
@@ -799,7 +799,7 @@
RawExternalUint8Array* stream = ptr()->stream_;
intptr_t len = Smi::Value(stream->ptr()->length_);
writer->Write<RawObject*>(stream->ptr()->length_);
- writer->WriteBytes(stream->ptr()->external_data_->data(), len);
+ writer->WriteBytes(stream->ptr()->data_, len);
// Write out the literal/identifier token array.
writer->WriteObjectImpl(ptr()->token_objects_);
@@ -2035,10 +2035,14 @@
ASSERT(kind != Snapshot::kFull); \
intptr_t length = reader->ReadSmiValue(); \
type* data = reinterpret_cast<type*>(reader->ReadIntptrValue()); \
+ const External##name##Array& obj = External##name##Array::Handle( \
+ External##name##Array::New(data, length)); \
void* peer = reinterpret_cast<void*>(reader->ReadIntptrValue()); \
- Dart_PeerFinalizer callback = \
- reinterpret_cast<Dart_PeerFinalizer>(reader->ReadIntptrValue()); \
- return New(data, length, peer, callback, HEAP_SPACE(kind)); \
+ Dart_WeakPersistentHandleFinalizer callback = \
+ reinterpret_cast<Dart_WeakPersistentHandleFinalizer>( \
+ reader->ReadIntptrValue()); \
+ obj.AddFinalizer(peer, callback); \
+ return obj.raw(); \
} \
@@ -2109,7 +2113,7 @@
k##name##ArrayCid, \
writer->GetObjectTags(this), \
ptr()->length_, \
- ptr()->external_data_->data()); \
+ ptr()->data_); \
} \
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index c4dca42..0b4d1bc 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -790,7 +790,7 @@
// it will be possible to disassemble the code and inspect registers.
char buffer[128];
snprintf(buffer, sizeof(buffer),
- "illegal memory access at 0x%x, pc=0x%x\n",
+ "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
addr, fault_pc);
SimulatorDebugger dbg(this);
dbg.Stop(instr, buffer);
@@ -812,7 +812,7 @@
// it will be possible to disassemble the code and inspect registers.
char buffer[64];
snprintf(buffer, sizeof(buffer),
- "unaligned %s at 0x%x, pc=%p\n", msg, addr, instr);
+ "unaligned %s at 0x%"Px", pc=%p\n", msg, addr, instr);
SimulatorDebugger dbg(this);
dbg.Stop(instr, buffer);
// The debugger will return control in non-interactive mode.
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 6538b90..1069755 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -422,12 +422,9 @@
uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress());
ASSERT(array != NULL);
Advance(len);
- ExternalByteArrayData<uint8_t>* external_data =
- new ExternalByteArrayData<uint8_t>(array, NULL, NULL);
- ASSERT(external_data != NULL);
data_ = reinterpret_cast<RawExternalUint8Array*>(
AllocateUninitialized(cls_, ExternalUint8Array::InstanceSize()));
- data_.SetExternalData(external_data);
+ data_.SetData(array);
data_.SetLength(len);
stream_.SetStream(data_);
return stream_.raw();
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 594ab31..3628e9b 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -669,7 +669,7 @@
ctype data[] = { 0, 11, 22, 33, 44, 55, 66, 77 }; \
intptr_t length = ARRAY_SIZE(data); \
External##darttype& array = External##darttype::Handle( \
- External##darttype::New(data, length, NULL, NULL)); \
+ External##darttype::New(data, length)); \
uint8_t* buffer; \
MessageWriter writer(&buffer, &zone_allocator); \
writer.WriteMessage(array); \
@@ -1384,7 +1384,7 @@
EXPECT(Dart_IsString(crappy_string_result));
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
{
StackZone zone(Isolate::Current());
@@ -1475,7 +1475,7 @@
EXPECT_VALID(lib);
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
{
// Generate a list of nulls from Dart code.
ApiNativeScope scope;
@@ -1593,7 +1593,7 @@
EXPECT_VALID(lib);
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
{
// Generate a list of nulls from Dart code.
ApiNativeScope scope;
@@ -1816,7 +1816,7 @@
EXPECT_VALID(lib);
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
{
// Generate a list of strings from Dart code.
@@ -1991,7 +1991,7 @@
EXPECT_VALID(lib);
{
- DARTSCOPE_NOCHECKS(isolate);
+ DARTSCOPE(isolate);
{
// Generate a list of strings from Dart code.
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 8fb425a..d4306f5 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -280,51 +280,62 @@
}
-InlinedFunctionsInDartFrameIterator::InlinedFunctionsInDartFrameIterator(
- StackFrame* frame) : index_(0),
- frame_(frame),
- func_(Function::Handle()),
- deopt_info_(DeoptInfo::Handle()),
- object_table_(Array::Handle()) {
- ASSERT(frame_ != NULL);
- const Code& code = Code::Handle(frame_->LookupDartCode());
- ASSERT(code.is_optimized());
- func_ = code.function();
+InlinedFunctionsIterator::InlinedFunctionsIterator(StackFrame* frame)
+ : index_(0),
+ code_(Code::Handle()),
+ deopt_info_(DeoptInfo::Handle()),
+ function_(Function::Handle()),
+ pc_(0),
+ deopt_instructions_(),
+ object_table_(Array::Handle()) {
+ ASSERT(frame != NULL);
+ code_ = frame->LookupDartCode();
+ ASSERT(code_.is_optimized());
intptr_t deopt_reason = kDeoptUnknown;
- deopt_info_ = code.GetDeoptInfoAtPc(frame_->pc(), &deopt_reason);
- object_table_ = code.object_table();
+ deopt_info_ = code_.GetDeoptInfoAtPc(frame->pc(), &deopt_reason);
+ if (deopt_info_.IsNull()) {
+ // This is the case when a call without deopt info in optimzed code
+ // throws an exception. (e.g. in the parameter copying prologue).
+ // In that case there won't be any inlined frames.
+ function_ = code_.function();
+ pc_ = frame->pc();
+ ASSERT(pc_ != 0);
+ } else {
+ // Unpack deopt info into instructions (translate away suffixes).
+ const Array& deopt_table = Array::Handle(code_.deopt_info_array());
+ ASSERT(!deopt_table.IsNull());
+ deopt_info_.ToInstructions(deopt_table, &deopt_instructions_);
+ object_table_ = code_.object_table();
+ Advance();
+ }
}
-RawFunction* InlinedFunctionsInDartFrameIterator::GetNextFunction(uword* pc) {
- if (index_ == -1) {
- return Function::null();
- }
- if (deopt_info_.IsNull()) {
- // We are at a PC that has no deoptimization info so there are no
- // inlined functions to iterate over, we return the function.
- index_ = -1; // No more functions.
- *pc = frame_->pc();
- return func_.raw();
- }
+void InlinedFunctionsIterator::Advance() {
// Iterate over the deopt instructions and determine the inlined
// functions if any and iterate over them.
- ASSERT(deopt_info_.Length() != 0);
- while (index_ < deopt_info_.Length()) {
- intptr_t cur_index = index_;
- index_ += 1;
- intptr_t deopt_instr = deopt_info_.Instruction(cur_index);
- ASSERT(deopt_instr != DeoptInstr::kRetBeforeAddress);
- if (deopt_instr == DeoptInstr::kRetAfterAddress) {
- intptr_t deopt_from_index = deopt_info_.FromIndex(cur_index);
- *pc = DeoptInstr::GetRetAfterAddress(deopt_from_index,
+ ASSERT(!Done());
+
+ if (deopt_info_.IsNull()) {
+ SetDone();
+ return;
+ }
+
+ Function& func = Function::Handle();
+ ASSERT(deopt_instructions_.length() != 0);
+ while (index_ < deopt_instructions_.length()) {
+ DeoptInstr* deopt_instr = deopt_instructions_[index_++];
+ ASSERT(deopt_instr->kind() != DeoptInstr::kRetBeforeAddress);
+ if (deopt_instr->kind() == DeoptInstr::kRetAfterAddress) {
+ pc_ = DeoptInstr::GetRetAfterAddress(deopt_instr,
object_table_,
- &func_);
- return func_.raw();
+ &func);
+ code_ = func.unoptimized_code();
+ function_ = func.raw();
+ return;
}
}
- index_ = -1;
- return Function::null();
+ SetDone();
}
} // namespace dart
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 04a55dd..c4dd50dd 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -229,19 +229,39 @@
// Iterator for iterating over all inlined dart functions in an optimized
// dart frame (the iteration includes the function that is inlining the
// other functions).
-class InlinedFunctionsInDartFrameIterator : public ValueObject {
+class InlinedFunctionsIterator : public ValueObject {
public:
- explicit InlinedFunctionsInDartFrameIterator(StackFrame* frame);
- RawFunction* GetNextFunction(uword* pc);
+ explicit InlinedFunctionsIterator(StackFrame* frame);
+ bool Done() const { return index_ == -1; }
+ void Advance();
+
+ RawFunction* function() const {
+ ASSERT(!Done());
+ return function_.raw();
+ }
+
+ uword pc() const {
+ ASSERT(!Done());
+ return pc_;
+ }
+
+ RawCode* code() const {
+ ASSERT(!Done());
+ return code_.raw();
+ }
private:
+ void SetDone() { index_ = -1; }
+
intptr_t index_;
- StackFrame* frame_;
- Function& func_;
+ Code& code_;
DeoptInfo& deopt_info_;
+ Function& function_;
+ uword pc_;
+ GrowableArray<DeoptInstr*> deopt_instructions_;
Array& object_table_;
- DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsInDartFrameIterator);
+ DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator);
};
} // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 3fdc4b0..660f46f 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -191,6 +191,7 @@
V(_instanceOf, "_instanceOf") \
V(PrivateGetterPrefix, "get:_") \
V(PrivateSetterPrefix, "set:_") \
+ V(_New, "_new") \
// Contains a list of frequently used strings in a canonicalized form. This
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index 3f74135..80dabd6 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -42,7 +42,7 @@
if test -f "$SNAPSHOT"; then
# TODO(ahe): Remove the following line when we are relatively sure it works.
echo Using snapshot "$SNAPSHOT" 1>&2
- EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]="--use_script_snapshot=$SNAPSHOT"
+ EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]="--use-script-snapshot=$SNAPSHOT"
fi
# Tell the VM to grow the heap more aggressively. This should only
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 3992aa0..87584ff 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -10,6 +10,6 @@
set arguments=%*
set SNAPSHOTNAME="%SCRIPTPATH%dart2js.snapshot"
-if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+if exist %SNAPSHOTNAME% set SNAPSHOT=--use-script-snapshot=%SNAPSHOTNAME%
"%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
diff --git a/sdk/bin/dartdoc b/sdk/bin/dartdoc
index f694a9e..74b7a8a 100755
--- a/sdk/bin/dartdoc
+++ b/sdk/bin/dartdoc
@@ -21,6 +21,6 @@
if test -f "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"; then
# TODO(ahe): Remove the following line when we are relatively sure it works.
echo Using snapshot "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot" 1>&2
- SNAPSHOT="--use_script_snapshot=$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"
+ SNAPSHOT="--use-script-snapshot=$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"
fi
exec "$BIN_DIR"/dart --no_use_inlining --heap_growth_rate=32 $SNAPSHOT "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart" $COLORS "$@"
diff --git a/sdk/bin/dartdoc.bat b/sdk/bin/dartdoc.bat
index 8fe00ea..5923d19 100644
--- a/sdk/bin/dartdoc.bat
+++ b/sdk/bin/dartdoc.bat
@@ -10,6 +10,6 @@
set arguments=%*
rem set SNAPSHOTNAME="%SCRIPTPATH%dartdoc.snapshot"
-rem if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+rem if exist %SNAPSHOTNAME% set SNAPSHOT=--use-script-snapshot=%SNAPSHOTNAME%
"%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=32 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\dartdoc\bin\dartdoc.dart" %arguments%
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index b5dd3dd..cf7eb2a 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -16,9 +16,34 @@
* [uri]. If an exception occurs, the future completes with this
* exception.
*/
+typedef Future<String> CompilerInputProvider(Uri uri);
+
+/// Deprecated, please use [CompilerInputProvider] instead.
typedef Future<String> ReadStringFromUri(Uri uri);
/**
+ * Returns a [Sink] that will serve as compiler output for the given
+ * component.
+ *
+ * Components are identified by [name] and [extension]. By convention,
+ * the empty string [:"":] will represent the main script
+ * (corresponding to the script parameter of [compile]) even if the
+ * main script is a library. For libraries that are compiled
+ * separately, the library name is used.
+ *
+ * At least the following extensions can be expected:
+ *
+ * * "js" for JavaScript output.
+ * * "js.map" for source maps.
+ * * "dart" for Dart output.
+ * * "dart.map" for source maps.
+ *
+ * As more features are added to the compiler, new names and
+ * extensions may be introduced.
+ */
+typedef Sink<String> CompilerOutputProvider(String name, String extension);
+
+/**
* Invoked by the compiler to report diagnostics. If [uri] is
* [:null:], so are [begin] and [end]. No other arguments may be
* [:null:]. If [uri] is not [:null:], neither are [begin] and
@@ -32,17 +57,27 @@
String message, Diagnostic kind);
/**
- * Returns a future that completes to [script] compiled to JavaScript. If
- * the compilation fails, the future's value will be [:null:] and
+ * Returns a future that completes to a non-null String when [script]
+ * has been successfully compiled.
+ *
+ * The compiler output is obtained by providing an [outputProvider].
+ *
+ * If the compilation fails, the future's value will be [:null:] and
* [handler] will have been invoked at least once with [:kind ==
* Diagnostic.ERROR:] or [:kind == Diagnostic.CRASH:].
+ *
+ * Deprecated: if no [outputProvider] is given, the future completes
+ * to the compiled script. This behavior will be removed in the future
+ * as the compiler may create multiple files to support lazy loading
+ * of libraries.
*/
Future<String> compile(Uri script,
Uri libraryRoot,
Uri packageRoot,
- ReadStringFromUri provider,
+ CompilerInputProvider inputProvider,
DiagnosticHandler handler,
- [List<String> options = const []]) {
+ [List<String> options = const [],
+ CompilerOutputProvider outputProvider]) {
if (!libraryRoot.path.endsWith("/")) {
throw new ArgumentError("libraryRoot must end with a /");
}
@@ -51,10 +86,24 @@
}
// TODO(ahe): Consider completing the future with an exception if
// code is null.
- Compiler compiler = new Compiler(provider, handler, libraryRoot, packageRoot,
+ Compiler compiler = new Compiler(inputProvider,
+ outputProvider,
+ handler,
+ libraryRoot,
+ packageRoot,
options);
compiler.run(script);
String code = compiler.assembledCode;
+ if (code != null && outputProvider != null) {
+ String outputType = 'js';
+ if (options.contains('--output-type=dart')) {
+ outputType = 'dart';
+ }
+ outputProvider('', outputType)
+ ..add(code)
+ ..close();
+ code = ''; // Non-null signals success.
+ }
return new Future.immediate(code);
}
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index fd9ccd9..663e003 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -24,12 +24,17 @@
bool mockableLibraryUsed = false;
final Set<String> allowedLibraryCategories;
- Compiler(this.provider, this.handler, this.libraryRoot, this.packageRoot,
+ Compiler(this.provider,
+ api.CompilerOutputProvider outputProvider,
+ this.handler,
+ this.libraryRoot,
+ this.packageRoot,
List<String> options)
: this.options = options,
this.allowedLibraryCategories = getAllowedLibraryCategories(options),
super(
tracer: new ssa.HTracer(),
+ outputProvider: outputProvider,
enableTypeAssertions: hasOption(options, '--enable-checked-mode'),
enableUserAssertions: hasOption(options, '--enable-checked-mode'),
enableMinification: hasOption(options, '--minify'),
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index e400f5c..4ed1564 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -6,6 +6,7 @@
import "elements/elements.dart";
import "dart2jslib.dart";
+import "dart_types.dart";
import "scanner/scannerlib.dart" show Token;
import "tree/tree.dart";
import "util/util.dart";
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index c805e1e..691cbac 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -148,7 +148,7 @@
if (isConst) {
MessageKind kind = MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS;
compiler.reportError(node,
- new CompileTimeConstantError(kind, const []));
+ new CompileTimeConstantError(kind));
} else {
lazyStatics.add(element);
return null;
@@ -173,9 +173,9 @@
if (elementType.isMalformed || constantType.isMalformed ||
!constantSystem.isSubtype(compiler, constantType, elementType)) {
if (isConst) {
- MessageKind kind = MessageKind.NOT_ASSIGNABLE;
compiler.reportError(node, new CompileTimeConstantError(
- kind, [elementType, constantType]));
+ MessageKind.NOT_ASSIGNABLE,
+ {'fromType': elementType, 'toType': constantType}));
} else {
// If the field can be lazily initialized, we will throw
// the exception at runtime.
@@ -229,7 +229,9 @@
return initialVariableValues.keys.where((element) {
return element.kind == ElementKind.FIELD
&& !element.isInstanceMember()
- && !element.modifiers.isFinal();
+ && !element.modifiers.isFinal()
+ // The const fields are all either emitted elsewhere or inlined.
+ && !element.modifiers.isConst();
});
}
@@ -354,7 +356,7 @@
Constant key = evaluateConstant(entry.key);
if (!key.isString() || entry.key.asStringNode() == null) {
MessageKind kind = MessageKind.KEY_NOT_A_STRING_LITERAL;
- compiler.reportError(entry.key, new ResolutionError(kind, const []));
+ compiler.reportError(entry.key, new ResolutionError(kind));
}
StringConstant keyConstant = key;
if (!map.containsKey(key)) keys.add(key);
@@ -468,7 +470,7 @@
&& element.isVariable()
&& element.modifiers.isConst()) {
Constant result = handler.compileConstant(element);
- if (result != null) return result;
+ if (result != null) return result;
}
return signalNotCompileTimeConstant(send);
} else if (send.isCall) {
@@ -624,7 +626,7 @@
if (!succeeded) {
MessageKind kind = MessageKind.INVALID_ARGUMENTS;
compiler.reportError(node,
- new CompileTimeConstantError(kind, [target.name.slowToString()]));
+ new CompileTimeConstantError(kind, {'methodName': target.name}));
}
return compiledArguments;
}
@@ -672,7 +674,7 @@
// TODO(floitsch): get the list of constants that are currently compiled
// and present some kind of stack-trace.
MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
- compiler.reportError(node, new CompileTimeConstantError(kind, const []));
+ compiler.reportError(node, new CompileTimeConstantError(kind));
}
Constant signalNotCompileTimeConstant(Node node) {
@@ -697,7 +699,7 @@
error(Node node) {
// Just fail without reporting it anywhere.
throw new CompileTimeConstantError(
- MessageKind.NOT_A_COMPILE_TIME_CONSTANT, const []);
+ MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
}
}
@@ -745,9 +747,9 @@
if (elementType.element.isTypeVariable()) return;
if (elementType.isMalformed || constantType.isMalformed ||
!constantSystem.isSubtype(compiler, constantType, elementType)) {
- MessageKind kind = MessageKind.NOT_ASSIGNABLE;
compiler.reportError(node, new CompileTimeConstantError(
- kind, [elementType, constantType]));
+ MessageKind.NOT_ASSIGNABLE,
+ {'fromType': elementType, 'toType': constantType}));
}
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 0137e2f..01e5cc2 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -203,6 +203,8 @@
*/
final bool preserveComments;
+ final api.CompilerOutputProvider outputProvider;
+
bool disableInlining = false;
List<Uri> librariesToAnalyzeWhenRun;
@@ -331,9 +333,13 @@
this.rejectDeprecatedFeatures: false,
this.checkDeprecationInSdk: false,
this.preserveComments: false,
+ outputProvider,
List<String> strips: const []})
: libraries = new Map<String, LibraryElement>(),
- progress = new Stopwatch() {
+ progress = new Stopwatch(),
+ this.outputProvider =
+ (outputProvider == null) ? NullSink.outputProvider : outputProvider
+ {
progress.start();
world = new World(this);
@@ -409,7 +415,7 @@
}
void pleaseReportCrash() {
- print(MessageKind.PLEASE_REPORT_THE_CRASH.message([BUILD_ID]));
+ print(MessageKind.PLEASE_REPORT_THE_CRASH.message({'buildId': BUILD_ID}));
}
void cancel(String reason, {Node node, Token token,
@@ -433,6 +439,9 @@
}
SourceSpan spanFromSpannable(Spannable node, [Uri uri]) {
+ if (node == CURRENT_ELEMENT_SPANNABLE) {
+ node = currentElement;
+ }
if (node is Node) {
return spanFromNode(node, uri);
} else if (node is Token) {
@@ -839,12 +848,21 @@
reportDiagnostic(span, 'Warning: $message', api.Diagnostic.WARNING);
}
+ // TODO(ahe): Remove this method.
reportError(Node node, var message) {
SourceSpan span = spanFromNode(node);
reportDiagnostic(span, 'Error: $message', api.Diagnostic.ERROR);
throw new CompilerCancelledException(message.toString());
}
+ // TODO(ahe): Rename to reportError when that method has been removed.
+ void reportErrorCode(Spannable node, MessageKind errorCode,
+ [Map arguments = const {}]) {
+ reportMessage(spanFromSpannable(node),
+ errorCode.error(arguments),
+ api.Diagnostic.ERROR);
+ }
+
void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind) {
// TODO(ahe): The names Diagnostic and api.Diagnostic are in
// conflict. Fix it.
@@ -862,8 +880,9 @@
var kind = rejectDeprecatedFeatures
? api.Diagnostic.ERROR : api.Diagnostic.WARNING;
var message = rejectDeprecatedFeatures
- ? MessageKind.DEPRECATED_FEATURE_ERROR.error([feature])
- : MessageKind.DEPRECATED_FEATURE_WARNING.error([feature]);
+ ? MessageKind.DEPRECATED_FEATURE_ERROR.error({'featureName': feature})
+ : MessageKind.DEPRECATED_FEATURE_WARNING.error(
+ {'featureName': feature});
reportMessage(spanFromSpannable(span), message, kind);
return true;
}
@@ -1087,3 +1106,21 @@
}
return true;
}
+
+/// A sink that drains into /dev/null.
+class NullSink extends Sink<String> {
+ final String name;
+
+ NullSink(this.name);
+
+ add(String value) {}
+
+ void close() {}
+
+ toString() => name;
+
+ /// Convenience method for getting an [api.CompilerOutputProvider].
+ static NullSink outputProvider(String name, String extension) {
+ return new NullSink('$name.$extension');
+ }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index cf774f5..d66579f 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -131,7 +131,7 @@
setCategories(String argument) {
List<String> categories = extractParameter(argument).split(',');
Set<String> allowedCategories =
- LIBRARIES.values.mappedBy((x) => x.category).toSet();
+ LIBRARIES.values.map((x) => x.category).toSet();
allowedCategories.remove('Shared');
allowedCategories.remove('Internal');
List<String> allowedCategoriesList =
@@ -233,12 +233,6 @@
void handler(Uri uri, int begin, int end, String message,
api.Diagnostic kind) {
- if (identical(kind.name, 'source map')) {
- // TODO(podivilov): We should find a better way to return source maps from
- // emitter. Using diagnostic handler for that purpose is a temporary hack.
- writeString(sourceMapOut, message);
- return;
- }
diagnosticHandler.diagnosticHandler(uri, begin, end, message, kind);
}
@@ -249,34 +243,89 @@
diagnosticHandler.info('package root is $packageRoot');
- // TODO(ahe): We expect the future to be complete and call value
- // directly. In effect, we don't support truly asynchronous API.
- String code = deprecatedFutureValue(
- api.compile(uri, libraryRoot, packageRoot,
- inputProvider.readStringFromUri,
- handler,
- options));
- if (analyzeOnly) return;
+ int charactersWritten = 0;
- if (code == null) {
- fail('Error: Compilation failed.');
+ compilationDone(String code) {
+ if (analyzeOnly) return;
+ if (code == null) {
+ fail('Error: Compilation failed.');
+ }
+ writeString(Uri.parse('$out.deps'),
+ getDepsOutput(inputProvider.sourceFiles));
+ diagnosticHandler.info(
+ 'compiled ${inputProvider.dartCharactersRead} characters Dart '
+ '-> $charactersWritten characters $outputLanguage '
+ 'in ${relativize(cwd, out, isWindows)}');
+ if (!explicitOut) {
+ String input = uriPathToNative(arguments[0]);
+ String output = relativize(cwd, out, isWindows);
+ print('Dart file $input compiled to $outputLanguage: $output');
+ }
}
- String sourceMapFileName =
- sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1);
- code = '$code\n//@ sourceMappingURL=${sourceMapFileName}';
- writeString(out, code);
- writeString(Uri.parse('$out.deps'),
- getDepsOutput(inputProvider.sourceFiles));
- int dartBytesRead = inputProvider.dartBytesRead;
- int bytesWritten = code.length;
- diagnosticHandler.info(
- 'compiled $dartBytesRead bytes Dart -> $bytesWritten bytes '
- '$outputLanguage in ${relativize(cwd, out, isWindows)}');
- if (!explicitOut) {
- String input = uriPathToNative(arguments[0]);
- String output = relativize(cwd, out, isWindows);
- print('Dart file $input compiled to $outputLanguage: $output');
+
+ Sink<String> outputProvider(String name, String extension) {
+ Uri uri;
+ String sourceMapFileName;
+ bool isPrimaryOutput = false;
+ if (name == '') {
+ if (extension == 'js' || extension == 'dart') {
+ isPrimaryOutput = true;
+ uri = out;
+ sourceMapFileName =
+ sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1);
+ } else if (extension == 'js.map' || extension == 'dart.map') {
+ uri = sourceMapOut;
+ } else {
+ fail('Error: Unknown extension: $extension');
+ }
+ } else {
+ uri = out.resolve('$name.$extension');
+ }
+
+ if (uri.scheme != 'file') {
+ fail('Error: Unhandled scheme ${uri.scheme} in $uri.');
+ }
+ var outputStream = new File(uriPathToNative(uri.path)).openOutputStream();
+
+ CountingSink sink;
+
+ onDone() {
+ if (sourceMapFileName != null) {
+ String sourceMapTag = '//@ sourceMappingURL=$sourceMapFileName\n';
+ sink.count += sourceMapTag.length;
+ outputStream.writeString(sourceMapTag);
+ }
+ outputStream.close();
+ if (isPrimaryOutput) {
+ charactersWritten += sink.count;
+ }
+ }
+
+ var controller = new StreamController<String>();
+ controller.stream.listen(outputStream.writeString, onDone: onDone);
+ sink = new CountingSink(controller);
+ return sink;
}
+
+ api.compile(uri, libraryRoot, packageRoot,
+ inputProvider.readStringFromUri, handler,
+ options, outputProvider)
+ .then(compilationDone);
+}
+
+// TODO(ahe): Get rid of this class if http://dartbug.com/8118 is fixed.
+class CountingSink implements Sink<String> {
+ final Sink<String> sink;
+ int count = 0;
+
+ CountingSink(this.sink);
+
+ add(String value) {
+ sink.add(value);
+ count += value.length;
+ }
+
+ close() => sink.close();
}
class AbortLeg {
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index a5c63c37..8a1e012 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -9,6 +9,7 @@
import 'closure.dart' as closureMapping;
import 'dart_backend/dart_backend.dart' as dart_backend;
+import 'dart_types.dart';
import 'elements/elements.dart';
import 'elements/modelx.dart'
show ErroneousElementX,
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index e2be554..6a3b000 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -89,7 +89,7 @@
return false;
}
- rewiteStatement(Statement statement) {
+ rewriteStatement(Statement statement) {
if (statement is Block) {
Link statements = statement.statements.nodes;
if (!statements.isEmpty && statements.tail.isEmpty) {
@@ -106,7 +106,7 @@
LinkBuilder<Statement> builder = new LinkBuilder<Statement>();
for (Statement statement in statements.nodes) {
if (!shouldOmit(statement)) {
- builder.addLast(visit(rewiteStatement(statement)));
+ builder.addLast(visit(rewriteStatement(statement)));
}
}
return new Block(rewriteNodeList(statements, builder.toLink()));
@@ -137,7 +137,7 @@
Set<DartType> processedTypes = new Set<DartType>();
List<DartType> workQueue = new List<DartType>();
workQueue.addAll(
- classMembers.keys.mappedBy((classElement) => classElement.thisType));
+ classMembers.keys.map((classElement) => classElement.thisType));
workQueue.addAll(compiler.resolverWorld.isChecks);
Element typeErrorElement =
compiler.coreLibrary.find(new SourceString('TypeError'));
@@ -387,8 +387,13 @@
SynthesizedConstructorElementX constructor =
new SynthesizedConstructorElementX(classElement);
constructor.type = new FunctionType(
- compiler.types.voidType, const Link<DartType>(),
- constructor);
+ constructor,
+ compiler.types.voidType,
+ const Link<DartType>(),
+ const Link<DartType>(),
+ const Link<SourceString>(),
+ const Link<DartType>()
+ );
constructor.cachedNode = new FunctionExpression(
new Send(classNode.name, synthesizedIdentifier),
new NodeList(new StringToken(OPEN_PAREN_INFO, '(', -1),
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
index cea56ff..8a8abe4 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
@@ -7,6 +7,7 @@
import '../elements/elements.dart';
import '../elements/modelx.dart' show SynthesizedConstructorElementX;
import '../dart2jslib.dart';
+import '../dart_types.dart';
import '../tree/tree.dart';
import '../util/util.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index 4b9f3e0..886d39e 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -191,7 +191,7 @@
sorted(functionScope.localPlaceholders,
compareBy((LocalPlaceholder ph) => -ph.nodes.length));
List<Set<Node>> currentSortedNodes =
- currentSortedPlaceholders.mappedBy((ph) => ph.nodes).toList();
+ currentSortedPlaceholders.map((ph) => ph.nodes).toList();
// Make room in all sorted locals list for new stuff.
while (currentSortedNodes.length > allSortedLocals.length) {
allSortedLocals.add(new Set<Node>());
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
new file mode 100644
index 0000000..b43de38
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -0,0 +1,817 @@
+// Copyright (c) 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 dart_types;
+
+import 'dart2jslib.dart' show Compiler, invariant, Script, Message;
+import 'elements/modelx.dart' show VoidElementX, LibraryElementX;
+import 'elements/elements.dart';
+import 'scanner/scannerlib.dart' show SourceString;
+import 'util/util.dart' show Link, LinkBuilder;
+
+class TypeKind {
+ final String id;
+
+ const TypeKind(String this.id);
+
+ static const TypeKind FUNCTION = const TypeKind('function');
+ static const TypeKind INTERFACE = const TypeKind('interface');
+ static const TypeKind STATEMENT = const TypeKind('statement');
+ static const TypeKind TYPEDEF = const TypeKind('typedef');
+ static const TypeKind TYPE_VARIABLE = const TypeKind('type variable');
+ static const TypeKind MALFORMED_TYPE = const TypeKind('malformed');
+ static const TypeKind VOID = const TypeKind('void');
+
+ String toString() => id;
+}
+
+abstract class DartType {
+ SourceString get name;
+
+ TypeKind get kind;
+
+ const DartType();
+
+ /**
+ * Returns the [Element] which declared this type.
+ *
+ * This can be [ClassElement] for classes, [TypedefElement] for typedefs,
+ * [TypeVariableElement] for type variables and [FunctionElement] for
+ * function types.
+ *
+ * Invariant: [element] must be a declaration element.
+ */
+ Element get element;
+
+ /**
+ * Performs the substitution [: [arguments[i]/parameters[i]]this :].
+ *
+ * The notation is known from this lambda calculus rule:
+ *
+ * (lambda x.e0)e1 -> [e1/x]e0.
+ *
+ * See [TypeVariableType] for a motivation for this method.
+ *
+ * Invariant: There must be the same number of [arguments] and [parameters].
+ */
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters);
+
+ /**
+ * Returns the unaliased type of this type.
+ *
+ * The unaliased type of a typedef'd type is the unaliased type to which its
+ * name is bound. The unaliased version of any other type is the type itself.
+ *
+ * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the
+ * function type [: (B) -> A :] and the unaliased type of
+ * [: Func<int,String> :] is the function type [: (String) -> int :].
+ */
+ DartType unalias(Compiler compiler);
+
+ /**
+ * A type is malformed if it is itself a malformed type or contains a
+ * malformed type.
+ */
+ bool get isMalformed => false;
+
+ /**
+ * Calls [f] with each [MalformedType] within this type.
+ *
+ * If [f] returns [: false :], the traversal stops prematurely.
+ *
+ * [forEachMalformedType] returns [: false :] if the traversal was stopped
+ * prematurely.
+ */
+ bool forEachMalformedType(bool f(MalformedType type)) => true;
+
+ bool operator ==(other);
+
+ /**
+ * Is [: true :] if this type has no explict type arguments.
+ */
+ bool get isRaw => true;
+
+ DartType asRaw() => this;
+}
+
+/**
+ * Represents a type variable, that is the type parameters of a class type.
+ *
+ * For example, in [: class Array<E> { ... } :], E is a type variable.
+ *
+ * Each class should have its own unique type variables, one for each type
+ * parameter. A class with type parameters is said to be parameterized or
+ * generic.
+ *
+ * Non-static members, constructors, and factories of generic
+ * class/interface can refer to type variables of the current class
+ * (not of supertypes).
+ *
+ * When using a generic type, also known as an application or
+ * instantiation of the type, the actual type arguments should be
+ * substituted for the type variables in the class declaration.
+ *
+ * For example, given a box, [: class Box<T> { T value; } :], the
+ * type of the expression [: new Box<String>().value :] is
+ * [: String :] because we must substitute [: String :] for the
+ * the type variable [: T :].
+ */
+class TypeVariableType extends DartType {
+ final TypeVariableElement element;
+
+ TypeVariableType(this.element);
+
+ TypeKind get kind => TypeKind.TYPE_VARIABLE;
+
+ SourceString get name => element.name;
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ if (parameters.isEmpty) {
+ assert(arguments.isEmpty);
+ // Return fast on empty substitutions.
+ return this;
+ }
+ Link<DartType> parameterLink = parameters;
+ Link<DartType> argumentLink = arguments;
+ while (!argumentLink.isEmpty && !parameterLink.isEmpty) {
+ TypeVariableType parameter = parameterLink.head;
+ DartType argument = argumentLink.head;
+ if (parameter == this) {
+ assert(argumentLink.tail.isEmpty == parameterLink.tail.isEmpty);
+ return argument;
+ }
+ parameterLink = parameterLink.tail;
+ argumentLink = argumentLink.tail;
+ }
+ assert(argumentLink.isEmpty && parameterLink.isEmpty);
+ // The type variable was not substituted.
+ return this;
+ }
+
+ DartType unalias(Compiler compiler) => this;
+
+ int get hashCode => 17 * element.hashCode;
+
+ bool operator ==(other) {
+ if (other is !TypeVariableType) return false;
+ return identical(other.element, element);
+ }
+
+ String toString() => name.slowToString();
+}
+
+/**
+ * A statement type tracks whether a statement returns or may return.
+ */
+class StatementType extends DartType {
+ final String stringName;
+
+ Element get element => null;
+
+ TypeKind get kind => TypeKind.STATEMENT;
+
+ SourceString get name => new SourceString(stringName);
+
+ const StatementType(this.stringName);
+
+ static const RETURNING = const StatementType('<returning>');
+ static const NOT_RETURNING = const StatementType('<not returning>');
+ static const MAYBE_RETURNING = const StatementType('<maybe returning>');
+
+ /** Combine the information about two control-flow edges that are joined. */
+ StatementType join(StatementType other) {
+ return (identical(this, other)) ? this : MAYBE_RETURNING;
+ }
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ // Statement types are not substitutable.
+ return this;
+ }
+
+ DartType unalias(Compiler compiler) => this;
+
+ int get hashCode => 17 * stringName.hashCode;
+
+ bool operator ==(other) {
+ if (other is !StatementType) return false;
+ return other.stringName == stringName;
+ }
+
+ String toString() => stringName;
+}
+
+class VoidType extends DartType {
+ const VoidType(this.element);
+
+ TypeKind get kind => TypeKind.VOID;
+
+ SourceString get name => element.name;
+
+ final Element element;
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ // Void cannot be substituted.
+ return this;
+ }
+
+ DartType unalias(Compiler compiler) => this;
+
+ int get hashCode => 1729;
+
+ bool operator ==(other) => other is VoidType;
+
+ String toString() => name.slowToString();
+}
+
+class MalformedType extends DartType {
+ final ErroneousElement element;
+
+ /**
+ * [declaredType] holds the type which the user wrote in code.
+ *
+ * For instance, for a resolved but malformed type like [: Map<String> :] the
+ * [declaredType] is [: Map<String> :] whereas for an unresolved type
+ */
+ final DartType userProvidedBadType;
+
+ /**
+ * Type arguments for the malformed typed, if these cannot fit in the
+ * [declaredType].
+ *
+ * This field is for instance used for [: dynamic<int> :] and [: T<int> :]
+ * where [: T :] is a type variable, in which case [declaredType] holds
+ * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :]
+ * is not resolved or does not imply a type.
+ */
+ final Link<DartType> typeArguments;
+
+ MalformedType(this.element, this.userProvidedBadType,
+ [this.typeArguments = null]);
+
+ TypeKind get kind => TypeKind.MALFORMED_TYPE;
+
+ SourceString get name => element.name;
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ // Malformed types are not substitutable.
+ return this;
+ }
+
+ bool get isMalformed => true;
+
+ bool forEachMalformedType(bool f(MalformedType type)) => f(this);
+
+ DartType unalias(Compiler compiler) => this;
+
+ String toString() {
+ var sb = new StringBuffer();
+ if (typeArguments != null) {
+ if (userProvidedBadType != null) {
+ sb.add(userProvidedBadType.name.slowToString());
+ } else {
+ sb.add(element.name.slowToString());
+ }
+ if (!typeArguments.isEmpty) {
+ sb.add('<');
+ typeArguments.printOn(sb, ', ');
+ sb.add('>');
+ }
+ } else {
+ sb.add(userProvidedBadType.toString());
+ }
+ return sb.toString();
+ }
+}
+
+bool hasMalformed(Link<DartType> types) {
+ for (DartType typeArgument in types) {
+ if (typeArgument.isMalformed) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// TODO(johnniwinther): Add common supertype for InterfaceType and TypedefType.
+class InterfaceType extends DartType {
+ final ClassElement element;
+ final Link<DartType> typeArguments;
+ final bool isMalformed;
+
+ InterfaceType(this.element,
+ [Link<DartType> typeArguments = const Link<DartType>()])
+ : this.typeArguments = typeArguments,
+ this.isMalformed = hasMalformed(typeArguments) {
+ assert(invariant(element, element.isDeclaration));
+ }
+
+ TypeKind get kind => TypeKind.INTERFACE;
+
+ SourceString get name => element.name;
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ if (typeArguments.isEmpty) {
+ // Return fast on non-generic types.
+ return this;
+ }
+ if (parameters.isEmpty) {
+ assert(arguments.isEmpty);
+ // Return fast on empty substitutions.
+ return this;
+ }
+ Link<DartType> newTypeArguments =
+ Types.substTypes(typeArguments, arguments, parameters);
+ if (!identical(typeArguments, newTypeArguments)) {
+ // Create a new type only if necessary.
+ return new InterfaceType(element, newTypeArguments);
+ }
+ return this;
+ }
+
+ bool forEachMalformedType(bool f(MalformedType type)) {
+ for (DartType typeArgument in typeArguments) {
+ if (!typeArgument.forEachMalformedType(f)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the type as an instance of class [other], if possible, null
+ * otherwise.
+ */
+ DartType asInstanceOf(ClassElement other) {
+ if (element == other) return this;
+ for (InterfaceType supertype in element.allSupertypes) {
+ ClassElement superclass = supertype.element;
+ if (superclass == other) {
+ Link<DartType> arguments = Types.substTypes(supertype.typeArguments,
+ typeArguments,
+ element.typeVariables);
+ return new InterfaceType(superclass, arguments);
+ }
+ }
+ return null;
+ }
+
+ DartType unalias(Compiler compiler) => this;
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.add(name.slowToString());
+ if (!isRaw) {
+ sb.add('<');
+ typeArguments.printOn(sb, ', ');
+ sb.add('>');
+ }
+ return sb.toString();
+ }
+
+ int get hashCode {
+ int hash = element.hashCode;
+ for (Link<DartType> arguments = this.typeArguments;
+ !arguments.isEmpty;
+ arguments = arguments.tail) {
+ int argumentHash = arguments.head != null ? arguments.head.hashCode : 0;
+ hash = 17 * hash + 3 * argumentHash;
+ }
+ return hash;
+ }
+
+ bool operator ==(other) {
+ if (other is !InterfaceType) return false;
+ if (!identical(element, other.element)) return false;
+ return typeArguments == other.typeArguments;
+ }
+
+ bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
+
+ InterfaceType asRaw() => element.rawType;
+}
+
+class FunctionType extends DartType {
+ final Element element;
+ final DartType returnType;
+ final Link<DartType> parameterTypes;
+ final Link<DartType> optionalParameterTypes;
+
+ /**
+ * The names of the named parameters ordered lexicographically.
+ */
+ final Link<SourceString> namedParameters;
+
+ /**
+ * The types of the named parameters in the order corresponding to the
+ * [namedParameters].
+ */
+ final Link<DartType> namedParameterTypes;
+ final bool isMalformed;
+
+ factory FunctionType(Element element,
+ DartType returnType,
+ Link<DartType> parameterTypes,
+ Link<DartType> optionalParameterTypes,
+ Link<SourceString> namedParameters,
+ Link<DartType> namedParameterTypes) {
+ // Compute [isMalformed] eagerly since it is faster than a lazy computation
+ // and since [isMalformed] most likely will be accessed in [Types.isSubtype]
+ // anyway.
+ bool isMalformed = returnType != null &&
+ returnType.isMalformed ||
+ hasMalformed(parameterTypes) ||
+ hasMalformed(optionalParameterTypes) ||
+ hasMalformed(namedParameterTypes);
+ return new FunctionType.internal(element,
+ returnType,
+ parameterTypes,
+ optionalParameterTypes,
+ namedParameters,
+ namedParameterTypes,
+ isMalformed);
+ }
+
+ FunctionType.internal(Element this.element,
+ DartType this.returnType,
+ Link<DartType> this.parameterTypes,
+ Link<DartType> this.optionalParameterTypes,
+ Link<SourceString> this.namedParameters,
+ Link<DartType> this.namedParameterTypes,
+ bool this.isMalformed) {
+ assert(element == null || invariant(element, element.isDeclaration));
+ // Assert that optional and named parameters are not used at the same time.
+ assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty);
+ assert(namedParameters.slowLength() == namedParameterTypes.slowLength());
+ }
+
+ TypeKind get kind => TypeKind.FUNCTION;
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ if (parameters.isEmpty) {
+ assert(arguments.isEmpty);
+ // Return fast on empty substitutions.
+ return this;
+ }
+ var newReturnType = returnType.subst(arguments, parameters);
+ bool changed = !identical(newReturnType, returnType);
+ var newParameterTypes =
+ Types.substTypes(parameterTypes, arguments, parameters);
+ var newOptionalParameterTypes =
+ Types.substTypes(optionalParameterTypes, arguments, parameters);
+ var newNamedParameterTypes =
+ Types.substTypes(namedParameterTypes, arguments, parameters);
+ if (!changed &&
+ (!identical(parameterTypes, newParameterTypes) ||
+ !identical(optionalParameterTypes, newOptionalParameterTypes) ||
+ !identical(namedParameterTypes, newNamedParameterTypes))) {
+ changed = true;
+ }
+ if (changed) {
+ // Create a new type only if necessary.
+ return new FunctionType(element,
+ newReturnType,
+ newParameterTypes,
+ newOptionalParameterTypes,
+ namedParameters,
+ newNamedParameterTypes);
+ }
+ return this;
+ }
+
+ bool forEachMalformedType(bool f(MalformedType type)) {
+ if (!returnType.forEachMalformedType(f)) {
+ return false;
+ }
+ for (DartType parameterType in parameterTypes) {
+ if (!parameterType.forEachMalformedType(f)) {
+ return false;
+ }
+ }
+ for (DartType parameterType in optionalParameterTypes) {
+ if (!parameterType.forEachMalformedType(f)) {
+ return false;
+ }
+ }
+ for (DartType parameterType in namedParameterTypes) {
+ if (!parameterType.forEachMalformedType(f)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ DartType unalias(Compiler compiler) => this;
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.add('(');
+ parameterTypes.printOn(sb, ', ');
+ bool first = parameterTypes.isEmpty;
+ if (!optionalParameterTypes.isEmpty) {
+ if (!first) {
+ sb.add(', ');
+ }
+ sb.add('[');
+ optionalParameterTypes.printOn(sb, ', ');
+ sb.add(']');
+ first = false;
+ }
+ if (!namedParameterTypes.isEmpty) {
+ if (!first) {
+ sb.add(', ');
+ }
+ sb.add('{');
+ Link<SourceString> namedParameter = namedParameters;
+ Link<DartType> namedParameterType = namedParameterTypes;
+ first = true;
+ while (!namedParameter.isEmpty && !namedParameterType.isEmpty) {
+ if (!first) {
+ sb.add(', ');
+ }
+ sb.add(namedParameterType.head);
+ sb.add(' ');
+ sb.add(namedParameter.head.slowToString());
+ namedParameter = namedParameter.tail;
+ namedParameterType = namedParameterType.tail;
+ first = false;
+ }
+ sb.add('}');
+ }
+ sb.add(') -> ${returnType}');
+ return sb.toString();
+ }
+
+ SourceString get name => const SourceString('Function');
+
+ int computeArity() {
+ int arity = 0;
+ parameterTypes.forEach((_) { arity++; });
+ return arity;
+ }
+
+ int get hashCode {
+ int hash = 17 * element.hashCode + 3 * returnType.hashCode;
+ for (DartType parameter in parameterTypes) {
+ hash = 17 * hash + 3 * parameter.hashCode;
+ }
+ for (DartType parameter in optionalParameterTypes) {
+ hash = 17 * hash + 3 * parameter.hashCode;
+ }
+ for (SourceString name in namedParameters) {
+ hash = 17 * hash + 3 * name.hashCode;
+ }
+ for (DartType parameter in namedParameterTypes) {
+ hash = 17 * hash + 3 * parameter.hashCode;
+ }
+ return hash;
+ }
+
+ bool operator ==(other) {
+ if (other is !FunctionType) return false;
+ return returnType == other.returnType
+ && parameterTypes == other.parameterTypes
+ && optionalParameterTypes == other.optionalParameterTypes
+ && namedParameters == other.namedParameters
+ && namedParameterTypes == other.namedParameterTypes;
+ }
+}
+
+class TypedefType extends DartType {
+ final TypedefElement element;
+ final Link<DartType> typeArguments;
+ final bool isMalformed;
+
+ TypedefType(this.element,
+ [Link<DartType> typeArguments = const Link<DartType>()])
+ : this.typeArguments = typeArguments,
+ this.isMalformed = hasMalformed(typeArguments);
+
+ TypeKind get kind => TypeKind.TYPEDEF;
+
+ SourceString get name => element.name;
+
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+ if (typeArguments.isEmpty) {
+ // Return fast on non-generic typedefs.
+ return this;
+ }
+ if (parameters.isEmpty) {
+ assert(arguments.isEmpty);
+ // Return fast on empty substitutions.
+ return this;
+ }
+ Link<DartType> newTypeArguments = Types.substTypes(typeArguments, arguments,
+ parameters);
+ if (!identical(typeArguments, newTypeArguments)) {
+ // Create a new type only if necessary.
+ return new TypedefType(element, newTypeArguments);
+ }
+ return this;
+ }
+
+ bool forEachMalformedType(bool f(MalformedType type)) {
+ for (DartType typeArgument in typeArguments) {
+ if (!typeArgument.forEachMalformedType(f)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ DartType unalias(Compiler compiler) {
+ // TODO(ahe): This should be [ensureResolved].
+ compiler.resolveTypedef(element);
+ DartType definition = element.alias.unalias(compiler);
+ TypedefType declaration = element.computeType(compiler);
+ return definition.subst(typeArguments, declaration.typeArguments);
+ }
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.add(name.slowToString());
+ if (!isRaw) {
+ sb.add('<');
+ typeArguments.printOn(sb, ', ');
+ sb.add('>');
+ }
+ return sb.toString();
+ }
+
+ int get hashCode => 17 * element.hashCode;
+
+ bool operator ==(other) {
+ if (other is !TypedefType) return false;
+ if (!identical(element, other.element)) return false;
+ return typeArguments == other.typeArguments;
+ }
+
+ bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
+
+ TypedefType asRaw() => element.rawType;
+}
+
+/**
+ * Special type to hold the [dynamic] type. Used for correctly returning
+ * 'dynamic' on [toString].
+ */
+class DynamicType extends InterfaceType {
+ DynamicType(ClassElement element) : super(element);
+
+ SourceString get name => const SourceString('dynamic');
+}
+
+class Types {
+ final Compiler compiler;
+ // TODO(karlklose): should we have a class Void?
+ final VoidType voidType;
+ final DynamicType dynamicType;
+
+ factory Types(Compiler compiler, ClassElement dynamicElement) {
+ LibraryElement library = new LibraryElementX(new Script(null, null));
+ VoidType voidType = new VoidType(new VoidElementX(library));
+ DynamicType dynamicType = new DynamicType(dynamicElement);
+ dynamicElement.rawType = dynamicElement.thisType = dynamicType;
+ return new Types.internal(compiler, voidType, dynamicType);
+ }
+
+ Types.internal(this.compiler, this.voidType, this.dynamicType);
+
+ /** Returns true if t is a subtype of s */
+ bool isSubtype(DartType t, DartType s) {
+ if (identical(t, s) ||
+ identical(t, dynamicType) ||
+ identical(s, dynamicType) ||
+ t.isMalformed ||
+ s.isMalformed ||
+ identical(s.element, compiler.objectClass) ||
+ identical(t.element, compiler.nullClass)) {
+ return true;
+ }
+ t = t.unalias(compiler);
+ s = s.unalias(compiler);
+
+ if (t is VoidType) {
+ return false;
+ } else if (t is InterfaceType) {
+ if (s is !InterfaceType) return false;
+ ClassElement tc = t.element;
+ if (identical(tc, s.element)) return true;
+ for (Link<DartType> supertypes = tc.allSupertypes;
+ supertypes != null && !supertypes.isEmpty;
+ supertypes = supertypes.tail) {
+ DartType supertype = supertypes.head;
+ if (identical(supertype.element, s.element)) return true;
+ }
+ return false;
+ } else if (t is FunctionType) {
+ if (identical(s.element, compiler.functionClass)) return true;
+ if (s is !FunctionType) return false;
+ FunctionType tf = t;
+ FunctionType sf = s;
+ Link<DartType> tps = tf.parameterTypes;
+ Link<DartType> sps = sf.parameterTypes;
+ while (!tps.isEmpty && !sps.isEmpty) {
+ if (!isAssignable(tps.head, sps.head)) return false;
+ tps = tps.tail;
+ sps = sps.tail;
+ }
+ if (!tps.isEmpty || !sps.isEmpty) return false;
+ if (!isAssignable(sf.returnType, tf.returnType)) return false;
+ if (!sf.namedParameters.isEmpty) {
+ // Since named parameters are globally ordered we can determine the
+ // subset relation with a linear search for [:sf.NamedParameters:]
+ // within [:tf.NamedParameters:].
+ Link<SourceString> tNames = tf.namedParameters;
+ Link<DartType> tTypes = tf.namedParameterTypes;
+ Link<SourceString> sNames = sf.namedParameters;
+ Link<DartType> sTypes = sf.namedParameterTypes;
+ while (!tNames.isEmpty && !sNames.isEmpty) {
+ if (sNames.head == tNames.head) {
+ if (!isAssignable(tTypes.head, sTypes.head)) return false;
+
+ sNames = sNames.tail;
+ sTypes = sTypes.tail;
+ }
+ tNames = tNames.tail;
+ tTypes = tTypes.tail;
+ }
+ if (!sNames.isEmpty) {
+ // We didn't find all names.
+ return false;
+ }
+ }
+ if (!sf.optionalParameterTypes.isEmpty) {
+ Link<DartType> tOptionalParameterType = tf.optionalParameterTypes;
+ Link<DartType> sOptionalParameterType = sf.optionalParameterTypes;
+ while (!tOptionalParameterType.isEmpty &&
+ !sOptionalParameterType.isEmpty) {
+ if (!isAssignable(tOptionalParameterType.head,
+ sOptionalParameterType.head)) {
+ return false;
+ }
+ sOptionalParameterType = sOptionalParameterType.tail;
+ tOptionalParameterType = tOptionalParameterType.tail;
+ }
+ if (!sOptionalParameterType.isEmpty) {
+ // We didn't find enough optional parameters.
+ return false;
+ }
+ }
+ return true;
+ } else if (t is TypeVariableType) {
+ if (s is !TypeVariableType) return false;
+ return (identical(t.element, s.element));
+ } else {
+ throw 'internal error: unknown type kind';
+ }
+ }
+
+ bool isAssignable(DartType r, DartType s) {
+ return isSubtype(r, s) || isSubtype(s, r);
+ }
+
+
+ /**
+ * Helper method for performing substitution of a linked list of types.
+ *
+ * If no types are changed by the substitution, the [types] is returned
+ * instead of a newly created linked list.
+ */
+ static Link<DartType> substTypes(Link<DartType> types,
+ Link<DartType> arguments,
+ Link<DartType> parameters) {
+ bool changed = false;
+ var builder = new LinkBuilder<DartType>();
+ Link<DartType> typeLink = types;
+ while (!typeLink.isEmpty) {
+ var argument = typeLink.head.subst(arguments, parameters);
+ if (!changed && !identical(argument, typeLink.head)) {
+ changed = true;
+ }
+ builder.addLast(argument);
+ typeLink = typeLink.tail;
+ }
+ if (changed) {
+ // Create a new link only if necessary.
+ return builder.toLink();
+ }
+ return types;
+ }
+
+ /**
+ * Combine error messages in a malformed type to a single message string.
+ */
+ static String fetchReasonsFromMalformedType(DartType type) {
+ // TODO(johnniwinther): Figure out how to produce good error message in face
+ // of multiple errors, and how to ensure non-localized error messages.
+ var reasons = new List<String>();
+ type.forEachMalformedType((MalformedType malformedType) {
+ ErroneousElement error = malformedType.element;
+ Message message = error.messageKind.message(error.messageArguments);
+ reasons.add(message.toString());
+ return true;
+ });
+ return Strings.join(reasons, ', ');
+ }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
index f80a616..1d0c2b9 100644
--- a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
@@ -16,10 +16,13 @@
{Node node, Token token, HInstruction instruction,
Element element});
- SourceSpan spanFromSpannable(Node node, [Uri uri]);
+ SourceSpan spanFromSpannable(Spannable node, [Uri uri]);
void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind);
+ // TODO(ahe): Rename to reportError when that method has been removed.
+ void reportErrorCode(Spannable node, MessageKind errorCode, [Map arguments]);
+
/// Returns true if a diagnostic was emitted.
bool onDeprecatedFeature(Spannable span, String feature);
}
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 8d94a9d..81e2fc0 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -24,6 +24,8 @@
Constant,
Compiler;
+import '../dart_types.dart';
+
import '../scanner/scannerlib.dart' show Token,
isUserDefinableOperator,
isMinusOperator;
@@ -444,12 +446,12 @@
abstract class ErroneousElement extends Element implements FunctionElement {
MessageKind get messageKind;
- List get messageArguments;
+ Map get messageArguments;
}
abstract class AmbiguousElement extends Element {
MessageKind get messageKind;
- List get messageArguments;
+ Map get messageArguments;
Element get existingElement;
Element get newElement;
}
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 2d1bf8f..8c43df5 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -26,6 +26,8 @@
Constant,
Compiler;
+import '../dart_types.dart';
+
import '../scanner/scannerlib.dart' show Token, EOF_TOKEN;
@@ -297,7 +299,7 @@
*/
class ErroneousElementX extends ElementX implements ErroneousElement {
final MessageKind messageKind;
- final List messageArguments;
+ final Map messageArguments;
ErroneousElementX(this.messageKind, this.messageArguments,
SourceString name, Element enclosing)
@@ -324,7 +326,7 @@
computeSignature(compiler) => unsupported();
requiredParameterCount(compiler) => unsupported();
optionalParameterCount(compiler) => unsupported();
- parameterCount(copmiler) => unsupported();
+ parameterCount(compiler) => unsupported();
// TODO(kasperl): These seem unnecessary.
set patch(value) => unsupported();
@@ -357,7 +359,7 @@
/**
* The message arguments to report on resolving this element.
*/
- final List messageArguments;
+ final Map messageArguments;
/**
* The first element that this ambiguous element might refer to.
@@ -491,10 +493,7 @@
return;
}
if (!localMembers.isEmpty) {
- listener.reportMessage(
- listener.spanFromSpannable(tag),
- MessageKind.BEFORE_TOP_LEVEL.error(),
- api.Diagnostic.ERROR);
+ listener.reportErrorCode(tag, MessageKind.BEFORE_TOP_LEVEL);
return;
}
if (partTag != null) {
@@ -512,7 +511,8 @@
if (expectedName != actualName) {
listener.reportMessage(
listener.spanFromSpannable(tag.name),
- MessageKind.LIBRARY_NAME_MISMATCH.error([expectedName]),
+ MessageKind.LIBRARY_NAME_MISMATCH.error(
+ {'libraryName': expectedName}),
api.Diagnostic.WARNING);
}
}
@@ -603,7 +603,7 @@
// TODO(johnniwinther): Provide access to the import tags from which
// the elements came.
importScope[element.name] = new AmbiguousElementX(
- MessageKind.DUPLICATE_IMPORT, [element.name],
+ MessageKind.DUPLICATE_IMPORT, {'name': element.name},
this, existing, element);
} else {
importScope[element.name] = element;
@@ -1257,10 +1257,12 @@
Compiler compiler)
: super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
Modifiers.EMPTY, enclosing) {
- type = new FunctionType(
+ type = new FunctionType(this,
compiler.types.voidType,
const Link<DartType>(),
- this);
+ const Link<DartType>(),
+ const Link<SourceString>(),
+ const Link<DartType>());
cachedNode = new FunctionExpression(
new Identifier(enclosing.position()),
new NodeList.empty(),
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index 8a4960a..da8cd44 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -778,7 +778,7 @@
ArrayInitializer(this.length, this.elements);
- factory ArrayInitializer.from(List<Expression> expressions) =>
+ factory ArrayInitializer.from(Iterable<Expression> expressions) =>
new ArrayInitializer(expressions.length, _convert(expressions));
accept(NodeVisitor visitor) => visitor.visitArrayInitializer(this);
@@ -789,9 +789,9 @@
int get precedenceLevel => PRIMARY;
- static List<ArrayElement> _convert(List<Expression> expressions) {
+ static List<ArrayElement> _convert(Iterable<Expression> expressions) {
int index = 0;
- return expressions.mappedBy(
+ return expressions.map(
(expression) => new ArrayElement(index++, expression))
.toList();
}
@@ -896,8 +896,7 @@
}
Fun fun(List<String> parameterNames, Block body) {
- return new Fun(parameterNames.mappedBy((n) => new Parameter(n)).toList(),
- body);
+ return new Fun(parameterNames.map((n) => new Parameter(n)).toList(), body);
}
Assignment assign(Expression leftHandSide, Expression value) {
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index 1cdfbf9..504933d 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -16,6 +16,7 @@
bool pendingSemicolon = false;
bool pendingSpace = false;
static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]');
+ static final expressionContinuationRegExp = new RegExp(r'^[-+([]');
Printer(leg.Compiler compiler, { allowVariableMinification: true })
: shouldCompressOutput = compiler.enableMinification,
@@ -52,8 +53,23 @@
void out(String str) {
if (str != "") {
- if (pendingSemicolon && (!shouldCompressOutput || str != "}")) {
- outBuffer.add(";");
+ if (pendingSemicolon) {
+ if (!shouldCompressOutput) {
+ outBuffer.add(";");
+ } else if (str != "}") {
+ // We want to output newline instead of semicolon because it makes
+ // the raw stack traces much easier to read and it also makes line-
+ // based tools like diff work much better. JavaScript will
+ // automatically insert the semicolon at the newline if it means a
+ // parsing error is avoided, so we can only do this trick if the
+ // next line is not something that can be glued onto a valid
+ // expression to make a new valid expression.
+ if (expressionContinuationRegExp.hasMatch(str)) {
+ outBuffer.add(";");
+ } else {
+ outBuffer.add("\n");
+ }
+ }
}
if (pendingSpace &&
(!shouldCompressOutput || identifierCharacterRegExp.hasMatch(str))) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index a9361fa..f2e4f8f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -84,7 +84,20 @@
* interceptor instance, and the actual receiver of the method.
*/
final Map<int, String> interceptorClosureCache;
+
+ /**
+ * Raw ClassElement symbols occuring in is-checks and type assertions. If the
+ * program contains parameterized checks `x is Set<int>` and
+ * `x is Set<String>` then the ClassElement `Set` will occur once in
+ * [checkedClasses].
+ */
Set<ClassElement> checkedClasses;
+
+ /**
+ * Raw Typedef symbols occuring in is-checks and type assertions. If the
+ * program contains `x is F<int>` and `x is F<bool>` then the TypedefElement
+ * `F` will occur once in [checkedTypedefs].
+ */
Set<TypedefElement> checkedTypedefs;
final bool generateSourceMap;
@@ -880,10 +893,15 @@
void visitField(ClassElement enclosingClass, Element member) {
assert(invariant(classElement, member.isDeclaration));
-
LibraryElement library = member.getLibrary();
SourceString name = member.name;
bool isPrivate = name.isPrivate();
+
+ // Keep track of whether or not we're dealing with a field mixin
+ // into a native class.
+ bool isMixinNativeField =
+ classElement.isNative() && enclosingClass.isMixinApplication;
+
// See if we can dynamically create getters and setters.
// We can only generate getters and setters for [classElement] since
// the fields of super classes could be overwritten with getters or
@@ -893,7 +911,7 @@
// We need to name shadowed fields differently, so they don't clash with
// the non-shadowed field.
bool isShadowed = false;
- if (identical(enclosingClass, classElement)) {
+ if (isMixinNativeField || identical(enclosingClass, classElement)) {
needsGetter = instanceFieldNeedsGetter(member);
needsSetter = instanceFieldNeedsSetter(member);
} else {
@@ -908,7 +926,7 @@
: namer.getName(member);
String fieldName = member.hasFixedBackendName()
? member.fixedBackendName()
- : accessorName;
+ : (isMixinNativeField ? member.name.slowToString() : accessorName);
bool needsCheckedSetter = false;
if (needsSetter && compiler.enableTypeAssertions
&& canGenerateCheckedSetter(member)) {
@@ -1147,12 +1165,26 @@
bool get getterAndSetterCanBeImplementedByFieldSpec => true;
+ int _selectorRank(Selector selector) {
+ int arity = selector.argumentCount * 3;
+ if (selector.isGetter()) return arity + 2;
+ if (selector.isSetter()) return arity + 1;
+ return arity;
+ }
+
+ int _compareSelectorNames(Selector selector1, Selector selector2) {
+ String name1 = selector1.name.toString();
+ String name2 = selector2.name.toString();
+ if (name1 != name2) return Comparable.compare(name1, name2);
+ return _selectorRank(selector1) - _selectorRank(selector2);
+ }
+
void emitInterceptorMethods(ClassBuilder builder) {
JavaScriptBackend backend = compiler.backend;
// Emit forwarders for the ObjectInterceptor class. We need to
// emit all possible sends on intercepted methods.
- for (Selector selector in backend.usedInterceptors) {
-
+ for (Selector selector in
+ backend.usedInterceptors.toList()..sort(_compareSelectorNames)) {
List<js.Parameter> parameters = <js.Parameter>[];
List<js.Expression> arguments = <js.Expression>[];
parameters.add(new js.Parameter('receiver'));
@@ -1181,11 +1213,13 @@
}
Iterable<Element> getTypedefChecksOn(DartType type) {
- return checkedTypedefs.where((TypedefElement typedef) {
+ bool isSubtype(TypedefElement typedef) {
FunctionType typedefType =
typedef.computeType(compiler).unalias(compiler);
return compiler.types.isSubtype(type, typedefType);
- });
+ }
+ return checkedTypedefs.where(isSubtype).toList()
+ ..sort(Elements.compareByPosition);
}
/**
@@ -1815,7 +1849,7 @@
}
List<js.Expression> argNames =
- selector.getOrderedNamedArguments().mappedBy((SourceString name) =>
+ selector.getOrderedNamedArguments().map((SourceString name) =>
js.string(name.slowToString())).toList();
String internalName = namer.invocationMirrorInternalName(selector);
@@ -1836,7 +1870,7 @@
js.string(internalName),
new js.LiteralNumber('$type'),
new js.ArrayInitializer.from(
- parameters.mappedBy((param) => js.use(param.name))
+ parameters.map((param) => js.use(param.name))
.toList()),
new js.ArrayInitializer.from(argNames)])]);
js.Expression function =
@@ -2142,10 +2176,11 @@
// 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) {
- emitGetInterceptorMethod(buffer, objectName, key, classes);
- });
+ var specializedGetInterceptors = backend.specializedGetInterceptors;
+ for (String name in specializedGetInterceptors.keys.toList()..sort()) {
+ Collection<ClassElement> classes = specializedGetInterceptors[name];
+ emitGetInterceptorMethod(buffer, objectName, name, classes);
+ }
}
void computeNeededClasses() {
@@ -2163,9 +2198,27 @@
}
}
+ int _compareSelectors(Selector selector1, Selector selector2) {
+ int comparison = _compareSelectorNames(selector1, selector2);
+ if (comparison != 0) return comparison;
+
+ JavaScriptBackend backend = compiler.backend;
+ Set<ClassElement> classes1 = backend.getInterceptedClassesOn(selector1);
+ Set<ClassElement> classes2 = backend.getInterceptedClassesOn(selector2);
+ if (classes1.length != classes2.length) {
+ return classes1.length - classes2.length;
+ }
+ String getInterceptor1 =
+ namer.getInterceptorName(backend.getInterceptorMethod, classes1);
+ String getInterceptor2 =
+ namer.getInterceptorName(backend.getInterceptorMethod, classes2);
+ return Comparable.compare(getInterceptor1, getInterceptor2);
+ }
+
void emitOneShotInterceptors(CodeBuffer buffer) {
JavaScriptBackend backend = compiler.backend;
- for (Selector selector in backend.oneShotInterceptors) {
+ for (Selector selector in
+ backend.oneShotInterceptors.toList()..sort(_compareSelectors)) {
Set<ClassElement> classes = backend.getInterceptedClassesOn(selector);
String oneShotInterceptorName = namer.oneShotInterceptorName(selector);
String getInterceptorName =
@@ -2265,11 +2318,9 @@
if (generateSourceMap) {
SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
String sourceMap = buildSourceMap(mainBuffer, compiledFile);
- // TODO(podivilov): We should find a better way to return source maps to
- // compiler. Using diagnostic handler for that purpose is a temporary
- // hack.
- compiler.reportDiagnostic(
- null, sourceMap, new api.Diagnostic(-1, 'source map'));
+ compiler.outputProvider('', 'js.map')
+ ..add(sourceMap)
+ ..close();
}
});
return compiler.assembledCode;
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 c4ff47f..06d5d01 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
@@ -80,10 +80,10 @@
new js.VariableDeclaration(mangledName),
new js.Fun(
fieldNames
- .mappedBy((fieldName) => new js.Parameter(fieldName))
+ .map((fieldName) => new js.Parameter(fieldName))
.toList(),
new js.Block(
- fieldNames.mappedBy((fieldName) =>
+ fieldNames.map((fieldName) =>
new js.ExpressionStatement(
new js.Assignment(
new js.This().dot(fieldName),
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 077d897..52e6ee0 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -11,6 +11,7 @@
import '../elements/elements.dart';
import '../elements/modelx.dart' show FunctionElementX;
import '../dart2jslib.dart' hide Selector;
+import '../dart_types.dart';
import '../js/js.dart' as js;
import '../native_handler.dart' as native;
import '../source_file.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
index 07ed2f8..bbe7368 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
@@ -52,17 +52,6 @@
// 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.
@@ -72,7 +61,7 @@
// 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++) {
+ for (var n = 2; n <= 3; n++) {
int h = hash;
while (h > 10) {
var codes = <int>[_letterNumber(h)];
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 6a5067d..e424168 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -25,9 +25,132 @@
];
static const reservedPropertySymbols =
- const <String>["__proto__", "prototype", "constructor"];
+ const <String>["__proto__", "prototype", "constructor", "call"];
- static Set<String> _jsReserved = null;
+ // Symbols that we might be using in our JS snippets.
+ static const reservedGlobalSymbols = const <String>[
+ // Section references are from Ecma-262
+ // (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)
+
+ // 15.1.1 Value Properties of the Global Object
+ "NaN", "Infinity", "undefined",
+
+ // 15.1.2 Function Properties of the Global Object
+ "eval", "parseInt", "parseFloat", "isNaN", "isFinite",
+
+ // 15.1.3 URI Handling Function Properties
+ "decodeURI", "decodeURIComponent",
+ "encodeURI",
+ "encodeURIComponent",
+
+ // 15.1.4 Constructor Properties of the Global Object
+ "Object", "Function", "Array", "String", "Boolean", "Number", "Date",
+ "RegExp", "Error", "EvalError", "RangeError", "ReferenceError",
+ "SyntaxError", "TypeError", "URIError",
+
+ // 15.1.5 Other Properties of the Global Object
+ "Math",
+
+ // 10.1.6 Activation Object
+ "arguments",
+
+ // B.2 Additional Properties (non-normative)
+ "escape", "unescape",
+
+ // Window props (https://developer.mozilla.org/en/DOM/window)
+ "applicationCache", "closed", "Components", "content", "controllers",
+ "crypto", "defaultStatus", "dialogArguments", "directories",
+ "document", "frameElement", "frames", "fullScreen", "globalStorage",
+ "history", "innerHeight", "innerWidth", "length",
+ "location", "locationbar", "localStorage", "menubar",
+ "mozInnerScreenX", "mozInnerScreenY", "mozScreenPixelsPerCssPixel",
+ "name", "navigator", "opener", "outerHeight", "outerWidth",
+ "pageXOffset", "pageYOffset", "parent", "personalbar", "pkcs11",
+ "returnValue", "screen", "scrollbars", "scrollMaxX", "scrollMaxY",
+ "self", "sessionStorage", "sidebar", "status", "statusbar", "toolbar",
+ "top", "window",
+
+ // Window methods (https://developer.mozilla.org/en/DOM/window)
+ "alert", "addEventListener", "atob", "back", "blur", "btoa",
+ "captureEvents", "clearInterval", "clearTimeout", "close", "confirm",
+ "disableExternalCapture", "dispatchEvent", "dump",
+ "enableExternalCapture", "escape", "find", "focus", "forward",
+ "GeckoActiveXObject", "getAttention", "getAttentionWithCycleCount",
+ "getComputedStyle", "getSelection", "home", "maximize", "minimize",
+ "moveBy", "moveTo", "open", "openDialog", "postMessage", "print",
+ "prompt", "QueryInterface", "releaseEvents", "removeEventListener",
+ "resizeBy", "resizeTo", "restore", "routeEvent", "scroll", "scrollBy",
+ "scrollByLines", "scrollByPages", "scrollTo", "setInterval",
+ "setResizeable", "setTimeout", "showModalDialog", "sizeToContent",
+ "stop", "uuescape", "updateCommands", "XPCNativeWrapper",
+ "XPCSafeJSOjbectWrapper",
+
+ // Mozilla Window event handlers, same cite
+ "onabort", "onbeforeunload", "onchange", "onclick", "onclose",
+ "oncontextmenu", "ondragdrop", "onerror", "onfocus", "onhashchange",
+ "onkeydown", "onkeypress", "onkeyup", "onload", "onmousedown",
+ "onmousemove", "onmouseout", "onmouseover", "onmouseup",
+ "onmozorientation", "onpaint", "onreset", "onresize", "onscroll",
+ "onselect", "onsubmit", "onunload",
+
+ // Safari Web Content Guide
+ // http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/SafariWebContent.pdf
+ // WebKit Window member data, from WebKit DOM Reference
+ // (http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/DOMWindow_idl/Classes/DOMWindow/index.html)
+ "ontouchcancel", "ontouchend", "ontouchmove", "ontouchstart",
+ "ongesturestart", "ongesturechange", "ongestureend",
+
+ // extra window methods
+ "uneval",
+
+ // keywords https://developer.mozilla.org/en/New_in_JavaScript_1.7,
+ // https://developer.mozilla.org/en/New_in_JavaScript_1.8.1
+ "getPrototypeOf", "let", "yield",
+
+ // "future reserved words"
+ "abstract", "int", "short", "boolean", "interface", "static", "byte",
+ "long", "char", "final", "native", "synchronized", "float", "package",
+ "throws", "goto", "private", "transient", "implements", "protected",
+ "volatile", "double", "public",
+
+ // IE methods
+ // (http://msdn.microsoft.com/en-us/library/ms535873(VS.85).aspx#)
+ "attachEvent", "clientInformation", "clipboardData", "createPopup",
+ "dialogHeight", "dialogLeft", "dialogTop", "dialogWidth",
+ "onafterprint", "onbeforedeactivate", "onbeforeprint",
+ "oncontrolselect", "ondeactivate", "onhelp", "onresizeend",
+
+ // Common browser-defined identifiers not defined in ECMAScript
+ "event", "external", "Debug", "Enumerator", "Global", "Image",
+ "ActiveXObject", "VBArray", "Components",
+
+ // Functions commonly defined on Object
+ "toString", "getClass", "constructor", "prototype", "valueOf",
+
+ // Client-side JavaScript identifiers
+ "Anchor", "Applet", "Attr", "Canvas", "CanvasGradient",
+ "CanvasPattern", "CanvasRenderingContext2D", "CDATASection",
+ "CharacterData", "Comment", "CSS2Properties", "CSSRule",
+ "CSSStyleSheet", "Document", "DocumentFragment", "DocumentType",
+ "DOMException", "DOMImplementation", "DOMParser", "Element", "Event",
+ "ExternalInterface", "FlashPlayer", "Form", "Frame", "History",
+ "HTMLCollection", "HTMLDocument", "HTMLElement", "IFrame", "Image",
+ "Input", "JSObject", "KeyEvent", "Link", "Location", "MimeType",
+ "MouseEvent", "Navigator", "Node", "NodeList", "Option", "Plugin",
+ "ProcessingInstruction", "Range", "RangeException", "Screen", "Select",
+ "Table", "TableCell", "TableRow", "TableSelection", "Text", "TextArea",
+ "UIEvent", "Window", "XMLHttpRequest", "XMLSerializer",
+ "XPathException", "XPathResult", "XSLTProcessor",
+
+ // These keywords trigger the loading of the java-plugin. For the
+ // next-generation plugin, this results in starting a new Java process.
+ "java", "Packages", "netscape", "sun", "JavaObject", "JavaClass",
+ "JavaArray", "JavaMember"
+ ];
+
+ Set<String> _jsReserved = null;
+ /// Names that cannot be used by members, top level and static
+ /// methods.
Set<String> get jsReserved {
if (_jsReserved == null) {
_jsReserved = new Set<String>();
@@ -37,6 +160,18 @@
return _jsReserved;
}
+ Set<String> _jsVariableReserved = null;
+ /// Names that cannot be used by local variables and parameters.
+ Set<String> get jsVariableReserved {
+ if (_jsVariableReserved == null) {
+ _jsVariableReserved = new Set<String>();
+ _jsVariableReserved.addAll(javaScriptKeywords);
+ _jsVariableReserved.addAll(reservedPropertySymbols);
+ _jsVariableReserved.addAll(reservedGlobalSymbols);
+ }
+ return _jsVariableReserved;
+ }
+
final String CURRENT_ISOLATE = r'$';
/**
@@ -532,14 +667,17 @@
* Returns a name that does not clash with reserved JS keywords,
* and also ensures it won't clash with other identifiers.
*/
- String safeName(String name) {
- if (jsReserved.contains(name) || name.startsWith(r'$')) {
+ String _safeName(String name, Set<String> reserved) {
+ if (reserved.contains(name) || name.startsWith(r'$')) {
name = '\$$name';
}
- assert(!jsReserved.contains(name));
+ assert(!reserved.contains(name));
return name;
}
+ String safeName(String name) => _safeName(name, jsReserved);
+ String safeVariableName(String name) => _safeName(name, jsVariableReserved);
+
String oneShotInterceptorName(Selector selector) {
// TODO(ngeoffray): What to do about typed selectors? We could
// filter them out, or keep them and hope the generated one shot
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 4345861..9400f5f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -161,7 +161,7 @@
compiler.findHelper(const SourceString('convertDartClosureToJS'));
String closureConverter = backend.namer.isolateAccess(converter);
Set<String> stubParameterNames = new Set<String>.from(
- stubParameters.mappedBy((param) => param.name));
+ stubParameters.map((param) => param.name));
parameters.forEachParameter((Element parameter) {
String name = parameter.name.slowToString();
// If [name] is not in [stubParameters], then the parameter is an optional
@@ -255,7 +255,7 @@
js.use('Object').dot('prototype').dot(methodName).dot('call')
.callWith(
<js.Expression>[js.use('this')]..addAll(
- parameters.mappedBy((param) => js.use(param.name))))));
+ parameters.map((param) => js.use(param.name))))));
}
js.Block generateMethodBodyWithPrototypeCheckForElement(
@@ -406,7 +406,7 @@
// [['Node', 'Text|HTMLElement|HTMLDivElement|...'], ...]
js.Expression table =
new js.ArrayInitializer.from(
- preorderDispatchClasses.mappedBy((cls) =>
+ preorderDispatchClasses.map((cls) =>
new js.ArrayInitializer.from([
js.string(toNativeTag(cls)),
tagDefns[cls]])));
diff --git a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
index 625e0ed..75446c7 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
@@ -35,8 +35,7 @@
}
Iterable<V> get values {
- // TODO(floitsch): don't wrap the map twice.
- return keys.mappedBy((String key) => this[key]);
+ return _keys.map((String key) => this[key]);
}
bool get isEmpty => length == 0;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 4297edb..8d68c8d 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -14,13 +14,8 @@
stringJoinUnchecked,
JsStringBuffer;
-// Patch for 'print' function.
patch void print(var object) {
- if (object is String) {
- Primitives.printString(object);
- } else {
- Primitives.printString(object.toString());
- }
+ Primitives.printString(object.toString());
}
// Patch for Object implementation.
@@ -194,25 +189,6 @@
}
return result;
}
-
- /**
- * Creates an extendable list of the given [length] where each entry is
- * filled with [fill].
- */
- patch factory List.filled(int length, E fill) {
- // Explicit type test is necessary to protect Primitives.newGrowableList in
- // unchecked mode.
- if ((length is !int) || (length < 0)) {
- throw new ArgumentError("Length must be a positive integer: $length.");
- }
- List result = Primitives.newGrowableList(length);
- if (length != 0 && fill != null) {
- for (int i = 0; i < result.length; i++) {
- result[i] = fill;
- }
- }
- return result;
- }
}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index 654edc0..3491591 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -84,6 +84,10 @@
return IterableMixinWorkaround.forEach(this, f);
}
+ Iterable map(f(E element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(E element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -97,7 +101,7 @@
return JS('String', "#.join(#)", list, separator);
}
- List<E> take(int n) {
+ Iterable<E> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -105,7 +109,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<E> skip(int n) {
+ Iterable<E> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -222,7 +226,7 @@
bool every(bool f(E element)) => IterableMixinWorkaround.every(this, f);
- List<E> get reversed => new ReversedListView<E>(this, 0, null);
+ List<E> get reversed => IterableMixinWorkaround.reversedList(this);
void sort([int compare(E a, E b)]) {
checkMutable(this, 'sort');
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 1014f04..2c80eaa 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -5,7 +5,6 @@
library _js_helper;
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS,
JS,
JS_CALL_IN_ISOLATE,
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 39c084d..074cece 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -319,12 +319,12 @@
Uri uri = library.entryCompilationUnit.script.uri;
compiler.reportMessage(
compiler.spanFromSpannable(tag.name, uri),
- MessageKind.DUPLICATED_LIBRARY_NAME.error([name]),
+ MessageKind.DUPLICATED_LIBRARY_NAME.error({'libraryName': name}),
api.Diagnostic.WARNING);
Uri existingUri = existing.entryCompilationUnit.script.uri;
compiler.reportMessage(
compiler.spanFromSpannable(existing.libraryTag.name, existingUri),
- MessageKind.DUPLICATED_LIBRARY_NAME.error([name]),
+ MessageKind.DUPLICATED_LIBRARY_NAME.error({'libraryName': name}),
api.Diagnostic.WARNING);
}
}
@@ -374,7 +374,7 @@
if (wasDiagnosticEmitted) {
compiler.reportMessage(
compiler.spanFromElement(unit),
- MessageKind.MISSING_PART_OF_TAG.error([]),
+ MessageKind.MISSING_PART_OF_TAG.error(),
api.Diagnostic.INFO);
}
}
@@ -675,17 +675,17 @@
Element existingElement = exportScope[name];
if (existingElement != null) {
if (existingElement.isErroneous()) {
- compiler.reportMessage(compiler.spanFromElement(element),
- MessageKind.DUPLICATE_EXPORT.error([name]), api.Diagnostic.ERROR);
+ compiler.reportErrorCode(element, MessageKind.DUPLICATE_EXPORT,
+ {'name': name});
element = existingElement;
} else if (existingElement.getLibrary() != library) {
// Declared elements hide exported elements.
- compiler.reportMessage(compiler.spanFromElement(existingElement),
- MessageKind.DUPLICATE_EXPORT.error([name]), api.Diagnostic.ERROR);
- compiler.reportMessage(compiler.spanFromElement(element),
- MessageKind.DUPLICATE_EXPORT.error([name]), api.Diagnostic.ERROR);
+ compiler.reportErrorCode(existingElement, MessageKind.DUPLICATE_EXPORT,
+ {'name': name});
+ compiler.reportErrorCode(element, MessageKind.DUPLICATE_EXPORT,
+ {'name': name});
element = exportScope[name] = new ErroneousElementX(
- MessageKind.DUPLICATE_EXPORT, [name], name, library);
+ MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
}
} else {
exportScope[name] = element;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 8f8689d..ea9b593 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -16,6 +16,7 @@
import '../scanner/scannerlib.dart' hide SourceString;
import '../ssa/ssa.dart';
import '../dart2jslib.dart';
+import '../dart_types.dart';
import '../filenames.dart';
import '../source_file.dart';
import '../tree/tree.dart';
@@ -248,7 +249,7 @@
diagnostics.DiagnosticHandler handler,
Uri libraryRoot, Uri packageRoot,
List<String> options)
- : super(provider, handler, libraryRoot, packageRoot, options) {
+ : super(provider, null, handler, libraryRoot, packageRoot, options) {
checker = new LibraryTypeCheckerTask(this);
resolver = new LibraryResolverTask(this);
}
@@ -389,7 +390,7 @@
} else {
packageUri = libraryUri;
}
- _compiler = new api.Compiler(provider, handler,
+ _compiler = new api.Compiler(provider, null, handler,
libraryUri, packageUri, opts);
var scriptUri = cwd.resolve(script.toString());
// TODO(johnniwinther): Detect file not found
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index ccef7f0..933e96d 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -7,6 +7,7 @@
import 'dart:collection' show Queue;
import 'dart:uri';
import 'dart2jslib.dart' hide SourceString;
+import 'dart_types.dart';
import 'elements/elements.dart';
import 'js_backend/js_backend.dart';
import 'resolution/resolution.dart' show ResolverVisitor;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index a8fa300..bc90813 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -154,8 +154,10 @@
patchParameter.parseNode(compiler).toString();
if (originParameterText != patchParameterText) {
error(originParameter.parseNode(compiler),
- MessageKind.PATCH_PARAMETER_MISMATCH,
- [origin.name, originParameterText, patchParameterText]);
+ MessageKind.PATCH_PARAMETER_MISMATCH,
+ {'methodName': origin.name,
+ 'originParameter': originParameterText,
+ 'patchParameter': patchParameterText});
}
originParameters = originParameters.tail;
@@ -183,8 +185,10 @@
compiler.withCurrentElement(patch, () {
Node errorNode =
patchTree.returnType != null ? patchTree.returnType : patchTree;
- error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, [origin.name,
- originSignature.returnType, patchSignature.returnType]);
+ error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH,
+ {'methodName': origin.name,
+ 'originReturnType': originSignature.returnType,
+ 'patchReturnType': patchSignature.returnType});
});
}
if (originSignature.requiredParameterCount !=
@@ -192,8 +196,9 @@
compiler.withCurrentElement(patch, () {
error(patchTree,
MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
- [origin.name, originSignature.requiredParameterCount,
- patchSignature.requiredParameterCount]);
+ {'methodName': origin.name,
+ 'originParameterCount': originSignature.requiredParameterCount,
+ 'patchParameterCount': patchSignature.requiredParameterCount});
});
} else {
checkMatchingPatchParameters(origin,
@@ -206,8 +211,8 @@
patchSignature.optionalParametersAreNamed) {
compiler.withCurrentElement(patch, () {
error(patchTree,
- MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
- [origin.name]);
+ MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
+ {'methodName': origin.name});
});
}
}
@@ -216,8 +221,9 @@
compiler.withCurrentElement(patch, () {
error(patchTree,
MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
- [origin.name, originSignature.optionalParameterCount,
- patchSignature.optionalParameterCount]);
+ {'methodName': origin.name,
+ 'originParameterCount': originSignature.optionalParameterCount,
+ 'patchParameterCount': patchSignature.optionalParameterCount});
});
} else {
checkMatchingPatchParameters(origin,
@@ -243,6 +249,10 @@
}
return compiler.withCurrentElement(element, () {
FunctionExpression tree = element.parseNode(compiler);
+ if (tree.modifiers.isExternal()) {
+ error(tree, MessageKind.EXTERNAL_WITHOUT_IMPLEMENTATION);
+ return;
+ }
if (isConstructor) {
if (tree.returnType != null) {
error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
@@ -307,7 +317,8 @@
if (!intrface.isInterface()) return;
DartType defaultType = intrface.defaultClass;
if (defaultType == null) {
- error(node, MessageKind.NO_DEFAULT_CLASS, [intrface.name]);
+ error(node, MessageKind.NO_DEFAULT_CLASS,
+ {'interfaceName': intrface.name});
}
ClassElement defaultClass = defaultType.element;
defaultClass.ensureResolved(compiler);
@@ -315,7 +326,7 @@
assert(defaultClass.supertypeLoadState == STATE_DONE);
if (defaultClass.isInterface()) {
error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
- [defaultClass.name]);
+ {'interfaceName': defaultClass.name});
}
// We have now established the following:
// [intrface] is an interface, let's say "MyInterface".
@@ -356,7 +367,7 @@
// the error message below.
error(node,
MessageKind.CANNOT_FIND_CONSTRUCTOR2,
- [selector.name, defaultClass.name]);
+ {'constructorName': selector.name, 'className': defaultClass.name});
}
}
@@ -410,10 +421,8 @@
compiler.withCurrentElement(cls, () => measure(() {
if (cls.supertypeLoadState == STATE_DONE) return;
if (cls.supertypeLoadState == STATE_STARTED) {
- compiler.reportMessage(
- compiler.spanFromSpannable(from),
- MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
+ {'className': cls.name});
cls.supertypeLoadState = STATE_DONE;
cls.allSupertypes = const Link<DartType>().prepend(
compiler.objectClass.computeType(compiler));
@@ -522,11 +531,10 @@
int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
if (illegalFlags != 0) {
Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
- CompilationError error =
- MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS.error(
- [illegalModifiers]);
- compiler.reportMessage(compiler.spanFromSpannable(modifiers),
- error, Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ modifiers,
+ MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
+ {'modifiers': illegalModifiers});
}
// In case of cyclic mixin applications, the mixin chain will have
@@ -537,18 +545,14 @@
// Check that the mixed in class has Object as its superclass.
if (!mixin.superclass.isObject(compiler)) {
- CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPERCLASS.error();
- compiler.reportMessage(compiler.spanFromElement(mixin),
- error, Diagnostic.ERROR);
+ compiler.reportErrorCode(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
}
// Check that the mixed in class doesn't have any constructors and
// make sure we aren't mixing in methods that use 'super'.
mixin.forEachLocalMember((Element member) {
if (member.isGenerativeConstructor() && !member.isSynthesized) {
- CompilationError error = MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR.error();
- compiler.reportMessage(compiler.spanFromElement(member),
- error, Diagnostic.ERROR);
+ compiler.reportErrorCode(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
} else {
// Get the resolution tree and check that the resolved member
// doesn't use 'super'. This is the part of the 'super' mixin
@@ -568,10 +572,9 @@
if (resolutionTree == null) return;
Set<Node> superUses = resolutionTree.superUses;
if (superUses.isEmpty) return;
- CompilationError error = MessageKind.ILLEGAL_MIXIN_WITH_SUPER.error(
- [mixin.name]);
- compiler.reportMessage(compiler.spanFromElement(mixinApplication),
- error, Diagnostic.ERROR);
+ compiler.reportErrorCode(mixinApplication,
+ MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
+ {'className': mixin.name});
// Show the user the problematic uses of 'super' in the mixin.
for (Node use in superUses) {
CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPER_USE.error();
@@ -592,10 +595,8 @@
// Check modifiers.
if (member.isFunction() && member.modifiers.isFinal()) {
- compiler.reportMessage(
- compiler.spanFromElement(member),
- MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
}
if (member.isConstructor()) {
final mismatchedFlagsBits =
@@ -604,11 +605,10 @@
if (mismatchedFlagsBits != 0) {
final mismatchedFlags =
new Modifiers.withFlags(null, mismatchedFlagsBits);
- compiler.reportMessage(
- compiler.spanFromElement(member),
- MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS.error(
- [mismatchedFlags]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ member,
+ MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
+ {'modifiers': mismatchedFlags});
}
checkConstructorNameHack(holder, member);
}
@@ -641,8 +641,8 @@
if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) {
compiler.reportMessage(
compiler.spanFromElement(otherMember),
- MessageKind.GENERIC.error(['This member conflicts with a'
- ' constructor.']),
+ MessageKind.GENERIC.error({'text': 'This member conflicts with a'
+ ' constructor.'}),
Diagnostic.INFO);
}
}
@@ -673,14 +673,14 @@
if (!identical(getterFlags, setterFlags)) {
final mismatchedFlags =
new Modifiers.withFlags(null, getterFlags ^ setterFlags);
- compiler.reportMessage(
- compiler.spanFromElement(field.getter),
- MessageKind.GETTER_MISMATCH.error([mismatchedFlags]),
- Diagnostic.ERROR);
- compiler.reportMessage(
- compiler.spanFromElement(field.setter),
- MessageKind.SETTER_MISMATCH.error([mismatchedFlags]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ field.getter,
+ MessageKind.GETTER_MISMATCH,
+ {'modifiers': mismatchedFlags});
+ compiler.reportErrorCode(
+ field.setter,
+ MessageKind.SETTER_MISMATCH,
+ {'modifiers': mismatchedFlags});
}
}
@@ -729,24 +729,22 @@
errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
}
}
- compiler.reportMessage(
- compiler.spanFromSpannable(errorNode),
- messageKind.error([function.name]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ errorNode, messageKind, {'operatorName': function.name});
}
if (signature.optionalParameterCount != 0) {
Node errorNode =
node.parameters.nodes.skip(signature.requiredParameterCount).head;
if (signature.optionalParametersAreNamed) {
- compiler.reportMessage(
- compiler.spanFromSpannable(errorNode),
- MessageKind.OPERATOR_NAMED_PARAMETERS.error([function.name]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ errorNode,
+ MessageKind.OPERATOR_NAMED_PARAMETERS,
+ {'operatorName': function.name});
} else {
- compiler.reportMessage(
- compiler.spanFromSpannable(errorNode),
- MessageKind.OPERATOR_OPTIONAL_PARAMETERS.error([function.name]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ errorNode,
+ MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
+ {'operatorName': function.name});
}
}
}
@@ -755,11 +753,11 @@
MessageKind errorMessage,
Element contextElement,
MessageKind contextMessage) {
- compiler.reportMessage(
- compiler.spanFromElement(errorneousElement),
- errorMessage.error([contextElement.name,
- contextElement.getEnclosingClass().name]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ errorneousElement,
+ errorMessage,
+ {'memberName': contextElement.name,
+ 'className': contextElement.getEnclosingClass().name});
compiler.reportMessage(
compiler.spanFromElement(contextElement),
contextMessage.error(),
@@ -840,16 +838,35 @@
FunctionType computeFunctionType(Element element,
FunctionSignature signature) {
- LinkBuilder<DartType> parameterTypes = new LinkBuilder<DartType>();
- for (Link<Element> link = signature.requiredParameters;
- !link.isEmpty;
- link = link.tail) {
- parameterTypes.addLast(link.head.computeType(compiler));
- // TODO(karlklose): optional parameters.
+ var parameterTypes = new LinkBuilder<DartType>();
+ for (Element parameter in signature.requiredParameters) {
+ parameterTypes.addLast(parameter.computeType(compiler));
}
- return new FunctionType(signature.returnType,
- parameterTypes.toLink(),
- element);
+ var optionalParameterTypes = const Link<DartType>();
+ var namedParameters = const Link<SourceString>();
+ var namedParameterTypes = const Link<DartType>();
+ if (signature.optionalParametersAreNamed) {
+ var namedParametersBuilder = new LinkBuilder<SourceString>();
+ var namedParameterTypesBuilder = new LinkBuilder<DartType>();
+ for (Element parameter in signature.orderedOptionalParameters) {
+ namedParametersBuilder.addLast(parameter.name);
+ namedParameterTypesBuilder.addLast(parameter.computeType(compiler));
+ }
+ namedParameters = namedParametersBuilder.toLink();
+ namedParameterTypes = namedParameterTypesBuilder.toLink();
+ } else {
+ var optionalParameterTypesBuilder = new LinkBuilder<DartType>();
+ for (Element parameter in signature.optionalParameters) {
+ optionalParameterTypesBuilder.addLast(parameter.computeType(compiler));
+ }
+ optionalParameterTypes = optionalParameterTypesBuilder.toLink();
+ }
+ return new FunctionType(element,
+ signature.returnType,
+ parameterTypes.toLink(),
+ optionalParameterTypes,
+ namedParameters,
+ namedParameterTypes);
}
void resolveMetadataAnnotation(PartialMetadataAnnotation annotation) {
@@ -868,7 +885,7 @@
}));
}
- error(Node node, MessageKind kind, [arguments = const []]) {
+ error(Node node, MessageKind kind, [arguments = const {}]) {
ResolutionError message = new ResolutionError(kind, arguments);
compiler.reportError(node, message);
}
@@ -883,11 +900,11 @@
InitializerResolver(this.visitor)
: initialized = new Map<SourceString, Node>(), hasSuper = false;
- error(Node node, MessageKind kind, [arguments = const []]) {
+ error(Node node, MessageKind kind, [arguments = const {}]) {
visitor.error(node, kind, arguments);
}
- warning(Node node, MessageKind kind, [arguments = const []]) {
+ warning(Node node, MessageKind kind, [arguments = const {}]) {
visitor.warning(node, kind, arguments);
}
@@ -900,8 +917,9 @@
void checkForDuplicateInitializers(SourceString name, Node init) {
if (initialized.containsKey(name)) {
- error(init, MessageKind.DUPLICATE_INITIALIZER, [name]);
- warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]);
+ error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name});
+ warning(initialized[name], MessageKind.ALREADY_INITIALIZED,
+ {'fieldName': name});
}
initialized[name] = init;
}
@@ -915,11 +933,11 @@
if (isFieldInitializer(init)) {
target = constructor.getEnclosingClass().lookupLocalMember(name);
if (target == null) {
- error(selector, MessageKind.CANNOT_RESOLVE, [name]);
+ error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
} else if (target.kind != ElementKind.FIELD) {
- error(selector, MessageKind.NOT_A_FIELD, [name]);
+ error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
} else if (!target.isInstanceMember()) {
- error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
+ error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
}
} else {
error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
@@ -1032,7 +1050,7 @@
MessageKind kind = isImplicitSuperCall
? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
: MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
- error(diagnosticNode, kind, [fullConstructorName]);
+ error(diagnosticNode, kind, {'constructorName': fullConstructorName});
} else {
if (!call.applies(lookedupConstructor, visitor.compiler)) {
MessageKind kind = isImplicitSuperCall
@@ -1131,12 +1149,12 @@
/** Convenience method for visiting nodes that may be null. */
R visit(Node node) => (node == null) ? null : node.accept(this);
- void error(Node node, MessageKind kind, [arguments = const []]) {
+ void error(Node node, MessageKind kind, [Map arguments = const {}]) {
ResolutionError message = new ResolutionError(kind, arguments);
compiler.reportError(node, message);
}
- void warning(Node node, MessageKind kind, [arguments = const []]) {
+ void warning(Node node, MessageKind kind, [Map arguments = const {}]) {
ResolutionWarning message = new ResolutionWarning(kind, arguments);
compiler.reportWarning(node, message);
}
@@ -1296,7 +1314,7 @@
TypeAnnotation node,
Scope scope,
Element enclosingElement,
- {onFailure(Node node, MessageKind kind, [List arguments]),
+ {onFailure(Node node, MessageKind kind, [Map arguments]),
whenResolved(Node node, DartType type)}) {
if (onFailure == null) {
onFailure = (n, k, [arguments]) {};
@@ -1329,7 +1347,7 @@
DartType type;
DartType reportFailureAndCreateType(MessageKind messageKind,
- List messageArguments) {
+ Map messageArguments) {
onFailure(node, messageKind, messageArguments);
var erroneousElement = new ErroneousElementX(
messageKind, messageArguments, typeName.source, enclosingElement);
@@ -1348,7 +1366,7 @@
if (hashTypeArgumentMismatch) {
type = new MalformedType(
new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- [node], typeName.source, enclosingElement),
+ {'type': node}, typeName.source, enclosingElement),
type, arguments.toLink());
}
return type;
@@ -1356,14 +1374,14 @@
if (element == null) {
type = reportFailureAndCreateType(
- MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]);
+ MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
} else if (element.isAmbiguous()) {
AmbiguousElement ambiguous = element;
type = reportFailureAndCreateType(
ambiguous.messageKind, ambiguous.messageArguments);
} else if (!element.impliesType()) {
type = reportFailureAndCreateType(
- MessageKind.NOT_A_TYPE, [node.typeName]);
+ MessageKind.NOT_A_TYPE, {'node': node.typeName});
} else {
if (identical(element, compiler.types.voidType.element) ||
identical(element, compiler.types.dynamicType.element)) {
@@ -1379,7 +1397,7 @@
if (hashTypeArgumentMismatch) {
type = new MalformedType(
new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- [node], typeName.source, enclosingElement),
+ {'type': node}, typeName.source, enclosingElement),
new InterfaceType(cls.declaration, arguments.toLink()));
} else {
if (arguments.isEmpty) {
@@ -1399,7 +1417,7 @@
if (hashTypeArgumentMismatch) {
type = new MalformedType(
new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
- [node], typeName.source, enclosingElement),
+ {'type': node}, typeName.source, enclosingElement),
new TypedefType(typdef, arguments.toLink()));
} else {
if (arguments.isEmpty) {
@@ -1412,11 +1430,12 @@
if (enclosingElement.isInStaticMember()) {
compiler.reportWarning(node,
MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
- [node]));
+ {'typeVariableName': node}));
type = new MalformedType(
new ErroneousElementX(
MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
- [node], typeName.source, enclosingElement),
+ {'typeVariableName': node},
+ typeName.source, enclosingElement),
element.computeType(compiler));
} else {
type = element.computeType(compiler);
@@ -1516,20 +1535,18 @@
Element result = scope.lookup(name);
if (!Elements.isUnresolved(result)) {
if (!inInstanceContext && result.isInstanceMember()) {
- compiler.reportMessage(compiler.spanFromSpannable(node),
- MessageKind.NO_INSTANCE_AVAILABLE.error([name]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
- [name],
- name, enclosingElement);
+ {'name': name},
+ name, enclosingElement);
} else if (result.isAmbiguous()) {
AmbiguousElement ambiguous = result;
- compiler.reportMessage(compiler.spanFromSpannable(node),
- ambiguous.messageKind.error(ambiguous.messageArguments),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ node, ambiguous.messageKind, ambiguous.messageArguments);
return new ErroneousElementX(ambiguous.messageKind,
- ambiguous.messageArguments,
- name, enclosingElement);
+ ambiguous.messageArguments,
+ name, enclosingElement);
}
}
return result;
@@ -1570,7 +1587,7 @@
ErroneousElement warnAndCreateErroneousElement(Node node,
SourceString name,
MessageKind kind,
- List<Node> arguments) {
+ [Map arguments = const {}]) {
ResolutionWarning warning = new ResolutionWarning(kind, arguments);
compiler.reportWarning(node, warning);
return new ErroneousElementX(kind, arguments, name, enclosingElement);
@@ -1579,7 +1596,7 @@
Element visitIdentifier(Identifier node) {
if (node.isThis()) {
if (!inInstanceContext) {
- error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
+ error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
}
return null;
} else if (node.isSuper()) {
@@ -1594,14 +1611,15 @@
if (!inInstanceContext) {
element = warnAndCreateErroneousElement(node, node.source,
MessageKind.CANNOT_RESOLVE,
- [node]);
+ {'name': node});
}
} else if (element.isErroneous()) {
// Use the erroneous element.
} else {
if ((element.kind.category & allowedCategory) == 0) {
// TODO(ahe): Improve error message. Need UX input.
- error(node, MessageKind.GENERIC, ["is not an expression $element"]);
+ error(node, MessageKind.GENERIC,
+ {'text': "is not an expression $element"});
}
}
if (!Elements.isUnresolved(element)
@@ -1631,7 +1649,7 @@
if (doAddToScope) {
Element existing = scope.add(element);
if (existing != element) {
- error(node, MessageKind.DUPLICATE_DEFINITION, [node]);
+ error(node, MessageKind.DUPLICATE_DEFINITION, {'name': node});
}
}
return element;
@@ -1829,11 +1847,11 @@
if (selector.argumentCount != 1) {
error(node.selector,
MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
- [selector.argumentCount]);
+ {'argumentCount': selector.argumentCount});
} else if (selector.namedArgumentCount != 0) {
error(node.selector,
MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
- [selector.namedArgumentCount]);
+ {'argumentCount': selector.namedArgumentCount});
}
return compiler.assertMethod;
}
@@ -1849,23 +1867,25 @@
Element target;
SourceString name = node.selector.asIdentifier().source;
if (identical(name.stringValue, 'this')) {
- error(node.selector, MessageKind.GENERIC, ["expected an identifier"]);
+ error(node.selector, MessageKind.GENERIC,
+ {'text': "expected an identifier"});
} else if (node.isSuperCall) {
if (node.isOperator) {
if (isUserDefinableOperator(name.stringValue)) {
name = selector.name;
} else {
- error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, [name]);
+ error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name});
}
}
if (!inInstanceContext) {
- error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]);
+ error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
return null;
}
if (currentClass.supertype == null) {
// This is just to guard against internal errors, so no need
// for a real error message.
- error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]);
+ error(node.receiver, MessageKind.GENERIC,
+ {'text': "Object has no superclass"});
}
// TODO(johnniwinther): Ensure correct behavior if currentClass is a
// patch.
@@ -1897,9 +1917,12 @@
// setters.
return warnAndCreateErroneousElement(node, name,
MessageKind.METHOD_NOT_FOUND,
- [receiverClass.name, name]);
+ {'className': receiverClass.name,
+ 'methodName': name});
} else if (target.isInstanceMember()) {
- error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]);
+ error(node, MessageKind.MEMBER_NOT_STATIC,
+ {'className': receiverClass.name,
+ 'memberName': name});
}
} else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) {
PrefixElement prefix = resolvedReceiver;
@@ -1907,7 +1930,7 @@
if (Elements.isUnresolved(target)) {
return warnAndCreateErroneousElement(
node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER,
- [prefix.name, name]);
+ {'libraryName': prefix.name, 'memberName': name});
} else if (target.kind == ElementKind.CLASS) {
ClassElement classElement = target;
classElement.ensureResolved(compiler);
@@ -1999,7 +2022,7 @@
SourceString source = namedArgument.name.source;
if (seenNamedArguments.contains(source)) {
error(argument, MessageKind.DUPLICATE_DEFINITION,
- [source.slowToString()]);
+ {'name': source});
}
seenNamedArguments.add(source);
} else if (!seenNamedArguments.isEmpty) {
@@ -2017,8 +2040,7 @@
if (target == null && !inInstanceContext) {
target =
warnAndCreateErroneousElement(node.selector, field.name,
- MessageKind.CANNOT_RESOLVE_GETTER,
- [node.selector]);
+ MessageKind.CANNOT_RESOLVE_GETTER);
}
}
@@ -2091,7 +2113,7 @@
// TODO(karlklose): we can be more precise about the reason of the
// mismatch.
warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS,
- [target.name]);
+ {'methodName': target.name});
}
/// Callback for native enqueuer to parse a type. Returns [:null:] on error.
@@ -2118,14 +2140,12 @@
if (setter == null && !inInstanceContext) {
setter =
warnAndCreateErroneousElement(node.selector, field.name,
- MessageKind.CANNOT_RESOLVE_SETTER,
- [node.selector]);
+ MessageKind.CANNOT_RESOLVE_SETTER);
}
if (isComplex && getter == null && !inInstanceContext) {
getter =
warnAndCreateErroneousElement(node.selector, field.name,
- MessageKind.CANNOT_RESOLVE_GETTER,
- [node.selector]);
+ MessageKind.CANNOT_RESOLVE_GETTER);
}
}
@@ -2238,14 +2258,10 @@
void handleRedirectingFactoryBody(Return node) {
if (!enclosingElement.isFactoryConstructor()) {
- compiler.reportMessage(
- compiler.spanFromSpannable(node),
- MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY.error([]),
- Diagnostic.ERROR);
- compiler.reportMessage(
- compiler.spanFromSpannable(enclosingElement),
- MessageKind.MISSING_FACTORY_KEYWORD.error([]),
- Diagnostic.INFO);
+ compiler.reportErrorCode(
+ node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
+ compiler.reportErrorCode(
+ enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
}
Element redirectionTarget = resolveRedirectingFactory(node);
var type = mapping.getType(node.expression);
@@ -2420,11 +2436,11 @@
if (arguments != null) {
Link<Node> nodes = arguments.nodes;
if (nodes.isEmpty) {
- error(arguments, MessageKind.MISSING_TYPE_ARGUMENT, []);
+ error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
} else {
resolveTypeRequired(nodes.head);
for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
- error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT, []);
+ error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
resolveTypeRequired(nodes.head);
}
}
@@ -2459,12 +2475,12 @@
String labelName = node.target.source.slowToString();
LabelElement label = statementScope.lookupLabel(labelName);
if (label == null) {
- error(node.target, MessageKind.UNBOUND_LABEL, [labelName]);
+ error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
return;
}
target = label.target;
if (!target.statement.isValidBreakTarget()) {
- error(node.target, MessageKind.INVALID_BREAK, [labelName]);
+ error(node.target, MessageKind.INVALID_BREAK);
return;
}
label.setBreakTarget();
@@ -2492,12 +2508,12 @@
String labelName = node.target.source.slowToString();
LabelElement label = statementScope.lookupLabel(labelName);
if (label == null) {
- error(node.target, MessageKind.UNBOUND_LABEL, [labelName]);
+ error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
return;
}
target = label.target;
if (!target.statement.isValidContinueTarget()) {
- error(node.target, MessageKind.INVALID_CONTINUE, [labelName]);
+ error(node.target, MessageKind.INVALID_CONTINUE);
}
// TODO(lrn): Handle continues to switch cases.
if (target.statement is SwitchCase) {
@@ -2540,7 +2556,7 @@
{
// The variable declaration is either not an identifier, not a
// declaration, or it's declaring more than one variable.
- error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []);
+ error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN);
}
}
@@ -2565,7 +2581,8 @@
if (element.isTarget) {
mapping[element.label] = element;
} else {
- warning(element.label, MessageKind.UNUSED_LABEL, [labelName]);
+ warning(element.label, MessageKind.UNUSED_LABEL,
+ {'labelName': labelName});
}
});
if (!targetElement.isTarget && identical(mapping[body], targetElement)) {
@@ -2603,15 +2620,17 @@
LabelElement existingElement = continueLabels[labelName];
if (existingElement != null) {
// It's an error if the same label occurs twice in the same switch.
- warning(label, MessageKind.DUPLICATE_LABEL, [labelName]);
- error(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]);
+ warning(label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
+ error(existingElement.label, MessageKind.EXISTING_LABEL,
+ {'labelName': labelName});
} else {
// It's only a warning if it shadows another label.
existingElement = statementScope.lookupLabel(labelName);
if (existingElement != null) {
- warning(label, MessageKind.DUPLICATE_LABEL, [labelName]);
+ warning(label, MessageKind.DUPLICATE_LABEL,
+ {'labelName': labelName});
warning(existingElement.label,
- MessageKind.EXISTING_LABEL, [labelName]);
+ MessageKind.EXISTING_LABEL, {'labelName': labelName});
}
}
@@ -2750,7 +2769,8 @@
SourceString typeName = typeVariable.name;
TypeVariable typeNode = nodeLink.head;
if (nameSet.contains(typeName)) {
- error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
+ error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
+ {'typeVariableName': typeName});
}
nameSet.add(typeName);
@@ -2762,7 +2782,7 @@
// TODO(johnniwinther): Check for more general cycles, like
// [: <A extends B, B extends C, C extends B> :].
warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
- [variableElement.name]);
+ {'typeVariableName': variableElement.name});
} else if (boundType != null) {
variableElement.bound = boundType;
} else {
@@ -2942,10 +2962,9 @@
while (current != null && current.isMixinApplication) {
MixinApplicationElement currentMixinApplication = current;
if (currentMixinApplication == mixinApplication) {
- CompilationError error = MessageKind.ILLEGAL_MIXIN_CYCLE.error(
- [current.name, previous.name]);
- compiler.reportMessage(compiler.spanFromElement(mixinApplication),
- error, Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ mixinApplication, MessageKind.ILLEGAL_MIXIN_CYCLE,
+ {'mixinName1': current.name, 'mixinName2': previous.name});
// We have found a cycle in the mixin chain. Return null as
// the mixin for this application to avoid getting into
// infinite recursion when traversing members.
@@ -2967,10 +2986,10 @@
DartType visitIdentifier(Identifier node) {
Element element = scope.lookup(node.source);
if (element == null) {
- error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
+ error(node, MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node});
return null;
} else if (!element.impliesType() && !element.isTypeVariable()) {
- error(node, MessageKind.NOT_A_TYPE, [node]);
+ error(node, MessageKind.NOT_A_TYPE, {'node': node});
return null;
} else {
if (element.isTypeVariable()) {
@@ -2990,19 +3009,20 @@
DartType visitSend(Send node) {
Identifier prefix = node.receiver.asIdentifier();
if (prefix == null) {
- error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+ error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
return null;
}
Element element = scope.lookup(prefix.source);
if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
- error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+ error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
return null;
}
PrefixElement prefixElement = element;
Identifier selector = node.selector.asIdentifier();
var e = prefixElement.lookupLocalMember(selector.source);
if (e == null || !e.impliesType()) {
- error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
+ error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
+ {'typeName': node.selector});
return null;
}
return e.computeType(compiler);
@@ -3017,10 +3037,10 @@
return null;
} else if (!identical(supertype.kind, TypeKind.INTERFACE)) {
// TODO(johnniwinther): Handle dynamic.
- error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED, []);
+ error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED);
return null;
} else if (isBlackListed(supertype)) {
- error(superclass, MessageKind.CANNOT_EXTEND, [supertype]);
+ error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype});
return null;
}
}
@@ -3039,27 +3059,28 @@
} else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) {
// TODO(johnniwinther): Handle dynamic.
TypeAnnotation typeAnnotation = link.head;
- error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED, []);
+ error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
} else {
if (interfaceType == element.supertype) {
- compiler.reportMessage(
- compiler.spanFromSpannable(superclass),
- MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error([interfaceType]),
- Diagnostic.ERROR);
- compiler.reportMessage(
- compiler.spanFromSpannable(link.head),
- MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error([interfaceType]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ superclass,
+ MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+ {'type': interfaceType});
+ compiler.reportErrorCode(
+ link.head,
+ MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+ {'type': interfaceType});
}
if (result.contains(interfaceType)) {
- compiler.reportMessage(
- compiler.spanFromSpannable(link.head),
- MessageKind.DUPLICATE_IMPLEMENTS.error([interfaceType]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(
+ link.head,
+ MessageKind.DUPLICATE_IMPLEMENTS,
+ {'type': interfaceType});
}
result = result.prepend(interfaceType);
if (isBlackListed(interfaceType)) {
- error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]);
+ error(link.head, MessageKind.CANNOT_IMPLEMENT,
+ {'type': interfaceType});
}
}
}
@@ -3167,17 +3188,14 @@
void visitIdentifier(Identifier node) {
Element element = context.lookup(node.source);
if (element == null) {
- error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
+ error(node, MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node});
} else if (!element.impliesType()) {
- error(node, MessageKind.NOT_A_TYPE, [node]);
+ error(node, MessageKind.NOT_A_TYPE, {'node': node});
} else {
if (element.isClass()) {
loadSupertype(element, node);
} else {
- compiler.reportMessage(
- compiler.spanFromSpannable(node),
- MessageKind.CLASS_NAME_EXPECTED.error([]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(node, MessageKind.CLASS_NAME_EXPECTED);
}
}
}
@@ -3185,19 +3203,20 @@
void visitSend(Send node) {
Identifier prefix = node.receiver.asIdentifier();
if (prefix == null) {
- error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+ error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
return;
}
Element element = context.lookup(prefix.source);
if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
- error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+ error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
return;
}
PrefixElement prefixElement = element;
Identifier selector = node.selector.asIdentifier();
var e = prefixElement.lookupLocalMember(selector.source);
if (e == null || !e.impliesType()) {
- error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
+ error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
+ {'typeName': node.selector});
return;
}
loadSupertype(e, node);
@@ -3321,16 +3340,18 @@
FieldParameterElement element;
if (node.receiver.asIdentifier() == null ||
!node.receiver.asIdentifier().isThis()) {
- error(node, MessageKind.INVALID_PARAMETER, []);
- } else if (!identical(enclosingElement.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
- error(node, MessageKind.FIELD_PARAMETER_NOT_ALLOWED, []);
+ error(node, MessageKind.INVALID_PARAMETER);
+ } else if (!identical(enclosingElement.kind,
+ ElementKind.GENERATIVE_CONSTRUCTOR)) {
+ error(node, MessageKind.FIELD_PARAMETER_NOT_ALLOWED);
} else {
SourceString name = getParameterName(node);
Element fieldElement = currentClass.lookupLocalMember(name);
- if (fieldElement == null || !identical(fieldElement.kind, ElementKind.FIELD)) {
- error(node, MessageKind.NOT_A_FIELD, [name]);
+ if (fieldElement == null ||
+ !identical(fieldElement.kind, ElementKind.FIELD)) {
+ error(node, MessageKind.NOT_A_FIELD, {'fieldName': name});
} else if (!fieldElement.isInstanceMember()) {
- error(node, MessageKind.NOT_INSTANCE_FIELD, [name]);
+ error(node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name});
}
Element variables = new VariableListElementX.node(currentDefinitions,
ElementKind.VARIABLE_LIST, enclosingElement);
@@ -3390,9 +3411,7 @@
int requiredParameterCount = 0;
if (formalParameters == null) {
if (!element.isGetter()) {
- compiler.reportMessage(compiler.spanFromElement(element),
- MessageKind.MISSING_FORMALS.error([]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(element, MessageKind.MISSING_FORMALS);
}
} else {
if (element.isGetter()) {
@@ -3402,9 +3421,8 @@
if (compiler.rejectDeprecatedFeatures &&
// TODO(ahe): Remove isPlatformLibrary check.
!element.getLibrary().isPlatformLibrary) {
- compiler.reportMessage(compiler.spanFromSpannable(formalParameters),
- MessageKind.EXTRA_FORMALS.error([]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(formalParameters,
+ MessageKind.EXTRA_FORMALS);
} else {
compiler.onDeprecatedFeature(formalParameters, 'getter parameters');
}
@@ -3420,16 +3438,13 @@
visitor.optionalParameterCount != 0)) {
// If there are no formal parameters, we already reported an error above.
if (formalParameters != null) {
- compiler.reportMessage(compiler.spanFromSpannable(formalParameters),
- MessageKind.ILLEGAL_SETTER_FORMALS.error([]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(formalParameters,
+ MessageKind.ILLEGAL_SETTER_FORMALS);
}
}
if (element.isGetter() && (requiredParameterCount != 0
|| visitor.optionalParameterCount != 0)) {
- compiler.reportMessage(compiler.spanFromSpannable(formalParameters),
- MessageKind.EXTRA_FORMALS.error([]),
- Diagnostic.ERROR);
+ compiler.reportErrorCode(formalParameters, MessageKind.EXTRA_FORMALS);
}
return new FunctionSignatureX(parameters,
visitor.optionalParameters,
@@ -3466,7 +3481,7 @@
failOrReturnErroneousElement(Element enclosing, Node diagnosticNode,
SourceString targetName, MessageKind kind,
- List arguments) {
+ Map arguments) {
if (inConstContext) {
error(diagnosticNode, kind, arguments);
} else {
@@ -3502,7 +3517,7 @@
diagnosticNode,
new SourceString(fullConstructorName),
MessageKind.CANNOT_FIND_CONSTRUCTOR,
- [fullConstructorName]);
+ {'constructorName': fullConstructorName});
} else if (inConstContext && !result.modifiers.isConst()) {
error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
}
@@ -3530,7 +3545,8 @@
// TODO(ahe): Remove this check and error message when we
// don't have interfaces anymore.
error(diagnosticNode,
- MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
+ MessageKind.CANNOT_INSTANTIATE_INTERFACE,
+ {'interfaceName': cls.name});
}
// The unnamed constructor may not exist, so [e] may become unresolved.
e = lookupConstructor(cls, diagnosticNode, const SourceString(''));
@@ -3562,8 +3578,9 @@
ClassElement cls = e;
cls.ensureResolved(compiler);
if (cls.isInterface() && (cls.defaultClass == null)) {
- error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
- [cls.name]);
+ error(node.receiver,
+ MessageKind.CANNOT_INSTANTIATE_INTERFACE,
+ {'interfaceName': cls.name});
}
return lookupConstructor(cls, name, name.source);
} else if (identical(e.kind, ElementKind.PREFIX)) {
@@ -3573,9 +3590,9 @@
return failOrReturnErroneousElement(resolver.enclosingElement, name,
name.source,
MessageKind.CANNOT_RESOLVE,
- [name]);
+ {'name': name});
} else if (!identical(e.kind, ElementKind.CLASS)) {
- error(node, MessageKind.NOT_A_TYPE, [name]);
+ error(node, MessageKind.NOT_A_TYPE, {'node': name});
}
} else {
internalError(node.receiver, 'unexpected element $e');
@@ -3589,16 +3606,19 @@
// TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
if (e == null) {
return failOrReturnErroneousElement(resolver.enclosingElement, node, name,
- MessageKind.CANNOT_RESOLVE, [name]);
+ MessageKind.CANNOT_RESOLVE,
+ {'name': name});
} else if (e.isErroneous()) {
return e;
} else if (identical(e.kind, ElementKind.TYPEDEF)) {
- error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]);
+ error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
+ {'typedefName': name});
} else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) {
- error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]);
+ error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
+ {'typeVariableName': name});
} else if (!identical(e.kind, ElementKind.CLASS)
&& !identical(e.kind, ElementKind.PREFIX)) {
- error(node, MessageKind.NOT_A_TYPE, [name]);
+ error(node, MessageKind.NOT_A_TYPE, {'node': name});
}
return e;
}
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index 2f6ce5d..130486c 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -7,6 +7,7 @@
import 'dart:collection' show Queue, LinkedHashMap;
import '../dart2jslib.dart' hide Diagnostic;
+import '../dart_types.dart';
import '../../compiler.dart' show Diagnostic;
import '../tree/tree.dart';
import '../elements/elements.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index b74cc82..289c2c8 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -1919,12 +1919,6 @@
FunctionExpression parseNode(DiagnosticListener listener) {
if (cachedNode != null) return cachedNode;
- if (patch == null) {
- if (modifiers.isExternal()) {
- listener.cancel("External method without an implementation",
- element: this);
- }
- }
parseFunction(Parser p) {
if (isMember() && modifiers.isFactory()) {
p.parseFactoryMethod(beginToken);
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index ae56ccf..1c27852 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -29,7 +29,7 @@
bool isWindows = (Platform.operatingSystem == 'windows');
Uri cwd = getCurrentDirectory();
Map<String, SourceFile> sourceFiles = <String, SourceFile>{};
- int dartBytesRead = 0;
+ int dartCharactersRead = 0;
Future<String> readStringFromUri(Uri resourceUri) {
if (resourceUri.scheme != 'file') {
@@ -42,7 +42,7 @@
throw 'Error: Cannot read "${relativize(cwd, resourceUri, isWindows)}" '
'(${ex.osError}).';
}
- dartBytesRead += source.length;
+ dartCharactersRead += source.length;
sourceFiles[resourceUri.toString()] =
new SourceFile(relativize(cwd, resourceUri, isWindows), source);
return new Future.immediate(source);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index 162fac5..ddf6bab 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -393,10 +393,27 @@
*/
class SsaBailoutPropagator extends HBaseVisitor {
final Compiler compiler;
+ /**
+ * A list to propagate bailout information to blocks that start a
+ * guarded or labeled list of statements. Currently, these blocks
+ * are:
+ * - first block of a then branch,
+ * - first block of an else branch,
+ * - a loop header,
+ * - labeled block.
+ */
final List<HBasicBlock> blocks;
- final List<HLabeledBlockInformation> labeledBlockInformations;
- final Set<HInstruction> generateAtUseSite;
+
+ /**
+ * The current subgraph we are visiting.
+ */
SubGraph subGraph;
+
+ /**
+ * The current block information we are visiting.
+ */
+ HBlockInformation currentBlockInformation;
+
/**
* Max number of arguments to the bailout (not counting the state).
*/
@@ -434,11 +451,8 @@
* version.
*/
- SsaBailoutPropagator(this.compiler,
- this.generateAtUseSite,
- this.variableNames)
+ SsaBailoutPropagator(this.compiler, this.variableNames)
: blocks = <HBasicBlock>[],
- labeledBlockInformations = <HLabeledBlockInformation>[],
bailoutArity = 0,
parameterNames = new Map<String, int>();
@@ -451,18 +465,63 @@
}
}
+ /**
+ * Returns true if we can visit the given [blockFlow]. False
+ * otherwise. Currently, try/catch and switch are not in bailout
+ * methods, so this method only deals with loops and labeled blocks.
+ * If [blockFlow] is a labeled block or a loop, we also visit the
+ * continuation of the block flow.
+ */
+ bool handleBlockFlow(HBlockFlow blockFlow) {
+ HBlockInformation body = blockFlow.body;
+
+ // We reach here again when starting to visit a subgraph. Just
+ // return to visiting the block.
+ if (currentBlockInformation == body) return false;
+
+ HBlockInformation oldInformation = currentBlockInformation;
+ if (body is HLabeledBlockInformation) {
+ currentBlockInformation = body;
+ HLabeledBlockInformation info = body;
+ visitStatements(info.body, newFlow: true);
+ } else if (body is HLoopBlockInformation) {
+ currentBlockInformation = body;
+ HLoopBlockInformation info = body;
+ if (info.initializer != null) {
+ visitExpression(info.initializer);
+ }
+ blocks.addLast(info.loopHeader);
+ if (!info.isDoWhile()) {
+ visitExpression(info.condition);
+ }
+ visitStatements(info.body, newFlow: false);
+ if (info.isDoWhile()) {
+ visitExpression(info.condition);
+ }
+ if (info.updates != null) {
+ visitExpression(info.updates);
+ }
+ blocks.removeLast();
+ } else {
+ assert(body is! HTryBlockInformation);
+ assert(body is! HSwitchBlockInformation);
+ // [HIfBlockInformation] is handled by visitIf.
+ return false;
+ }
+
+ currentBlockInformation = oldInformation;
+ if (blockFlow.continuation != null) {
+ visitBasicBlock(blockFlow.continuation);
+ }
+ return true;
+ }
+
void visitBasicBlock(HBasicBlock block) {
// Abort traversal if we are leaving the currently active sub-graph.
if (!subGraph.contains(block)) return;
- if (block.isLoopHeader()) {
- blocks.addLast(block);
- } else if (block.isLabeledBlock()
- && (blocks.isEmpty || !identical(blocks.last, block))) {
- HLabeledBlockInformation info = block.blockFlow.body;
- visitStatements(info.body);
- return;
- }
+ HBlockFlow blockFlow = block.blockFlow;
+ if (blockFlow != null && handleBlockFlow(blockFlow)) return;
HInstruction instruction = block.first;
while (instruction != null) {
@@ -471,35 +530,34 @@
}
}
- void visitStatements(HStatementInformation info) {
- assert(info is HSubGraphBlockInformation);
- HSubGraphBlockInformation graph = info;
- visitSubGraph(graph.subGraph);
+ void visitExpression(HSubExpressionBlockInformation info) {
+ visitSubGraph(info.subExpression);
+ }
+
+ /**
+ * Visit the statements in [info]. If [newFlow] is true, we add the
+ * first block of [statements] to the list of [blocks].
+ */
+ void visitStatements(HSubGraphBlockInformation info, {bool newFlow}) {
+ SubGraph graph = info.subGraph;
+ if (newFlow) blocks.addLast(graph.start);
+ visitSubGraph(graph);
+ if (newFlow) blocks.removeLast();
}
void visitSubGraph(SubGraph graph) {
SubGraph oldSubGraph = subGraph;
subGraph = graph;
- HBasicBlock start = graph.start;
- blocks.addLast(start);
- visitBasicBlock(start);
- blocks.removeLast();
+ visitBasicBlock(graph.start);
subGraph = oldSubGraph;
-
- if (start.isLabeledBlock()) {
- HBasicBlock continuation = start.blockFlow.continuation;
- if (continuation != null) {
- visitBasicBlock(continuation);
- }
- }
}
void visitIf(HIf instruction) {
int preVisitedBlocks = 0;
HIfBlockInformation info = instruction.blockInformation.body;
- visitStatements(info.thenGraph);
+ visitStatements(info.thenGraph, newFlow: true);
preVisitedBlocks++;
- visitStatements(info.elseGraph);
+ visitStatements(info.elseGraph, newFlow: true);
preVisitedBlocks++;
HBasicBlock joinBlock = instruction.joinBlock;
@@ -532,24 +590,9 @@
}
void visitLoopBranch(HLoopBranch branch) {
- HBasicBlock branchBlock = branch.block;
- List<HBasicBlock> dominated = branchBlock.dominatedBlocks;
// For a do-while loop, the body has already been visited.
if (!branch.isDoWhile()) {
- visitBasicBlock(dominated[0]);
- }
- blocks.removeLast();
-
- // If the branch does not dominate the code after the loop, the
- // dominator will visit it.
- if (!identical(branchBlock.successors[1].dominator, branchBlock)) return;
-
- visitBasicBlock(branchBlock.successors[1]);
- // With labeled breaks we can have more dominated blocks.
- if (dominated.length >= 3) {
- for (int i = 2; i < dominated.length; i++) {
- visitBasicBlock(dominated[i]);
- }
+ visitBasicBlock(branch.block.dominatedBlocks[0]);
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 8150846..67085fd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -136,14 +136,19 @@
/**
* The values of locals that can be directly accessed (without redirections
* to boxes or closure-fields).
+ *
+ * [directLocals] is iterated, so it is a [LinkedHashMap] to make the
+ * iteration order a function only of insertions and not a function of
+ * e.g. Element hash codes. I'd prefer to use a SortedMap but some elements
+ * don't have source locations for [Elements.compareByPosition].
*/
- Map<Element, HInstruction> directLocals;
+ LinkedHashMap<Element, HInstruction> directLocals;
Map<Element, Element> redirectionMapping;
SsaBuilder builder;
ClosureClassMap closureData;
LocalsHandler(this.builder)
- : directLocals = new Map<Element, HInstruction>(),
+ : directLocals = new LinkedHashMap<Element, HInstruction>(),
redirectionMapping = new Map<Element, Element>();
get typesTask => builder.compiler.typesTask;
@@ -154,7 +159,8 @@
* throughout the AST visit.
*/
LocalsHandler.from(LocalsHandler other)
- : directLocals = new Map<Element, HInstruction>.from(other.directLocals),
+ : directLocals =
+ new LinkedHashMap<Element, HInstruction>.from(other.directLocals),
redirectionMapping = other.redirectionMapping,
builder = other.builder,
closureData = other.closureData;
@@ -524,10 +530,9 @@
}
void beginLoopHeader(Node node, HBasicBlock loopEntry) {
- // Create a copy because we modify the map while iterating over
- // it.
+ // Create a copy because we modify the map while iterating over it.
Map<Element, HInstruction> saved =
- new Map<Element, HInstruction>.from(directLocals);
+ new LinkedHashMap<Element, HInstruction>.from(directLocals);
// Create phis for all elements in the definitions environment.
saved.forEach((Element element, HInstruction instruction) {
@@ -590,7 +595,8 @@
// block. Since variable declarations are scoped the declared
// variable cannot be alive outside the block. Note: this is only
// true for nodes where we do joins.
- Map<Element, HInstruction> joinedLocals = new Map<Element, HInstruction>();
+ Map<Element, HInstruction> joinedLocals =
+ new LinkedHashMap<Element, HInstruction>();
otherLocals.directLocals.forEach((element, instruction) {
// We know 'this' cannot be modified.
if (identical(element, closureData.thisElement)) {
@@ -622,7 +628,8 @@
HBasicBlock joinBlock) {
assert(locals.length > 0);
if (locals.length == 1) return locals[0];
- Map<Element, HInstruction> joinedLocals = new Map<Element,HInstruction>();
+ Map<Element, HInstruction> joinedLocals =
+ new LinkedHashMap<Element,HInstruction>();
HInstruction thisValue = null;
directLocals.forEach((Element element, HInstruction instruction) {
if (!identical(element, closureData.thisElement)) {
@@ -819,10 +826,9 @@
// block is closed.
HBasicBlock lastOpenedBlock;
- List<Element> sourceElementStack;
+ final List<Element> sourceElementStack;
- LibraryElement get currentLibrary => work.element.getLibrary();
- Element get currentElement => work.element;
+ Element get currentElement => sourceElementStack.last.declaration;
Compiler get compiler => builder.compiler;
CodeEmitterTask get emitter => builder.emitter;
@@ -980,7 +986,8 @@
*/
InliningState enterInlinedMethod(PartialFunctionElement function,
Selector selector,
- Link<Node> arguments) {
+ Link<Node> arguments,
+ Node currentNode) {
assert(invariant(function, function.isImplementation));
// Once we start to compile the arguments we must be sure that we don't
@@ -992,11 +999,36 @@
compiledArguments);
assert(succeeded);
+ FunctionSignature signature = function.computeSignature(compiler);
+ int index = 0;
+ signature.orderedForEachParameter((Element parameter) {
+ HInstruction argument = compiledArguments[index++];
+ localsHandler.updateLocal(parameter, argument);
+ potentiallyCheckType(argument, parameter.computeType(compiler));
+ });
+
+ if (function.isConstructor()) {
+ ClassElement enclosing = function.getEnclosingClass();
+ if (compiler.world.needsRti(enclosing)) {
+ assert(currentNode is NewExpression);
+ InterfaceType type = elements.getType(currentNode);
+ Link<DartType> typeVariable = enclosing.typeVariables;
+ type.typeArguments.forEach((DartType argument) {
+ HInstruction instruction =
+ analyzeTypeArgument(argument, currentNode);
+ localsHandler.updateLocal(typeVariable.head.element, instruction);
+ typeVariable = typeVariable.tail;
+ });
+ while (!typeVariable.isEmpty) {
+ localsHandler.updateLocal(typeVariable.head.element,
+ graph.addConstantNull(constantSystem));
+ typeVariable = typeVariable.tail;
+ }
+ }
+ }
InliningState state =
new InliningState(function, returnElement, returnType, elements, stack);
- inliningStack.add(state);
- sourceElementStack.add(function);
- stack = <HInstruction>[];
+
// TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
returnElement = new ElementX(const SourceString("result"),
ElementKind.VARIABLE,
@@ -1005,22 +1037,15 @@
graph.addConstantNull(constantSystem));
elements = compiler.enqueuer.resolution.getCachedElements(function);
assert(elements != null);
- FunctionSignature signature = function.computeSignature(compiler);
returnType = signature.returnType;
- int index = 0;
- signature.orderedForEachParameter((Element parameter) {
- HInstruction argument = compiledArguments[index++];
- localsHandler.updateLocal(parameter, argument);
- potentiallyCheckType(argument, parameter.computeType(compiler));
- });
+ stack = <HInstruction>[];
+ inliningStack.add(state);
return state;
}
void leaveInlinedMethod(InliningState state) {
InliningState poppedState = inliningStack.removeLast();
assert(state == poppedState);
- FunctionElement poppedElement = sourceElementStack.removeLast();
- assert(poppedElement == poppedState.function);
elements = state.oldElements;
stack.add(localsHandler.readLocal(returnElement));
returnElement = state.oldReturnElement;
@@ -1031,11 +1056,13 @@
}
/**
- * Documentation wanted -- johnniwinther
+ * Try to inline [element] within the currect context of the
+ * builder. The insertion point is the state of the builder.
*/
bool tryInlineMethod(Element element,
Selector selector,
- Link<Node> arguments) {
+ Link<Node> arguments,
+ Node currentNode) {
if (compiler.disableInlining) return false;
// Ensure that [element] is an implementation element.
element = element.implementation;
@@ -1045,11 +1072,14 @@
// containing nodes.
// [PartialFunctionElement]s are [FunctionElement]s that have [Node]s.
if (element is !PartialFunctionElement) return false;
+ // TODO(ngeoffray): try to inline generative constructors. They
+ // don't have any body, which make it more difficult.
+ if (element.isGenerativeConstructor()) return false;
if (inliningStack.length > MAX_INLINING_DEPTH) return false;
// Don't inline recursive calls. We use the same elements for the inlined
// functions and would thus clobber our local variables.
// Use [:element.declaration:] since [work.element] is always a declaration.
- if (work.element == element.declaration) return false;
+ if (currentElement == element.declaration) return false;
for (int i = 0; i < inliningStack.length; i++) {
if (inliningStack[i].function == element) return false;
}
@@ -1068,8 +1098,11 @@
return false;
}
- InliningState state = enterInlinedMethod(function, selector, arguments);
- functionExpression.body.accept(this);
+ InliningState state = enterInlinedMethod(
+ function, selector, arguments, currentNode);
+ inlinedFrom(element, () {
+ functionExpression.body.accept(this);
+ });
leaveInlinedMethod(state);
return true;
}
@@ -1143,9 +1176,15 @@
ClosureClassMap oldClosureData = localsHandler.closureData;
Node node = constructor.parseNode(compiler);
- localsHandler.closureData =
+ ClosureClassMap newClosureData =
compiler.closureToClassMapper.computeClosureToClassMapping(
constructor, node, elements);
+ // The [:this:] element now refers to the one in the new closure
+ // data, that is the [:this:] of the super constructor. We
+ // update the element to refer to the current [:this:].
+ localsHandler.updateLocal(newClosureData.thisElement,
+ localsHandler.readThis());
+ localsHandler.closureData = newClosureData;
params.orderedForEachParameter((Element parameterElement) {
if (elements.isParameterChecked(parameterElement)) {
@@ -1341,7 +1380,6 @@
List bodyCallInputs = <HInstruction>[];
bodyCallInputs.add(newObject);
FunctionSignature functionSignature = body.computeSignature(compiler);
- int arity = functionSignature.parameterCount;
functionSignature.orderedForEachParameter((parameter) {
if (!localsHandler.isBoxed(parameter)) {
// The parameter will be a field in the box passed as the
@@ -1381,7 +1419,8 @@
// these selectors. Maybe the resolver can do more of the work
// for us here?
LibraryElement library = body.getLibrary();
- Selector selector = new Selector.call(name, library, arity);
+ Selector selector = new Selector.call(
+ name, library, bodyCallInputs.length - 1);
HInvokeDynamic invoke =
new HInvokeDynamicMethod(selector, bodyCallInputs);
invoke.element = body;
@@ -1620,7 +1659,9 @@
SourceFileLocation location = new SourceFileLocation(sourceFile, token);
if (!location.isValid()) {
throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
- [token.charOffset, sourceFile.filename, sourceFile.text.length]);
+ {'offset': token.charOffset,
+ 'fileName': sourceFile.filename,
+ 'length': sourceFile.text.length});
}
return location;
}
@@ -2040,7 +2081,7 @@
endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler);
if (!isAbortingBody || hasContinues) {
loopEntryBlock.postProcessLoopHeader();
- SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
+ SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock);
HLoopBlockInformation loopBlockInfo =
new HLoopBlockInformation(
HLoopBlockInformation.DO_WHILE_LOOP,
@@ -2345,7 +2386,7 @@
} else {
if (element.isGetter()) {
Selector selector = elements.getSelector(send);
- if (tryInlineMethod(element, selector, const Link<Node>())) {
+ if (tryInlineMethod(element, selector, const Link<Node>(), send)) {
return;
}
}
@@ -2749,7 +2790,7 @@
Element element = elements[node];
bool isClosureCall = false;
if (element != null && compiler.world.hasNoOverridingMember(element)) {
- if (tryInlineMethod(element, selector, node.arguments)) {
+ if (tryInlineMethod(element, selector, node.arguments, node)) {
if (element.isGetter()) {
// If the element is a getter, we are doing a closure call
// on what this getter returns.
@@ -3008,7 +3049,7 @@
Selector selector = elements.getSelector(node);
SourceString name = selector.name;
- ClassElement cls = work.element.getEnclosingClass();
+ ClassElement cls = currentElement.getEnclosingClass();
Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
if (element.enclosingElement.declaration != compiler.objectClass) {
// Register the call as dynamic if [:noSuchMethod:] on the super class
@@ -3064,7 +3105,7 @@
visitSend(Send node) {
Element element = elements[node];
- if (element != null && identical(element, work.element)) {
+ if (element != null && identical(element, currentElement)) {
graph.isRecursiveMethod = true;
}
super.visitSend(node);
@@ -3125,7 +3166,7 @@
* Helper to create an instruction that gets the value of a type variable.
*/
void addTypeVariableReference(TypeVariableType type) {
- Element member = work.element;
+ Element member = currentElement;
if (member.enclosingElement.isClosure()) {
ClosureClassElement closureClass = member.enclosingElement;
member = closureClass.methodElement;
@@ -3248,11 +3289,17 @@
generateAbstractClassInstantiationError(node, cls.name.slowToString());
return;
}
- if (compiler.world.needsRti(constructor.enclosingElement)) {
- if (!type.isRaw) {
- type.typeArguments.forEach((DartType argument) {
- inputs.add(analyzeTypeArgument(argument, node));
- });
+ if (compiler.world.needsRti(cls)) {
+ Link<DartType> typeVariable = cls.typeVariables;
+ type.typeArguments.forEach((DartType argument) {
+ inputs.add(analyzeTypeArgument(argument, node));
+ typeVariable = typeVariable.tail;
+ });
+ // Also add null to non-provided type variables to call the
+ // constructor with the right number of arguments.
+ while (!typeVariable.isEmpty) {
+ inputs.add(graph.addConstantNull(constantSystem));
+ typeVariable = typeVariable.tail;
}
}
@@ -3292,7 +3339,7 @@
bool isIdenticalFunction = element == compiler.identicalFunction;
if (!isIdenticalFunction
- && tryInlineMethod(element, selector, node.arguments)) {
+ && tryInlineMethod(element, selector, node.arguments, node)) {
return;
}
@@ -3319,7 +3366,7 @@
// useful.
HType returnType =
builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange(
- work.element, element);
+ currentElement, element);
if (returnType != null) instruction.guaranteedType = returnType;
pushWithPosition(instruction, node);
} else {
@@ -3487,7 +3534,12 @@
} else {
// TODO(karlklose): move this type registration to the codegen.
compiler.codegenWorld.instantiatedTypes.add(type);
- visitNewSend(node.send, type);
+ Send send = node.send;
+ Element constructor = elements[send];
+ Selector selector = elements.getSelector(send);
+ if (!tryInlineMethod(constructor, selector, send.arguments, node)) {
+ visitNewSend(send, type);
+ }
}
}
}
@@ -3849,7 +3901,7 @@
void buildInitializer() {
SourceString iteratorName = const SourceString("iterator");
Selector selector =
- new Selector.getter(iteratorName, work.element.getLibrary());
+ new Selector.getter(iteratorName, currentElement.getLibrary());
Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
visit(node.expression);
HInstruction receiver = pop();
@@ -3870,14 +3922,15 @@
}
HInstruction buildCondition() {
SourceString name = const SourceString('moveNext');
- Selector selector = new Selector.call(name, work.element.getLibrary(), 0);
+ Selector selector = new Selector.call(
+ name, currentElement.getLibrary(), 0);
bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator]));
return popBoolified();
}
void buildBody() {
SourceString name = const SourceString('current');
- Selector call = new Selector.getter(name, work.element.getLibrary());
+ Selector call = new Selector.getter(name, currentElement.getLibrary());
bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call);
push(new HInvokeDynamicGetter(call, null, iterator, hasGetter));
@@ -4381,8 +4434,9 @@
open(startCatchBlock);
// TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
// Note that the name of this element is irrelevant.
- Element element = new ElementX(
- const SourceString('exception'), ElementKind.PARAMETER, work.element);
+ Element element = new ElementX(const SourceString('exception'),
+ ElementKind.PARAMETER,
+ currentElement);
exception = new HLocalValue(element);
add(exception);
HInstruction oldRethrowableException = rethrowableException;
@@ -4678,8 +4732,10 @@
if (seenReturn) tooDifficult = true;
}
- void visitReturn(Node node) {
- if (seenReturn || identical(node.getBeginToken().stringValue, 'native')) {
+ void visitReturn(Return node) {
+ if (seenReturn
+ || identical(node.getBeginToken().stringValue, 'native')
+ || node.isRedirectingFactoryBody) {
tooDifficult = true;
return;
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 3f0a0b6..eeaad2a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -337,10 +337,6 @@
beginGraph(HGraph graph);
endGraph(HGraph graph);
- beginLoop(HBasicBlock block);
- endLoop(HBasicBlock block);
- handleLoopCondition(HLoopBranch node);
-
preLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
startLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
endLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
@@ -959,11 +955,7 @@
assignPhisOfSuccessors(avoidEdge);
bool hasPhiUpdates = !updateBody.statements.isEmpty;
currentContainer = body;
- if (hasPhiUpdates || !isConditionExpression || info.updates != null) {
- wrapLoopBodyForContinue(info);
- } else {
- visitBodyIgnoreLabels(info);
- }
+ visitBodyIgnoreLabels(info);
if (info.updates != null) {
generateStatements(info.updates);
}
@@ -1125,15 +1117,9 @@
currentBlock = node;
// If this node has block-structure based information attached,
// try using that to traverse from here.
- if (node.blockFlow != null &&
- handleBlockFlow(node.blockFlow)) {
+ if (node.blockFlow != null && handleBlockFlow(node.blockFlow)) {
return;
}
- // Flow based traversal.
- if (node.isLoopHeader() &&
- !identical(node.loopInformation.loopBlockInformation, currentBlockInformation)) {
- beginLoop(node);
- }
iterateBasicBlock(node);
}
@@ -1228,7 +1214,7 @@
if (handler == null) return;
// Map the instructions to strings.
- Iterable<Copy> copies = handler.copies.mappedBy((Copy copy) {
+ Iterable<Copy> copies = handler.copies.map((Copy copy) {
return new Copy(variableNames.getName(copy.source),
variableNames.getName(copy.destination));
});
@@ -1363,6 +1349,18 @@
visitBasicBlock(dominated[0]);
}
+ visitLoopBranch(HLoopBranch node) {
+ assert(node.block == subGraph.end);
+ // We are generating code for a loop condition.
+ // If we are generating the subgraph as an expression, the
+ // condition will be generated as the expression.
+ // Otherwise, we don't generate the expression, and leave that
+ // to the code that called [visitSubGraph].
+ if (isGeneratingExpression) {
+ use(node.inputs[0]);
+ }
+ }
+
/**
* Checks if [map] contains an [ElementAction] for [element], and
* if so calls that action and returns true.
@@ -1833,43 +1831,6 @@
world.registerInstantiatedClass(type.element);
}
- visitLoopBranch(HLoopBranch node) {
- if (subGraph != null && identical(node.block, subGraph.end)) {
- // We are generating code for a loop condition.
- // If doing this as part of a SubGraph traversal, the
- // calling code will handle the control flow logic.
-
- // If we are generating the subgraph as an expression, the
- // condition will be generated as the expression.
- // Otherwise, we don't generate the expression, and leave that
- // to the code that called [visitSubGraph].
- if (isGeneratingExpression) {
- use(node.inputs[0]);
- }
- return;
- }
- HBasicBlock branchBlock = currentBlock;
- handleLoopCondition(node);
- List<HBasicBlock> dominated = currentBlock.dominatedBlocks;
- if (!node.isDoWhile()) {
- // For a do while loop, the body has already been visited.
- visitBasicBlock(dominated[0]);
- }
- endLoop(node.block);
-
- // If the branch does not dominate the code after the loop, the
- // dominator will visit it.
- if (!identical(branchBlock.successors[1].dominator, branchBlock)) return;
-
- visitBasicBlock(branchBlock.successors[1]);
- // With labeled breaks we can have more dominated blocks.
- if (dominated.length >= 3) {
- for (int i = 2; i < dominated.length; i++) {
- visitBasicBlock(dominated[i]);
- }
- }
- }
-
visitNot(HNot node) {
assert(node.inputs.length == 1);
generateNot(node.inputs[0]);
@@ -2538,7 +2499,7 @@
// of the control flow (controlled by the state argument passed
// above). We need to pass it to get later arguments in the right
// position.
- arguments.add(new js.LiteralNull());
+ arguments.add(new js.LiteralNumber('0'));
}
use(parameter);
arguments.add(pop());
@@ -2655,33 +2616,6 @@
// Do nothing. Bailout targets are only used in the non-optimized version.
}
- void beginLoop(HBasicBlock block) {
- oldContainerStack.add(currentContainer);
- currentContainer = new js.Block.empty();
- }
-
- void endLoop(HBasicBlock block) {
- js.Statement body = currentContainer;
- currentContainer = oldContainerStack.removeLast();
- body = unwrapStatement(body);
- js.While loop = new js.While(newLiteralBool(true), body);
-
- HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader;
- HLoopInformation info = header.loopInformation;
- attachLocationRange(loop,
- info.loopBlockInformation.sourcePosition,
- info.loopBlockInformation.endSourcePosition);
- pushStatement(wrapIntoLabels(loop, info.labels));
- }
-
- void handleLoopCondition(HLoopBranch node) {
- use(node.inputs[0]);
- js.Expression test = new js.Prefix('!', pop());
- js.Statement then = new js.Break(null);
- pushStatement(new js.If.noElse(test, then), node);
- }
-
-
void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
}
@@ -2735,8 +2669,7 @@
=> new js.VariableUse(variableNames.stateName);
HBasicBlock beginGraph(HGraph graph) {
- propagator =
- new SsaBailoutPropagator(compiler, generateAtUseSite, variableNames);
+ propagator = new SsaBailoutPropagator(compiler, variableNames);
propagator.visitGraph(graph);
// TODO(ngeoffray): We could avoid generating the state at the
// call site for non-complex bailout methods.
@@ -2795,6 +2728,22 @@
bool visitAndOrInfo(HAndOrBlockInformation info) => false;
+ visitLoopBranch(HLoopBranch node) {
+ if (node.computeLoopHeader().hasBailoutTargets()) {
+ // The graph visitor in [visitLoopInfo] does not handle the
+ // condition. We must instead manually emit it here.
+ handleLoopCondition(node);
+ // We must also visit the body from here.
+ // For a do while loop, the body has already been visited.
+ if (!node.isDoWhile()) {
+ visitBasicBlock(node.block.dominatedBlocks[0]);
+ }
+ } else {
+ super.visitLoopBranch(node);
+ }
+ }
+
+
bool visitIfInfo(HIfBlockInformation info) {
if (info.thenGraph.start.hasBailoutTargets()) return false;
if (info.elseGraph.start.hasBailoutTargets()) return false;
@@ -2802,8 +2751,27 @@
}
bool visitLoopInfo(HLoopBlockInformation info) {
- if (info.start.hasBailoutTargets()) return false;
- if (info.loopHeader.hasBailoutTargets()) return false;
+ // Always emit with block flow traversal.
+ if (info.loopHeader.hasBailoutTargets()) {
+ // If there are any bailout targets in the loop, we cannot use
+ // the pretty [SsaCodeGenerator.visitLoopInfo] printer.
+ if (info.initializer != null) {
+ generateStatements(info.initializer);
+ }
+ beginLoop(info.loopHeader);
+ if (!info.isDoWhile()) {
+ generateStatements(info.condition);
+ }
+ generateStatements(info.body);
+ if (info.isDoWhile()) {
+ generateStatements(info.condition);
+ }
+ if (info.updates != null) {
+ generateStatements(info.updates);
+ }
+ endLoop(info.end);
+ return true;
+ }
return super.visitLoopInfo(info);
}
@@ -2843,14 +2811,14 @@
// undefined for the trailing arguments.
node.padding = new List<int>(node.inputs.length);
int j = 0;
- int pendingNulls = 0;
+ int pendingUnusedArguments = 0;
for (int i = 0; i < newInputs.length; i++) {
HInstruction input = newInputs[i];
if (input == null) {
- pendingNulls++;
+ pendingUnusedArguments++;
} else {
- node.padding[j] = pendingNulls;
- pendingNulls = 0;
+ node.padding[j] = pendingUnusedArguments;
+ pendingUnusedArguments = 0;
node.updateInput(j, input);
j++;
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 99329fd..2876e06 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1857,6 +1857,23 @@
bool isDoWhile() {
return identical(kind, DO_WHILE_LOOP);
}
+
+ HBasicBlock computeLoopHeader() {
+ HBasicBlock result;
+ if (isDoWhile()) {
+ // In case of a do/while, the successor is a block that avoids
+ // a critical edge and branchs to the loop header.
+ result = block.successors[0].successors[0];
+ } else {
+ // For other loops, the loop header might be up the dominator
+ // tree if the loop condition has control flow.
+ result = block;
+ while (!result.isLoopHeader()) result = result.dominator;
+ }
+
+ assert(result.isLoopHeader());
+ return result;
+ }
}
class HConstant extends HInstruction {
@@ -2589,7 +2606,10 @@
this.target,
this.labels,
this.sourcePosition,
- this.endSourcePosition);
+ this.endSourcePosition) {
+ assert(
+ (kind == DO_WHILE_LOOP ? body.start : condition.start).isLoopHeader());
+ }
HBasicBlock get start {
if (initializer != null) return initializer.start;
@@ -2615,6 +2635,8 @@
return node.accept(const LoopTypeVisitor());
}
+ bool isDoWhile() => kind == DO_WHILE_LOOP;
+
bool accept(HStatementInformationVisitor visitor) =>
visitor.visitLoopInfo(this);
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index ed1f6cf..c51395f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -1529,6 +1529,7 @@
HOneShotInterceptor interceptor = new HOneShotInterceptor(
user.selector, inputs, node.interceptedClasses);
interceptor.sourcePosition = user.sourcePosition;
+ interceptor.sourceElement = user.sourceElement;
HBasicBlock block = user.block;
block.addAfter(user, interceptor);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index f1e0c71..13de8b6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -9,6 +9,7 @@
import '../closure.dart';
import '../js/js.dart' as js;
import '../dart2jslib.dart' hide Selector;
+import '../dart_types.dart';
import '../source_file.dart';
import '../source_map_builder.dart';
import '../elements/elements.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
index 1f545d3..34f960d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
@@ -473,9 +473,9 @@
String allocateWithHint(String originalName) {
int i = 0;
JavaScriptBackend backend = compiler.backend;
- String name = backend.namer.safeName(originalName);
+ String name = backend.namer.safeVariableName(originalName);
while (usedNames.contains(name)) {
- name = backend.namer.safeName('$originalName${i++}');
+ name = backend.namer.safeVariableName('$originalName${i++}');
}
return name;
}
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index c826241..ed5ac45 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -26,677 +26,6 @@
}
}
-class TypeKind {
- final String id;
-
- const TypeKind(String this.id);
-
- static const TypeKind FUNCTION = const TypeKind('function');
- static const TypeKind INTERFACE = const TypeKind('interface');
- static const TypeKind STATEMENT = const TypeKind('statement');
- static const TypeKind TYPEDEF = const TypeKind('typedef');
- static const TypeKind TYPE_VARIABLE = const TypeKind('type variable');
- static const TypeKind MALFORMED_TYPE = const TypeKind('malformed');
- static const TypeKind VOID = const TypeKind('void');
-
- String toString() => id;
-}
-
-abstract class DartType {
- SourceString get name;
-
- TypeKind get kind;
-
- const DartType();
-
- /**
- * Returns the [Element] which declared this type.
- *
- * This can be [ClassElement] for classes, [TypedefElement] for typedefs,
- * [TypeVariableElement] for type variables and [FunctionElement] for
- * function types.
- *
- * Invariant: [element] must be a declaration element.
- */
- Element get element;
-
- /**
- * Performs the substitution [: [arguments[i]/parameters[i]]this :].
- *
- * The notation is known from this lambda calculus rule:
- *
- * (lambda x.e0)e1 -> [e1/x]e0.
- *
- * See [TypeVariableType] for a motivation for this method.
- *
- * Invariant: There must be the same number of [arguments] and [parameters].
- */
- DartType subst(Link<DartType> arguments, Link<DartType> parameters);
-
- /**
- * Returns the unaliased type of this type.
- *
- * The unaliased type of a typedef'd type is the unaliased type to which its
- * name is bound. The unaliased version of any other type is the type itself.
- *
- * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the
- * function type [: (B) -> A :] and the unaliased type of
- * [: Func<int,String> :] is the function type [: (String) -> int :].
- */
- DartType unalias(Compiler compiler);
-
- /**
- * A type is malformed if it is itself a malformed type or contains a
- * malformed type.
- */
- bool get isMalformed => false;
-
- /**
- * Calls [f] with each [MalformedType] within this type.
- *
- * If [f] returns [: false :], the traversal stops prematurely.
- *
- * [forEachMalformedType] returns [: false :] if the traversal was stopped
- * prematurely.
- */
- bool forEachMalformedType(bool f(MalformedType type)) => true;
-
- bool operator ==(other);
-
- /**
- * Is [: true :] if this type has no explict type arguments.
- */
- bool get isRaw => true;
-
- DartType asRaw() => this;
-}
-
-/**
- * Represents a type variable, that is the type parameters of a class type.
- *
- * For example, in [: class Array<E> { ... } :], E is a type variable.
- *
- * Each class should have its own unique type variables, one for each type
- * parameter. A class with type parameters is said to be parameterized or
- * generic.
- *
- * Non-static members, constructors, and factories of generic
- * class/interface can refer to type variables of the current class
- * (not of supertypes).
- *
- * When using a generic type, also known as an application or
- * instantiation of the type, the actual type arguments should be
- * substituted for the type variables in the class declaration.
- *
- * For example, given a box, [: class Box<T> { T value; } :], the
- * type of the expression [: new Box<String>().value :] is
- * [: String :] because we must substitute [: String :] for the
- * the type variable [: T :].
- */
-class TypeVariableType extends DartType {
- final TypeVariableElement element;
-
- TypeVariableType(this.element);
-
- TypeKind get kind => TypeKind.TYPE_VARIABLE;
-
- SourceString get name => element.name;
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- if (parameters.isEmpty) {
- assert(arguments.isEmpty);
- // Return fast on empty substitutions.
- return this;
- }
- Link<DartType> parameterLink = parameters;
- Link<DartType> argumentLink = arguments;
- while (!argumentLink.isEmpty && !parameterLink.isEmpty) {
- TypeVariableType parameter = parameterLink.head;
- DartType argument = argumentLink.head;
- if (parameter == this) {
- assert(argumentLink.tail.isEmpty == parameterLink.tail.isEmpty);
- return argument;
- }
- parameterLink = parameterLink.tail;
- argumentLink = argumentLink.tail;
- }
- assert(argumentLink.isEmpty && parameterLink.isEmpty);
- // The type variable was not substituted.
- return this;
- }
-
- DartType unalias(Compiler compiler) => this;
-
- int get hashCode => 17 * element.hashCode;
-
- bool operator ==(other) {
- if (other is !TypeVariableType) return false;
- return identical(other.element, element);
- }
-
- String toString() => name.slowToString();
-}
-
-/**
- * A statement type tracks whether a statement returns or may return.
- */
-class StatementType extends DartType {
- final String stringName;
-
- Element get element => null;
-
- TypeKind get kind => TypeKind.STATEMENT;
-
- SourceString get name => new SourceString(stringName);
-
- const StatementType(this.stringName);
-
- static const RETURNING = const StatementType('<returning>');
- static const NOT_RETURNING = const StatementType('<not returning>');
- static const MAYBE_RETURNING = const StatementType('<maybe returning>');
-
- /** Combine the information about two control-flow edges that are joined. */
- StatementType join(StatementType other) {
- return (identical(this, other)) ? this : MAYBE_RETURNING;
- }
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- // Statement types are not substitutable.
- return this;
- }
-
- DartType unalias(Compiler compiler) => this;
-
- int get hashCode => 17 * stringName.hashCode;
-
- bool operator ==(other) {
- if (other is !StatementType) return false;
- return other.stringName == stringName;
- }
-
- String toString() => stringName;
-}
-
-class VoidType extends DartType {
- const VoidType(this.element);
-
- TypeKind get kind => TypeKind.VOID;
-
- SourceString get name => element.name;
-
- final Element element;
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- // Void cannot be substituted.
- return this;
- }
-
- DartType unalias(Compiler compiler) => this;
-
- int get hashCode => 1729;
-
- bool operator ==(other) => other is VoidType;
-
- String toString() => name.slowToString();
-}
-
-class MalformedType extends DartType {
- final ErroneousElement element;
-
- /**
- * [declaredType] holds the type which the user wrote in code.
- *
- * For instance, for a resolved but malformed type like [: Map<String> :] the
- * [declaredType] is [: Map<String> :] whereas for an unresolved type
- */
- final DartType userProvidedBadType;
-
- /**
- * Type arguments for the malformed typed, if these cannot fit in the
- * [declaredType].
- *
- * This field is for instance used for [: dynamic<int> :] and [: T<int> :]
- * where [: T :] is a type variable, in which case [declaredType] holds
- * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :]
- * is not resolved or does not imply a type.
- */
- final Link<DartType> typeArguments;
-
- MalformedType(this.element, this.userProvidedBadType,
- [this.typeArguments = null]);
-
- TypeKind get kind => TypeKind.MALFORMED_TYPE;
-
- SourceString get name => element.name;
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- // Malformed types are not substitutable.
- return this;
- }
-
- bool get isMalformed => true;
-
- bool forEachMalformedType(bool f(MalformedType type)) => f(this);
-
- DartType unalias(Compiler compiler) => this;
-
- String toString() {
- var sb = new StringBuffer();
- if (typeArguments != null) {
- if (userProvidedBadType != null) {
- sb.add(userProvidedBadType.name.slowToString());
- } else {
- sb.add(element.name.slowToString());
- }
- if (!typeArguments.isEmpty) {
- sb.add('<');
- typeArguments.printOn(sb, ', ');
- sb.add('>');
- }
- } else {
- sb.add(userProvidedBadType.toString());
- }
- return sb.toString();
- }
-}
-
-bool hasMalformed(Link<DartType> types) {
- for (DartType typeArgument in types) {
- if (typeArgument.isMalformed) {
- return true;
- }
- }
- return false;
-}
-
-// TODO(johnniwinther): Add common supertype for InterfaceType and TypedefType.
-class InterfaceType extends DartType {
- final ClassElement element;
- final Link<DartType> typeArguments;
- final bool isMalformed;
-
- InterfaceType(this.element,
- [Link<DartType> typeArguments = const Link<DartType>()])
- : this.typeArguments = typeArguments,
- this.isMalformed = hasMalformed(typeArguments) {
- assert(invariant(element, element.isDeclaration));
- }
-
- TypeKind get kind => TypeKind.INTERFACE;
-
- SourceString get name => element.name;
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- if (typeArguments.isEmpty) {
- // Return fast on non-generic types.
- return this;
- }
- if (parameters.isEmpty) {
- assert(arguments.isEmpty);
- // Return fast on empty substitutions.
- return this;
- }
- Link<DartType> newTypeArguments =
- Types.substTypes(typeArguments, arguments, parameters);
- if (!identical(typeArguments, newTypeArguments)) {
- // Create a new type only if necessary.
- return new InterfaceType(element, newTypeArguments);
- }
- return this;
- }
-
- bool forEachMalformedType(bool f(MalformedType type)) {
- for (DartType typeArgument in typeArguments) {
- if (!typeArgument.forEachMalformedType(f)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns the type as an instance of class [other], if possible, null
- * otherwise.
- */
- DartType asInstanceOf(ClassElement other) {
- if (element == other) return this;
- for (InterfaceType supertype in element.allSupertypes) {
- ClassElement superclass = supertype.element;
- if (superclass == other) {
- Link<DartType> arguments = Types.substTypes(supertype.typeArguments,
- typeArguments,
- element.typeVariables);
- return new InterfaceType(superclass, arguments);
- }
- }
- return null;
- }
-
- DartType unalias(Compiler compiler) => this;
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.add(name.slowToString());
- if (!isRaw) {
- sb.add('<');
- typeArguments.printOn(sb, ', ');
- sb.add('>');
- }
- return sb.toString();
- }
-
- int get hashCode {
- int hash = element.hashCode;
- for (Link<DartType> arguments = this.typeArguments;
- !arguments.isEmpty;
- arguments = arguments.tail) {
- int argumentHash = arguments.head != null ? arguments.head.hashCode : 0;
- hash = 17 * hash + 3 * argumentHash;
- }
- return hash;
- }
-
- bool operator ==(other) {
- if (other is !InterfaceType) return false;
- if (!identical(element, other.element)) return false;
- return typeArguments == other.typeArguments;
- }
-
- bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
-
- InterfaceType asRaw() => element.rawType;
-}
-
-class FunctionType extends DartType {
- final Element element;
- DartType returnType;
- Link<DartType> parameterTypes;
- final bool isMalformed;
-
- FunctionType(DartType returnType, Link<DartType> parameterTypes,
- Element this.element)
- : this.returnType = returnType,
- this.parameterTypes = parameterTypes,
- this.isMalformed = returnType != null && returnType.isMalformed ||
- hasMalformed(parameterTypes) {
- assert(element == null || invariant(element, element.isDeclaration));
- }
-
- TypeKind get kind => TypeKind.FUNCTION;
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- if (parameters.isEmpty) {
- assert(arguments.isEmpty);
- // Return fast on empty substitutions.
- return this;
- }
- var newReturnType = returnType.subst(arguments, parameters);
- bool changed = !identical(newReturnType, returnType);
- var newParameterTypes = Types.substTypes(parameterTypes, arguments,
- parameters);
- if (!changed && !identical(parameterTypes, newParameterTypes)) {
- changed = true;
- }
- if (changed) {
- // Create a new type only if necessary.
- return new FunctionType(newReturnType, newParameterTypes, element);
- }
- return this;
- }
-
- bool forEachMalformedType(bool f(MalformedType type)) {
- if (!returnType.forEachMalformedType(f)) {
- return false;
- }
- for (DartType parameterType in parameterTypes) {
- if (!parameterType.forEachMalformedType(f)) {
- return false;
- }
- }
- return true;
- }
-
- DartType unalias(Compiler compiler) => this;
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- bool first = true;
- sb.add('(');
- parameterTypes.printOn(sb, ', ');
- sb.add(') -> ${returnType}');
- return sb.toString();
- }
-
- SourceString get name => const SourceString('Function');
-
- int computeArity() {
- int arity = 0;
- parameterTypes.forEach((_) { arity++; });
- return arity;
- }
-
- void initializeFrom(FunctionType other) {
- assert(returnType == null);
- assert(parameterTypes == null);
- returnType = other.returnType;
- parameterTypes = other.parameterTypes;
- }
-
- int get hashCode {
- int hash = 17 * element.hashCode + 3 * returnType.hashCode;
- for (Link<DartType> parameters = parameterTypes;
- !parameters.isEmpty;
- parameters = parameters.tail) {
- hash = 17 * hash + 3 * parameters.head.hashCode;
- }
- return hash;
- }
-
- bool operator ==(other) {
- if (other is !FunctionType) return false;
- return returnType == other.returnType
- && parameterTypes == other.parameterTypes;
- }
-}
-
-class TypedefType extends DartType {
- final TypedefElement element;
- final Link<DartType> typeArguments;
- final bool isMalformed;
-
- TypedefType(this.element,
- [Link<DartType> typeArguments = const Link<DartType>()])
- : this.typeArguments = typeArguments,
- this.isMalformed = hasMalformed(typeArguments);
-
- TypeKind get kind => TypeKind.TYPEDEF;
-
- SourceString get name => element.name;
-
- DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
- if (typeArguments.isEmpty) {
- // Return fast on non-generic typedefs.
- return this;
- }
- if (parameters.isEmpty) {
- assert(arguments.isEmpty);
- // Return fast on empty substitutions.
- return this;
- }
- Link<DartType> newTypeArguments = Types.substTypes(typeArguments, arguments,
- parameters);
- if (!identical(typeArguments, newTypeArguments)) {
- // Create a new type only if necessary.
- return new TypedefType(element, newTypeArguments);
- }
- return this;
- }
-
- bool forEachMalformedType(bool f(MalformedType type)) {
- for (DartType typeArgument in typeArguments) {
- if (!typeArgument.forEachMalformedType(f)) {
- return false;
- }
- }
- return true;
- }
-
- DartType unalias(Compiler compiler) {
- // TODO(ahe): This should be [ensureResolved].
- compiler.resolveTypedef(element);
- // TODO(johnniwinther): Perform substitution on the unaliased type.
- return element.alias.unalias(compiler);
- }
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.add(name.slowToString());
- if (!isRaw) {
- sb.add('<');
- typeArguments.printOn(sb, ', ');
- sb.add('>');
- }
- return sb.toString();
- }
-
- int get hashCode => 17 * element.hashCode;
-
- bool operator ==(other) {
- if (other is !TypedefType) return false;
- if (!identical(element, other.element)) return false;
- return typeArguments == other.typeArguments;
- }
-
- bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
-
- TypedefType asRaw() => element.rawType;
-}
-
-/**
- * Special type to hold the [dynamic] type. Used for correctly returning
- * 'dynamic' on [toString].
- */
-class DynamicType extends InterfaceType {
- DynamicType(ClassElement element) : super(element);
-
- SourceString get name => const SourceString('dynamic');
-}
-
-class Types {
- final Compiler compiler;
- // TODO(karlklose): should we have a class Void?
- final VoidType voidType;
- final DynamicType dynamicType;
-
- factory Types(Compiler compiler, ClassElement dynamicElement) {
- LibraryElement library = new LibraryElementX(new Script(null, null));
- VoidType voidType = new VoidType(new VoidElementX(library));
- DynamicType dynamicType = new DynamicType(dynamicElement);
- dynamicElement.rawType = dynamicElement.thisType = dynamicType;
- return new Types.internal(compiler, voidType, dynamicType);
- }
-
- Types.internal(this.compiler, this.voidType, this.dynamicType);
-
- /** Returns true if t is a subtype of s */
- bool isSubtype(DartType t, DartType s) {
- if (identical(t, s) ||
- identical(t, dynamicType) ||
- identical(s, dynamicType) ||
- t.isMalformed ||
- s.isMalformed ||
- identical(s.element, compiler.objectClass) ||
- identical(t.element, compiler.nullClass)) {
- return true;
- }
- t = t.unalias(compiler);
- s = s.unalias(compiler);
-
- if (t is VoidType) {
- return false;
- } else if (t is InterfaceType) {
- if (s is !InterfaceType) return false;
- ClassElement tc = t.element;
- if (identical(tc, s.element)) return true;
- for (Link<DartType> supertypes = tc.allSupertypes;
- supertypes != null && !supertypes.isEmpty;
- supertypes = supertypes.tail) {
- DartType supertype = supertypes.head;
- if (identical(supertype.element, s.element)) return true;
- }
- return false;
- } else if (t is FunctionType) {
- if (identical(s.element, compiler.functionClass)) return true;
- if (s is !FunctionType) return false;
- FunctionType tf = t;
- FunctionType sf = s;
- Link<DartType> tps = tf.parameterTypes;
- Link<DartType> sps = sf.parameterTypes;
- while (!tps.isEmpty && !sps.isEmpty) {
- if (!isAssignable(tps.head, sps.head)) return false;
- tps = tps.tail;
- sps = sps.tail;
- }
- if (!tps.isEmpty || !sps.isEmpty) return false;
- if (!isAssignable(sf.returnType, tf.returnType)) return false;
- return true;
- } else if (t is TypeVariableType) {
- if (s is !TypeVariableType) return false;
- return (identical(t.element, s.element));
- } else {
- throw 'internal error: unknown type kind';
- }
- }
-
- bool isAssignable(DartType r, DartType s) {
- return isSubtype(r, s) || isSubtype(s, r);
- }
-
-
- /**
- * Helper method for performing substitution of a linked list of types.
- *
- * If no types are changed by the substitution, the [types] is returned
- * instead of a newly created linked list.
- */
- static Link<DartType> substTypes(Link<DartType> types,
- Link<DartType> arguments,
- Link<DartType> parameters) {
- bool changed = false;
- var builder = new LinkBuilder<DartType>();
- Link<DartType> typeLink = types;
- while (!typeLink.isEmpty) {
- var argument = typeLink.head.subst(arguments, parameters);
- if (!changed && !identical(argument, typeLink.head)) {
- changed = true;
- }
- builder.addLast(argument);
- typeLink = typeLink.tail;
- }
- if (changed) {
- // Create a new link only if necessary.
- return builder.toLink();
- }
- return types;
- }
-
- /**
- * Combine error messages in a malformed type to a single message string.
- */
- static String fetchReasonsFromMalformedType(DartType type) {
- // TODO(johnniwinther): Figure out how to produce good error message in face
- // of multiple errors, and how to ensure non-localized error messages.
- var reasons = new List<String>();
- type.forEachMalformedType((MalformedType malformedType) {
- ErroneousElement error = malformedType.element;
- Message message = error.messageKind.message(error.messageArguments);
- reasons.add(message.toString());
- return true;
- });
- return Strings.join(reasons, ', ');
- }
-}
-
class CancelTypeCheckException {
final Node node;
final String reason;
@@ -739,7 +68,7 @@
throw new CancelTypeCheckException(node, message);
}
- reportTypeWarning(Node node, MessageKind kind, [List arguments = const []]) {
+ reportTypeWarning(Node node, MessageKind kind, [Map arguments = const {}]) {
compiler.reportWarning(node, new TypeWarning(kind, arguments));
}
@@ -784,7 +113,8 @@
*/
checkAssignable(Node node, DartType s, DartType t) {
if (!types.isAssignable(s, t)) {
- reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE, [s, t]);
+ reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE,
+ {'fromType': s, 'toType': t});
}
}
@@ -924,7 +254,7 @@
return computeType(member);
}
reportTypeWarning(node, MessageKind.METHOD_NOT_FOUND,
- [classElement.name, name]);
+ {'className': classElement.name, 'methodName': name});
return types.dynamicType;
}
@@ -948,7 +278,7 @@
reportTypeWarning(arguments.head, MessageKind.ADDITIONAL_ARGUMENT);
} else if (!parameterTypes.isEmpty) {
reportTypeWarning(send, MessageKind.MISSING_ARGUMENT,
- [parameterTypes.head]);
+ {'argumentType': parameterTypes.head});
}
}
}
@@ -1156,8 +486,7 @@
final expressionType = analyze(expression);
if (isVoidFunction
&& !types.isAssignable(expressionType, types.voidType)) {
- reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID,
- [expressionType]);
+ reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
} else {
checkAssignable(expression, expectedReturnType, expressionType);
}
@@ -1168,7 +497,8 @@
// - f is not a generative constructor.
// - The return type of f may not be assigned to void.
} else if (!types.isAssignable(expectedReturnType, types.voidType)) {
- reportTypeWarning(node, MessageKind.RETURN_NOTHING, [expectedReturnType]);
+ reportTypeWarning(node, MessageKind.RETURN_NOTHING,
+ {'returnType': expectedReturnType});
}
return StatementType.RETURNING;
}
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 ee7845c..6c05203 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -970,7 +970,11 @@
compiler.listClass.getLibrary()));
}
- void analyzeMain(Element element) {
+ /**
+ * Performs concrete type inference of the code reachable from [element].
+ * Returns [:true:] if and only if analysis succeeded.
+ */
+ bool analyzeMain(Element element) {
initialize();
cache[element] = new Map<ConcreteTypesEnvironment, ConcreteType>();
populateCacheWithBuiltinRules();
@@ -985,10 +989,12 @@
template[item.environment] = concreteType;
invalidateCallers(item.method);
}
+ return true;
} on CancelTypeInferenceException catch(e) {
if (LOG_FAILURES) {
- compiler.log("'${e.node.toDebugString()}': ${e.reason}");
+ compiler.log(e.reason);
}
+ return false;
}
}
@@ -1498,6 +1504,11 @@
}
ConcreteType visitOperatorSend(Send node) {
+ SourceString name =
+ canonicalizeMethodName(node.selector.asIdentifier().source);
+ if (name == const SourceString('is')) {
+ return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
+ }
return visitDynamicSend(node);
}
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index a2d7edfc..fdce427 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -22,7 +22,7 @@
final String name = 'Type inference';
final Set<Element> untypedElements;
final Map<Element, Link<Element>> typedSends;
- final ConcreteTypesInferrer concreteTypesInferrer;
+ ConcreteTypesInferrer concreteTypesInferrer;
TypesTask(Compiler compiler)
: untypedElements = new Set<Element>(),
@@ -47,7 +47,13 @@
void onResolutionComplete(Element mainElement) {
measure(() {
if (concreteTypesInferrer != null) {
- concreteTypesInferrer.analyzeMain(mainElement);
+ bool success = concreteTypesInferrer.analyzeMain(mainElement);
+ if (!success) {
+ // If the concrete type inference bailed out, we pretend it didn't
+ // happen. In the future we might want to record that it failed but
+ // use the partial results as hints.
+ concreteTypesInferrer = null;
+ }
}
});
}
@@ -219,7 +225,7 @@
}
void interest(Node node, String note) {
- var message = MessageKind.GENERIC.message([note]);
+ var message = MessageKind.GENERIC.message({'text': note});
task.compiler.reportWarning(node, message);
}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 3619f47..34954ec 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -7,6 +7,7 @@
import '../closure.dart';
import '../elements/elements.dart';
import '../dart2jslib.dart';
+import '../dart_types.dart';
import '../tree/tree.dart';
import '../util/util.dart';
import '../js/js.dart' as js;
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index a78f395..9cc81cc 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -66,6 +66,8 @@
get length {
throw new UnsupportedError('get:length');
}
+
+ int slowLength() => 0;
}
abstract class LinkBuilder<T> {
diff --git a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
index 90b863c..d00ec86 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
@@ -107,6 +107,8 @@
}
return myElements.isEmpty && other.isEmpty;
}
+
+ int slowLength() => 1 + tail.slowLength();
}
class LinkBuilderImplementation<T> implements LinkBuilder<T> {
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 70c1eaf..8a07687 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -16,6 +16,17 @@
// TODO(ahe): How about "Bolt"?
abstract class Spannable {}
+class _SpannableSentinel implements Spannable {
+ final String name;
+
+ const _SpannableSentinel(this.name);
+
+ String toString() => name;
+}
+
+const Spannable CURRENT_ELEMENT_SPANNABLE =
+ const _SpannableSentinel("Current element");
+
class SpannableAssertionFailure {
final Spannable node;
final String message;
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 3d9c1da..343ad14 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -8,10 +8,10 @@
final String template;
const MessageKind(this.template);
- static const GENERIC = const MessageKind('#{1}');
+ static const GENERIC = const MessageKind('#{text}');
static const NOT_ASSIGNABLE = const MessageKind(
- '#{2} is not assignable to #{1}');
+ '#{fromType} is not assignable to #{toType}');
static const VOID_EXPRESSION = const MessageKind(
'expression does not yield a value');
static const VOID_VARIABLE = const MessageKind(
@@ -19,17 +19,17 @@
static const RETURN_VALUE_IN_VOID = const MessageKind(
'cannot return value from void function');
static const RETURN_NOTHING = const MessageKind(
- 'value of type #{1} expected');
+ 'value of type #{returnType} expected');
static const MISSING_ARGUMENT = const MessageKind(
- 'missing argument of type #{1}');
+ 'missing argument of type #{argumentType}');
static const ADDITIONAL_ARGUMENT = const MessageKind(
'additional argument');
static const METHOD_NOT_FOUND = const MessageKind(
- 'no method named #{2} in class #{1}');
+ 'no method named #{methodName} in class #{className}');
static const MEMBER_NOT_STATIC = const MessageKind(
- '#{1}.#{2} is not static');
+ '#{className}.#{memberName} is not static');
static const NO_INSTANCE_AVAILABLE = const MessageKind(
- '#{1} is only available in instance methods');
+ '#{name} is only available in instance methods');
static const UNREACHABLE_CODE = const MessageKind(
'unreachable code');
@@ -39,43 +39,43 @@
'not all paths lead to a return or throw statement');
static const CANNOT_RESOLVE = const MessageKind(
- 'cannot resolve #{1}');
+ 'cannot resolve #{name}');
static const CANNOT_RESOLVE_CONSTRUCTOR = const MessageKind(
- 'cannot resolve constructor #{1}');
+ 'cannot resolve constructor #{constructorName}');
static const CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
- 'cannot resolve constructor #{1} for implicit super call');
+ 'cannot resolve constructor #{constructorName} for implicit super call');
static const CANNOT_RESOLVE_TYPE = const MessageKind(
- 'cannot resolve type #{1}');
+ 'cannot resolve type #{typeName}');
static const DUPLICATE_DEFINITION = const MessageKind(
- 'duplicate definition of #{1}');
+ 'duplicate definition of #{name}');
static const DUPLICATE_IMPORT = const MessageKind(
- 'duplicate import of #{1}');
+ 'duplicate import of #{name}');
static const DUPLICATE_EXPORT = const MessageKind(
- 'duplicate export of #{1}');
+ 'duplicate export of #{name}');
static const NOT_A_TYPE = const MessageKind(
- '#{1} is not a type');
+ '#{node} is not a type');
static const NOT_A_PREFIX = const MessageKind(
- '#{1} is not a prefix');
+ '#{node} is not a prefix');
static const NO_SUPER_IN_OBJECT = const MessageKind(
"'Object' does not have a superclass");
static const CANNOT_FIND_CONSTRUCTOR = const MessageKind(
- 'cannot find constructor #{1}');
+ 'cannot find constructor #{constructorName}');
static const CANNOT_FIND_CONSTRUCTOR2 = const MessageKind(
- 'cannot find constructor #{1} in #{2}');
+ 'cannot find constructor #{constructorName} in #{className}');
static const CYCLIC_CLASS_HIERARCHY = const MessageKind(
- '#{1} creates a cycle in the class hierarchy');
+ '#{className} creates a cycle in the class hierarchy');
static const INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
'field initializer expected');
static const NO_SUPER_IN_STATIC = const MessageKind(
"'super' is only available in instance methods");
static const DUPLICATE_INITIALIZER = const MessageKind(
- 'field #{1} is initialized more than once');
+ 'field #{fieldName} is initialized more than once');
static const ALREADY_INITIALIZED = const MessageKind(
- '#{1} was already initialized here');
+ '#{fieldName} was already initialized here');
static const INIT_STATIC_FIELD = const MessageKind(
- 'cannot initialize static field #{1}');
+ 'cannot initialize static field #{fieldName}');
static const NOT_A_FIELD = const MessageKind(
- '#{1} is not a field');
+ '#{fieldName} is not a field');
static const CONSTRUCTOR_CALL_EXPECTED = const MessageKind(
"only call to 'this' or 'super' constructor allowed");
static const INVALID_FOR_IN = const MessageKind(
@@ -95,19 +95,17 @@
static const DUPLICATE_SUPER_INITIALIZER = const MessageKind(
'cannot have more than one super initializer');
static const INVALID_ARGUMENTS = const MessageKind(
- "arguments do not match the expected parameters of #{1}");
+ "arguments do not match the expected parameters of #{methodName}");
static const NO_MATCHING_CONSTRUCTOR = const MessageKind(
"super call arguments and constructor parameters don't match");
static const NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
"implicit super call arguments and constructor parameters don't match");
- static const NO_CONSTRUCTOR = const MessageKind(
- '#{1} is a #{2}, not a constructor');
static const FIELD_PARAMETER_NOT_ALLOWED = const MessageKind(
'a field parameter is only allowed in generative constructors');
static const INVALID_PARAMETER = const MessageKind(
"cannot resolve parameter");
static const NOT_INSTANCE_FIELD = const MessageKind(
- '#{1} is not an instance field');
+ '#{fieldName} is not an instance field');
static const NO_CATCH_NOR_FINALLY = const MessageKind(
"expected 'catch' or 'finally'");
static const EMPTY_CATCH_DECLARATION = const MessageKind(
@@ -124,27 +122,30 @@
'cannot use re-throw outside of catch block (expression expected after '
'"throw")');
static const UNBOUND_LABEL = const MessageKind(
- 'cannot resolve label #{1}');
+ 'cannot resolve label #{labelName}');
static const NO_BREAK_TARGET = const MessageKind(
'break statement not inside switch or loop');
static const NO_CONTINUE_TARGET = const MessageKind(
'continue statement not inside loop');
static const EXISTING_LABEL = const MessageKind(
- 'original declaration of duplicate label #{1}');
+ 'original declaration of duplicate label #{labelName}');
static const DUPLICATE_LABEL = const MessageKind(
- 'duplicate declaration of label #{1}');
+ 'duplicate declaration of label #{labelName}');
static const UNUSED_LABEL = const MessageKind(
- 'unused label #{1}');
+ 'unused label #{labelName}');
static const INVALID_CONTINUE = const MessageKind(
'target of continue is not a loop or switch case');
+ static const INVALID_BREAK = const MessageKind(
+ 'target of break is not a statement');
+
static const TYPE_VARIABLE_AS_CONSTRUCTOR = const MessageKind(
'cannot use type variable as constructor');
static const DUPLICATE_TYPE_VARIABLE_NAME = const MessageKind(
- 'type variable #{1} already declared');
+ 'type variable #{typeVariableName} already declared');
static const TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const MessageKind(
- 'cannot refer to type variable #{1} within a static member');
- static const INVALID_BREAK = const MessageKind(
- 'target of break is not a statement');
+ 'cannot refer to type variable #{typeVariableName} '
+ 'within a static member');
+
static const INVALID_USE_OF_SUPER = const MessageKind(
'super not allowed here');
static const INVALID_CASE_DEFAULT = const MessageKind(
@@ -171,22 +172,22 @@
'map-literal key not a string literal');
static const NO_SUCH_LIBRARY_MEMBER = const MessageKind(
- '#{1} has no member named #{2}');
+ '#{libraryName} has no member named #{memberName}');
static const CANNOT_INSTANTIATE_INTERFACE = const MessageKind(
- "cannot instantiate interface '#{1}'");
+ "cannot instantiate interface '#{interfaceName}'");
static const CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
- "cannot instantiate typedef '#{1}'");
+ "cannot instantiate typedef '#{typedefName}'");
static const CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
- "cannot instantiate type variable '#{1}'");
+ "cannot instantiate type variable '#{typeVariableName}'");
static const NO_DEFAULT_CLASS = const MessageKind(
- "no default class on enclosing interface '#{1}'");
+ "no default class on enclosing interface '#{interfaceName}'");
static const CYCLIC_TYPE_VARIABLE = const MessageKind(
- "cyclic reference to type variable #{1}");
+ "cyclic reference to type variable #{typeVariableName}");
static const CLASS_NAME_EXPECTED = const MessageKind(
"class name expected");
@@ -195,19 +196,20 @@
"interface type expected");
static const CANNOT_EXTEND = const MessageKind(
- "#{1} cannot be extended");
+ "#{type} cannot be extended");
static const CANNOT_IMPLEMENT = const MessageKind(
- "#{1} cannot be implemented");
+ "#{type} cannot be implemented");
static const DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
- "Error: #{1} can not be both extended and implemented.");
+ "Error: #{type} can not be both extended and implemented.");
static const DUPLICATE_IMPLEMENTS = const MessageKind(
- "Error: #{1} must not occur more than once in the implements clause.");
+ "Error: #{type} must not occur more than once "
+ "in the implements clause.");
static const ILLEGAL_SUPER_SEND = const MessageKind(
- "#{1} cannot be called on super");
+ "#{name} cannot be called on super");
static const ADDITIONAL_TYPE_ARGUMENT = const MessageKind(
"additional type argument");
@@ -218,41 +220,42 @@
// TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or MISSING_TYPE_ARGUMENT
// instead.
static const TYPE_ARGUMENT_COUNT_MISMATCH = const MessageKind(
- "incorrect number of type arguments on #{1}");
+ "incorrect number of type arguments on #{type}");
static const MISSING_ARGUMENTS_TO_ASSERT = const MessageKind(
"missing arguments to assert");
static const GETTER_MISMATCH = const MessageKind(
- "Error: setter disagrees on: #{1}.");
+ "Error: setter disagrees on: #{modifiers}.");
static const SETTER_MISMATCH = const MessageKind(
- "Error: getter disagrees on: #{1}.");
+ "Error: getter disagrees on: #{modifiers}.");
static const ILLEGAL_SETTER_FORMALS = const MessageKind(
"Error: a setter must have exactly one argument.");
static const NO_STATIC_OVERRIDE = const MessageKind(
- "Error: static member cannot override instance member '#{1}' of '#{2}'.");
+ "Error: static member cannot override instance member '#{memberName}' of "
+ "'#{className}'.");
static const NO_STATIC_OVERRIDE_CONT = const MessageKind(
"Info: this is the instance member that cannot be overridden "
"by a static member.");
static const CANNOT_OVERRIDE_FIELD_WITH_METHOD = const MessageKind(
- "Error: method cannot override field '#{1}' of '#{2}'.");
+ "Error: method cannot override field '#{memberName}' of '#{className}'.");
static const CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT = const MessageKind(
"Info: this is the field that cannot be overridden by a method.");
static const CANNOT_OVERRIDE_METHOD_WITH_FIELD = const MessageKind(
- "Error: field cannot override method '#{1}' of '#{2}'.");
+ "Error: field cannot override method '#{memberName}' of '#{className}'.");
static const CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT = const MessageKind(
"Info: this is the method that cannot be overridden by a field.");
static const BAD_ARITY_OVERRIDE = const MessageKind(
- "Error: cannot override method '#{1}' in '#{2}'; "
+ "Error: cannot override method '#{memberName}' in '#{className}'; "
"the parameters do not match.");
static const BAD_ARITY_OVERRIDE_CONT = const MessageKind(
@@ -265,33 +268,33 @@
"Error: Formal parameters are not allowed here.");
static const UNARY_OPERATOR_BAD_ARITY = const MessageKind(
- "Error: Operator #{1} must have no parameters.");
+ "Error: Operator #{operatorName} must have no parameters.");
static const MINUS_OPERATOR_BAD_ARITY = const MessageKind(
"Error: Operator - must have 0 or 1 parameters.");
static const BINARY_OPERATOR_BAD_ARITY = const MessageKind(
- "Error: Operator #{1} must have exactly 1 parameter.");
+ "Error: Operator #{operatorName} must have exactly 1 parameter.");
static const TERNARY_OPERATOR_BAD_ARITY = const MessageKind(
- "Error: Operator #{1} must have exactly 2 parameters.");
+ "Error: Operator #{operatorName} must have exactly 2 parameters.");
static const OPERATOR_OPTIONAL_PARAMETERS = const MessageKind(
- "Error: Operator #{1} cannot have optional parameters.");
+ "Error: Operator #{operatorName} cannot have optional parameters.");
static const OPERATOR_NAMED_PARAMETERS = const MessageKind(
- "Error: Operator #{1} cannot have named parameters.");
+ "Error: Operator #{operatorName} cannot have named parameters.");
// TODO(ahe): This message is hard to localize. This is acceptable,
// as it will be removed when we ship Dart version 1.0.
static const DEPRECATED_FEATURE_WARNING = const MessageKind(
- "Warning: deprecated language feature, #{1}, "
+ "Warning: deprecated language feature, #{featureName}, "
"will be removed in a future Dart milestone.");
// TODO(ahe): This message is hard to localize. This is acceptable,
// as it will be removed when we ship Dart version 1.0.
static const DEPRECATED_FEATURE_ERROR = const MessageKind(
- "Error: #{1} are not legal "
+ "Error: #{featureName} are not legal "
"due to option --reject-deprecated-language-features.");
static const CONSTRUCTOR_WITH_RETURN_TYPE = const MessageKind(
@@ -301,10 +304,10 @@
"Error: cannot have final modifier on method.");
static const ILLEGAL_CONSTRUCTOR_MODIFIERS = const MessageKind(
- "Error: illegal constructor modifiers: #{1}.");
+ "Error: illegal constructor modifiers: #{modifiers}.");
static const ILLEGAL_MIXIN_APPLICATION_MODIFIERS = const MessageKind(
- "Error: illegal mixin application modifiers: #{1}.");
+ "Error: illegal mixin application modifiers: #{modifiers}.");
static const ILLEGAL_MIXIN_SUPERCLASS = const MessageKind(
"Error: class used as mixin must have Object as superclass.");
@@ -313,10 +316,11 @@
"Error: class used as mixin cannot have non-factory constructor.");
static const ILLEGAL_MIXIN_CYCLE = const MessageKind(
- "Error: class used as mixin introduces mixin cycle: #{1} <-> #{2}.");
+ "Error: class used as mixin introduces mixin cycle: "
+ "#{mixinName1} <-> #{mixinName2}.");
static const ILLEGAL_MIXIN_WITH_SUPER = const MessageKind(
- "Error: cannot use class #{1} as a mixin because it uses super.");
+ "Error: cannot use class #{className} as a mixin because it uses super.");
static const ILLEGAL_MIXIN_SUPER_USE = const MessageKind(
"Use of super in class used as mixin.");
@@ -337,7 +341,7 @@
'Error: part header must come before top-level definitions.');
static const LIBRARY_NAME_MISMATCH = const MessageKind(
- 'Warning: expected part of library name "#{1}".');
+ 'Warning: expected part of library name "#{libraryName}".');
static const MISSING_PART_OF_TAG = const MessageKind(
'Note: This file has no part-of tag, but it is being used as a part.');
@@ -349,43 +353,47 @@
'Error: directive not allowed here.');
static const DUPLICATED_LIBRARY_NAME = const MessageKind(
- 'Warning: duplicated library name "#{1}".');
+ 'Warning: duplicated library name "#{libraryName}".');
static const INVALID_SOURCE_FILE_LOCATION = const MessageKind('''
-Invalid offset (#{1}) in source map.
-File: #{2}
-Length: #{3}''');
+Invalid offset (#{offset}) in source map.
+File: #{fileName}
+Length: #{length}''');
static const PATCH_RETURN_TYPE_MISMATCH = const MessageKind(
- "Patch return type '#{3}' doesn't match '#{2}' on origin method '#{1}'.");
+ "Patch return type '#{patchReturnType}' doesn't match "
+ "'#{originReturnType}' on origin method '#{methodName}'.");
static const PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH = const MessageKind(
- "Required parameter count of patch method (#{3}) doesn't match parameter "
- "count on origin method '#{1}' (#{2}).");
+ "Required parameter count of patch method (#{patchParameterCount}) "
+ "doesn't match parameter count on origin method '#{methodName}' "
+ "(#{originParameterCount}).");
static const PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH = const MessageKind(
- "Optional parameter count of patch method (#{3}) doesn't match parameter "
- "count on origin method '#{1}' (#{2}).");
+ "Optional parameter count of patch method (#{patchParameterCount}) "
+ "doesn't match parameter count on origin method '#{methodName}' "
+ "(#{originParameterCount}).");
static const PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH = const MessageKind(
- "Optional parameters of origin and patch method '#{1}' must "
+ "Optional parameters of origin and patch method '#{methodName}' must "
"both be either named or positional.");
static const PATCH_PARAMETER_MISMATCH = const MessageKind(
- "Patch method parameter '#{3}' doesn't match '#{2}' on origin method "
- "#{1}.");
+ "Patch method parameter '#{patchParameter}' doesn't match "
+ "'#{originParameter}' on origin method #{methodName}.");
+
+ static const EXTERNAL_WITHOUT_IMPLEMENTATION = const MessageKind(
+ "External method without an implementation.");
static const TOP_LEVEL_VARIABLE_DECLARED_STATIC = const MessageKind(
"Top-level variable cannot be declared static.");
static const WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT = const MessageKind(
- "Wrong number of arguments to assert. Should be 1, but given #{1}.");
+ "Wrong number of arguments to assert. Should be 1, but given "
+ "#{argumentCount}.");
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}.");
+ "assert takes no named arguments, but given #{argumentCount}.");
static const FACTORY_REDIRECTION_IN_NON_FACTORY = const MessageKind(
"Error: Factory redirection only allowed in factories.");
@@ -410,7 +418,7 @@
* the name and version of your operating system,
-* the Dart SDK build number (#{1}), and
+* the Dart SDK build number (#{buildId}), and
* the entire message you see here (including the full stack trace
below as well as the source location above).
@@ -418,34 +426,43 @@
toString() => template;
- Message message([List arguments = const []]) {
+ Message message([Map arguments = const {}]) {
return new Message(this, arguments);
}
- CompilationError error([List arguments = const []]) {
+ CompilationError error([Map arguments = const {}]) {
return new CompilationError(this, arguments);
}
}
class Message {
final kind;
- final List arguments;
+ final Map arguments;
String message;
- Message(this.kind, this.arguments);
+ Message(this.kind, this.arguments) {
+ assert(() { computeMessage(); return true; });
+ }
- String toString() {
+ String computeMessage() {
if (message == null) {
message = kind.template;
- int position = 1;
- for (var argument in arguments) {
- String string = slowToString(argument);
- message = message.replaceAll('#{${position++}}', string);
- }
+ arguments.forEach((key, value) {
+ String string = slowToString(value);
+ message = message.replaceAll('#{${key}}', string);
+ });
+ assert(invariant(
+ CURRENT_ELEMENT_SPANNABLE,
+ !message.contains(new RegExp(r"#\{.+\}")),
+ message: 'Missing arguments in error message: "$message"'));
}
return message;
}
+ String toString() {
+ return computeMessage();
+ }
+
bool operator==(other) {
if (other is !Message) return false;
return (kind == other.kind) && (toString() == other.toString());
@@ -462,32 +479,32 @@
class Diagnostic {
final Message message;
- Diagnostic(MessageKind kind, List arguments)
- : message = new Message(kind, arguments);
+ Diagnostic(MessageKind kind, [Map arguments = const {}])
+ : message = new Message(kind, arguments);
String toString() => message.toString();
}
class TypeWarning extends Diagnostic {
- TypeWarning(MessageKind kind, List arguments)
+ TypeWarning(MessageKind kind, [Map arguments = const {}])
: super(kind, arguments);
}
class ResolutionError extends Diagnostic {
- ResolutionError(MessageKind kind, List arguments)
- : super(kind, arguments);
+ ResolutionError(MessageKind kind, [Map arguments = const {}])
+ : super(kind, arguments);
}
class ResolutionWarning extends Diagnostic {
- ResolutionWarning(MessageKind kind, List arguments)
+ ResolutionWarning(MessageKind kind, [Map arguments = const {}])
: super(kind, arguments);
}
class CompileTimeConstantError extends Diagnostic {
- CompileTimeConstantError(MessageKind kind, List arguments)
+ CompileTimeConstantError(MessageKind kind, [Map arguments = const {}])
: super(kind, arguments);
}
class CompilationError extends Diagnostic {
- CompilationError(MessageKind kind, List arguments)
+ CompilationError(MessageKind kind, [Map arguments = const {}])
: super(kind, arguments);
}
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 6576701..2520489 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -357,7 +357,7 @@
}
startFile("apidoc.json");
- var libraries = _sortedLibraries.mappedBy(
+ var libraries = _sortedLibraries.map(
(lib) => new LibraryElement(lib.qualifiedName, lib))
.toList();
write(json_serializer.serialize(libraries));
@@ -1700,7 +1700,7 @@
final typeArgs = type.typeArguments;
if (typeArgs.length > 0) {
final args =
- Strings.join(typeArgs.mappedBy((arg) => typeName(arg)), ', ');
+ Strings.join(typeArgs.map((arg) => typeName(arg)), ', ');
return '${type.originalDeclaration.simpleName}<$args>';
}
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
index 021b7f7..194bc5f 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
@@ -11,13 +11,10 @@
// TODO(rnystrom): Use "package:" URL (#4968).
import '../../classify.dart';
import '../../markdown.dart' as md;
-part '../dartdoc/nav.dart';
-
-// TODO(rnystrom): Use "package:" URL (#4968).
-part 'dropdown.dart';
-part 'search.dart';
-part '../dartdoc/nav.dart';
-part 'client-shared.dart';
+import '../dartdoc/nav.dart';
+import 'dropdown.dart';
+import 'search.dart';
+import 'client-shared.dart';
main() {
setup();
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart
index 82a71c7..7348f2e 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart
@@ -2,7 +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.
-part of client;
+library client_shared;
+
+import 'dart:html';
+import 'dropdown.dart';
+import '../../classify.dart';
+import '../dartdoc/nav.dart';
+
// Code shared between the different client-side libraries.
@@ -49,7 +55,7 @@
} else {
// Syntax highlight.
if (!pre.classes.contains('formatted')) {
- pre.innerHTML = classifySource(pre.text);
+ pre.innerHtml = classifySource(pre.text);
pre.classes.add('formatted');
};
pre.classes.add('expanded');
@@ -70,10 +76,10 @@
String display = showInherited.dataAttributes['show-inherited'];
if (display == 'block') {
display = 'none';
- showInherited.innerHTML = 'Show inherited';
+ showInherited.innerHtml = 'Show inherited';
} else {
display = 'block';
- showInherited.innerHTML = 'Hide inherited';
+ showInherited.innerHtml = 'Hide inherited';
}
showInherited.dataAttributes['show-inherited'] = display;
for (var elem in document.queryAll('.inherited')) {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart
index a411064..d76b21e 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart
@@ -7,15 +7,9 @@
import 'dart:html';
import 'dart:json';
-import '../../../../compiler/implementation/source_file.dart';
-// TODO(rnystrom): Use "package:" URL (#4968).
-import '../../classify.dart';
-import '../dartdoc/nav.dart';
+import 'dropdown.dart';
+import 'client-shared.dart';
-// TODO(rnystrom): Use "package:" URL (#4968).
-part 'dropdown.dart';
-part 'search.dart';
-part 'client-shared.dart';
part '../../../tmp/nav.dart';
main() {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
index ca0ff81..05798b3 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
@@ -2,7 +2,12 @@
// for 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 client;
+library dropdown;
+
+import 'dart:html';
+import 'search.dart';
+import 'client-shared.dart';
+import '../dartdoc/nav.dart';
List libraryList;
InputElement searchInput;
@@ -59,7 +64,7 @@
if (results.isEmpty) {
var row = table.insertRow(0);
- row.innerHTML = "<tr><td>No matches found for '$text'.</td></tr>";
+ row.innerHtml = "<tr><td>No matches found for '$text'.</td></tr>";
} else {
results.sort(resultComparator);
@@ -72,11 +77,11 @@
}
if (results.length >= 10) {
var row = table.insertRow(table.rows.length);
- row.innerHTML = '<tr><td>+ ${results.length-10} more.</td></tr>';
+ row.innerHtml = '<tr><td>+ ${results.length-10} more.</td></tr>';
results = results.getRange(0, 10);
}
}
- dropdown.elements = elements;
+ dropdown.children = elements;
updateResults(text, results);
showDropDown();
}
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
index 111d333..22f4880 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
@@ -2,7 +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.
-part of client;
+library search;
+
+import 'dart:html';
+import 'dropdown.dart';
+import '../dartdoc/nav.dart';
/**
* [SearchText] represent the search field text. The text is viewed in three
diff --git a/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart b/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart
index afab003..017633f 100644
--- a/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart
@@ -5,8 +5,8 @@
library dartdoc_search_test;
// TODO(rnystrom): Use "package:" URL (#4968).
-part '../lib/src/dartdoc/nav.dart';
-part '../lib/src/client/search.dart';
+import '../lib/src/dartdoc/nav.dart';
+import '../lib/src/client/search.dart';
const String URL = 'dummy-url';
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 9e0fefd..80716fb 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -7,7 +7,6 @@
part 'async_error.dart';
part 'future.dart';
part 'future_impl.dart';
-part 'merge_stream.dart';
part 'stream.dart';
part 'stream_controller.dart';
part 'stream_impl.dart';
diff --git a/sdk/lib/async/async_sources.gypi b/sdk/lib/async/async_sources.gypi
index 74daf49..fe95d17 100644
--- a/sdk/lib/async/async_sources.gypi
+++ b/sdk/lib/async/async_sources.gypi
@@ -8,7 +8,6 @@
'async_error.dart',
'future.dart',
'future_impl.dart',
- 'merge_stream.dart',
'stream.dart',
'stream_controller.dart',
'stream_impl.dart',
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 0c4daa0..0d32aae 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -85,16 +85,50 @@
// TODO(floitsch): document chaining.
abstract class Future<T> {
/**
+ * Creates a future containing the result of calling [function].
+ *
+ * The result of computing [:function():] is either a returned value or
+ * a throw.
+ *
+ * If a value is returned, it becomes the result of the created future.
+ *
+ * If calling [function] throws, the created [Future] will be completed
+ * with an async error containing the thrown value and a captured
+ * stacktrace.
+ *
+ * However, if the result of calling [function] is already an asynchronous
+ * result, we treat it specially.
+ *
+ * If the returned value is itself a [Future], completion of
+ * the created future will wait until the returned future completes,
+ * and will then complete with the same result.
+ *
+ * If a thrown value is an [AsyncError], it is used directly as the result
+ * of the created future.
+ */
+ factory Future.of(function()) {
+ try {
+ var result = function();
+ return new _FutureImpl<T>().._setOrChainValue(result);
+ } catch (error, stackTrace) {
+ return new _FutureImpl<T>.immediateError(error, stackTrace);
+ }
+ }
+
+ /**
* A future whose value is available in the next event-loop iteration.
*
- * See [Completer]s, for futures with values that are computed asynchronously.
+ * If [value] is not a [Future], using this constructor is equivalent
+ * to [:new Future.of(() => value):].
+ *
+ * See [Completer] to create a Future and complete it later.
*/
factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value);
/**
* A future that completes with an error in the next event-loop iteration.
*
- * See [Completer]s, for futures with values that are computed asynchronously.
+ * See [Completer] to create a Future and complete it later.
*/
factory Future.immediateError(var error, [Object stackTrace]) {
return new _FutureImpl<T>.immediateError(error, stackTrace);
@@ -113,7 +147,8 @@
* See [Completer]s, for futures with values that are computed asynchronously.
*/
factory Future.delayed(int milliseconds, T value()) {
- _FutureImpl<T> future = new _ThenFuture<dynamic, T>((_) => value());
+ _ThenFuture<dynamic, T> future =
+ new _ThenFuture<dynamic, T>((_) => value());
new Timer(milliseconds, (_) => future._sendValue(null));
return future;
}
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index e91da2b..53ba3f3 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -304,31 +304,8 @@
}
}
- _FutureListener _asListener() => new _FutureListener.wrap(this);
-}
-
-/**
- * Transforming future base class.
- *
- * A transforming future is itself a future and a future listener.
- * Subclasses override [_sendValue]/[_sendError] to intercept
- * the results of a previous future.
- */
-abstract class _TransformFuture<S, T> extends _FutureImpl<T>
- implements _FutureListener<S> {
- // _FutureListener implementation.
- _FutureListener _nextListener;
-
- void _sendValue(S value);
-
- void _sendError(AsyncError error);
-
- void _subscribeTo(_FutureImpl future) {
- future._addListener(this);
- }
-
/**
- * Helper function to hand the result of transforming an incoming event.
+ * Helper function to handle the result of transforming an incoming event.
*
* If the result is itself a [Future], this future is linked to that
* future's output. If not, this future is completed with the result.
@@ -351,6 +328,29 @@
_setValue(result);
}
}
+
+ _FutureListener _asListener() => new _FutureListener.wrap(this);
+}
+
+/**
+ * Transforming future base class.
+ *
+ * A transforming future is itself a future and a future listener.
+ * Subclasses override [_sendValue]/[_sendError] to intercept
+ * the results of a previous future.
+ */
+abstract class _TransformFuture<S, T> extends _FutureImpl<T>
+ implements _FutureListener<S> {
+ // _FutureListener implementation.
+ _FutureListener _nextListener;
+
+ void _sendValue(S value);
+
+ void _sendError(AsyncError error);
+
+ void _subscribeTo(_FutureImpl future) {
+ future._addListener(this);
+ }
}
/** The onValue and onError handlers return either a value or a future */
diff --git a/sdk/lib/async/merge_stream.dart b/sdk/lib/async/merge_stream.dart
deleted file mode 100644
index 424b69c..0000000
--- a/sdk/lib/async/merge_stream.dart
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart.async;
-
-class _SupercedeEntry<T> {
- final SupercedeStream stream;
- Stream<T> source;
- StreamSubscription subscription = null;
- _SupercedeEntry next;
-
- _SupercedeEntry(this.stream, this.source, this.next);
-
- // Whether the source stream is complete.
- bool get isDone => source == null;
-
- void onData(T data) {
- // Stop all lower-priority sources.
- stream._setData(this, data);
- }
-
- void onError(AsyncError error) {
- stream._signalError(error);
- }
-
- void onDone() {
- subscription = null;
- source = null;
- stream._setDone(this);
- }
-
- void start() {
- assert(subscription == null);
- if (!isDone) {
- subscription =
- source.listen(onData, onError: onError, onDone: onDone);
- }
- }
-
- void stop() {
- if (!isDone) {
- subscription.cancel();
- subscription = null;
- }
- }
-
- void pause() {
- if (!isDone) subscription.pause();
- }
-
- void resume() {
- if (!isDone) subscription.resume();
- }
-}
-
-/**
- * [Stream] that forwards data from its active source with greatest priority.
- *
- * The [SupercedeStream] gets data from some source [Stream]s which
- * are ordered in order of increasing priority.
- * When a higher priority stream provides data, all lower priority streams
- * are dropped.
- *
- * Errors from all (undropped) streams are forwarded.
- */
-class SupercedeStream<T> extends _MultiStreamImpl<T> {
- _SupercedeEntry _entries = null;
-
- /**
- * Create [SupercedeStream] from the given [sources].
- *
- * The [sources] are iterated in order of increasing priority.
- */
- SupercedeStream(Iterable<Stream<T>> sources) {
- // Set up linked list of sources in decreasing priority order.
- // The order allows us to drop all lower priority streams when a higher
- // priority stream provides a value.
- for (Stream<T> stream in sources) {
- _entries = new _SupercedeEntry(this, stream, _entries);
- }
- }
-
- void _onSubscriptionStateChange() {
- if (_hasSubscribers) {
- for (_SupercedeEntry entry = _entries;
- entry != null;
- entry = entry.next) {
- entry.start();
- }
- } else {
- for (_SupercedeEntry entry = _entries;
- entry != null;
- entry = entry.next) {
- entry.stop();
- }
- }
- }
-
- void _onPauseStateChange() {
- if (_isPaused) {
- for (_SupercedeEntry entry = _entries;
- entry != null;
- entry = entry.next) {
- entry.pause();
- }
- } else {
- for (_SupercedeEntry entry = _entries;
- entry != null;
- entry = entry.next) {
- entry.resume();
- }
- }
- }
-
- void _setData(_SupercedeEntry entry, T data) {
- while (entry.next != null) {
- _SupercedeEntry nextEntry = entry.next;
- entry.next = null;
- nextEntry.stop();
- entry = nextEntry;
- }
- _add(data);
- }
-
- void _setDone(_SupercedeEntry entry) {
- if (identical(_entries, entry)) {
- // Remove the leading completed streams. These are streams
- // the completed without ever providing data.
- while (_entries.isDone) {
- _entries = _entries.next;
- if (_entries == null) {
- _close();
- return;
- }
- }
- }
- // Otherwise we leave the completed entry in the list and
- // remove it when a higher priority stream provides data or
- // all higher priority streams have completed.
- }
-}
-
-/**
- * Helper class for [CyclicScheduleStream].
- *
- * Used to maintain a list of source streams which are activated in cyclic
- * order.
- *
- * The stream is either unsubscribed, paused or active. Only one stream
- * will be active at a time. A source is not subscribed until it's first
- * activated.
- *
- * If the source completes, the entry is removed from [stream].
- */
-class _CycleEntry<T> {
- final CyclicScheduleStream stream;
- /** A single source stream for the [CyclicScheduleStream]. */
- Stream source;
- /** The active subscription, if any. */
- StreamSubscription subscription = null;
- /** Next entry in a linked list of entries. */
- _CycleEntry next;
-
- _CycleEntry(this.stream, this.source);
-
- void cancel() {
- // This method may be called event if this entry has never been activated.
- if (subscription != null) {
- subscription.cancel();
- subscription = null;
- }
- }
-
- void pause() {
- ensureSubscribed();
- if (!subscription.isPaused) {
- subscription.pause();
- }
- }
-
- void activate() {
- ensureSubscribed();
- if (subscription.isPaused) {
- subscription.resume();
- }
- }
-
- void ensureSubscribed() {
- if (subscription == null) {
- subscription =
- source.listen(stream._onData,
- onError: stream._signalError,
- onDone: stream._onDone);
- }
- }
-}
-
-/**
- * [Stream] that schedules events from multiple sources in cyclic order.
- *
- * The source streams are activated and paused so that only one data event
- * is generated at a time, and those data events are output on this stream.
- *
- * Error events from the currently active stream are forwarded without
- * changing the schedule. When a source stream ends, it is removed from
- * the schedule.
- */
-class CyclicScheduleStream<T> extends _MultiStreamImpl<T> {
- _CycleEntry _currentEntry = null;
- _CycleEntry _lastEntry = null;
-
- /**
- * Create a [Stream] that provides data from [sources] one event at a time.
- *
- * The data are provided as one event from each stream in the order they are
- * given by the [Iterable], and then cycling as long as there are data.
- */
- CyclicScheduleStream(Iterable<Stream<T>> sources) {
- _CycleEntry entry = null;
- for (Stream<T> source in sources) {
- _CycleEntry newEntry = new _CycleEntry(this, source);
- if (_lastEntry == null) {
- _currentEntry = _lastEntry = newEntry;
- } else {
- _lastEntry = _lastEntry.next = newEntry;
- }
- }
- if (_currentEntry == null) {
- _close();
- }
- }
-
- void _onSubscriptionStateChange() {
- if (_hasSubscribers) {
- _currentEntry.activate();
- for (_CycleEntry entry = _currentEntry.next;
- entry != null;
- entry = entry.next) {
- entry.pause();
- }
- return;
- }
- for (_CycleEntry entry = _currentEntry; entry != null; entry = entry.next) {
- entry.cancel();
- }
- }
-
- void _onPauseStateChange() {
- if (_isPaused) {
- _currentEntry.pause();
- } else {
- _currentEntry.activate();
- }
- }
-
- void _onData(T data) {
- if (_currentEntry.next != null) {
- _currentEntry.pause();
- _add(data);
- // Move the current entry to the end of the list.
- _lastEntry = _lastEntry.next = _currentEntry;
- _currentEntry = _currentEntry.next;
- _lastEntry.next = null;
- _currentEntry.activate();
- } else {
- // No pausing with only one entry left.
- _add(data);
- }
- }
-
- void _onDone() {
- if (_currentEntry.next == null) {
- _close();
- _currentEntry = _lastEntry = null;
- } else {
- // Remove the current entry from the list now that it's complete.
- _currentEntry = _currentEntry.next;
- _currentEntry.activate();
- }
- }
-}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index ed4ab1a..afdeaf3 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -40,12 +40,11 @@
* A broadcast stream allows any number of listeners, and it fires
* its events when they are ready, whether there are listeners or not.
*
- * Braodcast streams are used for independent events/observers.
+ * Broadcast streams are used for independent events/observers.
*
- * The default implementation of [isBroadcast] and
- * [asBroadcastStream] are assuming this is a single-subscription stream
- * and a broadcast stream inheriting from [Stream] must override these
- * to return [:true:] and [:this:] respectively.
+ * The default implementation of [isBroadcast] returns false.
+ * A broadcast stream inheriting from [Stream] must override [isBroadcast]
+ * to return [:true:].
*/
abstract class Stream<T> {
Stream();
@@ -93,37 +92,11 @@
* If this stream is already a broadcast stream, it is returned unmodified.
*/
Stream<T> asBroadcastStream() {
+ if (isBroadcast) return this;
return new _SingleStreamMultiplexer<T>(this);
}
/**
- * Stream that outputs events from the [sources] in cyclic order.
- *
- * The merged streams are paused and resumed in order to ensure the proper
- * order of output events.
- */
- factory Stream.cyclic(Iterable<Stream> sources) {
- return new CyclicScheduleStream<T>(sources);
- }
-
- /**
- * Create a stream that forwards data from the highest priority active source.
- *
- * Sources are provided in order of increasing priority, and only data from
- * the highest priority source stream that has provided data are output
- * on the created stream.
- *
- * Errors from the most recent active stream, and any higher priority stream,
- * are forwarded to the created stream.
- *
- * If a higher priority source stream completes without providing data,
- * it will have no effect on lower priority streams.
- */
- factory Stream.superceding(Iterable<Stream<T>> sources) {
- return new SupercedeStream<T>(sources);
- }
-
- /**
* Add a subscription to this stream.
*
* On each data event from this stream, the subscribers [onData] handler
@@ -149,18 +122,25 @@
* but it only sends the data events that satisfy the [test].
*/
Stream<T> where(bool test(T event)) {
- return new WhereStream<T>(this, test);
+ return new _WhereStream<T>(this, test);
}
/**
* Create a new stream that converts each element of this stream
* to a new value using the [convert] function.
*/
- Stream mappedBy(convert(T event)) {
- return new MapStream<T, dynamic>(this, convert);
+ Stream map(convert(T event)) {
+ return new _MapStream<T, dynamic>(this, convert);
}
/**
+ * Deprecated alias for [map].
+ *
+ * @deprecated
+ */
+ Stream mappedBy(f(T element)) => map(f);
+
+ /**
* Create a wrapper Stream that intercepts some errors from this stream.
*
* If this stream sends an error that matches [test], then it is intercepted
@@ -172,10 +152,13 @@
* If the error is intercepted, the [handle] function can decide what to do
* with it. It can throw if it wants to raise a new (or the same) error,
* or simply return to make the stream forget the error.
+ *
+ * If you need to transform an error into a data event, use the more generic
+ * [Stream.transformEvent] to handle the event by writing a data event to
+ * the output sink
*/
- // TODO(lrn): Say what to do if you want to convert the error to a value.
Stream<T> handleError(void handle(AsyncError error), { bool test(error) }) {
- return new HandleErrorStream<T>(this, handle, test);
+ return new _HandleErrorStream<T>(this, handle, test);
}
/**
@@ -187,13 +170,13 @@
* in order.
*/
Stream expand(Iterable convert(T value)) {
- return new ExpandStream<T, dynamic>(this, convert);
+ return new _ExpandStream<T, dynamic>(this, convert);
}
/**
* Bind this stream as the input of the provided [StreamConsumer].
*/
- Future pipe(StreamConsumer<dynamic, T> streamConsumer) {
+ Future pipe(StreamConsumer<T, dynamic> streamConsumer) {
return streamConsumer.consume(this);
}
@@ -206,14 +189,15 @@
return streamTransformer.bind(this);
}
-
/** Reduces a sequence of values by repeatedly applying [combine]. */
Future reduce(var initialValue, combine(var previous, T element)) {
_FutureImpl result = new _FutureImpl();
var value = initialValue;
StreamSubscription subscription;
subscription = this.listen(
- (T element) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ element) {
_runUserCode(
() => combine(value, element),
(result) { value = result; },
@@ -257,13 +241,15 @@
_FutureImpl<bool> future = new _FutureImpl<bool>();
StreamSubscription subscription;
subscription = this.listen(
- (T element) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ element) {
_runUserCode(
- () => match(element),
+ () => (element == match),
(bool isMatch) {
if (isMatch) {
subscription.cancel();
- future._setValue(element);
+ future._setValue(true);
}
},
_cancelAndError(subscription, future)
@@ -287,7 +273,9 @@
_FutureImpl<bool> future = new _FutureImpl<bool>();
StreamSubscription subscription;
subscription = this.listen(
- (T element) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ element) {
_runUserCode(
() => test(element),
(bool isMatch) {
@@ -317,7 +305,9 @@
_FutureImpl<bool> future = new _FutureImpl<bool>();
StreamSubscription subscription;
subscription = this.listen(
- (T element) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ element) {
_runUserCode(
() => test(element),
(bool isMatch) {
@@ -363,12 +353,17 @@
* If [compare] is omitted, it defaults to [Comparable.compare].
*/
Future<T> min([int compare(T a, T b)]) {
- if (compare == null) compare = Comparable.compare;
+ if (compare == null) {
+ var defaultCompare = Comparable.compare;
+ compare = defaultCompare;
+ }
_FutureImpl<T> future = new _FutureImpl<T>();
StreamSubscription subscription;
T min = null;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
min = value;
subscription.onData((T value) {
_runUserCode(
@@ -402,12 +397,17 @@
* If [compare] is omitted, it defaults to [Comparable.compare].
*/
Future<T> max([int compare(T a, T b)]) {
- if (compare == null) compare = Comparable.compare;
+ if (compare == null) {
+ var defaultCompare = Comparable.compare;
+ compare = defaultCompare;
+ }
_FutureImpl<T> future = new _FutureImpl<T>();
StreamSubscription subscription;
T max = null;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
max = value;
subscription.onData((T value) {
_runUserCode(
@@ -452,7 +452,9 @@
List<T> result = <T>[];
_FutureImpl<List<T>> future = new _FutureImpl<List<T>>();
this.listen(
- (T data) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ data) {
result.add(data);
},
onError: future._setError,
@@ -468,7 +470,9 @@
Set<T> result = new Set<T>();
_FutureImpl<Set<T>> future = new _FutureImpl<Set<T>>();
this.listen(
- (T data) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ data) {
result.add(data);
},
onError: future._setError,
@@ -489,7 +493,7 @@
* so will the returned stream.
*/
Stream<T> take(int count) {
- return new TakeStream(this, count);
+ return new _TakeStream(this, count);
}
/**
@@ -501,14 +505,14 @@
* a value that [test] doesn't accept.
*/
Stream<T> takeWhile(bool test(T value)) {
- return new TakeWhileStream(this, test);
+ return new _TakeWhileStream(this, test);
}
/**
* Skips the first [count] data events from this stream.
*/
Stream<T> skip(int count) {
- return new SkipStream(this, count);
+ return new _SkipStream(this, count);
}
/**
@@ -520,7 +524,7 @@
* event data, the returned stream will have the same events as this stream.
*/
Stream<T> skipWhile(bool test(T value)) {
- return new SkipWhileStream(this, test);
+ return new _SkipWhileStream(this, test);
}
/**
@@ -533,7 +537,7 @@
* omitted, the '==' operator on the last provided data element is used.
*/
Stream<T> distinct([bool equals(T previous, T next)]) {
- return new DistinctStream(this, equals);
+ return new _DistinctStream(this, equals);
}
/**
@@ -546,7 +550,9 @@
_FutureImpl<T> future = new _FutureImpl<T>();
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
future._setValue(value);
subscription.cancel();
return;
@@ -570,7 +576,9 @@
bool foundResult = false;
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
foundResult = true;
result = value;
},
@@ -597,7 +605,9 @@
bool foundResult = false;
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
if (foundResult) {
// This is the second element we get.
Error error = new StateError("More than one element");
@@ -638,7 +648,9 @@
_FutureImpl<T> future = new _FutureImpl<T>();
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
_runUserCode(
() => test(value),
(bool isMatch) {
@@ -676,7 +688,9 @@
bool foundResult = false;
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
_runUserCode(
() => true == test(value),
(bool isMatch) {
@@ -717,7 +731,9 @@
bool foundResult = false;
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
_runUserCode(
() => true == test(value),
(bool isMatch) {
@@ -761,7 +777,9 @@
_FutureImpl<T> future = new _FutureImpl<T>();
StreamSubscription subscription;
subscription = this.listen(
- (T value) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ (/*T*/ value) {
if (index == 0) {
future._setValue(value);
subscription.cancel();
@@ -880,6 +898,7 @@
Future<T> consume(Stream<S> stream);
}
+
/**
* The target of a [Stream.transform] call.
*
@@ -890,17 +909,212 @@
/**
* Create a [StreamTransformer] that delegates events to the given functions.
*
- * If a parameter is omitted, a default handler is used that forwards the
- * event directly to the sink.
+ * This is actually a [StreamEventTransformer] where the event handling is
+ * performed by the function arguments.
+ * If an argument is omitted, it acts as the corresponding default method from
+ * [StreamEventTransformer].
*
- * Pauses on the returned stream are forwarded to the input stream as well.
+ * Example use:
+ *
+ * stringStream.transform(new StreamTransformer<String, String>(
+ * handleData: (Strung value, StreamSink<String> sink) {
+ * sink.add(value);
+ * sink.add(value); // Duplicate the incoming events.
+ * }));
+ *
*/
- factory StreamTransformer.from({
- void onData(S data, StreamSink<T> sink),
- void onError(AsyncError error, StreamSink<T> sink),
- void onDone(StreamSink<T> sink)}) {
- return new _StreamTransformerImpl<S, T>(onData, onError, onDone);
+ factory StreamTransformer({
+ void handleData(S data, StreamSink<T> sink),
+ void handleError(AsyncError error, StreamSink<T> sink),
+ void handleDone(StreamSink<T> sink)}) {
+ return new _StreamTransformerImpl<S, T>(handleData,
+ handleError,
+ handleDone);
}
Stream<T> bind(Stream<S> stream);
}
+
+
+/**
+ * Base class for transformers that modifies stream events.
+ *
+ * A [StreamEventTransformer] transforms incoming Stream
+ * events of one kind into outgoing events of (possibly) another kind.
+ *
+ * Subscribing on the stream returned by [bind] is the same as subscribing on
+ * the source stream, except that events are passed through the [transformer]
+ * before being emitted. The transformer may generate any number and
+ * types of events for each incoming event. Pauses on the returned
+ * subscription are forwarded to this stream.
+ *
+ * An example that duplicates all data events:
+ *
+ * class DoubleTransformer<T> extends StreamEventTransformerBase<T, T> {
+ * void handleData(T data, StreamSink<T> sink) {
+ * sink.add(value);
+ * sink.add(value);
+ * }
+ * }
+ * someTypeStream.transform(new DoubleTransformer<Type>());
+ *
+ * The default implementations of the "handle" methods forward
+ * the events unmodified. If using the default [handleData] the generic type [T]
+ * needs to be assignable to [S].
+ */
+abstract class StreamEventTransformer<S, T> implements StreamTransformer<S, T> {
+ const StreamEventTransformer();
+
+ Stream<T> bind(Stream<S> source) {
+ return new EventTransformStream<S, T>(source, this);
+ }
+
+ /**
+ * Act on incoming data event.
+ *
+ * The method may generate any number of events on the sink, but should
+ * not throw.
+ */
+ void handleData(S event, StreamSink<T> sink) {
+ var data = event;
+ sink.add(data);
+ }
+
+ /**
+ * Act on incoming error event.
+ *
+ * The method may generate any number of events on the sink, but should
+ * not throw.
+ */
+ void handleError(AsyncError error, StreamSink<T> sink) {
+ sink.signalError(error);
+ }
+
+ /**
+ * Act on incoming done event.
+ *
+ * The method may generate any number of events on the sink, but should
+ * not throw.
+ */
+ void handleDone(StreamSink<T> sink){
+ sink.close();
+ }
+}
+
+
+/**
+ * Stream that transforms another stream by intercepting and replacing events.
+ *
+ * This [Stream] is a transformation of a source stream. Listening on this
+ * stream is the same as listening on the source stream, except that events
+ * are intercepted and modified by a [StreamEventTransformer] before becoming
+ * events on this stream.
+ */
+class EventTransformStream<S, T> extends Stream<T> {
+ final Stream<S> _source;
+ final StreamEventTransformer _transformer;
+ EventTransformStream(Stream<S> source,
+ StreamEventTransformer<S, T> transformer)
+ : _source = source, _transformer = transformer;
+
+ StreamSubscription<T> listen(void onData(T data),
+ { void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError }) {
+ return new _EventTransformStreamSubscription(_source, _transformer,
+ onData, onError, onDone,
+ unsubscribeOnError);
+ }
+}
+
+class _EventTransformStreamSubscription<S, T>
+ extends _BaseStreamSubscription<T>
+ implements _StreamOutputSink<T> {
+ /** The transformer used to transform events. */
+ final StreamEventTransformer<S, T> _transformer;
+ /** Whether to unsubscribe when emitting an error. */
+ final bool _unsubscribeOnError;
+ /** Source of incoming events. */
+ StreamSubscription<S> _subscription;
+ /** Cached StreamSink wrapper for this class. */
+ StreamSink<T> _sink;
+
+ _EventTransformStreamSubscription(Stream<S> source,
+ this._transformer,
+ void onData(T data),
+ void onError(AsyncError error),
+ void onDone(),
+ this._unsubscribeOnError)
+ : super(onData, onError, onDone) {
+ _sink = new _StreamOutputSinkWrapper<T>(this);
+ _subscription = source.listen(_handleData,
+ onError: _handleError,
+ onDone: _handleDone);
+ }
+
+ void pause([Future pauseSignal]) {
+ if (_subscription != null) _subscription.pause(pauseSignal);
+ }
+
+ void resume() {
+ if (_subscription != null) _subscription.resume();
+ }
+
+ void cancel() {
+ if (_subscription != null) {
+ _subscription.cancel();
+ _subscription = null;
+ }
+ }
+
+ void _handleData(S data) {
+ try {
+ _transformer.handleData(data, _sink);
+ } catch (e, s) {
+ _sendError(_asyncError(e, s));
+ }
+ }
+
+ void _handleError(AsyncError error) {
+ try {
+ _transformer.handleError(error, _sink);
+ } catch (e, s) {
+ _sendError(_asyncError(e, s, error));
+ }
+ }
+
+ void _handleDone() {
+ try {
+ _transformer.handleDone(_sink);
+ } catch (e, s) {
+ _sendError(_asyncError(e, s));
+ }
+ }
+
+ // StreamOutputSink interface.
+ void _sendData(T data) {
+ _onData(data);
+ }
+
+ void _sendError(AsyncError error) {
+ _onError(error);
+ if (_unsubscribeOnError) {
+ cancel();
+ }
+ }
+
+ void _sendDone() {
+ // It's ok to cancel even if we have been unsubscribed already.
+ cancel();
+ _onDone();
+ }
+}
+
+class _StreamOutputSinkWrapper<T> implements StreamSink<T> {
+ _StreamOutputSink _sink;
+ _StreamOutputSinkWrapper(this._sink);
+
+ void add(T data) => _sink._sendData(data);
+ void signalError(AsyncError error) => _sink._sendError(error);
+ void close() => _sink._sendDone();
+}
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 28c41b0..caa6318 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -62,10 +62,10 @@
// ------------------------------------------------------------------
// Stream interface.
- StreamSubscription listen(void onData(T data),
- { void onError(AsyncError error),
- void onDone(),
- bool unsubscribeOnError }) {
+ StreamSubscription<T> listen(void onData(T data),
+ { void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError }) {
if (_isComplete) {
return new _DoneSubscription(onDone);
}
@@ -73,7 +73,7 @@
if (onError == null) onError = _nullErrorHandler;
if (onDone == null) onDone = _nullDoneHandler;
unsubscribeOnError = identical(true, unsubscribeOnError);
- _StreamListener subscription =
+ _StreamSubscriptionImpl subscription =
_createSubscription(onData, onError, onDone, unsubscribeOnError);
_addListener(subscription);
return subscription;
@@ -1092,8 +1092,10 @@
bool get _isComplete => _timer == null && _pauseCount == 0;
void onData(void handleAction(T value)) {}
- void onError(void handleError(StateError error)) {}
- void onDone(void handleDone(T value)) {
+
+ void onError(void handleError(AsyncError error)) {}
+
+ void onDone(void handleDone()) {
_handler = handleDone;
}
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index 1945bb2..8867ee0 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -53,20 +53,23 @@
bool get isBroadcast => _source.isBroadcast;
- bool asBroadcastStream() => _source.asBroadcastStream;
-
- StreamSubscription listen(void onData(T value),
- { void onError(AsyncError error),
- void onDone(),
- bool unsubscribeOnError }) {
+ StreamSubscription<T> listen(void onData(T value),
+ { void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError }) {
if (onData == null) onData = _nullDataHandler;
if (onError == null) onError = _nullErrorHandler;
if (onDone == null) onDone = _nullDoneHandler;
unsubscribeOnError = identical(true, unsubscribeOnError);
- StreamSubscription subscription =
- new _ForwardingStreamSubscription<S, T>(
- this, onData, onError, onDone, unsubscribeOnError);
- return subscription;
+ return _createSubscription(onData, onError, onDone, unsubscribeOnError);
+ }
+
+ StreamSubscription<T> _createSubscription(void onData(T value),
+ void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError) {
+ return new _ForwardingStreamSubscription<S, T>(
+ this, onData, onError, onDone, unsubscribeOnError);
}
// Override the following methods in subclasses to change the behavior.
@@ -86,33 +89,26 @@
}
/**
- * Abstract superclass for subscriptions that forward to other subscriptions.
+ * Common behavior of [StreamSubscription] classes.
+ *
+ * Stores and allows updating of the event handlers of a [StreamSubscription].
*/
-class _ForwardingStreamSubscription<S, T>
- implements StreamSubscription<T>, _StreamOutputSink<T> {
- final _ForwardingStream<S, T> _stream;
+abstract class _BaseStreamSubscription<T> implements StreamSubscription<T> {
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
var /* _DataHandler<T> */ _onData;
_ErrorHandler _onError;
_DoneHandler _onDone;
- StreamSubscription<S> _subscription;
-
- _ForwardingStreamSubscription(this._stream,
- this._onData,
- this._onError,
- this._onDone,
- bool unsubscribeOnError) {
- _subscription =
- _stream._source.listen(_handleData,
- onError: _handleError,
- onDone: _handleDone,
- unsubscribeOnError: unsubscribeOnError);
+ _BaseStreamSubscription(this._onData,
+ this._onError,
+ this._onDone) {
+ if (_onData == null) _onData = _nullDataHandler;
+ if (_onError == null) _onError = _nullErrorHandler;
+ if (_onDone == null) _onDone = _nullDoneHandler;
}
// StreamSubscription interface.
-
void onData(void handleData(T event)) {
if (handleData == null) handleData = _nullDataHandler;
_onData = handleData;
@@ -128,6 +124,39 @@
_onDone = handleDone;
}
+ void pause([Future resumeSignal]);
+
+ void resume();
+
+ void cancel();
+}
+
+
+/**
+ * Abstract superclass for subscriptions that forward to other subscriptions.
+ */
+class _ForwardingStreamSubscription<S, T>
+ extends _BaseStreamSubscription<T> implements _StreamOutputSink<T> {
+ final _ForwardingStream<S, T> _stream;
+ final bool _unsubscribeOnError;
+
+ StreamSubscription<S> _subscription;
+
+ _ForwardingStreamSubscription(this._stream,
+ void onData(T data),
+ void onError(AsyncError error),
+ void onDone(),
+ this._unsubscribeOnError)
+ : super(onData, onError, onDone) {
+ // Don't unsubscribe on incoming error, only if we send an error forwards.
+ _subscription =
+ _stream._source.listen(_handleData,
+ onError: _handleError,
+ onDone: _handleDone);
+ }
+
+ // StreamSubscription interface.
+
void pause([Future resumeSignal]) {
if (_subscription == null) {
throw new StateError("Subscription has been unsubscribed");
@@ -158,6 +187,10 @@
void _sendError(AsyncError error) {
_onError(error);
+ if (_unsubscribeOnError) {
+ _subscription.cancel();
+ _subscription = null;
+ }
}
void _sendDone() {
@@ -171,7 +204,9 @@
// Methods used as listener on source subscription.
- void _handleData(S data) {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ void _handleData(/*S*/ data) {
_stream._handleData(data, this);
}
@@ -190,10 +225,10 @@
typedef bool _Predicate<T>(T value);
-class WhereStream<T> extends _ForwardingStream<T, T> {
+class _WhereStream<T> extends _ForwardingStream<T, T> {
final _Predicate<T> _test;
- WhereStream(Stream<T> source, bool test(T value))
+ _WhereStream(Stream<T> source, bool test(T value))
: _test = test, super(source);
void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -216,10 +251,10 @@
/**
* A stream pipe that converts data events before passing them on.
*/
-class MapStream<S, T> extends _ForwardingStream<S, T> {
+class _MapStream<S, T> extends _ForwardingStream<S, T> {
final _Transformation _transform;
- MapStream(Stream<S> source, T transform(S event))
+ _MapStream(Stream<S> source, T transform(S event))
: this._transform = transform, super(source);
void _handleData(S inputEvent, _StreamOutputSink<T> sink) {
@@ -237,10 +272,10 @@
/**
* A stream pipe that converts data events before passing them on.
*/
-class ExpandStream<S, T> extends _ForwardingStream<S, T> {
+class _ExpandStream<S, T> extends _ForwardingStream<S, T> {
final _Transformation<S, Iterable<T>> _expand;
- ExpandStream(Stream<S> source, Iterable<T> expand(S event))
+ _ExpandStream(Stream<S> source, Iterable<T> expand(S event))
: this._expand = expand, super(source);
void _handleData(S inputEvent, _StreamOutputSink<T> sink) {
@@ -264,11 +299,11 @@
* A stream pipe that converts or disposes error events
* before passing them on.
*/
-class HandleErrorStream<T> extends _ForwardingStream<T, T> {
+class _HandleErrorStream<T> extends _ForwardingStream<T, T> {
final _ErrorTransformation _transform;
final _ErrorTest _test;
- HandleErrorStream(Stream<T> source,
+ _HandleErrorStream(Stream<T> source,
void transform(AsyncError event),
bool test(error))
: this._transform = transform, this._test = test, super(source);
@@ -297,10 +332,10 @@
}
-class TakeStream<T> extends _ForwardingStream<T, T> {
+class _TakeStream<T> extends _ForwardingStream<T, T> {
int _remaining;
- TakeStream(Stream<T> source, int count)
+ _TakeStream(Stream<T> source, int count)
: this._remaining = count, super(source) {
// This test is done early to avoid handling an async error
// in the _handleData method.
@@ -321,10 +356,10 @@
}
-class TakeWhileStream<T> extends _ForwardingStream<T, T> {
+class _TakeWhileStream<T> extends _ForwardingStream<T, T> {
final _Predicate<T> _test;
- TakeWhileStream(Stream<T> source, bool test(T value))
+ _TakeWhileStream(Stream<T> source, bool test(T value))
: this._test = test, super(source);
void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -345,10 +380,10 @@
}
}
-class SkipStream<T> extends _ForwardingStream<T, T> {
+class _SkipStream<T> extends _ForwardingStream<T, T> {
int _remaining;
- SkipStream(Stream<T> source, int count)
+ _SkipStream(Stream<T> source, int count)
: this._remaining = count, super(source) {
// This test is done early to avoid handling an async error
// in the _handleData method.
@@ -364,11 +399,11 @@
}
}
-class SkipWhileStream<T> extends _ForwardingStream<T, T> {
+class _SkipWhileStream<T> extends _ForwardingStream<T, T> {
final _Predicate<T> _test;
bool _hasFailed = false;
- SkipWhileStream(Stream<T> source, bool test(T value))
+ _SkipWhileStream(Stream<T> source, bool test(T value))
: this._test = test, super(source);
void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -393,13 +428,13 @@
typedef bool _Equality<T>(T a, T b);
-class DistinctStream<T> extends _ForwardingStream<T, T> {
+class _DistinctStream<T> extends _ForwardingStream<T, T> {
static var _SENTINEL = new Object();
_Equality<T> _equals;
var _previous = _SENTINEL;
- DistinctStream(Stream<T> source, bool equals(T a, T b))
+ _DistinctStream(Stream<T> source, bool equals(T a, T b))
: _equals = equals, super(source);
void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -426,79 +461,28 @@
}
}
+// Stream transformations and event transformations.
typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink);
typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink);
typedef void _TransformDoneHandler<T>(StreamSink<T> sink);
-/**
- * A stream transformer that intercepts all events and can generate any event as
- * output.
- *
- * Each incoming event on the source stream is passed to the corresponding
- * provided event handler, along with a [StreamSink] linked to the output
- * Stream.
- * The handler can then decide exactly which events to send to the output.
- */
-class _StreamTransformerImpl<S, T> implements StreamTransformer<S, T> {
- final _TransformDataHandler<S, T> _onData;
- final _TransformErrorHandler<T> _onError;
- final _TransformDoneHandler<T> _onDone;
- StreamSink<T> _sink;
-
- _StreamTransformerImpl(void onData(S data, StreamSink<T> sink),
- void onError(AsyncError data, StreamSink<T> sink),
- void onDone(StreamSink<T> sink))
- : this._onData = (onData == null ? _defaultHandleData : onData),
- this._onError = (onError == null ? _defaultHandleError : onError),
- this._onDone = (onDone == null ? _defaultHandleDone : onDone);
-
- Stream<T> bind(Stream<S> source) {
- Stream<T> stream = new _SingleStreamImpl<T>();
- // Cache a Sink object to avoid creating a new one for each event.
- _sink = new _StreamImplSink(stream);
- source.listen(_handleData, onError: _handleError, onDone: _handleDone);
- return stream;
- }
-
- void _handleData(S data) {
- try {
- _onData(data, _sink);
- } catch (e, s) {
- _stream._signalError(_asyncError(e, s));
- }
- }
-
- void _handleError(AsyncError error) {
- try {
- _onError(error, _sink);
- } catch (e, s) {
- _stream._signalError(_asyncError(e, s, error));
- }
- }
-
- void _handleDone() {
- try {
- _onDone(_sink);
- } catch (e, s) {
- _stream._signalError(_asyncError(e, s));
- }
- }
-
- /** Default data handler forwards all data. */
- static void _defaultHandleData(var data, StreamSink sink) {
- sink.add(data);
- }
- /** Default error handler forwards all errors. */
- static void _defaultHandleError(AsyncError error, StreamSink sink) {
- sink.signalError(error);
- }
- /** Default done handler forwards done. */
- static void _defaultHandleDone(StreamSink sink) {
- sink.close();
- }
+/** Default data handler forwards all data. */
+void _defaultHandleData(var data, StreamSink sink) {
+ sink.add(data);
}
+/** Default error handler forwards all errors. */
+void _defaultHandleError(AsyncError error, StreamSink sink) {
+ sink.signalError(error);
+}
+
+/** Default done handler forwards done. */
+void _defaultHandleDone(StreamSink sink) {
+ sink.close();
+}
+
+
/** Creates a [StreamSink] from a [_StreamImpl]'s input methods. */
class _StreamImplSink<T> implements StreamSink<T> {
_StreamImpl<T> _target;
@@ -508,4 +492,43 @@
void close() { _target._close(); }
}
+/**
+ * A [StreamTransformer] that modifies stream events.
+ *
+ * This class is used by [StreamTransformer]'s factory constructor.
+ * It is actually an [StreamEventTransformer] where the functions used to
+ * modify the events are passed as constructor arguments.
+ *
+ * If an argument is omitted, it acts as the default method from
+ * [StreamEventTransformer].
+ */
+class _StreamTransformerImpl<S, T> extends StreamEventTransformer<S, T> {
+ // TODO(ahe): Restore type when feature is implemented in dart2js
+ // checked mode. http://dartbug.com/7733
+ final Function /*_TransformDataHandler<S, T>*/ _handleData;
+ final _TransformErrorHandler<T> _handleError;
+ final _TransformDoneHandler<T> _handleDone;
+
+ _StreamTransformerImpl(void handleData(S data, StreamSink<T> sink),
+ void handleError(AsyncError data, StreamSink<T> sink),
+ void handleDone(StreamSink<T> sink))
+ : this._handleData = (handleData == null ? _defaultHandleData
+ : handleData),
+ this._handleError = (handleError == null ? _defaultHandleError
+ : handleError),
+ this._handleDone = (handleDone == null ? _defaultHandleDone
+ : handleDone);
+
+ void handleData(S data, StreamSink<T> sink) {
+ _handleData(data, sink);
+ }
+
+ void handleError(AsyncError error, StreamSink<T> sink) {
+ _handleError(error, sink);
+ }
+
+ void handleDone(StreamSink<T> sink) {
+ _handleDone(sink);
+ }
+}
diff --git a/sdk/lib/chrome/dart2js/chrome_dart2js.dart b/sdk/lib/chrome/dart2js/chrome_dart2js.dart
index bba2925..7c982f4 100644
--- a/sdk/lib/chrome/dart2js/chrome_dart2js.dart
+++ b/sdk/lib/chrome/dart2js/chrome_dart2js.dart
@@ -1,6 +1,8 @@
library chrome;
import 'dart:_foreign_helper' show JS;
+import 'dart:html_common';
+import 'dart:html';
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -10,39 +12,975 @@
+
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * A set of utilities for use with the Chrome Extension APIs.
+ *
+ * Allows for easy access to required JS objects.
+ */
+
+/**
+ * A dart object, that is convertible to JS. Used for creating objects in dart,
+ * then passing them to JS.
+ *
+ * Objects that are passable to JS need to implement this interface.
+ */
+abstract class ChromeObject {
+ /*
+ * Default Constructor
+ *
+ * Called by child objects during their regular construction.
+ */
+ ChromeObject() : _jsObject = JS('var', '{}');
+
+ /*
+ * Internal proxy constructor
+ *
+ * Creates a new Dart object using this existing proxy.
+ */
+ ChromeObject._proxy(this._jsObject);
+
+ /*
+ * JS Object Representation
+ */
+ Object _jsObject;
+}
+
+/**
+ * Useful functions for converting arguments.
+ */
+
+/**
+ * Converts the given map-type argument to js-friendly format, recursively.
+ * Returns the new Map object.
+ */
+Object _convertMapArgument(Map argument) {
+ Map m = new Map();
+ for (Object key in argument.keys)
+ m[key] = convertArgument(argument[key]);
+ return convertDartToNative_Dictionary(m);
+}
+
+/**
+ * Converts the given list-type argument to js-friendly format, recursively.
+ * Returns the new List object.
+ */
+List _convertListArgument(List argument) {
+ List l = new List();
+ for (var i = 0; i < argument.length; i ++)
+ l.add(convertArgument(argument[i]));
+ return l;
+}
+
+/**
+ * Converts the given argument Object to js-friendly format, recursively.
+ *
+ * Flattens out all Chrome objects into their corresponding ._toMap()
+ * definitions, then converts them to JS objects.
+ *
+ * Returns the new argument.
+ *
+ * Cannot be used for functions.
+ */
+Object convertArgument(var argument) {
+ if (argument == null)
+ return argument;
+
+ if (argument is num || argument is String || argument is bool)
+ return argument;
+
+ if (argument is ChromeObject)
+ return argument._jsObject;
+
+ if (argument is List)
+ return _convertListArgument(argument);
+
+ if (argument is Map)
+ return _convertMapArgument(argument);
+
+ if (argument is Function)
+ throw new Exception("Cannot serialize Function argument ${argument}.");
+
+ // TODO(sashab): Try and detect whether the argument is already serialized.
+ return argument;
+}
+
+/// Description of a declarative rule for handling events.
+class Rule extends ChromeObject {
+ /*
+ * Public (Dart) constructor
+ */
+ Rule({String id, List conditions, List actions, int priority}) {
+ this.id = id;
+ this.conditions = conditions;
+ this.actions = actions;
+ this.priority = priority;
+ }
+
+ /*
+ * Private (JS) constructor
+ */
+ Rule._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ String get id => JS('String', '#.id', this._jsObject);
+
+ void set id(String id) {
+ JS('void', '#.id = #', this._jsObject, id);
+ }
+
+ // TODO(sashab): Wrap these generic Lists somehow.
+ List get conditions => JS('List', '#.conditions', this._jsObject);
+
+ void set conditions(List conditions) {
+ JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions));
+ }
+
+ // TODO(sashab): Wrap these generic Lists somehow.
+ List get actions => JS('List', '#.actions', this._jsObject);
+
+ void set actions(List actions) {
+ JS('void', '#.actions = #', this._jsObject, convertArgument(actions));
+ }
+
+ int get priority => JS('int', '#.priority', this._jsObject);
+
+ void set priority(int priority) {
+ JS('void', '#.priority = #', this._jsObject, priority);
+ }
+
+}
+
+/**
+ * The Event class.
+ *
+ * Chrome Event classes extend this interface.
+ *
+ * e.g.
+ *
+ * // chrome.app.runtime.onLaunched
+ * class Event_ChromeAppRuntimeOnLaunched extends Event {
+ * // constructor, passing the arity of the callback
+ * Event_ChromeAppRuntimeOnLaunched(jsObject) :
+ * super._(jsObject, 1);
+ *
+ * // methods, strengthening the Function parameter specificity
+ * void addListener(void callback(LaunchData launchData))
+ * => super.addListener(callback);
+ * void removeListener(void callback(LaunchData launchData))
+ * => super.removeListener(callback);
+ * bool hasListener(void callback(LaunchData launchData))
+ * => super.hasListener(callback);
+ * }
+ *
+ */
+class Event {
+ /*
+ * JS Object Representation
+ */
+ Object _jsObject;
+
+ /*
+ * Number of arguments the callback takes.
+ */
+ int _callbackArity;
+
+ /*
+ * Private constructor
+ */
+ Event._(this._jsObject, this._callbackArity);
+
+ /*
+ * Methods
+ */
+
+ /// Registers an event listener <em>callback</em> to an event.
+ void addListener(Function callback) =>
+ JS('void',
+ '#.addListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /// Deregisters an event listener <em>callback</em> from an event.
+ void removeListener(Function callback) =>
+ JS('void',
+ '#.removeListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /// Returns True if <em>callback</em> is registered to the event.
+ bool hasListener(Function callback) =>
+ JS('bool',
+ '#.hasListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /// Returns true if any event listeners are registered to the event.
+ bool hasListeners() =>
+ JS('bool',
+ '#.hasListeners()',
+ this._jsObject
+ );
+
+ /// Registers rules to handle events.
+ ///
+ /// [eventName] is the name of the event this function affects and [rules] are
+ /// the rules to be registered. These do not replace previously registered
+ /// rules. [callback] is called with registered rules.
+ ///
+ void addRules(String eventName, List<Rule> rules,
+ [void callback(List<Rule> rules)]) {
+ // proxy the callback
+ void __proxy_callback(List rules) {
+ if (?callback) {
+ List<Rule> __proxy_rules = new List<Rule>();
+
+ for (Object o in rules)
+ __proxy_rules.add(new Rule._proxy(o));
+
+ callback(__proxy_rules);
+ }
+ }
+
+ JS('void',
+ '#.addRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(rules),
+ convertDartClosureToJS(__proxy_callback, 1)
+ );
+ }
+
+ /// Returns currently registered rules.
+ ///
+ /// [eventName] is the name of the event this function affects and, if an array
+ /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+ /// this array are returned. [callback] is called with registered rules.
+ ///
+ void getRules(String eventName, [List<String> ruleIdentifiers,
+ void callback(List<Rule> rules)]) {
+ // proxy the callback
+ void __proxy_callback(List rules) {
+ if (?callback) {
+ List<Rule> __proxy_rules = new List<Rule>();
+
+ for (Object o in rules)
+ __proxy_rules.add(new Rule._proxy(o));
+
+ callback(__proxy_rules);
+ }
+ }
+
+ JS('void',
+ '#.getRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(ruleIdentifiers),
+ convertDartClosureToJS(__proxy_callback, 1)
+ );
+ }
+
+ /// Unregisters currently registered rules.
+ ///
+ /// [eventName] is the name of the event this function affects and, if an array
+ /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+ /// this array are unregistered. [callback] is called when the rules are
+ /// unregistered.
+ ///
+ void removeRules(String eventName, [List<String> ruleIdentifiers,
+ void callback()]) =>
+ JS('void',
+ '#.removeRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(ruleIdentifiers),
+ convertDartClosureToJS(callback, 0)
+ );
+}
+
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// This is an example of exposing chrome APIs in Dart and will be replaced with
-// the proper implementation in the future.
+// chrome.app
+class API_ChromeApp {
+ /*
+ * JS Variable
+ */
+ Object _jsObject;
-class AppModule {
- AppModule._();
+ /*
+ * Members
+ */
+ API_ChromeAppWindow window;
+ API_ChromeAppRuntime runtime;
- WindowModule get window => new WindowModule._();
-}
+ /*
+ * Constructor
+ */
+ API_ChromeApp(this._jsObject) {
+ var window_object = JS('', '#.window', this._jsObject);
+ if (window_object == null)
+ throw new UnsupportedError('Not supported by current browser.');
+ window = new API_ChromeAppWindow(window_object);
-class WindowModule {
- WindowModule._();
-
- void create(String url) {
- var chrome = JS('', 'chrome');
-
- if (chrome == null) {
- throw new UnsupportedError('Not supported by current browser');
- }
- var app = JS('', '#.app', chrome);
- if (app == null) {
- throw new UnsupportedError('Not supported by current browser');
- }
- var window = JS('', '#.window', app);
- if (app == null) {
- throw new UnsupportedError('Not supported by current browser');
- }
- JS('void', '#.create(#)', window, url);
+ var runtime_object = JS('', '#.runtime', this._jsObject);
+ if (runtime_object == null)
+ throw new UnsupportedError('Not supported by current browser.');
+ runtime = new API_ChromeAppRuntime(runtime_object);
}
}
-final app = new AppModule._();
+// chrome
+class API_Chrome {
+ /*
+ * JS Variable
+ */
+ Object _jsObject;
+
+ /*
+ * Members
+ */
+ API_ChromeApp app;
+
+ /*
+ * Constructor
+ */
+ API_Chrome() {
+ this._jsObject = JS("Object", "chrome");
+ if (this._jsObject == null)
+ throw new UnsupportedError('Not supported by current browser.');
+
+ var app_object = JS('', '#.app', this._jsObject);
+ if (app_object == null)
+ throw new UnsupportedError('Not supported by current browser.');
+ app = new API_ChromeApp(app_object);
+ }
+}
+
+// The final chrome objects
+final API_Chrome chrome = new API_Chrome();
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// from app_runtime.idl
+
+/**
+ * Types
+ */
+
+/// A WebIntents intent object. Deprecated.
+class Intent extends ChromeObject {
+ /*
+ * Public (Dart) constructor
+ */
+ Intent({String action, String type, var data}) {
+ this.action = action;
+ this.type = type;
+ this.data = data;
+ }
+
+ /*
+ * Private (JS) constructor
+ */
+ Intent._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+
+ /// The WebIntent being invoked.
+ String get action => JS('String', '#.action', this._jsObject);
+
+ void set action(String action) {
+ JS('void', '#.action = #', this._jsObject, action);
+ }
+
+ /// The MIME type of the data.
+ String get type => JS('String', '#.type', this._jsObject);
+
+ void set type(String type) {
+ JS('void', '#.type = #', this._jsObject, type);
+ }
+
+ /// Data associated with the intent.
+ // TODO(sashab): What is the best way to serialize/return generic JS objects?
+ Object get data => JS('Object', '#.data', this._jsObject);
+
+ void set data(Object data) {
+ JS('void', '#.data = #', this._jsObject, convertArgument(data));
+ }
+
+ /*
+ * TODO(sashab): What is a NullCallback() type?
+ * Add postResult and postFailure once understanding what this type is, and
+ * once there is a way to pass functions back from JS.
+ */
+}
+
+class LaunchItem extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ LaunchItem({FileEntry entry, String type}) {
+ this.entry = entry;
+ this.type = type;
+ }
+
+ /*
+ * Private constructor
+ */
+ LaunchItem._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+
+ /// FileEntry for the file.
+ FileEntry get entry => JS('FileEntry', '#.entry', this._jsObject);
+
+ void set entry(FileEntry entry) {
+ JS('void', '#.entry = #', this._jsObject, entry);
+ }
+
+ /// The MIME type of the file.
+ String get type => JS('String', '#.type', this._jsObject);
+
+ void set type(String type) {
+ JS('void', '#.type = #', this._jsObject, type);
+ }
+}
+
+/// Optional data for the launch.
+class LaunchData extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ LaunchData({Intent intent, String id, List<LaunchItem> items}) {
+ this.intent = intent;
+ this.id = id;
+ this.items = items;
+ }
+
+ /*
+ * Private constructor
+ */
+ LaunchData._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ Intent get intent => new Intent._proxy(JS('', '#.intent', this._jsObject));
+
+ void set intent(Intent intent) {
+ JS('void', '#.intent = #', this._jsObject, convertArgument(intent));
+ }
+
+ /// The id of the file handler that the app is being invoked with.
+ String get id => JS('String', '#.id', this._jsObject);
+
+ void set id(String id) {
+ JS('void', '#.id = #', this._jsObject, id);
+ }
+
+ List<LaunchItem> get items() {
+ List<LaunchItem> items_final = new List<LaunchItem>();
+ for (var o in JS('List', '#.items', this._jsObject)) {
+ items_final.add(new LaunchItem._proxy(o));
+ }
+ return items_final;
+ }
+
+ void set items(List<LaunchItem> items) {
+ JS('void', '#.items = #', this._jsObject, convertArgument(items));
+ }
+}
+
+class IntentResponse extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ IntentResponse({int intentId, bool success, Object data}) {
+ this.intentId = intentId;
+ this.success = success;
+ this.data = data;
+ }
+
+ /*
+ * Private constructor
+ */
+ IntentResponse._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+
+ /// Identifies the intent.
+ int get intentId => JS('int', '#.intentId', this._jsObject);
+
+ void set intentId(int intentId) {
+ JS('void', '#.intentId = #', this._jsObject, intentId);
+ }
+
+ /// Was this intent successful? (i.e., postSuccess vs postFailure).
+ bool get success => JS('bool', '#.success', this._jsObject);
+
+ void set success(bool success) {
+ JS('void', '#.success = #', this._jsObject, success);
+ }
+
+ /// Data associated with the intent response.
+ // TODO(sashab): What's the best way to serialize/return generic JS objects?
+ Object get data => JS('Object', '#.data', this._jsObject);
+
+ void set data(Object data) {
+ JS('void', '#.data = #', this._jsObject, convertArgument(data));
+ }
+}
+
+/**
+ * Events
+ */
+
+/// Fired at Chrome startup to apps that were running when Chrome last shut
+/// down.
+class Event_ChromeAppRuntimeOnRestarted extends Event {
+ /*
+ * Override callback type definitions
+ */
+ void addListener(void callback())
+ => super.addListener(callback);
+ void removeListener(void callback())
+ => super.removeListener(callback);
+ bool hasListener(void callback())
+ => super.hasListener(callback);
+
+ /*
+ * Constructor
+ */
+ Event_ChromeAppRuntimeOnRestarted(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when an app is launched from the launcher or in response to a web
+/// intent.
+class Event_ChromeAppRuntimeOnLaunched extends Event {
+ /*
+ * Override callback type definitions
+ */
+ void addListener(void callback(LaunchData launchData))
+ => super.addListener(callback);
+ void removeListener(void callback(LaunchData launchData))
+ => super.removeListener(callback);
+ bool hasListener(void callback(LaunchData launchData))
+ => super.hasListener(callback);
+
+ /*
+ * Constructor
+ */
+ Event_ChromeAppRuntimeOnLaunched(jsObject) : super._(jsObject, 1);
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppRuntime {
+ /*
+ * API connection
+ */
+ Object _jsObject;
+
+ /*
+ * Events
+ */
+ Event_ChromeAppRuntimeOnRestarted onRestarted;
+ Event_ChromeAppRuntimeOnLaunched onLaunched;
+
+ /*
+ * Functions
+ */
+ void postIntentResponse(IntentResponse intentResponse) =>
+ JS('void', '#.postIntentResponse(#)', this._jsObject,
+ convertArgument(intentResponse));
+
+ /*
+ * Constructor
+ */
+ API_ChromeAppRuntime(this._jsObject) {
+ onRestarted = new Event_ChromeAppRuntimeOnRestarted(JS('Object',
+ '#.onRestarted',
+ this._jsObject));
+ onLaunched = new Event_ChromeAppRuntimeOnLaunched(JS('Object',
+ '#.onLaunched',
+ this._jsObject));
+ }
+}
+
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// from app.window.idl
+
+/**
+ * Types
+ */
+class CreateWindowOptions extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ CreateWindowOptions({String id, int defaultWidth, int defaultHeight,
+ int defaultLeft, int defaultTop, int width, int height, int left, int top,
+ int minWidth, int minHeight, int maxWidth, int maxHeight, String type,
+ String frame, Bounds bounds, bool hidden}) {
+ this.id = id;
+ this.defaultWidth = defaultWidth;
+ this.defaultHeight = defaultHeight;
+ this.defaultLeft = defaultLeft;
+ this.defaultTop = defaultTop;
+ this.width = width;
+ this.height = height;
+ this.left = left;
+ this.top = top;
+ this.minWidth = minWidth;
+ this.minHeight = minHeight;
+ this.maxWidth = maxWidth;
+ this.maxHeight = maxHeight;
+ this.type = type;
+ this.frame = frame;
+ this.bounds = bounds;
+ this.hidden = hidden;
+ }
+
+ /*
+ * Private constructor
+ */
+ CreateWindowOptions._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ /// Id to identify the window. This will be used to remember the size
+ /// and position of the window and restore that geometry when a window
+ /// with the same id (and no explicit size or position) is later opened.
+ String get id => JS('String', '#.id', this._jsObject);
+
+ void set id(String id) {
+ JS('void', '#.id = #', this._jsObject, id);
+ }
+
+ /// Default width of the window. (Deprecated; regular bounds act like this
+ /// now.)
+ int get defaultWidth => JS('int', '#.defaultWidth', this._jsObject);
+
+ void set defaultWidth(int defaultWidth) {
+ JS('void', '#.defaultWidth = #', this._jsObject, defaultWidth);
+ }
+
+ /// Default height of the window. (Deprecated; regular bounds act like this
+ /// now.)
+ int get defaultHeight => JS('int', '#.defaultHeight', this._jsObject);
+
+ void set defaultHeight(int defaultHeight) {
+ JS('void', '#.defaultHeight = #', this._jsObject, defaultHeight);
+ }
+
+ /// Default X coordinate of the window. (Deprecated; regular bounds act like
+ /// this now.)
+ int get defaultLeft => JS('int', '#.defaultLeft', this._jsObject);
+
+ void set defaultLeft(int defaultLeft) {
+ JS('void', '#.defaultLeft = #', this._jsObject, defaultLeft);
+ }
+
+ /// Default Y coordinate of the window. (Deprecated; regular bounds act like
+ /// this now.)
+ int get defaultTop => JS('int', '#.defaultTop', this._jsObject);
+
+ void set defaultTop(int defaultTop) {
+ JS('void', '#.defaultTop = #', this._jsObject, defaultTop);
+ }
+
+ /// Width of the window. (Deprecated; use 'bounds'.)
+ int get width => JS('int', '#.width', this._jsObject);
+
+ void set width(int width) {
+ JS('void', '#.width = #', this._jsObject, width);
+ }
+
+ /// Height of the window. (Deprecated; use 'bounds'.)
+ int get height => JS('int', '#.height', this._jsObject);
+
+ void set height(int height) {
+ JS('void', '#.height = #', this._jsObject, height);
+ }
+
+ /// X coordinate of the window. (Deprecated; use 'bounds'.)
+ int get left => JS('int', '#.left', this._jsObject);
+
+ void set left(int left) {
+ JS('void', '#.left = #', this._jsObject, left);
+ }
+
+ /// Y coordinate of the window. (Deprecated; use 'bounds'.)
+ int get top => JS('int', '#.top', this._jsObject);
+
+ void set top(int top) {
+ JS('void', '#.top = #', this._jsObject, top);
+ }
+
+ /// Minimium width of the window.
+ int get minWidth => JS('int', '#.minWidth', this._jsObject);
+
+ void set minWidth(int minWidth) {
+ JS('void', '#.minWidth = #', this._jsObject, minWidth);
+ }
+
+ /// Minimum height of the window.
+ int get minHeight => JS('int', '#.minHeight', this._jsObject);
+
+ void set minHeight(int minHeight) {
+ JS('void', '#.minHeight = #', this._jsObject, minHeight);
+ }
+
+ /// Maximum width of the window.
+ int get maxWidth => JS('int', '#.maxWidth', this._jsObject);
+
+ void set maxWidth(int maxWidth) {
+ JS('void', '#.maxWidth = #', this._jsObject, maxWidth);
+ }
+
+ /// Maximum height of the window.
+ int get maxHeight => JS('int', '#.maxHeight', this._jsObject);
+
+ void set maxHeight(int maxHeight) {
+ JS('void', '#.maxHeight = #', this._jsObject, maxHeight);
+ }
+
+ /// Window type: 'shell' (the default) is the only currently supported value.
+ String get type => JS('String', '#.type', this._jsObject);
+
+ void set type(String type) {
+ JS('void', '#.type = #', this._jsObject, type);
+ }
+
+ /// Frame type: 'none' or 'chrome' (defaults to 'chrome').
+ String get frame => JS('String', '#.frame', this._jsObject);
+
+ void set frame(String frame) {
+ JS('void', '#.frame = #', this._jsObject, frame);
+ }
+
+ /// Size of the content in the window (excluding the titlebar). If specified
+ /// in addition to any of the left/top/width/height parameters, this field
+ /// takes precedence. If a frameBounds is specified, the frameBounds take
+ /// precedence.
+ Bounds get bounds =>
+ new Bounds._proxy(JS('Bounds', '#.bounds', this._jsObject));
+
+ void set bounds(Bounds bounds) {
+ JS('void', '#.bounds = #', this._jsObject, convertArgument(bounds));
+ }
+
+ /// If true, the window will be created in a hidden state. Call show() on
+ /// the window to show it once it has been created. Defaults to false.
+ bool get hidden => JS('bool', '#.hidden', this._jsObject);
+
+ void set hidden(bool hidden) {
+ JS('void', '#.hidden = #', this._jsObject, hidden);
+ }
+}
+
+class Bounds extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ Bounds({int left, int top, int width, int height}) {
+ this.left = left;
+ this.top = top;
+ this.width = width;
+ this.height = height;
+ }
+
+ /*
+ * Private constructor
+ */
+ Bounds._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ int get left => JS('int', '#.left', this._jsObject);
+
+ void set left(int left) {
+ JS('void', '#.left = #', this._jsObject, left);
+ }
+
+ int get top => JS('int', '#.top', this._jsObject);
+
+ void set top(int top) {
+ JS('void', '#.top = #', this._jsObject, top);
+ }
+
+ int get width => JS('int', '#.width', this._jsObject);
+
+ void set width(int width) {
+ JS('void', '#.width = #', this._jsObject, width);
+ }
+
+ int get height => JS('int', '#.height', this._jsObject);
+
+ void set height(int height) {
+ JS('void', '#.height = #', this._jsObject, height);
+ }
+}
+
+class AppWindow extends ChromeObject {
+ /*
+ * Public constructor
+ * TODO(sashab): Does it make sense to be able to create a new AppWindow this
+ * way?
+ */
+ //AppWindow();
+
+ /*
+ * Private constructor
+ */
+ AppWindow._proxy(jsObject) : super._proxy(jsObject);
+
+ /*
+ * Public accessors
+ */
+ /// The JavaScript 'window' object for the created child.
+ // TODO(sashab, sra): Detect whether this is the current window, or an
+ // external one, and return an appropriately-typed object
+ WindowBase get contentWindow =>
+ JS("Window", "#.contentWindow", this._jsObject);
+
+ /*
+ * Functions
+ */
+
+ /// Focus the window.
+ void focus() => JS("void", "#.focus()", this._jsObject);
+
+ /// Minimize the window.
+ void minimize() => JS("void", "#.minimize()", this._jsObject);
+
+ /// Is the window minimized?
+ bool isMinimized() => JS("bool", "#.isMinimized()", this._jsObject);
+
+ /// Maximize the window.
+ void maximize() => JS("void", "#.maximize()", this._jsObject);
+
+ /// Is the window maximized?
+ bool isMaximized() => JS("bool", "c#.isMaximized()", this._jsObject);
+
+ /// Restore the window.
+ void restore() => JS("void", "#.restore()", this._jsObject);
+
+ /// Move the window to the position (|left|, |top|).
+ void moveTo(int left, int top) =>
+ JS("void", "#.moveTo(#, #)", this._jsObject, left, top);
+
+ /// Resize the window to |width|x|height| pixels in size.
+ void resizeTo(int width, int height) =>
+ JS("void", "#.resizeTo(#, #)", this._jsObject, width, height);
+
+ /// Draw attention to the window.
+ void drawAttention() => JS("void", "#.drawAttention()", this._jsObject);
+
+ /// Clear attention to the window.
+ void clearAttention() => JS("void", "#.clearAttention()", this._jsObject);
+
+ /// Close the window.
+ void close() => JS("void", "#.close()", this._jsObject);
+
+ /// Show the window. Does nothing if the window is already visible.
+ void show() => JS("void", "#.show()", this._jsObject);
+
+ /// Hide the window. Does nothing if the window is already hidden.
+ void hide() => JS("void", "#.hide()", this._jsObject);
+
+ /// Set the window's bounds.
+ void setBounds(Bounds bounds) =>
+ JS("void", "#.setBounds(#)", this._jsObject, convertArgument(bounds));
+
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppWindow {
+ /**
+ * JS object
+ */
+ Object _jsObject;
+
+ /**
+ * Constructor
+ */
+ API_ChromeAppWindow(this._jsObject);
+
+ /**
+ * Functions
+ */
+
+ /// Returns an <a href="#type-AppWindow">AppWindow</a> object for the
+ /// current script context (ie JavaScript 'window' object). This can also be
+ /// called on a handle to a script context for another page, for example:
+ /// otherWindow.chrome.app.window.current().
+ AppWindow current() =>
+ new AppWindow._proxy(JS("Object", "#.current()", this._jsObject));
+
+ /// The size and position of a window can be specified in a number of
+ /// different ways. The most simple option is not specifying anything at
+ /// all, in which case a default size and platform dependent position will
+ /// be used.
+ ///
+ /// Another option is to use the top/left and width/height properties,
+ /// which will always put the window at the specified coordinates with the
+ /// specified size.
+ ///
+ /// Yet another option is to give the window a (unique) id. This id is then
+ /// used to remember the size and position of the window whenever it is
+ /// moved or resized. This size and position is then used instead of the
+ /// specified bounds on subsequent opening of a window with the same id. If
+ /// you need to open a window with an id at a location other than the
+ /// remembered default, you can create it hidden, move it to the desired
+ /// location, then show it.
+ ///
+ /// You can also combine these various options, explicitly specifying for
+ /// example the size while having the position be remembered or other
+ /// combinations like that. Size and position are dealt with seperately,
+ /// but individual coordinates are not. So if you specify a top (or left)
+ /// coordinate, you should also specify a left (or top) coordinate, and
+ /// similar for size.
+ ///
+ /// If you specify both a regular and a default value for the same option
+ /// the regular value is the only one that takes effect.
+ void create(String url, [CreateWindowOptions options,
+ void callback(AppWindow created_window)]) {
+ void __proxy_callback(Object created_window) {
+ if (?callback)
+ callback(new AppWindow._proxy(created_window));
+ }
+
+ JS("void", "#.create(#, #, #)",
+ this._jsObject,
+ url,
+ convertArgument(options),
+ convertDartClosureToJS(__proxy_callback, 1)
+ );
+ }
+}
\ No newline at end of file
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 5d4b81c..d63b8be 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -13,5 +13,4 @@
part 'maps.dart';
part 'queue.dart';
part 'set.dart';
-part 'sort.dart';
part 'splay_tree.dart';
diff --git a/sdk/lib/collection/collection_sources.gypi b/sdk/lib/collection/collection_sources.gypi
index 3f1c117..b262c10 100644
--- a/sdk/lib/collection/collection_sources.gypi
+++ b/sdk/lib/collection/collection_sources.gypi
@@ -12,7 +12,6 @@
'maps.dart',
'queue.dart',
'set.dart',
- 'sort.dart',
'splay_tree.dart',
],
}
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index a8e89cc..0c45e21 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -313,12 +313,18 @@
return new WhereIterable(iterable, f);
}
+ static Iterable map(Iterable iterable, f(var element)) {
+ return new MappedIterable(iterable, f);
+ }
+
static List mappedByList(List list, f(var element)) {
+ // This is currently a List as well as an Iterable.
return new MappedList(list, f);
}
- static List takeList(List list, int n) {
+ static Iterable takeList(List list, int n) {
// The generic type is currently lost. It will be fixed with mixins.
+ // This is currently a List as well as an Iterable.
return new ListView(list, 0, n);
}
@@ -327,8 +333,9 @@
return new TakeWhileIterable(iterable, test);
}
- static List skipList(List list, int n) {
+ static Iterable skipList(List list, int n) {
// The generic type is currently lost. It will be fixed with mixins.
+ // This is currently a List as well as an Iterable.
return new ListView(list, n, null);
}
@@ -337,9 +344,13 @@
return new SkipWhileIterable(iterable, test);
}
+ static List reversedList(List l) {
+ return new ReversedListView(l, 0, null);
+ }
+
static void sortList(List l, int compare(a, b)) {
if (compare == null) compare = Comparable.compare;
- _Sort.sort(l, compare);
+ Sort.sort(l, compare);
}
}
@@ -439,7 +450,7 @@
=> IterableMixinWorkaround.mappedByList(list, f);
/** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
- static List takeList(List list, int n)
+ static Iterable takeList(List list, int n)
=> IterableMixinWorkaround.takeList(list, n);
/** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
@@ -447,110 +458,13 @@
=> IterableMixinWorkaround.takeWhile(iterable, test);
/** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
- static List skipList(List list, int n)
+ static Iterable skipList(List list, int n)
=> IterableMixinWorkaround.skipList(list, n);
/** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
static Iterable skipWhile(Iterable iterable, bool test(var value))
=> IterableMixinWorkaround.skipWhile(iterable, test);
- // TODO(jjb): visiting list should be an identityHashSet when it exists
-
- /**
- * Returns a string representing the specified collection. If the
- * collection is a [List], the returned string looks like this:
- * [:'[element0, element1, ... elementN]':]. The value returned by its
- * [toString] method is used to represent each element. If the specified
- * collection is not a list, the returned string looks like this:
- * [:{element0, element1, ... elementN}:]. In other words, the strings
- * returned for lists are surrounded by square brackets, while the strings
- * returned for other collections are surrounded by curly braces.
- *
- * If the specified collection contains a reference to itself, either
- * directly or indirectly through other collections or maps, the contained
- * reference is rendered as [:'[...]':] if it is a list, or [:'{...}':] if
- * it is not. This prevents the infinite regress that would otherwise occur.
- * So, for example, calling this method on a list whose sole element is a
- * reference to itself would return [:'[[...]]':].
- *
- * A typical implementation of a collection's [toString] method will
- * simply return the results of this method applied to the collection.
- */
- static String collectionToString(Collection c) {
- var result = new StringBuffer();
- _emitCollection(c, result, new List());
- return result.toString();
- }
-
- /**
- * Appends a string representing the specified collection to the specified
- * string buffer. The string is formatted as per [collectionToString].
- * The [:visiting:] list contains references to all of the enclosing
- * collections and maps (which are currently in the process of being
- * emitted into [:result:]). The [:visiting:] parameter allows this method to
- * generate a [:'[...]':] or [:'{...}':] where required. In other words,
- * it allows this method and [_emitMap] to identify recursive collections
- * and maps.
- */
- static void _emitCollection(Collection c,
- StringBuffer result,
- List visiting) {
- visiting.add(c);
- bool isList = c is List;
- result.add(isList ? '[' : '{');
-
- bool first = true;
- for (var e in c) {
- if (!first) {
- result.add(', ');
- }
- first = false;
- _emitObject(e, result, visiting);
- }
-
- result.add(isList ? ']' : '}');
- visiting.removeLast();
- }
-
- /**
- * Appends a string representing the specified object to the specified
- * string buffer. If the object is a [Collection] or [Map], it is formatted
- * as per [collectionToString] or [mapToString]; otherwise, it is formatted
- * by invoking its own [toString] method.
- *
- * The [:visiting:] list contains references to all of the enclosing
- * collections and maps (which are currently in the process of being
- * emitted into [:result:]). The [:visiting:] parameter allows this method
- * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
- * it allows this method and [_emitCollection] to identify recursive maps
- * and collections.
- */
- static void _emitObject(Object o, StringBuffer result, List visiting) {
- if (o is Collection) {
- if (_containsRef(visiting, o)) {
- result.add(o is List ? '[...]' : '{...}');
- } else {
- _emitCollection(o, result, visiting);
- }
- } else if (o is Map) {
- if (_containsRef(visiting, o)) {
- result.add('{...}');
- } else {
- Maps._emitMap(o, result, visiting);
- }
- } else { // o is neither a collection nor a map
- result.add(o);
- }
- }
-
- /**
- * Returns true if the specified collection contains the specified object
- * reference.
- */
- static _containsRef(Collection c, Object ref) {
- for (var e in c) {
- if (identical(e, ref)) return true;
- }
- return false;
- }
+ static String collectionToString(Collection c)
+ => ToString.collectionToString(c);
}
diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart
index 62c760f..b4eef3f 100644
--- a/sdk/lib/collection/maps.dart
+++ b/sdk/lib/collection/maps.dart
@@ -51,7 +51,7 @@
}
static Iterable getValues(Map map) {
- return map.keys.mappedBy((key) => map[key]);
+ return map.keys.map((key) => map[key]);
}
static int length(Map map) => map.keys.length;
@@ -74,38 +74,5 @@
* A typical implementation of a map's [toString] method will
* simply return the results of this method applied to the collection.
*/
- static String mapToString(Map m) {
- var result = new StringBuffer();
- _emitMap(m, result, new List());
- return result.toString();
- }
-
- /**
- * Appends a string representing the specified map to the specified
- * string buffer. The string is formatted as per [mapToString].
- * The [:visiting:] list contains references to all of the enclosing
- * collections and maps (which are currently in the process of being
- * emitted into [:result:]). The [:visiting:] parameter allows this method
- * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
- * it allows this method and [_emitCollection] to identify recursive maps
- * and collections.
- */
- static void _emitMap(Map m, StringBuffer result, List visiting) {
- visiting.add(m);
- result.add('{');
-
- bool first = true;
- m.forEach((k, v) {
- if (!first) {
- result.add(', ');
- }
- first = false;
- Collections._emitObject(k, result, visiting);
- result.add(': ');
- Collections._emitObject(v, result, visiting);
- });
-
- result.add('}');
- visiting.removeLast();
- }
+ static String mapToString(Map m) => ToString.mapToString(m);
}
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index f5dea8b..87c6fb7 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -160,7 +160,7 @@
* WARNING: This class is temporary located in dart:core. It'll be removed
* at some point in the near future.
*/
-class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
+class DoubleLinkedQueue<E> extends Collection<E> implements Queue<E> {
_DoubleLinkedQueueEntrySentinel<E> _sentinel;
DoubleLinkedQueue() {
diff --git a/sdk/lib/collection_dev/collection_dev.dart b/sdk/lib/collection_dev/collection_dev.dart
index 20eaac9..12e8e62 100644
--- a/sdk/lib/collection_dev/collection_dev.dart
+++ b/sdk/lib/collection_dev/collection_dev.dart
@@ -6,3 +6,5 @@
part 'iterable.dart';
part 'list.dart';
+part 'sort.dart';
+part 'to_string.dart';
diff --git a/sdk/lib/collection_dev/collection_dev_sources.gypi b/sdk/lib/collection_dev/collection_dev_sources.gypi
index 4bee7d2..819f237 100644
--- a/sdk/lib/collection_dev/collection_dev_sources.gypi
+++ b/sdk/lib/collection_dev/collection_dev_sources.gypi
@@ -7,5 +7,7 @@
'sources': [
'iterable.dart',
'list.dart',
+ 'sort.dart',
+ 'to_string.dart',
],
}
diff --git a/sdk/lib/collection_dev/list.dart b/sdk/lib/collection_dev/list.dart
index 10facd6..09d6deb 100644
--- a/sdk/lib/collection_dev/list.dart
+++ b/sdk/lib/collection_dev/list.dart
@@ -93,6 +93,10 @@
return result;
}
+ Iterable map(f(E element)) {
+ return new MappedIterable(this, f);
+ }
+
List mappedBy(f(E element)) {
return new MappedList(this, f);
}
@@ -105,7 +109,11 @@
return new ListView(this, n, null);
}
- String toString() => Collections.collectionToString(this);
+ String toString() => ToString.collectionToString(this);
+
+ List<E> get reversed {
+ return new ReversedListView(this, 0, null);
+ }
}
/**
@@ -114,10 +122,8 @@
abstract class FixedLengthListBase<E> extends ListBase<E> {
void operator[]=(int index, E value);
- List<E> get reversed => new ReversedListView<E>(this, 0, null);
-
void sort([Comparator<E> compare]) {
- coreSort(this, compare);
+ Sort.sort(this, compare);
}
void setRange(int start, int length, List<E> from, [int startFrom]) {
@@ -531,7 +537,7 @@
bool moveNext() {
if (_list.length != _originalLength) {
- throw new ConcurrentModificationError(list);
+ throw new ConcurrentModificationError(_list);
}
if (_index <= _start) return false;
_index -= 1;
diff --git a/sdk/lib/collection/sort.dart b/sdk/lib/collection_dev/sort.dart
similarity index 99%
rename from sdk/lib/collection/sort.dart
rename to sdk/lib/collection_dev/sort.dart
index a5805cd..9b89e63 100644
--- a/sdk/lib/collection/sort.dart
+++ b/sdk/lib/collection_dev/sort.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.
-part of dart.collection;
+part of dart.collection.dev;
/**
* Dual-Pivot Quicksort algorithm.
@@ -12,7 +12,7 @@
*
* Some improvements have been copied from Android's implementation.
*/
-class _Sort {
+class Sort {
// When a list has less then [:_INSERTION_SORT_THRESHOLD:] elements it will
// be sorted by an insertion sort.
static const int _INSERTION_SORT_THRESHOLD = 32;
diff --git a/sdk/lib/collection_dev/to_string.dart b/sdk/lib/collection_dev/to_string.dart
new file mode 100644
index 0000000..c55ccac
--- /dev/null
+++ b/sdk/lib/collection_dev/to_string.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.collection.dev;
+
+/**
+ * Temporary move `toString` methods into this class.
+ */
+class ToString {
+ // TODO(jjb): visiting list should be an identityHashSet when it exists
+
+ /**
+ * Returns a string representing the specified collection. If the
+ * collection is a [List], the returned string looks like this:
+ * [:'[element0, element1, ... elementN]':]. The value returned by its
+ * [toString] method is used to represent each element. If the specified
+ * collection is not a list, the returned string looks like this:
+ * [:{element0, element1, ... elementN}:]. In other words, the strings
+ * returned for lists are surrounded by square brackets, while the strings
+ * returned for other collections are surrounded by curly braces.
+ *
+ * If the specified collection contains a reference to itself, either
+ * directly or indirectly through other collections or maps, the contained
+ * reference is rendered as [:'[...]':] if it is a list, or [:'{...}':] if
+ * it is not. This prevents the infinite regress that would otherwise occur.
+ * So, for example, calling this method on a list whose sole element is a
+ * reference to itself would return [:'[[...]]':].
+ *
+ * A typical implementation of a collection's [toString] method will
+ * simply return the results of this method applied to the collection.
+ */
+ static String collectionToString(Collection c) {
+ var result = new StringBuffer();
+ _emitCollection(c, result, new List());
+ return result.toString();
+ }
+
+ /**
+ * Appends a string representing the specified collection to the specified
+ * string buffer. The string is formatted as per [collectionToString].
+ * The [:visiting:] list contains references to all of the enclosing
+ * collections and maps (which are currently in the process of being
+ * emitted into [:result:]). The [:visiting:] parameter allows this method to
+ * generate a [:'[...]':] or [:'{...}':] where required. In other words,
+ * it allows this method and [_emitMap] to identify recursive collections
+ * and maps.
+ */
+ static void _emitCollection(Collection c,
+ StringBuffer result,
+ List visiting) {
+ visiting.add(c);
+ bool isList = c is List;
+ result.add(isList ? '[' : '{');
+
+ bool first = true;
+ for (var e in c) {
+ if (!first) {
+ result.add(', ');
+ }
+ first = false;
+ _emitObject(e, result, visiting);
+ }
+
+ result.add(isList ? ']' : '}');
+ visiting.removeLast();
+ }
+
+ /**
+ * Appends a string representing the specified object to the specified
+ * string buffer. If the object is a [Collection] or [Map], it is formatted
+ * as per [collectionToString] or [mapToString]; otherwise, it is formatted
+ * by invoking its own [toString] method.
+ *
+ * The [:visiting:] list contains references to all of the enclosing
+ * collections and maps (which are currently in the process of being
+ * emitted into [:result:]). The [:visiting:] parameter allows this method
+ * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
+ * it allows this method and [_emitCollection] to identify recursive maps
+ * and collections.
+ */
+ static void _emitObject(Object o, StringBuffer result, List visiting) {
+ if (o is Collection) {
+ if (_containsRef(visiting, o)) {
+ result.add(o is List ? '[...]' : '{...}');
+ } else {
+ _emitCollection(o, result, visiting);
+ }
+ } else if (o is Map) {
+ if (_containsRef(visiting, o)) {
+ result.add('{...}');
+ } else {
+ _emitMap(o, result, visiting);
+ }
+ } else { // o is neither a collection nor a map
+ result.add(o);
+ }
+ }
+
+ /**
+ * Returns true if the specified collection contains the specified object
+ * reference.
+ */
+ static _containsRef(Collection c, Object ref) {
+ for (var e in c) {
+ if (identical(e, ref)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a string representing the specified map. The returned string
+ * looks like this: [:'{key0: value0, key1: value1, ... keyN: valueN}':].
+ * The value returned by its [toString] method is used to represent each
+ * key or value.
+ *
+ * If the map collection contains a reference to itself, either
+ * directly as a key or value, or indirectly through other collections
+ * or maps, the contained reference is rendered as [:'{...}':]. This
+ * prevents the infinite regress that would otherwise occur. So, for example,
+ * calling this method on a map whose sole entry maps the string key 'me'
+ * to a reference to the map would return [:'{me: {...}}':].
+ *
+ * A typical implementation of a map's [toString] method will
+ * simply return the results of this method applied to the collection.
+ */
+ static String mapToString(Map m) {
+ var result = new StringBuffer();
+ _emitMap(m, result, new List());
+ return result.toString();
+ }
+
+ /**
+ * Appends a string representing the specified map to the specified
+ * string buffer. The string is formatted as per [mapToString].
+ * The [:visiting:] list contains references to all of the enclosing
+ * collections and maps (which are currently in the process of being
+ * emitted into [:result:]). The [:visiting:] parameter allows this method
+ * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
+ * it allows this method and [_emitCollection] to identify recursive maps
+ * and collections.
+ */
+ static void _emitMap(Map m, StringBuffer result, List visiting) {
+ visiting.add(m);
+ result.add('{');
+
+ bool first = true;
+ m.forEach((k, v) {
+ if (!first) {
+ result.add(', ');
+ }
+ first = false;
+ _emitObject(k, result, visiting);
+ result.add(': ');
+ _emitObject(v, result, visiting);
+ });
+
+ result.add('}');
+ visiting.removeLast();
+ }
+}
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 92321f6..fadf0cc 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -99,7 +99,7 @@
}
/**
- * Date is the public interface to a point in time.
+ * A DateTime object represents a point in time.
*
* It can represent time values that are at a distance of at most
* 8,640,000,000,000,000ms (100,000,000 days) from epoch (1970-01-01 UTC). In
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index e13f2fe..160e773 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -27,7 +27,7 @@
* with that index to create the next value.
*
* As an [Iterable], [:new Iterable.generate(n, generator)):] is equivalent to
- * [:const [0, ..., n - 1].mappedBy(generator):]
+ * [:const [0, ..., n - 1].map(generator):]
*/
factory Iterable.generate(int count, E generator(int index)) {
return new _GeneratorIterable<E>(count, generator);
@@ -48,7 +48,14 @@
* multiple times over the the returned [Iterable] will invoke the supplied
* function [f] multiple times on the same element.
*/
- Iterable mappedBy(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+ Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+
+ /**
+ * Deprecated alias for [map].
+ *
+ * @deprecated
+ */
+ Iterable mappedBy(f(E element)) => map(f);
/**
* Returns a lazy [Iterable] with all elements that satisfy the
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index b98743c..10ba3e0 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -23,14 +23,6 @@
external factory List.fixedLength(int length, {E fill: null});
/**
- * Creates an list of the given [length] where each entry is
- * filled with [fill].
- *
- * The length of the returned list is not fixed.
- */
- external factory List.filled(int length, E fill);
-
- /**
* Creates an list with the elements of [other]. The order in
* the list will be the order provided by the iterator of [other].
*
@@ -198,36 +190,4 @@
* [start] is greater than the length of the list.
*/
void insertRange(int start, int length, [E fill]);
-
- /**
- * Returns a lazy unmodifiable [List] where each element [:e:] of [:this:] is
- * replaced by the result of [:f(e):].
- *
- * This method returns a view of the mapped elements. As long as the
- * returned [List] is not indexed or iterated over, the supplied function [f]
- * will not be invoked. The transformed elements will not be cached. Accessing
- * elements multiple times will invoke the supplied function [f] multiple
- * times.
- */
- List mappedBy(f(E element));
-
- /**
- * Returns an unmodifiable [List] that hides the first [n] elements.
- *
- * The returned list is a view backed by [:this:].
- *
- * While [:this:] has fewer than [n] elements, then the resulting [List]
- * will be empty.
- */
- List<E> skip(int n);
-
- /**
- * Returns an unmodifiable [List] with at most [n] elements.
- *
- * The returned list is a view backed by this.
- *
- * The returned [List] may contain fewer than [n] elements, while [:this:]
- * contains fewer than [n] elements.
- */
- List<E> take(int n);
}
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 7f2dcbd..27eb67f 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -80,6 +80,11 @@
/**
* Creates a new string by concatenating this string with [other].
+ *
+ * A sequence of strings can be concatenated by using [Iterable.join]:
+ *
+ * var strings = ['foo', 'bar', 'geez'];
+ * var concatenated = strings.join();
*/
String concat(String other);
diff --git a/sdk/lib/core/strings.dart b/sdk/lib/core/strings.dart
index dcdcafc..412e23f 100644
--- a/sdk/lib/core/strings.dart
+++ b/sdk/lib/core/strings.dart
@@ -7,11 +7,15 @@
abstract class Strings {
/**
* Joins all the given strings to create a new string.
+ *
+ * *Deprecated* Use `strings.join(separator)` instead.
*/
external static String join(Iterable<String> strings, String separator);
/**
* Concatenates all the given strings to create a new string.
+ *
+ * *Deprecated* Use `strings.join()` instead.
*/
external static String concatAll(Iterable<String> strings);
}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index e1340e2..d540e7b 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -1,8 +1,7 @@
-library html;
+library dart.dom.html;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
@@ -109,6 +108,7 @@
@DomName('HTMLAnchorElement')
class AnchorElement extends Element native "*HTMLAnchorElement" {
+ @DomName('HTMLAnchorElement.HTMLAnchorElement')
@DocsEditable
factory AnchorElement({String href}) {
var e = document.$dom_createElement("a");
@@ -370,6 +370,7 @@
@DomName('HTMLAreaElement')
class AreaElement extends Element native "*HTMLAreaElement" {
+ @DomName('HTMLAreaElement.HTMLAreaElement')
@DocsEditable
factory AreaElement() => document.$dom_createElement("area");
@@ -437,9 +438,12 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class ArrayBuffer native "*ArrayBuffer" {
+ @DomName('ArrayBuffer.ArrayBuffer')
@DocsEditable
- factory ArrayBuffer(int length) => ArrayBuffer._create(length);
- static ArrayBuffer _create(int length) => JS('ArrayBuffer', 'new ArrayBuffer(#)', length);
+ factory ArrayBuffer(int length) {
+ return ArrayBuffer._create_1(length);
+ }
+ static ArrayBuffer _create_1(length) => JS('ArrayBuffer', 'new ArrayBuffer(#)', length);
/// Checks if this type is supported on the current platform.
static bool get supported => JS('bool', 'typeof window.ArrayBuffer != "undefined"');
@@ -520,19 +524,16 @@
@DomName('HTMLAudioElement')
class AudioElement extends MediaElement native "*HTMLAudioElement" {
+ @DomName('HTMLAudioElement.HTMLAudioElement')
@DocsEditable
factory AudioElement([String src]) {
- if (!?src) {
- return AudioElement._create();
+ if (?src) {
+ return AudioElement._create_1(src);
}
- return AudioElement._create(src);
+ return AudioElement._create_2();
}
- static AudioElement _create([String src]) {
- if (!?src) {
- return JS('AudioElement', 'new Audio()');
- }
- return JS('AudioElement', 'new Audio(#)', src);
- }
+ static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
+ static AudioElement _create_2() => JS('AudioElement', 'new 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
@@ -543,6 +544,7 @@
@DomName('HTMLBRElement')
class BRElement extends Element native "*HTMLBRElement" {
+ @DomName('HTMLBRElement.HTMLBRElement')
@DocsEditable
factory BRElement() => document.$dom_createElement("br");
}
@@ -568,6 +570,7 @@
@DomName('HTMLBaseElement')
class BaseElement extends Element native "*HTMLBaseElement" {
+ @DomName('HTMLBaseElement.HTMLBaseElement')
@DocsEditable
factory BaseElement() => document.$dom_createElement("base");
@@ -696,17 +699,6 @@
@DomName('Blob')
class Blob native "*Blob" {
- @DocsEditable
- factory Blob(List blobParts, [String type, String endings]) {
- if (!?type) {
- return Blob._create(blobParts);
- }
- if (!?endings) {
- return Blob._create(blobParts, type);
- }
- return Blob._create(blobParts, type, endings);
- }
-
@DomName('Blob.size')
@DocsEditable
final int size;
@@ -719,7 +711,7 @@
@DocsEditable
Blob slice([int start, int end, String contentType]) native;
- static Blob _create([List blobParts = null, String type, String endings]) {
+ factory Blob(List blobParts, [String type, String endings]) {
// TODO: validate that blobParts is a JS Array and convert if not.
// TODO: any coercions on the elements of blobParts, e.g. coerce a typed
// array to ArrayBuffer if it is a total view.
@@ -800,6 +792,7 @@
@DocsEditable
static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
+ @DomName('HTMLBodyElement.HTMLBodyElement')
@DocsEditable
factory BodyElement() => document.$dom_createElement("body");
@@ -916,6 +909,7 @@
@DomName('HTMLButtonElement')
class ButtonElement extends Element native "*HTMLButtonElement" {
+ @DomName('HTMLButtonElement.HTMLButtonElement')
@DocsEditable
factory ButtonElement() => document.$dom_createElement("button");
@@ -1006,6 +1000,7 @@
@DomName('HTMLCanvasElement')
class CanvasElement extends Element native "*HTMLCanvasElement" {
+ @DomName('HTMLCanvasElement.HTMLCanvasElement')
@DocsEditable
factory CanvasElement({int width, int height}) {
var e = document.$dom_createElement("canvas");
@@ -1014,22 +1009,99 @@
return e;
}
+ /// The height of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.height')
@DocsEditable
int height;
+ /// The width of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.width')
@DocsEditable
int width;
+ CanvasRenderingContext getContext(String contextId, [Map attrs]) {
+ if (?attrs) {
+ var attrs_1 = convertDartToNative_Dictionary(attrs);
+ return _getContext_1(contextId, attrs_1);
+ }
+ return _getContext_2(contextId);
+ }
+ @JSName('getContext')
+ @DomName('HTMLCanvasElement.getContext')
+ @DocsEditable
+ CanvasRenderingContext _getContext_1(contextId, attrs) native;
+ @JSName('getContext')
+ @DomName('HTMLCanvasElement.getContext')
+ @DocsEditable
+ CanvasRenderingContext _getContext_2(contextId) native;
+
@JSName('toDataURL')
+ /**
+ * Returns a data URI containing a representation of the image in the
+ * format specified by type (defaults to 'image/png').
+ *
+ * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+ *
+ * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]
+ * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default
+ * value is used. Note: the default value varies by browser.
+ *
+ * If the height or width of this canvas element is 0, then 'data:' is returned,
+ * representing no data.
+ *
+ * If the type requested is not 'image/png', and the returned value is
+ * 'data:image/png', then the requested type is not supported.
+ *
+ * Example usage:
+ *
+ * CanvasElement canvas = new CanvasElement();
+ * var ctx = canvas.context2d
+ * ..fillStyle = "rgb(200,0,0)"
+ * ..fillRect(10, 10, 55, 50);
+ * var dataUrl = canvas.toDataURL("image/jpeg", 0.95);
+ * // The Data Uri would look similar to
+ * // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+ * // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+ * // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+ * //Create a new image element from the data URI.
+ * var img = new ImageElement();
+ * img.src = dataUrl;
+ * document.body.children.add(img);
+ *
+ * See also:
+ *
+ * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+ *
+ * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+ *
+ * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+ */
@DomName('HTMLCanvasElement.toDataURL')
@DocsEditable
String toDataUrl(String type, [num quality]) native;
-
- CanvasRenderingContext getContext(String contextId) native;
CanvasRenderingContext2D get context2d => getContext('2d');
+
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.FIREFOX)
+ @Experimental
+ WebGLRenderingContext getContext3d({alpha: true, depth: true, stencil: false,
+ antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {
+
+ var options = {
+ 'alpha': alpha,
+ 'depth': depth,
+ 'stencil': stencil,
+ 'antialias': antialias,
+ 'premultipliedAlpha': premultipliedAlpha,
+ 'preserveDrawingBuffer': preserveDrawingBuffer,
+ };
+ var context = getContext('webgl', options);
+ if (context == null) {
+ context = getContext('experimental-webgl', options);
+ }
+ return context;
+ }
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -1037,9 +1109,47 @@
@DocsEditable
+/**
+ * An opaque canvas object representing a gradient.
+ *
+ * Created by calling [createLinearGradient] or [createRadialGradient] on a
+ * [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ * var canvas = new CanvasElement(width: 600, height: 600);
+ * var ctx = canvas.context2d;
+ * ctx.clearRect(0, 0, 600, 600);
+ * ctx.save();
+ * // Create radial gradient.
+ * CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
+ * gradient.addColorStop(0, '#000');
+ * gradient.addColorStop(1, 'rgb(255, 255, 255)');
+ * // Assign gradients to fill.
+ * ctx.fillStyle = gradient;
+ * // Draw a rectangle with a gradient fill.
+ * ctx.fillRect(0, 0, 600, 600);
+ * ctx.save();
+ * document.body.children.add(canvas);
+ *
+ * See also:
+ *
+ * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
+ * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
+ */
@DomName('CanvasGradient')
class CanvasGradient native "*CanvasGradient" {
+ /**
+ * Adds a color stop to this gradient at the offset.
+ *
+ * The [offset] can range between 0.0 and 1.0.
+ *
+ * See also:
+ *
+ * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
+ */
@DomName('CanvasGradient.addColorStop')
@DocsEditable
void addColorStop(num offset, String color) native;
@@ -1050,6 +1160,33 @@
@DocsEditable
+/**
+ * An opaque object representing a pattern of image, canvas, or video.
+ *
+ * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ * var canvas = new CanvasElement(width: 600, height: 600);
+ * var ctx = canvas.context2d;
+ * var img = new ImageElement();
+ * // Image src needs to be loaded before pattern is applied.
+ * img.onLoad.listen((event) {
+ * // When the image is loaded, create a pattern
+ * // from the ImageElement.
+ * CanvasPattern pattern = ctx.createPattern(img, 'repeat');
+ * ctx.rect(0, 0, canvas.width, canvas.height);
+ * ctx.fillStyle = pattern;
+ * ctx.fill();
+ * });
+ * img.src = "images/foo.jpg";
+ * document.body.children.add(canvas);
+ *
+ * See also:
+ * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
+ * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
+ */
@DomName('CanvasPattern')
class CanvasPattern native "*CanvasPattern" {
}
@@ -1059,9 +1196,16 @@
@DocsEditable
+/**
+ * A rendering context for a canvas element.
+ *
+ * This context is extended by [CanvasRenderingContext2D] and
+ * [WebGLRenderingContext].
+ */
@DomName('CanvasRenderingContext')
class CanvasRenderingContext native "*CanvasRenderingContext" {
+ /// Reference to the canvas element to which this context belongs.
@DomName('CanvasRenderingContext.canvas')
@DocsEditable
final CanvasElement canvas;
@@ -1180,7 +1324,7 @@
@DomName('CanvasRenderingContext2D.clip')
@DocsEditable
- void clip() native;
+ void clip([String winding]) native;
@DomName('CanvasRenderingContext2D.closePath')
@DocsEditable
@@ -1225,7 +1369,7 @@
@DomName('CanvasRenderingContext2D.fill')
@DocsEditable
- void fill() native;
+ void fill([String winding]) native;
@DomName('CanvasRenderingContext2D.fillRect')
@DocsEditable
@@ -1250,7 +1394,7 @@
@DomName('CanvasRenderingContext2D.isPointInPath')
@DocsEditable
- bool isPointInPath(num x, num y) native;
+ bool isPointInPath(num x, num y, [String winding]) native;
@DomName('CanvasRenderingContext2D.lineTo')
@DocsEditable
@@ -1482,53 +1626,6 @@
@DocsEditable
-@DomName('Clipboard')
-class Clipboard native "*Clipboard" {
-
- @DomName('Clipboard.dropEffect')
- @DocsEditable
- String dropEffect;
-
- @DomName('Clipboard.effectAllowed')
- @DocsEditable
- String effectAllowed;
-
- @DomName('Clipboard.files')
- @DocsEditable
- @Returns('FileList')
- @Creates('FileList')
- final List<File> files;
-
- @DomName('Clipboard.items')
- @DocsEditable
- final DataTransferItemList items;
-
- @DomName('Clipboard.types')
- @DocsEditable
- final List types;
-
- @DomName('Clipboard.clearData')
- @DocsEditable
- void clearData([String type]) native;
-
- @DomName('Clipboard.getData')
- @DocsEditable
- String getData(String type) native;
-
- @DomName('Clipboard.setData')
- @DocsEditable
- bool setData(String type, String data) native;
-
- @DomName('Clipboard.setDragImage')
- @DocsEditable
- void setDragImage(ImageElement image, int x, int y) 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.
-
-
-@DocsEditable
@DomName('CloseEvent')
class CloseEvent extends Event native "*CloseEvent" {
@@ -1695,6 +1792,7 @@
@Experimental
class ContentElement extends Element native "*HTMLContentElement" {
+ @DomName('HTMLContentElement.HTMLContentElement')
@DocsEditable
factory ContentElement() => document.$dom_createElement("content");
@@ -1818,6 +1916,29 @@
@DocsEditable
+@DomName('CSSHostRule')
+class CssHostRule extends CssRule native "*CSSHostRule" {
+
+ @DomName('CSSHostRule.cssRules')
+ @DocsEditable
+ @Returns('_CssRuleList')
+ @Creates('_CssRuleList')
+ final List<CssRule> cssRules;
+
+ @DomName('CSSHostRule.deleteRule')
+ @DocsEditable
+ void deleteRule(int index) native;
+
+ @DomName('CSSHostRule.insertRule')
+ @DocsEditable
+ int insertRule(String rule, 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.
+
+
+@DocsEditable
@DomName('CSSImportRule')
class CssImportRule extends CssRule native "*CSSImportRule" {
@@ -1888,21 +2009,24 @@
@DocsEditable
@DomName('WebKitCSSMatrix')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class CssMatrix native "*WebKitCSSMatrix" {
+ @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
@DocsEditable
factory CssMatrix([String cssValue]) {
- if (!?cssValue) {
- return CssMatrix._create();
+ if (?cssValue) {
+ return CssMatrix._create_1(cssValue);
}
- return CssMatrix._create(cssValue);
+ return CssMatrix._create_2();
}
- static CssMatrix _create([String cssValue]) {
- if (!?cssValue) {
- return JS('CssMatrix', 'new WebKitCSSMatrix()');
- }
- return JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
- }
+ static CssMatrix _create_1(cssValue) => JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
+ static CssMatrix _create_2() => JS('CssMatrix', 'new WebKitCSSMatrix()');
+
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => JS('bool', '!!(window.WebKitCSSMatrix)');
@DomName('WebKitCSSMatrix.a')
@DocsEditable
@@ -2189,6 +2313,8 @@
static const int FONT_FACE_RULE = 5;
+ static const int HOST_RULE = 1001;
+
static const int IMPORT_RULE = 3;
static const int MEDIA_RULE = 4;
@@ -5639,6 +5765,7 @@
@DomName('HTMLDListElement')
class DListElement extends Element native "*HTMLDListElement" {
+ @DomName('HTMLDListElement.HTMLDListElement')
@DocsEditable
factory DListElement() => document.$dom_createElement("dl");
}
@@ -5655,6 +5782,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class DataListElement extends Element native "*HTMLDataListElement" {
+ @DomName('HTMLDataListElement.HTMLDataListElement')
@DocsEditable
factory DataListElement() => document.$dom_createElement("datalist");
@@ -5671,6 +5799,53 @@
@DocsEditable
+@DomName('Clipboard')
+class DataTransfer native "*Clipboard" {
+
+ @DomName('Clipboard.dropEffect')
+ @DocsEditable
+ String dropEffect;
+
+ @DomName('Clipboard.effectAllowed')
+ @DocsEditable
+ String effectAllowed;
+
+ @DomName('Clipboard.files')
+ @DocsEditable
+ @Returns('FileList')
+ @Creates('FileList')
+ final List<File> files;
+
+ @DomName('Clipboard.items')
+ @DocsEditable
+ final DataTransferItemList items;
+
+ @DomName('Clipboard.types')
+ @DocsEditable
+ final List types;
+
+ @DomName('Clipboard.clearData')
+ @DocsEditable
+ void clearData([String type]) native;
+
+ @DomName('Clipboard.getData')
+ @DocsEditable
+ String getData(String type) native;
+
+ @DomName('Clipboard.setData')
+ @DocsEditable
+ bool setData(String type, String data) native;
+
+ @DomName('Clipboard.setDragImage')
+ @DocsEditable
+ void setDragImage(ImageElement image, int x, int y) 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.
+
+
+@DocsEditable
@DomName('DataTransferItem')
class DataTransferItem native "*DataTransferItem" {
@@ -5728,25 +5903,20 @@
@DomName('DataView')
class DataView extends ArrayBufferView native "*DataView" {
+ @DomName('DataView.DataView')
@DocsEditable
factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
- if (!?byteOffset) {
- return DataView._create(buffer);
+ if (?byteLength) {
+ return DataView._create_1(buffer, byteOffset, byteLength);
}
- if (!?byteLength) {
- return DataView._create(buffer, byteOffset);
+ if (?byteOffset) {
+ return DataView._create_2(buffer, byteOffset);
}
- return DataView._create(buffer, byteOffset, byteLength);
+ return DataView._create_3(buffer);
}
- static DataView _create(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
- if (!?byteOffset) {
- return JS('DataView', 'new DataView(#)', buffer);
- }
- if (!?byteLength) {
- return JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
- }
- return JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
- }
+ static DataView _create_1(buffer, byteOffset, byteLength) => JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
+ static DataView _create_2(buffer, byteOffset) => JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
+ static DataView _create_3(buffer) => JS('DataView', 'new DataView(#)', buffer);
@DomName('DataView.getFloat32')
@DocsEditable
@@ -5819,8 +5989,14 @@
@DocsEditable
@DomName('Database')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class Database native "*Database" {
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => JS('bool', '!!(window.openDatabase)');
+
@DomName('Database.version')
@DocsEditable
final String version;
@@ -5852,6 +6028,9 @@
@DocsEditable
@DomName('DatabaseSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class DatabaseSync native "*DatabaseSync" {
@DomName('DatabaseSync.lastErrorMessage')
@@ -5938,6 +6117,7 @@
@Experimental
class DetailsElement extends Element native "*HTMLDetailsElement" {
+ @DomName('HTMLDetailsElement.HTMLDetailsElement')
@DocsEditable
factory DetailsElement() => document.$dom_createElement("details");
@@ -6159,9 +6339,31 @@
@DocsEditable
+/**
+ * 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')
class DivElement extends Element native "*HTMLDivElement" {
+ @DomName('HTMLDivElement.HTMLDivElement')
@DocsEditable
factory DivElement() => document.$dom_createElement("div");
}
@@ -6207,6 +6409,7 @@
new DocumentEvents(this);
@JSName('body')
+ /// Moved to [HtmlDocument].
@DomName('Document.body')
@DocsEditable
Element $dom_body;
@@ -6236,6 +6439,7 @@
final String domain;
@JSName('head')
+ /// Moved to [HtmlDocument].
@DomName('Document.head')
@DocsEditable
final HeadElement $dom_head;
@@ -6245,6 +6449,7 @@
final DomImplementation implementation;
@JSName('lastModified')
+ /// Moved to [HtmlDocument].
@DomName('Document.lastModified')
@DocsEditable
final String $dom_lastModified;
@@ -6259,6 +6464,7 @@
final String readyState;
@JSName('referrer')
+ /// Moved to [HtmlDocument].
@DomName('Document.referrer')
@DocsEditable
final String $dom_referrer;
@@ -6269,6 +6475,7 @@
String $dom_selectedStylesheetSet;
@JSName('styleSheets')
+ /// Moved to [HtmlDocument]
@DomName('Document.styleSheets')
@DocsEditable
@Returns('_StyleSheetList')
@@ -6276,31 +6483,37 @@
final List<StyleSheet> $dom_styleSheets;
@JSName('title')
+ /// Moved to [HtmlDocument].
@DomName('Document.title')
@DocsEditable
String $dom_title;
@JSName('webkitFullscreenElement')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitFullscreenElement')
@DocsEditable
final Element $dom_webkitFullscreenElement;
@JSName('webkitFullscreenEnabled')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitFullscreenEnabled')
@DocsEditable
final bool $dom_webkitFullscreenEnabled;
@JSName('webkitHidden')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitHidden')
@DocsEditable
final bool $dom_webkitHidden;
@JSName('webkitIsFullScreen')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitIsFullScreen')
@DocsEditable
final bool $dom_webkitIsFullScreen;
@JSName('webkitPointerLockElement')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitPointerLockElement')
@DocsEditable
final Element $dom_webkitPointerLockElement;
@@ -6311,6 +6524,7 @@
final String $dom_webkitVisibilityState;
@JSName('caretRangeFromPoint')
+ /// Use the [Range] constructor instead.
@DomName('Document.caretRangeFromPoint')
@DocsEditable
Range $dom_caretRangeFromPoint(int x, int y) native;
@@ -6325,6 +6539,7 @@
DocumentFragment createDocumentFragment() native;
@JSName('createElement')
+ /// Deprecated: use new Element.tag(tagName) instead.
@DomName('Document.createElement')
@DocsEditable
Element $dom_createElement(String tagName) native;
@@ -6359,6 +6574,7 @@
Touch _$dom_createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
@JSName('createTouchList')
+ /// Use the [TouchList] constructor instead.
@DomName('Document.createTouchList')
@DocsEditable
TouchList $dom_createTouchList() native;
@@ -6373,11 +6589,13 @@
bool execCommand(String command, bool userInterface, String value) native;
@JSName('getCSSCanvasContext')
+ /// Moved to [HtmlDocument].
@DomName('Document.getCSSCanvasContext')
@DocsEditable
CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native;
@JSName('getElementById')
+ /// Deprecated: use query("#$elementId") instead.
@DomName('Document.getElementById')
@DocsEditable
Element $dom_getElementById(String elementId) native;
@@ -6424,11 +6642,13 @@
String queryCommandValue(String command) native;
@JSName('querySelector')
+ /// Deprecated: renamed to the shorter name [query].
@DomName('Document.querySelector')
@DocsEditable
Element $dom_querySelector(String selectors) native;
@JSName('querySelectorAll')
+ /// Deprecated: use query("#$elementId") instead.
@DomName('Document.querySelectorAll')
@DocsEditable
@Returns('NodeList')
@@ -6436,16 +6656,19 @@
List<Node> $dom_querySelectorAll(String selectors) native;
@JSName('webkitCancelFullScreen')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitCancelFullScreen')
@DocsEditable
void $dom_webkitCancelFullScreen() native;
@JSName('webkitExitFullscreen')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitExitFullscreen')
@DocsEditable
void $dom_webkitExitFullscreen() native;
@JSName('webkitExitPointerLock')
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitExitPointerLock')
@DocsEditable
void $dom_webkitExitPointerLock() native;
@@ -6996,7 +7219,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(DomMimeType element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(DomMimeType element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(DomMimeType element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<DomMimeType> where(bool f(DomMimeType element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7010,13 +7237,13 @@
bool get isEmpty => this.length == 0;
- List<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<DomMimeType> takeWhile(bool test(DomMimeType value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<DomMimeType> skipWhile(bool test(DomMimeType value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -7061,8 +7288,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<DomMimeType> get reversed =>
- new ReversedListView<DomMimeType>(this, 0, null);
+ List<DomMimeType> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(DomMimeType a, DomMimeType b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -7160,9 +7388,12 @@
@DomName('DOMParser')
class DomParser native "*DOMParser" {
+ @DomName('DOMParser.DOMParser')
@DocsEditable
- factory DomParser() => DomParser._create();
- static DomParser _create() => JS('DomParser', 'new DOMParser()');
+ factory DomParser() {
+ return DomParser._create_1();
+ }
+ static DomParser _create_1() => JS('DomParser', 'new DOMParser()');
@DomName('DOMParser.parseFromString')
@DocsEditable
@@ -7242,7 +7473,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(DomPlugin element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(DomPlugin element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(DomPlugin element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<DomPlugin> where(bool f(DomPlugin element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7256,13 +7491,13 @@
bool get isEmpty => this.length == 0;
- List<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<DomPlugin> takeWhile(bool test(DomPlugin value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<DomPlugin> skipWhile(bool test(DomPlugin value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -7307,8 +7542,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<DomPlugin> get reversed =>
- new ReversedListView<DomPlugin>(this, 0, null);
+ List<DomPlugin> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(DomPlugin a, DomPlugin b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -7407,6 +7643,36 @@
@DocsEditable
+@DomName('WebKitPoint')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
+class DomPoint native "*WebKitPoint" {
+
+ @DomName('WebKitPoint.WebKitPoint')
+ @DocsEditable
+ factory DomPoint(num x, num y) {
+ return DomPoint._create_1(x, y);
+ }
+ static DomPoint _create_1(x, y) => JS('DomPoint', 'new WebKitPoint(#,#)', x, y);
+
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => JS('bool', '!!(window.WebKitPoint)');
+
+ @DomName('WebKitPoint.x')
+ @DocsEditable
+ num x;
+
+ @DomName('WebKitPoint.y')
+ @DocsEditable
+ num y;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('Selection')
class DomSelection native "*Selection" {
@@ -7568,7 +7834,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(String element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(String element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<String> where(bool f(String element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7582,13 +7852,13 @@
bool get isEmpty => this.length == 0;
- List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<String> takeWhile(bool test(String value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<String> skipWhile(bool test(String value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -7633,8 +7903,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<String> get reversed =>
- new ReversedListView<String>(this, 0, null);
+ List<String> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(String a, String b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -7822,6 +8093,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Element element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Element element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -7834,7 +8109,7 @@
return _element.$dom_firstElementChild == null;
}
- List<Element> take(int n) {
+ Iterable<Element> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -7842,7 +8117,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Element> skip(int n) {
+ Iterable<Element> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -7898,8 +8173,9 @@
}
}
- List<Element> get reversed =>
- new ReversedListView<Element>(this, 0, null);
+ List<Element> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -7917,7 +8193,7 @@
void remove(Object object) {
if (object is Element) {
Element element = object;
- if (identical(element.parentNode, this)) {
+ if (identical(element.parentNode, _element)) {
_element.$dom_removeChild(element);
}
}
@@ -8034,6 +8310,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Element element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Element element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -8063,7 +8343,7 @@
List<Element> toList() => new List<Element>.from(this);
Set<Element> toSet() => new Set<Element>.from(this);
- List<Element> take(int n) {
+ Iterable<Element> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -8071,7 +8351,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Element> skip(int n) {
+ Iterable<Element> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -8123,8 +8403,9 @@
throw new UnsupportedError('');
}
- List<Element> get reversed =>
- new ReversedListView<Element>(this, 0, null);
+ List<Element> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('');
@@ -8469,27 +8750,20 @@
* [style] property, which contains only the values specified directly on this
* element.
*
+ * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+ * `::line-marker`.
+ *
* See also:
*
* * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
- */
- Future<CssStyleDeclaration> get computedStyle {
- // TODO(jacobr): last param should be null, see b/5045788
- return getComputedStyle('');
- }
-
- /**
- * Returns the computed styles for pseudo-elements such as `::after`,
- * `::before`, `::marker`, `::line-marker`.
- *
- * See also:
- *
* * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
*/
- Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) {
- return _createMeasurementFuture(
- () => window.$dom_getComputedStyle(this, pseudoElement),
- new Completer<CssStyleDeclaration>());
+ CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+ if (pseudoElement == null) {
+ pseudoElement = '';
+ }
+ // TODO(jacobr): last param should be null, see b/5045788
+ return window.$dom_getComputedStyle(this, pseudoElement);
}
/**
@@ -8666,6 +8940,7 @@
} else if (JS('bool', '!!#.msMatchesSelector', this)) {
return JS('bool', '#.msMatchesSelector(#)', this, selectors);
}
+ throw new UnsupportedError("Not supported on this platform");
}
@@ -9667,6 +9942,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class EmbedElement extends Element native "*HTMLEmbedElement" {
+ @DomName('HTMLEmbedElement.HTMLEmbedElement')
@DocsEditable
factory EmbedElement() => document.$dom_createElement("embed");
@@ -9949,7 +10225,7 @@
@DomName('Event.clipboardData')
@DocsEditable
- final Clipboard clipboardData;
+ final DataTransfer clipboardData;
EventTarget get currentTarget => _convertNativeToDart_EventTarget(this._currentTarget);
@JSName('currentTarget')
@@ -10067,19 +10343,16 @@
@DocsEditable
static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
+ @DomName('EventSource.EventSource')
@DocsEditable
factory EventSource(String url, [Map eventSourceInit]) {
- if (!?eventSourceInit) {
- return EventSource._create(url);
+ if (?eventSourceInit) {
+ return EventSource._create_1(url, eventSourceInit);
}
- return EventSource._create(url, eventSourceInit);
+ return EventSource._create_2(url);
}
- static EventSource _create(String url, [Map eventSourceInit]) {
- if (!?eventSourceInit) {
- return JS('EventSource', 'new EventSource(#)', url);
- }
- return JS('EventSource', 'new EventSource(#,#)', url, eventSourceInit);
- }
+ static EventSource _create_1(url, eventSourceInit) => JS('EventSource', 'new EventSource(#,#)', url, eventSourceInit);
+ static EventSource _create_2(url) => JS('EventSource', 'new EventSource(#)', url);
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -10268,6 +10541,7 @@
@DomName('HTMLFieldSetElement')
class FieldSetElement extends Element native "*HTMLFieldSetElement" {
+ @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
@DocsEditable
factory FieldSetElement() => document.$dom_createElement("fieldset");
@@ -10501,7 +10775,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(File element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(File element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(File element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<File> where(bool f(File element)) =>
IterableMixinWorkaround.where(this, f);
@@ -10515,13 +10793,13 @@
bool get isEmpty => this.length == 0;
- List<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<File> takeWhile(bool test(File value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<File> skipWhile(bool test(File value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -10566,8 +10844,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<File> get reversed =>
- new ReversedListView<File>(this, 0, null);
+ List<File> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(File a, File b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -10685,9 +10964,12 @@
@DocsEditable
static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
+ @DomName('FileReader.FileReader')
@DocsEditable
- factory FileReader() => FileReader._create();
- static FileReader _create() => JS('FileReader', 'new FileReader()');
+ factory FileReader() {
+ return FileReader._create_1();
+ }
+ static FileReader _create_1() => JS('FileReader', 'new FileReader()');
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -10807,9 +11089,12 @@
@DomName('FileReaderSync')
class FileReaderSync native "*FileReaderSync" {
+ @DomName('FileReaderSync.FileReaderSync')
@DocsEditable
- factory FileReaderSync() => FileReaderSync._create();
- static FileReaderSync _create() => JS('FileReaderSync', 'new FileReaderSync()');
+ factory FileReaderSync() {
+ return FileReaderSync._create_1();
+ }
+ static FileReaderSync _create_1() => JS('FileReaderSync', 'new FileReaderSync()');
@DomName('FileReaderSync.readAsArrayBuffer')
@DocsEditable
@@ -11059,12 +11344,18 @@
@DomName('Float32Array')
class Float32Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<num> native "*Float32Array" {
+ @DomName('Float32Array.Float32Array')
+ @DocsEditable
factory Float32Array(int length) =>
_TypedArrayFactoryProvider.createFloat32Array(length);
+ @DomName('Float32Array.fromList')
+ @DocsEditable
factory Float32Array.fromList(List<num> list) =>
_TypedArrayFactoryProvider.createFloat32Array_fromList(list);
+ @DomName('Float32Array.fromBuffer')
+ @DocsEditable
factory Float32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createFloat32Array_fromBuffer(buffer, byteOffset, length);
@@ -11099,7 +11390,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(num element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(num element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<num> where(bool f(num element)) =>
IterableMixinWorkaround.where(this, f);
@@ -11113,13 +11408,13 @@
bool get isEmpty => this.length == 0;
- List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<num> takeWhile(bool test(num value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<num> skipWhile(bool test(num value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -11164,8 +11459,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<num> get reversed =>
- new ReversedListView<num>(this, 0, null);
+ List<num> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(num a, num b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -11264,12 +11560,18 @@
@DomName('Float64Array')
class Float64Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<num> native "*Float64Array" {
+ @DomName('Float64Array.Float64Array')
+ @DocsEditable
factory Float64Array(int length) =>
_TypedArrayFactoryProvider.createFloat64Array(length);
+ @DomName('Float64Array.fromList')
+ @DocsEditable
factory Float64Array.fromList(List<num> list) =>
_TypedArrayFactoryProvider.createFloat64Array_fromList(list);
+ @DomName('Float64Array.fromBuffer')
+ @DocsEditable
factory Float64Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createFloat64Array_fromBuffer(buffer, byteOffset, length);
@@ -11304,7 +11606,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(num element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(num element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<num> where(bool f(num element)) =>
IterableMixinWorkaround.where(this, f);
@@ -11318,13 +11624,13 @@
bool get isEmpty => this.length == 0;
- List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<num> takeWhile(bool test(num value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<num> skipWhile(bool test(num value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -11369,8 +11675,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<num> get reversed =>
- new ReversedListView<num>(this, 0, null);
+ List<num> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(num a, num b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -11469,19 +11776,16 @@
@DomName('FormData')
class FormData native "*FormData" {
+ @DomName('DOMFormData.DOMFormData')
@DocsEditable
factory FormData([FormElement form]) {
- if (!?form) {
- return FormData._create();
+ if (?form) {
+ return FormData._create_1(form);
}
- return FormData._create(form);
+ return FormData._create_2();
}
- static FormData _create([FormElement form]) {
- if (!?form) {
- return JS('FormData', 'new FormData()');
- }
- return JS('FormData', 'new FormData(#)', form);
- }
+ static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
+ static FormData _create_2() => JS('FormData', 'new FormData()');
@DomName('DOMFormData.append')
@DocsEditable
@@ -11496,6 +11800,7 @@
@DomName('HTMLFormElement')
class FormElement extends Element native "*HTMLFormElement" {
+ @DomName('HTMLFormElement.HTMLFormElement')
@DocsEditable
factory FormElement() => document.$dom_createElement("form");
@@ -11627,6 +11932,7 @@
@DomName('HTMLHRElement')
class HRElement extends Element native "*HTMLHRElement" {
+ @DomName('HTMLHRElement.HTMLHRElement')
@DocsEditable
factory HRElement() => document.$dom_createElement("hr");
}
@@ -11678,6 +11984,7 @@
@DomName('HTMLHeadElement')
class HeadElement extends Element native "*HTMLHeadElement" {
+ @DomName('HTMLHeadElement.HTMLHeadElement')
@DocsEditable
factory HeadElement() => document.$dom_createElement("head");
}
@@ -11690,21 +11997,27 @@
@DomName('HTMLHeadingElement')
class HeadingElement extends Element native "*HTMLHeadingElement" {
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h1() => document.$dom_createElement("h1");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h2() => document.$dom_createElement("h2");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h3() => document.$dom_createElement("h3");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h4() => document.$dom_createElement("h4");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h5() => document.$dom_createElement("h5");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h6() => document.$dom_createElement("h6");
}
@@ -11808,7 +12121,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -11822,13 +12139,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -11873,8 +12190,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -12010,7 +12328,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -12024,13 +12346,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -12075,8 +12397,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -12309,6 +12632,7 @@
@DomName('HTMLHtmlElement')
class HtmlElement extends Element native "*HTMLHtmlElement" {
+ @DomName('HTMLHtmlElement.HTMLHtmlElement')
@DocsEditable
factory HtmlElement() => document.$dom_createElement("html");
}
@@ -12366,25 +12690,39 @@
*/
@DomName('XMLHttpRequest')
class HttpRequest extends EventTarget native "*XMLHttpRequest" {
- /**
- * Creates a URL get request for the specified `url`.
- *
- * After completing the request, the object will call the user-provided
- * [onComplete] callback.
- */
- factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
- _HttpRequestUtils.get(url, onComplete, false);
- // 80 char issue for comments in lists: dartbug.com/7588.
/**
- * Creates a URL GET request for the specified `url` with
- * credentials such a cookie (already) set in the header or
- * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
+ * Creates a URL get request for the specified [url].
*
- * After completing the request, the object will call the user-provided
- * [onComplete] callback.
+ * The server response must be a `text/` mime type for this request to
+ * succeed.
*
- * A few other details to keep in mind when using credentials:
+ * This is similar to [request] but specialized for HTTP GET requests which
+ * return text content.
+ *
+ * See also:
+ *
+ * * [request]
+ */
+ static Future<String> getString(String url,
+ {bool withCredentials, void onProgress(ProgressEvent e)}) {
+ return request(url, withCredentials: withCredentials,
+ onProgress: onProgress).then((xhr) => xhr.responseText);
+ }
+
+ /**
+ * Creates a URL request for the specified [url].
+ *
+ * By default this will do an HTTP GET request, this can be overridden with
+ * [method].
+ *
+ * The Future is completed when the response is available.
+ *
+ * The [withCredentials] parameter specified that credentials such as a cookie
+ * (already) set in the header or
+ * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+ * should be specified for the request. Details to keep in mind when using
+ * credentials:
*
* * Using credentials is only useful for cross-origin requests.
* * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
@@ -12393,11 +12731,59 @@
*
* See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
*/
- factory HttpRequest.getWithCredentials(String url,
- onComplete(HttpRequest request)) =>
- _HttpRequestUtils.get(url, onComplete, true);
+ static Future<HttpRequest> request(String url,
+ {String method, bool withCredentials, String responseType, sendData,
+ void onProgress(ProgressEvent e)}) {
+ var completer = new Completer<HttpRequest>();
+
+ var xhr = new HttpRequest();
+ if (method == null) {
+ method = 'GET';
+ }
+ xhr.open(method, url, true);
+
+ if (withCredentials != null) {
+ xhr.withCredentials = withCredentials;
+ }
+
+ if (responseType != null) {
+ xhr.responseType = responseType;
+ }
+
+ if (onProgress != null) {
+ xhr.onProgress.listen(onProgress);
+ }
+
+ xhr.onLoad.listen((e) {
+ if (xhr.status >= 200 && xhr.status < 300 ||
+ xhr.status == 304 ) {
+ completer.complete(xhr);
+ } else {
+ completer.completeError(e);
+ }
+ });
+
+ xhr.onError.listen((e) {
+ completer.completeError(e);
+ });
+
+ if (sendData != null) {
+ xhr.send(sendData);
+ } else {
+ xhr.send();
+ }
+
+ return completer.future;
+ }
+ /**
+ * Stop the current request.
+ *
+ * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+ * `LOADING`. If this method is not in the process of being sent, the method
+ * has no effect.
+ */
@DomName('XMLHttpRequest.abort')
@DocsEditable
static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
@@ -12426,9 +12812,26 @@
@DocsEditable
static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');
+ /**
+ * General constructor for any type of request (GET, POST, etc).
+ *
+ * This call is used in conjunction with [open]:
+ *
+ * var request = new HttpRequest();
+ * request.open('GET', 'http://dartlang.org')
+ * request.on.load.add((event) => print('Request complete'));
+ *
+ * is the (more verbose) equivalent of
+ *
+ * var request = new HttpRequest.get('http://dartlang.org',
+ * (event) => print('Request complete'));
+ */
+ @DomName('XMLHttpRequest.XMLHttpRequest')
@DocsEditable
- factory HttpRequest() => HttpRequest._create();
- static HttpRequest _create() => JS('HttpRequest', 'new XMLHttpRequest()');
+ factory HttpRequest() {
+ return HttpRequest._create_1();
+ }
+ static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -12446,44 +12849,128 @@
static const int UNSENT = 0;
+ /**
+ * Indicator of the current state of the request:
+ *
+ * <table>
+ * <tr>
+ * <td>Value</td>
+ * <td>State</td>
+ * <td>Meaning</td>
+ * </tr>
+ * <tr>
+ * <td>0</td>
+ * <td>unsent</td>
+ * <td><code>open()</code> has not yet been called</td>
+ * </tr>
+ * <tr>
+ * <td>1</td>
+ * <td>opened</td>
+ * <td><code>send()</code> has not yet been called</td>
+ * </tr>
+ * <tr>
+ * <td>2</td>
+ * <td>headers received</td>
+ * <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
+ * </tr>
+ * <tr>
+ * <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
+ * </tr>
+ * <tr>
+ * <td>4</td> <td>done</td> <td>request is complete</td>
+ * </tr>
+ * </table>
+ */
@DomName('XMLHttpRequest.readyState')
@DocsEditable
final int readyState;
+ /**
+ * The data received as a reponse from the request.
+ *
+ * The data could be in the
+ * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+ * [String]). `null` indicates request failure.
+ */
@DomName('XMLHttpRequest.response')
@DocsEditable
@Creates('ArrayBuffer|Blob|Document|=Object|=List|String|num')
final Object response;
+ /**
+ * The response in string form or `null on failure.
+ */
@DomName('XMLHttpRequest.responseText')
@DocsEditable
final String responseText;
+ /**
+ * [String] telling the server the desired response format.
+ *
+ * Default is `String`.
+ * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+ * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+ * `responseType` is set while performing a synchronous request.
+ *
+ * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+ */
@DomName('XMLHttpRequest.responseType')
@DocsEditable
String responseType;
@JSName('responseXML')
+ /**
+ * The request response, or null on failure.
+ *
+ * The response is processed as
+ * `text/xml` stream, unless responseType = 'document' and the request is
+ * synchronous.
+ */
@DomName('XMLHttpRequest.responseXML')
@DocsEditable
final Document responseXml;
+ /**
+ * The http result code from the request (200, 404, etc).
+ * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+ */
@DomName('XMLHttpRequest.status')
@DocsEditable
final int status;
+ /**
+ * The request response string (such as \"200 OK\").
+ * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+ */
@DomName('XMLHttpRequest.statusText')
@DocsEditable
final String statusText;
+ /**
+ * [EventTarget] that can hold listeners to track the progress of the request.
+ * The events fired will be members of [HttpRequestUploadEvents].
+ */
@DomName('XMLHttpRequest.upload')
@DocsEditable
final HttpRequestUpload upload;
+ /**
+ * True if cross-site requests should use credentials such as cookies
+ * or authorization headers; false otherwise.
+ *
+ * This value is ignored for same-site requests.
+ */
@DomName('XMLHttpRequest.withCredentials')
@DocsEditable
bool withCredentials;
+ /**
+ * Stop the current request.
+ *
+ * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+ * `LOADING`. If this method is not in the process of being sent, the method
+ * has no effect.
+ */
@DomName('XMLHttpRequest.abort')
@DocsEditable
void abort() native;
@@ -12497,18 +12984,51 @@
@DocsEditable
bool dispatchEvent(Event evt) native;
+ /**
+ * Retrieve all the response headers from a request.
+ *
+ * `null` if no headers have been received. For multipart requests,
+ * `getAllResponseHeaders` will return the response headers for the current
+ * part of the request.
+ *
+ * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+ * for a list of common response headers.
+ */
@DomName('XMLHttpRequest.getAllResponseHeaders')
@DocsEditable
String getAllResponseHeaders() native;
+ /**
+ * Return the response header named `header`, or `null` if not found.
+ *
+ * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+ * for a list of common response headers.
+ */
@DomName('XMLHttpRequest.getResponseHeader')
@DocsEditable
String getResponseHeader(String header) native;
+ /**
+ * Specify the desired `url`, and `method` to use in making the request.
+ *
+ * By default the request is done asyncronously, with no user or password
+ * authentication information. If `async` is false, the request will be send
+ * synchronously.
+ *
+ * Calling `open` again on a currently active request is equivalent to
+ * calling `abort`.
+ */
@DomName('XMLHttpRequest.open')
@DocsEditable
void open(String method, String url, [bool async, String user, String password]) native;
+ /**
+ * Specify a particular MIME type (such as `text/xml`) desired for the
+ * response.
+ *
+ * This value must be set before the request has been sent. See also the list
+ * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+ */
@DomName('XMLHttpRequest.overrideMimeType')
@DocsEditable
void overrideMimeType(String override) native;
@@ -12518,6 +13038,13 @@
@DocsEditable
void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
+ /**
+ * Send the request with any given `data`.
+ *
+ * See also:
+ * [send() docs](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send())
+ * from MDN.
+ */
@DomName('XMLHttpRequest.send')
@DocsEditable
void send([data]) native;
@@ -12526,6 +13053,13 @@
@DocsEditable
void setRequestHeader(String header, String value) native;
+ /**
+ * Stop the current request.
+ *
+ * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+ * `LOADING`. If this method is not in the process of being sent, the method
+ * has no effect.
+ */
@DomName('XMLHttpRequest.abort')
@DocsEditable
Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
@@ -12746,6 +13280,7 @@
@DomName('HTMLIFrameElement')
class IFrameElement extends Element native "*HTMLIFrameElement" {
+ @DomName('HTMLIFrameElement.HTMLIFrameElement')
@DocsEditable
factory IFrameElement() => document.$dom_createElement("iframe");
@@ -12812,6 +13347,7 @@
@DomName('HTMLImageElement')
class ImageElement extends Element native "*HTMLImageElement" {
+ @DomName('HTMLImageElement.HTMLImageElement')
@DocsEditable
factory ImageElement({String src, int width, int height}) {
var e = document.$dom_createElement("img");
@@ -13765,12 +14301,18 @@
@DomName('Int16Array')
class Int16Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Int16Array" {
+ @DomName('Int16Array.Int16Array')
+ @DocsEditable
factory Int16Array(int length) =>
_TypedArrayFactoryProvider.createInt16Array(length);
+ @DomName('Int16Array.fromList')
+ @DocsEditable
factory Int16Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createInt16Array_fromList(list);
+ @DomName('Int16Array.fromBuffer')
+ @DocsEditable
factory Int16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createInt16Array_fromBuffer(buffer, byteOffset, length);
@@ -13805,7 +14347,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -13819,13 +14365,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -13870,8 +14416,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -13970,12 +14517,18 @@
@DomName('Int32Array')
class Int32Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Int32Array" {
+ @DomName('Int32Array.Int32Array')
+ @DocsEditable
factory Int32Array(int length) =>
_TypedArrayFactoryProvider.createInt32Array(length);
+ @DomName('Int32Array.fromList')
+ @DocsEditable
factory Int32Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createInt32Array_fromList(list);
+ @DomName('Int32Array.fromBuffer')
+ @DocsEditable
factory Int32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createInt32Array_fromBuffer(buffer, byteOffset, length);
@@ -14010,7 +14563,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -14024,13 +14581,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -14075,8 +14632,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -14175,12 +14733,18 @@
@DomName('Int8Array')
class Int8Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Int8Array" {
+ @DomName('Int8Array.Int8Array')
+ @DocsEditable
factory Int8Array(int length) =>
_TypedArrayFactoryProvider.createInt8Array(length);
+ @DomName('Int8Array.fromList')
+ @DocsEditable
factory Int8Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createInt8Array_fromList(list);
+ @DomName('Int8Array.fromBuffer')
+ @DocsEditable
factory Int8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createInt8Array_fromBuffer(buffer, byteOffset, length);
@@ -14215,7 +14779,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -14229,13 +14797,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -14280,8 +14848,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -14524,6 +15093,7 @@
@Experimental
class KeygenElement extends Element native "*HTMLKeygenElement" {
+ @DomName('HTMLKeygenElement.HTMLKeygenElement')
@DocsEditable
factory KeygenElement() => document.$dom_createElement("keygen");
@@ -14593,6 +15163,7 @@
@DomName('HTMLLIElement')
class LIElement extends Element native "*HTMLLIElement" {
+ @DomName('HTMLLIElement.HTMLLIElement')
@DocsEditable
factory LIElement() => document.$dom_createElement("li");
@@ -14613,6 +15184,7 @@
@DomName('HTMLLabelElement')
class LabelElement extends Element native "*HTMLLabelElement" {
+ @DomName('HTMLLabelElement.HTMLLabelElement')
@DocsEditable
factory LabelElement() => document.$dom_createElement("label");
@@ -14637,6 +15209,7 @@
@DomName('HTMLLegendElement')
class LegendElement extends Element native "*HTMLLegendElement" {
+ @DomName('HTMLLegendElement.HTMLLegendElement')
@DocsEditable
factory LegendElement() => document.$dom_createElement("legend");
@@ -14653,6 +15226,7 @@
@DomName('HTMLLinkElement')
class LinkElement extends Element native "*HTMLLinkElement" {
+ @DomName('HTMLLinkElement.HTMLLinkElement')
@DocsEditable
factory LinkElement() => document.$dom_createElement("link");
@@ -14777,6 +15351,7 @@
@DomName('HTMLMapElement')
class MapElement extends Element native "*HTMLMapElement" {
+ @DomName('HTMLMapElement.HTMLMapElement')
@DocsEditable
factory MapElement() => document.$dom_createElement("map");
@@ -14797,9 +15372,12 @@
@DomName('MediaController')
class MediaController extends EventTarget native "*MediaController" {
+ @DomName('MediaController.MediaController')
@DocsEditable
- factory MediaController() => MediaController._create();
- static MediaController _create() => JS('MediaController', 'new MediaController()');
+ factory MediaController() {
+ return MediaController._create_1();
+ }
+ static MediaController _create_1() => JS('MediaController', 'new MediaController()');
@DomName('MediaController.buffered')
@DocsEditable
@@ -15505,9 +16083,12 @@
@DomName('MediaSource')
class MediaSource extends EventTarget native "*MediaSource" {
+ @DomName('MediaSource.MediaSource')
@DocsEditable
- factory MediaSource() => MediaSource._create();
- static MediaSource _create() => JS('MediaSource', 'new MediaSource()');
+ factory MediaSource() {
+ return MediaSource._create_1();
+ }
+ static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');
@DomName('MediaSource.activeSourceBuffers')
@DocsEditable
@@ -15564,9 +16145,23 @@
@DocsEditable
static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
+ @DomName('MediaStream.MediaStream')
@DocsEditable
- factory MediaStream() => MediaStream._create();
- static MediaStream _create() => JS('MediaStream', 'new MediaStream()');
+ factory MediaStream([stream_OR_tracks]) {
+ if (!?stream_OR_tracks) {
+ return MediaStream._create_1();
+ }
+ if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
+ return MediaStream._create_2(stream_OR_tracks);
+ }
+ if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
+ return MediaStream._create_3(stream_OR_tracks);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+ static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
+ static MediaStream _create_2(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
+ static MediaStream _create_3(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -15699,12 +16294,6 @@
MediaStreamTrackEvents get on =>
new MediaStreamTrackEvents(this);
- static const int ENDED = 2;
-
- static const int LIVE = 0;
-
- static const int MUTED = 1;
-
@DomName('MediaStreamTrack.enabled')
@DocsEditable
bool enabled;
@@ -15723,7 +16312,7 @@
@DomName('MediaStreamTrack.readyState')
@DocsEditable
- final int readyState;
+ final String readyState;
@JSName('addEventListener')
@DomName('MediaStreamTrack.addEventListener')
@@ -15813,6 +16402,7 @@
@DomName('HTMLMenuElement')
class MenuElement extends Element native "*HTMLMenuElement" {
+ @DomName('HTMLMenuElement.HTMLMenuElement')
@DocsEditable
factory MenuElement() => document.$dom_createElement("menu");
}
@@ -15825,9 +16415,12 @@
@DomName('MessageChannel')
class MessageChannel native "*MessageChannel" {
+ @DomName('MessageChannel.MessageChannel')
@DocsEditable
- factory MessageChannel() => MessageChannel._create();
- static MessageChannel _create() => JS('MessageChannel', 'new MessageChannel()');
+ factory MessageChannel() {
+ return MessageChannel._create_1();
+ }
+ static MessageChannel _create_1() => JS('MessageChannel', 'new MessageChannel()');
@DomName('MessageChannel.port1')
@DocsEditable
@@ -16026,6 +16619,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class MeterElement extends Element native "*HTMLMeterElement" {
+ @DomName('HTMLMeterElement.HTMLMeterElement')
@DocsEditable
factory MeterElement() => document.$dom_createElement("meter");
@@ -16124,7 +16718,7 @@
@DomName('MouseEvent.dataTransfer')
@DocsEditable
- final Clipboard dataTransfer;
+ final DataTransfer dataTransfer;
@DomName('MouseEvent.fromElement')
@DocsEditable
@@ -16285,9 +16879,6 @@
@Experimental
class MutationObserver native "*MutationObserver" {
- @DocsEditable
- factory MutationObserver(MutationCallback callback) => MutationObserver._create(callback);
-
@DomName('MutationObserver.disconnect')
@DocsEditable
void disconnect() native;
@@ -16377,7 +16968,7 @@
@JSName('observe')
void _call(target, options) native;
- static MutationObserver _create(MutationCallback callback) {
+ factory MutationObserver(MutationCallback callback) {
// Dummy statement to mark types as instantiated.
JS('MutationObserver|MutationRecord', '0');
@@ -16477,7 +17068,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -16491,13 +17086,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -16542,8 +17137,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -16942,6 +17538,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Node element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Node element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -16961,7 +17561,7 @@
// From List<Node>:
- List<Node> take(int n) {
+ Iterable<Node> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -16969,7 +17569,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) {
+ Iterable<Node> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -16993,8 +17593,9 @@
return this[index];
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
// TODO(jacobr): this could be implemented for child node lists.
// The exception we throw here is misleading.
@@ -17329,7 +17930,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -17343,13 +17948,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -17394,8 +17999,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -17527,19 +18133,16 @@
@DocsEditable
static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
+ @DomName('Notification.Notification')
@DocsEditable
factory Notification(String title, [Map options]) {
- if (!?options) {
- return Notification._create(title);
+ if (?options) {
+ return Notification._create_1(title, options);
}
- return Notification._create(title, options);
+ return Notification._create_2(title);
}
- static Notification _create(String title, [Map options]) {
- if (!?options) {
- return JS('Notification', 'new Notification(#)', title);
- }
- return JS('Notification', 'new Notification(#,#)', title, options);
- }
+ static Notification _create_1(title, options) => JS('Notification', 'new Notification(#,#)', title, options);
+ static Notification _create_2(title) => JS('Notification', 'new Notification(#)', title);
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -17684,6 +18287,7 @@
@DomName('HTMLOListElement')
class OListElement extends Element native "*HTMLOListElement" {
+ @DomName('HTMLOListElement.HTMLOListElement')
@DocsEditable
factory OListElement() => document.$dom_createElement("ol");
@@ -17711,6 +18315,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class ObjectElement extends Element native "*HTMLObjectElement" {
+ @DomName('HTMLObjectElement.HTMLObjectElement')
@DocsEditable
factory ObjectElement() => document.$dom_createElement("object");
@@ -17838,6 +18443,7 @@
@DomName('HTMLOptGroupElement')
class OptGroupElement extends Element native "*HTMLOptGroupElement" {
+ @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
@DocsEditable
factory OptGroupElement() => document.$dom_createElement("optgroup");
@@ -17858,37 +18464,28 @@
@DomName('HTMLOptionElement')
class OptionElement extends Element native "*HTMLOptionElement" {
+ @DomName('HTMLOptionElement.HTMLOptionElement')
@DocsEditable
factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
- if (!?data) {
- return OptionElement._create();
+ if (?selected) {
+ return OptionElement._create_1(data, value, defaultSelected, selected);
}
- if (!?value) {
- return OptionElement._create(data);
+ if (?defaultSelected) {
+ return OptionElement._create_2(data, value, defaultSelected);
}
- if (!?defaultSelected) {
- return OptionElement._create(data, value);
+ if (?value) {
+ return OptionElement._create_3(data, value);
}
- if (!?selected) {
- return OptionElement._create(data, value, defaultSelected);
+ if (?data) {
+ return OptionElement._create_4(data);
}
- return OptionElement._create(data, value, defaultSelected, selected);
+ return OptionElement._create_5();
}
- static OptionElement _create([String data, String value, bool defaultSelected, bool selected]) {
- if (!?data) {
- return JS('OptionElement', 'new Option()');
- }
- if (!?value) {
- return JS('OptionElement', 'new Option(#)', data);
- }
- if (!?defaultSelected) {
- return JS('OptionElement', 'new Option(#,#)', data, value);
- }
- if (!?selected) {
- return JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
- }
- return JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
- }
+ static OptionElement _create_1(data, value, defaultSelected, selected) => JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
+ static OptionElement _create_2(data, value, defaultSelected) => JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
+ static OptionElement _create_3(data, value) => JS('OptionElement', 'new Option(#,#)', data, value);
+ static OptionElement _create_4(data) => JS('OptionElement', 'new Option(#)', data);
+ static OptionElement _create_5() => JS('OptionElement', 'new Option()');
@DomName('HTMLOptionElement.defaultSelected')
@DocsEditable
@@ -17930,6 +18527,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class OutputElement extends Element native "*HTMLOutputElement" {
+ @DomName('HTMLOutputElement.HTMLOutputElement')
@DocsEditable
factory OutputElement() => document.$dom_createElement("output");
@@ -18060,6 +18658,7 @@
@DomName('HTMLParagraphElement')
class ParagraphElement extends Element native "*HTMLParagraphElement" {
+ @DomName('HTMLParagraphElement.HTMLParagraphElement')
@DocsEditable
factory ParagraphElement() => document.$dom_createElement("p");
}
@@ -18072,6 +18671,7 @@
@DomName('HTMLParamElement')
class ParamElement extends Element native "*HTMLParamElement" {
+ @DomName('HTMLParamElement.HTMLParamElement')
@DocsEditable
factory ParamElement() => document.$dom_createElement("param");
@@ -18238,27 +18838,6 @@
@DocsEditable
-@DomName('WebKitPoint')
-class Point native "*WebKitPoint" {
-
- @DocsEditable
- factory Point(num x, num y) => Point._create(x, y);
- static Point _create(num x, num y) => JS('Point', 'new WebKitPoint(#,#)', x, y);
-
- @DomName('WebKitPoint.x')
- @DocsEditable
- num x;
-
- @DomName('WebKitPoint.y')
- @DocsEditable
- num y;
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
@DomName('PopStateEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -18322,6 +18901,7 @@
@DomName('HTMLPreElement')
class PreElement extends Element native "*HTMLPreElement" {
+ @DomName('HTMLPreElement.HTMLPreElement')
@DocsEditable
factory PreElement() => document.$dom_createElement("pre");
@@ -18363,6 +18943,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class ProgressElement extends Element native "*HTMLProgressElement" {
+ @DomName('HTMLProgressElement.HTMLProgressElement')
@DocsEditable
factory ProgressElement() => document.$dom_createElement("progress");
@@ -18826,9 +19407,12 @@
@DomName('RTCIceCandidate')
class RtcIceCandidate native "*RTCIceCandidate" {
+ @DomName('RTCIceCandidate.RTCIceCandidate')
@DocsEditable
- factory RtcIceCandidate(Map dictionary) => RtcIceCandidate._create(dictionary);
- static RtcIceCandidate _create(Map dictionary) => JS('RtcIceCandidate', 'new RTCIceCandidate(#)', dictionary);
+ factory RtcIceCandidate(Map dictionary) {
+ return RtcIceCandidate._create_1(dictionary);
+ }
+ static RtcIceCandidate _create_1(dictionary) => JS('RtcIceCandidate', 'new RTCIceCandidate(#)', dictionary);
@DomName('RTCIceCandidate.candidate')
@DocsEditable
@@ -18884,10 +19468,6 @@
@DocsEditable
static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');
- @DomName('RTCPeerConnection.open')
- @DocsEditable
- static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
-
@DomName('RTCPeerConnection.removestream')
@DocsEditable
static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');
@@ -18896,19 +19476,16 @@
@DocsEditable
static const EventStreamProvider<Event> stateChangeEvent = const EventStreamProvider<Event>('statechange');
+ @DomName('RTCPeerConnection.RTCPeerConnection')
@DocsEditable
factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
- if (!?mediaConstraints) {
- return RtcPeerConnection._create(rtcIceServers);
+ if (?mediaConstraints) {
+ return RtcPeerConnection._create_1(rtcIceServers, mediaConstraints);
}
- return RtcPeerConnection._create(rtcIceServers, mediaConstraints);
+ return RtcPeerConnection._create_2(rtcIceServers);
}
- static RtcPeerConnection _create(Map rtcIceServers, [Map mediaConstraints]) {
- if (!?mediaConstraints) {
- return JS('RtcPeerConnection', 'new RTCPeerConnection(#)', rtcIceServers);
- }
- return JS('RtcPeerConnection', 'new RTCPeerConnection(#,#)', rtcIceServers, mediaConstraints);
- }
+ static RtcPeerConnection _create_1(rtcIceServers, mediaConstraints) => JS('RtcPeerConnection', 'new RTCPeerConnection(#,#)', rtcIceServers, mediaConstraints);
+ static RtcPeerConnection _create_2(rtcIceServers) => JS('RtcPeerConnection', 'new RTCPeerConnection(#)', rtcIceServers);
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -18916,14 +19493,14 @@
RtcPeerConnectionEvents get on =>
new RtcPeerConnectionEvents(this);
+ @DomName('RTCPeerConnection.iceConnectionState')
+ @DocsEditable
+ final String iceConnectionState;
+
@DomName('RTCPeerConnection.iceGatheringState')
@DocsEditable
final String iceGatheringState;
- @DomName('RTCPeerConnection.iceState')
- @DocsEditable
- final String iceState;
-
@DomName('RTCPeerConnection.localDescription')
@DocsEditable
final RtcSessionDescription localDescription;
@@ -18948,6 +19525,10 @@
@Creates('_MediaStreamList')
final List<MediaStream> remoteStreams;
+ @DomName('RTCPeerConnection.signalingState')
+ @DocsEditable
+ final String signalingState;
+
@JSName('addEventListener')
@DomName('RTCPeerConnection.addEventListener')
@DocsEditable
@@ -19104,10 +19685,6 @@
@DocsEditable
Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);
- @DomName('RTCPeerConnection.open')
- @DocsEditable
- Stream<Event> get onOpen => openEvent.forTarget(this);
-
@DomName('RTCPeerConnection.removestream')
@DocsEditable
Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);
@@ -19136,9 +19713,6 @@
EventListenerList get negotiationNeeded => this['negotiationneeded'];
@DocsEditable
- EventListenerList get open => this['open'];
-
- @DocsEditable
EventListenerList get removeStream => this['removestream'];
@DocsEditable
@@ -19153,9 +19727,12 @@
@DomName('RTCSessionDescription')
class RtcSessionDescription native "*RTCSessionDescription" {
+ @DomName('RTCSessionDescription.RTCSessionDescription')
@DocsEditable
- factory RtcSessionDescription(Map dictionary) => RtcSessionDescription._create(dictionary);
- static RtcSessionDescription _create(Map dictionary) => JS('RtcSessionDescription', 'new RTCSessionDescription(#)', dictionary);
+ factory RtcSessionDescription(Map dictionary) {
+ return RtcSessionDescription._create_1(dictionary);
+ }
+ static RtcSessionDescription _create_1(dictionary) => JS('RtcSessionDescription', 'new RTCSessionDescription(#)', dictionary);
@DomName('RTCSessionDescription.sdp')
@DocsEditable
@@ -19306,6 +19883,7 @@
@DomName('HTMLScriptElement')
class ScriptElement extends Element native "*HTMLScriptElement" {
+ @DomName('HTMLScriptElement.HTMLScriptElement')
@DocsEditable
factory ScriptElement() => document.$dom_createElement("script");
@@ -19420,6 +19998,7 @@
@DomName('HTMLSelectElement')
class SelectElement extends Element native "*HTMLSelectElement" {
+ @DomName('HTMLSelectElement.HTMLSelectElement')
@DocsEditable
factory SelectElement() => document.$dom_createElement("select");
@@ -19616,19 +20195,16 @@
@DomName('SharedWorker')
class SharedWorker extends AbstractWorker native "*SharedWorker" {
+ @DomName('SharedWorker.SharedWorker')
@DocsEditable
factory SharedWorker(String scriptURL, [String name]) {
- if (!?name) {
- return SharedWorker._create(scriptURL);
+ if (?name) {
+ return SharedWorker._create_1(scriptURL, name);
}
- return SharedWorker._create(scriptURL, name);
+ return SharedWorker._create_2(scriptURL);
}
- static SharedWorker _create(String scriptURL, [String name]) {
- if (!?name) {
- return JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
- }
- return JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
- }
+ static SharedWorker _create_1(scriptURL, name) => JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
+ static SharedWorker _create_2(scriptURL) => JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
@DomName('SharedWorker.port')
@DocsEditable
@@ -19737,7 +20313,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SourceBuffer element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SourceBuffer element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SourceBuffer element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SourceBuffer> where(bool f(SourceBuffer element)) =>
IterableMixinWorkaround.where(this, f);
@@ -19751,13 +20331,13 @@
bool get isEmpty => this.length == 0;
- List<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SourceBuffer> takeWhile(bool test(SourceBuffer value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SourceBuffer> skipWhile(bool test(SourceBuffer value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -19802,8 +20382,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SourceBuffer> get reversed =>
- new ReversedListView<SourceBuffer>(this, 0, null);
+ List<SourceBuffer> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SourceBuffer a, SourceBuffer b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -19911,6 +20492,7 @@
@DomName('HTMLSourceElement')
class SourceElement extends Element native "*HTMLSourceElement" {
+ @DomName('HTMLSourceElement.HTMLSourceElement')
@DocsEditable
factory SourceElement() => document.$dom_createElement("source");
@@ -19935,6 +20517,7 @@
@DomName('HTMLSpanElement')
class SpanElement extends Element native "*HTMLSpanElement" {
+ @DomName('HTMLSpanElement.HTMLSpanElement')
@DocsEditable
factory SpanElement() => document.$dom_createElement("span");
}
@@ -19947,9 +20530,12 @@
@DomName('SpeechGrammar')
class SpeechGrammar native "*SpeechGrammar" {
+ @DomName('SpeechGrammar.SpeechGrammar')
@DocsEditable
- factory SpeechGrammar() => SpeechGrammar._create();
- static SpeechGrammar _create() => JS('SpeechGrammar', 'new SpeechGrammar()');
+ factory SpeechGrammar() {
+ return SpeechGrammar._create_1();
+ }
+ static SpeechGrammar _create_1() => JS('SpeechGrammar', 'new SpeechGrammar()');
@DomName('SpeechGrammar.src')
@DocsEditable
@@ -19968,9 +20554,12 @@
@DomName('SpeechGrammarList')
class SpeechGrammarList implements JavaScriptIndexingBehavior, List<SpeechGrammar> native "*SpeechGrammarList" {
+ @DomName('SpeechGrammarList.SpeechGrammarList')
@DocsEditable
- factory SpeechGrammarList() => SpeechGrammarList._create();
- static SpeechGrammarList _create() => JS('SpeechGrammarList', 'new SpeechGrammarList()');
+ factory SpeechGrammarList() {
+ return SpeechGrammarList._create_1();
+ }
+ static SpeechGrammarList _create_1() => JS('SpeechGrammarList', 'new SpeechGrammarList()');
@DomName('SpeechGrammarList.length')
@DocsEditable
@@ -20004,7 +20593,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SpeechGrammar element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SpeechGrammar element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SpeechGrammar element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SpeechGrammar> where(bool f(SpeechGrammar element)) =>
IterableMixinWorkaround.where(this, f);
@@ -20018,13 +20611,13 @@
bool get isEmpty => this.length == 0;
- List<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SpeechGrammar> takeWhile(bool test(SpeechGrammar value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SpeechGrammar> skipWhile(bool test(SpeechGrammar value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -20069,8 +20662,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SpeechGrammar> get reversed =>
- new ReversedListView<SpeechGrammar>(this, 0, null);
+ List<SpeechGrammar> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SpeechGrammar a, SpeechGrammar b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -20249,9 +20843,6 @@
@DocsEditable
static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');
- @DocsEditable
- factory SpeechRecognition() => SpeechRecognition._create();
-
/// Checks if this type is supported on the current platform.
static bool get supported => JS('bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');
@@ -20351,7 +20942,7 @@
@DocsEditable
Stream<Event> get onStart => startEvent.forTarget(this);
- static SpeechRecognition _create() {
+ factory SpeechRecognition() {
return JS('SpeechRecognition',
'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
}
@@ -20616,7 +21207,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Map element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Map element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Map element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Map> where(bool f(Map element)) =>
IterableMixinWorkaround.where(this, f);
@@ -20630,13 +21225,13 @@
bool get isEmpty => this.length == 0;
- List<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Map> takeWhile(bool test(Map value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Map> skipWhile(bool test(Map value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -20681,8 +21276,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Map> get reversed =>
- new ReversedListView<Map>(this, 0, null);
+ List<Map> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Map a, Map b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -20779,6 +21375,9 @@
@DocsEditable
@DomName('SQLTransaction')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class SqlTransaction native "*SQLTransaction" {
@DomName('SQLTransaction.executeSql')
@@ -20792,6 +21391,9 @@
@DocsEditable
@DomName('SQLTransactionSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class SqlTransactionSync native "*SQLTransactionSync" {
@DomName('SQLTransactionSync.executeSql')
@@ -20992,6 +21594,7 @@
@DomName('HTMLStyleElement')
class StyleElement extends Element native "*HTMLStyleElement" {
+ @DomName('HTMLStyleElement.HTMLStyleElement')
@DocsEditable
factory StyleElement() => document.$dom_createElement("style");
@@ -21078,6 +21681,7 @@
@DomName('HTMLTableCaptionElement')
class TableCaptionElement extends Element native "*HTMLTableCaptionElement" {
+ @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
@DocsEditable
factory TableCaptionElement() => document.$dom_createElement("caption");
}
@@ -21090,6 +21694,7 @@
@DomName('HTMLTableCellElement')
class TableCellElement extends Element native "*HTMLTableCellElement" {
+ @DomName('HTMLTableCellElement.HTMLTableCellElement')
@DocsEditable
factory TableCellElement() => document.$dom_createElement("td");
@@ -21118,6 +21723,7 @@
@DomName('HTMLTableColElement')
class TableColElement extends Element native "*HTMLTableColElement" {
+ @DomName('HTMLTableColElement.HTMLTableColElement')
@DocsEditable
factory TableColElement() => document.$dom_createElement("col");
@@ -21133,6 +21739,7 @@
@DomName('HTMLTableElement')
class TableElement extends Element native "*HTMLTableElement" {
+ @DomName('HTMLTableElement.HTMLTableElement')
@DocsEditable
factory TableElement() => document.$dom_createElement("table");
@@ -21214,6 +21821,7 @@
@DomName('HTMLTableRowElement')
class TableRowElement extends Element native "*HTMLTableRowElement" {
+ @DomName('HTMLTableRowElement.HTMLTableRowElement')
@DocsEditable
factory TableRowElement() => document.$dom_createElement("tr");
@@ -21291,6 +21899,7 @@
@DomName('HTMLTextAreaElement')
class TextAreaElement extends Element native "*HTMLTextAreaElement" {
+ @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
@DocsEditable
factory TextAreaElement() => document.$dom_createElement("textarea");
@@ -21546,9 +22155,12 @@
@DocsEditable
static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');
+ @DomName('TextTrackCue.TextTrackCue')
@DocsEditable
- factory TextTrackCue(num startTime, num endTime, String text) => TextTrackCue._create(startTime, endTime, text);
- static TextTrackCue _create(num startTime, num endTime, String text) => JS('TextTrackCue', 'new TextTrackCue(#,#,#)', startTime, endTime, text);
+ factory TextTrackCue(num startTime, num endTime, String text) {
+ return TextTrackCue._create_1(startTime, endTime, text);
+ }
+ static TextTrackCue _create_1(startTime, endTime, text) => JS('TextTrackCue', 'new TextTrackCue(#,#,#)', startTime, endTime, text);
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -21685,7 +22297,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(TextTrackCue element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(TextTrackCue element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(TextTrackCue element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<TextTrackCue> where(bool f(TextTrackCue element)) =>
IterableMixinWorkaround.where(this, f);
@@ -21699,13 +22315,13 @@
bool get isEmpty => this.length == 0;
- List<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<TextTrackCue> takeWhile(bool test(TextTrackCue value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<TextTrackCue> skipWhile(bool test(TextTrackCue value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -21750,8 +22366,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<TextTrackCue> get reversed =>
- new ReversedListView<TextTrackCue>(this, 0, null);
+ List<TextTrackCue> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(TextTrackCue a, TextTrackCue b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -21891,7 +22508,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(TextTrack element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(TextTrack element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(TextTrack element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<TextTrack> where(bool f(TextTrack element)) =>
IterableMixinWorkaround.where(this, f);
@@ -21905,13 +22526,13 @@
bool get isEmpty => this.length == 0;
- List<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<TextTrack> takeWhile(bool test(TextTrack value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<TextTrack> skipWhile(bool test(TextTrack value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -21956,8 +22577,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<TextTrack> get reversed =>
- new ReversedListView<TextTrack>(this, 0, null);
+ List<TextTrack> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(TextTrack a, TextTrack b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -22108,6 +22730,7 @@
@DomName('HTMLTitleElement')
class TitleElement extends Element native "*HTMLTitleElement" {
+ @DomName('HTMLTitleElement.HTMLTitleElement')
@DocsEditable
factory TitleElement() => document.$dom_createElement("title");
}
@@ -22228,6 +22851,19 @@
@DocsEditable
void $dom_initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;
+
+ /**
+ * Checks if touch events supported on the current platform.
+ *
+ * Note that touch events are only supported if the user is using a touch
+ * device.
+ */
+ static bool get supported {
+ if (JS('bool', '"ontouchstart" in window')) {
+ return Event._isTypeSupported('TouchEvent');
+ }
+ return false;
+ }
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -22270,7 +22906,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Touch element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Touch element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Touch element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Touch> where(bool f(Touch element)) =>
IterableMixinWorkaround.where(this, f);
@@ -22284,13 +22924,13 @@
bool get isEmpty => this.length == 0;
- List<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Touch> takeWhile(bool test(Touch value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Touch> skipWhile(bool test(Touch value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -22335,8 +22975,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Touch> get reversed =>
- new ReversedListView<Touch>(this, 0, null);
+ List<Touch> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Touch a, Touch b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -22433,6 +23074,7 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class TrackElement extends Element native "*HTMLTrackElement" {
+ @DomName('HTMLTrackElement.HTMLTrackElement')
@DocsEditable
factory TrackElement() => document.$dom_createElement("track");
@@ -22646,6 +23288,7 @@
@DomName('HTMLUListElement')
class UListElement extends Element native "*HTMLUListElement" {
+ @DomName('HTMLUListElement.HTMLUListElement')
@DocsEditable
factory UListElement() => document.$dom_createElement("ul");
}
@@ -22658,12 +23301,18 @@
@DomName('Uint16Array')
class Uint16Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Uint16Array" {
+ @DomName('Uint16Array.Uint16Array')
+ @DocsEditable
factory Uint16Array(int length) =>
_TypedArrayFactoryProvider.createUint16Array(length);
+ @DomName('Uint16Array.fromList')
+ @DocsEditable
factory Uint16Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint16Array_fromList(list);
+ @DomName('Uint16Array.fromBuffer')
+ @DocsEditable
factory Uint16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint16Array_fromBuffer(buffer, byteOffset, length);
@@ -22698,7 +23347,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -22712,13 +23365,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -22763,8 +23416,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -22863,12 +23517,18 @@
@DomName('Uint32Array')
class Uint32Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Uint32Array" {
+ @DomName('Uint32Array.Uint32Array')
+ @DocsEditable
factory Uint32Array(int length) =>
_TypedArrayFactoryProvider.createUint32Array(length);
+ @DomName('Uint32Array.fromList')
+ @DocsEditable
factory Uint32Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint32Array_fromList(list);
+ @DomName('Uint32Array.fromBuffer')
+ @DocsEditable
factory Uint32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint32Array_fromBuffer(buffer, byteOffset, length);
@@ -22903,7 +23563,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -22917,13 +23581,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -22968,8 +23632,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -23068,12 +23733,18 @@
@DomName('Uint8Array')
class Uint8Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Uint8Array" {
+ @DomName('Uint8Array.Uint8Array')
+ @DocsEditable
factory Uint8Array(int length) =>
_TypedArrayFactoryProvider.createUint8Array(length);
+ @DomName('Uint8Array.fromList')
+ @DocsEditable
factory Uint8Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint8Array_fromList(list);
+ @DomName('Uint8Array.fromBuffer')
+ @DocsEditable
factory Uint8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint8Array_fromBuffer(buffer, byteOffset, length);
@@ -23108,7 +23779,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -23122,13 +23797,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -23173,8 +23848,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -23273,12 +23949,18 @@
@DomName('Uint8ClampedArray')
class Uint8ClampedArray extends Uint8Array implements JavaScriptIndexingBehavior, List<int> native "*Uint8ClampedArray" {
+ @DomName('Uint8ClampedArray.Uint8ClampedArray')
+ @DocsEditable
factory Uint8ClampedArray(int length) =>
_TypedArrayFactoryProvider.createUint8ClampedArray(length);
+ @DomName('Uint8ClampedArray.fromList')
+ @DocsEditable
factory Uint8ClampedArray.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint8ClampedArray_fromList(list);
+ @DomName('Uint8ClampedArray.fromBuffer')
+ @DocsEditable
factory Uint8ClampedArray.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint8ClampedArray_fromBuffer(buffer, byteOffset, length);
@@ -23310,7 +23992,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -23324,13 +24010,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -23375,8 +24061,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -23551,6 +24238,7 @@
@DomName('HTMLVideoElement')
class VideoElement extends MediaElement native "*HTMLVideoElement" {
+ @DomName('HTMLVideoElement.HTMLVideoElement')
@DocsEditable
factory VideoElement() => document.$dom_createElement("video");
@@ -23795,8 +24483,14 @@
@DocsEditable
@DomName('WebGLRenderingContext')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Experimental
class WebGLRenderingContext extends CanvasRenderingContext native "*WebGLRenderingContext" {
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => JS('bool', '!!(window.WebGLRenderingContext)');
+
static const int ACTIVE_ATTRIBUTES = 0x8B89;
static const int ACTIVE_TEXTURE = 0x84E0;
@@ -25210,9 +25904,23 @@
@DocsEditable
static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
+ @DomName('WebSocket.WebSocket')
@DocsEditable
- factory WebSocket(String url) => WebSocket._create(url);
- static WebSocket _create(String url) => JS('WebSocket', 'new WebSocket(#)', url);
+ factory WebSocket(String url, [protocol_OR_protocols]) {
+ if ((url is String || url == null) && !?protocol_OR_protocols) {
+ return WebSocket._create_1(url);
+ }
+ if ((url is String || url == null) && (protocol_OR_protocols is List<String> || protocol_OR_protocols == null)) {
+ return WebSocket._create_2(url, protocol_OR_protocols);
+ }
+ if ((url is String || url == null) && (protocol_OR_protocols is String || protocol_OR_protocols == null)) {
+ return WebSocket._create_3(url, protocol_OR_protocols);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+ static WebSocket _create_1(url) => JS('WebSocket', 'new WebSocket(#)', url);
+ static WebSocket _create_2(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);
+ static WebSocket _create_3(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);
/// Checks if this type is supported on the current platform.
static bool get supported => JS('bool', 'typeof window.WebSocket != "undefined"');
@@ -25589,12 +26297,13 @@
}
/**
- * Executes a [callback] after the next batch of browser layout measurements
- * has completed or would have completed if any browser layout measurements
- * had been scheduled.
+ * Executes a [callback] after the immediate execution stack has completed.
+ *
+ * This will cause the callback to be executed after all processing has
+ * completed for the current event, but before any subsequent events.
*/
- void requestLayoutFrame(TimeoutHandler callback) {
- _addMeasurementFrameCallback(callback);
+ void setImmediate(TimeoutHandler callback) {
+ _addMicrotaskCallback(callback);
}
@DomName('DOMWindow.requestAnimationFrame')
@@ -25677,6 +26386,15 @@
@DomName('Window.console')
Console get console => Console.safeConsole;
+ /// Checks if _setImmediate is supported.
+ static bool get _supportsSetImmediate =>
+ JS('bool', '!!(window.setImmediate)');
+
+ // Set immediate implementation for IE
+ void _setImmediate(void callback()) {
+ JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0));
+ }
+
@DomName('DOMWindow.DOMContentLoaded')
@DocsEditable
@@ -26030,6 +26748,9 @@
@DomName('DOMWindow.openDatabase')
@DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
@Creates('Database')
@Creates('DatabaseSync')
Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
@@ -26105,13 +26826,15 @@
@DocsEditable
void stop() native;
+ @JSName('webkitConvertPointFromNodeToPage')
@DomName('DOMWindow.webkitConvertPointFromNodeToPage')
@DocsEditable
- Point webkitConvertPointFromNodeToPage(Node node, Point p) native;
+ DomPoint convertPointFromNodeToPage(Node node, DomPoint p) native;
+ @JSName('webkitConvertPointFromPageToNode')
@DomName('DOMWindow.webkitConvertPointFromPageToNode')
@DocsEditable
- Point webkitConvertPointFromPageToNode(Node node, Point p) native;
+ DomPoint convertPointFromPageToNode(Node node, DomPoint p) native;
@JSName('webkitRequestFileSystem')
@DomName('DOMWindow.webkitRequestFileSystem')
@@ -26586,9 +27309,12 @@
@DocsEditable
static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
+ @DomName('Worker.Worker')
@DocsEditable
- factory Worker(String scriptUrl) => Worker._create(scriptUrl);
- static Worker _create(String scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);
+ factory Worker(String scriptUrl) {
+ return Worker._create_1(scriptUrl);
+ }
+ static Worker _create_1(scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -26698,10 +27424,16 @@
@DomName('WorkerContext.openDatabase')
@DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
@DomName('WorkerContext.openDatabaseSync')
@DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
@JSName('removeEventListener')
@@ -26858,9 +27590,12 @@
@DomName('XPathEvaluator')
class XPathEvaluator native "*XPathEvaluator" {
+ @DomName('XPathEvaluator.XPathEvaluator')
@DocsEditable
- factory XPathEvaluator() => XPathEvaluator._create();
- static XPathEvaluator _create() => JS('XPathEvaluator', 'new XPathEvaluator()');
+ factory XPathEvaluator() {
+ return XPathEvaluator._create_1();
+ }
+ static XPathEvaluator _create_1() => JS('XPathEvaluator', 'new XPathEvaluator()');
@DomName('XPathEvaluator.createExpression')
@DocsEditable
@@ -27004,9 +27739,12 @@
@DomName('XMLSerializer')
class XmlSerializer native "*XMLSerializer" {
+ @DomName('XMLSerializer.XMLSerializer')
@DocsEditable
- factory XmlSerializer() => XmlSerializer._create();
- static XmlSerializer _create() => JS('XmlSerializer', 'new XMLSerializer()');
+ factory XmlSerializer() {
+ return XmlSerializer._create_1();
+ }
+ static XmlSerializer _create_1() => JS('XmlSerializer', 'new XMLSerializer()');
@DomName('XMLSerializer.serializeToString')
@DocsEditable
@@ -27019,11 +27757,20 @@
@DocsEditable
@DomName('XSLTProcessor')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
class XsltProcessor native "*XSLTProcessor" {
+ @DomName('XSLTProcessor.XSLTProcessor')
@DocsEditable
- factory XsltProcessor() => XsltProcessor._create();
- static XsltProcessor _create() => JS('XsltProcessor', 'new XSLTProcessor()');
+ factory XsltProcessor() {
+ return XsltProcessor._create_1();
+ }
+ static XsltProcessor _create_1() => JS('XsltProcessor', 'new XSLTProcessor()');
+
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => JS('bool', '!!(window.XSLTProcessor)');
@DomName('XSLTProcessor.clearParameters')
@DocsEditable
@@ -27116,7 +27863,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(ClientRect element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(ClientRect element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(ClientRect element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<ClientRect> where(bool f(ClientRect element)) =>
IterableMixinWorkaround.where(this, f);
@@ -27130,13 +27881,13 @@
bool get isEmpty => this.length == 0;
- List<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<ClientRect> takeWhile(bool test(ClientRect value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<ClientRect> skipWhile(bool test(ClientRect value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -27181,8 +27932,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<ClientRect> get reversed =>
- new ReversedListView<ClientRect>(this, 0, null);
+ List<ClientRect> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(ClientRect a, ClientRect b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -27308,7 +28060,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(CssRule element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(CssRule element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(CssRule element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<CssRule> where(bool f(CssRule element)) =>
IterableMixinWorkaround.where(this, f);
@@ -27322,13 +28078,13 @@
bool get isEmpty => this.length == 0;
- List<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<CssRule> takeWhile(bool test(CssRule value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<CssRule> skipWhile(bool test(CssRule value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -27373,8 +28129,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<CssRule> get reversed =>
- new ReversedListView<CssRule>(this, 0, null);
+ List<CssRule> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(CssRule a, CssRule b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -27500,7 +28257,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(CssValue element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(CssValue element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(CssValue element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<CssValue> where(bool f(CssValue element)) =>
IterableMixinWorkaround.where(this, f);
@@ -27514,13 +28275,13 @@
bool get isEmpty => this.length == 0;
- List<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<CssValue> takeWhile(bool test(CssValue value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<CssValue> skipWhile(bool test(CssValue value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -27565,8 +28326,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<CssValue> get reversed =>
- new ReversedListView<CssValue>(this, 0, null);
+ List<CssValue> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(CssValue a, CssValue b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -27701,7 +28463,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Entry element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Entry element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Entry element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Entry> where(bool f(Entry element)) =>
IterableMixinWorkaround.where(this, f);
@@ -27715,13 +28481,13 @@
bool get isEmpty => this.length == 0;
- List<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Entry> takeWhile(bool test(Entry value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Entry> skipWhile(bool test(Entry value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -27766,8 +28532,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Entry> get reversed =>
- new ReversedListView<Entry>(this, 0, null);
+ List<Entry> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Entry a, Entry b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -27893,7 +28660,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(EntrySync element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(EntrySync element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(EntrySync element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<EntrySync> where(bool f(EntrySync element)) =>
IterableMixinWorkaround.where(this, f);
@@ -27907,13 +28678,13 @@
bool get isEmpty => this.length == 0;
- List<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<EntrySync> takeWhile(bool test(EntrySync value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<EntrySync> skipWhile(bool test(EntrySync value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -27958,8 +28729,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<EntrySync> get reversed =>
- new ReversedListView<EntrySync>(this, 0, null);
+ List<EntrySync> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(EntrySync a, EntrySync b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -28164,7 +28936,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Gamepad element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Gamepad element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Gamepad element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Gamepad> where(bool f(Gamepad element)) =>
IterableMixinWorkaround.where(this, f);
@@ -28178,13 +28954,13 @@
bool get isEmpty => this.length == 0;
- List<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Gamepad> takeWhile(bool test(Gamepad value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Gamepad> skipWhile(bool test(Gamepad value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -28229,8 +29005,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Gamepad> get reversed =>
- new ReversedListView<Gamepad>(this, 0, null);
+ List<Gamepad> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Gamepad a, Gamepad b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -28365,7 +29142,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(MediaStream element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(MediaStream element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(MediaStream element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<MediaStream> where(bool f(MediaStream element)) =>
IterableMixinWorkaround.where(this, f);
@@ -28379,13 +29160,13 @@
bool get isEmpty => this.length == 0;
- List<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<MediaStream> takeWhile(bool test(MediaStream value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<MediaStream> skipWhile(bool test(MediaStream value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -28430,8 +29211,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<MediaStream> get reversed =>
- new ReversedListView<MediaStream>(this, 0, null);
+ List<MediaStream> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(MediaStream a, MediaStream b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -28557,7 +29339,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SpeechInputResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SpeechInputResult element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SpeechInputResult element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SpeechInputResult> where(bool f(SpeechInputResult element)) =>
IterableMixinWorkaround.where(this, f);
@@ -28571,13 +29357,13 @@
bool get isEmpty => this.length == 0;
- List<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SpeechInputResult> takeWhile(bool test(SpeechInputResult value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SpeechInputResult> skipWhile(bool test(SpeechInputResult value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -28622,8 +29408,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SpeechInputResult> get reversed =>
- new ReversedListView<SpeechInputResult>(this, 0, null);
+ List<SpeechInputResult> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SpeechInputResult a, SpeechInputResult b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -28749,7 +29536,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SpeechRecognitionResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SpeechRecognitionResult element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SpeechRecognitionResult element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SpeechRecognitionResult> where(bool f(SpeechRecognitionResult element)) =>
IterableMixinWorkaround.where(this, f);
@@ -28763,13 +29554,13 @@
bool get isEmpty => this.length == 0;
- List<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SpeechRecognitionResult> takeWhile(bool test(SpeechRecognitionResult value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SpeechRecognitionResult> skipWhile(bool test(SpeechRecognitionResult value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -28814,8 +29605,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SpeechRecognitionResult> get reversed =>
- new ReversedListView<SpeechRecognitionResult>(this, 0, null);
+ List<SpeechRecognitionResult> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SpeechRecognitionResult a, SpeechRecognitionResult b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -28941,7 +29733,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(StyleSheet element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(StyleSheet element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(StyleSheet element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<StyleSheet> where(bool f(StyleSheet element)) =>
IterableMixinWorkaround.where(this, f);
@@ -28955,13 +29751,13 @@
bool get isEmpty => this.length == 0;
- List<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<StyleSheet> takeWhile(bool test(StyleSheet value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<StyleSheet> skipWhile(bool test(StyleSheet value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -29006,8 +29802,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<StyleSheet> get reversed =>
- new ReversedListView<StyleSheet>(this, 0, null);
+ List<StyleSheet> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(StyleSheet a, StyleSheet b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -29487,6 +30284,8 @@
String join([String separator]) => readClasses().join(separator);
+ Iterable map(f(String element)) => readClasses().map(f);
+
Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
Iterable<String> where(bool f(String element)) => readClasses().where(f);
@@ -29584,7 +30383,7 @@
* Helper method used to modify the set of css classes on this element.
*
* f - callback with:
- * s - a Set of all the css class name currently on this element.
+ * s - a Set of all the css class name currently on this element.
*
* After f returns, the modified set is written to the
* className property of this element.
@@ -29667,7 +30466,7 @@
_EventStream(this._target, this._eventType, this._useCapture);
// DOM events are inherently multi-subscribers.
- Stream<T> asMultiSubscriberStream() => this;
+ Stream<T> asBroadcastStream() => this;
StreamSubscription<T> listen(void onData(T event),
{ void onError(AsyncError error),
@@ -29840,9 +30639,8 @@
// The distance to shift from upper case alphabet Roman letters to lower case.
final 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;
+ StreamSubscription _keyUpSubscription, _keyDownSubscription,
+ _keyPressSubscription;
/**
* An enumeration of key identifiers currently part of the W3C draft for DOM3
@@ -29898,9 +30696,6 @@
_callbacks = [];
_type = type;
_target = target;
- _keyDown = processKeyDown;
- _keyUp = processKeyUp;
- _keyPress = processKeyPress;
}
/**
@@ -29909,9 +30704,14 @@
*/
void _initializeAllEventListeners() {
_keyDownList = [];
- _target.on.keyDown.add(_keyDown, true);
- _target.on.keyPress.add(_keyPress, true);
- _target.on.keyUp.add(_keyUp, true);
+ if (_keyDownSubscription == null) {
+ _keyDownSubscription = Element.keyDownEvent.forTarget(
+ _target, useCapture: true).listen(processKeyDown);
+ _keyPressSubscription = Element.keyPressEvent.forTarget(
+ _target, useCapture: true).listen(processKeyUp);
+ _keyUpSubscription = Element.keyUpEvent.forTarget(
+ _target, useCapture: true).listen(processKeyPress);
+ }
}
/** Add a callback that wishes to be notified when a KeyEvent occurs. */
@@ -29945,9 +30745,12 @@
}
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);
+ _keyDownSubscription.cancel();
+ _keyDownSubscription = null;
+ _keyPressSubscription.cancel();
+ _keyPressSubscription = null;
+ _keyUpSubscription.cancel();
+ _keyUpSubscription = null;
}
}
@@ -31044,7 +31847,7 @@
request.withCredentials = withCredentials;
- request.on.readyStateChange.add((e) {
+ request.onReadyStateChange.listen((e) {
if (request.readyState == HttpRequest.DONE) {
onComplete(request);
}
@@ -31284,46 +32087,38 @@
// BSD-style license that can be found in the LICENSE file.
-typedef Object ComputeValue();
-
-class _MeasurementRequest<T> {
- final ComputeValue computeValue;
- final Completer<T> completer;
- Object value;
- bool exception = false;
- _MeasurementRequest(this.computeValue, this.completer);
-}
-
-typedef void _MeasurementCallback();
+typedef void _MicrotaskCallback();
/**
* This class attempts to invoke a callback as soon as the current event stack
* unwinds, but before the browser repaints.
*/
-abstract class _MeasurementScheduler {
- bool _nextMeasurementFrameScheduled = false;
- _MeasurementCallback _callback;
+abstract class _MicrotaskScheduler {
+ bool _nextMicrotaskFrameScheduled = false;
+ _MicrotaskCallback _callback;
- _MeasurementScheduler(this._callback);
+ _MicrotaskScheduler(this._callback);
/**
- * Creates the best possible measurement scheduler for the current platform.
+ * Creates the best possible microtask scheduler for the current platform.
*/
- factory _MeasurementScheduler.best(_MeasurementCallback callback) {
- if (MutationObserver.supported) {
+ factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+ if (Window._supportsSetImmediate) {
+ return new _SetImmediateScheduler(callback);
+ } else if (MutationObserver.supported) {
return new _MutationObserverScheduler(callback);
}
return new _PostMessageScheduler(callback);
}
/**
- * Schedules a measurement callback if one has not been scheduled already.
+ * Schedules a microtask callback if one has not been scheduled already.
*/
void maybeSchedule() {
- if (this._nextMeasurementFrameScheduled) {
+ if (this._nextMicrotaskFrameScheduled) {
return;
}
- this._nextMeasurementFrameScheduled = true;
+ this._nextMicrotaskFrameScheduled = true;
this._schedule();
}
@@ -31333,14 +32128,14 @@
void _schedule();
/**
- * Handles the measurement callback and forwards it if necessary.
+ * Handles the microtask callback and forwards it if necessary.
*/
void _onCallback() {
// Ignore spurious messages.
- if (!_nextMeasurementFrameScheduled) {
+ if (!_nextMicrotaskFrameScheduled) {
return;
}
- _nextMeasurementFrameScheduled = false;
+ _nextMicrotaskFrameScheduled = false;
this._callback();
}
}
@@ -31348,22 +32143,22 @@
/**
* Scheduler which uses window.postMessage to schedule events.
*/
-class _PostMessageScheduler extends _MeasurementScheduler {
- const _MEASUREMENT_MESSAGE = "DART-MEASURE";
+class _PostMessageScheduler extends _MicrotaskScheduler {
+ const _MICROTASK_MESSAGE = "DART-MICROTASK";
- _PostMessageScheduler(_MeasurementCallback callback): super(callback) {
+ _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
// Messages from other windows do not cause a security risk as
// all we care about is that _handleMessage is called
// after the current event loop is unwound and calling the function is
// a noop when zero requests are pending.
- window.on.message.add(this._handleMessage);
+ window.onMessage.listen(this._handleMessage);
}
void _schedule() {
- window.postMessage(_MEASUREMENT_MESSAGE, "*");
+ window.postMessage(_MICROTASK_MESSAGE, "*");
}
- _handleMessage(e) {
+ void _handleMessage(e) {
this._onCallback();
}
}
@@ -31371,11 +32166,11 @@
/**
* Scheduler which uses a MutationObserver to schedule events.
*/
-class _MutationObserverScheduler extends _MeasurementScheduler {
+class _MutationObserverScheduler extends _MicrotaskScheduler {
MutationObserver _observer;
Element _dummy;
- _MutationObserverScheduler(_MeasurementCallback callback): super(callback) {
+ _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
// Mutation events get fired as soon as the current event stack is unwound
// so we just make a dummy event and listen for that.
_observer = new MutationObserver(this._handleMutation);
@@ -31393,89 +32188,53 @@
}
}
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+ _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
-List<_MeasurementRequest> _pendingRequests;
-List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
-_MeasurementScheduler _measurementScheduler = null;
-
-void _maybeScheduleMeasurementFrame() {
- if (_measurementScheduler == null) {
- _measurementScheduler =
- new _MeasurementScheduler.best(_completeMeasurementFutures);
+ void _schedule() {
+ window._setImmediate(_handleImmediate);
}
- _measurementScheduler.maybeSchedule();
+
+ void _handleImmediate() {
+ this._onCallback();
+ }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+ if (_microtaskScheduler == null) {
+ _microtaskScheduler =
+ new _MicrotaskScheduler.best(_completeMicrotasks);
+ }
+ _microtaskScheduler.maybeSchedule();
}
/**
- * Registers a [callback] which is called after the next batch of measurements
- * completes. Even if no measurements completed, the callback is triggered
- * when they would have completed to avoid confusing bugs if it happened that
- * no measurements were actually requested.
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
*/
-void _addMeasurementFrameCallback(TimeoutHandler callback) {
- if (_pendingMeasurementFrameCallbacks == null) {
- _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
- _maybeScheduleMeasurementFrame();
+void _addMicrotaskCallback(TimeoutHandler callback) {
+ if (_pendingMicrotasks == null) {
+ _pendingMicrotasks = <TimeoutHandler>[];
+ _maybeScheduleMicrotaskFrame();
}
- _pendingMeasurementFrameCallbacks.add(callback);
+ _pendingMicrotasks.add(callback);
}
-/**
- * Returns a [Future] whose value will be the result of evaluating
- * [computeValue] during the next safe measurement interval.
- * The next safe measurement interval is after the current event loop has
- * unwound but before the browser has rendered the page.
- * It is important that the [computeValue] function only queries the html
- * layout and html in any way.
- */
-Future _createMeasurementFuture(ComputeValue computeValue,
- Completer completer) {
- if (_pendingRequests == null) {
- _pendingRequests = <_MeasurementRequest>[];
- _maybeScheduleMeasurementFrame();
- }
- _pendingRequests.add(new _MeasurementRequest(computeValue, completer));
- return completer.future;
-}
/**
- * Complete all pending measurement futures evaluating them in a single batch
- * so that the the browser is guaranteed to avoid multiple layouts.
+ * Complete all pending microtasks.
*/
-void _completeMeasurementFutures() {
- // We must compute all new values before fulfilling the futures as
- // the onComplete callbacks for the futures could modify the DOM making
- // subsequent measurement calculations expensive to compute.
- if (_pendingRequests != null) {
- for (_MeasurementRequest request in _pendingRequests) {
- try {
- request.value = request.computeValue();
- } catch (e) {
- request.value = e;
- request.exception = true;
- }
- }
- }
-
- final completedRequests = _pendingRequests;
- final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
- _pendingRequests = null;
- _pendingMeasurementFrameCallbacks = null;
- if (completedRequests != null) {
- for (_MeasurementRequest request in completedRequests) {
- if (request.exception) {
- request.completer.completeError(request.value);
- } else {
- request.completer.complete(request.value);
- }
- }
- }
-
- if (readyMeasurementFrameCallbacks != null) {
- for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
- // TODO(jacobr): wrap each call to a handler in a try-catch block.
- handler();
- }
+void _completeMicrotasks() {
+ var callbacks = _pendingMicrotasks;
+ _pendingMicrotasks = null;
+ for (var callback in callbacks) {
+ callback();
}
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -31945,7 +32704,7 @@
_parent.cancelBubble = cancel;
}
/** Accessor to the clipboardData available for this event. */
- Clipboard get clipboardData => _parent.clipboardData;
+ DataTransfer 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. */
@@ -32247,26 +33006,6 @@
// copies the list.
static ensureNative(List list) => list; // TODO: make sure.
}
-// Copyright (c) 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(rnystrom): add a way to supress public classes from DartDoc output.
-// TODO(jacobr): we can remove this class now that we are using the $dom_
-// convention for deprecated methods rather than truly private methods.
-/**
- * This class is intended for testing purposes only.
- */
-class Testing {
- static void addEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
- target.$dom_addEventListener(type, listener, useCapture);
- }
- static void removeEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
- target.$dom_removeEventListener(type, listener, useCapture);
- }
-
-}
// 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.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index f44afd1..41f2758 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1,8 +1,7 @@
-library html;
+library dart.dom.html;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
@@ -127,6 +126,7 @@
class AnchorElement extends _Element_Merged {
AnchorElement.internal() : super.internal();
+ @DomName('HTMLAnchorElement.HTMLAnchorElement')
@DocsEditable
factory AnchorElement({String href}) {
var e = document.$dom_createElement("a");
@@ -458,6 +458,7 @@
class AreaElement extends _Element_Merged {
AreaElement.internal() : super.internal();
+ @DomName('HTMLAreaElement.HTMLAreaElement')
@DocsEditable
factory AreaElement() => document.$dom_createElement("area");
@@ -553,10 +554,10 @@
@SupportedBrowser(SupportedBrowser.SAFARI)
class ArrayBuffer extends NativeFieldWrapperClass1 {
ArrayBuffer.internal();
+ factory ArrayBuffer(int length) => _create(length);
@DocsEditable
- factory ArrayBuffer(int length) => ArrayBuffer._create(length);
- static ArrayBuffer _create(int length) native "ArrayBuffer_constructor_Callback";
+ static ArrayBuffer _create(length) native "ArrayBuffer_constructorCallback";
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -635,14 +636,14 @@
class AudioElement extends MediaElement {
AudioElement.internal() : super.internal();
+ @DomName('HTMLAudioElement.HTMLAudioElement')
@DocsEditable
factory AudioElement([String src]) {
- if (!?src) {
- return AudioElement._create();
- }
- return AudioElement._create(src);
+ return AudioElement._create_1(src);
}
- static AudioElement _create([String src]) native "HTMLAudioElement_constructor_Callback";
+
+ @DocsEditable
+ static AudioElement _create_1(src) native "HTMLAudioElement__create_1constructorCallback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -657,6 +658,7 @@
class BRElement extends _Element_Merged {
BRElement.internal() : super.internal();
+ @DomName('HTMLBRElement.HTMLBRElement')
@DocsEditable
factory BRElement() => document.$dom_createElement("br");
@@ -690,6 +692,7 @@
class BaseElement extends _Element_Merged {
BaseElement.internal() : super.internal();
+ @DomName('HTMLBaseElement.HTMLBaseElement')
@DocsEditable
factory BaseElement() => document.$dom_createElement("base");
@@ -833,18 +836,10 @@
@DomName('Blob')
class Blob extends NativeFieldWrapperClass1 {
Blob.internal();
+ factory Blob(List blobParts, [String type, String endings]) => _create(blobParts, type, endings);
@DocsEditable
- factory Blob(List blobParts, [String type, String endings]) {
- if (!?type) {
- return Blob._create(blobParts);
- }
- if (!?endings) {
- return Blob._create(blobParts, type);
- }
- return Blob._create(blobParts, type, endings);
- }
- static Blob _create(List blobParts, [String type, String endings]) native "Blob_constructor_Callback";
+ static Blob _create(blobParts, type, endings) native "Blob_constructorCallback";
@DomName('Blob.size')
@DocsEditable
@@ -949,6 +944,7 @@
@DocsEditable
static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
+ @DomName('HTMLBodyElement.HTMLBodyElement')
@DocsEditable
factory BodyElement() => document.$dom_createElement("body");
@@ -1069,6 +1065,7 @@
class ButtonElement extends _Element_Merged {
ButtonElement.internal() : super.internal();
+ @DomName('HTMLButtonElement.HTMLButtonElement')
@DocsEditable
factory ButtonElement() => document.$dom_createElement("button");
@@ -1203,6 +1200,7 @@
class CanvasElement extends _Element_Merged {
CanvasElement.internal() : super.internal();
+ @DomName('HTMLCanvasElement.HTMLCanvasElement')
@DocsEditable
factory CanvasElement({int width, int height}) {
var e = document.$dom_createElement("canvas");
@@ -1211,32 +1209,96 @@
return e;
}
+ /// The height of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.height')
@DocsEditable
int get height native "HTMLCanvasElement_height_Getter";
+ /// The height of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.height')
@DocsEditable
void set height(int value) native "HTMLCanvasElement_height_Setter";
+ /// The width of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.width')
@DocsEditable
int get width native "HTMLCanvasElement_width_Getter";
+ /// The width of this canvas element in CSS pixels.
@DomName('HTMLCanvasElement.width')
@DocsEditable
void set width(int value) native "HTMLCanvasElement_width_Setter";
@DomName('HTMLCanvasElement.getContext')
@DocsEditable
- Object getContext(String contextId) native "HTMLCanvasElement_getContext_Callback";
+ CanvasRenderingContext getContext(String contextId, [Map attrs]) native "HTMLCanvasElement_getContext_Callback";
+ /**
+ * Returns a data URI containing a representation of the image in the
+ * format specified by type (defaults to 'image/png').
+ *
+ * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+ *
+ * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]
+ * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default
+ * value is used. Note: the default value varies by browser.
+ *
+ * If the height or width of this canvas element is 0, then 'data:' is returned,
+ * representing no data.
+ *
+ * If the type requested is not 'image/png', and the returned value is
+ * 'data:image/png', then the requested type is not supported.
+ *
+ * Example usage:
+ *
+ * CanvasElement canvas = new CanvasElement();
+ * var ctx = canvas.context2d
+ * ..fillStyle = "rgb(200,0,0)"
+ * ..fillRect(10, 10, 55, 50);
+ * var dataUrl = canvas.toDataURL("image/jpeg", 0.95);
+ * // The Data Uri would look similar to
+ * // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+ * // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+ * // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+ * //Create a new image element from the data URI.
+ * var img = new ImageElement();
+ * img.src = dataUrl;
+ * document.body.children.add(img);
+ *
+ * See also:
+ *
+ * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+ *
+ * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+ *
+ * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+ */
@DomName('HTMLCanvasElement.toDataURL')
@DocsEditable
String toDataUrl(String type, [num quality]) native "HTMLCanvasElement_toDataURL_Callback";
-
CanvasRenderingContext2D get context2d => getContext('2d');
+
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.FIREFOX)
+ @Experimental
+ WebGLRenderingContext getContext3d({alpha: true, depth: true, stencil: false,
+ antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {
+
+ var options = {
+ 'alpha': alpha,
+ 'depth': depth,
+ 'stencil': stencil,
+ 'antialias': antialias,
+ 'premultipliedAlpha': premultipliedAlpha,
+ 'preserveDrawingBuffer': preserveDrawingBuffer,
+ };
+ var context = getContext('webgl', options);
+ if (context == null) {
+ context = getContext('experimental-webgl', options);
+ }
+ return context;
+ }
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -1246,10 +1308,48 @@
@DocsEditable
+/**
+ * An opaque canvas object representing a gradient.
+ *
+ * Created by calling [createLinearGradient] or [createRadialGradient] on a
+ * [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ * var canvas = new CanvasElement(width: 600, height: 600);
+ * var ctx = canvas.context2d;
+ * ctx.clearRect(0, 0, 600, 600);
+ * ctx.save();
+ * // Create radial gradient.
+ * CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
+ * gradient.addColorStop(0, '#000');
+ * gradient.addColorStop(1, 'rgb(255, 255, 255)');
+ * // Assign gradients to fill.
+ * ctx.fillStyle = gradient;
+ * // Draw a rectangle with a gradient fill.
+ * ctx.fillRect(0, 0, 600, 600);
+ * ctx.save();
+ * document.body.children.add(canvas);
+ *
+ * See also:
+ *
+ * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
+ * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
+ */
@DomName('CanvasGradient')
class CanvasGradient extends NativeFieldWrapperClass1 {
CanvasGradient.internal();
+ /**
+ * Adds a color stop to this gradient at the offset.
+ *
+ * The [offset] can range between 0.0 and 1.0.
+ *
+ * See also:
+ *
+ * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
+ */
@DomName('CanvasGradient.addColorStop')
@DocsEditable
void addColorStop(num offset, String color) native "CanvasGradient_addColorStop_Callback";
@@ -1263,6 +1363,33 @@
@DocsEditable
+/**
+ * An opaque object representing a pattern of image, canvas, or video.
+ *
+ * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ * var canvas = new CanvasElement(width: 600, height: 600);
+ * var ctx = canvas.context2d;
+ * var img = new ImageElement();
+ * // Image src needs to be loaded before pattern is applied.
+ * img.onLoad.listen((event) {
+ * // When the image is loaded, create a pattern
+ * // from the ImageElement.
+ * CanvasPattern pattern = ctx.createPattern(img, 'repeat');
+ * ctx.rect(0, 0, canvas.width, canvas.height);
+ * ctx.fillStyle = pattern;
+ * ctx.fill();
+ * });
+ * img.src = "images/foo.jpg";
+ * document.body.children.add(canvas);
+ *
+ * See also:
+ * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
+ * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
+ */
@DomName('CanvasPattern')
class CanvasPattern extends NativeFieldWrapperClass1 {
CanvasPattern.internal();
@@ -1276,10 +1403,17 @@
@DocsEditable
+/**
+ * A rendering context for a canvas element.
+ *
+ * This context is extended by [CanvasRenderingContext2D] and
+ * [WebGLRenderingContext].
+ */
@DomName('CanvasRenderingContext')
class CanvasRenderingContext extends NativeFieldWrapperClass1 {
CanvasRenderingContext.internal();
+ /// Reference to the canvas element to which this context belongs.
@DomName('CanvasRenderingContext.canvas')
@DocsEditable
CanvasElement get canvas native "CanvasRenderingContext_canvas_Getter";
@@ -1470,9 +1604,22 @@
@DocsEditable
void clearRect(num x, num y, num width, num height) native "CanvasRenderingContext2D_clearRect_Callback";
- @DomName('CanvasRenderingContext2D.clip')
+ void clip([String winding]) {
+ if (?winding) {
+ _clip_1(winding);
+ return;
+ }
+ _clip_2();
+ return;
+ }
+
+ @DomName('CanvasRenderingContext2D._clip_1')
@DocsEditable
- void clip() native "CanvasRenderingContext2D_clip_Callback";
+ void _clip_1(winding) native "CanvasRenderingContext2D__clip_1_Callback";
+
+ @DomName('CanvasRenderingContext2D._clip_2')
+ @DocsEditable
+ void _clip_2() native "CanvasRenderingContext2D__clip_2_Callback";
@DomName('CanvasRenderingContext2D.closePath')
@DocsEditable
@@ -1598,9 +1745,22 @@
@DocsEditable
void _drawImage_9(canvas_OR_image_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh) native "CanvasRenderingContext2D__drawImage_9_Callback";
- @DomName('CanvasRenderingContext2D.fill')
+ void fill([String winding]) {
+ if (?winding) {
+ _fill_1(winding);
+ return;
+ }
+ _fill_2();
+ return;
+ }
+
+ @DomName('CanvasRenderingContext2D._fill_1')
@DocsEditable
- void fill() native "CanvasRenderingContext2D_fill_Callback";
+ void _fill_1(winding) native "CanvasRenderingContext2D__fill_1_Callback";
+
+ @DomName('CanvasRenderingContext2D._fill_2')
+ @DocsEditable
+ void _fill_2() native "CanvasRenderingContext2D__fill_2_Callback";
@DomName('CanvasRenderingContext2D.fillRect')
@DocsEditable
@@ -1631,9 +1791,20 @@
@DocsEditable
List<num> getLineDash() native "CanvasRenderingContext2D_getLineDash_Callback";
- @DomName('CanvasRenderingContext2D.isPointInPath')
+ bool isPointInPath(num x, num y, [String winding]) {
+ if (?winding) {
+ return _isPointInPath_1(x, y, winding);
+ }
+ return _isPointInPath_2(x, y);
+ }
+
+ @DomName('CanvasRenderingContext2D._isPointInPath_1')
@DocsEditable
- bool isPointInPath(num x, num y) native "CanvasRenderingContext2D_isPointInPath_Callback";
+ bool _isPointInPath_1(x, y, winding) native "CanvasRenderingContext2D__isPointInPath_1_Callback";
+
+ @DomName('CanvasRenderingContext2D._isPointInPath_2')
+ @DocsEditable
+ bool _isPointInPath_2(x, y) native "CanvasRenderingContext2D__isPointInPath_2_Callback";
@DomName('CanvasRenderingContext2D.lineTo')
@DocsEditable
@@ -1900,63 +2071,6 @@
@DocsEditable
-@DomName('Clipboard')
-class Clipboard extends NativeFieldWrapperClass1 {
- Clipboard.internal();
-
- @DomName('Clipboard.dropEffect')
- @DocsEditable
- String get dropEffect native "Clipboard_dropEffect_Getter";
-
- @DomName('Clipboard.dropEffect')
- @DocsEditable
- void set dropEffect(String value) native "Clipboard_dropEffect_Setter";
-
- @DomName('Clipboard.effectAllowed')
- @DocsEditable
- String get effectAllowed native "Clipboard_effectAllowed_Getter";
-
- @DomName('Clipboard.effectAllowed')
- @DocsEditable
- void set effectAllowed(String value) native "Clipboard_effectAllowed_Setter";
-
- @DomName('Clipboard.files')
- @DocsEditable
- List<File> get files native "Clipboard_files_Getter";
-
- @DomName('Clipboard.items')
- @DocsEditable
- DataTransferItemList get items native "Clipboard_items_Getter";
-
- @DomName('Clipboard.types')
- @DocsEditable
- List get types native "Clipboard_types_Getter";
-
- @DomName('Clipboard.clearData')
- @DocsEditable
- void clearData([String type]) native "Clipboard_clearData_Callback";
-
- @DomName('Clipboard.getData')
- @DocsEditable
- String getData(String type) native "Clipboard_getData_Callback";
-
- @DomName('Clipboard.setData')
- @DocsEditable
- bool setData(String type, String data) native "Clipboard_setData_Callback";
-
- @DomName('Clipboard.setDragImage')
- @DocsEditable
- void setDragImage(ImageElement image, int x, int y) native "Clipboard_setDragImage_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.
-
-
-@DocsEditable
@DomName('CloseEvent')
class CloseEvent extends Event {
CloseEvent.internal() : super.internal();
@@ -2132,6 +2246,7 @@
class ContentElement extends _Element_Merged {
ContentElement.internal() : super.internal();
+ @DomName('HTMLContentElement.HTMLContentElement')
@DocsEditable
factory ContentElement() => document.$dom_createElement("content");
@@ -2288,6 +2403,31 @@
@DocsEditable
+@DomName('CSSHostRule')
+class CssHostRule extends CssRule {
+ CssHostRule.internal() : super.internal();
+
+ @DomName('CSSHostRule.cssRules')
+ @DocsEditable
+ List<CssRule> get cssRules native "CSSHostRule_cssRules_Getter";
+
+ @DomName('CSSHostRule.deleteRule')
+ @DocsEditable
+ void deleteRule(int index) native "CSSHostRule_deleteRule_Callback";
+
+ @DomName('CSSHostRule.insertRule')
+ @DocsEditable
+ int insertRule(String rule, int index) native "CSSHostRule_insertRule_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.
+
+
+@DocsEditable
@DomName('CSSImportRule')
class CssImportRule extends CssRule {
CssImportRule.internal() : super.internal();
@@ -2376,17 +2516,23 @@
@DocsEditable
@DomName('WebKitCSSMatrix')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class CssMatrix extends NativeFieldWrapperClass1 {
CssMatrix.internal();
+ @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
@DocsEditable
factory CssMatrix([String cssValue]) {
- if (!?cssValue) {
- return CssMatrix._create();
- }
- return CssMatrix._create(cssValue);
+ return CssMatrix._create_1(cssValue);
}
- static CssMatrix _create([String cssValue]) native "WebKitCSSMatrix_constructor_Callback";
+
+ @DocsEditable
+ static CssMatrix _create_1(cssValue) native "WebKitCSSMatrix__create_1constructorCallback";
+
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => true;
@DomName('WebKitCSSMatrix.a')
@DocsEditable
@@ -2778,6 +2924,8 @@
static const int FONT_FACE_RULE = 5;
+ static const int HOST_RULE = 1001;
+
static const int IMPORT_RULE = 3;
static const int MEDIA_RULE = 4;
@@ -6271,6 +6419,7 @@
class DListElement extends _Element_Merged {
DListElement.internal() : super.internal();
+ @DomName('HTMLDListElement.HTMLDListElement')
@DocsEditable
factory DListElement() => document.$dom_createElement("dl");
@@ -6291,6 +6440,7 @@
class DataListElement extends _Element_Merged {
DataListElement.internal() : super.internal();
+ @DomName('HTMLDataListElement.HTMLDataListElement')
@DocsEditable
factory DataListElement() => document.$dom_createElement("datalist");
@@ -6310,6 +6460,63 @@
@DocsEditable
+@DomName('Clipboard')
+class DataTransfer extends NativeFieldWrapperClass1 {
+ DataTransfer.internal();
+
+ @DomName('Clipboard.dropEffect')
+ @DocsEditable
+ String get dropEffect native "Clipboard_dropEffect_Getter";
+
+ @DomName('Clipboard.dropEffect')
+ @DocsEditable
+ void set dropEffect(String value) native "Clipboard_dropEffect_Setter";
+
+ @DomName('Clipboard.effectAllowed')
+ @DocsEditable
+ String get effectAllowed native "Clipboard_effectAllowed_Getter";
+
+ @DomName('Clipboard.effectAllowed')
+ @DocsEditable
+ void set effectAllowed(String value) native "Clipboard_effectAllowed_Setter";
+
+ @DomName('Clipboard.files')
+ @DocsEditable
+ List<File> get files native "Clipboard_files_Getter";
+
+ @DomName('Clipboard.items')
+ @DocsEditable
+ DataTransferItemList get items native "Clipboard_items_Getter";
+
+ @DomName('Clipboard.types')
+ @DocsEditable
+ List get types native "Clipboard_types_Getter";
+
+ @DomName('Clipboard.clearData')
+ @DocsEditable
+ void clearData([String type]) native "Clipboard_clearData_Callback";
+
+ @DomName('Clipboard.getData')
+ @DocsEditable
+ String getData(String type) native "Clipboard_getData_Callback";
+
+ @DomName('Clipboard.setData')
+ @DocsEditable
+ bool setData(String type, String data) native "Clipboard_setData_Callback";
+
+ @DomName('Clipboard.setDragImage')
+ @DocsEditable
+ void setDragImage(ImageElement image, int x, int y) native "Clipboard_setDragImage_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.
+
+
+@DocsEditable
@DomName('DataTransferItem')
class DataTransferItem extends NativeFieldWrapperClass1 {
DataTransferItem.internal();
@@ -6391,18 +6598,10 @@
@DomName('DataView')
class DataView extends ArrayBufferView {
DataView.internal() : super.internal();
+ factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) => _create(buffer, byteOffset, byteLength);
@DocsEditable
- factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
- if (!?byteOffset) {
- return DataView._create(buffer);
- }
- if (!?byteLength) {
- return DataView._create(buffer, byteOffset);
- }
- return DataView._create(buffer, byteOffset, byteLength);
- }
- static DataView _create(ArrayBuffer buffer, [int byteOffset, int byteLength]) native "DataView_constructor_Callback";
+ static DataView _create(buffer, byteOffset, byteLength) native "DataView_constructorCallback";
num getFloat32(int byteOffset, {bool littleEndian}) {
if (?littleEndian) {
@@ -6622,9 +6821,15 @@
@DocsEditable
@DomName('Database')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class Database extends NativeFieldWrapperClass1 {
Database.internal();
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => true;
+
@DomName('Database.version')
@DocsEditable
String get version native "Database_version_Getter";
@@ -6659,6 +6864,9 @@
@DocsEditable
@DomName('DatabaseSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class DatabaseSync extends NativeFieldWrapperClass1 {
DatabaseSync.internal();
@@ -6739,6 +6947,7 @@
class DetailsElement extends _Element_Merged {
DetailsElement.internal() : super.internal();
+ @DomName('HTMLDetailsElement.HTMLDetailsElement')
@DocsEditable
factory DetailsElement() => document.$dom_createElement("details");
@@ -6911,10 +7120,32 @@
@DocsEditable
+/**
+ * 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')
class DivElement extends _Element_Merged {
DivElement.internal() : super.internal();
+ @DomName('HTMLDivElement.HTMLDivElement')
@DocsEditable
factory DivElement() => document.$dom_createElement("div");
@@ -6961,10 +7192,12 @@
DocumentEvents get on =>
new DocumentEvents(this);
+ /// Moved to [HtmlDocument].
@DomName('Document.body')
@DocsEditable
Element get $dom_body native "Document_body_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.body')
@DocsEditable
void set $dom_body(Element value) native "Document_body_Setter";
@@ -6997,6 +7230,7 @@
@DocsEditable
String get domain native "Document_domain_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.head')
@DocsEditable
HeadElement get $dom_head native "Document_head_Getter";
@@ -7005,6 +7239,7 @@
@DocsEditable
DomImplementation get implementation native "Document_implementation_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.lastModified')
@DocsEditable
String get $dom_lastModified native "Document_lastModified_Getter";
@@ -7017,6 +7252,7 @@
@DocsEditable
String get readyState native "Document_readyState_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.referrer')
@DocsEditable
String get $dom_referrer native "Document_referrer_Getter";
@@ -7029,34 +7265,42 @@
@DocsEditable
void set $dom_selectedStylesheetSet(String value) native "Document_selectedStylesheetSet_Setter";
+ /// Moved to [HtmlDocument]
@DomName('Document.styleSheets')
@DocsEditable
List<StyleSheet> get $dom_styleSheets native "Document_styleSheets_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.title')
@DocsEditable
String get $dom_title native "Document_title_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.title')
@DocsEditable
void set $dom_title(String value) native "Document_title_Setter";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitFullscreenElement')
@DocsEditable
Element get $dom_webkitFullscreenElement native "Document_webkitFullscreenElement_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitFullscreenEnabled')
@DocsEditable
bool get $dom_webkitFullscreenEnabled native "Document_webkitFullscreenEnabled_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitHidden')
@DocsEditable
bool get $dom_webkitHidden native "Document_webkitHidden_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitIsFullScreen')
@DocsEditable
bool get $dom_webkitIsFullScreen native "Document_webkitIsFullScreen_Getter";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitPointerLockElement')
@DocsEditable
Element get $dom_webkitPointerLockElement native "Document_webkitPointerLockElement_Getter";
@@ -7065,6 +7309,7 @@
@DocsEditable
String get $dom_webkitVisibilityState native "Document_webkitVisibilityState_Getter";
+ /// Use the [Range] constructor instead.
@DomName('Document.caretRangeFromPoint')
@DocsEditable
Range $dom_caretRangeFromPoint(int x, int y) native "Document_caretRangeFromPoint_Callback";
@@ -7077,6 +7322,7 @@
@DocsEditable
DocumentFragment createDocumentFragment() native "Document_createDocumentFragment_Callback";
+ /// Deprecated: use new Element.tag(tagName) instead.
@DomName('Document.createElement')
@DocsEditable
Element $dom_createElement(String tagName) native "Document_createElement_Callback";
@@ -7101,6 +7347,7 @@
@DocsEditable
Touch $dom_createTouch(Window window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) native "Document_createTouch_Callback";
+ /// Use the [TouchList] constructor instead.
@DomName('Document.createTouchList')
@DocsEditable
TouchList $dom_createTouchList() native "Document_createTouchList_Callback";
@@ -7113,10 +7360,12 @@
@DocsEditable
bool execCommand(String command, bool userInterface, String value) native "Document_execCommand_Callback";
+ /// Moved to [HtmlDocument].
@DomName('Document.getCSSCanvasContext')
@DocsEditable
CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
+ /// Deprecated: use query("#$elementId") instead.
@DomName('Document.getElementById')
@DocsEditable
Element $dom_getElementById(String elementId) native "Document_getElementById_Callback";
@@ -7153,22 +7402,27 @@
@DocsEditable
String queryCommandValue(String command) native "Document_queryCommandValue_Callback";
+ /// Deprecated: renamed to the shorter name [query].
@DomName('Document.querySelector')
@DocsEditable
Element $dom_querySelector(String selectors) native "Document_querySelector_Callback";
+ /// Deprecated: use query("#$elementId") instead.
@DomName('Document.querySelectorAll')
@DocsEditable
List<Node> $dom_querySelectorAll(String selectors) native "Document_querySelectorAll_Callback";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitCancelFullScreen')
@DocsEditable
void $dom_webkitCancelFullScreen() native "Document_webkitCancelFullScreen_Callback";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitExitFullscreen')
@DocsEditable
void $dom_webkitExitFullscreen() native "Document_webkitExitFullscreen_Callback";
+ /// Moved to [HtmlDocument].
@DomName('Document.webkitExitPointerLock')
@DocsEditable
void $dom_webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
@@ -7725,7 +7979,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(DomMimeType element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(DomMimeType element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(DomMimeType element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<DomMimeType> where(bool f(DomMimeType element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7739,13 +7997,13 @@
bool get isEmpty => this.length == 0;
- List<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<DomMimeType> takeWhile(bool test(DomMimeType value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<DomMimeType> skipWhile(bool test(DomMimeType value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -7790,8 +8048,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<DomMimeType> get reversed =>
- new ReversedListView<DomMimeType>(this, 0, null);
+ List<DomMimeType> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(DomMimeType a, DomMimeType b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -7893,9 +8152,14 @@
class DomParser extends NativeFieldWrapperClass1 {
DomParser.internal();
+ @DomName('DOMParser.DOMParser')
@DocsEditable
- factory DomParser() => DomParser._create();
- static DomParser _create() native "DOMParser_constructor_Callback";
+ factory DomParser() {
+ return DomParser._create_1();
+ }
+
+ @DocsEditable
+ static DomParser _create_1() native "DOMParser__create_1constructorCallback";
@DomName('DOMParser.parseFromString')
@DocsEditable
@@ -7983,7 +8247,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(DomPlugin element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(DomPlugin element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(DomPlugin element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<DomPlugin> where(bool f(DomPlugin element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7997,13 +8265,13 @@
bool get isEmpty => this.length == 0;
- List<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<DomPlugin> takeWhile(bool test(DomPlugin value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<DomPlugin> skipWhile(bool test(DomPlugin value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -8048,8 +8316,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<DomPlugin> get reversed =>
- new ReversedListView<DomPlugin>(this, 0, null);
+ List<DomPlugin> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(DomPlugin a, DomPlugin b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -8151,6 +8420,45 @@
@DocsEditable
+@DomName('WebKitPoint')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
+class DomPoint extends NativeFieldWrapperClass1 {
+ DomPoint.internal();
+ factory DomPoint(num x, num y) => _create(x, y);
+
+ @DocsEditable
+ static DomPoint _create(x, y) native "WebKitPoint_constructorCallback";
+
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => true;
+
+ @DomName('WebKitPoint.x')
+ @DocsEditable
+ num get x native "WebKitPoint_x_Getter";
+
+ @DomName('WebKitPoint.x')
+ @DocsEditable
+ void set x(num value) native "WebKitPoint_x_Setter";
+
+ @DomName('WebKitPoint.y')
+ @DocsEditable
+ num get y native "WebKitPoint_y_Getter";
+
+ @DomName('WebKitPoint.y')
+ @DocsEditable
+ void set y(num value) native "WebKitPoint_y_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.
+
+
+@DocsEditable
@DomName('Selection')
class DomSelection extends NativeFieldWrapperClass1 {
DomSelection.internal();
@@ -8325,7 +8633,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(String element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(String element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<String> where(bool f(String element)) =>
IterableMixinWorkaround.where(this, f);
@@ -8339,13 +8651,13 @@
bool get isEmpty => this.length == 0;
- List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<String> takeWhile(bool test(String value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<String> skipWhile(bool test(String value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -8390,8 +8702,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<String> get reversed =>
- new ReversedListView<String>(this, 0, null);
+ List<String> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(String a, String b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -8600,6 +8913,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Element element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Element element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -8612,7 +8929,7 @@
return _element.$dom_firstElementChild == null;
}
- List<Element> take(int n) {
+ Iterable<Element> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -8620,7 +8937,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Element> skip(int n) {
+ Iterable<Element> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -8676,8 +8993,9 @@
}
}
- List<Element> get reversed =>
- new ReversedListView<Element>(this, 0, null);
+ List<Element> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -8695,7 +9013,7 @@
void remove(Object object) {
if (object is Element) {
Element element = object;
- if (identical(element.parentNode, this)) {
+ if (identical(element.parentNode, _element)) {
_element.$dom_removeChild(element);
}
}
@@ -8812,6 +9130,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Element element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Element element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -8841,7 +9163,7 @@
List<Element> toList() => new List<Element>.from(this);
Set<Element> toSet() => new Set<Element>.from(this);
- List<Element> take(int n) {
+ Iterable<Element> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -8849,7 +9171,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Element> skip(int n) {
+ Iterable<Element> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -8901,8 +9223,9 @@
throw new UnsupportedError('');
}
- List<Element> get reversed =>
- new ReversedListView<Element>(this, 0, null);
+ List<Element> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('');
@@ -9247,27 +9570,20 @@
* [style] property, which contains only the values specified directly on this
* element.
*
+ * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+ * `::line-marker`.
+ *
* See also:
*
* * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
- */
- Future<CssStyleDeclaration> get computedStyle {
- // TODO(jacobr): last param should be null, see b/5045788
- return getComputedStyle('');
- }
-
- /**
- * Returns the computed styles for pseudo-elements such as `::after`,
- * `::before`, `::marker`, `::line-marker`.
- *
- * See also:
- *
* * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
*/
- Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) {
- return _createMeasurementFuture(
- () => window.$dom_getComputedStyle(this, pseudoElement),
- new Completer<CssStyleDeclaration>());
+ CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+ if (pseudoElement == null) {
+ pseudoElement = '';
+ }
+ // TODO(jacobr): last param should be null, see b/5045788
+ return window.$dom_getComputedStyle(this, pseudoElement);
}
/**
@@ -10307,6 +10623,7 @@
class EmbedElement extends _Element_Merged {
EmbedElement.internal() : super.internal();
+ @DomName('HTMLEmbedElement.HTMLEmbedElement')
@DocsEditable
factory EmbedElement() => document.$dom_createElement("embed");
@@ -10659,7 +10976,7 @@
@DomName('Event.clipboardData')
@DocsEditable
- Clipboard get clipboardData native "Event_clipboardData_Getter";
+ DataTransfer get clipboardData native "Event_clipboardData_Getter";
@DomName('Event.currentTarget')
@DocsEditable
@@ -10779,14 +11096,14 @@
@DocsEditable
static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
+ @DomName('EventSource.EventSource')
@DocsEditable
factory EventSource(String url, [Map eventSourceInit]) {
- if (!?eventSourceInit) {
- return EventSource._create(url);
- }
- return EventSource._create(url, eventSourceInit);
+ return EventSource._create_1(url, eventSourceInit);
}
- static EventSource _create(String url, [Map eventSourceInit]) native "EventSource_constructor_Callback";
+
+ @DocsEditable
+ static EventSource _create_1(url, eventSourceInit) native "EventSource__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -10980,6 +11297,7 @@
class FieldSetElement extends _Element_Merged {
FieldSetElement.internal() : super.internal();
+ @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
@DocsEditable
factory FieldSetElement() => document.$dom_createElement("fieldset");
@@ -11245,7 +11563,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(File element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(File element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(File element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<File> where(bool f(File element)) =>
IterableMixinWorkaround.where(this, f);
@@ -11259,13 +11581,13 @@
bool get isEmpty => this.length == 0;
- List<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<File> takeWhile(bool test(File value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<File> skipWhile(bool test(File value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -11310,8 +11632,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<File> get reversed =>
- new ReversedListView<File>(this, 0, null);
+ List<File> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(File a, File b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -11433,9 +11756,14 @@
@DocsEditable
static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
+ @DomName('FileReader.FileReader')
@DocsEditable
- factory FileReader() => FileReader._create();
- static FileReader _create() native "FileReader_constructor_Callback";
+ factory FileReader() {
+ return FileReader._create_1();
+ }
+
+ @DocsEditable
+ static FileReader _create_1() native "FileReader__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -11568,9 +11896,14 @@
class FileReaderSync extends NativeFieldWrapperClass1 {
FileReaderSync.internal();
+ @DomName('FileReaderSync.FileReaderSync')
@DocsEditable
- factory FileReaderSync() => FileReaderSync._create();
- static FileReaderSync _create() native "FileReaderSync_constructor_Callback";
+ factory FileReaderSync() {
+ return FileReaderSync._create_1();
+ }
+
+ @DocsEditable
+ static FileReaderSync _create_1() native "FileReaderSync__create_1constructorCallback";
@DomName('FileReaderSync.readAsArrayBuffer')
@DocsEditable
@@ -11848,12 +12181,18 @@
class Float32Array extends ArrayBufferView implements List<num> {
Float32Array.internal() : super.internal();
+ @DomName('Float32Array.Float32Array')
+ @DocsEditable
factory Float32Array(int length) =>
_TypedArrayFactoryProvider.createFloat32Array(length);
+ @DomName('Float32Array.fromList')
+ @DocsEditable
factory Float32Array.fromList(List<num> list) =>
_TypedArrayFactoryProvider.createFloat32Array_fromList(list);
+ @DomName('Float32Array.fromBuffer')
+ @DocsEditable
factory Float32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createFloat32Array_fromBuffer(buffer, byteOffset, length);
@@ -11893,7 +12232,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(num element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(num element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<num> where(bool f(num element)) =>
IterableMixinWorkaround.where(this, f);
@@ -11907,13 +12250,13 @@
bool get isEmpty => this.length == 0;
- List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<num> takeWhile(bool test(num value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<num> skipWhile(bool test(num value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -11958,8 +12301,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<num> get reversed =>
- new ReversedListView<num>(this, 0, null);
+ List<num> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(num a, num b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -12072,12 +12416,18 @@
class Float64Array extends ArrayBufferView implements List<num> {
Float64Array.internal() : super.internal();
+ @DomName('Float64Array.Float64Array')
+ @DocsEditable
factory Float64Array(int length) =>
_TypedArrayFactoryProvider.createFloat64Array(length);
+ @DomName('Float64Array.fromList')
+ @DocsEditable
factory Float64Array.fromList(List<num> list) =>
_TypedArrayFactoryProvider.createFloat64Array_fromList(list);
+ @DomName('Float64Array.fromBuffer')
+ @DocsEditable
factory Float64Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createFloat64Array_fromBuffer(buffer, byteOffset, length);
@@ -12117,7 +12467,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(num element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(num element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<num> where(bool f(num element)) =>
IterableMixinWorkaround.where(this, f);
@@ -12131,13 +12485,13 @@
bool get isEmpty => this.length == 0;
- List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<num> takeWhile(bool test(num value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<num> skipWhile(bool test(num value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -12182,8 +12536,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<num> get reversed =>
- new ReversedListView<num>(this, 0, null);
+ List<num> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(num a, num b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -12295,15 +12650,10 @@
@DomName('FormData')
class FormData extends NativeFieldWrapperClass1 {
FormData.internal();
+ factory FormData([FormElement form]) => _create(form);
@DocsEditable
- factory FormData([FormElement form]) {
- if (!?form) {
- return FormData._create();
- }
- return FormData._create(form);
- }
- static FormData _create([FormElement form]) native "DOMFormData_constructor_Callback";
+ static FormData _create(form) native "DOMFormData_constructorCallback";
@DomName('DOMFormData.append')
@DocsEditable
@@ -12322,6 +12672,7 @@
class FormElement extends _Element_Merged {
FormElement.internal() : super.internal();
+ @DomName('HTMLFormElement.HTMLFormElement')
@DocsEditable
factory FormElement() => document.$dom_createElement("form");
@@ -12505,6 +12856,7 @@
class HRElement extends _Element_Merged {
HRElement.internal() : super.internal();
+ @DomName('HTMLHRElement.HTMLHRElement')
@DocsEditable
factory HRElement() => document.$dom_createElement("hr");
@@ -12558,6 +12910,7 @@
class HeadElement extends _Element_Merged {
HeadElement.internal() : super.internal();
+ @DomName('HTMLHeadElement.HTMLHeadElement')
@DocsEditable
factory HeadElement() => document.$dom_createElement("head");
@@ -12574,21 +12927,27 @@
class HeadingElement extends _Element_Merged {
HeadingElement.internal() : super.internal();
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h1() => document.$dom_createElement("h1");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h2() => document.$dom_createElement("h2");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h3() => document.$dom_createElement("h3");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h4() => document.$dom_createElement("h4");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h5() => document.$dom_createElement("h5");
+ @DomName('HTMLHeadingElement.HTMLHeadingElement')
@DocsEditable
factory HeadingElement.h6() => document.$dom_createElement("h6");
@@ -12693,7 +13052,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -12707,13 +13070,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -12758,8 +13121,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -12897,7 +13261,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -12911,13 +13279,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -12962,8 +13330,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -13200,6 +13569,7 @@
class HtmlElement extends _Element_Merged {
HtmlElement.internal() : super.internal();
+ @DomName('HTMLHtmlElement.HTMLHtmlElement')
@DocsEditable
factory HtmlElement() => document.$dom_createElement("html");
@@ -13270,25 +13640,39 @@
*/
@DomName('XMLHttpRequest')
class HttpRequest extends EventTarget {
- /**
- * Creates a URL get request for the specified `url`.
- *
- * After completing the request, the object will call the user-provided
- * [onComplete] callback.
- */
- factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
- _HttpRequestUtils.get(url, onComplete, false);
- // 80 char issue for comments in lists: dartbug.com/7588.
/**
- * Creates a URL GET request for the specified `url` with
- * credentials such a cookie (already) set in the header or
- * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
+ * Creates a URL get request for the specified [url].
*
- * After completing the request, the object will call the user-provided
- * [onComplete] callback.
+ * The server response must be a `text/` mime type for this request to
+ * succeed.
*
- * A few other details to keep in mind when using credentials:
+ * This is similar to [request] but specialized for HTTP GET requests which
+ * return text content.
+ *
+ * See also:
+ *
+ * * [request]
+ */
+ static Future<String> getString(String url,
+ {bool withCredentials, void onProgress(ProgressEvent e)}) {
+ return request(url, withCredentials: withCredentials,
+ onProgress: onProgress).then((xhr) => xhr.responseText);
+ }
+
+ /**
+ * Creates a URL request for the specified [url].
+ *
+ * By default this will do an HTTP GET request, this can be overridden with
+ * [method].
+ *
+ * The Future is completed when the response is available.
+ *
+ * The [withCredentials] parameter specified that credentials such as a cookie
+ * (already) set in the header or
+ * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+ * should be specified for the request. Details to keep in mind when using
+ * credentials:
*
* * Using credentials is only useful for cross-origin requests.
* * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
@@ -13297,12 +13681,60 @@
*
* See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
*/
- factory HttpRequest.getWithCredentials(String url,
- onComplete(HttpRequest request)) =>
- _HttpRequestUtils.get(url, onComplete, true);
+ static Future<HttpRequest> request(String url,
+ {String method, bool withCredentials, String responseType, sendData,
+ void onProgress(ProgressEvent e)}) {
+ var completer = new Completer<HttpRequest>();
+
+ var xhr = new HttpRequest();
+ if (method == null) {
+ method = 'GET';
+ }
+ xhr.open(method, url, true);
+
+ if (withCredentials != null) {
+ xhr.withCredentials = withCredentials;
+ }
+
+ if (responseType != null) {
+ xhr.responseType = responseType;
+ }
+
+ if (onProgress != null) {
+ xhr.onProgress.listen(onProgress);
+ }
+
+ xhr.onLoad.listen((e) {
+ if (xhr.status >= 200 && xhr.status < 300 ||
+ xhr.status == 304 ) {
+ completer.complete(xhr);
+ } else {
+ completer.completeError(e);
+ }
+ });
+
+ xhr.onError.listen((e) {
+ completer.completeError(e);
+ });
+
+ if (sendData != null) {
+ xhr.send(sendData);
+ } else {
+ xhr.send();
+ }
+
+ return completer.future;
+ }
HttpRequest.internal() : super.internal();
+ /**
+ * Stop the current request.
+ *
+ * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+ * `LOADING`. If this method is not in the process of being sent, the method
+ * has no effect.
+ */
@DomName('XMLHttpRequest.abort')
@DocsEditable
static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
@@ -13331,9 +13763,28 @@
@DocsEditable
static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');
+ /**
+ * General constructor for any type of request (GET, POST, etc).
+ *
+ * This call is used in conjunction with [open]:
+ *
+ * var request = new HttpRequest();
+ * request.open('GET', 'http://dartlang.org')
+ * request.on.load.add((event) => print('Request complete'));
+ *
+ * is the (more verbose) equivalent of
+ *
+ * var request = new HttpRequest.get('http://dartlang.org',
+ * (event) => print('Request complete'));
+ */
+ @DomName('XMLHttpRequest.XMLHttpRequest')
@DocsEditable
- factory HttpRequest() => HttpRequest._create();
- static HttpRequest _create() native "XMLHttpRequest_constructor_Callback";
+ factory HttpRequest() {
+ return HttpRequest._create_1();
+ }
+
+ @DocsEditable
+ static HttpRequest _create_1() native "XMLHttpRequest__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -13351,50 +13802,150 @@
static const int UNSENT = 0;
+ /**
+ * Indicator of the current state of the request:
+ *
+ * <table>
+ * <tr>
+ * <td>Value</td>
+ * <td>State</td>
+ * <td>Meaning</td>
+ * </tr>
+ * <tr>
+ * <td>0</td>
+ * <td>unsent</td>
+ * <td><code>open()</code> has not yet been called</td>
+ * </tr>
+ * <tr>
+ * <td>1</td>
+ * <td>opened</td>
+ * <td><code>send()</code> has not yet been called</td>
+ * </tr>
+ * <tr>
+ * <td>2</td>
+ * <td>headers received</td>
+ * <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
+ * </tr>
+ * <tr>
+ * <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
+ * </tr>
+ * <tr>
+ * <td>4</td> <td>done</td> <td>request is complete</td>
+ * </tr>
+ * </table>
+ */
@DomName('XMLHttpRequest.readyState')
@DocsEditable
int get readyState native "XMLHttpRequest_readyState_Getter";
+ /**
+ * The data received as a reponse from the request.
+ *
+ * The data could be in the
+ * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+ * [String]). `null` indicates request failure.
+ */
@DomName('XMLHttpRequest.response')
@DocsEditable
Object get response native "XMLHttpRequest_response_Getter";
+ /**
+ * The response in string form or `null on failure.
+ */
@DomName('XMLHttpRequest.responseText')
@DocsEditable
String get responseText native "XMLHttpRequest_responseText_Getter";
+ /**
+ * [String] telling the server the desired response format.
+ *
+ * Default is `String`.
+ * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+ * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+ * `responseType` is set while performing a synchronous request.
+ *
+ * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+ */
@DomName('XMLHttpRequest.responseType')
@DocsEditable
String get responseType native "XMLHttpRequest_responseType_Getter";
+ /**
+ * [String] telling the server the desired response format.
+ *
+ * Default is `String`.
+ * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+ * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+ * `responseType` is set while performing a synchronous request.
+ *
+ * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+ */
@DomName('XMLHttpRequest.responseType')
@DocsEditable
void set responseType(String value) native "XMLHttpRequest_responseType_Setter";
+ /**
+ * The request response, or null on failure.
+ *
+ * The response is processed as
+ * `text/xml` stream, unless responseType = 'document' and the request is
+ * synchronous.
+ */
@DomName('XMLHttpRequest.responseXML')
@DocsEditable
Document get responseXml native "XMLHttpRequest_responseXML_Getter";
+ /**
+ * The http result code from the request (200, 404, etc).
+ * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+ */
@DomName('XMLHttpRequest.status')
@DocsEditable
int get status native "XMLHttpRequest_status_Getter";
+ /**
+ * The request response string (such as \"200 OK\").
+ * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+ */
@DomName('XMLHttpRequest.statusText')
@DocsEditable
String get statusText native "XMLHttpRequest_statusText_Getter";
+ /**
+ * [EventTarget] that can hold listeners to track the progress of the request.
+ * The events fired will be members of [HttpRequestUploadEvents].
+ */
@DomName('XMLHttpRequest.upload')
@DocsEditable
HttpRequestUpload get upload native "XMLHttpRequest_upload_Getter";
+ /**
+ * True if cross-site requests should use credentials such as cookies
+ * or authorization headers; false otherwise.
+ *
+ * This value is ignored for same-site requests.
+ */
@DomName('XMLHttpRequest.withCredentials')
@DocsEditable
bool get withCredentials native "XMLHttpRequest_withCredentials_Getter";
+ /**
+ * True if cross-site requests should use credentials such as cookies
+ * or authorization headers; false otherwise.
+ *
+ * This value is ignored for same-site requests.
+ */
@DomName('XMLHttpRequest.withCredentials')
@DocsEditable
void set withCredentials(bool value) native "XMLHttpRequest_withCredentials_Setter";
+ /**
+ * Stop the current request.
+ *
+ * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+ * `LOADING`. If this method is not in the process of being sent, the method
+ * has no effect.
+ */
@DomName('XMLHttpRequest.abort')
@DocsEditable
void abort() native "XMLHttpRequest_abort_Callback";
@@ -13407,18 +13958,51 @@
@DocsEditable
bool dispatchEvent(Event evt) native "XMLHttpRequest_dispatchEvent_Callback";
+ /**
+ * Retrieve all the response headers from a request.
+ *
+ * `null` if no headers have been received. For multipart requests,
+ * `getAllResponseHeaders` will return the response headers for the current
+ * part of the request.
+ *
+ * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+ * for a list of common response headers.
+ */
@DomName('XMLHttpRequest.getAllResponseHeaders')
@DocsEditable
String getAllResponseHeaders() native "XMLHttpRequest_getAllResponseHeaders_Callback";
+ /**
+ * Return the response header named `header`, or `null` if not found.
+ *
+ * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+ * for a list of common response headers.
+ */
@DomName('XMLHttpRequest.getResponseHeader')
@DocsEditable
String getResponseHeader(String header) native "XMLHttpRequest_getResponseHeader_Callback";
+ /**
+ * Specify the desired `url`, and `method` to use in making the request.
+ *
+ * By default the request is done asyncronously, with no user or password
+ * authentication information. If `async` is false, the request will be send
+ * synchronously.
+ *
+ * Calling `open` again on a currently active request is equivalent to
+ * calling `abort`.
+ */
@DomName('XMLHttpRequest.open')
@DocsEditable
void open(String method, String url, [bool async, String user, String password]) native "XMLHttpRequest_open_Callback";
+ /**
+ * Specify a particular MIME type (such as `text/xml`) desired for the
+ * response.
+ *
+ * This value must be set before the request has been sent. See also the list
+ * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+ */
@DomName('XMLHttpRequest.overrideMimeType')
@DocsEditable
void overrideMimeType(String override) native "XMLHttpRequest_overrideMimeType_Callback";
@@ -13427,6 +14011,13 @@
@DocsEditable
void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "XMLHttpRequest_removeEventListener_Callback";
+ /**
+ * Send the request with any given `data`.
+ *
+ * See also:
+ * [send() docs](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send())
+ * from MDN.
+ */
@DomName('XMLHttpRequest.send')
@DocsEditable
void send([data]) native "XMLHttpRequest_send_Callback";
@@ -13435,6 +14026,13 @@
@DocsEditable
void setRequestHeader(String header, String value) native "XMLHttpRequest_setRequestHeader_Callback";
+ /**
+ * Stop the current request.
+ *
+ * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+ * `LOADING`. If this method is not in the process of being sent, the method
+ * has no effect.
+ */
@DomName('XMLHttpRequest.abort')
@DocsEditable
Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
@@ -13668,6 +14266,7 @@
class IFrameElement extends _Element_Merged {
IFrameElement.internal() : super.internal();
+ @DomName('HTMLIFrameElement.HTMLIFrameElement')
@DocsEditable
factory IFrameElement() => document.$dom_createElement("iframe");
@@ -13767,6 +14366,7 @@
class ImageElement extends _Element_Merged {
ImageElement.internal() : super.internal();
+ @DomName('HTMLImageElement.HTMLImageElement')
@DocsEditable
factory ImageElement({String src, int width, int height}) {
var e = document.$dom_createElement("img");
@@ -14965,12 +15565,18 @@
class Int16Array extends ArrayBufferView implements List<int> {
Int16Array.internal() : super.internal();
+ @DomName('Int16Array.Int16Array')
+ @DocsEditable
factory Int16Array(int length) =>
_TypedArrayFactoryProvider.createInt16Array(length);
+ @DomName('Int16Array.fromList')
+ @DocsEditable
factory Int16Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createInt16Array_fromList(list);
+ @DomName('Int16Array.fromBuffer')
+ @DocsEditable
factory Int16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createInt16Array_fromBuffer(buffer, byteOffset, length);
@@ -15010,7 +15616,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -15024,13 +15634,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -15075,8 +15685,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -15189,12 +15800,18 @@
class Int32Array extends ArrayBufferView implements List<int> {
Int32Array.internal() : super.internal();
+ @DomName('Int32Array.Int32Array')
+ @DocsEditable
factory Int32Array(int length) =>
_TypedArrayFactoryProvider.createInt32Array(length);
+ @DomName('Int32Array.fromList')
+ @DocsEditable
factory Int32Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createInt32Array_fromList(list);
+ @DomName('Int32Array.fromBuffer')
+ @DocsEditable
factory Int32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createInt32Array_fromBuffer(buffer, byteOffset, length);
@@ -15234,7 +15851,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -15248,13 +15869,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -15299,8 +15920,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -15413,12 +16035,18 @@
class Int8Array extends ArrayBufferView implements List<int> {
Int8Array.internal() : super.internal();
+ @DomName('Int8Array.Int8Array')
+ @DocsEditable
factory Int8Array(int length) =>
_TypedArrayFactoryProvider.createInt8Array(length);
+ @DomName('Int8Array.fromList')
+ @DocsEditable
factory Int8Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createInt8Array_fromList(list);
+ @DomName('Int8Array.fromBuffer')
+ @DocsEditable
factory Int8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createInt8Array_fromBuffer(buffer, byteOffset, length);
@@ -15458,7 +16086,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -15472,13 +16104,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -15523,8 +16155,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -15769,6 +16402,7 @@
class KeygenElement extends _Element_Merged {
KeygenElement.internal() : super.internal();
+ @DomName('HTMLKeygenElement.HTMLKeygenElement')
@DocsEditable
factory KeygenElement() => document.$dom_createElement("keygen");
@@ -15860,6 +16494,7 @@
class LIElement extends _Element_Merged {
LIElement.internal() : super.internal();
+ @DomName('HTMLLIElement.HTMLLIElement')
@DocsEditable
factory LIElement() => document.$dom_createElement("li");
@@ -15892,6 +16527,7 @@
class LabelElement extends _Element_Merged {
LabelElement.internal() : super.internal();
+ @DomName('HTMLLabelElement.HTMLLabelElement')
@DocsEditable
factory LabelElement() => document.$dom_createElement("label");
@@ -15924,6 +16560,7 @@
class LegendElement extends _Element_Merged {
LegendElement.internal() : super.internal();
+ @DomName('HTMLLegendElement.HTMLLegendElement')
@DocsEditable
factory LegendElement() => document.$dom_createElement("legend");
@@ -15944,6 +16581,7 @@
class LinkElement extends _Element_Merged {
LinkElement.internal() : super.internal();
+ @DomName('HTMLLinkElement.HTMLLinkElement')
@DocsEditable
factory LinkElement() => document.$dom_createElement("link");
@@ -16138,6 +16776,7 @@
class MapElement extends _Element_Merged {
MapElement.internal() : super.internal();
+ @DomName('HTMLMapElement.HTMLMapElement')
@DocsEditable
factory MapElement() => document.$dom_createElement("map");
@@ -16166,9 +16805,14 @@
class MediaController extends EventTarget {
MediaController.internal() : super.internal();
+ @DomName('MediaController.MediaController')
@DocsEditable
- factory MediaController() => MediaController._create();
- static MediaController _create() native "MediaController_constructor_Callback";
+ factory MediaController() {
+ return MediaController._create_1();
+ }
+
+ @DocsEditable
+ static MediaController _create_1() native "MediaController__create_1constructorCallback";
@DomName('MediaController.buffered')
@DocsEditable
@@ -17034,9 +17678,14 @@
class MediaSource extends EventTarget {
MediaSource.internal() : super.internal();
+ @DomName('MediaSource.MediaSource')
@DocsEditable
- factory MediaSource() => MediaSource._create();
- static MediaSource _create() native "MediaSource_constructor_Callback";
+ factory MediaSource() {
+ return MediaSource._create_1();
+ }
+
+ @DocsEditable
+ static MediaSource _create_1() native "MediaSource__create_1constructorCallback";
@DomName('MediaSource.activeSourceBuffers')
@DocsEditable
@@ -17097,9 +17746,29 @@
@DocsEditable
static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
+ @DomName('MediaStream.MediaStream')
@DocsEditable
- factory MediaStream() => MediaStream._create();
- static MediaStream _create() native "MediaStream_constructor_Callback";
+ factory MediaStream([stream_OR_tracks]) {
+ if (!?stream_OR_tracks) {
+ return MediaStream._create_1();
+ }
+ if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
+ return MediaStream._create_2(stream_OR_tracks);
+ }
+ if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
+ return MediaStream._create_3(stream_OR_tracks);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+
+ @DocsEditable
+ static MediaStream _create_1() native "MediaStream__create_1constructorCallback";
+
+ @DocsEditable
+ static MediaStream _create_2(stream_OR_tracks) native "MediaStream__create_2constructorCallback";
+
+ @DocsEditable
+ static MediaStream _create_3(stream_OR_tracks) native "MediaStream__create_3constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -17231,12 +17900,6 @@
MediaStreamTrackEvents get on =>
new MediaStreamTrackEvents(this);
- static const int ENDED = 2;
-
- static const int LIVE = 0;
-
- static const int MUTED = 1;
-
@DomName('MediaStreamTrack.enabled')
@DocsEditable
bool get enabled native "MediaStreamTrack_enabled_Getter";
@@ -17259,7 +17922,7 @@
@DomName('MediaStreamTrack.readyState')
@DocsEditable
- int get readyState native "MediaStreamTrack_readyState_Getter";
+ String get readyState native "MediaStreamTrack_readyState_Getter";
@DomName('MediaStreamTrack.addEventListener')
@DocsEditable
@@ -17359,6 +18022,7 @@
class MenuElement extends _Element_Merged {
MenuElement.internal() : super.internal();
+ @DomName('HTMLMenuElement.HTMLMenuElement')
@DocsEditable
factory MenuElement() => document.$dom_createElement("menu");
@@ -17375,9 +18039,14 @@
class MessageChannel extends NativeFieldWrapperClass1 {
MessageChannel.internal();
+ @DomName('MessageChannel.MessageChannel')
@DocsEditable
- factory MessageChannel() => MessageChannel._create();
- static MessageChannel _create() native "MessageChannel_constructor_Callback";
+ factory MessageChannel() {
+ return MessageChannel._create_1();
+ }
+
+ @DocsEditable
+ static MessageChannel _create_1() native "MessageChannel__create_1constructorCallback";
@DomName('MessageChannel.port1')
@DocsEditable
@@ -17578,6 +18247,7 @@
class MeterElement extends _Element_Merged {
MeterElement.internal() : super.internal();
+ @DomName('HTMLMeterElement.HTMLMeterElement')
@DocsEditable
factory MeterElement() => document.$dom_createElement("meter");
@@ -17714,7 +18384,7 @@
@DomName('MouseEvent.dataTransfer')
@DocsEditable
- Clipboard get dataTransfer native "MouseEvent_dataTransfer_Getter";
+ DataTransfer get dataTransfer native "MouseEvent_dataTransfer_Getter";
@DomName('MouseEvent.fromElement')
@DocsEditable
@@ -17845,10 +18515,10 @@
@Experimental
class MutationObserver extends NativeFieldWrapperClass1 {
MutationObserver.internal();
+ factory MutationObserver(MutationCallback callback) => _create(callback);
@DocsEditable
- factory MutationObserver(MutationCallback callback) => MutationObserver._create(callback);
- static MutationObserver _create(MutationCallback callback) native "MutationObserver_constructor_Callback";
+ static MutationObserver _create(callback) native "MutationObserver_constructorCallback";
@DomName('MutationObserver.disconnect')
@DocsEditable
@@ -18025,7 +18695,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -18039,13 +18713,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -18090,8 +18764,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -18487,6 +19162,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Node element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Node element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -18506,7 +19185,7 @@
// From List<Node>:
- List<Node> take(int n) {
+ Iterable<Node> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -18514,7 +19193,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) {
+ Iterable<Node> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -18538,8 +19217,9 @@
return this[index];
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
// TODO(jacobr): this could be implemented for child node lists.
// The exception we throw here is misleading.
@@ -18871,7 +19551,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Node element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Node element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Node> where(bool f(Node element)) =>
IterableMixinWorkaround.where(this, f);
@@ -18885,13 +19569,13 @@
bool get isEmpty => this.length == 0;
- List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Node> takeWhile(bool test(Node value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Node> skipWhile(bool test(Node value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -18936,8 +19620,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Node a, Node b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -19076,14 +19761,14 @@
@DocsEditable
static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
+ @DomName('Notification.Notification')
@DocsEditable
factory Notification(String title, [Map options]) {
- if (!?options) {
- return Notification._create(title);
- }
- return Notification._create(title, options);
+ return Notification._create_1(title, options);
}
- static Notification _create(String title, [Map options]) native "Notification_constructor_Callback";
+
+ @DocsEditable
+ static Notification _create_1(title, options) native "Notification__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -19245,6 +19930,7 @@
class OListElement extends _Element_Merged {
OListElement.internal() : super.internal();
+ @DomName('HTMLOListElement.HTMLOListElement')
@DocsEditable
factory OListElement() => document.$dom_createElement("ol");
@@ -19288,6 +19974,7 @@
class ObjectElement extends _Element_Merged {
ObjectElement.internal() : super.internal();
+ @DomName('HTMLObjectElement.HTMLObjectElement')
@DocsEditable
factory ObjectElement() => document.$dom_createElement("object");
@@ -19459,6 +20146,7 @@
class OptGroupElement extends _Element_Merged {
OptGroupElement.internal() : super.internal();
+ @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
@DocsEditable
factory OptGroupElement() => document.$dom_createElement("optgroup");
@@ -19491,23 +20179,14 @@
class OptionElement extends _Element_Merged {
OptionElement.internal() : super.internal();
+ @DomName('HTMLOptionElement.HTMLOptionElement')
@DocsEditable
factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
- if (!?data) {
- return OptionElement._create();
- }
- if (!?value) {
- return OptionElement._create(data);
- }
- if (!?defaultSelected) {
- return OptionElement._create(data, value);
- }
- if (!?selected) {
- return OptionElement._create(data, value, defaultSelected);
- }
- return OptionElement._create(data, value, defaultSelected, selected);
+ return OptionElement._create_1(data, value, defaultSelected, selected);
}
- static OptionElement _create([String data, String value, bool defaultSelected, bool selected]) native "HTMLOptionElement_constructor_Callback";
+
+ @DocsEditable
+ static OptionElement _create_1(data, value, defaultSelected, selected) native "HTMLOptionElement__create_1constructorCallback";
@DomName('HTMLOptionElement.defaultSelected')
@DocsEditable
@@ -19573,6 +20252,7 @@
class OutputElement extends _Element_Merged {
OutputElement.internal() : super.internal();
+ @DomName('HTMLOutputElement.HTMLOutputElement')
@DocsEditable
factory OutputElement() => document.$dom_createElement("output");
@@ -19733,6 +20413,7 @@
class ParagraphElement extends _Element_Merged {
ParagraphElement.internal() : super.internal();
+ @DomName('HTMLParagraphElement.HTMLParagraphElement')
@DocsEditable
factory ParagraphElement() => document.$dom_createElement("p");
@@ -19749,6 +20430,7 @@
class ParamElement extends _Element_Merged {
ParamElement.internal() : super.internal();
+ @DomName('HTMLParamElement.HTMLParamElement')
@DocsEditable
factory ParamElement() => document.$dom_createElement("param");
@@ -19938,39 +20620,6 @@
@DocsEditable
-@DomName('WebKitPoint')
-class Point extends NativeFieldWrapperClass1 {
- Point.internal();
-
- @DocsEditable
- factory Point(num x, num y) => Point._create(x, y);
- static Point _create(num x, num y) native "WebKitPoint_constructor_Callback";
-
- @DomName('WebKitPoint.x')
- @DocsEditable
- num get x native "WebKitPoint_x_Getter";
-
- @DomName('WebKitPoint.x')
- @DocsEditable
- void set x(num value) native "WebKitPoint_x_Setter";
-
- @DomName('WebKitPoint.y')
- @DocsEditable
- num get y native "WebKitPoint_y_Getter";
-
- @DomName('WebKitPoint.y')
- @DocsEditable
- void set y(num value) native "WebKitPoint_y_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.
-
-
-@DocsEditable
@DomName('PopStateEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -20039,6 +20688,7 @@
class PreElement extends _Element_Merged {
PreElement.internal() : super.internal();
+ @DomName('HTMLPreElement.HTMLPreElement')
@DocsEditable
factory PreElement() => document.$dom_createElement("pre");
@@ -20096,6 +20746,7 @@
class ProgressElement extends _Element_Merged {
ProgressElement.internal() : super.internal();
+ @DomName('HTMLProgressElement.HTMLProgressElement')
@DocsEditable
factory ProgressElement() => document.$dom_createElement("progress");
@@ -20642,9 +21293,14 @@
class RtcIceCandidate extends NativeFieldWrapperClass1 {
RtcIceCandidate.internal();
+ @DomName('RTCIceCandidate.RTCIceCandidate')
@DocsEditable
- factory RtcIceCandidate(Map dictionary) => RtcIceCandidate._create(dictionary);
- static RtcIceCandidate _create(Map dictionary) native "RTCIceCandidate_constructor_Callback";
+ factory RtcIceCandidate(Map dictionary) {
+ return RtcIceCandidate._create_1(dictionary);
+ }
+
+ @DocsEditable
+ static RtcIceCandidate _create_1(dictionary) native "RTCIceCandidate__create_1constructorCallback";
@DomName('RTCIceCandidate.candidate')
@DocsEditable
@@ -20708,10 +21364,6 @@
@DocsEditable
static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');
- @DomName('RTCPeerConnection.open')
- @DocsEditable
- static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
-
@DomName('RTCPeerConnection.removestream')
@DocsEditable
static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');
@@ -20720,14 +21372,14 @@
@DocsEditable
static const EventStreamProvider<Event> stateChangeEvent = const EventStreamProvider<Event>('statechange');
+ @DomName('RTCPeerConnection.RTCPeerConnection')
@DocsEditable
factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
- if (!?mediaConstraints) {
- return RtcPeerConnection._create(rtcIceServers);
- }
- return RtcPeerConnection._create(rtcIceServers, mediaConstraints);
+ return RtcPeerConnection._create_1(rtcIceServers, mediaConstraints);
}
- static RtcPeerConnection _create(Map rtcIceServers, [Map mediaConstraints]) native "RTCPeerConnection_constructor_Callback";
+
+ @DocsEditable
+ static RtcPeerConnection _create_1(rtcIceServers, mediaConstraints) native "RTCPeerConnection__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -20735,14 +21387,14 @@
RtcPeerConnectionEvents get on =>
new RtcPeerConnectionEvents(this);
+ @DomName('RTCPeerConnection.iceConnectionState')
+ @DocsEditable
+ String get iceConnectionState native "RTCPeerConnection_iceConnectionState_Getter";
+
@DomName('RTCPeerConnection.iceGatheringState')
@DocsEditable
String get iceGatheringState native "RTCPeerConnection_iceGatheringState_Getter";
- @DomName('RTCPeerConnection.iceState')
- @DocsEditable
- String get iceState native "RTCPeerConnection_iceState_Getter";
-
@DomName('RTCPeerConnection.localDescription')
@DocsEditable
RtcSessionDescription get localDescription native "RTCPeerConnection_localDescription_Getter";
@@ -20763,6 +21415,10 @@
@DocsEditable
List<MediaStream> get remoteStreams native "RTCPeerConnection_remoteStreams_Getter";
+ @DomName('RTCPeerConnection.signalingState')
+ @DocsEditable
+ String get signalingState native "RTCPeerConnection_signalingState_Getter";
+
@DomName('RTCPeerConnection.addEventListener')
@DocsEditable
void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "RTCPeerConnection_addEventListener_Callback";
@@ -20839,10 +21495,6 @@
@DocsEditable
Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);
- @DomName('RTCPeerConnection.open')
- @DocsEditable
- Stream<Event> get onOpen => openEvent.forTarget(this);
-
@DomName('RTCPeerConnection.removestream')
@DocsEditable
Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);
@@ -20872,9 +21524,6 @@
EventListenerList get negotiationNeeded => this['negotiationneeded'];
@DocsEditable
- EventListenerList get open => this['open'];
-
- @DocsEditable
EventListenerList get removeStream => this['removestream'];
@DocsEditable
@@ -20892,9 +21541,14 @@
class RtcSessionDescription extends NativeFieldWrapperClass1 {
RtcSessionDescription.internal();
+ @DomName('RTCSessionDescription.RTCSessionDescription')
@DocsEditable
- factory RtcSessionDescription(Map dictionary) => RtcSessionDescription._create(dictionary);
- static RtcSessionDescription _create(Map dictionary) native "RTCSessionDescription_constructor_Callback";
+ factory RtcSessionDescription(Map dictionary) {
+ return RtcSessionDescription._create_1(dictionary);
+ }
+
+ @DocsEditable
+ static RtcSessionDescription _create_1(dictionary) native "RTCSessionDescription__create_1constructorCallback";
@DomName('RTCSessionDescription.sdp')
@DocsEditable
@@ -21073,6 +21727,7 @@
class ScriptElement extends _Element_Merged {
ScriptElement.internal() : super.internal();
+ @DomName('HTMLScriptElement.HTMLScriptElement')
@DocsEditable
factory ScriptElement() => document.$dom_createElement("script");
@@ -21228,6 +21883,7 @@
class SelectElement extends _Element_Merged {
SelectElement.internal() : super.internal();
+ @DomName('HTMLSelectElement.HTMLSelectElement')
@DocsEditable
factory SelectElement() => document.$dom_createElement("select");
@@ -21472,14 +22128,14 @@
class SharedWorker extends AbstractWorker {
SharedWorker.internal() : super.internal();
+ @DomName('SharedWorker.SharedWorker')
@DocsEditable
factory SharedWorker(String scriptURL, [String name]) {
- if (!?name) {
- return SharedWorker._create(scriptURL);
- }
- return SharedWorker._create(scriptURL, name);
+ return SharedWorker._create_1(scriptURL, name);
}
- static SharedWorker _create(String scriptURL, [String name]) native "SharedWorker_constructor_Callback";
+
+ @DocsEditable
+ static SharedWorker _create_1(scriptURL, name) native "SharedWorker__create_1constructorCallback";
@DomName('SharedWorker.port')
@DocsEditable
@@ -21604,7 +22260,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SourceBuffer element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SourceBuffer element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SourceBuffer element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SourceBuffer> where(bool f(SourceBuffer element)) =>
IterableMixinWorkaround.where(this, f);
@@ -21618,13 +22278,13 @@
bool get isEmpty => this.length == 0;
- List<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SourceBuffer> takeWhile(bool test(SourceBuffer value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SourceBuffer> skipWhile(bool test(SourceBuffer value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -21669,8 +22329,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SourceBuffer> get reversed =>
- new ReversedListView<SourceBuffer>(this, 0, null);
+ List<SourceBuffer> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SourceBuffer a, SourceBuffer b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -21780,6 +22441,7 @@
class SourceElement extends _Element_Merged {
SourceElement.internal() : super.internal();
+ @DomName('HTMLSourceElement.HTMLSourceElement')
@DocsEditable
factory SourceElement() => document.$dom_createElement("source");
@@ -21820,6 +22482,7 @@
class SpanElement extends _Element_Merged {
SpanElement.internal() : super.internal();
+ @DomName('HTMLSpanElement.HTMLSpanElement')
@DocsEditable
factory SpanElement() => document.$dom_createElement("span");
@@ -21836,9 +22499,14 @@
class SpeechGrammar extends NativeFieldWrapperClass1 {
SpeechGrammar.internal();
+ @DomName('SpeechGrammar.SpeechGrammar')
@DocsEditable
- factory SpeechGrammar() => SpeechGrammar._create();
- static SpeechGrammar _create() native "SpeechGrammar_constructor_Callback";
+ factory SpeechGrammar() {
+ return SpeechGrammar._create_1();
+ }
+
+ @DocsEditable
+ static SpeechGrammar _create_1() native "SpeechGrammar__create_1constructorCallback";
@DomName('SpeechGrammar.src')
@DocsEditable
@@ -21869,9 +22537,14 @@
class SpeechGrammarList extends NativeFieldWrapperClass1 implements List<SpeechGrammar> {
SpeechGrammarList.internal();
+ @DomName('SpeechGrammarList.SpeechGrammarList')
@DocsEditable
- factory SpeechGrammarList() => SpeechGrammarList._create();
- static SpeechGrammarList _create() native "SpeechGrammarList_constructor_Callback";
+ factory SpeechGrammarList() {
+ return SpeechGrammarList._create_1();
+ }
+
+ @DocsEditable
+ static SpeechGrammarList _create_1() native "SpeechGrammarList__create_1constructorCallback";
@DomName('SpeechGrammarList.length')
@DocsEditable
@@ -21905,7 +22578,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SpeechGrammar element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SpeechGrammar element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SpeechGrammar element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SpeechGrammar> where(bool f(SpeechGrammar element)) =>
IterableMixinWorkaround.where(this, f);
@@ -21919,13 +22596,13 @@
bool get isEmpty => this.length == 0;
- List<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SpeechGrammar> takeWhile(bool test(SpeechGrammar value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SpeechGrammar> skipWhile(bool test(SpeechGrammar value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -21970,8 +22647,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SpeechGrammar> get reversed =>
- new ReversedListView<SpeechGrammar>(this, 0, null);
+ List<SpeechGrammar> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SpeechGrammar a, SpeechGrammar b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -22187,9 +22865,14 @@
@DocsEditable
static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');
+ @DomName('SpeechRecognition.SpeechRecognition')
@DocsEditable
- factory SpeechRecognition() => SpeechRecognition._create();
- static SpeechRecognition _create() native "SpeechRecognition_constructor_Callback";
+ factory SpeechRecognition() {
+ return SpeechRecognition._create_1();
+ }
+
+ @DocsEditable
+ static SpeechRecognition _create_1() native "SpeechRecognition__create_1constructorCallback";
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -22596,7 +23279,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Map element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Map element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Map element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Map> where(bool f(Map element)) =>
IterableMixinWorkaround.where(this, f);
@@ -22610,13 +23297,13 @@
bool get isEmpty => this.length == 0;
- List<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Map> takeWhile(bool test(Map value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Map> skipWhile(bool test(Map value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -22661,8 +23348,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Map> get reversed =>
- new ReversedListView<Map>(this, 0, null);
+ List<Map> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Map a, Map b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -22757,6 +23445,9 @@
@DocsEditable
@DomName('SQLTransaction')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class SqlTransaction extends NativeFieldWrapperClass1 {
SqlTransaction.internal();
@@ -22774,6 +23465,9 @@
@DocsEditable
@DomName('SQLTransactionSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
class SqlTransactionSync extends NativeFieldWrapperClass1 {
SqlTransactionSync.internal();
@@ -22978,6 +23672,7 @@
class StyleElement extends _Element_Merged {
StyleElement.internal() : super.internal();
+ @DomName('HTMLStyleElement.HTMLStyleElement')
@DocsEditable
factory StyleElement() => document.$dom_createElement("style");
@@ -23096,6 +23791,7 @@
class TableCaptionElement extends _Element_Merged {
TableCaptionElement.internal() : super.internal();
+ @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
@DocsEditable
factory TableCaptionElement() => document.$dom_createElement("caption");
@@ -23112,6 +23808,7 @@
class TableCellElement extends _Element_Merged {
TableCellElement.internal() : super.internal();
+ @DomName('HTMLTableCellElement.HTMLTableCellElement')
@DocsEditable
factory TableCellElement() => document.$dom_createElement("td");
@@ -23156,6 +23853,7 @@
class TableColElement extends _Element_Merged {
TableColElement.internal() : super.internal();
+ @DomName('HTMLTableColElement.HTMLTableColElement')
@DocsEditable
factory TableColElement() => document.$dom_createElement("col");
@@ -23180,6 +23878,7 @@
class TableElement extends _Element_Merged {
TableElement.internal() : super.internal();
+ @DomName('HTMLTableElement.HTMLTableElement')
@DocsEditable
factory TableElement() => document.$dom_createElement("table");
@@ -23272,6 +23971,7 @@
class TableRowElement extends _Element_Merged {
TableRowElement.internal() : super.internal();
+ @DomName('HTMLTableRowElement.HTMLTableRowElement')
@DocsEditable
factory TableRowElement() => document.$dom_createElement("tr");
@@ -23358,6 +24058,7 @@
class TextAreaElement extends _Element_Merged {
TextAreaElement.internal() : super.internal();
+ @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
@DocsEditable
factory TextAreaElement() => document.$dom_createElement("textarea");
@@ -23718,9 +24419,14 @@
@DocsEditable
static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');
+ @DomName('TextTrackCue.TextTrackCue')
@DocsEditable
- factory TextTrackCue(num startTime, num endTime, String text) => TextTrackCue._create(startTime, endTime, text);
- static TextTrackCue _create(num startTime, num endTime, String text) native "TextTrackCue_constructor_Callback";
+ factory TextTrackCue(num startTime, num endTime, String text) {
+ return TextTrackCue._create_1(startTime, endTime, text);
+ }
+
+ @DocsEditable
+ static TextTrackCue _create_1(startTime, endTime, text) native "TextTrackCue__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -23902,7 +24608,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(TextTrackCue element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(TextTrackCue element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(TextTrackCue element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<TextTrackCue> where(bool f(TextTrackCue element)) =>
IterableMixinWorkaround.where(this, f);
@@ -23916,13 +24626,13 @@
bool get isEmpty => this.length == 0;
- List<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<TextTrackCue> takeWhile(bool test(TextTrackCue value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<TextTrackCue> skipWhile(bool test(TextTrackCue value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -23967,8 +24677,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<TextTrackCue> get reversed =>
- new ReversedListView<TextTrackCue>(this, 0, null);
+ List<TextTrackCue> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(TextTrackCue a, TextTrackCue b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -24112,7 +24823,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(TextTrack element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(TextTrack element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(TextTrack element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<TextTrack> where(bool f(TextTrack element)) =>
IterableMixinWorkaround.where(this, f);
@@ -24126,13 +24841,13 @@
bool get isEmpty => this.length == 0;
- List<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<TextTrack> takeWhile(bool test(TextTrack value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<TextTrack> skipWhile(bool test(TextTrack value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -24177,8 +24892,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<TextTrack> get reversed =>
- new ReversedListView<TextTrack>(this, 0, null);
+ List<TextTrack> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(TextTrack a, TextTrack b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -24335,6 +25051,7 @@
class TitleElement extends _Element_Merged {
TitleElement.internal() : super.internal();
+ @DomName('HTMLTitleElement.HTMLTitleElement')
@DocsEditable
factory TitleElement() => document.$dom_createElement("title");
@@ -24456,6 +25173,19 @@
@DocsEditable
void $dom_initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native "TouchEvent_initTouchEvent_Callback";
+
+ /**
+ * Checks if touch events supported on the current platform.
+ *
+ * Note that touch events are only supported if the user is using a touch
+ * device.
+ */
+ static bool get supported {
+ // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
+ // Basically, this is a fairly common check and it'd be great if it did not
+ // throw exceptions.
+ return Event._isTypeSupported('TouchEvent');
+ }
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -24501,7 +25231,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Touch element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Touch element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Touch element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Touch> where(bool f(Touch element)) =>
IterableMixinWorkaround.where(this, f);
@@ -24515,13 +25249,13 @@
bool get isEmpty => this.length == 0;
- List<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Touch> takeWhile(bool test(Touch value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Touch> skipWhile(bool test(Touch value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -24566,8 +25300,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Touch> get reversed =>
- new ReversedListView<Touch>(this, 0, null);
+ List<Touch> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Touch a, Touch b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -24668,6 +25403,7 @@
class TrackElement extends _Element_Merged {
TrackElement.internal() : super.internal();
+ @DomName('HTMLTrackElement.HTMLTrackElement')
@DocsEditable
factory TrackElement() => document.$dom_createElement("track");
@@ -24914,6 +25650,7 @@
class UListElement extends _Element_Merged {
UListElement.internal() : super.internal();
+ @DomName('HTMLUListElement.HTMLUListElement')
@DocsEditable
factory UListElement() => document.$dom_createElement("ul");
@@ -24930,12 +25667,18 @@
class Uint16Array extends ArrayBufferView implements List<int> {
Uint16Array.internal() : super.internal();
+ @DomName('Uint16Array.Uint16Array')
+ @DocsEditable
factory Uint16Array(int length) =>
_TypedArrayFactoryProvider.createUint16Array(length);
+ @DomName('Uint16Array.fromList')
+ @DocsEditable
factory Uint16Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint16Array_fromList(list);
+ @DomName('Uint16Array.fromBuffer')
+ @DocsEditable
factory Uint16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint16Array_fromBuffer(buffer, byteOffset, length);
@@ -24975,7 +25718,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -24989,13 +25736,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -25040,8 +25787,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -25154,12 +25902,18 @@
class Uint32Array extends ArrayBufferView implements List<int> {
Uint32Array.internal() : super.internal();
+ @DomName('Uint32Array.Uint32Array')
+ @DocsEditable
factory Uint32Array(int length) =>
_TypedArrayFactoryProvider.createUint32Array(length);
+ @DomName('Uint32Array.fromList')
+ @DocsEditable
factory Uint32Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint32Array_fromList(list);
+ @DomName('Uint32Array.fromBuffer')
+ @DocsEditable
factory Uint32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint32Array_fromBuffer(buffer, byteOffset, length);
@@ -25199,7 +25953,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -25213,13 +25971,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -25264,8 +26022,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -25378,12 +26137,18 @@
class Uint8Array extends ArrayBufferView implements List<int> {
Uint8Array.internal() : super.internal();
+ @DomName('Uint8Array.Uint8Array')
+ @DocsEditable
factory Uint8Array(int length) =>
_TypedArrayFactoryProvider.createUint8Array(length);
+ @DomName('Uint8Array.fromList')
+ @DocsEditable
factory Uint8Array.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint8Array_fromList(list);
+ @DomName('Uint8Array.fromBuffer')
+ @DocsEditable
factory Uint8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint8Array_fromBuffer(buffer, byteOffset, length);
@@ -25423,7 +26188,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -25437,13 +26206,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -25488,8 +26257,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -25602,12 +26372,18 @@
class Uint8ClampedArray extends Uint8Array implements List<int> {
Uint8ClampedArray.internal() : super.internal();
+ @DomName('Uint8ClampedArray.Uint8ClampedArray')
+ @DocsEditable
factory Uint8ClampedArray(int length) =>
_TypedArrayFactoryProvider.createUint8ClampedArray(length);
+ @DomName('Uint8ClampedArray.fromList')
+ @DocsEditable
factory Uint8ClampedArray.fromList(List<int> list) =>
_TypedArrayFactoryProvider.createUint8ClampedArray_fromList(list);
+ @DomName('Uint8ClampedArray.fromBuffer')
+ @DocsEditable
factory Uint8ClampedArray.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) =>
_TypedArrayFactoryProvider.createUint8ClampedArray_fromBuffer(buffer, byteOffset, length);
@@ -25645,7 +26421,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(int element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(int element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<int> where(bool f(int element)) =>
IterableMixinWorkaround.where(this, f);
@@ -25659,13 +26439,13 @@
bool get isEmpty => this.length == 0;
- List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<int> takeWhile(bool test(int value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<int> skipWhile(bool test(int value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -25710,8 +26490,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<int> get reversed =>
- new ReversedListView<int>(this, 0, null);
+ List<int> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(int a, int b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -25932,6 +26713,7 @@
class VideoElement extends MediaElement {
VideoElement.internal() : super.internal();
+ @DomName('HTMLVideoElement.HTMLVideoElement')
@DocsEditable
factory VideoElement() => document.$dom_createElement("video");
@@ -26263,9 +27045,15 @@
@DocsEditable
@DomName('WebGLRenderingContext')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Experimental
class WebGLRenderingContext extends CanvasRenderingContext {
WebGLRenderingContext.internal() : super.internal();
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => true;
+
static const int ACTIVE_ATTRIBUTES = 0x8B89;
static const int ACTIVE_TEXTURE = 0x84E0;
@@ -27745,9 +28533,29 @@
@DocsEditable
static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
+ @DomName('WebSocket.WebSocket')
@DocsEditable
- factory WebSocket(String url) => WebSocket._create(url);
- static WebSocket _create(String url) native "WebSocket_constructor_Callback";
+ factory WebSocket(String url, [protocol_OR_protocols]) {
+ if ((url is String || url == null) && !?protocol_OR_protocols) {
+ return WebSocket._create_1(url);
+ }
+ if ((url is String || url == null) && (protocol_OR_protocols is List<String> || protocol_OR_protocols == null)) {
+ return WebSocket._create_2(url, protocol_OR_protocols);
+ }
+ if ((url is String || url == null) && (protocol_OR_protocols is String || protocol_OR_protocols == null)) {
+ return WebSocket._create_3(url, protocol_OR_protocols);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+
+ @DocsEditable
+ static WebSocket _create_1(url) native "WebSocket__create_1constructorCallback";
+
+ @DocsEditable
+ static WebSocket _create_2(url, protocol_OR_protocols) native "WebSocket__create_2constructorCallback";
+
+ @DocsEditable
+ static WebSocket _create_3(url, protocol_OR_protocols) native "WebSocket__create_3constructorCallback";
/// Checks if this type is supported on the current platform.
static bool get supported => true;
@@ -27946,12 +28754,13 @@
class Window extends EventTarget implements WindowBase {
/**
- * Executes a [callback] after the next batch of browser layout measurements
- * has completed or would have completed if any browser layout measurements
- * had been scheduled.
+ * Executes a [callback] after the immediate execution stack has completed.
+ *
+ * This will cause the callback to be executed after all processing has
+ * completed for the current event, but before any subsequent events.
*/
- void requestLayoutFrame(TimeoutHandler callback) {
- _addMeasurementFrameCallback(callback);
+ void setImmediate(TimeoutHandler callback) {
+ _addMicrotaskCallback(callback);
}
/**
@@ -27973,6 +28782,14 @@
document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
}
+ /// Checks if _setImmediate is supported.
+ static bool get _supportsSetImmediate => false;
+
+ /// Dartium stub for IE's setImmediate.
+ void _setImmediate(void callback()) {
+ throw new UnsupportedError('setImmediate is not supported');
+ }
+
Window.internal() : super.internal();
@DomName('DOMWindow.DOMContentLoaded')
@@ -28349,6 +29166,9 @@
@DomName('DOMWindow.openDatabase')
@DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "DOMWindow_openDatabase_Callback";
@DomName('DOMWindow.postMessage')
@@ -28413,11 +29233,11 @@
@DomName('DOMWindow.webkitConvertPointFromNodeToPage')
@DocsEditable
- Point webkitConvertPointFromNodeToPage(Node node, Point p) native "DOMWindow_webkitConvertPointFromNodeToPage_Callback";
+ DomPoint convertPointFromNodeToPage(Node node, DomPoint p) native "DOMWindow_webkitConvertPointFromNodeToPage_Callback";
@DomName('DOMWindow.webkitConvertPointFromPageToNode')
@DocsEditable
- Point webkitConvertPointFromPageToNode(Node node, Point p) native "DOMWindow_webkitConvertPointFromPageToNode_Callback";
+ DomPoint convertPointFromPageToNode(Node node, DomPoint p) native "DOMWindow_webkitConvertPointFromPageToNode_Callback";
@DomName('DOMWindow.webkitRequestAnimationFrame')
@DocsEditable
@@ -28897,9 +29717,14 @@
@DocsEditable
static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
+ @DomName('Worker.Worker')
@DocsEditable
- factory Worker(String scriptUrl) => Worker._create(scriptUrl);
- static Worker _create(String scriptUrl) native "Worker_constructor_Callback";
+ factory Worker(String scriptUrl) {
+ return Worker._create_1(scriptUrl);
+ }
+
+ @DocsEditable
+ static Worker _create_1(scriptUrl) native "Worker__create_1constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -29006,10 +29831,16 @@
@DomName('WorkerContext.openDatabase')
@DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "WorkerContext_openDatabase_Callback";
@DomName('WorkerContext.openDatabaseSync')
@DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "WorkerContext_openDatabaseSync_Callback";
@DomName('WorkerContext.removeEventListener')
@@ -29157,9 +29988,14 @@
class XPathEvaluator extends NativeFieldWrapperClass1 {
XPathEvaluator.internal();
+ @DomName('XPathEvaluator.XPathEvaluator')
@DocsEditable
- factory XPathEvaluator() => XPathEvaluator._create();
- static XPathEvaluator _create() native "XPathEvaluator_constructor_Callback";
+ factory XPathEvaluator() {
+ return XPathEvaluator._create_1();
+ }
+
+ @DocsEditable
+ static XPathEvaluator _create_1() native "XPathEvaluator__create_1constructorCallback";
@DomName('XPathEvaluator.createExpression')
@DocsEditable
@@ -29322,9 +30158,14 @@
class XmlSerializer extends NativeFieldWrapperClass1 {
XmlSerializer.internal();
+ @DomName('XMLSerializer.XMLSerializer')
@DocsEditable
- factory XmlSerializer() => XmlSerializer._create();
- static XmlSerializer _create() native "XMLSerializer_constructor_Callback";
+ factory XmlSerializer() {
+ return XmlSerializer._create_1();
+ }
+
+ @DocsEditable
+ static XmlSerializer _create_1() native "XMLSerializer__create_1constructorCallback";
@DomName('XMLSerializer.serializeToString')
@DocsEditable
@@ -29340,12 +30181,23 @@
@DocsEditable
@DomName('XSLTProcessor')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
class XsltProcessor extends NativeFieldWrapperClass1 {
XsltProcessor.internal();
+ @DomName('XSLTProcessor.XSLTProcessor')
@DocsEditable
- factory XsltProcessor() => XsltProcessor._create();
- static XsltProcessor _create() native "XSLTProcessor_constructor_Callback";
+ factory XsltProcessor() {
+ return XsltProcessor._create_1();
+ }
+
+ @DocsEditable
+ static XsltProcessor _create_1() native "XSLTProcessor__create_1constructorCallback";
+
+ /// Checks if this type is supported on the current platform.
+ static bool get supported => true;
@DomName('XSLTProcessor.clearParameters')
@DocsEditable
@@ -29450,7 +30302,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(ClientRect element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(ClientRect element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(ClientRect element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<ClientRect> where(bool f(ClientRect element)) =>
IterableMixinWorkaround.where(this, f);
@@ -29464,13 +30320,13 @@
bool get isEmpty => this.length == 0;
- List<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<ClientRect> takeWhile(bool test(ClientRect value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<ClientRect> skipWhile(bool test(ClientRect value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -29515,8 +30371,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<ClientRect> get reversed =>
- new ReversedListView<ClientRect>(this, 0, null);
+ List<ClientRect> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(ClientRect a, ClientRect b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -29646,7 +30503,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(CssRule element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(CssRule element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(CssRule element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<CssRule> where(bool f(CssRule element)) =>
IterableMixinWorkaround.where(this, f);
@@ -29660,13 +30521,13 @@
bool get isEmpty => this.length == 0;
- List<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<CssRule> takeWhile(bool test(CssRule value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<CssRule> skipWhile(bool test(CssRule value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -29711,8 +30572,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<CssRule> get reversed =>
- new ReversedListView<CssRule>(this, 0, null);
+ List<CssRule> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(CssRule a, CssRule b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -29842,7 +30704,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(CssValue element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(CssValue element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(CssValue element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<CssValue> where(bool f(CssValue element)) =>
IterableMixinWorkaround.where(this, f);
@@ -29856,13 +30722,13 @@
bool get isEmpty => this.length == 0;
- List<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<CssValue> takeWhile(bool test(CssValue value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<CssValue> skipWhile(bool test(CssValue value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -29907,8 +30773,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<CssValue> get reversed =>
- new ReversedListView<CssValue>(this, 0, null);
+ List<CssValue> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(CssValue a, CssValue b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -30188,7 +31055,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Entry element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Entry element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Entry element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Entry> where(bool f(Entry element)) =>
IterableMixinWorkaround.where(this, f);
@@ -30202,13 +31073,13 @@
bool get isEmpty => this.length == 0;
- List<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Entry> takeWhile(bool test(Entry value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Entry> skipWhile(bool test(Entry value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -30253,8 +31124,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Entry> get reversed =>
- new ReversedListView<Entry>(this, 0, null);
+ List<Entry> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Entry a, Entry b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -30384,7 +31256,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(EntrySync element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(EntrySync element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(EntrySync element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<EntrySync> where(bool f(EntrySync element)) =>
IterableMixinWorkaround.where(this, f);
@@ -30398,13 +31274,13 @@
bool get isEmpty => this.length == 0;
- List<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<EntrySync> takeWhile(bool test(EntrySync value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<EntrySync> skipWhile(bool test(EntrySync value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -30449,8 +31325,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<EntrySync> get reversed =>
- new ReversedListView<EntrySync>(this, 0, null);
+ List<EntrySync> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(EntrySync a, EntrySync b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -30671,7 +31548,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Gamepad element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Gamepad element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Gamepad element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Gamepad> where(bool f(Gamepad element)) =>
IterableMixinWorkaround.where(this, f);
@@ -30685,13 +31566,13 @@
bool get isEmpty => this.length == 0;
- List<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Gamepad> takeWhile(bool test(Gamepad value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Gamepad> skipWhile(bool test(Gamepad value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -30736,8 +31617,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<Gamepad> get reversed =>
- new ReversedListView<Gamepad>(this, 0, null);
+ List<Gamepad> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Gamepad a, Gamepad b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -30880,7 +31762,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(MediaStream element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(MediaStream element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(MediaStream element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<MediaStream> where(bool f(MediaStream element)) =>
IterableMixinWorkaround.where(this, f);
@@ -30894,13 +31780,13 @@
bool get isEmpty => this.length == 0;
- List<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<MediaStream> takeWhile(bool test(MediaStream value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<MediaStream> skipWhile(bool test(MediaStream value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -30945,8 +31831,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<MediaStream> get reversed =>
- new ReversedListView<MediaStream>(this, 0, null);
+ List<MediaStream> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(MediaStream a, MediaStream b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -31076,7 +31963,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SpeechInputResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SpeechInputResult element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SpeechInputResult element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SpeechInputResult> where(bool f(SpeechInputResult element)) =>
IterableMixinWorkaround.where(this, f);
@@ -31090,13 +31981,13 @@
bool get isEmpty => this.length == 0;
- List<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SpeechInputResult> takeWhile(bool test(SpeechInputResult value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SpeechInputResult> skipWhile(bool test(SpeechInputResult value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -31141,8 +32032,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SpeechInputResult> get reversed =>
- new ReversedListView<SpeechInputResult>(this, 0, null);
+ List<SpeechInputResult> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SpeechInputResult a, SpeechInputResult b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -31272,7 +32164,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(SpeechRecognitionResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(SpeechRecognitionResult element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(SpeechRecognitionResult element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<SpeechRecognitionResult> where(bool f(SpeechRecognitionResult element)) =>
IterableMixinWorkaround.where(this, f);
@@ -31286,13 +32182,13 @@
bool get isEmpty => this.length == 0;
- List<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<SpeechRecognitionResult> takeWhile(bool test(SpeechRecognitionResult value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<SpeechRecognitionResult> skipWhile(bool test(SpeechRecognitionResult value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -31337,8 +32233,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<SpeechRecognitionResult> get reversed =>
- new ReversedListView<SpeechRecognitionResult>(this, 0, null);
+ List<SpeechRecognitionResult> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(SpeechRecognitionResult a, SpeechRecognitionResult b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -31468,7 +32365,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(StyleSheet element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(StyleSheet element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(StyleSheet element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<StyleSheet> where(bool f(StyleSheet element)) =>
IterableMixinWorkaround.where(this, f);
@@ -31482,13 +32383,13 @@
bool get isEmpty => this.length == 0;
- List<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<StyleSheet> takeWhile(bool test(StyleSheet value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<StyleSheet> skipWhile(bool test(StyleSheet value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -31533,8 +32434,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<StyleSheet> get reversed =>
- new ReversedListView<StyleSheet>(this, 0, null);
+ List<StyleSheet> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(StyleSheet a, StyleSheet b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -32015,6 +32917,8 @@
String join([String separator]) => readClasses().join(separator);
+ Iterable map(f(String element)) => readClasses().map(f);
+
Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
Iterable<String> where(bool f(String element)) => readClasses().where(f);
@@ -32112,7 +33016,7 @@
* Helper method used to modify the set of css classes on this element.
*
* f - callback with:
- * s - a Set of all the css class name currently on this element.
+ * s - a Set of all the css class name currently on this element.
*
* After f returns, the modified set is written to the
* className property of this element.
@@ -32159,7 +33063,7 @@
_EventStream(this._target, this._eventType, this._useCapture);
// DOM events are inherently multi-subscribers.
- Stream<T> asMultiSubscriberStream() => this;
+ Stream<T> asBroadcastStream() => this;
StreamSubscription<T> listen(void onData(T event),
{ void onError(AsyncError error),
@@ -32332,9 +33236,8 @@
// The distance to shift from upper case alphabet Roman letters to lower case.
final 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;
+ StreamSubscription _keyUpSubscription, _keyDownSubscription,
+ _keyPressSubscription;
/**
* An enumeration of key identifiers currently part of the W3C draft for DOM3
@@ -32390,9 +33293,6 @@
_callbacks = [];
_type = type;
_target = target;
- _keyDown = processKeyDown;
- _keyUp = processKeyUp;
- _keyPress = processKeyPress;
}
/**
@@ -32401,9 +33301,14 @@
*/
void _initializeAllEventListeners() {
_keyDownList = [];
- _target.on.keyDown.add(_keyDown, true);
- _target.on.keyPress.add(_keyPress, true);
- _target.on.keyUp.add(_keyUp, true);
+ if (_keyDownSubscription == null) {
+ _keyDownSubscription = Element.keyDownEvent.forTarget(
+ _target, useCapture: true).listen(processKeyDown);
+ _keyPressSubscription = Element.keyPressEvent.forTarget(
+ _target, useCapture: true).listen(processKeyUp);
+ _keyUpSubscription = Element.keyUpEvent.forTarget(
+ _target, useCapture: true).listen(processKeyPress);
+ }
}
/** Add a callback that wishes to be notified when a KeyEvent occurs. */
@@ -32437,9 +33342,12 @@
}
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);
+ _keyDownSubscription.cancel();
+ _keyDownSubscription = null;
+ _keyPressSubscription.cancel();
+ _keyPressSubscription = null;
+ _keyUpSubscription.cancel();
+ _keyUpSubscription = null;
}
}
@@ -33536,7 +34444,7 @@
request.withCredentials = withCredentials;
- request.on.readyStateChange.add((e) {
+ request.onReadyStateChange.listen((e) {
if (request.readyState == HttpRequest.DONE) {
onComplete(request);
}
@@ -33659,7 +34567,7 @@
_parent.cancelBubble = cancel;
}
/** Accessor to the clipboardData available for this event. */
- Clipboard get clipboardData => _parent.clipboardData;
+ DataTransfer 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. */
@@ -34060,46 +34968,38 @@
// BSD-style license that can be found in the LICENSE file.
-typedef Object ComputeValue();
-
-class _MeasurementRequest<T> {
- final ComputeValue computeValue;
- final Completer<T> completer;
- Object value;
- bool exception = false;
- _MeasurementRequest(this.computeValue, this.completer);
-}
-
-typedef void _MeasurementCallback();
+typedef void _MicrotaskCallback();
/**
* This class attempts to invoke a callback as soon as the current event stack
* unwinds, but before the browser repaints.
*/
-abstract class _MeasurementScheduler {
- bool _nextMeasurementFrameScheduled = false;
- _MeasurementCallback _callback;
+abstract class _MicrotaskScheduler {
+ bool _nextMicrotaskFrameScheduled = false;
+ _MicrotaskCallback _callback;
- _MeasurementScheduler(this._callback);
+ _MicrotaskScheduler(this._callback);
/**
- * Creates the best possible measurement scheduler for the current platform.
+ * Creates the best possible microtask scheduler for the current platform.
*/
- factory _MeasurementScheduler.best(_MeasurementCallback callback) {
- if (MutationObserver.supported) {
+ factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+ if (Window._supportsSetImmediate) {
+ return new _SetImmediateScheduler(callback);
+ } else if (MutationObserver.supported) {
return new _MutationObserverScheduler(callback);
}
return new _PostMessageScheduler(callback);
}
/**
- * Schedules a measurement callback if one has not been scheduled already.
+ * Schedules a microtask callback if one has not been scheduled already.
*/
void maybeSchedule() {
- if (this._nextMeasurementFrameScheduled) {
+ if (this._nextMicrotaskFrameScheduled) {
return;
}
- this._nextMeasurementFrameScheduled = true;
+ this._nextMicrotaskFrameScheduled = true;
this._schedule();
}
@@ -34109,14 +35009,14 @@
void _schedule();
/**
- * Handles the measurement callback and forwards it if necessary.
+ * Handles the microtask callback and forwards it if necessary.
*/
void _onCallback() {
// Ignore spurious messages.
- if (!_nextMeasurementFrameScheduled) {
+ if (!_nextMicrotaskFrameScheduled) {
return;
}
- _nextMeasurementFrameScheduled = false;
+ _nextMicrotaskFrameScheduled = false;
this._callback();
}
}
@@ -34124,22 +35024,22 @@
/**
* Scheduler which uses window.postMessage to schedule events.
*/
-class _PostMessageScheduler extends _MeasurementScheduler {
- const _MEASUREMENT_MESSAGE = "DART-MEASURE";
+class _PostMessageScheduler extends _MicrotaskScheduler {
+ const _MICROTASK_MESSAGE = "DART-MICROTASK";
- _PostMessageScheduler(_MeasurementCallback callback): super(callback) {
+ _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
// Messages from other windows do not cause a security risk as
// all we care about is that _handleMessage is called
// after the current event loop is unwound and calling the function is
// a noop when zero requests are pending.
- window.on.message.add(this._handleMessage);
+ window.onMessage.listen(this._handleMessage);
}
void _schedule() {
- window.postMessage(_MEASUREMENT_MESSAGE, "*");
+ window.postMessage(_MICROTASK_MESSAGE, "*");
}
- _handleMessage(e) {
+ void _handleMessage(e) {
this._onCallback();
}
}
@@ -34147,11 +35047,11 @@
/**
* Scheduler which uses a MutationObserver to schedule events.
*/
-class _MutationObserverScheduler extends _MeasurementScheduler {
+class _MutationObserverScheduler extends _MicrotaskScheduler {
MutationObserver _observer;
Element _dummy;
- _MutationObserverScheduler(_MeasurementCallback callback): super(callback) {
+ _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
// Mutation events get fired as soon as the current event stack is unwound
// so we just make a dummy event and listen for that.
_observer = new MutationObserver(this._handleMutation);
@@ -34169,89 +35069,53 @@
}
}
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+ _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
-List<_MeasurementRequest> _pendingRequests;
-List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
-_MeasurementScheduler _measurementScheduler = null;
-
-void _maybeScheduleMeasurementFrame() {
- if (_measurementScheduler == null) {
- _measurementScheduler =
- new _MeasurementScheduler.best(_completeMeasurementFutures);
+ void _schedule() {
+ window._setImmediate(_handleImmediate);
}
- _measurementScheduler.maybeSchedule();
+
+ void _handleImmediate() {
+ this._onCallback();
+ }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+ if (_microtaskScheduler == null) {
+ _microtaskScheduler =
+ new _MicrotaskScheduler.best(_completeMicrotasks);
+ }
+ _microtaskScheduler.maybeSchedule();
}
/**
- * Registers a [callback] which is called after the next batch of measurements
- * completes. Even if no measurements completed, the callback is triggered
- * when they would have completed to avoid confusing bugs if it happened that
- * no measurements were actually requested.
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
*/
-void _addMeasurementFrameCallback(TimeoutHandler callback) {
- if (_pendingMeasurementFrameCallbacks == null) {
- _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
- _maybeScheduleMeasurementFrame();
+void _addMicrotaskCallback(TimeoutHandler callback) {
+ if (_pendingMicrotasks == null) {
+ _pendingMicrotasks = <TimeoutHandler>[];
+ _maybeScheduleMicrotaskFrame();
}
- _pendingMeasurementFrameCallbacks.add(callback);
+ _pendingMicrotasks.add(callback);
}
-/**
- * Returns a [Future] whose value will be the result of evaluating
- * [computeValue] during the next safe measurement interval.
- * The next safe measurement interval is after the current event loop has
- * unwound but before the browser has rendered the page.
- * It is important that the [computeValue] function only queries the html
- * layout and html in any way.
- */
-Future _createMeasurementFuture(ComputeValue computeValue,
- Completer completer) {
- if (_pendingRequests == null) {
- _pendingRequests = <_MeasurementRequest>[];
- _maybeScheduleMeasurementFrame();
- }
- _pendingRequests.add(new _MeasurementRequest(computeValue, completer));
- return completer.future;
-}
/**
- * Complete all pending measurement futures evaluating them in a single batch
- * so that the the browser is guaranteed to avoid multiple layouts.
+ * Complete all pending microtasks.
*/
-void _completeMeasurementFutures() {
- // We must compute all new values before fulfilling the futures as
- // the onComplete callbacks for the futures could modify the DOM making
- // subsequent measurement calculations expensive to compute.
- if (_pendingRequests != null) {
- for (_MeasurementRequest request in _pendingRequests) {
- try {
- request.value = request.computeValue();
- } catch (e) {
- request.value = e;
- request.exception = true;
- }
- }
- }
-
- final completedRequests = _pendingRequests;
- final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
- _pendingRequests = null;
- _pendingMeasurementFrameCallbacks = null;
- if (completedRequests != null) {
- for (_MeasurementRequest request in completedRequests) {
- if (request.exception) {
- request.completer.completeError(request.value);
- } else {
- request.completer.complete(request.value);
- }
- }
- }
-
- if (readyMeasurementFrameCallbacks != null) {
- for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
- // TODO(jacobr): wrap each call to a handler in a try-catch block.
- handler();
- }
+void _completeMicrotasks() {
+ var callbacks = _pendingMicrotasks;
+ _pendingMicrotasks = null;
+ for (var callback in callbacks) {
+ callback();
}
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -34433,26 +35297,6 @@
}
}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-// TODO(rnystrom): add a way to supress public classes from DartDoc output.
-// TODO(jacobr): we can remove this class now that we are using the $dom_
-// convention for deprecated methods rather than truly private methods.
-/**
- * This class is intended for testing purposes only.
- */
-class Testing {
- static void addEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
- target.$dom_addEventListener(type, listener, useCapture);
- }
- static void removeEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
- target.$dom_removeEventListener(type, listener, useCapture);
- }
-
-}
// 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.
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index 2414539..a16d42c 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -69,8 +69,7 @@
return element is Element && _childNodes.contains(element);
}
- List<Element> get reversed =>
- new ReversedListView<Element>(_filtered, 0, null);
+ List<Element> get reversed => _filtered.reversed;
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -102,7 +101,8 @@
return result;
}
- Iterable mappedBy(f(Element element)) => _filtered.mappedBy(f);
+ Iterable map(f(Element element)) => _filtered.map(f);
+ List mappedBy(f(Element element)) => _filtered.mappedBy(f);
Iterable<Element> where(bool f(Element element)) => _filtered.where(f);
Element removeAt(int index) {
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index d4c2635..94ddf18 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -5,7 +5,6 @@
library html_common;
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'metadata.dart';
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index 3e2d10d..7392945 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -5,7 +5,6 @@
library html_common;
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:_js_helper' show Creates, Returns;
import 'dart:_foreign_helper' show JS;
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index e3f6e10..8a37de0 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1,4 +1,4 @@
-library indexed_db;
+library dart.dom.indexed_db;
import 'dart:async';
import 'dart:html';
@@ -161,23 +161,10 @@
@DocsEditable
void advance(int count) native;
- void continueFunction([/*IDBKey*/ key]) {
- if (?key) {
- var key_1 = _convertDartToNative_IDBKey(key);
- _continueFunction_1(key_1);
- return;
- }
- _continueFunction_2();
- return;
- }
@JSName('continue')
@DomName('IDBCursor.continue')
@DocsEditable
- void _continueFunction_1(key) native;
- @JSName('continue')
- @DomName('IDBCursor.continue')
- @DocsEditable
- void _continueFunction_2() native;
+ void continueFunction([Object key]) native;
@DomName('IDBCursor.delete')
@DocsEditable
@@ -357,15 +344,9 @@
}
- int cmp(/*IDBKey*/ first, /*IDBKey*/ second) {
- var first_1 = _convertDartToNative_IDBKey(first);
- var second_2 = _convertDartToNative_IDBKey(second);
- return _cmp_1(first_1, second_2);
- }
- @JSName('cmp')
@DomName('IDBFactory.cmp')
@DocsEditable
- int _cmp_1(first, second) native;
+ int cmp(Object first, Object second) native;
@DomName('IDBFactory.deleteDatabase')
@DocsEditable
@@ -412,204 +393,38 @@
@DocsEditable
final bool unique;
- Request count([key_OR_range]) {
- if (!?key_OR_range) {
- return _count_1();
- }
- if ((key_OR_range is KeyRange || key_OR_range == null)) {
- return _count_2(key_OR_range);
- }
- if (?key_OR_range) {
- var key_1 = _convertDartToNative_IDBKey(key_OR_range);
- return _count_3(key_1);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('count')
@DomName('IDBIndex.count')
@DocsEditable
- Request _count_1() native;
- @JSName('count')
- @DomName('IDBIndex.count')
- @DocsEditable
- Request _count_2(KeyRange range) native;
- @JSName('count')
- @DomName('IDBIndex.count')
- @DocsEditable
- Request _count_3(key) native;
+ Request count([key_OR_range]) native;
- Request get(key) {
- if ((key is KeyRange || key == null)) {
- return _get_1(key);
- }
- if (?key) {
- var key_1 = _convertDartToNative_IDBKey(key);
- return _get_2(key_1);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('get')
@DomName('IDBIndex.get')
@DocsEditable
@Returns('Request')
@Creates('Request')
@annotation_Creates_SerializedScriptValue
- Request _get_1(KeyRange key) native;
- @JSName('get')
- @DomName('IDBIndex.get')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @annotation_Creates_SerializedScriptValue
- Request _get_2(key) native;
+ Request get(key) native;
- Request getKey(key) {
- if ((key is KeyRange || key == null)) {
- return _getKey_1(key);
- }
- if (?key) {
- var key_1 = _convertDartToNative_IDBKey(key);
- return _getKey_2(key_1);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('getKey')
@DomName('IDBIndex.getKey')
@DocsEditable
@Returns('Request')
@Creates('Request')
@annotation_Creates_SerializedScriptValue
@Creates('ObjectStore')
- Request _getKey_1(KeyRange key) native;
- @JSName('getKey')
- @DomName('IDBIndex.getKey')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @annotation_Creates_SerializedScriptValue
- @Creates('ObjectStore')
- Request _getKey_2(key) native;
+ Request getKey(key) native;
- Request openCursor([key_OR_range, String direction]) {
- if (!?key_OR_range && !?direction) {
- return _openCursor_1();
- }
- if ((key_OR_range is KeyRange || key_OR_range == null) && !?direction) {
- return _openCursor_2(key_OR_range);
- }
- if ((key_OR_range is KeyRange || key_OR_range == null)) {
- return _openCursor_3(key_OR_range, direction);
- }
- if (?key_OR_range && !?direction) {
- var key_1 = _convertDartToNative_IDBKey(key_OR_range);
- return _openCursor_4(key_1);
- }
- if (?key_OR_range) {
- var key_2 = _convertDartToNative_IDBKey(key_OR_range);
- return _openCursor_5(key_2, direction);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('openCursor')
@DomName('IDBIndex.openCursor')
@DocsEditable
@Returns('Request')
@Creates('Request')
@Creates('Cursor')
- Request _openCursor_1() native;
- @JSName('openCursor')
- @DomName('IDBIndex.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_2(KeyRange range) native;
- @JSName('openCursor')
- @DomName('IDBIndex.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_3(KeyRange range, direction) native;
- @JSName('openCursor')
- @DomName('IDBIndex.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_4(key) native;
- @JSName('openCursor')
- @DomName('IDBIndex.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_5(key, direction) native;
+ Request openCursor([key_OR_range, String direction]) native;
- Request openKeyCursor([key_OR_range, String direction]) {
- if (!?key_OR_range && !?direction) {
- return _openKeyCursor_1();
- }
- if ((key_OR_range is KeyRange || key_OR_range == null) && !?direction) {
- return _openKeyCursor_2(key_OR_range);
- }
- if ((key_OR_range is KeyRange || key_OR_range == null)) {
- return _openKeyCursor_3(key_OR_range, direction);
- }
- if (?key_OR_range && !?direction) {
- var key_1 = _convertDartToNative_IDBKey(key_OR_range);
- return _openKeyCursor_4(key_1);
- }
- if (?key_OR_range) {
- var key_2 = _convertDartToNative_IDBKey(key_OR_range);
- return _openKeyCursor_5(key_2, direction);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('openKeyCursor')
@DomName('IDBIndex.openKeyCursor')
@DocsEditable
@Returns('Request')
@Creates('Request')
@Creates('Cursor')
- Request _openKeyCursor_1() native;
- @JSName('openKeyCursor')
- @DomName('IDBIndex.openKeyCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openKeyCursor_2(KeyRange range) native;
- @JSName('openKeyCursor')
- @DomName('IDBIndex.openKeyCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openKeyCursor_3(KeyRange range, direction) native;
- @JSName('openKeyCursor')
- @DomName('IDBIndex.openKeyCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openKeyCursor_4(key) native;
- @JSName('openKeyCursor')
- @DomName('IDBIndex.openKeyCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _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
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
-@DomName('IDBKey')
-class Key native "*IDBKey" {
+ Request openKeyCursor([key_OR_range, String 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
@@ -637,96 +452,41 @@
lower, upper, lowerOpen, upperOpen);
- dynamic get lower => _convertNativeToDart_IDBKey(this._lower);
- @JSName('lower')
@DomName('IDBKeyRange.lower')
@DocsEditable
- final dynamic _lower;
+ final Object lower;
@DomName('IDBKeyRange.lowerOpen')
@DocsEditable
final bool lowerOpen;
- dynamic get upper => _convertNativeToDart_IDBKey(this._upper);
- @JSName('upper')
@DomName('IDBKeyRange.upper')
@DocsEditable
- final dynamic _upper;
+ final Object upper;
@DomName('IDBKeyRange.upperOpen')
@DocsEditable
final bool upperOpen;
- static KeyRange bound_(/*IDBKey*/ lower, /*IDBKey*/ upper, [bool lowerOpen, bool upperOpen]) {
- if (?upperOpen) {
- var lower_1 = _convertDartToNative_IDBKey(lower);
- var upper_2 = _convertDartToNative_IDBKey(upper);
- return _bound__1(lower_1, upper_2, lowerOpen, upperOpen);
- }
- if (?lowerOpen) {
- var lower_3 = _convertDartToNative_IDBKey(lower);
- var upper_4 = _convertDartToNative_IDBKey(upper);
- return _bound__2(lower_3, upper_4, lowerOpen);
- }
- var lower_5 = _convertDartToNative_IDBKey(lower);
- var upper_6 = _convertDartToNative_IDBKey(upper);
- return _bound__3(lower_5, upper_6);
- }
@JSName('bound')
@DomName('IDBKeyRange.bound')
@DocsEditable
- static KeyRange _bound__1(lower, upper, lowerOpen, upperOpen) native;
- @JSName('bound')
- @DomName('IDBKeyRange.bound')
- @DocsEditable
- static KeyRange _bound__2(lower, upper, lowerOpen) native;
- @JSName('bound')
- @DomName('IDBKeyRange.bound')
- @DocsEditable
- static KeyRange _bound__3(lower, upper) native;
+ static KeyRange bound_(Object lower, Object upper, [bool lowerOpen, bool upperOpen]) native;
- static KeyRange lowerBound_(/*IDBKey*/ bound, [bool open]) {
- if (?open) {
- var bound_1 = _convertDartToNative_IDBKey(bound);
- return _lowerBound__1(bound_1, open);
- }
- var bound_2 = _convertDartToNative_IDBKey(bound);
- return _lowerBound__2(bound_2);
- }
@JSName('lowerBound')
@DomName('IDBKeyRange.lowerBound')
@DocsEditable
- static KeyRange _lowerBound__1(bound, open) native;
- @JSName('lowerBound')
- @DomName('IDBKeyRange.lowerBound')
- @DocsEditable
- static KeyRange _lowerBound__2(bound) native;
+ static KeyRange lowerBound_(Object bound, [bool open]) native;
- static KeyRange only_(/*IDBKey*/ value) {
- var value_1 = _convertDartToNative_IDBKey(value);
- return _only__1(value_1);
- }
@JSName('only')
@DomName('IDBKeyRange.only')
@DocsEditable
- static KeyRange _only__1(value) native;
+ static KeyRange only_(Object value) native;
- static KeyRange upperBound_(/*IDBKey*/ bound, [bool open]) {
- if (?open) {
- var bound_1 = _convertDartToNative_IDBKey(bound);
- return _upperBound__1(bound_1, open);
- }
- var bound_2 = _convertDartToNative_IDBKey(bound);
- return _upperBound__2(bound_2);
- }
@JSName('upperBound')
@DomName('IDBKeyRange.upperBound')
@DocsEditable
- static KeyRange _upperBound__1(bound, open) native;
- @JSName('upperBound')
- @DomName('IDBKeyRange.upperBound')
- @DocsEditable
- static KeyRange _upperBound__2(bound) native;
+ static KeyRange upperBound_(Object bound, [bool open]) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -760,10 +520,10 @@
@DocsEditable
final Transaction transaction;
- Request add(/*any*/ value, [/*IDBKey*/ key]) {
+ Request add(/*any*/ value, [/*any*/ key]) {
if (?key) {
var value_1 = convertDartToNative_SerializedScriptValue(value);
- var key_2 = _convertDartToNative_IDBKey(key);
+ var key_2 = convertDartToNative_SerializedScriptValue(key);
return _add_1(value_1, key_2);
}
var value_3 = convertDartToNative_SerializedScriptValue(value);
@@ -788,31 +548,9 @@
@DocsEditable
Request clear() native;
- Request count([key_OR_range]) {
- if (!?key_OR_range) {
- return _count_1();
- }
- if ((key_OR_range is KeyRange || key_OR_range == null)) {
- return _count_2(key_OR_range);
- }
- if (?key_OR_range) {
- var key_1 = _convertDartToNative_IDBKey(key_OR_range);
- return _count_3(key_1);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('count')
@DomName('IDBObjectStore.count')
@DocsEditable
- Request _count_1() native;
- @JSName('count')
- @DomName('IDBObjectStore.count')
- @DocsEditable
- Request _count_2(KeyRange range) native;
- @JSName('count')
- @DomName('IDBObjectStore.count')
- @DocsEditable
- Request _count_3(key) native;
+ Request count([key_OR_range]) native;
Index createIndex(String name, keyPath, [Map options]) {
if ((keyPath is List<String> || keyPath == null) && !?options) {
@@ -848,118 +586,37 @@
@DocsEditable
Index _createIndex_4(name, String keyPath, options) native;
- Request delete(key_OR_keyRange) {
- if ((key_OR_keyRange is KeyRange || key_OR_keyRange == null)) {
- return _delete_1(key_OR_keyRange);
- }
- if (?key_OR_keyRange) {
- var key_1 = _convertDartToNative_IDBKey(key_OR_keyRange);
- return _delete_2(key_1);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('delete')
@DomName('IDBObjectStore.delete')
@DocsEditable
- Request _delete_1(KeyRange keyRange) native;
- @JSName('delete')
- @DomName('IDBObjectStore.delete')
- @DocsEditable
- Request _delete_2(key) native;
+ Request delete(key_OR_keyRange) native;
@DomName('IDBObjectStore.deleteIndex')
@DocsEditable
void deleteIndex(String name) native;
- Request getObject(key) {
- if ((key is KeyRange || key == null)) {
- return _getObject_1(key);
- }
- if (?key) {
- var key_1 = _convertDartToNative_IDBKey(key);
- return _getObject_2(key_1);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
@JSName('get')
@DomName('IDBObjectStore.get')
@DocsEditable
@Returns('Request')
@Creates('Request')
@annotation_Creates_SerializedScriptValue
- Request _getObject_1(KeyRange key) native;
- @JSName('get')
- @DomName('IDBObjectStore.get')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @annotation_Creates_SerializedScriptValue
- Request _getObject_2(key) native;
+ Request getObject(key) native;
@DomName('IDBObjectStore.index')
@DocsEditable
Index index(String name) native;
- Request openCursor([key_OR_range, String direction]) {
- if (!?key_OR_range && !?direction) {
- return _openCursor_1();
- }
- if ((key_OR_range is KeyRange || key_OR_range == null) && !?direction) {
- return _openCursor_2(key_OR_range);
- }
- if ((key_OR_range is KeyRange || key_OR_range == null)) {
- return _openCursor_3(key_OR_range, direction);
- }
- if (?key_OR_range && !?direction) {
- var key_1 = _convertDartToNative_IDBKey(key_OR_range);
- return _openCursor_4(key_1);
- }
- if (?key_OR_range) {
- var key_2 = _convertDartToNative_IDBKey(key_OR_range);
- return _openCursor_5(key_2, direction);
- }
- throw new ArgumentError("Incorrect number or type of arguments");
- }
- @JSName('openCursor')
@DomName('IDBObjectStore.openCursor')
@DocsEditable
@Returns('Request')
@Creates('Request')
@Creates('Cursor')
- Request _openCursor_1() native;
- @JSName('openCursor')
- @DomName('IDBObjectStore.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_2(KeyRange range) native;
- @JSName('openCursor')
- @DomName('IDBObjectStore.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_3(KeyRange range, direction) native;
- @JSName('openCursor')
- @DomName('IDBObjectStore.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_4(key) native;
- @JSName('openCursor')
- @DomName('IDBObjectStore.openCursor')
- @DocsEditable
- @Returns('Request')
- @Creates('Request')
- @Creates('Cursor')
- Request _openCursor_5(key, direction) native;
+ Request openCursor([key_OR_range, String direction]) native;
- Request put(/*any*/ value, [/*IDBKey*/ key]) {
+ Request put(/*any*/ value, [/*any*/ key]) {
if (?key) {
var value_1 = convertDartToNative_SerializedScriptValue(value);
- var key_2 = _convertDartToNative_IDBKey(key);
+ var key_2 = convertDartToNative_SerializedScriptValue(key);
return _put_1(value_1, key_2);
}
var value_3 = convertDartToNative_SerializedScriptValue(value);
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index ea68244..184fb00 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -1,4 +1,4 @@
-library indexed_db;
+library dart.dom.indexed_db;
import 'dart:async';
import 'dart:html';
@@ -65,7 +65,7 @@
@DocsEditable
void advance(int count) native "IDBCursor_advance_Callback";
- void continueFunction([/*IDBKey*/ key]) {
+ void continueFunction([Object key]) {
if (?key) {
_continue_1(key);
return;
@@ -254,7 +254,7 @@
@DomName('IDBFactory.cmp')
@DocsEditable
- int cmp(/*IDBKey*/ first, /*IDBKey*/ second) native "IDBFactory_cmp_Callback";
+ int cmp(Object first, Object second) native "IDBFactory_cmp_Callback";
@DomName('IDBFactory.deleteDatabase')
@DocsEditable
@@ -456,19 +456,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.
-
-
-@DocsEditable
-@DomName('IDBKey')
-class Key extends NativeFieldWrapperClass1 {
- Key.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.
-
@DomName('IDBKeyRange')
class KeyRange extends NativeFieldWrapperClass1 {
@@ -494,7 +481,7 @@
@DomName('IDBKeyRange.lower')
@DocsEditable
- dynamic get lower native "IDBKeyRange_lower_Getter";
+ Object get lower native "IDBKeyRange_lower_Getter";
@DomName('IDBKeyRange.lowerOpen')
@DocsEditable
@@ -502,13 +489,13 @@
@DomName('IDBKeyRange.upper')
@DocsEditable
- dynamic get upper native "IDBKeyRange_upper_Getter";
+ Object get upper native "IDBKeyRange_upper_Getter";
@DomName('IDBKeyRange.upperOpen')
@DocsEditable
bool get upperOpen native "IDBKeyRange_upperOpen_Getter";
- static KeyRange bound_(/*IDBKey*/ lower, /*IDBKey*/ upper, [bool lowerOpen, bool upperOpen]) {
+ static KeyRange bound_(Object lower, Object upper, [bool lowerOpen, bool upperOpen]) {
if (?upperOpen) {
return _bound_1(lower, upper, lowerOpen, upperOpen);
}
@@ -530,7 +517,7 @@
@DocsEditable
static KeyRange _bound_3(lower, upper) native "IDBKeyRange__bound_3_Callback";
- static KeyRange lowerBound_(/*IDBKey*/ bound, [bool open]) {
+ static KeyRange lowerBound_(Object bound, [bool open]) {
if (?open) {
return _lowerBound_1(bound, open);
}
@@ -547,9 +534,9 @@
@DomName('IDBKeyRange.only_')
@DocsEditable
- static KeyRange only_(/*IDBKey*/ value) native "IDBKeyRange_only__Callback";
+ static KeyRange only_(Object value) native "IDBKeyRange_only__Callback";
- static KeyRange upperBound_(/*IDBKey*/ bound, [bool open]) {
+ static KeyRange upperBound_(Object bound, [bool open]) {
if (?open) {
return _upperBound_1(bound, open);
}
@@ -597,7 +584,7 @@
@DocsEditable
Transaction get transaction native "IDBObjectStore_transaction_Getter";
- Request add(Object value, [/*IDBKey*/ key]) {
+ Request add(Object value, [Object key]) {
if (?key) {
return _add_1(value, key);
}
@@ -742,7 +729,7 @@
@DocsEditable
Request _openCursor_5(key_OR_range, direction) native "IDBObjectStore__openCursor_5_Callback";
- Request put(Object value, [/*IDBKey*/ key]) {
+ Request put(Object value, [Object key]) {
if (?key) {
return _put_1(value, key);
}
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
index e85d93f..4348767 100644
--- a/sdk/lib/json/json.dart
+++ b/sdk/lib/json/json.dart
@@ -507,7 +507,7 @@
case BACKSLASH:
case QUOTE:
break;
- case CHAR_u: {
+ case CHAR_u:
int hexStart = position - 1;
int value = 0;
for (int i = 0; i < 4; i++) {
@@ -530,7 +530,6 @@
}
char = value;
break;
- }
default:
if (char < SPACE) fail(position, "Control character in string");
fail(position, "Unrecognized string escape");
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index cefba24..be4a8ff 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -8,7 +8,7 @@
* A random number generator. The default implementation supplies a stream of
* pseudo-random bits which is not suitable for cryptographic purposes.
*/
-class Random {
+abstract class Random {
/**
* Creates a random-number generator. The optional parameter [seed] is used
* to initialize the internal state of the generator. The implementation of
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index ca9734e..1f52ee3 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -1,8 +1,7 @@
-library svg;
+library dart.dom.svg;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, Returns, JavaScriptIndexingBehavior, JSName;
@@ -62,8 +61,9 @@
@DocsEditable
@DomName('SVGAElement')
-class AElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGAElement" {
+class AElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGAElement" {
+ @DomName('SVGAElement.SVGAElement')
@DocsEditable
factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
@@ -115,18 +115,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGAElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGAElement.requiredExtensions')
@@ -250,6 +238,7 @@
@DomName('SVGAnimateColorElement')
class AnimateColorElement extends AnimationElement native "*SVGAnimateColorElement" {
+ @DomName('SVGAnimateColorElement.SVGAnimateColorElement')
@DocsEditable
factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
}
@@ -262,6 +251,7 @@
@DomName('SVGAnimateElement')
class AnimateElement extends AnimationElement native "*SVGAnimateElement" {
+ @DomName('SVGAnimateElement.SVGAnimateElement')
@DocsEditable
factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
}
@@ -274,6 +264,7 @@
@DomName('SVGAnimateMotionElement')
class AnimateMotionElement extends AnimationElement native "*SVGAnimateMotionElement" {
+ @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
@DocsEditable
factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
}
@@ -286,6 +277,7 @@
@DomName('SVGAnimateTransformElement')
class AnimateTransformElement extends AnimationElement native "*SVGAnimateTransformElement" {
+ @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
@DocsEditable
factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
}
@@ -502,6 +494,7 @@
@DomName('SVGAnimationElement')
class AnimationElement extends SvgElement implements Tests, ElementTimeControl, ExternalResourcesRequired native "*SVGAnimationElement" {
+ @DomName('SVGAnimationElement.SVGAnimationElement')
@DocsEditable
factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
@@ -570,8 +563,9 @@
@DocsEditable
@DomName('SVGCircleElement')
-class CircleElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGCircleElement" {
+class CircleElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGCircleElement" {
+ @DomName('SVGCircleElement.SVGCircleElement')
@DocsEditable
factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
@@ -631,18 +625,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGCircleElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGCircleElement.requiredExtensions')
@@ -674,8 +656,9 @@
@DocsEditable
@DomName('SVGClipPathElement')
-class ClipPathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGClipPathElement" {
+class ClipPathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGClipPathElement" {
+ @DomName('SVGClipPathElement.SVGClipPathElement')
@DocsEditable
factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
@@ -727,18 +710,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGClipPathElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGClipPathElement.requiredExtensions')
@@ -860,6 +831,7 @@
@DomName('SVGCursorElement')
class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired native "*SVGCursorElement" {
+ @DomName('SVGCursorElement.SVGCursorElement')
@DocsEditable
factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
@@ -908,8 +880,9 @@
@DocsEditable
@DomName('SVGDefsElement')
-class DefsElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGDefsElement" {
+class DefsElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGDefsElement" {
+ @DomName('SVGDefsElement.SVGDefsElement')
@DocsEditable
factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
@@ -957,18 +930,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGDefsElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGDefsElement.requiredExtensions')
@@ -1000,8 +961,9 @@
@DocsEditable
@DomName('SVGDescElement')
-class DescElement extends SvgElement implements Stylable, LangSpace native "*SVGDescElement" {
+class DescElement extends StyledElement implements LangSpace native "*SVGDescElement" {
+ @DomName('SVGDescElement.SVGDescElement')
@DocsEditable
factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
@@ -1014,18 +976,6 @@
@DomName('SVGDescElement.xmlspace')
@DocsEditable
String xmlspace;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGDescElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -1546,8 +1496,9 @@
@DocsEditable
@DomName('SVGEllipseElement')
-class EllipseElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGEllipseElement" {
+class EllipseElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGEllipseElement" {
+ @DomName('SVGEllipseElement.SVGEllipseElement')
@DocsEditable
factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
@@ -1611,18 +1562,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGEllipseElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGEllipseElement.requiredExtensions')
@@ -1664,7 +1603,7 @@
@DocsEditable
@DomName('SVGFEBlendElement')
-class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEBlendElement" {
+class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEBlendElement" {
static const int SVG_FEBLEND_MODE_DARKEN = 4;
@@ -1711,18 +1650,6 @@
@DomName('SVGFEBlendElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEBlendElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -1731,7 +1658,7 @@
@DocsEditable
@DomName('SVGFEColorMatrixElement')
-class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEColorMatrixElement" {
+class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEColorMatrixElement" {
static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
@@ -1776,18 +1703,6 @@
@DomName('SVGFEColorMatrixElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEColorMatrixElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -1796,7 +1711,7 @@
@DocsEditable
@DomName('SVGFEComponentTransferElement')
-class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEComponentTransferElement" {
+class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEComponentTransferElement" {
@DomName('SVGFEComponentTransferElement.in1')
@DocsEditable
@@ -1823,18 +1738,6 @@
@DomName('SVGFEComponentTransferElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEComponentTransferElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -1843,7 +1746,7 @@
@DocsEditable
@DomName('SVGFECompositeElement')
-class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFECompositeElement" {
+class FECompositeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFECompositeElement" {
static const int SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
@@ -1908,18 +1811,6 @@
@DomName('SVGFECompositeElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFECompositeElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -1928,7 +1819,7 @@
@DocsEditable
@DomName('SVGFEConvolveMatrixElement')
-class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEConvolveMatrixElement" {
+class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEConvolveMatrixElement" {
static const int SVG_EDGEMODE_DUPLICATE = 1;
@@ -2007,18 +1898,6 @@
@DomName('SVGFEConvolveMatrixElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEConvolveMatrixElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2027,7 +1906,7 @@
@DocsEditable
@DomName('SVGFEDiffuseLightingElement')
-class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEDiffuseLightingElement" {
+class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDiffuseLightingElement" {
@DomName('SVGFEDiffuseLightingElement.diffuseConstant')
@DocsEditable
@@ -2070,18 +1949,6 @@
@DomName('SVGFEDiffuseLightingElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEDiffuseLightingElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2090,7 +1957,7 @@
@DocsEditable
@DomName('SVGFEDisplacementMapElement')
-class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEDisplacementMapElement" {
+class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDisplacementMapElement" {
static const int SVG_CHANNEL_A = 4;
@@ -2143,18 +2010,6 @@
@DomName('SVGFEDisplacementMapElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEDisplacementMapElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2180,7 +2035,7 @@
@DocsEditable
@DomName('SVGFEDropShadowElement')
-class FEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEDropShadowElement" {
+class FEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDropShadowElement" {
@DomName('SVGFEDropShadowElement.dx')
@DocsEditable
@@ -2227,18 +2082,6 @@
@DomName('SVGFEDropShadowElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEDropShadowElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2247,7 +2090,7 @@
@DocsEditable
@DomName('SVGFEFloodElement')
-class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEFloodElement" {
+class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEFloodElement" {
// From SVGFilterPrimitiveStandardAttributes
@@ -2270,18 +2113,6 @@
@DomName('SVGFEFloodElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEFloodElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2326,7 +2157,7 @@
@DocsEditable
@DomName('SVGFEGaussianBlurElement')
-class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEGaussianBlurElement" {
+class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEGaussianBlurElement" {
@DomName('SVGFEGaussianBlurElement.in1')
@DocsEditable
@@ -2365,18 +2196,6 @@
@DomName('SVGFEGaussianBlurElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEGaussianBlurElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2385,7 +2204,7 @@
@DocsEditable
@DomName('SVGFEImageElement')
-class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace native "*SVGFEImageElement" {
+class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace native "*SVGFEImageElement" {
@DomName('SVGFEImageElement.preserveAspectRatio')
@DocsEditable
@@ -2429,18 +2248,6 @@
@DocsEditable
String xmlspace;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEImageElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGURIReference
@DomName('SVGFEImageElement.href')
@@ -2454,7 +2261,7 @@
@DocsEditable
@DomName('SVGFEMergeElement')
-class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEMergeElement" {
+class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEMergeElement" {
// From SVGFilterPrimitiveStandardAttributes
@@ -2477,18 +2284,6 @@
@DomName('SVGFEMergeElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEMergeElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2510,7 +2305,7 @@
@DocsEditable
@DomName('SVGFEMorphologyElement')
-class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEMorphologyElement" {
+class FEMorphologyElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEMorphologyElement" {
static const int SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
@@ -2559,18 +2354,6 @@
@DomName('SVGFEMorphologyElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEMorphologyElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2579,7 +2362,7 @@
@DocsEditable
@DomName('SVGFEOffsetElement')
-class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEOffsetElement" {
+class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEOffsetElement" {
@DomName('SVGFEOffsetElement.dx')
@DocsEditable
@@ -2614,18 +2397,6 @@
@DomName('SVGFEOffsetElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFEOffsetElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2655,7 +2426,7 @@
@DocsEditable
@DomName('SVGFESpecularLightingElement')
-class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFESpecularLightingElement" {
+class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFESpecularLightingElement" {
@DomName('SVGFESpecularLightingElement.in1')
@DocsEditable
@@ -2694,18 +2465,6 @@
@DomName('SVGFESpecularLightingElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFESpecularLightingElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2755,7 +2514,7 @@
@DocsEditable
@DomName('SVGFETileElement')
-class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFETileElement" {
+class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFETileElement" {
@DomName('SVGFETileElement.in1')
@DocsEditable
@@ -2782,18 +2541,6 @@
@DomName('SVGFETileElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFETileElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2802,7 +2549,7 @@
@DocsEditable
@DomName('SVGFETurbulenceElement')
-class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFETurbulenceElement" {
+class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFETurbulenceElement" {
static const int SVG_STITCHTYPE_NOSTITCH = 2;
@@ -2861,18 +2608,6 @@
@DomName('SVGFETurbulenceElement.y')
@DocsEditable
final AnimatedLength y;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFETurbulenceElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -2881,8 +2616,9 @@
@DocsEditable
@DomName('SVGFilterElement')
-class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable, LangSpace native "*SVGFilterElement" {
+class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired, LangSpace native "*SVGFilterElement" {
+ @DomName('SVGFilterElement.SVGFilterElement')
@DocsEditable
factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
@@ -2938,18 +2674,6 @@
@DocsEditable
String xmlspace;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGFilterElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGURIReference
@DomName('SVGFilterElement.href')
@@ -2962,7 +2686,7 @@
@DomName('SVGFilterPrimitiveStandardAttributes')
-abstract class FilterPrimitiveStandardAttributes implements Stylable {
+abstract class FilterPrimitiveStandardAttributes {
AnimatedLength height;
@@ -2973,14 +2697,6 @@
AnimatedLength x;
AnimatedLength y;
-
- // From SVGStylable
-
- AnimatedString $dom_svgClassName;
-
- CssStyleDeclaration style;
-
- CssValue getPresentationAttribute(String name);
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -3003,6 +2719,7 @@
@DomName('SVGFontElement')
class FontElement extends SvgElement native "*SVGFontElement" {
+ @DomName('SVGFontElement.SVGFontElement')
@DocsEditable
factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
}
@@ -3015,6 +2732,7 @@
@DomName('SVGFontFaceElement')
class FontFaceElement extends SvgElement native "*SVGFontFaceElement" {
+ @DomName('SVGFontFaceElement.SVGFontFaceElement')
@DocsEditable
factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
}
@@ -3027,6 +2745,7 @@
@DomName('SVGFontFaceFormatElement')
class FontFaceFormatElement extends SvgElement native "*SVGFontFaceFormatElement" {
+ @DomName('SVGFontFaceFormatElement.SVGFontFaceFormatElement')
@DocsEditable
factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
}
@@ -3039,6 +2758,7 @@
@DomName('SVGFontFaceNameElement')
class FontFaceNameElement extends SvgElement native "*SVGFontFaceNameElement" {
+ @DomName('SVGFontFaceNameElement.SVGFontFaceNameElement')
@DocsEditable
factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
}
@@ -3051,6 +2771,7 @@
@DomName('SVGFontFaceSrcElement')
class FontFaceSrcElement extends SvgElement native "*SVGFontFaceSrcElement" {
+ @DomName('SVGFontFaceSrcElement.SVGFontFaceSrcElement')
@DocsEditable
factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
}
@@ -3063,6 +2784,7 @@
@DomName('SVGFontFaceUriElement')
class FontFaceUriElement extends SvgElement native "*SVGFontFaceUriElement" {
+ @DomName('SVGFontFaceUriElement.SVGFontFaceUriElement')
@DocsEditable
factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
}
@@ -3073,8 +2795,9 @@
@DocsEditable
@DomName('SVGForeignObjectElement')
-class ForeignObjectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGForeignObjectElement" {
+class ForeignObjectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGForeignObjectElement" {
+ @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
@DocsEditable
factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
@@ -3138,18 +2861,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGForeignObjectElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGForeignObjectElement.requiredExtensions')
@@ -3181,8 +2892,9 @@
@DocsEditable
@DomName('SVGGElement')
-class GElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGGElement" {
+class GElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGGElement" {
+ @DomName('SVGGElement.SVGGElement')
@DocsEditable
factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
@@ -3230,18 +2942,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGGElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGGElement.requiredExtensions')
@@ -3275,6 +2975,7 @@
@DomName('SVGGlyphElement')
class GlyphElement extends SvgElement native "*SVGGlyphElement" {
+ @DomName('SVGGlyphElement.SVGGlyphElement')
@DocsEditable
factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
}
@@ -3285,7 +2986,7 @@
@DocsEditable
@DomName('SVGGlyphRefElement')
-class GlyphRefElement extends SvgElement implements UriReference, Stylable native "*SVGGlyphRefElement" {
+class GlyphRefElement extends StyledElement implements UriReference native "*SVGGlyphRefElement" {
@DomName('SVGGlyphRefElement.dx')
@DocsEditable
@@ -3311,18 +3012,6 @@
@DocsEditable
num y;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGGlyphRefElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGURIReference
@DomName('SVGGlyphRefElement.href')
@@ -3336,7 +3025,7 @@
@DocsEditable
@DomName('SVGGradientElement')
-class GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable native "*SVGGradientElement" {
+class GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired native "*SVGGradientElement" {
static const int SVG_SPREADMETHOD_PAD = 1;
@@ -3364,18 +3053,6 @@
@DocsEditable
final AnimatedBoolean externalResourcesRequired;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGGradientElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGURIReference
@DomName('SVGGradientElement.href')
@@ -3391,6 +3068,7 @@
@DomName('SVGHKernElement')
class HKernElement extends SvgElement native "*SVGHKernElement" {
+ @DomName('SVGHKernElement.SVGHKernElement')
@DocsEditable
factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
}
@@ -3401,8 +3079,9 @@
@DocsEditable
@DomName('SVGImageElement')
-class ImageElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGImageElement" {
+class ImageElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGImageElement" {
+ @DomName('SVGImageElement.SVGImageElement')
@DocsEditable
factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
@@ -3470,18 +3149,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGImageElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGImageElement.requiredExtensions')
@@ -3622,7 +3289,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Length element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Length element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Length element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Length> where(bool f(Length element)) =>
IterableMixinWorkaround.where(this, f);
@@ -3636,13 +3307,13 @@
bool get isEmpty => this.length == 0;
- List<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Length> takeWhile(bool test(Length value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Length> skipWhile(bool test(Length value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -3685,8 +3356,9 @@
// clear() defined by IDL.
- List<Length> get reversed =>
- new ReversedListView<Length>(this, 0, null);
+ List<Length> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Length a, Length b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -3802,8 +3474,9 @@
@DocsEditable
@DomName('SVGLineElement')
-class LineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGLineElement" {
+class LineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGLineElement" {
+ @DomName('SVGLineElement.SVGLineElement')
@DocsEditable
factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
@@ -3867,18 +3540,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGLineElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGLineElement.requiredExtensions')
@@ -3912,6 +3573,7 @@
@DomName('SVGLinearGradientElement')
class LinearGradientElement extends GradientElement native "*SVGLinearGradientElement" {
+ @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
@DocsEditable
factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
@@ -3960,6 +3622,7 @@
@DomName('SVGMPathElement')
class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired native "*SVGMPathElement" {
+ @DomName('SVGMPathElement.SVGMPathElement')
@DocsEditable
factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
@@ -3982,8 +3645,9 @@
@DocsEditable
@DomName('SVGMarkerElement')
-class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace native "*SVGMarkerElement" {
+class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace native "*SVGMarkerElement" {
+ @DomName('SVGMarkerElement.SVGMarkerElement')
@DocsEditable
factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
@@ -4060,18 +3724,6 @@
@DomName('SVGMarkerElement.xmlspace')
@DocsEditable
String xmlspace;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGMarkerElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -4080,8 +3732,9 @@
@DocsEditable
@DomName('SVGMaskElement')
-class MaskElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGMaskElement" {
+class MaskElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace native "*SVGMaskElement" {
+ @DomName('SVGMaskElement.SVGMaskElement')
@DocsEditable
factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
@@ -4125,18 +3778,6 @@
@DocsEditable
String xmlspace;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGMaskElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGMaskElement.requiredExtensions')
@@ -4248,7 +3889,7 @@
@DocsEditable
@DomName('SVGMissingGlyphElement')
-class MissingGlyphElement extends SvgElement native "*SVGMissingGlyphElement" {
+class MissingGlyphElement extends StyledElement native "*SVGMissingGlyphElement" {
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -4306,7 +3947,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Number element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Number element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Number element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Number> where(bool f(Number element)) =>
IterableMixinWorkaround.where(this, f);
@@ -4320,13 +3965,13 @@
bool get isEmpty => this.length == 0;
- List<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Number> takeWhile(bool test(Number value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Number> skipWhile(bool test(Number value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -4369,8 +4014,9 @@
// clear() defined by IDL.
- List<Number> get reversed =>
- new ReversedListView<Number>(this, 0, null);
+ List<Number> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Number a, Number b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -4531,8 +4177,9 @@
@DocsEditable
@DomName('SVGPathElement')
-class PathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPathElement" {
+class PathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGPathElement" {
+ @DomName('SVGPathElement.SVGPathElement')
@DocsEditable
factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
@@ -4707,18 +4354,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGPathElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGPathElement.requiredExtensions')
@@ -5212,7 +4847,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(PathSeg element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(PathSeg element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(PathSeg element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<PathSeg> where(bool f(PathSeg element)) =>
IterableMixinWorkaround.where(this, f);
@@ -5226,13 +4865,13 @@
bool get isEmpty => this.length == 0;
- List<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<PathSeg> takeWhile(bool test(PathSeg value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<PathSeg> skipWhile(bool test(PathSeg value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -5275,8 +4914,9 @@
// clear() defined by IDL.
- List<PathSeg> get reversed =>
- new ReversedListView<PathSeg>(this, 0, null);
+ List<PathSeg> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(PathSeg a, PathSeg b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -5426,8 +5066,9 @@
@DocsEditable
@DomName('SVGPatternElement')
-class PatternElement extends SvgElement implements FitToViewBox, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPatternElement" {
+class PatternElement extends StyledElement implements FitToViewBox, UriReference, Tests, ExternalResourcesRequired, LangSpace native "*SVGPatternElement" {
+ @DomName('SVGPatternElement.SVGPatternElement')
@DocsEditable
factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
@@ -5485,18 +5126,6 @@
@DocsEditable
String xmlspace;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGPatternElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGPatternElement.requiredExtensions')
@@ -5590,8 +5219,9 @@
@DocsEditable
@DomName('SVGPolygonElement')
-class PolygonElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPolygonElement" {
+class PolygonElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGPolygonElement" {
+ @DomName('SVGPolygonElement.SVGPolygonElement')
@DocsEditable
factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
@@ -5647,18 +5277,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGPolygonElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGPolygonElement.requiredExtensions')
@@ -5690,8 +5308,9 @@
@DocsEditable
@DomName('SVGPolylineElement')
-class PolylineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPolylineElement" {
+class PolylineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGPolylineElement" {
+ @DomName('SVGPolylineElement.SVGPolylineElement')
@DocsEditable
factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
@@ -5747,18 +5366,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGPolylineElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGPolylineElement.requiredExtensions')
@@ -5837,6 +5444,7 @@
@DomName('SVGRadialGradientElement')
class RadialGradientElement extends GradientElement native "*SVGRadialGradientElement" {
+ @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
@DocsEditable
factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
@@ -5896,8 +5504,9 @@
@DocsEditable
@DomName('SVGRectElement')
-class RectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGRectElement" {
+class RectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGRectElement" {
+ @DomName('SVGRectElement.SVGRectElement')
@DocsEditable
factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
@@ -5969,18 +5578,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGRectElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGRectElement.requiredExtensions')
@@ -6035,6 +5632,7 @@
@DomName('SVGScriptElement')
class ScriptElement extends SvgElement implements UriReference, ExternalResourcesRequired native "*SVGScriptElement" {
+ @DomName('SVGScriptElement.SVGScriptElement')
@DocsEditable
factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
@@ -6063,6 +5661,7 @@
@DomName('SVGSetElement')
class SetElement extends AnimationElement native "*SVGSetElement" {
+ @DomName('SVGSetElement.SVGSetElement')
@DocsEditable
factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
}
@@ -6073,26 +5672,15 @@
@DocsEditable
@DomName('SVGStopElement')
-class StopElement extends SvgElement implements Stylable native "*SVGStopElement" {
+class StopElement extends StyledElement native "*SVGStopElement" {
+ @DomName('SVGStopElement.SVGStopElement')
@DocsEditable
factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
@DomName('SVGStopElement.offset')
@DocsEditable
final AnimatedNumber offset;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGStopElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -6137,7 +5725,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(String element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(String element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<String> where(bool f(String element)) =>
IterableMixinWorkaround.where(this, f);
@@ -6151,13 +5743,13 @@
bool get isEmpty => this.length == 0;
- List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<String> takeWhile(bool test(String value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<String> skipWhile(bool test(String value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -6200,8 +5792,9 @@
// clear() defined by IDL.
- List<String> get reversed =>
- new ReversedListView<String>(this, 0, null);
+ List<String> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(String a, String b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -6315,24 +5908,11 @@
// BSD-style license that can be found in the LICENSE file.
-@DomName('SVGStylable')
-abstract class Stylable {
-
- AnimatedString $dom_svgClassName;
-
- CssStyleDeclaration style;
-
- CssValue getPresentationAttribute(String name);
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
@DocsEditable
@DomName('SVGStyleElement')
class StyleElement extends SvgElement implements LangSpace native "*SVGStyleElement" {
+ @DomName('SVGStyleElement.SVGStyleElement')
@DocsEditable
factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
@@ -6371,6 +5951,25 @@
@DocsEditable
+@DomName('SVGStyledElement')
+class StyledElement extends SvgElement native "*SVGStyledElement" {
+
+ // Shadowing definition.
+ AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
+
+ // Use implementation from Element.
+ // final CssStyleDeclaration style;
+
+ @DomName('SVGStyledElement.getPresentationAttribute')
+ @DocsEditable
+ CssValue getPresentationAttribute(String name) 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.
+
+
+@DocsEditable
@DomName('SVGDocument')
class SvgDocument extends Document native "*SVGDocument" {
@@ -6555,7 +6154,7 @@
@DomName('SVGSVGElement')
-class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace native "*SVGSVGElement" {
+class SvgSvgElement extends StyledElement implements FitToViewBox, Transformable, Tests, ExternalResourcesRequired, ZoomAndPan, LangSpace native "*SVGSVGElement" {
factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
@@ -6777,18 +6376,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGSVGElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGSVGElement.requiredExtensions')
@@ -6807,6 +6394,12 @@
@DocsEditable
bool hasExtension(String extension) native;
+ // From SVGTransformable
+
+ @DomName('SVGSVGElement.transform')
+ @DocsEditable
+ final AnimatedTransformList transform;
+
// From SVGZoomAndPan
@DomName('SVGSVGElement.zoomAndPan')
@@ -6821,8 +6414,9 @@
@DocsEditable
@DomName('SVGSwitchElement')
-class SwitchElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGSwitchElement" {
+class SwitchElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGSwitchElement" {
+ @DomName('SVGSwitchElement.SVGSwitchElement')
@DocsEditable
factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
@@ -6870,18 +6464,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGSwitchElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGSwitchElement.requiredExtensions')
@@ -6913,8 +6495,9 @@
@DocsEditable
@DomName('SVGSymbolElement')
-class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace native "*SVGSymbolElement" {
+class SymbolElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace native "*SVGSymbolElement" {
+ @DomName('SVGSymbolElement.SVGSymbolElement')
@DocsEditable
factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
@@ -6943,18 +6526,6 @@
@DomName('SVGSymbolElement.xmlspace')
@DocsEditable
String xmlspace;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGSymbolElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -6965,6 +6536,7 @@
@DomName('SVGTRefElement')
class TRefElement extends TextPositioningElement implements UriReference native "*SVGTRefElement" {
+ @DomName('SVGTRefElement.SVGTRefElement')
@DocsEditable
factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
@@ -6983,6 +6555,7 @@
@DomName('SVGTSpanElement')
class TSpanElement extends TextPositioningElement native "*SVGTSpanElement" {
+ @DomName('SVGTSpanElement.SVGTSpanElement')
@DocsEditable
factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
}
@@ -7009,7 +6582,7 @@
@DocsEditable
@DomName('SVGTextContentElement')
-class TextContentElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGTextContentElement" {
+class TextContentElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace native "*SVGTextContentElement" {
static const int LENGTHADJUST_SPACING = 1;
@@ -7077,18 +6650,6 @@
@DocsEditable
String xmlspace;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGTextContentElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGTextContentElement.requiredExtensions')
@@ -7116,6 +6677,7 @@
@DomName('SVGTextElement')
class TextElement extends TextPositioningElement implements Transformable native "*SVGTextElement" {
+ @DomName('SVGTextElement.SVGTextElement')
@DocsEditable
factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
@@ -7228,8 +6790,9 @@
@DocsEditable
@DomName('SVGTitleElement')
-class TitleElement extends SvgElement implements Stylable, LangSpace native "*SVGTitleElement" {
+class TitleElement extends StyledElement implements LangSpace native "*SVGTitleElement" {
+ @DomName('SVGTitleElement.SVGTitleElement')
@DocsEditable
factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
@@ -7242,18 +6805,6 @@
@DomName('SVGTitleElement.xmlspace')
@DocsEditable
String xmlspace;
-
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGTitleElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) 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
@@ -7357,7 +6908,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Transform element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Transform element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Transform element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Transform> where(bool f(Transform element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7371,13 +6926,13 @@
bool get isEmpty => this.length == 0;
- List<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Transform> takeWhile(bool test(Transform value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Transform> skipWhile(bool test(Transform value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -7420,8 +6975,9 @@
// clear() defined by IDL.
- List<Transform> get reversed =>
- new ReversedListView<Transform>(this, 0, null);
+ List<Transform> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Transform a, Transform b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -7595,8 +7151,9 @@
@DocsEditable
@DomName('SVGUseElement')
-class UseElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGUseElement" {
+class UseElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGUseElement" {
+ @DomName('SVGUseElement.SVGUseElement')
@DocsEditable
factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
@@ -7668,18 +7225,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native;
- // From SVGStylable
-
- // Shadowing definition.
- AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
- // Use implementation from Element.
- // final CssStyleDeclaration style;
-
- @DomName('SVGUseElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native;
-
// From SVGTests
@DomName('SVGUseElement.requiredExtensions')
@@ -7719,6 +7264,7 @@
@DomName('SVGVKernElement')
class VKernElement extends SvgElement native "*SVGVKernElement" {
+ @DomName('SVGVKernElement.SVGVKernElement')
@DocsEditable
factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
}
@@ -7731,6 +7277,7 @@
@DomName('SVGViewElement')
class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan native "*SVGViewElement" {
+ @DomName('SVGViewElement.SVGViewElement')
@DocsEditable
factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
@@ -7891,7 +7438,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(ElementInstance element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(ElementInstance element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(ElementInstance element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<ElementInstance> where(bool f(ElementInstance element)) =>
IterableMixinWorkaround.where(this, f);
@@ -7905,13 +7456,13 @@
bool get isEmpty => this.length == 0;
- List<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<ElementInstance> takeWhile(bool test(ElementInstance value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<ElementInstance> skipWhile(bool test(ElementInstance value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -7956,8 +7507,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<ElementInstance> get reversed =>
- new ReversedListView<ElementInstance>(this, 0, null);
+ List<ElementInstance> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(ElementInstance a, ElementInstance b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 8463359..17a4b29 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -1,8 +1,7 @@
-library svg;
+library dart.dom.svg;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
@@ -62,9 +61,10 @@
@DocsEditable
@DomName('SVGAElement')
-class AElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class AElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
AElement.internal() : super.internal();
+ @DomName('SVGAElement.SVGAElement')
@DocsEditable
factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
@@ -116,18 +116,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGAElement_getTransformToElement_Callback";
- @DomName('SVGAElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGAElement_className_Getter";
-
- @DomName('SVGAElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGAElement_style_Getter";
-
- @DomName('SVGAElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGAElement_getPresentationAttribute_Callback";
-
@DomName('SVGAElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGAElement_requiredExtensions_Getter";
@@ -283,6 +271,7 @@
class AnimateColorElement extends AnimationElement {
AnimateColorElement.internal() : super.internal();
+ @DomName('SVGAnimateColorElement.SVGAnimateColorElement')
@DocsEditable
factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
@@ -299,6 +288,7 @@
class AnimateElement extends AnimationElement {
AnimateElement.internal() : super.internal();
+ @DomName('SVGAnimateElement.SVGAnimateElement')
@DocsEditable
factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
@@ -315,6 +305,7 @@
class AnimateMotionElement extends AnimationElement {
AnimateMotionElement.internal() : super.internal();
+ @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
@DocsEditable
factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
@@ -331,6 +322,7 @@
class AnimateTransformElement extends AnimationElement {
AnimateTransformElement.internal() : super.internal();
+ @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
@DocsEditable
factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
@@ -619,6 +611,7 @@
class AnimationElement extends SvgElement implements Tests, ElementTimeControl, ExternalResourcesRequired {
AnimationElement.internal() : super.internal();
+ @DomName('SVGAnimationElement.SVGAnimationElement')
@DocsEditable
factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
@@ -684,9 +677,10 @@
@DocsEditable
@DomName('SVGCircleElement')
-class CircleElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class CircleElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
CircleElement.internal() : super.internal();
+ @DomName('SVGCircleElement.SVGCircleElement')
@DocsEditable
factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
@@ -746,18 +740,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGCircleElement_getTransformToElement_Callback";
- @DomName('SVGCircleElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGCircleElement_className_Getter";
-
- @DomName('SVGCircleElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGCircleElement_style_Getter";
-
- @DomName('SVGCircleElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGCircleElement_getPresentationAttribute_Callback";
-
@DomName('SVGCircleElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGCircleElement_requiredExtensions_Getter";
@@ -788,9 +770,10 @@
@DocsEditable
@DomName('SVGClipPathElement')
-class ClipPathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class ClipPathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
ClipPathElement.internal() : super.internal();
+ @DomName('SVGClipPathElement.SVGClipPathElement')
@DocsEditable
factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
@@ -842,18 +825,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGClipPathElement_getTransformToElement_Callback";
- @DomName('SVGClipPathElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGClipPathElement_className_Getter";
-
- @DomName('SVGClipPathElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGClipPathElement_style_Getter";
-
- @DomName('SVGClipPathElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGClipPathElement_getPresentationAttribute_Callback";
-
@DomName('SVGClipPathElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGClipPathElement_requiredExtensions_Getter";
@@ -981,6 +952,7 @@
class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired {
CursorElement.internal() : super.internal();
+ @DomName('SVGCursorElement.SVGCursorElement')
@DocsEditable
factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
@@ -1026,9 +998,10 @@
@DocsEditable
@DomName('SVGDefsElement')
-class DefsElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class DefsElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
DefsElement.internal() : super.internal();
+ @DomName('SVGDefsElement.SVGDefsElement')
@DocsEditable
factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
@@ -1076,18 +1049,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGDefsElement_getTransformToElement_Callback";
- @DomName('SVGDefsElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGDefsElement_className_Getter";
-
- @DomName('SVGDefsElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGDefsElement_style_Getter";
-
- @DomName('SVGDefsElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGDefsElement_getPresentationAttribute_Callback";
-
@DomName('SVGDefsElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGDefsElement_requiredExtensions_Getter";
@@ -1118,9 +1079,10 @@
@DocsEditable
@DomName('SVGDescElement')
-class DescElement extends SvgElement implements Stylable, LangSpace {
+class DescElement extends StyledElement implements LangSpace {
DescElement.internal() : super.internal();
+ @DomName('SVGDescElement.SVGDescElement')
@DocsEditable
factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
@@ -1140,18 +1102,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGDescElement_xmlspace_Setter";
- @DomName('SVGDescElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGDescElement_className_Getter";
-
- @DomName('SVGDescElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGDescElement_style_Getter";
-
- @DomName('SVGDescElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGDescElement_getPresentationAttribute_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
@@ -1689,9 +1639,10 @@
@DocsEditable
@DomName('SVGEllipseElement')
-class EllipseElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class EllipseElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
EllipseElement.internal() : super.internal();
+ @DomName('SVGEllipseElement.SVGEllipseElement')
@DocsEditable
factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
@@ -1755,18 +1706,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGEllipseElement_getTransformToElement_Callback";
- @DomName('SVGEllipseElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGEllipseElement_className_Getter";
-
- @DomName('SVGEllipseElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGEllipseElement_style_Getter";
-
- @DomName('SVGEllipseElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGEllipseElement_getPresentationAttribute_Callback";
-
@DomName('SVGEllipseElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGEllipseElement_requiredExtensions_Getter";
@@ -1814,7 +1753,7 @@
@DocsEditable
@DomName('SVGFEBlendElement')
-class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEBlendElement.internal() : super.internal();
static const int SVG_FEBLEND_MODE_DARKEN = 4;
@@ -1861,18 +1800,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEBlendElement_y_Getter";
- @DomName('SVGFEBlendElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEBlendElement_className_Getter";
-
- @DomName('SVGFEBlendElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEBlendElement_style_Getter";
-
- @DomName('SVGFEBlendElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEBlendElement_getPresentationAttribute_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
@@ -1883,7 +1810,7 @@
@DocsEditable
@DomName('SVGFEColorMatrixElement')
-class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEColorMatrixElement.internal() : super.internal();
static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
@@ -1928,18 +1855,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEColorMatrixElement_y_Getter";
- @DomName('SVGFEColorMatrixElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEColorMatrixElement_className_Getter";
-
- @DomName('SVGFEColorMatrixElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEColorMatrixElement_style_Getter";
-
- @DomName('SVGFEColorMatrixElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEColorMatrixElement_getPresentationAttribute_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
@@ -1950,7 +1865,7 @@
@DocsEditable
@DomName('SVGFEComponentTransferElement')
-class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEComponentTransferElement.internal() : super.internal();
@DomName('SVGFEComponentTransferElement.in1')
@@ -1977,18 +1892,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEComponentTransferElement_y_Getter";
- @DomName('SVGFEComponentTransferElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEComponentTransferElement_className_Getter";
-
- @DomName('SVGFEComponentTransferElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEComponentTransferElement_style_Getter";
-
- @DomName('SVGFEComponentTransferElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEComponentTransferElement_getPresentationAttribute_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
@@ -1999,7 +1902,7 @@
@DocsEditable
@DomName('SVGFECompositeElement')
-class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FECompositeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FECompositeElement.internal() : super.internal();
static const int SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
@@ -2064,18 +1967,6 @@
@DocsEditable
AnimatedLength get y native "SVGFECompositeElement_y_Getter";
- @DomName('SVGFECompositeElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFECompositeElement_className_Getter";
-
- @DomName('SVGFECompositeElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFECompositeElement_style_Getter";
-
- @DomName('SVGFECompositeElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFECompositeElement_getPresentationAttribute_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
@@ -2086,7 +1977,7 @@
@DocsEditable
@DomName('SVGFEConvolveMatrixElement')
-class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEConvolveMatrixElement.internal() : super.internal();
static const int SVG_EDGEMODE_DUPLICATE = 1;
@@ -2165,18 +2056,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEConvolveMatrixElement_y_Getter";
- @DomName('SVGFEConvolveMatrixElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEConvolveMatrixElement_className_Getter";
-
- @DomName('SVGFEConvolveMatrixElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEConvolveMatrixElement_style_Getter";
-
- @DomName('SVGFEConvolveMatrixElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEConvolveMatrixElement_getPresentationAttribute_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
@@ -2187,7 +2066,7 @@
@DocsEditable
@DomName('SVGFEDiffuseLightingElement')
-class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEDiffuseLightingElement.internal() : super.internal();
@DomName('SVGFEDiffuseLightingElement.diffuseConstant')
@@ -2230,18 +2109,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEDiffuseLightingElement_y_Getter";
- @DomName('SVGFEDiffuseLightingElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEDiffuseLightingElement_className_Getter";
-
- @DomName('SVGFEDiffuseLightingElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEDiffuseLightingElement_style_Getter";
-
- @DomName('SVGFEDiffuseLightingElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEDiffuseLightingElement_getPresentationAttribute_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
@@ -2252,7 +2119,7 @@
@DocsEditable
@DomName('SVGFEDisplacementMapElement')
-class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEDisplacementMapElement.internal() : super.internal();
static const int SVG_CHANNEL_A = 4;
@@ -2305,18 +2172,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEDisplacementMapElement_y_Getter";
- @DomName('SVGFEDisplacementMapElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEDisplacementMapElement_className_Getter";
-
- @DomName('SVGFEDisplacementMapElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEDisplacementMapElement_style_Getter";
-
- @DomName('SVGFEDisplacementMapElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEDisplacementMapElement_getPresentationAttribute_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
@@ -2348,7 +2203,7 @@
@DocsEditable
@DomName('SVGFEDropShadowElement')
-class FEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEDropShadowElement.internal() : super.internal();
@DomName('SVGFEDropShadowElement.dx')
@@ -2395,18 +2250,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEDropShadowElement_y_Getter";
- @DomName('SVGFEDropShadowElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEDropShadowElement_className_Getter";
-
- @DomName('SVGFEDropShadowElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEDropShadowElement_style_Getter";
-
- @DomName('SVGFEDropShadowElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEDropShadowElement_getPresentationAttribute_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
@@ -2417,7 +2260,7 @@
@DocsEditable
@DomName('SVGFEFloodElement')
-class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEFloodElement.internal() : super.internal();
@DomName('SVGFEFloodElement.height')
@@ -2440,18 +2283,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEFloodElement_y_Getter";
- @DomName('SVGFEFloodElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEFloodElement_className_Getter";
-
- @DomName('SVGFEFloodElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEFloodElement_style_Getter";
-
- @DomName('SVGFEFloodElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEFloodElement_getPresentationAttribute_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
@@ -2514,7 +2345,7 @@
@DocsEditable
@DomName('SVGFEGaussianBlurElement')
-class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEGaussianBlurElement.internal() : super.internal();
@DomName('SVGFEGaussianBlurElement.in1')
@@ -2553,18 +2384,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEGaussianBlurElement_y_Getter";
- @DomName('SVGFEGaussianBlurElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEGaussianBlurElement_className_Getter";
-
- @DomName('SVGFEGaussianBlurElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEGaussianBlurElement_style_Getter";
-
- @DomName('SVGFEGaussianBlurElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEGaussianBlurElement_getPresentationAttribute_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
@@ -2575,7 +2394,7 @@
@DocsEditable
@DomName('SVGFEImageElement')
-class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace {
+class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace {
FEImageElement.internal() : super.internal();
@DomName('SVGFEImageElement.preserveAspectRatio')
@@ -2622,18 +2441,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGFEImageElement_xmlspace_Setter";
- @DomName('SVGFEImageElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEImageElement_className_Getter";
-
- @DomName('SVGFEImageElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEImageElement_style_Getter";
-
- @DomName('SVGFEImageElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEImageElement_getPresentationAttribute_Callback";
-
@DomName('SVGFEImageElement.href')
@DocsEditable
AnimatedString get href native "SVGFEImageElement_href_Getter";
@@ -2648,7 +2455,7 @@
@DocsEditable
@DomName('SVGFEMergeElement')
-class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEMergeElement.internal() : super.internal();
@DomName('SVGFEMergeElement.height')
@@ -2671,18 +2478,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEMergeElement_y_Getter";
- @DomName('SVGFEMergeElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEMergeElement_className_Getter";
-
- @DomName('SVGFEMergeElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEMergeElement_style_Getter";
-
- @DomName('SVGFEMergeElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEMergeElement_getPresentationAttribute_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
@@ -2710,7 +2505,7 @@
@DocsEditable
@DomName('SVGFEMorphologyElement')
-class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEMorphologyElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEMorphologyElement.internal() : super.internal();
static const int SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
@@ -2759,18 +2554,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEMorphologyElement_y_Getter";
- @DomName('SVGFEMorphologyElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEMorphologyElement_className_Getter";
-
- @DomName('SVGFEMorphologyElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEMorphologyElement_style_Getter";
-
- @DomName('SVGFEMorphologyElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEMorphologyElement_getPresentationAttribute_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
@@ -2781,7 +2564,7 @@
@DocsEditable
@DomName('SVGFEOffsetElement')
-class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FEOffsetElement.internal() : super.internal();
@DomName('SVGFEOffsetElement.dx')
@@ -2816,18 +2599,6 @@
@DocsEditable
AnimatedLength get y native "SVGFEOffsetElement_y_Getter";
- @DomName('SVGFEOffsetElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFEOffsetElement_className_Getter";
-
- @DomName('SVGFEOffsetElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFEOffsetElement_style_Getter";
-
- @DomName('SVGFEOffsetElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFEOffsetElement_getPresentationAttribute_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
@@ -2863,7 +2634,7 @@
@DocsEditable
@DomName('SVGFESpecularLightingElement')
-class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FESpecularLightingElement.internal() : super.internal();
@DomName('SVGFESpecularLightingElement.in1')
@@ -2902,18 +2673,6 @@
@DocsEditable
AnimatedLength get y native "SVGFESpecularLightingElement_y_Getter";
- @DomName('SVGFESpecularLightingElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFESpecularLightingElement_className_Getter";
-
- @DomName('SVGFESpecularLightingElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFESpecularLightingElement_style_Getter";
-
- @DomName('SVGFESpecularLightingElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFESpecularLightingElement_getPresentationAttribute_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
@@ -2969,7 +2728,7 @@
@DocsEditable
@DomName('SVGFETileElement')
-class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FETileElement.internal() : super.internal();
@DomName('SVGFETileElement.in1')
@@ -2996,18 +2755,6 @@
@DocsEditable
AnimatedLength get y native "SVGFETileElement_y_Getter";
- @DomName('SVGFETileElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFETileElement_className_Getter";
-
- @DomName('SVGFETileElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFETileElement_style_Getter";
-
- @DomName('SVGFETileElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFETileElement_getPresentationAttribute_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
@@ -3018,7 +2765,7 @@
@DocsEditable
@DomName('SVGFETurbulenceElement')
-class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes {
FETurbulenceElement.internal() : super.internal();
static const int SVG_STITCHTYPE_NOSTITCH = 2;
@@ -3077,18 +2824,6 @@
@DocsEditable
AnimatedLength get y native "SVGFETurbulenceElement_y_Getter";
- @DomName('SVGFETurbulenceElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFETurbulenceElement_className_Getter";
-
- @DomName('SVGFETurbulenceElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFETurbulenceElement_style_Getter";
-
- @DomName('SVGFETurbulenceElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFETurbulenceElement_getPresentationAttribute_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
@@ -3099,9 +2834,10 @@
@DocsEditable
@DomName('SVGFilterElement')
-class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable, LangSpace {
+class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired, LangSpace {
FilterElement.internal() : super.internal();
+ @DomName('SVGFilterElement.SVGFilterElement')
@DocsEditable
factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
@@ -3161,18 +2897,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGFilterElement_xmlspace_Setter";
- @DomName('SVGFilterElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFilterElement_className_Getter";
-
- @DomName('SVGFilterElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFilterElement_style_Getter";
-
- @DomName('SVGFilterElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFilterElement_getPresentationAttribute_Callback";
-
@DomName('SVGFilterElement.href')
@DocsEditable
AnimatedString get href native "SVGFilterElement_href_Getter";
@@ -3187,7 +2911,7 @@
@DocsEditable
@DomName('SVGFilterPrimitiveStandardAttributes')
-class FilterPrimitiveStandardAttributes extends NativeFieldWrapperClass1 implements Stylable {
+class FilterPrimitiveStandardAttributes extends NativeFieldWrapperClass1 {
FilterPrimitiveStandardAttributes.internal();
@DomName('SVGFilterPrimitiveStandardAttributes.height')
@@ -3210,18 +2934,6 @@
@DocsEditable
AnimatedLength get y native "SVGFilterPrimitiveStandardAttributes_y_Getter";
- @DomName('SVGFilterPrimitiveStandardAttributes.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGFilterPrimitiveStandardAttributes_className_Getter";
-
- @DomName('SVGFilterPrimitiveStandardAttributes.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGFilterPrimitiveStandardAttributes_style_Getter";
-
- @DomName('SVGFilterPrimitiveStandardAttributes.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGFilterPrimitiveStandardAttributes_getPresentationAttribute_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
@@ -3256,6 +2968,7 @@
class FontElement extends SvgElement {
FontElement.internal() : super.internal();
+ @DomName('SVGFontElement.SVGFontElement')
@DocsEditable
factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
@@ -3272,6 +2985,7 @@
class FontFaceElement extends SvgElement {
FontFaceElement.internal() : super.internal();
+ @DomName('SVGFontFaceElement.SVGFontFaceElement')
@DocsEditable
factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
@@ -3288,6 +3002,7 @@
class FontFaceFormatElement extends SvgElement {
FontFaceFormatElement.internal() : super.internal();
+ @DomName('SVGFontFaceFormatElement.SVGFontFaceFormatElement')
@DocsEditable
factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
@@ -3304,6 +3019,7 @@
class FontFaceNameElement extends SvgElement {
FontFaceNameElement.internal() : super.internal();
+ @DomName('SVGFontFaceNameElement.SVGFontFaceNameElement')
@DocsEditable
factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
@@ -3320,6 +3036,7 @@
class FontFaceSrcElement extends SvgElement {
FontFaceSrcElement.internal() : super.internal();
+ @DomName('SVGFontFaceSrcElement.SVGFontFaceSrcElement')
@DocsEditable
factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
@@ -3336,6 +3053,7 @@
class FontFaceUriElement extends SvgElement {
FontFaceUriElement.internal() : super.internal();
+ @DomName('SVGFontFaceUriElement.SVGFontFaceUriElement')
@DocsEditable
factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
@@ -3349,9 +3067,10 @@
@DocsEditable
@DomName('SVGForeignObjectElement')
-class ForeignObjectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class ForeignObjectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
ForeignObjectElement.internal() : super.internal();
+ @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
@DocsEditable
factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
@@ -3415,18 +3134,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGForeignObjectElement_getTransformToElement_Callback";
- @DomName('SVGForeignObjectElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGForeignObjectElement_className_Getter";
-
- @DomName('SVGForeignObjectElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGForeignObjectElement_style_Getter";
-
- @DomName('SVGForeignObjectElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGForeignObjectElement_getPresentationAttribute_Callback";
-
@DomName('SVGForeignObjectElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGForeignObjectElement_requiredExtensions_Getter";
@@ -3457,9 +3164,10 @@
@DocsEditable
@DomName('SVGGElement')
-class GElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class GElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
GElement.internal() : super.internal();
+ @DomName('SVGGElement.SVGGElement')
@DocsEditable
factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
@@ -3507,18 +3215,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGGElement_getTransformToElement_Callback";
- @DomName('SVGGElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGGElement_className_Getter";
-
- @DomName('SVGGElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGGElement_style_Getter";
-
- @DomName('SVGGElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGGElement_getPresentationAttribute_Callback";
-
@DomName('SVGGElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGGElement_requiredExtensions_Getter";
@@ -3552,6 +3248,7 @@
class GlyphElement extends SvgElement {
GlyphElement.internal() : super.internal();
+ @DomName('SVGGlyphElement.SVGGlyphElement')
@DocsEditable
factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
@@ -3565,7 +3262,7 @@
@DocsEditable
@DomName('SVGGlyphRefElement')
-class GlyphRefElement extends SvgElement implements UriReference, Stylable {
+class GlyphRefElement extends StyledElement implements UriReference {
GlyphRefElement.internal() : super.internal();
@DomName('SVGGlyphRefElement.dx')
@@ -3616,18 +3313,6 @@
@DocsEditable
void set y(num value) native "SVGGlyphRefElement_y_Setter";
- @DomName('SVGGlyphRefElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGGlyphRefElement_className_Getter";
-
- @DomName('SVGGlyphRefElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGGlyphRefElement_style_Getter";
-
- @DomName('SVGGlyphRefElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGGlyphRefElement_getPresentationAttribute_Callback";
-
@DomName('SVGGlyphRefElement.href')
@DocsEditable
AnimatedString get href native "SVGGlyphRefElement_href_Getter";
@@ -3642,7 +3327,7 @@
@DocsEditable
@DomName('SVGGradientElement')
-class GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable {
+class GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired {
GradientElement.internal() : super.internal();
static const int SVG_SPREADMETHOD_PAD = 1;
@@ -3669,18 +3354,6 @@
@DocsEditable
AnimatedBoolean get externalResourcesRequired native "SVGGradientElement_externalResourcesRequired_Getter";
- @DomName('SVGGradientElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGGradientElement_className_Getter";
-
- @DomName('SVGGradientElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGGradientElement_style_Getter";
-
- @DomName('SVGGradientElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGGradientElement_getPresentationAttribute_Callback";
-
@DomName('SVGGradientElement.href')
@DocsEditable
AnimatedString get href native "SVGGradientElement_href_Getter";
@@ -3698,6 +3371,7 @@
class HKernElement extends SvgElement {
HKernElement.internal() : super.internal();
+ @DomName('SVGHKernElement.SVGHKernElement')
@DocsEditable
factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
@@ -3711,9 +3385,10 @@
@DocsEditable
@DomName('SVGImageElement')
-class ImageElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class ImageElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
ImageElement.internal() : super.internal();
+ @DomName('SVGImageElement.SVGImageElement')
@DocsEditable
factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
@@ -3781,18 +3456,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGImageElement_getTransformToElement_Callback";
- @DomName('SVGImageElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGImageElement_className_Getter";
-
- @DomName('SVGImageElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGImageElement_style_Getter";
-
- @DomName('SVGImageElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGImageElement_getPresentationAttribute_Callback";
-
@DomName('SVGImageElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGImageElement_requiredExtensions_Getter";
@@ -3964,7 +3627,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Length element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Length element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Length element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Length> where(bool f(Length element)) =>
IterableMixinWorkaround.where(this, f);
@@ -3978,13 +3645,13 @@
bool get isEmpty => this.length == 0;
- List<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Length> takeWhile(bool test(Length value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Length> skipWhile(bool test(Length value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -4027,8 +3694,9 @@
// clear() defined by IDL.
- List<Length> get reversed =>
- new ReversedListView<Length>(this, 0, null);
+ List<Length> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Length a, Length b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -4147,9 +3815,10 @@
@DocsEditable
@DomName('SVGLineElement')
-class LineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class LineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
LineElement.internal() : super.internal();
+ @DomName('SVGLineElement.SVGLineElement')
@DocsEditable
factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
@@ -4213,18 +3882,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGLineElement_getTransformToElement_Callback";
- @DomName('SVGLineElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGLineElement_className_Getter";
-
- @DomName('SVGLineElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGLineElement_style_Getter";
-
- @DomName('SVGLineElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGLineElement_getPresentationAttribute_Callback";
-
@DomName('SVGLineElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGLineElement_requiredExtensions_Getter";
@@ -4258,6 +3915,7 @@
class LinearGradientElement extends GradientElement {
LinearGradientElement.internal() : super.internal();
+ @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
@DocsEditable
factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
@@ -4327,6 +3985,7 @@
class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired {
MPathElement.internal() : super.internal();
+ @DomName('SVGMPathElement.SVGMPathElement')
@DocsEditable
factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
@@ -4348,9 +4007,10 @@
@DocsEditable
@DomName('SVGMarkerElement')
-class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace {
+class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace {
MarkerElement.internal() : super.internal();
+ @DomName('SVGMarkerElement.SVGMarkerElement')
@DocsEditable
factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
@@ -4430,18 +4090,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGMarkerElement_xmlspace_Setter";
- @DomName('SVGMarkerElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGMarkerElement_className_Getter";
-
- @DomName('SVGMarkerElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGMarkerElement_style_Getter";
-
- @DomName('SVGMarkerElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGMarkerElement_getPresentationAttribute_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
@@ -4452,9 +4100,10 @@
@DocsEditable
@DomName('SVGMaskElement')
-class MaskElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class MaskElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace {
MaskElement.internal() : super.internal();
+ @DomName('SVGMaskElement.SVGMaskElement')
@DocsEditable
factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
@@ -4502,18 +4151,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGMaskElement_xmlspace_Setter";
- @DomName('SVGMaskElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGMaskElement_className_Getter";
-
- @DomName('SVGMaskElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGMaskElement_style_Getter";
-
- @DomName('SVGMaskElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGMaskElement_getPresentationAttribute_Callback";
-
@DomName('SVGMaskElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGMaskElement_requiredExtensions_Getter";
@@ -4658,7 +4295,7 @@
@DocsEditable
@DomName('SVGMissingGlyphElement')
-class MissingGlyphElement extends SvgElement {
+class MissingGlyphElement extends StyledElement {
MissingGlyphElement.internal() : super.internal();
}
@@ -4729,7 +4366,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Number element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Number element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Number element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Number> where(bool f(Number element)) =>
IterableMixinWorkaround.where(this, f);
@@ -4743,13 +4384,13 @@
bool get isEmpty => this.length == 0;
- List<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Number> takeWhile(bool test(Number value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Number> skipWhile(bool test(Number value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -4792,8 +4433,9 @@
// clear() defined by IDL.
- List<Number> get reversed =>
- new ReversedListView<Number>(this, 0, null);
+ List<Number> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Number a, Number b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -4961,9 +4603,10 @@
@DocsEditable
@DomName('SVGPathElement')
-class PathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class PathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
PathElement.internal() : super.internal();
+ @DomName('SVGPathElement.SVGPathElement')
@DocsEditable
factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
@@ -5119,18 +4762,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGPathElement_getTransformToElement_Callback";
- @DomName('SVGPathElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGPathElement_className_Getter";
-
- @DomName('SVGPathElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGPathElement_style_Getter";
-
- @DomName('SVGPathElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGPathElement_getPresentationAttribute_Callback";
-
@DomName('SVGPathElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGPathElement_requiredExtensions_Getter";
@@ -5912,7 +5543,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(PathSeg element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(PathSeg element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(PathSeg element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<PathSeg> where(bool f(PathSeg element)) =>
IterableMixinWorkaround.where(this, f);
@@ -5926,13 +5561,13 @@
bool get isEmpty => this.length == 0;
- List<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<PathSeg> takeWhile(bool test(PathSeg value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<PathSeg> skipWhile(bool test(PathSeg value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -5975,8 +5610,9 @@
// clear() defined by IDL.
- List<PathSeg> get reversed =>
- new ReversedListView<PathSeg>(this, 0, null);
+ List<PathSeg> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(PathSeg a, PathSeg b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -6153,9 +5789,10 @@
@DocsEditable
@DomName('SVGPatternElement')
-class PatternElement extends SvgElement implements FitToViewBox, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class PatternElement extends StyledElement implements FitToViewBox, UriReference, Tests, ExternalResourcesRequired, LangSpace {
PatternElement.internal() : super.internal();
+ @DomName('SVGPatternElement.SVGPatternElement')
@DocsEditable
factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
@@ -6215,18 +5852,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGPatternElement_xmlspace_Setter";
- @DomName('SVGPatternElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGPatternElement_className_Getter";
-
- @DomName('SVGPatternElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGPatternElement_style_Getter";
-
- @DomName('SVGPatternElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGPatternElement_getPresentationAttribute_Callback";
-
@DomName('SVGPatternElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGPatternElement_requiredExtensions_Getter";
@@ -6335,9 +5960,10 @@
@DocsEditable
@DomName('SVGPolygonElement')
-class PolygonElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class PolygonElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
PolygonElement.internal() : super.internal();
+ @DomName('SVGPolygonElement.SVGPolygonElement')
@DocsEditable
factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
@@ -6393,18 +6019,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGPolygonElement_getTransformToElement_Callback";
- @DomName('SVGPolygonElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGPolygonElement_className_Getter";
-
- @DomName('SVGPolygonElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGPolygonElement_style_Getter";
-
- @DomName('SVGPolygonElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGPolygonElement_getPresentationAttribute_Callback";
-
@DomName('SVGPolygonElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGPolygonElement_requiredExtensions_Getter";
@@ -6435,9 +6049,10 @@
@DocsEditable
@DomName('SVGPolylineElement')
-class PolylineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class PolylineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
PolylineElement.internal() : super.internal();
+ @DomName('SVGPolylineElement.SVGPolylineElement')
@DocsEditable
factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
@@ -6493,18 +6108,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGPolylineElement_getTransformToElement_Callback";
- @DomName('SVGPolylineElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGPolylineElement_className_Getter";
-
- @DomName('SVGPolylineElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGPolylineElement_style_Getter";
-
- @DomName('SVGPolylineElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGPolylineElement_getPresentationAttribute_Callback";
-
@DomName('SVGPolylineElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGPolylineElement_requiredExtensions_Getter";
@@ -6595,6 +6198,7 @@
class RadialGradientElement extends GradientElement {
RadialGradientElement.internal() : super.internal();
+ @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
@DocsEditable
factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
@@ -6677,9 +6281,10 @@
@DocsEditable
@DomName('SVGRectElement')
-class RectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class RectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
RectElement.internal() : super.internal();
+ @DomName('SVGRectElement.SVGRectElement')
@DocsEditable
factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
@@ -6751,18 +6356,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGRectElement_getTransformToElement_Callback";
- @DomName('SVGRectElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGRectElement_className_Getter";
-
- @DomName('SVGRectElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGRectElement_style_Getter";
-
- @DomName('SVGRectElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGRectElement_getPresentationAttribute_Callback";
-
@DomName('SVGRectElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGRectElement_requiredExtensions_Getter";
@@ -6821,6 +6414,7 @@
class ScriptElement extends SvgElement implements UriReference, ExternalResourcesRequired {
ScriptElement.internal() : super.internal();
+ @DomName('SVGScriptElement.SVGScriptElement')
@DocsEditable
factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
@@ -6853,6 +6447,7 @@
class SetElement extends AnimationElement {
SetElement.internal() : super.internal();
+ @DomName('SVGSetElement.SVGSetElement')
@DocsEditable
factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
@@ -6866,9 +6461,10 @@
@DocsEditable
@DomName('SVGStopElement')
-class StopElement extends SvgElement implements Stylable {
+class StopElement extends StyledElement {
StopElement.internal() : super.internal();
+ @DomName('SVGStopElement.SVGStopElement')
@DocsEditable
factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
@@ -6876,18 +6472,6 @@
@DocsEditable
AnimatedNumber get offset native "SVGStopElement_offset_Getter";
- @DomName('SVGStopElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGStopElement_className_Getter";
-
- @DomName('SVGStopElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGStopElement_style_Getter";
-
- @DomName('SVGStopElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGStopElement_getPresentationAttribute_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
@@ -6935,7 +6519,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(String element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(String element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<String> where(bool f(String element)) =>
IterableMixinWorkaround.where(this, f);
@@ -6949,13 +6537,13 @@
bool get isEmpty => this.length == 0;
- List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<String> takeWhile(bool test(String value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<String> skipWhile(bool test(String value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -6998,8 +6586,9 @@
// clear() defined by IDL.
- List<String> get reversed =>
- new ReversedListView<String>(this, 0, null);
+ List<String> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(String a, String b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -7117,35 +6706,11 @@
@DocsEditable
-@DomName('SVGStylable')
-class Stylable extends NativeFieldWrapperClass1 {
- Stylable.internal();
-
- @DomName('SVGStylable.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGStylable_className_Getter";
-
- @DomName('SVGStylable.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGStylable_style_Getter";
-
- @DomName('SVGStylable.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGStylable_getPresentationAttribute_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.
-
-
-@DocsEditable
@DomName('SVGStyleElement')
class StyleElement extends SvgElement implements LangSpace {
StyleElement.internal() : super.internal();
+ @DomName('SVGStyleElement.SVGStyleElement')
@DocsEditable
factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
@@ -7206,6 +6771,31 @@
@DocsEditable
+@DomName('SVGStyledElement')
+class StyledElement extends SvgElement {
+ StyledElement.internal() : super.internal();
+
+ @DomName('SVGStyledElement.className')
+ @DocsEditable
+ AnimatedString get $dom_svgClassName native "SVGStyledElement_className_Getter";
+
+ @DomName('SVGStyledElement.style')
+ @DocsEditable
+ CssStyleDeclaration get style native "SVGStyledElement_style_Getter";
+
+ @DomName('SVGStyledElement.getPresentationAttribute')
+ @DocsEditable
+ CssValue getPresentationAttribute(String name) native "SVGStyledElement_getPresentationAttribute_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.
+
+
+@DocsEditable
@DomName('SVGDocument')
class SvgDocument extends Document {
SvgDocument.internal() : super.internal();
@@ -7400,7 +6990,7 @@
@DomName('SVGSVGElement')
-class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace {
+class SvgSvgElement extends StyledElement implements FitToViewBox, Transformable, Tests, ExternalResourcesRequired, ZoomAndPan, LangSpace {
factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
SvgSvgElement.internal() : super.internal();
@@ -7621,18 +7211,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGSVGElement_getTransformToElement_Callback";
- @DomName('SVGSVGElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGSVGElement_className_Getter";
-
- @DomName('SVGSVGElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGSVGElement_style_Getter";
-
- @DomName('SVGSVGElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGSVGElement_getPresentationAttribute_Callback";
-
@DomName('SVGSVGElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGSVGElement_requiredExtensions_Getter";
@@ -7649,6 +7227,10 @@
@DocsEditable
bool hasExtension(String extension) native "SVGSVGElement_hasExtension_Callback";
+ @DomName('SVGSVGElement.transform')
+ @DocsEditable
+ AnimatedTransformList get transform native "SVGSVGElement_transform_Getter";
+
@DomName('SVGSVGElement.zoomAndPan')
@DocsEditable
int get zoomAndPan native "SVGSVGElement_zoomAndPan_Getter";
@@ -7667,9 +7249,10 @@
@DocsEditable
@DomName('SVGSwitchElement')
-class SwitchElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class SwitchElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
SwitchElement.internal() : super.internal();
+ @DomName('SVGSwitchElement.SVGSwitchElement')
@DocsEditable
factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
@@ -7717,18 +7300,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGSwitchElement_getTransformToElement_Callback";
- @DomName('SVGSwitchElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGSwitchElement_className_Getter";
-
- @DomName('SVGSwitchElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGSwitchElement_style_Getter";
-
- @DomName('SVGSwitchElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGSwitchElement_getPresentationAttribute_Callback";
-
@DomName('SVGSwitchElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGSwitchElement_requiredExtensions_Getter";
@@ -7759,9 +7330,10 @@
@DocsEditable
@DomName('SVGSymbolElement')
-class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace {
+class SymbolElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace {
SymbolElement.internal() : super.internal();
+ @DomName('SVGSymbolElement.SVGSymbolElement')
@DocsEditable
factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
@@ -7793,18 +7365,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGSymbolElement_xmlspace_Setter";
- @DomName('SVGSymbolElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGSymbolElement_className_Getter";
-
- @DomName('SVGSymbolElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGSymbolElement_style_Getter";
-
- @DomName('SVGSymbolElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGSymbolElement_getPresentationAttribute_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
@@ -7818,6 +7378,7 @@
class TRefElement extends TextPositioningElement implements UriReference {
TRefElement.internal() : super.internal();
+ @DomName('SVGTRefElement.SVGTRefElement')
@DocsEditable
factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
@@ -7838,6 +7399,7 @@
class TSpanElement extends TextPositioningElement {
TSpanElement.internal() : super.internal();
+ @DomName('SVGTSpanElement.SVGTSpanElement')
@DocsEditable
factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
@@ -7880,7 +7442,7 @@
@DocsEditable
@DomName('SVGTextContentElement')
-class TextContentElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class TextContentElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace {
TextContentElement.internal() : super.internal();
static const int LENGTHADJUST_SPACING = 1;
@@ -7953,18 +7515,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGTextContentElement_xmlspace_Setter";
- @DomName('SVGTextContentElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGTextContentElement_className_Getter";
-
- @DomName('SVGTextContentElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGTextContentElement_style_Getter";
-
- @DomName('SVGTextContentElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGTextContentElement_getPresentationAttribute_Callback";
-
@DomName('SVGTextContentElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGTextContentElement_requiredExtensions_Getter";
@@ -7994,6 +7544,7 @@
class TextElement extends TextPositioningElement implements Transformable {
TextElement.internal() : super.internal();
+ @DomName('SVGTextElement.SVGTextElement')
@DocsEditable
factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
@@ -8109,9 +7660,10 @@
@DocsEditable
@DomName('SVGTitleElement')
-class TitleElement extends SvgElement implements Stylable, LangSpace {
+class TitleElement extends StyledElement implements LangSpace {
TitleElement.internal() : super.internal();
+ @DomName('SVGTitleElement.SVGTitleElement')
@DocsEditable
factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
@@ -8131,18 +7683,6 @@
@DocsEditable
void set xmlspace(String value) native "SVGTitleElement_xmlspace_Setter";
- @DomName('SVGTitleElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGTitleElement_className_Getter";
-
- @DomName('SVGTitleElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGTitleElement_style_Getter";
-
- @DomName('SVGTitleElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGTitleElement_getPresentationAttribute_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
@@ -8253,7 +7793,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(Transform element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(Transform element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(Transform element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<Transform> where(bool f(Transform element)) =>
IterableMixinWorkaround.where(this, f);
@@ -8267,13 +7811,13 @@
bool get isEmpty => this.length == 0;
- List<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<Transform> takeWhile(bool test(Transform value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<Transform> skipWhile(bool test(Transform value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -8316,8 +7860,9 @@
// clear() defined by IDL.
- List<Transform> get reversed =>
- new ReversedListView<Transform>(this, 0, null);
+ List<Transform> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Transform a, Transform b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
@@ -8521,9 +8066,10 @@
@DocsEditable
@DomName('SVGUseElement')
-class UseElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class UseElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
UseElement.internal() : super.internal();
+ @DomName('SVGUseElement.SVGUseElement')
@DocsEditable
factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
@@ -8595,18 +8141,6 @@
@DocsEditable
Matrix getTransformToElement(SvgElement element) native "SVGUseElement_getTransformToElement_Callback";
- @DomName('SVGUseElement.className')
- @DocsEditable
- AnimatedString get $dom_svgClassName native "SVGUseElement_className_Getter";
-
- @DomName('SVGUseElement.style')
- @DocsEditable
- CssStyleDeclaration get style native "SVGUseElement_style_Getter";
-
- @DomName('SVGUseElement.getPresentationAttribute')
- @DocsEditable
- CssValue getPresentationAttribute(String name) native "SVGUseElement_getPresentationAttribute_Callback";
-
@DomName('SVGUseElement.requiredExtensions')
@DocsEditable
StringList get requiredExtensions native "SVGUseElement_requiredExtensions_Getter";
@@ -8644,6 +8178,7 @@
class VKernElement extends SvgElement {
VKernElement.internal() : super.internal();
+ @DomName('SVGVKernElement.SVGVKernElement')
@DocsEditable
factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
@@ -8660,6 +8195,7 @@
class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan {
ViewElement.internal() : super.internal();
+ @DomName('SVGViewElement.SVGViewElement')
@DocsEditable
factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
@@ -8845,7 +8381,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f(ElementInstance element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f(ElementInstance element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f(ElementInstance element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<ElementInstance> where(bool f(ElementInstance element)) =>
IterableMixinWorkaround.where(this, f);
@@ -8859,13 +8399,13 @@
bool get isEmpty => this.length == 0;
- List<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<ElementInstance> takeWhile(bool test(ElementInstance value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<ElementInstance> skipWhile(bool test(ElementInstance value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -8910,8 +8450,9 @@
throw new UnsupportedError("Cannot clear immutable List.");
}
- List<ElementInstance> get reversed =>
- new ReversedListView<ElementInstance>(this, 0, null);
+ List<ElementInstance> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(ElementInstance a, ElementInstance b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
diff --git a/sdk/lib/utf/utf16.dart b/sdk/lib/utf/utf16.dart
index 4fbb80f..c451b1e 100644
--- a/sdk/lib/utf/utf16.dart
+++ b/sdk/lib/utf/utf16.dart
@@ -206,7 +206,7 @@
* to produce the code unit (0-(2^16)-1). Relies on BOM to determine
* endian-ness, and defaults to BE.
*/
-class Utf16BytesToCodeUnitsDecoder implements _ListRangeIterator {
+abstract class Utf16BytesToCodeUnitsDecoder implements _ListRangeIterator {
final _ListRangeIterator utf16EncodedBytesIterator;
final int replacementCodepoint;
int _current = null;
diff --git a/sdk/lib/utf/utf32.dart b/sdk/lib/utf/utf32.dart
index b9d9e98..acf6ac3 100644
--- a/sdk/lib/utf/utf32.dart
+++ b/sdk/lib/utf/utf32.dart
@@ -195,7 +195,7 @@
/**
* Abstrace parent class converts encoded bytes to codepoints.
*/
-class Utf32BytesDecoder implements _ListRangeIterator {
+abstract class Utf32BytesDecoder implements _ListRangeIterator {
final _ListRangeIterator utf32EncodedBytesIterator;
final int replacementCodepoint;
int _current = null;
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 5d466fd..5042795 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -1,8 +1,7 @@
-library web_audio;
+library dart.dom.web_audio;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_foreign_helper' show JS;
@@ -182,9 +181,6 @@
static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
@DocsEditable
- factory AudioContext() => AudioContext._create();
-
- @DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@deprecated
AudioContextEvents get on =>
@@ -286,7 +282,7 @@
@DocsEditable
Stream<Event> get onComplete => completeEvent.forTarget(this);
- static AudioContext _create() => JS('AudioContext',
+ factory AudioContext() => JS('AudioContext',
'new (window.AudioContext || window.webkitAudioContext)()');
GainNode createGain() {
@@ -690,9 +686,12 @@
@DomName('OfflineAudioContext')
class OfflineAudioContext extends AudioContext implements EventTarget native "*OfflineAudioContext" {
+ @DomName('OfflineAudioContext.OfflineAudioContext')
@DocsEditable
- factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) => OfflineAudioContext._create(numberOfChannels, numberOfFrames, sampleRate);
- static OfflineAudioContext _create(int numberOfChannels, int numberOfFrames, num sampleRate) => JS('OfflineAudioContext', 'new OfflineAudioContext(#,#,#)', numberOfChannels, numberOfFrames, sampleRate);
+ factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) {
+ return OfflineAudioContext._create_1(numberOfChannels, numberOfFrames, sampleRate);
+ }
+ static OfflineAudioContext _create_1(numberOfChannels, numberOfFrames, sampleRate) => JS('OfflineAudioContext', 'new OfflineAudioContext(#,#,#)', numberOfChannels, numberOfFrames, sampleRate);
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 44782ea..ec52898 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -1,8 +1,7 @@
-library web_audio;
+library dart.dom.web_audio;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
@@ -231,10 +230,10 @@
@DomName('AudioContext.complete')
@DocsEditable
static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
+ factory AudioContext() => _create();
@DocsEditable
- factory AudioContext() => AudioContext._create();
- static AudioContext _create() native "AudioContext_constructor_Callback";
+ static AudioContext _create() native "AudioContext_constructorCallback";
@DocsEditable
@DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -904,9 +903,14 @@
class OfflineAudioContext extends AudioContext implements EventTarget {
OfflineAudioContext.internal() : super.internal();
+ @DomName('OfflineAudioContext.OfflineAudioContext')
@DocsEditable
- factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) => OfflineAudioContext._create(numberOfChannels, numberOfFrames, sampleRate);
- static OfflineAudioContext _create(int numberOfChannels, int numberOfFrames, num sampleRate) native "OfflineAudioContext_constructor_Callback";
+ factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) {
+ return OfflineAudioContext._create_1(numberOfChannels, numberOfFrames, sampleRate);
+ }
+
+ @DocsEditable
+ static OfflineAudioContext _create_1(numberOfChannels, numberOfFrames, sampleRate) native "OfflineAudioContext__create_1constructorCallback";
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 3884bbd..aba9917 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -180,7 +180,7 @@
[ $compiler == dart2js && $runtime == jsshell ]
-LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
+LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
Language/05_Variables/05_Variables_A13_t02: Fail # TODO(ngeoaffray): Please triage these failure.
Language/06_Functions/3_Type_of_a_Function_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t02: Fail # TODO(ngeoaffray): Please triage these failure.
@@ -229,7 +229,6 @@
Language/13_Libraries_and_Scripts/1_Imports_A03_t26: 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.
Language/14_Types/8_Parameterized_Types_A02_t01: Fail # TODO(ahe): Please triage this failure.
LibTest/core/AssertionError/column_A01_t02: Fail # TODO(ahe): Please triage this failure.
LibTest/core/AssertionError/failedAssertion_A01_t01: Fail # TODO(ahe): Please triage this failure.
@@ -784,10 +783,8 @@
Language/14_Types/5_Function_Types_A01_t09: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A01_t11: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A02_t05: Fail # dartbug.com/7342
-Language/14_Types/5_Function_Types_A02_t07: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A02_t09: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A02_t10: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A03_t06: Fail # dartbug.com/7342
-Language/14_Types/5_Function_Types_A03_t08: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A03_t10: Fail # dartbug.com/7342
Language/14_Types/5_Function_Types_A03_t11: Fail # dartbug.com/7342
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 0162524..9e1d365 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -45,6 +45,7 @@
var handler = new CollectingDiagnosticHandler(provider);
var compiler = new Compiler(
provider.readStringFromUri,
+ null,
handler.diagnosticHandler,
libraryRoot, libraryRoot,
<String>['--analyze-only', '--analyze-all',
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index ae90593..2e8e529 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -1023,6 +1023,17 @@
result.checkNodeHasUnknownType('x');
}
+testIsCheck() {
+ final String source = r"""
+ main () {
+ var x = (1 is String);
+ x;
+ }
+ """;
+ AnalysisResult result = analyze(source);
+ result.checkNodeHasType('x', [result.bool]);
+}
+
void main() {
testDynamicBackDoor();
testLiterals();
@@ -1063,4 +1074,5 @@
testLists();
testListWithCapacity();
testEmptyList();
+ testIsCheck();
}
diff --git a/tests/compiler/dart2js/emit_const_fields_test.dart b/tests/compiler/dart2js/emit_const_fields_test.dart
new file mode 100644
index 0000000..290c50a
--- /dev/null
+++ b/tests/compiler/dart2js/emit_const_fields_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test that unused static consts are not emitted.
+
+import 'compiler_helper.dart';
+
+const String TEST_GUIDE = r"""
+class Guide {
+ static const LTUAE = 42;
+ static const TITLE = 'Life, the Universe and Everything';
+}
+
+main() {
+ return "${Guide.LTUAE}, ${Guide.TITLE}";
+}
+""";
+
+main() {
+ String generated = compileAll(TEST_GUIDE);
+ Expect.isTrue(generated.contains("42"));
+ Expect.isFalse(generated.contains("TITLE"));
+}
+
diff --git a/tests/compiler/dart2js/erroneous_element_test.dart b/tests/compiler/dart2js/erroneous_element_test.dart
index d0a85a9..97078356 100644
--- a/tests/compiler/dart2js/erroneous_element_test.dart
+++ b/tests/compiler/dart2js/erroneous_element_test.dart
@@ -12,7 +12,8 @@
show MessageKind;
void main() {
- ErroneousElement e = new ErroneousElementX(MessageKind.GENERIC, ['error'],
+ ErroneousElement e = new ErroneousElementX(MessageKind.GENERIC,
+ {'text': 'error'},
buildSourceString('foo'), null);
Expect.stringEquals('<foo: error>', '$e');
}
diff --git a/tests/compiler/dart2js/interceptor_test.dart b/tests/compiler/dart2js/interceptor_test.dart
index 29a8a0d..c7be7c5 100644
--- a/tests/compiler/dart2js/interceptor_test.dart
+++ b/tests/compiler/dart2js/interceptor_test.dart
@@ -14,9 +14,23 @@
}
""";
+const String TEST_TWO = r"""
+ foo(a) {
+ var myVariableName = a + 42;
+ print(myVariableName);
+ print(myVariableName);
+ }
+""";
+
main() {
var generated = compile(TEST_ONE, entry: 'foo');
// Check that the one shot interceptor got converted to a direct
// call to the interceptor object.
Expect.isTrue(generated.contains('CONSTANT.get\$toString(a + 42);'));
+
+ // Check that one-shot interceptors preserve variable names, see
+ // https://code.google.com/p/dart/issues/detail?id=8106.
+ generated = compile(TEST_TWO, entry: 'foo');
+ Expect.isTrue(generated.contains('\$.\$\$add(a, 42)'));
+ Expect.isTrue(generated.contains('myVariableName'));
}
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index cd1bd89..b12336e 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -23,6 +23,8 @@
import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
hide TreeElementMapping;
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+
class WarningMessage {
Node node;
Message message;
diff --git a/tests/compiler/dart2js/part_of_test.dart b/tests/compiler/dart2js/part_of_test.dart
index 54c0bc9..d80b8dc 100644
--- a/tests/compiler/dart2js/part_of_test.dart
+++ b/tests/compiler/dart2js/part_of_test.dart
@@ -32,6 +32,6 @@
Expect.equals(1, compiler.warnings.length);
Expect.equals(MessageKind.LIBRARY_NAME_MISMATCH,
compiler.warnings[0].message.kind);
- Expect.equals("${MessageKind.LIBRARY_NAME_MISMATCH.error(['foo'])}",
- compiler.warnings[0].message.toString());
+ Expect.equals('foo',
+ compiler.warnings[0].message.arguments['libraryName'].toString());
}
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 720c85d..883ca27 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -40,46 +40,46 @@
Element ensure(compiler,
String name,
Element lookup(name),
- {bool isPatched: false,
- bool isPatch: false,
- bool isMethod: true,
- bool isGetter: false,
- bool isFound: true}) {
+ {bool expectIsPatched: false,
+ bool expectIsPatch: false,
+ bool checkHasBody: false,
+ bool expectIsGetter: false,
+ bool expectIsFound: true}) {
var element = lookup(buildSourceString(name));
- if (!isFound) {
+ if (!expectIsFound) {
Expect.isNull(element);
return element;
}
Expect.isNotNull(element);
- if (isGetter) {
+ if (expectIsGetter) {
Expect.isTrue(element is AbstractFieldElement);
Expect.isNotNull(element.getter);
element = element.getter;
}
- Expect.equals(isPatched, element.isPatched);
- if (isPatched) {
+ Expect.equals(expectIsPatched, element.isPatched);
+ if (expectIsPatched) {
Expect.isNull(element.origin);
Expect.isNotNull(element.patch);
Expect.equals(element, element.declaration);
Expect.equals(element.patch, element.implementation);
- if (isMethod) {
+ if (checkHasBody) {
expectHasNoBody(compiler, element);
expectHasBody(compiler, element.patch);
}
} else {
Expect.isTrue(element.isImplementation);
}
- Expect.equals(isPatch, element.isPatch);
- if (isPatch) {
+ Expect.equals(expectIsPatch, element.isPatch);
+ if (expectIsPatch) {
Expect.isNotNull(element.origin);
Expect.isNull(element.patch);
Expect.equals(element.origin, element.declaration);
Expect.equals(element, element.implementation);
- if (isMethod) {
+ if (checkHasBody) {
expectHasBody(compiler, element);
expectHasNoBody(compiler, element.origin);
}
@@ -93,7 +93,7 @@
Expect.equals(element, element.declaration);
Expect.equals(element, element.implementation);
- if (isMethod) {
+ if (checkHasBody) {
expectHasBody(compiler, element);
}
}
@@ -105,8 +105,10 @@
var compiler = applyPatch(
"external test();",
"patch test() { return 'string'; } ");
- ensure(compiler, "test", compiler.coreLibrary.find, isPatched: true);
- ensure(compiler, "test", compiler.coreLibrary.patch.find, isPatch: true);
+ ensure(compiler, "test", compiler.coreLibrary.find,
+ expectIsPatched: true, checkHasBody: true);
+ ensure(compiler, "test", compiler.coreLibrary.patch.find,
+ expectIsPatch: true, checkHasBody: true);
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
@@ -127,15 +129,15 @@
}
""");
var container = ensure(compiler, "Class", compiler.coreLibrary.find,
- isMethod: false, isPatched: true);
+ expectIsPatched: true);
container.parseNode(compiler);
ensure(compiler, "Class", compiler.coreLibrary.patch.find,
- isMethod: false, isPatch: true);
+ expectIsPatch: true);
ensure(compiler, "toString", container.lookupLocalMember,
- isPatched: true);
+ expectIsPatched: true, checkHasBody: true);
ensure(compiler, "toString", container.patch.lookupLocalMember,
- isPatch: true);
+ expectIsPatch: true, checkHasBody: true);
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
@@ -156,18 +158,20 @@
}
""");
var container = ensure(compiler, "Class", compiler.coreLibrary.find,
- isPatched: true, isMethod: false);
+ expectIsPatched: true);
container.parseNode(compiler);
ensure(compiler,
"field",
container.lookupLocalMember,
- isGetter: true,
- isPatched: true);
+ expectIsGetter: true,
+ expectIsPatched: true,
+ checkHasBody: true);
ensure(compiler,
"field",
container.patch.lookupLocalMember,
- isGetter: true,
- isPatch: true);
+ expectIsGetter: true,
+ expectIsPatch: true,
+ checkHasBody: true);
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
@@ -187,13 +191,15 @@
}
""");
var container = ensure(compiler, "Class", compiler.coreLibrary.find,
- isMethod: false, isPatched: true);
+ expectIsPatched: true);
container.parseNode(compiler);
ensure(compiler, "Class", compiler.coreLibrary.patch.find,
- isMethod: false, isPatch: true);
+ expectIsPatch: true);
- ensure(compiler, "regular", container.lookupLocalMember);
- ensure(compiler, "regular", container.patch.lookupLocalMember);
+ ensure(compiler, "regular", container.lookupLocalMember,
+ checkHasBody: true);
+ ensure(compiler, "regular", container.patch.lookupLocalMember,
+ checkHasBody: true);
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
@@ -213,13 +219,15 @@
}
""");
var container = ensure(compiler, "Class", compiler.coreLibrary.find,
- isMethod: false, isPatched: true);
+ expectIsPatched: true);
container.parseNode(compiler);
ensure(compiler, "Class", compiler.coreLibrary.patch.find,
- isMethod: false, isPatch: true);
+ expectIsPatch: true);
- ensure(compiler, "ghost", container.lookupLocalMember, isFound: false);
- ensure(compiler, "ghost", container.patch.lookupLocalMember);
+ ensure(compiler, "ghost", container.lookupLocalMember,
+ expectIsFound: false);
+ ensure(compiler, "ghost", container.patch.lookupLocalMember,
+ checkHasBody: true);
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
@@ -234,10 +242,11 @@
ensure(compiler,
"_function",
compiler.coreLibrary.find,
- isFound: false);
+ expectIsFound: false);
ensure(compiler,
"_function",
- compiler.coreLibrary.patch.find);
+ compiler.coreLibrary.patch.find,
+ checkHasBody: true);
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
@@ -272,13 +281,13 @@
}
""");
var container = ensure(compiler, "Class", compiler.coreLibrary.find,
- isMethod: false, isPatched: true);
+ expectIsPatched: true);
container.ensureResolved(compiler);
container.parseNode(compiler);
compiler.resolver.resolveMethodElement(
ensure(compiler, "method1", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -288,7 +297,7 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method2", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -298,7 +307,7 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method3", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -308,7 +317,7 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method4", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -318,7 +327,7 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method5", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -328,7 +337,7 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method6", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -338,7 +347,7 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method7", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
@@ -348,13 +357,65 @@
compiler.errors.clear();
compiler.resolver.resolveMethodElement(
ensure(compiler, "method8", container.lookupLocalMember,
- isPatched: true));
+ expectIsPatched: true, checkHasBody: true));
Expect.isTrue(compiler.warnings.isEmpty,
"Unexpected warnings: ${compiler.warnings}");
Expect.isFalse(compiler.errors.isEmpty);
print('method8:${compiler.errors}');
}
+testExternalWithoutImplementationTopLevel() {
+ var compiler = applyPatch(
+ """
+ external void foo();
+ """,
+ """
+ // patch void foo() {}
+ """);
+ var function = ensure(compiler, "foo", compiler.coreLibrary.find);
+ compiler.resolver.resolve(function);
+ Expect.isTrue(compiler.warnings.isEmpty,
+ "Unexpected warnings: ${compiler.warnings}");
+ print('testExternalWithoutImplementationTopLevel:${compiler.errors}');
+ Expect.equals(1, compiler.errors.length);
+ Expect.isTrue(
+ compiler.errors[0].message.kind ==
+ MessageKind.EXTERNAL_WITHOUT_IMPLEMENTATION);
+ Expect.equals('External method without an implementation.',
+ compiler.errors[0].message.toString());
+}
+
+testExternalWithoutImplementationMember() {
+ var compiler = applyPatch(
+ """
+ class Class {
+ external void foo();
+ }
+ """,
+ """
+ patch class Class {
+ // patch void foo() {}
+ }
+ """);
+ var container = ensure(compiler, "Class", compiler.coreLibrary.find,
+ expectIsPatched: true);
+ container.parseNode(compiler);
+
+ compiler.warnings.clear();
+ compiler.errors.clear();
+ compiler.resolver.resolveMethodElement(
+ ensure(compiler, "foo", container.lookupLocalMember));
+ Expect.isTrue(compiler.warnings.isEmpty,
+ "Unexpected warnings: ${compiler.warnings}");
+ print('testExternalWithoutImplementationMember:${compiler.errors}');
+ Expect.equals(1, compiler.errors.length);
+ Expect.isTrue(
+ compiler.errors[0].message.kind ==
+ MessageKind.EXTERNAL_WITHOUT_IMPLEMENTATION);
+ Expect.equals('External method without an implementation.',
+ compiler.errors[0].message.toString());
+}
+
main() {
testPatchFunction();
testPatchMember();
@@ -363,4 +424,7 @@
testGhostMember();
testInjectFunction();
testPatchSignatureCheck();
+
+ testExternalWithoutImplementationTopLevel();
+ testExternalWithoutImplementationMember();
}
diff --git a/tests/compiler/dart2js/pretty_parameter_test.dart b/tests/compiler/dart2js/pretty_parameter_test.dart
index 82309e6..28c8d1f 100644
--- a/tests/compiler/dart2js/pretty_parameter_test.dart
+++ b/tests/compiler/dart2js/pretty_parameter_test.dart
@@ -72,7 +72,7 @@
Expect.isTrue(generated.contains(r"function(a, b) {"));
generated = compile(BAR, entry: 'bar');
- Expect.isTrue(generated.contains(r"function(eval, $$eval) {"));
+ Expect.isTrue(generated.contains(r"function($eval, $$eval) {"));
generated = compile(PARAMETER_AND_TEMP, entry: 'bar');
Expect.isTrue(generated.contains(r"print(t00)"));
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index fbe3db2..a2e3742 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -15,6 +15,7 @@
import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart"
hide TreeElementMapping, TreeElements, SourceString;
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
Node buildIdentifier(String name) => new Identifier(scan(name));
@@ -219,7 +220,7 @@
MockCompiler compiler = testLocals([["foo", false], ["foo", false]]);
Expect.equals(1, compiler.errors.length);
Expect.equals(
- new Message(MessageKind.DUPLICATE_DEFINITION, ['foo']),
+ new Message(MessageKind.DUPLICATE_DEFINITION, {'name': 'foo'}),
compiler.errors[0].message);
}
@@ -401,7 +402,7 @@
Node warningNode = compiler.warnings[0].node;
Expect.equals(
- new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Foo']),
+ new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'Foo'}),
compiler.warnings[0].message);
VariableDefinitions definition = compiler.parsedTree;
Expect.equals(warningNode, definition.type);
@@ -427,7 +428,8 @@
// ClassResolverVisitor, and once from ClassSupertypeResolver. We
// should only the get the error once.
Expect.equals(2, compiler.errors.length);
- var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Bar']);
+ var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE,
+ {'typeName': 'Bar'});
Expect.equals(cannotResolveBar, compiler.errors[0].message);
Expect.equals(cannotResolveBar, compiler.errors[1].message);
compiler.clearErrors();
@@ -452,7 +454,7 @@
compiler.resolveStatement("Foo bar;");
Expect.equals(1, compiler.errors.length);
Expect.equals(
- new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['var']),
+ new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'var'}),
compiler.errors[0].message);
compiler.clearErrors();
}
@@ -463,7 +465,7 @@
compiler.resolveStatement("Foo bar;");
Expect.equals(1, compiler.errors.length);
Expect.equals(
- new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['bar']),
+ new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'bar'}),
compiler.errors[0].message);
compiler.clearErrors();
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 85dcbd8..e51a50f 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -14,6 +14,8 @@
import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
hide SourceString;
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+
DartType intType;
DartType boolType;
DartType stringType;
@@ -35,7 +37,9 @@
testConditionalExpression,
testIfStatement,
testThis,
- testFunctionSubtyping];
+ testFunctionSubtyping,
+ testFunctionSubtypingOptional,
+ testFunctionSubtypingNamed];
for (Function test in tests) {
setup();
test();
@@ -360,8 +364,12 @@
bool isSubtype(List<DartType> in1, DartType out1, List<DartType> in2,
DartType out2) {
return compiler.types.isSubtype(
- new FunctionType(out1, new Link<DartType>.fromList(in1), null),
- new FunctionType(out2, new Link<DartType>.fromList(in2), null));
+ new FunctionType(null, out1, new Link<DartType>.fromList(in1),
+ const Link<DartType>(),
+ const Link<SourceString>(), const Link<DartType>()),
+ new FunctionType(null, out2, new Link<DartType>.fromList(in2),
+ const Link<DartType>(),
+ const Link<SourceString>(), const Link<DartType>()));
}
Expect.isTrue(isSubtype([], intType, [], intType));
Expect.isTrue(isSubtype([], intType, [], objectType));
@@ -373,6 +381,129 @@
Expect.isFalse(isSubtype([intType, intType], intType, [intType], intType));
}
+testFunctionSubtypingOptional() {
+ // Checks whether the type (in1,[opt1] -> void) is a subtype of
+ // (in2,[opt2] -> void).
+ expect(bool value, List<DartType> in1, List<DartType> opt1,
+ List<DartType> in2, List<DartType> opt2) {
+ var fn1 = new FunctionType(null,
+ compiler.types.dynamicType,
+ new Link<DartType>.fromList(in1),
+ new Link<DartType>.fromList(opt1),
+ const Link<SourceString>(), const Link<DartType>());
+ var fn2 = new FunctionType(null,
+ compiler.types.dynamicType,
+ new Link<DartType>.fromList(in2),
+ new Link<DartType>.fromList(opt2),
+ const Link<SourceString>(), const Link<DartType>());
+ Expect.equals(value, compiler.types.isSubtype(fn1, fn2), "$fn1 <: $fn2");
+ }
+
+ // Test ()->void <: ()->void.
+ expect(true, [], [], [], []);
+ // Test ([int])->void <: ()->void.
+ expect(true, [], [intType], [], []);
+ // Test ([int])->void <: (int)->void.
+ expect(false, [], [intType], [intType], []);
+ // Test (int)->void <: ([int])->void.
+ expect(false, [intType], [], [], [intType]);
+ // Test ([int])->void <: ([int])->void.
+ expect(true, [], [intType], [], [intType]);
+ // Test ([Object])->void <: ([int])->void.
+ expect(true, [], [objectType], [], [intType]);
+ // Test ([int])->void <: ([Object])->void.
+ expect(true, [], [intType], [], [objectType]);
+ // Test (int,[int])->void <: (int,[int])->void.
+ expect(true, [intType], [intType], [intType], [intType]);
+ // Test ([int])->void <: ([double])->void.
+ expect(false, [], [intType], [], [doubleType]);
+ // Test ([int])->void <: ([int,int])->void.
+ expect(false, [], [intType], [], [intType, intType]);
+ // Test ([int,int])->void <: ([int])->void.
+ expect(true, [], [intType, intType], [], [intType]);
+ // Test ([Object,int])->void <: ([int])->void.
+ expect(true, [], [objectType, intType], [], [intType]);
+}
+
+
+testFunctionSubtypingNamed() {
+ // Checks whether the type (in1,{nm1} -> out1) is a subtype of
+ // (in2,{nm2} -> out2).
+ expect(bool value, List<DartType> in1, Map<String,DartType> nm1,
+ List<DartType> in2, Map<String,DartType> nm2) {
+
+ SourceString convertString(String string) => new SourceString(string);
+ int compareString(a, b) => a.compareTo(b);
+
+ Link<SourceString> createNames(Map<String,DartType> nm) {
+ List<String> nmSorted = new List<String>.from(nm.keys)..sort();
+ List<SourceString> nmSourceStrings =
+ nmSorted.map((string) => new SourceString(string)).toList();
+ return new Link<SourceString>.fromList(nmSourceStrings);
+ }
+
+ Link<DartType> createTypes(Map<String,DartType> nm,
+ Link<SourceString> names) {
+ var types = new LinkBuilder<DartType>();
+ for (SourceString name in names) {
+ types.addLast(nm[name.slowToString()]);
+ }
+ return types.toLink();
+ }
+
+ Link<SourceString> names1 = createNames(nm1);
+ Link<DartType> types1 = createTypes(nm1, names1);
+ Link<SourceString> names2 = createNames(nm2);
+ Link<DartType> types2 = createTypes(nm2, names2);
+ var fn1 = new FunctionType(null,
+ compiler.types.dynamicType,
+ new Link<DartType>.fromList(in1),
+ const Link<DartType>(),
+ names1, types1);
+ var fn2 = new FunctionType(null,
+ compiler.types.dynamicType,
+ new Link<DartType>.fromList(in2),
+ const Link<DartType>(),
+ names2, types2);
+ Expect.equals(value, compiler.types.isSubtype(fn1, fn2), "$fn1 <: $fn2");
+ }
+
+ // Test ()->void <: ()->void.
+ expect(true, [], {}, [], {});
+ // Test ({int a})->void <: ()->void.
+ expect(true, [], {'a': intType}, [], {});
+ // Test ({int a})->void <: (int)->void.
+ expect(false, [], {'a': intType}, [intType], {});
+ // Test (int)->void <: ({int a})->void.
+ expect(false, [intType], {}, [], {'a': intType});
+ // Test ({int a})->void <: ({int a})->void.
+ expect(true, [], {'a': intType}, [], {'a': intType});
+ // Test ({int a})->void <: ({int b})->void.
+ expect(false, [], {'a': intType}, [], {'b': intType});
+ // Test ({Object a})->void <: ({int a})->void.
+ expect(true, [], {'a': objectType}, [], {'a': intType});
+ // Test ({int a})->void <: ([Object])->void.
+ expect(true, [], {'a': intType}, [], {'a': objectType});
+ // Test (int,{int a})->void <: (int,{int a})->void.
+ expect(true, [intType], {'a': intType}, [intType], {'a': intType});
+ // Test ({int a})->void <: ({double a})->void.
+ expect(false, [], {'a': intType}, [], {'a': doubleType});
+ // Test ({int a})->void <: ({int a,int b})->void.
+ expect(false, [], {'a': intType}, [], {'a': intType, 'b': intType});
+ // Test ({int a,int b})->void <: ({int a})->void.
+ expect(true, [], {'a': intType, 'b': intType}, [], {'a': intType});
+ // Test ({int a,int b,int c})->void <: ({int a,int c})->void.
+ expect(true, [], {'a': intType, 'b': intType, 'c': intType},
+ [], {'a': intType, 'c': intType});
+ // Test ({int a,int b,int c})->void <: ({int b,int c})->void.
+ expect(true, [], {'a': intType, 'b': intType, 'c': intType},
+ [], {'b': intType, 'c': intType});
+ // Test ({int a,int b,int c})->void <: ({int c})->void.
+ expect(true, [], {'a': intType, 'b': intType, 'c': intType},
+ [], {'c': intType});
+}
+
+
const CLASS_WITH_METHODS = '''
class ClassWithMethods {
untypedNoArgumentMethod() {}
diff --git a/tests/compiler/dart2js/type_equals_test.dart b/tests/compiler/dart2js/type_equals_test.dart
index 3c621a0..57d468b 100644
--- a/tests/compiler/dart2js/type_equals_test.dart
+++ b/tests/compiler/dart2js/type_equals_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
diff --git a/tests/compiler/dart2js/type_substitution_test.dart b/tests/compiler/dart2js/type_substitution_test.dart
index fb32d7e..0c4ee89 100644
--- a/tests/compiler/dart2js/type_substitution_test.dart
+++ b/tests/compiler/dart2js/type_substitution_test.dart
@@ -5,6 +5,7 @@
library type_substitution_test;
import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
@@ -237,4 +238,21 @@
testSubstitution(compiler, arguments, parameters, "Typedef1c", "Typedef2c");
testSubstitution(compiler, arguments, parameters, "Typedef1d", "Typedef2d");
testSubstitution(compiler, arguments, parameters, "Typedef1e", "Typedef2e");
+
+ // Substitution in unalias.
+ DartType Typedef2_int_String = getType(compiler, "Typedef2a");
+ Expect.isNotNull(Typedef2_int_String);
+ DartType Function_int_String = getType(compiler, "Function2b");
+ Expect.isNotNull(Function_int_String);
+ DartType unalias1 = Typedef2_int_String.unalias(compiler);
+ Expect.equals(Function_int_String, unalias1,
+ '$Typedef2_int_String.unalias=$unalias1 != $Function_int_String');
+
+ DartType Typedef1 = getType(compiler, "Typedef1c");
+ Expect.isNotNull(Typedef1);
+ DartType Function_dynamic_dynamic = getType(compiler, "Function1c");
+ Expect.isNotNull(Function_dynamic_dynamic);
+ DartType unalias2 = Typedef1.unalias(compiler);
+ Expect.equals(Function_dynamic_dynamic, unalias2,
+ '$Typedef1.unalias=$unalias2 != $Function_dynamic_dynamic');
}
diff --git a/tests/compiler/dart2js_native/foreign_test.dart b/tests/compiler/dart2js_native/foreign_test.dart
index b9feea9..f7fd7c6d 100644
--- a/tests/compiler/dart2js_native/foreign_test.dart
+++ b/tests/compiler/dart2js_native/foreign_test.dart
@@ -30,4 +30,10 @@
Expect.equals(998, foreign2());
Expect.equals('1234567891011',
foreign11('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'));
+ // Ensure there will be isNaN and NaN variable names.
+ var isNaN = called ? 42 : 44;
+ var NaN = called ? 52 : 54;
+ Expect.isFalse(JS('bool', 'isNaN(#)', isNaN));
+ Expect.isFalse(JS('bool', 'isNaN(#)', NaN));
+ Expect.isTrue(JS('bool', 'isNaN(#)', double.NAN));
}
diff --git a/tests/compiler/dart2js_native/native_field_name_test.dart b/tests/compiler/dart2js_native/native_field_name_test.dart
index c1bb426..5d1e7bc 100644
--- a/tests/compiler/dart2js_native/native_field_name_test.dart
+++ b/tests/compiler/dart2js_native/native_field_name_test.dart
@@ -23,7 +23,7 @@
function setter(x) {
this.getValue += 10;
}
-
+
function A(){
var a = Object.create(
{ constructor: { name: 'A'}},
diff --git a/tests/compiler/dart2js_native/native_mixin_field_test.dart b/tests/compiler/dart2js_native/native_mixin_field_test.dart
new file mode 100644
index 0000000..4cf361e
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_mixin_field_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that native classes can use ordinary Dart classes with fields
+// as mixins.
+
+class A native "*A" {
+ var foo;
+}
+
+class B extends A with M1, M2 native "*B" {
+ var bar;
+}
+
+class M1 {
+ var baz;
+}
+
+class M2 {
+ var bar;
+ var buz;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() native """
+function A() {this.foo='A-foo';}
+function B() {A.call(this);this.bar='B-bar';this.baz='M1-baz';}
+makeA = function(){return new A;};
+makeB = function(){return new B;};
+""";
+
+main() {
+ setup();
+ A a = makeA();
+ Expect.equals("A-foo", a.foo);
+ Expect.throws(() => a.bar, (e) => e is NoSuchMethodError);
+ Expect.throws(() => a.baz, (e) => e is NoSuchMethodError);
+ Expect.throws(() => a.buz, (e) => e is NoSuchMethodError);
+
+ B b = makeB();
+ Expect.equals("A-foo", b.foo);
+ Expect.equals("B-bar", b.bar);
+ Expect.equals("M1-baz", b.baz);
+ Expect.isNull(b.buz);
+
+ M1 m1 = new M1();
+ Expect.throws(() => m1.foo, (e) => e is NoSuchMethodError);
+ Expect.throws(() => m1.bar, (e) => e is NoSuchMethodError);
+ Expect.isNull(m1.baz);
+ Expect.throws(() => m1.buz, (e) => e is NoSuchMethodError);
+
+ M2 m2 = new M2();
+ Expect.throws(() => m2.foo, (e) => e is NoSuchMethodError);
+ Expect.isNull(m2.bar);
+ Expect.throws(() => m2.baz, (e) => e is NoSuchMethodError);
+ Expect.isNull(m2.buz);
+}
diff --git a/tests/compiler/dart2js_native/native_mixin_multiple_test.dart b/tests/compiler/dart2js_native/native_mixin_multiple_test.dart
new file mode 100644
index 0000000..bd917cb
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_mixin_multiple_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that native classes can use ordinary Dart classes as mixins.
+
+class A native "*A" {
+ foo() => "A-foo";
+ baz() => "A-baz";
+}
+
+class B extends A with M1, M2 native "*B" {
+ bar() => baz();
+}
+
+class M1 {
+ foo() => "M1-foo";
+ baz() => "M1-baz";
+}
+
+class M2 {
+ foo() => "M2-foo";
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() native """
+function A() {}
+function B() {}
+makeA = function(){return new A;};
+makeB = function(){return new B;};
+""";
+
+main() {
+ setup();
+ A a = makeA();
+ Expect.equals("A-foo", a.foo());
+ Expect.throws(() => a.bar(), (error) => error is NoSuchMethodError);
+ Expect.equals("A-baz", a.baz());
+ Expect.isTrue(a is A);
+ Expect.isFalse(a is B);
+ Expect.isFalse(a is M1);
+ Expect.isFalse(a is M2);
+
+ B b = makeB();
+ Expect.equals("M2-foo", b.foo());
+ Expect.equals("M1-baz", b.bar());
+ Expect.equals("M1-baz", b.baz());
+ Expect.isTrue(b is A);
+ Expect.isTrue(b is B);
+ Expect.isTrue(b is M1);
+ Expect.isTrue(b is M2);
+
+ M1 m1 = new M1();
+ Expect.equals("M1-foo", m1.foo());
+ Expect.throws(() => m1.bar(), (error) => error is NoSuchMethodError);
+ Expect.equals("M1-baz", m1.baz());
+ Expect.isFalse(m1 is A);
+ Expect.isFalse(m1 is B);
+ Expect.isTrue(m1 is M1);
+ Expect.isFalse(m1 is M2);
+
+ M2 m2 = new M2();
+ Expect.equals("M2-foo", m2.foo());
+ Expect.throws(() => m2.bar(), (error) => error is NoSuchMethodError);
+ Expect.throws(() => m2.baz(), (error) => error is NoSuchMethodError);
+ Expect.isFalse(m2 is A);
+ Expect.isFalse(m2 is B);
+ Expect.isFalse(m2 is M1);
+ Expect.isTrue(m2 is M2);
+}
diff --git a/tests/compiler/dart2js_native/native_mixin_test.dart b/tests/compiler/dart2js_native/native_mixin_test.dart
index 197a085..7dfdd5d 100644
--- a/tests/compiler/dart2js_native/native_mixin_test.dart
+++ b/tests/compiler/dart2js_native/native_mixin_test.dart
@@ -5,8 +5,8 @@
// Test that native classes can use ordinary Dart classes as mixins.
class A native "*A" {
- foo() => 42;
- baz() => 99;
+ foo() => "A-foo";
+ baz() => "A-baz";
}
class B extends A with M native "*B" {
@@ -14,8 +14,8 @@
}
class M {
- foo() => 87;
- bar() => 101;
+ foo() => "M-foo";
+ bar() => "M-bar";
}
A makeA() native;
@@ -31,24 +31,24 @@
main() {
setup();
A a = makeA();
- Expect.equals(42, a.foo());
+ Expect.equals("A-foo", a.foo());
Expect.throws(() => a.bar(), (error) => error is NoSuchMethodError);
- Expect.equals(99, a.baz());
+ Expect.equals("A-baz", a.baz());
Expect.isTrue(a is A);
Expect.isFalse(a is B);
Expect.isFalse(a is M);
B b = makeB();
- Expect.equals(87, b.foo());
- Expect.equals(99, b.bar());
- Expect.equals(99, b.baz());
+ Expect.equals("M-foo", b.foo());
+ Expect.equals("A-baz", b.bar());
+ Expect.equals("A-baz", b.baz());
Expect.isTrue(b is A);
Expect.isTrue(b is B);
Expect.isTrue(b is M);
M m = new M();
- Expect.equals(87, m.foo());
- Expect.equals(101, m.bar());
+ Expect.equals("M-foo", m.foo());
+ Expect.equals("M-bar", m.bar());
Expect.throws(() => m.baz(), (error) => error is NoSuchMethodError);
Expect.isFalse(m is A);
Expect.isFalse(m is B);
diff --git a/tests/corelib/iterable_join_test.dart b/tests/corelib/iterable_join_test.dart
index a1df9b7..707abf1 100644
--- a/tests/corelib/iterable_join_test.dart
+++ b/tests/corelib/iterable_join_test.dart
@@ -42,7 +42,7 @@
void testArray(array) {
testJoin("1,3,5,7,9", array.where((i) => i.isOdd), ",");
- testJoin("0,2,4,6,8,10,12,14,16,18", array.mappedBy((i) => i * 2), ",");
+ testJoin("0,2,4,6,8,10,12,14,16,18", array.map((i) => i * 2), ",");
testJoin("5,6,7,8,9", array.skip(5), ",");
testJoin("5,6,7,8,9", array.skipWhile((i) => i < 5), ",");
testJoin("0,1,2,3,4", array.take(5), ",");
diff --git a/tests/corelib/iterable_length_test.dart b/tests/corelib/iterable_length_test.dart
index 8dd6cda..e70f82f 100644
--- a/tests/corelib/iterable_length_test.dart
+++ b/tests/corelib/iterable_length_test.dart
@@ -36,6 +36,6 @@
a = new A(0);
Expect.equals(0, a.length);
a = new A(5);
- Expect.equals(5, a.mappedBy((e) => e + 1).length);
+ Expect.equals(5, a.map((e) => e + 1).length);
Expect.equals(3, a.where((e) => e >= 3).length);
}
diff --git a/tests/corelib/iterable_mapping_test.dart b/tests/corelib/iterable_mapping_test.dart
index 4cb7b97..eae0a2d 100644
--- a/tests/corelib/iterable_mapping_test.dart
+++ b/tests/corelib/iterable_mapping_test.dart
@@ -10,46 +10,40 @@
set1.addAll([11, 12, 13]);
Set set2 = new Set();
- Iterable mapped = list1.mappedBy((x) => x + 1);
- Expect.isTrue(mapped is List);
- Expect.listEquals([2, 3, 4], mapped);
+ Iterable mapped = list1.map((x) => x + 1);
+ Expect.listEquals([2, 3, 4], mapped.toList());
- mapped = mapped.mappedBy((x) => x + 1);
- Expect.isTrue(mapped is List);
- Expect.listEquals([3, 4, 5], mapped);
+ mapped = mapped.map((x) => x + 1);
+ Expect.listEquals([3, 4, 5], mapped.toList());
- mapped = list2.mappedBy((x) => x + 1);
- Expect.isTrue(mapped is List);
- Expect.listEquals([5, 6], mapped);
+ mapped = list2.map((x) => x + 1);
+ Expect.listEquals([5, 6], mapped.toList());
- mapped = mapped.mappedBy((x) => x + 1);
- Expect.isTrue(mapped is List);
- Expect.listEquals([6, 7], mapped);
+ mapped = mapped.map((x) => x + 1);
+ Expect.listEquals([6, 7], mapped.toList());
- mapped = list3.mappedBy((x) => x + 1);
- Expect.isTrue(mapped is List);
- Expect.listEquals([], mapped);
+ mapped = list3.map((x) => x + 1);
+ Expect.listEquals([], mapped.toList());
- mapped = mapped.mappedBy((x) => x + 1);
- Expect.isTrue(mapped is List);
- Expect.listEquals([], mapped);
+ mapped = mapped.map((x) => x + 1);
+ Expect.listEquals([], mapped.toList());
var expected = new Set<int>()..addAll([12, 13, 14]);
- mapped = set1.mappedBy((x) => x + 1);
+ mapped = set1.map((x) => x + 1);
Expect.isFalse(mapped is List);
Expect.setEquals(expected, mapped.toSet());
expected = new Set<int>()..addAll([13, 14, 15]);
- mapped = mapped.mappedBy((x) => x + 1);
+ mapped = mapped.map((x) => x + 1);
Expect.isFalse(mapped is List);
Expect.setEquals(expected, mapped.toSet());
- mapped = set2.mappedBy((x) => x + 1);
+ mapped = set2.map((x) => x + 1);
Expect.isFalse(mapped is List);
Expect.listEquals([], mapped.toList());
- mapped = mapped.mappedBy((x) => x + 1);
+ mapped = mapped.map((x) => x + 1);
Expect.isFalse(mapped is List);
Expect.listEquals([], mapped.toList());
-}
\ No newline at end of file
+}
diff --git a/tests/corelib/list_growable_test.dart b/tests/corelib/list_growable_test.dart
index 5066c12..616b450 100644
--- a/tests/corelib/list_growable_test.dart
+++ b/tests/corelib/list_growable_test.dart
@@ -33,28 +33,4 @@
a.clear();
Expect.equals(0, a.length);
Expect.throws(() => a[0], (e) => e is RangeError);
-
- a = new List.filled(42, -1);
- Expect.equals(42, a.length);
- a.add(499);
- Expect.equals(43, a.length);
- Expect.equals(499, a[42]);
- for (int i = 0; i < 42; i++) {
- Expect.equals(-1, a[i]);
- }
- a.clear();
- Expect.equals(0, a.length);
- Expect.throws(() => a[0], (e) => e is RangeError);
-
- a = new List<int>.filled(42, -1);
- Expect.equals(42, a.length);
- a.add(499);
- Expect.equals(43, a.length);
- Expect.equals(499, a[42]);
- for (int i = 0; i < 42; i++) {
- Expect.equals(-1, a[i]);
- }
- a.clear();
- Expect.equals(0, a.length);
- Expect.throws(() => a[0], (e) => e is RangeError);
}
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index 970eba5..5aa5ae9 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -21,7 +21,7 @@
static void testClosures(List list) {
testMap(val) {return val * 2 + 10; }
- List mapped = list.mappedBy(testMap).toList();
+ List mapped = list.map(testMap).toList();
Expect.equals(mapped.length, list.length);
for (var i = 0; i < list.length; i++) {
Expect.equals(mapped[i], list[i]*2 + 10);
diff --git a/tests/corelib/queue_test.dart b/tests/corelib/queue_test.dart
index 11f6e3c..bc0e381 100644
--- a/tests/corelib/queue_test.dart
+++ b/tests/corelib/queue_test.dart
@@ -43,7 +43,7 @@
return (value == 10);
}
- Queue mapped = new Queue.from(queue.mappedBy(mapTest));
+ Queue mapped = new Queue.from(queue.map(mapTest));
checkQueue(mapped, 3, 111);
checkQueue(queue, 3, 1110);
Expect.equals(1, mapped.removeFirst());
diff --git a/tests/corelib/reg_exp_all_matches_test.dart b/tests/corelib/reg_exp_all_matches_test.dart
index 27c8ea7..bc31c0b 100644
--- a/tests/corelib/reg_exp_all_matches_test.dart
+++ b/tests/corelib/reg_exp_all_matches_test.dart
@@ -40,7 +40,7 @@
static testMap() {
var matches = new RegExp("foo?").allMatches("foo fo foo fo");
- var mapped = matches.mappedBy((Match m) => "${m.group(0)}bar");
+ var mapped = matches.map((Match m) => "${m.group(0)}bar");
Expect.equals(4, mapped.length);
var strbuf = new StringBuffer();
for (String s in mapped) {
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index 2a9cd1b..efe8cf1 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -51,7 +51,7 @@
return val * val;
}
- Set mapped = set.mappedBy(testMap).toSet();
+ Set mapped = set.map(testMap).toSet();
Expect.equals(10, mapped.length);
Expect.equals(true, mapped.contains(0));
diff --git a/tests/html/async_window_test.dart b/tests/html/async_window_test.dart
index 59b3dee..1e55448 100644
--- a/tests/html/async_window_test.dart
+++ b/tests/html/async_window_test.dart
@@ -11,18 +11,20 @@
test('Window.setInterval', () {
int counter = 0;
int id = null;
- id = window.setInterval(expectAsync0(() {
- if (counter == 3) {
- counter = 1024;
- window.clearInterval(id);
- // Wait some more time to be sure callback won't be invoked any more.
- window.setTimeout(expectAsync0((){}), 50);
- return;
- }
- // As callback should have been cleared on 4th invocation, counter
- // should never be greater than 3.
- assert(counter < 3);
- counter++;
- }, 3), 10);
+ id = window.setInterval(expectAsyncUntil0(
+ () {
+ if (counter == 3) {
+ counter = 1024;
+ window.clearInterval(id);
+ // Wait some more time to be sure callback won't be invoked any more.
+ window.setTimeout(expectAsync0((){}), 50);
+ return;
+ }
+ // As callback should have been cleared on 4th invocation, counter
+ // should never be greater than 3.
+ assert(counter < 3);
+ counter++;
+ },
+ () => counter == 3), 10);
});
}
diff --git a/tests/html/canvas_test.dart b/tests/html/canvas_test.dart
index 79c48cb..6d95d3a 100644
--- a/tests/html/canvas_test.dart
+++ b/tests/html/canvas_test.dart
@@ -37,10 +37,10 @@
var url = canvas.toDataUrl('image/png');
var img = new ImageElement();
- img.on.load.add(expectAsync1((_) {
+ img.onLoad.listen(expectAsync1((_) {
expect(img.complete, true);
}));
- img.on.error.add((_) {
+ img.onError.listen((_) {
guardAsync(() {
expect(true, isFalse, reason: 'URL failed to load.');
});
diff --git a/tests/html/css_test.dart b/tests/html/css_test.dart
index d827ab3..13418f3 100644
--- a/tests/html/css_test.dart
+++ b/tests/html/css_test.dart
@@ -1,43 +1,64 @@
library CssTest;
import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
import 'dart:html';
main() {
- useHtmlConfiguration();
- test('CssMatrix', () {
- CssMatrix matrix1 = new CssMatrix();
- expect(matrix1.m11.round(), equals(1));
- expect(matrix1.m12.round(), isZero);
+ useHtmlIndividualConfiguration();
- CssMatrix matrix2 = new CssMatrix('matrix(1, 0, 0, 1, -835, 0)');
- expect(matrix2.a.round(), equals(1));
- expect(matrix2.e.round(), equals(-835));
+ group('supported_CssMatrix', () {
+ test('supported', () {
+ expect(CssMatrix.supported, true);
+ });
});
- test('Point', () {
- Element element = new Element.tag('div');
- element.attributes['style'] =
- '''
- position: absolute;
- width: 60px;
- height: 100px;
- left: 0px;
- top: 0px;
- background-color: red;
- -webkit-transform: translate3d(250px, 100px, 0px) perspective(500px) rotateX(30deg);
- ''';
- document.body.nodes.add(element);
- Point point = new Point(5, 2);
- checkPoint(5, 2, point);
- checkPoint(256, 110, window.webkitConvertPointFromNodeToPage(element, point));
- point.y = 100;
- checkPoint(5, 100, point);
- checkPoint(254, 196, window.webkitConvertPointFromNodeToPage(element, point));
+ group('supported_DomPoint', () {
+ test('supported', () {
+ expect(DomPoint.supported, true);
+ });
+ });
+
+ group('functional', () {
+ test('CssMatrix', () {
+ var expectation = CssMatrix.supported ? returnsNormally : throws;
+ expect(() {
+ CssMatrix matrix1 = new CssMatrix();
+ expect(matrix1.m11.round(), equals(1));
+ expect(matrix1.m12.round(), isZero);
+
+ CssMatrix matrix2 = new CssMatrix('matrix(1, 0, 0, 1, -835, 0)');
+ expect(matrix2.a.round(), equals(1));
+ expect(matrix2.e.round(), equals(-835));
+ }, expectation);
+ });
+ test('DomPoint', () {
+ var expectation = DomPoint.supported ? returnsNormally : throws;
+ expect(() {
+ Element element = new Element.tag('div');
+ element.attributes['style'] =
+ '''
+ position: absolute;
+ width: 60px;
+ height: 100px;
+ left: 0px;
+ top: 0px;
+ background-color: red;
+ -webkit-transform: translate3d(250px, 100px, 0px);
+ ''';
+ document.body.nodes.add(element);
+
+ DomPoint point = new DomPoint(5, 2);
+ checkPoint(5, 2, point);
+ checkPoint(255, 102, window.convertPointFromNodeToPage(element, point));
+ point.y = 100;
+ checkPoint(5, 100, point);
+ checkPoint(255, 200, window.convertPointFromNodeToPage(element, point));
+ }, expectation);
+ });
});
}
-void checkPoint(expectedX, expectedY, Point point) {
+void checkPoint(expectedX, expectedY, DomPoint point) {
expect(point.x.round(), equals(expectedX), reason: 'Wrong point.x');
expect(point.y.round(), equals(expectedY), reason: 'Wrong point.y');
}
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index b176436..a0ef366 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -72,13 +72,10 @@
element.style.transform = 'translateX(10px)';
document.body.children.add(element);
- element.getComputedStyle('').then(expectAsync1(
- (CssStyleDeclaration style) {
- // Some browsers will normalize this, so it'll be a matrix rather than
- // the original string. Just check that it's something other than null.
- expect(style.transform.length, greaterThan(3));
- }
- ));
+ var style = element.getComputedStyle();
+ // Some browsers will normalize this, so it'll be a matrix rather than
+ // the original string. Just check that it's something other than null.
+ expect(style.transform.length, greaterThan(3));
});
// IE9 requires an extra poke for some properties to get applied.
@@ -89,11 +86,8 @@
// Need to wait one tick after the element has been added to the page.
window.setTimeout(expectAsync0(() {
element.style.textDecoration = 'underline';
- element.getComputedStyle('').then(expectAsync1(
- (CssStyleDeclaration style) {
- expect(style.textDecoration, equals('underline'));
- }
- ));
+ var style = element.getComputedStyle();
+ expect(style.textDecoration, equals('underline'));
}), 10);
});
}
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
new file mode 100644
index 0000000..fbae236
--- /dev/null
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dromaeo;
+import 'dart:html';
+import 'dart:json' as json;
+import '../../../samples/third_party/dromaeo/common/common.dart';
+import 'dart:math' as Math;
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/unittest/lib/html_config.dart';
+part '../../../samples/third_party/dromaeo/tests/Common.dart';
+part '../../../samples/third_party/dromaeo/tests/RunnerSuite.dart';
+
+/**
+ * The smoketest equivalent of an individual test run, much like
+ * dom-attr-html.dart, dom-modify-html.dart, dom-query-html.dart and others.
+ */
+void main() {
+ new Suite(window, 'dom-nothing')
+ .prep(() {})
+ .test('no-op', () {})
+ .end();
+}
+
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart.js b/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
new file mode 100644
index 0000000..d1f3214
--- /dev/null
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+window.onload = function(){
+ startTest("dom-nothing");
+ test( "no-op", function(){});
+ endTest();
+};
diff --git a/tests/html/dromaeo_smoke-html.html b/tests/html/dromaeo_smoke-html.html
new file mode 100644
index 0000000..96d65b4
--- /dev/null
+++ b/tests/html/dromaeo_smoke-html.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<!-- The inner smoketest iframe, corresponds to dom-attr-html.html,
+dom-modify-html.html and others in the dromaeo tests directory. -->
+<html>
+<head>
+<script type="application/dart" src="dromaeo_noop/dromaeo_smoke.dart"></script>
+<script src='../../pkg/browser/lib/dart.js'></script>
+<script src='../../samples/third_party/dromaeo/htmlrunner.js'></script>
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
new file mode 100644
index 0000000..946ddbc
--- /dev/null
+++ b/tests/html/dromaeo_smoke_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dromaeo;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import '../../samples/third_party/dromaeo/Dromaeo.dart' as originalTest;
+import 'dart:html';
+import 'dart:async';
+
+/** A variant of the Dromaeo test shoehorned into a unit test. */
+void main() {
+ var combo = '?dartANDhtmlANDnothing';
+ if (!window.location.search.toString().contains(combo)) {
+ if (window.location.href.toString().indexOf("?") == -1) {
+ window.location.href = '${window.location.href}${combo}';
+ } else {
+ window.location.href = '${window.location.href.toString().substring(0,
+ window.location.href.toString().indexOf("?"))}${combo}';
+ }
+ }
+
+ useHtmlConfiguration();
+
+ var scriptSrc = new ScriptElement();
+ scriptSrc.src = '../../../../pkg/browser/lib/dart.js';
+ document.head.children.add(scriptSrc);
+ document.body.innerHtml = '''${document.body.innerHtml}
+ <div id="main">
+ <h1 id="overview" class="test"><span>Performance Tests</span>
+ <input type="button" id="pause" class="pause" value="Loading..."/>
+ <div class="bar">
+ <div id="timebar" style="width:25%;">
+ <span class="left">Est. Time: <strong id="left">0:00</strong>
+ </span>
+ </div>
+ </div>
+ <ul id="tests">
+ <li><a href="?dom">Smoke Tests</a></li>
+ </ul>
+ </div>''';
+
+ bool isDone = false;
+ originalTest.main();
+
+ test('dromaeo runs', () {
+ new Timer.repeating(500, expectAsyncUntil1((timer) {
+ if (document.query('.alldone') != null) {
+ timer.cancel();
+ isDone = true;
+ }
+ }, () => isDone));
+ });
+}
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index 809ef47..89434fc 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -67,7 +67,7 @@
});
test('mappedBy', () {
- expect(makeClassSet().mappedBy((c) => c.toUpperCase()).toList(),
+ expect(makeClassSet().map((c) => c.toUpperCase()).toList(),
unorderedEquals(['FOO', 'BAR', 'BAZ']));
});
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index d849731..4ec1bfc 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -5,6 +5,7 @@
library ElementTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:async';
import 'dart:html';
import 'dart:svg' as svg;
@@ -17,34 +18,6 @@
expect(rect.right, rect.left + rect.width);
}
-void testEventHelper(EventListenerList listenerList, String type,
- [Function registerOnEventListener = null]) {
- testMultipleEventHelper(listenerList, [type], registerOnEventListener);
-}
-// Allows testing where we polyfill different browsers firing different events.
-void testMultipleEventHelper(EventListenerList listenerList, List<String> types,
- [Function registerOnEventListener = null]) {
- bool firedWhenAddedToListenerList = false;
- bool firedOnEvent = false;
- listenerList.add((e) {
- firedWhenAddedToListenerList = true;
- });
- if (registerOnEventListener != null) {
- registerOnEventListener((e) {
- firedOnEvent = true;
- });
- }
- for (var type in types) {
- final event = new Event(type);
- listenerList.dispatch(event);
- }
-
- expect(firedWhenAddedToListenerList, isTrue);
- if (registerOnEventListener != null) {
- expect(firedOnEvent, isTrue);
- }
-}
-
main() {
useHtmlIndividualConfiguration();
@@ -69,33 +42,34 @@
Element makeElementWithChildren() =>
new Element.html("<div><br/><img/><input/></div>");
- test('computedStyle', () {
- final element = document.body;
- element.computedStyle.then(expectAsync1((style) {
+ group('position', () {
+ test('computedStyle', () {
+ final element = document.body;
+ var style = element.getComputedStyle();
expect(style.getPropertyValue('left'), 'auto');
- }));
- });
+ });
- test('client position synchronous', () {
- final container = new Element.tag("div");
- container.style.position = 'absolute';
- container.style.top = '8px';
- container.style.left = '8px';
- final element = new Element.tag("div");
- element.style.width = '200px';
- element.style.height = '200px';
- container.children.add(element);
- document.body.children.add(container);
+ test('client position synchronous', () {
+ final container = new Element.tag("div");
+ container.style.position = 'absolute';
+ container.style.top = '8px';
+ container.style.left = '8px';
+ final element = new Element.tag("div");
+ element.style.width = '200px';
+ element.style.height = '200px';
+ container.children.add(element);
+ document.body.children.add(container);
- expect(element.clientWidth, greaterThan(100));
- expect(element.clientHeight, greaterThan(100));
- expect(element.offsetWidth, greaterThan(100));
- expect(element.offsetHeight, greaterThan(100));
- expect(element.scrollWidth, greaterThan(100));
- expect(element.scrollHeight, greaterThan(100));
- expect(element.getBoundingClientRect().left, 8);
- expect(element.getBoundingClientRect().top, 8);
- container.remove();
+ expect(element.clientWidth, greaterThan(100));
+ expect(element.clientHeight, greaterThan(100));
+ expect(element.offsetWidth, greaterThan(100));
+ expect(element.offsetHeight, greaterThan(100));
+ expect(element.scrollWidth, greaterThan(100));
+ expect(element.scrollHeight, greaterThan(100));
+ expect(element.getBoundingClientRect().left, 8);
+ expect(element.getBoundingClientRect().top, 8);
+ container.remove();
+ });
});
group('constructors', () {
@@ -135,7 +109,7 @@
expect(node.tHead.rows[0].cells.length, 3);
expect(node.tBodies.length, 1);
expect(node.tBodies[0].rows.length, 2);
- expect(node.tBodies[0].rows[1].cells.mappedBy((c) => c.innerHtml),
+ expect(node.tBodies[0].rows[1].cells.map((c) => c.innerHtml),
[' Failing\n ', ' Grade\n ', ' Passing\n']);
});
@@ -208,7 +182,7 @@
'is a TableRowElement'));
expect(node.tagName, 'TR');
expect(node.parent, isNull);
- expect(node.cells.mappedBy((c) => c.innerHtml), ['foo', 'bar']);
+ expect(node.cells.map((c) => c.innerHtml), ['foo', 'bar']);
});
test('.html td', () {
@@ -231,143 +205,65 @@
});
group('eventListening', () {
- test('eventListeners', () {
- final element = new Element.tag('div');
- final on = element.on;
+ test('streams', () {
+ final target = new Element.tag('div');
- testEventHelper(on.abort, 'abort',
- (listener) => Testing.addEventListener(
- element, 'abort', listener, true));
- testEventHelper(on.beforeCopy, 'beforecopy',
- (listener) => Testing.addEventListener(
- element, 'beforecopy', listener, true));
- testEventHelper(on.beforeCut, 'beforecut',
- (listener) => Testing.addEventListener(
- element, 'beforecut', listener, true));
- testEventHelper(on.beforePaste, 'beforepaste',
- (listener) => Testing.addEventListener(
- element, 'beforepaste', listener, true));
- testEventHelper(on.blur, 'blur',
- (listener) => Testing.addEventListener(
- element, 'blur', listener, true));
- testEventHelper(on.change, 'change',
- (listener) => Testing.addEventListener(
- element, 'change', listener, true));
- testEventHelper(on.contextMenu, 'contextmenu',
- (listener) => Testing.addEventListener(
- element, 'contextmenu', listener, true));
- testEventHelper(on.copy, 'copy',
- (listener) => Testing.addEventListener(
- element, 'copy', listener, true));
- testEventHelper(on.cut, 'cut',
- (listener) => Testing.addEventListener(
- element, 'cut', listener, true));
- testEventHelper(on.doubleClick, 'dblclick',
- (listener) => Testing.addEventListener(
- element, 'dblclick', listener, true));
- testEventHelper(on.drag, 'drag',
- (listener) => Testing.addEventListener(
- element, 'drag', listener, true));
- testEventHelper(on.dragEnd, 'dragend',
- (listener) => Testing.addEventListener(
- element, 'dragend', listener, true));
- testEventHelper(on.dragEnter, 'dragenter',
- (listener) => Testing.addEventListener(
- element, 'dragenter', listener, true));
- testEventHelper(on.dragLeave, 'dragleave',
- (listener) => Testing.addEventListener(
- element, 'dragleave', listener, true));
- testEventHelper(on.dragOver, 'dragover',
- (listener) => Testing.addEventListener(
- element, 'dragover', listener, true));
- testEventHelper(on.dragStart, 'dragstart',
- (listener) => Testing.addEventListener(
- element, 'dragstart', listener, true));
- testEventHelper(on.drop, 'drop',
- (listener) => Testing.addEventListener(
- element, 'drop', listener, true));
- testEventHelper(on.error, 'error',
- (listener) => Testing.addEventListener(
- element, 'error', listener, true));
- testEventHelper(on.focus, 'focus',
- (listener) => Testing.addEventListener(
- element, 'focus', listener, true));
- testEventHelper(on.input, 'input',
- (listener) => Testing.addEventListener(
- element, 'input', listener, true));
- testEventHelper(on.invalid, 'invalid',
- (listener) => Testing.addEventListener(
- element, 'invalid', listener, true));
- testEventHelper(on.keyDown, 'keydown',
- (listener) => Testing.addEventListener(
- element, 'keydown', listener, true));
- testEventHelper(on.keyPress, 'keypress',
- (listener) => Testing.addEventListener(
- element, 'keypress', listener, true));
- testEventHelper(on.keyUp, 'keyup',
- (listener) => Testing.addEventListener(
- element, 'keyup', listener, true));
- testEventHelper(on.load, 'load',
- (listener) => Testing.addEventListener(
- element, 'load', listener, true));
- testEventHelper(on.mouseDown, 'mousedown',
- (listener) => Testing.addEventListener(
- element, 'mousedown', listener, true));
- testEventHelper(on.mouseMove, 'mousemove',
- (listener) => Testing.addEventListener(
- element, 'mousemove', listener, true));
- testEventHelper(on.mouseOut, 'mouseout',
- (listener) => Testing.addEventListener(
- element, 'mouseout', listener, true));
- testEventHelper(on.mouseOver, 'mouseover',
- (listener) => Testing.addEventListener(
- element, 'mouseover', listener, true));
- testEventHelper(on.mouseUp, 'mouseup',
- (listener) => Testing.addEventListener(
- element, 'mouseup', listener, true));
- // Browsers have different events that they use, so fire all variants.
- testMultipleEventHelper(on.mouseWheel,
- ['mousewheel', 'wheel', 'DOMMouseScroll'],
- (listener) => Testing.addEventListener(
- element, 'mousewheel', listener, true));
- testEventHelper(on.paste, 'paste',
- (listener) => Testing.addEventListener(
- element, 'paste', listener, true));
- testEventHelper(on.reset, 'reset',
- (listener) => Testing.addEventListener(
- element, 'reset', listener, true));
- testEventHelper(on.scroll, 'scroll',
- (listener) => Testing.addEventListener(
- element, 'scroll', listener, true));
- testEventHelper(on.search, 'search',
- (listener) => Testing.addEventListener(
- element, 'search', listener, true));
- testEventHelper(on.select, 'select',
- (listener) => Testing.addEventListener(
- element, 'select', listener, true));
- testEventHelper(on.selectStart, 'selectstart',
- (listener) => Testing.addEventListener(
- element, 'selectstart', listener, true));
- testEventHelper(on.submit, 'submit',
- (listener) => Testing.addEventListener(
- element, 'submit', listener, true));
- testEventHelper(on.touchCancel, 'touchcancel',
- (listener) => Testing.addEventListener(
- element, 'touchcancel', listener, true));
- testEventHelper(on.touchEnd, 'touchend',
- (listener) => Testing.addEventListener(
- element, 'touchend', listener, true));
- testEventHelper(on.touchLeave, 'touchleave');
- testEventHelper(on.touchMove, 'touchmove',
- (listener) => Testing.addEventListener(
- element, 'touchmove', listener, true));
- testEventHelper(on.touchStart, 'touchstart',
- (listener) => Testing.addEventListener(
- element, 'touchstart', listener, true));
- testEventHelper(on.transitionEnd, 'webkitTransitionEnd');
- testEventHelper(on.fullscreenChange, 'webkitfullscreenchange',
- (listener) => Testing.addEventListener(element,
- 'webkitfullscreenchange', listener, true));
+ void testEvent(Stream stream, String type) {
+ var firedOnEvent = false;
+ stream.listen((e) {
+ firedOnEvent = true;
+ });
+ expect(firedOnEvent, isFalse);
+ var event = new Event(type);
+ target.dispatchEvent(event);
+
+ expect(firedOnEvent, isTrue);
+ }
+
+ testEvent(target.onAbort, 'abort');
+ testEvent(target.onBeforeCopy, 'beforecopy');
+ testEvent(target.onBeforeCut, 'beforecut');
+ testEvent(target.onBeforePaste, 'beforepaste');
+ testEvent(target.onBlur, 'blur');
+ testEvent(target.onChange, 'change');
+ testEvent(target.onContextMenu, 'contextmenu');
+ testEvent(target.onCopy, 'copy');
+ testEvent(target.onCut, 'cut');
+ testEvent(target.onDoubleClick, 'dblclick');
+ testEvent(target.onDrag, 'drag');
+ testEvent(target.onDragEnd, 'dragend');
+ testEvent(target.onDragEnter, 'dragenter');
+ testEvent(target.onDragLeave, 'dragleave');
+ testEvent(target.onDragOver, 'dragover');
+ testEvent(target.onDragStart, 'dragstart');
+ testEvent(target.onDrop, 'drop');
+ testEvent(target.onError, 'error');
+ testEvent(target.onFocus, 'focus');
+ testEvent(target.onFullscreenChange, 'webkitfullscreenchange');
+ testEvent(target.onInput, 'input');
+ testEvent(target.onInvalid, 'invalid');
+ testEvent(target.onKeyDown, 'keydown');
+ testEvent(target.onKeyPress, 'keypress');
+ testEvent(target.onKeyUp, 'keyup');
+ testEvent(target.onLoad, 'load');
+ testEvent(target.onMouseDown, 'mousedown');
+ testEvent(target.onMouseMove, 'mousemove');
+ testEvent(target.onMouseOut, 'mouseout');
+ testEvent(target.onMouseOver, 'mouseover');
+ testEvent(target.onMouseUp, 'mouseup');
+ testEvent(target.onPaste, 'paste');
+ testEvent(target.onReset, 'reset');
+ testEvent(target.onScroll, 'scroll');
+ testEvent(target.onSearch, 'search');
+ testEvent(target.onSelect, 'select');
+ testEvent(target.onSelectStart, 'selectstart');
+ testEvent(target.onSubmit, 'submit');
+ testEvent(target.onTouchCancel, 'touchcancel');
+ testEvent(target.onTouchEnd, 'touchend');
+ testEvent(target.onTouchLeave, 'touchleave');
+ testEvent(target.onTouchMove, 'touchmove');
+ testEvent(target.onTouchStart, 'touchstart');
+ testEvent(target.onTransitionEnd, 'webkitTransitionEnd');
});
});
@@ -375,7 +271,7 @@
test('clickEvent', () {
var e = new DivElement();
var firedEvent = false;
- e.on.click.add((event) {
+ e.onClick.listen((event) {
firedEvent = true;
});
expect(firedEvent, false);
@@ -643,7 +539,7 @@
});
test('mappedBy', () {
- var texts = getQueryAll().mappedBy((el) => el.text).toList();
+ var texts = getQueryAll().map((el) => el.text).toList();
expect(texts, equals(['Dart!', 'Hello', '']));
});
diff --git a/tests/html/event_customevent_test.dart b/tests/html/event_customevent_test.dart
index 2f50627..4e0ed48 100644
--- a/tests/html/event_customevent_test.dart
+++ b/tests/html/event_customevent_test.dart
@@ -26,9 +26,19 @@
main() {
useHtmlConfiguration();
- eventTest('CustomEvent.initCustomEvent', () {
- return new CustomEvent('foo', canBubble: false, cancelable: false,
+ test('custom events', () {
+ var provider = new EventStreamProvider<CustomEvent>('foo');
+ var el = new DivElement();
+
+ var fired = false;
+ provider.forTarget(el).listen((ev) {
+ fired = true;
+ expect(ev.detail, 'detail');
+ });
+
+ var ev = new CustomEvent('foo', canBubble: false, cancelable: false,
detail: 'detail');
- },
- (ev) { expect(ev.detail, equals('detail')); });
+ el.dispatchEvent(ev);
+ expect(fired, isTrue);
+ });
}
diff --git a/tests/html/events_test.dart b/tests/html/events_test.dart
index 11a9623..a88d631 100644
--- a/tests/html/events_test.dart
+++ b/tests/html/events_test.dart
@@ -29,27 +29,29 @@
Event event = new Event('test');
invocationCounter = 0;
- element.on['test'].dispatch(event);
+ element.dispatchEvent(event);
expect(invocationCounter, isZero);
- element.on['test'].add(handler, false);
+ var provider = new EventStreamProvider<CustomEvent>('test');
+
+ var sub = provider.forTarget(element).listen(handler);
invocationCounter = 0;
- element.on['test'].dispatch(event);
+ element.dispatchEvent(event);
expect(invocationCounter, 1);
- element.on['test'].remove(handler, false);
+ sub.cancel();
invocationCounter = 0;
- element.on['test'].dispatch(event);
+ element.dispatchEvent(event);
expect(invocationCounter, isZero);
- element.on['test'].add(handler, false);
+ provider.forTarget(element).listen(handler);
invocationCounter = 0;
- element.on['test'].dispatch(event);
+ element.dispatchEvent(event);
expect(invocationCounter, 1);
- element.on['test'].add(handler, false);
+ provider.forTarget(element).listen(handler);
invocationCounter = 0;
- element.on['test'].dispatch(event);
+ element.dispatchEvent(event);
expect(invocationCounter, 1);
});
test('InitMouseEvent', () {
diff --git a/tests/html/form_data_test.dart b/tests/html/form_data_test.dart
index cdcca7e..0ddd97d 100644
--- a/tests/html/form_data_test.dart
+++ b/tests/html/form_data_test.dart
@@ -61,10 +61,10 @@
var xhr = new HttpRequest();
xhr.open("POST", "http://localhost:${window.location.port}/echo");
- xhr.on.load.add(expectAsync1((e) {
+ xhr.onLoad.listen(expectAsync1((e) {
expect(xhr.responseText.contains(blobString), true);
}));
- xhr.on.error.add((e) {
+ xhr.onError.listen((e) {
fail('$e');
});
xhr.send(form);
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index 6f4eb3a..f2c7c12 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -3,16 +3,6 @@
import '../../pkg/unittest/lib/html_individual_config.dart';
import 'dart:html';
-/// Waits for a callback once, then removes the event handler.
-void expectAsync1Once(EventListenerList list, void callback(arg)) {
- var fn = null;
- fn = expectAsync1((arg) {
- list.remove(fn);
- callback(arg);
- });
- list.add(fn);
-}
-
main() {
useHtmlIndividualConfiguration();
@@ -53,10 +43,10 @@
// Need to wait a frame or two to let the pushState events occur.
window.setTimeout(expectAsync0(() {
- expectAsync1Once(window.on.popState, (_) {
+ window.onPopState.first.then(expectAsync1((_){
expect(window.history.length, length);
expect(window.location.href.endsWith('dummy1'), isTrue);
- });
+ }));
window.history.back();
}), 100);
diff --git a/tests/html/html.status b/tests/html/html.status
index 36b8e1a..1853065 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -5,7 +5,6 @@
window_open_test: Skip # http://dartbug.com/5151
event_test: Skip # Issue 1996
-webgl_1_test: Skip # Issue 1495
# Layout tests are only supported on DRT.
[ $runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == opera ]
@@ -21,12 +20,15 @@
input_element_test/supported_week: Fail
speechrecognition_test/supported: Pass, Fail # Chrome stable does not support it.
shadow_dom_test/supported: Fail
-css_test: Pass, Fail # Issue 7978
speechrecognition_test/types: Pass, Fail
+touchevent_test/supported: Fail
-[ $runtime == chrome || $runtime == drt]
-audiobuffersourcenode_test: Pass, Fail, Timeout # AudiobufferSourceNode is flaky on Chrome and Dartium - filed issue 8021 for the timeout.
-audiocontext_test: Pass, Timeout # Issue 8021.
+[$runtime == drt || $runtime == dartium || $runtime == chrome]
+webgl_1_test: Pass, Fail # Issue 8219
+
+[ $runtime == drt || $runtime == chrome]
+audiobuffersourcenode_test: Pass, Fail, Timeout, Crash # AudiobufferSourceNode is flaky on Chrome and Dartium - filed issue 8021 for the timeout.
+audiocontext_test: Pass, Timeout, Crash # Issue 8021.
[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
request_animation_frame_test: Skip # drt hangs; requestAnimationFrame not implemented
@@ -48,8 +50,10 @@
# TODO(efortuna, blois): Triage.
audiobuffersourcenode_test: Fail
audiocontext_test: Fail
-css_test: Fail
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
document_test/supports_cssCanvasContext: Fail
+dromaeo_smoke_test: Skip #TODO(efortuna): investigating.
element_test/click: Fail # IE does not support firing this event.
element_types_test/supported_content: Fail
element_types_test/supported_details: Fail
@@ -74,6 +78,7 @@
media_stream_test/supported_MediaStreamEvent: Fail
media_stream_test/supported_MediaStreamTrackEvent: Fail
messageevent_test: Fail
+microtask_test: Fail, Pass # Appears to be flaky
mutationobserver_test/supported: Fail
native_gc_test: Fail, Pass # BUG(7774): Untriaged.
notifications_test/supported: Fail
@@ -83,16 +88,19 @@
storage_test: Fail, Pass
svgelement_test/additionalConstructors: Fail
svgelement2_test: Fail
-svg_3_test: Fail
-websql_test: Fail
+touchevent_test/supported: Fail
+webgl_1_test/supported: Fail
+websql_test/supported: Fail
websocket_test/websocket: Fail # TODO(efortuna): Issue 7875.
window_open_test: Skip
xhr_cross_origin_test: Fail # TODO(efortuna): Issue 7875.
xhr_test/supported_HttpRequestProgressEvent: Fail
-xsltprocessor_test: Fail
+xsltprocessor_test/supported: Fail
+history_test/history: Pass, Fail # issue 8183
[ $runtime == ie9 ]
document_test/supports_cssCanvasContext: Fail
+dromaeo_smoke_test: Skip #TODO(efortuna): investigating.
element_test/click: Fail # IE does not support firing this event.
element_types_test/supported_content: Fail
element_types_test/supported_datalist: Fail
@@ -109,7 +117,8 @@
inner_frame_test: Skip # Issue 5727 (timeout)
typed_arrays_1_test/supported: Fail
localstorage_test: Fail
-websql_test: Fail # IE does not support web SQL
+webgl_1_test/supported: Fail
+websql_test/supported: Fail
#
# Investigate and triage the following into bug reports.
#
@@ -117,7 +126,8 @@
audiocontext_test: Fail
blob_constructor_test: Fail
cache_test/supported: Fail
-css_test: Fail
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
dom_constructors_test: Fail
element_test/matches: Fail # IE9 does not support matches
fileapi_test/supported: Fail
@@ -149,25 +159,19 @@
svg_3_test: Fail
svgelement_test/additionalConstructors: Fail
svgelement2_test: Fail
+touchevent_test/supported: Fail
url_test: Fail # IE9 does not support createObjectURL (it is supported in IE10)
websocket_test/supported: Fail
window_open_test: Skip # BUG(4016)
-xsltprocessor_test: Skip # BUG(4016)
isolates_test: Skip # BUG(4016)
xhr_test: Skip # BUG(4016)
xhr_test/supported_HttpRequestProgressEvent: Fail
xhr_cross_origin_test: Fail # Issue 6016.
+xsltprocessor_test/supported: Fail
[ $runtime == safari ]
element_types_test/supported_content: Fail
element_types_test/supported_datalist: Fail
-element_types_test/supported_details: Fail
-element_types_test/supported_embed: Fail
-element_types_test/supported_keygen: Fail
-element_types_test/supported_meter: Fail
-element_types_test/supported_object: Fail
-element_types_test/supported_output: Fail
-element_types_test/supported_progress: Fail
element_types_test/supported_shadow: Fail
element_types_test/supported_track: Pass, Fail
fileapi_test/supported: Fail
@@ -175,12 +179,8 @@
input_element_test/supported_date: Fail
input_element_test/supported_datetime-local: Fail
input_element_test/supported_datetime: Fail
-input_element_test/supported_email: Fail
input_element_test/supported_month: Fail, Crash
-input_element_test/supported_number: Fail
-input_element_test/supported_range: Fail, Crash # TODO(efortuna): Please triage this failure.
input_element_test/supported_time: Fail, Crash
-input_element_test/supported_url: Fail
input_element_test/supported_week: Fail, Crash
media_stream_test/supported_media: Fail
media_stream_test/supported_MediaStreamEvent: Fail
@@ -189,25 +189,13 @@
performance_api_test/supported: Fail
shadow_dom_test/supported: Fail
speechrecognition_test/supported: Fail
+touchevent_test/supported: Fail
+webgl_1_test: Pass, Fail # Issue 8219
audiocontext_test: Crash, Fail # Issue: 7414
datalistelement_test: Fail # Issue: 7414
element_test/elements: Crash, Fail # Issue: 7414
-element_types_test/constructors: Fail
-fileapi_test/getDirectory: Fail # Issue: 7414
-fileapi_test/getFile: Pass, Fail # Issue: 7414
-fileapi_test/unsupported_throws: Fail # Issue: 7414
-input_element_test/constructors: Fail # Issue: 7414
-input_element_test/supported_tel: Pass, Fail # Issue: 7414
-media_stream_test/constructors: Pass, Fail # Issue: 7414
-node_test: Skip # Issue 6457
-notifications_test/unsupported_throws: Fail # Issue: 7414
-notifications_test/webkitNotifications: Fail # Issue: 7414
-performance_api_test/performance: Fail # Issue: 7414
-shadow_dom_test/ShadowDOM_tests: Fail # Issue: 7414
wheelevent_test: Fail # Issue: 7414
-speechrecognition_test/types: Pass, Fail
-
[ $runtime == opera ]
document_test/supports_cssCanvasContext: Fail
@@ -222,7 +210,8 @@
blob_constructor_test: Fail
canvas_using_html_test: Fail
canvas_test: Fail
-css_test: Fail
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
cssstyledeclaration_test: Fail
element_add_test: Fail
element_constructor_1_test: Fail
@@ -248,12 +237,13 @@
js_interop_3_test: Skip # Timeout.
js_interop_4_test: Skip # Timeout.
isolates_test: Skip # Timeout.
-websql_test: Skip # Timeout.
+websql_test/supported: Fail
[ $runtime == ff ]
audiobuffersourcenode_test: Fail # FF only has Audio element.
audiocontext_test: Fail # FF only has Audio element
-css_test: Fail # No analog to WebKitCssMatrix
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
dart_object_local_storage_test: Skip # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
document_test/supports_cssCanvasContext: Fail
element_types_test/supported_content: Fail
@@ -282,9 +272,12 @@
svg_3_test: Fail
svgelement_test/additionalConstructors: Fail
svgelement2_test: Fail
+touchevent_test/supported: Fail
transferables_test: Fail # Issue 3392.
-websql_test: Fail # FF does not support web SQL
+webgl_1_test: Pass, Fail # Issue 8219
+websql_test/supported: Fail
xhr_test/supported_HttpRequestProgressEvent: Fail
+dromaeo_smoke_test: Pass, Fail # Issue: 8257
[ $runtime == ie9 && ($system == linux || $system == macos) ]
*: Skip
diff --git a/tests/html/indexeddb_1_test.dart b/tests/html/indexeddb_1_test.dart
index f9ae43f..92eef20 100644
--- a/tests/html/indexeddb_1_test.dart
+++ b/tests/html/indexeddb_1_test.dart
@@ -28,19 +28,19 @@
step2(e) {
var transaction = db.transaction(storeName, 'readonly');
var request = transaction.objectStore(storeName).getObject(key);
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
var object = e.target.result;
db.close();
expect(object, matcher);
}));
- request.on.error.add(fail);
+ request.onError.listen(fail);
}
step1() {
var transaction = db.transaction([storeName], 'readwrite');
var request = transaction.objectStore(storeName).put(value, key);
- request.on.success.add(expectAsync1(step2));
- request.on.error.add(fail);
+ request.onSuccess.listen(expectAsync1(step2));
+ request.onError.listen(fail);
}
initDb(e) {
@@ -48,15 +48,15 @@
if (version != db.version) {
// Legacy 'setVersion' upgrade protocol. Chrome 23 and earlier.
var request = db.setVersion('$version');
- request.on.success.add(
+ request.onSuccess.listen(
expectAsync1((e) {
createObjectStore(db);
var transaction = e.target.result;
- transaction.on.complete.add(expectAsync1((e) => step1()));
- transaction.on.error.add(fail);
+ transaction.onComplete.listen(expectAsync1((e) => step1()));
+ transaction.onError.listen(fail);
})
);
- request.on.error.add(fail);
+ request.onError.listen(fail);
} else {
step1();
}
@@ -65,12 +65,12 @@
openDb(e) {
var request = html.window.indexedDB.open(dbName, version);
expect(request, isNotNull);
- request.on.success.add(expectAsync1(initDb));
- request.on.error.add(fail);
+ request.onSuccess.listen(expectAsync1(initDb));
+ request.onError.listen(fail);
if (request is idb.OpenDBRequest) {
// New upgrade protocol. Old API has no 'upgradeNeeded' and uses
// setVersion instead. This path take by FireFox 15, Chrome 24.
- request.on.upgradeNeeded.add((e) {
+ request.onUpgradeNeeded.listen((e) {
guardAsync(() {
createObjectStore(e.target.result);
});
@@ -80,8 +80,8 @@
// Delete any existing DB.
var deleteRequest = html.window.indexedDB.deleteDatabase(dbName);
- deleteRequest.on.success.add(expectAsync1(openDb));
- deleteRequest.on.error.add(fail);
+ deleteRequest.onSuccess.listen(expectAsync1(openDb));
+ deleteRequest.onError.listen(fail);
};
testReadWriteTyped(key, value, matcher,
@@ -104,19 +104,19 @@
step2(e) {
idb.Transaction transaction = db.transaction(storeName, 'readonly');
idb.Request request = transaction.objectStore(storeName).getObject(key);
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
var object = e.target.result;
db.close();
expect(object, matcher);
}));
- request.on.error.add(fail);
+ request.onError.listen(fail);
}
step1() {
idb.Transaction transaction = db.transaction([storeName], 'readwrite');
idb.Request request = transaction.objectStore(storeName).put(value, key);
- request.on.success.add(expectAsync1(step2));
- request.on.error.add(fail);
+ request.onSuccess.listen(expectAsync1(step2));
+ request.onError.listen(fail);
}
initDb(e) {
@@ -124,15 +124,15 @@
if (version != db.version) {
// Legacy 'setVersion' upgrade protocol.
idb.Request request = db.setVersion('$version');
- request.on.success.add(
+ request.onSuccess.listen(
expectAsync1((e) {
createObjectStore(db);
idb.Transaction transaction = e.target.result;
- transaction.on.complete.add(expectAsync1((e) => step1()));
- transaction.on.error.add(fail);
+ transaction.onComplete.listen(expectAsync1((e) => step1()));
+ transaction.onError.listen(fail);
})
);
- request.on.error.add(fail);
+ request.onError.listen(fail);
} else {
step1();
}
@@ -141,12 +141,12 @@
openDb(e) {
idb.Request request = html.window.indexedDB.open(dbName, version);
expect(request, isNotNull);
- request.on.success.add(expectAsync1(initDb));
- request.on.error.add(fail);
+ request.onSuccess.listen(expectAsync1(initDb));
+ request.onError.listen(fail);
if (request is idb.OpenDBRequest) {
// New upgrade protocol. Old API has no 'upgradeNeeded' and uses
// setVersion instead.
- request.on.upgradeNeeded.add((e) {
+ request.onUpgradeNeeded.listen((e) {
guardAsync(() {
createObjectStore(e.target.result);
});
@@ -156,8 +156,8 @@
// Delete any existing DB.
idb.Request deleteRequest = html.window.indexedDB.deleteDatabase(dbName);
- deleteRequest.on.success.add(expectAsync1(openDb));
- deleteRequest.on.error.add(fail);
+ deleteRequest.onSuccess.listen(expectAsync1(openDb));
+ deleteRequest.onError.listen(fail);
};
tests_dynamic() {
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index ac41b3d..66fef6c 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -32,19 +32,19 @@
step2(e) {
var transaction = db.transaction(storeName, 'readonly');
var request = transaction.objectStore(storeName).getObject(key);
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
var object = e.target.result;
db.close();
check(value, object);
}));
- request.on.error.add(fail);
+ request.onError.listen(fail);
}
step1() {
var transaction = db.transaction([storeName], 'readwrite');
var request = transaction.objectStore(storeName).put(value, key);
- request.on.success.add(expectAsync1(step2));
- request.on.error.add(fail);
+ request.onSuccess.listen(expectAsync1(step2));
+ request.onError.listen(fail);
}
initDb(e) {
@@ -52,15 +52,15 @@
if (version != db.version) {
// Legacy 'setVersion' upgrade protocol.
var request = db.setVersion('$version');
- request.on.success.add(
+ request.onSuccess.listen(
expectAsync1((e) {
createObjectStore(db);
var transaction = e.target.result;
- transaction.on.complete.add(expectAsync1((e) => step1()));
- transaction.on.error.add(fail);
+ transaction.onComplete.listen(expectAsync1((e) => step1()));
+ transaction.onError.listen(fail);
})
);
- request.on.error.add(fail);
+ request.onError.listen(fail);
} else {
step1();
}
@@ -69,12 +69,12 @@
openDb(e) {
var request = html.window.indexedDB.open(dbName, version);
expect(request, isNotNull);
- request.on.success.add(expectAsync1(initDb));
- request.on.error.add(fail);
+ request.onSuccess.listen(expectAsync1(initDb));
+ request.onError.listen(fail);
if (request is idb.OpenDBRequest) {
// New upgrade protocol. Old API has no 'upgradeNeeded' and uses
// setVersion instead.
- request.on.upgradeNeeded.add((e) {
+ request.onUpgradeNeeded.listen((e) {
guardAsync(() {
createObjectStore(e.target.result);
});
@@ -84,8 +84,8 @@
// Delete any existing DB.
var deleteRequest = html.window.indexedDB.deleteDatabase(dbName);
- deleteRequest.on.success.add(expectAsync1(openDb));
- deleteRequest.on.error.add(fail);
+ deleteRequest.onSuccess.listen(expectAsync1(openDb));
+ deleteRequest.onError.listen(fail);
};
diff --git a/tests/html/indexeddb_3_test.dart b/tests/html/indexeddb_3_test.dart
index 5a4f7e5..436b125 100644
--- a/tests/html/indexeddb_3_test.dart
+++ b/tests/html/indexeddb_3_test.dart
@@ -34,43 +34,43 @@
var request = window.indexedDB.open(DB_NAME, VERSION);
if (request is OpenDBRequest) {
// New upgrade protocol. FireFox 15, Chrome 24, hopefully IE10.
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
db = e.target.result;
afterOpen();
}));
- request.on.upgradeNeeded.add((e) {
+ request.onUpgradeNeeded.listen((e) {
guardAsync(() {
_createObjectStore(e.target.result);
});
});
- request.on.error.add(fail('open'));
+ request.onError.listen(fail('open'));
} else {
// Legacy setVersion upgrade protocol. Chrome < 23.
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
db = e.target.result;
if (db.version != '$VERSION') {
var setRequest = db.setVersion('$VERSION');
- setRequest.on.success.add(
+ setRequest.onSuccess.listen(
expectAsync1((e) {
_createObjectStore(db);
var transaction = e.target.result;
- transaction.on.complete.add(
+ transaction.onComplete.listen(
expectAsync1((e) => afterOpen()));
- transaction.on.error.add(fail('Upgrade'));
+ transaction.onError.listen(fail('Upgrade'));
}));
- setRequest.on.error.add(fail('setVersion error'));
+ setRequest.onError.listen(fail('setVersion error'));
} else {
afterOpen();
}
}));
- request.on.error.add(fail('open'));
+ request.onError.listen(fail('open'));
}
}
_createAndOpenDb(afterOpen()) {
var request = window.indexedDB.deleteDatabase(DB_NAME);
- request.on.success.add(expectAsync1((e) { _openDb(afterOpen); }));
- request.on.error.add(fail('delete old Db'));
+ request.onSuccess.listen(expectAsync1((e) { _openDb(afterOpen); }));
+ request.onError.listen(fail('delete old Db'));
}
writeItems(int index) {
@@ -78,11 +78,11 @@
var transaction = db.transaction([STORE_NAME], 'readwrite');
var request = transaction.objectStore(STORE_NAME)
.put('Item $index', index);
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
writeItems(index + 1);
}
));
- request.on.error.add(fail('put'));
+ request.onError.listen(fail('put'));
}
}
@@ -95,7 +95,7 @@
int itemCount = 0;
int sumKeys = 0;
int lastKey = null;
- cursorRequest.on.success.add(expectAsync1((e) {
+ cursorRequest.onSuccess.listen(expectAsync1((e) {
var cursor = e.target.result;
if (cursor != null) {
lastKey = cursor.key;
@@ -111,7 +111,7 @@
expect(sumKeys, (100 * 99) ~/ 2);
}
}, count:101));
- cursorRequest.on.error.add(fail('openCursor'));
+ cursorRequest.onError.listen(fail('openCursor'));
}
readAllReversedViaCursor() {
@@ -122,7 +122,7 @@
int itemCount = 0;
int sumKeys = 0;
int lastKey = null;
- cursorRequest.on.success.add(expectAsync1((e) {
+ cursorRequest.onSuccess.listen(expectAsync1((e) {
var cursor = e.target.result;
if (cursor != null) {
lastKey = cursor.key;
@@ -137,7 +137,7 @@
expect(sumKeys, (100 * 99) ~/ 2);
}
}, count:101));
- cursorRequest.on.error.add(fail('openCursor'));
+ cursorRequest.onError.listen(fail('openCursor'));
}
}
diff --git a/tests/html/indexeddb_4_test.dart b/tests/html/indexeddb_4_test.dart
index d8a1341..6704af0 100644
--- a/tests/html/indexeddb_4_test.dart
+++ b/tests/html/indexeddb_4_test.dart
@@ -32,43 +32,43 @@
var request = window.indexedDB.open(DB_NAME, VERSION);
if (request is OpenDBRequest) {
// New upgrade protocol.
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
db = e.target.result;
afterOpen();
}));
- request.on.upgradeNeeded.add((e) {
+ request.onUpgradeNeeded.listen((e) {
guardAsync(() {
_createObjectStore(e.target.result);
});
});
- request.on.error.add(fail('open'));
+ request.onError.listen(fail('open'));
} else {
// Legacy setVersion upgrade protocol.
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
db = e.target.result;
if (db.version != '$VERSION') {
var setRequest = db.setVersion('$VERSION');
- setRequest.on.success.add(
+ setRequest.onSuccess.listen(
expectAsync1((e) {
_createObjectStore(db);
var transaction = e.target.result;
- transaction.on.complete.add(
+ transaction.onComplete.listen(
expectAsync1((e) => afterOpen()));
- transaction.on.error.add(fail('Upgrade'));
+ transaction.onError.listen(fail('Upgrade'));
}));
- setRequest.on.error.add(fail('setVersion error'));
+ setRequest.onError.listen(fail('setVersion error'));
} else {
afterOpen();
}
}));
- request.on.error.add(fail('open'));
+ request.onError.listen(fail('open'));
}
}
_createAndOpenDb(afterOpen()) {
var request = window.indexedDB.deleteDatabase(DB_NAME);
- request.on.success.add(expectAsync1((e) { _openDb(afterOpen); }));
- request.on.error.add(fail('delete old Db'));
+ request.onSuccess.listen(expectAsync1((e) { _openDb(afterOpen); }));
+ request.onError.listen(fail('delete old Db'));
}
writeItems(int index) {
@@ -76,11 +76,11 @@
var transaction = db.transaction([STORE_NAME], 'readwrite');
var request = transaction.objectStore(STORE_NAME)
.put('Item $index', index);
- request.on.success.add(expectAsync1((e) {
+ request.onSuccess.listen(expectAsync1((e) {
writeItems(index + 1);
}
));
- request.on.error.add(fail('put'));
+ request.onError.listen(fail('put'));
}
}
@@ -93,7 +93,7 @@
int itemCount = 0;
int firstKey = null;
int lastKey = null;
- cursorRequest.on.success.add(expectAsync1((e) {
+ cursorRequest.onSuccess.listen(expectAsync1((e) {
var cursor = e.target.result;
if (cursor != null) {
if (firstKey == null) firstKey = cursor.key;
@@ -114,7 +114,7 @@
},
count: 1 + ((expectedFirst == null) ?
0 : (expectedLast - expectedFirst + 1))));
- cursorRequest.on.error.add(fail('openCursor'));
+ cursorRequest.onError.listen(fail('openCursor'));
}
only1() => testRange(new KeyRange.only(55), 55, 55);
diff --git a/tests/html/inner_frame_test.dart b/tests/html/inner_frame_test.dart
index ef42a84..3001925 100644
--- a/tests/html/inner_frame_test.dart
+++ b/tests/html/inner_frame_test.dart
@@ -10,7 +10,7 @@
// The child's frame should not be able to access its parent's
// document.
- window.on.message.add((Event e) {
+ window.onMessage.listen((Event e) {
switch (e.data) {
case 'frameElement': {
// Check window.frameElement.
@@ -74,13 +74,13 @@
var child;
test('prepare', () {
- iframe.on.load.add(expectAsync1((e) { child = iframe.contentWindow;}));
+ iframe.onLoad.listen(expectAsync1((e) { child = iframe.contentWindow;}));
document.body.nodes.add(iframe);
});
final validate = (testName, verify) {
final expectedVerify = expectAsync0(verify);
- window.on.message.add((e) {
+ window.onMessage.listen((e) {
guardAsync(() {
if (e.data == 'pass_$testName') {
expectedVerify();
diff --git a/tests/html/js_interop_1_test.dart b/tests/html/js_interop_1_test.dart
index 3d63ac1..3bf0951 100644
--- a/tests/html/js_interop_1_test.dart
+++ b/tests/html/js_interop_1_test.dart
@@ -19,15 +19,16 @@
var callback;
test('js-to-dart-post-message', () {
- var onSuccess = expectAsync1((e) {
- window.on.message.remove(callback);
- });
- callback = (e) {
- if (e.data == 'hello') {
- onSuccess(e);
- }
- };
- window.on.message.add(callback);
+ var subscription = null;
+ var complete = false;
+ subscription = window.onMessage.listen(expectAsyncUntil1(
+ (e) {
+ if (e.data == 'hello') {
+ subscription.cancel();
+ complete = true;
+ }
+ },
+ () => complete));
injectSource("window.postMessage('hello', '*');");
});
}
diff --git a/tests/html/keyboard_event_test.dart b/tests/html/keyboard_event_test.dart
index 0fe4fdb..da0842a 100644
--- a/tests/html/keyboard_event_test.dart
+++ b/tests/html/keyboard_event_test.dart
@@ -26,7 +26,7 @@
var controller = new KeyboardEventController.keydown(document.body);
var func = keydownHandlerTest;
controller.add(func);
- document.body.on.keyDown.add((e) => print('regular listener'), false);
+ document.body.onKeyDown.listen((e) => print('regular listener'));
});
}
diff --git a/tests/html/measurement_test.dart b/tests/html/measurement_test.dart
deleted file mode 100644
index 7d77bb8..0000000
--- a/tests/html/measurement_test.dart
+++ /dev/null
@@ -1,43 +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.
-
-library MeasurementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-
-main() {
- useHtmlConfiguration();
-
- test('measurement is async but before setTimout 0', () {
- final element = document.body;
- bool fnComplete = false;
- bool timeout0 = false;
- window.setTimeout(() { timeout0 = true; }, 0);
- final computedStyle = element.computedStyle;
- computedStyle.then(expectAsync1((style) {
- expect(style.getPropertyValue('left'), equals('auto'));
- expect(fnComplete, isTrue);
- expect(timeout0, isFalse);
- }));
- fnComplete = true;
- });
-
- test('requestLayoutFrame', () {
- var computedStyle;
- var computedStyleCalled = false;
- window.requestLayoutFrame(expectAsync0(() {
- expect(computedStyleCalled, true);
- }));
-
- final element = document.body;
- computedStyle = element.computedStyle;
- computedStyle.then(expectAsync1((style) {
- computedStyleCalled = true;
- }));
- });
-
- // TODO(jacobr): add more tests that the results return by measurement
- // functions are correct.
-}
diff --git a/tests/html/microtask_test.dart b/tests/html/microtask_test.dart
new file mode 100644
index 0000000..0dfcc53
--- /dev/null
+++ b/tests/html/microtask_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+library microtask_;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:html';
+
+main() {
+ useHtmlConfiguration();
+
+ test('setImmediate', () {
+ var timeoutCalled = false;
+ var rafCalled = false;
+ var immediateCalled = false;
+
+ window.setTimeout(expectAsync0(() {
+ timeoutCalled = true;
+ expect(immediateCalled, true);
+ }), 0);
+
+
+ window.requestAnimationFrame((_) {
+ rafCalled = true;
+ });
+
+ window.setImmediate(expectAsync0(() {
+ expect(timeoutCalled, false);
+ expect(rafCalled, false);
+ immediateCalled = true;
+ }));
+ expect(immediateCalled, false);
+ });
+}
diff --git a/tests/html/native_gc_test.dart b/tests/html/native_gc_test.dart
index e85acfb..45a89e9 100644
--- a/tests/html/native_gc_test.dart
+++ b/tests/html/native_gc_test.dart
@@ -3,6 +3,8 @@
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:html';
+var testEvent = new EventStreamProvider<Event>('test');
+
main() {
useHtmlConfiguration();
@@ -20,15 +22,15 @@
l[N - 1] = i;
div = new Element.tag('div');
- div.on['test'].add((_) {
+ testEvent.forTarget(div).listen((_) {
// Only the final iteration's listener should be invoked.
// Note: the reference to l keeps the entire list alive.
expect(l[N - 1], M - 1);
- }, false);
+ });
}
final event = new Event('test');
- div.on['test'].dispatch(event);
+ div.dispatchEvent(event);
});
test('WindowEventListener', () {
@@ -37,7 +39,7 @@
Element testDiv = new DivElement();
testDiv.id = '#TestDiv';
document.body.nodes.add(testDiv);
- window.on.message.add((e) {
+ window.onMessage.listen((e) {
if (e.data == message) testDiv.click();
});
@@ -45,7 +47,7 @@
triggerMajorGC();
}
- testDiv.on.click.add(expectAsync1((e) {}));
+ testDiv.onClick.listen(expectAsync1((e) {}));
window.postMessage(message, '*');
});
}
@@ -53,5 +55,5 @@
void triggerMajorGC() {
List list = new List.fixedLength(1000000);
Element div = new DivElement();
- div.on.click.add((e) => print(list[0]));
+ div.onClick.listen((e) => print(list[0]));
}
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index 8581dc2..0eb79f4 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -26,20 +26,18 @@
final JS_CODE = """
window.postMessage({eggs: 3}, '*');
""";
- var callback;
- var onSuccess = expectAsync1((e) {
- window.on.message.remove(callback);
- });
- callback = (e) {
- guardAsync(() {
- var data = e.data;
- if (data is String) return; // Messages from unit test protocol.
- expect(data, isMap);
- expect(data['eggs'], equals(3));
- onSuccess(e);
- });
- };
- window.on.message.add(callback);
+ var completed = false;
+ var subscription = null;
+ subscription = window.onMessage.listen(expectAsyncUntil1(
+ (e) {
+ var data = e.data;
+ if (data is String) return; // Messages from unit test protocol.
+ completed = true;
+ subscription.cancel();
+ expect(data, isMap);
+ expect(data['eggs'], equals(3));
+ },
+ () => completed));
injectSource(JS_CODE);
});
@@ -58,21 +56,19 @@
window.postMessage(response, '*');
}
""";
- var callback;
- var onSuccess = expectAsync1((e) {
- window.on.message.remove(callback);
- });
- callback = (e) {
- guardAsync(() {
- var data = e.data;
- if (data is String) return; // Messages from unit test protocol.
- expect(data, isMap);
- if (data['recipient'] != 'DART') return; // Hearing the sent message.
- expect(data['peas'], equals(50));
- onSuccess(e);
- });
- };
- window.on.message.add(callback);
+ var completed = false;
+ var subscription = null;
+ subscription = window.onMessage.listen(expectAsyncUntil1(
+ (e) {
+ var data = e.data;
+ if (data is String) return; // Messages from unit test protocol.
+ if (data['recipient'] != 'DART') return; // Hearing the sent message.
+ completed = true;
+ subscription.cancel();
+ expect(data, isMap);
+ expect(data['peas'], equals(50));
+ },
+ () => completed));
injectSource(JS_CODE);
window.postMessage({'recipient': 'JS', 'curry': 'peas'}, '*');
});
@@ -93,22 +89,21 @@
window.postMessage(response, '*');
}
""";
- var onSuccess = expectAsync0(() {});
- callback(e) {
- guardAsync(() {
- var data = e.data;
- if (data is String) return; // Messages from unit test protocol.
- expect(data, isMap);
- if (data['recipient'] != 'DART') return; // Not for me.
- var returnedValue = data['data'];
-
- window.on.message.remove(callback);
- expect(returnedValue, isNot(same(value)));
- verifyGraph(value, returnedValue);
- onSuccess();
- });
- };
- window.on.message.add(callback);
+ var completed = false;
+ var subscription = null;
+ subscription = window.onMessage.listen(expectAsyncUntil1(
+ (e) {
+ var data = e.data;
+ if (data is String) return; // Messages from unit test protocol.
+ if (data['recipient'] != 'DART') return; // Not for me.
+ completed = true;
+ subscription.cancel();
+ expect(data, isMap);
+ var returnedValue = data['data'];
+ expect(returnedValue, isNot(same(value)));
+ verifyGraph(value, returnedValue);
+ },
+ () => completed));
injectSource(JS_CODE);
window.postMessage({'recipient': 'JS', 'data': value}, '*');
});
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 07d77a6..6c75dfe 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -169,4 +169,111 @@
helper.pulse();
expect(callCountOne, 1);
});
+
+ var stream = new StreamHelper().stream;
+ // Streams have had some type-checking issues, these tests just validate that
+ // those are OK.
+ test('first', () {
+ stream.first.then((_) {});
+ });
+
+ test('asBroadcastStream', () {
+ stream.asBroadcastStream().listen((_) {});
+ });
+
+ test('where', () {
+ stream.where((_) => true).listen((_) {});
+ });
+
+ test('mappedBy', () {
+ stream.map((_) => null).listen((_) {});
+ });
+
+ test('reduce', () {
+ stream.reduce(null, (a, b) => null).then((_) {});
+ });
+
+ test('contains', () {
+ stream.contains((_) => true).then((_) {});
+ });
+
+ test('every', () {
+ stream.every((_) => true).then((_) {});
+ });
+
+ test('any', () {
+ stream.any((_) => true).then((_) {});
+ });
+
+ test('length', () {
+ stream.length.then((_) {});
+ });
+
+ test('min', () {
+ stream.min((a, b) => 0).then((_) {});
+ });
+
+ test('max', () {
+ stream.max((a, b) => 0).then((_) {});
+ });
+
+ test('isEmpty', () {
+ stream.isEmpty.then((_) {});
+ });
+
+ test('toList', () {
+ stream.toList().then((_) {});
+ });
+
+ test('toSet', () {
+ stream.toSet().then((_) {});
+ });
+
+ test('take', () {
+ stream.take(1).listen((_) {});
+ });
+
+ test('takeWhile', () {
+ stream.takeWhile((_) => false).listen((_) {});
+ });
+
+ test('skip', () {
+ stream.skip(0).listen((_) {});
+ });
+
+ test('skipWhile', () {
+ stream.skipWhile((_) => false).listen((_) {});
+ });
+
+ test('distinct', () {
+ stream.distinct((a, b) => false).listen((_) {});
+ });
+
+ test('first', () {
+ stream.first.then((_) {});
+ });
+
+ test('last', () {
+ stream.last.then((_) {});
+ });
+
+ test('single', () {
+ stream.single.then((_) {});
+ });
+
+ test('firstMatching', () {
+ stream.firstMatching((_) => true).then((_) {});
+ });
+
+ test('lastMatching', () {
+ stream.lastMatching((_) => true).then((_) {});
+ });
+
+ test('singleMatching', () {
+ stream.singleMatching((_) => true).then((_) {});
+ });
+
+ test('elementAt', () {
+ stream.elementAt(0).then((_) {});
+ });
}
diff --git a/tests/html/svg_2_test.dart b/tests/html/svg_2_test.dart
index 89f4fe2..b2c4547 100644
--- a/tests/html/svg_2_test.dart
+++ b/tests/html/svg_2_test.dart
@@ -32,7 +32,6 @@
var isSvgExternalResourcesRequired =
predicate((x) => x is svg.ExternalResourcesRequired,
'is a svg.ExternalResourcesRequired');
- var isSvgStylable = predicate((x) => x is svg.Stylable, 'is a svg.Stylable');
var isSvgTransformable =
predicate((x) => x is svg.Transformable, 'is a svg.Transformable');
var isSvgLocatable =
@@ -53,7 +52,6 @@
expect(r, isSvgTests);
expect(r, isSvgLangSpace);
expect(r, isSvgExternalResourcesRequired);
- expect(r, isSvgStylable);
expect(r, isSvgTransformable);
expect(r, isSvgLocatable);
diff --git a/tests/html/svg_3_test.dart b/tests/html/svg_3_test.dart
index 06271da..91e2eee 100644
--- a/tests/html/svg_3_test.dart
+++ b/tests/html/svg_3_test.dart
@@ -81,20 +81,6 @@
}
/**
- * Verifies that [e] supports the operations on the svg.Stylable interface.
- */
- checkSvgStylable(e) {
- var className = e.$dom_svgClassName;
- expect(className, isSvgAnimatedString);
-
- var s = e.style;
- expect(s, isCssStyleDeclaration);
-
- var attributeA = e.getPresentationAttribute('A');
- expect(attributeA, anyOf(isNull, isCssValue));
- }
-
- /**
* Verifies that [e] supports the operations on the svg.Locatable interface.
*/
checkSvgLocatable(e) {
@@ -137,7 +123,6 @@
testRect('rect_SvgLangSpace', checkSvgLangSpace);
testRect('rect_SvgExternalResourcesRequired',
checkSvgExternalResourcesRequired);
- testRect('rect_SvgStylable', checkSvgStylable);
testRect('rect_SvgLocatable', checkSvgLocatable);
testRect('rect_SvgTransformable', checkSvgTransformable);
diff --git a/tests/html/touchevent_test.dart b/tests/html/touchevent_test.dart
new file mode 100644
index 0000000..8d90e5b
--- /dev/null
+++ b/tests/html/touchevent_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library touch_event_test;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+ useHtmlIndividualConfiguration();
+
+ group('supported', () {
+ test('supported', () {
+ expect(TouchEvent.supported, true);
+ });
+ });
+
+ group('functional', () {
+ test('unsupported throws', () {
+ var expectation = TouchEvent.supported ? returnsNormally : throws;
+
+ expect(() {
+ var e = new TouchEvent(null, null, null, 'touch');
+ expect(e is TouchEvent, true);
+ }, expectation);
+ });
+ });
+}
diff --git a/tests/html/transferables_test.dart b/tests/html/transferables_test.dart
index 0a709a5..3db9c42 100644
--- a/tests/html/transferables_test.dart
+++ b/tests/html/transferables_test.dart
@@ -14,7 +14,7 @@
predicate((x) => x is ArrayBuffer, 'is an ArrayBuffer');
test('TransferableTest', () {
- window.on.message.add(expectAsync1((messageEvent) {
+ window.onMessage.listen(expectAsync1((messageEvent) {
expect(messageEvent.data, isArrayBuffer);
}));
final buffer = (new Float32Array(3)).buffer;
diff --git a/tests/html/url_test.dart b/tests/html/url_test.dart
index c52b7c6..f332b30 100644
--- a/tests/html/url_test.dart
+++ b/tests/html/url_test.dart
@@ -41,10 +41,10 @@
expect(url, startsWith('blob:'));
var img = new ImageElement();
- img.on.load.add(expectAsync1((_) {
+ img.onLoad.listen(expectAsync1((_) {
expect(img.complete, true);
}));
- img.on.error.add((_) {
+ img.onError.listen((_) {
guardAsync(() {
expect(true, isFalse, reason: 'URL failed to load.');
});
@@ -60,9 +60,9 @@
var img = new ImageElement();
// Image should fail to load since the URL was revoked.
- img.on.error.add(expectAsync1((_) {
+ img.onError.listen(expectAsync1((_) {
}));
- img.on.load.add((_) {
+ img.onLoad.listen((_) {
guardAsync(() {
expect(true, isFalse, reason: 'URL should not have loaded.');
});
diff --git a/tests/html/webgl_1_test.dart b/tests/html/webgl_1_test.dart
index 87073d3..32c076a 100644
--- a/tests/html/webgl_1_test.dart
+++ b/tests/html/webgl_1_test.dart
@@ -1,21 +1,57 @@
-library WebGL1Test;
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library web_gl_test;
import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
import 'dart:html';
// Test that WebGL is present in dart:html API
main() {
- useHtmlConfiguration();
+ useHtmlIndividualConfiguration();
- test('simple', () {
- var canvas = document.createElement("canvas");
- var gl = canvas.getContext("experimental-webgl");
- var shader = gl.createShader(WebGLRenderingContext.VERTEX_SHADER);
- gl.shaderSource(shader, "void main() { }");
- gl.compileShader(shader);
- var success =
- gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS);
- expect(success, isTrue);
+ group('supported', () {
+ test('supported', () {
+ expect(WebGLRenderingContext.supported, isTrue);
+ });
+ });
+
+ group('functional', () {
+ test('unsupported fails', () {
+ var canvas = new CanvasElement();
+ var gl = canvas.getContext3d();
+ if (WebGLRenderingContext.supported) {
+ expect(gl, isNotNull);
+ expect(gl, new isInstanceOf<WebGLRenderingContext>());
+ } else {
+ expect(gl, isNull);
+ }
+ });
+
+ if (WebGLRenderingContext.supported) {
+ test('simple', () {
+ var canvas = new CanvasElement();
+ var gl = canvas.getContext('experimental-webgl');
+ var shader = gl.createShader(WebGLRenderingContext.VERTEX_SHADER);
+ gl.shaderSource(shader, 'void main() { }');
+ gl.compileShader(shader);
+ var success =
+ gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS);
+ expect(success, isTrue);
+ });
+
+ test('getContext3d', () {
+ var canvas = new CanvasElement();
+ var gl = canvas.getContext3d();
+ expect(gl, isNotNull);
+ expect(gl, new isInstanceOf<WebGLRenderingContext>());
+
+ gl = canvas.getContext3d(depth: false);
+ expect(gl, isNotNull);
+ expect(gl, new isInstanceOf<WebGLRenderingContext>());
+ });
+ }
});
}
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index 338c618..16871b8 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -1,6 +1,6 @@
library WebDBTest;
import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
import 'dart:async';
import 'dart:html';
@@ -87,31 +87,51 @@
};
main() {
- useHtmlConfiguration();
+ useHtmlIndividualConfiguration();
- test('Web Database', () {
- final tableName = 'test_table';
- final columnName = 'test_data';
+ group('supported', () {
+ test('supported', () {
+ expect(Database.supported, true);
+ });
+ });
- final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+ group('functional', () {
+ test('unsupported throws', () {
+ var expectation = Database.supported ? returnsNormally : throws;
+ expect(() {
+ window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+ }, expectation);
- expect(db, isNotNull, reason: 'Unable to open database');
+ });
+ test('Web Database', () {
+ // Skip if not supported.
+ if (!Database.supported) {
+ return;
+ }
- createTransaction(db)
- // Attempt to clear out any tables which may be lurking from previous
- // runs.
- .then(dropTable(tableName, true))
- .then(createTable(tableName, columnName))
- .then(insert(tableName, columnName, 'Some text data'))
- .then(queryTable(tableName, (resultSet) {
- guardAsync(() {
- expect(resultSet.rows.length, 1);
- var row = resultSet.rows.item(0);
- expect(row.containsKey(columnName), isTrue);
- expect(row[columnName], 'Some text data');
- });
- }))
- .then(dropTable(tableName))
- .then(expectAsync1((tx) {}));
+ final tableName = 'test_table';
+ final columnName = 'test_data';
+
+ final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+
+ expect(db, isNotNull, reason: 'Unable to open database');
+
+ createTransaction(db)
+ // Attempt to clear out any tables which may be lurking from previous
+ // runs.
+ .then(dropTable(tableName, true))
+ .then(createTable(tableName, columnName))
+ .then(insert(tableName, columnName, 'Some text data'))
+ .then(queryTable(tableName, (resultSet) {
+ guardAsync(() {
+ expect(resultSet.rows.length, 1);
+ var row = resultSet.rows.item(0);
+ expect(row.containsKey(columnName), isTrue);
+ expect(row[columnName], 'Some text data');
+ });
+ }))
+ .then(dropTable(tableName))
+ .then(expectAsync1((tx) {}));
+ });
});
}
diff --git a/tests/html/wheelevent_test.dart b/tests/html/wheelevent_test.dart
index b4c3c9b..f5b7e2d 100644
--- a/tests/html/wheelevent_test.dart
+++ b/tests/html/wheelevent_test.dart
@@ -30,7 +30,7 @@
test('wheelEvent', () {
var element = new DivElement();
- element.on.mouseWheel.add(expectAsync1((e) {
+ element.onMouseWheel.listen(expectAsync1((e) {
expect(e.screenX, 100);
expect(e.deltaX, 0);
expect(e.deltaY, 240);
diff --git a/tests/html/xhr_cross_origin_test.dart b/tests/html/xhr_cross_origin_test.dart
index fabc5a1..3bbb5ca 100644
--- a/tests/html/xhr_cross_origin_test.dart
+++ b/tests/html/xhr_cross_origin_test.dart
@@ -38,7 +38,7 @@
expect(data['feed'], contains('entry'));
expect(data, isMap);
});
- xhr.on.readyStateChange.add((e) {
+ xhr.onReadyStateChange.listen((e) {
guardAsync(() {
if (xhr.readyState == HttpRequest.DONE) {
validate(json.parse(xhr.response));
@@ -50,7 +50,7 @@
test('XHR.get Cross-domain', () {
var url = "http://localhost:$port/tests/html/xhr_cross_origin_data.txt";
- new HttpRequest.get(url, expectAsync1((xhr) {
+ HttpRequest.request(url).then(expectAsync1((xhr) {
var data = json.parse(xhr.response);
expect(data, contains('feed'));
expect(data['feed'], contains('entry'));
@@ -60,7 +60,7 @@
test('XHR.getWithCredentials Cross-domain', () {
var url = "http://localhost:$port/tests/html/xhr_cross_origin_data.txt";
- new HttpRequest.getWithCredentials(url, expectAsync1((xhr) {
+ HttpRequest.request(url, withCredentials: true).then(expectAsync1((xhr) {
var data = json.parse(xhr.response);
expect(data, contains('feed'));
expect(data['feed'], contains('entry'));
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index c5d16a3..d590ace 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -8,6 +8,12 @@
import 'dart:html';
import 'dart:json' as json;
+void fail(message) {
+ guardAsync(() {
+ expect(false, isTrue, reason: message);
+ });
+}
+
main() {
useHtmlIndividualConfiguration();
var url = "/tests/html/xhr_cross_origin_data.txt";
@@ -35,7 +41,7 @@
test('XHR No file', () {
HttpRequest xhr = new HttpRequest();
xhr.open("GET", "NonExistingFile", true);
- xhr.on.readyStateChange.add(expectAsyncUntil1((event) {
+ xhr.onReadyStateChange.listen(expectAsyncUntil1((event) {
if (xhr.readyState == HttpRequest.DONE) {
validate404(xhr);
}
@@ -46,42 +52,90 @@
test('XHR file', () {
var xhr = new HttpRequest();
xhr.open('GET', url, true);
- xhr.on.readyStateChange.add(expectAsyncUntil1((e) {
+ xhr.onReadyStateChange.listen(expectAsyncUntil1((e) {
if (xhr.readyState == HttpRequest.DONE) {
validate200Response(xhr);
}
}, () => xhr.readyState == HttpRequest.DONE));
+
+ xhr.onLoadEnd.listen(expectAsync1((ProgressEvent e) {
+ expect(e.currentTarget, xhr);
+ expect(e.target, xhr);
+ }));
xhr.send();
});
- test('XHR.get No file', () {
- new HttpRequest.get("NonExistingFile", expectAsync1((xhr) {
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate404(xhr);
- }));
+ test('XHR.request No file', () {
+ HttpRequest.request('NonExistingFile').then(
+ (_) { fail('Request should not have succeeded.'); },
+ onError: expectAsync1((e) {
+ var xhr = e.error.target;
+ expect(xhr.readyState, equals(HttpRequest.DONE));
+ validate404(xhr);
+ }));
});
- test('XHR.get file', () {
- var xhr = new HttpRequest.get(url, expectAsync1((event) {
- expect(event.readyState, equals(HttpRequest.DONE));
- validate200Response(event);
- }));
- });
-
- test('XHR.getWithCredentials No file', () {
- new HttpRequest.getWithCredentials("NonExistingFile", expectAsync1((xhr) {
- expect(xhr.readyState, equals(HttpRequest.DONE));
- validate404(xhr);
- }));
- });
-
- test('XHR.getWithCredentials file', () {
- new HttpRequest.getWithCredentials(url, expectAsync1((xhr) {
+ test('XHR.request file', () {
+ HttpRequest.request(url).then(expectAsync1((xhr) {
expect(xhr.readyState, equals(HttpRequest.DONE));
validate200Response(xhr);
}));
});
+ test('XHR.request onProgress', () {
+ var progressCalled = false;
+ HttpRequest.request(url,
+ onProgress: (_) {
+ progressCalled = true;
+ }).then(expectAsync1(
+ (xhr) {
+ expect(xhr.readyState, equals(HttpRequest.DONE));
+ expect(progressCalled, isTrue);
+ validate200Response(xhr);
+ }));
+ });
+
+ test('XHR.request withCredentials No file', () {
+ HttpRequest.request('NonExistingFile', withCredentials: true).then(
+ (_) { fail('Request should not have succeeded.'); },
+ onError: expectAsync1((e) {
+ var xhr = e.error.target;
+ expect(xhr.readyState, equals(HttpRequest.DONE));
+ validate404(xhr);
+ }));
+ });
+
+ test('XHR.request withCredentials file', () {
+ HttpRequest.request(url, withCredentials: true).then(expectAsync1((xhr) {
+ expect(xhr.readyState, equals(HttpRequest.DONE));
+ validate200Response(xhr);
+ }));
+ });
+
+ test('XHR.getString file', () {
+ HttpRequest.getString(url).then(expectAsync1((str) {}));
+ });
+
+ test('XHR.getString No file', () {
+ HttpRequest.getString('NonExistingFile').then(
+ (_) { fail('Succeeded for non-existing file.'); },
+ onError: expectAsync1((e) {
+ validate404(e.error.target);
+ }));
+ });
+
+ test('XHR.request responseType', () {
+ if (ArrayBuffer.supported) {
+ HttpRequest.request(url, responseType: 'arraybuffer').then(
+ expectAsync1((xhr) {
+ expect(xhr.status, equals(200));
+ var arrayBuffer = xhr.response;
+ expect(arrayBuffer, new isInstanceOf<ArrayBuffer>());
+ expect(arrayBuffer, isNotNull);
+ }));
+ }
+ });
+
test('HttpRequestProgressEvent', () {
var expectation = HttpRequestProgressEvent.supported ?
returnsNormally : throws;
diff --git a/tests/html/xsltprocessor_test.dart b/tests/html/xsltprocessor_test.dart
index ea803f6..48d7b10 100644
--- a/tests/html/xsltprocessor_test.dart
+++ b/tests/html/xsltprocessor_test.dart
@@ -1,18 +1,31 @@
library XSLTProcessorTest;
import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
import 'dart:html';
main() {
- useHtmlConfiguration();
+ useHtmlIndividualConfiguration();
- var isXsltProcessor =
+ group('supported', () {
+ test('supported', () {
+ expect(XsltProcessor.supported, true);
+ });
+ });
+
+ group('functional', () {
+ var isXsltProcessor =
predicate((x) => x is XsltProcessor, 'is an XsltProcessor');
- test('constructorTest', () {
- var processor = new XsltProcessor();
- expect(processor, isNotNull);
- expect(processor, isXsltProcessor);
+ var expectation = XsltProcessor.supported ? returnsNormally : throws;
+
+ test('constructorTest', () {
+ expect(() {
+ var processor = new XsltProcessor();
+ expect(processor, isNotNull);
+ expect(processor, isXsltProcessor);
+ }, expectation);
});
+ });
+
}
diff --git a/tests/language/bailout5_test.dart b/tests/language/bailout5_test.dart
new file mode 100644
index 0000000..157e1ca
--- /dev/null
+++ b/tests/language/bailout5_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to make sure the bailout environment in dart2js is correct.
+
+var global;
+
+class A {
+ var array;
+
+ initArray() {
+ return global[0] == null ? [null] : new Map();
+ }
+
+ bar() {
+ array = initArray();
+ do {
+ var element = array[0]; // bailout here
+ if (element is Map) continue;
+ if (element == null) break;
+ } while (true);
+ return global[0]; // bailout here
+ }
+
+ baz() {
+ do {
+ var element = bar();
+ if (element == null) return global[0]; // bailout here
+ if (element is Map) continue;
+ if (element is num) break;
+ } while (true);
+ return global[0]; // bailout here
+ }
+}
+
+
+void main() {
+ global = [1];
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(1, new A().baz());
+ Expect.equals(1, new A().bar());
+ }
+ global = new Map();
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(null, new A().baz());
+ Expect.equals(null, new A().bar());
+ }
+
+ global[0] = 42;
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(42, new A().baz());
+ Expect.equals(42, new A().bar());
+ }
+}
diff --git a/tests/language/bailout6_test.dart b/tests/language/bailout6_test.dart
new file mode 100644
index 0000000..5227f65
--- /dev/null
+++ b/tests/language/bailout6_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for dart2js to make sure the computed bailout environment is
+// correct.
+
+var global;
+
+class A {
+ var array;
+
+ foo() {
+ do {
+ var element = global;
+ if (element is Map) continue;
+ if (element is num) break;
+ } while (true);
+ return array[0]; // bailout here.
+ }
+}
+
+void main() {
+ var a = new A();
+ a.array = [42];
+ global = 42;
+
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(42, a.foo());
+ }
+
+ a.array = new Map();
+ a.array[0] = 42;
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(42, a.foo());
+ }
+ global = null;
+}
diff --git a/tests/language/bailout7_test.dart b/tests/language/bailout7_test.dart
new file mode 100644
index 0000000..e61d688
--- /dev/null
+++ b/tests/language/bailout7_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to make sure the do/while loop exit condition is generated.
+
+var global;
+
+class A {
+ var array;
+
+ initArray() {
+ if (global[0] == null) {
+ return [2];
+ } else {
+ var map = new Map();
+ map[0] = 2;
+ return map;
+ }
+ }
+
+ bar() {
+ array = initArray();
+ var element;
+ do {
+ element = array[0]; // bailout here
+ if (element is Map) continue;
+ if (element == null) break;
+ } while (element != 2);
+ return global[0]; // bailout here
+ }
+}
+
+
+void main() {
+ global = [2];
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(2, new A().bar());
+ }
+
+ global = new Map();
+ global[0] = 2;
+ for (int i = 0; i < 2; i++) {
+ Expect.equals(2, new A().bar());
+ }
+}
diff --git a/tests/language/constructor8_test.dart b/tests/language/constructor8_test.dart
new file mode 100644
index 0000000..0cfcc76
--- /dev/null
+++ b/tests/language/constructor8_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to crash on this program.
+
+class A {
+ var b;
+
+ // The parameter check here used to confuse the SSA builder when it
+ // created the call to the constructor body.
+ A([Map a]) : b = ?a {
+ Expect.isTrue(b);
+ }
+
+ // The closure in the constructor body used to confuse the SSA builder
+ // when it created the call to the constructor body.
+ A.withClosure(Map a) {
+ var c;
+ var f = () { return c = 42; };
+ b = f();
+ Expect.equals(42, b);
+ Expect.equals(42, c);
+ }
+}
+
+main() {
+ new A(null);
+ new A({});
+ new A.withClosure(null);
+ new A.withClosure({});
+}
diff --git a/tests/language/double_modulo_test.dart b/tests/language/double_modulo_test.dart
new file mode 100644
index 0000000..6a9a15a
--- /dev/null
+++ b/tests/language/double_modulo_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test optimization of modulo operator on Double.
+
+main() {
+ double k = -0.33333;
+ double firstResPos = doMod(k, 1.0);
+ double firstResNeg = doMod(k, -1.0);
+ for (int i = 0; i < 5000; i++) {
+ Expect.equals(firstResPos, doMod(k, 1.0));
+ Expect.equals(firstResNeg, doMod(k, -1.0));
+ }
+}
+
+doMod(a, b) => a % b;
diff --git a/tests/language/emit_const_fields_test.dart b/tests/language/emit_const_fields_test.dart
new file mode 100644
index 0000000..17e5ab5
--- /dev/null
+++ b/tests/language/emit_const_fields_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test that used static consts are emitted.
+
+class Guide {
+ static const LTUAE = 42;
+ static const TITLE = "Life, the Universe and Everything";
+ static const EARTH = const {
+ "Sector": "ZZ9 Plural Z Alpha",
+ "Status": const [ "Scheduled for demolition", "1978-03-08" ],
+ "Description": "Mostly harmless"
+ };
+}
+
+main() {
+ Expect.isTrue(42 == Guide.LTUAE);
+ Expect.isTrue("1978-03-08" == Guide.EARTH["Status"][1]);
+}
+
diff --git a/tests/language/language.status b/tests/language/language.status
index 43ca19a..85b14a8 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -109,9 +109,13 @@
list_literal1_negative_test: Fail
map_literal1_negative_test: Fail
+
+# test issue 8129
+redirecting_factory_infinite_steps_test/01: Fail
+
+
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
implicit_this_test/none: Fail # should not warn about allocating SubAbstract2
metadata_test: Fail
const_locals_test: Fail
@@ -292,8 +296,10 @@
# test issue 7523 (const declared without type, so not-a-function warning should not be reported)
call_through_getter_test: Fail
-mixin_illegal_cycles_test/01: Fail # issue 8027
-mixin_illegal_cycles_test/02: Fail # issue 8027
+
+# test issue 8127 (using mixin application as mixin)
+mixin_mixin_test: Fail
+
#
# Add new dartc annotations above in alphabetical order
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 0f9ec67..6551691 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -115,7 +115,6 @@
bad_constructor_test/06: Fail # http://dartbug.com/5519
call_nonexistent_constructor_test: Fail
constructor_named_arguments_test/01: Fail # http://dartbug.com/5519
-external_test/10: Fail # http://dartbug.com/5519
getter_no_setter2_test/01: Fail # http://dartbug.com/5519
getter_no_setter_test/01: Fail # http://dartbug.com/5519
illegal_invocation_test/03: Fail # http://dartbug.com/5519
@@ -350,6 +349,7 @@
expect_test: Fail
factory3_test: Fail
stack_overflow_test: Fail
+stack_overflow_stacktrace_test: Fail
type_checks_in_factory_method_test: Fail
@@ -374,6 +374,7 @@
method_invocation_test: Fail
null_pointer_exception_test: Fail
stack_overflow_test: Fail
+stack_overflow_stacktrace_test: Fail
string_interpolate_npe_test: Fail
closure_call_wrong_argument_count_negative_test: Skip
label_test: Skip
diff --git a/tests/language/modulo_test.dart b/tests/language/modulo_test.dart
index 70e1a9f..7fac3bc 100644
--- a/tests/language/modulo_test.dart
+++ b/tests/language/modulo_test.dart
@@ -1,7 +1,7 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Dart test optimization of modulo oeprator on Smi.
+// Dart test optimization of modulo operator on Smi.
main() {
diff --git a/tests/language/stack_overflow_stacktrace_test.dart b/tests/language/stack_overflow_stacktrace_test.dart
new file mode 100644
index 0000000..3bef1d6
--- /dev/null
+++ b/tests/language/stack_overflow_stacktrace_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart program testing stack overflow.
+
+class StackOverflowTest {
+
+ static void curseTheRecurse(a, b, c) {
+ curseTheRecurse(b, c, a);
+ }
+
+ static void testMain() {
+ bool exceptionCaught = false;
+ try {
+ curseTheRecurse(1, 2, 3);
+ } on StackOverflowError catch (e, stacktrace) {
+ String s = stacktrace.toString();
+ Expect.equals(-1, s.indexOf("-1:-1"));
+ exceptionCaught = true;
+ }
+ Expect.equals(true, exceptionCaught);
+ }
+}
+
+main() {
+ StackOverflowTest.testMain();
+}
diff --git a/tests/language/type_variable_initializer_test.dart b/tests/language/type_variable_initializer_test.dart
new file mode 100644
index 0000000..721be03
--- /dev/null
+++ b/tests/language/type_variable_initializer_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js where the reference to [:this:] in a
+// constructor was not propagated to the super initializers.
+
+class A<T> {
+ var map;
+ // Usage of type variables in the intializer makes the SSA builder
+ // want to access [:this:]. And because the initializers of A are
+ // inlined in the constructor of B, we have to make sure the
+ // [:this:] in the A constructor has a corresponding
+ // SSA instruction.
+ A() : map = new Map<T, T>();
+}
+
+class B<T> extends A<T> {
+}
+
+main() {
+ Expect.isTrue(new B<int>().map is Map<int, int>);
+}
diff --git a/tests/language/typedef_is_test.dart b/tests/language/typedef_is_test.dart
new file mode 100644
index 0000000..56c6d37
--- /dev/null
+++ b/tests/language/typedef_is_test.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 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 is-test of typedefs with optional and named parameters.
+
+typedef int Func1(int a);
+typedef int Func2(int a, [int b]);
+typedef int Func3(int a, [int b, int c]);
+typedef int Func4([int a, int b, int c]);
+typedef int Func5(int a, {int b});
+typedef int Func6(int a, {int b, int c});
+typedef int Func7({int a, int b, int c});
+
+void main() {
+ int func1(int i) {}
+ Expect.isTrue(func1 is Func1);
+ Expect.isFalse(func1 is Func2);
+ Expect.isFalse(func1 is Func3);
+ Expect.isFalse(func1 is Func4);
+ Expect.isFalse(func1 is Func5);
+ Expect.isFalse(func1 is Func6);
+ Expect.isFalse(func1 is Func7);
+
+ int func2(int i, int j) {}
+ Expect.isFalse(func2 is Func1);
+ Expect.isFalse(func2 is Func2);
+ Expect.isFalse(func2 is Func3);
+ Expect.isFalse(func2 is Func4);
+ Expect.isFalse(func2 is Func5);
+ Expect.isFalse(func2 is Func6);
+ Expect.isFalse(func2 is Func7);
+
+ int func3(int i, int j, int k) {}
+ Expect.isFalse(func3 is Func1);
+ Expect.isFalse(func3 is Func2);
+ Expect.isFalse(func3 is Func3);
+ Expect.isFalse(func3 is Func4);
+ Expect.isFalse(func3 is Func5);
+ Expect.isFalse(func3 is Func6);
+ Expect.isFalse(func3 is Func7);
+
+ int func4(int i, [int j]) {}
+ Expect.isTrue(func4 is Func1);
+ Expect.isTrue(func4 is Func2);
+ Expect.isFalse(func4 is Func3);
+ Expect.isFalse(func4 is Func4);
+ Expect.isFalse(func4 is Func5);
+ Expect.isFalse(func4 is Func6);
+ Expect.isFalse(func4 is Func7);
+
+ int func5(int i, [int j, int k]) {}
+ Expect.isTrue(func5 is Func1);
+ Expect.isTrue(func5 is Func2);
+ Expect.isTrue(func5 is Func3);
+ Expect.isFalse(func5 is Func4);
+ Expect.isFalse(func5 is Func5);
+ Expect.isFalse(func5 is Func6);
+ Expect.isFalse(func5 is Func7);
+
+ int func6([int i, int j, int k]) {}
+ Expect.isFalse(func6 is Func1);
+ Expect.isFalse(func6 is Func2);
+ Expect.isFalse(func6 is Func3);
+ Expect.isTrue(func6 is Func4);
+ Expect.isFalse(func6 is Func5);
+ Expect.isFalse(func6 is Func6);
+ Expect.isFalse(func6 is Func7);
+
+ int func7(int i, {int j}) {}
+ Expect.isTrue(func7 is Func1);
+ Expect.isFalse(func7 is Func2);
+ Expect.isFalse(func7 is Func3);
+ Expect.isFalse(func7 is Func4);
+ Expect.isFalse(func7 is Func5);
+ Expect.isFalse(func7 is Func6);
+ Expect.isFalse(func7 is Func7);
+
+ int func8(int i, {int b}) {}
+ Expect.isTrue(func8 is Func1);
+ Expect.isFalse(func8 is Func2);
+ Expect.isFalse(func8 is Func3);
+ Expect.isFalse(func8 is Func4);
+ Expect.isTrue(func8 is Func5);
+ Expect.isFalse(func8 is Func6);
+ Expect.isFalse(func8 is Func7);
+
+ int func9(int i, {int b, int c}) {}
+ Expect.isTrue(func9 is Func1);
+ Expect.isFalse(func9 is Func2);
+ Expect.isFalse(func9 is Func3);
+ Expect.isFalse(func9 is Func4);
+ Expect.isTrue(func9 is Func5);
+ Expect.isTrue(func9 is Func6);
+ Expect.isFalse(func9 is Func7);
+
+ int func10(int i, {int c, int b}) {}
+ Expect.isTrue(func10 is Func1);
+ Expect.isFalse(func10 is Func2);
+ Expect.isFalse(func10 is Func3);
+ Expect.isFalse(func10 is Func4);
+ Expect.isTrue(func10 is Func5);
+ Expect.isTrue(func10 is Func6);
+ Expect.isFalse(func10 is Func7);
+
+ int func11({int a, int b, int c}) {}
+ Expect.isFalse(func11 is Func1);
+ Expect.isFalse(func11 is Func2);
+ Expect.isFalse(func11 is Func3);
+ Expect.isFalse(func11 is Func4);
+ Expect.isFalse(func11 is Func5);
+ Expect.isFalse(func11 is Func6);
+ Expect.isTrue(func11 is Func7);
+
+ int func12({int c, int a, int b}) {}
+ Expect.isFalse(func12 is Func1);
+ Expect.isFalse(func12 is Func2);
+ Expect.isFalse(func12 is Func3);
+ Expect.isFalse(func12 is Func4);
+ Expect.isFalse(func12 is Func5);
+ Expect.isFalse(func12 is Func6);
+ Expect.isTrue(func12 is Func7);
+}
\ No newline at end of file
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index 844721b6..e6816e6 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -6,7 +6,7 @@
import 'dart:async';
-class Event {
+abstract class Event {
void replay(StreamSink sink);
}
@@ -121,9 +121,6 @@
throw new StateError("Not capturing events.");
}
- /** Whether the underlying subscription has been paused. */
- bool get isPaused => false;
-
/**
* Sets an action to be called when this [Events] receives a 'done' event.
*/
@@ -165,8 +162,6 @@
subscription.resume();
}
- bool get isPaused => subscription.isPaused;
-
void onDone(void action()) {
onDoneSignal.future.whenComplete(action);
}
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 373a131..19c09f8 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -16,6 +16,31 @@
});
}
+testOf() {
+ compare(func) {
+ // Compare the results of the following two futures.
+ Future f1 = new Future.of(func);
+ Future f2 = new Future.immediate(null).then((_) => func());
+ f2.catchError((_){}); // I'll get the error later.
+ f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); },
+ onError: (e1) {
+ f2.then((_) { Expect.fail("Expected error"); },
+ onError: (e2) {
+ Expect.equals(e1.error, e2.error);
+ });
+ });
+ }
+ Future val = new Future.immediate(42);
+ Future err1 = new Future.immediateError("Error")..catchError((_){});
+ Future err2 = new Future.immediateError(new AsyncError("AsyncError"))..catchError((_){});
+ compare(() => 42);
+ compare(() => val);
+ compare(() { throw "Flif"; });
+ compare(() { throw new AsyncError("AsyncFlif"); });
+ compare(() => err1);
+ compare(() => err2);
+}
+
testNeverComplete() {
final completer = new Completer<int>();
final future = completer.future;
@@ -559,6 +584,7 @@
main() {
testImmediate();
+ testOf();
testNeverComplete();
testComplete();
@@ -599,3 +625,4 @@
testChainedFutureError();
}
+
diff --git a/tests/lib/async/merge_stream_test.dart b/tests/lib/async/merge_stream_test.dart
deleted file mode 100644
index 924f5d3..0000000
--- a/tests/lib/async/merge_stream_test.dart
+++ /dev/null
@@ -1,174 +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.
-
-// Test merging streams.
-library merge_stream_test;
-
-import "dart:async";
-import '../../../pkg/unittest/lib/unittest.dart';
-import 'event_helper.dart';
-
-testSupercedeStream() {
- { // Simple case of superceding lower priority streams.
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
- Events expected = new Events()..add(1)..add(2)..add(3)..add(4)..close();
- Events actual = new Events.capture(merge);
- s1.add(1);
- s2.add(2);
- s1.add(1); // Ignored.
- s2.add(3);
- s3.add(4);
- s2.add(3); // Ignored.
- s3.close();
- Expect.listEquals(expected.events, actual.events);
- }
-
- { // Superceding more than one stream at a time.
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
- Events expected = new Events()..add(1)..add(2)..close();
- Events actual = new Events.capture(merge);
- s1.add(1);
- s3.add(2);
- s1.add(1); // Ignored.
- s2.add(1); // Ignored.
- s3.close();
- Expect.listEquals(expected.events, actual.events);
- }
-
- { // Closing a stream before superceding it.
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
- Events expected = new Events()..add(1)..add(2)..add(3)..close();
- Events actual = new Events.capture(merge);
- s1.add(1);
- s1.close();
- s3.close();
- s2.add(2);
- s2.add(3);
- s2.close();
- Expect.listEquals(expected.events, actual.events);
- }
-
- { // Errors from all non-superceded streams are forwarded.
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
- Events expected =
- new Events()..add(1)..error("1")..error("2")..error("3")
- ..add(3)..error("6")..add(4)..close();
- Events actual = new Events.capture(merge);
- s1.add(1);
- s1.signalError(new AsyncError("1"));
- s2.signalError(new AsyncError("2"));
- s3.signalError(new AsyncError("3"));
- s3.add(3);
- s1.signalError(new AsyncError("4"));
- s2.signalError(new AsyncError("5"));
- s3.signalError(new AsyncError("6"));
- s1.close();
- s2.close();
- s3.add(4);
- s3.close();
- Expect.listEquals(expected.events, actual.events);
- }
-
- test("Pausing on a superceding stream", () {
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
- Events expected = new Events()..add(1)..add(2)..add(3);
- Events actual = new Events.capture(merge);
- s1.add(1);
- s2.add(2);
- s2.add(3);
- Expect.listEquals(expected.events, actual.events);
- actual.pause(); // Pauses the stream that feeds the actual Events.
- Events expected2 = expected.copy();
- expected..add(5)..add(6)..close();
- expected2..add(6)..close();
- s1.add(4);
- s2.add(5); // May or may not arrive before '6' when resuming.
- s3.add(6);
- s3.close();
- actual.onDone(expectAsync0(() {
- if (expected.events.length == actual.events.length) {
- Expect.listEquals(expected.events, actual.events);
- } else {
- Expect.listEquals(expected2.events, actual.events);
- }
- }));
- actual.resume();
- });
-}
-
-void testCyclicStream() {
- test("Simple case of superceding lower priority streams", () {
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.cyclic([s1.stream, s2.stream, s3.stream]);
- Events expected =
- new Events()..add(1)..add(2)..add(3)..add(4)..add(5)..add(6)..close();
- Events actual = new Events.capture(merge);
- Expect.isFalse(s1.isPaused);
- Expect.isTrue(s2.isPaused);
- Expect.isTrue(s3.isPaused);
- s3.add(3);
- s1.add(1);
- s1.add(4);
- s1.add(6);
- s1.close();
- s2.add(2);
- s2.add(5);
- s2.close();
- s3.close();
- actual.onDone(expectAsync0(() {
- Expect.listEquals(expected.events, actual.events);
- }));
- });
-
- test("Cyclic merge with errors", () {
- StreamController s1 = new StreamController.broadcast();
- StreamController s2 = new StreamController.broadcast();
- StreamController s3 = new StreamController.broadcast();
- Stream merge = new Stream.cyclic([s1.stream, s2.stream, s3.stream]);
- Events expected =
- new Events()..add(1)..error("1")..add(2)..add(3)..error("2")
- ..add(4)..add(5)..error("3")..add(6)..close();
- Events actual = new Events.capture(merge);
- Expect.isFalse(s1.isPaused);
- Expect.isTrue(s2.isPaused);
- Expect.isTrue(s3.isPaused);
- s3.add(3);
- s3.signalError(new AsyncError("3")); // Error just before a "done".
- s1.add(1);
- s1.signalError(new AsyncError("2")); // Error between events.
- s1.add(4);
- s1.add(6);
- s1.close();
- s2.signalError(new AsyncError("1")); // Error as first event.
- s2.add(2);
- s2.add(5);
- s2.close();
- s3.close();
- actual.onDone(expectAsync0(() {
- Expect.listEquals(expected.events, actual.events);
- }));
- });
-}
-
-main() {
- testSupercedeStream();
- testCyclicStream();
-}
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index d35e0c1..79b8568 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -439,7 +439,7 @@
}
testStream("where", (s, act) => s.where(act));
- testStream("mappedBy", (s, act) => s.mappedBy(act));
+ testStream("mappedBy", (s, act) => s.map(act));
testStream("expand", (s, act) => s.expand(act));
testStream("where", (s, act) => s.where(act));
testStreamError("handleError", (s, act) => s.handleError(act));
diff --git a/tests/lib/async/stream_controller_test.dart b/tests/lib/async/stream_controller_test.dart
index 9dd7509..8cfabf5 100644
--- a/tests/lib/async/stream_controller_test.dart
+++ b/tests/lib/async/stream_controller_test.dart
@@ -53,7 +53,7 @@
c = new StreamController.broadcast();
expectedEvents = new Events()..add("abab")..error("error")..close();
sentEvents = new Events()..add("ab")..error("error")..close();
- actualEvents = new Events.capture(c.stream.mappedBy((v) => "$v$v"));
+ actualEvents = new Events.capture(c.stream.map((v) => "$v$v"));
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
@@ -93,10 +93,10 @@
expectedEvents =
new Events()..error("a")..add(42)..error("b")..add("foo")..close();
actualEvents = new Events.capture(c.stream.transform(
- new StreamTransformer.from(
- onData: (v, s) { s.signalError(new AsyncError(v)); },
- onError: (e, s) { s.add(e.error); },
- onDone: (s) {
+ new StreamTransformer(
+ handleData: (v, s) { s.signalError(new AsyncError(v)); },
+ handleError: (e, s) { s.add(e.error); },
+ handleDone: (s) {
s.add("foo");
s.close();
})));
@@ -114,7 +114,7 @@
expectedEvents = new Events()..add(42)..error("not FormatException");
actualEvents = new Events.capture(
c.stream.where((v) => v is String)
- .mappedBy((v) => int.parse(v))
+ .map((v) => int.parse(v))
.handleError((v) {
if (v.error is! FormatException) throw v;
})
@@ -194,7 +194,7 @@
c = new StreamController();
expectedEvents = new Events()..add("abab")..error("error")..close();
sentEvents = new Events()..add("ab")..error("error")..close();
- actualEvents = new Events.capture(c.stream.mappedBy((v) => "$v$v"));
+ actualEvents = new Events.capture(c.stream.map((v) => "$v$v"));
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
@@ -240,16 +240,52 @@
c.add(9);
c.close();
+ // test contains.
+ {
+ c = new StreamController();
+ // Error after match is not important.
+ sentEvents = new Events()..add("a")..add("x")..error("FAIL")..close();
+ Future<bool> contains = c.stream.contains("x");
+ contains.then((var c) {
+ Expect.isTrue(c);
+ });
+ sentEvents.replay(c);
+ }
+
+ {
+ c = new StreamController();
+ // Not matching is ok.
+ sentEvents = new Events()..add("a")..add("x")..add("b")..close();
+ Future<bool> contains = c.stream.contains("y");
+ contains.then((var c) {
+ Expect.isFalse(c);
+ });
+ sentEvents.replay(c);
+ }
+
+ {
+ c = new StreamController();
+ // Error before match makes future err.
+ sentEvents = new Events()..add("a")..error("FAIL")..add("b")..close();
+ Future<bool> contains = c.stream.contains("b");
+ contains.then((var c) {
+ Expect.fail("no value expected");
+ }).catchError((AsyncError e) {
+ Expect.equals("FAIL", e.error);
+ });
+ sentEvents.replay(c);
+ }
+
// Test transform.
c = new StreamController();
sentEvents = new Events()..add("a")..error(42)..add("b")..close();
expectedEvents =
new Events()..error("a")..add(42)..error("b")..add("foo")..close();
actualEvents = new Events.capture(c.stream.transform(
- new StreamTransformer.from(
- onData: (v, s) { s.signalError(new AsyncError(v)); },
- onError: (e, s) { s.add(e.error); },
- onDone: (s) {
+ new StreamTransformer(
+ handleData: (v, s) { s.signalError(new AsyncError(v)); },
+ handleError: (e, s) { s.add(e.error); },
+ handleDone: (s) {
s.add("foo");
s.close();
})));
@@ -267,7 +303,7 @@
expectedEvents = new Events()..add(42)..error("not FormatException");
actualEvents = new Events.capture(
c.stream.where((v) => v is String)
- .mappedBy((v) => int.parse(v))
+ .map((v) => int.parse(v))
.handleError((v) {
if (v.error is! FormatException) throw v;
})
diff --git a/tests/lib/async/stream_event_transform_test.dart b/tests/lib/async/stream_event_transform_test.dart
new file mode 100644
index 0000000..debc2c0c
--- /dev/null
+++ b/tests/lib/async/stream_event_transform_test.dart
@@ -0,0 +1,81 @@
+// 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.
+
+library stream_event_transform_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+import 'event_helper.dart';
+
+void handleData(int data, StreamSink<int> sink) {
+ sink.signalError(new AsyncError("$data"));
+ sink.add(data + 1);
+}
+
+void handleError(AsyncError e, StreamSink<int> sink) {
+ String value = e.error;
+ int data = int.parse(value);
+ sink.add(data);
+ sink.signalError(new AsyncError("${data + 1}"));
+}
+
+void handleDone(StreamSink<int> sink) {
+ sink.add(99);
+ sink.close();
+}
+
+class EventTransformer extends StreamEventTransformer<int,int> {
+ void handleData(int data, StreamSink<int> sink) {
+ sink.signalError(new AsyncError("$data"));
+ sink.add(data + 1);
+ }
+
+ void handleError(AsyncError e, StreamSink<int> sink) {
+ String value = e.error;
+ int data = int.parse(value);
+ sink.add(data);
+ sink.signalError(new AsyncError("${data + 1}"));
+ }
+
+ void handleDone(StreamSink<int> sink) {
+ sink.add(99);
+ sink.close();
+ }
+}
+
+main() {
+ {
+ StreamController c = new StreamController();
+ Events expected = new Events()..error("0")..add(1)
+ ..error("1")..add(2)
+ ..add(3)..error("4")
+ ..add(99)..close();
+ Events input = new Events()..add(0)..add(1)..error("3")..close();
+ Events actual = new Events.capture(
+ c.stream.transform(new EventTransformer()));
+ actual.onDone(() {
+ Expect.listEquals(expected.events, actual.events);
+ });
+ input.replay(c);
+ }
+
+ {
+ StreamController c = new StreamController();
+ Events expected = new Events()..error("0")..add(1)
+ ..error("1")..add(2)
+ ..add(3)..error("4")
+ ..add(99)..close();
+ Events input = new Events()..add(0)..add(1)..error("3")..close();
+ Events actual = new Events.capture(
+ c.stream.transform(new StreamTransformer(
+ handleData: handleData,
+ handleError: handleError,
+ handleDone: handleDone
+ )));
+ actual.onDone(() {
+ Expect.listEquals(expected.events, actual.events);
+ });
+ input.replay(c);
+ }
+}
diff --git a/tests/lib/async/stream_from_iterable_test.dart b/tests/lib/async/stream_from_iterable_test.dart
index f724bf4..182bf1c 100644
--- a/tests/lib/async/stream_from_iterable_test.dart
+++ b/tests/lib/async/stream_from_iterable_test.dart
@@ -33,7 +33,7 @@
new IterableTest<String>(["one", "two", "three", "four"]).run();
new IterableTest<int>(new Iterable<int>.generate(1000, (i) => i)).run();
new IterableTest<String>(new Iterable<int>.generate(1000, (i) => i)
- .mappedBy((i) => "$i")).run();
+ .map((i) => "$i")).run();
Iterable<int> iter = new Iterable.generate(25, (i) => i * 2);
@@ -47,10 +47,10 @@
test("iterable-mapped-toList", () {
new Stream.fromIterable(iter)
- .mappedBy((i) => i * 3)
+ .map((i) => i * 3)
.toList()
.then(expectAsync1((actual) {
- List expected = iter.mappedBy((i) => i * 3).toList();
+ List expected = iter.map((i) => i * 3).toList();
Expect.listEquals(expected, actual);
}));
});
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index 82a115b..6a38ca4 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -8,7 +8,7 @@
import "dart:io";
import "dart:utf";
-import "dart:json";
+import "dart:json" as JSON;
// TODO(hausner): need to select a different port number for each
// test that runs in parallel.
@@ -430,7 +430,7 @@
if (errorsDetected) {
error("Error while handling script entry ${script.currentIndex}");
error("Message received from debug target: $msg");
- close();
+ close(killDebugee: true);
return;
}
if (shutdownEventSeen) {
@@ -471,27 +471,29 @@
handleMessages();
} catch(e, trace) {
print("Unexpected exception:\n$e\n$trace");
- close();
+ close(killDebugee: true);
}
};
from.onClosed = () {
print("Connection closed by debug target");
- close();
+ close(killDebugee: true);
};
from.onError = (e) {
print("Error '$e' detected in input stream from debug target");
- close();
+ close(killDebugee: true);
};
}
- void close() {
+ void close({killDebugee: false}) {
if (errorsDetected) {
for (int i = 0; i < errors.length; i++) print(errors[i]);
}
to.close();
socket.close();
- targetProcess.kill();
- print("Target process killed");
+ if (killDebugee) {
+ targetProcess.kill();
+ print("Target process killed");
+ }
Expect.isTrue(!errorsDetected);
stdin.close();
stdout.close();
@@ -519,11 +521,12 @@
process.stdout.onData = process.stdout.read;
process.stderr.onData = process.stderr.read;
process.onExit = (int exitCode) {
+ Expect.equals(0, exitCode);
print("Debug target process exited with exit code $exitCode");
};
var debugger = new Debugger(process, debugPort);
- stdin.onClosed = () => debugger.close();
- stdin.onError = (error) => debugger.close();
+ stdin.onClosed = () => debugger.close(killDebugee: true);
+ stdin.onError = (error) => debugger.close(killDebugee: true);
debugger.runScript(script);
});
return true;
diff --git a/tests/standalone/int_array_deopt.dart b/tests/standalone/int_array_deopt.dart
new file mode 100644
index 0000000..4f4bf89
--- /dev/null
+++ b/tests/standalone/int_array_deopt.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart deoptimization of Uint32Array and Int32Array loads.
+
+import 'dart:scalarlist';
+
+loadI32(a) => a[0] + 1;
+loadUi32(a) => a[0] + 1;
+
+main() {
+ var i32 = new Int32List(10);
+ var ui32 = new Uint32List(10);
+ i32[0] = ui32[0] = 8;
+ // Optimize loadI32 and LoadUi32 for Smi result of indexed load.
+ for (int i = 0; i < 2000; i++) {
+ Expect.equals(9, loadI32(i32));
+ Expect.equals(9, loadUi32(ui32));
+ }
+ // On ia32, deoptimize when attempting to load a value that exceeds
+ // Smi range.
+ i32[0] = ui32[0] = 2147483647;
+ Expect.equals(2147483648, loadI32(i32));
+ Expect.equals(2147483648, loadUi32(ui32));
+ // Reoptimize again, but this time assume mixed Smi/Mint results
+ i32[0] = ui32[0] = 10;
+ for (int i = 0; i < 2000; i++) {
+ Expect.equals(11, loadI32(i32));
+ Expect.equals(11, loadUi32(ui32));
+ }
+}
diff --git a/tests/standalone/io/skipping_dart2js_compilations_test.dart b/tests/standalone/io/skipping_dart2js_compilations_test.dart
index 9409fc0..74058a7 100644
--- a/tests/standalone/io/skipping_dart2js_compilations_test.dart
+++ b/tests/standalone/io/skipping_dart2js_compilations_test.dart
@@ -206,8 +206,9 @@
fs_upToDate.touchFile(fs_upToDate.testJs);
void runTest(String name, FileUtils fileUtils, bool shouldRun) {
- new runner.RunningProcess(makeTestCase(name,
- new TestCompletedHandler(fileUtils, shouldRun))).start();
+ var testCase = makeTestCase(
+ name, new TestCompletedHandler(fileUtils, shouldRun));
+ new runner.RunningProcess(testCase, testCase.commands[0]).start();
}
runTest("fs_noTestJs", fs_noTestJs, true);
runTest("fs_noTestJsDeps", fs_noTestJsDeps, true);
diff --git a/tests/standalone/io/test_extension_fail_test.dart b/tests/standalone/io/test_extension_fail_test.dart
index 0bde0a9..7109416 100644
--- a/tests/standalone/io/test_extension_fail_test.dart
+++ b/tests/standalone/io/test_extension_fail_test.dart
@@ -59,6 +59,7 @@
print("ERR: ${result.stderr}\n\n");
print("OUT: ${result.stdout}\n\n");
Expect.equals(255, result.exitCode);
- Expect.isTrue(result.stderr.contains("Unhandled exception:\nball\n"));
+ Expect.isTrue(result.stderr.contains("Unhandled exception:"));
+ Expect.isTrue(result.stderr.contains("ball"));
}).whenComplete(() => tempDirectory.deleteSync(recursive: true));
}
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index c492161..65a0ea9 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -2,74 +2,99 @@
// for 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:isolate";
import "dart:async";
import "dart:utf";
import "../../../tools/testing/dart/test_runner.dart";
+import "../../../tools/testing/dart/test_suite.dart";
import "../../../tools/testing/dart/status_file_parser.dart";
import "../../../tools/testing/dart/test_options.dart";
import "process_test_util.dart";
+final DEFAULT_TIMEOUT = 2;
+final LONG_TIMEOUT = 30;
+
class TestController {
- static const int numTests = 4;
+ static int numTests = 0;
static int numCompletedTests = 0;
// Used as TestCase.completedCallback.
static processCompletedTest(TestCase testCase) {
+ numCompletedTests++;
CommandOutput output = testCase.lastCommandOutput;
- print("Test: ${testCase.commands.last.commandLine}");
- if (output.unexpectedOutput) {
- throw "Unexpected output: ${output.result}";
+ if (testCase.displayName == "fail-unexpected") {
+ Expect.isTrue(output.unexpectedOutput);
+ } else {
+ Expect.isFalse(output.unexpectedOutput);
}
- print("stdout: ");
- print(decodeUtf8(output.stdout));
- print("stderr: ");
- print(decodeUtf8(output.stderr));
+ }
- print("Time: ${output.time}");
- print("Exit code: ${output.exitCode}");
-
- ++numCompletedTests;
- print("$numCompletedTests/$numTests");
- if (numCompletedTests == numTests) {
- print("test_runner_test.dart PASSED");
- }
+ static void finished() {
+ Expect.equals(numTests, numCompletedTests);
}
}
-TestCase MakeTestCase(String testName, List<String> expectations) {
- var configuration = new TestOptionsParser().parse(['--timeout', '2'])[0];
- return new TestCase(testName,
- [new Command(new Options().executable,
- <String>[new Options().script,
- testName])],
- configuration,
- TestController.processCompletedTest,
- new Set<String>.from(expectations));
+
+class CustomTestSuite extends TestSuite {
+ CustomTestSuite() : super({}, "CustomTestSuite");
+
+ void forEachTest(TestCaseEvent onTest, Map testCache, [onDone]) {
+ void enqueueTestCase(testCase) {
+ TestController.numTests++;
+ onTest(testCase);
+ }
+
+ var testCaseCrash = _makeCrashTestCase("crash", [CRASH]);
+ var testCasePass = _makeNormalTestCase("pass", [PASS]);
+ var testCaseFail = _makeNormalTestCase("fail", [FAIL]);
+ var testCaseTimeout = _makeNormalTestCase("timeout", [TIMEOUT]);
+ var testCaseFailUnexpected =
+ _makeNormalTestCase("fail-unexpected", [PASS]);
+
+ enqueueTestCase(testCaseCrash);
+ enqueueTestCase(testCasePass);
+ enqueueTestCase(testCaseFail);
+ enqueueTestCase(testCaseTimeout);
+ enqueueTestCase(testCaseFailUnexpected);
+
+ if (onDone != null) {
+ onDone();
+ }
+ }
+
+ TestCase _makeNormalTestCase(name, expectations) {
+ var command = new Command(new Options().executable,
+ [new Options().script, name]);
+ return _makeTestCase(name, DEFAULT_TIMEOUT, command, expectations);
+ }
+
+ _makeCrashTestCase(name, expectations) {
+ var crashCommand = new Command(getProcessTestFileName(),
+ ["0", "0", "1", "1"]);
+ // The crash test sometimes times out. Run it with a large timeout
+ // to help diagnose the delay.
+ // The test loads a new executable, which may sometimes take a long time.
+ // It involves a wait on the VM event loop, and possible system
+ // delays.
+ return _makeTestCase(name, LONG_TIMEOUT, crashCommand, expectations);
+ }
+
+ _makeTestCase(name, timeout, command, expectations) {
+ var configuration = new TestOptionsParser()
+ .parse(['--timeout', '$timeout'])[0];
+ return new TestCase(name,
+ [command],
+ configuration,
+ TestController.processCompletedTest,
+ new Set<String>.from(expectations));
+ }
}
-void testTestRunner() {
- new RunningProcess(MakeTestCase("pass", [PASS])).start();
- new RunningProcess(MakeTestCase("fail", [FAIL])).start();
- new RunningProcess(MakeTestCase("timeout", [TIMEOUT])).start();
-
- // The crash test sometimes times out. Run it with a large timeout to help
- // diagnose the delay.
- // The test loads a new executable, which may sometimes take a long time.
- // It involves a wait on the VM event loop, and possible system delays.
- var configuration = new TestOptionsParser().parse(['--timeout', '60'])[0];
- new RunningProcess(new TestCase("CrashTest",
- [new Command(getProcessTestFileName(),
- const ["0", "0", "1", "1"])],
- configuration,
- TestController.processCompletedTest,
- new Set<String>.from([CRASH]))).start();
- Expect.equals(4, TestController.numTests);
- // Test that the test runner throws an exception if a test with
- // expectation SKIP is run. The RunningProcess constructor must throw
- // the exception synchronously, for it to be caught here at the call site.
- Expect.throws(new RunningProcess(MakeTestCase("pass", [SKIP])).start);
+void testProcessQueue() {
+ var maxProcesses = 2;
+ var maxBrowserProcesses = maxProcesses;
+ new ProcessQueue(maxProcesses, maxBrowserProcesses, "silent",
+ new Date.now(), false, [new CustomTestSuite()], TestController.finished);
}
void main() {
@@ -78,14 +103,15 @@
// fail, or timeout.
var arguments = new Options().arguments;
if (arguments.isEmpty) {
- testTestRunner();
+ testProcessQueue();
} else {
switch (arguments[0]) {
case 'pass':
return;
+ case 'fail-unexpected':
case 'fail':
Expect.fail("This test always fails, to test the test scripts.");
- break;
+ break;
case 'timeout':
// Run for 10 seconds, then exit. This tests a 2 second timeout.
new Timer(10 * 1000, (t){ });
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index fdcfa9d..35a839c 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -6,7 +6,6 @@
[ $runtime == vm ]
package/package_isolate_test: Fail # Issue 7520.
-io/test_runner_test: Pass, Fail # Issue 1947
[ $runtime == vm && $checked ]
# These tests have type errors on purpose.
@@ -22,7 +21,11 @@
[ $runtime == vm && $system == macos && $arch == x64 ]
io/regress_7191_test: Pass, Timeout # http://dartbug.com/8091
-[ $runtime == vm && $system == macos ]
+[ $runtime == vm ]
+# Fails with a connection refused error on the buildbot.
+# Issue 8232.
+debugger/basic_debugger_test: Pass, Fail
+
# This test fails with "Too many open files" on the Mac OS buildbot.
# This is expected as MacOS by default runs with a very low number
# of allowed open files ('ulimit -n' says something like 256).
@@ -41,12 +44,6 @@
[ $runtime == vm && $system == windows ]
io/file_system_links_test: Skip # No links on Windows.
-io/test_extension_fail_test: Fail # Issue 7157
-io/secure_no_builtin_roots_test: Pass, Crash # Issue 7157
-io/secure_socket_bad_certificate_test: Pass, Crash, Fail, Timeout # Issue 7157
-io/directory_list_nonexistent_test: Skip # Issue 7157
-io/web_socket_test: Skip # Issue 7157
-io/web_socket_no_secure_test: Pass # Issue 7157 - Remove test when fixed.
[ $compiler == none && $runtime == drt ]
io/*: Skip # Don't run tests using dart:io in the browser
diff --git a/tools/VERSION b/tools/VERSION
index 2a2b2cb..0445e6e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 3
-BUILD 2
+BUILD 3
PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index a995bcc..fbcaeb3 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -162,12 +162,6 @@
- test_set: Specification of a non standard test set, default None
"""
- if system.startswith('win') and runtime.startswith('ie'):
- # There should not be more than one InternetExplorerDriver instance
- # running at a time. For details, see
- # http://code.google.com/p/selenium/wiki/InternetExplorerDriver.
- flags += ['-j1']
-
def GetPath(runtime):
""" Helper to get the path to the Chrome or Firefox executable for a
particular platform on the buildbot. Throws a KeyError if runtime is not
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 1cb8fa8..053f110 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -110,8 +110,8 @@
CopyShellScript(os.path.join(home, 'sdk', 'bin', executable),
os.path.join(sdk_root, 'bin'))
- subprocess.call([os.path.join(build_dir, 'gen_snapshot'),
- '--script_snapshot=%s' %
+ subprocess.call([os.path.join(build_dir, 'dart'),
+ '--generate-script-snapshot=%s' %
os.path.join(sdk_root, 'lib', '_internal', 'compiler',
'implementation', 'dart2js.dart.snapshot'),
os.path.join(sdk_root, 'lib', '_internal', 'compiler',
@@ -221,8 +221,8 @@
# Create and populate pkg/{args, intl, logging, meta, unittest, ...}
#
- for library in ['args', 'http', 'intl', 'logging',
- 'meta', 'oauth2', 'path', 'serialization', 'unittest']:
+ for library in ['args', 'http', 'intl', 'logging', 'meta', 'oauth2', 'path',
+ 'serialization', 'unittest', 'yaml']:
copytree(join(HOME, 'pkg', library), join(PKG, library),
ignore=ignore_patterns('*.svn', 'doc', 'docs',
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 9e26dfe..89087ea 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -1 +1,414 @@
-{}
\ No newline at end of file
+{
+ "dart.dom.html": {
+ "CanvasGradient": {
+ "comment": [
+ "/**",
+ " * An opaque canvas object representing a gradient.",
+ " *",
+ " * Created by calling [createLinearGradient] or [createRadialGradient] on a",
+ " * [CanvasRenderingContext2D] object.",
+ " *",
+ " * Example usage:",
+ " *",
+ " * var canvas = new CanvasElement(width: 600, height: 600);",
+ " * var ctx = canvas.context2d;",
+ " * ctx.clearRect(0, 0, 600, 600);",
+ " * ctx.save();",
+ " * // Create radial gradient.",
+ " * CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);",
+ " * gradient.addColorStop(0, '#000');",
+ " * gradient.addColorStop(1, 'rgb(255, 255, 255)');",
+ " * // Assign gradients to fill.",
+ " * ctx.fillStyle = gradient;",
+ " * // Draw a rectangle with a gradient fill.",
+ " * ctx.fillRect(0, 0, 600, 600);",
+ " * ctx.save();",
+ " * document.body.children.add(canvas);",
+ " *",
+ " * See also:",
+ " *",
+ " * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.",
+ " * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.",
+ " * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.",
+ " */"
+ ],
+ "members": {
+ "addColorStop": [
+ "/**",
+ " * Adds a color stop to this gradient at the offset.",
+ " *",
+ " * The [offset] can range between 0.0 and 1.0.",
+ " *",
+ " * See also:",
+ " *",
+ " * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.",
+ " */"
+ ]
+ }
+ },
+ "CanvasPattern": {
+ "comment": [
+ "/**",
+ " * An opaque object representing a pattern of image, canvas, or video.",
+ " *",
+ " * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.",
+ " *",
+ " * Example usage:",
+ " *",
+ " * var canvas = new CanvasElement(width: 600, height: 600);",
+ " * var ctx = canvas.context2d;",
+ " * var img = new ImageElement();",
+ " * // Image src needs to be loaded before pattern is applied.",
+ " * img.onLoad.listen((event) {",
+ " * // When the image is loaded, create a pattern",
+ " * // from the ImageElement.",
+ " * CanvasPattern pattern = ctx.createPattern(img, 'repeat');",
+ " * ctx.rect(0, 0, canvas.width, canvas.height);",
+ " * ctx.fillStyle = pattern;",
+ " * ctx.fill();",
+ " * });",
+ " * img.src = \"images/foo.jpg\";",
+ " * document.body.children.add(canvas);",
+ " *",
+ " * See also:",
+ " * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.",
+ " * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.",
+ " * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.",
+ " */"
+ ]
+ },
+ "CanvasRenderingContext": {
+ "comment": [
+ "/**",
+ " * A rendering context for a canvas element.",
+ " *",
+ " * This context is extended by [CanvasRenderingContext2D] and",
+ " * [WebGLRenderingContext].",
+ " */"
+ ],
+ "members": {
+ "canvas": [
+ "/// Reference to the canvas element to which this context belongs."
+ ]
+ }
+ },
+ "Document": {
+ "members": {
+ "body": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "caretRangeFromPoint": [
+ "/// Use the [Range] constructor instead."
+ ],
+ "createElement": [
+ "/// Deprecated: use new Element.tag(tagName) instead."
+ ],
+ "createTouchList": [
+ "/// Use the [TouchList] constructor instead."
+ ],
+ "getCSSCanvasContext": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "getElementById": [
+ "/// Deprecated: use query(\"#$elementId\") instead."
+ ],
+ "head": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "lastModified": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "querySelector": [
+ "/// Deprecated: renamed to the shorter name [query]."
+ ],
+ "querySelectorAll": [
+ "/// Deprecated: use query(\"#$elementId\") instead."
+ ],
+ "referrer": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "styleSheets": [
+ "/// Moved to [HtmlDocument]"
+ ],
+ "title": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitCancelFullScreen": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitExitFullscreen": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitExitPointerLock": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitFullscreenElement": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitFullscreenEnabled": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitHidden": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitIsFullScreen": [
+ "/// Moved to [HtmlDocument]."
+ ],
+ "webkitPointerLockElement": [
+ "/// Moved to [HtmlDocument]."
+ ]
+ }
+ },
+ "HTMLCanvasElement": {
+ "members": {
+ "height": [
+ "/// The height of this canvas element in CSS pixels."
+ ],
+ "toDataURL": [
+ "/**",
+ " * Returns a data URI containing a representation of the image in the",
+ " * format specified by type (defaults to 'image/png').",
+ " *",
+ " * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`",
+ " *",
+ " * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]",
+ " * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default",
+ " * value is used. Note: the default value varies by browser.",
+ " *",
+ " * If the height or width of this canvas element is 0, then 'data:' is returned,",
+ " * representing no data.",
+ " *",
+ " * If the type requested is not 'image/png', and the returned value is",
+ " * 'data:image/png', then the requested type is not supported.",
+ " *",
+ " * Example usage:",
+ " *",
+ " * CanvasElement canvas = new CanvasElement();",
+ " * var ctx = canvas.context2d",
+ " * ..fillStyle = \"rgb(200,0,0)\"",
+ " * ..fillRect(10, 10, 55, 50);",
+ " * var dataUrl = canvas.toDataURL(\"image/jpeg\", 0.95);",
+ " * // The Data Uri would look similar to",
+ " * // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA",
+ " * // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO",
+ " * // 9TXL0Y4OHwAAAABJRU5ErkJggg=='",
+ " * //Create a new image element from the data URI.",
+ " * var img = new ImageElement();",
+ " * img.src = dataUrl;",
+ " * document.body.children.add(img);",
+ " *",
+ " * See also:",
+ " *",
+ " * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.",
+ " *",
+ " * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.",
+ " *",
+ " * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.",
+ " */"
+ ],
+ "width": [
+ "/// The width of this canvas element in CSS pixels."
+ ]
+ }
+ },
+ "HTMLDivElement": {
+ "comment": [
+ "/**",
+ " * 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.",
+ " */"
+ ]
+ },
+ "XMLHttpRequest": {
+ "members": {
+ "abort": [
+ "/**",
+ " * Stop the current request.",
+ " *",
+ " * The request can only be stopped if readyState is `HEADERS_RECIEVED` or",
+ " * `LOADING`. If this method is not in the process of being sent, the method",
+ " * has no effect.",
+ " */"
+ ],
+ "getAllResponseHeaders": [
+ "/**",
+ " * Retrieve all the response headers from a request.",
+ " *",
+ " * `null` if no headers have been received. For multipart requests,",
+ " * `getAllResponseHeaders` will return the response headers for the current",
+ " * part of the request.",
+ " *",
+ " * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+ " * for a list of common response headers.",
+ " */"
+ ],
+ "getResponseHeader": [
+ "/**",
+ " * Return the response header named `header`, or `null` if not found.",
+ " *",
+ " * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+ " * for a list of common response headers.",
+ " */"
+ ],
+ "open": [
+ "/**",
+ " * Specify the desired `url`, and `method` to use in making the request.",
+ " *",
+ " * By default the request is done asyncronously, with no user or password",
+ " * authentication information. If `async` is false, the request will be send",
+ " * synchronously.",
+ " *",
+ " * Calling `open` again on a currently active request is equivalent to",
+ " * calling `abort`.",
+ " */"
+ ],
+ "overrideMimeType": [
+ "/**",
+ " * Specify a particular MIME type (such as `text/xml`) desired for the",
+ " * response.",
+ " *",
+ " * This value must be set before the request has been sent. See also the list",
+ " * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)",
+ " */"
+ ],
+ "readyState": [
+ "/**",
+ " * Indicator of the current state of the request:",
+ " *",
+ " * <table>",
+ " * <tr>",
+ " * <td>Value</td>",
+ " * <td>State</td>",
+ " * <td>Meaning</td>",
+ " * </tr>",
+ " * <tr>",
+ " * <td>0</td>",
+ " * <td>unsent</td>",
+ " * <td><code>open()</code> has not yet been called</td>",
+ " * </tr>",
+ " * <tr>",
+ " * <td>1</td>",
+ " * <td>opened</td>",
+ " * <td><code>send()</code> has not yet been called</td>",
+ " * </tr>",
+ " * <tr>",
+ " * <td>2</td>",
+ " * <td>headers received</td>",
+ " * <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>",
+ " * </tr>",
+ " * <tr>",
+ " * <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>",
+ " * </tr>",
+ " * <tr>",
+ " * <td>4</td> <td>done</td> <td>request is complete</td>",
+ " * </tr>",
+ " * </table>",
+ " */"
+ ],
+ "response": [
+ "/**",
+ " * The data received as a reponse from the request.",
+ " *",
+ " * The data could be in the",
+ " * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a",
+ " * [String]). `null` indicates request failure.",
+ " */"
+ ],
+ "responseText": [
+ "/**",
+ " * The response in string form or `null on failure.",
+ " */"
+ ],
+ "responseType": [
+ "/**",
+ " * [String] telling the server the desired response format.",
+ " *",
+ " * Default is `String`.",
+ " * Other options are one of 'arraybuffer', 'blob', 'document', 'json',",
+ " * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if",
+ " * `responseType` is set while performing a synchronous request.",
+ " *",
+ " * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)",
+ " */"
+ ],
+ "responseXML": [
+ "/**",
+ " * The request response, or null on failure.",
+ " *",
+ " * The response is processed as",
+ " * `text/xml` stream, unless responseType = 'document' and the request is",
+ " * synchronous.",
+ " */"
+ ],
+ "send": [
+ "/**",
+ " * Send the request with any given `data`.",
+ " *",
+ " * See also:",
+ " * [send() docs](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send())",
+ " * from MDN.",
+ " */"
+ ],
+ "status": [
+ "/**",
+ " * The http result code from the request (200, 404, etc).",
+ " * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+ " */"
+ ],
+ "statusText": [
+ "/**",
+ " * The request response string (such as \\\"200 OK\\\").",
+ " * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+ " */"
+ ],
+ "upload": [
+ "/**",
+ " * [EventTarget] that can hold listeners to track the progress of the request.",
+ " * The events fired will be members of [HttpRequestUploadEvents].",
+ " */"
+ ],
+ "withCredentials": [
+ "/**",
+ " * True if cross-site requests should use credentials such as cookies",
+ " * or authorization headers; false otherwise.",
+ " *",
+ " * This value is ignored for same-site requests.",
+ " */"
+ ],
+ "XMLHttpRequest": [
+ "/**",
+ " * General constructor for any type of request (GET, POST, etc).",
+ " *",
+ " * This call is used in conjunction with [open]:",
+ " *",
+ " * var request = new HttpRequest();",
+ " * request.open('GET', 'http://dartlang.org')",
+ " * request.on.load.add((event) => print('Request complete'));",
+ " *",
+ " * is the (more verbose) equivalent of",
+ " *",
+ " * var request = new HttpRequest.get('http://dartlang.org',",
+ " * (event) => print('Request complete'));",
+ " */"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/dom/docs/lib/docs.dart b/tools/dom/docs/lib/docs.dart
index 69d9854..74529c4 100644
--- a/tools/dom/docs/lib/docs.dart
+++ b/tools/dom/docs/lib/docs.dart
@@ -29,7 +29,9 @@
* comment: "$comment"
* members: {
* $member: [
- * $comment1,
+ * [$comment1line1,
+ * $comment1line2,
+ * ...],
* ...
* ],
* ...
@@ -85,7 +87,7 @@
var libraryJson = {};
var sortedClasses = _sortAndFilterMirrors(
- libMirror.classes.values.toList());
+ libMirror.classes.values.toList(), ignoreDocsEditable: true);
for (ClassMirror classMirror in sortedClasses) {
var classJson = {};
@@ -95,7 +97,8 @@
var membersJson = {};
for (var memberMirror in sortedMembers) {
var memberDomName = domNames(memberMirror)[0];
- var memberComment = computeUntrimmedCommentAsList(memberMirror);
+ var memberComment = _splitCommentsByNewline(
+ computeUntrimmedCommentAsList(memberMirror));
// Remove interface name from Dom Name.
if (memberDomName.indexOf('.') >= 0) {
@@ -107,8 +110,11 @@
}
}
- var classComment = computeUntrimmedCommentAsList(classMirror);
- if (!classComment.isEmpty) {
+ // Only include the comment if DocsEditable is set.
+ var classComment = _splitCommentsByNewline(
+ computeUntrimmedCommentAsList(classMirror));
+ if (!classComment.isEmpty &&
+ findMetadata(classMirror.metadata, 'DocsEditable') != null) {
classJson.putIfAbsent('comment', () => classComment);
}
if (!membersJson.isEmpty) {
@@ -131,13 +137,19 @@
return convertedJson;
}
-List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors) {
- // Filter out mirrors that are private, or which are not part of this docs
- // process. That is, ones without the DocsEditable annotation.
+/// Filter out mirrors that are private, or which are not part of this docs
+/// process. That is, ones without the DocsEditable annotation.
+/// If [ignoreDocsEditable] is true, relax the restriction on @DocsEditable.
+/// This is to account for classes that are defined in a template, but whose
+/// members are generated.
+List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors,
+ {ignoreDocsEditable: false}) {
+
var filteredMirrors = mirrors.where((DeclarationMirror c) =>
!domNames(c).isEmpty &&
!c.displayName.startsWith('_') &&
- (findMetadata(c.metadata, 'DocsEditable') != null))
+ (!ignoreDocsEditable ? (findMetadata(c.metadata, 'DocsEditable') != null)
+ : true))
.toList();
filteredMirrors.sort((x, y) =>
@@ -147,6 +159,16 @@
return filteredMirrors;
}
+List<String> _splitCommentsByNewline(List<String> comments) {
+ var out = [];
+
+ comments.forEach((c) {
+ out.addAll(c.split(new RegExp('\n')));
+ });
+
+ return out;
+}
+
/// Given the class mirror, returns the names found or an empty list.
List<String> domNames(DeclarationMirror mirror) {
var domNameMetadata = findMetadata(mirror.metadata, 'DomName');
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index e823e52..d822bc0 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -26,10 +26,6 @@
};
Element implements ElementTraversal;
-// TODO(antonm): fix it
-[Supplemental, Constructor]
-interface MediaStream {};
-
[Callback]
interface TimeoutHandler {
void handleEvent();
@@ -44,6 +40,9 @@
interface HTMLCanvasElement {
[Suppressed] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type) raises(DOMException);
[Custom] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type, [Optional] in float quality) raises(DOMException);
+
+ [Suppressed] DOMObject getContext(in DOMString contextId);
+ [Custom] CanvasRenderingContext getContext(in DOMString contextId, [Optional] in Dictionary attrs);
};
[Supplemental]
@@ -231,7 +230,7 @@
// TODO(vsm): Define new names for these (see b/4436830).
[Supplemental]
interface IDBCursor {
- [DartName=continueFunction] void continue([Optional] in IDBKey key);
+ [DartName=continueFunction] void continue([Optional] in any key);
};
[Supplemental]
interface IDBDatabase {
@@ -246,20 +245,20 @@
};
[Supplemental]
interface IDBIndex {
- [DartName=getObject] IDBRequest get(in IDBKey key);
+ [DartName=getObject] IDBRequest get(in any key);
};
[Supplemental]
interface IDBObjectStore {
- [DartName=getObject] IDBRequest get(in IDBKey key);
+ [DartName=getObject] IDBRequest get(in any key);
[DartName=getObject] IDBRequest get(in IDBKeyRange key);
};
[Supplemental]
interface IDBKeyRange {
- [DartName=only_] static IDBKeyRange only(in IDBKey value) raises (IDBDatabaseException);
- [DartName=lowerBound_] static IDBKeyRange lowerBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
- [DartName=upperBound_] static IDBKeyRange upperBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
- [DartName=bound_] static IDBKeyRange bound(in IDBKey lower, in IDBKey upper, [Optional] in boolean lowerOpen, [Optional] in boolean upperOpen) raises (IDBDatabaseException);
+ [DartName=only_] static IDBKeyRange only(in any value) raises (IDBDatabaseException);
+ [DartName=lowerBound_] static IDBKeyRange lowerBound(in any bound, [Optional] in boolean open) raises (IDBDatabaseException);
+ [DartName=upperBound_] static IDBKeyRange upperBound(in any bound, [Optional] in boolean open) raises (IDBDatabaseException);
+ [DartName=bound_] static IDBKeyRange bound(in any lower, in any upper, [Optional] in boolean lowerOpen, [Optional] in boolean upperOpen) raises (IDBDatabaseException);
};
interface EntrySync {
@@ -327,7 +326,7 @@
[Custom] Dictionary item(in unsigned long index);
};
-[Supplemental, CustomConstructor, Constructor(in DOMString url)]
+[Supplemental]
interface WebSocket {
// Suppress the default since it has non-standard return type and add
// overrides.
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index bc65b11..d4622cd 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -31,7 +31,6 @@
'SVGFitToViewBox',
'SVGLangSpace',
'SVGLocatable',
- 'SVGStylable',
'SVGTests',
'SVGTransformable',
'SVGURIReference',
@@ -222,20 +221,15 @@
"""
if 'Constructor' in interface.ext_attrs:
name = None
- func_value = interface.ext_attrs.get('Constructor')
- if not func_value:
- args = []
- idl_args = []
+ overloads = interface.ext_attrs['Constructor']
+ idl_args = [[] if f is None else f.arguments for f in overloads]
elif 'NamedConstructor' in interface.ext_attrs:
func_value = interface.ext_attrs.get('NamedConstructor')
+ idl_args = [func_value.arguments]
name = func_value.id
else:
return None
- if func_value:
- idl_args = func_value.arguments
- args =_BuildArguments([idl_args], interface, True)
-
info = OperationInfo()
info.overloads = None
info.idl_args = idl_args
@@ -244,7 +238,7 @@
info.constructor_name = None
info.js_name = name
info.type_name = interface.id
- info.param_infos = args
+ info.param_infos = _BuildArguments(idl_args, interface, constructor=True)
info.requires_named_arguments = False
info.pure_dart_constructor = False
return info
@@ -704,6 +698,18 @@
"@Experimental",
]
+_web_sql_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ "@Experimental",
+]
+
+_webgl_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@Experimental",
+]
+
# Annotations to be placed on generated members.
# The table is indexed as:
# INTERFACE: annotations to be added to the interface declaration
@@ -711,6 +717,8 @@
dart_annotations = {
'ArrayBuffer': _all_but_ie9_annotations,
'ArrayBufferView': _all_but_ie9_annotations,
+ 'Database': _web_sql_annotations,
+ 'DatabaseSync': _web_sql_annotations,
'DOMApplicationCache': [
"@SupportedBrowser(SupportedBrowser.CHROME)",
"@SupportedBrowser(SupportedBrowser.FIREFOX)",
@@ -718,7 +726,10 @@
"@SupportedBrowser(SupportedBrowser.OPERA)",
"@SupportedBrowser(SupportedBrowser.SAFARI)",
],
+ 'DOMWindow.convertPointFromNodeToPage': _webkit_experimental_annotations,
+ 'DOMWindow.convertPointFromPageToNode': _webkit_experimental_annotations,
'DOMWindow.indexedDB': _indexed_db_annotations,
+ 'DOMWindow.openDatabase': _web_sql_annotations,
'DOMWindow.performance': _performance_annotations,
'DOMWindow.webkitNotifications': _webkit_experimental_annotations,
'DOMWindow.webkitRequestFileSystem': _file_system_annotations,
@@ -793,38 +804,54 @@
'SpeechRecognitionError': _speech_recognition_annotations,
'SpeechRecognitionEvent': _speech_recognition_annotations,
'SpeechRecognitionResult': _speech_recognition_annotations,
+ 'SQLTransaction': _web_sql_annotations,
+ 'SQLTransactionSync': _web_sql_annotations,
+ 'WebGLRenderingContext': _webgl_annotations,
+ 'WebKitCSSMatrix': _webkit_experimental_annotations,
+ 'WebKitPoint': _webkit_experimental_annotations,
'WebSocket': _all_but_ie9_annotations,
'WorkerContext.indexedDB': _indexed_db_annotations,
+ 'WorkerContext.openDatabase': _web_sql_annotations,
+ 'WorkerContext.openDatabaseSync': _web_sql_annotations,
'WorkerContext.webkitRequestFileSystem': _file_system_annotations,
'WorkerContext.webkitRequestFileSystemSync': _file_system_annotations,
'WorkerContext.webkitResolveLocalFileSystemSyncURL': _file_system_annotations,
'WorkerContext.webkitResolveLocalFileSystemURL': _file_system_annotations,
'XMLHttpRequestProgressEvent': _webkit_experimental_annotations,
+ 'XSLTProcessor': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
}
-def GetComments(interface_name, member_name=None, library_name=None):
+def GetComments(library_name, interface_name, member_name=None):
""" Finds all comments for the interface or member and returns a list. """
# Add documentation from JSON.
comments = []
-
+ library_name = 'dart.dom.%s' % library_name
if library_name in _dom_json and interface_name in _dom_json[library_name]:
- if member_name and (member_name in
- _dom_json[library_name][interface_name]['members']):
+ if (member_name and 'members' in _dom_json[library_name][interface_name] and
+ (member_name in _dom_json[library_name][interface_name]['members'])):
comments = _dom_json[library_name][interface_name]['members'][member_name]
- elif 'comment' in _dom_json[library_name][interface_name]:
+ elif (not member_name and 'comment' in
+ _dom_json[library_name][interface_name]):
comments = _dom_json[library_name][interface_name]['comment']
+ if (len(comments)):
+ comments = ['\n'.join(comments)]
+
return comments
-def GetAnnotationsAndComments(interface_name, member_name=None,
- library_name=None):
- annotations = GetComments(interface_name, member_name, library_name)
- annotations.extend(FindCommonAnnotations(interface_name, member_name,
- library_name))
+def GetAnnotationsAndComments(library_name, interface_name, member_name=None):
+ annotations = GetComments(library_name, interface_name, member_name)
+ annotations = annotations + (FindCommonAnnotations(library_name, interface_name,
+ member_name))
+
return annotations
-def FindCommonAnnotations(interface_name, member_name=None, library_name=None):
+def FindCommonAnnotations(library_name, interface_name, member_name=None):
""" Finds annotations common between dart2js and dartium.
"""
if member_name:
@@ -844,13 +871,12 @@
return annotations
-def FindDart2JSAnnotationsAndComments(idl_type, interface_name, member_name,
- library_name=None):
+def FindDart2JSAnnotationsAndComments(idl_type, library_name, interface_name,
+ member_name,):
""" Finds all annotations for Dart2JS members- including annotations for
both dart2js and dartium.
"""
- annotations = GetAnnotationsAndComments(interface_name, member_name,
- library_name)
+ annotations = GetAnnotationsAndComments(library_name, interface_name, member_name)
ann2 = _FindDart2JSSpecificAnnotations(idl_type, interface_name, member_name)
if ann2:
@@ -869,6 +895,7 @@
def FormatAnnotationsAndComments(annotations, indentation):
if annotations:
+
newline = '\n%s' % indentation
result = newline.join(annotations) + newline
return result
@@ -938,7 +965,7 @@
return 'Dart%s' % self.idl_type()
def vector_to_dart_template_parameter(self):
- return self.bindings_class()
+ return self.native_type()
def to_native_info(self, idl_node, interface_name):
cls = self.bindings_class()
@@ -1097,12 +1124,16 @@
def to_native_info(self, idl_node, interface_name):
item_native_type = self._item_info.vector_to_dart_template_parameter()
- return '%s', 'Vector<%s>' % item_native_type, 'DartUtilities', 'toNativeVector<%s>' % item_native_type
+ if isinstance(self._item_info, PrimitiveIDLTypeInfo):
+ return '%s', 'Vector<%s>' % item_native_type, 'DartUtilities', 'toNativeVector<%s>' % item_native_type
+ return '%s', 'Vector< RefPtr<%s> >' % item_native_type, 'DartUtilities', 'toNativeVector< RefPtr<%s> >' % item_native_type
def pass_native_by_ref(self): return True
def to_dart_conversion(self, value, interface_name=None, attributes=None):
- return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.vector_to_dart_template_parameter(), value)
+ if isinstance(self._item_info, PrimitiveIDLTypeInfo):
+ return 'DartDOMWrapper::vectorToDart(%s)' % value
+ return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.bindings_class(), value)
def conversion_includes(self):
return self._item_info.conversion_includes()
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 6ff883a..dccbf03 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -6,9 +6,11 @@
"""This module provides shared functionality for the system to generate
dart:html APIs from the IDL database."""
+import emitter
from generator import AnalyzeOperation, ConstantOutputOrder, \
DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \
- IsPureInterface, TypeOrNothing, FindCommonAnnotations
+ IsPureInterface, TypeOrNothing, GetAnnotationsAndComments, \
+ FormatAnnotationsAndComments
# Types that are accessible cross-frame in a limited fashion.
# In these cases, the base type (e.g., WindowBase) provides restricted access
@@ -28,6 +30,7 @@
self._type_registry = options.type_registry
self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
self._renamer = options.renamer
+ self._library_name = self._renamer.GetLibraryName(self._interface)
def EmitSupportCheck(self):
if self.HasSupportCheck():
@@ -176,8 +179,9 @@
else:
self.EmitOperation(info, method_name)
- def _GenerateDispatcherBody(self,
- operations,
+ def _GenerateOverloadDispatcher(self,
+ signatures,
+ is_void,
parameter_names,
declaration,
generate_call,
@@ -192,7 +196,7 @@
DECLARATION=declaration)
version = [0]
- def GenerateCall(operation, argument_count, checks):
+ def GenerateCall(signature_index, argument_count, checks):
if checks:
(stmts_emitter, call_emitter) = body_emitter.Emit(
' if ($CHECKS) {\n$!STMTS$!CALL }\n',
@@ -203,19 +207,19 @@
'$!STMTS$!CALL',
INDENT=' ');
- if operation.type.id == 'void':
+ if is_void:
call_emitter = call_emitter.Emit('$(INDENT)$!CALL;\n$(INDENT)return;\n')
else:
call_emitter = call_emitter.Emit('$(INDENT)return $!CALL;\n')
version[0] += 1
- generate_call(
- stmts_emitter, call_emitter, version[0], operation, argument_count)
+ generate_call(stmts_emitter, call_emitter,
+ version[0], signature_index, argument_count)
- def GenerateChecksAndCall(operation, argument_count):
+ def GenerateChecksAndCall(signature_index, argument_count):
checks = []
for i in range(0, argument_count):
- argument = operation.arguments[i]
+ argument = signatures[signature_index][i]
parameter_name = parameter_names[i]
test_type = self._DartType(argument.type.id)
if test_type in ['dynamic', 'Object']:
@@ -227,34 +231,60 @@
# optional argument could have been passed by name, leaving 'holes'.
checks.extend(['!?%s' % name for name in parameter_names[argument_count:]])
- GenerateCall(operation, argument_count, checks)
+ GenerateCall(signature_index, argument_count, checks)
# TODO: Optimize the dispatch to avoid repeated checks.
- if len(operations) > 1:
- for operation in operations:
- for position, argument in enumerate(operation.arguments):
- if is_optional(operation, argument):
- GenerateChecksAndCall(operation, position)
- GenerateChecksAndCall(operation, len(operation.arguments))
+ if len(signatures) > 1:
+ for signature_index, signature in enumerate(signatures):
+ for argument_position, argument in enumerate(signature):
+ if is_optional(signature_index, argument):
+ GenerateChecksAndCall(signature_index, argument_position)
+ GenerateChecksAndCall(signature_index, len(signature))
body_emitter.Emit(
' throw new ArgumentError("Incorrect number or type of arguments");'
'\n');
else:
- operation = operations[0]
- argument_count = len(operation.arguments)
- for position, argument in list(enumerate(operation.arguments))[::-1]:
- if is_optional(operation, argument):
- check = '?%s' % parameter_names[position]
- # argument_count instead of position + 1 is used here to cover one
+ signature = signatures[0]
+ argument_count = len(signature)
+ for argument_position, argument in list(enumerate(signature))[::-1]:
+ if is_optional(0, argument):
+ check = '?%s' % parameter_names[argument_position]
+ # argument_count instead of argument_position + 1 is used here to cover one
# complicated case with the effectively optional argument in the middle.
# Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z)
# (as of now it's modelled after HTMLMediaElement.webkitAddKey).
# y is optional in WebCore, while z is not.
# In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation,
# not foo(x, y).
- GenerateCall(operation, argument_count, [check])
- argument_count = position
- GenerateCall(operation, argument_count, [])
+ GenerateCall(0, argument_count, [check])
+ argument_count = argument_position
+ GenerateCall(0, argument_count, [])
+
+ def _GenerateDispatcherBody(self,
+ operations,
+ parameter_names,
+ declaration,
+ generate_call,
+ is_optional,
+ can_omit_type_check=lambda type, pos: False):
+
+ def GenerateCall(
+ stmts_emitter, call_emitter, version, signature_index, argument_count):
+ generate_call(
+ stmts_emitter, call_emitter,
+ version, operations[signature_index], argument_count)
+
+ def IsOptional(signature_index, argument):
+ return is_optional(operations[signature_index], argument)
+
+ self._GenerateOverloadDispatcher(
+ [operation.arguments for operation in operations],
+ operations[0].type.id == 'void',
+ parameter_names,
+ declaration,
+ GenerateCall,
+ IsOptional,
+ can_omit_type_check)
def AdditionalImplementedInterfaces(self):
# TODO: Include all implemented interfaces, including other Lists.
@@ -288,25 +318,43 @@
if type_info.is_typed_array():
typed_array_type = type_info.list_item_type()
break
+
+ annotations = FormatAnnotationsAndComments(
+ GetAnnotationsAndComments(self._library_name, self._interface.id,
+ self._interface.id), ' ')
+
+ fromListAnnotations = FormatAnnotationsAndComments(
+ GetAnnotationsAndComments(self._library_name, self._interface.id,
+ 'fromList'), ' ')
+
+ fromBufferAnnotations = FormatAnnotationsAndComments(
+ GetAnnotationsAndComments(self._library_name, self._interface.id,
+ 'fromBuffer'), ' ')
+
if typed_array_type:
self._members_emitter.Emit(
- '\n'
- ' factory $CTOR(int length) =>\n'
+ '\n $(ANNOTATIONS)factory $CTOR(int length) =>\n'
' $FACTORY.create$(CTOR)(length);\n'
- '\n'
- ' factory $CTOR.fromList(List<$TYPE> list) =>\n'
+ '\n $(LIST_ANNOTATIONS)factory $CTOR.fromList(List<$TYPE> list) =>\n'
' $FACTORY.create$(CTOR)_fromList(list);\n'
- '\n'
- ' factory $CTOR.fromBuffer(ArrayBuffer buffer, '
+ '\n $(BUFFER_ANNOTATIONS)factory $CTOR.fromBuffer(ArrayBuffer buffer, '
'[int byteOffset, int length]) => \n'
' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n',
CTOR=self._interface.id,
+ ANNOTATIONS=annotations,
+ LIST_ANNOTATIONS=fromListAnnotations,
+ BUFFER_ANNOTATIONS=fromBufferAnnotations,
TYPE=self._DartType(typed_array_type),
FACTORY=factory_name)
def _AddConstructor(self,
constructor_info, factory_name, factory_constructor_name):
- self._members_emitter.Emit('\n @DocsEditable');
+ if self.GenerateCustomFactory(constructor_info):
+ return
+
+ annotations = FormatAnnotationsAndComments(
+ GetAnnotationsAndComments(self._library_name, self._interface.id,
+ self._interface.id), ' ')
if not factory_constructor_name:
factory_constructor_name = '_create'
@@ -316,61 +364,90 @@
factory_parameters = ', '.join(constructor_info.factory_parameters)
has_factory_provider = False
- has_optional = any(param_info.is_optional
- for param_info in constructor_info.param_infos)
+ if constructor_info.pure_dart_constructor:
+ # TODO(antonm): use common dispatcher generation for this case as well.
+ has_optional = any(param_info.is_optional
+ for param_info in constructor_info.param_infos)
- if not has_optional:
- self._members_emitter.Emit(
- '\n'
- ' factory $CTOR($PARAMS) => '
- '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
- CTOR=constructor_info._ConstructorFullName(self._DartType),
- PARAMS=constructor_info.ParametersDeclaration(self._DartType),
- FACTORY=factory_name,
- CTOR_FACTORY_NAME=factory_constructor_name,
- FACTORY_PARAMS=factory_parameters)
- else:
- if has_factory_provider:
- dispatcher_emitter = self._members_emitter.Emit(
- '\n'
- ' factory $CTOR($PARAMS) {\n'
- '$!DISPATCHER'
- ' return $FACTORY._create($FACTORY_PARAMS);\n'
- ' }\n',
+ if not has_optional:
+ self._members_emitter.Emit(
+ '\n $(ANNOTATIONS)'
+ 'factory $CTOR($PARAMS) => '
+ '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
CTOR=constructor_info._ConstructorFullName(self._DartType),
PARAMS=constructor_info.ParametersDeclaration(self._DartType),
FACTORY=factory_name,
- FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
-
- for index, param_info in enumerate(constructor_info.param_infos):
- if param_info.is_optional:
- dispatcher_emitter.Emit(
- ' if (!?$OPT_PARAM_NAME) {\n'
- ' return $FACTORY._create($FACTORY_PARAMS);\n'
- ' }\n',
- OPT_PARAM_NAME=param_info.name,
- FACTORY=factory_name,
- FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
- else:
- inits = self._members_emitter.Emit(
- '\n'
- ' factory $CONSTRUCTOR($PARAMS) {\n'
- ' var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
- '$!INITS'
- ' return e;\n'
- ' }\n',
- CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
- FACTORY=factory_name,
+ ANNOTATIONS=annotations,
CTOR_FACTORY_NAME=factory_constructor_name,
- PARAMS=constructor_info.ParametersDeclaration(self._DartType),
FACTORY_PARAMS=factory_parameters)
+ else:
+ if has_factory_provider:
+ dispatcher_emitter = self._members_emitter.Emit(
+ '\n $(ANNOTATIONS)'
+ 'factory $CTOR($PARAMS) {\n'
+ '$!DISPATCHER'
+ ' return $FACTORY._create($FACTORY_PARAMS);\n'
+ ' }\n',
+ CTOR=constructor_info._ConstructorFullName(self._DartType),
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+ FACTORY=factory_name,
+ ANNOTATIONS=annotations,
+ FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
- for index, param_info in enumerate(constructor_info.param_infos):
- if param_info.is_optional:
- inits.Emit(' if ($E != null) e.$E = $E;\n', E=param_info.name)
+ for index, param_info in enumerate(constructor_info.param_infos):
+ if param_info.is_optional:
+ dispatcher_emitter.Emit(
+ ' if (!?$OPT_PARAM_NAME) {\n'
+ ' return $FACTORY._create($FACTORY_PARAMS);\n'
+ ' }\n',
+ OPT_PARAM_NAME=param_info.name,
+ FACTORY=factory_name,
+ FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
+ else:
+ inits = self._members_emitter.Emit(
+ '\n $(ANNOTATIONS)'
+ 'factory $CONSTRUCTOR($PARAMS) {\n'
+ ' var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
+ '$!INITS'
+ ' return e;\n'
+ ' }\n',
+ CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
+ ANNOTATIONS=annotations,
+ FACTORY=factory_name,
+ CTOR_FACTORY_NAME=factory_constructor_name,
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+ FACTORY_PARAMS=factory_parameters)
- if not constructor_info.pure_dart_constructor:
- self.EmitStaticFactory(constructor_info)
+ for index, param_info in enumerate(constructor_info.param_infos):
+ if param_info.is_optional:
+ inits.Emit(' if ($E != null) e.$E = $E;\n', E=param_info.name)
+ else:
+ def GenerateCall(
+ stmts_emitter, call_emitter,
+ version, signature_index, argument_count):
+ name = emitter.Format('_create_$VERSION', VERSION=version)
+ call_emitter.Emit('$FACTORY.$NAME($FACTORY_PARAMS)',
+ FACTORY=factory_name,
+ NAME=name,
+ FACTORY_PARAMS= \
+ constructor_info.ParametersAsArgumentList(argument_count))
+ self.EmitStaticFactoryOverload(
+ constructor_info, name,
+ constructor_info.idl_args[signature_index][:argument_count])
+
+ def IsOptional(signature_index, argument):
+ return self.IsConstructorArgumentOptional(argument)
+
+ self._GenerateOverloadDispatcher(
+ constructor_info.idl_args,
+ False,
+ [info.name for info in constructor_info.param_infos],
+ emitter.Format('$(ANNOTATIONS)factory $CTOR($PARAMS)',
+ CTOR=constructor_info._ConstructorFullName(self._DartType),
+ ANNOTATIONS=annotations,
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType)),
+ GenerateCall,
+ IsOptional)
def EmitHelpers(self, base_class):
pass
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index fd180ec..8c351a4 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -396,7 +396,7 @@
continue
annotations = FormatAnnotationsAndComments(
- GetAnnotationsAndComments(interface.id, dom_name, library_name), ' ')
+ GetAnnotationsAndComments(library_name, interface.id, dom_name), ' ')
members_emitter.Emit(
"\n"
@@ -425,7 +425,7 @@
provider = html_name + 'Event'
annotations = FormatAnnotationsAndComments(
- GetAnnotationsAndComments(interface.id, dom_name, library_name), ' ')
+ GetAnnotationsAndComments(library_name, interface.id, dom_name), ' ')
members_emitter.Emit(
"\n"
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 8d49ed7..6fb4c86 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -8,6 +8,7 @@
html_interface_renames = monitored.Dict('htmlrenamer.html_interface_renames', {
'CDATASection': 'CDataSection',
+ 'Clipboard': 'DataTransfer',
'DOMApplicationCache': 'ApplicationCache',
'DOMCoreException': 'DomException',
'DOMFileSystem': 'FileSystem',
@@ -37,7 +38,7 @@
'WebKitCSSKeyframesRule': 'CssKeyframesRule',
'WebKitCSSMatrix': 'CssMatrix',
'WebKitCSSTransformValue': 'CssTransformValue',
- 'WebKitPoint': 'Point',
+ 'WebKitPoint': 'DomPoint',
'WebKitTransitionEvent': 'TransitionEvent',
'XMLHttpRequest': 'HttpRequest',
'XMLHttpRequestException': 'HttpRequestException',
@@ -154,6 +155,8 @@
_renamed_html_members = monitored.Dict('htmlrenamer._renamed_html_members', {
'DOMURL.createObjectURL': 'createObjectUrl',
'DOMURL.revokeObjectURL': 'revokeObjectUrl',
+ 'DOMWindow.webkitConvertPointFromNodeToPage': 'convertPointFromNodeToPage',
+ 'DOMWindow.webkitConvertPointFromPageToNode': 'convertPointFromPageToNode',
'DOMWindow.webkitNotifications': 'notifications',
'DOMWindow.webkitRequestFileSystem': 'requestFileSystem',
'DOMWindow.webkitResolveLocalFileSystemURL': 'resolveLocalFileSystemUrl',
@@ -172,7 +175,6 @@
'Node.previousSibling': 'previousNode',
'Node.textContent': 'text',
'SVGElement.className': '$dom_svgClassName',
- 'SVGStylable.className': '$dom_svgClassName',
'WorkerContext.webkitRequestFileSystem': 'requestFileSystem',
'WorkerContext.webkitRequestFileSystemSync': 'requestFileSystemSync',
'WorkerContext.webkitResolveLocalFileSystemSyncURL':
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index 7c488a5..7442912 100755
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -216,6 +216,9 @@
def get(self, key, default=None):
return self.__map.get(key, default)
+ def setdefault(self, key, value=None):
+ return self.__map.setdefault(key, value)
+
def items(self):
return self.__map.items()
@@ -287,6 +290,18 @@
name = self._find_first(ext_attr, 'Id')
value = self._find_first(ext_attr, 'ExtAttrValue')
+ if name == 'Constructor':
+ # There might be multiple constructor attributes, collect them
+ # as a list. Represent plain Constructor attribute
+ # (without any signature) as None.
+ assert value is None
+ func_value = None
+ ctor_args = self._find_first(ext_attr, 'ExtAttrArgList')
+ if ctor_args:
+ func_value = IDLExtAttrFunctionValue(None, ctor_args)
+ self.setdefault('Constructor', []).append(func_value)
+ continue
+
func_value = self._find_first(value, 'ExtAttrFunctionValue')
if func_value:
# E.g. NamedConstructor=Audio(in [Optional] DOMString src)
@@ -295,12 +310,6 @@
self._find_first(func_value, 'ExtAttrArgList'))
continue
- ctor_args = not value and self._find_first(ext_attr, 'ExtAttrArgList')
- if ctor_args:
- # E.g. Constructor(Element host)
- self[name] = IDLExtAttrFunctionValue(None, ctor_args)
- continue
-
self[name] = value
def _all_subnodes(self):
diff --git a/tools/dom/scripts/idlrenderer.py b/tools/dom/scripts/idlrenderer.py
index 6e3e4d5..c145ade 100755
--- a/tools/dom/scripts/idlrenderer.py
+++ b/tools/dom/scripts/idlrenderer.py
@@ -121,6 +121,11 @@
if v.id:
w('=')
w(v)
+ elif isinstance(v, list):
+ assert k == 'Constructor'
+ w(v[0])
+ for c in v[1:]:
+ w(', '); w(k); w(c)
else:
w('=%s' % v.__str__())
i += 1
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 08156fa..78b1934c 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -46,7 +46,6 @@
'Element.remove',
'ElementEvents.mouseWheel',
'DOMException.name',
- 'HTMLCanvasElement.getContext',
'HTMLTableElement.createTBody',
'IDBDatabase.transaction',
'KeyboardEvent.initKeyboardEvent',
@@ -72,6 +71,7 @@
js_support_checks = {
'ArrayBuffer': "JS('bool', 'typeof window.ArrayBuffer != \"undefined\"')",
+ 'Database': "JS('bool', '!!(window.openDatabase)')",
'DOMApplicationCache': "JS('bool', '!!(window.applicationCache)')",
'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
'HashChangeEvent': "Event._isTypeSupported('HashChangeEvent')",
@@ -96,7 +96,11 @@
"window.webkitSpeechRecognition)')",
'XMLHttpRequestProgressEvent':
"Event._isTypeSupported('XMLHttpRequestProgressEvent')",
+ 'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
+ 'WebKitCSSMatrix': "JS('bool', '!!(window.WebKitCSSMatrix)')",
+ 'WebKitPoint': "JS('bool', '!!(window.WebKitPoint)')",
'WebSocket': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
+ 'XSLTProcessor': "JS('bool', '!!(window.XSLTProcessor)')",
}
# Classes that offer only static methods, and therefore we should suppress
@@ -331,6 +335,7 @@
typedef_name = self._renamer.RenameInterface(self._interface)
code.Emit('typedef void $NAME($PARAMS);\n',
+ LIBRARYNAME='dart.dom.%s' % self._library_name,
NAME=typedef_name,
PARAMS=info.ParametersDeclaration(self._DartType))
self._backend.GenerateCallback(info)
@@ -402,12 +407,12 @@
implements_str = ' implements ' + ', '.join(set(implements))
annotations = FormatAnnotationsAndComments(
- GetAnnotationsAndComments(self._interface.doc_js_name,
- library_name=self._library_name), '')
+ GetAnnotationsAndComments(self._library_name,
+ self._interface.doc_js_name), '')
self._implementation_members_emitter = implementation_emitter.Emit(
self._backend.ImplementationTemplate(),
- LIBRARYNAME=self._library_name,
+ LIBRARYNAME='dart.dom.%s' % self._library_name,
ANNOTATIONS=annotations,
CLASSNAME=self._interface_type_info.implementation_name(),
EXTENDS=' extends %s' % base_class if base_class else '',
@@ -518,56 +523,33 @@
def GetSupportCheck(self):
return js_support_checks.get(self._interface.doc_js_name)
- def EmitStaticFactory(self, constructor_info):
- WITH_CUSTOM_STATIC_FACTORY = [
+ def GenerateCustomFactory(self, constructor_info):
+ # Custom factory will be taken from the template.
+ return self._interface.doc_js_name in [
'AudioContext',
'Blob',
'MutationObserver',
'SpeechRecognition',
]
- if self._interface.doc_js_name in WITH_CUSTOM_STATIC_FACTORY:
- return
+ def IsConstructorArgumentOptional(self, argument):
+ return 'Optional' in argument.ext_attrs
- has_optional = any(param_info.is_optional
- for param_info in constructor_info.param_infos)
-
- def FormatJS(index):
- arguments = constructor_info.ParametersAsArgumentList(index)
- if arguments:
- arguments = ', ' + arguments
- return "JS('%s', 'new %s(%s)'%s)" % (
- self._interface_type_info.interface_name(),
- constructor_info.name or self._interface.doc_js_name,
- ','.join(['#'] * index),
- arguments)
-
- if not has_optional:
- self._members_emitter.Emit(
- " static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) => $JS;\n",
- INTERFACE_NAME=self._interface_type_info.interface_name(),
- PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
- self._DartType),
- JS=FormatJS(len(constructor_info.param_infos)))
- else:
- dispatcher_emitter = self._members_emitter.Emit(
- " static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) {\n"
- "$!DISPATCHER"
- " return $JS;\n"
- " }\n",
- INTERFACE_NAME=self._interface_type_info.interface_name(),
- PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
- self._DartType),
- JS=FormatJS(len(constructor_info.param_infos)))
-
- for index, param_info in enumerate(constructor_info.param_infos):
- if param_info.is_optional:
- dispatcher_emitter.Emit(
- " if (!?$OPT_PARAM_NAME) {\n"
- " return $JS;\n"
- " }\n",
- OPT_PARAM_NAME=constructor_info.param_infos[index].name,
- JS=FormatJS(index))
+ def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
+ index = len(arguments)
+ arguments = constructor_info.ParametersAsArgumentList(index)
+ if arguments:
+ arguments = ', ' + arguments
+ self._members_emitter.Emit(
+ " static $INTERFACE_NAME $NAME($PARAMETERS) => "
+ "JS('$INTERFACE_NAME', 'new $CTOR_NAME($PLACEHOLDERS)'$ARGUMENTS);\n",
+ INTERFACE_NAME=self._interface_type_info.interface_name(),
+ NAME=name,
+ # TODO(antonm): add types to parameters.
+ PARAMETERS=constructor_info.ParametersAsArgumentList(index),
+ CTOR_NAME=constructor_info.name or self._interface.doc_js_name,
+ PLACEHOLDERS=','.join(['#'] * index),
+ ARGUMENTS=arguments)
def SecondaryContext(self, interface):
if interface is not self._current_secondary_parent:
@@ -916,8 +898,9 @@
return ''
def _Annotations(self, idl_type, idl_member_name, indent=' '):
- anns = FindDart2JSAnnotationsAndComments(idl_type, self._interface.id,
- idl_member_name, self._library_name)
+ anns = FindDart2JSAnnotationsAndComments(idl_type, self._library_name,
+ self._interface.id,
+ idl_member_name)
if not AnyConversionAnnotations(idl_type, self._interface.id,
idl_member_name):
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 08d6708..df82ca7 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -160,44 +160,72 @@
CLASSNAME=self._interface_type_info.implementation_name(),
SUPERCONSTRUCTOR=super_constructor)
- def EmitStaticFactory(self, constructor_info):
- constructor_callback_id = self._interface.id + '_constructor_Callback'
+ def _EmitConstructorInfrastructure(self,
+ constructor_info, constructor_callback_cpp_name, factory_method_name,
+ argument_count=None):
+ constructor_callback_id = self._interface.id + '_' + constructor_callback_cpp_name
+ if argument_count is None:
+ argument_count = len(constructor_info.param_infos)
self._members_emitter.Emit(
- ' static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) '
- 'native "$CONSTRUCTOR_CALLBACK_ID";\n',
+ '\n @DocsEditable\n'
+ ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) '
+ 'native "$ID";\n',
INTERFACE_NAME=self._interface_type_info.interface_name(),
- PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
- self._DartType),
- CONSTRUCTOR_CALLBACK_ID=constructor_callback_id)
+ FACTORY_METHOD_NAME=factory_method_name,
+ # TODO: add types to parameters.
+ PARAMETERS=constructor_info.ParametersAsArgumentList(argument_count),
+ ID=constructor_callback_id)
- # TODO(antonm): currently we don't have information about number of arguments expected by
- # the constructor, so name only dispatch.
self._cpp_resolver_emitter.Emit(
- ' if (name == "$CONSTRUCTOR_CALLBACK_ID")\n'
- ' return Dart$(WEBKIT_INTERFACE_NAME)Internal::constructorCallback;\n',
- CONSTRUCTOR_CALLBACK_ID=constructor_callback_id,
- WEBKIT_INTERFACE_NAME=self._interface.id)
+ ' if (name == "$ID")\n'
+ ' return Dart$(WEBKIT_INTERFACE_NAME)Internal::$CPP_CALLBACK;\n',
+ ID=constructor_callback_id,
+ WEBKIT_INTERFACE_NAME=self._interface.id,
+ CPP_CALLBACK=constructor_callback_cpp_name)
+
+ def GenerateCustomFactory(self, constructor_info):
+ if 'CustomConstructor' not in self._interface.ext_attrs:
+ return False
+
+ self._members_emitter.Emit(
+ ' factory $CTOR($PARAMS) => _create($FACTORY_PARAMS);\n',
+ CTOR=constructor_info._ConstructorFullName(self._DartType),
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+ FACTORY_PARAMS= \
+ constructor_info.ParametersAsArgumentList())
+
+ constructor_callback_cpp_name = 'constructorCallback'
+ self._EmitConstructorInfrastructure(
+ constructor_info, constructor_callback_cpp_name, '_create')
+
+ self._cpp_declarations_emitter.Emit(
+ '\n'
+ 'void $CPP_CALLBACK(Dart_NativeArguments);\n',
+ CPP_CALLBACK=constructor_callback_cpp_name)
+
+ return True
+
+ def IsConstructorArgumentOptional(self, argument):
+ return False
+
+ def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
+ constructor_callback_cpp_name = name + 'constructorCallback'
+ self._EmitConstructorInfrastructure(
+ constructor_info, constructor_callback_cpp_name, name, len(arguments))
ext_attrs = self._interface.ext_attrs
- if 'CustomConstructor' in ext_attrs:
- # We have a custom implementation for it.
- self._cpp_declarations_emitter.Emit(
- '\n'
- 'void constructorCallback(Dart_NativeArguments);\n')
- return
-
create_function = 'create'
if 'NamedConstructor' in ext_attrs:
create_function = 'createForJSConstructor'
function_expression = '%s::%s' % (self._interface_type_info.native_type(), create_function)
self._GenerateNativeCallback(
- 'constructorCallback',
+ constructor_callback_cpp_name,
False,
function_expression,
self._interface,
- constructor_info.idl_args,
+ arguments,
self._interface.id,
'ConstructorRaisesException' in ext_attrs)
@@ -674,7 +702,8 @@
type_info.to_native_info(argument, self._interface.id)
if ((IsOptional(argument) and not self._IsArgumentOptionalInWebCore(node, argument)) or
- (argument.ext_attrs.get('Optional') == 'DefaultIsNullString')):
+ (argument.ext_attrs.get('Optional') == 'DefaultIsNullString') or
+ _IsOptionalStringArgumentInInitEventMethod(self._interface, node, argument)):
function += 'WithNullCheck'
argument_name = DartDomNameOfAttribute(argument)
@@ -734,7 +763,9 @@
def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
native_suffix, is_custom):
annotations = FormatAnnotationsAndComments(
- GetAnnotationsAndComments(self._interface.id, idl_name), ' ')
+ GetAnnotationsAndComments(self._renamer.GetLibraryName(self._interface),
+ self._interface.id, idl_name),
+ ' ')
native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
self._members_emitter.Emit(
@@ -859,3 +890,10 @@
' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount))\n'
' return func;\n',
CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
+
+def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument):
+ return (
+ interface.id.endswith('Event') and
+ operation.id.startswith('init') and
+ argument.ext_attrs.get('Optional') == 'DefaultIsUndefined' and
+ argument.type.id == 'DOMString')
diff --git a/tools/dom/src/CssClassSet.dart b/tools/dom/src/CssClassSet.dart
index 2c875b0..c688181 100644
--- a/tools/dom/src/CssClassSet.dart
+++ b/tools/dom/src/CssClassSet.dart
@@ -44,6 +44,8 @@
String join([String separator]) => readClasses().join(separator);
+ Iterable map(f(String element)) => readClasses().map(f);
+
Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
Iterable<String> where(bool f(String element)) => readClasses().where(f);
@@ -141,7 +143,7 @@
* Helper method used to modify the set of css classes on this element.
*
* f - callback with:
- * s - a Set of all the css class name currently on this element.
+ * s - a Set of all the css class name currently on this element.
*
* After f returns, the modified set is written to the
* className property of this element.
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 477359a..776d602 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -15,7 +15,7 @@
_EventStream(this._target, this._eventType, this._useCapture);
// DOM events are inherently multi-subscribers.
- Stream<T> asMultiSubscriberStream() => this;
+ Stream<T> asBroadcastStream() => this;
StreamSubscription<T> listen(void onData(T event),
{ void onError(AsyncError error),
diff --git a/tools/dom/src/KeyboardEventController.dart b/tools/dom/src/KeyboardEventController.dart
index 1e0f97a..73a7602 100644
--- a/tools/dom/src/KeyboardEventController.dart
+++ b/tools/dom/src/KeyboardEventController.dart
@@ -37,9 +37,8 @@
// The distance to shift from upper case alphabet Roman letters to lower case.
final 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;
+ StreamSubscription _keyUpSubscription, _keyDownSubscription,
+ _keyPressSubscription;
/**
* An enumeration of key identifiers currently part of the W3C draft for DOM3
@@ -95,9 +94,6 @@
_callbacks = [];
_type = type;
_target = target;
- _keyDown = processKeyDown;
- _keyUp = processKeyUp;
- _keyPress = processKeyPress;
}
/**
@@ -106,9 +102,14 @@
*/
void _initializeAllEventListeners() {
_keyDownList = [];
- _target.on.keyDown.add(_keyDown, true);
- _target.on.keyPress.add(_keyPress, true);
- _target.on.keyUp.add(_keyUp, true);
+ if (_keyDownSubscription == null) {
+ _keyDownSubscription = Element.keyDownEvent.forTarget(
+ _target, useCapture: true).listen(processKeyDown);
+ _keyPressSubscription = Element.keyPressEvent.forTarget(
+ _target, useCapture: true).listen(processKeyUp);
+ _keyUpSubscription = Element.keyUpEvent.forTarget(
+ _target, useCapture: true).listen(processKeyPress);
+ }
}
/** Add a callback that wishes to be notified when a KeyEvent occurs. */
@@ -142,9 +143,12 @@
}
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);
+ _keyDownSubscription.cancel();
+ _keyDownSubscription = null;
+ _keyPressSubscription.cancel();
+ _keyPressSubscription = null;
+ _keyUpSubscription.cancel();
+ _keyUpSubscription = null;
}
}
diff --git a/tools/dom/src/Measurement.dart b/tools/dom/src/Measurement.dart
deleted file mode 100644
index f664aac..0000000
--- a/tools/dom/src/Measurement.dart
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-typedef Object ComputeValue();
-
-class _MeasurementRequest<T> {
- final ComputeValue computeValue;
- final Completer<T> completer;
- Object value;
- bool exception = false;
- _MeasurementRequest(this.computeValue, this.completer);
-}
-
-typedef void _MeasurementCallback();
-
-/**
- * This class attempts to invoke a callback as soon as the current event stack
- * unwinds, but before the browser repaints.
- */
-abstract class _MeasurementScheduler {
- bool _nextMeasurementFrameScheduled = false;
- _MeasurementCallback _callback;
-
- _MeasurementScheduler(this._callback);
-
- /**
- * Creates the best possible measurement scheduler for the current platform.
- */
- factory _MeasurementScheduler.best(_MeasurementCallback callback) {
- if (MutationObserver.supported) {
- return new _MutationObserverScheduler(callback);
- }
- return new _PostMessageScheduler(callback);
- }
-
- /**
- * Schedules a measurement callback if one has not been scheduled already.
- */
- void maybeSchedule() {
- if (this._nextMeasurementFrameScheduled) {
- return;
- }
- this._nextMeasurementFrameScheduled = true;
- this._schedule();
- }
-
- /**
- * Does the actual scheduling of the callback.
- */
- void _schedule();
-
- /**
- * Handles the measurement callback and forwards it if necessary.
- */
- void _onCallback() {
- // Ignore spurious messages.
- if (!_nextMeasurementFrameScheduled) {
- return;
- }
- _nextMeasurementFrameScheduled = false;
- this._callback();
- }
-}
-
-/**
- * Scheduler which uses window.postMessage to schedule events.
- */
-class _PostMessageScheduler extends _MeasurementScheduler {
- const _MEASUREMENT_MESSAGE = "DART-MEASURE";
-
- _PostMessageScheduler(_MeasurementCallback callback): super(callback) {
- // Messages from other windows do not cause a security risk as
- // all we care about is that _handleMessage is called
- // after the current event loop is unwound and calling the function is
- // a noop when zero requests are pending.
- window.on.message.add(this._handleMessage);
- }
-
- void _schedule() {
- window.postMessage(_MEASUREMENT_MESSAGE, "*");
- }
-
- _handleMessage(e) {
- this._onCallback();
- }
-}
-
-/**
- * Scheduler which uses a MutationObserver to schedule events.
- */
-class _MutationObserverScheduler extends _MeasurementScheduler {
- MutationObserver _observer;
- Element _dummy;
-
- _MutationObserverScheduler(_MeasurementCallback callback): super(callback) {
- // Mutation events get fired as soon as the current event stack is unwound
- // so we just make a dummy event and listen for that.
- _observer = new MutationObserver(this._handleMutation);
- _dummy = new DivElement();
- _observer.observe(_dummy, attributes: true);
- }
-
- void _schedule() {
- // Toggle it to trigger the mutation event.
- _dummy.hidden = !_dummy.hidden;
- }
-
- _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
- this._onCallback();
- }
-}
-
-
-List<_MeasurementRequest> _pendingRequests;
-List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
-_MeasurementScheduler _measurementScheduler = null;
-
-void _maybeScheduleMeasurementFrame() {
- if (_measurementScheduler == null) {
- _measurementScheduler =
- new _MeasurementScheduler.best(_completeMeasurementFutures);
- }
- _measurementScheduler.maybeSchedule();
-}
-
-/**
- * Registers a [callback] which is called after the next batch of measurements
- * completes. Even if no measurements completed, the callback is triggered
- * when they would have completed to avoid confusing bugs if it happened that
- * no measurements were actually requested.
- */
-void _addMeasurementFrameCallback(TimeoutHandler callback) {
- if (_pendingMeasurementFrameCallbacks == null) {
- _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
- _maybeScheduleMeasurementFrame();
- }
- _pendingMeasurementFrameCallbacks.add(callback);
-}
-
-/**
- * Returns a [Future] whose value will be the result of evaluating
- * [computeValue] during the next safe measurement interval.
- * The next safe measurement interval is after the current event loop has
- * unwound but before the browser has rendered the page.
- * It is important that the [computeValue] function only queries the html
- * layout and html in any way.
- */
-Future _createMeasurementFuture(ComputeValue computeValue,
- Completer completer) {
- if (_pendingRequests == null) {
- _pendingRequests = <_MeasurementRequest>[];
- _maybeScheduleMeasurementFrame();
- }
- _pendingRequests.add(new _MeasurementRequest(computeValue, completer));
- return completer.future;
-}
-
-/**
- * Complete all pending measurement futures evaluating them in a single batch
- * so that the the browser is guaranteed to avoid multiple layouts.
- */
-void _completeMeasurementFutures() {
- // We must compute all new values before fulfilling the futures as
- // the onComplete callbacks for the futures could modify the DOM making
- // subsequent measurement calculations expensive to compute.
- if (_pendingRequests != null) {
- for (_MeasurementRequest request in _pendingRequests) {
- try {
- request.value = request.computeValue();
- } catch (e) {
- request.value = e;
- request.exception = true;
- }
- }
- }
-
- final completedRequests = _pendingRequests;
- final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
- _pendingRequests = null;
- _pendingMeasurementFrameCallbacks = null;
- if (completedRequests != null) {
- for (_MeasurementRequest request in completedRequests) {
- if (request.exception) {
- request.completer.completeError(request.value);
- } else {
- request.completer.complete(request.value);
- }
- }
- }
-
- if (readyMeasurementFrameCallbacks != null) {
- for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
- // TODO(jacobr): wrap each call to a handler in a try-catch block.
- handler();
- }
- }
-}
diff --git a/tools/dom/src/Microtask.dart b/tools/dom/src/Microtask.dart
new file mode 100644
index 0000000..4b811e4
--- /dev/null
+++ b/tools/dom/src/Microtask.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 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;
+
+typedef void _MicrotaskCallback();
+
+/**
+ * This class attempts to invoke a callback as soon as the current event stack
+ * unwinds, but before the browser repaints.
+ */
+abstract class _MicrotaskScheduler {
+ bool _nextMicrotaskFrameScheduled = false;
+ _MicrotaskCallback _callback;
+
+ _MicrotaskScheduler(this._callback);
+
+ /**
+ * Creates the best possible microtask scheduler for the current platform.
+ */
+ factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+ if (Window._supportsSetImmediate) {
+ return new _SetImmediateScheduler(callback);
+ } else if (MutationObserver.supported) {
+ return new _MutationObserverScheduler(callback);
+ }
+ return new _PostMessageScheduler(callback);
+ }
+
+ /**
+ * Schedules a microtask callback if one has not been scheduled already.
+ */
+ void maybeSchedule() {
+ if (this._nextMicrotaskFrameScheduled) {
+ return;
+ }
+ this._nextMicrotaskFrameScheduled = true;
+ this._schedule();
+ }
+
+ /**
+ * Does the actual scheduling of the callback.
+ */
+ void _schedule();
+
+ /**
+ * Handles the microtask callback and forwards it if necessary.
+ */
+ void _onCallback() {
+ // Ignore spurious messages.
+ if (!_nextMicrotaskFrameScheduled) {
+ return;
+ }
+ _nextMicrotaskFrameScheduled = false;
+ this._callback();
+ }
+}
+
+/**
+ * Scheduler which uses window.postMessage to schedule events.
+ */
+class _PostMessageScheduler extends _MicrotaskScheduler {
+ const _MICROTASK_MESSAGE = "DART-MICROTASK";
+
+ _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
+ // Messages from other windows do not cause a security risk as
+ // all we care about is that _handleMessage is called
+ // after the current event loop is unwound and calling the function is
+ // a noop when zero requests are pending.
+ window.onMessage.listen(this._handleMessage);
+ }
+
+ void _schedule() {
+ window.postMessage(_MICROTASK_MESSAGE, "*");
+ }
+
+ void _handleMessage(e) {
+ this._onCallback();
+ }
+}
+
+/**
+ * Scheduler which uses a MutationObserver to schedule events.
+ */
+class _MutationObserverScheduler extends _MicrotaskScheduler {
+ MutationObserver _observer;
+ Element _dummy;
+
+ _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
+ // Mutation events get fired as soon as the current event stack is unwound
+ // so we just make a dummy event and listen for that.
+ _observer = new MutationObserver(this._handleMutation);
+ _dummy = new DivElement();
+ _observer.observe(_dummy, attributes: true);
+ }
+
+ void _schedule() {
+ // Toggle it to trigger the mutation event.
+ _dummy.hidden = !_dummy.hidden;
+ }
+
+ _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
+ this._onCallback();
+ }
+}
+
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+ _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
+
+ void _schedule() {
+ window._setImmediate(_handleImmediate);
+ }
+
+ void _handleImmediate() {
+ this._onCallback();
+ }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+ if (_microtaskScheduler == null) {
+ _microtaskScheduler =
+ new _MicrotaskScheduler.best(_completeMicrotasks);
+ }
+ _microtaskScheduler.maybeSchedule();
+}
+
+/**
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
+ */
+void _addMicrotaskCallback(TimeoutHandler callback) {
+ if (_pendingMicrotasks == null) {
+ _pendingMicrotasks = <TimeoutHandler>[];
+ _maybeScheduleMicrotaskFrame();
+ }
+ _pendingMicrotasks.add(callback);
+}
+
+
+/**
+ * Complete all pending microtasks.
+ */
+void _completeMicrotasks() {
+ var callbacks = _pendingMicrotasks;
+ _pendingMicrotasks = null;
+ for (var callback in callbacks) {
+ callback();
+ }
+}
diff --git a/tools/dom/src/_HttpRequestUtils.dart b/tools/dom/src/_HttpRequestUtils.dart
index 7ebd01f..352ddfc 100644
--- a/tools/dom/src/_HttpRequestUtils.dart
+++ b/tools/dom/src/_HttpRequestUtils.dart
@@ -15,7 +15,7 @@
request.withCredentials = withCredentials;
- request.on.readyStateChange.add((e) {
+ request.onReadyStateChange.listen((e) {
if (request.readyState == HttpRequest.DONE) {
onComplete(request);
}
diff --git a/tools/dom/src/_Testing.dart b/tools/dom/src/_Testing.dart
deleted file mode 100644
index 7b15688..0000000
--- a/tools/dom/src/_Testing.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-// TODO(rnystrom): add a way to supress public classes from DartDoc output.
-// TODO(jacobr): we can remove this class now that we are using the $dom_
-// convention for deprecated methods rather than truly private methods.
-/**
- * This class is intended for testing purposes only.
- */
-class Testing {
- static void addEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
- target.$dom_addEventListener(type, listener, useCapture);
- }
- static void removeEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
- target.$dom_removeEventListener(type, listener, useCapture);
- }
-
-}
diff --git a/tools/dom/src/chrome/app.runtime.dart b/tools/dom/src/chrome/app.runtime.dart
new file mode 100644
index 0000000..8b38aac
--- /dev/null
+++ b/tools/dom/src/chrome/app.runtime.dart
@@ -0,0 +1,257 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// from app_runtime.idl
+part of chrome;
+
+/**
+ * Types
+ */
+
+/// A WebIntents intent object. Deprecated.
+class Intent extends ChromeObject {
+ /*
+ * Public (Dart) constructor
+ */
+ Intent({String action, String type, var data}) {
+ this.action = action;
+ this.type = type;
+ this.data = data;
+ }
+
+ /*
+ * Private (JS) constructor
+ */
+ Intent._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+
+ /// The WebIntent being invoked.
+ String get action => JS('String', '#.action', this._jsObject);
+
+ void set action(String action) {
+ JS('void', '#.action = #', this._jsObject, action);
+ }
+
+ /// The MIME type of the data.
+ String get type => JS('String', '#.type', this._jsObject);
+
+ void set type(String type) {
+ JS('void', '#.type = #', this._jsObject, type);
+ }
+
+ /// Data associated with the intent.
+ // TODO(sashab): What is the best way to serialize/return generic JS objects?
+ Object get data => JS('Object', '#.data', this._jsObject);
+
+ void set data(Object data) {
+ JS('void', '#.data = #', this._jsObject, convertArgument(data));
+ }
+
+ /*
+ * TODO(sashab): What is a NullCallback() type?
+ * Add postResult and postFailure once understanding what this type is, and
+ * once there is a way to pass functions back from JS.
+ */
+}
+
+class LaunchItem extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ LaunchItem({FileEntry entry, String type}) {
+ this.entry = entry;
+ this.type = type;
+ }
+
+ /*
+ * Private constructor
+ */
+ LaunchItem._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+
+ /// FileEntry for the file.
+ FileEntry get entry => JS('FileEntry', '#.entry', this._jsObject);
+
+ void set entry(FileEntry entry) {
+ JS('void', '#.entry = #', this._jsObject, entry);
+ }
+
+ /// The MIME type of the file.
+ String get type => JS('String', '#.type', this._jsObject);
+
+ void set type(String type) {
+ JS('void', '#.type = #', this._jsObject, type);
+ }
+}
+
+/// Optional data for the launch.
+class LaunchData extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ LaunchData({Intent intent, String id, List<LaunchItem> items}) {
+ this.intent = intent;
+ this.id = id;
+ this.items = items;
+ }
+
+ /*
+ * Private constructor
+ */
+ LaunchData._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ Intent get intent => new Intent._proxy(JS('', '#.intent', this._jsObject));
+
+ void set intent(Intent intent) {
+ JS('void', '#.intent = #', this._jsObject, convertArgument(intent));
+ }
+
+ /// The id of the file handler that the app is being invoked with.
+ String get id => JS('String', '#.id', this._jsObject);
+
+ void set id(String id) {
+ JS('void', '#.id = #', this._jsObject, id);
+ }
+
+ List<LaunchItem> get items() {
+ List<LaunchItem> items_final = new List<LaunchItem>();
+ for (var o in JS('List', '#.items', this._jsObject)) {
+ items_final.add(new LaunchItem._proxy(o));
+ }
+ return items_final;
+ }
+
+ void set items(List<LaunchItem> items) {
+ JS('void', '#.items = #', this._jsObject, convertArgument(items));
+ }
+}
+
+class IntentResponse extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ IntentResponse({int intentId, bool success, Object data}) {
+ this.intentId = intentId;
+ this.success = success;
+ this.data = data;
+ }
+
+ /*
+ * Private constructor
+ */
+ IntentResponse._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+
+ /// Identifies the intent.
+ int get intentId => JS('int', '#.intentId', this._jsObject);
+
+ void set intentId(int intentId) {
+ JS('void', '#.intentId = #', this._jsObject, intentId);
+ }
+
+ /// Was this intent successful? (i.e., postSuccess vs postFailure).
+ bool get success => JS('bool', '#.success', this._jsObject);
+
+ void set success(bool success) {
+ JS('void', '#.success = #', this._jsObject, success);
+ }
+
+ /// Data associated with the intent response.
+ // TODO(sashab): What's the best way to serialize/return generic JS objects?
+ Object get data => JS('Object', '#.data', this._jsObject);
+
+ void set data(Object data) {
+ JS('void', '#.data = #', this._jsObject, convertArgument(data));
+ }
+}
+
+/**
+ * Events
+ */
+
+/// Fired at Chrome startup to apps that were running when Chrome last shut
+/// down.
+class Event_ChromeAppRuntimeOnRestarted extends Event {
+ /*
+ * Override callback type definitions
+ */
+ void addListener(void callback())
+ => super.addListener(callback);
+ void removeListener(void callback())
+ => super.removeListener(callback);
+ bool hasListener(void callback())
+ => super.hasListener(callback);
+
+ /*
+ * Constructor
+ */
+ Event_ChromeAppRuntimeOnRestarted(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when an app is launched from the launcher or in response to a web
+/// intent.
+class Event_ChromeAppRuntimeOnLaunched extends Event {
+ /*
+ * Override callback type definitions
+ */
+ void addListener(void callback(LaunchData launchData))
+ => super.addListener(callback);
+ void removeListener(void callback(LaunchData launchData))
+ => super.removeListener(callback);
+ bool hasListener(void callback(LaunchData launchData))
+ => super.hasListener(callback);
+
+ /*
+ * Constructor
+ */
+ Event_ChromeAppRuntimeOnLaunched(jsObject) : super._(jsObject, 1);
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppRuntime {
+ /*
+ * API connection
+ */
+ Object _jsObject;
+
+ /*
+ * Events
+ */
+ Event_ChromeAppRuntimeOnRestarted onRestarted;
+ Event_ChromeAppRuntimeOnLaunched onLaunched;
+
+ /*
+ * Functions
+ */
+ void postIntentResponse(IntentResponse intentResponse) =>
+ JS('void', '#.postIntentResponse(#)', this._jsObject,
+ convertArgument(intentResponse));
+
+ /*
+ * Constructor
+ */
+ API_ChromeAppRuntime(this._jsObject) {
+ onRestarted = new Event_ChromeAppRuntimeOnRestarted(JS('Object',
+ '#.onRestarted',
+ this._jsObject));
+ onLaunched = new Event_ChromeAppRuntimeOnLaunched(JS('Object',
+ '#.onLaunched',
+ this._jsObject));
+ }
+}
+
diff --git a/tools/dom/src/chrome/app.window.dart b/tools/dom/src/chrome/app.window.dart
new file mode 100644
index 0000000..24aad67
--- /dev/null
+++ b/tools/dom/src/chrome/app.window.dart
@@ -0,0 +1,359 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// from app.window.idl
+part of chrome;
+
+/**
+ * Types
+ */
+class CreateWindowOptions extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ CreateWindowOptions({String id, int defaultWidth, int defaultHeight,
+ int defaultLeft, int defaultTop, int width, int height, int left, int top,
+ int minWidth, int minHeight, int maxWidth, int maxHeight, String type,
+ String frame, Bounds bounds, bool hidden}) {
+ this.id = id;
+ this.defaultWidth = defaultWidth;
+ this.defaultHeight = defaultHeight;
+ this.defaultLeft = defaultLeft;
+ this.defaultTop = defaultTop;
+ this.width = width;
+ this.height = height;
+ this.left = left;
+ this.top = top;
+ this.minWidth = minWidth;
+ this.minHeight = minHeight;
+ this.maxWidth = maxWidth;
+ this.maxHeight = maxHeight;
+ this.type = type;
+ this.frame = frame;
+ this.bounds = bounds;
+ this.hidden = hidden;
+ }
+
+ /*
+ * Private constructor
+ */
+ CreateWindowOptions._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ /// Id to identify the window. This will be used to remember the size
+ /// and position of the window and restore that geometry when a window
+ /// with the same id (and no explicit size or position) is later opened.
+ String get id => JS('String', '#.id', this._jsObject);
+
+ void set id(String id) {
+ JS('void', '#.id = #', this._jsObject, id);
+ }
+
+ /// Default width of the window. (Deprecated; regular bounds act like this
+ /// now.)
+ int get defaultWidth => JS('int', '#.defaultWidth', this._jsObject);
+
+ void set defaultWidth(int defaultWidth) {
+ JS('void', '#.defaultWidth = #', this._jsObject, defaultWidth);
+ }
+
+ /// Default height of the window. (Deprecated; regular bounds act like this
+ /// now.)
+ int get defaultHeight => JS('int', '#.defaultHeight', this._jsObject);
+
+ void set defaultHeight(int defaultHeight) {
+ JS('void', '#.defaultHeight = #', this._jsObject, defaultHeight);
+ }
+
+ /// Default X coordinate of the window. (Deprecated; regular bounds act like
+ /// this now.)
+ int get defaultLeft => JS('int', '#.defaultLeft', this._jsObject);
+
+ void set defaultLeft(int defaultLeft) {
+ JS('void', '#.defaultLeft = #', this._jsObject, defaultLeft);
+ }
+
+ /// Default Y coordinate of the window. (Deprecated; regular bounds act like
+ /// this now.)
+ int get defaultTop => JS('int', '#.defaultTop', this._jsObject);
+
+ void set defaultTop(int defaultTop) {
+ JS('void', '#.defaultTop = #', this._jsObject, defaultTop);
+ }
+
+ /// Width of the window. (Deprecated; use 'bounds'.)
+ int get width => JS('int', '#.width', this._jsObject);
+
+ void set width(int width) {
+ JS('void', '#.width = #', this._jsObject, width);
+ }
+
+ /// Height of the window. (Deprecated; use 'bounds'.)
+ int get height => JS('int', '#.height', this._jsObject);
+
+ void set height(int height) {
+ JS('void', '#.height = #', this._jsObject, height);
+ }
+
+ /// X coordinate of the window. (Deprecated; use 'bounds'.)
+ int get left => JS('int', '#.left', this._jsObject);
+
+ void set left(int left) {
+ JS('void', '#.left = #', this._jsObject, left);
+ }
+
+ /// Y coordinate of the window. (Deprecated; use 'bounds'.)
+ int get top => JS('int', '#.top', this._jsObject);
+
+ void set top(int top) {
+ JS('void', '#.top = #', this._jsObject, top);
+ }
+
+ /// Minimium width of the window.
+ int get minWidth => JS('int', '#.minWidth', this._jsObject);
+
+ void set minWidth(int minWidth) {
+ JS('void', '#.minWidth = #', this._jsObject, minWidth);
+ }
+
+ /// Minimum height of the window.
+ int get minHeight => JS('int', '#.minHeight', this._jsObject);
+
+ void set minHeight(int minHeight) {
+ JS('void', '#.minHeight = #', this._jsObject, minHeight);
+ }
+
+ /// Maximum width of the window.
+ int get maxWidth => JS('int', '#.maxWidth', this._jsObject);
+
+ void set maxWidth(int maxWidth) {
+ JS('void', '#.maxWidth = #', this._jsObject, maxWidth);
+ }
+
+ /// Maximum height of the window.
+ int get maxHeight => JS('int', '#.maxHeight', this._jsObject);
+
+ void set maxHeight(int maxHeight) {
+ JS('void', '#.maxHeight = #', this._jsObject, maxHeight);
+ }
+
+ /// Window type: 'shell' (the default) is the only currently supported value.
+ String get type => JS('String', '#.type', this._jsObject);
+
+ void set type(String type) {
+ JS('void', '#.type = #', this._jsObject, type);
+ }
+
+ /// Frame type: 'none' or 'chrome' (defaults to 'chrome').
+ String get frame => JS('String', '#.frame', this._jsObject);
+
+ void set frame(String frame) {
+ JS('void', '#.frame = #', this._jsObject, frame);
+ }
+
+ /// Size of the content in the window (excluding the titlebar). If specified
+ /// in addition to any of the left/top/width/height parameters, this field
+ /// takes precedence. If a frameBounds is specified, the frameBounds take
+ /// precedence.
+ Bounds get bounds =>
+ new Bounds._proxy(JS('Bounds', '#.bounds', this._jsObject));
+
+ void set bounds(Bounds bounds) {
+ JS('void', '#.bounds = #', this._jsObject, convertArgument(bounds));
+ }
+
+ /// If true, the window will be created in a hidden state. Call show() on
+ /// the window to show it once it has been created. Defaults to false.
+ bool get hidden => JS('bool', '#.hidden', this._jsObject);
+
+ void set hidden(bool hidden) {
+ JS('void', '#.hidden = #', this._jsObject, hidden);
+ }
+}
+
+class Bounds extends ChromeObject {
+ /*
+ * Public constructor
+ */
+ Bounds({int left, int top, int width, int height}) {
+ this.left = left;
+ this.top = top;
+ this.width = width;
+ this.height = height;
+ }
+
+ /*
+ * Private constructor
+ */
+ Bounds._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ int get left => JS('int', '#.left', this._jsObject);
+
+ void set left(int left) {
+ JS('void', '#.left = #', this._jsObject, left);
+ }
+
+ int get top => JS('int', '#.top', this._jsObject);
+
+ void set top(int top) {
+ JS('void', '#.top = #', this._jsObject, top);
+ }
+
+ int get width => JS('int', '#.width', this._jsObject);
+
+ void set width(int width) {
+ JS('void', '#.width = #', this._jsObject, width);
+ }
+
+ int get height => JS('int', '#.height', this._jsObject);
+
+ void set height(int height) {
+ JS('void', '#.height = #', this._jsObject, height);
+ }
+}
+
+class AppWindow extends ChromeObject {
+ /*
+ * Public constructor
+ * TODO(sashab): Does it make sense to be able to create a new AppWindow this
+ * way?
+ */
+ //AppWindow();
+
+ /*
+ * Private constructor
+ */
+ AppWindow._proxy(jsObject) : super._proxy(jsObject);
+
+ /*
+ * Public accessors
+ */
+ /// The JavaScript 'window' object for the created child.
+ // TODO(sashab, sra): Detect whether this is the current window, or an
+ // external one, and return an appropriately-typed object
+ WindowBase get contentWindow =>
+ JS("Window", "#.contentWindow", this._jsObject);
+
+ /*
+ * Functions
+ */
+
+ /// Focus the window.
+ void focus() => JS("void", "#.focus()", this._jsObject);
+
+ /// Minimize the window.
+ void minimize() => JS("void", "#.minimize()", this._jsObject);
+
+ /// Is the window minimized?
+ bool isMinimized() => JS("bool", "#.isMinimized()", this._jsObject);
+
+ /// Maximize the window.
+ void maximize() => JS("void", "#.maximize()", this._jsObject);
+
+ /// Is the window maximized?
+ bool isMaximized() => JS("bool", "c#.isMaximized()", this._jsObject);
+
+ /// Restore the window.
+ void restore() => JS("void", "#.restore()", this._jsObject);
+
+ /// Move the window to the position (|left|, |top|).
+ void moveTo(int left, int top) =>
+ JS("void", "#.moveTo(#, #)", this._jsObject, left, top);
+
+ /// Resize the window to |width|x|height| pixels in size.
+ void resizeTo(int width, int height) =>
+ JS("void", "#.resizeTo(#, #)", this._jsObject, width, height);
+
+ /// Draw attention to the window.
+ void drawAttention() => JS("void", "#.drawAttention()", this._jsObject);
+
+ /// Clear attention to the window.
+ void clearAttention() => JS("void", "#.clearAttention()", this._jsObject);
+
+ /// Close the window.
+ void close() => JS("void", "#.close()", this._jsObject);
+
+ /// Show the window. Does nothing if the window is already visible.
+ void show() => JS("void", "#.show()", this._jsObject);
+
+ /// Hide the window. Does nothing if the window is already hidden.
+ void hide() => JS("void", "#.hide()", this._jsObject);
+
+ /// Set the window's bounds.
+ void setBounds(Bounds bounds) =>
+ JS("void", "#.setBounds(#)", this._jsObject, convertArgument(bounds));
+
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppWindow {
+ /**
+ * JS object
+ */
+ Object _jsObject;
+
+ /**
+ * Constructor
+ */
+ API_ChromeAppWindow(this._jsObject);
+
+ /**
+ * Functions
+ */
+
+ /// Returns an <a href="#type-AppWindow">AppWindow</a> object for the
+ /// current script context (ie JavaScript 'window' object). This can also be
+ /// called on a handle to a script context for another page, for example:
+ /// otherWindow.chrome.app.window.current().
+ AppWindow current() =>
+ new AppWindow._proxy(JS("Object", "#.current()", this._jsObject));
+
+ /// The size and position of a window can be specified in a number of
+ /// different ways. The most simple option is not specifying anything at
+ /// all, in which case a default size and platform dependent position will
+ /// be used.
+ ///
+ /// Another option is to use the top/left and width/height properties,
+ /// which will always put the window at the specified coordinates with the
+ /// specified size.
+ ///
+ /// Yet another option is to give the window a (unique) id. This id is then
+ /// used to remember the size and position of the window whenever it is
+ /// moved or resized. This size and position is then used instead of the
+ /// specified bounds on subsequent opening of a window with the same id. If
+ /// you need to open a window with an id at a location other than the
+ /// remembered default, you can create it hidden, move it to the desired
+ /// location, then show it.
+ ///
+ /// You can also combine these various options, explicitly specifying for
+ /// example the size while having the position be remembered or other
+ /// combinations like that. Size and position are dealt with seperately,
+ /// but individual coordinates are not. So if you specify a top (or left)
+ /// coordinate, you should also specify a left (or top) coordinate, and
+ /// similar for size.
+ ///
+ /// If you specify both a regular and a default value for the same option
+ /// the regular value is the only one that takes effect.
+ void create(String url, [CreateWindowOptions options,
+ void callback(AppWindow created_window)]) {
+ void __proxy_callback(Object created_window) {
+ if (?callback)
+ callback(new AppWindow._proxy(created_window));
+ }
+
+ JS("void", "#.create(#, #, #)",
+ this._jsObject,
+ url,
+ convertArgument(options),
+ convertDartClosureToJS(__proxy_callback, 1)
+ );
+ }
+}
\ No newline at end of file
diff --git a/tools/dom/src/chrome/chrome.dart b/tools/dom/src/chrome/chrome.dart
new file mode 100644
index 0000000..97464a1
--- /dev/null
+++ b/tools/dom/src/chrome/chrome.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 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 chrome;
+
+// chrome.app
+class API_ChromeApp {
+ /*
+ * JS Variable
+ */
+ Object _jsObject;
+
+ /*
+ * Members
+ */
+ API_ChromeAppWindow window;
+ API_ChromeAppRuntime runtime;
+
+ /*
+ * Constructor
+ */
+ API_ChromeApp(this._jsObject) {
+ var window_object = JS('', '#.window', this._jsObject);
+ if (window_object == null)
+ throw new UnsupportedError('Not supported by current browser.');
+ window = new API_ChromeAppWindow(window_object);
+
+ var runtime_object = JS('', '#.runtime', this._jsObject);
+ if (runtime_object == null)
+ throw new UnsupportedError('Not supported by current browser.');
+ runtime = new API_ChromeAppRuntime(runtime_object);
+ }
+}
+
+// chrome
+class API_Chrome {
+ /*
+ * JS Variable
+ */
+ Object _jsObject;
+
+ /*
+ * Members
+ */
+ API_ChromeApp app;
+
+ /*
+ * Constructor
+ */
+ API_Chrome() {
+ this._jsObject = JS("Object", "chrome");
+ if (this._jsObject == null)
+ throw new UnsupportedError('Not supported by current browser.');
+
+ var app_object = JS('', '#.app', this._jsObject);
+ if (app_object == null)
+ throw new UnsupportedError('Not supported by current browser.');
+ app = new API_ChromeApp(app_object);
+ }
+}
+
+// The final chrome objects
+final API_Chrome chrome = new API_Chrome();
diff --git a/tools/dom/src/chrome/sample.dart b/tools/dom/src/chrome/sample.dart
deleted file mode 100644
index 4578b44..0000000
--- a/tools/dom/src/chrome/sample.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of chrome;
-
-// This is an example of exposing chrome APIs in Dart and will be replaced with
-// the proper implementation in the future.
-
-class AppModule {
- AppModule._();
-
- WindowModule get window => new WindowModule._();
-}
-
-class WindowModule {
- WindowModule._();
-
- void create(String url) {
- var chrome = JS('', 'chrome');
-
- if (chrome == null) {
- throw new UnsupportedError('Not supported by current browser');
- }
- var app = JS('', '#.app', chrome);
- if (app == null) {
- throw new UnsupportedError('Not supported by current browser');
- }
- var window = JS('', '#.window', app);
- if (app == null) {
- throw new UnsupportedError('Not supported by current browser');
- }
- JS('void', '#.create(#)', window, url);
- }
-}
-
-final app = new AppModule._();
diff --git a/tools/dom/src/chrome/utils.dart b/tools/dom/src/chrome/utils.dart
new file mode 100644
index 0000000..eddc6a4
--- /dev/null
+++ b/tools/dom/src/chrome/utils.dart
@@ -0,0 +1,295 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * A set of utilities for use with the Chrome Extension APIs.
+ *
+ * Allows for easy access to required JS objects.
+ */
+part of chrome;
+
+/**
+ * A dart object, that is convertible to JS. Used for creating objects in dart,
+ * then passing them to JS.
+ *
+ * Objects that are passable to JS need to implement this interface.
+ */
+abstract class ChromeObject {
+ /*
+ * Default Constructor
+ *
+ * Called by child objects during their regular construction.
+ */
+ ChromeObject() : _jsObject = JS('var', '{}');
+
+ /*
+ * Internal proxy constructor
+ *
+ * Creates a new Dart object using this existing proxy.
+ */
+ ChromeObject._proxy(this._jsObject);
+
+ /*
+ * JS Object Representation
+ */
+ Object _jsObject;
+}
+
+/**
+ * Useful functions for converting arguments.
+ */
+
+/**
+ * Converts the given map-type argument to js-friendly format, recursively.
+ * Returns the new Map object.
+ */
+Object _convertMapArgument(Map argument) {
+ Map m = new Map();
+ for (Object key in argument.keys)
+ m[key] = convertArgument(argument[key]);
+ return convertDartToNative_Dictionary(m);
+}
+
+/**
+ * Converts the given list-type argument to js-friendly format, recursively.
+ * Returns the new List object.
+ */
+List _convertListArgument(List argument) {
+ List l = new List();
+ for (var i = 0; i < argument.length; i ++)
+ l.add(convertArgument(argument[i]));
+ return l;
+}
+
+/**
+ * Converts the given argument Object to js-friendly format, recursively.
+ *
+ * Flattens out all Chrome objects into their corresponding ._toMap()
+ * definitions, then converts them to JS objects.
+ *
+ * Returns the new argument.
+ *
+ * Cannot be used for functions.
+ */
+Object convertArgument(var argument) {
+ if (argument == null)
+ return argument;
+
+ if (argument is num || argument is String || argument is bool)
+ return argument;
+
+ if (argument is ChromeObject)
+ return argument._jsObject;
+
+ if (argument is List)
+ return _convertListArgument(argument);
+
+ if (argument is Map)
+ return _convertMapArgument(argument);
+
+ if (argument is Function)
+ throw new Exception("Cannot serialize Function argument ${argument}.");
+
+ // TODO(sashab): Try and detect whether the argument is already serialized.
+ return argument;
+}
+
+/// Description of a declarative rule for handling events.
+class Rule extends ChromeObject {
+ /*
+ * Public (Dart) constructor
+ */
+ Rule({String id, List conditions, List actions, int priority}) {
+ this.id = id;
+ this.conditions = conditions;
+ this.actions = actions;
+ this.priority = priority;
+ }
+
+ /*
+ * Private (JS) constructor
+ */
+ Rule._proxy(_jsObject) : super._proxy(_jsObject);
+
+ /*
+ * Public accessors
+ */
+ String get id => JS('String', '#.id', this._jsObject);
+
+ void set id(String id) {
+ JS('void', '#.id = #', this._jsObject, id);
+ }
+
+ // TODO(sashab): Wrap these generic Lists somehow.
+ List get conditions => JS('List', '#.conditions', this._jsObject);
+
+ void set conditions(List conditions) {
+ JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions));
+ }
+
+ // TODO(sashab): Wrap these generic Lists somehow.
+ List get actions => JS('List', '#.actions', this._jsObject);
+
+ void set actions(List actions) {
+ JS('void', '#.actions = #', this._jsObject, convertArgument(actions));
+ }
+
+ int get priority => JS('int', '#.priority', this._jsObject);
+
+ void set priority(int priority) {
+ JS('void', '#.priority = #', this._jsObject, priority);
+ }
+
+}
+
+/**
+ * The Event class.
+ *
+ * Chrome Event classes extend this interface.
+ *
+ * e.g.
+ *
+ * // chrome.app.runtime.onLaunched
+ * class Event_ChromeAppRuntimeOnLaunched extends Event {
+ * // constructor, passing the arity of the callback
+ * Event_ChromeAppRuntimeOnLaunched(jsObject) :
+ * super._(jsObject, 1);
+ *
+ * // methods, strengthening the Function parameter specificity
+ * void addListener(void callback(LaunchData launchData))
+ * => super.addListener(callback);
+ * void removeListener(void callback(LaunchData launchData))
+ * => super.removeListener(callback);
+ * bool hasListener(void callback(LaunchData launchData))
+ * => super.hasListener(callback);
+ * }
+ *
+ */
+class Event {
+ /*
+ * JS Object Representation
+ */
+ Object _jsObject;
+
+ /*
+ * Number of arguments the callback takes.
+ */
+ int _callbackArity;
+
+ /*
+ * Private constructor
+ */
+ Event._(this._jsObject, this._callbackArity);
+
+ /*
+ * Methods
+ */
+
+ /// Registers an event listener <em>callback</em> to an event.
+ void addListener(Function callback) =>
+ JS('void',
+ '#.addListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /// Deregisters an event listener <em>callback</em> from an event.
+ void removeListener(Function callback) =>
+ JS('void',
+ '#.removeListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /// Returns True if <em>callback</em> is registered to the event.
+ bool hasListener(Function callback) =>
+ JS('bool',
+ '#.hasListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /// Returns true if any event listeners are registered to the event.
+ bool hasListeners() =>
+ JS('bool',
+ '#.hasListeners()',
+ this._jsObject
+ );
+
+ /// Registers rules to handle events.
+ ///
+ /// [eventName] is the name of the event this function affects and [rules] are
+ /// the rules to be registered. These do not replace previously registered
+ /// rules. [callback] is called with registered rules.
+ ///
+ void addRules(String eventName, List<Rule> rules,
+ [void callback(List<Rule> rules)]) {
+ // proxy the callback
+ void __proxy_callback(List rules) {
+ if (?callback) {
+ List<Rule> __proxy_rules = new List<Rule>();
+
+ for (Object o in rules)
+ __proxy_rules.add(new Rule._proxy(o));
+
+ callback(__proxy_rules);
+ }
+ }
+
+ JS('void',
+ '#.addRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(rules),
+ convertDartClosureToJS(__proxy_callback, 1)
+ );
+ }
+
+ /// Returns currently registered rules.
+ ///
+ /// [eventName] is the name of the event this function affects and, if an array
+ /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+ /// this array are returned. [callback] is called with registered rules.
+ ///
+ void getRules(String eventName, [List<String> ruleIdentifiers,
+ void callback(List<Rule> rules)]) {
+ // proxy the callback
+ void __proxy_callback(List rules) {
+ if (?callback) {
+ List<Rule> __proxy_rules = new List<Rule>();
+
+ for (Object o in rules)
+ __proxy_rules.add(new Rule._proxy(o));
+
+ callback(__proxy_rules);
+ }
+ }
+
+ JS('void',
+ '#.getRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(ruleIdentifiers),
+ convertDartClosureToJS(__proxy_callback, 1)
+ );
+ }
+
+ /// Unregisters currently registered rules.
+ ///
+ /// [eventName] is the name of the event this function affects and, if an array
+ /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+ /// this array are unregistered. [callback] is called when the rules are
+ /// unregistered.
+ ///
+ void removeRules(String eventName, [List<String> ruleIdentifiers,
+ void callback()]) =>
+ JS('void',
+ '#.removeRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(ruleIdentifiers),
+ convertDartClosureToJS(callback, 0)
+ );
+}
+
diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
index 332ce8d..17e0905 100644
--- a/tools/dom/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -59,7 +59,7 @@
_parent.cancelBubble = cancel;
}
/** Accessor to the clipboardData available for this event. */
- Clipboard get clipboardData => _parent.clipboardData;
+ DataTransfer 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. */
diff --git a/tools/dom/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
index c610b8e..a8eff57 100644
--- a/tools/dom/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -59,7 +59,7 @@
_parent.cancelBubble = cancel;
}
/** Accessor to the clipboardData available for this event. */
- Clipboard get clipboardData => _parent.clipboardData;
+ DataTransfer 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. */
diff --git a/tools/dom/templates/callback.darttemplate b/tools/dom/templates/callback.darttemplate
index 9ffc669..5c891ce 100644
--- a/tools/dom/templates/callback.darttemplate
+++ b/tools/dom/templates/callback.darttemplate
@@ -4,6 +4,6 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
//$ Keep previous blank line when editor removes trailing empty lines.
diff --git a/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate b/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
index b41466f..56dec80 100644
--- a/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
@@ -8,5 +8,11 @@
library chrome;
import 'dart:_foreign_helper' show JS;
+import 'dart:html_common';
+import 'dart:html';
-part '$AUXILIARY_DIR/chrome/sample.dart';
+part "$AUXILIARY_DIR/chrome/utils.dart";
+part "$AUXILIARY_DIR/chrome/chrome.dart";
+part "$AUXILIARY_DIR/chrome/app.runtime.dart";
+part "$AUXILIARY_DIR/chrome/app.window.dart";
+
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 1094cf7..f87c1b2 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -5,11 +5,10 @@
// DO NOT EDIT
// Auto-generated dart:html library.
-library html;
+library dart.dom.html;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
@@ -38,7 +37,7 @@
part '$AUXILIARY_DIR/Timer.dart';
part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
part '$AUXILIARY_DIR/Isolates.dart';
-part '$AUXILIARY_DIR/Measurement.dart';
+part '$AUXILIARY_DIR/Microtask.dart';
part '$AUXILIARY_DIR/Serialization.dart';
part '$AUXILIARY_DIR/shared_FactoryProviders.dart';
part '$AUXILIARY_DIR/dart2js_Conversions.dart';
@@ -47,7 +46,6 @@
part '$AUXILIARY_DIR/dart2js_FactoryProviders.dart';
part '$AUXILIARY_DIR/dart2js_LocationWrapper.dart';
part '$AUXILIARY_DIR/dart2js_TypedArrayFactoryProvider.dart';
-part '$AUXILIARY_DIR/_Testing.dart';
part '$AUXILIARY_DIR/_ListIterators.dart';
diff --git a/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate b/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
index e67365c..36529bb 100644
--- a/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
@@ -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.
-part of web_audio;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
diff --git a/tools/dom/templates/html/dart2js/impl_Console.darttemplate b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
index eb4f5e5..dbd7bc3 100644
--- a/tools/dom/templates/html/dart2js/impl_Console.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class Console {
diff --git a/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate b/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
index dd355c6..3e82f58 100644
--- a/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
@deprecated
class $CLASSNAME extends $SUPER {
diff --git a/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
index 261fffd..52f7436 100644
--- a/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate b/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
index e2b870c..cc7154d 100644
--- a/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
@@ -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.
-part of indexed_db;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
diff --git a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
index ed29b0f..7ca2b26 100644
--- a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate b/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate
index 599b50c..139f6c5 100644
--- a/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate
@@ -6,7 +6,7 @@
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
- static SpeechRecognition _create() {
+ factory SpeechRecognition() {
return JS('SpeechRecognition',
'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
}
diff --git a/tools/dom/templates/html/dart2js/impl_URL.darttemplate b/tools/dom/templates/html/dart2js/impl_URL.darttemplate
index 8188c31..1a02aa1 100644
--- a/tools/dom/templates/html/dart2js/impl_URL.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_URL.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
diff --git a/tools/dom/templates/html/dart2js/impl_Window.darttemplate b/tools/dom/templates/html/dart2js/impl_Window.darttemplate
index 037ef2d..1f74f22 100644
--- a/tools/dom/templates/html/dart2js/impl_Window.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_Window.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" {
@@ -71,12 +71,13 @@
}
/**
- * Executes a [callback] after the next batch of browser layout measurements
- * has completed or would have completed if any browser layout measurements
- * had been scheduled.
+ * Executes a [callback] after the immediate execution stack has completed.
+ *
+ * This will cause the callback to be executed after all processing has
+ * completed for the current event, but before any subsequent events.
*/
- void requestLayoutFrame(TimeoutHandler callback) {
- _addMeasurementFrameCallback(callback);
+ void setImmediate(TimeoutHandler callback) {
+ _addMicrotaskCallback(callback);
}
@DomName('DOMWindow.requestAnimationFrame')
@@ -159,5 +160,14 @@
@DomName('Window.console')
Console get console => Console.safeConsole;
+ /// Checks if _setImmediate is supported.
+ static bool get _supportsSetImmediate =>
+ JS('bool', '!!(window.setImmediate)');
+
+ // Set immediate implementation for IE
+ void _setImmediate(void callback()) {
+ JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0));
+ }
+
$!MEMBERS
}
diff --git a/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate b/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
index 4461917..27275bf 100644
--- a/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
index 8dc5ad5..cf7542f 100644
--- a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
@@ -5,7 +5,7 @@
// DO NOT EDIT
// Auto-generated dart:svg library.
-library indexed_db;
+library dart.dom.indexed_db;
import 'dart:async';
import 'dart:html';
diff --git a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
index bb5a01d..d907998 100644
--- a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
@@ -1,11 +1,10 @@
// DO NOT EDIT
// Auto-generated dart:svg library.
-library svg;
+library dart.dom.svg;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, Returns, JavaScriptIndexingBehavior, JSName;
diff --git a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
index 4812b82..17c774a 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -1,11 +1,10 @@
// DO NOT EDIT
// Auto-generated dart:audio library.
-library web_audio;
+library dart.dom.web_audio;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_foreign_helper' show JS;
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index a10a44a..3445f6b 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -5,11 +5,10 @@
// DO NOT EDIT
// Auto-generated dart:html library.
-library html;
+library dart.dom.html;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
@@ -38,9 +37,8 @@
part '$AUXILIARY_DIR/dartium_FactoryProviders.dart';
part '$AUXILIARY_DIR/Device.dart';
part '$AUXILIARY_DIR/Isolates.dart';
-part '$AUXILIARY_DIR/Measurement.dart';
+part '$AUXILIARY_DIR/Microtask.dart';
part '$AUXILIARY_DIR/Serialization.dart';
-part '$AUXILIARY_DIR/_Testing.dart';
part '$AUXILIARY_DIR/_ListIterators.dart';
part '$AUXILIARY_DIR/native_DOMPublic.dart';
diff --git a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
index d3de585..bb1be2c 100644
--- a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/dartium/impl_Window.darttemplate b/tools/dom/templates/html/dartium/impl_Window.darttemplate
index 381e58b..3c4125b 100644
--- a/tools/dom/templates/html/dartium/impl_Window.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_Window.darttemplate
@@ -2,17 +2,18 @@
// for 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;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
/**
- * Executes a [callback] after the next batch of browser layout measurements
- * has completed or would have completed if any browser layout measurements
- * had been scheduled.
+ * Executes a [callback] after the immediate execution stack has completed.
+ *
+ * This will cause the callback to be executed after all processing has
+ * completed for the current event, but before any subsequent events.
*/
- void requestLayoutFrame(TimeoutHandler callback) {
- _addMeasurementFrameCallback(callback);
+ void setImmediate(TimeoutHandler callback) {
+ _addMicrotaskCallback(callback);
}
/**
@@ -34,5 +35,13 @@
document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
}
+ /// Checks if _setImmediate is supported.
+ static bool get _supportsSetImmediate => false;
+
+ /// Dartium stub for IE's setImmediate.
+ void _setImmediate(void callback()) {
+ throw new UnsupportedError('setImmediate is not supported');
+ }
+
$!MEMBERS
}
diff --git a/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate b/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
index 47a3433..34e1d23 100644
--- a/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
@@ -5,7 +5,7 @@
// DO NOT EDIT
// Auto-generated dart:indexed_db library.
-library indexed_db;
+library dart.dom.indexed_db;
import 'dart:async';
import 'dart:html';
diff --git a/tools/dom/templates/html/dartium/svg_dartium.darttemplate b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
index 70af41e..13f2891 100644
--- a/tools/dom/templates/html/dartium/svg_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
@@ -1,11 +1,10 @@
// DO NOT EDIT
// Auto-generated dart:svg library.
-library svg;
+library dart.dom.svg;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
index f4526bb..b6319de 100644
--- a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
@@ -1,11 +1,10 @@
// DO NOT EDIT
// Auto-generated dart:audio library.
-library web_audio;
+library dart.dom.web_audio;
import 'dart:async';
import 'dart:collection';
-import 'dart:collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/impl/impl_AudioContext.darttemplate b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
index 9c30422..1ef4069 100644
--- a/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
+++ b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
@@ -7,7 +7,7 @@
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
$if DART2JS
- static AudioContext _create() => JS('AudioContext',
+ factory AudioContext() => JS('AudioContext',
'new (window.AudioContext || window.webkitAudioContext)()');
GainNode createGain() {
diff --git a/tools/dom/templates/html/impl/impl_Blob.darttemplate b/tools/dom/templates/html/impl/impl_Blob.darttemplate
index 12554be..022b6de 100644
--- a/tools/dom/templates/html/impl/impl_Blob.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Blob.darttemplate
@@ -2,12 +2,12 @@
// for 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;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
$if DART2JS
- static Blob _create([List blobParts = null, String type, String endings]) {
+ factory Blob(List blobParts, [String type, String endings]) {
// TODO: validate that blobParts is a JS Array and convert if not.
// TODO: any coercions on the elements of blobParts, e.g. coerce a typed
// array to ArrayBuffer if it is a total view.
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index 0212570..67152b1 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
String _cachedBrowserPrefix;
diff --git a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
index fb76557..e26e050 100644
--- a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate b/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
index 64b5298..c190a86 100644
--- a/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
index 2d2b6c0..e568a09 100644
--- a/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_DOMException.darttemplate b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
index 07aacbb..593fd4c 100644
--- a/tools/dom/templates/html/impl/impl_DOMException.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
/// @domName $DOMNAME
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
diff --git a/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate b/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
index 221c014..e613959 100644
--- a/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$ANNOTATIONS
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index f707aac..ad71764 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
/**
* The base class for all documents.
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index d9af150..13edffb 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createDocumentFragment();
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index b554609..340774c 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
// TODO(jacobr): use _Lists.dart to remove some of the duplicated
// functionality.
@@ -61,6 +61,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Element element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Element element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -73,7 +77,7 @@
return _element.$dom_firstElementChild == null;
}
- List<Element> take(int n) {
+ Iterable<Element> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -81,7 +85,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Element> skip(int n) {
+ Iterable<Element> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -137,8 +141,9 @@
}
}
- List<Element> get reversed =>
- new ReversedListView<Element>(this, 0, null);
+ List<Element> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -156,7 +161,7 @@
void remove(Object object) {
if (object is Element) {
Element element = object;
- if (identical(element.parentNode, this)) {
+ if (identical(element.parentNode, _element)) {
_element.$dom_removeChild(element);
}
}
@@ -273,6 +278,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Element element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Element element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -302,7 +311,7 @@
List<Element> toList() => new List<Element>.from(this);
Set<Element> toSet() => new Set<Element>.from(this);
- List<Element> take(int n) {
+ Iterable<Element> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -310,7 +319,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Element> skip(int n) {
+ Iterable<Element> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -362,8 +371,9 @@
throw new UnsupportedError('');
}
- List<Element> get reversed =>
- new ReversedListView<Element>(this, 0, null);
+ List<Element> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare(Element a, Element b)]) {
throw new UnsupportedError('');
@@ -707,27 +717,20 @@
* [style] property, which contains only the values specified directly on this
* element.
*
+ * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+ * `::line-marker`.
+ *
* See also:
*
* * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
- */
- Future<CssStyleDeclaration> get computedStyle {
- // TODO(jacobr): last param should be null, see b/5045788
- return getComputedStyle('');
- }
-
- /**
- * Returns the computed styles for pseudo-elements such as `::after`,
- * `::before`, `::marker`, `::line-marker`.
- *
- * See also:
- *
* * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
*/
- Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) {
- return _createMeasurementFuture(
- () => window.$dom_getComputedStyle(this, pseudoElement),
- new Completer<CssStyleDeclaration>());
+ CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+ if (pseudoElement == null) {
+ pseudoElement = '';
+ }
+ // TODO(jacobr): last param should be null, see b/5045788
+ return window.$dom_getComputedStyle(this, pseudoElement);
}
/**
@@ -907,6 +910,7 @@
} else if (JS('bool', '!!#.msMatchesSelector', this)) {
return JS('bool', '#.msMatchesSelector(#)', this, selectors);
}
+ throw new UnsupportedError("Not supported on this platform");
}
$else
$endif
diff --git a/tools/dom/templates/html/impl/impl_Event.darttemplate b/tools/dom/templates/html/impl/impl_Event.darttemplate
index b9b7b4c..70c340a 100644
--- a/tools/dom/templates/html/impl/impl_Event.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Event.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
// In JS, canBubble and cancelable are technically required parameters to
diff --git a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
index f0bf5ce..e0ff57e 100644
--- a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
+++ b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
/**
* Base class that supports listening for and dispatching browser events.
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index 50c46d1..699a328 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -2,13 +2,30 @@
// for 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;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
-
-$if DART2JS
- CanvasRenderingContext getContext(String contextId) native;
-$endif
CanvasRenderingContext2D get context2d => getContext('2d');
+
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.FIREFOX)
+ @Experimental
+ WebGLRenderingContext getContext3d({alpha: true, depth: true, stencil: false,
+ antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {
+
+ var options = {
+ 'alpha': alpha,
+ 'depth': depth,
+ 'stencil': stencil,
+ 'antialias': antialias,
+ 'premultipliedAlpha': premultipliedAlpha,
+ 'preserveDrawingBuffer': preserveDrawingBuffer,
+ };
+ var context = getContext('webgl', options);
+ if (context == null) {
+ context = getContext('experimental-webgl', options);
+ }
+ return context;
+ }
}
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 422278a..c64f11a 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
index e215391..0f378ab 100644
--- a/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
index 515dd4a..dd908aa 100644
--- a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$ANNOTATIONS
class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate b/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
index 0c24dd9..7599fa9 100644
--- a/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
@@ -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.
-part of indexed_db;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
@DomName('IDBKeyRange.only')
diff --git a/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate b/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
index 8aae717..da137de 100644
--- a/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate b/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
index bcef767..0f7c316 100644
--- a/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
index 5c70356..abab691 100644
--- a/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
@@ -91,7 +91,7 @@
@JSName('observe')
void _call(target, options) native;
- static MutationObserver _create(MutationCallback callback) {
+ factory MutationObserver(MutationCallback callback) {
// Dummy statement to mark types as instantiated.
JS('MutationObserver|MutationRecord', '0');
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index e23c5d8..473f94a 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
/**
* Lazy implementation of the child nodes of an element that does not request
@@ -138,6 +138,10 @@
return IterableMixinWorkaround.joinList(this, separator);
}
+ Iterable map(f(Node element)) {
+ return IterableMixinWorkaround.map(this, f);
+ }
+
List mappedBy(f(Node element)) {
return IterableMixinWorkaround.mappedByList(this, f);
}
@@ -157,7 +161,7 @@
// From List<Node>:
- List<Node> take(int n) {
+ Iterable<Node> take(int n) {
return IterableMixinWorkaround.takeList(this, n);
}
@@ -165,7 +169,7 @@
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<Node> skip(int n) {
+ Iterable<Node> skip(int n) {
return IterableMixinWorkaround.skipList(this, n);
}
@@ -189,8 +193,9 @@
return this[index];
}
- List<Node> get reversed =>
- new ReversedListView<Node>(this, 0, null);
+ List<Node> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
// TODO(jacobr): this could be implemented for child node lists.
// The exception we throw here is misleading.
diff --git a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
index 0fbdacb..42ad450 100644
--- a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
@@ -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.
-part of svg;
+part of $LIBRARYNAME;
class _AttributeClassSet extends CssClassSet {
final Element _element;
diff --git a/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
index bc77c46..cc21d77 100644
--- a/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
@@ -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.
-part of svg;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createSvgSvgElement();
diff --git a/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate b/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
index 30752ce..cb2e479 100644
--- a/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
+++ b/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
index 273adfd..7cde516 100644
--- a/tools/dom/templates/html/impl/impl_Storage.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Storage.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS implements Map<String, String>
$NATIVESPEC {
diff --git a/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate b/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
index 72b640d..686dc1c 100644
--- a/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_Text.darttemplate b/tools/dom/templates/html/impl/impl_Text.darttemplate
index b558e60..e5bbf5d 100644
--- a/tools/dom/templates/html/impl/impl_Text.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Text.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String data) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(data);
diff --git a/tools/dom/templates/html/impl/impl_TextEvent.darttemplate b/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
index 7249ce2..c877d70 100644
--- a/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
index ea0bef9..7223959 100644
--- a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
factory $CLASSNAME(TouchList touches, TouchList targetTouches,
@@ -21,4 +21,24 @@
return e;
}
$!MEMBERS
+
+ /**
+ * Checks if touch events supported on the current platform.
+ *
+ * Note that touch events are only supported if the user is using a touch
+ * device.
+ */
+ static bool get supported {
+$if DART2JS
+ if (JS('bool', '"ontouchstart" in window')) {
+ return Event._isTypeSupported('TouchEvent');
+ }
+ return false;
+$else
+ // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
+ // Basically, this is a fairly common check and it'd be great if it did not
+ // throw exceptions.
+ return Event._isTypeSupported('TouchEvent');
+$endif
+ }
}
diff --git a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
index 939ce85..a4d2830 100644
--- a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
@@ -4,7 +4,7 @@
// WARNING: Do not edit - generated code.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
// In JS, canBubble and cancelable are technically required parameters to
diff --git a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
index a49a979..a3cf320 100644
--- a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 11efa77..078d873 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -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.
-part of html;
+part of $LIBRARYNAME;
/**
* A utility for retrieving data from a URL.
@@ -30,25 +30,39 @@
* * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
*/
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
- /**
- * Creates a URL get request for the specified `url`.
- *
- * After completing the request, the object will call the user-provided
- * [onComplete] callback.
- */
- factory $CLASSNAME.get(String url, onComplete($CLASSNAME request)) =>
- _HttpRequestUtils.get(url, onComplete, false);
- // 80 char issue for comments in lists: dartbug.com/7588.
/**
- * Creates a URL GET request for the specified `url` with
- * credentials such a cookie (already) set in the header or
- * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
+ * Creates a URL get request for the specified [url].
*
- * After completing the request, the object will call the user-provided
- * [onComplete] callback.
+ * The server response must be a `text/` mime type for this request to
+ * succeed.
*
- * A few other details to keep in mind when using credentials:
+ * This is similar to [request] but specialized for HTTP GET requests which
+ * return text content.
+ *
+ * See also:
+ *
+ * * [request]
+ */
+ static Future<String> getString(String url,
+ {bool withCredentials, void onProgress(ProgressEvent e)}) {
+ return request(url, withCredentials: withCredentials,
+ onProgress: onProgress).then((xhr) => xhr.responseText);
+ }
+
+ /**
+ * Creates a URL request for the specified [url].
+ *
+ * By default this will do an HTTP GET request, this can be overridden with
+ * [method].
+ *
+ * The Future is completed when the response is available.
+ *
+ * The [withCredentials] parameter specified that credentials such as a cookie
+ * (already) set in the header or
+ * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+ * should be specified for the request. Details to keep in mind when using
+ * credentials:
*
* * Using credentials is only useful for cross-origin requests.
* * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
@@ -57,9 +71,50 @@
*
* See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
*/
- factory $CLASSNAME.getWithCredentials(String url,
- onComplete($CLASSNAME request)) =>
- _HttpRequestUtils.get(url, onComplete, true);
+ static Future<HttpRequest> request(String url,
+ {String method, bool withCredentials, String responseType, sendData,
+ void onProgress(ProgressEvent e)}) {
+ var completer = new Completer<HttpRequest>();
+
+ var xhr = new HttpRequest();
+ if (method == null) {
+ method = 'GET';
+ }
+ xhr.open(method, url, true);
+
+ if (withCredentials != null) {
+ xhr.withCredentials = withCredentials;
+ }
+
+ if (responseType != null) {
+ xhr.responseType = responseType;
+ }
+
+ if (onProgress != null) {
+ xhr.onProgress.listen(onProgress);
+ }
+
+ xhr.onLoad.listen((e) {
+ if (xhr.status >= 200 && xhr.status < 300 ||
+ xhr.status == 304 ) {
+ completer.complete(xhr);
+ } else {
+ completer.completeError(e);
+ }
+ });
+
+ xhr.onError.listen((e) {
+ completer.completeError(e);
+ });
+
+ if (sendData != null) {
+ xhr.send(sendData);
+ } else {
+ xhr.send();
+ }
+
+ return completer.future;
+ }
$!MEMBERS
}
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 3a09ac5..58cf40c 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -29,7 +29,11 @@
String join([String separator]) =>
IterableMixinWorkaround.joinList(this, separator);
- List mappedBy(f($E element)) => IterableMixinWorkaround.mappedByList(this, f);
+ Iterable map(f($E element)) =>
+ IterableMixinWorkaround.map(this, f);
+
+ List mappedBy(f($E element)) =>
+ IterableMixinWorkaround.mappedByList(this, f);
Iterable<$E> where(bool f($E element)) =>
IterableMixinWorkaround.where(this, f);
@@ -43,13 +47,13 @@
bool get isEmpty => this.length == 0;
- List<$E> take(int n) => IterableMixinWorkaround.takeList(this, n);
+ Iterable<$E> take(int n) => IterableMixinWorkaround.takeList(this, n);
Iterable<$E> takeWhile(bool test($E value)) {
return IterableMixinWorkaround.takeWhile(this, test);
}
- List<$E> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+ Iterable<$E> skip(int n) => IterableMixinWorkaround.skipList(this, n);
Iterable<$E> skipWhile(bool test($E value)) {
return IterableMixinWorkaround.skipWhile(this, test);
@@ -100,8 +104,9 @@
// clear() defined by IDL.
$endif
- List<$E> get reversed =>
- new ReversedListView<$E>(this, 0, null);
+ List<$E> get reversed {
+ return IterableMixinWorkaround.reversedList(this);
+ }
void sort([int compare($E a, $E b)]) {
throw new UnsupportedError("Cannot sort immutable List.");
diff --git a/tools/publish_all_pkgs.py b/tools/publish_all_pkgs.py
new file mode 100644
index 0000000..c20ed29
--- /dev/null
+++ b/tools/publish_all_pkgs.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Upload all packages in pkg/ (other than a few that should be explicitly
+# excluded), plus sdk/lib/_internal/compiler .
+#
+# Usage: publish_all_pkgs.py
+#
+# "pub" must be in PATH.
+
+
+import os
+import os.path
+import subprocess
+import sys
+
+def Main(argv):
+ pkgs_to_publish = []
+ for name in os.listdir('pkg'):
+ if os.path.isdir(os.path.join('pkg', name)):
+ if (name != '.svn' and name != 'fixnum' and
+ not name.endswith('-experimental')):
+ pkgs_to_publish.append(os.path.join('pkg', name))
+
+ # Publish dart2js as an "unsupported" package.
+ pkgs_to_publish.append(
+ os.path.join('sdk', 'lib', '_internal', 'compiler'))
+
+ for pkg in pkgs_to_publish:
+ print "Publishing " + pkg
+ subprocess.call(['python', 'tools/publish_pkg.py', pkg])
+
+if __name__ == '__main__':
+ sys.exit(Main(sys.argv))
diff --git a/tools/test-runtime.dart b/tools/test-runtime.dart
index a959f23..036c861 100755
--- a/tools/test-runtime.dart
+++ b/tools/test-runtime.dart
@@ -102,9 +102,12 @@
if (runningBrowserTests) startHttpServer('127.0.0.1', 9876);
}
+ var maxBrowserProcesses = maxProcesses;
+
// Start process queue.
new ProcessQueue(
maxProcesses,
+ maxBrowserProcesses,
progressIndicator,
startTime,
printTiming,
diff --git a/tools/test.dart b/tools/test.dart
index 3077ac6..12cff10 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -126,7 +126,14 @@
}
var testSuites = new List<TestSuite>();
+ var maxBrowserProcesses = maxProcesses;
for (var conf in configurations) {
+ // There should not be more than one InternetExplorerDriver instance
+ // running at a time. For details, see
+ // http://code.google.com/p/selenium/wiki/InternetExplorerDriver.
+ if (conf['runtime'].startsWith('ie')) {
+ maxBrowserProcesses = 1;
+ }
TestingServerRunner.setPackageRootDir(conf);
for (String key in selectors.keys) {
if (key == 'co19') {
@@ -158,6 +165,7 @@
// Start process queue.
new ProcessQueue(maxProcesses,
+ maxBrowserProcesses,
progressIndicator,
startTime,
printTiming,
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index dcc37a6..84a5b77 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -27,6 +27,7 @@
defaultsTo: 'ia32');
parser.addFlag('help', abbr: 'h', negatable: false,
help: 'Print this usage information.');
+ parser.addOption('package-root', help: 'The package root to use.');
var args = parser.parse(new Options().arguments);
if (args['help']) {
print(parser.getUsage());
@@ -39,10 +40,7 @@
.join(new Path('../../test.dart'))
.canonicalize()
.toNativePath();
- TestingServerRunner.setPackageRootDir({'mode': args['mode'],
- 'arch': args['arch'], 'system': Platform.operatingSystem,
- 'build_directory': ''});
-
+ TestingServerRunner._packageRootDir = new Path(args['package-root']);
TestingServerRunner.startHttpServer('127.0.0.1',
port: int.parse(args['port']));
print('Server listening on port '
@@ -125,7 +123,6 @@
}
}
});
-
};
// Echos back the contents of the request as the response data.
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 7a45a41..3de6e2f 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -208,7 +208,8 @@
'http_server.dart -m ${test.configuration["mode"]} '
'-a ${test.configuration["arch"]} '
'-p ${http_server.TestingServerRunner.serverList[0].port} '
- '-c ${http_server.TestingServerRunner.serverList[1].port}');
+ '-c ${http_server.TestingServerRunner.serverList[1].port} '
+ '--package-root=${http_server.TestingServerRunner.packageRootDir}');
}
for (Command c in test.commands) {
output.add('');
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index a3e72c9..356b664 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -27,6 +27,8 @@
const int NO_TIMEOUT = 0;
const int SLOW_TIMEOUT_MULTIPLIER = 4;
+const int CRASHING_BROWSER_EXITCODE = -10;
+
typedef void TestCaseEvent(TestCase testCase);
typedef void ExitCodeEvent(int exitCode);
typedef void EnqueueMoreWork(ProcessQueue queue);
@@ -566,6 +568,11 @@
if (exitCode == 3) {
return !timedOut;
}
+ // TODO(ricow): Remove this dirty hack ones we have a selenium
+ // replacement.
+ if (exitCode == CRASHING_BROWSER_EXITCODE) {
+ return !timedOut;
+ }
// If a program receives an uncaught system exception, the program
// terminates with the exception code as exit code.
// The 0x3FFFFF00 mask here tries to determine if an exception indicates
@@ -925,124 +932,69 @@
* be garbage collected as soon as it is done.
*/
class RunningProcess {
- ProcessQueue processQueue;
- io.Process process;
TestCase testCase;
+ Command command;
bool timedOut = false;
Date startTime;
Timer timeoutTimer;
- List<int> stdout;
- List<int> stderr;
- List<String> notifications;
- bool compilationSkipped;
- bool allowRetries;
+ List<int> stdout = <int>[];
+ List<int> stderr = <int>[];
+ bool compilationSkipped = false;
+ Completer<CommandOutput> completer;
- /** Which command of [testCase.commands] is currently being executed. */
- int currentStep;
+ RunningProcess(TestCase this.testCase, Command this.command);
- RunningProcess(TestCase this.testCase,
- [this.allowRetries = false, this.processQueue]);
+ Future<CommandOutput> start() {
+ Expect.isFalse(testCase.expectedOutcomes.contains(SKIP));
- /**
- * Called when all commands are executed.
- */
- void testComplete(CommandOutput lastCommandOutput) {
- var command = lastCommandOutput.command;
+ completer = new Completer<CommandOutput>();
+ startTime = new Date.now();
+ _runCommand();
+ return completer.future;
+ }
+ void _runCommand() {
+ command.outputIsUpToDate.then((bool isUpToDate) {
+ if (isUpToDate) {
+ compilationSkipped = true;
+ _commandComplete(0);
+ } else {
+ var processOptions = _createProcessOptions();
+ Future processFuture = io.Process.start(command.executable,
+ command.arguments,
+ processOptions);
+ processFuture.then((io.Process process) {
+ void timeoutHandler(_) {
+ timedOut = true;
+ if (process != null) {
+ process.kill();
+ }
+ }
+ process.onExit = _commandComplete;
+ _drainStream(process.stdout, stdout);
+ _drainStream(process.stderr, stderr);
+ timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
+ }).catchError((e) {
+ print("Process error:");
+ print(" Command: $command");
+ print(" Error: $e");
+ _commandComplete(-1);
+ return true;
+ });
+ }
+ });
+ }
+
+ void _commandComplete(int exitCode) {
if (timeoutTimer != null) {
timeoutTimer.cancel();
}
- if (lastCommandOutput.unexpectedOutput
- && testCase.configuration['verbose'] != null
- && testCase.configuration['verbose']) {
- print(testCase.displayName);
-
- print(decodeUtf8(lastCommandOutput.stderr));
- if (!lastCommandOutput.command.isPixelTest) {
- print(decodeUtf8(lastCommandOutput.stdout));
- } else {
- print("DRT pixel test failed! stdout is not printed because it "
- "contains binary data!");
- }
- print('');
- if (notifications.length > 0) {
- print("Notifications:");
- for (var line in notifications) {
- print(notifications);
- }
- print('');
- }
- }
- if (allowRetries && testCase.usesWebDriver
- && lastCommandOutput.unexpectedOutput
- && (testCase as BrowserTestCase).numRetries > 0) {
- // Selenium tests can be flaky. Try rerunning.
- lastCommandOutput.requestRetry = true;
- }
- if (lastCommandOutput.requestRetry) {
- lastCommandOutput.requestRetry = false;
- this.timedOut = false;
- (testCase as BrowserTestCase).numRetries--;
- print("Potential flake. Re-running ${testCase.displayName} "
- "(${(testCase as BrowserTestCase).numRetries} attempt(s) remains)");
- // When retrying we need to reset the timeout as well.
- // Otherwise there will be no timeout handling for the retry.
- timeoutTimer = null;
- this.start();
- } else {
- testCase.completed();
- }
+ var commandOutput = _createCommandOutput(command, exitCode);
+ completer.complete(commandOutput);
}
- /**
- * Process exit handler called at the end of every command. It internally
- * treats all but the last command as compilation steps. The last command is
- * the actual test and its output is analyzed in [testComplete].
- */
- void commandComplete(Command command, int exitCode) {
- process = null;
- int totalSteps = testCase.commands.length;
- String suffix =' (step $currentStep of $totalSteps)';
- if (timedOut) {
- // Non-webdriver test timed out before it could complete. Webdriver tests
- // run their own timeouts by timing from the launch of the browser (which
- // could be delayed).
- testComplete(createCommandOutput(command, 0, true));
- } else if (currentStep == totalSteps) {
- // Done with all test commands.
- testComplete(createCommandOutput(command, exitCode, false));
- } else if (exitCode != 0) {
- // One of the steps failed.
- notifications.add('test.dart: Compilation failed$suffix, '
- 'exit code $exitCode\n');
- testComplete(createCommandOutput(command, exitCode, true));
- } else {
- createCommandOutput(command, exitCode, true);
- // One compilation step successfully completed, move on to the
- // next step.
- notifications.add('test.dart: Compilation finished $suffix\n\n');
- if (currentStep == totalSteps - 1 && testCase.usesWebDriver &&
- !testCase.configuration['noBatch']) {
- // Note: processQueue will always be non-null for runtime == ie9, ie10,
- // ff, safari, chrome, opera. (It is only null for runtime == vm)
- // This RunningProcess object is done, and hands over control to
- // BatchRunner.startTest(), which handles reporting, etc.
- if (timeoutTimer != null) {
- timeoutTimer.cancel();
- }
- processQueue._getBatchRunner(testCase).startTest(testCase);
- } else {
- runCommand(testCase.commands[currentStep++], commandComplete);
- }
- }
- }
-
- /**
- * Called for all executed commands.
- */
- CommandOutput createCommandOutput(Command command,
- int exitCode,
- bool incomplete) {
+ CommandOutput _createCommandOutput(Command command, int exitCode) {
+ var incomplete = command != testCase.commands.last;
var commandOutput = new CommandOutput.fromCase(
testCase,
command,
@@ -1053,18 +1005,10 @@
stderr,
new Date.now().difference(startTime),
compilationSkipped);
- resetLocalOutputInformation();
return commandOutput;
}
- void resetLocalOutputInformation() {
- stdout = new List<int>();
- stderr = new List<int>();
- notifications = new List<String>();
- compilationSkipped = false;
- }
-
- void drainStream(io.InputStream source, List<int> destination) {
+ void _drainStream(io.InputStream source, List<int> destination) {
void onDataHandler () {
if (source.closed) {
return; // TODO(whesse): Remove when bug is fixed.
@@ -1079,77 +1023,14 @@
source.onClosed = onDataHandler;
}
- void start() {
- Expect.isFalse(testCase.expectedOutcomes.contains(SKIP));
- resetLocalOutputInformation();
- currentStep = 0;
- startTime = new Date.now();
- runCommand(testCase.commands[currentStep++], commandComplete);
- }
-
- void runCommand(Command command, void commandCompleteHandler(Command, int)) {
- void processExitHandler(int returnCode) {
- commandCompleteHandler(command, returnCode);
- }
-
- command.outputIsUpToDate.then((bool isUpToDate) {
- if (isUpToDate) {
- notifications.add("Skipped compilation because the old output is "
- "still up to date!");
- compilationSkipped = true;
- commandComplete(command, 0);
- } else {
- io.ProcessOptions options = new io.ProcessOptions();
- if (command.environment != null) {
- options.environment =
- new Map<String, String>.from(command.environment);
- } else {
- options.environment =
- new Map<String, String>.from(io.Platform.environment);
- }
-
- options.environment['DART_CONFIGURATION'] =
- TestUtils.configurationDir(testCase.configuration);
- Future processFuture = io.Process.start(command.executable,
- command.arguments,
- options);
- processFuture.then((io.Process p) {
- process = p;
- process.onExit = processExitHandler;
- drainStream(process.stdout, stdout);
- drainStream(process.stderr, stderr);
- if (timeoutTimer == null) {
- // Create one timeout timer when starting test case, remove it at
- // the end.
- timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
- }
- // If the timeout fired in between two commands, kill the just
- // started process immediately.
- if (timedOut) safeKill(process);
- }).catchError((e) {
- print("Process error:");
- print(" Command: $command");
- print(" Error: $e");
- testComplete(createCommandOutput(command, -1, false));
- return true;
- });
- }
- });
- }
-
- void timeoutHandler(Timer unusedTimer) {
- timedOut = true;
- safeKill(process);
- }
-
- void safeKill(io.Process p) {
- if (p != null) {
- try {
- p.kill();
- } on io.ProcessException {
- // Hopefully, this means that the process died on its own.
- }
- }
+ io.ProcessOptions _createProcessOptions() {
+ var baseEnvironment = command.environment != null ?
+ command.environment : io.Platform.environment;
+ io.ProcessOptions options = new io.ProcessOptions();
+ options.environment = new Map<String, String>.from(baseEnvironment);
+ options.environment['DART_CONFIGURATION'] =
+ TestUtils.configurationDir(testCase.configuration);
+ return options;
}
}
@@ -1280,7 +1161,7 @@
var outcome = _status.split(" ")[2];
var exitCode = 0;
- if (outcome == "CRASH") exitCode = -10;
+ if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE;
if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1;
new CommandOutput.fromCase(_currentTest,
_command,
@@ -1434,6 +1315,8 @@
class ProcessQueue {
int _numProcesses = 0;
int _maxProcesses;
+ int _numBrowserProcesses = 0;
+ int _maxBrowserProcesses;
bool _allTestsWereEnqueued = false;
/** The number of tests we allow to actually fail before we stop retrying. */
@@ -1470,7 +1353,8 @@
/** True if we find that there is already a selenium jar running. */
bool _seleniumAlreadyRunning = false;
- ProcessQueue(int this._maxProcesses,
+ ProcessQueue(this._maxProcesses,
+ this._maxBrowserProcesses,
String progress,
Date startTime,
bool printTiming,
@@ -1707,7 +1591,7 @@
// The test is not yet ready to run. Put the test back in
// the queue. Avoid spin-polling by using a timeout.
_tests.add(test);
- new Timer(100, (timer) {_tryRunTest();}); // Don't lose a process.
+ new Timer(100, (_) => _tryRunTest()); // Don't lose a process.
return;
}
if (_verbose) {
@@ -1715,11 +1599,13 @@
if (test is BrowserTestCase) {
// Additional command for rerunning the steps locally after the fact.
print('$i. ${TestUtils.dartTestExecutable.toNativePath()} '
- '${TestUtils.dartDir().toNativePath()}/tools/testing/dart/'
- 'http_server.dart -m ${test.configuration["mode"]} '
- '-a ${test.configuration["arch"]} '
- '-p ${http_server.TestingServerRunner.serverList[0].port} '
- '-c ${http_server.TestingServerRunner.serverList[1].port}');
+ '${TestUtils.dartDir().toNativePath()}/tools/testing/dart/'
+ 'http_server.dart -m ${test.configuration["mode"]} '
+ '-a ${test.configuration["arch"]} '
+ '-p ${http_server.TestingServerRunner.serverList[0].port} '
+ '-c ${http_server.TestingServerRunner.serverList[1].port} '
+ '--package-root='
+ '${http_server.TestingServerRunner.packageRootDir}');
i++;
}
for (Command command in test.commands) {
@@ -1727,23 +1613,40 @@
i++;
}
}
- _progress.start(test);
- TestCaseEvent oldCallback = test.completedHandler;
- void wrapper(TestCase test_arg) {
- _numProcesses--;
- _progress.done(test_arg);
- if (test_arg is BrowserTestCase) test_arg.notifyObservers();
- _tryRunTest();
- oldCallback(test_arg);
- };
- test.completedHandler = wrapper;
- if ((test.configuration['compiler'] == 'dartc' &&
- test.displayName != 'dartc/junit_tests') ||
- (test.commands.length == 1 && test.usesWebDriver &&
- !test.configuration['noBatch'])) {
- // Dartc and browser test cases that do not require a precompilation
- // step, start with the batch runner right away.
+ var isLastCommand =
+ ((test.commands.length-1) == test.commandOutputs.length);
+ var isBrowserCommand = isLastCommand && (test is BrowserTestCase);
+ if (isBrowserCommand && _numBrowserProcesses == _maxBrowserProcesses) {
+ // If there is no free browser runner, put it back into the queue.
+ _tests.add(test);
+ new Timer(100, (_) => _tryRunTest()); // Don't lose a process.
+ return;
+ }
+
+ _progress.start(test);
+
+ // Dartc and browser test commands can be run by a [BatchRunnerProcess]
+ var nextCommandIndex = test.commandOutputs.keys.length;
+ var numberOfCommands = test.commands.length;
+ var useBatchRunnerForDartc = test.configuration['compiler'] == 'dartc' &&
+ test.displayName != 'dartc/junit_tests';
+ var isWebdriverCommand = nextCommandIndex == (numberOfCommands - 1) &&
+ test.usesWebDriver &&
+ !test.configuration['noBatch'];
+ if (useBatchRunnerForDartc || isWebdriverCommand) {
+ TestCaseEvent oldCallback = test.completedHandler;
+ void testCompleted(TestCase test_arg) {
+ _numProcesses--;
+ if (isBrowserCommand) {
+ _numBrowserProcesses--;
+ }
+ _progress.done(test_arg);
+ if (test_arg is BrowserTestCase) test_arg.notifyObservers();
+ oldCallback(test_arg);
+ _tryRunTest();
+ };
+ test.completedHandler = testCompleted;
_getBatchRunner(test).startTest(test);
} else {
// Once we've actually failed a test, technically, we wouldn't need to
@@ -1754,9 +1657,104 @@
// tests that appear to be broken but were actually just flakes that
// didn't get retried because there had already been one failure.
bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests;
- new RunningProcess(test, allowRetry, this).start();
+ runNextCommandWithRetries(test, allowRetry).then((TestCase testCase) {
+ _numProcesses--;
+ if (isBrowserCommand) {
+ _numBrowserProcesses--;
+ }
+ if (isTestCaseFinished(testCase)) {
+ testCase.completed();
+ _progress.done(testCase);
+ if (testCase is BrowserTestCase) testCase.notifyObservers();
+ } else {
+ _tests.addFirst(testCase);
+ }
+ _tryRunTest();
+ });
}
+
_numProcesses++;
+ if (isBrowserCommand) {
+ _numBrowserProcesses++;
+ }
}
}
+
+ bool isTestCaseFinished(TestCase testCase) {
+ var numberOfCommandOutputs = testCase.commandOutputs.keys.length;
+ var numberOfCommands = testCase.commands.length;
+
+ var lastCommandCompleted = (numberOfCommandOutputs == numberOfCommands);
+ var lastCommandOutput = testCase.lastCommandOutput;
+ var lastCommand = lastCommandOutput.command;
+ var timedOut = lastCommandOutput.hasTimedOut;
+ var nonZeroExitCode = lastCommandOutput.exitCode != 0;
+ // NOTE: If this was the last command or there was unexpected output
+ // we're done with the test.
+ // Otherwise we need to enqueue it again into the test queue.
+ if (lastCommandCompleted || timedOut || nonZeroExitCode) {
+ var verbose = testCase.configuration['verbose'];
+ if (lastCommandOutput.unexpectedOutput && verbose != null && verbose) {
+ print(testCase.displayName);
+ print("stderr:");
+ print(decodeUtf8(lastCommandOutput.stderr));
+ if (!lastCommand.isPixelTest) {
+ print("stdout:");
+ print(decodeUtf8(lastCommandOutput.stdout));
+ } else {
+ print("");
+ print("DRT pixel test failed! stdout is not printed because it "
+ "contains binary data!");
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ Future runNextCommandWithRetries(TestCase testCase, bool allowRetry) {
+ var completer = new Completer();
+
+ var nextCommandIndex = testCase.commandOutputs.keys.length;
+ var numberOfCommands = testCase.commands.length;
+ Expect.isTrue(nextCommandIndex < numberOfCommands);
+ var command = testCase.commands[nextCommandIndex];
+ var isLastCommand = nextCommandIndex == (numberOfCommands - 1);
+
+ void runCommand() {
+ var runningProcess = new RunningProcess(testCase, command);
+ runningProcess.start().then((CommandOutput commandOutput) {
+ if (isLastCommand) {
+ // NOTE: We need to call commandOutput.unexpectedOutput here.
+ // Calling this getter may result in the side-effect, that
+ // commandOutput.requestRetry is set to true.
+ // (BrowserCommandOutputImpl._failedBecauseOfMissingXDisplay
+ // does that for example)
+ // TODO(ricow/kustermann): Issue 8206
+ var unexpectedOutput = commandOutput.unexpectedOutput;
+ if (allowRetry && testCase.usesWebDriver
+ && unexpectedOutput
+ && (testCase as BrowserTestCase).numRetries > 0) {
+ // Selenium tests can be flaky. Try rerunning.
+ commandOutput.requestRetry = true;
+ }
+ }
+ if (commandOutput.requestRetry) {
+ commandOutput.requestRetry = false;
+ (testCase as BrowserTestCase).numRetries--;
+ DebugLogger.warning("Rerunning Test: ${testCase.displayName} "
+ "(${(testCase as BrowserTestCase).numRetries} "
+ "attempt(s) remains) [cmd:$command]");
+ runCommand();
+ } else {
+ completer.complete(testCase);
+ }
+ });
+ }
+ runCommand();
+
+ return completer.future;
+ }
}
+
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 9a1f7b9..349a8a6 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -970,13 +970,25 @@
htmlPath = htmlPath.startsWith(basePath) ?
htmlPath.substring(basePath.length) : htmlPath;
String fullHtmlPath = htmlPath;
+ var searchStr = '?';
if (!htmlPath.startsWith('http')) {
- fullHtmlPath = 'http://127.0.0.1:${serverList[0].port}$htmlPath?'
- 'crossOriginPort=${serverList[1].port}';
+ // Note: If we run test.py with the "--list" option, no http servers
+ // will be started. Therefore serverList is an empty list in this
+ // case. So we use PORT/CROSS_ORIGIN_PORT instead of real ports.
+ var serverPort = "PORT";
+ var crossOriginPort = "CROSS_ORIGIN_PORT";
+ if (!configuration['list']) {
+ serverPort = serverList[0].port.toString();
+ crossOriginPort = serverList[1].port.toString();
+ }
+ fullHtmlPath = 'http://127.0.0.1:$serverPort$htmlPath${searchStr}'
+ 'crossOriginPort=$crossOriginPort';
+ searchStr = '&';
}
if (info.optionsFromFile['isMultiHtmlTest']
&& subtestNames.length > 0) {
- fullHtmlPath = '${fullHtmlPath}#${subtestNames[subtestIndex]}';
+ fullHtmlPath = '${fullHtmlPath}${searchStr}group='
+ '${subtestNames[subtestIndex]}';
}
if (TestUtils.usesWebDriver(runtime)) {
diff --git a/tools/testing/run_selenium.py b/tools/testing/run_selenium.py
index 18f7798..ba4cc6d 100755
--- a/tools/testing/run_selenium.py
+++ b/tools/testing/run_selenium.py
@@ -43,6 +43,7 @@
import threading
TIMEOUT_ERROR_MSG = 'FAIL (timeout)'
+CRASH_ERROR_MSG = 'CRASH'
def correctness_test_done(source):
"""Checks if test has completed."""
@@ -84,12 +85,28 @@
if refresh:
browser.refresh()
try:
+ def pythonTimeout():
+ # The builtin quit call for chrome will call close on the RemoteDriver
+ # which may hang. Explicitly call browser.service.stop()
+ if (type(browser) is selenium.webdriver.chrome.webdriver.WebDriver):
+ # Browser may be dead
+ try:
+ browser.service.stop()
+ except:
+ print("Trying to close browser that has already been closed")
+ # If the browser is crashing selenium may not time out.
+ # Explicitly catch this case with a python timer.
+ t = threading.Timer(timeout, pythonTimeout)
+ t.start()
test_done = CONFIGURATIONS[mode]
element = WebDriverWait(browser, float(timeout)).until(
lambda driver: test_done(driver.page_source))
+ t.cancel()
return browser.page_source
except selenium.common.exceptions.TimeoutException:
return TIMEOUT_ERROR_MSG
+ except:
+ return CRASH_ERROR_MSG
def run_test_in_browser_selenium_rc(sel, html_out, timeout, mode, refresh):
""" Run the desired test in the browser using Selenium 1.0 syntax, and wait
@@ -226,6 +243,7 @@
if (type(browser) is not selenium.webdriver.chrome.webdriver.WebDriver and
type(browser) is not selenium.webdriver.ie.webdriver.WebDriver):
browser.close()
+
browser.quit()
def report_results(mode, source, browser):
@@ -321,6 +339,11 @@
print '>>> TEST PASS'
elif source == TIMEOUT_ERROR_MSG:
print '>>> TEST TIMEOUT'
+ elif source == CRASH_ERROR_MSG:
+ print '>>> TEST CRASH'
+ # The browser crashed, set the browser to None so that we will
+ # create a new instance on next iteration.
+ browser = None
else:
print '>>> TEST FAIL'
sys.stdout.flush()
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index bba8136..bf6324f 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -63,7 +63,7 @@
} else if (arg.startsWith('--out=')) {
outputDir = new Path(arg.substring('--out='.length));
} else if (arg.startsWith('--pkg=')) {
- pkgPath = arg.substring('--pkg='.length);
+ pkgPath = new Path(arg.substring('--pkg='.length));
} else {
print('Unknown option: $arg');
return;
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index 81a0330..b27cceb 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -53,6 +53,7 @@
'--exclude-lib=oauth2',
'--exclude-lib=path',
'--exclude-lib=webdriver',
+ '--exclude-lib=yaml',
'--include-lib=matcher',
'--include-lib=mock',
],
diff --git a/utils/apidoc/html_diff.dart b/utils/apidoc/html_diff.dart
index e251745..c9aaf84 100644
--- a/utils/apidoc/html_diff.dart
+++ b/utils/apidoc/html_diff.dart
@@ -26,9 +26,9 @@
'dart:svg',
'dart:web_audio'];
const List<String> HTML_DECLARED_NAMES = const [
- 'html',
- 'svg',
- 'web_audio'];
+ 'dart.dom.html',
+ 'dart.dom.svg',
+ 'dart.dom.web_audio'];
/**
* A class for computing a many-to-many mapping between the types and
@@ -234,4 +234,4 @@
}
return new Set.from([name]);
}
-}
\ No newline at end of file
+}
diff --git a/utils/compiler/compiler.gyp b/utils/compiler/compiler.gyp
index 4226483..784a75b 100644
--- a/utils/compiler/compiler.gyp
+++ b/utils/compiler/compiler.gyp
@@ -17,7 +17,6 @@
{
'action_name': 'generate_dart2js_snapshot',
'inputs': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)',
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
'../../sdk/lib/_internal/libraries.dart',
'<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../sdk/lib/_internal/compiler", "../../runtime/lib"])',
@@ -26,13 +25,13 @@
'<(PRODUCT_DIR)/dart2js.snapshot',
],
'action': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)',
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
# 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
# for dart2js compiler engineers. However, we install the
# snapshot in the proper location when building the SDK.
- '--script_snapshot=<(PRODUCT_DIR)/dart2js.snapshot',
+ '--generate-script-snapshot=<(PRODUCT_DIR)/dart2js.snapshot',
'../../sdk/lib/_internal/compiler/implementation/dart2js.dart',
],
},
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 59bfbbf..536a3aa 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -87,20 +87,21 @@
Future onRun() {
var files;
- return _filesToPublish.then((f) {
+ var packageBytesFuture = _filesToPublish.then((f) {
files = f;
log.fine('Archiving and publishing ${entrypoint.root}.');
return createTarGz(files, baseDir: entrypoint.root.dir);
- }).then(consumeInputStream).then((packageBytes) {
- // Show the package contents so the user can verify they look OK.
- var package = entrypoint.root;
- log.message(
- 'Publishing "${package.name}" ${package.version}:\n'
- '${generateTree(files)}');
+ }).then(consumeInputStream);
+
+ // Show the package contents so the user can verify they look OK.
+ var package = entrypoint.root;
+ log.message(
+ 'Publishing "${package.name}" ${package.version}:\n'
+ '${generateTree(files)}');
// Validate the package.
- return _validate().then((_) => _publish(packageBytes));
- });
+ return _validate(packageBytesFuture.then((bytes) => bytes.length))
+ .then((_) => packageBytesFuture).then(_publish);
}
/// The basenames of files that are automatically excluded from archives.
@@ -128,7 +129,7 @@
}
return listDir(rootDir, recursive: true).then((entries) {
- return Future.wait(entries.mappedBy((entry) {
+ return Future.wait(entries.map((entry) {
return fileExists(entry).then((isFile) {
// Skip directories.
if (!isFile) return null;
@@ -159,8 +160,8 @@
}
/// Validates the package. Throws an exception if it's invalid.
- Future _validate() {
- return Validator.runAll(entrypoint).then((pair) {
+ Future _validate(Future<int> packageSize) {
+ return Validator.runAll(entrypoint, packageSize).then((pair) {
var errors = pair.first;
var warnings = pair.last;
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index 30bfeb1..d562997 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -130,7 +130,7 @@
/// [packageVersions], and writes a [LockFile].
Future _installDependencies(List<PackageId> packageVersions) {
return cleanDir(path).then((_) {
- return Future.wait(packageVersions.mappedBy((id) {
+ return Future.wait(packageVersions.map((id) {
if (id.isRoot) return new Future.immediate(id);
return install(id);
}));
@@ -207,7 +207,7 @@
return _linkSecondaryPackageDir(dir)
.then((_) => _listDirWithoutPackages(dir))
.then((files) {
- return Future.wait(files.mappedBy((file) {
+ return Future.wait(files.map((file) {
return dirExists(file).then((isDir) {
if (!isDir) return;
return _linkSecondaryPackageDir(file);
@@ -222,7 +222,7 @@
/// files and `package` files.
Future<List<String>> _listDirWithoutPackages(dir) {
return listDir(dir).then((files) {
- return Future.wait(files.mappedBy((file) {
+ return Future.wait(files.map((file) {
if (basename(file) == 'packages') return new Future.immediate([]);
return dirExists(file).then((isDir) {
if (!isDir) return [];
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index 81a8057..b774bc0 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -39,7 +39,7 @@
return httpClient.read(fullUrl).then((body) {
var doc = json.parse(body);
return doc['versions']
- .mappedBy((version) => new Version.parse(version))
+ .map((version) => new Version.parse(version))
.toList();
}).catchError((ex) {
_throwFriendlyError(ex, parsed.first, parsed.last);
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 79f0a06..8243a28 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -22,7 +22,7 @@
/// [File] objects.
String join(part1, [part2, part3, part4, part5, part6, part7, part8]) {
var parts = [part1, part2, part3, part4, part5, part6, part7, part8]
- .mappedBy((part) => part == null ? null : _getPath(part)).toList();
+ .map((part) => part == null ? null : _getPath(part)).toList();
return path.join(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5],
parts[6], parts[7]);
@@ -85,6 +85,16 @@
});
}
+/// Reads the contents of the binary file [file], which can either be a [String]
+/// or a [File].
+List<int> readBinaryFile(file) {
+ var path = _getPath(file);
+ log.io("Reading binary file $path.");
+ var contents = new File(path).readAsBytesSync();
+ log.io("Read ${contents.length} bytes from $path.");
+ return contents;
+}
+
/// Creates [file] (which can either be a [String] or a [File]), and writes
/// [contents] to it. Completes when the file is written and closed.
///
@@ -109,6 +119,20 @@
});
}
+/// Creates [file] (which can either be a [String] or a [File]), and writes
+/// [contents] to it.
+File writeBinaryFile(file, List<int> contents) {
+ var path = _getPath(file);
+ file = new File(path);
+
+ log.io("Writing ${contents.length} bytes to binary file $path.");
+ file.openSync(FileMode.WRITE)
+ ..writeListSync(contents, 0, contents.length)
+ ..closeSync();
+ log.fine("Wrote text file $path.");
+ return file;
+}
+
/// Asynchronously deletes [file], which can be a [String] or a [File]. Returns
/// a [Future] that completes when the deletion is done.
Future<File> deleteFile(file) {
@@ -873,7 +897,7 @@
if (baseDir == null) baseDir = path.current;
baseDir = getFullPath(baseDir);
- contents = contents.mappedBy((entry) {
+ contents = contents.map((entry) {
entry = getFullPath(entry);
if (!isBeneath(entry, baseDir)) {
throw 'Entry $entry is not inside $baseDir.';
@@ -883,7 +907,7 @@
if (Platform.operatingSystem != "windows") {
var args = ["--create", "--gzip", "--directory", baseDir];
- args.addAll(contents.mappedBy(_getPath));
+ 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.
@@ -903,7 +927,7 @@
// Create the tar file.
var tarFile = join(tempDir, "intermediate.tar");
var args = ["a", "-w$baseDir", tarFile];
- args.addAll(contents.mappedBy((entry) => '-i!"$entry"'));
+ 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.
diff --git a/utils/pub/lock_file.dart b/utils/pub/lock_file.dart
index 1e97585..23e7099 100644
--- a/utils/pub/lock_file.dart
+++ b/utils/pub/lock_file.dart
@@ -9,7 +9,7 @@
import 'source_registry.dart';
import 'utils.dart';
import 'version.dart';
-import 'yaml/yaml.dart';
+import '../../pkg/yaml/lib/yaml.dart';
/// A parsed and validated `pubspec.lock` file.
class LockFile {
@@ -26,7 +26,6 @@
var packages = <String, PackageId>{};
if (contents.trim() == '') return new LockFile.empty();
-
var parsed = loadYaml(contents);
if (parsed.containsKey('packages')) {
@@ -85,6 +84,9 @@
// TODO(nweiz): Serialize using the YAML library once it supports
// serialization. For now, we use JSON, since it's a subset of YAML anyway.
- return json.stringify({'packages': packagesObj});
+ return '''
+ # Generated by pub. See: http://pub.dartlang.org/doc/glossary.html#lockfile
+ ${json.stringify({'packages': packagesObj})}
+ ''';
}
}
diff --git a/utils/pub/package.dart b/utils/pub/package.dart
index f62e2be..15fcb97 100644
--- a/utils/pub/package.dart
+++ b/utils/pub/package.dart
@@ -11,6 +11,8 @@
import 'source_registry.dart';
import 'version.dart';
+final _README_REGEXP = new RegExp(r"^README($|\.)", caseSensitive: false);
+
/// A named, versioned, unit of code and resource reuse.
class Package {
/// Loads the package whose root directory is [packageDir]. [name] is the
@@ -58,6 +60,26 @@
/// specified in the pubspec when this package depends on another.
Collection<PackageRef> get dependencies => pubspec.dependencies;
+ /// Returns the path to the README file at the root of the entrypoint, or null
+ /// if no README file is found. If multiple READMEs are found, this uses the
+ /// same conventions as pub.dartlang.org for choosing the primary one: the
+ /// README with the fewest extensions that is lexically ordered first is
+ /// chosen.
+ Future<String> get readmePath {
+ return listDir(dir).then((entries) {
+ var readmes = entries.where((entry) => entry.contains(_README_REGEXP));
+ if (readmes.isEmpty) return;
+
+ return readmes.min((readme1, readme2) {
+ var extensions1 = ".".allMatches(readme1).length;
+ var extensions2 = ".".allMatches(readme2).length;
+ var comparison = extensions1.compareTo(extensions2);
+ if (comparison != 0) return comparison;
+ return readme1.compareTo(readme2);
+ });
+ });
+ }
+
/// Constructs a package with the given pubspec. The package will have no
/// directory associated with it.
Package.inMemory(this.pubspec)
diff --git a/utils/pub/pubspec.dart b/utils/pub/pubspec.dart
index aaabdd1..11b840e 100644
--- a/utils/pub/pubspec.dart
+++ b/utils/pub/pubspec.dart
@@ -9,7 +9,7 @@
import 'source_registry.dart';
import 'utils.dart';
import 'version.dart';
-import 'yaml/yaml.dart';
+import '../../pkg/yaml/lib/yaml.dart';
/// The parsed and validated contents of a pubspec file.
class Pubspec {
diff --git a/utils/pub/sdk.dart b/utils/pub/sdk.dart
index 0e47acd..98007b5 100644
--- a/utils/pub/sdk.dart
+++ b/utils/pub/sdk.dart
@@ -14,7 +14,7 @@
/// Matches an Eclipse-style SDK version number. This is four dotted numbers
/// (major, minor, patch, build) with an optional suffix attached to the build
/// number.
-final _versionPattern = new RegExp(r'^(\d+)\.(\d+)\.(\d+)\.(\d+)(.*)$');
+final _versionPattern = new RegExp(r'^(\d+)\.(\d+)\.(\d+)\.(\d+.*)$');
/// Gets the path to the root directory of the SDK.
String get rootDirectory {
@@ -41,15 +41,15 @@
var version = new File(revisionPath).readAsStringSync().trim();
// Given a version file like: 0.1.2.0_r17495
- // We create a semver like: 0.1.2+0._r17495
+ // We create a semver like: 0.1.2+0.r17495
var match = _versionPattern.firstMatch(version);
if (match == null) {
throw new FormatException("The Dart SDK's 'version' file was not in a "
"format pub could recognize. Found: $version");
}
- var build = match[4];
- if (match[5].length > 0) build = '$build.${match[5]}';
+ // Semantic versions cannot use "_".
+ var build = match[4].replaceAll('_', '.');
return new Version(
int.parse(match[1]), int.parse(match[2]), int.parse(match[3]),
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 7710ac1..4311c09 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -118,6 +118,18 @@
onError: (e) => completer.completeError(e.error, e.stackTrace));
}
+/// Like [Iterable.where], but allows [test] to return [Future]s and uses the
+/// results of those [Future]s as the test.
+Future<Iterable> futureWhere(Iterable iter, test(value)) {
+ return Future.wait(iter.mappedBy((e) {
+ var result = test(e);
+ if (result is! Future) result = new Future.immediate(result);
+ return result.then((result) => new Pair(e, result));
+ }))
+ .then((pairs) => pairs.where((pair) => pair.last))
+ .then((pairs) => pairs.mappedBy((pair) => pair.first));
+}
+
// TODO(nweiz): unify the following functions with the utility functions in
// pkg/http.
@@ -162,7 +174,7 @@
value = (value == null || value.isEmpty) ? null : encodeUriComponent(value);
pairs.add([key, value]);
});
- return Strings.join(pairs.mappedBy((pair) {
+ return Strings.join(pairs.map((pair) {
if (pair[1] == null) return pair[0];
return "${pair[0]}=${pair[1]}";
}), "&");
diff --git a/utils/pub/validator.dart b/utils/pub/validator.dart
index 5ec0f23..72f65d1 100644
--- a/utils/pub/validator.dart
+++ b/utils/pub/validator.dart
@@ -11,12 +11,15 @@
import 'io.dart';
import 'system_cache.dart';
import 'utils.dart';
+import 'validator/compiled_dartdoc.dart';
import 'validator/dependency.dart';
import 'validator/directory.dart';
import 'validator/lib.dart';
import 'validator/license.dart';
import 'validator/name.dart';
import 'validator/pubspec_field.dart';
+import 'validator/size.dart';
+import 'validator/utf8_readme.dart';
/// The base class for validators that check whether a package is fit for
/// uploading. Each validator should override [errors], [warnings], or both to
@@ -42,23 +45,32 @@
/// Run all validators on the [entrypoint] package and print their results.
/// The future will complete with the error and warning messages,
/// respectively.
+ ///
+ /// [packageSize], if passed, should complete to the size of the tarred
+ /// package, in bytes. This is used to validate that it's not too big to
+ /// upload to the server.
static Future<Pair<List<String>, List<String>>> runAll(
- Entrypoint entrypoint) {
+ Entrypoint entrypoint, [Future<int> packageSize]) {
var validators = [
new LibValidator(entrypoint),
new LicenseValidator(entrypoint),
new NameValidator(entrypoint),
new PubspecFieldValidator(entrypoint),
new DependencyValidator(entrypoint),
- new DirectoryValidator(entrypoint)
+ new DirectoryValidator(entrypoint),
+ new CompiledDartdocValidator(entrypoint),
+ new Utf8ReadmeValidator(entrypoint)
];
+ if (packageSize != null) {
+ validators.add(new SizeValidator(entrypoint, packageSize));
+ }
- return Future.wait(validators.mappedBy((validator) => validator.validate()))
+ return Future.wait(validators.map((validator) => validator.validate()))
.then((_) {
var errors =
- flatten(validators.mappedBy((validator) => validator.errors));
+ flatten(validators.map((validator) => validator.errors));
var warnings =
- flatten(validators.mappedBy((validator) => validator.warnings));
+ flatten(validators.map((validator) => validator.warnings));
if (!errors.isEmpty) {
log.error("Missing requirements:");
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
new file mode 100644
index 0000000..c2c93f3
--- /dev/null
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 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 compiled_dartdoc_validator;
+
+import 'dart:async';
+
+import '../../../pkg/path/lib/path.dart' as path;
+
+import '../entrypoint.dart';
+import '../io.dart';
+import '../utils.dart';
+import '../validator.dart';
+
+/// Validates that a package doesn't contain compiled Dartdoc
+/// output.
+class CompiledDartdocValidator extends Validator {
+ CompiledDartdocValidator(Entrypoint entrypoint)
+ : super(entrypoint);
+
+ Future validate() {
+ return listDir(entrypoint.root.dir, recursive: true).then((entries) {
+ return futureWhere(entries, (entry) {
+ if (basename(entry) != "nav.json") return false;
+ var dir = dirname(entry);
+
+ // Look for tell-tale Dartdoc output files all in the same directory.
+ return Future.wait([
+ fileExists(entry),
+ fileExists(join(dir, "index.html")),
+ fileExists(join(dir, "styles.css")),
+ fileExists(join(dir, "dart-logo-small.png")),
+ fileExists(join(dir, "client-live-nav.js"))
+ ]).then((results) => results.every((val) => val));
+ }).then((files) {
+ for (var dartdocDir in files.mappedBy(dirname)) {
+ var relativePath = path.relative(dartdocDir);
+ warnings.add("Avoid putting generated documentation in "
+ "$relativePath.\n"
+ "Generated documentation bloats the package with redundant "
+ "data.");
+ }
+ });
+ });
+ }
+}
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
index 132bdd7..09a6c7e 100644
--- a/utils/pub/validator/directory.dart
+++ b/utils/pub/validator/directory.dart
@@ -19,7 +19,7 @@
Future validate() {
return listDir(entrypoint.root.dir).then((dirs) {
- return Future.wait(dirs.mappedBy((dir) {
+ return Future.wait(dirs.map((dir) {
return dirExists(dir).then((exists) {
if (!exists) return;
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index e679847..faee7290 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -31,7 +31,7 @@
}
return listDir(libDir).then((files) {
- files = files.mappedBy((file) => relativeTo(file, libDir)).toList();
+ files = files.map((file) => relativeTo(file, libDir)).toList();
if (files.isEmpty) {
errors.add('You must have a non-empty "lib" directory.\n'
"Without that, users cannot import any code from your package.");
diff --git a/utils/pub/validator/license.dart b/utils/pub/validator/license.dart
index 25556f8..8c32548 100644
--- a/utils/pub/validator/license.dart
+++ b/utils/pub/validator/license.dart
@@ -20,7 +20,7 @@
return listDir(entrypoint.root.dir).then((files) {
var licenseLike = new RegExp(
r"^([a-zA-Z0-9]+[-_])?(LICENSE|COPYING)(\..*)?$");
- if (files.mappedBy(basename).any(licenseLike.hasMatch)) return;
+ if (files.map(basename).any(licenseLike.hasMatch)) return;
errors.add(
"You must have a COPYING or LICENSE file in the root directory.\n"
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index eb1bc85..7c4778c 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -52,7 +52,7 @@
return listDir(libDir, recursive: true);
}).then((files) {
return files
- .mappedBy((file) => relativeTo(file, dirname(libDir)))
+ .map((file) => relativeTo(file, dirname(libDir)))
.where((file) => !splitPath(file).contains("src") &&
path.extension(file) == '.dart')
.toList();
diff --git a/utils/pub/validator/size.dart b/utils/pub/validator/size.dart
new file mode 100644
index 0000000..8014b29
--- /dev/null
+++ b/utils/pub/validator/size.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library size_validator;
+
+import 'dart:async';
+import 'dart:math' as math;
+
+import '../entrypoint.dart';
+import '../validator.dart';
+
+/// The maximum size of the package to upload (10 MB).
+const _MAX_SIZE = 10 * 1024 * 1024;
+
+/// A validator that validates that a package isn't too big.
+class SizeValidator extends Validator {
+ final Future<int> packageSize;
+
+ SizeValidator(Entrypoint entrypoint, this.packageSize)
+ : super(entrypoint);
+
+ Future validate() {
+ return packageSize.then((size) {
+ if (size <= _MAX_SIZE) return;
+ var sizeInMb = (size / math.pow(2, 20)).toStringAsPrecision(4);
+ errors.add("Your package is $sizeInMb MB. Hosted packages must be "
+ "smaller than 10 MB.");
+ });
+ }
+}
+
diff --git a/utils/pub/validator/utf8_readme.dart b/utils/pub/validator/utf8_readme.dart
new file mode 100644
index 0000000..e586230
--- /dev/null
+++ b/utils/pub/validator/utf8_readme.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library utf8_readme_validator;
+
+import 'dart:async';
+import 'dart:utf';
+
+import '../../../pkg/path/lib/path.dart' as path;
+
+import '../entrypoint.dart';
+import '../io.dart';
+import '../utils.dart';
+import '../validator.dart';
+
+/// Validates that a package's README is valid utf-8.
+class Utf8ReadmeValidator extends Validator {
+ Utf8ReadmeValidator(Entrypoint entrypoint)
+ : super(entrypoint);
+
+ Future validate() {
+ return entrypoint.root.readmePath.then((readme) {
+ if (readme == null) return;
+ var bytes = readBinaryFile(readme);
+ try {
+ // The second and third arguments here are the default values. The
+ // fourth tells [decodeUtf8] to throw an ArgumentError if `bytes` isn't
+ // valid utf-8.
+ decodeUtf8(bytes, 0, null, null);
+ } on ArgumentError catch (_) {
+ warnings.add("$readme contains invalid UTF-8.\n"
+ "This will cause it to be displayed incorrectly on "
+ "pub.dartlang.org.");
+ }
+ });
+ }
+}
+
diff --git a/utils/pub/version.dart b/utils/pub/version.dart
index 18e15a5..06c14fd 100644
--- a/utils/pub/version.dart
+++ b/utils/pub/version.dart
@@ -192,7 +192,7 @@
/// Splits a string of dot-delimited identifiers into their component parts.
/// Identifiers that are numeric are converted to numbers.
List _splitParts(String text) {
- return text.split('.').mappedBy((part) {
+ return text.split('.').map((part) {
try {
return int.parse(part);
} on FormatException catch (ex) {
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 21f8cad..a45af91 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -189,12 +189,12 @@
}
}
- return dependency.dependers.mappedBy(getDependency).any((subdependency) =>
+ return dependency.dependers.map(getDependency).any((subdependency) =>
tryUnlockDepender(subdependency, seen));
}
List<PackageId> buildResults() {
- return _packages.values.where((dep) => dep.isDependedOn).mappedBy((dep) {
+ return _packages.values.where((dep) => dep.isDependedOn).map((dep) {
var description = dep.description;
// If the lockfile contains a fully-resolved description for the package,
@@ -507,7 +507,7 @@
VersionConstraint get constraint {
if (_refs.isEmpty) return null;
return new VersionConstraint.intersection(
- _refs.values.mappedBy((ref) => ref.constraint));
+ _refs.values.map((ref) => ref.constraint));
}
/// The source of this dependency's package.
diff --git a/utils/tests/archive/reader_test.dart b/utils/tests/archive/reader_test.dart
index 0feac52..e95d5dd 100644
--- a/utils/tests/archive/reader_test.dart
+++ b/utils/tests/archive/reader_test.dart
@@ -58,7 +58,7 @@
.then((input) => input.readAll())
.then((entries) {
entries = entries
- .mappedBy((entry) => [entry.pathname, entry.contents.trim()])
+ .map((entry) => [entry.pathname, entry.contents.trim()])
.toList();
expect(entries[0], orderedEquals(["filename1", "contents 1"]));
expect(entries[1], orderedEquals(["filename2", "contents 2"]));
diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
index 1d4f7bf..71df35e 100644
--- a/utils/tests/pub/command_line_config.dart
+++ b/utils/tests/pub/command_line_config.dart
@@ -6,6 +6,7 @@
import 'dart:io';
+import '../../../pkg/path/lib/path.dart' as path;
import '../../../pkg/unittest/lib/unittest.dart';
import '../../pub/utils.dart';
@@ -70,6 +71,8 @@
void _printStackTrace(String stackTrace) {
if (stackTrace == null || stackTrace == '') return;
+ print('');
+
// Parse out each stack entry.
var stack = [];
for (var line in stackTrace.split('\n')) {
@@ -79,35 +82,8 @@
if (stack.length == 0) return;
- // Find the common prefixes of the paths.
- var common = 0;
- while (true) {
- var matching = true;
- var c;
- for (var frame in stack) {
- if (frame.isCore) continue;
- if (c == null) c = frame.library[common];
-
- if (frame.library.length <= common || frame.library[common] != c) {
- matching = false;
- break;
- }
- }
-
- if (!matching) break;
- common++;
- }
-
- // Remove them.
- if (common > 0) {
- for (var frame in stack) {
- if (frame.isCore) continue;
- frame.library = frame.library.substring(common);
- }
- }
-
// Figure out the longest path so we know how much to pad.
- int longest = stack.mappedBy((frame) => frame.location.length).max();
+ int longest = stack.map((frame) => frame.location.length).max();
// Print out the stack trace nicely formatted.
for (var frame in stack) {
@@ -132,13 +108,13 @@
String _indent(String str) {
// TODO(nweiz): Use this simpler code once issue 2980 is fixed.
// return str.replaceAll(new RegExp("^", multiLine: true), " ");
- return Strings.join(str.split("\n").mappedBy((line) => " $line"), "\n");
+ return Strings.join(str.split("\n").map((line) => " $line"), "\n");
}
}
class _StackFrame {
static final fileRegExp = new RegExp(
- r'#\d+\s+(.*) \((file:///.+):(\d+):(\d+)\)');
+ r'#\d+\s+(.*) \(file://(/.+):(\d+):(\d+)\)');
static final coreRegExp = new RegExp(r'#\d+\s+(.*) \((.+):(\d+):(\d+)\)');
/// If `true`, then this stack frame is for a library built into Dart and
@@ -172,7 +148,13 @@
isCore = true;
}
+ var library = match[2];
+ if (!isCore) {
+ // Make the library path relative to the entrypoint.
+ library = path.relative(library);
+ }
+
var member = match[1].replaceAll("<anonymous closure>", _LAMBDA);
- return new _StackFrame._(isCore, match[2], match[3], match[4], member);
+ return new _StackFrame._(isCore, library, match[3], match[4], member);
}
}
\ No newline at end of file
diff --git a/utils/tests/pub/curl_client_test.dart b/utils/tests/pub/curl_client_test.dart
index ba57e21..924e994 100644
--- a/utils/tests/pub/curl_client_test.dart
+++ b/utils/tests/pub/curl_client_test.dart
@@ -168,19 +168,6 @@
}
}
-// TODO(nweiz): remove this once it's built in to unittest (issue 7922).
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
- const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
- const _StateError() : super("StateError");
- bool matches(item, MatchState matchState) => item is StateError;
-}
-
/// A matcher for HttpExceptions.
const isHttpException = const _HttpException();
diff --git a/utils/tests/pub/error_group_test.dart b/utils/tests/pub/error_group_test.dart
index 9d2d59e0..c2f10fe 100644
--- a/utils/tests/pub/error_group_test.dart
+++ b/utils/tests/pub/error_group_test.dart
@@ -451,16 +451,3 @@
});
});
}
-
-// TODO(nweiz): remove this once it's built in to unittest (issue 7922).
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
- const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
- const _StateError() : super("StateError");
- bool matches(item, MatchState matchState) => item is StateError;
-}
diff --git a/utils/tests/pub/lock_file_test.dart b/utils/tests/pub/lock_file_test.dart
index d1aeb00..eeef7bf 100644
--- a/utils/tests/pub/lock_file_test.dart
+++ b/utils/tests/pub/lock_file_test.dart
@@ -5,13 +5,13 @@
library lock_file_test;
import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/yaml/lib/yaml.dart';
import '../../pub/lock_file.dart';
import '../../pub/package.dart';
import '../../pub/source.dart';
import '../../pub/source_registry.dart';
import '../../pub/utils.dart';
import '../../pub/version.dart';
-import '../../pub/yaml/yaml.dart';
class MockSource extends Source {
final String name = 'mock';
diff --git a/utils/tests/pub/pub.status b/utils/tests/pub/pub.status
index 09fcf6d..ab958ef 100644
--- a/utils/tests/pub/pub.status
+++ b/utils/tests/pub/pub.status
@@ -4,7 +4,7 @@
pub_uploader_test: Pass, Fail # Issue 7905
pub_lish_test: Pass, Fail # Issue 7905
-oauth2_test: Pass, Fail # Issue 7905, 7920
+oauth2_test: Pass, Fail, Timeout # Issue 7905, 7920
curl_client_test: Pass, Fail # Issue 7920
# Pub only runs on the VM, so just rule out all compilers.
diff --git a/utils/tests/pub/pub_test.dart b/utils/tests/pub/pub_test.dart
index 13426f1..6de4dbc 100644
--- a/utils/tests/pub/pub_test.dart
+++ b/utils/tests/pub/pub_test.dart
@@ -123,11 +123,31 @@
});
- integration('displays the current version', () {
- dir(sdkPath, [
- file('version', '0.1.2.3'),
- ]).scheduleCreate();
+ group('version', () {
+ integration('displays the current version', () {
+ dir(sdkPath, [
+ file('version', '0.1.2.3'),
+ ]).scheduleCreate();
- schedulePub(args: ['version'], output: VERSION_STRING);
+ schedulePub(args: ['version'], output: VERSION_STRING);
+ });
+
+ integration('parses a release-style version', () {
+ dir(sdkPath, [
+ file('version', '0.1.2.0_r17645'),
+ ]).scheduleCreate();
+
+ schedulePub(args: ['version'], output: "Pub 0.1.2+0.r17645\n");
+ });
+
+ integration('parses a dev-only style version', () {
+ // The "version" file generated on developer builds is a little funky and
+ // we need to make sure we don't choke on it.
+ dir(sdkPath, [
+ file('version', '0.1.2.0_r16279_bobross'),
+ ]).scheduleCreate();
+
+ schedulePub(args: ['version'], output: "Pub 0.1.2+0.r16279.bobross\n");
+ });
});
}
diff --git a/utils/tests/pub/real_version_test.dart b/utils/tests/pub/real_version_test.dart
index 1688fa7..b0329a6 100644
--- a/utils/tests/pub/real_version_test.dart
+++ b/utils/tests/pub/real_version_test.dart
@@ -25,7 +25,7 @@
// Note that this test expects to be invoked from a Dart executable that is
// in the built SDK's "bin" directory. Note also that this invokes pub from
// the built SDK directory, and not the live pub code directly in the repo.
- test('Pub can parse the real SDK "version" file', () {
+ test('parse the real SDK "version" file', () {
// Get the path to the pub binary in the SDK.
var dartPath = new Options().executable;
var pubPath = path.join(path.dirname(dartPath), "pub");
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 2ef2689..27708ff 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -14,11 +14,13 @@
import 'dart:json' as json;
import 'dart:math';
import 'dart:uri';
+import 'dart:utf';
+import '../../../pkg/http/lib/testing.dart';
import '../../../pkg/oauth2/lib/oauth2.dart' as oauth2;
import '../../../pkg/path/lib/path.dart' as path;
import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/http/lib/testing.dart';
+import '../../../pkg/yaml/lib/yaml.dart';
import '../../lib/file_system.dart' as fs;
import '../../pub/entrypoint.dart';
// TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides
@@ -33,7 +35,6 @@
import '../../pub/system_cache.dart';
import '../../pub/utils.dart';
import '../../pub/validator.dart';
-import '../../pub/yaml/yaml.dart';
import 'command_line_config.dart';
/// This should be called at the top of a test file to set up an appropriate
@@ -49,6 +50,10 @@
FileDescriptor file(Pattern name, String contents) =>
new FileDescriptor(name, contents);
+/// Creates a new [FileDescriptor] with [name] and [contents].
+FileDescriptor binaryFile(Pattern name, List<int> contents) =>
+ new FileDescriptor.bytes(name, contents);
+
/// Creates a new [DirectoryDescriptor] with [name] and [contents].
DirectoryDescriptor dir(Pattern name, [List<Descriptor> contents]) =>
new DirectoryDescriptor(name, contents);
@@ -190,7 +195,7 @@
file('$name.json',
json.stringify({'versions': versions})),
dir(name, [
- dir('versions', flatten(versions.mappedBy((version) {
+ dir('versions', flatten(versions.map((version) {
return [
file('$version.yaml', _servedPackages[name][version]),
tar('$version.tar.gz', [
@@ -462,42 +467,42 @@
/// operations which will be run asynchronously.
void integration(String description, void body()) {
test(description, () {
+ // Schedule the test.
body();
- _run();
- });
-}
-/// Runs all the scheduled events for a test case. This should only be called
-/// once per test case.
-void _run() {
- var createdSandboxDir;
- var asyncDone = expectAsync0(() {});
-
- Future cleanup() {
- return _runScheduled(createdSandboxDir, _scheduledCleanup).then((_) {
- _scheduled = null;
- _scheduledCleanup = null;
- _scheduledOnException = null;
- if (createdSandboxDir != null) return deleteDir(createdSandboxDir);
- });
- }
-
- timeout(_setUpSandbox().then((sandboxDir) {
- createdSandboxDir = sandboxDir;
- return _runScheduled(sandboxDir, _scheduled);
- }).catchError((e) {
- // 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.
- return _runScheduled(createdSandboxDir, _scheduledOnException)
- .then((_) => registerException(e.error, e.stackTrace)).catchError((e) {
- print("Exception while cleaning up: ${e.error}");
- print(e.stackTrace);
+ // Run all of the scheduled tasks. If an error occurs, it will propagate
+ // through the futures back up to here where we can hand it off to unittest.
+ var asyncDone = expectAsync0(() {});
+ var createdSandboxDir;
+ _setUpSandbox().then((sandboxDir) {
+ createdSandboxDir = sandboxDir;
+ return timeout(_runScheduled(sandboxDir, _scheduled),
+ _TIMEOUT, 'waiting for a test to complete');
+ }).catchError((e) {
+ return _runScheduled(createdSandboxDir, _scheduledOnException).then((_) {
+ // Rethrow the original error so it keeps propagating.
+ throw e;
+ });
+ }).whenComplete(() {
+ // Clean up after ourselves. Do this first before reporting back to
+ // unittest because it will advance to the next test immediately.
+ return _runScheduled(createdSandboxDir, _scheduledCleanup).then((_) {
+ _scheduled = null;
+ _scheduledCleanup = null;
+ _scheduledOnException = null;
+ if (createdSandboxDir != null) return deleteDir(createdSandboxDir);
+ });
+ }).then((_) {
+ // If we got here, the test completed successfully so tell unittest so.
+ asyncDone();
+ }).catchError((e) {
+ // If we got here, an error occurred. We will register it with unittest
+ // directly so that the error message isn't wrapped in any matcher stuff.
+ // We do this call last because it will cause unittest to *synchronously*
+ // advance to the next test and run it.
registerException(e.error, e.stackTrace);
});
- }), _TIMEOUT, 'waiting for a test to complete')
- .then((_) => cleanup())
- .then((_) => asyncDone());
+ });
}
/// Get the path to the root "util/test/pub" directory containing the pub
@@ -514,8 +519,7 @@
void schedulePub({List args, Pattern output, Pattern error,
Future<Uri> tokenEndpoint, int exitCode: 0}) {
_schedule((sandboxDir) {
- return _doPub(runProcess, sandboxDir, args, tokenEndpoint)
- .then((result) {
+ return _doPub(runProcess, sandboxDir, args, tokenEndpoint).then((result) {
var failures = [];
_validateOutput(failures, 'stdout', output, result.stdout);
@@ -530,7 +534,7 @@
if (error == null) {
// If we aren't validating the error, still show it on failure.
failures.add('Pub stderr:');
- failures.addAll(result.stderr.mappedBy((line) => '| $line'));
+ failures.addAll(result.stderr.map((line) => '| $line'));
}
throw new ExpectException(Strings.join(failures, '\n'));
@@ -702,7 +706,7 @@
failures.add('Expected $pipe to match "${expected.pattern}" but got none.');
} else {
failures.add('Expected $pipe to match "${expected.pattern}" but got:');
- failures.addAll(actual.mappedBy((line) => '| $line'));
+ failures.addAll(actual.map((line) => '| $line'));
}
}
@@ -747,7 +751,7 @@
// If any lines mismatched, show the expected and actual.
if (failed) {
failures.add('Expected $pipe:');
- failures.addAll(expected.mappedBy((line) => '| $line'));
+ failures.addAll(expected.map((line) => '| $line'));
failures.add('Got:');
failures.addAll(results);
}
@@ -808,7 +812,9 @@
if (name is String) {
var path = join(dir, name);
return exists(path).then((exists) {
- if (!exists) Expect.fail('File $name in $dir not found.');
+ if (!exists) {
+ throw new ExpectException('File $name in $dir not found.');
+ }
return validate(path);
});
}
@@ -824,7 +830,7 @@
return listDir(dir).then((files) {
var matches = files.where((file) => endsWithPattern(file, name)).toList();
if (matches.isEmpty) {
- Expect.fail('No files in $dir match pattern $name.');
+ throw new ExpectException('No files in $dir match pattern $name.');
}
if (matches.length == 1) return validate(matches[0]);
@@ -865,16 +871,20 @@
/// tree before running a test, and for validating that the file system matches
/// some expectations after running it.
class FileDescriptor extends Descriptor {
- /// The text contents of the file.
- final String contents;
+ /// The contents of the file, in bytes.
+ final List<int> contents;
- FileDescriptor(Pattern name, this.contents) : super(name);
+ String get textContents => new String.fromCharCodes(contents);
+
+ FileDescriptor.bytes(Pattern name, this.contents) : super(name);
+
+ FileDescriptor(Pattern name, String contents) :
+ this.bytes(name, encodeUtf8(contents));
/// Creates the file within [dir]. Returns a [Future] that is completed after
/// the creation is done.
- Future<File> create(dir) {
- return writeTextFile(join(dir, _stringName), contents);
- }
+ Future<File> create(dir) => new Future.immediate(null).then((_) =>
+ writeBinaryFile(join(dir, _stringName), contents));
/// Deletes the file within [dir]. Returns a [Future] that is completed after
/// the deletion is done.
@@ -886,10 +896,11 @@
Future validate(String path) {
return _validateOneMatch(path, (file) {
return readTextFile(file).then((text) {
- if (text == contents) return null;
+ if (text == textContents) return null;
- Expect.fail('File $file should contain:\n\n$contents\n\n'
- 'but contained:\n\n$text');
+ throw new ExpectException(
+ 'File $file should contain:\n\n$textContents\n\n'
+ 'but contained:\n\n$text');
});
});
}
@@ -902,7 +913,7 @@
}
var stream = new ListInputStream();
- stream.write(contents.charCodes);
+ stream.write(contents);
stream.markEndOfStream();
return stream;
}
@@ -928,7 +939,7 @@
// Recursively create all of its children.
final childFutures =
- contents.mappedBy((child) => child.create(dir)).toList();
+ contents.map((child) => child.create(dir)).toList();
// Only complete once all of the children have been created too.
return Future.wait(childFutures).then((_) => dir);
});
@@ -948,7 +959,7 @@
return _validateOneMatch(path, (dir) {
// Validate each of the items in this directory.
final entryFutures =
- contents.mappedBy((entry) => entry.validate(dir)).toList();
+ contents.map((entry) => entry.validate(dir)).toList();
// If they are all valid, the directory is valid.
return Future.wait(entryFutures).then((entries) => null);
@@ -1080,7 +1091,7 @@
var tempDir;
return createTempDir().then((_tempDir) {
tempDir = _tempDir;
- return Future.wait(contents.mappedBy((child) => child.create(tempDir)));
+ return Future.wait(contents.map((child) => child.create(tempDir)));
}).then((createdContents) {
return consumeInputStream(createTarGz(createdContents, baseDir: tempDir));
}).then((bytes) {
@@ -1133,7 +1144,9 @@
Future validate(String dir) {
return exists(join(dir, name)).then((exists) {
- if (exists) Expect.fail('File $name in $dir should not exist.');
+ if (exists) {
+ throw new ExpectException('File $name in $dir should not exist.');
+ }
});
}
@@ -1489,7 +1502,7 @@
// Unroll nested futures.
if (object is Future) return object.then(_awaitObject);
if (object is Collection) {
- return Future.wait(object.mappedBy(_awaitObject).toList());
+ return Future.wait(object.map(_awaitObject).toList());
}
if (object is! Map) return new Future.immediate(object);
diff --git a/utils/tests/pub/validator_test.dart b/utils/tests/pub/validator_test.dart
index 75b51ff..b9eb6b7 100644
--- a/utils/tests/pub/validator_test.dart
+++ b/utils/tests/pub/validator_test.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'dart:io';
import 'dart:json' as json;
+import 'dart:math' as math;
import 'test_pub.dart';
import '../../../pkg/unittest/lib/unittest.dart';
@@ -15,12 +16,15 @@
import '../../pub/entrypoint.dart';
import '../../pub/io.dart';
import '../../pub/validator.dart';
+import '../../pub/validator/compiled_dartdoc.dart';
import '../../pub/validator/dependency.dart';
import '../../pub/validator/directory.dart';
import '../../pub/validator/lib.dart';
import '../../pub/validator/license.dart';
import '../../pub/validator/name.dart';
import '../../pub/validator/pubspec_field.dart';
+import '../../pub/validator/size.dart';
+import '../../pub/validator/utf8_readme.dart';
void expectNoValidationError(ValidatorCreator fn) {
expectLater(schedulePackageValidation(fn), pairOf(isEmpty, isEmpty));
@@ -34,6 +38,9 @@
expectLater(schedulePackageValidation(fn), pairOf(isEmpty, isNot(isEmpty)));
}
+Validator compiledDartdoc(Entrypoint entrypoint) =>
+ new CompiledDartdocValidator(entrypoint);
+
Validator dependency(Entrypoint entrypoint) =>
new DependencyValidator(entrypoint);
@@ -49,6 +56,14 @@
Validator pubspecField(Entrypoint entrypoint) =>
new PubspecFieldValidator(entrypoint);
+Function size(int size) {
+ return (entrypoint) =>
+ new SizeValidator(entrypoint, new Future.immediate(size));
+}
+
+Validator utf8Readme(Entrypoint entrypoint) =>
+ new Utf8ReadmeValidator(entrypoint);
+
void scheduleNormalPackage() => normalPackage.scheduleCreate();
main() {
@@ -125,6 +140,31 @@
]).scheduleCreate();
expectNoValidationError(directory);
});
+
+ integration('is <= 10 MB', () {
+ expectNoValidationError(size(100));
+ expectNoValidationError(size(10 * math.pow(2, 20)));
+ });
+
+ integration('has most but not all files from compiling dartdoc', () {
+ dir(appPath, [
+ dir("doc-out", [
+ file("nav.json", ""),
+ file("index.html", ""),
+ file("styles.css", ""),
+ file("dart-logo-small.png", "")
+ ])
+ ]).scheduleCreate();
+ expectNoValidationError(compiledDartdoc);
+ });
+
+ integration('has a non-primary readme with invalid utf-8', () {
+ dir(appPath, [
+ file("README", "Valid utf-8"),
+ binaryFile("README.invalid", [192])
+ ]).scheduleCreate();
+ expectNoValidationError(utf8Readme);
+ });
});
group('should consider a package invalid if it', () {
@@ -520,5 +560,30 @@
});
}
});
+
+ integration('is more than 10 MB', () {
+ expectValidationError(size(10 * math.pow(2, 20) + 1));
+ });
+
+ test('contains compiled dartdoc', () {
+ dir(appPath, [
+ dir('doc-out', [
+ file('nav.json', ''),
+ file('index.html', ''),
+ file('styles.css', ''),
+ file('dart-logo-small.png', ''),
+ file('client-live-nav.js', '')
+ ])
+ ]).scheduleCreate();
+
+ expectValidationWarning(compiledDartdoc);
+ });
+
+ test('has a README with invalid utf-8', () {
+ dir(appPath, [
+ binaryFile("README", [192])
+ ]).scheduleCreate();
+ expectValidationWarning(utf8Readme);
+ });
});
}