397a397f7b
Change-Id: I8b94f93a57e600d2b4925faf635690229c605ac8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400642 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
215 lines
7.4 KiB
Dart
215 lines
7.4 KiB
Dart
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// 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.
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:_fe_analyzer_shared/src/messages/severity.dart';
|
|
import 'package:expect/expect.dart' show Expect;
|
|
import 'package:front_end/src/api_prototype/compiler_options.dart';
|
|
import 'package:front_end/src/api_prototype/standard_file_system.dart';
|
|
import 'package:front_end/src/base/compiler_context.dart';
|
|
import 'package:front_end/src/base/file_system_dependency_tracker.dart';
|
|
import 'package:front_end/src/base/import_chains.dart';
|
|
import 'package:front_end/src/base/processed_options.dart';
|
|
import 'package:front_end/src/base/ticker.dart';
|
|
import 'package:front_end/src/base/uri_translator.dart';
|
|
import 'package:front_end/src/builder/library_builder.dart';
|
|
import 'package:front_end/src/compute_platform_binaries_location.dart'
|
|
show computePlatformBinariesLocation;
|
|
import 'package:front_end/src/dill/dill_target.dart';
|
|
import 'package:front_end/src/kernel/kernel_target.dart';
|
|
import 'package:kernel/kernel.dart';
|
|
import 'package:kernel/target/targets.dart';
|
|
import 'package:package_config/src/package_config.dart';
|
|
import 'package:vm/modular/target/vm.dart' show VmTarget;
|
|
|
|
import 'utils/io_utils.dart' show computeRepoDirUri;
|
|
|
|
final Uri repoDir = computeRepoDirUri();
|
|
|
|
Set<String> allowlistedExternalDartFiles = {
|
|
// TODO(CFE-team): These files should not be included.
|
|
// The package isn't even in pubspec.yaml.
|
|
// They're included via at least
|
|
// _fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
|
|
"pkg/meta/lib/meta.dart",
|
|
"pkg/meta/lib/meta_meta.dart",
|
|
};
|
|
|
|
Set<String> allowedPackages = {
|
|
"front_end",
|
|
"kernel",
|
|
"_fe_analyzer_shared",
|
|
"package_config",
|
|
"macros",
|
|
"_macros",
|
|
// package:front_end imports package:yaml for the 'dynamic modules'
|
|
// experiment.
|
|
"yaml",
|
|
// package:yaml uses package:source_span, package:string_scanner and
|
|
// package:collection.
|
|
"source_span",
|
|
"string_scanner",
|
|
"collection",
|
|
// package:source_span imports package:path.
|
|
"path",
|
|
// package:source_span imports package:term_glyph.
|
|
"term_glyph",
|
|
};
|
|
|
|
List<String> allowedRelativePaths = [
|
|
// For VmTarget for macros.
|
|
"pkg/vm/lib/modular/",
|
|
// Platform.
|
|
"sdk/lib/",
|
|
];
|
|
|
|
/// Returns true on no errors and false if errors was found.
|
|
Future<bool> main() async {
|
|
Ticker ticker = new Ticker(isVerbose: false);
|
|
CompilerOptions compilerOptions = getOptions();
|
|
|
|
Uri packageConfigUri = repoDir.resolve(".dart_tool/package_config.json");
|
|
if (!new File.fromUri(packageConfigUri).existsSync()) {
|
|
throw "Couldn't find .dart_tool/package_config.json";
|
|
}
|
|
compilerOptions.packagesFileUri = packageConfigUri;
|
|
FileSystemDependencyTracker tracker = new FileSystemDependencyTracker();
|
|
compilerOptions.fileSystem = StandardFileSystem.instanceWithTracking(tracker);
|
|
|
|
ProcessedOptions options = new ProcessedOptions(options: compilerOptions);
|
|
|
|
Uri frontendLibUri = repoDir.resolve("pkg/front_end/lib/");
|
|
List<FileSystemEntity> entities =
|
|
new Directory.fromUri(frontendLibUri).listSync(recursive: true);
|
|
for (FileSystemEntity entity in entities) {
|
|
if (entity is File && entity.path.endsWith(".dart")) {
|
|
options.inputs.add(entity.uri);
|
|
}
|
|
}
|
|
|
|
LoadedLibraries? loadedLibraries;
|
|
Map<Uri, Uri> fileUriToImportUri = {};
|
|
List<String> allowedUriPrefixes = [
|
|
for (String relativePath in allowedRelativePaths)
|
|
repoDir.resolve(relativePath).toString()
|
|
];
|
|
|
|
List<Uri> result = await CompilerContext.runWithOptions<List<Uri>>(options,
|
|
(CompilerContext c) async {
|
|
UriTranslator uriTranslator = await c.options.getUriTranslator();
|
|
for (Package package in uriTranslator.packages.packages) {
|
|
if (allowedPackages.contains(package.name)) {
|
|
allowedUriPrefixes.add(package.packageUriRoot.toString());
|
|
}
|
|
}
|
|
DillTarget dillTarget =
|
|
new DillTarget(c, ticker, uriTranslator, c.options.target);
|
|
KernelTarget kernelTarget =
|
|
new KernelTarget(c, c.fileSystem, false, dillTarget, uriTranslator);
|
|
Uri? platform = c.options.sdkSummary;
|
|
if (platform != null) {
|
|
var bytes = new File.fromUri(platform).readAsBytesSync();
|
|
var platformComponent = loadComponentFromBytes(bytes);
|
|
dillTarget.loader
|
|
.appendLibraries(platformComponent, byteCount: bytes.length);
|
|
}
|
|
|
|
kernelTarget.setEntryPoints(c.options.inputs);
|
|
dillTarget.buildOutlines();
|
|
await kernelTarget.loader.buildOutlines();
|
|
|
|
{
|
|
List<CompilationUnit> compilationUnits =
|
|
kernelTarget.loader.compilationUnits.toList(growable: false);
|
|
List<CompilationUnit> rootCompilationUnits = [];
|
|
Set<Uri> inputs = new Set.of(options.inputs);
|
|
for (CompilationUnit unit in compilationUnits) {
|
|
fileUriToImportUri[unit.fileUri] = unit.importUri;
|
|
if (inputs.contains(unit.fileUri) || inputs.contains(unit.importUri)) {
|
|
rootCompilationUnits.add(unit);
|
|
}
|
|
}
|
|
loadedLibraries =
|
|
new LoadedLibrariesImpl(rootCompilationUnits, compilationUnits);
|
|
}
|
|
|
|
return new List<Uri>.from(tracker.dependencies);
|
|
});
|
|
|
|
Set<Uri> otherDartUris = new Set<Uri>();
|
|
Set<Uri> otherNonDartUris = new Set<Uri>();
|
|
for (Uri uri in result) {
|
|
final String uriAsString = uri.toString();
|
|
bool allowed = false;
|
|
for (String prefix in allowedUriPrefixes) {
|
|
if (uriAsString.startsWith(prefix)) {
|
|
allowed = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!allowed) {
|
|
if (uri.toString().endsWith(".dart")) {
|
|
otherDartUris.add(uri);
|
|
} else {
|
|
otherNonDartUris.add(uri);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove allow-listed non-dart files.
|
|
otherNonDartUris.remove(packageConfigUri);
|
|
otherNonDartUris.remove(repoDir.resolve("sdk/lib/libraries.json"));
|
|
|
|
// Remove allow-listed dart files.
|
|
for (String s in allowlistedExternalDartFiles) {
|
|
otherDartUris.remove(repoDir.resolve(s));
|
|
}
|
|
|
|
// Everything else is an error.
|
|
if (otherNonDartUris.isNotEmpty || otherDartUris.isNotEmpty) {
|
|
print("The following files was imported without being allowlisted:");
|
|
for (Uri uri in otherNonDartUris) {
|
|
print(" - $uri");
|
|
}
|
|
for (Uri uri in otherDartUris) {
|
|
print(" - $uri");
|
|
if (loadedLibraries != null) {
|
|
Uri? importUri = fileUriToImportUri[uri];
|
|
if (importUri != null) {
|
|
Set<String> importChains = (computeImportChainsFor(
|
|
Uri.parse("<entry>"), loadedLibraries!, importUri,
|
|
verbose: false));
|
|
for (String s in importChains) {
|
|
print(" => $s");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
exitCode = 1;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
CompilerOptions getOptions() {
|
|
// Compile sdk because when this is run from a lint it uses the checked-in sdk
|
|
// and we might not have a suitable compiled platform.dill file.
|
|
Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
|
|
CompilerOptions options = new CompilerOptions()
|
|
..sdkRoot = sdkRoot
|
|
..compileSdk = true
|
|
..target = new VmTarget(new TargetFlags())
|
|
..librariesSpecificationUri = repoDir.resolve("sdk/lib/libraries.json")
|
|
..omitPlatform = true
|
|
..onDiagnostic = (DiagnosticMessage message) {
|
|
if (message.severity == Severity.error) {
|
|
Expect.fail(
|
|
"Unexpected error: ${message.plainTextFormatted.join('\n')}");
|
|
}
|
|
}
|
|
..environmentDefines = const {};
|
|
return options;
|
|
}
|