[js] Restrict imports in strict mode.

Change-Id: I90cdf408e60cf8115c6321448623cf363dc92f66
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292960
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Joshua Litt
2023-04-18 17:21:27 +00:00
committed by Commit Queue
parent 25348fb95c
commit c4167766f2
5 changed files with 67 additions and 3 deletions
@@ -8345,6 +8345,34 @@ Message _withArgumentsJsInteropStaticInteropWithNonStaticSupertype(
arguments: {'name': name, 'name2': name2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
templateJsInteropStrictModeForbiddenLibrary =
const Template<Message Function(String name)>(
problemMessageTemplate:
r"""Library '#name' is forbidden when strict mode is enabled.""",
correctionMessageTemplate:
r"""Remove the import of a forbidden library.""",
withArguments: _withArgumentsJsInteropStrictModeForbiddenLibrary);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)>
codeJsInteropStrictModeForbiddenLibrary =
const Code<Message Function(String name)>(
"JsInteropStrictModeForbiddenLibrary",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsJsInteropStrictModeForbiddenLibrary(String name) {
if (name.isEmpty) throw 'No name provided';
name = demangleMixinApplicationName(name);
return new Message(codeJsInteropStrictModeForbiddenLibrary,
problemMessage:
"""Library '${name}' is forbidden when strict mode is enabled.""",
correctionMessage: """Remove the import of a forbidden library.""",
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(String name)> templateLabelNotFound = const Template<
@@ -32,7 +32,8 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart'
templateJsInteropJSClassExtendsDartClass,
templateJsInteropNativeClassInAnnotation,
templateJsInteropStaticInteropTrustTypesUsageNotAllowed,
templateJsInteropStaticInteropTrustTypesUsedWithoutStaticInterop;
templateJsInteropStaticInteropTrustTypesUsedWithoutStaticInterop,
templateJsInteropStrictModeForbiddenLibrary;
import 'package:_js_interop_checks/src/transformations/export_checker.dart';
import 'package:_js_interop_checks/src/transformations/js_util_optimizer.dart';
// Used for importing CFE utility functions for constructor tear-offs.
@@ -326,10 +327,12 @@ class JsInteropChecks extends RecursiveVisitor {
_inlineExtensionIndex = InlineExtensionIndex(node);
// Allow only Flutter and package:test to opt out from strict mode on
// Dart2Wasm.
final isSDKLibrary = node.importUri.isScheme('dart');
final importUriString = node.importUri.toString();
_nonStrictModeIsAllowed = !enableStrictMode ||
node.importUri.isScheme('dart') ||
isSDKLibrary ||
importUriString.startsWith('package:ui') ||
importUriString.startsWith('package:js') ||
importUriString.startsWith('package:flutter') ||
importUriString.startsWith('package:flute') ||
importUriString.startsWith('package:engine') ||
@@ -338,6 +341,27 @@ class JsInteropChecks extends RecursiveVisitor {
(node.fileUri.toString().contains(RegExp(r'(?<!generated_)tests/')) &&
!node.fileUri.toString().contains(RegExp(
r'(?<!generated_)tests/lib/js/static_interop_test/strict_mode_test.dart')));
// Disallow importing some libraries in non-SDK code when in strict mode.
if (!_nonStrictModeIsAllowed && !isSDKLibrary) {
for (final dependency in node.dependencies) {
final dependencyUriString =
dependency.targetLibrary.importUri.toString();
if (dependencyUriString == 'package:js/js.dart' ||
dependencyUriString == 'package:js/js_util.dart' ||
dependencyUriString == 'dart:html' ||
dependencyUriString == 'dart:js_util' ||
dependencyUriString == 'dart:js') {
_diagnosticsReporter.report(
templateJsInteropStrictModeForbiddenLibrary
.withArguments(dependencyUriString),
dependency.fileOffset,
dependencyUriString.length,
node.fileUri);
}
}
}
if (_libraryHasJSAnnotation) {
var libraryAnnotation = getJSName(node);
var globalRegexp = RegExp(r'^(self|window)(\.(self|window))*$');
+2
View File
@@ -640,6 +640,8 @@ JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specif
JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specific
JsInteropStrictModeViolation/analyzerCode: Fail # Web compiler specific
JsInteropStrictModeViolation/example: Fail # Web compiler specific
JsInteropStrictModeForbiddenLibrary/analyzerCode: Fail # Web compiler specific
JsInteropStrictModeForbiddenLibrary/example: Fail # Web compiler specific
LanguageVersionInvalidInDotPackages/analyzerCode: Fail
LanguageVersionMismatchInPart/analyzerCode: Fail
LanguageVersionMismatchInPart/part_wrapped_script: Fail # Part in (now) part.
+4
View File
@@ -5583,6 +5583,10 @@ JsInteropStrictModeViolation:
problemMessage: "JS interop requires JS types when strict mode is enabled, but Type '#type' is not a type or subtype of a type from `dart:js_interop`."
correctionMessage: "Use a JS type instead."
JsInteropStrictModeForbiddenLibrary:
problemMessage: "Library '#name' is forbidden when strict mode is enabled."
correctionMessage: "Remove the import of a forbidden library."
NonNullableInNullAware:
problemMessage: "Operand of null-aware operation '#name' has type '#type' which excludes null."
severity: WARNING
@@ -6,7 +6,13 @@
library strict_mode_test;
import 'dart:js_interop';
import 'package:js/js.dart' hide JS;
import 'dart:js';
// ^
// [web] Library 'dart:js' is forbidden when strict mode is enabled.
import 'dart:js_util';
// ^
// [web] Library 'dart:js_util' is forbidden when strict mode is enabled.
@JS()
@staticInterop