Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: pkg/kernel/lib/verifier.dart

Issue 2533793005: Check that invocations have well-formed targets in kernel verifier. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/kernel/lib/transformations/mixin_full_resolution.dart ('k') | pkg/kernel/test/verify_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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'
« no previous file with comments | « pkg/kernel/lib/transformations/mixin_full_resolution.dart ('k') | pkg/kernel/test/verify_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698