mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 08:51:21 +00:00
Reland "[ddc] Add web library environment variables"
This is a reland of fb36bba5f2
with
a fix to the ordering to ensure all the expectations run.
Original change's description:
> [ddc] Add web library environment variables
>
> Ensure frontend server builds for the `DevCompilerTarget` add the
> environment variables needed for `bool.fromEnvironment()` calls for
> conditional imports.
>
> Change-Id: Ifd372c1cf385fc843534d85af1ac9ae75a6285b8
> Fixes: https://github.com/dart-lang/sdk/issues/47207
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/213802
> Commit-Queue: Nicholas Shahan <nshahan@google.com>
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
Change-Id: Id88aeaf0ddc783936d413c06099df031bc7cb0a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/214224
Reviewed-by: Anna Gringauze <annagrin@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
parent
68aac9d9ec
commit
6c4593929f
|
@ -23,34 +23,6 @@ import 'module_builder.dart';
|
|||
/// This file should only implement functionality that does not depend on
|
||||
/// Analyzer/Kernel imports.
|
||||
|
||||
/// Variables that indicate which libraries are available in dev compiler.
|
||||
// TODO(jmesserly): provide an option to compile without dart:html & friends?
|
||||
Map<String, String> sdkLibraryVariables = {
|
||||
'dart.isVM': 'false',
|
||||
'dart.library.async': 'true',
|
||||
'dart.library.core': 'true',
|
||||
'dart.library.collection': 'true',
|
||||
'dart.library.convert': 'true',
|
||||
// TODO(jmesserly): this is not really supported in dart4web other than
|
||||
// `debugger()`
|
||||
'dart.library.developer': 'true',
|
||||
'dart.library.io': 'false',
|
||||
'dart.library.isolate': 'false',
|
||||
'dart.library.js': 'true',
|
||||
'dart.library.js_util': 'true',
|
||||
'dart.library.math': 'true',
|
||||
'dart.library.mirrors': 'false',
|
||||
'dart.library.typed_data': 'true',
|
||||
'dart.library.indexed_db': 'true',
|
||||
'dart.library.html': 'true',
|
||||
'dart.library.html_common': 'true',
|
||||
'dart.library.svg': 'true',
|
||||
'dart.library.ui': 'false',
|
||||
'dart.library.web_audio': 'true',
|
||||
'dart.library.web_gl': 'true',
|
||||
'dart.library.web_sql': 'true',
|
||||
};
|
||||
|
||||
/// Compiler options for the `dartdevc` backend.
|
||||
class SharedCompilerOptions {
|
||||
/// Whether to emit the source mapping file.
|
||||
|
|
|
@ -819,7 +819,8 @@ Map<String, String> parseAndRemoveDeclaredVariables(List<String> args) {
|
|||
}
|
||||
|
||||
// Add platform defined variables
|
||||
declaredVariables.addAll(sdkLibraryVariables);
|
||||
// TODO(47243) Remove when all code paths read these from the `Target`.
|
||||
declaredVariables.addAll(sdkLibraryEnvironmentDefines);
|
||||
|
||||
return declaredVariables;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import 'dart:isolate';
|
|||
import 'package:args/args.dart';
|
||||
import 'package:build_integration/file_system/multi_root.dart';
|
||||
import 'package:dev_compiler/dev_compiler.dart';
|
||||
import 'package:dev_compiler/src/kernel/target.dart'
|
||||
show sdkLibraryEnvironmentDefines;
|
||||
import 'package:front_end/src/api_prototype/file_system.dart';
|
||||
import 'package:front_end/src/api_unstable/ddc.dart';
|
||||
import 'package:kernel/ast.dart' show Component, Library;
|
||||
|
@ -206,7 +208,7 @@ class ExpressionCompilerWorker {
|
|||
@required Uri sdkSummary,
|
||||
@required FileSystem fileSystem,
|
||||
Uri packagesFile,
|
||||
Map<String, String> environmentDefines = const {},
|
||||
Map<String, String> environmentDefines,
|
||||
Map<ExperimentalFlag, bool> explicitExperimentalFlags = const {},
|
||||
Uri sdkRoot,
|
||||
bool trackWidgetCreation = false,
|
||||
|
@ -228,7 +230,11 @@ class ExpressionCompilerWorker {
|
|||
TargetFlags(trackWidgetCreation: trackWidgetCreation))
|
||||
..fileSystem = fileSystem
|
||||
..omitPlatform = true
|
||||
..environmentDefines = environmentDefines
|
||||
..environmentDefines = {
|
||||
if (environmentDefines != null) ...environmentDefines,
|
||||
// TODO(47243) Remove when all code paths read these from the `Target`.
|
||||
...sdkLibraryEnvironmentDefines
|
||||
}
|
||||
..explicitExperimentalFlags = explicitExperimentalFlags
|
||||
..onDiagnostic = _onDiagnosticHandler(errors, warnings, infos)
|
||||
..nnbdMode = soundNullSafety ? NnbdMode.Strong : NnbdMode.Weak
|
||||
|
|
|
@ -19,6 +19,35 @@ import 'package:kernel/transformations/track_widget_constructor_locations.dart';
|
|||
import 'constants.dart' show DevCompilerConstantsBackend;
|
||||
import 'kernel_helpers.dart';
|
||||
|
||||
/// Boolean environment variables that indicate which libraries are available in
|
||||
/// dev compiler.
|
||||
// TODO(jmesserly): provide an option to compile without dart:html & friends?
|
||||
const sdkLibraryEnvironmentDefines = {
|
||||
'dart.isVM': 'false',
|
||||
'dart.library.async': 'true',
|
||||
'dart.library.core': 'true',
|
||||
'dart.library.collection': 'true',
|
||||
'dart.library.convert': 'true',
|
||||
// TODO(jmesserly): this is not really supported in dart4web other than
|
||||
// `debugger()`
|
||||
'dart.library.developer': 'true',
|
||||
'dart.library.io': 'false',
|
||||
'dart.library.isolate': 'false',
|
||||
'dart.library.js': 'true',
|
||||
'dart.library.js_util': 'true',
|
||||
'dart.library.math': 'true',
|
||||
'dart.library.mirrors': 'false',
|
||||
'dart.library.typed_data': 'true',
|
||||
'dart.library.indexed_db': 'true',
|
||||
'dart.library.html': 'true',
|
||||
'dart.library.html_common': 'true',
|
||||
'dart.library.svg': 'true',
|
||||
'dart.library.ui': 'false',
|
||||
'dart.library.web_audio': 'true',
|
||||
'dart.library.web_gl': 'true',
|
||||
'dart.library.web_sql': 'true',
|
||||
};
|
||||
|
||||
/// A kernel [Target] to configure the Dart Front End for dartdevc.
|
||||
class DevCompilerTarget extends Target {
|
||||
DevCompilerTarget(this.flags);
|
||||
|
@ -30,6 +59,10 @@ class DevCompilerTarget extends Target {
|
|||
|
||||
Map<String, Class>? _nativeClasses;
|
||||
|
||||
@override
|
||||
Map<String, String> updateEnvironmentDefines(Map<String, String> map) =>
|
||||
map..addAll(sdkLibraryEnvironmentDefines);
|
||||
|
||||
@override
|
||||
bool get enableSuperMixins => true;
|
||||
|
||||
|
|
|
@ -175,6 +175,40 @@ void runExpressionCompilationTests(TestDriver driver) {
|
|||
]));
|
||||
});
|
||||
|
||||
test('compile expressions include "dart.library..." environment defines.',
|
||||
() async {
|
||||
driver.requestController.add({
|
||||
'command': 'UpdateDeps',
|
||||
'inputs': driver.inputs,
|
||||
});
|
||||
|
||||
driver.requestController.add({
|
||||
'command': 'CompileExpression',
|
||||
'expression': 'const bool.fromEnvironment("dart.library.html")',
|
||||
'line': 5,
|
||||
'column': 1,
|
||||
'jsModules': {},
|
||||
'jsScope': {'formal': 'formal'},
|
||||
'libraryUri': driver.config.testModule.libraryUri,
|
||||
'moduleName': driver.config.testModule.moduleName,
|
||||
});
|
||||
|
||||
expect(
|
||||
driver.responseController.stream,
|
||||
emitsInOrder([
|
||||
equals({
|
||||
'succeeded': true,
|
||||
}),
|
||||
equals({
|
||||
'succeeded': true,
|
||||
'errors': isEmpty,
|
||||
'warnings': isEmpty,
|
||||
'infos': isEmpty,
|
||||
'compiledProcedure': contains('true'),
|
||||
})
|
||||
]));
|
||||
});
|
||||
|
||||
test('can compile expressions in main', () async {
|
||||
driver.requestController.add({
|
||||
'command': 'UpdateDeps',
|
||||
|
|
|
@ -2327,6 +2327,116 @@ class BarState extends State<FizzWidget> {
|
|||
expect(count, 3);
|
||||
});
|
||||
|
||||
test('compiled Javascript includes web library environment defines',
|
||||
() async {
|
||||
var file = File('${tempDir.path}/foo.dart')..createSync();
|
||||
file.writeAsStringSync(
|
||||
"main() {print(const bool.fromEnvironment('dart.library.html'));}\n");
|
||||
var package_config =
|
||||
File('${tempDir.path}/.dart_tool/package_config.json')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('''
|
||||
{
|
||||
"configVersion": 2,
|
||||
"packages": [
|
||||
{
|
||||
"name": "hello",
|
||||
"rootUri": "../",
|
||||
"packageUri": "./"
|
||||
}
|
||||
]
|
||||
}
|
||||
''');
|
||||
|
||||
var library = 'package:hello/foo.dart';
|
||||
var module = 'packages/hello/foo.dart';
|
||||
|
||||
var dillFile = File('${tempDir.path}/foo.dart.dill');
|
||||
var sourceFile = File('${dillFile.path}.sources');
|
||||
var manifestFile = File('${dillFile.path}.json');
|
||||
var sourceMapsFile = File('${dillFile.path}.map');
|
||||
|
||||
expect(dillFile.existsSync(), false);
|
||||
|
||||
final List<String> args = <String>[
|
||||
'--sdk-root=${sdkRoot.toFilePath()}',
|
||||
'--incremental',
|
||||
'--platform=${ddcPlatformKernel.path}',
|
||||
'--output-dill=${dillFile.path}',
|
||||
'--target=dartdevc',
|
||||
'--packages=${package_config.path}',
|
||||
];
|
||||
|
||||
final StreamController<List<int>> streamController =
|
||||
StreamController<List<int>>();
|
||||
final StreamController<List<int>> stdoutStreamController =
|
||||
StreamController<List<int>>();
|
||||
final IOSink ioSink = IOSink(stdoutStreamController.sink);
|
||||
StreamController<Result> receivedResults = StreamController<Result>();
|
||||
final outputParser = OutputParser(receivedResults);
|
||||
stdoutStreamController.stream
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen(outputParser.listener);
|
||||
|
||||
Future<int> result =
|
||||
starter(args, input: streamController.stream, output: ioSink);
|
||||
streamController.add('compile $library\n'.codeUnits);
|
||||
int count = 0;
|
||||
receivedResults.stream.listen((Result compiledResult) {
|
||||
CompilationResult result =
|
||||
CompilationResult.parse(compiledResult.status);
|
||||
if (count == 0) {
|
||||
// Request to 'compile', which results in full JavaScript.
|
||||
expect(result.errorsCount, equals(0));
|
||||
expect(sourceFile.existsSync(), equals(true));
|
||||
expect(manifestFile.existsSync(), equals(true));
|
||||
expect(sourceMapsFile.existsSync(), equals(true));
|
||||
expect(result.filename, dillFile.path);
|
||||
|
||||
var compiledOutput = sourceFile.readAsStringSync();
|
||||
// The constant environment variable should be inlined as a boolean
|
||||
// literal.
|
||||
expect(compiledOutput, contains('print(true);'));
|
||||
|
||||
streamController.add('accept\n'.codeUnits);
|
||||
|
||||
// 'compile-expression-to-js <boundarykey>
|
||||
// libraryUri
|
||||
// line
|
||||
// column
|
||||
// jsModules (one k-v pair per line)
|
||||
// ...
|
||||
// <boundarykey>
|
||||
// jsFrameValues (one k-v pair per line)
|
||||
// ...
|
||||
// <boundarykey>
|
||||
// moduleName
|
||||
// expression
|
||||
outputParser.expectSources = false;
|
||||
streamController.add('compile-expression-to-js abc\n'
|
||||
'$library\n2\n1\nabc\nabc\n$module\n'
|
||||
'const bool.fromEnvironment("dart.library.html")\n'
|
||||
.codeUnits);
|
||||
count += 1;
|
||||
} else {
|
||||
expect(count, 1);
|
||||
// Second request is to 'compile-expression-to-js' that should
|
||||
// result in a literal `true` .
|
||||
expect(result.errorsCount, 0);
|
||||
var resultFile = File(result.filename);
|
||||
// The constant environment variable should be inlined as a boolean
|
||||
// literal.
|
||||
expect(resultFile.readAsStringSync(), contains('return true;'));
|
||||
outputParser.expectSources = false;
|
||||
count += 1;
|
||||
streamController.add('quit\n'.codeUnits);
|
||||
}
|
||||
});
|
||||
expect(await result, 0);
|
||||
expect(count, 2);
|
||||
});
|
||||
|
||||
test('mixed compile expression commands with web target', () async {
|
||||
var file = File('${tempDir.path}/foo.dart')..createSync();
|
||||
file.writeAsStringSync("main() {\n\n}\n");
|
||||
|
|
Loading…
Reference in a new issue