30ae8e3d14
This CL is a warm-up to a follow-up change that will make running the CFE trybot faster. This CL: * Rename tests that require git (because when working with filesets and shards in the test system, the "checkout" is not a git checkout and git commands thus doesn't work properly. * Filters the front-end unit test setup on the front-end bot the way it was probably intended, i.e. run tests in pkg/kernel, pkg/front_end and pkg/fasta (actually, the last one doesn't exist, but still) instead of just in folders inside the "suite" 'pkg' that somewhere in the path has something called 'kernel', 'front_end' or 'fasta'. * Split unit_test_suites.dart into a "forwarding shell" and a impl. In a follow-up CL the impl will be converted to nnbd to allow for using 'required' on named parameters, but if the entry point was nnbd it would run in sound nnbd mode and nothing would compile because all imports are not nnbd. Overall this CL should change very little, mostly just run a few less tests, i.e. for instance skip tests that live inside a folder called 'fasta' somewhere inside the analyzer directory path. Change-Id: I3226c7261cff8b68cc287cff07dc1715dfd85159 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181381 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
299 lines
10 KiB
Dart
299 lines
10 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.
|
|
|
|
// @dart = 2.9
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:_fe_analyzer_shared/src/messages/severity.dart';
|
|
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
|
|
import 'package:front_end/src/api_prototype/compiler_options.dart' as api;
|
|
import 'package:front_end/src/api_prototype/file_system.dart' as api;
|
|
import 'package:front_end/src/base/processed_options.dart';
|
|
import 'package:front_end/src/compute_platform_binaries_location.dart'
|
|
show computePlatformBinariesLocation;
|
|
import 'package:front_end/src/fasta/builder/declaration_builder.dart';
|
|
import 'package:front_end/src/fasta/builder/field_builder.dart';
|
|
import 'package:front_end/src/fasta/builder/library_builder.dart';
|
|
import 'package:front_end/src/fasta/builder/modifier_builder.dart';
|
|
import 'package:front_end/src/fasta/builder/type_declaration_builder.dart';
|
|
import 'package:front_end/src/fasta/builder/unresolved_type.dart';
|
|
import 'package:front_end/src/fasta/compiler_context.dart';
|
|
import 'package:front_end/src/fasta/constant_context.dart';
|
|
import 'package:front_end/src/fasta/dill/dill_target.dart';
|
|
import 'package:front_end/src/fasta/fasta_codes.dart' as fasta;
|
|
import 'package:front_end/src/fasta/kernel/body_builder.dart';
|
|
import 'package:front_end/src/fasta/kernel/constness.dart';
|
|
import 'package:front_end/src/fasta/kernel/kernel_target.dart';
|
|
import 'package:front_end/src/fasta/scope.dart';
|
|
import 'package:front_end/src/fasta/source/diet_listener.dart';
|
|
import 'package:front_end/src/fasta/source/source_library_builder.dart';
|
|
import 'package:front_end/src/fasta/source/source_loader.dart';
|
|
import 'package:front_end/src/fasta/source/stack_listener_impl.dart';
|
|
import 'package:front_end/src/fasta/ticker.dart';
|
|
import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
|
|
import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
|
|
import 'package:front_end/src/fasta/uri_translator.dart';
|
|
import 'package:kernel/class_hierarchy.dart';
|
|
import 'package:kernel/core_types.dart';
|
|
import 'package:kernel/kernel.dart';
|
|
import 'package:kernel/target/targets.dart';
|
|
import "package:vm/target/vm.dart" show VmTarget;
|
|
|
|
import 'testing_utils.dart' show getGitFiles;
|
|
import "utils/io_utils.dart";
|
|
|
|
final Uri repoDir = computeRepoDirUri();
|
|
|
|
Set<Uri> libUris = {};
|
|
|
|
Future<void> main(List<String> args) async {
|
|
Ticker ticker = new Ticker(isVerbose: false);
|
|
api.CompilerOptions compilerOptions = getOptions();
|
|
|
|
Uri dotPackagesUri = repoDir.resolve(".packages");
|
|
if (!new File.fromUri(dotPackagesUri).existsSync()) {
|
|
throw "Couldn't find .packages";
|
|
}
|
|
compilerOptions.packagesFileUri = dotPackagesUri;
|
|
|
|
ProcessedOptions options = new ProcessedOptions(options: compilerOptions);
|
|
|
|
if (args.isEmpty) {
|
|
libUris.add(repoDir.resolve("pkg/front_end/lib/"));
|
|
libUris.add(repoDir.resolve("pkg/_fe_analyzer_shared/lib/"));
|
|
} else {
|
|
if (args[0] == "--front-end-only") {
|
|
libUris.add(repoDir.resolve("pkg/front_end/lib/"));
|
|
} else if (args[0] == "--shared-only") {
|
|
libUris.add(repoDir.resolve("pkg/_fe_analyzer_shared/lib/"));
|
|
} else {
|
|
throw "Unsupported arguments: $args";
|
|
}
|
|
}
|
|
for (Uri uri in libUris) {
|
|
Set<Uri> gitFiles = await getGitFiles(uri);
|
|
List<FileSystemEntity> entities =
|
|
new Directory.fromUri(uri).listSync(recursive: true);
|
|
for (FileSystemEntity entity in entities) {
|
|
if (entity is File &&
|
|
entity.path.endsWith(".dart") &&
|
|
gitFiles.contains(entity.uri)) {
|
|
options.inputs.add(entity.uri);
|
|
}
|
|
}
|
|
}
|
|
|
|
Stopwatch stopwatch = new Stopwatch()..start();
|
|
|
|
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 KernelTargetTest(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);
|
|
await dillTarget.buildOutlines();
|
|
await kernelTarget.buildOutlines();
|
|
await kernelTarget.buildComponent();
|
|
return null;
|
|
});
|
|
|
|
print("Done in ${stopwatch.elapsedMilliseconds} ms. "
|
|
"Found $errorCount errors.");
|
|
}
|
|
|
|
class KernelTargetTest extends KernelTarget {
|
|
KernelTargetTest(api.FileSystem fileSystem, bool includeComments,
|
|
DillTarget dillTarget, UriTranslator uriTranslator)
|
|
: super(fileSystem, includeComments, dillTarget, uriTranslator);
|
|
|
|
@override
|
|
SourceLoader createLoader() {
|
|
return new SourceLoaderTest(fileSystem, includeComments, this);
|
|
}
|
|
}
|
|
|
|
class SourceLoaderTest extends SourceLoader {
|
|
SourceLoaderTest(
|
|
api.FileSystem fileSystem, bool includeComments, KernelTarget target)
|
|
: super(fileSystem, includeComments, target);
|
|
|
|
@override
|
|
DietListener createDietListener(SourceLibraryBuilder library) {
|
|
return new DietListenerTest(
|
|
library, hierarchy, coreTypes, typeInferenceEngine);
|
|
}
|
|
|
|
BodyBuilder createBodyBuilderForOutlineExpression(
|
|
LibraryBuilder library,
|
|
DeclarationBuilder declarationBuilder,
|
|
ModifierBuilder member,
|
|
Scope scope,
|
|
Uri fileUri) {
|
|
return new BodyBuilderTest.forOutlineExpression(
|
|
library, declarationBuilder, member, scope, fileUri);
|
|
}
|
|
|
|
BodyBuilder createBodyBuilderForField(
|
|
FieldBuilder field, TypeInferrer typeInferrer) {
|
|
return new BodyBuilderTest.forField(field, typeInferrer);
|
|
}
|
|
}
|
|
|
|
class DietListenerTest extends DietListener {
|
|
DietListenerTest(SourceLibraryBuilder library, ClassHierarchy hierarchy,
|
|
CoreTypes coreTypes, TypeInferenceEngine typeInferenceEngine)
|
|
: super(library, hierarchy, coreTypes, typeInferenceEngine);
|
|
|
|
@override
|
|
StackListenerImpl createListenerInternal(
|
|
ModifierBuilder builder,
|
|
Scope memberScope,
|
|
Scope formalParameterScope,
|
|
bool isDeclarationInstanceMember,
|
|
VariableDeclaration extensionThis,
|
|
List<TypeParameter> extensionTypeParameters,
|
|
TypeInferrer typeInferrer,
|
|
ConstantContext constantContext) {
|
|
return new BodyBuilderTest(
|
|
libraryBuilder: libraryBuilder,
|
|
member: builder,
|
|
enclosingScope: memberScope,
|
|
formalParameterScope: formalParameterScope,
|
|
hierarchy: hierarchy,
|
|
coreTypes: coreTypes,
|
|
declarationBuilder: currentDeclaration,
|
|
isDeclarationInstanceMember: isDeclarationInstanceMember,
|
|
extensionThis: extensionThis,
|
|
extensionTypeParameters: extensionTypeParameters,
|
|
uri: uri,
|
|
typeInferrer: typeInferrer)
|
|
..constantContext = constantContext;
|
|
}
|
|
}
|
|
|
|
class BodyBuilderTest extends BodyBuilder {
|
|
@override
|
|
BodyBuilderTest(
|
|
{libraryBuilder,
|
|
member,
|
|
enclosingScope,
|
|
formalParameterScope,
|
|
hierarchy,
|
|
coreTypes,
|
|
declarationBuilder,
|
|
isDeclarationInstanceMember,
|
|
extensionThis,
|
|
extensionTypeParameters,
|
|
uri,
|
|
typeInferrer})
|
|
: super(
|
|
libraryBuilder: libraryBuilder,
|
|
member: member,
|
|
enclosingScope: enclosingScope,
|
|
formalParameterScope: formalParameterScope,
|
|
hierarchy: hierarchy,
|
|
coreTypes: coreTypes,
|
|
declarationBuilder: declarationBuilder,
|
|
isDeclarationInstanceMember: isDeclarationInstanceMember,
|
|
extensionThis: extensionThis,
|
|
extensionTypeParameters: extensionTypeParameters,
|
|
uri: uri,
|
|
typeInferrer: typeInferrer);
|
|
|
|
@override
|
|
BodyBuilderTest.forField(FieldBuilder field, TypeInferrer typeInferrer)
|
|
: super.forField(field, typeInferrer);
|
|
|
|
@override
|
|
BodyBuilderTest.forOutlineExpression(
|
|
SourceLibraryBuilder library,
|
|
DeclarationBuilder declarationBuilder,
|
|
ModifierBuilder member,
|
|
Scope scope,
|
|
Uri fileUri)
|
|
: super.forOutlineExpression(
|
|
library, declarationBuilder, member, scope, fileUri);
|
|
|
|
@override
|
|
Expression buildConstructorInvocation(
|
|
TypeDeclarationBuilder type,
|
|
Token nameToken,
|
|
Token nameLastToken,
|
|
Arguments arguments,
|
|
String name,
|
|
List<UnresolvedType> typeArguments,
|
|
int charOffset,
|
|
Constness constness,
|
|
{bool isTypeArgumentsInForest = false}) {
|
|
Token maybeNewOrConst = nameToken.previous;
|
|
bool doReport = true;
|
|
if (maybeNewOrConst is KeywordToken) {
|
|
if (maybeNewOrConst.lexeme == "new" ||
|
|
maybeNewOrConst.lexeme == "const") {
|
|
doReport = false;
|
|
}
|
|
} else if (maybeNewOrConst is SimpleToken) {
|
|
if (maybeNewOrConst.lexeme == "@") {
|
|
doReport = false;
|
|
}
|
|
}
|
|
if (doReport) {
|
|
bool match = false;
|
|
for (Uri libUri in libUris) {
|
|
if (uri.toString().startsWith(libUri.toString())) {
|
|
match = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!match) {
|
|
doReport = false;
|
|
}
|
|
}
|
|
if (doReport) {
|
|
addProblem(
|
|
fasta.templateUnspecified.withArguments("Should use new or const"),
|
|
nameToken.charOffset,
|
|
nameToken.length);
|
|
}
|
|
return super.buildConstructorInvocation(type, nameToken, nameLastToken,
|
|
arguments, name, typeArguments, charOffset, constness,
|
|
isTypeArgumentsInForest: isTypeArgumentsInForest);
|
|
}
|
|
}
|
|
|
|
int errorCount = 0;
|
|
|
|
api.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);
|
|
api.CompilerOptions options = new api.CompilerOptions()
|
|
..sdkRoot = sdkRoot
|
|
..compileSdk = true
|
|
..target = new VmTarget(new TargetFlags())
|
|
..librariesSpecificationUri = repoDir.resolve("sdk/lib/libraries.json")
|
|
..omitPlatform = true
|
|
..onDiagnostic = (api.DiagnosticMessage message) {
|
|
if (message.severity == Severity.error) {
|
|
print(message.plainTextFormatted.join('\n'));
|
|
errorCount++;
|
|
exitCode = 1;
|
|
}
|
|
}
|
|
..environmentDefines = const {};
|
|
return options;
|
|
}
|