| Index: pkg/kernel/lib/verifier.dart
|
| diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
|
| index e40b2c00ca0729eaffb100c384ed4599c95a2b41..bed541706342a9719e87cc246e47823734604c06 100644
|
| --- a/pkg/kernel/lib/verifier.dart
|
| +++ b/pkg/kernel/lib/verifier.dart
|
| @@ -246,6 +246,147 @@ class VerifyingVisitor extends RecursiveVisitor {
|
| }
|
|
|
| @override
|
| + visitStaticGet(StaticGet node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'StaticGet without target found in $context.';
|
| + }
|
| + if (!node.target.hasGetter) {
|
| + throw 'StaticGet to ${node.target} without getter found in $context';
|
| + }
|
| + if (node.target.isInstanceMember) {
|
| + throw 'StaticGet to ${node.target} that is not static found in $context';
|
| + }
|
| + }
|
| +
|
| + @override
|
| + visitStaticSet(StaticSet node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'StaticSet without target found in $context.';
|
| + }
|
| + if (!node.target.hasSetter) {
|
| + throw 'StaticSet to ${node.target} without setter found in $context';
|
| + }
|
| + if (node.target.isInstanceMember) {
|
| + throw 'StaticSet to ${node.target} that is not static found in $context';
|
| + }
|
| + }
|
| +
|
| + @override
|
| + visitStaticInvocation(StaticInvocation node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'StaticInvocation without target found in $context.';
|
| + }
|
| + if (node.target.isInstanceMember) {
|
| + throw 'StaticInvocation to ${node.target} that is not static found in '
|
| + '$context';
|
| + }
|
| + if (!areArgumentsCompatible(node.arguments, node.target.function)) {
|
| + throw 'StaticInvocation with incompatible arguments to '
|
| + '${node.target} found in $context';
|
| + }
|
| + if (node.arguments.types.length !=
|
| + node.target.function.typeParameters.length) {
|
| + throw 'Wrong number of type arguments provided in StaticInvocation '
|
| + 'to ${node.target} found in $context';
|
| + }
|
| + }
|
| +
|
| + @override
|
| + visitDirectPropertyGet(DirectPropertyGet node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'DirectPropertyGet without target found in $context.';
|
| + }
|
| + if (!node.target.hasGetter) {
|
| + throw 'DirectPropertyGet to ${node.target} without getter found in '
|
| + '$context';
|
| + }
|
| + if (!node.target.isInstanceMember) {
|
| + throw 'DirectPropertyGet to ${node.target} that is static found in '
|
| + '$context';
|
| + }
|
| + }
|
| +
|
| + @override
|
| + visitDirectPropertySet(DirectPropertySet node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'DirectPropertySet without target found in $context.';
|
| + }
|
| + if (!node.target.hasSetter) {
|
| + throw 'DirectPropertyGet to ${node.target} without setter found in '
|
| + '$context';
|
| + }
|
| + if (!node.target.isInstanceMember) {
|
| + throw 'DirectPropertySet to ${node.target} that is static found in '
|
| + '$context';
|
| + }
|
| + }
|
| +
|
| + @override
|
| + visitDirectMethodInvocation(DirectMethodInvocation node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'DirectMethodInvocation without target found in $context.';
|
| + }
|
| + if (!node.target.isInstanceMember) {
|
| + throw 'DirectMethodInvocation to ${node.target} that is static found in '
|
| + '$context';
|
| + }
|
| + if (!areArgumentsCompatible(node.arguments, node.target.function)) {
|
| + throw 'DirectMethodInvocation with incompatible arguments to '
|
| + '${node.target} found in $context';
|
| + }
|
| + if (node.arguments.types.length !=
|
| + node.target.function.typeParameters.length) {
|
| + throw 'Wrong number of type arguments provided in DirectMethodInvocation '
|
| + 'to ${node.target} found in $context';
|
| + }
|
| + }
|
| +
|
| + @override
|
| + visitConstructorInvocation(ConstructorInvocation node) {
|
| + visitChildren(node);
|
| + if (node.target == null) {
|
| + throw 'ConstructorInvocation without target found in $context.';
|
| + }
|
| + if (node.target.enclosingClass.isAbstract) {
|
| + throw 'ConstructorInvocation to abstract class found in $context';
|
| + }
|
| + if (!areArgumentsCompatible(node.arguments, node.target.function)) {
|
| + throw 'ConstructorInvocation with incompatible arguments to '
|
| + '${node.target} found in $context';
|
| + }
|
| + if (node.arguments.types.length !=
|
| + node.target.enclosingClass.typeParameters.length) {
|
| + throw 'Wrong number of type arguments provided in ConstructorInvocation '
|
| + 'to ${node.target} found in $context';
|
| + }
|
| + }
|
| +
|
| + bool areArgumentsCompatible(Arguments arguments, FunctionNode function) {
|
| + if (arguments.positional.length < function.requiredParameterCount) {
|
| + return false;
|
| + }
|
| + if (arguments.positional.length > function.positionalParameters.length) {
|
| + return false;
|
| + }
|
| + namedLoop:
|
| + for (int i = 0; i < arguments.named.length; ++i) {
|
| + var argument = arguments.named[i];
|
| + String name = argument.name;
|
| + for (int j = 0; j < function.namedParameters.length; ++j) {
|
| + if (function.namedParameters[j].name == name) continue namedLoop;
|
| + }
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + @override
|
| defaultMemberReference(Member node) {
|
| if (node.transformerFlags & TransformerFlag.seenByVerifier == 0) {
|
| throw 'Dangling reference to $node found in $context.\n'
|
|
|