Skip to content

Commit

Permalink
Version 3.7.0-251.0.dev
Browse files Browse the repository at this point in the history
Merge 4d7d290 into dev
  • Loading branch information
Dart CI committed Dec 14, 2024
2 parents 9a213cc + 4d7d290 commit e8aa9bd
Show file tree
Hide file tree
Showing 833 changed files with 56,507 additions and 33,945 deletions.
474 changes: 313 additions & 161 deletions pkg/_js_interop_checks/lib/js_interop_checks.dart

Large diffs are not rendered by default.

41 changes: 27 additions & 14 deletions pkg/_js_interop_checks/lib/src/js_interop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ final _jsInterop = Uri.parse('dart:js_interop');
///
/// If [interopLibraries] is null, we check `package:js`,
/// `dart:_js_annotations`, and `dart:js_interop`.
bool _isInteropAnnotation(Expression value, String annotationClassName,
{Set<Uri>? interopLibraries}) {
bool _isInteropAnnotation(
Expression value,
String annotationClassName, {
Set<Uri>? interopLibraries,
}) {
interopLibraries ??= {_packageJs, _jsAnnotations, _jsInterop};
var c = annotationClass(value);
if (c == null || c.name != annotationClassName) return false;
Expand All @@ -130,9 +133,11 @@ bool _isInteropAnnotation(Expression value, String annotationClassName,
bool _isJSInteropAnnotation(Expression value) =>
_isInteropAnnotation(value, 'JS');

bool _isPackageJSAnnotation(Expression value) =>
_isInteropAnnotation(value, 'JS',
interopLibraries: {_packageJs, _jsAnnotations});
bool _isPackageJSAnnotation(Expression value) => _isInteropAnnotation(
value,
'JS',
interopLibraries: {_packageJs, _jsAnnotations},
);

bool _isDartJSInteropAnnotation(Expression value) =>
_isInteropAnnotation(value, 'JS', interopLibraries: {_jsInterop});
Expand Down Expand Up @@ -211,15 +216,19 @@ List<String> stringAnnotationValues(Expression node) {
var value = constant.fieldValues.values.elementAt(0);
if (value is StringConstant) values.addAll(value.value.split(','));
} else if (argLength > 1) {
throw ArgumentError('Method expects annotation with at most one '
'positional argument: $node.');
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 ArgumentError('Method expects annotation with at most one '
'positional argument: $node.');
throw ArgumentError(
'Method expects annotation with at most one positional argument: '
'$node.',
);
} else if (argLength == 1) {
var value = node.arguments.positional[0];
if (value is StringLiteral) {
Expand Down Expand Up @@ -267,17 +276,21 @@ Library? _findJsInteropLibrary(Component component, Uri interopUri) {
/// `calculateTransitiveImportsOfDartFfiIfUsed` in
/// pkg/vm/lib/transformations/ffi/common.dart.
Set<Library> calculateTransitiveImportsOfJsInteropIfUsed(
Component component, Uri interopUri) {
Component component,
Uri interopUri,
) {
// Check for the presence of [jsInteropLibrary] as a dependency of any of the
// libraries in [component]. We use this to bypass the expensive
// [calculateTransitiveDependenciesOf] call for cases where js interop is
// not used, otherwise we could just use the index of the library instead.
Library? jsInteropLibrary = _findJsInteropLibrary(component, interopUri);
if (jsInteropLibrary == null) return const <Library>{};

kernel_graph.LibraryGraph graph =
kernel_graph.LibraryGraph(component.libraries);
Set<Library> result =
kernel_graph.calculateTransitiveDependenciesOf(graph, {jsInteropLibrary});
kernel_graph.LibraryGraph graph = kernel_graph.LibraryGraph(
component.libraries,
);
Set<Library> result = kernel_graph.calculateTransitiveDependenciesOf(graph, {
jsInteropLibrary,
});
return result;
}
66 changes: 35 additions & 31 deletions pkg/_js_interop_checks/lib/src/transformations/export_checker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ import 'package:_js_interop_checks/js_interop_checks.dart'
import 'package:_js_interop_checks/src/js_interop.dart' as js_interop;
import 'package:kernel/ast.dart';

enum ExportStatus {
exportError,
exportable,
nonExportable,
}
enum ExportStatus { exportError, exportable, nonExportable }

class ExportChecker {
final JsInteropDiagnosticReporter _diagnosticReporter;
Expand Down Expand Up @@ -85,7 +81,7 @@ class ExportChecker {
var demangledCls = cls.isMixinApplication ? cls.mixin : cls;
for (var member in [
...demangledCls.procedures.where((proc) => proc.exportable),
...demangledCls.fields.where((field) => field.exportable)
...demangledCls.fields.where((field) => field.exportable),
]) {
var memberName = member.name.text;
if (member is Procedure && member.isSetter) {
Expand Down Expand Up @@ -122,23 +118,25 @@ class ExportChecker {

if (classHasJSExport && js_interop.getJSExportName(cls).isNotEmpty) {
_diagnosticReporter.report(
templateJsInteropExportDartInterfaceHasNonEmptyJSExportValue
.withArguments(cls.name),
cls.fileOffset,
cls.name.length,
cls.location?.file);
templateJsInteropExportDartInterfaceHasNonEmptyJSExportValue
.withArguments(cls.name),
cls.fileOffset,
cls.name.length,
cls.location?.file,
);
exportStatus[cls.reference] = ExportStatus.exportError;
}

_collectOverrides(cls);

var allExportableMembers = _overrideMap[cls.reference]!.values.where(
(member) =>
// Only members that qualify are those that are exportable, and
// either their class has the annotation or they have it themselves.
member.exportable &&
(js_interop.hasJSExportAnnotation(member) ||
js_interop.hasJSExportAnnotation(member.enclosingClass!)));
(member) =>
// Only members that qualify are those that are exportable, and
// either their class has the annotation or they have it themselves.
member.exportable &&
(js_interop.hasJSExportAnnotation(member) ||
js_interop.hasJSExportAnnotation(member.enclosingClass!)),
);
var exports = <String, Set<Member>>{};

// Store the exportable members.
Expand Down Expand Up @@ -183,20 +181,24 @@ class ExportChecker {
var sortedExistingMembers =
existingMembers.map((member) => member.toString()).toList()..sort();
_diagnosticReporter.report(
templateJsInteropExportMemberCollision.withArguments(
exportName, sortedExistingMembers.join(', ')),
cls.fileOffset,
cls.name.length,
cls.location?.file);
templateJsInteropExportMemberCollision.withArguments(
exportName,
sortedExistingMembers.join(', '),
),
cls.fileOffset,
cls.name.length,
cls.location?.file,
);
exportStatus[cls.reference] = ExportStatus.exportError;
}

if (exports.isEmpty) {
_diagnosticReporter.report(
templateJsInteropExportNoExportableMembers.withArguments(cls.name),
cls.fileOffset,
cls.name.length,
cls.location?.file);
templateJsInteropExportNoExportableMembers.withArguments(cls.name),
cls.fileOffset,
cls.name.length,
cls.location?.file,
);
exportStatus[cls.reference] = ExportStatus.exportError;
}

Expand All @@ -212,11 +214,13 @@ class ExportChecker {
if (memberHasJSExportAnnotation) {
if (!member.exportable) {
_diagnosticReporter.report(
templateJsInteropExportDisallowedMember
.withArguments(member.name.text),
member.fileOffset,
member.name.text.length,
member.location?.file);
templateJsInteropExportDisallowedMember.withArguments(
member.name.text,
),
member.fileOffset,
member.name.text.length,
member.location?.file,
);
if (cls != null) {
exportStatus[cls.reference] = ExportStatus.exportError;
}
Expand Down
Loading

0 comments on commit e8aa9bd

Please sign in to comment.