mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:10:22 +00:00
[jsinterop] Add static check for JSName of static class members.
Static class members could technically be mapped to a name with dots, but in the early days of JSInterop we thought this was not necessary since it could also be modeled as a top-level member or by adding additional classes and exposing the member as a simple name on a deeper class. This invariant was assumed by DDC (which crashed if this was not the case) and ignored by dart2js. This change adds a static check to ensure both compilers act consistenlty. Fixes https://github.com/dart-lang/sdk/issues/27926 Change-Id: I20e59fbb75f0378a58ca88dc3910e079b4eeb7a3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247180 Reviewed-by: Riley Porter <rileyporter@google.com> Commit-Queue: Riley Porter <rileyporter@google.com>
This commit is contained in:
parent
0517e97250
commit
e808fa1751
6 changed files with 46 additions and 10 deletions
|
@ -6939,6 +6939,16 @@ const MessageCode messageJsInteropExternalMemberNotJSAnnotated = const MessageCo
|
|||
correctionMessage:
|
||||
r"""Try removing the 'external' keyword or adding a JS interop annotation.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeJsInteropInvalidStaticClassMemberName =
|
||||
messageJsInteropInvalidStaticClassMemberName;
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const MessageCode messageJsInteropInvalidStaticClassMemberName = const MessageCode(
|
||||
"JsInteropInvalidStaticClassMemberName",
|
||||
problemMessage:
|
||||
r"""JS interop static class members cannot have '.' in their JS name.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart'
|
|||
messageJsInteropEnclosingClassJSAnnotationContext,
|
||||
messageJsInteropExternalExtensionMemberOnTypeInvalid,
|
||||
messageJsInteropExternalMemberNotJSAnnotated,
|
||||
messageJsInteropInvalidStaticClassMemberName,
|
||||
messageJsInteropNamedParameters,
|
||||
messageJsInteropNonExternalConstructor,
|
||||
messageJsInteropNonExternalMember,
|
||||
|
@ -274,6 +275,18 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
// named parameters.
|
||||
_checkNoNamedParameters(procedure.function);
|
||||
}
|
||||
|
||||
// JS static methods cannot use a JS name with dots.
|
||||
if (procedure.isStatic && procedure.enclosingClass != null) {
|
||||
String name = getJSName(procedure);
|
||||
if (name.contains('.')) {
|
||||
_diagnosticsReporter.report(
|
||||
messageJsInteropInvalidStaticClassMemberName,
|
||||
procedure.fileOffset,
|
||||
procedure.name.text.length,
|
||||
procedure.fileUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_classHasStaticInteropAnnotation &&
|
||||
|
|
|
@ -2645,16 +2645,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
|||
|
||||
js_ast.LiteralString _emitJSInteropStaticMemberName(NamedNode n) {
|
||||
if (!usesJSInterop(n)) return null;
|
||||
var name = _annotationName(n, isPublicJSAnnotation);
|
||||
if (name != null) {
|
||||
if (name.contains('.')) {
|
||||
throw UnsupportedError(
|
||||
'static members do not support "." in their names. '
|
||||
'See https://github.com/dart-lang/sdk/issues/27926');
|
||||
}
|
||||
} else {
|
||||
name = getTopLevelName(n);
|
||||
}
|
||||
var name = _annotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
|
||||
assert(name != null && !name.contains('.'),
|
||||
'JS interop checker rejects dotted names on static class members');
|
||||
return js.escapedString(name, "'");
|
||||
}
|
||||
|
||||
|
|
|
@ -562,6 +562,8 @@ JsInteropExternalExtensionMemberOnTypeInvalid/analyzerCode: Fail # Web compiler
|
|||
JsInteropExternalExtensionMemberOnTypeInvalid/example: Fail # Web compiler specific
|
||||
JsInteropExternalMemberNotJSAnnotated/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropExternalMemberNotJSAnnotated/example: Fail # Web compiler specific
|
||||
JsInteropInvalidStaticClassMemberName/analyzerCode: Fail
|
||||
JsInteropInvalidStaticClassMemberName/example: Fail
|
||||
JsInteropJSClassExtendsDartClass/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropJSClassExtendsDartClass/example: Fail # Web compiler specific
|
||||
JsInteropNamedParameters/analyzerCode: Fail # Web compiler specific
|
||||
|
|
|
@ -5173,6 +5173,9 @@ JsInteropOperatorsNotSupported:
|
|||
problemMessage: "JS interop classes do not support operator methods."
|
||||
correctionMessage: "Try replacing this with a normal method."
|
||||
|
||||
JsInteropInvalidStaticClassMemberName:
|
||||
problemMessage: "JS interop static class members cannot have '.' in their JS name."
|
||||
|
||||
JsInteropStaticInteropWithInstanceMembers:
|
||||
problemMessage: "JS interop class '#name' with `@staticInterop` annotation cannot declare instance members."
|
||||
correctionMessage: "Try moving the instance member to a static extension."
|
||||
|
|
15
tests/lib/js/static_class_member_static_test.dart
Normal file
15
tests/lib/js/static_class_member_static_test.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
|
||||
@JS('a.Foo')
|
||||
class Foo {
|
||||
@JS('c.d.plus')
|
||||
external static plus1(arg);
|
||||
// ^
|
||||
// [web] JS interop static class members cannot have '.' in their JS name.
|
||||
}
|
||||
|
||||
main() {}
|
Loading…
Reference in a new issue