Version 2.12.0-140.0.dev
Merge commit '8e663541c9a25f491be015c684c170dbe57f3276' into 'dev'
diff --git a/DEPS b/DEPS
index 80e12ef..4c67d48 100644
--- a/DEPS
+++ b/DEPS
@@ -81,7 +81,7 @@
"cli_util_rev" : "50cc840b146615899e97b892578848401b2028d5",
"clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3",
"collection_rev": "e4bb038ce2d8e66fb15818aa40685c68d53692ab",
- "convert_rev": "dd3bd28f63be7cb8ab961f38bc73229e4473b555",
+ "convert_rev": "6513985a1b1ea8a0b987fbef699250ce2cdc3cca",
"crypto_rev": "a5ec902dda5a635a35c6b363ec64458cf84c5872",
"csslib_rev": "6f77b3dcee957d3e2d5083f666221a220e9ed1f1",
"dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 2357561..f782575 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -828,7 +828,7 @@
/// The lazy initialized map from [ErrorCode.uniqueName] to the [ErrorCode]
/// instance.
-HashMap<String, ErrorCode> _uniqueNameToCodeMap;
+/*late final*/ HashMap<String, ErrorCode> _uniqueNameToCodeMap;
/// Return the [ErrorCode] with the given [uniqueName], or `null` if not
/// found.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 0b09d2e..1d90610 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -14,7 +14,7 @@
/// An analysis context whose implementation is based on an analysis driver.
class DriverBasedAnalysisContext implements AnalysisContext {
/// The resource provider used to access the file system.
- final ResourceProvider resourceProvider;
+ final ResourceProvider /*!*/ resourceProvider;
@override
final ContextRoot contextRoot;
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 0ab40ba..8806048 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -116,12 +116,12 @@
}
@override
- ClassElement get boolElement {
+ ClassElement /*!*/ get boolElement {
return _boolElement ??= _getClassElement(_coreLibrary, 'bool');
}
@override
- InterfaceType get boolType {
+ InterfaceType /*!*/ get boolType {
_boolType ??= _getType(_coreLibrary, "bool");
return _boolType;
}
@@ -135,37 +135,37 @@
}
@override
- InterfaceType get deprecatedType {
+ InterfaceType /*!*/ get deprecatedType {
_deprecatedType ??= _getType(_coreLibrary, "Deprecated");
return _deprecatedType;
}
@override
- ClassElement get doubleElement {
+ ClassElement /*!*/ get doubleElement {
return _doubleElement ??= _getClassElement(_coreLibrary, "double");
}
@override
- InterfaceType get doubleType {
+ InterfaceType /*!*/ get doubleType {
_doubleType ??= _getType(_coreLibrary, "double");
return _doubleType;
}
- InterfaceType get doubleTypeQuestion =>
+ InterfaceType /*!*/ get doubleTypeQuestion =>
_doubleTypeQuestion ??= (doubleType as InterfaceTypeImpl)
.withNullability(NullabilitySuffix.question);
@override
- DartType get dynamicType => DynamicTypeImpl.instance;
+ DartType /*!*/ get dynamicType => DynamicTypeImpl.instance;
@override
- InterfaceType get functionType {
+ InterfaceType /*!*/ get functionType {
_functionType ??= _getType(_coreLibrary, "Function");
return _functionType;
}
@override
- InterfaceType get futureDynamicType {
+ InterfaceType /*!*/ get futureDynamicType {
_futureDynamicType ??= InterfaceTypeImpl(
element: futureElement,
typeArguments: [dynamicType],
@@ -175,12 +175,12 @@
}
@override
- ClassElement get futureElement {
+ ClassElement /*!*/ get futureElement {
return _futureElement ??= _getClassElement(_asyncLibrary, 'Future');
}
@override
- InterfaceType get futureNullType {
+ InterfaceType /*!*/ get futureNullType {
_futureNullType ??= InterfaceTypeImpl(
element: futureElement,
typeArguments: [nullType],
@@ -190,12 +190,12 @@
}
@override
- ClassElement get futureOrElement {
+ ClassElement /*!*/ get futureOrElement {
return _futureOrElement ??= _getClassElement(_asyncLibrary, 'FutureOr');
}
@override
- InterfaceType get futureOrNullType {
+ InterfaceType /*!*/ get futureOrNullType {
_futureOrNullType ??= InterfaceTypeImpl(
element: futureOrElement,
typeArguments: [nullType],
@@ -205,22 +205,22 @@
}
@override
- ClassElement get intElement {
+ ClassElement /*!*/ get intElement {
return _intElement ??= _getClassElement(_coreLibrary, "int");
}
@override
- InterfaceType get intType {
+ InterfaceType /*!*/ get intType {
_intType ??= _getType(_coreLibrary, "int");
return _intType;
}
- InterfaceType get intTypeQuestion =>
+ InterfaceType /*!*/ get intTypeQuestion =>
_intTypeQuestion ??= (intType as InterfaceTypeImpl)
.withNullability(NullabilitySuffix.question);
@override
- InterfaceType get iterableDynamicType {
+ InterfaceType /*!*/ get iterableDynamicType {
_iterableDynamicType ??= InterfaceTypeImpl(
element: iterableElement,
typeArguments: [dynamicType],
@@ -230,12 +230,12 @@
}
@override
- ClassElement get iterableElement {
+ ClassElement /*!*/ get iterableElement {
return _iterableElement ??= _getClassElement(_coreLibrary, 'Iterable');
}
@override
- InterfaceType get iterableObjectType {
+ InterfaceType /*!*/ get iterableObjectType {
_iterableObjectType ??= InterfaceTypeImpl(
element: iterableElement,
typeArguments: [objectType],
@@ -245,17 +245,17 @@
}
@override
- ClassElement get listElement {
+ ClassElement /*!*/ get listElement {
return _listElement ??= _getClassElement(_coreLibrary, 'List');
}
@override
- ClassElement get mapElement {
+ ClassElement /*!*/ get mapElement {
return _mapElement ??= _getClassElement(_coreLibrary, 'Map');
}
@override
- InterfaceType get mapObjectObjectType {
+ InterfaceType /*!*/ get mapObjectObjectType {
_mapObjectObjectType ??= InterfaceTypeImpl(
element: mapElement,
typeArguments: [objectType, objectType],
@@ -265,12 +265,13 @@
}
@override
- DartType get neverType => isNonNullableByDefault
+ DartType /*!*/ get neverType => isNonNullableByDefault
? NeverTypeImpl.instance
: NeverTypeImpl.instanceLegacy;
@override
- Set<ClassElement> get nonSubtypableClasses => _nonSubtypableClasses ??= {
+ Set<ClassElement> /*!*/ get nonSubtypableClasses =>
+ _nonSubtypableClasses ??= {
boolElement,
doubleElement,
futureOrElement,
@@ -281,11 +282,11 @@
};
@override
- ClassElement get nullElement {
+ ClassElement /*!*/ get nullElement {
return _nullElement ??= _getClassElement(_coreLibrary, 'Null');
}
- InterfaceTypeImpl get nullStar {
+ InterfaceTypeImpl /*!*/ get nullStar {
return _nullStar ??= nullElement.instantiate(
typeArguments: const [],
nullabilitySuffix: NullabilitySuffix.star,
@@ -293,49 +294,49 @@
}
@override
- InterfaceType get nullType {
+ InterfaceType /*!*/ get nullType {
_nullType ??= _getType(_coreLibrary, "Null");
return _nullType;
}
@override
- ClassElement get numElement {
+ ClassElement /*!*/ get numElement {
return _numElement ??= _getClassElement(_coreLibrary, 'num');
}
@override
- InterfaceType get numType {
+ InterfaceType /*!*/ get numType {
_numType ??= _getType(_coreLibrary, "num");
return _numType;
}
- InterfaceType get numTypeQuestion =>
+ InterfaceType /*!*/ get numTypeQuestion =>
_numTypeQuestion ??= (numType as InterfaceTypeImpl)
.withNullability(NullabilitySuffix.question);
- ClassElement get objectElement {
+ ClassElement /*!*/ get objectElement {
return _objectElement ??= _getClassElement(_coreLibrary, 'Object');
}
@override
- InterfaceType get objectType {
+ InterfaceType /*!*/ get objectType {
_objectType ??= _getType(_coreLibrary, "Object");
return _objectType;
}
@override
- ClassElement get setElement {
+ ClassElement /*!*/ get setElement {
return _setElement ??= _getClassElement(_coreLibrary, 'Set');
}
@override
- InterfaceType get stackTraceType {
+ InterfaceType /*!*/ get stackTraceType {
_stackTraceType ??= _getType(_coreLibrary, "StackTrace");
return _stackTraceType;
}
@override
- InterfaceType get streamDynamicType {
+ InterfaceType /*!*/ get streamDynamicType {
_streamDynamicType ??= InterfaceTypeImpl(
element: streamElement,
typeArguments: [dynamicType],
@@ -345,34 +346,34 @@
}
@override
- ClassElement get streamElement {
+ ClassElement /*!*/ get streamElement {
return _streamElement ??= _getClassElement(_asyncLibrary, 'Stream');
}
@override
- ClassElement get stringElement {
+ ClassElement /*!*/ get stringElement {
return _stringElement ??= _getClassElement(_coreLibrary, 'String');
}
@override
- InterfaceType get stringType {
+ InterfaceType /*!*/ get stringType {
_stringType ??= _getType(_coreLibrary, "String");
return _stringType;
}
@override
- ClassElement get symbolElement {
+ ClassElement /*!*/ get symbolElement {
return _symbolElement ??= _getClassElement(_coreLibrary, 'Symbol');
}
@override
- InterfaceType get symbolType {
+ InterfaceType /*!*/ get symbolType {
_symbolType ??= _getType(_coreLibrary, "Symbol");
return _symbolType;
}
@override
- InterfaceType get typeType {
+ InterfaceType /*!*/ get typeType {
_typeType ??= _getType(_coreLibrary, "Type");
return _typeType;
}
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 0a0d0fa..8b55ebf 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -29,7 +29,7 @@
/// library map.
abstract class AbstractDartSdk implements DartSdk {
/// The resource provider used to access the file system.
- ResourceProvider resourceProvider;
+ /*late final*/ ResourceProvider resourceProvider;
/// A mapping from Dart library URI's to the library represented by that URI.
LibraryMap libraryMap = LibraryMap();
@@ -130,7 +130,7 @@
}
@override
- Source mapDartUri(String dartUri) {
+ Source mapDartUri(String /*!*/ dartUri) {
Source source = _uriToSourceMap[dartUri];
if (source == null) {
source = internalMapDartUri(dartUri);
@@ -288,9 +288,9 @@
///
/// If a key doesn't begin with `dart:` it is ignored.
void _processEmbedderYaml(Folder libDir, YamlMap map) {
- YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
- if (embedded_libs is YamlMap) {
- embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
+ YamlNode embeddedLibs = map[_EMBEDDED_LIB_MAP_KEY];
+ if (embeddedLibs is YamlMap) {
+ embeddedLibs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
}
}
}
@@ -351,17 +351,17 @@
final Folder _sdkDirectory;
/// The directory within the SDK directory that contains the libraries.
- Folder _libraryDirectory;
+ /*late final*/ Folder _libraryDirectory;
/// The revision number of this SDK, or `"0"` if the revision number cannot be
/// discovered.
- String _sdkVersion;
+ /*late final*/ String _sdkVersion;
/// The cached language version of this SDK.
- Version _languageVersion;
+ /*late final*/ Version _languageVersion;
/// The file containing the pub executable.
- File _pubExecutable;
+ /*late final*/ File _pubExecutable;
/// Initialize a newly created SDK to represent the Dart SDK installed in the
/// [sdkDirectory].
@@ -473,8 +473,8 @@
/// Return the initialized library map.
LibraryMap initialLibraryMap() {
List<String> searchedPaths = <String>[];
- StackTrace lastStackTrace;
- Object lastException;
+ /*late*/ StackTrace lastStackTrace;
+ /*late*/ Object lastException;
for (File librariesFile in _libraryMapLocations) {
try {
String contents = librariesFile.readAsStringSync();
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 0e9ad99..729e32c 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -210,8 +210,8 @@
}
void createTypeProviders(
- LibraryElementImpl dartCore,
- LibraryElementImpl dartAsync,
+ LibraryElementImpl /*!*/ dartCore,
+ LibraryElementImpl /*!*/ dartAsync,
) {
if (analysisContext.typeProviderNonNullableByDefault != null) {
return;
diff --git a/pkg/analyzer/test/embedder_tests.dart b/pkg/analyzer/test/embedder_tests.dart
index c59eb00..ac01db8 100644
--- a/pkg/analyzer/test/embedder_tests.dart
+++ b/pkg/analyzer/test/embedder_tests.dart
@@ -14,8 +14,8 @@
final String foxPath = '/home/.pub-cache/fox';
final String foxLib = '/home/.pub-cache/fox/lib';
- TestPathTranslator pathTranslator;
- ResourceProvider resourceProvider;
+ /*late*/ TestPathTranslator pathTranslator;
+ /*late*/ ResourceProvider resourceProvider;
buildResourceProvider() {
MemoryResourceProvider rawProvider = MemoryResourceProvider();
@@ -34,16 +34,7 @@
''');
}
- clearResourceProvider() {
- resourceProvider = null;
- pathTranslator = null;
- }
-
void setUp() {
buildResourceProvider();
}
-
- void tearDown() {
- clearResourceProvider();
- }
}
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index b5a67dd..148b6cd 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -2140,6 +2140,10 @@
} else if (node is ir.Constructor) {
parts.add(utils.reconstructConstructorName(getMember(node)));
break;
+ } else if (node is ir.Field) {
+ // Add the field name for closures in field initializers.
+ String name = node.name?.name;
+ if (name != null) parts.add(name);
}
current = current.parent;
}
diff --git a/pkg/js/README.md b/pkg/js/README.md
index e5563a1..7279082 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -201,3 +201,10 @@
**Workaround:** Avoid importing `dart:js` and only use the `package:js` provided
approach. To handle object literals use `@anonymous` on an `@JS()` annotated
class.
+
+#### `is` checks and `as` casts between JS interop types will always succeed
+
+For any two `@JS()` types, with or without `@anonymous`, a check of whether an
+object of one type `is` another type will always return true, regardless of
+whether those two types are in the same prototype chain. Similarly, an explicit
+cast using `as` will also succeed.
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index 6ca0990..c07969e 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -133,6 +133,7 @@
@visibleForTesting
static String optCodeOutOfNullSafety(String code) {
+ var newline = '\n';
var length = code.length;
if (length == 0) {
@@ -156,12 +157,19 @@
// Skip past blank lines.
var line = getLine();
+ if (code.codeUnitAt(index - 1) == $lf) {
+ if (index - 2 >= 0 && code.codeUnitAt(index - 2) == $cr) {
+ // Looks like Windows-style line endings ("\r\n"). Use "\r\n" for all
+ // inserted line endings.
+ newline = '\r\n';
+ }
+ }
var lineStart = line.indexOf(_nonWhitespaceChar);
while (lineStart < 0) {
line = getLine();
if (index == length) {
// [code] consists _only_ of blank lines.
- return '// @dart=2.9\n\n$code';
+ return '// @dart=2.9$newline$newline$code';
}
lineStart = line.indexOf(_nonWhitespaceChar);
}
@@ -173,7 +181,7 @@
// Comment.
if (index == length) {
// [code] consists _only_ of one comment line.
- return '$code\n\n// @dart=2.9\n';
+ return '$code$newline$newline// @dart=2.9$newline';
}
line = getLine();
lineStart = line.indexOf(_nonWhitespaceChar);
@@ -185,17 +193,17 @@
line = getLine();
if (index == length) {
// [code] consists _only_ of this block comment.
- return '$code\n\n// @dart=2.9\n';
+ return '$code$newline$newline// @dart=2.9$newline';
}
lineStart = line.indexOf(_nonWhitespaceChar);
}
// [index] points to the start of [line], which is the first
// non-comment line following the first comment.
- return '${code.substring(0, index)}\n// @dart=2.9\n\n'
+ return '${code.substring(0, index)}$newline// @dart=2.9$newline$newline'
'${code.substring(index)}';
} else {
// [code] does not start with a block comment.
- return '// @dart=2.9\n\n$code';
+ return '// @dart=2.9$newline$newline$code';
}
}
}
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 6cb416a..c725f02 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -145,12 +145,24 @@
equals('// @dart=2.9\n\n \n \n'));
}
+ void test_optOutOfNullSafety_blankLines_windows() {
+ expect(IncrementalPlan.optCodeOutOfNullSafety(' \r\n \r\n'),
+ equals('// @dart=2.9\r\n\r\n \r\n \r\n'));
+ }
+
void test_optOutOfNullSafety_commentThenCode() {
expect(
IncrementalPlan.optCodeOutOfNullSafety('// comment\n\nvoid main() {}'),
equals('// comment\n\n\n// @dart=2.9\n\nvoid main() {}'));
}
+ void test_optOutOfNullSafety_commentThenCode_windows() {
+ expect(
+ IncrementalPlan.optCodeOutOfNullSafety(
+ '// comment\r\n\r\nvoid main() {}'),
+ equals('// comment\r\n\r\n\r\n// @dart=2.9\r\n\r\nvoid main() {}'));
+ }
+
void test_optOutOfNullSafety_empty() {
expect(IncrementalPlan.optCodeOutOfNullSafety(''), equals('// @dart=2.9'));
}
@@ -185,6 +197,11 @@
equals('// @dart=2.9\n\n\n\nvoid main() {}'));
}
+ void test_optOutOfNullSafety_singleLine_windows() {
+ expect(IncrementalPlan.optCodeOutOfNullSafety('void main() {}\r\n'),
+ equals('// @dart=2.9\r\n\r\nvoid main() {}\r\n'));
+ }
+
void test_performEdit() {
final path = convertPath('/test.dart');
final file = getFile(path);
@@ -373,39 +390,6 @@
expect(getFile(path).readAsStringSync(), '// @dart=2.9');
}
- void test_applyMigration_optOutOne_migrateAnother() async {
- final pathA = convertPath('$projectPath/lib/a.dart');
- final pathB = convertPath('$projectPath/lib/b.dart');
- final content = 'void main() {}';
- await setUpMigrationInfo({pathA: content, pathB: content});
- site.unitInfoMap[pathA] = UnitInfo(pathA)
- ..diskContent = content
- ..wasExplicitlyOptedOut = false;
- site.unitInfoMap[pathB] = UnitInfo(pathB)
- ..diskContent = content
- ..wasExplicitlyOptedOut = false;
- dartfixListener.addSourceFileEdit(
- 'test change',
- Location(pathA, 10, 0, 1, 10),
- SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
- dartfixListener.addSourceFileEdit(
- 'test change',
- Location(pathB, 10, 0, 1, 10),
- SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
- var navigationTree =
- NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
- var libDir = navigationTree.single as NavigationTreeDirectoryNode;
- (libDir.subtree[0] as NavigationTreeFileNode).migrationStatus =
- UnitMigrationStatus.optingOut;
- site.performApply(navigationTree);
- expect(getFile(pathA).readAsStringSync(), '''
-// @dart=2.9
-
-void main() {}''');
- expect(getFile(pathB).readAsStringSync(), '''
-void main(List args) {}''');
- }
-
void test_applyMigration_optOutFileWithEdits() async {
final path = convertPath('$projectPath/lib/a.dart');
final content = 'void main() {}';
@@ -448,6 +432,39 @@
void main() {}''');
}
+ void test_applyMigration_optOutOne_migrateAnother() async {
+ final pathA = convertPath('$projectPath/lib/a.dart');
+ final pathB = convertPath('$projectPath/lib/b.dart');
+ final content = 'void main() {}';
+ await setUpMigrationInfo({pathA: content, pathB: content});
+ site.unitInfoMap[pathA] = UnitInfo(pathA)
+ ..diskContent = content
+ ..wasExplicitlyOptedOut = false;
+ site.unitInfoMap[pathB] = UnitInfo(pathB)
+ ..diskContent = content
+ ..wasExplicitlyOptedOut = false;
+ dartfixListener.addSourceFileEdit(
+ 'test change',
+ Location(pathA, 10, 0, 1, 10),
+ SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
+ dartfixListener.addSourceFileEdit(
+ 'test change',
+ Location(pathB, 10, 0, 1, 10),
+ SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
+ var navigationTree =
+ NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
+ var libDir = navigationTree.single as NavigationTreeDirectoryNode;
+ (libDir.subtree[0] as NavigationTreeFileNode).migrationStatus =
+ UnitMigrationStatus.optingOut;
+ site.performApply(navigationTree);
+ expect(getFile(pathA).readAsStringSync(), '''
+// @dart=2.9
+
+void main() {}''');
+ expect(getFile(pathB).readAsStringSync(), '''
+void main(List args) {}''');
+ }
+
void test_applyMigration_optOutPreviouslyOptedOutFile() async {
final path = convertPath('$projectPath/lib/a.dart');
final content = '''
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index f0fa4f0..7fa6bbe 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -240,18 +240,13 @@
Object rawJSTypeForCheck() => _getRawJSType() ?? jsobject;
@notNull
- bool isRawJSType(obj) {
- var raw = _getRawJSType();
- if (raw != null) return JS('!', '# instanceof #', obj, raw);
- return _isJsObject(obj);
- }
-
- @notNull
@JSExportName('is')
- bool is_T(obj) => isRawJSType(obj) || instanceOf(obj, this);
+ bool is_T(obj) =>
+ obj != null &&
+ (_isJsObject(obj) || isSubtypeOf(getReifiedType(obj), this));
@JSExportName('as')
- as_T(obj) => obj == null || is_T(obj) ? obj : castError(obj, this);
+ as_T(obj) => is_T(obj) ? obj : castError(obj, this);
}
/// An anonymous JS type
@@ -263,10 +258,12 @@
toString() => _dartName;
@JSExportName('is')
- bool is_T(obj) => _isJsObject(obj) || instanceOf(obj, this);
+ bool is_T(obj) =>
+ obj != null &&
+ (_isJsObject(obj) || isSubtypeOf(getReifiedType(obj), this));
@JSExportName('as')
- as_T(obj) => obj == null || _isJsObject(obj) ? obj : cast(obj, this);
+ as_T(obj) => is_T(obj) ? obj : castError(obj, this);
}
void _warn(arg) {
diff --git a/tests/lib/html/js_mock_test.dart b/tests/lib/html/js_mock_test.dart
deleted file mode 100644
index 310abc9..0000000
--- a/tests/lib/html/js_mock_test.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@JS()
-library mock;
-
-import 'package:js/js.dart';
-import 'package:expect/minitest.dart';
-
-@JS('Node')
-class Node {}
-
-@JS('HTMLDocument')
-class Document extends Node {
- external Element get body;
-}
-
-@JS()
-external get foo;
-
-@JS()
-external Document get document;
-
-@JS('Element')
-class Element extends Node {
- external String get tagName;
-}
-
-class MockDocument implements Document {
- final Element body = new MockElement();
-}
-
-class MockElement implements Element {
- final tagName = 'MockBody';
-}
-
-void main() {
- test('js', () {
- var f = foo;
- expect(f, isNull);
-
- var doc = document;
- expect(doc is Document, isTrue);
- // Fails in dart2js
- //expect(doc is! Element, isTrue);
-
- expect(doc is Node, isTrue);
-
- expect(doc is! MockDocument, isTrue);
- expect(doc is! MockElement, isTrue);
- });
-
- test('mock', () {
- var doc = new MockDocument();
- expect(doc is Document, isTrue);
- // Fails in dart2js
- // expect(doc is! Element, isTrue);
- expect(doc is Node, isTrue);
-
- var body = doc.body;
- // Fails in dart2js
- // expect(body is! Document, isTrue);
- expect(body is Element, isTrue);
- expect(body is Node, isTrue);
- });
-}
diff --git a/tests/lib/html/js_typed_interop_lazy_test.dart b/tests/lib/html/js_typed_interop_lazy_test.dart
index 98b26ff..63c578d 100644
--- a/tests/lib/html/js_typed_interop_lazy_test.dart
+++ b/tests/lib/html/js_typed_interop_lazy_test.dart
@@ -133,7 +133,6 @@
expect(l is AnonClass, isTrue);
expect((l as AnonClass) == l, isTrue);
expect((l as AnonClass2) == l, isTrue);
- expect(anon is! LazyClass, isTrue); //# 01: ok
expect(anon is AnonClass, isTrue);
expect(anon is AnonClass2, isTrue);
@@ -226,7 +225,6 @@
expect(l is AnonClass, isTrue);
expect((l as AnonClass) == l, isTrue);
expect((l as AnonClass2) == l, isTrue);
- expect(anon is! NestedLazyClass, isTrue); //# 01: ok
expect(anon is AnonClass, isTrue);
expect(anon is AnonClass2, isTrue);
diff --git a/tests/lib/js/is_check_and_as_cast_test.dart b/tests/lib/js/is_check_and_as_cast_test.dart
index d88255c..b84e625 100644
--- a/tests/lib/js/is_check_and_as_cast_test.dart
+++ b/tests/lib/js/is_check_and_as_cast_test.dart
@@ -136,12 +136,21 @@
expect(() => (a as DartClass), throws);
// Test that nullability is still respected with JS types.
+ expect(foo is Foo?, isTrue);
+ expect(() => (foo as Foo?), returnsNormally);
Foo? nullableFoo = null;
- expect(nullableFoo is Foo, false);
+ expect(nullableFoo is Foo?, isTrue);
+ expect(() => (nullableFoo as Foo?), returnsNormally);
+ expect(nullableFoo is Foo, isFalse);
expect(() => (nullableFoo as Foo),
hasUnsoundNullSafety ? returnsNormally : throws);
+
+ expect(a is LiteralA?, isTrue);
+ expect(() => (a as LiteralA?), returnsNormally);
LiteralA? nullableA = null;
- expect(nullableA is LiteralA, false);
+ expect(nullableA is LiteralA?, isTrue);
+ expect(() => (nullableA as LiteralA?), returnsNormally);
+ expect(nullableA is LiteralA, isFalse);
expect(() => (nullableA as LiteralA),
hasUnsoundNullSafety ? returnsNormally : throws);
}
diff --git a/tests/lib/js/mock_test.dart b/tests/lib/js/mock_test.dart
new file mode 100644
index 0000000..a33ac5e
--- /dev/null
+++ b/tests/lib/js/mock_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library mock_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String code);
+
+@JS()
+class JSClass {}
+
+@JS()
+class DerivedA extends JSClass {
+ external DerivedB get derivedB;
+}
+
+@JS()
+external DerivedA get derivedA;
+
+@JS()
+class DerivedB extends JSClass {}
+
+class MockDerivedA implements DerivedA {
+ final DerivedB derivedB = new MockDerivedB();
+}
+
+class MockDerivedB implements DerivedB {}
+
+void main() {
+ eval(r"""
+ function inherits(child, parent) {
+ if (child.prototype.__proto__) {
+ child.prototype.__proto__ = parent.prototype;
+ } else {
+ function tmp() {};
+ tmp.prototype = parent.prototype;
+ child.prototype = new tmp();
+ child.prototype.constructor = child;
+ }
+ }
+ function JSClass() {
+ }
+ function DerivedA() {
+ JSClass.call(this);
+ this.derivedB = new DerivedB();
+ }
+ inherits(DerivedA, JSClass);
+ function DerivedB() {
+ JSClass.call(this);
+ }
+ inherits(DerivedB, JSClass);
+ var derivedA = new DerivedA();
+ """);
+ test('js', () {
+ var jsA = derivedA;
+ // `is` checks will return true for any two JS interop types.
+ expect(jsA is JSClass, isTrue);
+ expect(jsA is DerivedA, isTrue);
+ expect(jsA is DerivedB, isTrue);
+
+ expect(jsA is! MockDerivedA, isTrue);
+ expect(jsA is! MockDerivedB, isTrue);
+ });
+
+ test('mock', () {
+ var mockA = new MockDerivedA();
+ expect(mockA is JSClass, isTrue); //# 44252: ok
+ expect(mockA is DerivedA, isTrue);
+ // Fails in dart2js
+ // expect(mockA is! DerivedB, isTrue);
+ expect(mockA is MockDerivedA, isTrue);
+ expect(mockA is! MockDerivedB, isTrue);
+
+ var mockB = mockA.derivedB;
+ expect(mockB is JSClass, isTrue); //# 44252: continued
+ // Fails in dart2js
+ // expect(mockB is! DerivedA, isTrue);
+ expect(mockB is DerivedB, isTrue);
+ expect(mockB is! MockDerivedA, isTrue);
+ expect(mockB is MockDerivedB, isTrue);
+ });
+}
diff --git a/tests/lib_2/html/js_mock_test.dart b/tests/lib_2/html/js_mock_test.dart
deleted file mode 100644
index 310abc9..0000000
--- a/tests/lib_2/html/js_mock_test.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@JS()
-library mock;
-
-import 'package:js/js.dart';
-import 'package:expect/minitest.dart';
-
-@JS('Node')
-class Node {}
-
-@JS('HTMLDocument')
-class Document extends Node {
- external Element get body;
-}
-
-@JS()
-external get foo;
-
-@JS()
-external Document get document;
-
-@JS('Element')
-class Element extends Node {
- external String get tagName;
-}
-
-class MockDocument implements Document {
- final Element body = new MockElement();
-}
-
-class MockElement implements Element {
- final tagName = 'MockBody';
-}
-
-void main() {
- test('js', () {
- var f = foo;
- expect(f, isNull);
-
- var doc = document;
- expect(doc is Document, isTrue);
- // Fails in dart2js
- //expect(doc is! Element, isTrue);
-
- expect(doc is Node, isTrue);
-
- expect(doc is! MockDocument, isTrue);
- expect(doc is! MockElement, isTrue);
- });
-
- test('mock', () {
- var doc = new MockDocument();
- expect(doc is Document, isTrue);
- // Fails in dart2js
- // expect(doc is! Element, isTrue);
- expect(doc is Node, isTrue);
-
- var body = doc.body;
- // Fails in dart2js
- // expect(body is! Document, isTrue);
- expect(body is Element, isTrue);
- expect(body is Node, isTrue);
- });
-}
diff --git a/tests/lib_2/html/js_typed_interop_lazy_test.dart b/tests/lib_2/html/js_typed_interop_lazy_test.dart
index 429e135..3fce5a0 100644
--- a/tests/lib_2/html/js_typed_interop_lazy_test.dart
+++ b/tests/lib_2/html/js_typed_interop_lazy_test.dart
@@ -133,7 +133,6 @@
expect(l is AnonClass, isTrue);
expect((l as AnonClass) == l, isTrue);
expect((l as AnonClass2) == l, isTrue);
- expect(anon is! LazyClass, isTrue); //# 01: ok
expect(anon is AnonClass, isTrue);
expect(anon is AnonClass2, isTrue);
@@ -226,7 +225,6 @@
expect(l is AnonClass, isTrue);
expect((l as AnonClass) == l, isTrue);
expect((l as AnonClass2) == l, isTrue);
- expect(anon is! NestedLazyClass, isTrue); //# 01: ok
expect(anon is AnonClass, isTrue);
expect(anon is AnonClass2, isTrue);
diff --git a/tests/lib_2/js/mock_test.dart b/tests/lib_2/js/mock_test.dart
new file mode 100644
index 0000000..a33ac5e
--- /dev/null
+++ b/tests/lib_2/js/mock_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library mock_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String code);
+
+@JS()
+class JSClass {}
+
+@JS()
+class DerivedA extends JSClass {
+ external DerivedB get derivedB;
+}
+
+@JS()
+external DerivedA get derivedA;
+
+@JS()
+class DerivedB extends JSClass {}
+
+class MockDerivedA implements DerivedA {
+ final DerivedB derivedB = new MockDerivedB();
+}
+
+class MockDerivedB implements DerivedB {}
+
+void main() {
+ eval(r"""
+ function inherits(child, parent) {
+ if (child.prototype.__proto__) {
+ child.prototype.__proto__ = parent.prototype;
+ } else {
+ function tmp() {};
+ tmp.prototype = parent.prototype;
+ child.prototype = new tmp();
+ child.prototype.constructor = child;
+ }
+ }
+ function JSClass() {
+ }
+ function DerivedA() {
+ JSClass.call(this);
+ this.derivedB = new DerivedB();
+ }
+ inherits(DerivedA, JSClass);
+ function DerivedB() {
+ JSClass.call(this);
+ }
+ inherits(DerivedB, JSClass);
+ var derivedA = new DerivedA();
+ """);
+ test('js', () {
+ var jsA = derivedA;
+ // `is` checks will return true for any two JS interop types.
+ expect(jsA is JSClass, isTrue);
+ expect(jsA is DerivedA, isTrue);
+ expect(jsA is DerivedB, isTrue);
+
+ expect(jsA is! MockDerivedA, isTrue);
+ expect(jsA is! MockDerivedB, isTrue);
+ });
+
+ test('mock', () {
+ var mockA = new MockDerivedA();
+ expect(mockA is JSClass, isTrue); //# 44252: ok
+ expect(mockA is DerivedA, isTrue);
+ // Fails in dart2js
+ // expect(mockA is! DerivedB, isTrue);
+ expect(mockA is MockDerivedA, isTrue);
+ expect(mockA is! MockDerivedB, isTrue);
+
+ var mockB = mockA.derivedB;
+ expect(mockB is JSClass, isTrue); //# 44252: continued
+ // Fails in dart2js
+ // expect(mockB is! DerivedA, isTrue);
+ expect(mockB is DerivedB, isTrue);
+ expect(mockB is! MockDerivedA, isTrue);
+ expect(mockB is MockDerivedB, isTrue);
+ });
+}
diff --git a/tools/VERSION b/tools/VERSION
index af89db5..7cff4c5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 139
+PRERELEASE 140
PRERELEASE_PATCH 0
\ No newline at end of file