Skip to content

Commit c409e77

Browse files
alexmarkovCommit Queue
authored andcommitted
Validation of dynamic modules
TEST=pkg/front_end/testcases/general/dynamic_modules Change-Id: I591d029ed163961f5ece859233874f828d63c857 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388442 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Sigmund Cherem <[email protected]>
1 parent 6a5b3d0 commit c409e77

39 files changed

+3021
-181
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,77 @@ const MessageCode messageClassInClass = const MessageCode(
13701370
correctionMessage: r"""Try moving the class to the top-level.""",
13711371
);
13721372

1373+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1374+
const Template<Message Function(String name)>
1375+
templateClassShouldBeListedAsCallableInDynamicInterface =
1376+
const Template<Message Function(String name)>(
1377+
"ClassShouldBeListedAsCallableInDynamicInterface",
1378+
problemMessageTemplate: r"""Cannot use class '#name' in a dynamic module.""",
1379+
correctionMessageTemplate:
1380+
r"""Try removing the reference to class '#name' or update the dynamic interface to list class '#name' as callable.""",
1381+
withArguments: _withArgumentsClassShouldBeListedAsCallableInDynamicInterface,
1382+
);
1383+
1384+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1385+
const Code<Message Function(String name)>
1386+
codeClassShouldBeListedAsCallableInDynamicInterface =
1387+
const Code<Message Function(String name)>(
1388+
"ClassShouldBeListedAsCallableInDynamicInterface",
1389+
);
1390+
1391+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1392+
Message _withArgumentsClassShouldBeListedAsCallableInDynamicInterface(
1393+
String name) {
1394+
if (name.isEmpty) throw 'No name provided';
1395+
name = demangleMixinApplicationName(name);
1396+
return new Message(
1397+
codeClassShouldBeListedAsCallableInDynamicInterface,
1398+
problemMessage: """Cannot use class '${name}' in a dynamic module.""",
1399+
correctionMessage:
1400+
"""Try removing the reference to class '${name}' or update the dynamic interface to list class '${name}' as callable.""",
1401+
arguments: {
1402+
'name': name,
1403+
},
1404+
);
1405+
}
1406+
1407+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1408+
const Template<Message Function(String name)>
1409+
templateClassShouldBeListedAsExtendableInDynamicInterface =
1410+
const Template<Message Function(String name)>(
1411+
"ClassShouldBeListedAsExtendableInDynamicInterface",
1412+
problemMessageTemplate:
1413+
r"""Cannot extend, implement or mix-in class '#name' in a dynamic module.""",
1414+
correctionMessageTemplate:
1415+
r"""Try removing the reference to class '#name' or update the dynamic interface to list class '#name' as extendable.""",
1416+
withArguments:
1417+
_withArgumentsClassShouldBeListedAsExtendableInDynamicInterface,
1418+
);
1419+
1420+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1421+
const Code<Message Function(String name)>
1422+
codeClassShouldBeListedAsExtendableInDynamicInterface =
1423+
const Code<Message Function(String name)>(
1424+
"ClassShouldBeListedAsExtendableInDynamicInterface",
1425+
);
1426+
1427+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1428+
Message _withArgumentsClassShouldBeListedAsExtendableInDynamicInterface(
1429+
String name) {
1430+
if (name.isEmpty) throw 'No name provided';
1431+
name = demangleMixinApplicationName(name);
1432+
return new Message(
1433+
codeClassShouldBeListedAsExtendableInDynamicInterface,
1434+
problemMessage:
1435+
"""Cannot extend, implement or mix-in class '${name}' in a dynamic module.""",
1436+
correctionMessage:
1437+
"""Try removing the reference to class '${name}' or update the dynamic interface to list class '${name}' as extendable.""",
1438+
arguments: {
1439+
'name': name,
1440+
},
1441+
);
1442+
}
1443+
13731444
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
13741445
const Code<Null> codeColonInPlaceOfIn = messageColonInPlaceOfIn;
13751446

@@ -2370,6 +2441,43 @@ const MessageCode messageConstructorNotSync = const MessageCode(
23702441
r"""Constructor bodies can't use 'async', 'async*', or 'sync*'.""",
23712442
);
23722443

