|
3 | 3 | // BSD-style license that can be found in the LICENSE file.
|
4 | 4 |
|
5 | 5 | import 'package:_fe_analyzer_shared/src/messages/codes.dart'
|
6 |
| - show Message, LocatedMessage; |
| 6 | + show Message, LocatedMessage, messageWasmImportOrExportInUserCode; |
7 | 7 | import 'package:_js_interop_checks/js_interop_checks.dart';
|
8 | 8 | import 'package:_js_interop_checks/src/js_interop.dart' as jsInteropHelper;
|
9 | 9 | import 'package:_js_interop_checks/src/transformations/shared_interop_transformer.dart';
|
@@ -243,6 +243,11 @@ class WasmTarget extends Target {
|
243 | 243 | ReferenceFromIndex? referenceFromIndex,
|
244 | 244 | {void Function(String msg)? logger,
|
245 | 245 | ChangedStructureNotifier? changedStructureNotifier}) {
|
| 246 | + // Check `wasm:import` and `wasm:export` pragmas before FFI transforms as |
| 247 | + // FFI transforms convert JS interop annotations to these pragmas. |
| 248 | + _checkWasmImportExportPragmas(libraries, coreTypes, |
| 249 | + diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>); |
| 250 | + |
246 | 251 | Set<Library> transitiveImportingJSInterop = {
|
247 | 252 | ...?jsInteropHelper.calculateTransitiveImportsOfJsInteropIfUsed(
|
248 | 253 | component, Uri.parse("package:js/js.dart")),
|
@@ -518,3 +523,49 @@ class WasmVerification extends Verification {
|
518 | 523 | return false;
|
519 | 524 | }
|
520 | 525 | }
|
| 526 | + |
| 527 | +final _dartCoreUri = Uri.parse('dart:core'); |
| 528 | + |
| 529 | +/// Check that `wasm:import` and `wasm:export` pragmas are only used in `dart:` |
| 530 | +/// libraries and in tests, with the exception of |
| 531 | +/// `reject_import_export_pragmas` test. |
| 532 | +void _checkWasmImportExportPragmas(List<Library> libraries, CoreTypes coreTypes, |
| 533 | + DiagnosticReporter<Message, LocatedMessage> diagnosticReporter) { |
| 534 | + for (Library library in libraries) { |
| 535 | + final importUri = library.importUri; |
| 536 | + if (importUri.isScheme('dart') || |
| 537 | + (importUri.path.contains('tests/web/wasm') && |
| 538 | + !importUri.path.contains('reject_import_export_pragmas'))) { |
| 539 | + continue; |
| 540 | + } |
| 541 | + |
| 542 | + for (Member member in library.members) { |
| 543 | + for (Expression annotation in member.annotations) { |
| 544 | + if (annotation is! ConstantExpression) { |
| 545 | + continue; |
| 546 | + } |
| 547 | + final annotationConstant = annotation.constant; |
| 548 | + if (annotationConstant is! InstanceConstant) { |
| 549 | + continue; |
| 550 | + } |
| 551 | + final cls = annotationConstant.classNode; |
| 552 | + if (cls.name == 'pragma' && |
| 553 | + cls.enclosingLibrary.importUri == _dartCoreUri) { |
| 554 | + final pragmaName = annotationConstant |
| 555 | + .fieldValues[coreTypes.pragmaName.fieldReference]; |
| 556 | + if (pragmaName is StringConstant) { |
| 557 | + if (pragmaName.value == 'wasm:import' || |
| 558 | + pragmaName.value == 'wasm:export') { |
| 559 | + diagnosticReporter.report( |
| 560 | + messageWasmImportOrExportInUserCode, |
| 561 | + annotation.fileOffset, |
| 562 | + 0, |
| 563 | + library.fileUri, |
| 564 | + ); |
| 565 | + } |
| 566 | + } |
| 567 | + } |
| 568 | + } |
| 569 | + } |
| 570 | + } |
| 571 | +} |
0 commit comments