| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #import("../../../lib/compiler/implementation/leg.dart"); | 5 #import("../../../lib/compiler/implementation/leg.dart"); |
| 6 #import("../../../lib/compiler/implementation/elements/elements.dart"); | 6 #import("../../../lib/compiler/implementation/elements/elements.dart"); |
| 7 #import("../../../lib/compiler/implementation/tree/tree.dart"); | 7 #import("../../../lib/compiler/implementation/tree/tree.dart"); |
| 8 #import("../../../lib/compiler/implementation/util/util.dart"); | 8 #import("../../../lib/compiler/implementation/util/util.dart"); |
| 9 #import("mock_compiler.dart"); | 9 #import("mock_compiler.dart"); |
| 10 #import("parser_helper.dart"); | 10 #import("parser_helper.dart"); |
| 11 #import("dart:uri"); | 11 #import("dart:uri"); |
| 12 | 12 |
| 13 Compiler applyPatch(String script, String patch) { | 13 Compiler applyPatch(String script, String patch) { |
| 14 String core = "$DEFAULT_CORELIB\n$script"; | 14 String core = "$DEFAULT_CORELIB\n$script"; |
| 15 MockCompiler compiler = new MockCompiler(coreSource: core); | 15 MockCompiler compiler = new MockCompiler(coreSource: core); |
| 16 var uri = new Uri("core.dartp"); | 16 var uri = new Uri("core.dartp"); |
| 17 compiler.sourceFiles[uri.toString()] = new MockFile(patch); | 17 compiler.sourceFiles[uri.toString()] = new MockFile(patch); |
| 18 compiler.patchParser.patchLibrary(uri, compiler.coreLibrary); | 18 compiler.patchParser.patchLibrary(uri, compiler.coreLibrary); |
| 19 return compiler; | 19 return compiler; |
| 20 } | 20 } |
| 21 | 21 |
| 22 void expectHasBody(compiler, Element element) { |
| 23 var node = element.parseNode(compiler); |
| 24 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); |
| 25 Expect.isNotNull(node.body); |
| 26 // If the element has a body it is either a Block or a Return statement, |
| 27 // both with different begin and end tokens. |
| 28 Expect.isTrue(node.body is Block || node.body is Return); |
| 29 Expect.notEquals(node.body.getBeginToken(), node.body.getEndToken()); |
| 30 } |
| 31 |
| 32 void expectHasNoBody(compiler, Element element) { |
| 33 var node = element.parseNode(compiler); |
| 34 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); |
| 35 Expect.isNotNull(node.body); |
| 36 // If the element has no body it is a Block with identical begin and end |
| 37 // tokens (the semicolon). |
| 38 Expect.isTrue(node.body is Block); |
| 39 Expect.identical(node.body.getBeginToken(), node.body.getEndToken()); |
| 40 } |
| 41 |
| 22 Element ensure(compiler, | 42 Element ensure(compiler, |
| 23 String name, | 43 String name, |
| 24 Element lookup(name), | 44 Element lookup(name), |
| 25 [bool isPatched = true, | 45 [bool isPatched = false, |
| 26 bool hasBody = false, | 46 bool isPatch = false, |
| 27 bool isGetter = false]) { | 47 bool isMethod = true, |
| 48 bool isGetter = false, |
| 49 bool isFound = true]) { |
| 28 var element = lookup(buildSourceString(name)); | 50 var element = lookup(buildSourceString(name)); |
| 51 if (!isFound) { |
| 52 Expect.isNull(element); |
| 53 return element; |
| 54 } |
| 29 Expect.isNotNull(element); | 55 Expect.isNotNull(element); |
| 30 if (isGetter) { | 56 if (isGetter) { |
| 31 Expect.isTrue(element is AbstractFieldElement); | 57 Expect.isTrue(element is AbstractFieldElement); |
| 32 Expect.isNotNull(element.getter); | 58 Expect.isNotNull(element.getter); |
| 33 element = element.getter; | 59 element = element.getter; |
| 34 } | 60 } |
| 35 if (element is! ContainerElement && | 61 Expect.equals(isPatched, element.isPatched); |
| 36 element is! AbstractFieldElement) { | 62 if (isPatched) { |
| 37 // Classes aren't patched like functions and variables are. | 63 Expect.isNull(element.origin); |
| 38 Expect.equals(isPatched, element.isPatched); | 64 Expect.isNotNull(element.patch); |
| 65 |
| 66 Expect.equals(element, element.declaration); |
| 67 Expect.equals(element.patch, element.implementation); |
| 68 |
| 69 if (isMethod) { |
| 70 expectHasNoBody(compiler, element); |
| 71 expectHasBody(compiler, element.patch); |
| 72 } |
| 73 } else { |
| 74 Expect.isTrue(element.isImplementation); |
| 39 } | 75 } |
| 40 if (hasBody) { | 76 Expect.equals(isPatch, element.isPatch); |
| 41 var node = element.parseNode(compiler); | 77 if (isPatch) { |
| 42 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); | 78 Expect.isNotNull(element.origin); |
| 43 Expect.isNotNull(node.body, "expected body, bot none found"); | 79 Expect.isNull(element.patch); |
| 80 |
| 81 Expect.equals(element.origin, element.declaration); |
| 82 Expect.equals(element, element.implementation); |
| 83 |
| 84 if (isMethod) { |
| 85 expectHasBody(compiler, element); |
| 86 expectHasNoBody(compiler, element.origin); |
| 87 } |
| 88 } else { |
| 89 Expect.isTrue(element.isDeclaration); |
| 44 } | 90 } |
| 91 if (!(element.isPatched || element.isPatch)) { |
| 92 Expect.isNull(element.origin); |
| 93 Expect.isNull(element.patch); |
| 94 |
| 95 Expect.equals(element, element.declaration); |
| 96 Expect.equals(element, element.implementation); |
| 97 |
| 98 if (isMethod) { |
| 99 expectHasBody(compiler, element); |
| 100 } |
| 101 } |
| 102 Expect.isFalse(element.isPatched && element.isPatch); |
| 45 return element; | 103 return element; |
| 46 } | 104 } |
| 47 | 105 |
| 48 testPatchFunction() { | 106 testPatchFunction() { |
| 49 var compiler = applyPatch( | 107 var compiler = applyPatch( |
| 50 "external test();", | 108 "external test();", |
| 51 "patch test() { return 'string'; } "); | 109 "patch test() { return 'string'; } "); |
| 52 ensure(compiler, "test", compiler.coreLibrary.find, hasBody: true); | 110 ensure(compiler, "test", compiler.coreLibrary.find, isPatched: true); |
| 111 ensure(compiler, "test", compiler.coreLibrary.patch.find, isPatch: true); |
| 53 } | 112 } |
| 54 | 113 |
| 55 testPatchMember() { | 114 testPatchMember() { |
| 56 var compiler = applyPatch( | 115 var compiler = applyPatch( |
| 57 """ | 116 """ |
| 58 class Class { | 117 class Class { |
| 59 external String toString(); | 118 external String toString(); |
| 60 } | 119 } |
| 61 """, | 120 """, |
| 62 """ | 121 """ |
| 63 patch class Class { | 122 patch class Class { |
| 64 patch String toString() => 'string'; | 123 patch String toString() => 'string'; |
| 65 } | 124 } |
| 66 """); | 125 """); |
| 67 var container = ensure(compiler, "Class", compiler.coreLibrary.find); | 126 var container = ensure(compiler, "Class", compiler.coreLibrary.find, |
| 127 isMethod: false, isPatched: true); |
| 68 container.parseNode(compiler); | 128 container.parseNode(compiler); |
| 69 ensure(compiler, "toString", container.lookupLocalMember, hasBody:true); | 129 ensure(compiler, "Class", compiler.coreLibrary.patch.find, |
| 130 isMethod: false, isPatch: true); |
| 131 |
| 132 ensure(compiler, "toString", container.lookupLocalMember, |
| 133 isPatched: true); |
| 134 ensure(compiler, "toString", container.patch.lookupLocalMember, |
| 135 isPatch: true); |
| 70 } | 136 } |
| 71 | 137 |
| 72 testPatchGetter() { | 138 testPatchGetter() { |
| 73 var compiler = applyPatch( | 139 var compiler = applyPatch( |
| 74 """ | 140 """ |
| 75 class Class { | 141 class Class { |
| 76 external int get field; | 142 external int get field; |
| 77 } | 143 } |
| 78 """, | 144 """, |
| 79 """ | 145 """ |
| 80 patch class Class { | 146 patch class Class { |
| 81 patch int get field => 5; | 147 patch int get field => 5; |
| 82 } | 148 } |
| 83 """); | 149 """); |
| 84 var container = ensure(compiler, "Class", compiler.coreLibrary.find); | 150 var container = ensure(compiler, "Class", compiler.coreLibrary.find, |
| 151 isPatched: true, isMethod: false); |
| 85 container.parseNode(compiler); | 152 container.parseNode(compiler); |
| 86 ensure(compiler, | 153 ensure(compiler, |
| 87 "field", | 154 "field", |
| 88 container.lookupLocalMember, | 155 container.lookupLocalMember, |
| 89 isGetter: true, | 156 isGetter: true, |
| 90 hasBody: true); | 157 isPatched: true); |
| 158 ensure(compiler, |
| 159 "field", |
| 160 container.patch.lookupLocalMember, |
| 161 isGetter: true, |
| 162 isPatch: true); |
| 163 } |
| 164 |
| 165 testRegularMember() { |
| 166 var compiler = applyPatch( |
| 167 """ |
| 168 class Class { |
| 169 void regular() {} |
| 170 } |
| 171 """, |
| 172 """ |
| 173 patch class Class { |
| 174 } |
| 175 """); |
| 176 var container = ensure(compiler, "Class", compiler.coreLibrary.find, |
| 177 isMethod: false, isPatched: true); |
| 178 container.parseNode(compiler); |
| 179 ensure(compiler, "Class", compiler.coreLibrary.patch.find, |
| 180 isMethod: false, isPatch: true); |
| 181 |
| 182 ensure(compiler, "regular", container.lookupLocalMember); |
| 183 ensure(compiler, "regular", container.patch.lookupLocalMember); |
| 184 } |
| 185 |
| 186 testGhostMember() { |
| 187 var compiler = applyPatch( |
| 188 """ |
| 189 class Class { |
| 190 } |
| 191 """, |
| 192 """ |
| 193 patch class Class { |
| 194 void ghost() {} |
| 195 } |
| 196 """); |
| 197 var container = ensure(compiler, "Class", compiler.coreLibrary.find, |
| 198 isMethod: false, isPatched: true); |
| 199 container.parseNode(compiler); |
| 200 ensure(compiler, "Class", compiler.coreLibrary.patch.find, |
| 201 isMethod: false, isPatch: true); |
| 202 |
| 203 ensure(compiler, "ghost", container.lookupLocalMember, isFound: false); |
| 204 ensure(compiler, "ghost", container.patch.lookupLocalMember); |
| 91 } | 205 } |
| 92 | 206 |
| 93 testInjectFunction() { | 207 testInjectFunction() { |
| 94 var compiler = applyPatch( | 208 var compiler = applyPatch( |
| 95 "", | 209 "", |
| 96 "int _function() => 5;"); | 210 "int _function() => 5;"); |
| 97 ensure(compiler, | 211 ensure(compiler, |
| 98 "_function", | 212 "_function", |
| 99 compiler.coreLibrary.find, | 213 compiler.coreLibrary.find, |
| 100 hasBody: true, | 214 isFound: false); |
| 101 isPatched: false); | 215 ensure(compiler, |
| 216 "_function", |
| 217 compiler.coreLibrary.patch.find); |
| 102 } | 218 } |
| 103 | 219 |
| 104 main() { | 220 main() { |
| 105 testPatchFunction(); | 221 testPatchFunction(); |
| 106 testPatchMember(); | 222 testPatchMember(); |
| 107 testPatchGetter(); | 223 testPatchGetter(); |
| 224 testRegularMember(); |
| 225 testGhostMember(); |
| 108 testInjectFunction(); | 226 testInjectFunction(); |
| 109 } | 227 } |
| OLD | NEW |