diff --git a/pkg/_js_interop_checks/analysis_options.yaml b/pkg/_js_interop_checks/analysis_options.yaml index c36c2c5d39f..f18363961ff 100644 --- a/pkg/_js_interop_checks/analysis_options.yaml +++ b/pkg/_js_interop_checks/analysis_options.yaml @@ -1 +1,7 @@ -include: package:lints/core.yaml +include: package:lints/recommended.yaml + +linter: + rules: + depend_on_referenced_packages: true + directives_ordering: true + sort_pub_dependencies: true diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart index c334b9fcd9c..c7ca65cb8bb 100644 --- a/pkg/_js_interop_checks/lib/js_interop_checks.dart +++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart @@ -2,11 +2,8 @@ // 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. -// Used for importing CFE utility functions for constructor tear-offs. -import 'package:front_end/src/api_prototype/lowering_predicates.dart'; -import 'package:kernel/core_types.dart'; -import 'package:kernel/kernel.dart'; -import 'package:kernel/target/targets.dart'; +// ignore_for_file: implementation_imports + import 'package:_fe_analyzer_shared/src/messages/codes.dart' show Message, @@ -35,6 +32,11 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart' templateJsInteropStaticInteropTrustTypesUsageNotAllowed, templateJsInteropStaticInteropTrustTypesUsedWithoutStaticInterop; import 'package:_js_interop_checks/src/transformations/export_checker.dart'; +// Used for importing CFE utility functions for constructor tear-offs. +import 'package:front_end/src/api_prototype/lowering_predicates.dart'; +import 'package:kernel/core_types.dart'; +import 'package:kernel/kernel.dart'; +import 'package:kernel/target/targets.dart'; import 'src/js_interop.dart'; @@ -89,7 +91,7 @@ class JsInteropChecks extends RecursiveVisitor { /// Native tests to exclude from checks on external. // TODO(rileyporter): Use ExternalName from CFE to exclude native tests. - List _allowedNativeTestPatterns = [ + final List _allowedNativeTestPatterns = [ RegExp(r'(? _allowedTrustTypesTestPatterns = [ + final List _allowedTrustTypesTestPatterns = [ RegExp(r'(?= Version(2, 13) && + if (node.enclosingLibrary.languageVersion >= Version(2, 13) && _classHasJSAnnotation && !_classHasStaticInteropAnnotation && !_classHasAnonymousAnnotation && _libraryIsGlobalNamespace) { - var jsClass = getJSName(cls); + var jsClass = getJSName(node); if (jsClass.isEmpty) { // No rename, take the name of the class directly. - jsClass = cls.name; + jsClass = node.name; } else { // Remove any global prefixes. Regex here is greedy and will only return // a value for `className` that doesn't start with 'self.' or 'window.'. - var classRegexp = new RegExp(r'^((self|window)\.)*(?.*)$'); + var classRegexp = RegExp(r'^((self|window)\.)*(?.*)$'); var matches = classRegexp.allMatches(jsClass); jsClass = matches.first.namedGroup('className')!; } @@ -255,29 +257,29 @@ class JsInteropChecks extends RecursiveVisitor { if (nativeClass != null) { _diagnosticsReporter.report( templateJsInteropNativeClassInAnnotation.withArguments( - cls.name, + node.name, nativeClass.name, nativeClass.enclosingLibrary.importUri.toString()), - cls.fileOffset, - cls.name.length, - cls.fileUri); + node.fileOffset, + node.name.length, + node.fileUri); } } - super.visitClass(cls); + super.visitClass(node); // Validate `@JSExport` usage after so we know if the members have the // annotation. - exportChecker.visitClass(cls); + exportChecker.visitClass(node); _classHasAnonymousAnnotation = false; _classHasJSAnnotation = false; } @override - void visitLibrary(Library lib) { - _libraryHasJSAnnotation = hasJSInteropAnnotation(lib); + void visitLibrary(Library node) { + _libraryHasJSAnnotation = hasJSInteropAnnotation(node); _libraryIsGlobalNamespace = false; if (_libraryHasJSAnnotation) { - var libraryAnnotation = getJSName(lib); - var globalRegexp = new RegExp(r'^(self|window)(\.(self|window))*$'); + var libraryAnnotation = getJSName(node); + var globalRegexp = RegExp(r'^(self|window)(\.(self|window))*$'); if (libraryAnnotation.isEmpty || globalRegexp.hasMatch(libraryAnnotation)) { _libraryIsGlobalNamespace = true; @@ -285,52 +287,43 @@ class JsInteropChecks extends RecursiveVisitor { } else { _libraryIsGlobalNamespace = true; } - super.visitLibrary(lib); - exportChecker.visitLibrary(lib); + super.visitLibrary(node); + exportChecker.visitLibrary(node); _libraryIsGlobalNamespace = false; _libraryHasJSAnnotation = false; _libraryExtensionsIndex = null; } @override - void visitProcedure(Procedure procedure) { + void visitProcedure(Procedure node) { // TODO(joshualitt): Add a check that only supported operators are allowed // in external extension members / inline classes. - _checkInstanceMemberJSAnnotation(procedure); - if (_classHasJSAnnotation && !procedure.isExternal) { + _checkInstanceMemberJSAnnotation(node); + if (_classHasJSAnnotation && !node.isExternal) { // If not one of few exceptions, member is not allowed to exclude // `external` inside of a JS interop class. - if (!(procedure.isAbstract || - procedure.isFactory || - procedure.isStatic)) { - _diagnosticsReporter.report( - messageJsInteropNonExternalMember, - procedure.fileOffset, - procedure.name.text.length, - procedure.fileUri); + if (!(node.isAbstract || node.isFactory || node.isStatic)) { + _diagnosticsReporter.report(messageJsInteropNonExternalMember, + node.fileOffset, node.name.text.length, node.fileUri); } } - if (!_isJSInteropMember(procedure)) { - _checkDisallowedExternal(procedure); + if (!_isJSInteropMember(node)) { + _checkDisallowedExternal(node); } else { // Check JS interop indexing. - if (!procedure.isStatic && procedure.kind == ProcedureKind.Operator) { - _diagnosticsReporter.report( - messageJsInteropOperatorsNotSupported, - procedure.fileOffset, - procedure.name.text.length, - procedure.fileUri); + if (!node.isStatic && node.kind == ProcedureKind.Operator) { + _diagnosticsReporter.report(messageJsInteropOperatorsNotSupported, + node.fileOffset, node.name.text.length, node.fileUri); } // Check JS Interop positional and named parameters. - var isAnonymousFactory = - _classHasAnonymousAnnotation && procedure.isFactory; + var isAnonymousFactory = _classHasAnonymousAnnotation && node.isFactory; if (isAnonymousFactory) { // ignore: unnecessary_null_comparison - if (procedure.function != null && - procedure.function.positionalParameters.isNotEmpty) { - var firstPositionalParam = procedure.function.positionalParameters[0]; + if (node.function != null && + node.function.positionalParameters.isNotEmpty) { + var firstPositionalParam = node.function.positionalParameters[0]; _diagnosticsReporter.report( messageJsInteropAnonymousFactoryPositionalParameters, firstPositionalParam.fileOffset, @@ -340,97 +333,94 @@ class JsInteropChecks extends RecursiveVisitor { } else { // Only factory constructors for anonymous classes are allowed to have // named parameters. - _checkNoNamedParameters(procedure.function); + _checkNoNamedParameters(node.function); } // JS static methods cannot use a JS name with dots. - if (procedure.isStatic && procedure.enclosingClass != null) { - String name = getJSName(procedure); + if (node.isStatic && node.enclosingClass != null) { + String name = getJSName(node); if (name.contains('.')) { _diagnosticsReporter.report( messageJsInteropInvalidStaticClassMemberName, - procedure.fileOffset, - procedure.name.text.length, - procedure.fileUri); + node.fileOffset, + node.name.text.length, + node.fileUri); } } } if (_classHasStaticInteropAnnotation && - procedure.isInstanceMember && - !procedure.isFactory && - !procedure.isSynthetic) { + node.isInstanceMember && + !node.isFactory && + !node.isSynthetic) { _diagnosticsReporter.report( templateJsInteropStaticInteropWithInstanceMembers - .withArguments(procedure.enclosingClass!.name), - procedure.fileOffset, - procedure.name.text.length, - procedure.fileUri); + .withArguments(node.enclosingClass!.name), + node.fileOffset, + node.name.text.length, + node.fileUri); } - if (procedure.isExternal && - procedure.isExtensionMember && - _isStaticInteropExtensionMember(procedure) && - !_isAllowedCustomStaticInteropImplementation(procedure)) { + if (node.isExternal && + node.isExtensionMember && + _isStaticInteropExtensionMember(node) && + !_isAllowedCustomStaticInteropImplementation(node)) { // If the extension has type parameters of its own, it copies those type // parameters to the procedure's type parameters (in the front) as well. // Ignore these for the analysis. var extensionTypeParams = - _libraryExtensionsIndex![procedure.reference]!.typeParameters; - var procedureTypeParams = List.from(procedure.function.typeParameters); + _libraryExtensionsIndex![node.reference]!.typeParameters; + var procedureTypeParams = List.from(node.function.typeParameters); procedureTypeParams.removeRange(0, extensionTypeParams.length); if (procedureTypeParams.isNotEmpty || - _typeParameterVisitor.usesTypeParameters(procedure)) { + _typeParameterVisitor.usesTypeParameters(node)) { _diagnosticsReporter.report( messageJsInteropStaticInteropExternalExtensionMembersWithTypeParameters, - procedure.fileOffset, - procedure.name.text.length, - procedure.fileUri); + node.fileOffset, + node.name.text.length, + node.fileUri); } } - _inTearoff = isTearOffLowering(procedure); - super.visitProcedure(procedure); + _inTearoff = isTearOffLowering(node); + super.visitProcedure(node); _inTearoff = false; } @override - void visitField(Field field) { - if (_classHasStaticInteropAnnotation && field.isInstanceMember) { + void visitField(Field node) { + if (_classHasStaticInteropAnnotation && node.isInstanceMember) { _diagnosticsReporter.report( templateJsInteropStaticInteropWithInstanceMembers - .withArguments(field.enclosingClass!.name), - field.fileOffset, - field.name.text.length, - field.fileUri); + .withArguments(node.enclosingClass!.name), + node.fileOffset, + node.name.text.length, + node.fileUri); } - super.visitField(field); + super.visitField(node); } @override - void visitConstructor(Constructor constructor) { - _checkInstanceMemberJSAnnotation(constructor); - if (!constructor.isSynthetic) { - if (_classHasJSAnnotation && !constructor.isExternal) { + void visitConstructor(Constructor node) { + _checkInstanceMemberJSAnnotation(node); + if (!node.isSynthetic) { + if (_classHasJSAnnotation && !node.isExternal) { // Non-synthetic constructors must be annotated with `external`. - _diagnosticsReporter.report( - messageJsInteropNonExternalConstructor, - constructor.fileOffset, - constructor.name.text.length, - constructor.fileUri); + _diagnosticsReporter.report(messageJsInteropNonExternalConstructor, + node.fileOffset, node.name.text.length, node.fileUri); } if (_classHasStaticInteropAnnotation) { _diagnosticsReporter.report( messageJsInteropStaticInteropGenerativeConstructor, - constructor.fileOffset, - constructor.name.text.length, - constructor.fileUri); + node.fileOffset, + node.name.text.length, + node.fileUri); } } - if (!_isJSInteropMember(constructor)) { - _checkDisallowedExternal(constructor); + if (!_isJSInteropMember(node)) { + _checkDisallowedExternal(node); } else { - _checkNoNamedParameters(constructor.function); + _checkNoNamedParameters(node.function); } } @@ -619,9 +609,11 @@ class JsInteropChecks extends RecursiveVisitor { assert(member.isExtensionMember); if (_libraryExtensionsIndex == null) { _libraryExtensionsIndex = {}; - member.enclosingLibrary.extensions.forEach((extension) => - extension.members.forEach((memberDescriptor) => - _libraryExtensionsIndex![memberDescriptor.member] = extension)); + for (var extension in member.enclosingLibrary.extensions) { + for (var memberDescriptor in extension.members) { + _libraryExtensionsIndex![memberDescriptor.member] = extension; + } + } } var onType = _libraryExtensionsIndex![member.reference]!.onType; diff --git a/pkg/_js_interop_checks/lib/src/js_interop.dart b/pkg/_js_interop_checks/lib/src/js_interop.dart index 2a735dc207c..9eaa3eeacee 100644 --- a/pkg/_js_interop_checks/lib/src/js_interop.dart +++ b/pkg/_js_interop_checks/lib/src/js_interop.dart @@ -185,14 +185,14 @@ List stringAnnotationValues(Expression node) { var value = constant.fieldValues.values.elementAt(0); if (value is StringConstant) values.addAll(value.value.split(',')); } else if (argLength > 1) { - throw new ArgumentError('Method expects annotation with at most one ' + throw ArgumentError('Method expects annotation with at most one ' 'positional argument: $node.'); } } } else if (node is ConstructorInvocation) { var argLength = node.arguments.positional.length; if (argLength > 1 || node.arguments.named.isNotEmpty) { - throw new ArgumentError('Method expects annotation with at most one ' + throw ArgumentError('Method expects annotation with at most one ' 'positional argument: $node.'); } else if (argLength == 1) { var value = node.arguments.positional[0]; @@ -233,7 +233,7 @@ List? calculateTransitiveImportsOfJsInteropIfUsed( if (jsInteropLibrary == null) return null; kernel_graph.LibraryGraph graph = - new kernel_graph.LibraryGraph(component.libraries); + kernel_graph.LibraryGraph(component.libraries); Set result = kernel_graph.calculateTransitiveDependenciesOf(graph, {jsInteropLibrary}); return result.toList(); diff --git a/pkg/_js_interop_checks/lib/src/transformations/export_checker.dart b/pkg/_js_interop_checks/lib/src/transformations/export_checker.dart index eaaf8a6533b..4867269be23 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/export_checker.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/export_checker.dart @@ -2,8 +2,8 @@ // 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:kernel/ast.dart'; -import 'package:kernel/target/targets.dart'; +// ignore_for_file: implementation_imports + import 'package:_fe_analyzer_shared/src/messages/codes.dart' show Message, @@ -13,18 +13,20 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart' templateJsInteropExportMemberCollision, templateJsInteropExportNoExportableMembers; import 'package:_js_interop_checks/src/js_interop.dart' as js_interop; +import 'package:kernel/ast.dart'; +import 'package:kernel/target/targets.dart'; enum ExportStatus { - EXPORT_ERROR, - EXPORTABLE, - NON_EXPORTABLE, + exportError, + exportable, + nonExportable, } -class _GetSet { +class GetSet { Member? getter; Member? setter; - _GetSet(this.getter, this.setter); + GetSet(this.getter, this.setter); } class ExportChecker { @@ -44,7 +46,7 @@ class ExportChecker { /// /// [exports] should be a set of members from the [exportClassToMemberMap]. If /// missing a getter and/or setter, the corresponding field will be `null`. - _GetSet getGetterSetter(Set exports) { + GetSet getGetterSetter(Set exports) { assert(exports.isNotEmpty && exports.length <= 2); Member? getter; Member? setter; @@ -70,7 +72,7 @@ class ExportChecker { } } - return _GetSet(getter, setter); + return GetSet(getter, setter); } /// Calculates the overrides, including inheritance, for [cls]. @@ -95,10 +97,10 @@ class ExportChecker { ]) { var memberName = member.name.text; if (member is Procedure && member.isSetter) { - memberMap[memberName + '='] = member; + memberMap['$memberName='] = member; } else { if (member is Field && !member.isFinal) { - memberMap[memberName + '='] = member; + memberMap['$memberName='] = member; } memberMap[memberName] = member; } @@ -122,8 +124,8 @@ class ExportChecker { // when we visited the members and checked their annotations, there's // nothing to do for this class. if (!classHasJSExport && - exportStatus[cls.reference] != ExportStatus.EXPORTABLE) { - exportStatus[cls.reference] = ExportStatus.NON_EXPORTABLE; + exportStatus[cls.reference] != ExportStatus.exportable) { + exportStatus[cls.reference] = ExportStatus.nonExportable; return; } @@ -134,7 +136,7 @@ class ExportChecker { cls.fileOffset, cls.name.length, cls.location?.file); - exportStatus[cls.reference] = ExportStatus.EXPORT_ERROR; + exportStatus[cls.reference] = ExportStatus.exportError; } _collectOverrides(cls); @@ -195,7 +197,7 @@ class ExportChecker { cls.fileOffset, cls.name.length, cls.location?.file); - exportStatus[cls.reference] = ExportStatus.EXPORT_ERROR; + exportStatus[cls.reference] = ExportStatus.exportError; } if (exports.isEmpty) { @@ -204,11 +206,11 @@ class ExportChecker { cls.fileOffset, cls.name.length, cls.location?.file); - exportStatus[cls.reference] = ExportStatus.EXPORT_ERROR; + exportStatus[cls.reference] = ExportStatus.exportError; } exportClassToMemberMap[cls.reference] = exports; - exportStatus[cls.reference] ??= ExportStatus.EXPORTABLE; + exportStatus[cls.reference] ??= ExportStatus.exportable; } /// Check that the [member] can be exportable if it has an annotation, and if @@ -225,12 +227,12 @@ class ExportChecker { member.name.text.length, member.location?.file); if (cls != null) { - exportStatus[cls.reference] = ExportStatus.EXPORT_ERROR; + exportStatus[cls.reference] = ExportStatus.exportError; } } else { // Mark as exportable so we know that the class has an exportable member // when we process the class later. - if (cls != null) exportStatus[cls.reference] = ExportStatus.EXPORTABLE; + if (cls != null) exportStatus[cls.reference] = ExportStatus.exportable; } } } @@ -249,34 +251,34 @@ class ExportChecker { } extension ExtensionMemberDescriptorExtension on ExtensionMemberDescriptor { - bool get isGetter => this.kind == ExtensionMemberKind.Getter; - bool get isSetter => this.kind == ExtensionMemberKind.Setter; - bool get isMethod => this.kind == ExtensionMemberKind.Method; + bool get isGetter => kind == ExtensionMemberKind.Getter; + bool get isSetter => kind == ExtensionMemberKind.Setter; + bool get isMethod => kind == ExtensionMemberKind.Method; - bool get isExternal => (this.member.asProcedure).isExternal; + bool get isExternal => (member.asProcedure).isExternal; } extension ProcedureExtension on Procedure { // We only care about concrete instance procedures. bool get exportable => - !this.isAbstract && - !this.isStatic && - !this.isExtensionMember && - !this.isFactory && - !this.isExternal && - this.kind != ProcedureKind.Operator; + !isAbstract && + !isStatic && + !isExtensionMember && + !isFactory && + !isExternal && + kind != ProcedureKind.Operator; } extension FieldExtension on Field { // We only care about concrete instance fields. - bool get exportable => !this.isAbstract && !this.isStatic && !this.isExternal; + bool get exportable => !isAbstract && !isStatic && !isExternal; } extension MemberExtension on Member { // Get the property name that this member will be exported as. String get exportPropertyName { var rename = js_interop.getJSExportName(this); - return rename.isEmpty ? this.name.text : rename; + return rename.isEmpty ? name.text : rename; } bool get exportable => @@ -297,8 +299,7 @@ extension MemberExtension on Member { this is Field || (this is Procedure && (this as Procedure).isGetter); bool get isSetter => - this.isNonFinalField || - (this is Procedure && (this as Procedure).isSetter); + isNonFinalField || (this is Procedure && (this as Procedure).isSetter); bool get isMethod => this is Procedure && (this as Procedure).kind == ProcedureKind.Method; diff --git a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart index d49eaba7b8e..1ee0e954bdd 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart @@ -2,6 +2,14 @@ // 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. +// ignore_for_file: implementation_imports + +import 'package:_fe_analyzer_shared/src/messages/codes.dart' + show + Message, + LocatedMessage, + templateJsInteropExportClassNotMarkedExportable; +import 'package:_js_interop_checks/src/js_interop.dart' as js_interop; import 'package:front_end/src/fasta/fasta_codes.dart' show templateJsInteropExportInvalidInteropTypeArgument, @@ -9,12 +17,6 @@ import 'package:front_end/src/fasta/fasta_codes.dart' import 'package:kernel/ast.dart'; import 'package:kernel/target/targets.dart'; import 'package:kernel/type_environment.dart'; -import 'package:_fe_analyzer_shared/src/messages/codes.dart' - show - Message, - LocatedMessage, - templateJsInteropExportClassNotMarkedExportable; -import 'package:_js_interop_checks/src/js_interop.dart' as js_interop; import 'export_checker.dart'; import 'static_interop_mock_validator.dart'; @@ -126,13 +128,16 @@ class ExportCreator extends Transformer { // This occurs when we deserialize previously compiled modules. Those // modules may contain export classes, so we need to revisit the classes // in those previously compiled modules if they are used. - dartClass.procedures - .forEach((member) => _exportChecker.visitMember(member)); - dartClass.fields.forEach((member) => _exportChecker.visitMember(member)); + for (var member in dartClass.procedures) { + _exportChecker.visitMember(member); + } + for (var member in dartClass.fields) { + _exportChecker.visitMember(member); + } _exportChecker.visitClass(dartClass); } var exportStatus = _exportChecker.exportStatus[dartClass.reference]; - if (exportStatus == ExportStatus.NON_EXPORTABLE) { + if (exportStatus == ExportStatus.nonExportable) { _diagnosticReporter.report( templateJsInteropExportClassNotMarkedExportable .withArguments(dartClass.name), @@ -141,7 +146,7 @@ class ExportCreator extends Transformer { node.location?.file); return false; } - return exportStatus == ExportStatus.EXPORTABLE; + return exportStatus == ExportStatus.exportable; } /// Create the object literal using the export map that was computed from the diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart index f6f934df142..e45a224ba30 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart @@ -97,15 +97,15 @@ class JsUtilOptimizer extends Transformer { _listEmptyFactory = _coreTypes.index.getProcedure('dart:core', 'List', 'empty'), _staticTypeContext = StatefulStaticTypeContext.stacked( - TypeEnvironment(_coreTypes, hierarchy)) {} + TypeEnvironment(_coreTypes, hierarchy)); @override - visitLibrary(Library lib) { - _inlineExtensionIndex = InlineExtensionIndex(lib); - _staticTypeContext.enterLibrary(lib); - lib.transformChildren(this); - _staticTypeContext.leaveLibrary(lib); - return lib; + visitLibrary(Library node) { + _inlineExtensionIndex = InlineExtensionIndex(node); + _staticTypeContext.enterLibrary(node); + node.transformChildren(this); + _staticTypeContext.leaveLibrary(node); + return node; } @override @@ -660,26 +660,27 @@ class InlineExtensionIndex { if (_extensionMemberIndex != null) return; _extensionMemberIndex = {}; _shouldTrustType = {}; - _library.extensions - .forEach((extension) => extension.members.forEach((descriptor) { - var reference = descriptor.member; - var onType = extension.onType; - Annotatable? cls; - if (onType is InterfaceType) { - cls = onType.classNode; - // For now, `@trustTypes` can only be used on non-inline - // classes. - if (hasTrustTypesAnnotation(cls)) { - _shouldTrustType.add(reference); - } - } else if (onType is InlineType) { - cls = onType.inlineClass; - } - if (cls == null) return; - if (hasJSInteropAnnotation(cls) || hasNativeAnnotation(cls)) { - _extensionMemberIndex![reference] = descriptor; - } - })); + for (var extension in _library.extensions) { + for (var descriptor in extension.members) { + var reference = descriptor.member; + var onType = extension.onType; + Annotatable? cls; + if (onType is InterfaceType) { + cls = onType.classNode; + // For now, `@trustTypes` can only be used on non-inline + // classes. + if (hasTrustTypesAnnotation(cls)) { + _shouldTrustType.add(reference); + } + } else if (onType is InlineType) { + cls = onType.inlineClass; + } + if (cls == null) continue; + if (hasJSInteropAnnotation(cls) || hasNativeAnnotation(cls)) { + _extensionMemberIndex![reference] = descriptor; + } + } + } } ExtensionMemberDescriptor? getExtensionDescriptor(Reference reference) { @@ -700,15 +701,15 @@ class InlineExtensionIndex { if (_inlineMemberIndex != null) return; _inlineMemberIndex = {}; _inlineClassIndex = {}; - _library.inlineClasses.forEach((inlineClass) { + for (var inlineClass in _library.inlineClasses) { if (hasJSInteropAnnotation(inlineClass)) { - inlineClass.members.forEach((descriptor) { + for (var descriptor in inlineClass.members) { var reference = descriptor.member; _inlineMemberIndex![reference] = descriptor; _inlineClassIndex[reference] = inlineClass; - }); + } } - }); + } } InlineClassMemberDescriptor? getInlineDescriptor(Reference reference) { diff --git a/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart b/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart index 0c23cd1517d..8ddb9bfa8a8 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart @@ -2,6 +2,9 @@ // 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. +// ignore_for_file: implementation_imports + +import 'package:_js_interop_checks/src/js_interop.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/clone.dart'; import 'package:kernel/core_types.dart'; @@ -9,7 +12,6 @@ import 'package:kernel/kernel.dart'; import 'package:kernel/reference_from_index.dart'; import 'package:kernel/src/constant_replacer.dart'; import 'package:kernel/src/replacement_visitor.dart'; -import 'package:_js_interop_checks/src/js_interop.dart'; class _TypeSubstitutor extends ReplacementVisitor { final Class _javaScriptObject; @@ -36,7 +38,7 @@ class StaticInteropClassEraser extends Transformer { // Visiting core libraries that don't contain `@staticInterop` adds overhead. // To avoid this, we use an allowlist that contains libraries that we know use // `@staticInterop`. - late Set _erasableCoreLibraries = {'ui', '_engine'}; + late final Set _erasableCoreLibraries = {'ui', '_engine'}; StaticInteropClassEraser(CoreTypes coreTypes, this.referenceFromIndex, {String libraryForJavaScriptObject = 'dart:_interceptors', @@ -218,9 +220,9 @@ class StaticInteropClassEraser extends Transformer { } @override - DartType visitDartType(DartType type) { - var substitutedType = _getSubstitutedType(type); - return substitutedType != null ? substitutedType : type; + DartType visitDartType(DartType node) { + var substitutedType = _getSubstitutedType(node); + return substitutedType ?? node; } @override diff --git a/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_validator.dart b/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_validator.dart index 3496a8651fa..24f051169ec 100644 --- a/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_validator.dart +++ b/pkg/_js_interop_checks/lib/src/transformations/static_interop_mock_validator.dart @@ -2,11 +2,8 @@ // 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:front_end/src/fasta/fasta_codes.dart' - show templateJsInteropStaticInteropMockNotStaticInteropType; -import 'package:kernel/ast.dart'; -import 'package:kernel/target/targets.dart'; -import 'package:kernel/type_environment.dart'; +// ignore_for_file: implementation_imports + import 'package:_fe_analyzer_shared/src/messages/codes.dart' show Message, @@ -14,6 +11,11 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart' templateJsInteropStaticInteropMockMissingGetterOrSetter, templateJsInteropStaticInteropMockMissingImplements; import 'package:_js_interop_checks/src/js_interop.dart' as js_interop; +import 'package:front_end/src/fasta/fasta_codes.dart' + show templateJsInteropStaticInteropMockNotStaticInteropType; +import 'package:kernel/ast.dart'; +import 'package:kernel/target/targets.dart'; +import 'package:kernel/type_environment.dart'; import 'export_checker.dart'; @@ -289,9 +291,9 @@ class StaticInteropMockValidator { } } } - cls.supers.forEach((Supertype supertype) { + for (var supertype in cls.supers) { getAllDescriptors(supertype.classNode); - }); + } } }