From 8bff8336a470ce59f4be6ccdea92fc2f7889ef6b Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Fri, 23 Sep 2022 01:41:18 +0000 Subject: [PATCH] [dart2js] migrate source_file_provider This reapplies f740b500e2e5b309e07b89ee9bed77d80e3f2f95 The change is not that different from the original, except that a few changes have landed in between to address the failure encountered by the SDK roll last time. Namely, the map lookup on `resolvedUri` is normalized, so that the lookup will always match how the store operation is done, and hence will succeed when copying cache entries between resolvedUri and uri (see also https://dart-review.googlesource.com/c/sdk/+/250440). Change-Id: Ic3ad778a3e9ea465b515de9800f296c71683970c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/260081 Reviewed-by: Stephen Adams Commit-Queue: Sigmund Cherem --- .../lib/src/source_file_provider.dart | 89 +++++++++++-------- .../test/equivalence/show_helper.dart | 3 +- .../sourcemaps/helpers/sourcemap_helper.dart | 3 +- 3 files changed, 54 insertions(+), 41 deletions(-) diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart index 667f25fa76c..8218c1104b6 100644 --- a/pkg/compiler/lib/src/source_file_provider.dart +++ b/pkg/compiler/lib/src/source_file_provider.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.10 - library source_file_provider; import 'dart:async'; @@ -14,14 +12,13 @@ import 'package:front_end/src/api_unstable/dart2js.dart' as fe; import '../compiler_api.dart' as api; import 'colors.dart' as colors; -import 'dart2js.dart' show AbortLeg; import 'io/source_file.dart'; abstract class SourceFileProvider implements api.CompilerInput { bool isWindows = (Platform.operatingSystem == 'windows'); Uri cwd = Uri.base; - Map utf8SourceFiles = {}; - Map binarySourceFiles = {}; + Map>> utf8SourceFiles = {}; + Map>> binarySourceFiles = {}; int dartCharactersRead = 0; Future>> readBytesFromUri( @@ -29,7 +26,7 @@ abstract class SourceFileProvider implements api.CompilerInput { if (!resourceUri.isAbsolute) { resourceUri = cwd.resolveUri(resourceUri); } - api.Input> input = _loadInputFromCache(resourceUri, inputKind); + api.Input>? input = _loadInputFromCache(resourceUri, inputKind); if (input != null) return Future.value(input); if (resourceUri.isScheme('file')) { @@ -47,11 +44,11 @@ abstract class SourceFileProvider implements api.CompilerInput { /// utf8, the CFE file system may read them as binary inputs. In case the CFE /// needs to report errors, dart2js will only find the location data if it /// checks both caches. - api.Input> _loadInputFromCache( + api.Input>? _loadInputFromCache( Uri resourceUri, api.InputKind inputKind) { switch (inputKind) { case api.InputKind.UTF8: - var input = utf8SourceFiles[resourceUri]; + api.Input>? input = utf8SourceFiles[resourceUri]; if (input != null) return input; input = binarySourceFiles[resourceUri]; if (input == null) return null; @@ -59,11 +56,10 @@ abstract class SourceFileProvider implements api.CompilerInput { case api.InputKind.binary: return binarySourceFiles[resourceUri]; } - return null; } /// Adds [source] to the cache under the [resourceUri] key. - api.Input _storeSourceInCache( + api.Input> _storeSourceInCache( Uri resourceUri, List source, api.InputKind inputKind) { switch (inputKind) { case api.InputKind.UTF8: @@ -72,7 +68,6 @@ abstract class SourceFileProvider implements api.CompilerInput { case api.InputKind.binary: return binarySourceFiles[resourceUri] = Binary(resourceUri, source); } - return null; } @override @@ -85,14 +80,15 @@ abstract class SourceFileProvider implements api.CompilerInput { } } - api.Input _readFromFileSync(Uri resourceUri, api.InputKind inputKind) { + api.Input> _readFromFileSync( + Uri resourceUri, api.InputKind inputKind) { assert(resourceUri.isScheme('file')); List source; try { source = readAll(resourceUri.toFilePath(), zeroTerminated: inputKind == api.InputKind.UTF8); } on FileSystemException catch (ex) { - String message = ex.osError?.message; + String? message = ex.osError?.message; String detail = message != null ? ' ($message)' : ''; throw "Error reading '${relativizeUri(resourceUri)}' $detail"; } @@ -102,7 +98,7 @@ abstract class SourceFileProvider implements api.CompilerInput { /// Read [resourceUri] directly as a UTF-8 file. If reading fails, `null` is /// returned. - api.Input readUtf8FromFileSyncForTesting(Uri resourceUri) { + api.Input>? readUtf8FromFileSyncForTesting(Uri resourceUri) { try { return _readFromFileSync(resourceUri, api.InputKind.UTF8); } catch (e) { @@ -125,18 +121,15 @@ abstract class SourceFileProvider implements api.CompilerInput { relativizeUri(Uri uri) => fe.relativizeUri(cwd, uri, isWindows); - SourceFile> getUtf8SourceFile(Uri resourceUri) { + api.Input>? getUtf8SourceFile(Uri resourceUri) { return _loadInputFromCache(resourceUri, api.InputKind.UTF8); } Iterable getSourceUris() { - Set uris = Set(); // Note: this includes also indirect sources that were used to create // `.dill` inputs to the compiler. This is OK, since this API is only // used to calculate DEPS for gn build systems. - uris.addAll(utf8SourceFiles.keys); - uris.addAll(binarySourceFiles.keys); - return uris; + return {...utf8SourceFiles.keys, ...binarySourceFiles.keys}; } } @@ -170,16 +163,15 @@ class FormattingDiagnosticHandler implements api.CompilerDiagnostics { bool enableColors = false; bool throwOnError = false; int throwOnErrorCount = 0; - api.Diagnostic lastKind = null; + api.Diagnostic? lastKind = null; int fatalCount = 0; final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal; final int INFO = api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal; - FormattingDiagnosticHandler([SourceFileProvider provider]) - : this.provider = - (provider == null) ? CompilerSourceFileProvider() : provider; + FormattingDiagnosticHandler([SourceFileProvider? provider]) + : this.provider = provider ?? CompilerSourceFileProvider(); void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) { if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return; @@ -209,7 +201,7 @@ class FormattingDiagnosticHandler implements api.CompilerDiagnostics { } @override - void report(var code, Uri uri, int begin, int end, String message, + void report(var code, Uri? uri, int? begin, int? end, String message, api.Diagnostic kind) { if (isAborting) return; isAborting = (kind == api.Diagnostic.CRASH); @@ -253,29 +245,41 @@ class FormattingDiagnosticHandler implements api.CompilerDiagnostics { if (uri == null) { print('${color(message)}'); } else { - api.Input file = provider.getUtf8SourceFile(uri); - if (file is SourceFile) { - print(file.getLocationMessage(color(message), begin, end, - colorize: color)); + api.Input>? file = provider.getUtf8SourceFile(uri); + if (file is SourceFile && begin != null && end != null) { + print((file as SourceFile) + .getLocationMessage(color(message), begin, end, colorize: color)); } else { - String position = end - begin > 0 ? '@$begin+${end - begin}' : ''; + String position = begin != null && end != null && end - begin > 0 + ? '@$begin+${end - begin}' + : ''; print('${provider.relativizeUri(uri)}$position:\n' '${color(message)}'); } } if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) { isAborting = true; - throw AbortLeg(message); + throw _CompilationErrorError(message); } } } +class _CompilationErrorError { + final message; + _CompilationErrorError(this.message); + @override + toString() => 'Aborted due to --throw-on-error: $message'; +} + typedef MessageCallback = void Function(String message); class RandomAccessFileOutputProvider implements api.CompilerOutput { final Uri out; final Uri sourceMapOut; final MessageCallback onInfo; + + // TODO(48820): Make [onFailure] return `Never`. The value passed in for the + // real compiler exits. [onFailure] is not specified or faked in some tests. final MessageCallback onFailure; int totalCharactersWritten = 0; @@ -286,7 +290,9 @@ class RandomAccessFileOutputProvider implements api.CompilerOutput { List allOutputFiles = []; RandomAccessFileOutputProvider(this.out, this.sourceMapOut, - {this.onInfo, this.onFailure}); + {this.onInfo = _ignore, this.onFailure = _ignore}); + + static void _ignore(String message) {} Uri createUri(String name, String extension, api.OutputType type) { Uri uri; @@ -330,6 +336,7 @@ class RandomAccessFileOutputProvider implements api.CompilerOutput { break; default: onFailure('Unknown output type: $type'); + throw StateError('unreachable'); } return uri; } @@ -350,6 +357,8 @@ class RandomAccessFileOutputProvider implements api.CompilerOutput { .openSync(mode: FileMode.write); } on FileSystemException catch (e) { onFailure('$e'); + // TODO(48820): Make onFailure return `Never` + throw StateError('unreachable'); } allOutputFiles.add(fe.relativizeUri(Uri.base, uri, Platform.isWindows)); @@ -414,11 +423,13 @@ class RandomAccessFileOutputProvider implements api.CompilerOutput { .openSync(mode: FileMode.write); } on FileSystemException catch (e) { onFailure('$e'); + // TODO(48820): Make `onFailure` return `Never`. + throw StateError('unreachable'); } int bytesWritten = 0; - void writeBytesSync(List data, [int start = 0, int end]) { + void writeBytesSync(List data, [int start = 0, int? end]) { output.writeFromSync(data, start, end); bytesWritten += (end ?? data.length) - start; } @@ -439,7 +450,7 @@ class RandomAccessBinaryOutputSink implements api.BinaryOutputSink { : output = File.fromUri(uri).openSync(mode: FileMode.write); @override - void write(List buffer, [int start = 0, int end]) { + void write(List buffer, [int start = 0, int? end]) { output.writeFromSync(buffer, start, end); } @@ -463,13 +474,13 @@ class _OutputSinkWrapper extends api.OutputSink { } class _BinaryOutputSinkWrapper extends api.BinaryOutputSink { - void Function(List, [int, int]) onWrite; + void Function(List, [int, int?]) onWrite; void Function() onClose; _BinaryOutputSinkWrapper(this.onWrite, this.onClose); @override - void write(List data, [int start = 0, int end]) => + void write(List data, [int start = 0, int? end]) => onWrite(data, start, end); @override @@ -543,10 +554,10 @@ class BazelInputProvider extends SourceFileProvider { } switch (inputKind) { case api.InputKind.UTF8: - utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri]; + utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri]!; break; case api.InputKind.binary: - binarySourceFiles[uri] = binarySourceFiles[resolvedUri]; + binarySourceFiles[uri] = binarySourceFiles[resolvedUri]!; break; } } @@ -590,10 +601,10 @@ class MultiRootInputProvider extends SourceFileProvider { await readBytesFromUri(resolvedUri, inputKind); switch (inputKind) { case api.InputKind.UTF8: - utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri]; + utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri]!; break; case api.InputKind.binary: - binarySourceFiles[uri] = binarySourceFiles[resolvedUri]; + binarySourceFiles[uri] = binarySourceFiles[resolvedUri]!; break; } return result; diff --git a/pkg/compiler/test/equivalence/show_helper.dart b/pkg/compiler/test/equivalence/show_helper.dart index d8b955bde6d..6f27a8663e4 100644 --- a/pkg/compiler/test/equivalence/show_helper.dart +++ b/pkg/compiler/test/equivalence/show_helper.dart @@ -71,7 +71,8 @@ show(ArgResults argResults, DataComputer dataComputer, if (show != null && !show.any((f) => '$fileUri'.endsWith(f))) { continue; } - SourceFile sourceFile = provider.readUtf8FromFileSyncForTesting(fileUri); + SourceFile> sourceFile = + provider.readUtf8FromFileSyncForTesting(fileUri); String sourceCode = sourceFile?.slowText(); if (sourceCode == null) { sourceCode = new File.fromUri(fileUri).readAsStringSync(); diff --git a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart index ba0851d5561..d13cd7180db 100644 --- a/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart +++ b/pkg/compiler/test/sourcemaps/helpers/sourcemap_helper.dart @@ -104,7 +104,8 @@ class ProviderSourceFileManager implements SourceFileManager { @override SourceFile getSourceFile(uri) { - SourceFile sourceFile = sourceFileProvider.getUtf8SourceFile(uri); + SourceFile> sourceFile = + sourceFileProvider.getUtf8SourceFile(uri); sourceFile ??= sourceFileProvider.readUtf8FromFileSyncForTesting(uri); if (sourceFile == null) { sourceFile = outputProvider.getSourceFile(uri);