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

Unified Diff: pkg/compiler/lib/src/stats/builder.dart

Issue 1220043005: dart2js send stats, includes: (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months 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
Index: pkg/compiler/lib/src/stats/builder.dart
diff --git a/pkg/compiler/lib/src/stats/builder.dart b/pkg/compiler/lib/src/stats/builder.dart
new file mode 100644
index 0000000000000000000000000000000000000000..1e683bd22ff1a743d19905636e6875d136a1d88c
--- /dev/null
+++ b/pkg/compiler/lib/src/stats/builder.dart
@@ -0,0 +1,2381 @@
+// Copyright (c) 2015, 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.
+
+/// Computes statistical data about a program. See `stats.dart` for more details
+/// on the kind of data we collect.
+library compiler.src.stats.stats_builder;
+
+import 'dart:convert';
+import 'package:dart2js_info/src/measurements.dart';
+import 'package:dart2js_info/src/util.dart' show recursiveDiagnosticString;
+
+import '../diagnostics/messages.dart' show MessageKind;
+import '../compiler.dart' show Compiler;
+import '../common/tasks.dart' show CompilerTask;
+import '../dart_types.dart';
+import '../closure.dart';
+import '../elements/elements.dart';
+import '../elements/visitor.dart' show ElementVisitor;
+import '../resolution/operators.dart';
+import '../resolution/semantic_visitor.dart';
+import '../resolution/send_resolver.dart';
+import '../resolution/tree_elements.dart';
+import '../constants/expressions.dart';
+import '../parser/partial_elements.dart' show PartialElement;
+import '../tree/tree.dart';
+import '../universe/selector.dart' show Selector;
+import '../universe/call_structure.dart' show CallStructure;
+
+import 'analysis_result.dart';
+import 'naive_analysis_result.dart';
+import 'trusted_types_analysis_result.dart';
+
+/// Collects a set of [Measurements] about send expressions in the function [f].
+// TODO(sigmund): collect information on initializers too.
+Measurements collectSendMeasurements(FunctionElement f, Compiler compiler) {
+ return compiler.withCurrentElement(f, () {
+ // TODO(sigmund): enable for platform too.
+ if (f.library.isPlatformLibrary) return;
+ var name = _qualifiedName(f);
+ if (!f.hasNode) {
+ if (f is PartialElement) return const Measurements.unreachableFunction();
+ assert (f is ConstructorElement && f.isSynthesized);
+ // TODO(sigmund): measure synthethic forwarding sends, measure
+ // initializers
+ return new Measurements.reachableFunction();
+ }
+ if (!f.hasResolvedAst) {
+ _debug('no resolved ast ${f.runtimeType}');
+ return null;
+ }
+ var resolvedAst = f.resolvedAst;
+ if (resolvedAst.node == null) {
+ _debug('no node ${f.runtimeType}');
+ return null;
+ }
+ var def = resolvedAst.elements.getFunctionDefinition(resolvedAst.node);
+ if (def == null) {
+ assert (f is PartialElement);
+ return const Measurements.unreachableFunction();
+ }
+
+ var visitor = new _StatsTraversalVisitor(
+ compiler, resolvedAst.elements,
+ compiler.spanFromNode(resolvedAst.node).uri);
+ resolvedAst.node.accept(visitor);
+ return visitor.measurements;
+ });
+}
+
+_qualifiedName(FunctionElement f) {
+ var cls = f.enclosingClass;
+ return (cls != null) ? '${cls.name}.${f.name}' : f.name;
+}
+
+/// Visitor that categorizes data about an individual send.
+class _StatsVisitor<T> extends Visitor
+ with SendResolverMixin, SemanticSendResolvedMixin<dynamic, T>
+ implements SemanticSendVisitor<dynamic, T> {
+
+ // TODO(sigmund): consider passing in several AnalysisResults at once, so we
+ // can compute the different metrics together.
+ /// Information we know about the program from static analysis.
+ final AnalysisResult info;
+
+ /// Results from this function.
+ final Measurements measurements;
+
+ final Compiler compiler;
+ final TreeElements elements;
+
+ SemanticSendVisitor<dynamic, T> get sendVisitor => this;
+
+ _StatsVisitor(this.compiler, this.elements, this.info, Uri sourceUri)
+ : measurements = new Measurements.reachableFunction(sourceUri);
+
+ visitNode(Node node) => throw "unhandled ${node.runtimeType}: $node";
+ apply(Node node, T arg) => throw "missing apply ${node.runtimeType}: $node";
+ internalError(Node node, String arg) => throw "internal error on $node";
+
+ visitSend(Send node) {
+ _checkInvariant(node, 'before');
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.send, span.begin, span.end);
+ if (node is SendSet) {
+ if ((node.assignmentOperator != null &&
+ node.assignmentOperator.source != '=') ||
+ node.isPrefix ||
+ node.isPostfix) {
+ assert(!node.isIfNullAssignment);
+ // We count get and set separately in case one of them is defined by the
+ // other could be a nSM error.
+ measurements.record(Metric.send, span.begin, span.end);
+ measurements.record(Metric.send, span.begin, span.end);
+ } else if (node.isIfNullAssignment) {
+ measurements.record(Metric.send, span.begin, span.end);
+ }
+ }
+ super.visitSend(node);
+ _checkInvariant(node, 'after ');
+ }
+
+ visitNewExpression(NewExpression node) {
+ _checkInvariant(node, 'before');
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.send, span.begin, span.end);
+ super.visitNewExpression(node);
+ _checkInvariant(node, 'after ');
+ }
+
+ /// A monomorphic local variable read.
+ ///
+ /// See [Metric.send] for a full categorization of sends.
+ handleLocal(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.localSend, span.begin, span.end);
+ }
+
+ /// A monomorphic virual call on [node], where we know which function is the
+ /// target of the call (for example, because only one type in a class
+ /// hierarchy implements a function with a given name).
+ ///
+ /// See [Metric.send] for a full categorization of sends.
+ handleSingleInstance(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.instanceSend, span.begin, span.end);
+ }
+
+ /// A monomorphic call that goes through an interceptor. This is equivalent in
+ /// terms of what the compiler knows as we do with [handleSignleInstance], and
+ /// because we know the target of the call, we also know that it doesn't live
+ /// in the object instance, but on an interceptor on the side.
+ ///
+ /// See [Metric.send] for a full categorization of sends.
+ handleSingleInterceptor(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.interceptorSend, span.begin, span.end);
+ }
+
+ /// A polymorphic call that goes through an interceptor.
+ ///
+ /// See [Metric.send] for a full categorization of sends.
+ handleMultiInterceptor(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.polymorphicSend, span.begin, span.end);
+ measurements.record(Metric.multiInterceptorSend, span.begin, span.end);
+ }
+
+ handleConstructor(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.constructorSend, span.begin, span.end);
+ }
+
+ handleDynamic(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.polymorphicSend, span.begin, span.end);
+ measurements.record(Metric.dynamicSend, span.begin, span.end);
+ }
+
+ handleVirtual(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.polymorphicSend, span.begin, span.end);
+ measurements.record(Metric.virtualSend, span.begin, span.end);
+ }
+
+ handleNSMError(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.nsmErrorSend, span.begin, span.end);
+ }
+
+ handleNSMSingle(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.singleNsmCallSend, span.begin, span.end);
+ }
+
+ handleNSMSuper(Node node, ClassElement type) {
+ var superclass = type.superclass;
+ var member = superclass.lookupMember('noSuchMethod');
+ if (!member.enclosingClass.isObject) {
+ handleNSMSingle(node);
+ } else {
+ handleNSMError(node);
+ }
+ }
+
+ handleNSMAny(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.polymorphicSend, span.begin, span.end);
+ measurements.record(Metric.multiNsmCallSend, span.begin, span.end);
+ }
+
+ handleSuper(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.superSend, span.begin, span.end);
+ }
+ handleTypeVariable(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.typeVariableSend, span.begin, span.end);
+ }
+ handleStatic(Node node) {
+ var span = compiler.spanFromNode(node);
+ measurements.record(Metric.monomorphicSend, span.begin, span.end);
+ measurements.record(Metric.staticSend, span.begin, span.end);
+ }
+
+ handleNoSend(Node node) {
+ measurements.popLast(Metric.send);
+ }
+
+ void handleDynamicProperty(Node node, Node receiver, Selector selector) {
+ // staticSend: no (automatically)
+ // superSend: no (automatically)
+ // localSend: no (automatically)
+ // constructorSend: no (automatically)
+ // typeVariableSend: no (automatically)
+
+ // nsmErrorSend: receiver has no `selector` nor nSM.
+ // singleNsmCallSend: receiver has no `selector`, but definitely has `nSM`
+ // instanceSend: receiver has `selector`, no need to use an interceptor
+ // interceptorSend: receiver has `selector`, but we know we need an
+ // interceptor to get it
+
+ // multiNsmCallSend: receiver has no `selector`, not sure if receiver has
+ // nSM, or not sure which nSM is called (does this one
+ // matter, or does nSM is treated like an instance method
+ // call)?
+ // virtualSend: receiver has `selector`, we know we do not need an
+ // interceptor, not sure which specific type implements
+ // the selector.
+ // multiInterceptorSend: multiple possible receiver types, all using an
+ // interceptor to get the `selector`, might be
+ // possbile to pick a special selector logic for this
+ // combination?
+ // dynamicSend: any combination of the above.
+
+ ReceiverInfo receiverInfo = info.infoForReceiver(receiver);
+ SelectorInfo selectorInfo = info.infoForSelector(receiver, selector);
+ Boolish hasSelector = selectorInfo.exists;
+ Boolish hasNsm = receiverInfo.hasNoSuchMethod;
+
+ if (hasSelector == Boolish.no) {
+ if (hasNsm == Boolish.no) {
+ handleNSMError(node);
+ } else if (hasNsm == Boolish.yes) {
+ if (receiverInfo.possibleNsmTargets == 1) {
+ handleNSMSingle(node);
+ } else {
+ handleNSMAny(node);
+ }
+ } else {
+ handleDynamic(node);
+ }
+ return;
+ }
+
+ Boolish usesInterceptor = selectorInfo.usesInterceptor;
+ if (hasSelector == Boolish.yes) {
+ if (selectorInfo.isAccurate && selectorInfo.possibleTargets == 1) {
+ assert (usesInterceptor != Boolish.maybe);
+ if (usesInterceptor == Boolish.yes) {
+ handleSingleInterceptor(node);
+ } else {
+ handleSingleInstance(node);
+ }
+ } else {
+ if (usesInterceptor == Boolish.no) {
+ handleVirtual(node);
+ } else if (usesInterceptor == Boolish.yes) {
+ handleMultiInterceptor(node);
+ } else {
+ handleDynamic(node);
+ }
+ }
+ return;
+ }
+ handleDynamic(node);
+ }
+
+ void handleThisProperty(Send node, Selector selector) {
+ handleDynamicProperty(node, node.receiver, selector);
+ }
+
+ void handleIndex(Node node) {
+ handleDynamic(node);
+ }
+
+ void handleOperator(Node node) {
+ handleDynamic(node);
+ }
+
+ void handleInvoke(Node node) {
+ handleDynamic(node);
+ }
+
+ void handleEquals(Node node) {
+ handleDynamic(node);
+ }
+
+ // Constructors
+
+ void visitAbstractClassConstructorInvoke(NewExpression node,
+ ConstructorElement element, InterfaceType type, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
+ BoolFromEnvironmentConstantExpression constant, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitConstConstructorInvoke(
+ NewExpression node, ConstructedConstantExpression constant, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitGenerativeConstructorInvoke(NewExpression node,
+ ConstructorElement constructor, InterfaceType type, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitIntFromEnvironmentConstructorInvoke(NewExpression node,
+ IntFromEnvironmentConstantExpression constant, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitRedirectingFactoryConstructorInvoke(NewExpression node,
+ ConstructorElement constructor, InterfaceType type,
+ ConstructorElement effectiveTarget, InterfaceType effectiveTargetType,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitRedirectingGenerativeConstructorInvoke(NewExpression node,
+ ConstructorElement constructor, InterfaceType type, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleConstructor(node);
+ }
+
+ void visitStringFromEnvironmentConstructorInvoke(NewExpression node,
+ StringFromEnvironmentConstantExpression constant, T arg) {
+ handleConstructor(node);
+ }
+
+ // Dynamic sends
+
+
+ // TODO(sigmund): many many things to add:
+ // -- support for operators, indexers, etc.
+ // -- logic about nullables
+ // -- int, JSArray
+ // -- all interceptors
+
+ void visitBinary(
+ Send node, Node left, BinaryOperator operator, Node right, T arg) {
+ handleOperator(node);
+ }
+
+ void visitCompoundIndexSet(SendSet node, Node receiver, Node index,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleIndex(node); // t1 = receiver[index]
+ handleOperator(node); // t2 = t1 op rhs
+ handleIndex(node); // receiver[index] = t2
+ }
+
+ void visitDynamicPropertyCompound(Send node, Node receiver,
+ Name name, AssignmentOperator operator, Node rhs, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleOperator(node);
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+
+ void visitDynamicPropertyGet(
+ Send node, Node receiver, Name name, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ }
+
+ void visitDynamicPropertyInvoke(
+ Send node, Node receiver, NodeList arguments, Selector selector, T arg) {
+ handleDynamicProperty(node, receiver, selector);
+ }
+
+ void visitDynamicPropertyPostfix(Send node, Node receiver,
+ Name name, IncDecOperator operator, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleOperator(node);
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitDynamicPropertyPrefix(Send node, Node receiver, Name name,
+ IncDecOperator operator, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleOperator(node);
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitDynamicPropertySet(
+ SendSet node, Node receiver, Name name, Node rhs, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitDynamicPropertySetIfNull(
+ Send node, Node receiver, Name name, Node rhs, T arg) {
+ // read to check for null?
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitEquals(Send node, Node left, Node right, T arg) {
+ handleEquals(node);
+ }
+
+ void visitExpressionInvoke(Send node, Node expression, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitIfNotNullDynamicPropertyCompound(Send node, Node receiver,
+ Name name, AssignmentOperator operator, Node rhs, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleOperator(node);
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitIfNotNullDynamicPropertyGet(
+ Send node, Node receiver, Name name, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ }
+
+ void visitIfNotNullDynamicPropertyInvoke(
+ Send node, Node receiver, NodeList arguments, Selector selector, T arg) {
+ handleDynamicProperty(node, receiver, selector);
+ }
+
+ void visitIfNotNullDynamicPropertyPostfix(Send node, Node receiver, Name name,
+ IncDecOperator operator, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleOperator(node);
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitIfNotNullDynamicPropertyPrefix(Send node, Node receiver, Name name,
+ IncDecOperator operator, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleOperator(node);
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitIfNotNullDynamicPropertySet(
+ SendSet node, Node receiver, Name name, Node rhs, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitIfNotNullDynamicPropertySetIfNull(
+ Send node, Node receiver, Name name, Node rhs, T arg) {
+ handleDynamicProperty(node, receiver, new Selector.getter(name));
+ handleDynamicProperty(node, receiver, new Selector.setter(name));
+ }
+
+ void visitIndex(Send node, Node receiver, Node index, T arg) {
+ handleIndex(node);
+ }
+
+ void visitIndexPostfix(
+ Send node, Node receiver, Node index, IncDecOperator operator, T arg) {
+ handleIndex(node);
+ handleOperator(node);
+ handleIndex(node);
+ }
+
+ void visitIndexPrefix(
+ Send node, Node receiver, Node index, IncDecOperator operator, T arg) {
+ handleIndex(node);
+ handleOperator(node);
+ handleIndex(node);
+ }
+
+ void visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, T arg) {
+ handleIndex(node);
+ }
+
+ void visitLocalVariableCompound(Send node, LocalVariableElement variable,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleLocal(node);
+ }
+
+ void visitLocalVariableInvoke(Send node, LocalVariableElement variable,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitLocalVariablePostfix(Send node, LocalVariableElement variable,
+ IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleLocal(node);
+ }
+
+ void visitLocalVariablePrefix(Send node, LocalVariableElement variable,
+ IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleLocal(node);
+ }
+
+ void visitNotEquals(Send node, Node left, Node right, T arg) {
+ handleEquals(node);
+ }
+
+ void visitParameterCompound(Send node, ParameterElement parameter,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleLocal(node);
+ }
+
+ void visitParameterInvoke(Send node, ParameterElement parameter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitParameterPostfix(
+ Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleLocal(node);
+ }
+
+ void visitParameterPrefix(
+ Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleLocal(node);
+ }
+
+ void visitStaticFieldCompound(Send node, FieldElement field,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitStaticFieldPostfix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitStaticFieldPrefix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitStaticGetterInvoke(Send node, FunctionElement getter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitStaticGetterSetterCompound(Send node, FunctionElement getter,
+ FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitStaticGetterSetterPostfix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitStaticGetterSetterPrefix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitSuperFieldCompound(Send node, FieldElement field,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldFieldCompound(Send node, FieldElement readField,
+ FieldElement writtenField, AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldFieldPostfix(Send node, FieldElement readField,
+ FieldElement writtenField, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldFieldPrefix(Send node, FieldElement readField,
+ FieldElement writtenField, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldFieldSetIfNull(
+ Send node, FieldElement readField, FieldElement writtenField, Node rhs,
+ T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, readField.enclosingClass);
+ }
+
+ void visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitSuperFieldPostfix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldPrefix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldSetterCompound(Send node, FieldElement field,
+ FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldSetterPostfix(Send node, FieldElement field,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldSetterPrefix(Send node, FieldElement field,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperFieldSetterSetIfNull(Send node, FieldElement field,
+ FunctionElement setter, Node rhs, T arg) {
+ handleSuper(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterFieldCompound(Send node, FunctionElement getter,
+ FieldElement field, AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterFieldPostfix(Send node, FunctionElement getter,
+ FieldElement field, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterFieldPrefix(Send node, FunctionElement getter,
+ FieldElement field, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterFieldSetIfNull(Send node, FunctionElement getter,
+ FieldElement field, Node rhs, T arg) {
+ handleSuper(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterInvoke(Send node, FunctionElement getter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitSuperGetterSetterCompound(Send node, FunctionElement getter,
+ FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterSetterPostfix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterSetterPrefix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterSetterSetIfNull(Send node, FunctionElement getter,
+ FunctionElement setter, Node rhs, T arg) {
+ handleSuper(node);
+ handleSuper(node);
+ }
+
+ void visitSuperIndexPostfix(Send node, MethodElement indexFunction,
+ MethodElement indexSetFunction, Node index, IncDecOperator operator,
+ T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperIndexPrefix(Send node, MethodElement indexFunction,
+ MethodElement indexSetFunction, Node index, IncDecOperator operator,
+ T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitSuperMethodSetterCompound(Send node, FunctionElement method,
+ FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, method.enclosingClass);
+ handleSuper(node);
+ }
+
+ void visitSuperMethodSetterPostfix(Send node, FunctionElement method,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, method.enclosingClass);
+ handleSuper(node);
+ }
+
+ void visitSuperMethodSetterPrefix(Send node, FunctionElement method,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, method.enclosingClass);
+ handleSuper(node);
+ }
+
+ void visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
+ FunctionElement setter, Node rhs, T arg) {
+ handleSuper(node);
+ handleSuper(node);
+ }
+
+ void visitThisPropertyCompound(Send node, Name name,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleThisProperty(node, new Selector.getter(name));
+ handleOperator(node);
+ handleThisProperty(node, new Selector.setter(name));
+ }
+
+ void visitThisPropertyInvoke(
+ Send node, NodeList arguments, Selector selector, T arg) {
+ handleThisProperty(node, selector);
+ }
+
+ void visitThisPropertyPostfix(Send node, Name name, IncDecOperator operator,
+ T arg) {
+ handleThisProperty(node, new Selector.getter(name));
+ handleOperator(node);
+ handleThisProperty(node, new Selector.setter(name));
+ }
+
+ void visitThisPropertyPrefix(Send node, Name name, IncDecOperator operator,
+ T arg) {
+ handleThisProperty(node, new Selector.getter(name));
+ handleOperator(node);
+ handleThisProperty(node, new Selector.setter(name));
+ }
+
+ void visitTopLevelFieldCompound(Send node, FieldElement field,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelFieldInvoke(Send node, FieldElement field,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitTopLevelFieldPostfix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelFieldPrefix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelGetterInvoke(Send node, FunctionElement getter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleInvoke(node);
+ }
+
+ void visitTopLevelGetterSetterCompound(Send node, FunctionElement getter,
+ FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelGetterSetterPostfix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelGetterSetterPrefix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleStatic(node);
+ }
+
+ void visitUnary(Send node, UnaryOperator operator, Node expression, T arg) {
+ handleDynamic(node);
+ }
+
+ // Local variable sends
+
+ void visitLocalFunctionGet(Send node, LocalFunctionElement function, T arg) {
+ handleLocal(node);
+ }
+
+ void visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleLocal(node);
+ }
+
+ void visitLocalVariableGet(Send node, LocalVariableElement variable, T arg) {
+ handleLocal(node);
+ }
+
+ void visitLocalVariableSet(
+ SendSet node, LocalVariableElement variable, Node rhs, T arg) {
+ handleLocal(node);
+ }
+
+ void visitLocalVariableSetIfNull(
+ SendSet node, LocalVariableElement variable, Node rhs, T arg) {
+ handleLocal(node);
+ handleLocal(node);
+ }
+
+ void visitParameterGet(Send node, ParameterElement parameter, T arg) {
+ handleLocal(node);
+ }
+
+ void visitParameterSet(
+ SendSet node, ParameterElement parameter, Node rhs, T arg) {
+ handleLocal(node);
+ }
+
+ void visitParameterSetIfNull(
+ Send node, ParameterElement parameter, Node rhs, T arg) {
+ handleLocal(node);
+ handleLocal(node);
+ }
+
+ // Super monomorphic sends
+
+ void visitSuperBinary(Send node, FunctionElement function,
+ BinaryOperator operator, Node argument, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperEquals(
+ Send node, FunctionElement function, Node argument, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperFieldGet(Send node, FieldElement field, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperFieldSetIfNull(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleSuper(node);
+ handleSuper(node);
+ }
+
+ void visitSuperGetterGet(Send node, FunctionElement getter, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperGetterSet(
+ SendSet node, FunctionElement getter, Node rhs, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperIndex(Send node, FunctionElement function, Node index, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperIndexSet(
+ SendSet node, FunctionElement function, Node index, Node rhs, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperMethodGet(Send node, MethodElement method, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperMethodInvoke(Send node, MethodElement method,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperNotEquals(
+ Send node, FunctionElement function, Node argument, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperSetterSet(
+ SendSet node, FunctionElement setter, Node rhs, T arg) {
+ handleSuper(node);
+ }
+
+ void visitSuperUnary(
+ Send node, UnaryOperator operator, FunctionElement function, T arg) {
+ handleSuper(node);
+ }
+
+ // Statically known "no such method" sends
+
+ void visitConstructorIncompatibleInvoke(NewExpression node,
+ ConstructorElement constructor, InterfaceType type, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
+ IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
+ IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalLocalVariableSet(
+ SendSet node, LocalVariableElement variable, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitFinalLocalVariableSetIfNull(
+ SendSet node, LocalVariableElement variable, Node rhs, T arg) {
+ handleLocal(node); // read for null
+ handleNSMError(node); // set fails
+ }
+
+ void visitFinalParameterCompound(Send node, ParameterElement parameter,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalParameterPostfix(
+ Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalParameterPrefix(
+ Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalParameterSet(
+ SendSet node, ParameterElement parameter, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitFinalParameterSetIfNull(
+ SendSet node, ParameterElement parameter, Node rhs, T arg) {
+ handleLocal(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalStaticFieldCompound(Send node, FieldElement field,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalStaticFieldPostfix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalStaticFieldPrefix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalStaticFieldSet(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitFinalStaticFieldSetIfNull(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalSuperFieldSetIfNull(Send node, FieldElement field,
+ Node rhs, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, field.enclosingClass);
+ }
+
+ void visitFinalSuperFieldCompound(Send node, FieldElement field,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, field.enclosingClass);
+ }
+
+ void visitFinalSuperFieldPostfix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, field.enclosingClass);
+ }
+
+ void visitFinalSuperFieldPrefix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, field.enclosingClass);
+ }
+
+ void visitFinalSuperFieldSet(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleNSMSuper(node, field.enclosingClass);
+ }
+
+ void visitFinalTopLevelFieldCompound(Send node, FieldElement field,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalTopLevelFieldPostfix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalTopLevelFieldPrefix(
+ Send node, FieldElement field, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleOperator(node);
+ handleNSMError(node);
+ }
+
+ void visitFinalTopLevelFieldSet(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitFinalTopLevelFieldSetIfNull(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitTopLevelGetterSetterSetIfNull(Send node, FunctionElement getter,
+ FunctionElement setter, Node rhs, T arg) {
+ handleStatic(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
+ FunctionElement setter, Node rhs, T arg) {
+ handleStatic(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelMethodSetIfNull(Send node, FunctionElement method,
+ Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitLocalFunctionIncompatibleInvoke(Send node,
+ LocalFunctionElement function, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitLocalFunctionCompound(Send node, LocalFunctionElement function,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleLocal(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
+ IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
+ IncDecOperator operator, T arg) {
+ handleLocal(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitLocalFunctionSet(
+ SendSet node, LocalFunctionElement function, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitLocalFunctionSetIfNull(
+ SendSet node, LocalFunctionElement function, Node rhs, T arg) {
+ handleLocal(node);
+ handleNSMError(node);
+ }
+
+ void visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitStaticFunctionSet(
+ Send node, MethodElement function, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitStaticMethodCompound(Send node, MethodElement method,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node); // operator on a method closure yields nSM
+ handleNoSend(node); // setter is not invoked, don't count it.
+ }
+
+ void visitStaticMethodPostfix(
+ Send node, MethodElement method, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitStaticMethodPrefix(
+ Send node, MethodElement method, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitStaticMethodSetterCompound(Send node, MethodElement method,
+ MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node); // operator on a method closure yields nSM
+ handleNoSend(node); // setter is not invoked, don't count it.
+ }
+
+ void visitStaticMethodSetterPostfix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitStaticMethodSetterPrefix(Send node, FunctionElement getter,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitStaticSetterGet(Send node, FunctionElement setter, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitStaticSetterInvoke(Send node, FunctionElement setter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitSuperMethodCompound(Send node, FunctionElement method,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+
+ // An operator send on a method closure yields nSM
+ handleNSMSuper(node, method.enclosingClass);
+
+ handleNoSend(node); // setter is not invoked, don't count it.
+ }
+
+ void visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMSuper(node, method.enclosingClass);
+ }
+
+ void visitSuperMethodPostfix(
+ Send node, FunctionElement method, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, method.enclosingClass);
+ handleNoSend(node);
+ }
+
+ void visitSuperMethodPrefix(
+ Send node, FunctionElement method, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, method.enclosingClass);
+ handleNoSend(node);
+ }
+
+ void visitSuperMethodSet(Send node, MethodElement method, Node rhs, T arg) {
+ handleNSMSuper(node, method.enclosingClass);
+ }
+
+ void visitSuperMethodSetIfNull(
+ Send node, MethodElement method, Node rhs, T arg) {
+ handleNSMSuper(node, method.enclosingClass);
+ }
+
+ void visitSuperSetterGet(Send node, FunctionElement setter, T arg) {
+ handleNSMSuper(node, setter.enclosingClass);
+ }
+
+ void visitSuperSetterInvoke(Send node, FunctionElement setter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMSuper(node, setter.enclosingClass);
+ }
+
+ void visitTopLevelFunctionIncompatibleInvoke(Send node,
+ MethodElement function, NodeList arguments, CallStructure callStructure,
+ T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTopLevelFunctionSet(
+ Send node, MethodElement function, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTopLevelGetterSet(
+ SendSet node, FunctionElement getter, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTopLevelMethodCompound(Send node, FunctionElement method,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node); // operator on a method closure yields nSM
+ handleNoSend(node); // setter is not invoked, don't count it.
+ }
+
+ void visitTopLevelMethodPostfix(
+ Send node, MethodElement method, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTopLevelMethodPrefix(
+ Send node, MethodElement method, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
+ FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node); // operator on a method closure yields nSM
+ handleNoSend(node); // setter is not invoked, don't count it.
+ }
+
+ void visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
+ FunctionElement setter, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTopLevelSetterGet(Send node, FunctionElement setter, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTopLevelSetterInvoke(Send node, FunctionElement setter,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTypeVariableTypeLiteralCompound(Send node,
+ TypeVariableElement element, AssignmentOperator operator, Node rhs,
+ T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node); // operator on a method closure yields nSM
+ handleNoSend(node); // setter is not invoked, don't count it.
+ }
+
+ void visitTypeVariableTypeLiteralGet(
+ Send node, TypeVariableElement element, T arg) {
+ handleTypeVariable(node);
+ }
+
+ void visitTypeVariableTypeLiteralInvoke(Send node,
+ TypeVariableElement element, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTypeVariableTypeLiteralPostfix(
+ Send node, TypeVariableElement element, IncDecOperator operator, T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTypeVariableTypeLiteralPrefix(
+ Send node, TypeVariableElement element, IncDecOperator operator, T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTypeVariableTypeLiteralSet(
+ SendSet node, TypeVariableElement element, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTypeVariableTypeLiteralSetIfNull(
+ SendSet node, TypeVariableElement element, Node rhs, T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node);
+ }
+
+ void visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTypedefTypeLiteralGet(
+ Send node, ConstantExpression constant, T arg) {
+ handleTypeVariable(node);
+ }
+
+ void visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTypedefTypeLiteralPostfix(
+ Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTypedefTypeLiteralPrefix(
+ Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
+ handleTypeVariable(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitTypedefTypeLiteralSet(
+ SendSet node, ConstantExpression constant, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitTypedefTypeLiteralSetIfNull(
+ SendSet node, ConstantExpression constant, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedClassConstructorInvoke(NewExpression node,
+ Element element, DartType type, NodeList arguments, Selector selector,
+ T arg) {
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedCompound(Send node, Element element,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
+ DartType type, NodeList arguments, Selector selector, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedGet(Send node, Element element, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedInvoke(Send node, Element element, NodeList arguments,
+ Selector selector, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedPostfix(
+ Send node, Element element, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedPrefix(
+ Send node, Element element, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedRedirectingFactoryConstructorInvoke(NewExpression node,
+ ConstructorElement constructor, InterfaceType type, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedSet(Send node, Element element, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitUnresolvedSetIfNull(Send node, Element element, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticGetterCompound(Send node, Element element,
+ MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticGetterPostfix(Send node, Element element,
+ MethodElement setter, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticGetterPrefix(Send node, Element element,
+ MethodElement setter, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticGetterSetIfNull(Send node, Element element,
+ MethodElement setter, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticSetterCompound(Send node, MethodElement getter,
+ Element element, AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticSetterPostfix(Send node, MethodElement getter,
+ Element element, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticSetterPrefix(Send node, MethodElement getter,
+ Element element, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedStaticSetterSetIfNull(Send node, MethodElement getter,
+ Element element, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedSuperBinary(Send node, Element element,
+ BinaryOperator operator, Node argument, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperCompound(Send node, Element element,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ // TODO(sigmund): we should only count the next 2 if we know that the
+ // superclass has a nSM method.
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperCompoundIndexSet(Send node, Element element,
+ Node index, AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleNoSend(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperGet(Send node, Element element, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetIfNull(
+ Send node, Element element, Node rhs, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedSuperGetterCompound(Send node, Element element,
+ MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperGetterCompoundIndexSet(Send node, Element element,
+ MethodElement setter, Node index, AssignmentOperator operator, Node rhs,
+ T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperGetterIndexPostfix(Send node, Element element,
+ MethodElement setter, Node index, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperGetterIndexPrefix(Send node, Element element,
+ MethodElement setter, Node index, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperGetterPostfix(Send node, Element element,
+ MethodElement setter, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperGetterPrefix(Send node, Element element,
+ MethodElement setter, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperGetterSetIfNull(Send node, Element element,
+ MethodElement setter, Node rhs, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleSuper(node);
+ }
+
+ void visitUnresolvedSuperIndex(
+ Send node, Element element, Node index, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperIndexPostfix(
+ Send node, Element element, Node index, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperIndexPrefix(
+ Send node, Element element, Node index, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperIndexSet(
+ Send node, Element element, Node index, Node rhs, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperInvoke(Send node, Element element,
+ NodeList arguments, Selector selector, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperPostfix(
+ Send node, Element element, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperPrefix(
+ Send node, Element element, IncDecOperator operator, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterCompound(Send node, MethodElement getter,
+ Element element, AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterCompoundIndexSet(Send node,
+ MethodElement getter, Element element, Node index,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterIndexPostfix(Send node,
+ MethodElement indexFunction, Element element, Node index,
+ IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterIndexPrefix(Send node,
+ MethodElement indexFunction, Element element, Node index,
+ IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterPostfix(Send node, MethodElement getter,
+ Element element, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterPrefix(Send node, MethodElement getter,
+ Element element, IncDecOperator operator, T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperSetterSetIfNull(Send node, MethodElement getter,
+ Element element, Node rhs, T arg) {
+ handleSuper(node);
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedSuperUnary(
+ Send node, UnaryOperator operator, Element element, T arg) {
+ handleNSMSuper(node, element.enclosingClass);
+ }
+
+ void visitUnresolvedTopLevelGetterCompound(Send node, Element element,
+ MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
+ MethodElement setter, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
+ MethodElement setter, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelGetterSetIfNull(Send node, Element element,
+ MethodElement setter, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelSetterCompound(Send node, MethodElement getter,
+ Element element, AssignmentOperator operator, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelSetterPostfix(Send node, MethodElement getter,
+ Element element, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelSetterPrefix(Send node, MethodElement getter,
+ Element element, IncDecOperator operator, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void visitUnresolvedTopLevelSetterSetIfNull(Send node, MethodElement getter,
+ Element element, Node rhs, T arg) {
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ // Static
+
+ void visitConstantGet(Send node, ConstantExpression constant, T arg) {
+ handleStatic(node);
+ }
+
+ void visitConstantInvoke(Send node, ConstantExpression constant,
+ NodeList arguments, CallStructure callStreucture, T arg) {
+ handleStatic(node);
+ }
+
+ void visitFactoryConstructorInvoke(NewExpression node,
+ ConstructorElement constructor, InterfaceType type, NodeList arguments,
+ CallStructure callStructure, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticFieldGet(Send node, FieldElement field, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticFieldSetIfNull(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleStatic(node);
+ handleStatic(node);
+ }
+
+ void visitStaticFunctionGet(Send node, MethodElement function, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticFunctionInvoke(Send node, MethodElement function,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticGetterGet(Send node, FunctionElement getter, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticGetterSet(
+ SendSet node, FunctionElement getter, Node rhs, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticSetterSet(
+ SendSet node, FunctionElement setter, Node rhs, T arg) {
+ handleStatic(node);
+ }
+
+ void visitStaticGetterSetterSetIfNull(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ Node rhs,
+ T arg) {
+ handleStatic(node);
+ handleStatic(node);
+ }
+
+ void visitStaticMethodSetterSetIfNull(
+ Send node,
+ MethodElement method,
+ MethodElement setter,
+ Node rhs,
+ T arg) {
+ handleStatic(node);
+ handleStatic(node);
+ }
+
+ void visitStaticMethodSetIfNull(
+ Send node,
+ FunctionElement method,
+ Node rhs,
+ T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitTopLevelFieldGet(Send node, FieldElement field, T arg) {
+ handleStatic(node);
+ }
+
+ void visitTopLevelFieldSet(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleStatic(node);
+ }
+
+ void visitTopLevelFieldSetIfNull(
+ SendSet node, FieldElement field, Node rhs, T arg) {
+ handleStatic(node);
+ handleStatic(node);
+ }
+
+ void visitTopLevelFunctionGet(Send node, MethodElement function, T arg) {
+ handleStatic(node);
+ }
+
+ void visitTopLevelFunctionInvoke(Send node, MethodElement function,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleStatic(node);
+ }
+
+ void visitTopLevelGetterGet(Send node, FunctionElement getter, T arg) {
+ handleStatic(node);
+ }
+
+ void visitTopLevelSetterSet(
+ SendSet node, FunctionElement setter, Node rhs, T arg) {
+ handleStatic(node);
+ }
+
+ // Virtual
+
+ void visitSuperCompoundIndexSet(SendSet node, MethodElement getter,
+ MethodElement setter, Node index, AssignmentOperator operator, Node rhs,
+ T arg) {
+ handleSuper(node);
+ handleOperator(node);
+ handleSuper(node);
+ }
+
+ void visitThisGet(Identifier node, T arg) {
+ handleLocal(node); // TODO(sigmund): should we add a metric for "this"?
+ }
+
+ void visitThisInvoke(
+ Send node, NodeList arguments, CallStructure callStructure, T arg) {
+ // TODO(sigmund): implement (treat like this.call())
+ handleDynamic(node);
+ }
+
+ void visitThisPropertyGet(Send node, Name name, T arg) {
+ handleThisProperty(node, new Selector.getter(name));
+ }
+
+ void visitThisPropertySet(SendSet node, Name name, Node rhs, T arg) {
+ handleThisProperty(node, new Selector.setter(name));
+ }
+
+ void visitThisPropertySetIfNull(Send node, Name name, Node rhs, T arg) {
+ handleThisProperty(node, new Selector.getter(name));
+ handleThisProperty(node, new Selector.setter(name));
+ }
+
+ // Not count
+
+ void errorNonConstantConstructorInvoke(NewExpression node, Element element,
+ DartType type, NodeList arguments, CallStructure callStructure, T arg) {
+ handleNoSend(node);
+ }
+
+ void errorUndefinedBinaryExpression(
+ Send node, Node left, Operator operator, Node right, T arg) {
+ handleNoSend(node);
+ }
+
+ void errorUndefinedUnaryExpression(
+ Send node, Operator operator, Node expression, T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidGet(
+ Send node,
+ ErroneousElement error,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidInvoke(
+ Send node,
+ ErroneousElement error,
+ NodeList arguments,
+ Selector selector,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidSet(
+ Send node,
+ ErroneousElement error,
+ Node rhs,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidSetIfNull(
+ Send node, ErroneousElement error, Node rhs, T arg) {
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+
+ void errorInvalidPrefix(
+ Send node,
+ ErroneousElement error,
+ IncDecOperator operator,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidPostfix(
+ Send node,
+ ErroneousElement error,
+ IncDecOperator operator,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidCompound(
+ Send node,
+ ErroneousElement error,
+ AssignmentOperator operator,
+ Node rhs,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidUnary(
+ Send node,
+ UnaryOperator operator,
+ ErroneousElement error,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidEquals(
+ Send node,
+ ErroneousElement error,
+ Node right,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidNotEquals(
+ Send node,
+ ErroneousElement error,
+ Node right,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidBinary(
+ Send node,
+ ErroneousElement error,
+ BinaryOperator operator,
+ Node right,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidIndex(
+ Send node,
+ ErroneousElement error,
+ Node index,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidIndexSet(
+ Send node,
+ ErroneousElement error,
+ Node index,
+ Node rhs,
+ T arg) {
+ handleNoSend(node);
+ }
+
+ void errorInvalidCompoundIndexSet(
+ Send node,
+ ErroneousElement error,
+ Node index,
+ AssignmentOperator operator,
+ Node rhs,
+ T arg) {
+ handleNoSend(node);
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void errorInvalidIndexPrefix(
+ Send node,
+ ErroneousElement error,
+ Node index,
+ IncDecOperator operator,
+ T arg) {
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void errorInvalidIndexPostfix(
+ Send node,
+ ErroneousElement error,
+ Node index,
+ IncDecOperator operator,
+ T arg) {
+ handleNoSend(node);
+ handleNoSend(node);
+ }
+
+ void previsitDeferredAccess(
+ Send node,
+ PrefixElement prefix,
+ T arg) {
+ }
+
+
+ void visitAs(Send node, Node expression, DartType type, T arg) {
+ handleNoSend(node);
+ }
+
+ void visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitClassTypeLiteralGet(Send node, ConstantExpression constant, T arg) {
+ handleStatic(node);
+ }
+
+ void visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitClassTypeLiteralPostfix(
+ Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitClassTypeLiteralPrefix(
+ Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitClassTypeLiteralSet(
+ SendSet node, ConstantExpression constant, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitClassTypeLiteralSetIfNull(
+ SendSet node, ConstantExpression constant, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
+ AssignmentOperator operator, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitDynamicTypeLiteralGet(
+ Send node, ConstantExpression constant, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
+ NodeList arguments, CallStructure callStructure, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitDynamicTypeLiteralPostfix(
+ Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitDynamicTypeLiteralPrefix(
+ Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ handleNoSend(node);
+ }
+
+ void visitDynamicTypeLiteralSet(
+ SendSet node, ConstantExpression constant, Node rhs, T arg) {
+ handleNSMError(node);
+ }
+
+ void visitDynamicTypeLiteralSetIfNull(
+ SendSet node, ConstantExpression constant, Node rhs, T arg) {
+ handleStatic(node);
+ handleNSMError(node);
+ }
+
+ void visitIfNull(Send node, Node left, Node right, T arg) {
+ handleNoSend(node);
+ }
+
+ void visitIs(Send node, Node expression, DartType type, T arg) {
+ handleNoSend(node);
+ }
+
+ void visitIsNot(Send node, Node expression, DartType type, T arg) {
+ handleNoSend(node);
+ }
+
+ void visitLogicalAnd(Send node, Node left, Node right, T arg) {
+ handleNoSend(node);
+ }
+
+ void visitLogicalOr(Send node, Node left, Node right, T arg) {
+ handleNoSend(node);
+ }
+
+ void visitNot(Send node, Node expression, T arg) {
+ handleNoSend(node);
+ }
+
+ String last;
+ _checkInvariant(node, String msg) {
+ msg = '$msg ${recursiveDiagnosticString(measurements, Metric.send)}';
+ if (!measurements.checkInvariant(Metric.send) ||
+ !measurements.checkInvariant(Metric.monomorphicSend) ||
+ !measurements.checkInvariant(Metric.polymorphicSend)) {
+ compiler.reportErrorMessage(node,
+ MessageKind.GENERIC, {'text': 'bad\n-- $msg\nlast:\n-- $last\n'});
+ last = msg;
+ } else {
+ last = msg;
+ }
+ }
+}
+
+/// Visitor that collects statistics for a single function.
+class _StatsTraversalVisitor<T> extends TraversalVisitor<dynamic, T>
+ implements SemanticSendVisitor<dynamic, T> {
+ final Compiler compiler;
+ final _StatsVisitor statsVisitor;
+ Measurements get measurements => statsVisitor.measurements;
+ _StatsTraversalVisitor(
+ Compiler compiler, TreeElements elements, Uri sourceUri)
+ : compiler = compiler,
+ statsVisitor = new _StatsVisitor(compiler, elements,
+ // TODO(sigmund): accept a list of analyses, so we can compare them
+ // together.
+ true
+ ? new TrustTypesAnalysisResult(elements, compiler.world)
+ : new NaiveAnalysisResult(),
+ sourceUri),
+ super(elements);
+
+ void visitSend(Send node) {
+ try {
+ node.accept(statsVisitor);
+ } catch (e, t) {
+ compiler.reportErrorMessage(
+ node, MessageKind.GENERIC, {'text': '$e\n$t'});
+ }
+ super.visitSend(node);
+ }
+
+ void visitNewExpression(NewExpression node) {
+ try {
+ node.accept(statsVisitor);
+ } catch (e, t) {
+ compiler.reportErrorMessage(
+ node, MessageKind.GENERIC, {'text': '$e\n$t'});
+ }
+ super.visitNewExpression(node);
+ }
+}
+
+/// Helper to visit elements recursively
+// TODO(sigmund): maybe generalize and move to elements/visitor.dart?
+abstract class RecursiveElementVisitor<R, A> extends ElementVisitor<R, A> {
+
+ @override
+ R visitWarnOnUseElement(WarnOnUseElement e, A arg) =>
+ e.wrappedElement.accept(this, arg);
+
+ R visitScopeContainerElement(ScopeContainerElement e, A arg) {
+ e.forEachLocalMember((l) => l.accept(this, arg));
+ return null;
+ }
+
+ @override
+ R visitCompilationUnitElement(CompilationUnitElement e, A arg) {
+ e.forEachLocalMember((l) => l.accept(this, arg));
+ return null;
+ }
+
+ @override
+ R visitLibraryElement(LibraryElement e, A arg) {
+ e.implementation.compilationUnits.forEach((u) => u.accept(this, arg));
+ return null;
+ }
+
+ @override
+ R visitVariableElement(VariableElement e, A arg) => null;
+
+ @override
+ R visitParameterElement(ParameterElement e, A arg) => null;
+
+ @override
+ R visitFormalElement(FormalElement e, A arg) => null;
+
+ @override
+ R visitFieldElement(FieldElement e, A arg) => null;
+
+ @override
+ R visitFieldParameterElement(InitializingFormalElement e, A arg) => null;
+
+ @override
+ R visitAbstractFieldElement(AbstractFieldElement e, A arg) => null;
+
+ @override
+ R visitFunctionElement(FunctionElement e, A arg) => null;
+
+ @override
+ R visitConstructorElement(ConstructorElement e, A arg) {
+ return visitFunctionElement(e, arg);
+ }
+
+ @override
+ R visitConstructorBodyElement(ConstructorBodyElement e, A arg) {
+ return visitFunctionElement(e.constructor, arg);
+ }
+
+ @override
+ R visitClassElement(ClassElement e, A arg) {
+ return visitScopeContainerElement(e, arg);
+ }
+
+ @override
+ R visitEnumClassElement(EnumClassElement e, A arg) {
+ return visitClassElement(e, arg);
+ }
+
+ @override
+ R visitBoxFieldElement(BoxFieldElement e, A arg) => null;
+
+ @override
+ R visitClosureClassElement(ClosureClassElement e, A arg) {
+ return visitClassElement(e, arg);
+ }
+
+ @override
+ R visitClosureFieldElement(ClosureFieldElement e, A arg) {
+ return visitVariableElement(e, arg);
+ }
+}
+
+// TODO(sigmund): get rid of debug messages.
+_debug(String message) {
+ print('debug: $message');
+}
« no previous file with comments | « pkg/compiler/lib/src/stats/analysis_result.dart ('k') | pkg/compiler/lib/src/stats/naive_analysis_result.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698