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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../constants/constant_system.dart'; | 7 import '../constants/constant_system.dart'; |
| 8 import '../constants/expressions.dart'; | 8 import '../constants/expressions.dart'; |
| 9 import '../constants/values.dart' show PrimitiveConstantValue; | 9 import '../constants/values.dart' show PrimitiveConstantValue; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 | 459 |
| 460 /// Reifies the value of [variable] on the current receiver object. | 460 /// Reifies the value of [variable] on the current receiver object. |
| 461 ir.Primitive buildReifyTypeVariable(TypeVariableType variable); | 461 ir.Primitive buildReifyTypeVariable(TypeVariableType variable); |
| 462 | 462 |
| 463 /// Creates an access to the receiver from the current (or enclosing) method. | 463 /// Creates an access to the receiver from the current (or enclosing) method. |
| 464 /// | 464 /// |
| 465 /// If inside a closure class, [buildThis] will redirect access through | 465 /// If inside a closure class, [buildThis] will redirect access through |
| 466 /// closure fields in order to access the receiver from the enclosing method. | 466 /// closure fields in order to access the receiver from the enclosing method. |
| 467 ir.Primitive buildThis(); | 467 ir.Primitive buildThis(); |
| 468 | 468 |
| 469 /// In JS-mode, gets an interceptor for [value]. | 469 /// Creates a type test or type cast of [value] against [type]. |
| 470 /// In Dart-mode, simply returns [value]. | 470 ir.Primitive buildTypeOperator(ir.Primitive value, |
| 471 ir.Primitive buildGetInterceptor(ir.Primitive value); | 471 DartType type, |
| 472 {bool isTypeTest}); | |
| 472 | 473 |
| 473 // TODO(johnniwinther): Make these field final and remove the default values | 474 // TODO(johnniwinther): Make these field final and remove the default values |
| 474 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. | 475 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. |
| 475 | 476 |
| 476 final List<ir.Parameter> _parameters = <ir.Parameter>[]; | 477 final List<ir.Parameter> _parameters = <ir.Parameter>[]; |
| 477 | 478 |
| 478 IrBuilderSharedState state; | 479 IrBuilderSharedState state; |
| 479 | 480 |
| 480 /// A map from variable indexes to their values. | 481 /// A map from variable indexes to their values. |
| 481 /// | 482 /// |
| (...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1794 catchBuilder.removeMutableVariable(variable); | 1795 catchBuilder.removeMutableVariable(variable); |
| 1795 catchBuilder.environment.update(variable, value); | 1796 catchBuilder.environment.update(variable, value); |
| 1796 } | 1797 } |
| 1797 | 1798 |
| 1798 // Handlers are always translated as having both exception and stack trace | 1799 // Handlers are always translated as having both exception and stack trace |
| 1799 // parameters. Multiple clauses do not have to use the same names for | 1800 // parameters. Multiple clauses do not have to use the same names for |
| 1800 // them. Choose the first of each as the name hint for the respective | 1801 // them. Choose the first of each as the name hint for the respective |
| 1801 // handler parameter. | 1802 // handler parameter. |
| 1802 ir.Parameter exceptionParameter = | 1803 ir.Parameter exceptionParameter = |
| 1803 new ir.Parameter(catchClauseInfos.first.exceptionVariable); | 1804 new ir.Parameter(catchClauseInfos.first.exceptionVariable); |
| 1804 ir.Primitive exceptionInterceptor = new ir.Parameter(null); | |
| 1805 LocalVariableElement traceVariable; | 1805 LocalVariableElement traceVariable; |
| 1806 CatchClauseInfo catchAll; | 1806 CatchClauseInfo catchAll; |
| 1807 for (int i = 0; i < catchClauseInfos.length; ++i) { | 1807 for (int i = 0; i < catchClauseInfos.length; ++i) { |
| 1808 CatchClauseInfo info = catchClauseInfos[i]; | 1808 CatchClauseInfo info = catchClauseInfos[i]; |
| 1809 if (info.type == null) { | 1809 if (info.type == null) { |
| 1810 catchAll = info; | 1810 catchAll = info; |
| 1811 catchClauseInfos.length = i; | 1811 catchClauseInfos.length = i; |
| 1812 break; | 1812 break; |
| 1813 } | 1813 } |
| 1814 if (traceVariable == null) { | 1814 if (traceVariable == null) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1841 clauseBuilder.declareLocalVariable(clause.stackTraceVariable, | 1841 clauseBuilder.declareLocalVariable(clause.stackTraceVariable, |
| 1842 initialValue: traceParameter); | 1842 initialValue: traceParameter); |
| 1843 } | 1843 } |
| 1844 clause.buildCatchBlock(clauseBuilder); | 1844 clause.buildCatchBlock(clauseBuilder); |
| 1845 if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join); | 1845 if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join); |
| 1846 ir.Continuation thenContinuation = new ir.Continuation([]); | 1846 ir.Continuation thenContinuation = new ir.Continuation([]); |
| 1847 thenContinuation.body = clauseBuilder._root; | 1847 thenContinuation.body = clauseBuilder._root; |
| 1848 ir.Continuation elseContinuation = new ir.Continuation([]); | 1848 ir.Continuation elseContinuation = new ir.Continuation([]); |
| 1849 elseContinuation.body = catchBody; | 1849 elseContinuation.body = catchBody; |
| 1850 | 1850 |
| 1851 ir.Parameter typeMatches = new ir.Parameter(null); | 1851 // Build the type test guarding this clause. We can share the environment |
| 1852 ir.Continuation checkType = new ir.Continuation([typeMatches]); | 1852 // with the nested builder because this part cannot mutate it. |
| 1853 checkType.body = | 1853 IrBuilder checkBuilder = catchBuilder.makeDelimitedBuilder(environment); |
| 1854 new ir.LetCont.many([thenContinuation, elseContinuation], | 1854 ir.Primitive typeMatches = |
| 1855 new ir.Branch(new ir.IsTrue(typeMatches), | 1855 checkBuilder.buildTypeOperator(exceptionParameter, |
| 1856 thenContinuation, | 1856 clause.type, |
| 1857 elseContinuation)); | 1857 isTypeTest: true); |
| 1858 catchBody = | 1858 checkBuilder.add(new ir.LetCont.many([thenContinuation, elseContinuation], |
| 1859 new ir.LetCont(checkType, | 1859 new ir.Branch(new ir.IsTrue(typeMatches), |
| 1860 new ir.TypeOperator(exceptionInterceptor, clause.type, checkType, | 1860 thenContinuation, |
| 1861 isTypeTest: true)); | 1861 elseContinuation))); |
| 1862 catchBody = checkBuilder._root; | |
| 1862 } | 1863 } |
| 1863 | 1864 |
| 1864 List<ir.Parameter> catchParameters = | 1865 List<ir.Parameter> catchParameters = |
| 1865 <ir.Parameter>[exceptionParameter, traceParameter]; | 1866 <ir.Parameter>[exceptionParameter, traceParameter]; |
| 1866 ir.Continuation catchContinuation = new ir.Continuation(catchParameters); | 1867 ir.Continuation catchContinuation = new ir.Continuation(catchParameters); |
| 1867 catchBuilder.buildGetInterceptor(exceptionParameter) | |
| 1868 .substituteFor(exceptionInterceptor); | |
| 1869 catchBuilder.add(catchBody); | 1868 catchBuilder.add(catchBody); |
| 1870 catchContinuation.body = catchBuilder._root; | 1869 catchContinuation.body = catchBuilder._root; |
| 1871 | 1870 |
| 1872 tryCatchBuilder.add( | 1871 tryCatchBuilder.add( |
| 1873 new ir.LetHandler(catchContinuation, tryBuilder._root)); | 1872 new ir.LetHandler(catchContinuation, tryBuilder._root)); |
| 1874 add(new ir.LetCont(join.continuation, tryCatchBuilder._root)); | 1873 add(new ir.LetCont(join.continuation, tryCatchBuilder._root)); |
| 1875 environment = join.environment; | 1874 environment = join.environment; |
| 1876 } | 1875 } |
| 1877 | 1876 |
| 1878 /// Create a return statement `return value;` or `return;` if [value] is | 1877 /// Create a return statement `return value;` or `return;` if [value] is |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2007 | 2006 |
| 2008 add(new ir.LetCont(joinContinuation, | 2007 add(new ir.LetCont(joinContinuation, |
| 2009 new ir.LetCont.many(<ir.Continuation>[thenContinuation, | 2008 new ir.LetCont.many(<ir.Continuation>[thenContinuation, |
| 2010 elseContinuation], | 2009 elseContinuation], |
| 2011 new ir.Branch(new ir.IsTrue(condition), | 2010 new ir.Branch(new ir.IsTrue(condition), |
| 2012 thenContinuation, | 2011 thenContinuation, |
| 2013 elseContinuation)))); | 2012 elseContinuation)))); |
| 2014 return resultParameter; | 2013 return resultParameter; |
| 2015 } | 2014 } |
| 2016 | 2015 |
| 2017 /// Creates a type test or type cast of [receiver] against [type]. | |
| 2018 /// | |
| 2019 /// Set [isTypeTest] to `true` to create a type test and furthermore set | |
| 2020 /// [isNotCheck] to `true` to create a negated type test. | |
| 2021 ir.Primitive buildTypeOperator(ir.Primitive receiver, | |
| 2022 DartType type, | |
| 2023 {bool isTypeTest: false, | |
| 2024 bool isNotCheck: false}); | |
| 2025 | |
| 2026 /// Create a lazy and/or expression. [leftValue] is the value of the left | 2016 /// Create a lazy and/or expression. [leftValue] is the value of the left |
| 2027 /// operand and [buildRightValue] is called to process the value of the right | 2017 /// operand and [buildRightValue] is called to process the value of the right |
| 2028 /// operand in the context of its own [IrBuilder]. | 2018 /// operand in the context of its own [IrBuilder]. |
| 2029 ir.Primitive buildLogicalOperator( | 2019 ir.Primitive buildLogicalOperator( |
| 2030 ir.Primitive leftValue, | 2020 ir.Primitive leftValue, |
| 2031 ir.Primitive buildRightValue(IrBuilder builder), | 2021 ir.Primitive buildRightValue(IrBuilder builder), |
| 2032 {bool isLazyOr: false}) { | 2022 {bool isLazyOr: false}) { |
| 2033 // e0 && e1 is translated as if e0 ? (e1 == true) : false. | 2023 // e0 && e1 is translated as if e0 ? (e1 == true) : false. |
| 2034 // e0 || e1 is translated as if e0 ? true : (e1 == true). | 2024 // e0 || e1 is translated as if e0 ? true : (e1 == true). |
| 2035 // The translation must convert both e0 and e1 to booleans and handle | 2025 // The translation must convert both e0 and e1 to booleans and handle |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2284 value.useElementAsHint(local); | 2274 value.useElementAsHint(local); |
| 2285 environment.update(local, value); | 2275 environment.update(local, value); |
| 2286 } | 2276 } |
| 2287 return value; | 2277 return value; |
| 2288 } | 2278 } |
| 2289 | 2279 |
| 2290 ir.Primitive buildThis() { | 2280 ir.Primitive buildThis() { |
| 2291 return state.enclosingMethodThisParameter; | 2281 return state.enclosingMethodThisParameter; |
| 2292 } | 2282 } |
| 2293 | 2283 |
| 2294 ir.Primitive buildGetInterceptor(ir.Primitive value) => value; | |
| 2295 | |
| 2296 @override | 2284 @override |
| 2297 ir.Primitive buildConstructorInvocation(ConstructorElement element, | 2285 ir.Primitive buildConstructorInvocation(ConstructorElement element, |
| 2298 CallStructure callStructure, | 2286 CallStructure callStructure, |
| 2299 DartType type, | 2287 DartType type, |
| 2300 List<ir.Primitive> arguments) { | 2288 List<ir.Primitive> arguments) { |
| 2301 assert(isOpen); | 2289 assert(isOpen); |
| 2302 Selector selector = | 2290 Selector selector = |
| 2303 new Selector(SelectorKind.CALL, element.memberName, callStructure); | 2291 new Selector(SelectorKind.CALL, element.memberName, callStructure); |
| 2304 return _continueWithExpression( | 2292 return _continueWithExpression( |
| 2305 (k) => new ir.InvokeConstructor(type, element, selector, | 2293 (k) => new ir.InvokeConstructor(type, element, selector, |
| 2306 arguments, k)); | 2294 arguments, k)); |
| 2307 } | 2295 } |
| 2308 | 2296 |
| 2309 @override | 2297 @override |
| 2310 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { | 2298 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { |
| 2311 return addPrimitive(new ir.ReifyTypeVar(variable.element)); | 2299 return addPrimitive(new ir.ReifyTypeVar(variable.element)); |
| 2312 } | 2300 } |
| 2313 | 2301 |
| 2314 @override | 2302 @override |
| 2315 ir.Primitive buildTypeOperator(ir.Primitive receiver, | 2303 ir.Primitive buildTypeOperator(ir.Primitive value, |
| 2316 DartType type, | 2304 DartType type, |
| 2317 {bool isTypeTest: false, | 2305 {bool isTypeTest}) { |
| 2318 bool isNotCheck: false}) { | |
| 2319 assert(isOpen); | 2306 assert(isOpen); |
| 2320 assert(isTypeTest != null); | 2307 assert(isTypeTest != null); |
| 2321 assert(!isNotCheck || isTypeTest); | |
| 2322 ir.Primitive check = _continueWithExpression( | 2308 ir.Primitive check = _continueWithExpression( |
| 2323 (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest )); | 2309 (k) => new ir.TypeOperator(value, |
| 2324 return isNotCheck ? buildNegation(check) : check; | 2310 type, [], k, isTypeTest: isTypeTest)); |
|
karlklose
2015/05/27 07:38:34
Please add type arguments to list literals (also i
asgerf
2015/05/27 09:19:16
Done.
| |
| 2311 return check; | |
| 2325 } | 2312 } |
| 2326 } | 2313 } |
| 2327 | 2314 |
| 2328 /// State shared between JsIrBuilders within the same function. | 2315 /// State shared between JsIrBuilders within the same function. |
| 2329 /// | 2316 /// |
| 2330 /// Note that this is not shared between builders of nested functions. | 2317 /// Note that this is not shared between builders of nested functions. |
| 2331 class JsIrBuilderSharedState { | 2318 class JsIrBuilderSharedState { |
| 2332 /// Maps boxed locals to their location. These locals are not part of | 2319 /// Maps boxed locals to their location. These locals are not part of |
| 2333 /// the environment. | 2320 /// the environment. |
| 2334 final Map<Local, ClosureLocation> boxedVariables = {}; | 2321 final Map<Local, ClosureLocation> boxedVariables = {}; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2551 } | 2538 } |
| 2552 environment.update(scope.box, newBox); | 2539 environment.update(scope.box, newBox); |
| 2553 } | 2540 } |
| 2554 | 2541 |
| 2555 ir.Primitive buildThis() { | 2542 ir.Primitive buildThis() { |
| 2556 if (jsState.receiver != null) return jsState.receiver; | 2543 if (jsState.receiver != null) return jsState.receiver; |
| 2557 assert(state.thisParameter != null); | 2544 assert(state.thisParameter != null); |
| 2558 return state.thisParameter; | 2545 return state.thisParameter; |
| 2559 } | 2546 } |
| 2560 | 2547 |
| 2561 ir.Primitive buildGetInterceptor(ir.Primitive value) { | |
| 2562 return addPrimitive(new ir.Interceptor(value, program.interceptedClasses)); | |
| 2563 } | |
| 2564 | |
| 2565 @override | 2548 @override |
| 2566 ir.Primitive buildSuperFieldGet(FieldElement target) { | 2549 ir.Primitive buildSuperFieldGet(FieldElement target) { |
| 2567 return addPrimitive(new ir.GetField(buildThis(), target)); | 2550 return addPrimitive(new ir.GetField(buildThis(), target)); |
| 2568 } | 2551 } |
| 2569 | 2552 |
| 2570 @override | 2553 @override |
| 2571 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { | 2554 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { |
| 2572 add(new ir.SetField(buildThis(), target, value)); | 2555 add(new ir.SetField(buildThis(), target, value)); |
| 2573 return value; | 2556 return value; |
| 2574 } | 2557 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2629 ir.Primitive buildTypeExpression(DartType type) { | 2612 ir.Primitive buildTypeExpression(DartType type) { |
| 2630 if (type is TypeVariableType) { | 2613 if (type is TypeVariableType) { |
| 2631 return buildTypeVariableAccess(type); | 2614 return buildTypeVariableAccess(type); |
| 2632 } else if (type is InterfaceType) { | 2615 } else if (type is InterfaceType) { |
| 2633 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2616 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 2634 type.forEachTypeVariable((TypeVariableType variable) { | 2617 type.forEachTypeVariable((TypeVariableType variable) { |
| 2635 ir.Primitive value = buildTypeVariableAccess(variable); | 2618 ir.Primitive value = buildTypeVariableAccess(variable); |
| 2636 arguments.add(value); | 2619 arguments.add(value); |
| 2637 }); | 2620 }); |
| 2638 return addPrimitive(new ir.TypeExpression(type, arguments)); | 2621 return addPrimitive(new ir.TypeExpression(type, arguments)); |
| 2622 } else if (type is DynamicType) { | |
| 2623 return buildNullConstant(); | |
| 2639 } else { | 2624 } else { |
| 2640 // TypedefType can reach here, and possibly other things. | 2625 // TypedefType can reach here, and possibly other things. |
| 2641 throw 'unimplemented translation of type expression $type'; | 2626 throw 'unimplemented translation of type expression $type'; |
| 2642 } | 2627 } |
| 2643 } | 2628 } |
| 2644 | 2629 |
| 2645 /// Obtains the internal type representation of the type held in [variable]. | 2630 /// Obtains the internal type representation of the type held in [variable]. |
| 2646 /// | 2631 /// |
| 2647 /// The value of [variable] is taken from the current receiver object, or | 2632 /// The value of [variable] is taken from the current receiver object, or |
| 2648 /// if we are currently building a constructor field initializer, from the | 2633 /// if we are currently building a constructor field initializer, from the |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2673 ir.Primitive typeArgument = buildTypeVariableAccess(variable); | 2658 ir.Primitive typeArgument = buildTypeVariableAccess(variable); |
| 2674 return addPrimitive(new ir.ReifyRuntimeType(typeArgument)); | 2659 return addPrimitive(new ir.ReifyRuntimeType(typeArgument)); |
| 2675 } | 2660 } |
| 2676 | 2661 |
| 2677 ir.Primitive buildInvocationMirror(Selector selector, | 2662 ir.Primitive buildInvocationMirror(Selector selector, |
| 2678 List<ir.Primitive> arguments) { | 2663 List<ir.Primitive> arguments) { |
| 2679 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); | 2664 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); |
| 2680 } | 2665 } |
| 2681 | 2666 |
| 2682 @override | 2667 @override |
| 2683 ir.Primitive buildTypeOperator(ir.Primitive receiver, | 2668 ir.Primitive buildTypeOperator(ir.Primitive value, |
| 2684 DartType type, | 2669 DartType type, |
| 2685 {bool isTypeTest: false, | 2670 {bool isTypeTest}) { |
| 2686 bool isNotCheck: false}) { | |
| 2687 assert(isOpen); | 2671 assert(isOpen); |
| 2688 assert(isTypeTest != null); | 2672 assert(isTypeTest != null); |
| 2689 assert(!isNotCheck || isTypeTest); | 2673 // The TypeOperator node does not allow the Object, dynamic, and Null types, |
| 2690 ir.Primitive interceptor = | 2674 // because the null value satisfies them. These must be handled here. |
| 2691 addPrimitive(new ir.Interceptor(receiver, program.interceptedClasses)); | 2675 if (type.isObject || type.isDynamic) { |
| 2676 // `x is Object` and `x is dynamic` are always true, even if x is null. | |
| 2677 return buildBooleanConstant(true); | |
| 2678 } | |
| 2679 if (type is InterfaceType && type.element == program.nullClass) { | |
| 2680 // `x is Null` is true if and only if x is null. | |
| 2681 return addPrimitive(new ir.Identical(value, buildNullConstant())); | |
| 2682 } | |
| 2683 // Null cannot not satisfy the check. Use a standard subtype check. | |
| 2684 List<ir.Primitive> typeArguments = const []; | |
| 2685 if (type is GenericType && type.typeArguments.isNotEmpty) { | |
| 2686 typeArguments = type.typeArguments.map(buildTypeExpression).toList(); | |
| 2687 } | |
| 2692 ir.Primitive check = _continueWithExpression( | 2688 ir.Primitive check = _continueWithExpression( |
| 2693 (k) => new ir.TypeOperator(interceptor, type, k, | 2689 (k) => new ir.TypeOperator(value, |
| 2694 isTypeTest: isTypeTest)); | 2690 type, typeArguments, k, isTypeTest: isTypeTest)); |
| 2695 return isNotCheck ? buildNegation(check) : check; | 2691 return check; |
| 2696 } | 2692 } |
| 2697 | |
| 2698 } | 2693 } |
| 2699 | 2694 |
| 2700 | 2695 |
| 2701 /// Location of a variable relative to a given closure. | 2696 /// Location of a variable relative to a given closure. |
| 2702 class ClosureLocation { | 2697 class ClosureLocation { |
| 2703 /// If not `null`, this location is [box].[field]. | 2698 /// If not `null`, this location is [box].[field]. |
| 2704 /// The location of [box] can be obtained separately from an | 2699 /// The location of [box] can be obtained separately from an |
| 2705 /// enclosing [ClosureEnvironment] or [ClosureScope]. | 2700 /// enclosing [ClosureEnvironment] or [ClosureScope]. |
| 2706 /// If `null`, then the location is [field] on the enclosing function object. | 2701 /// If `null`, then the location is [field] on the enclosing function object. |
| 2707 final BoxLocal box; | 2702 final BoxLocal box; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2769 } | 2764 } |
| 2770 | 2765 |
| 2771 /// Synthetic parameter to a JavaScript factory method that takes the type | 2766 /// Synthetic parameter to a JavaScript factory method that takes the type |
| 2772 /// argument given for the type variable [variable]. | 2767 /// argument given for the type variable [variable]. |
| 2773 class TypeInformationParameter implements Local { | 2768 class TypeInformationParameter implements Local { |
| 2774 final TypeVariableElement variable; | 2769 final TypeVariableElement variable; |
| 2775 final ExecutableElement executableContext; | 2770 final ExecutableElement executableContext; |
| 2776 TypeInformationParameter(this.variable, this.executableContext); | 2771 TypeInformationParameter(this.variable, this.executableContext); |
| 2777 String get name => variable.name; | 2772 String get name => variable.name; |
| 2778 } | 2773 } |
| OLD | NEW |