mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:27:43 +00:00
Prepare for improved error recovery from compile-time errors.
R=paulberry@google.com Review-Url: https://codereview.chromium.org/2931423002 .
This commit is contained in:
parent
d920dacad8
commit
14e9d0bd89
|
@ -877,16 +877,21 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
message = "Method not found: '$errorName'.";
|
||||
}
|
||||
if (constantExpressionRequired) {
|
||||
// TODO(ahe): Use error below instead of building a compile-time error,
|
||||
// should be:
|
||||
// return library.loader.throwCompileConstantError(error, charOffset);
|
||||
return buildCompileTimeError(message, charOffset);
|
||||
} else {
|
||||
Expression error = library.loader.instantiateNoSuchMethodError(
|
||||
receiver, name, arguments, charOffset,
|
||||
isMethod: !isGetter && !isSetter,
|
||||
isGetter: isGetter,
|
||||
isSetter: isSetter,
|
||||
isStatic: isStatic,
|
||||
isTopLevel: !isStatic && !isSuper);
|
||||
warning(message, charOffset);
|
||||
return new Throw(error);
|
||||
}
|
||||
warning(message, charOffset);
|
||||
return new Throw(library.loader.instantiateNoSuchMethodError(
|
||||
receiver, name, arguments, charOffset,
|
||||
isMethod: !isGetter && !isSetter,
|
||||
isGetter: isGetter,
|
||||
isSetter: isSetter,
|
||||
isStatic: isStatic,
|
||||
isTopLevel: !isStatic && !isSuper));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -2883,11 +2888,9 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
// extracted. Similar for statements and initializers. See also [issue
|
||||
// 29717](https://github.com/dart-lang/sdk/issues/29717)
|
||||
addCompileTimeError(charOffset, error);
|
||||
String message = formatUnexpected(uri, charOffset, error);
|
||||
Builder constructor = library.loader.getCompileTimeError();
|
||||
return new Throw(buildStaticInvocation(constructor.target,
|
||||
new KernelArguments(<Expression>[new StringLiteral(message)]),
|
||||
charOffset: charOffset));
|
||||
return library.loader.throwCompileConstantError(library.loader
|
||||
.buildCompileTimeError(
|
||||
formatUnexpected(uri, charOffset, error), charOffset));
|
||||
}
|
||||
|
||||
Expression wrapInCompileTimeError(Expression expression, String message) {
|
||||
|
|
|
@ -517,4 +517,13 @@ class SourceLoader<L> extends Loader<L> {
|
|||
isConstructor: isConstructor,
|
||||
isTopLevel: isTopLevel);
|
||||
}
|
||||
|
||||
Expression throwCompileConstantError(Expression error) {
|
||||
return target.backendTarget.throwCompileConstantError(coreTypes, error);
|
||||
}
|
||||
|
||||
Expression buildCompileTimeError(String message, int offset) {
|
||||
return target.backendTarget
|
||||
.buildCompileTimeError(coreTypes, message, offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ class CoreTypes {
|
|||
Procedure _listFromConstructor;
|
||||
Procedure _printProcedure;
|
||||
Procedure _identicalProcedure;
|
||||
Constructor _constantExpressionErrorDefaultConstructor;
|
||||
Constructor _compileTimeErrorDefaultConstructor;
|
||||
|
||||
Class _internalSymbolClass;
|
||||
|
||||
|
@ -255,4 +257,14 @@ class CoreTypes {
|
|||
Class get typeClass {
|
||||
return _typeClass ??= _index.getClass('dart:core', 'Type');
|
||||
}
|
||||
|
||||
Constructor get constantExpressionErrorDefaultConstructor {
|
||||
return _constantExpressionErrorDefaultConstructor ??=
|
||||
_index.getMember('dart:core', '_ConstantExpressionError', '');
|
||||
}
|
||||
|
||||
Constructor get compileTimeErrorDefaultConstructor {
|
||||
return _compileTimeErrorDefaultConstructor ??=
|
||||
_index.getMember('dart:core', '_CompileTimeError', '');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,6 +130,34 @@ abstract class Target {
|
|||
bool isConstructor: false,
|
||||
bool isTopLevel: false});
|
||||
|
||||
/// Builds an expression that throws [error] as compile-time error. The
|
||||
/// target must be able to handle this expression in a constant expression.
|
||||
Expression throwCompileConstantError(CoreTypes coreTypes, Expression error) {
|
||||
// This method returns `const _ConstantExpressionError()._throw(error)`.
|
||||
int offset = error.fileOffset;
|
||||
var receiver = new ConstructorInvocation(
|
||||
coreTypes.constantExpressionErrorDefaultConstructor,
|
||||
new Arguments.empty()..fileOffset = offset,
|
||||
isConst: true)
|
||||
..fileOffset = offset;
|
||||
return new MethodInvocation(
|
||||
receiver,
|
||||
new Name("_throw", coreTypes.coreLibrary),
|
||||
new Arguments(<Expression>[error])..fileOffset = error.fileOffset)
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
/// Builds an expression that represents a compile-time error which is
|
||||
/// suitable for being passed to [throwCompileConstantError].
|
||||
Expression buildCompileTimeError(
|
||||
CoreTypes coreTypes, String message, int offset) {
|
||||
return new ConstructorInvocation(
|
||||
coreTypes.compileTimeErrorDefaultConstructor,
|
||||
new Arguments(<Expression>[new StringLiteral(message)])
|
||||
..fileOffset = offset)
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
String toString() => 'Target($name)';
|
||||
}
|
||||
|
||||
|
|
|
@ -430,3 +430,9 @@ class _DuplicatedFieldInitializerError extends Error {
|
|||
|
||||
toString() => "Error: field '$_name' is already initialized.";
|
||||
}
|
||||
|
||||
@patch
|
||||
class _ConstantExpressionError {
|
||||
@patch
|
||||
_throw(error) => throw error;
|
||||
}
|
||||
|
|
|
@ -746,3 +746,9 @@ _unresolvedTopLevelMethodError(receiver, memberName, positionalArguments,
|
|||
return new NoSuchMethodError(
|
||||
receiver, memberName, positionalArguments, namedArguments);
|
||||
}
|
||||
|
||||
@patch
|
||||
class _ConstantExpressionError {
|
||||
@patch
|
||||
_throw(error) => throw error;
|
||||
}
|
||||
|
|
|
@ -557,3 +557,11 @@ class CyclicInitializationError extends Error {
|
|||
? "Reading static variable during its initialization"
|
||||
: "Reading static variable '$variableName' during its initialization";
|
||||
}
|
||||
|
||||
/// Used by Fasta to throw a compile-time error in a way that is compatible
|
||||
/// with compile-time constant evaluation.
|
||||
class _ConstantExpressionError {
|
||||
const _ConstantExpressionError();
|
||||
|
||||
external _throw(error);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue