mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:10:22 +00:00
Implement line and column numbers.
R=karlklose@google.com Review-Url: https://codereview.chromium.org/2704753002 .
This commit is contained in:
parent
fd918a2725
commit
d32f47b293
|
@ -53,15 +53,18 @@ class AstBuilder extends ScopeListener {
|
|||
|
||||
bool isFirstIdentifier = false;
|
||||
|
||||
@override
|
||||
final Uri uri;
|
||||
|
||||
/// If `true`, the first call to [handleIdentifier] should push a
|
||||
/// List<SimpleIdentifier> on the stack, and [handleQualified] should append
|
||||
/// to the list.
|
||||
var accumulateIdentifierComponents = false;
|
||||
|
||||
AstBuilder(this.library, this.member, this.elementStore, Scope scope)
|
||||
: super(scope);
|
||||
|
||||
Uri get uri => library.fileUri ?? library.uri;
|
||||
AstBuilder(this.library, this.member, this.elementStore, Scope scope,
|
||||
[Uri uri])
|
||||
: uri = uri ?? library.fileUri, super(scope);
|
||||
|
||||
createJumpTarget(JumpTargetKind kind, int charOffset) {
|
||||
// TODO(ahe): Implement jump targets.
|
||||
|
|
|
@ -12,9 +12,11 @@ import 'package:front_end/src/fasta/ast_kind.dart' show
|
|||
import 'package:front_end/src/fasta/compiler_command_line.dart' show
|
||||
CompilerCommandLine;
|
||||
|
||||
import 'package:front_end/src/fasta/compiler_context.dart' show
|
||||
CompilerContext;
|
||||
|
||||
import 'package:front_end/src/fasta/outline.dart' show
|
||||
doCompile,
|
||||
parseArguments;
|
||||
doCompile;
|
||||
|
||||
import 'package:front_end/src/fasta/errors.dart' show
|
||||
InputError;
|
||||
|
@ -29,20 +31,23 @@ const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
|
|||
|
||||
main(List<String> arguments) async {
|
||||
Uri uri;
|
||||
CompilerCommandLine cl;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
if (i > 0) {
|
||||
print("\n");
|
||||
}
|
||||
try {
|
||||
cl = parseArguments("run", arguments);
|
||||
uri =
|
||||
await doCompile(cl, new Ticker(isVerbose:cl.verbose), AstKind.Kernel);
|
||||
} on InputError catch (e) {
|
||||
print(e.format());
|
||||
exit(1);
|
||||
}
|
||||
if (exitCode != 0) exit(exitCode);
|
||||
await CompilerCommandLine.withGlobalOptions(
|
||||
"run", arguments, (CompilerContext c) async {
|
||||
if (i > 0) {
|
||||
print("\n");
|
||||
}
|
||||
try {
|
||||
uri = await doCompile(c, new Ticker(isVerbose: c.options.verbose),
|
||||
AstKind.Kernel);
|
||||
} on InputError catch (e) {
|
||||
print(e.format());
|
||||
exit(1);
|
||||
}
|
||||
if (exitCode != 0) exit(exitCode);
|
||||
if (i + 1 == iterations) {
|
||||
exit(await run(uri, c));
|
||||
}
|
||||
});
|
||||
}
|
||||
exit(await run(uri, cl));
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ library fasta.builder;
|
|||
import '../errors.dart' show
|
||||
internalError;
|
||||
|
||||
import '../messages.dart' show
|
||||
nit;
|
||||
|
||||
export 'class_builder.dart' show
|
||||
ClassBuilder;
|
||||
|
||||
|
@ -127,16 +130,17 @@ abstract class Builder {
|
|||
preferred = other;
|
||||
hidden = this;
|
||||
} else {
|
||||
print("${library.uri}: Note: '$name' is imported from both "
|
||||
nit(library.fileUri, -1, "'$name' is imported from both "
|
||||
"'${getUri(this)}' and '${getUri(other)}'.");
|
||||
return library.buildAmbiguousBuilder(name, this, other, charOffset);
|
||||
}
|
||||
if (isLocal) {
|
||||
print("${library.uri}: Note: local definition of '$name' hides imported "
|
||||
nit(library.fileUri, -1, "Local definition of '$name' hides imported "
|
||||
"version from '${getUri(other)}'.");
|
||||
} else {
|
||||
print("${library.uri}: import of '$name' (from '${getUri(preferred)}') "
|
||||
"hides imported version from '${getUri(hidden)}'.");
|
||||
nit(library.fileUri, -1, "Import of '$name' "
|
||||
"(from '${getUri(preferred)}') hides imported version from "
|
||||
"'${getUri(hidden)}'.");
|
||||
}
|
||||
return preferred;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@ import 'builder.dart' show
|
|||
Builder,
|
||||
TypeBuilder;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import 'scope.dart' show
|
||||
Scope;
|
||||
|
||||
|
@ -54,7 +57,7 @@ class ConstructorReferenceBuilder extends Builder {
|
|||
target = builder.constructors[suffix ?? ""];
|
||||
}
|
||||
if (target == null) {
|
||||
print("Couldn't find constructor $fullNameForErrors.");
|
||||
warning(null, -1, "Couldn't find constructor '$fullNameForErrors'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ import 'builder.dart' show
|
|||
LibraryBuilder,
|
||||
MemberBuilder;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import 'package:kernel/ast.dart' show
|
||||
Member;
|
||||
|
||||
|
@ -32,8 +35,8 @@ class PrefixBuilder extends Builder {
|
|||
// TODO(ahe): Move this to KernelPrefixBuilder.
|
||||
Builder builder = exports[name];
|
||||
if (builder == null) {
|
||||
// TODO(ahe): Report error?
|
||||
print("${this.name} has no member named $name");
|
||||
warning(parent.fileUri, -1,
|
||||
"'${this.name}' has no member named '$name'.");
|
||||
}
|
||||
if (builder is DillMemberBuilder) {
|
||||
return builder.member.isInstanceMember
|
||||
|
|
|
@ -11,11 +11,15 @@ import 'command_line.dart' show
|
|||
CommandLine,
|
||||
argumentError;
|
||||
|
||||
import 'compiler_context.dart' show
|
||||
CompilerContext;
|
||||
|
||||
const Map<String, dynamic> optionSpecification = const <String, dynamic>{
|
||||
"-o": Uri,
|
||||
"--output": Uri,
|
||||
"--platform": Uri,
|
||||
"--packages": Uri,
|
||||
"--fatal": ",",
|
||||
};
|
||||
|
||||
class CompilerCommandLine extends CommandLine {
|
||||
|
@ -65,6 +69,26 @@ class CompilerCommandLine extends CommandLine {
|
|||
? null
|
||||
: options["--platform"] ?? Uri.base.resolve("platform.dill");
|
||||
}
|
||||
|
||||
Set<String> get fatal {
|
||||
return new Set<String>.from(options["--fatal"] ?? <String>[]);
|
||||
}
|
||||
|
||||
bool get areErrorsFatal => fatal.contains("errors");
|
||||
|
||||
bool get areWarningsFatal => fatal.contains("warnings");
|
||||
|
||||
bool get areNitsFatal => fatal.contains("nits");
|
||||
|
||||
static dynamic withGlobalOptions(String programName, List<String> arguments,
|
||||
dynamic f(CompilerContext context)) {
|
||||
return CompilerContext.withGlobalOptions(
|
||||
new CompilerCommandLine(programName, arguments), f);
|
||||
}
|
||||
|
||||
static CompilerCommandLine forRootContext() {
|
||||
return new CompilerCommandLine("", [""]);
|
||||
}
|
||||
}
|
||||
|
||||
String computeUsage(String programName, bool verbose) {
|
||||
|
@ -140,4 +164,12 @@ Supported options:
|
|||
|
||||
--compile-sdk
|
||||
Compile the SDK from scratch instead of reading it from 'platform.dill'.
|
||||
|
||||
--fatal=errors
|
||||
--fatal=warnings
|
||||
--fatal=nits
|
||||
Makes messages of the given kinds fatal, that is, immediately stop the
|
||||
compiler with a non-zero exit-code. In --verbose mode, also display an
|
||||
internal stack trace from the compiler. Multiple kinds can be separated by
|
||||
commas, for example, --fatal=errors,warnings.
|
||||
""";
|
||||
|
|
40
pkg/front_end/lib/src/fasta/compiler_context.dart
Normal file
40
pkg/front_end/lib/src/fasta/compiler_context.dart
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2017, 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 fasta.compiler_context;
|
||||
|
||||
import 'dart:async' show
|
||||
Zone,
|
||||
runZoned;
|
||||
|
||||
import 'package:kernel/ast.dart' show
|
||||
Source;
|
||||
|
||||
import 'compiler_command_line.dart' show
|
||||
CompilerCommandLine;
|
||||
|
||||
final Object compilerContextKey = new Object();
|
||||
|
||||
final CompilerContext rootContext =
|
||||
new CompilerContext(CompilerCommandLine.forRootContext());
|
||||
|
||||
class CompilerContext {
|
||||
final CompilerCommandLine options;
|
||||
|
||||
final Map<String, Source> uriToSource = <String, Source>{};
|
||||
|
||||
CompilerContext(this.options);
|
||||
|
||||
static CompilerContext get current {
|
||||
return Zone.current[compilerContextKey] ?? rootContext;
|
||||
}
|
||||
|
||||
/// Perform [action] in a [Zone] where [cl] will be available as
|
||||
/// `CompilerContext.current.options`.
|
||||
static dynamic withGlobalOptions(CompilerCommandLine cl,
|
||||
dynamic action(CompilerContext c)) {
|
||||
CompilerContext c = new CompilerContext(cl);
|
||||
return runZoned(() => action(c), zoneValues: {compilerContextKey: c});
|
||||
}
|
||||
}
|
|
@ -45,6 +45,10 @@ class DillTarget extends TargetImplementation {
|
|||
loader = new DillLoader(this);
|
||||
}
|
||||
|
||||
void addLineStarts(Uri uri, List<int> lineStarts) {
|
||||
internalError("Unsupported operation.");
|
||||
}
|
||||
|
||||
void read(Uri uri) {
|
||||
if (loader.input == null) {
|
||||
loader.input = uri;
|
||||
|
|
|
@ -20,8 +20,7 @@ import 'dart:io' show
|
|||
import 'colors.dart' show
|
||||
red;
|
||||
|
||||
import 'util/relativize.dart' show
|
||||
relativizeUri;
|
||||
import 'messages.dart' as messages;
|
||||
|
||||
const String defaultServerAddress = "http://127.0.0.1:59410/";
|
||||
|
||||
|
@ -41,8 +40,13 @@ Uri firstSourceUri;
|
|||
/// error: " and a short description that may help a developer debug the issue.
|
||||
/// This method should be called instead of using `throw`, as this allows us to
|
||||
/// ensure that there are no throws anywhere in the codebase.
|
||||
dynamic internalError(Object error) {
|
||||
throw error;
|
||||
dynamic internalError(Object error, [Uri uri, int charOffset = -1]) {
|
||||
if (uri == null && charOffset == -1) {
|
||||
throw error;
|
||||
} else {
|
||||
throw messages.format(
|
||||
uri, charOffset, "Internal error: ${safeToString(error)}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to report an error in input.
|
||||
|
@ -58,6 +62,12 @@ dynamic inputError(Uri uri, int charOffset, Object error) {
|
|||
throw new InputError(uri, charOffset, error);
|
||||
}
|
||||
|
||||
String colorError(String message) {
|
||||
// TODO(ahe): Colors need to be optional. Doesn't work well in Emacs or on
|
||||
// Windows.
|
||||
return red(message);
|
||||
}
|
||||
|
||||
class InputError {
|
||||
final Uri uri;
|
||||
|
||||
|
@ -71,15 +81,8 @@ class InputError {
|
|||
toString() => "InputError: $error";
|
||||
|
||||
String format() {
|
||||
// TODO(ahe): Colors need to be optional. Doesn't work well in Emacs or on
|
||||
// Windows.
|
||||
String message = red("Error: ${safeToString(error)}");
|
||||
if (uri != null) {
|
||||
String position = charOffset == -1 ? "" : "$charOffset:";
|
||||
return "${relativizeUri(uri)}:$position $message";
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
return messages.format(
|
||||
uri, charOffset, colorError("Error: ${safeToString(error)}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,8 +79,6 @@ import 'redirecting_factory_body.dart' show
|
|||
|
||||
import 'kernel_builder.dart';
|
||||
|
||||
const bool showNits = false;
|
||||
|
||||
final Name callName = new Name("call");
|
||||
|
||||
final Name plusName = new Name("+");
|
||||
|
@ -126,6 +124,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
|
||||
final bool isDartLibrary;
|
||||
|
||||
@override
|
||||
final Uri uri;
|
||||
|
||||
Scope formalParameterScope;
|
||||
|
||||
bool isFirstIdentifier = false;
|
||||
|
@ -148,7 +149,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
|
||||
BodyBuilder(KernelLibraryBuilder library, this.member, Scope scope,
|
||||
this.formalParameterScope, this.hierarchy, this.coreTypes,
|
||||
this.classBuilder, this.isInstanceMember)
|
||||
this.classBuilder, this.isInstanceMember, this.uri)
|
||||
: enclosingScope = scope,
|
||||
library = library,
|
||||
isDartLibrary = library.uri.scheme == "dart",
|
||||
|
@ -272,9 +273,6 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
switchScope = pop();
|
||||
}
|
||||
|
||||
@override
|
||||
Uri get uri => library.fileUri ?? library.uri;
|
||||
|
||||
@override
|
||||
JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) {
|
||||
return new JumpTarget(kind, member, charOffset);
|
||||
|
@ -340,7 +338,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
@override
|
||||
void endMember() {
|
||||
debugEvent("Member");
|
||||
checkEmpty();
|
||||
checkEmpty(-1);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1153,9 +1151,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
return builder.buildTypesWithBuiltArguments(arguments);
|
||||
}
|
||||
if (builder == null) {
|
||||
print("$uri: Type not found: $name");
|
||||
warning("Type not found: '$name'.", charOffset);
|
||||
} else {
|
||||
print("$uri: Not a type: $name");
|
||||
warning("Not a type: '$name'.", charOffset);
|
||||
}
|
||||
// TODO(ahe): Create an error somehow.
|
||||
return const DynamicType();
|
||||
|
@ -1300,7 +1298,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
FieldBuilder field = builder;
|
||||
if (type != null) {
|
||||
nit("Ignoring type on 'this' parameter '${name.name}'.",
|
||||
name.fileOffset);
|
||||
thisKeyword.charOffset);
|
||||
}
|
||||
type = field.target.type ?? const DynamicType();
|
||||
variable = new VariableDeclaration(name.name, type: type,
|
||||
|
@ -2167,7 +2165,8 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
void handleRecoverableError(Token token, ErrorKind kind, Map arguments) {
|
||||
super.handleRecoverableError(token, kind, arguments);
|
||||
if (!hasParserError) {
|
||||
print("$uri:${recoverableErrors.last}");
|
||||
print(new InputError(uri, recoverableErrors.last.beginOffset,
|
||||
recoverableErrors.last.kind).format());
|
||||
}
|
||||
hasParserError = true;
|
||||
}
|
||||
|
@ -2189,17 +2188,6 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
return super.handleUnrecoverableError(token, kind, arguments);
|
||||
}
|
||||
|
||||
void warning(error, [int charOffset = -1]) {
|
||||
String message = new InputError(uri, charOffset, error).format();
|
||||
print(message);
|
||||
}
|
||||
|
||||
void nit(error, [int charOffset = -1]) {
|
||||
if (!showNits) return;
|
||||
String message = new InputError(uri, charOffset, error).format();
|
||||
print(message);
|
||||
}
|
||||
|
||||
@override
|
||||
Expression buildCompileTimeError(error, [int charOffset = -1]) {
|
||||
String message = new InputError(uri, charOffset, error).format();
|
||||
|
|
|
@ -16,6 +16,7 @@ import 'package:kernel/core_types.dart' show
|
|||
CoreTypes;
|
||||
|
||||
import '../errors.dart' show
|
||||
InputError,
|
||||
internalError;
|
||||
|
||||
import 'frontend_accessors.dart' as kernel show
|
||||
|
@ -694,7 +695,7 @@ class VariableAccessor extends kernel.VariableAccessor
|
|||
Expression throwNoSuchMethodError(String name, Arguments arguments, Uri uri,
|
||||
int charOffset, CoreTypes coreTypes,
|
||||
{bool isSuper: false, isGetter: false, isSetter: false}) {
|
||||
print("$uri:$charOffset: method not found: '$name'.");
|
||||
print(new InputError(uri, charOffset, "Method not found: '$name'.").format());
|
||||
Constructor constructor = coreTypes.getCoreClass(
|
||||
"dart:core", "NoSuchMethodError").constructors.first;
|
||||
return new Throw(new ConstructorInvocation(
|
||||
|
|
|
@ -17,6 +17,9 @@ import 'package:kernel/ast.dart' show
|
|||
import '../errors.dart' show
|
||||
internalError;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import 'kernel_builder.dart' show
|
||||
Builder,
|
||||
ClassBuilder,
|
||||
|
@ -105,9 +108,9 @@ abstract class KernelClassBuilder
|
|||
} else {
|
||||
// TODO(ahe): Throw NSM error. This requires access to core
|
||||
// types.
|
||||
String message =
|
||||
"Missing constructor: ${redirectionTarget.fullNameForErrors}";
|
||||
print(message);
|
||||
String message = "Redirection constructor target not found: "
|
||||
"${redirectionTarget.fullNameForErrors}";
|
||||
warning(library.fileUri, -1, message);
|
||||
builder.body = new ExpressionStatement(
|
||||
new Throw(new StringLiteral(message)));
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ import 'package:kernel/ast.dart' show
|
|||
import 'package:kernel/type_algebra.dart' show
|
||||
substitute;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import 'kernel_builder.dart' show
|
||||
FormalParameterBuilder,
|
||||
FunctionTypeAliasBuilder,
|
||||
|
@ -45,7 +48,8 @@ class KernelFunctionTypeAliasBuilder
|
|||
if (thisType == const InvalidType()) {
|
||||
thisType = const DynamicType();
|
||||
// TODO(ahe): Build an error somehow.
|
||||
print("${parent.uri}: Cyclic typedef: $name.");
|
||||
warning(parent.uri, -1,
|
||||
"The typedef '$name' has a reference to itself.");
|
||||
}
|
||||
return thisType;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ import 'package:kernel/ast.dart' show
|
|||
DartType,
|
||||
DynamicType;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import 'kernel_builder.dart' show
|
||||
InvalidTypeBuilder,
|
||||
KernelTypeBuilder;
|
||||
|
@ -19,14 +22,14 @@ class KernelInvalidTypeBuilder
|
|||
|
||||
DartType buildType(List<KernelTypeBuilder> arguments) {
|
||||
// TODO(ahe): Implement error handling.
|
||||
print("No type for: $name");
|
||||
warning(fileUri, charOffset, "No type for: '$name'.");
|
||||
return const DynamicType();
|
||||
}
|
||||
|
||||
/// [Arguments] have already been built.
|
||||
DartType buildTypesWithBuiltArguments(List<DartType> arguments) {
|
||||
// TODO(ahe): Implement error handling.
|
||||
print("No type for: $name");
|
||||
warning(fileUri, charOffset, "No type for: '$name'.");
|
||||
return const DynamicType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import 'package:kernel/ast.dart' show
|
|||
Supertype,
|
||||
VoidType;
|
||||
|
||||
import '../errors.dart' show
|
||||
inputError;
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import 'kernel_builder.dart' show
|
||||
KernelClassBuilder,
|
||||
|
@ -30,18 +30,19 @@ class KernelNamedTypeBuilder
|
|||
|
||||
KernelInvalidTypeBuilder buildInvalidType(String name) {
|
||||
// TODO(ahe): Record error instead of printing.
|
||||
print("$fileUri:$charOffset: Type not found: $name");
|
||||
warning(fileUri, charOffset, "Type not found: '$name'.");
|
||||
return new KernelInvalidTypeBuilder(name, charOffset, fileUri);
|
||||
}
|
||||
|
||||
DartType handleMissingType() {
|
||||
// TODO(ahe): Record error instead of printing.
|
||||
print("$fileUri:$charOffset: No type for: $name");
|
||||
warning(fileUri, charOffset, "No type for: '$name'.");
|
||||
return const DynamicType();
|
||||
}
|
||||
|
||||
Supertype handleMissingSuperType() {
|
||||
throw inputError(fileUri, charOffset, "No type for: $name");
|
||||
warning(fileUri, charOffset, "No type for: '$name'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
DartType build() {
|
||||
|
|
|
@ -40,6 +40,9 @@ import 'package:kernel/type_algebra.dart' show
|
|||
import '../errors.dart' show
|
||||
internalError;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import '../loader.dart' show
|
||||
Loader;
|
||||
|
||||
|
@ -129,7 +132,8 @@ abstract class KernelFunctionBuilder
|
|||
substitution[parameter] = const DynamicType();
|
||||
}
|
||||
}
|
||||
print("Can only use type variables in instance methods.");
|
||||
warning(fileUri, charOffset,
|
||||
"Can only use type variables in instance methods.");
|
||||
return substitute(type, substitution);
|
||||
}
|
||||
Set<TypeParameter> set = typeParameters.toSet();
|
||||
|
|
|
@ -75,6 +75,12 @@ import '../errors.dart' show
|
|||
reportCrash,
|
||||
resetCrashReporting;
|
||||
|
||||
import '../util/relativize.dart' show
|
||||
relativizeUri;
|
||||
|
||||
import '../compiler_context.dart' show
|
||||
CompilerContext;
|
||||
|
||||
import 'kernel_builder.dart' show
|
||||
Builder,
|
||||
ClassBuilder,
|
||||
|
@ -92,18 +98,29 @@ import 'kernel_builder.dart' show
|
|||
|
||||
class KernelTarget extends TargetImplementation {
|
||||
final DillTarget dillTarget;
|
||||
|
||||
/// Shared with [CompilerContext].
|
||||
final Map<String, Source> uriToSource;
|
||||
|
||||
SourceLoader<Library> loader;
|
||||
Program program;
|
||||
|
||||
final List errors = [];
|
||||
|
||||
KernelTarget(DillTarget dillTarget, TranslateUri uriTranslator)
|
||||
KernelTarget(DillTarget dillTarget, TranslateUri uriTranslator,
|
||||
[Map<String, Source> uriToSource])
|
||||
: dillTarget = dillTarget,
|
||||
uriToSource = uriToSource ?? CompilerContext.current.uriToSource,
|
||||
super(dillTarget.ticker, uriTranslator) {
|
||||
resetCrashReporting();
|
||||
loader = new SourceLoader<Library>(this);
|
||||
}
|
||||
|
||||
void addLineStarts(Uri uri, List<int> lineStarts) {
|
||||
String fileUri = relativizeUri(uri);
|
||||
uriToSource[fileUri] = new Source(lineStarts, fileUri);
|
||||
}
|
||||
|
||||
void read(Uri uri) {
|
||||
loader.read(uri);
|
||||
}
|
||||
|
@ -317,7 +334,9 @@ class KernelTarget extends TargetImplementation {
|
|||
program.mainMethod = builder.procedure;
|
||||
}
|
||||
}
|
||||
setup_builtin_library.transformProgram(program);
|
||||
if (errors.isEmpty || dillTarget.isLoaded) {
|
||||
setup_builtin_library.transformProgram(program);
|
||||
}
|
||||
ticker.logMs("Linked program");
|
||||
return program;
|
||||
}
|
||||
|
|
74
pkg/front_end/lib/src/fasta/messages.dart
Normal file
74
pkg/front_end/lib/src/fasta/messages.dart
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2016, 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 fasta.messages;
|
||||
|
||||
import 'package:kernel/ast.dart' show
|
||||
Location,
|
||||
Program;
|
||||
|
||||
import 'util/relativize.dart' show
|
||||
relativizeUri;
|
||||
|
||||
import 'compiler_context.dart' show
|
||||
CompilerContext;
|
||||
|
||||
import 'errors.dart' show
|
||||
InputError;
|
||||
|
||||
import 'colors.dart' show
|
||||
cyan,
|
||||
magenta;
|
||||
|
||||
const bool hideNits = false;
|
||||
|
||||
const bool hideWarnings = false;
|
||||
|
||||
void warning(Uri uri, int charOffset, String message) {
|
||||
if (hideWarnings) return;
|
||||
print(format(uri, charOffset, colorWarning("Warning: $message")));
|
||||
if (CompilerContext.current.options.areWarningsFatal) {
|
||||
if (CompilerContext.current.options.verbose) print(StackTrace.current);
|
||||
throw new InputError(
|
||||
uri, charOffset, "Compilation aborted due to fatal warnings.");
|
||||
}
|
||||
}
|
||||
|
||||
void nit(Uri uri, int charOffset, String message) {
|
||||
if (hideNits) return;
|
||||
print(format(uri, charOffset, colorNit("Nit: $message")));
|
||||
if (CompilerContext.current.options.areNitsFatal) {
|
||||
if (CompilerContext.current.options.verbose) print(StackTrace.current);
|
||||
throw new InputError(
|
||||
uri, charOffset, "Compilation aborted due to fatal nits.");
|
||||
}
|
||||
}
|
||||
|
||||
String colorWarning(String message) {
|
||||
// TODO(ahe): Colors need to be optional. Doesn't work well in Emacs or on
|
||||
// Windows.
|
||||
return magenta(message);
|
||||
}
|
||||
|
||||
String colorNit(String message) {
|
||||
// TODO(ahe): Colors need to be optional. Doesn't work well in Emacs or on
|
||||
// Windows.
|
||||
return cyan(message);
|
||||
}
|
||||
|
||||
String format(Uri uri, int charOffset, String message) {
|
||||
if (uri != null) {
|
||||
String path = relativizeUri(uri);
|
||||
String position = charOffset == -1
|
||||
? path : "${getLocation(path, charOffset)}";
|
||||
return "$position: $message";
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
Location getLocation(String path, int charOffset) {
|
||||
return new Program(null, CompilerContext.current.uriToSource)
|
||||
.getLocation(path, charOffset);
|
||||
}
|
|
@ -16,6 +16,9 @@ import 'package:kernel/verifier.dart' show
|
|||
import 'compiler_command_line.dart' show
|
||||
CompilerCommandLine;
|
||||
|
||||
import 'compiler_context.dart' show
|
||||
CompilerContext;
|
||||
|
||||
import 'errors.dart' show
|
||||
InputError,
|
||||
inputError;
|
||||
|
@ -40,15 +43,16 @@ import 'ast_kind.dart' show
|
|||
import 'testing/kernel_chain.dart' show
|
||||
computePatchedSdk;
|
||||
|
||||
CompilerCommandLine parseArguments(String programName, List<String> arguments) {
|
||||
return new CompilerCommandLine(programName, arguments);
|
||||
}
|
||||
|
||||
Future<KernelTarget> outline(List<String> arguments) async {
|
||||
try {
|
||||
CompilerCommandLine cl = parseArguments("outline", arguments);
|
||||
if (cl.verbose) print("Building outlines for ${arguments.join(' ')}");
|
||||
return await doOutline(cl, new Ticker(isVerbose: cl.verbose), cl.output);
|
||||
return await CompilerCommandLine.withGlobalOptions(
|
||||
"outline", arguments, (CompilerContext c) async {
|
||||
if (c.options.verbose) {
|
||||
print("Building outlines for ${arguments.join(' ')}");
|
||||
}
|
||||
return await doOutline(c, new Ticker(isVerbose: c.options.verbose),
|
||||
c.options.output);
|
||||
});
|
||||
} on InputError catch (e) {
|
||||
exitCode = 1;
|
||||
print(e.format());
|
||||
|
@ -58,12 +62,14 @@ Future<KernelTarget> outline(List<String> arguments) async {
|
|||
|
||||
Future<Uri> compile(List<String> arguments) async {
|
||||
try {
|
||||
CompilerCommandLine cl = parseArguments("compile", arguments);
|
||||
if (cl.verbose) {
|
||||
print("Compiling directly to Kernel: ${arguments.join(' ')}");
|
||||
}
|
||||
return
|
||||
await doCompile(cl, new Ticker(isVerbose: cl.verbose), AstKind.Kernel);
|
||||
return await CompilerCommandLine.withGlobalOptions(
|
||||
"compile", arguments, (CompilerContext c) async {
|
||||
if (c.options.verbose) {
|
||||
print("Compiling directly to Kernel: ${arguments.join(' ')}");
|
||||
}
|
||||
return await doCompile(c, new Ticker(isVerbose: c.options.verbose),
|
||||
AstKind.Kernel);
|
||||
});
|
||||
} on InputError catch (e) {
|
||||
exitCode = 1;
|
||||
print(e.format());
|
||||
|
@ -73,10 +79,14 @@ Future<Uri> compile(List<String> arguments) async {
|
|||
|
||||
Future<Uri> kompile(List<String> arguments) async {
|
||||
try {
|
||||
CompilerCommandLine cl = parseArguments("kompile", arguments);
|
||||
if (cl.verbose) print("Compiling via analyzer: ${arguments.join(' ')}");
|
||||
return await doCompile(
|
||||
cl, new Ticker(isVerbose: cl.verbose), AstKind.Analyzer);
|
||||
return await CompilerCommandLine.withGlobalOptions(
|
||||
"kompile", arguments, (CompilerContext c) async {
|
||||
if (c.options.verbose) {
|
||||
print("Compiling via analyzer: ${arguments.join(' ')}");
|
||||
}
|
||||
return await doCompile(c, new Ticker(isVerbose: c.options.verbose),
|
||||
AstKind.Analyzer);
|
||||
});
|
||||
} on InputError catch (e) {
|
||||
exitCode = 1;
|
||||
print(e.format());
|
||||
|
@ -84,19 +94,20 @@ Future<Uri> kompile(List<String> arguments) async {
|
|||
}
|
||||
}
|
||||
|
||||
Future<KernelTarget> doOutline(CompilerCommandLine cl, Ticker ticker,
|
||||
Future<KernelTarget> doOutline(CompilerContext c, Ticker ticker,
|
||||
[Uri output]) async {
|
||||
Uri sdk = await computePatchedSdk();
|
||||
ticker.logMs("Found patched SDK");
|
||||
TranslateUri uriTranslator = await TranslateUri.parse(sdk);
|
||||
ticker.logMs("Read packages file");
|
||||
DillTarget dillTarget = new DillTarget(ticker, uriTranslator);
|
||||
KernelTarget kernelTarget = new KernelTarget(dillTarget, uriTranslator);
|
||||
Uri platform = cl.platform;
|
||||
KernelTarget kernelTarget =
|
||||
new KernelTarget(dillTarget, uriTranslator, c.uriToSource);
|
||||
Uri platform = c.options.platform;
|
||||
if (platform != null) {
|
||||
dillTarget.read(platform);
|
||||
}
|
||||
String argument = cl.arguments.first;
|
||||
String argument = c.options.arguments.first;
|
||||
Uri uri = Uri.base.resolve(argument);
|
||||
String path = uriTranslator.translate(uri)?.path ?? argument;
|
||||
if (path.endsWith(".dart")) {
|
||||
|
@ -106,29 +117,28 @@ Future<KernelTarget> doOutline(CompilerCommandLine cl, Ticker ticker,
|
|||
}
|
||||
await dillTarget.writeOutline(null);
|
||||
await kernelTarget.writeOutline(output);
|
||||
if (cl.dumpIr && output != null) {
|
||||
if (c.options.dumpIr && output != null) {
|
||||
kernelTarget.dumpIr();
|
||||
}
|
||||
return kernelTarget;
|
||||
}
|
||||
|
||||
Future<Uri> doCompile(CompilerCommandLine cl, Ticker ticker,
|
||||
AstKind kind) async {
|
||||
KernelTarget kernelTarget = await doOutline(cl, ticker);
|
||||
Future<Uri> doCompile(CompilerContext c, Ticker ticker, AstKind kind) async {
|
||||
KernelTarget kernelTarget = await doOutline(c, ticker);
|
||||
if (exitCode != 0) return null;
|
||||
Uri uri = cl.output;
|
||||
Uri uri = c.options.output;
|
||||
await kernelTarget.writeProgram(uri, kind);
|
||||
if (cl.dumpIr) {
|
||||
if (c.options.dumpIr) {
|
||||
kernelTarget.dumpIr();
|
||||
}
|
||||
if (cl.verify) {
|
||||
if (c.options.verify) {
|
||||
try {
|
||||
verifyProgram(kernelTarget.program);
|
||||
ticker.logMs("Verified program");
|
||||
} catch (e, s) {
|
||||
exitCode = 1;
|
||||
print("Verification of program failed: $e");
|
||||
if (s != null && cl.verbose) {
|
||||
if (s != null && c.options.verbose) {
|
||||
print(s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,15 @@ import 'testing/kernel_chain.dart' show
|
|||
computeDartVm,
|
||||
computePatchedSdk;
|
||||
|
||||
import 'compiler_command_line.dart' show
|
||||
CompilerCommandLine;
|
||||
import 'compiler_context.dart' show
|
||||
CompilerContext;
|
||||
|
||||
Future<int> run(Uri uri, CompilerCommandLine cl) async {
|
||||
Future<int> run(Uri uri, CompilerContext c) async {
|
||||
Uri sdk = await computePatchedSdk();
|
||||
Uri dartVm = computeDartVm(sdk);
|
||||
List<String> arguments = <String>["${uri.toFilePath()}"]
|
||||
..addAll(cl.arguments.skip(1));
|
||||
if (cl.verbose) {
|
||||
..addAll(c.options.arguments.skip(1));
|
||||
if (c.options.verbose) {
|
||||
print("Running ${dartVm.toFilePath()} ${arguments.join(' ')}");
|
||||
}
|
||||
StdioProcess result = await StdioProcess.run(dartVm.toFilePath(), arguments);
|
||||
|
|
|
@ -78,15 +78,16 @@ class DietListener extends StackListener {
|
|||
/// this is the instance scope of [currentClass].
|
||||
Scope memberScope;
|
||||
|
||||
@override
|
||||
Uri uri;
|
||||
|
||||
DietListener(SourceLibraryBuilder library, this.elementStore, this.hierarchy,
|
||||
this.coreTypes, this.astKind)
|
||||
: library = library,
|
||||
uri = library.fileUri,
|
||||
memberScope = library.scope,
|
||||
isDartLibrary = library.uri.scheme == "dart";
|
||||
|
||||
@override
|
||||
Uri get uri => library.uri;
|
||||
|
||||
void discard(int n) {
|
||||
for (int i =0; i < n; i++) {
|
||||
pop();
|
||||
|
@ -192,7 +193,7 @@ class DietListener extends StackListener {
|
|||
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
|
||||
debugEvent("FunctionTypeAlias");
|
||||
discard(2); // Name + endToken.
|
||||
checkEmpty();
|
||||
checkEmpty(typedefKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -213,7 +214,7 @@ class DietListener extends StackListener {
|
|||
debugEvent("TopLevelMethod");
|
||||
Token bodyToken = pop();
|
||||
String name = pop();
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
buildFunctionBody(bodyToken, lookupBuilder(beginToken, getOrSet, name));
|
||||
}
|
||||
|
||||
|
@ -363,7 +364,7 @@ class DietListener extends StackListener {
|
|||
debugEvent("FactoryMethod");
|
||||
BeginGroupToken bodyToken = pop();
|
||||
String name = pop();
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
if (bodyToken == null || optional("=", bodyToken.endGroup.next)) {
|
||||
return;
|
||||
}
|
||||
|
@ -381,7 +382,7 @@ class DietListener extends StackListener {
|
|||
debugEvent("Method");
|
||||
Token bodyToken = pop();
|
||||
String name = pop();
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
if (bodyToken == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -394,10 +395,10 @@ class DietListener extends StackListener {
|
|||
case AstKind.Kernel:
|
||||
return new BodyBuilder(library, builder, memberScope,
|
||||
formalParameterScope, hierarchy, coreTypes, currentClass,
|
||||
isInstanceMember);
|
||||
isInstanceMember, uri);
|
||||
|
||||
case AstKind.Analyzer:
|
||||
return new AstBuilder(library, builder, elementStore, memberScope);
|
||||
return new AstBuilder(library, builder, elementStore, memberScope, uri);
|
||||
}
|
||||
|
||||
return internalError("Unknown $astKind");
|
||||
|
@ -423,7 +424,7 @@ class DietListener extends StackListener {
|
|||
@override
|
||||
void endMember() {
|
||||
debugEvent("Member");
|
||||
checkEmpty();
|
||||
checkEmpty(-1);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -440,7 +441,7 @@ class DietListener extends StackListener {
|
|||
void endClassBody(int memberCount, Token beginToken, Token endToken) {
|
||||
debugEvent("ClassBody");
|
||||
currentClass = null;
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
memberScope = library.scope;
|
||||
}
|
||||
|
||||
|
@ -448,7 +449,7 @@ class DietListener extends StackListener {
|
|||
void endClassDeclaration(int interfacesCount, Token beginToken,
|
||||
Token extendsKeyword, Token implementsKeyword, Token endToken) {
|
||||
debugEvent("ClassDeclaration");
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -456,7 +457,7 @@ class DietListener extends StackListener {
|
|||
debugEvent("Enum");
|
||||
discard(count);
|
||||
pop(); // Name.
|
||||
checkEmpty();
|
||||
checkEmpty(enumKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -464,7 +465,7 @@ class DietListener extends StackListener {
|
|||
Token classKeyword, Token implementsKeyword, Token endToken) {
|
||||
debugEvent("NamedMixinApplication");
|
||||
pop(); // Name.
|
||||
checkEmpty();
|
||||
checkEmpty(classKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -490,7 +491,7 @@ class DietListener extends StackListener {
|
|||
Parser parser = new Parser(listener);
|
||||
token = parser.parseFormalParametersOpt(token);
|
||||
var formals = listener.pop();
|
||||
listener.checkEmpty();
|
||||
listener.checkEmpty(token.charOffset);
|
||||
listener.prepareInitializers();
|
||||
token = parser.parseInitializersOpt(token);
|
||||
token = parser.parseAsyncModifier(token);
|
||||
|
@ -499,7 +500,7 @@ class DietListener extends StackListener {
|
|||
bool allowAbstract = true;
|
||||
parser.parseFunctionBody(token, isExpression, allowAbstract);
|
||||
var body = listener.pop();
|
||||
listener.checkEmpty();
|
||||
listener.checkEmpty(token.charOffset);
|
||||
listener.finishFunction(formals, asyncModifier, body);
|
||||
} on InputError {
|
||||
rethrow;
|
||||
|
@ -515,7 +516,7 @@ class DietListener extends StackListener {
|
|||
} else {
|
||||
token = parser.parseMember(token);
|
||||
}
|
||||
listener.checkEmpty();
|
||||
listener.checkEmpty(token.charOffset);
|
||||
}
|
||||
|
||||
Builder lookupBuilder(Token token, Token getOrSet, String name) {
|
||||
|
@ -531,7 +532,7 @@ class DietListener extends StackListener {
|
|||
builder = library.members[name];
|
||||
}
|
||||
if (builder == null) {
|
||||
return internalError("@${token.charOffset}: builder not found: $name");
|
||||
return internalError("Builder not found: $name", uri, token.charOffset);
|
||||
}
|
||||
if (builder.next != null) {
|
||||
Builder getterBuilder;
|
||||
|
@ -554,14 +555,13 @@ class DietListener extends StackListener {
|
|||
return builder;
|
||||
}
|
||||
|
||||
@override
|
||||
void debugEvent(String name) {
|
||||
// print(" ${stack.join('\n ')}");
|
||||
// print(name);
|
||||
}
|
||||
|
||||
bool get isTargetingDartVm {
|
||||
// TODO(ahe): Find a more reliable way to check if this is the Dart VM.
|
||||
return coreTypes.getCoreLibrary("dart:_js_helper") == null;
|
||||
}
|
||||
|
||||
@override
|
||||
void debugEvent(String name) {
|
||||
// printEvent(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
List<MetadataBuilder> metadata = pop();
|
||||
library.addExport(
|
||||
metadata, uri, conditionalUris, combinators, exportKeyword.charOffset);
|
||||
checkEmpty();
|
||||
checkEmpty(exportKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -156,7 +156,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
library.addImport(metadata, uri, conditionalUris, prefix, combinators,
|
||||
deferredKeyword != null, importKeyword.charOffset,
|
||||
asKeyword?.next?.charOffset ?? -1);
|
||||
checkEmpty();
|
||||
checkEmpty(importKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -165,7 +165,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
String uri = pop();
|
||||
List<MetadataBuilder> metadata = pop();
|
||||
library.addPart(metadata, uri);
|
||||
checkEmpty();
|
||||
checkEmpty(partKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -218,7 +218,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
List<MetadataBuilder> metadata = pop();
|
||||
library.addClass(metadata, modifiers, name, typeVariables, supertype,
|
||||
interfaces, beginToken.charOffset);
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
}
|
||||
|
||||
ProcedureKind computeProcedureKind(Token token) {
|
||||
|
@ -246,7 +246,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
int modifiers = Modifier.validate(pop(),
|
||||
isAbstract: kind == MethodBody.Abstract);
|
||||
List<MetadataBuilder> metadata = pop();
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
library.addProcedure(metadata, modifiers, returnType, name,
|
||||
typeVariables, formals, asyncModifier, computeProcedureKind(getOrSet),
|
||||
beginToken.charOffset, nativeMethodName, isTopLevel: true);
|
||||
|
@ -334,7 +334,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
library.addNamedMixinApplication(
|
||||
metadata, name, typeVariables, modifiers, mixinApplication, interfaces,
|
||||
classKeyword.charOffset);
|
||||
checkEmpty();
|
||||
checkEmpty(classKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -448,7 +448,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
String name = pop();
|
||||
List<MetadataBuilder> metadata = pop();
|
||||
library.addEnum(metadata, name, constants, enumKeyword.charOffset);
|
||||
checkEmpty();
|
||||
checkEmpty(enumKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -467,7 +467,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
library.addFunctionTypeAlias(
|
||||
metadata, returnType, name, typeVariables, formals,
|
||||
typedefKeyword.charOffset);
|
||||
checkEmpty();
|
||||
checkEmpty(typedefKeyword.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -478,7 +478,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
int modifiers = Modifier.validate(pop());
|
||||
List<MetadataBuilder> metadata = pop();
|
||||
library.addFields(metadata, modifiers, type, names);
|
||||
checkEmpty();
|
||||
checkEmpty(beginToken.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -14,6 +14,9 @@ import '../combinator.dart' show
|
|||
import '../errors.dart' show
|
||||
internalError;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import '../import.dart' show
|
||||
Import;
|
||||
|
||||
|
@ -302,14 +305,14 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|||
void includePart(SourceLibraryBuilder<T, R> part) {
|
||||
if (name != null) {
|
||||
if (part.partOf == null) {
|
||||
print("${part.uri} has no 'part of' declaration but is used as a part "
|
||||
"by ${name} ($uri)");
|
||||
warning(part.fileUri, -1, "Has no 'part of' declaration but is used as "
|
||||
"a part by ${name} ($uri).");
|
||||
parts.remove(part);
|
||||
return;
|
||||
}
|
||||
if (part.partOf != name) {
|
||||
print("${part.uri} is part of '${part.partOf}' but is used as a part "
|
||||
"by '${name}' ($uri)");
|
||||
warning(part.fileUri, -1, "Is part of '${part.partOf}' but is used as "
|
||||
"a part by '${name}' ($uri).");
|
||||
parts.remove(part);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'package:front_end/src/fasta/scanner/io.dart' show
|
|||
|
||||
import 'package:front_end/src/fasta/scanner.dart' show
|
||||
ErrorToken,
|
||||
ScannerResult,
|
||||
Token,
|
||||
scan;
|
||||
|
||||
|
@ -34,6 +35,9 @@ import '../errors.dart' show
|
|||
InputError,
|
||||
inputError;
|
||||
|
||||
import '../messages.dart' show
|
||||
warning;
|
||||
|
||||
import '../export.dart' show
|
||||
Export;
|
||||
|
||||
|
@ -86,13 +90,16 @@ class SourceLoader<L> extends Loader<L> {
|
|||
try {
|
||||
List<int> bytes = await readBytesFromFile(uri);
|
||||
byteCount += bytes.length - 1;
|
||||
Token token = scan(bytes).tokens;
|
||||
ScannerResult result = scan(bytes);
|
||||
Token token = result.tokens;
|
||||
if (!suppressLexicalErrors) {
|
||||
target.addLineStarts(library.fileUri, result.lineStarts);
|
||||
}
|
||||
while (token is ErrorToken) {
|
||||
if (!suppressLexicalErrors) {
|
||||
ErrorToken error = token;
|
||||
String message = new InputError(
|
||||
uri, token.charOffset, error.assertionMessage).format();
|
||||
print(message);
|
||||
print(new InputError(uri, token.charOffset, error.assertionMessage)
|
||||
.format());
|
||||
}
|
||||
token = token.next;
|
||||
}
|
||||
|
@ -128,6 +135,7 @@ class SourceLoader<L> extends Loader<L> {
|
|||
for (SourceLibraryBuilder part in library.parts) {
|
||||
Token tokens = await tokenize(part);
|
||||
if (tokens != null) {
|
||||
listener.uri = part.fileUri;
|
||||
parser.parseUnit(tokens);
|
||||
}
|
||||
}
|
||||
|
@ -335,8 +343,8 @@ class SourceLoader<L> extends Loader<L> {
|
|||
reported.add(cls);
|
||||
}
|
||||
}
|
||||
print("${cls.name} is a supertype of itself via "
|
||||
"${involved.map((c) => c.name).join(' ')}");
|
||||
warning(cls.fileUri, cls.charOffset, "'${cls.name}' is a supertype of "
|
||||
"itself via '${involved.map((c) => c.name).join(' ')}'.");
|
||||
}
|
||||
});
|
||||
ticker.logMs("Found cycles");
|
||||
|
|
|
@ -16,6 +16,8 @@ import '../errors.dart' show inputError, internalError;
|
|||
|
||||
import '../quote.dart' show unescapeString;
|
||||
|
||||
import '../messages.dart' as messages;
|
||||
|
||||
enum NullValue {
|
||||
Arguments,
|
||||
Block,
|
||||
|
@ -121,10 +123,10 @@ abstract class StackListener extends Listener {
|
|||
debugEvent("Initializer");
|
||||
}
|
||||
|
||||
void checkEmpty() {
|
||||
void checkEmpty(int charOffset) {
|
||||
if (stack.isNotEmpty) {
|
||||
internalError("${runtimeType}: Stack not empty $uri:\n"
|
||||
" ${stack.join('\n ')}");
|
||||
internalError("${runtimeType}: Stack not empty:\n"
|
||||
" ${stack.join('\n ')}", uri, charOffset);
|
||||
}
|
||||
if (recoverableErrors.isNotEmpty) {
|
||||
// TODO(ahe): Handle recoverable errors better.
|
||||
|
@ -135,13 +137,13 @@ abstract class StackListener extends Listener {
|
|||
@override
|
||||
void endTopLevelDeclaration(Token token) {
|
||||
debugEvent("TopLevelDeclaration");
|
||||
checkEmpty();
|
||||
checkEmpty(token.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
void endCompilationUnit(int count, Token token) {
|
||||
debugEvent("CompilationUnit");
|
||||
checkEmpty();
|
||||
checkEmpty(token.charOffset);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -229,4 +231,12 @@ abstract class StackListener extends Listener {
|
|||
Token handleUnrecoverableError(Token token, ErrorKind kind, Map arguments) {
|
||||
throw inputError(uri, token.charOffset, "$kind $arguments");
|
||||
}
|
||||
|
||||
void nit(String message, [int charOffset = -1]) {
|
||||
messages.nit(uri, charOffset, message);
|
||||
}
|
||||
|
||||
void warning(String message, [int charOffset = -1]) {
|
||||
messages.warning(uri, charOffset, message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,4 +73,6 @@ abstract class TargetImplementation extends Target {
|
|||
loader.read(Uri.parse(uri));
|
||||
}
|
||||
}
|
||||
|
||||
void addLineStarts(Uri uri, List<int> lineStarts);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ rasta/bad_setter_initializer: Crash
|
|||
rasta/bad_unicode: Fail
|
||||
rasta/breaking_bad: Crash
|
||||
rasta/cascades: Crash
|
||||
rasta/class_hierarchy: Fail
|
||||
rasta/class_hierarchy: Crash
|
||||
rasta/class_member: Crash
|
||||
rasta/constant_get_and_invoke: Crash
|
||||
rasta/deferred_lib: Fail
|
||||
|
|
|
@ -3609,7 +3609,7 @@ class Program extends TreeNode {
|
|||
Program([List<Library> libraries, Map<String, Source> uriToSource])
|
||||
: libraries = libraries ?? <Library>[],
|
||||
uriToSource = uriToSource ?? <String, Source>{} {
|
||||
setParents(libraries, this);
|
||||
setParents(this.libraries, this);
|
||||
}
|
||||
|
||||
accept(TreeVisitor v) => v.visitProgram(this);
|
||||
|
|
|
@ -175,7 +175,7 @@ Future<CompilationResult> parseScriptImpl(DartLoaderBatch batch_loader,
|
|||
.toList(growable: false));
|
||||
}
|
||||
} on InputError catch (e) {
|
||||
return new CompilationError(<String>[e.error]);
|
||||
return new CompilationError(<String>[e.format()]);
|
||||
}
|
||||
} else {
|
||||
DartOptions dartOptions = new DartOptions(
|
||||
|
|
Loading…
Reference in a new issue