mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
[dartdevc] Resetting lazy js types on hot restart
Fixes https://github.com/flutter/flutter/issues/66361 Change-Id: I4e68963a36c71bb4dac964d8b0fdcd8ee9187e97 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164101 Reviewed-by: Nicholas Shahan <nshahan@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Mark Zhou <markzipan@google.com>
This commit is contained in:
parent
712b9254be
commit
33044ddd9a
3 changed files with 56 additions and 5 deletions
|
@ -179,8 +179,8 @@ final List<Object> _cacheMaps = JS('!', '[]');
|
|||
/// A list of functions to reset static fields back to their uninitialized
|
||||
/// state.
|
||||
///
|
||||
/// This is populated by [defineLazyField], and only contains the list of fields
|
||||
/// that have actually been initialized.
|
||||
/// This is populated by [defineLazyField] and [LazyJSType] and only contains
|
||||
/// fields that have been initialized.
|
||||
@notNull
|
||||
final List<void Function()> _resetFields = JS('', '[]');
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ F tearoffInterop<F extends Function?>(F f) {
|
|||
/// we disable type checks for in these cases, and allow any JS object to work
|
||||
/// as if it were an instance of this JS type.
|
||||
class LazyJSType extends DartType {
|
||||
Function()? _getRawJSTypeFn;
|
||||
Function() _getRawJSTypeFn;
|
||||
@notNull
|
||||
final String _dartName;
|
||||
Object? _rawJSType;
|
||||
|
@ -199,14 +199,14 @@ class LazyJSType extends DartType {
|
|||
// overhead, especially if exceptions are being thrown. Also it means the
|
||||
// behavior of a given type check can change later on.
|
||||
try {
|
||||
raw = _getRawJSTypeFn!();
|
||||
raw = _getRawJSTypeFn();
|
||||
} catch (e) {}
|
||||
|
||||
if (raw == null) {
|
||||
_warn('Cannot find native JavaScript type ($_dartName) for type check');
|
||||
} else {
|
||||
_rawJSType = raw;
|
||||
_getRawJSTypeFn = null; // Free the function that computes the JS type.
|
||||
JS('', '#.push(() => # = null)', _resetFields, _rawJSType);
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
|
51
tests/dartdevc/hot_restart_js_interop_test.dart
Normal file
51
tests/dartdevc/hot_restart_js_interop_test.dart
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests that JS interop works with hot restart.
|
||||
|
||||
// Requirements=nnbd
|
||||
|
||||
@JS()
|
||||
library hot_restart_js_interop_test;
|
||||
|
||||
import 'dart:js' show context;
|
||||
import 'dart:js_util';
|
||||
import 'dart:_foreign_helper' as helper show JS;
|
||||
import 'dart:_runtime' as dart;
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
||||
@JS('window.MyClass')
|
||||
class MyClass {
|
||||
external MyClass();
|
||||
}
|
||||
|
||||
abstract class Wrapper<T> {
|
||||
T? rawObject;
|
||||
|
||||
Wrapper() {
|
||||
final T defaultObject = createDefault();
|
||||
rawObject = defaultObject;
|
||||
}
|
||||
|
||||
T createDefault();
|
||||
}
|
||||
|
||||
class WrappedClass extends Wrapper<MyClass> {
|
||||
@override
|
||||
MyClass createDefault() => MyClass();
|
||||
}
|
||||
|
||||
void main() {
|
||||
// See: https://github.com/flutter/flutter/issues/66361
|
||||
eval("self.MyClass = function MyClass() {}");
|
||||
var c = WrappedClass();
|
||||
dart.hotRestart();
|
||||
eval("self.MyClass = function MyClass() {}");
|
||||
c = WrappedClass();
|
||||
}
|
Loading…
Reference in a new issue