blob: 22a2cc849b889553618a7508f979c83b4b698af6 [file] [log] [blame]
// Copyright (c) 2018, 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:async';
import 'dart:io' show File;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import "package:front_end/src/api_prototype/front_end.dart";
import "package:front_end/src/api_prototype/memory_file_system.dart";
import "package:front_end/src/base/processed_options.dart";
import "package:front_end/src/compute_platform_binaries_location.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/fasta_codes.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_impl.dart';
import 'package:kernel/class_hierarchy.dart' as kernel;
import 'package:kernel/core_types.dart' as kernel;
import 'package:kernel/kernel.dart' as kernel;
import 'package:test/test.dart';
Element _buildElement(kernel.Class coreType) {
ClassElementImpl element =
new ClassElementImpl(coreType.name, coreType.fileOffset);
element.typeParameters = coreType.typeParameters.map((parameter) {
TypeParameterElementImpl element =
new TypeParameterElementImpl(parameter.name, parameter.fileOffset);
element.type = new TypeParameterTypeImpl(element);
return element;
}).toList();
return element;
}
class CompilerTestContext extends CompilerContext {
KernelTarget kernelTarget;
CompilerTestContext(ProcessedOptions options) : super(options);
Uri get entryPoint => options.inputs.single;
static Future<T> runWithTestOptions<T>(
Future<T> action(CompilerTestContext c)) async {
// TODO(danrubel): Consider HybridFileSystem.
final MemoryFileSystem fs =
new MemoryFileSystem(Uri.parse("org-dartlang-test:///"));
/// The custom URI used to locate the dill file in the MemoryFileSystem.
final Uri sdkSummary = fs.currentDirectory.resolve("vm_platform.dill");
/// The in memory test code URI
final Uri entryPoint = fs.currentDirectory.resolve("main.dart");
// Read the dill file containing kernel platform summaries into memory.
List<int> sdkSummaryBytes = await new File.fromUri(
computePlatformBinariesLocation().resolve("vm_platform.dill"))
.readAsBytes();
fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryBytes);
final CompilerOptions optionBuilder = new CompilerOptions()
..strongMode = false // TODO(danrubel): enable strong mode.
..reportMessages = true
..verbose = false
..fileSystem = fs
..sdkSummary = sdkSummary
..onProblem = (FormattedMessage problem, Severity severity,
List<FormattedMessage> context) {
// TODO(danrubel): Capture problems and check against expectations.
// print(problem.formatted);
};
final ProcessedOptions options =
new ProcessedOptions(optionBuilder, [entryPoint]);
UriTranslatorImpl uriTranslator = await options.getUriTranslator();
return await new CompilerTestContext(options)
.runInContext<T>((CompilerContext _c) async {
CompilerTestContext c = _c;
DillTarget dillTarget = new DillTarget(
new Ticker(isVerbose: false), uriTranslator, options.target);
c.kernelTarget = new KernelTarget(fs, true, dillTarget, uriTranslator);
// Load the dill file containing platform code.
dillTarget.loader.read(Uri.parse('dart:core'), -1, fileUri: sdkSummary);
kernel.Component sdkComponent =
kernel.loadComponentFromBytes(sdkSummaryBytes);
dillTarget.loader
.appendLibraries(sdkComponent, byteCount: sdkSummaryBytes.length);
await dillTarget.buildOutlines();
await c.kernelTarget.buildOutlines();
c.kernelTarget.computeCoreTypes();
assert(c.kernelTarget.loader.coreTypes != null);
// Initialize the typeProvider if types should be resolved.
Map<String, Element> map = <String, Element>{};
var coreTypes = c.kernelTarget.loader.coreTypes;
for (var coreType in [
coreTypes.boolClass,
coreTypes.doubleClass,
coreTypes.functionClass,
coreTypes.futureClass,
coreTypes.futureOrClass,
coreTypes.intClass,
coreTypes.iterableClass,
coreTypes.iteratorClass,
coreTypes.listClass,
coreTypes.mapClass,
coreTypes.nullClass,
coreTypes.numClass,
coreTypes.objectClass,
coreTypes.stackTraceClass,
coreTypes.streamClass,
coreTypes.stringClass,
coreTypes.symbolClass,
coreTypes.typeClass
]) {
map[coreType.name] = _buildElement(coreType);
}
T result;
Completer<T> completer = new Completer<T>();
// Since we're using `package:test_reflective_loader`, we can't rely on
// normal async behavior, as `defineReflectiveSuite` doesn't return a
// future. However, since it's built on top of `package:test`, we can
// obtain a future that completes when all the tests are done using
// `tearDownAll`. This allows this function to complete no earlier than
// when the tests are done. This is important, as we don't want to call
// `CompilerContext.clear` before then.
tearDownAll(() => completer.complete(result));
result = await action(c);
return completer.future;
});
}
static CompilerTestContext get current => CompilerContext.current;
}