@@ -22,7 +22,10 @@ import 'package:kernel/kernel.dart' show Component, loadComponentFromBytes;
2222import 'package:path/path.dart' as path;
2323
2424import '../frontend_server.dart' ;
25- import '../resident_frontend_server_utils.dart' show computeCachedDillPath;
25+ import '../resident_frontend_server_utils.dart'
26+ show
27+ CachedDillAndCompilerOptionsPaths,
28+ computeCachedDillAndCompilerOptionsPaths;
2629
2730/// Floor the system time by this amount in order to correctly detect modified
2831/// source files on all platforms. This has no effect on correctness,
@@ -321,6 +324,8 @@ class ResidentFrontendServer {
321324 static const String _packageString = 'packages' ;
322325 static const String _successString = 'success' ;
323326 static const String _outputString = 'output-dill' ;
327+ static const String _useCachedCompilerOptionsAsBaseString =
328+ 'useCachedCompilerOptionsAsBase' ;
324329 static const String _compileExpressionString = 'compileExpression' ;
325330 static const String _libraryUriString = 'libraryUri' ;
326331 static const String _rootLibraryUriString = 'rootLibraryUri' ;
@@ -351,11 +356,18 @@ class ResidentFrontendServer {
351356
352357 /// Returns a [ResidentCompiler] that has been configured with
353358 /// [compileOptions] and prepared to compile the [canonicalizedLibraryPath]
354- /// entrypoint.
355- static ResidentCompiler _getResidentCompilerForEntrypoint (
356- String canonicalizedLibraryPath,
357- ArgResults compileOptions,
358- ) {
359+ /// entrypoint. This function also writes [compileOptions.arguments] to
360+ /// [cachedCompilerOptions] as a JSON list.
361+ static ResidentCompiler _getResidentCompilerForEntrypoint ({
362+ required final String canonicalizedLibraryPath,
363+ required final ArgResults compileOptions,
364+ required final File cachedCompilerOptions,
365+ }) {
366+ cachedCompilerOptions.createSync ();
367+ cachedCompilerOptions.writeAsStringSync (
368+ compileOptions.arguments.map (jsonEncode).toList ().toString (),
369+ );
370+
359371 late final ResidentCompiler residentCompiler;
360372 if (compilers[canonicalizedLibraryPath] == null ) {
361373 // Avoids using too much memory.
@@ -398,8 +410,14 @@ class ResidentFrontendServer {
398410 component.mainMethod! .enclosingLibrary.fileUri.toFilePath (),
399411 );
400412
401- final String cachedDillPath =
402- computeCachedDillPath (canonicalizedLibraryPath);
413+ final String cachedDillPath;
414+ try {
415+ cachedDillPath =
416+ computeCachedDillAndCompilerOptionsPaths (canonicalizedLibraryPath)
417+ .cachedDillPath;
418+ } on Exception catch (e) {
419+ return _encodeErrorMessage (e.toString ());
420+ }
403421 replacementDillFile.copySync (cachedDillPath);
404422 } catch (e) {
405423 return _encodeErrorMessage ('Failed to replace cached dill' );
@@ -427,21 +445,29 @@ class ResidentFrontendServer {
427445 final String canonicalizedExecutablePath =
428446 path.canonicalize (request[_executableString]);
429447
430- late final String cachedDillPath;
448+ final String cachedDillPath;
449+ final File cachedCompilerOptions;
431450 try {
432- cachedDillPath = computeCachedDillPath (canonicalizedExecutablePath);
451+ final CachedDillAndCompilerOptionsPaths computationResult =
452+ computeCachedDillAndCompilerOptionsPaths (canonicalizedExecutablePath);
453+ cachedDillPath = computationResult.cachedDillPath;
454+ cachedCompilerOptions =
455+ new File (computationResult.cachedCompilerOptionsPath);
433456 } on Exception catch (e) {
434457 return _encodeErrorMessage (e.toString ());
435458 }
436459
437460 final ArgResults options = _generateCompilerOptions (
438461 request: request,
462+ cachedCompilerOptions: cachedCompilerOptions,
439463 outputDillOverride: cachedDillPath,
440464 initializeFromDillPath: cachedDillPath,
441465 );
466+
442467 final ResidentCompiler residentCompiler = _getResidentCompilerForEntrypoint (
443- canonicalizedExecutablePath,
444- options,
468+ canonicalizedLibraryPath: canonicalizedExecutablePath,
469+ compileOptions: options,
470+ cachedCompilerOptions: cachedCompilerOptions,
445471 );
446472 final Map <String , dynamic > response = await residentCompiler.compile ();
447473
@@ -488,8 +514,17 @@ class ResidentFrontendServer {
488514 );
489515 }
490516
491- final String cachedDillPath =
492- computeCachedDillPath (canonicalizedLibraryPath);
517+ final String cachedDillPath;
518+ final File cachedCompilerOptions;
519+ try {
520+ final CachedDillAndCompilerOptionsPaths computationResult =
521+ computeCachedDillAndCompilerOptionsPaths (canonicalizedLibraryPath);
522+ cachedDillPath = computationResult.cachedDillPath;
523+ cachedCompilerOptions =
524+ new File (computationResult.cachedCompilerOptionsPath);
525+ } on Exception catch (e) {
526+ return _encodeErrorMessage (e.toString ());
527+ }
493528 // Make the [ResidentCompiler] output the compiled expression to
494529 // [compiledExpressionDillPath] to prevent it from overwriting the
495530 // cached program dill.
@@ -499,14 +534,19 @@ class ResidentFrontendServer {
499534 null ,
500535 '.expr.dill' ,
501536 );
537+
502538 final ArgResults options = _generateCompilerOptions (
503539 request: request,
540+ cachedCompilerOptions: cachedCompilerOptions,
504541 outputDillOverride: compiledExpressionDillPath,
505542 initializeFromDillPath: cachedDillPath,
506543 );
507544
508- final ResidentCompiler residentCompiler =
509- _getResidentCompilerForEntrypoint (canonicalizedLibraryPath, options);
545+ final ResidentCompiler residentCompiler = _getResidentCompilerForEntrypoint (
546+ canonicalizedLibraryPath: canonicalizedLibraryPath,
547+ compileOptions: options,
548+ cachedCompilerOptions: cachedCompilerOptions,
549+ );
510550
511551 final String expression = request[_expressionString];
512552 final List <String > definitions =
@@ -580,13 +620,32 @@ class ResidentFrontendServer {
580620 /// Generates the compiler options needed to handle the [request] .
581621 static ArgResults _generateCompilerOptions ({
582622 required Map <String , dynamic > request,
623+ required File cachedCompilerOptions,
583624
584625 /// The compiled kernel file will be stored at this path, and not at
585626 /// [request['--output-dill'] ].
586627 required String outputDillOverride,
587628 required String initializeFromDillPath,
588629 }) {
589- return argParser.parse (< String > [
630+ final Map <String , dynamic > options = {};
631+ if (request[_useCachedCompilerOptionsAsBaseString] == true &&
632+ cachedCompilerOptions.existsSync ()) {
633+ // If [request[_useCachedCompilerOptionsAsBaseString]] is true, then we
634+ // start with the cached options and apply any options specified in
635+ // [request] as overrides.
636+ final String cachedCompilerOptionsContents =
637+ cachedCompilerOptions.readAsStringSync ();
638+ final List <String > cachedCompilerOptionsAsList =
639+ (jsonDecode (cachedCompilerOptionsContents) as List <dynamic >)
640+ .cast <String >();
641+ final ArgResults cachedOptions =
642+ argParser.parse (cachedCompilerOptionsAsList);
643+ for (final String option in cachedOptions.options) {
644+ options[option] = cachedOptions[option];
645+ }
646+ }
647+
648+ final ArgResults overrides = argParser.parse (< String > [
590649 '--sdk-root=${_sdkUri .toFilePath ()}' ,
591650 if (! (request['aot' ] ?? false )) '--incremental' ,
592651 '--platform=${_platformKernelUri .path }' ,
@@ -623,6 +682,28 @@ class ResidentFrontendServer {
623682 if (request['enable-experiment' ] != null )
624683 for (String experiment in request['enable-experiment' ]) experiment,
625684 ]);
685+
686+ for (final String option in overrides.options) {
687+ options[option] = overrides[option];
688+ }
689+
690+ // Transform [options] into a list that can be passed to [argParser.parse].
691+ final List <String > optionsAsList = < String > [];
692+ for (final MapEntry <String , dynamic >(: key, : value) in options.entries) {
693+ if (value is List <dynamic >) {
694+ for (final Object multiOptionValue in value) {
695+ optionsAsList.add ('--$key =$multiOptionValue ' );
696+ }
697+ } else if (value is bool ) {
698+ if (value) {
699+ optionsAsList.add ('--$key ' );
700+ }
701+ } else {
702+ optionsAsList.add ('--$key =$value ' );
703+ }
704+ }
705+
706+ return argParser.parse (optionsAsList);
626707 }
627708
628709 /// Encodes the [message] in JSON to be sent over the socket.
0 commit comments