Chromium Code Reviews| 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..e6aa97987997308b8fe171d6a47f847aa58b8c7b |
| --- /dev/null |
| +++ b/pkg/compiler/lib/src/stats/builder.dart |
| @@ -0,0 +1,2034 @@ |
| +// 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 '../dart2jslib.dart' |
| + show CompilerTask, Compiler, SourceSpan, MessageKind; |
| +import '../dart_types.dart'; |
| +import '../closure.dart'; |
| +import '../elements/elements.dart'; |
| +import '../elements/visitor.dart' show ElementVisitor; |
| +import '../resolution/operators.dart'; |
| +import '../resolution/resolution.dart'; |
| +import '../resolution/semantic_visitor.dart'; |
| +import '../constants/expressions.dart'; |
| +import '../scanner/scannerlib.dart' show PartialElement; |
| +import '../stats/stats.dart'; |
| +import '../tree/tree.dart'; |
| +import '../universe/universe.dart' show Selector, CallStructure; |
| + |
| +import 'analysis_result.dart'; |
| +import 'naive_analysis_result.dart'; |
| +import 'trusted_types_analysis_result.dart'; |
| + |
| +/// Task that collects all statistical data about a program. |
| +class StatsBuilderTask extends CompilerTask { |
| + String get name => "Inference Stats"; |
| + |
| + GlobalResult resultForTesting; |
| + |
| + StatsBuilderTask(Compiler compiler) : super(compiler); |
| + |
| + void run() { |
| + measure(() { |
| + var visitor = new StatsBuilder(compiler); |
| + for (var lib in compiler.libraryLoader.libraries) { |
| + lib.accept(visitor, null); |
| + } |
| + resultForTesting = visitor.result; |
| + var jsonString = new JsonEncoder.withIndent(' ') |
| + .convert(visitor.result.toJson()); |
| + compiler.outputProvider('', 'stats.json') |
| + ..add(jsonString) |
| + ..close(); |
| + }); |
| + } |
| +} |
| + |
| +/// Visitor that goes through all elements and builds the metrics information |
| +/// from them. |
| +class StatsBuilder extends RecursiveElementVisitor { |
| + /// The results produced by the builder. |
| + final GlobalResult result = new GlobalResult(); |
| + |
| + final Compiler compiler; |
| + |
| + LibraryResult currentLibrary; |
| + CompilationUnitResult currentFile; |
| + |
| + StatsBuilder(this.compiler); |
| + |
| + visitLibraryElement(LibraryElement e, arg) { |
| + currentLibrary = new LibraryResult(e.canonicalUri); |
| + result.add(currentLibrary); |
| + return super.visitLibraryElement(e, arg); |
| + } |
| + |
| + visitClassElement(ClassElement e, arg) { |
| + currentLibrary.classes.add(e.name); |
| + return super.visitClassElement(e, arg); |
| + } |
| + |
| + visitCompilationUnitElement(CompilationUnitElement e, arg) { |
| + var uri = e.script.resourceUri; |
| + currentLibrary.units.add(currentFile = new CompilationUnitResult(uri)); |
| + return super.visitCompilationUnitElement(e, arg); |
| + } |
| + |
| + _qualifiedName(FunctionElement e) { |
| + var cls = e.enclosingClass; |
| + return (cls != null) ? '${cls.name}.${e.name}' : e.name; |
| + } |
| + |
| + visitFunctionElement(FunctionElement e, arg) { |
| + compiler.withCurrentElement(e, () { |
| + if (e.library.isPlatformLibrary) return; |
| + var name = _qualifiedName(e); |
| + if (!e.hasNode) { |
| + if (e is PartialElement) { |
| + currentFile.functions.add(new FunctionResult(name, |
| + const Measurements.unreachableFunction())); |
| + } else { |
| + assert (e is ConstructorElement && e.isSynthesized); |
| + // TODO(sigmund): measure synthethic forwarding sends, measure |
| + // initializers |
| + currentFile.functions.add(new FunctionResult(name, |
| + new Measurements.reachableFunction())); |
| + } |
| + return; |
| + } |
| + if (!e.hasResolvedAst) { |
| + _debug('no resolved ast ${e.runtimeType}'); |
| + return; |
| + } |
| + var resolvedAst = e.resolvedAst; |
| + var visitor = new _StatsTraversalVisitor(compiler, resolvedAst.elements); |
| + if (resolvedAst.node == null) { |
| + _debug('no node ${e.runtimeType}'); |
| + return; |
| + } |
| + var def = resolvedAst.elements.getFunctionDefinition(resolvedAst.node); |
| + if (def == null) { |
| + assert (e is PartialElement); |
| + currentFile.functions.add(new FunctionResult(name, |
| + const Measurements.unreachableFunction())); |
| + return; |
| + } |
| + resolvedAst.node.accept(visitor); |
| + currentFile.functions |
| + .add(new FunctionResult(name, visitor.measurements)); |
| + }); |
| + } |
| + |
| + // TODO(sigmund): visit initializers too. |
| +} |
| + |
| +/// 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 = new Measurements.reachableFunction(); |
| + |
| + final Compiler compiler; |
| + final TreeElements elements; |
| + |
| + SemanticSendVisitor<dynamic, T> get sendVisitor => this; |
| + |
| + _StatsVisitor(this.compiler, this.elements, this.info); |
| + |
| + visitNode(Node node) => throw "unhandled ${node.runtimeType}: $node"; |
| + apply(Node node, T arg) => throw "missing apply ${node.runtimeType}: $node"; |
| + internalError(Node node, T 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 && |
| + ((node.assignmentOperator != null && |
| + node.assignmentOperator.source != '=') || |
| + node.isPrefix || |
| + node.isPostfix)) { |
| + measurements.record(Metric.send, span.begin, span.end); |
|
Johnni Winther
2015/07/13 19:21:44
Add a comment that you count both the get and the
Siggi Cherem (dart-lang)
2015/09/29 01:39:33
Done.
|
| + 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 '); |
| + } |
| + |
|
Johnni Winther
2015/07/13 19:21:43
Add comments for these. For instance what is the d
Siggi Cherem (dart-lang)
2015/09/29 01:39:34
Done - I made the comment a bit short here because
|
| + handleLocal(Node node) { |
| + var span = compiler.spanFromNode(node); |
| + measurements.record(Metric.monomorphicSend, span.begin, span.end); |
| + measurements.record(Metric.localSend, span.begin, span.end); |
| + } |
| + |
| + handleSingleInstance(Node node) { |
| + var span = compiler.spanFromNode(node); |
| + measurements.record(Metric.monomorphicSend, span.begin, span.end); |
| + measurements.record(Metric.instanceSend, span.begin, span.end); |
| + } |
| + |
| + handleSingleInterceptor(Node node) { |
| + var span = compiler.spanFromNode(node); |
| + measurements.record(Metric.monomorphicSend, span.begin, span.end); |
| + measurements.record(Metric.interceptorSend, span.begin, span.end); |
| + } |
| + |
| + 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 targetType) { |
| + var superclass = targetType.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, |
| + AssignmentOperator operator, Node rhs, Selector getterSelector, |
| + Selector setterSelector, T arg) { |
| + handleDynamicProperty(node, receiver, getterSelector); |
| + handleOperator(node); |
| + handleDynamicProperty(node, receiver, setterSelector); |
| + } |
| + |
| + |
| + void visitDynamicPropertyGet( |
| + Send node, Node receiver, Selector selector, T arg) { |
| + handleDynamicProperty(node, receiver, selector); |
| + } |
| + |
| + void visitDynamicPropertyInvoke( |
| + Send node, Node receiver, NodeList arguments, Selector selector, T arg) { |
| + handleDynamicProperty(node, receiver, selector); |
| + } |
| + |
| + void visitDynamicPropertyPostfix(Send node, Node receiver, |
| + IncDecOperator operator, Selector getterSelector, Selector setterSelector, |
| + T arg) { |
| + handleDynamicProperty(node, receiver, getterSelector); |
| + handleOperator(node); |
| + handleDynamicProperty(node, receiver, setterSelector); |
| + } |
| + |
| + void visitDynamicPropertyPrefix(Send node, Node receiver, |
| + IncDecOperator operator, Selector getterSelector, Selector setterSelector, |
| + T arg) { |
| + handleDynamicProperty(node, receiver, getterSelector); |
| + handleOperator(node); |
| + handleDynamicProperty(node, receiver, setterSelector); |
| + } |
| + |
| + void visitDynamicPropertySet( |
| + SendSet node, Node receiver, Selector selector, Node rhs, T arg) { |
| + handleDynamicProperty(node, receiver, selector); |
| + } |
| + |
| + void visitEquals(Send node, Node left, Node right, T arg) { |
| + handleEquals(node); |
| + } |
| + |
| + void visitExpressionInvoke(Send node, Node expression, NodeList arguments, |
| + Selector selector, T arg) { |
| + handleInvoke(node); |
| + } |
| + |
| + void visitIfNotNullDynamicPropertyCompound(Send node, Node receiver, |
| + AssignmentOperator operator, Node rhs, Selector getterSelector, |
| + Selector setterSelector, T arg) { |
| + handleDynamicProperty(node, receiver, getterSelector); |
| + handleOperator(node); |
| + handleDynamicProperty(node, receiver, setterSelector); |
| + } |
| + |
| + void visitIfNotNullDynamicPropertyGet( |
| + Send node, Node receiver, Selector selector, T arg) { |
| + handleDynamicProperty(node, receiver, selector); |
| + } |
| + |
| + void visitIfNotNullDynamicPropertyInvoke( |
| + Send node, Node receiver, NodeList arguments, Selector selector, T arg) { |
| + handleDynamicProperty(node, receiver, selector); |
| + } |
| + |
| + void visitIfNotNullDynamicPropertyPostfix(Send node, Node receiver, |
| + IncDecOperator operator, Selector getterSelector, Selector setterSelector, |
| + T arg) { |
| + handleDynamicProperty(node, receiver, getterSelector); |
| + handleOperator(node); |
| + handleDynamicProperty(node, receiver, setterSelector); |
| + } |
| + |
| + void visitIfNotNullDynamicPropertyPrefix(Send node, Node receiver, |
| + IncDecOperator operator, Selector getterSelector, Selector setterSelector, |
| + T arg) { |
| + handleDynamicProperty(node, receiver, getterSelector); |
| + handleOperator(node); |
| + handleDynamicProperty(node, receiver, setterSelector); |
| + } |
| + |
| + void visitIfNotNullDynamicPropertySet( |
| + SendSet node, Node receiver, Selector selector, Node rhs, T arg) { |
| + handleDynamicProperty(node, receiver, selector); |
| + } |
| + |
| + 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); |
|
Johnni Winther
2015/07/13 19:21:43
It looks a bit weird that you (don't have to) disc
Siggi Cherem (dart-lang)
2015/09/29 01:39:33
Yeah - this might change as right now handleIndex
|
| + 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 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 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 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 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 visitThisPropertyCompound(Send node, AssignmentOperator operator, |
| + Node rhs, Selector getterSelector, Selector setterSelector, T arg) { |
| + handleThisProperty(node, getterSelector); |
| + handleOperator(node); |
| + handleThisProperty(node, setterSelector); |
| + } |
| + |
| + void visitThisPropertyInvoke( |
| + Send node, NodeList arguments, Selector selector, T arg) { |
| + handleThisProperty(node, selector); |
| + } |
| + |
| + void visitThisPropertyPostfix(Send node, IncDecOperator operator, |
| + Selector getterSelector, Selector setterSelector, T arg) { |
| + handleThisProperty(node, getterSelector); |
| + handleOperator(node); |
| + handleThisProperty(node, setterSelector); |
| + } |
| + |
| + void visitThisPropertyPrefix(Send node, IncDecOperator operator, |
| + Selector getterSelector, Selector setterSelector, T arg) { |
| + handleThisProperty(node, getterSelector); |
| + handleOperator(node); |
| + handleThisProperty(node, setterSelector); |
| + } |
| + |
| + 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 visitParameterGet(Send node, ParameterElement parameter, T arg) { |
| + handleLocal(node); |
| + } |
| + |
| + void visitParameterSet( |
| + SendSet node, ParameterElement parameter, Node rhs, T arg) { |
| + 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 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 |
|
Johnni Winther
2015/07/13 19:21:43
Indent.
Siggi Cherem (dart-lang)
2015/09/29 01:39:33
Done.
|
| + |
| + 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 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 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 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 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 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 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 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 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 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 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 visitUnresolvedSuperBinary(Send node, Element element, |
| + BinaryOperator operator, Node argument, T arg) { |
| + handleNSMError(node); |
| + } |
| + |
| + void visitUnresolvedSuperCompound(Send node, Element element, |
| + AssignmentOperator operator, Node rhs, T arg) { |
| + handleNSMError(node); |
|
Johnni Winther
2015/07/13 19:21:43
This weird case might actually included both the o
Siggi Cherem (dart-lang)
2015/09/29 01:39:33
Good catch, you are correct. I thought in this sce
|
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperCompoundIndexSet(Send node, Element element, |
| + Node index, AssignmentOperator operator, Node rhs, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperGet(Send node, Element element, T arg) { |
| + handleNSMSuper(node, element.enclosingClass); |
| + } |
| + |
| + void visitUnresolvedSuperGetterCompound(Send node, Element element, |
| + MethodElement setter, AssignmentOperator operator, Node rhs, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterCompoundIndexSet(Send node, Element element, |
| + MethodElement setter, Node index, AssignmentOperator operator, Node rhs, |
| + T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterIndexPostfix(Send node, Element element, |
| + MethodElement setter, Node index, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterIndexPrefix(Send node, Element element, |
| + MethodElement setter, Node index, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterPostfix(Send node, Element element, |
| + MethodElement setter, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperGetterPrefix(Send node, Element element, |
| + MethodElement setter, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperIndex( |
| + Send node, Element element, Node index, T arg) { |
| + handleNSMError(node); |
| + } |
| + |
| + void visitUnresolvedSuperIndexPostfix( |
| + Send node, Element element, Node index, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperIndexPrefix( |
| + Send node, Element element, Node index, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperIndexSet( |
| + Send node, Element element, Node index, Node rhs, T arg) { |
| + handleNSMError(node); |
| + } |
| + |
| + void visitUnresolvedSuperInvoke(Send node, Element element, |
| + NodeList arguments, Selector selector, T arg) { |
| + handleNSMError(node); |
| + } |
| + |
| + void visitUnresolvedSuperPostfix( |
| + Send node, Element element, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperPrefix( |
| + Send node, Element element, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterCompound(Send node, MethodElement getter, |
| + Element element, AssignmentOperator operator, Node rhs, T arg) { |
|
Johnni Winther
2015/07/13 19:21:43
Here the getter _does_ exists but not the setter,
Siggi Cherem (dart-lang)
2015/09/29 01:39:33
good point. done
|
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterCompoundIndexSet(Send node, |
| + MethodElement getter, Element element, Node index, |
| + AssignmentOperator operator, Node rhs, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterIndexPostfix(Send node, |
| + MethodElement indexFunction, Element element, Node index, |
| + IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterIndexPrefix(Send node, |
| + MethodElement indexFunction, Element element, Node index, |
| + IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterPostfix(Send node, MethodElement getter, |
| + Element element, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperSetterPrefix(Send node, MethodElement getter, |
| + Element element, IncDecOperator operator, T arg) { |
| + handleNSMError(node); |
| + handleNoSend(node); |
| + handleNoSend(node); |
| + } |
| + |
| + void visitUnresolvedSuperUnary( |
| + Send node, UnaryOperator operator, Element element, T arg) { |
| + handleNSMError(node); |
| + } |
| + |
| + 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 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); |
| + } |
| + |
| + // 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 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 visitTopLevelFieldGet(Send node, FieldElement field, T arg) { |
| + handleStatic(node); |
| + } |
| + |
| + void visitTopLevelFieldSet( |
| + SendSet node, FieldElement field, Node rhs, T arg) { |
| + 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, Selector selector, T arg) { |
| + handleThisProperty(node, selector); |
| + } |
| + |
| + void visitThisPropertySet(SendSet node, Selector selector, Node rhs, T arg) { |
| + handleThisProperty(node, selector); |
| + } |
| + |
| + // Not count |
| + |
| + void errorInvalidAssert(Send node, NodeList arguments, T arg) { |
| + handleNoSend(node); |
| + } |
| + |
| + 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 visitAs(Send node, Node expression, DartType type, T arg) { |
| + handleNoSend(node); |
| + } |
| + |
| + void visitAssert(Send node, Node expression, 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 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 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.reportError(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) |
| + : compiler = compiler, |
| + statsVisitor = new _StatsVisitor(compiler, elements, |
| + // TODO(sigmund): accept a list of analyses, so we can compare them |
| + // together. |
| + new TrustTypesAnalysisResult(elements, compiler.world)), |
| + //new NaiveAnalysisResult()), |
| + super(elements); |
| + |
| + void visitSend(Send node) { |
| + try { |
| + node.accept(statsVisitor); |
| + } catch (e, t) { |
| + compiler.reportError(node, MessageKind.GENERIC, {'text': '$e\n$t'}); |
| + } |
| + super.visitSend(node); |
| + } |
| + |
| + void visitNewExpression(NewExpression node) { |
| + try { |
| + node.accept(statsVisitor); |
| + } catch (e, t) { |
| + compiler.reportError(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)); |
| + } |
| + |
| + @override |
| + R visitCompilationUnitElement(CompilationUnitElement e, A arg) { |
| + e.forEachLocalMember((l) => l.accept(this, arg)); |
| + } |
| + |
| + @override |
| + R visitLibraryElement(LibraryElement e, A arg) { |
| + e.implementation.compilationUnits.forEach((u) => u.accept(this, arg)); |
| + } |
| + |
| + @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'); |
| +} |