2444+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2445+
const Template<Message Function(String name)>
2446+
templateConstructorShouldBeListedAsCallableInDynamicInterface =
2447+
const Template<Message Function(String name)>(
2448+
"ConstructorShouldBeListedAsCallableInDynamicInterface",
2449+
problemMessageTemplate:
2450+
r"""Cannot invoke constructor '#name' from a dynamic module.""",
2451+
correctionMessageTemplate:
2452+
r"""Try removing the call or update the dynamic interface to list constructor '#name' as callable.""",
2453+
withArguments:
2454+
_withArgumentsConstructorShouldBeListedAsCallableInDynamicInterface,
2455+
);
2456+
2457+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2458+
const Code<Message Function(String name)>
2459+
codeConstructorShouldBeListedAsCallableInDynamicInterface =
2460+
const Code<Message Function(String name)>(
2461+
"ConstructorShouldBeListedAsCallableInDynamicInterface",
2462+
);
2463+
2464+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2465+
Message _withArgumentsConstructorShouldBeListedAsCallableInDynamicInterface(
2466+
String name) {
2467+
if (name.isEmpty) throw 'No name provided';
2468+
name = demangleMixinApplicationName(name);
2469+
return new Message(
2470+
codeConstructorShouldBeListedAsCallableInDynamicInterface,
2471+
problemMessage:
2472+
"""Cannot invoke constructor '${name}' from a dynamic module.""",
2473+
correctionMessage:
2474+
"""Try removing the call or update the dynamic interface to list constructor '${name}' as callable.""",
2475+
arguments: {
2476+
'name': name,
2477+
},
2478+
);
2479+
}
2480+
23732481
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
23742482
const Code<Null> codeConstructorTearOffWithTypeArguments =
23752483
messageConstructorTearOffWithTypeArguments;
@@ -3655,6 +3763,17 @@ Message _withArgumentsDuplicatedRecordTypeFieldNameContext(String name) {
36553763
);
36563764
}
36573765

3766+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3767+
const Code<Null> codeDynamicCallsAreNotAllowedInDynamicModule =
3768+
messageDynamicCallsAreNotAllowedInDynamicModule;
3769+
3770+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3771+
const MessageCode messageDynamicCallsAreNotAllowedInDynamicModule =
3772+
const MessageCode(
3773+
"DynamicCallsAreNotAllowedInDynamicModule",
3774+
problemMessage: r"""Dynamic calls are not allowed in a dynamic module.""",
3775+
);
3776+
36583777
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
36593778
const Code<Null> codeEmptyMapPattern = messageEmptyMapPattern;
36603779

@@ -11865,6 +11984,81 @@ Message _withArgumentsMemberNotFound(String name) {
1186511984
);
1186611985
}
1186711986

