Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart2js.ir_builder; | 5 part of dart2js.ir_builder; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * This task iterates through all resolved elements and builds [ir.Node]s. The | 8 * This task iterates through all resolved elements and builds [ir.Node]s. The |
| 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and | 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and |
| 10 * [getIr]. | 10 * [getIr]. |
| 11 * | 11 * |
| 12 * The functionality of the IrNodes is added gradually, therefore elements might | 12 * The functionality of the IrNodes is added gradually, therefore elements might |
| 13 * have an IR or not, depending on the language features that are used. For | 13 * have an IR or not, depending on the language features that are used. For |
| 14 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not | 14 * elements that do have an IR, the tree [ast.Node]s and the [Token]s are not |
| 15 * used in the rest of the compilation. This is ensured by setting the element's | 15 * used in the rest of the compilation. This is ensured by setting the element's |
| 16 * cached tree to `null` and also breaking the token stream to crash future | 16 * cached tree to `null` and also breaking the token stream to crash future |
| 17 * attempts to parse. | 17 * attempts to parse. |
| 18 * | 18 * |
| 19 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are | 19 * The type inferrer works on either IR nodes or tree nodes. The IR nodes are |
| 20 * then translated into the SSA form for optimizations and code generation. | 20 * then translated into the SSA form for optimizations and code generation. |
| 21 * Long-term, once the IR supports the full language, the backend can be | 21 * Long-term, once the IR supports the full language, the backend can be |
| 22 * re-implemented to work directly on the IR. | 22 * re-implemented to work directly on the IR. |
| 23 */ | 23 */ |
| 24 class IrBuilderTask extends CompilerTask { | 24 class IrBuilderTask extends CompilerTask { |
| 25 final Map<Element, ir.ExecutableDefinition> nodes = | 25 final Map<Element, ir.ExecutableDefinition> nodes = |
| 26 <Element, ir.ExecutableDefinition>{}; | 26 <Element, ir.ExecutableDefinition>{}; |
| 27 final bool generateSourceMap; | |
| 27 | 28 |
| 28 IrBuilderTask(Compiler compiler) : super(compiler); | 29 IrBuilderTask(Compiler compiler, {this.generateSourceMap: true}) |
| 30 : super(compiler); | |
| 29 | 31 |
| 30 String get name => 'IR builder'; | 32 String get name => 'IR builder'; |
| 31 | 33 |
| 32 bool hasIr(Element element) => nodes.containsKey(element.implementation); | 34 bool hasIr(Element element) => nodes.containsKey(element.implementation); |
| 33 | 35 |
| 34 ir.ExecutableDefinition getIr(ExecutableElement element) { | 36 ir.ExecutableDefinition getIr(ExecutableElement element) { |
| 35 return nodes[element.implementation]; | 37 return nodes[element.implementation]; |
| 36 } | 38 } |
| 37 | 39 |
| 38 ir.ExecutableDefinition buildNode(AstElement element) { | 40 ir.ExecutableDefinition buildNode(AstElement element) { |
| 39 if (!canBuild(element)) return null; | 41 if (!canBuild(element)) return null; |
| 42 | |
| 40 TreeElements elementsMapping = element.resolvedAst.elements; | 43 TreeElements elementsMapping = element.resolvedAst.elements; |
| 41 element = element.implementation; | 44 element = element.implementation; |
| 42 return compiler.withCurrentElement(element, () { | 45 return compiler.withCurrentElement(element, () { |
| 43 SourceFile sourceFile = elementSourceFile(element); | 46 SourceInformationBuilder sourceInformationBuilder = generateSourceMap |
| 47 ? new PositionSourceInformationBuilder(element) | |
| 48 : const SourceInformationBuilder(); | |
| 49 | |
| 44 IrBuilderVisitor builder = | 50 IrBuilderVisitor builder = |
| 45 compiler.backend is JavaScriptBackend | 51 compiler.backend is JavaScriptBackend |
| 46 ? new JsIrBuilderVisitor(elementsMapping, compiler, sourceFile) | 52 ? new JsIrBuilderVisitor( |
| 47 : new DartIrBuilderVisitor(elementsMapping, compiler, sourceFile); | 53 elementsMapping, compiler, sourceInformationBuilder) |
| 48 return builder.buildExecutable(element); | 54 : new DartIrBuilderVisitor( |
| 55 elementsMapping, compiler, sourceInformationBuilder); | |
| 56 ir.ExecutableDefinition definition = | |
| 57 builder.buildExecutable(element); | |
| 58 if (definition != null) { | |
| 59 nodes[element] = definition; | |
| 60 } | |
| 61 return definition; | |
| 49 }); | 62 }); |
| 50 } | 63 } |
| 51 | 64 |
| 52 void buildNodes() { | 65 void buildNodes() { |
| 53 measure(() { | 66 measure(() { |
| 54 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements; | 67 Set<Element> resolved = compiler.enqueuer.resolution.resolvedElements; |
| 55 resolved.forEach((AstElement element) { | 68 resolved.forEach(buildNode); |
| 56 ir.ExecutableDefinition definition = buildNode(element); | |
| 57 if (definition != null) { | |
| 58 nodes[element] = definition; | |
| 59 } | |
| 60 }); | |
| 61 }); | 69 }); |
| 62 } | 70 } |
| 63 | 71 |
| 64 bool canBuild(Element element) { | 72 bool canBuild(Element element) { |
| 65 if (element is TypedefElement) return false; | 73 if (element is TypedefElement) return false; |
| 66 if (element is FunctionElement) { | 74 if (element is FunctionElement) { |
| 67 // TODO(sigurdm): Support native functions for dart2js. | 75 // TODO(sigurdm): Support native functions for dart2js. |
| 68 assert(invariant(element, !element.isNative)); | 76 assert(invariant(element, !element.isNative)); |
| 69 | 77 |
| 70 if (element is ConstructorElement) { | 78 if (element is ConstructorElement) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 } | 116 } |
| 109 | 117 |
| 110 /** | 118 /** |
| 111 * A tree visitor that builds [IrNodes]. The visit methods add statements using | 119 * A tree visitor that builds [IrNodes]. The visit methods add statements using |
| 112 * to the [builder] and return the last added statement for trees that represent | 120 * to the [builder] and return the last added statement for trees that represent |
| 113 * an expression. | 121 * an expression. |
| 114 */ | 122 */ |
| 115 abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> | 123 abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> |
| 116 with IrBuilderMixin<ast.Node> { | 124 with IrBuilderMixin<ast.Node> { |
| 117 final Compiler compiler; | 125 final Compiler compiler; |
| 118 final SourceFile sourceFile; | 126 final SourceInformationBuilder sourceInformationBuilder; |
| 119 | 127 |
| 120 // In SSA terms, join-point continuation parameters are the phis and the | 128 // In SSA terms, join-point continuation parameters are the phis and the |
| 121 // continuation invocation arguments are the corresponding phi inputs. To | 129 // continuation invocation arguments are the corresponding phi inputs. To |
| 122 // support name introduction and renaming for source level variables, we use | 130 // support name introduction and renaming for source level variables, we use |
| 123 // nested (delimited) visitors for constructing subparts of the IR that will | 131 // nested (delimited) visitors for constructing subparts of the IR that will |
| 124 // need renaming. Each source variable is assigned an index. | 132 // need renaming. Each source variable is assigned an index. |
| 125 // | 133 // |
| 126 // Each nested visitor maintains a list of free variable uses in the body. | 134 // Each nested visitor maintains a list of free variable uses in the body. |
| 127 // These are implemented as a list of parameters, each with their own use | 135 // These are implemented as a list of parameters, each with their own use |
| 128 // list of references. When the delimited subexpression is plugged into the | 136 // list of references. When the delimited subexpression is plugged into the |
| 129 // surrounding context, the free occurrences can be captured or become free | 137 // surrounding context, the free occurrences can be captured or become free |
| 130 // occurrences in the next outer delimited subexpression. | 138 // occurrences in the next outer delimited subexpression. |
| 131 // | 139 // |
| 132 // Each nested visitor maintains a list that maps indexes of variables | 140 // Each nested visitor maintains a list that maps indexes of variables |
| 133 // assigned in the delimited subexpression to their reaching definition --- | 141 // assigned in the delimited subexpression to their reaching definition --- |
| 134 // that is, the definition in effect at the hole in 'current'. These are | 142 // that is, the definition in effect at the hole in 'current'. These are |
| 135 // used to determine if a join-point continuation needs to be passed | 143 // used to determine if a join-point continuation needs to be passed |
| 136 // arguments, and what the arguments are. | 144 // arguments, and what the arguments are. |
| 137 | 145 |
| 138 /// Construct a top-level visitor. | 146 /// Construct a top-level visitor. |
| 139 IrBuilderVisitor(TreeElements elements, this.compiler, this.sourceFile) | 147 IrBuilderVisitor(TreeElements elements, |
| 148 this.compiler, | |
| 149 this.sourceInformationBuilder) | |
| 140 : super(elements); | 150 : super(elements); |
| 141 | 151 |
| 142 /** | 152 /** |
| 143 * Builds the [ir.ExecutableDefinition] for an executable element. In case the | 153 * Builds the [ir.ExecutableDefinition] for an executable element. In case the |
| 144 * function uses features that cannot be expressed in the IR, this element | 154 * function uses features that cannot be expressed in the IR, this element |
| 145 * returns `null`. | 155 * returns `null`. |
| 146 */ | 156 */ |
| 147 ir.ExecutableDefinition buildExecutable(ExecutableElement element); | 157 ir.ExecutableDefinition buildExecutable(ExecutableElement element); |
| 148 | 158 |
| 149 ClosureScope getClosureScopeForNode(ast.Node node); | 159 ClosureScope getClosureScopeForNode(ast.Node node); |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 irBuilder.buildDynamicInvocation(receiver, selector, arguments); | 656 irBuilder.buildDynamicInvocation(receiver, selector, arguments); |
| 647 } | 657 } |
| 648 } else if (element.isField || element.isGetter || element.isErroneous || | 658 } else if (element.isField || element.isGetter || element.isErroneous || |
| 649 element.isSetter) { | 659 element.isSetter) { |
| 650 // TODO(johnniwinther): Change handling of setter selectors. | 660 // TODO(johnniwinther): Change handling of setter selectors. |
| 651 // Access to a static field or getter (non-static case handled above). | 661 // Access to a static field or getter (non-static case handled above). |
| 652 // Even if there is only a setter, we compile as if it was a getter, | 662 // Even if there is only a setter, we compile as if it was a getter, |
| 653 // so the vm can fail at runtime. | 663 // so the vm can fail at runtime. |
| 654 assert(selector.kind == SelectorKind.GETTER || | 664 assert(selector.kind == SelectorKind.GETTER || |
| 655 selector.kind == SelectorKind.SETTER); | 665 selector.kind == SelectorKind.SETTER); |
| 656 result = irBuilder.buildStaticGet(element, selector); | 666 result = irBuilder.buildStaticGet(element, selector, |
| 667 sourceInformation: sourceInformationBuilder.buildGet(node)); | |
| 657 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 668 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 658 // Convert a top-level or static function to a function object. | 669 // Convert a top-level or static function to a function object. |
| 659 result = translateConstant(node); | 670 result = translateConstant(node); |
| 660 } else { | 671 } else { |
| 661 throw "Unexpected SendSet getter: $node, $element"; | 672 throw "Unexpected SendSet getter: $node, $element"; |
| 662 } | 673 } |
| 663 return new _GetterElements( | 674 return new _GetterElements( |
| 664 result: result,index: index, receiver: receiver); | 675 result: result,index: index, receiver: receiver); |
| 665 } | 676 } |
| 666 | 677 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 return irBuilder.buildCallInvocation(receiver, call, arguments); | 756 return irBuilder.buildCallInvocation(receiver, call, arguments); |
| 746 } else if (selector.isGetter) { | 757 } else if (selector.isGetter) { |
| 747 // We are reading a static field or invoking a static getter. | 758 // We are reading a static field or invoking a static getter. |
| 748 return irBuilder.buildStaticGet(element, selector); | 759 return irBuilder.buildStaticGet(element, selector); |
| 749 } else { | 760 } else { |
| 750 // We are invoking a static method. | 761 // We are invoking a static method. |
| 751 assert(selector.isCall); | 762 assert(selector.isCall); |
| 752 assert(element is FunctionElement); | 763 assert(element is FunctionElement); |
| 753 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 764 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 754 arguments = normalizeStaticArguments(selector, element, arguments); | 765 arguments = normalizeStaticArguments(selector, element, arguments); |
| 755 return irBuilder.buildStaticInvocation(element, selector, arguments); | 766 return irBuilder.buildStaticInvocation(element, selector, arguments, |
| 767 sourceInformation: sourceInformationBuilder.buildCall(node)); | |
| 756 } | 768 } |
| 757 } | 769 } |
| 758 | 770 |
| 759 ir.Primitive visitSuperSend(ast.Send node) { | 771 ir.Primitive visitSuperSend(ast.Send node) { |
| 760 assert(irBuilder.isOpen); | 772 assert(irBuilder.isOpen); |
| 761 Selector selector = elements.getSelector(node); | 773 Selector selector = elements.getSelector(node); |
| 762 Element target = elements[node]; | 774 Element target = elements[node]; |
| 763 | 775 |
| 764 if (selector.isCall && (target.isGetter || target.isField)) { | 776 if (selector.isCall && (target.isGetter || target.isField)) { |
| 765 // We are invoking a field or getter as if it was a method, e.g: | 777 // We are invoking a field or getter as if it was a method, e.g: |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1071 currentFunction = oldFunction; | 1083 currentFunction = oldFunction; |
| 1072 } | 1084 } |
| 1073 } | 1085 } |
| 1074 | 1086 |
| 1075 /// IR builder specific to the Dart backend, coupled to the [DartIrBuilder]. | 1087 /// IR builder specific to the Dart backend, coupled to the [DartIrBuilder]. |
| 1076 class DartIrBuilderVisitor extends IrBuilderVisitor { | 1088 class DartIrBuilderVisitor extends IrBuilderVisitor { |
| 1077 /// Promote the type of [irBuilder] to [DartIrBuilder]. | 1089 /// Promote the type of [irBuilder] to [DartIrBuilder]. |
| 1078 DartIrBuilder get irBuilder => super.irBuilder; | 1090 DartIrBuilder get irBuilder => super.irBuilder; |
| 1079 | 1091 |
| 1080 DartIrBuilderVisitor(TreeElements elements, | 1092 DartIrBuilderVisitor(TreeElements elements, |
| 1081 Compiler compiler, | 1093 Compiler compiler, |
| 1082 SourceFile sourceFile) | 1094 SourceInformationBuilder sourceInformationBuilder) |
| 1083 : super(elements, compiler, sourceFile); | 1095 : super(elements, compiler, sourceInformationBuilder); |
| 1084 | 1096 |
| 1085 DartIrBuilder makeIRBuilder(ast.Node node, ExecutableElement element) { | 1097 DartIrBuilder makeIRBuilder(ast.Node node, ExecutableElement element) { |
| 1086 DartCapturedVariables closures = new DartCapturedVariables(elements); | 1098 DartCapturedVariables closures = new DartCapturedVariables(elements); |
| 1087 if (!element.isSynthesized) { | 1099 if (!element.isSynthesized) { |
| 1088 closures.visit(node); | 1100 closures.visit(node); |
| 1089 } | 1101 } |
| 1090 return new DartIrBuilder(compiler.backend.constantSystem, | 1102 return new DartIrBuilder(compiler.backend.constantSystem, |
| 1091 element, | 1103 element, |
| 1092 closures); | 1104 closures); |
| 1093 } | 1105 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1198 /// Will be initialized upon entering the body of a function. | 1210 /// Will be initialized upon entering the body of a function. |
| 1199 /// It is computed by the [ClosureTranslator]. | 1211 /// It is computed by the [ClosureTranslator]. |
| 1200 ClosureClassMap closureMap; | 1212 ClosureClassMap closureMap; |
| 1201 | 1213 |
| 1202 /// During construction of a constructor factory, [fieldValues] maps fields | 1214 /// During construction of a constructor factory, [fieldValues] maps fields |
| 1203 /// to the primitive containing their initial value. | 1215 /// to the primitive containing their initial value. |
| 1204 Map<FieldElement, ir.Primitive> fieldValues = <FieldElement, ir.Primitive>{}; | 1216 Map<FieldElement, ir.Primitive> fieldValues = <FieldElement, ir.Primitive>{}; |
| 1205 | 1217 |
| 1206 JsIrBuilderVisitor(TreeElements elements, | 1218 JsIrBuilderVisitor(TreeElements elements, |
| 1207 Compiler compiler, | 1219 Compiler compiler, |
| 1208 SourceFile sourceFile) | 1220 SourceInformationBuilder sourceInformationBuilder) |
| 1209 : super(elements, compiler, sourceFile); | 1221 : super(elements, compiler, sourceInformationBuilder); |
| 1210 | 1222 |
| 1211 /// Builds the IR for creating an instance of the closure class corresponding | 1223 /// Builds the IR for creating an instance of the closure class corresponding |
| 1212 /// to the given nested function. | 1224 /// to the given nested function. |
| 1213 ClosureClassElement makeSubFunction(ast.FunctionExpression node) { | 1225 ClosureClassElement makeSubFunction(ast.FunctionExpression node) { |
| 1214 ClosureClassMap innerMap = | 1226 ClosureClassMap innerMap = |
| 1215 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 1227 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
| 1216 ClosureClassElement closureClass = innerMap.closureClassElement; | 1228 ClosureClassElement closureClass = innerMap.closureClassElement; |
| 1217 return closureClass; | 1229 return closureClass; |
| 1218 } | 1230 } |
| 1219 | 1231 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 } | 1322 } |
| 1311 | 1323 |
| 1312 /// Builds the IR for an [expression] taken from a different [context]. | 1324 /// Builds the IR for an [expression] taken from a different [context]. |
| 1313 /// | 1325 /// |
| 1314 /// Such expressions need to be compiled with a different [sourceFile] and | 1326 /// Such expressions need to be compiled with a different [sourceFile] and |
| 1315 /// [elements] mapping. | 1327 /// [elements] mapping. |
| 1316 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 1328 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
| 1317 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | 1329 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( |
| 1318 context.resolvedAst.elements, | 1330 context.resolvedAst.elements, |
| 1319 compiler, | 1331 compiler, |
| 1320 elementSourceFile(context)); | 1332 sourceInformationBuilder.forContext(context)); |
| 1321 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 1333 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
| 1322 } | 1334 } |
| 1323 | 1335 |
| 1324 /// Builds the IR for a constant taken from a different [context]. | 1336 /// Builds the IR for a constant taken from a different [context]. |
| 1325 /// | 1337 /// |
| 1326 /// Such constants need to be compiled with a different [sourceFile] and | 1338 /// Such constants need to be compiled with a different [sourceFile] and |
| 1327 /// [elements] mapping. | 1339 /// [elements] mapping. |
| 1328 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | 1340 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { |
| 1329 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | 1341 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( |
| 1330 context.resolvedAst.elements, | 1342 context.resolvedAst.elements, |
| 1331 compiler, | 1343 compiler, |
| 1332 elementSourceFile(context)); | 1344 sourceInformationBuilder.forContext(context)); |
| 1333 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); | 1345 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); |
| 1334 } | 1346 } |
| 1335 | 1347 |
| 1336 /// Builds the IR for a given constructor. | 1348 /// Builds the IR for a given constructor. |
| 1337 /// | 1349 /// |
| 1338 /// 1. Evaluates all own or inherited field initializers. | 1350 /// 1. Evaluates all own or inherited field initializers. |
| 1339 /// 2. Creates the object and assigns its fields. | 1351 /// 2. Creates the object and assigns its fields. |
| 1340 /// 3. Calls constructor body and super constructor bodies. | 1352 /// 3. Calls constructor body and super constructor bodies. |
| 1341 /// 4. Returns the created object. | 1353 /// 4. Returns the created object. |
| 1342 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 1354 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1704 for (int i=0; i < selector.positionalArgumentCount; i++) { | 1716 for (int i=0; i < selector.positionalArgumentCount; i++) { |
| 1705 result.add(arguments[i]); | 1717 result.add(arguments[i]); |
| 1706 } | 1718 } |
| 1707 for (String argName in selector.getOrderedNamedArguments()) { | 1719 for (String argName in selector.getOrderedNamedArguments()) { |
| 1708 int nameIndex = selector.namedArguments.indexOf(argName); | 1720 int nameIndex = selector.namedArguments.indexOf(argName); |
| 1709 int translatedIndex = selector.positionalArgumentCount + nameIndex; | 1721 int translatedIndex = selector.positionalArgumentCount + nameIndex; |
| 1710 result.add(arguments[translatedIndex]); | 1722 result.add(arguments[translatedIndex]); |
| 1711 } | 1723 } |
| 1712 return result; | 1724 return result; |
| 1713 } | 1725 } |
| 1714 | |
| 1715 } | 1726 } |
| 1716 | 1727 |
| 1728 /// Interface for generating [SourceInformation] for the CPS. | |
| 1729 class SourceInformationBuilder { | |
| 1730 const SourceInformationBuilder(); | |
| 1731 | |
| 1732 /// Create a [SourceInformationBuilder] for [element]. | |
| 1733 SourceInformationBuilder forContext(AstElement element) => this; | |
| 1734 | |
| 1735 /// Generate [SourceInformation] for the read access in [node]. | |
| 1736 SourceInformation buildGet(ast.Node node) => null; | |
|
floitsch
2015/02/24 19:58:12
The "build" reads redundant at the use-sites, but
| |
| 1737 | |
| 1738 /// Generate [SourceInformation] for the invocation in [node]. | |
| 1739 SourceInformation buildCall(ast.Node node) => null; | |
| 1740 } | |
| 1741 | |
| 1742 /// [SourceInformationBuilder] that generates [PositionSourceInformation]. | |
| 1743 class PositionSourceInformationBuilder implements SourceInformationBuilder { | |
| 1744 final SourceFile sourceFile; | |
| 1745 final String name; | |
| 1746 | |
| 1747 PositionSourceInformationBuilder(AstElement element) | |
| 1748 : sourceFile = element.compilationUnit.script.file, | |
| 1749 name = element.name; | |
| 1750 | |
| 1751 @override | |
| 1752 SourceInformation buildGet(ast.Node node) { | |
| 1753 return new PositionSourceInformation( | |
| 1754 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | |
| 1755 } | |
| 1756 | |
| 1757 @override | |
| 1758 SourceInformation buildCall(ast.Node node) { | |
| 1759 return new PositionSourceInformation( | |
| 1760 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | |
| 1761 } | |
| 1762 | |
| 1763 @override | |
| 1764 SourceInformationBuilder forContext(AstElement element) { | |
|
floitsch
2015/02/24 19:58:12
I'm not sure I like this. Is this just to avoid ha
Johnni Winther
2015/02/26 10:21:34
It is made to handle the choice of strategy at one
| |
| 1765 return new PositionSourceInformationBuilder(element); | |
| 1766 } | |
| 1767 } | |
| OLD | NEW |