mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
CFE support for compiling individual expressions in a context.
Change-Id: I6469fb16e8846eccaeca3f8585872f4b69dd3f1e Reviewed-on: https://dart-review.googlesource.com/38123 Reviewed-by: Kevin Millikin <kmillikin@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
7d5025e814
commit
9038b8f45f
|
@ -4,7 +4,8 @@
|
|||
|
||||
import 'dart:async' show Future;
|
||||
|
||||
import 'package:kernel/kernel.dart' show Component;
|
||||
import 'package:kernel/kernel.dart'
|
||||
show Component, DartType, NamedNode, Procedure, TypeParameter;
|
||||
|
||||
import '../base/processed_options.dart' show ProcessedOptions;
|
||||
|
||||
|
@ -12,8 +13,19 @@ import '../fasta/compiler_context.dart' show CompilerContext;
|
|||
|
||||
import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
|
||||
|
||||
import '../fasta/scanner/string_scanner.dart' show StringScanner;
|
||||
|
||||
import 'compiler_options.dart' show CompilerOptions;
|
||||
|
||||
/// Identifies a position in the source program for expression compilation.
|
||||
///
|
||||
/// Currently this can be either a library-scope or a class-scope. This object
|
||||
/// may also contain references to FE-internal datastructures, so it is
|
||||
/// invalidated by any changes to the Kernel program.
|
||||
abstract class CompilationPosition {
|
||||
final NamedNode kernelNode = null;
|
||||
}
|
||||
|
||||
abstract class IncrementalKernelGenerator {
|
||||
factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint,
|
||||
[Uri bootstrapDill]) {
|
||||
|
@ -30,4 +42,42 @@ abstract class IncrementalKernelGenerator {
|
|||
/// valid files. This guarantees that those files will be re-read on the
|
||||
/// next call to [computeDelta]).
|
||||
void invalidate(Uri uri);
|
||||
|
||||
/// Compile [expression] as an [Expression]. A function returning that
|
||||
/// expression is compiled.
|
||||
///
|
||||
/// [expression] may use the variables supplied in [definitions] as free
|
||||
/// variables and [typeDefinitions] as free type variables. These will become
|
||||
/// required parameters to the compiled function. All elements of
|
||||
/// [definitions] and [typeDefinitions] will become parameters/type
|
||||
/// parameters, whether or not they appear free in [expression]. The type
|
||||
/// parameters should have a null parent pointer.
|
||||
///
|
||||
/// [enclosingNode] must refer to either a [Library] or a [Class] in which
|
||||
/// scope [expression] is compiled. If it refers to a [Class], the flag
|
||||
/// [isStatic] determines whether [expression] may reference "this".
|
||||
///
|
||||
/// It is illegal to use "await" in [expression] and the compiled function
|
||||
/// will always be synchronous.
|
||||
///
|
||||
/// [computeDelta] must have been called at least once prior.
|
||||
///
|
||||
/// [compileExpression] will return [null] if the library or class for
|
||||
/// [enclosingNode] could not be found. Otherwise, errors are reported in the
|
||||
/// normal way.
|
||||
Future<Procedure> compileExpression(
|
||||
String expression,
|
||||
Map<String, DartType> definitions,
|
||||
List<TypeParameter> typeDefinitions,
|
||||
CompilationPosition position,
|
||||
[bool isStatic = false]);
|
||||
|
||||
/// Finds the [CompilationPosition] referenced by [library] and optionally
|
||||
/// [class].
|
||||
CompilationPosition resolveCompilationPosition(Uri library,
|
||||
[String className]);
|
||||
}
|
||||
|
||||
bool isLegalIdentifier(String identifier) {
|
||||
return StringScanner.isLegalIdentifier(identifier);
|
||||
}
|
||||
|
|
|
@ -8,13 +8,25 @@ import 'dart:async' show Future;
|
|||
|
||||
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
|
||||
|
||||
import 'package:kernel/kernel.dart'
|
||||
show Component, Library, LibraryPart, Procedure, Source;
|
||||
|
||||
import '../api_prototype/file_system.dart' show FileSystemEntity;
|
||||
|
||||
import 'package:kernel/kernel.dart'
|
||||
show
|
||||
AsyncMarker,
|
||||
Component,
|
||||
DartType,
|
||||
DynamicType,
|
||||
InterfaceType,
|
||||
Library,
|
||||
LibraryPart,
|
||||
NamedNode,
|
||||
Procedure,
|
||||
ProcedureKind,
|
||||
Source,
|
||||
TypeParameter;
|
||||
|
||||
import '../api_prototype/incremental_kernel_generator.dart'
|
||||
show IncrementalKernelGenerator;
|
||||
show CompilationPosition, isLegalIdentifier, IncrementalKernelGenerator;
|
||||
|
||||
import 'builder/builder.dart' show LibraryBuilder;
|
||||
|
||||
|
@ -31,12 +43,55 @@ import 'kernel/kernel_incremental_target.dart'
|
|||
|
||||
import 'library_graph.dart' show LibraryGraph;
|
||||
|
||||
import 'kernel/kernel_library_builder.dart' show KernelLibraryBuilder;
|
||||
|
||||
import 'source/source_library_builder.dart' show SourceLibraryBuilder;
|
||||
|
||||
import 'ticker.dart' show Ticker;
|
||||
|
||||
import 'uri_translator.dart' show UriTranslator;
|
||||
|
||||
import 'modifier.dart' as Modifier;
|
||||
|
||||
import '../scanner/token.dart' show Token;
|
||||
|
||||
import 'scanner/error_token.dart' show ErrorToken;
|
||||
|
||||
import 'scanner/string_scanner.dart' show StringScanner;
|
||||
|
||||
import 'dill/built_type_builder.dart' show BuiltTypeBuilder;
|
||||
|
||||
import 'kernel/kernel_formal_parameter_builder.dart'
|
||||
show KernelFormalParameterBuilder;
|
||||
|
||||
import 'kernel/kernel_procedure_builder.dart' show KernelProcedureBuilder;
|
||||
|
||||
import 'builder/class_builder.dart' show ClassBuilder;
|
||||
|
||||
import 'kernel/kernel_shadow_ast.dart' show ShadowTypeInferenceEngine;
|
||||
|
||||
import 'kernel/body_builder.dart' show BodyBuilder;
|
||||
|
||||
import 'kernel/kernel_type_variable_builder.dart'
|
||||
show KernelTypeVariableBuilder;
|
||||
|
||||
import 'parser/parser.dart' show Parser;
|
||||
|
||||
import 'parser/member_kind.dart' show MemberKind;
|
||||
|
||||
import 'scope.dart' show Scope;
|
||||
|
||||
import 'type_inference/type_inferrer.dart' show TypeInferrer;
|
||||
|
||||
class IncrementalCompilationPosition implements CompilationPosition {
|
||||
final NamedNode kernelNode;
|
||||
final LibraryBuilder libraryBuilder; // will not be null
|
||||
final ClassBuilder classBuilder; // may be null if not inside a class
|
||||
|
||||
IncrementalCompilationPosition(
|
||||
this.kernelNode, this.libraryBuilder, this.classBuilder);
|
||||
}
|
||||
|
||||
class IncrementalCompiler implements IncrementalKernelGenerator {
|
||||
final CompilerContext context;
|
||||
|
||||
|
@ -46,7 +101,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
|
||||
DillTarget dillLoadedData;
|
||||
Map<Uri, Source> dillLoadedDataUriToSource = <Uri, Source>{};
|
||||
List<LibraryBuilder> platformBuilders;
|
||||
Map<Uri, LibraryBuilder> platformBuilders;
|
||||
Map<Uri, LibraryBuilder> userBuilders;
|
||||
final Uri initializeFromDillUri;
|
||||
bool initializedFromDill = false;
|
||||
|
@ -101,10 +156,10 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
}
|
||||
summaryBytes = null;
|
||||
userBuilders = <Uri, LibraryBuilder>{};
|
||||
platformBuilders = <LibraryBuilder>[];
|
||||
platformBuilders = <Uri, LibraryBuilder>{};
|
||||
dillLoadedData.loader.builders.forEach((uri, builder) {
|
||||
if (builder.uri.scheme == "dart") {
|
||||
platformBuilders.add(builder);
|
||||
platformBuilders[uri] = builder;
|
||||
} else {
|
||||
userBuilders[uri] = builder;
|
||||
}
|
||||
|
@ -132,7 +187,8 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
ticker.logMs("Decided to reuse ${reusedLibraries.length}"
|
||||
" of ${userCode.loader.builders.length} libraries");
|
||||
}
|
||||
reusedLibraries.addAll(platformBuilders);
|
||||
|
||||
reusedLibraries.addAll(platformBuilders.values);
|
||||
|
||||
KernelIncrementalTarget userCodeOld = userCode;
|
||||
userCode = new KernelIncrementalTarget(
|
||||
|
@ -168,8 +224,11 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
return new Component(
|
||||
libraries: compiledLibraries, uriToSource: <Uri, Source>{});
|
||||
}
|
||||
userCodeOld?.loader?.builders?.clear();
|
||||
userCodeOld = null;
|
||||
if (componentWithDill != null) {
|
||||
userCodeOld?.loader?.releaseAncillaryResources();
|
||||
userCodeOld?.loader?.builders?.clear();
|
||||
userCodeOld = null;
|
||||
}
|
||||
|
||||
List<Library> compiledLibraries =
|
||||
new List<Library>.from(userCode.loader.libraries);
|
||||
|
@ -188,8 +247,10 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
outputLibraries = compiledLibraries;
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
userCode.loader.releaseAncillaryResources();
|
||||
if (componentWithDill == null) {
|
||||
userCode.loader.builders.clear();
|
||||
userCode = userCodeOld;
|
||||
}
|
||||
|
||||
// This is the incremental component.
|
||||
return new Component(libraries: outputLibraries, uriToSource: uriToSource)
|
||||
|
@ -318,6 +379,194 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
ticker.logMs("Appended libraries");
|
||||
}
|
||||
|
||||
IncrementalCompilationPosition resolveCompilationPosition(Uri libraryUri,
|
||||
[String className]) {
|
||||
if (userCode == null || dillLoadedData == null) return null;
|
||||
|
||||
// Find library.
|
||||
LibraryBuilder enclosingLibrary = userCode.loader.builders[libraryUri];
|
||||
if (enclosingLibrary == null) return null;
|
||||
|
||||
if (className == null) {
|
||||
return new IncrementalCompilationPosition(
|
||||
enclosingLibrary.target, enclosingLibrary, null);
|
||||
}
|
||||
|
||||
ClassBuilder classBuilder = enclosingLibrary.scopeBuilder[className];
|
||||
if (classBuilder == null) return null;
|
||||
|
||||
return new IncrementalCompilationPosition(
|
||||
classBuilder.target, enclosingLibrary, classBuilder);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Procedure> compileExpression(
|
||||
String expression,
|
||||
Map<String, DartType> definitions,
|
||||
List<TypeParameter> typeDefinitions,
|
||||
covariant IncrementalCompilationPosition position,
|
||||
[bool isStatic = false]) async {
|
||||
assert(dillLoadedData != null && userCode != null);
|
||||
|
||||
dillLoadedData.loader.seenMessages.clear();
|
||||
userCode.loader.seenMessages.clear();
|
||||
|
||||
for (TypeParameter typeParam in typeDefinitions) {
|
||||
if (!isLegalIdentifier(typeParam.name)) return null;
|
||||
}
|
||||
for (String name in definitions.keys) {
|
||||
if (!isLegalIdentifier(name)) return null;
|
||||
}
|
||||
|
||||
String expressionPrefix =
|
||||
'(${definitions.keys.map((name) => "dynamic $name").join(",")}) =>';
|
||||
|
||||
return context.runInContext((CompilerContext c) async {
|
||||
// Find library builder or report error.
|
||||
bool inClass = position.classBuilder != null;
|
||||
LibraryBuilder enclosingLibraryBuilder = position.libraryBuilder;
|
||||
ClassBuilder classBuilder = position.classBuilder;
|
||||
Library enclosingLibrary = position.libraryBuilder.target;
|
||||
|
||||
dillLoadedData.loader.coreTypes = userCode.loader.coreTypes;
|
||||
|
||||
// Create a synthetic KernelLibraryBuilder to hold the compiled procedure.
|
||||
// This ensures that the uri and character offset positions inside the
|
||||
// expression refer to the the expression text, and not to random
|
||||
// positions in the enclosing library's source.
|
||||
Uri debugExprUri = new Uri(
|
||||
scheme: "org-dartlang-debug", path: "synthetic_debug_expression");
|
||||
KernelLibraryBuilder kernelLibraryBuilder = new KernelLibraryBuilder(
|
||||
debugExprUri,
|
||||
debugExprUri,
|
||||
userCode.loader,
|
||||
/*actualOrigin=*/ null,
|
||||
enclosingLibrary);
|
||||
|
||||
// Parse the function prefix.
|
||||
StringScanner scanner = new StringScanner(expressionPrefix);
|
||||
Token startToken = scanner.tokenize();
|
||||
assert(startToken is! ErrorToken);
|
||||
assert(!scanner.hasErrors);
|
||||
|
||||
// Parse the expression. By parsing the expression separately from the
|
||||
// function prefix, we ensure that the offsets for tokens coming from the
|
||||
// expression are correct.
|
||||
scanner = new StringScanner(expression);
|
||||
Token expressionStartToken = scanner.tokenize();
|
||||
while (expressionStartToken is ErrorToken) {
|
||||
ErrorToken token = expressionStartToken;
|
||||
// add compile time error
|
||||
kernelLibraryBuilder.addCompileTimeError(token.assertionMessage,
|
||||
token.charOffset, token.endOffset - token.charOffset, debugExprUri);
|
||||
}
|
||||
|
||||
var functionLastToken = startToken;
|
||||
while (!functionLastToken.next.isEof) {
|
||||
functionLastToken.offset = -1;
|
||||
functionLastToken = functionLastToken.next;
|
||||
}
|
||||
functionLastToken.offset = -1;
|
||||
|
||||
functionLastToken.next = expressionStartToken;
|
||||
expressionStartToken.previous = functionLastToken;
|
||||
|
||||
// If we're in a library loaded from a dill file, we'll have to do some
|
||||
// extra work to get the scope setup.
|
||||
if (enclosingLibraryBuilder is DillLibraryBuilder) {
|
||||
dillLoadedData.loader.buildOutline(enclosingLibraryBuilder);
|
||||
Map<Uri, LibraryBuilder> libraries = <Uri, LibraryBuilder>{};
|
||||
if (userBuilders != null) libraries.addAll(userBuilders);
|
||||
libraries.addAll(platformBuilders);
|
||||
enclosingLibraryBuilder.addImportsToScope(libraries);
|
||||
}
|
||||
Scope scope =
|
||||
inClass ? classBuilder.scope : enclosingLibraryBuilder.scope;
|
||||
|
||||
// Create a [ProcedureBuilder] and a [BodyBuilder] to parse the expression.
|
||||
dynamicType() => new BuiltTypeBuilder(new DynamicType());
|
||||
List<KernelFormalParameterBuilder> formalParameterBuilders =
|
||||
<KernelFormalParameterBuilder>[];
|
||||
definitions.forEach((name, type) {
|
||||
formalParameterBuilders.add(new KernelFormalParameterBuilder(
|
||||
null,
|
||||
Modifier.varMask,
|
||||
new BuiltTypeBuilder(type),
|
||||
name,
|
||||
false,
|
||||
kernelLibraryBuilder,
|
||||
-1));
|
||||
});
|
||||
List<KernelTypeVariableBuilder> typeVariableBuilders =
|
||||
<KernelTypeVariableBuilder>[];
|
||||
typeDefinitions.forEach((TypeParameter typeParam) {
|
||||
typeVariableBuilders.add(new KernelTypeVariableBuilder(
|
||||
typeParam.name,
|
||||
kernelLibraryBuilder,
|
||||
-1,
|
||||
new BuiltTypeBuilder(typeParam.bound),
|
||||
typeParam));
|
||||
});
|
||||
KernelProcedureBuilder procedureBuilder = new KernelProcedureBuilder(
|
||||
/*metadata=*/ null,
|
||||
isStatic ? Modifier.staticMask : Modifier.varMask,
|
||||
dynamicType(),
|
||||
"debugExpr",
|
||||
typeVariableBuilders,
|
||||
formalParameterBuilders,
|
||||
ProcedureKind.Method,
|
||||
kernelLibraryBuilder,
|
||||
/*charOffset=*/ -1,
|
||||
/*charOpenParenOffset=*/ -1,
|
||||
/*charEndOffset=*/ -1);
|
||||
Procedure procedure = procedureBuilder.build(kernelLibraryBuilder);
|
||||
procedure.parent =
|
||||
inClass ? classBuilder.target : kernelLibraryBuilder.target;
|
||||
scope = procedureBuilder.computeTypeParameterScope(scope);
|
||||
Scope formalParamScope =
|
||||
procedureBuilder.computeFormalParameterScope(scope);
|
||||
var typeInferenceEngine = new ShadowTypeInferenceEngine(
|
||||
null, /*strongMode=*/ context.options.strongMode);
|
||||
typeInferenceEngine.prepareTopLevel(
|
||||
userCode.loader.coreTypes, userCode.loader.hierarchy);
|
||||
InterfaceType thisType;
|
||||
if (inClass) {
|
||||
thisType = classBuilder.target.thisType;
|
||||
}
|
||||
TypeInferrer typeInferrer = typeInferenceEngine.createLocalTypeInferrer(
|
||||
debugExprUri, thisType, kernelLibraryBuilder);
|
||||
BodyBuilder bodyBuilder = new BodyBuilder(
|
||||
kernelLibraryBuilder,
|
||||
procedureBuilder,
|
||||
scope,
|
||||
formalParamScope,
|
||||
userCode.loader.hierarchy,
|
||||
userCode.loader.coreTypes,
|
||||
classBuilder,
|
||||
inClass && !isStatic,
|
||||
null /*uri*/,
|
||||
typeInferrer);
|
||||
bodyBuilder.scope = formalParamScope;
|
||||
|
||||
// Parse the expression.
|
||||
MemberKind kind = inClass
|
||||
? (isStatic ? MemberKind.StaticMethod : MemberKind.NonStaticMethod)
|
||||
: MemberKind.TopLevelMethod;
|
||||
Parser parser = new Parser(bodyBuilder);
|
||||
Token token = parser.syntheticPreviousToken(startToken);
|
||||
token = parser.parseFormalParametersOpt(token, kind);
|
||||
var formals = bodyBuilder.pop();
|
||||
bodyBuilder.checkEmpty(token.next.charOffset);
|
||||
parser.parseFunctionBody(
|
||||
token, /*isExpression=*/ true, /*allowAbstract=*/ false);
|
||||
var body = bodyBuilder.pop();
|
||||
bodyBuilder.checkEmpty(token.charOffset);
|
||||
bodyBuilder.finishFunction([], formals, AsyncMarker.Sync, body);
|
||||
|
||||
return procedure;
|
||||
});
|
||||
}
|
||||
|
||||
List<LibraryBuilder> computeReusedLibraries(
|
||||
Set<Uri> invalidatedUris, UriTranslator uriTranslator) {
|
||||
if (userCode == null && userBuilders == null) {
|
||||
|
|
|
@ -111,8 +111,11 @@ class KernelLibraryBuilder
|
|||
/// the error message is the corresponding value in the map.
|
||||
Map<String, String> unserializableExports;
|
||||
|
||||
KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin)
|
||||
: library = actualOrigin?.library ?? new Library(uri, fileUri: fileUri),
|
||||
KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin,
|
||||
[Library intendedTarget])
|
||||
: library = intendedTarget ??
|
||||
actualOrigin?.library ??
|
||||
new Library(uri, fileUri: fileUri),
|
||||
super(loader, fileUri);
|
||||
|
||||
@override
|
||||
|
|
|
@ -29,9 +29,12 @@ class KernelTypeVariableBuilder
|
|||
|
||||
KernelTypeVariableBuilder(
|
||||
String name, KernelLibraryBuilder compilationUnit, int charOffset,
|
||||
[KernelTypeBuilder bound])
|
||||
: actualParameter = new TypeParameter(name, null)
|
||||
..fileOffset = charOffset,
|
||||
[KernelTypeBuilder bound, TypeParameter actual])
|
||||
// TODO(32378): We would like to use '??' here instead, but in conjuction
|
||||
// with '..', it crashes Dart2JS.
|
||||
: actualParameter = actual != null
|
||||
? (actual..fileOffset = charOffset)
|
||||
: (new TypeParameter(name, null)..fileOffset = charOffset),
|
||||
super(name, bound, compilationUnit, charOffset);
|
||||
|
||||
@override
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
library dart2js.scanner.string_scanner;
|
||||
|
||||
import '../../scanner/token.dart' show SyntheticStringToken, TokenType;
|
||||
import '../../scanner/token.dart' show SyntheticStringToken, Token, TokenType;
|
||||
|
||||
import '../../scanner/token.dart' as analyzer show StringToken;
|
||||
|
||||
|
@ -12,6 +12,8 @@ import 'array_based_scanner.dart' show ArrayBasedScanner;
|
|||
|
||||
import 'token.dart' show CommentToken, DartDocToken, StringToken;
|
||||
|
||||
import 'error_token.dart' show ErrorToken;
|
||||
|
||||
/**
|
||||
* Scanner that reads from a String and creates tokens that points to
|
||||
* substrings.
|
||||
|
@ -37,6 +39,12 @@ class StringScanner extends ArrayBasedScanner {
|
|||
: string;
|
||||
}
|
||||
|
||||
static bool isLegalIdentifier(String identifier) {
|
||||
StringScanner scanner = new StringScanner(identifier);
|
||||
Token startToken = scanner.tokenize();
|
||||
return startToken is! ErrorToken && startToken.next.isEof;
|
||||
}
|
||||
|
||||
int advance() => string.codeUnitAt(++scanOffset);
|
||||
int peek() => string.codeUnitAt(scanOffset + 1);
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import "package:kernel/ast.dart"
|
|||
show
|
||||
Procedure,
|
||||
Component,
|
||||
CanonicalName,
|
||||
DynamicType,
|
||||
DartType,
|
||||
TypeParameter;
|
||||
|
@ -42,7 +41,7 @@ import 'package:front_end/src/base/processed_options.dart'
|
|||
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
|
||||
|
||||
import 'package:front_end/src/fasta/incremental_compiler.dart'
|
||||
show IncrementalCompiler;
|
||||
show IncrementalCompiler, IncrementalCompilationPosition;
|
||||
|
||||
import 'package:kernel/text/ast_to_text.dart' show Printer;
|
||||
|
||||
|
@ -123,7 +122,9 @@ class TestCase {
|
|||
|
||||
final bool isStaticMethod;
|
||||
|
||||
final CanonicalName enclosingNode;
|
||||
final Uri library;
|
||||
|
||||
final String className;
|
||||
|
||||
String expression;
|
||||
|
||||
|
@ -135,7 +136,8 @@ class TestCase {
|
|||
this.definitions,
|
||||
this.typeDefinitions,
|
||||
this.isStaticMethod,
|
||||
this.enclosingNode,
|
||||
this.library,
|
||||
this.className,
|
||||
this.expression);
|
||||
|
||||
String toString() {
|
||||
|
@ -143,7 +145,8 @@ class TestCase {
|
|||
"$entryPoint, "
|
||||
"$definitions, "
|
||||
"$typeDefinitions,"
|
||||
"$enclosingNode, "
|
||||
"$library, "
|
||||
"$className, "
|
||||
"static = $isStaticMethod)";
|
||||
}
|
||||
|
||||
|
@ -155,7 +158,7 @@ class TestCase {
|
|||
if (!(new File.fromUri(entryPoint)).existsSync()) {
|
||||
return "Entry point $entryPoint doesn't exist.";
|
||||
}
|
||||
if (enclosingNode == null || enclosingNode == "") {
|
||||
if (library == null) {
|
||||
return "No enclosing node.";
|
||||
}
|
||||
if (expression == null) {
|
||||
|
@ -233,7 +236,8 @@ class ReadTest extends Step<TestDescription, List<TestCase>, Context> {
|
|||
List<String> definitions = <String>[];
|
||||
List<String> typeDefinitions = <String>[];
|
||||
bool isStaticMethod = false;
|
||||
CanonicalName enclosingNode;
|
||||
Uri library;
|
||||
String className;
|
||||
String expression;
|
||||
|
||||
dynamic maps = loadYamlNode(contents, sourceUrl: uri);
|
||||
|
@ -248,13 +252,10 @@ class ReadTest extends Step<TestDescription, List<TestCase>, Context> {
|
|||
if (key == "entry_point") {
|
||||
entryPoint = description.uri.resolveUri(Uri.parse(value as String));
|
||||
} else if (key == "position") {
|
||||
Uri positionUri =
|
||||
description.uri.resolveUri(Uri.parse(value as String));
|
||||
enclosingNode = new CanonicalName.root();
|
||||
enclosingNode =
|
||||
enclosingNode.getChild("${positionUri.removeFragment()}");
|
||||
if (positionUri.fragment != null && positionUri.fragment != '') {
|
||||
enclosingNode = enclosingNode.getChild(positionUri.fragment);
|
||||
Uri uri = description.uri.resolveUri(Uri.parse(value as String));
|
||||
library = uri.removeFragment();
|
||||
if (uri.fragment != null && uri.fragment != '') {
|
||||
className = uri.fragment;
|
||||
}
|
||||
} else if (key == "definitions") {
|
||||
definitions = (value as YamlList).map((x) => x as String).toList();
|
||||
|
@ -268,7 +269,7 @@ class ReadTest extends Step<TestDescription, List<TestCase>, Context> {
|
|||
}
|
||||
}
|
||||
var test = new TestCase(description, entryPoint, definitions,
|
||||
typeDefinitions, isStaticMethod, enclosingNode, expression);
|
||||
typeDefinitions, isStaticMethod, library, className, expression);
|
||||
var result = test.validate();
|
||||
if (result != null) {
|
||||
return new Result.fail(tests, result);
|
||||
|
@ -325,9 +326,15 @@ class CompileExpression extends Step<List<TestCase>, List<TestCase>, Context> {
|
|||
}
|
||||
|
||||
for (var compiler in [sourceCompiler, dillCompiler]) {
|
||||
// TODO: actually run the compiler
|
||||
test.results
|
||||
.add(new CompilationResult(compiler == null ? null : null, []));
|
||||
IncrementalCompilationPosition enclosingNode =
|
||||
compiler.resolveCompilationPosition(test.library, test.className);
|
||||
Procedure compiledProcedure;
|
||||
if (enclosingNode != null) {
|
||||
compiledProcedure = await compiler.compileExpression(test.expression,
|
||||
definitions, typeParams, enclosingNode, test.isStaticMethod);
|
||||
}
|
||||
var errors = context.takeErrors();
|
||||
test.results.add(new CompilationResult(compiledProcedure, errors));
|
||||
}
|
||||
}
|
||||
return new Result.pass(tests);
|
||||
|
@ -357,7 +364,7 @@ Future<Context> createContext(
|
|||
final List<CompilationMessage> errors = <CompilationMessage>[];
|
||||
|
||||
final CompilerOptions optionBuilder = new CompilerOptions()
|
||||
..strongMode = false
|
||||
..strongMode = true
|
||||
..reportMessages = true
|
||||
..verbose = true
|
||||
..fileSystem = fs
|
||||
|
|
|
@ -49,6 +49,7 @@ final subpackageRules = {
|
|||
'lib/src/base',
|
||||
'lib/src/byte_store',
|
||||
'lib/src/fasta',
|
||||
'lib/src/fasta/scanner'
|
||||
]),
|
||||
'lib/src/api_unstable': new SubpackageRules(allowedDependencies: [
|
||||
'lib/src',
|
||||
|
@ -75,6 +76,7 @@ final subpackageRules = {
|
|||
'lib/src/fasta/scanner',
|
||||
'lib/src/fasta/source',
|
||||
'lib/src/fasta/util',
|
||||
'lib/src/fasta/type_inference',
|
||||
'lib/src/scanner',
|
||||
]),
|
||||
'lib/src/fasta/builder': new SubpackageRules(allowedDependencies: [
|
||||
|
|
|
@ -1,47 +1,3 @@
|
|||
// 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.
|
||||
|
||||
class_capture.expression: Fail
|
||||
class_getter.expression: Fail
|
||||
class_invalid_static.expression: Fail
|
||||
class_invalid_static_capture.expression: Fail
|
||||
class_invalid_static_getter.expression: Fail
|
||||
class_invalid_static_setter.expression: Fail
|
||||
class_method.expression: Fail
|
||||
class_setter.expression: Fail
|
||||
class_static.expression: Fail
|
||||
class_static2.expression: Fail
|
||||
class_static3.expression: Fail
|
||||
class_type_param_bound.expression: Fail
|
||||
class_type_param_bound_illegal.expression: Fail
|
||||
class_type_param_reference.expression: Fail
|
||||
class_type_param_reference_arg.expression: Fail
|
||||
class_type_param_reference_arg_inferred.expression: Fail
|
||||
class_type_param_reference_ctor.expression: Fail
|
||||
class_type_param_reference_ctor_inferred.expression: Fail
|
||||
class_type_param_reference_var.expression: Fail
|
||||
core_lib_imported.expression: Fail
|
||||
core_lib_internal.expression: Fail
|
||||
eval.dart: Fail
|
||||
invalid.expression: Fail
|
||||
lib_ctor.expression: Fail
|
||||
lib_external_ctor.expression: Fail
|
||||
lib_nonctor.expression: Fail
|
||||
lib_nonreference.expression: Fail
|
||||
lib_nonshown_ctor.expression: Fail
|
||||
lib_reference.expression: Fail
|
||||
lib_simple.expression: Fail
|
||||
missing_variable_types.expression: Fail
|
||||
param_assign.expression: Fail
|
||||
param_capture.expression: Fail
|
||||
param_conflict.expression: Fail
|
||||
param_conflict_class.expression: Fail
|
||||
param_method.expression: Fail
|
||||
type_param_bound.expression: Fail
|
||||
type_param_shadow.expression: Fail
|
||||
type_param_shadow_arg.expression: Fail
|
||||
type_param_shadow_arg_ctor_inferred.expression: Fail
|
||||
type_param_shadow_arg_inferred.expression: Fail
|
||||
type_param_shadow_ctor.expression: Fail
|
||||
type_param_shadow_var.expression: Fail
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// 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.
|
||||
|
||||
library main;
|
||||
|
||||
import 'dart:io' show File, Process, exit;
|
||||
|
|
|
@ -3,5 +3,5 @@ Errors: {
|
|||
}
|
||||
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
|
||||
return () → dart.core::Null {
|
||||
main::A::debugExpr::T k = let final dynamic #t1 = new main::A::•<dynamic>() in let dynamic _ = null in invalid-expression "Error: A value of type 'main::A<dynamic>' can't be assigned to a variable of type 'main::A::debugExpr::T'.\nTry changing the type of the left hand side, or casting the right hand side to 'main::A::debugExpr::T'.";
|
||||
main::A::debugExpr::T k = let final dynamic #t1 = let dynamic _ = null in invalid-expression "Error: A value of type 'main::A<dynamic>' can't be assigned to a variable of type 'main::A::debugExpr::T'.\nTry changing the type of the left hand side, or casting the right hand side to 'main::A::debugExpr::T'." in let final dynamic #t2 = new main::A::•<dynamic>() in null;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue