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 "package:expect/expect.dart"; | 5 import "package:expect/expect.dart"; |
| 6 import "package:async_helper/async_helper.dart"; |
6 import 'compiler_helper.dart'; | 7 import 'compiler_helper.dart'; |
7 import 'parser_helper.dart'; | 8 import 'parser_helper.dart'; |
8 | 9 |
9 void checkPosition(Spannable spannable, Node node, String source, compiler) { | 10 void checkPosition(Spannable spannable, Node node, String source, compiler) { |
10 SourceSpan span = compiler.spanFromSpannable(spannable); | 11 SourceSpan span = compiler.spanFromSpannable(spannable); |
11 Expect.isTrue(span.begin < span.end, | 12 Expect.isTrue(span.begin < span.end, |
12 'begin = ${span.begin}; end = ${span.end}'); | 13 'begin = ${span.begin}; end = ${span.end}'); |
13 Expect.isTrue(span.end < source.length, | 14 Expect.isTrue(span.end < source.length, |
14 'end = ${span.end}; length = ${source.length}'); | 15 'end = ${span.end}; length = ${source.length}'); |
15 String yield = source.substring(span.begin, span.end); | 16 String yield = source.substring(span.begin, span.end); |
16 | 17 |
17 // TODO(ahe): The node does not include "@". Fix that. | 18 // TODO(ahe): The node does not include "@". Fix that. |
18 Expect.stringEquals('@$node', yield); | 19 Expect.stringEquals('@$node', yield); |
19 } | 20 } |
20 | 21 |
21 void checkAnnotation(String name, String declaration, | 22 void checkAnnotation(String name, String declaration, |
22 {bool isTopLevelOnly: false}) { | 23 {bool isTopLevelOnly: false}) { |
23 var source; | |
24 | |
25 // Ensure that a compile-time constant can be resolved from an | 24 // Ensure that a compile-time constant can be resolved from an |
26 // annotation. | 25 // annotation. |
27 source = """const native = 'xyz'; | 26 var source1 = """const native = 'xyz'; |
28 @native | 27 @native |
29 $declaration | 28 $declaration |
30 main() {}"""; | 29 main() {}"""; |
31 | 30 |
32 compileAndCheck(source, name, (compiler, element) { | 31 compileAndCheck(source1, name, (compiler, element) { |
33 compiler.enqueuer.resolution.queueIsClosed = false; | 32 compiler.enqueuer.resolution.queueIsClosed = false; |
34 Expect.equals(1, length(element.metadata)); | 33 Expect.equals(1, length(element.metadata)); |
35 PartialMetadataAnnotation annotation = element.metadata.head; | 34 PartialMetadataAnnotation annotation = element.metadata.head; |
36 annotation.ensureResolved(compiler); | 35 annotation.ensureResolved(compiler); |
37 Constant value = annotation.value; | 36 Constant value = annotation.value; |
38 Expect.stringEquals('xyz', value.value.slowToString()); | 37 Expect.stringEquals('xyz', value.value.slowToString()); |
39 | 38 |
40 checkPosition(annotation, annotation.cachedNode, source, compiler); | 39 checkPosition(annotation, annotation.cachedNode, source1, compiler); |
41 }); | 40 }); |
42 | 41 |
43 // Ensure that each repeated annotation has a unique instance of | 42 // Ensure that each repeated annotation has a unique instance of |
44 // [MetadataAnnotation]. | 43 // [MetadataAnnotation]. |
45 source = """const native = 'xyz'; | 44 var source2 = """const native = 'xyz'; |
46 @native @native | 45 @native @native |
47 $declaration | 46 $declaration |
48 main() {}"""; | 47 main() {}"""; |
49 | 48 |
50 compileAndCheck(source, name, (compiler, element) { | 49 compileAndCheck(source2, name, (compiler, element) { |
51 compiler.enqueuer.resolution.queueIsClosed = false; | 50 compiler.enqueuer.resolution.queueIsClosed = false; |
52 Expect.equals(2, length(element.metadata)); | 51 Expect.equals(2, length(element.metadata)); |
53 PartialMetadataAnnotation annotation1 = element.metadata.head; | 52 PartialMetadataAnnotation annotation1 = element.metadata.head; |
54 PartialMetadataAnnotation annotation2 = element.metadata.tail.head; | 53 PartialMetadataAnnotation annotation2 = element.metadata.tail.head; |
55 annotation1.ensureResolved(compiler); | 54 annotation1.ensureResolved(compiler); |
56 annotation2.ensureResolved(compiler); | 55 annotation2.ensureResolved(compiler); |
57 Expect.isFalse(identical(annotation1, annotation2), | 56 Expect.isFalse(identical(annotation1, annotation2), |
58 'expected unique instances'); | 57 'expected unique instances'); |
59 Expect.notEquals(annotation1, annotation2, 'expected unequal instances'); | 58 Expect.notEquals(annotation1, annotation2, 'expected unequal instances'); |
60 Constant value1 = annotation1.value; | 59 Constant value1 = annotation1.value; |
61 Constant value2 = annotation2.value; | 60 Constant value2 = annotation2.value; |
62 Expect.identical(value1, value2, 'expected same compile-time constant'); | 61 Expect.identical(value1, value2, 'expected same compile-time constant'); |
63 Expect.stringEquals('xyz', value1.value.slowToString()); | 62 Expect.stringEquals('xyz', value1.value.slowToString()); |
64 Expect.stringEquals('xyz', value2.value.slowToString()); | 63 Expect.stringEquals('xyz', value2.value.slowToString()); |
65 | 64 |
66 checkPosition(annotation1, annotation1.cachedNode, source, compiler); | 65 checkPosition(annotation1, annotation1.cachedNode, source2, compiler); |
67 checkPosition(annotation2, annotation2.cachedNode, source, compiler); | 66 checkPosition(annotation2, annotation2.cachedNode, source2, compiler); |
68 }); | 67 }); |
69 | 68 |
70 if (isTopLevelOnly) return; | 69 if (isTopLevelOnly) return; |
71 | 70 |
72 // Ensure that a compile-time constant can be resolved from an | 71 // Ensure that a compile-time constant can be resolved from an |
73 // annotation. | 72 // annotation. |
74 source = """const native = 'xyz'; | 73 var source3 = """const native = 'xyz'; |
75 class Foo { | 74 class Foo { |
76 @native | 75 @native |
77 $declaration | 76 $declaration |
78 } | 77 } |
79 main() {}"""; | 78 main() {}"""; |
80 | 79 |
81 compileAndCheck(source, 'Foo', (compiler, element) { | 80 compileAndCheck(source3, 'Foo', (compiler, element) { |
82 compiler.enqueuer.resolution.queueIsClosed = false; | 81 compiler.enqueuer.resolution.queueIsClosed = false; |
83 Expect.equals(0, length(element.metadata)); | 82 Expect.equals(0, length(element.metadata)); |
84 element.ensureResolved(compiler); | 83 element.ensureResolved(compiler); |
85 Expect.equals(0, length(element.metadata)); | 84 Expect.equals(0, length(element.metadata)); |
86 element = element.lookupLocalMember(buildSourceString(name)); | 85 element = element.lookupLocalMember(buildSourceString(name)); |
87 Expect.equals(1, length(element.metadata)); | 86 Expect.equals(1, length(element.metadata)); |
88 PartialMetadataAnnotation annotation = element.metadata.head; | 87 PartialMetadataAnnotation annotation = element.metadata.head; |
89 annotation.ensureResolved(compiler); | 88 annotation.ensureResolved(compiler); |
90 Constant value = annotation.value; | 89 Constant value = annotation.value; |
91 Expect.stringEquals('xyz', value.value.slowToString()); | 90 Expect.stringEquals('xyz', value.value.slowToString()); |
92 | 91 |
93 checkPosition(annotation, annotation.cachedNode, source, compiler); | 92 checkPosition(annotation, annotation.cachedNode, source3, compiler); |
94 }); | 93 }); |
95 | 94 |
96 // Ensure that each repeated annotation has a unique instance of | 95 // Ensure that each repeated annotation has a unique instance of |
97 // [MetadataAnnotation]. | 96 // [MetadataAnnotation]. |
98 source = """const native = 'xyz'; | 97 var source4 = """const native = 'xyz'; |
99 class Foo { | 98 class Foo { |
100 @native @native | 99 @native @native |
101 $declaration | 100 $declaration |
102 } | 101 } |
103 main() {}"""; | 102 main() {}"""; |
104 | 103 |
105 compileAndCheck(source, 'Foo', (compiler, element) { | 104 compileAndCheck(source4, 'Foo', (compiler, element) { |
106 compiler.enqueuer.resolution.queueIsClosed = false; | 105 compiler.enqueuer.resolution.queueIsClosed = false; |
107 Expect.equals(0, length(element.metadata)); | 106 Expect.equals(0, length(element.metadata)); |
108 element.ensureResolved(compiler); | 107 element.ensureResolved(compiler); |
109 Expect.equals(0, length(element.metadata)); | 108 Expect.equals(0, length(element.metadata)); |
110 element = element.lookupLocalMember(buildSourceString(name)); | 109 element = element.lookupLocalMember(buildSourceString(name)); |
111 Expect.equals(2, length(element.metadata)); | 110 Expect.equals(2, length(element.metadata)); |
112 PartialMetadataAnnotation annotation1 = element.metadata.head; | 111 PartialMetadataAnnotation annotation1 = element.metadata.head; |
113 PartialMetadataAnnotation annotation2 = element.metadata.tail.head; | 112 PartialMetadataAnnotation annotation2 = element.metadata.tail.head; |
114 annotation1.ensureResolved(compiler); | 113 annotation1.ensureResolved(compiler); |
115 annotation2.ensureResolved(compiler); | 114 annotation2.ensureResolved(compiler); |
116 Expect.isFalse(identical(annotation1, annotation2), | 115 Expect.isFalse(identical(annotation1, annotation2), |
117 'expected unique instances'); | 116 'expected unique instances'); |
118 Expect.notEquals(annotation1, annotation2, 'expected unequal instances'); | 117 Expect.notEquals(annotation1, annotation2, 'expected unequal instances'); |
119 Constant value1 = annotation1.value; | 118 Constant value1 = annotation1.value; |
120 Constant value2 = annotation2.value; | 119 Constant value2 = annotation2.value; |
121 Expect.identical(value1, value2, 'expected same compile-time constant'); | 120 Expect.identical(value1, value2, 'expected same compile-time constant'); |
122 Expect.stringEquals('xyz', value1.value.slowToString()); | 121 Expect.stringEquals('xyz', value1.value.slowToString()); |
123 Expect.stringEquals('xyz', value2.value.slowToString()); | 122 Expect.stringEquals('xyz', value2.value.slowToString()); |
124 | 123 |
125 checkPosition(annotation1, annotation1.cachedNode, source, compiler); | 124 checkPosition(annotation1, annotation1.cachedNode, source4, compiler); |
126 checkPosition(annotation1, annotation2.cachedNode, source, compiler); | 125 checkPosition(annotation1, annotation2.cachedNode, source4, compiler); |
127 }); | 126 }); |
128 } | 127 } |
129 | 128 |
130 void testClassMetadata() { | 129 void testClassMetadata() { |
131 checkAnnotation('Foo', 'class Foo {}', isTopLevelOnly: true); | 130 checkAnnotation('Foo', 'class Foo {}', isTopLevelOnly: true); |
132 } | 131 } |
133 | 132 |
134 void testTopLevelMethodMetadata() { | 133 void testTopLevelMethodMetadata() { |
135 checkAnnotation('foo', 'foo() {}'); | 134 checkAnnotation('foo', 'foo() {}'); |
136 } | 135 } |
(...skipping 12 matching lines...) Expand all Loading... |
149 Uri libUri = new Uri(scheme: 'source', path: 'lib.dart'); | 148 Uri libUri = new Uri(scheme: 'source', path: 'lib.dart'); |
150 String libSource = 'library lib;'; | 149 String libSource = 'library lib;'; |
151 | 150 |
152 Uri uri = new Uri(scheme: 'source', path: 'main.dart'); | 151 Uri uri = new Uri(scheme: 'source', path: 'main.dart'); |
153 | 152 |
154 Uri async = new Uri(scheme: 'dart', path: 'async'); | 153 Uri async = new Uri(scheme: 'dart', path: 'async'); |
155 | 154 |
156 var compiler = compilerFor(source, uri) | 155 var compiler = compilerFor(source, uri) |
157 ..registerSource(partUri, partSource) | 156 ..registerSource(partUri, partSource) |
158 ..registerSource(libUri, libSource) | 157 ..registerSource(libUri, libSource) |
159 ..registerSource(async, 'class DeferredLibrary {}') | 158 ..registerSource(async, 'class DeferredLibrary {}'); |
160 ..runCompiler(uri); | |
161 compiler.enqueuer.resolution.queueIsClosed = false; | |
162 LibraryElement element = compiler.libraries['$uri']; | |
163 Expect.isNotNull(element, 'Cannot find $uri'); | |
164 | 159 |
165 Link<MetadataAnnotation> metadata = extractMetadata(element); | 160 asyncTest(() => compiler.runCompiler(uri).then((_) { |
166 Expect.equals(1, length(metadata)); | 161 compiler.enqueuer.resolution.queueIsClosed = false; |
| 162 LibraryElement element = compiler.libraries['$uri']; |
| 163 Expect.isNotNull(element, 'Cannot find $uri'); |
167 | 164 |
168 PartialMetadataAnnotation annotation = metadata.head; | 165 Link<MetadataAnnotation> metadata = extractMetadata(element); |
169 annotation.ensureResolved(compiler); | 166 Expect.equals(1, length(metadata)); |
170 Constant value = annotation.value; | |
171 Expect.stringEquals('xyz', value.value.slowToString()); | |
172 | 167 |
173 checkPosition(annotation, annotation.cachedNode, source, compiler); | 168 PartialMetadataAnnotation annotation = metadata.head; |
| 169 annotation.ensureResolved(compiler); |
| 170 Constant value = annotation.value; |
| 171 Expect.stringEquals('xyz', value.value.slowToString()); |
| 172 |
| 173 checkPosition(annotation, annotation.cachedNode, source, compiler); |
| 174 })); |
174 } | 175 } |
175 | 176 |
176 var source; | 177 var source; |
177 | 178 |
178 source = """@native | 179 source = """@native |
179 library foo; | 180 library foo; |
180 const native = 'xyz'; | 181 const native = 'xyz'; |
181 main() {}"""; | 182 main() {}"""; |
182 compileAndCheckLibrary(source, (e) => e.libraryTag.metadata); | 183 compileAndCheckLibrary(source, (e) => e.libraryTag.metadata); |
183 | 184 |
(...skipping 22 matching lines...) Expand all Loading... |
206 compileAndCheckLibrary(source, | 207 compileAndCheckLibrary(source, |
207 (e) => e.compilationUnits.first.partTag.metadata); | 208 (e) => e.compilationUnits.first.partTag.metadata); |
208 } | 209 } |
209 | 210 |
210 void main() { | 211 void main() { |
211 testClassMetadata(); | 212 testClassMetadata(); |
212 testTopLevelMethodMetadata(); | 213 testTopLevelMethodMetadata(); |
213 testTopLevelFieldMetadata(); | 214 testTopLevelFieldMetadata(); |
214 testLibraryTags(); | 215 testLibraryTags(); |
215 } | 216 } |
OLD | NEW |