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('[33mdebug:[0m $message'); |
+} |