diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index a9ec81e4927..60353302c7a 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -6568,17 +6568,6 @@ 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 codeJsInteropIndexNotSupported = - messageJsInteropIndexNotSupported; - -// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. -const MessageCode messageJsInteropIndexNotSupported = const MessageCode( - "JsInteropIndexNotSupported", - problemMessage: - r"""JS interop classes do not support [] and []= operator methods.""", - correctionMessage: r"""Try replacing with a normal method."""); - // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function( @@ -6684,6 +6673,16 @@ 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 Code codeJsInteropOperatorsNotSupported = + messageJsInteropOperatorsNotSupported; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageJsInteropOperatorsNotSupported = const MessageCode( + "JsInteropOperatorsNotSupported", + problemMessage: r"""JS interop classes do not support operator methods.""", + correctionMessage: r"""Try replacing this with a normal method."""); + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template templateJsInteropStaticInteropWithInstanceMembers = diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart index 6dab119649e..26d8396d93f 100644 --- a/pkg/_js_interop_checks/lib/js_interop_checks.dart +++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart @@ -14,10 +14,10 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart' messageJsInteropEnclosingClassJSAnnotationContext, messageJsInteropExternalExtensionMemberOnTypeInvalid, messageJsInteropExternalMemberNotJSAnnotated, - messageJsInteropIndexNotSupported, messageJsInteropNamedParameters, messageJsInteropNonExternalConstructor, messageJsInteropNonExternalMember, + messageJsInteropOperatorsNotSupported, templateJsInteropDartClassExtendsJSClass, templateJsInteropStaticInteropWithInstanceMembers, templateJsInteropStaticInteropWithNonStaticSupertype, @@ -220,10 +220,9 @@ class JsInteropChecks extends RecursiveVisitor { _checkDisallowedExternal(procedure); } else { // Check JS interop indexing. - if (!procedure.isStatic && - (procedure.name.text == '[]=' || procedure.name.text == '[]')) { + if (!procedure.isStatic && procedure.kind == ProcedureKind.Operator) { _diagnosticsReporter.report( - messageJsInteropIndexNotSupported, + messageJsInteropOperatorsNotSupported, procedure.fileOffset, procedure.name.text.length, procedure.fileUri); diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 6563de2406a..a4710b54dba 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -546,8 +546,6 @@ JsInteropExternalExtensionMemberOnTypeInvalid/analyzerCode: Fail # Web compiler JsInteropExternalExtensionMemberOnTypeInvalid/example: Fail # Web compiler specific JsInteropExternalMemberNotJSAnnotated/analyzerCode: Fail # Web compiler specific JsInteropExternalMemberNotJSAnnotated/example: Fail # Web compiler specific -JsInteropIndexNotSupported/analyzerCode: Fail # Web compiler specific -JsInteropIndexNotSupported/example: Fail # Web compiler specific JsInteropJSClassExtendsDartClass/analyzerCode: Fail # Web compiler specific JsInteropJSClassExtendsDartClass/example: Fail # Web compiler specific JsInteropNamedParameters/analyzerCode: Fail # Web compiler specific @@ -558,6 +556,8 @@ JsInteropNonExternalConstructor/analyzerCode: Fail # Web compiler specific JsInteropNonExternalConstructor/example: Fail # Web compiler specific JsInteropNonExternalMember/analyzerCode: Fail # Web compiler specific JsInteropNonExternalMember/example: Fail # Web compiler specific +JsInteropOperatorsNotSupported/analyzerCode: Fail # Web compiler specific +JsInteropOperatorsNotSupported/example: Fail # Web compiler specific JsInteropStaticInteropWithInstanceMembers/analyzerCode: Fail # Web compiler specific JsInteropStaticInteropWithInstanceMembers/example: Fail # Web compiler specific JsInteropStaticInteropWithNonStaticSupertype/analyzerCode: Fail # Web compiler specific diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index d165d4c49fc..21e529c0e01 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -5096,18 +5096,6 @@ JsInteropExternalMemberNotJSAnnotated: problemMessage: "Only JS interop members may be 'external'." correctionMessage: "Try removing the 'external' keyword or adding a JS interop annotation." -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." @@ -5128,6 +5116,18 @@ JsInteropNonExternalMember: problemMessage: "This JS interop member must be annotated with `external`. Only factories and static methods can be non-external." correctionMessage: "Try annotating the member with `external`." +JsInteropOperatorsNotSupported: + problemMessage: "JS interop classes do not support operator methods." + correctionMessage: "Try replacing this 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`." + DefaultListConstructorError: problemMessage: "Can't use the default List constructor." correctionMessage: "Try using List.filled instead." diff --git a/tests/lib/js/operator_test.dart b/tests/lib/js/operator_test.dart new file mode 100644 index 00000000000..cd688cc4bea --- /dev/null +++ b/tests/lib/js/operator_test.dart @@ -0,0 +1,170 @@ +// 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. + +@JS() +library operator_test; + +import 'package:js/js.dart'; + +@JS() +class JSClass { + // https://dart.dev/guides/language/language-tour#_operators for the list of + // operators allowed by the language. + external void operator <(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator -(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator +(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator /(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~/(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator *(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator %(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator |(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ^(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator &(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <<(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator [](_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator []=(_, __); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~(); + // ^ + // [web] JS interop classes do not support operator methods. + external bool operator ==(_); + // ^ + // [web] JS interop classes do not support operator methods. +} + +@JS() +@anonymous +class AnonymousClass { + external void operator <(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator -(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator +(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator /(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~/(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator *(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator %(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator |(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ^(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator &(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <<(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator [](_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator []=(_, __); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~(); + // ^ + // [web] JS interop classes do not support operator methods. + external bool operator ==(_); + // ^ + // [web] JS interop classes do not support operator methods. +} + +@JS() +class JSClassExtensions {} + +extension _ on JSClassExtensions { + // External operators in extensions are allowed for now, but don't work as + // intended. Specific operators will need to be allowlisted in the future. + // TODO(srujzs): Remove this test once we do that. + external void operator <(_); + external void operator >(_); + external void operator <=(_); + external void operator >=(_); + external void operator -(_); + external void operator +(_); + external void operator /(_); + external void operator ~/(_); + external void operator *(_); + external void operator %(_); + external void operator |(_); + external void operator ^(_); + external void operator &(_); + external void operator <<(_); + external void operator >>(_); + external void operator >>>(_); + external void operator [](_); + external void operator []=(_, __); + external void operator ~(); + // No `==` as it's an `Object` method. +} + +void main() {} diff --git a/tests/lib_2/js/operator_test.dart b/tests/lib_2/js/operator_test.dart new file mode 100644 index 00000000000..cd688cc4bea --- /dev/null +++ b/tests/lib_2/js/operator_test.dart @@ -0,0 +1,170 @@ +// 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. + +@JS() +library operator_test; + +import 'package:js/js.dart'; + +@JS() +class JSClass { + // https://dart.dev/guides/language/language-tour#_operators for the list of + // operators allowed by the language. + external void operator <(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator -(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator +(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator /(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~/(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator *(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator %(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator |(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ^(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator &(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <<(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator [](_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator []=(_, __); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~(); + // ^ + // [web] JS interop classes do not support operator methods. + external bool operator ==(_); + // ^ + // [web] JS interop classes do not support operator methods. +} + +@JS() +@anonymous +class AnonymousClass { + external void operator <(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >=(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator -(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator +(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator /(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~/(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator *(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator %(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator |(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ^(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator &(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator <<(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator >>>(_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator [](_); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator []=(_, __); + // ^ + // [web] JS interop classes do not support operator methods. + external void operator ~(); + // ^ + // [web] JS interop classes do not support operator methods. + external bool operator ==(_); + // ^ + // [web] JS interop classes do not support operator methods. +} + +@JS() +class JSClassExtensions {} + +extension _ on JSClassExtensions { + // External operators in extensions are allowed for now, but don't work as + // intended. Specific operators will need to be allowlisted in the future. + // TODO(srujzs): Remove this test once we do that. + external void operator <(_); + external void operator >(_); + external void operator <=(_); + external void operator >=(_); + external void operator -(_); + external void operator +(_); + external void operator /(_); + external void operator ~/(_); + external void operator *(_); + external void operator %(_); + external void operator |(_); + external void operator ^(_); + external void operator &(_); + external void operator <<(_); + external void operator >>(_); + external void operator >>>(_); + external void operator [](_); + external void operator []=(_, __); + external void operator ~(); + // No `==` as it's an `Object` method. +} + +void main() {}