blob: 59693433e0e47f8ceda757f9afc033ef4a38748d [file] [log] [blame]
// 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.md 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/base/processed_options.dart';
import 'package:front_end/src/fasta/compiler_context.dart';
import 'package:front_end/src/fasta/dill/dill_target.dart';
import 'package:front_end/src/fasta/kernel/kernel_target.dart';
import 'package:front_end/src/fasta/ticker.dart';
import 'package:front_end/src/fasta/uri_translator.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
import "package:vm/target/vm.dart" show VmTarget;
import 'utils/io_utils.dart' show computeRepoDirUri;
final Uri repoDir = computeRepoDirUri();
Set<String> allowlistedExternalDartFiles = {
"third_party/pkg/package_config/lib/package_config.dart",
"third_party/pkg/package_config/lib/package_config_types.dart",
"third_party/pkg/package_config/lib/src/discovery.dart",
"third_party/pkg/package_config/lib/src/errors.dart",
"third_party/pkg/package_config/lib/src/package_config_impl.dart",
"third_party/pkg/package_config/lib/src/package_config_io.dart",
"third_party/pkg/package_config/lib/src/package_config_json.dart",
"third_party/pkg/package_config/lib/src/package_config.dart",
"third_party/pkg/package_config/lib/src/packages_file.dart",
"third_party/pkg/package_config/lib/src/util.dart",
// TODO(johnniwinther): Fix to allow dependency of package:package_config.
"third_party/pkg/package_config/lib/src/util_io.dart",
// TODO(CFE-team): These files should not be included.
// The package isn't even in pubspec.yaml.
"pkg/meta/lib/meta.dart",
"pkg/meta/lib/meta_meta.dart",
};
Future<void> 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;
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);
}
}
List<Uri> result = await CompilerContext.runWithOptions<List<Uri>>(options,
(CompilerContext c) async {
UriTranslator uriTranslator = await c.options.getUriTranslator();
DillTarget dillTarget =
new DillTarget(ticker, uriTranslator, c.options.target);
KernelTarget kernelTarget =
new KernelTarget(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();
return new List<Uri>.from(c.dependencies);
});
Set<Uri> otherDartUris = new Set<Uri>();
Set<Uri> otherNonDartUris = new Set<Uri>();
Set<Uri> frontEndUris = new Set<Uri>();
Set<Uri> kernelUris = new Set<Uri>();
Set<Uri> feAnalyzerSharedUris = new Set<Uri>();
Set<Uri> dartPlatformUris = new Set<Uri>();
Uri kernelUri = repoDir.resolve("pkg/kernel/");
Uri feAnalyzerSharedUri = repoDir.resolve("pkg/_fe_analyzer_shared/");
Uri platformUri1 = repoDir.resolve("sdk/lib/");
Uri platformUri2 = repoDir.resolve("runtime/lib/");
Uri platformUri3 = repoDir.resolve("runtime/bin/");
for (Uri uri in result) {
if (uri.toString().startsWith(frontendLibUri.toString())) {
frontEndUris.add(uri);
} else if (uri.toString().startsWith(kernelUri.toString())) {
kernelUris.add(uri);
} else if (uri.toString().startsWith(feAnalyzerSharedUri.toString())) {
feAnalyzerSharedUris.add(uri);
} else if (uri.toString().startsWith(platformUri1.toString()) ||
uri.toString().startsWith(platformUri2.toString()) ||
uri.toString().startsWith(platformUri3.toString())) {
dartPlatformUris.add(uri);
} else if (uri.toString().endsWith(".dart")) {
otherDartUris.add(uri);
} else {
otherNonDartUris.add(uri);
}
}
// * Everything in frontEndUris is okay --- the frontend can import itself.
// * Everything in kernel is okay --- the frontend is allowed to
// import package:kernel.
// * For other entries, remove allowlisted entries.
// * Everything else is an error.
// Remove white-listed non-dart files.
otherNonDartUris.remove(packageConfigUri);
otherNonDartUris.remove(repoDir.resolve("sdk/lib/libraries.json"));
otherNonDartUris.remove(repoDir.resolve(".dart_tool/package_config.json"));
// Remove white-listed dart files.
for (String s in allowlistedExternalDartFiles) {
otherDartUris.remove(repoDir.resolve(s));
}
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");
}
exitCode = 1;
}
}
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;
}