11987+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
11988+
const Template<Message Function(String name)>
11989+
templateMemberShouldBeListedAsCallableInDynamicInterface =
11990+
const Template<Message Function(String name)>(
11991+
"MemberShouldBeListedAsCallableInDynamicInterface",
11992+
problemMessageTemplate:
11993+
r"""Cannot invoke member '#name' from a dynamic module.""",
11994+
correctionMessageTemplate:
11995+
r"""Try removing the call or update the dynamic interface to list member '#name' as callable.""",
11996+
withArguments: _withArgumentsMemberShouldBeListedAsCallableInDynamicInterface,
11997+
);
11998+
11999+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12000+
const Code<Message Function(String name)>
12001+
codeMemberShouldBeListedAsCallableInDynamicInterface =
12002+
const Code<Message Function(String name)>(
12003+
"MemberShouldBeListedAsCallableInDynamicInterface",
12004+
);
12005+
12006+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12007+
Message _withArgumentsMemberShouldBeListedAsCallableInDynamicInterface(
12008+
String name) {
12009+
if (name.isEmpty) throw 'No name provided';
12010+
name = demangleMixinApplicationName(name);
12011+
return new Message(
12012+
codeMemberShouldBeListedAsCallableInDynamicInterface,
12013+
problemMessage: """Cannot invoke member '${name}' from a dynamic module.""",
12014+
correctionMessage:
12015+
"""Try removing the call or update the dynamic interface to list member '${name}' as callable.""",
12016+
arguments: {
12017+
'name': name,
12018+
},
12019+
);
12020+
}
12021+
12022+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12023+
const Template<Message Function(String name, String name2)>
12024+
templateMemberShouldBeListedAsCanBeOverriddenInDynamicInterface =
12025+
const Template<Message Function(String name, String name2)>(
12026+
"MemberShouldBeListedAsCanBeOverriddenInDynamicInterface",
12027+
problemMessageTemplate:
12028+
r"""Cannot override member '#name.#name2' in a dynamic module.""",
12029+
correctionMessageTemplate:
12030+
r"""Try removing the override or update the dynamic interface to list member '#name.#name2' as can-be-overridden.""",
12031+
withArguments:
12032+
_withArgumentsMemberShouldBeListedAsCanBeOverriddenInDynamicInterface,
12033+
);
12034+
12035+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12036+
const Code<Message Function(String name, String name2)>
12037+
codeMemberShouldBeListedAsCanBeOverriddenInDynamicInterface =
12038+
const Code<Message Function(String name, String name2)>(
12039+
"MemberShouldBeListedAsCanBeOverriddenInDynamicInterface",
12040+
);
12041+
12042+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
12043+
Message _withArgumentsMemberShouldBeListedAsCanBeOverriddenInDynamicInterface(
12044+
String name, String name2) {
12045+
if (name.isEmpty) throw 'No name provided';
12046+
name = demangleMixinApplicationName(name);
12047+
if (name2.isEmpty) throw 'No name provided';
12048+
name2 = demangleMixinApplicationName(name2);
12049+
return new Message(
12050+
codeMemberShouldBeListedAsCanBeOverriddenInDynamicInterface,
12051+
problemMessage:
12052+
"""Cannot override member '${name}.${name2}' in a dynamic module.""",
12053+
correctionMessage:
12054+
"""Try removing the override or update the dynamic interface to list member '${name}.${name2}' as can-be-overridden.""",
12055+
arguments: {
12056+
'name': name,
12057+
'name2': name2,
12058+
},
12059+
);
12060+
}
12061+
1186812062
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1186912063
const Code<Null> codeMemberWithSameNameAsClass =
1187012064
messageMemberWithSameNameAsClass;

pkg/dart2bytecode/lib/dart2bytecode.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,17 @@ final ArgParser _argParser = ArgParser(allowTrailingOptions: true)
7979
..addOption('invocation-modes',
8080
help: 'Provides information to the front end about how it is invoked.',
8181
defaultsTo: '')
82+
..addOption('validate',
83+
help:
84+
'Validate dynamic module against specified dynamic interface YAML file',
85+
defaultsTo: null)
8286
..addOption('verbosity',
8387
help: 'Sets the verbosity level used for filtering messages during '
8488
'compilation.',
8589
defaultsTo: Verbosity.defaultValue);
8690

