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