CompilerContext always expects a Future now
This change is made because we were incorrectly calling
CompilerContext.clear *before* running the main compilation
task which is async.
Change-Id: I7181af33fe733e5bc653fa742b9e06782f4278d0
Reviewed-on: https://dart-review.googlesource.com/58201
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Dan Rubel <danrubel@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/test/generated/parser_forest_test.dart b/pkg/analyzer/test/generated/parser_forest_test.dart
index b1b4491..e428f1c 100644
--- a/pkg/analyzer/test/generated/parser_forest_test.dart
+++ b/pkg/analyzer/test/generated/parser_forest_test.dart
@@ -9,16 +9,18 @@
import 'parser_test.dart';
main() async {
- defineReflectiveSuite(() {
- defineReflectiveTests(ClassMemberParserTest_Forest);
- defineReflectiveTests(ComplexParserTest_Forest);
- defineReflectiveTests(ErrorParserTest_Forest);
- defineReflectiveTests(ExpressionParserTest_Forest);
- defineReflectiveTests(FormalParameterParserTest_Forest);
- defineReflectiveTests(RecoveryParserTest_Forest);
- defineReflectiveTests(SimpleParserTest_Forest);
- defineReflectiveTests(StatementParserTest_Forest);
- defineReflectiveTests(TopLevelParserTest_Forest);
+ await CompilerTestContext.runWithTestOptions((_) {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ClassMemberParserTest_Forest);
+ defineReflectiveTests(ComplexParserTest_Forest);
+ defineReflectiveTests(ErrorParserTest_Forest);
+ defineReflectiveTests(ExpressionParserTest_Forest);
+ defineReflectiveTests(FormalParameterParserTest_Forest);
+ defineReflectiveTests(RecoveryParserTest_Forest);
+ defineReflectiveTests(SimpleParserTest_Forest);
+ defineReflectiveTests(StatementParserTest_Forest);
+ defineReflectiveTests(TopLevelParserTest_Forest);
+ });
});
}
diff --git a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
index fc243e5..827a00a 100644
--- a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
+++ b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
@@ -40,27 +40,125 @@
import '../../generated/parser_test.dart';
import '../../generated/test_support.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;
+ TypeProvider _typeProvider;
+
+ 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);
+ }
+ Namespace namespace = new Namespace(map);
+ c._typeProvider =
+ new TypeProviderImpl.forNamespaces(namespace, namespace);
+
+ T result;
+ Completer<T> completer = new Completer<T>();
+ tearDownAll(() => completer.complete(result));
+ result = await action(c);
+ return completer.future;
+ });
+ }
+
+ static CompilerTestContext get current => CompilerContext.current;
+}
+
/// Implementation of [AbstractParserTestCase] specialized for testing building
/// Analyzer AST using the fasta [Forest] API.
class FastaBodyBuilderTestCase extends Object
with ParserTestHelpers
implements AbstractParserTestCase {
- // TODO(danrubel): Consider HybridFileSystem.
- static final MemoryFileSystem fs =
- new MemoryFileSystem(Uri.parse("org-dartlang-test:///"));
-
- /// The custom URI used to locate the dill file in the MemoryFileSystem.
- static final Uri sdkSummary = fs.currentDirectory.resolve("vm_platform.dill");
-
- /// The in memory test code URI
- static final Uri entryPoint = fs.currentDirectory.resolve("main.dart");
-
- static ProcessedOptions options;
-
- static KernelTarget kernelTarget;
-
- static TypeProvider _typeProvider;
-
final bool resolveTypes;
String content;
@@ -73,7 +171,7 @@
analyzer.Parser get parser => new ParserProxy(this);
- TypeProvider get typeProvider => _typeProvider;
+ TypeProvider get typeProvider => CompilerTestContext.current._typeProvider;
@override
void assertNoErrors() {
@@ -396,156 +494,68 @@
return statement.variables;
}
- Future setUp() async {
- // TODO(danrubel): Tear down once all tests in group have been run.
- if (options != null) {
- return;
- }
-
- // 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);
- };
-
- options = new ProcessedOptions(optionBuilder, [entryPoint]);
-
- UriTranslatorImpl uriTranslator = await options.getUriTranslator();
-
- await CompilerContext.runWithOptions(options, (CompilerContext c) async {
- DillTarget dillTarget = new DillTarget(
- new Ticker(isVerbose: false), uriTranslator, options.target);
-
- 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 kernelTarget.buildOutlines();
- kernelTarget.computeCoreTypes();
- assert(kernelTarget.loader.coreTypes != null);
-
- // Initialize the typeProvider if types should be resolved.
- Map<String, Element> map = <String, Element>{};
- var coreTypes = 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);
- }
- Namespace namespace = new Namespace(map);
- _typeProvider = new TypeProviderImpl.forNamespaces(namespace, namespace);
- });
- }
-
- 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;
- }
-
T _parse<T>(
String source, void parseFunction(Parser parser, Token previousToken),
{bool inAsync: false, bool inCatchBlock: false}) {
ScannerResult scan = scanString(source);
- return CompilerContext.runWithOptions(options, (CompilerContext c) {
- KernelLibraryBuilder library = new KernelLibraryBuilder(
- entryPoint,
- entryPoint,
- kernelTarget.loader,
- null /* actualOrigin */,
- null /* enclosingLibrary */,
- );
- List<KernelTypeVariableBuilder> typeVariableBuilders =
- <KernelTypeVariableBuilder>[];
- List<KernelFormalParameterBuilder> formalParameterBuilders =
- <KernelFormalParameterBuilder>[];
- KernelProcedureBuilder procedureBuilder = new KernelProcedureBuilder(
- null /* metadata */,
- Modifier.staticMask /* or Modifier.varMask */,
- kernelTarget.dynamicType,
- "analyzerTest",
- typeVariableBuilders,
- formalParameterBuilders,
- kernel.ProcedureKind.Method,
- library,
- -1 /* charOffset */,
- -1 /* charOpenParenOffset */,
- -1 /* charEndOffset */);
-
- TypeInferrerDisabled typeInferrer =
- new TypeInferrerDisabled(new TypeSchemaEnvironment(
- kernelTarget.loader.coreTypes,
- kernelTarget.loader.hierarchy,
- // TODO(danrubel): Enable strong mode.
- false /* strong mode */,
- ));
-
- AstBodyBuilder builder = new AstBodyBuilder(
+ CompilerTestContext c = CompilerTestContext.current;
+ KernelLibraryBuilder library = new KernelLibraryBuilder(
+ c.entryPoint,
+ c.entryPoint,
+ c.kernelTarget.loader,
+ null /* actualOrigin */,
+ null /* enclosingLibrary */,
+ );
+ List<KernelTypeVariableBuilder> typeVariableBuilders =
+ <KernelTypeVariableBuilder>[];
+ List<KernelFormalParameterBuilder> formalParameterBuilders =
+ <KernelFormalParameterBuilder>[];
+ KernelProcedureBuilder procedureBuilder = new KernelProcedureBuilder(
+ null /* metadata */,
+ Modifier.staticMask /* or Modifier.varMask */,
+ c.kernelTarget.dynamicType,
+ "analyzerTest",
+ typeVariableBuilders,
+ formalParameterBuilders,
+ kernel.ProcedureKind.Method,
library,
- procedureBuilder,
- new UnlinkedScope(),
- null,
- kernelTarget.loader.hierarchy,
- kernelTarget.loader.coreTypes,
- null /* classBuilder */,
- false /* isInstanceMember */,
- null /* uri */,
- typeInferrer,
- typeProvider,
- )..constantContext = ConstantContext.none; // .inferred ?
+ -1 /* charOffset */,
+ -1 /* charOpenParenOffset */,
+ -1 /* charEndOffset */);
- Parser parser = new Parser(builder);
- if (inAsync) {
- parser.asyncState = AsyncModifier.Async;
- }
- if (inCatchBlock) {
- builder.inCatchBlock = inCatchBlock;
- }
- parseFunction(parser, parser.syntheticPreviousToken(scan.tokens));
- // TODO(brianwilkerson) Check `expectedEndOffset` if it is not `null`.
- return builder.pop();
- });
+ TypeInferrerDisabled typeInferrer =
+ new TypeInferrerDisabled(new TypeSchemaEnvironment(
+ c.kernelTarget.loader.coreTypes,
+ c.kernelTarget.loader.hierarchy,
+ // TODO(danrubel): Enable strong mode.
+ false /* strong mode */,
+ ));
+
+ AstBodyBuilder builder = new AstBodyBuilder(
+ library,
+ procedureBuilder,
+ new UnlinkedScope(),
+ null,
+ c.kernelTarget.loader.hierarchy,
+ c.kernelTarget.loader.coreTypes,
+ null /* classBuilder */,
+ false /* isInstanceMember */,
+ null /* uri */,
+ typeInferrer,
+ typeProvider,
+ )..constantContext = ConstantContext.none; // .inferred ?
+
+ Parser parser = new Parser(builder);
+ if (inAsync) {
+ parser.asyncState = AsyncModifier.Async;
+ }
+ if (inCatchBlock) {
+ builder.inCatchBlock = inCatchBlock;
+ }
+ parseFunction(parser, parser.syntheticPreviousToken(scan.tokens));
+ // TODO(brianwilkerson) Check `expectedEndOffset` if it is not `null`.
+ return builder.pop();
}
}
diff --git a/pkg/analyzer/test/src/fasta/resolution_test.dart b/pkg/analyzer/test/src/fasta/resolution_test.dart
index 0eedb6b..9105bf8 100644
--- a/pkg/analyzer/test/src/fasta/resolution_test.dart
+++ b/pkg/analyzer/test/src/fasta/resolution_test.dart
@@ -11,8 +11,10 @@
import 'body_builder_test_helper.dart';
main() async {
- defineReflectiveSuite(() {
- defineReflectiveTests(ResolutionTest);
+ await CompilerTestContext.runWithTestOptions((_) {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ResolutionTest);
+ });
});
}
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 1795c7e..2eda950 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -4,7 +4,7 @@
library fasta.compiler_context;
-import 'dart:async' show Zone, runZoned;
+import 'dart:async' show Future, Zone, runZoned;
import 'package:kernel/ast.dart' show Source;
@@ -101,25 +101,23 @@
/// Perform [action] in a [Zone] where [this] will be available as
/// `CompilerContext.current`.
- T runInContext<T>(T action(CompilerContext c)) {
- try {
- return runZoned(() => action(this),
- zoneValues: {compilerContextKey: this});
- } finally {
- clear();
- }
+ Future<T> runInContext<T>(Future<T> action(CompilerContext c)) {
+ return runZoned(
+ () => new Future<T>.sync(() => action(this)).whenComplete(clear),
+ zoneValues: {compilerContextKey: this});
}
/// Perform [action] in a [Zone] where [options] will be available as
/// `CompilerContext.current.options`.
- static T runWithOptions<T>(
- ProcessedOptions options, T action(CompilerContext c)) {
+ static Future<T> runWithOptions<T>(
+ ProcessedOptions options, Future<T> action(CompilerContext c)) {
return new CompilerContext(options).runInContext(action);
}
- static T runWithDefaultOptions<T>(T action(CompilerContext c)) {
- var options = new ProcessedOptions(new CompilerOptions());
- return new CompilerContext(options).runInContext(action);
+ static Future<T> runWithDefaultOptions<T>(
+ Future<T> action(CompilerContext c)) {
+ return new CompilerContext(new ProcessedOptions(new CompilerOptions()))
+ .runInContext(action);
}
static bool get enableColors {
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 0cfc1d8a..2a95602 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -89,7 +89,7 @@
{Uri entryPoint, bool fullComponent: false}) async {
ticker.reset();
entryPoint ??= context.options.inputs.single;
- return context.runInContext<Future<Component>>((CompilerContext c) async {
+ return context.runInContext<Component>((CompilerContext c) async {
IncrementalCompilerData data = new IncrementalCompilerData();
bool bypassCache = false;
diff --git a/pkg/front_end/test/fasta/expression_test.dart b/pkg/front_end/test/fasta/expression_test.dart
index ee56f71..91f716e 100644
--- a/pkg/front_end/test/fasta/expression_test.dart
+++ b/pkg/front_end/test/fasta/expression_test.dart
@@ -66,7 +66,7 @@
MemoryFileSystem get fileSystem => options.fileSystem;
- T runInContext<T>(T action(CompilerContext c)) {
+ Future<T> runInContext<T>(Future<T> action(CompilerContext c)) {
return compilerContext.runInContext<T>(action);
}
diff --git a/pkg/front_end/test/fasta/incremental_test.dart b/pkg/front_end/test/fasta/incremental_test.dart
index 401d89b..d6e5f8d 100644
--- a/pkg/front_end/test/fasta/incremental_test.dart
+++ b/pkg/front_end/test/fasta/incremental_test.dart
@@ -70,7 +70,7 @@
MemoryFileSystem get fileSystem => options.fileSystem;
- T runInContext<T>(T action(CompilerContext c)) {
+ Future<T> runInContext<T>(Future<T> action(CompilerContext c)) {
return compilerContext.runInContext<T>(action);
}
diff --git a/pkg/front_end/tool/_fasta/compile_platform.dart b/pkg/front_end/tool/_fasta/compile_platform.dart
index 1b47a33..fd26f5f 100644
--- a/pkg/front_end/tool/_fasta/compile_platform.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform.dart
@@ -44,8 +44,8 @@
await compilePlatform(arguments);
} on deprecated_InputError catch (e) {
exitCode = 1;
- CompilerContext.runWithDefaultOptions(
- (c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
+ await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
+ () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
return null;
}
}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 026bccd..b2a1d8f 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -121,8 +121,8 @@
return await withGlobalOptions("compile", arguments, true,
(CompilerContext c, _) => batchCompileImpl(c));
} on deprecated_InputError catch (e) {
- CompilerContext.runWithDefaultOptions(
- (c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
+ await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
+ () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
return false;
}
}
@@ -173,8 +173,8 @@
});
} on deprecated_InputError catch (e) {
exitCode = 1;
- CompilerContext.runWithDefaultOptions(
- (c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
+ await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
+ () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
return null;
}
}
@@ -192,8 +192,8 @@
});
} on deprecated_InputError catch (e) {
exitCode = 1;
- CompilerContext.runWithDefaultOptions(
- (c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
+ await CompilerContext.runWithDefaultOptions((c) => new Future<void>.sync(
+ () => c.report(deprecated_InputError.toMessage(e), Severity.error)));
return null;
}
}