8791
final String _usage = '''
88-
Usage: dart2bytecode --platform vm_platform_strong.dill [--import-dill host_app.dill] [options] input.dart
92+
Usage: dart2bytecode --platform vm_platform_strong.dill [--import-dill host_app.dill] [--validate dynamic_interface.yaml] [options] input.dart
8993
Compiles Dart sources to Dart bytecode.
9094
9195
Options:
@@ -140,6 +144,10 @@ Future<int> runCompiler(ArgResults options) async {
140144
additionalDills.add(Uri.base.resolveUri(new Uri.file(importDill)));
141145
}
142146

147+
final String? validate = options['validate'];
148+
final Uri? dynamicInterfaceSpecificationUri =
149+
(validate != null) ? resolveInputUri(validate) : null;
150+
143151
final verbosity = Verbosity.parseArgument(options['verbosity']);
144152
final errorPrinter = ErrorPrinter(verbosity);
145153
final errorDetector = ErrorDetector(previousErrorHandler: errorPrinter.call);
@@ -154,6 +162,7 @@ Future<int> runCompiler(ArgResults options) async {
154162
..fileSystem = fileSystem
155163
..additionalDills = additionalDills
156164
..packagesFileUri = packagesUri
165+
..dynamicInterfaceSpecificationUri = dynamicInterfaceSpecificationUri
157166
..explicitExperimentalFlags = parseExperimentalFlags(
158167
parseExperimentalArguments(experimentalFlags),
159168
onError: print)

pkg/dynamic_modules/test/data/duplicate_library/dynamic_interface.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ callable:
1111
# TODO(sigmund): This should be included by default
1212
- library: 'dart:core'
1313
class: 'Object'
14-
member: ''
14+
- library: 'dart:core'
15+
class: 'pragma'
16+
member: '_'

pkg/dynamic_modules/test/data/extend_class/dynamic_interface.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,13 @@ callable:
1515
- library: 'shared/shared.dart'
1616
class: 'Base'
1717
member: ''
18+
# TODO(sigmund): This should be included by default
19+
- library: 'dart:core'
20+
class: 'Object'
21+
- library: 'dart:core'
22+
class: 'int'
23+
- library: 'dart:core'
24+
class: 'pragma'
25+
member: '_'
26+
- library: 'dart:core'
27+
member: 'override'

pkg/dynamic_modules/test/data/implement_interface/dynamic_interface.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ callable:
1212
# TODO(sigmund): This should be included by default
1313
- library: 'dart:core'
1414
class: 'Object'
15-
member: ''
15+
- library: 'dart:core'
16+
class: 'int'
17+
- library: 'dart:core'
18+
class: 'pragma'
19+
member: '_'
20+
- library: 'dart:core'
21+
member: 'override'
1622

1723
can-be-overridden:
1824
- library: 'shared/shared.dart'

pkg/dynamic_modules/test/data/load_twice/dynamic_interface.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ callable:
1111
# TODO(sigmund): This should be included by default
1212
- library: 'dart:core'
1313
class: 'Object'
14-
member: ''
14+
- library: 'dart:core'
15+
class: 'pragma'
16+
member: '_'

pkg/dynamic_modules/test/data/shared_const/dynamic_interface.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ callable:
66
- library: 'main.dart'
77
class: 'B'
88
member: ''
9+
# TODO(sigmund): This should be included by default
10+
- library: 'dart:core'
11+
class: 'Object'
12+
- library: 'dart:core'
13+
class: 'pragma'
14+
member: '_'

pkg/dynamic_modules/test/data/update_top_level/dynamic_interface.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
# BSD-style license that can be found in the LICENSE file.
44
callable:
55
- library: 'shared/shared.dart'
6+
# TODO(sigmund): This should be included by default
7+
- library: 'dart:core'
8+
class: 'pragma'
9+
member: '_'

pkg/dynamic_modules/test/runner/aot.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ class AotExecutor implements TargetExecutor {
126126
'-Ddart.vm.product=true',
127127
'--import-dill',
128128
'${test.main}_no_aot.dill',
129+
'--validate',
130+
'$rootScheme:/data/${test.name}/dynamic_interface.yaml',
129131
'--verbosity=all',
130132
'--filesystem-root',
131133
test.folder.resolve('../../').toFilePath(),

pkg/front_end/lib/src/api_prototype/compiler_options.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ class CompilerOptions {
8888
/// at a default location within [sdkRoot].
8989
Uri? sdkSummary;
9090

91+
/// Uri to a dynamic interface specification file.
92+
///
93+
/// A dynamic interface specification file is a YAML file that lists
94+
/// Dart APIs (libraries, classes and members) available for a dynamic module.
95+
///
96+
/// If value is specified, the compiled Dart libraries are validated
97+
/// to conform to the dynamic module interface and other dynamic module
98+
/// restrictions.
99+
Uri? dynamicInterfaceSpecificationUri;
100+
91101
/// The declared variables for use by configurable imports and constant
92102
/// evaluation.
93103
Map<String, String>? declaredVariables;
@@ -345,6 +355,10 @@ class CompilerOptions {
345355
if (packagesFileUri != other.packagesFileUri) return false;
346356
if (!equalLists(additionalDills, other.additionalDills)) return false;
347357
if (sdkSummary != other.sdkSummary) return false;
358+
if (dynamicInterfaceSpecificationUri !=
359+
other.dynamicInterfaceSpecificationUri) {
360+
return false;
361+
}
348362
if (!equalMaps(declaredVariables, other.declaredVariables)) return false;
349363
if (fileSystem != other.fileSystem) return false;
350364
if (compileSdk != other.compileSdk) return false;

0 commit comments

Comments
 (0)