mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 16:31:07 +00:00
[Kernel] Signal an error for invalid native invocations
Calls to the factory constructor 'new List' can turn into static invocations of a backend-specific factory function. Signal an error instead of crashing. Change-Id: Id0a8a7f0f847c03225b7fa9da2351032d15522e0 Reviewed-on: https://dart-review.googlesource.com/c/90006 Reviewed-by: Aske Simon Christensen <askesc@google.com> Commit-Queue: Kevin Millikin <kmillikin@google.com>
This commit is contained in:
parent
d51a847891
commit
b00193fa5f
|
@ -17,6 +17,7 @@ import 'package:kernel/ast.dart'
|
|||
MapConstant,
|
||||
Member,
|
||||
NullConstant,
|
||||
Procedure,
|
||||
StaticInvocation,
|
||||
StringConstant,
|
||||
TreeNode;
|
||||
|
@ -49,7 +50,7 @@ import '../fasta_codes.dart'
|
|||
|
||||
import '../loader.dart' show Loader;
|
||||
|
||||
import '../problems.dart' show unexpected, unimplemented;
|
||||
import '../problems.dart' show unexpected;
|
||||
|
||||
class KernelConstantErrorReporter extends ErrorReporter {
|
||||
final Loader<Library> loader;
|
||||
|
@ -110,10 +111,22 @@ class KernelConstantErrorReporter extends ErrorReporter {
|
|||
@override
|
||||
String invalidStaticInvocation(
|
||||
List<TreeNode> context, TreeNode node, Member target) {
|
||||
// TODO(kmillikin) For an invalid factory invocation we should adopt a
|
||||
// better message. This will show something like:
|
||||
//
|
||||
// "The invocation of 'List' is not allowed within a const context."
|
||||
//
|
||||
// Which is not quite right when the code was "new List()".
|
||||
String name = target.name.toString();
|
||||
if (target is Procedure && target.isFactory) {
|
||||
if (name.isEmpty) {
|
||||
name = target.enclosingClass.name;
|
||||
} else {
|
||||
name = '${target.enclosingClass.name}.${name}';
|
||||
}
|
||||
}
|
||||
return addProblem(
|
||||
node,
|
||||
templateConstEvalInvalidStaticInvocation
|
||||
.withArguments(target.name.toString()));
|
||||
node, templateConstEvalInvalidStaticInvocation.withArguments(name));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -200,7 +213,7 @@ class KernelConstantsBackend extends ConstantsBackend {
|
|||
List<TreeNode> context,
|
||||
StaticInvocation node,
|
||||
ErrorReporter errorReporter,
|
||||
void abortEvaluation(String message)) {
|
||||
Constant abortEvaluation(String message)) {
|
||||
// VM-specific names of the fromEnvironment factory constructors.
|
||||
if (nativeName == 'Bool_fromEnvironment' ||
|
||||
nativeName == 'Integer_fromEnvironment' ||
|
||||
|
@ -224,7 +237,7 @@ class KernelConstantsBackend extends ConstantsBackend {
|
|||
return unexpected('valid constructor invocation', node.toString(),
|
||||
node.fileOffset, node.location.file);
|
||||
}
|
||||
return unimplemented('constant evaluation of ${nativeName}',
|
||||
node.fileOffset, node.location.file);
|
||||
return abortEvaluation(
|
||||
errorReporter.invalidStaticInvocation(context, node, node.target));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1226,32 +1226,7 @@ class ConstantEvaluator extends RecursiveVisitor {
|
|||
// Helper methods:
|
||||
|
||||
void ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
|
||||
DartType constantType;
|
||||
if (constant is NullConstant) {
|
||||
constantType = new InterfaceType(coreTypes.nullClass);
|
||||
} else if (constant is BoolConstant) {
|
||||
constantType = new InterfaceType(coreTypes.boolClass);
|
||||
} else if (constant is IntConstant) {
|
||||
constantType = new InterfaceType(coreTypes.intClass);
|
||||
} else if (constant is DoubleConstant) {
|
||||
constantType = new InterfaceType(coreTypes.doubleClass);
|
||||
} else if (constant is StringConstant) {
|
||||
constantType = new InterfaceType(coreTypes.stringClass);
|
||||
} else if (constant is MapConstant) {
|
||||
constantType = new InterfaceType(
|
||||
coreTypes.mapClass, <DartType>[constant.keyType, constant.valueType]);
|
||||
} else if (constant is ListConstant) {
|
||||
constantType = new InterfaceType(
|
||||
coreTypes.stringClass, <DartType>[constant.typeArgument]);
|
||||
} else if (constant is InstanceConstant) {
|
||||
constantType = new InterfaceType(constant.klass, constant.typeArguments);
|
||||
} else if (constant is TearOffConstant) {
|
||||
constantType = constant.procedure.function.functionType;
|
||||
} else if (constant is TypeLiteralConstant) {
|
||||
constantType = new InterfaceType(coreTypes.typeClass);
|
||||
} else {
|
||||
throw new Exception('No support for ${constant.runtimeType}.runtimeType');
|
||||
}
|
||||
DartType constantType = constant.getType(typeEnvironment);
|
||||
|
||||
if (!typeEnvironment.isSubtypeOf(constantType, type)) {
|
||||
throw new _AbortCurrentEvaluation(
|
||||
|
@ -1463,7 +1438,7 @@ abstract class ConstantsBackend {
|
|||
List<TreeNode> context,
|
||||
StaticInvocation node,
|
||||
ErrorReporter errorReporter,
|
||||
void abortEvaluation(String message));
|
||||
Constant abortEvaluation(String message));
|
||||
Constant lowerListConstant(ListConstant constant);
|
||||
Constant lowerMapConstant(MapConstant constant);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ class VmConstantsBackend implements ConstantsBackend {
|
|||
List<TreeNode> context,
|
||||
StaticInvocation node,
|
||||
ErrorReporter errorReporter,
|
||||
void abortEvaluation(String message)) {
|
||||
Constant abortEvaluation(String message)) {
|
||||
if ([
|
||||
'Bool_fromEnvironment',
|
||||
'Integer_fromEnvironment',
|
||||
|
@ -118,7 +118,7 @@ class VmConstantsBackend implements ConstantsBackend {
|
|||
makeConstant: (v) => new StringConstant(v));
|
||||
}
|
||||
} else {
|
||||
abortEvaluation(errorReporter.invalidDartType(
|
||||
return abortEvaluation(errorReporter.invalidDartType(
|
||||
context,
|
||||
node.arguments.positional.first,
|
||||
argument,
|
||||
|
|
|
@ -56,7 +56,6 @@ LibTest/isolate/ReceivePort/lastWhere_A01_t01: RuntimeError
|
|||
[ $compiler == fasta ]
|
||||
Language/Statements/For/syntax_t13: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
|
||||
Language/Statements/For/syntax_t20: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
|
||||
LanguageFeatures/Constant_update2018/CastOperator_A04_t02: Crash
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A01_t01: Crash
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A01_t02: Crash
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A02_t01: CompileTimeError
|
||||
|
@ -66,11 +65,8 @@ LanguageFeatures/Constant_update2018/NewOperators_A02_t05: CompileTimeError
|
|||
LanguageFeatures/Constant_update2018/NewOperators_A02_t07: CompileTimeError
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A02_t08: CompileTimeError
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t02: Crash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t05: Crash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t05: Crash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: Crash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t04: Crash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t06: Crash
|
||||
LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: Crash
|
||||
LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: Crash
|
||||
LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: Crash
|
||||
|
@ -839,7 +835,6 @@ LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError
|
|||
LanguageFeatures/Constant_update2018/CastOperator_A01_t01: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/CastOperator_A02_t01: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/CastOperator_A02_t02: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/CastOperator_A04_t02: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A01_t01: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A01_t02: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A02_t01: Fail
|
||||
|
@ -849,10 +844,7 @@ LanguageFeatures/Constant_update2018/NewOperators_A02_t05: CompileTimeError
|
|||
LanguageFeatures/Constant_update2018/NewOperators_A02_t07: Fail
|
||||
LanguageFeatures/Constant_update2018/NewOperators_A02_t08: CompileTimeError
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t02: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t05: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t05: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t05: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t06: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: DartkCrash
|
||||
LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: DartkCrash
|
||||
|
|
Loading…
Reference in a new issue