[pkg:js] Add @staticInterop annotation to package:js
Adds @staticInterop annotation to allow users to declare static interop classes. Also adds errors for erroneous usage of static interop classes, like including instance members or using a non-static supertype. Change-Id: I21abafbf6ea6c2eb7cd0425f0a54c1ba35d6ec6c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215010 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
d3b0aa2670
commit
67be663490
@@ -6471,9 +6471,9 @@ const Template<
|
||||
Message Function(
|
||||
String name, String name2, String string3)>(
|
||||
problemMessageTemplate:
|
||||
r"""JS interop class '#name' conflicts with natively supported class '#name2' in '#string3'.""",
|
||||
r"""Non-static JS interop class '#name' conflicts with natively supported class '#name2' in '#string3'.""",
|
||||
correctionMessageTemplate:
|
||||
r"""Try making the @JS class into an @anonymous class or use js_util on the JS object.""",
|
||||
r"""Try replacing it with a static JS interop class using `@staticInterop` with extension methods, or use js_util to interact with the native object of type '#name2'.""",
|
||||
withArguments: _withArgumentsJsInteropNativeClassInAnnotation);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
@@ -6493,8 +6493,8 @@ Message _withArgumentsJsInteropNativeClassInAnnotation(
|
||||
if (string3.isEmpty) throw 'No string provided';
|
||||
return new Message(codeJsInteropNativeClassInAnnotation,
|
||||
problemMessage:
|
||||
"""JS interop class '${name}' conflicts with natively supported class '${name2}' in '${string3}'.""",
|
||||
correctionMessage: """Try making the @JS class into an @anonymous class or use js_util on the JS object.""",
|
||||
"""Non-static JS interop class '${name}' conflicts with natively supported class '${name2}' in '${string3}'.""",
|
||||
correctionMessage: """Try replacing it with a static JS interop class using `@staticInterop` with extension methods, or use js_util to interact with the native object of type '${name2}'.""",
|
||||
arguments: {'name': name, 'name2': name2, 'string3': string3});
|
||||
}
|
||||
|
||||
@@ -6520,6 +6520,66 @@ const MessageCode messageJsInteropNonExternalMember = const MessageCode(
|
||||
r"""This JS interop member must be annotated with `external`. Only factories and static methods can be non-external.""",
|
||||
correctionMessage: r"""Try annotating the member with `external`.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name)>
|
||||
templateJsInteropStaticInteropWithInstanceMembers =
|
||||
const Template<Message Function(String name)>(
|
||||
problemMessageTemplate:
|
||||
r"""JS interop class '#name' with `@staticInterop` annotation cannot declare instance members.""",
|
||||
correctionMessageTemplate:
|
||||
r"""Try moving the instance member to a static extension.""",
|
||||
withArguments: _withArgumentsJsInteropStaticInteropWithInstanceMembers);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name)>
|
||||
codeJsInteropStaticInteropWithInstanceMembers =
|
||||
const Code<Message Function(String name)>(
|
||||
"JsInteropStaticInteropWithInstanceMembers",
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsJsInteropStaticInteropWithInstanceMembers(String name) {
|
||||
if (name.isEmpty) throw 'No name provided';
|
||||
name = demangleMixinApplicationName(name);
|
||||
return new Message(codeJsInteropStaticInteropWithInstanceMembers,
|
||||
problemMessage:
|
||||
"""JS interop class '${name}' with `@staticInterop` annotation cannot declare instance members.""",
|
||||
correctionMessage: """Try moving the instance member to a static extension.""",
|
||||
arguments: {'name': name});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name, String name2)>
|
||||
templateJsInteropStaticInteropWithNonStaticSupertype =
|
||||
const Template<Message Function(String name, String name2)>(
|
||||
problemMessageTemplate:
|
||||
r"""JS interop class '#name' has an `@staticInterop` annotation, but has supertype '#name2', which is non-static.""",
|
||||
correctionMessageTemplate:
|
||||
r"""Try marking the supertype as a static interop class using `@staticInterop`.""",
|
||||
withArguments:
|
||||
_withArgumentsJsInteropStaticInteropWithNonStaticSupertype);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, String name2)>
|
||||
codeJsInteropStaticInteropWithNonStaticSupertype =
|
||||
const Code<Message Function(String name, String name2)>(
|
||||
"JsInteropStaticInteropWithNonStaticSupertype",
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsJsInteropStaticInteropWithNonStaticSupertype(
|
||||
String name, String name2) {
|
||||
if (name.isEmpty) throw 'No name provided';
|
||||
name = demangleMixinApplicationName(name);
|
||||
if (name2.isEmpty) throw 'No name provided';
|
||||
name2 = demangleMixinApplicationName(name2);
|
||||
return new Message(codeJsInteropStaticInteropWithNonStaticSupertype,
|
||||
problemMessage:
|
||||
"""JS interop class '${name}' has an `@staticInterop` annotation, but has supertype '${name2}', which is non-static.""",
|
||||
correctionMessage: """Try marking the supertype as a static interop class using `@staticInterop`.""",
|
||||
arguments: {'name': name, 'name2': name2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(String name)> templateLabelNotFound = const Template<
|
||||
|
||||
@@ -19,6 +19,8 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart'
|
||||
messageJsInteropNonExternalConstructor,
|
||||
messageJsInteropNonExternalMember,
|
||||
templateJsInteropDartClassExtendsJSClass,
|
||||
templateJsInteropStaticInteropWithInstanceMembers,
|
||||
templateJsInteropStaticInteropWithNonStaticSupertype,
|
||||
templateJsInteropJSClassExtendsDartClass,
|
||||
templateJsInteropNativeClassInAnnotation;
|
||||
|
||||
@@ -30,6 +32,7 @@ class JsInteropChecks extends RecursiveVisitor {
|
||||
final Map<String, Class> _nativeClasses;
|
||||
bool _classHasJSAnnotation = false;
|
||||
bool _classHasAnonymousAnnotation = false;
|
||||
bool _classHasStaticInteropAnnotation = false;
|
||||
bool _libraryHasJSAnnotation = false;
|
||||
Map<Reference, Extension>? _libraryExtensionsIndex;
|
||||
|
||||
@@ -99,6 +102,7 @@ class JsInteropChecks extends RecursiveVisitor {
|
||||
void visitClass(Class cls) {
|
||||
_classHasJSAnnotation = hasJSInteropAnnotation(cls);
|
||||
_classHasAnonymousAnnotation = hasAnonymousAnnotation(cls);
|
||||
_classHasStaticInteropAnnotation = hasStaticInteropAnnotation(cls);
|
||||
var superclass = cls.superclass;
|
||||
if (superclass != null && superclass != _coreTypes.objectClass) {
|
||||
var superHasJSAnnotation = hasJSInteropAnnotation(superclass);
|
||||
@@ -116,11 +120,35 @@ class JsInteropChecks extends RecursiveVisitor {
|
||||
cls.fileOffset,
|
||||
cls.name.length,
|
||||
cls.fileUri);
|
||||
} else if (_classHasStaticInteropAnnotation) {
|
||||
if (!hasStaticInteropAnnotation(superclass)) {
|
||||
_diagnosticsReporter.report(
|
||||
templateJsInteropStaticInteropWithNonStaticSupertype
|
||||
.withArguments(cls.name, superclass.name),
|
||||
cls.fileOffset,
|
||||
cls.name.length,
|
||||
cls.fileUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Validate that superinterfaces are all annotated as static as well. Note
|
||||
// that mixins are already disallowed and therefore are not checked here.
|
||||
if (_classHasStaticInteropAnnotation) {
|
||||
for (var supertype in cls.implementedTypes) {
|
||||
if (!hasStaticInteropAnnotation(supertype.classNode)) {
|
||||
_diagnosticsReporter.report(
|
||||
templateJsInteropStaticInteropWithNonStaticSupertype
|
||||
.withArguments(cls.name, supertype.classNode.name),
|
||||
cls.fileOffset,
|
||||
cls.name.length,
|
||||
cls.fileUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Since this is a breaking check, it is language-versioned.
|
||||
if (cls.enclosingLibrary.languageVersion >= Version(2, 13) &&
|
||||
_classHasJSAnnotation &&
|
||||
!_classHasStaticInteropAnnotation &&
|
||||
!_classHasAnonymousAnnotation &&
|
||||
_libraryIsGlobalNamespace) {
|
||||
var jsClass = getJSName(cls);
|
||||
@@ -221,6 +249,30 @@ class JsInteropChecks extends RecursiveVisitor {
|
||||
_checkNoNamedParameters(procedure.function);
|
||||
}
|
||||
}
|
||||
|
||||
if (_classHasStaticInteropAnnotation &&
|
||||
procedure.isInstanceMember &&
|
||||
!procedure.isFactory) {
|
||||
_diagnosticsReporter.report(
|
||||
templateJsInteropStaticInteropWithInstanceMembers
|
||||
.withArguments(procedure.enclosingClass!.name),
|
||||
procedure.fileOffset,
|
||||
procedure.name.text.length,
|
||||
procedure.fileUri);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitField(Field field) {
|
||||
if (_classHasStaticInteropAnnotation && field.isInstanceMember) {
|
||||
_diagnosticsReporter.report(
|
||||
templateJsInteropStaticInteropWithInstanceMembers
|
||||
.withArguments(field.enclosingClass!.name),
|
||||
field.fileOffset,
|
||||
field.name.text.length,
|
||||
field.fileUri);
|
||||
}
|
||||
super.visitField(field);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -9,11 +9,16 @@ import 'package:kernel/kernel.dart';
|
||||
bool hasJSInteropAnnotation(Annotatable a) =>
|
||||
a.annotations.any(_isPublicJSAnnotation);
|
||||
|
||||
/// Returns true iff the node has an `@anonymous(...)` annotation from
|
||||
/// `package:js` or from the internal `dart:_js_annotations`.
|
||||
/// Returns true iff the node has an `@anonymous` annotation from `package:js`
|
||||
/// or from the internal `dart:_js_annotations`.
|
||||
bool hasAnonymousAnnotation(Annotatable a) =>
|
||||
a.annotations.any(_isAnonymousAnnotation);
|
||||
|
||||
/// Returns true iff the node has an `@staticInterop` annotation from
|
||||
/// `package:js` or from the internal `dart:_js_annotations`.
|
||||
bool hasStaticInteropAnnotation(Annotatable a) =>
|
||||
a.annotations.any(_isStaticInteropAnnotation);
|
||||
|
||||
/// If [a] has a `@JS('...')` annotation, returns the value inside the
|
||||
/// parentheses.
|
||||
///
|
||||
@@ -52,26 +57,26 @@ final _packageJs = Uri.parse('package:js/js.dart');
|
||||
final _internalJs = Uri.parse('dart:_js_annotations');
|
||||
final _jsHelper = Uri.parse('dart:_js_helper');
|
||||
|
||||
/// Returns true if [value] is the `JS` annotation from `package:js` or from
|
||||
/// `dart:_js_annotations`.
|
||||
bool _isPublicJSAnnotation(Expression value) {
|
||||
/// Returns true if [value] is the interop annotation whose class is
|
||||
/// [annotationClassName] from `package:js` or from `dart:_js_annotations`.
|
||||
bool _isInteropAnnotation(Expression value, String annotationClassName) {
|
||||
var c = _annotationClass(value);
|
||||
return c != null &&
|
||||
c.name == 'JS' &&
|
||||
c.name == annotationClassName &&
|
||||
(c.enclosingLibrary.importUri == _packageJs ||
|
||||
c.enclosingLibrary.importUri == _internalJs);
|
||||
}
|
||||
|
||||
/// Returns true if [value] is the `anyonymous` annotation from `package:js` or
|
||||
/// from `dart:_js_annotations`.
|
||||
bool _isAnonymousAnnotation(Expression value) {
|
||||
var c = _annotationClass(value);
|
||||
return c != null &&
|
||||
c.name == '_Anonymous' &&
|
||||
(c.enclosingLibrary.importUri == _packageJs ||
|
||||
c.enclosingLibrary.importUri == _internalJs);
|
||||
}
|
||||
bool _isPublicJSAnnotation(Expression value) =>
|
||||
_isInteropAnnotation(value, 'JS');
|
||||
|
||||
bool _isAnonymousAnnotation(Expression value) =>
|
||||
_isInteropAnnotation(value, '_Anonymous');
|
||||
|
||||
bool _isStaticInteropAnnotation(Expression value) =>
|
||||
_isInteropAnnotation(value, '_StaticInterop');
|
||||
|
||||
/// Returns true if [value] is the `Native` annotation from `dart:_js_helper`.
|
||||
bool _isNativeAnnotation(Expression value) {
|
||||
var c = _annotationClass(value);
|
||||
return c != null &&
|
||||
@@ -85,6 +90,7 @@ bool _isNativeAnnotation(Expression value) {
|
||||
///
|
||||
/// - `@JS()` would return the "JS" class in "package:js".
|
||||
/// - `@anonymous` would return the "_Anonymous" class in "package:js".
|
||||
/// - `@staticInterop` would return the "_StaticInterop" class in "package:js".
|
||||
/// - `@Native` would return the "Native" class in "dart:_js_helper".
|
||||
///
|
||||
/// This function works regardless of whether the CFE is evaluating constants,
|
||||
|
||||
@@ -523,6 +523,10 @@ JsInteropExternalMemberNotJSAnnotated/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropExternalMemberNotJSAnnotated/example: Fail # Web compiler specific
|
||||
JsInteropIndexNotSupported/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropIndexNotSupported/example: Fail # Web compiler specific
|
||||
JsInteropStaticInteropWithInstanceMembers/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStaticInteropWithInstanceMembers/example: Fail # Web compiler specific
|
||||
JsInteropStaticInteropWithNonStaticSupertype/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specific
|
||||
JsInteropJSClassExtendsDartClass/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropJSClassExtendsDartClass/example: Fail # Web compiler specific
|
||||
JsInteropNamedParameters/analyzerCode: Fail # Web compiler specific
|
||||
|
||||
@@ -5050,6 +5050,14 @@ JsInteropIndexNotSupported:
|
||||
problemMessage: "JS interop classes do not support [] and []= operator methods."
|
||||
correctionMessage: "Try replacing with a normal method."
|
||||
|
||||
JsInteropStaticInteropWithInstanceMembers:
|
||||
problemMessage: "JS interop class '#name' with `@staticInterop` annotation cannot declare instance members."
|
||||
correctionMessage: "Try moving the instance member to a static extension."
|
||||
|
||||
JsInteropStaticInteropWithNonStaticSupertype:
|
||||
problemMessage: "JS interop class '#name' has an `@staticInterop` annotation, but has supertype '#name2', which is non-static."
|
||||
correctionMessage: "Try marking the supertype as a static interop class using `@staticInterop`."
|
||||
|
||||
JsInteropJSClassExtendsDartClass:
|
||||
problemMessage: "JS interop class '#name' cannot extend Dart class '#name2'."
|
||||
correctionMessage: "Try removing the JS interop annotation or adding it to the parent class."
|
||||
@@ -5059,8 +5067,8 @@ JsInteropNamedParameters:
|
||||
correctionMessage: "Try replacing them with normal or optional parameters."
|
||||
|
||||
JsInteropNativeClassInAnnotation:
|
||||
problemMessage: "JS interop class '#name' conflicts with natively supported class '#name2' in '#string3'."
|
||||
correctionMessage: "Try making the @JS class into an @anonymous class or use js_util on the JS object."
|
||||
problemMessage: "Non-static JS interop class '#name' conflicts with natively supported class '#name2' in '#string3'."
|
||||
correctionMessage: "Try replacing it with a static JS interop class using `@staticInterop` with extension methods, or use js_util to interact with the native object of type '#name2'."
|
||||
|
||||
JsInteropNonExternalConstructor:
|
||||
problemMessage: "JS interop classes do not support non-external constructors."
|
||||
|
||||
@@ -37,6 +37,7 @@ futureor
|
||||
guides
|
||||
h
|
||||
https
|
||||
interact
|
||||
interop
|
||||
intervening
|
||||
js_util
|
||||
@@ -65,6 +66,7 @@ re
|
||||
sdksummary
|
||||
solutions
|
||||
stacktrace
|
||||
staticinterop
|
||||
stringokempty
|
||||
struct<#name
|
||||
structs
|
||||
|
||||
@@ -25,6 +25,10 @@ class _Anonymous {
|
||||
const _Anonymous();
|
||||
}
|
||||
|
||||
class _StaticInterop {
|
||||
const _StaticInterop();
|
||||
}
|
||||
|
||||
/// An annotation that indicates a [JS] annotated class is structural and does
|
||||
/// not have a known JavaScript prototype.
|
||||
///
|
||||
@@ -33,3 +37,11 @@ class _Anonymous {
|
||||
/// desugars to creating a JavaScript object literal with name-value pairs
|
||||
/// corresponding to the parameter names and values.
|
||||
const _Anonymous anonymous = _Anonymous();
|
||||
|
||||
/// [staticInterop] enables the [JS] annotated class to be treated as a "static"
|
||||
/// interop class.
|
||||
///
|
||||
/// These classes allow interop with native types, like the ones in `dart:html`.
|
||||
/// These classes should not contain any instance members, inherited or
|
||||
/// otherwise, and should instead use static extension members.
|
||||
const _StaticInterop staticInterop = _StaticInterop();
|
||||
|
||||
@@ -18,4 +18,10 @@ class _Anonymous {
|
||||
const _Anonymous();
|
||||
}
|
||||
|
||||
const _Anonymous anonymous = const _Anonymous();
|
||||
class _StaticInterop {
|
||||
const _StaticInterop();
|
||||
}
|
||||
|
||||
const _Anonymous anonymous = _Anonymous();
|
||||
|
||||
const _StaticInterop staticInterop = _StaticInterop();
|
||||
|
||||
@@ -13,29 +13,29 @@ import 'package:js/js.dart';
|
||||
@JS()
|
||||
class HTMLDocument {}
|
||||
// ^
|
||||
// [web] JS interop class 'HTMLDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'HTMLDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
|
||||
// Test same annotation name as a native class.
|
||||
@JS('HTMLDocument')
|
||||
class HtmlDocument {}
|
||||
// ^
|
||||
// [web] JS interop class 'HtmlDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'HtmlDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
|
||||
// Test annotation name with 'self' and 'window' prefixes.
|
||||
@JS('self.Window')
|
||||
class WindowWithSelf {}
|
||||
// ^
|
||||
// [web] JS interop class 'WindowWithSelf' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'WindowWithSelf' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('window.Window')
|
||||
class WindowWithWindow {}
|
||||
// ^
|
||||
// [web] JS interop class 'WindowWithWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'WindowWithWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('self.window.self.window.self.Window')
|
||||
class WindowWithMultipleSelfsAndWindows {}
|
||||
// ^
|
||||
// [web] JS interop class 'WindowWithMultipleSelfsAndWindows' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'WindowWithMultipleSelfsAndWindows' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
// Test annotation with native class name but with a prefix that isn't 'self' or
|
||||
// 'window'.
|
||||
@@ -47,14 +47,14 @@ class WindowWithDifferentPrefix {}
|
||||
@JS()
|
||||
class DOMWindow {}
|
||||
// ^
|
||||
// [web] JS interop class 'DOMWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'DOMWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
// Test same annotation name as a native class with multiple annotation names
|
||||
// dart:html.Window uses both "Window" and "DOMWindow".
|
||||
@JS('DOMWindow')
|
||||
class DomWindow {}
|
||||
// ^
|
||||
// [web] JS interop class 'DomWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'DomWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
// Test different annotation name but with same class name as a @Native class.
|
||||
@JS('Foo')
|
||||
|
||||
@@ -12,27 +12,27 @@ import 'package:js/js.dart';
|
||||
@JS()
|
||||
class HTMLDocument {}
|
||||
// ^
|
||||
// [web] JS interop class 'HTMLDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'HTMLDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
|
||||
@JS('HTMLDocument')
|
||||
class HtmlDocument {}
|
||||
// ^
|
||||
// [web] JS interop class 'HtmlDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'HtmlDocument' conflicts with natively supported class 'HtmlDocument' in 'dart:html'.
|
||||
|
||||
@JS('self.Window')
|
||||
class WindowWithSelf {}
|
||||
// ^
|
||||
// [web] JS interop class 'WindowWithSelf' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'WindowWithSelf' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('window.Window')
|
||||
class WindowWithWindow {}
|
||||
// ^
|
||||
// [web] JS interop class 'WindowWithWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'WindowWithWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('self.window.self.window.self.Window')
|
||||
class WindowWithMultipleSelfsAndWindows {}
|
||||
// ^
|
||||
// [web] JS interop class 'WindowWithMultipleSelfsAndWindows' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'WindowWithMultipleSelfsAndWindows' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('foo.Window')
|
||||
class WindowWithDifferentPrefix {}
|
||||
@@ -40,12 +40,12 @@ class WindowWithDifferentPrefix {}
|
||||
@JS()
|
||||
class DOMWindow {}
|
||||
// ^
|
||||
// [web] JS interop class 'DOMWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'DOMWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('DOMWindow')
|
||||
class DomWindow {}
|
||||
// ^
|
||||
// [web] JS interop class 'DomWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
// [web] Non-static JS interop class 'DomWindow' conflicts with natively supported class 'Window' in 'dart:html'.
|
||||
|
||||
@JS('Foo')
|
||||
class Window {}
|
||||
|
||||
Reference in New Issue
Block a user