OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 library kernel.transformations.closure.mock; |
| 6 |
| 7 import '../../ast.dart' |
| 8 show |
| 9 Arguments, |
| 10 Block, |
| 11 Class, |
| 12 Constructor, |
| 13 ConstructorInvocation, |
| 14 DartType, |
| 15 DynamicType, |
| 16 EmptyStatement, |
| 17 Expression, |
| 18 ExpressionStatement, |
| 19 Field, |
| 20 FieldInitializer, |
| 21 FunctionNode, |
| 22 Initializer, |
| 23 IntLiteral, |
| 24 Library, |
| 25 MethodInvocation, |
| 26 Name, |
| 27 Procedure, |
| 28 ProcedureKind, |
| 29 Program, |
| 30 PropertyGet, |
| 31 ReturnStatement, |
| 32 Statement, |
| 33 StaticInvocation, |
| 34 Supertype, |
| 35 VariableDeclaration, |
| 36 VariableGet; |
| 37 |
| 38 import '../../core_types.dart' show CoreTypes; |
| 39 |
| 40 import '../../frontend/accessors.dart' |
| 41 show |
| 42 Accessor, |
| 43 IndexAccessor, |
| 44 PropertyAccessor, |
| 45 ThisPropertyAccessor, |
| 46 VariableAccessor; |
| 47 |
| 48 /// Extend the program with this mock: |
| 49 /// |
| 50 /// class Context { |
| 51 /// final List list; |
| 52 /// var parent; |
| 53 /// Context(int i) : list = new List(i); |
| 54 /// operator[] (int i) => list[i]; |
| 55 /// operator[]= (int i, value) { |
| 56 /// list[i] = value; |
| 57 /// } |
| 58 /// Context copy() { |
| 59 /// Context c = new Context(list.length); |
| 60 /// c.parent = parent; |
| 61 /// c.list.setRange(0, list.length, list); |
| 62 /// return c; |
| 63 /// } |
| 64 /// } |
| 65 /// |
| 66 /// Returns the mock. |
| 67 Class mockUpContext(CoreTypes coreTypes, Program program) { |
| 68 String fileUri = "dart:mock"; |
| 69 |
| 70 /// final List list; |
| 71 Field listField = new Field(new Name("list"), |
| 72 type: coreTypes.listClass.rawType, isFinal: true, fileUri: fileUri); |
| 73 Accessor listFieldAccessor = |
| 74 new ThisPropertyAccessor(listField.name, listField, null); |
| 75 |
| 76 /// var parent; |
| 77 Field parentField = new Field(new Name("parent"), fileUri: fileUri); |
| 78 Accessor parentFieldAccessor = |
| 79 new ThisPropertyAccessor(parentField.name, parentField, parentField); |
| 80 |
| 81 List<Field> fields = <Field>[listField, parentField]; |
| 82 |
| 83 /// Context(int i) : list = new List(i); |
| 84 VariableDeclaration iParameter = new VariableDeclaration("i", |
| 85 type: coreTypes.intClass.rawType, isFinal: true); |
| 86 Constructor constructor = new Constructor( |
| 87 new FunctionNode(new EmptyStatement(), |
| 88 positionalParameters: <VariableDeclaration>[iParameter]), |
| 89 name: new Name(""), |
| 90 initializers: <Initializer>[ |
| 91 new FieldInitializer( |
| 92 listField, |
| 93 new StaticInvocation( |
| 94 coreTypes.listClass.procedures.first, |
| 95 new Arguments(<Expression>[ |
| 96 new VariableAccessor(iParameter).buildSimpleRead() |
| 97 ], types: <DartType>[ |
| 98 const DynamicType() |
| 99 ]))) |
| 100 ]); |
| 101 |
| 102 /// operator[] (int i) => list[i]; |
| 103 iParameter = new VariableDeclaration("i", |
| 104 type: coreTypes.intClass.rawType, isFinal: true); |
| 105 Accessor accessor = IndexAccessor.make(listFieldAccessor.buildSimpleRead(), |
| 106 new VariableAccessor(iParameter).buildSimpleRead(), null, null); |
| 107 Procedure indexGet = new Procedure( |
| 108 new Name("[]"), |
| 109 ProcedureKind.Operator, |
| 110 new FunctionNode(new ReturnStatement(accessor.buildSimpleRead()), |
| 111 positionalParameters: <VariableDeclaration>[iParameter]), |
| 112 fileUri: fileUri); |
| 113 |
| 114 /// operator[]= (int i, value) { |
| 115 /// list[i] = value; |
| 116 /// } |
| 117 iParameter = new VariableDeclaration("i", |
| 118 type: coreTypes.intClass.rawType, isFinal: true); |
| 119 VariableDeclaration valueParameter = |
| 120 new VariableDeclaration("value", isFinal: true); |
| 121 accessor = IndexAccessor.make(listFieldAccessor.buildSimpleRead(), |
| 122 new VariableAccessor(iParameter).buildSimpleRead(), null, null); |
| 123 Expression expression = accessor.buildAssignment( |
| 124 new VariableAccessor(valueParameter).buildSimpleRead(), |
| 125 voidContext: true); |
| 126 Procedure indexSet = new Procedure( |
| 127 new Name("[]="), |
| 128 ProcedureKind.Operator, |
| 129 new FunctionNode(new ExpressionStatement(expression), |
| 130 positionalParameters: <VariableDeclaration>[ |
| 131 iParameter, |
| 132 valueParameter |
| 133 ]), |
| 134 fileUri: fileUri); |
| 135 |
| 136 /// Context copy() { |
| 137 /// Context c = new Context(list.length); |
| 138 /// c.parent = parent; |
| 139 /// c.list.setRange(0, list.length, list); |
| 140 /// return c; |
| 141 /// } |
| 142 VariableDeclaration c = new VariableDeclaration("c", |
| 143 initializer: new ConstructorInvocation( |
| 144 constructor, |
| 145 new Arguments(<Expression>[ |
| 146 new PropertyGet( |
| 147 listFieldAccessor.buildSimpleRead(), new Name("length")) |
| 148 ]))); |
| 149 Accessor accessCParent = PropertyAccessor.make( |
| 150 new VariableGet(c), parentField.name, parentField, parentField); |
| 151 Accessor accessCList = PropertyAccessor.make( |
| 152 new VariableGet(c), listField.name, listField, null); |
| 153 List<Statement> statements = <Statement>[ |
| 154 c, |
| 155 new ExpressionStatement(accessCParent.buildAssignment( |
| 156 parentFieldAccessor.buildSimpleRead(), |
| 157 voidContext: true)), |
| 158 new ExpressionStatement(new MethodInvocation( |
| 159 accessCList.buildSimpleRead(), |
| 160 new Name("setRange"), |
| 161 new Arguments(<Expression>[ |
| 162 new IntLiteral(0), |
| 163 new PropertyGet( |
| 164 listFieldAccessor.buildSimpleRead(), new Name("length")), |
| 165 listFieldAccessor.buildSimpleRead() |
| 166 ]))), |
| 167 new ReturnStatement(new VariableGet(c)) |
| 168 ]; |
| 169 Procedure copy = new Procedure(new Name("copy"), ProcedureKind.Method, |
| 170 new FunctionNode(new Block(statements)), |
| 171 fileUri: fileUri); |
| 172 |
| 173 List<Procedure> procedures = <Procedure>[indexGet, indexSet, copy]; |
| 174 |
| 175 Class contextClass = new Class( |
| 176 name: "Context", |
| 177 supertype: new Supertype(coreTypes.objectClass, const <DartType>[]), |
| 178 constructors: [constructor], |
| 179 fields: fields, |
| 180 procedures: procedures, |
| 181 fileUri: fileUri); |
| 182 Library mock = new Library(Uri.parse(fileUri), |
| 183 name: "mock", classes: [contextClass])..fileUri = fileUri; |
| 184 program.libraries.add(mock); |
| 185 mock.parent = program; |
| 186 program.uriToLineStarts[mock.fileUri] = <int>[0]; |
| 187 return contextClass; |
| 188 } |
OLD | NEW |