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 fasta.analyzer.element_store; | |
6 | |
7 import 'package:analyzer/src/kernel/loader.dart' show ReferenceLevelLoader; | |
8 | |
9 import 'package:kernel/ast.dart'; | |
10 | |
11 import 'package:analyzer/analyzer.dart' show ParameterKind; | |
12 | |
13 import 'package:analyzer/analyzer.dart' as analyzer; | |
14 | |
15 import 'package:analyzer/dart/element/element.dart'; | |
16 | |
17 import 'package:analyzer/dart/element/type.dart' as analyzer; | |
18 | |
19 import 'package:front_end/src/fasta/problems.dart' show unhandled, unsupported; | |
20 | |
21 import 'package:front_end/src/fasta/kernel/kernel_builder.dart'; | |
22 | |
23 import 'package:front_end/src/fasta/dill/dill_member_builder.dart'; | |
24 | |
25 import 'mock_element.dart'; | |
26 | |
27 import 'mock_type.dart'; | |
28 | |
29 abstract class ElementStore implements ReferenceLevelLoader { | |
30 Element operator [](Builder builder); | |
31 | |
32 factory ElementStore( | |
33 LibraryBuilder coreLibrary, Map<Uri, LibraryBuilder> builders) = | |
34 ElementStoreImplementation; | |
35 } | |
36 | |
37 // ClassElement, | |
38 // ClassMemberElement, | |
39 // CompilationUnitElement, | |
40 // ConstructorElement, | |
41 // Element, | |
42 // FieldElement, | |
43 // FieldFormalParameterElement, | |
44 // FunctionElement, | |
45 // FunctionTypedElement, | |
46 // LibraryElement, | |
47 // LocalElement, | |
48 // LocalVariableElement, | |
49 // MethodElement, | |
50 // ParameterElement, | |
51 // PrefixElement, | |
52 // PropertyAccessorElement, | |
53 // TopLevelVariableElement, | |
54 // TypeParameterElement, | |
55 // VariableElement; | |
56 class ElementStoreImplementation implements ElementStore { | |
57 final LibraryBuilder coreLibrary; | |
58 | |
59 final Map<Builder, Element> elements; | |
60 | |
61 ElementStoreImplementation.internal(this.coreLibrary, this.elements); | |
62 | |
63 Element operator [](Builder builder) { | |
64 // Avoid storing local elements in the element store to reduce memory | |
65 // usage. So they both implement [Element] and [Builder]. | |
66 return builder is Element ? builder : elements[builder]; | |
67 } | |
68 | |
69 factory ElementStoreImplementation( | |
70 LibraryBuilder coreLibrary, Map<Uri, LibraryBuilder> libraries) { | |
71 Map<Builder, Element> elements = <Builder, Element>{}; | |
72 libraries.forEach((Uri uri, LibraryBuilder library) { | |
73 KernelCompilationUnitElement unit = | |
74 new KernelCompilationUnitElement(library); | |
75 KernelLibraryElement element = new KernelLibraryElement(unit); | |
76 elements[library] = element; | |
77 unit.library = element; | |
78 library.forEach((String name, Builder builder) { | |
79 do { | |
80 if (builder is ClassBuilder) { | |
81 elements[builder] = new KernelClassElement(builder); | |
82 } else if (builder is KernelFunctionTypeAliasBuilder) { | |
83 elements[builder] = new KernelFunctionTypeAliasElement(builder); | |
84 } else if (builder is DillMemberBuilder) { | |
85 Member member = builder.member; | |
86 if (member is Field) {} else if (member is Procedure) { | |
87 buildDillFunctionElement(builder, unit, elements); | |
88 } else { | |
89 unhandled("'$name' (${member.runtimeType})", "element store", | |
90 builder.charOffset, uri); | |
91 } | |
92 } else if (builder is KernelProcedureBuilder) { | |
93 buildKernelFunctionElement(builder, unit, elements); | |
94 } else if (builder is BuiltinTypeBuilder) { | |
95 // TODO(ahe): Set up elements for dynamic and void. | |
96 } else { | |
97 unhandled("'$name' (${builder.runtimeType})", "element store", | |
98 builder.charOffset, uri); | |
99 } | |
100 builder = builder.next; | |
101 } while (builder != null); | |
102 }); | |
103 }); | |
104 return new ElementStoreImplementation.internal(coreLibrary, elements); | |
105 } | |
106 | |
107 bool get ignoreRedirectingFactories => false; | |
108 | |
109 Constructor getCoreClassConstructorReference(String className, | |
110 {String constructorName, String library}) { | |
111 assert(library == null); | |
112 return coreLibrary | |
113 .getConstructor(className, constructorName: constructorName) | |
114 .target; | |
115 } | |
116 | |
117 Library getLibraryReference(LibraryElement element) { | |
118 return unsupported("getLibraryReference", -1, null); | |
119 } | |
120 | |
121 Class getClassReference(covariant KernelClassElement cls) => cls.builder.cls; | |
122 | |
123 Member getMemberReference(Element element) { | |
124 if (element is KernelFunctionElement) { | |
125 return element.procedure; | |
126 } else { | |
127 return unhandled( | |
128 "${element.runtimeType}", "getMemberReference", -1, null); | |
129 } | |
130 } | |
131 | |
132 Class getRootClassReference() => | |
133 unsupported("getRootClassReference", -1, null); | |
134 | |
135 Constructor getRootClassConstructorReference() { | |
136 return unsupported("getRootClassConstructorReference", -1, null); | |
137 } | |
138 | |
139 Class getCoreClassReference(String className) { | |
140 return unsupported("getCoreClassReference", -1, null); | |
141 } | |
142 | |
143 TypeParameter tryGetClassTypeParameter(TypeParameterElement element) { | |
144 return unsupported("tryGetClassTypeParameter", -1, null); | |
145 } | |
146 | |
147 Class getSharedMixinApplicationClass( | |
148 Library library, Class supertype, Class mixin) { | |
149 return unsupported("getSharedMixinApplicationClass", -1, null); | |
150 } | |
151 | |
152 bool get strongMode => false; | |
153 | |
154 static void buildDillFunctionElement(DillMemberBuilder builder, | |
155 KernelCompilationUnitElement unit, Map<Builder, Element> elements) { | |
156 Procedure procedure = builder.member; | |
157 List<VariableDeclaration> positionalParameters = | |
158 procedure.function.positionalParameters; | |
159 List<VariableDeclaration> namedParameters = | |
160 procedure.function.namedParameters; | |
161 int requiredParameterCount = procedure.function.requiredParameterCount; | |
162 List<KernelParameterElement> parameters = new List<KernelParameterElement>( | |
163 positionalParameters.length + namedParameters.length); | |
164 int i = 0; | |
165 for (VariableDeclaration parameter in positionalParameters) { | |
166 parameters[i] = buildFormalParameter(parameter, | |
167 isOptional: i >= requiredParameterCount); | |
168 i++; | |
169 } | |
170 for (VariableDeclaration parameter in namedParameters) { | |
171 parameters[i++] = buildFormalParameter(parameter, isNamed: true); | |
172 } | |
173 elements[builder] = new KernelFunctionElement(procedure, unit, parameters); | |
174 } | |
175 | |
176 static void buildKernelFunctionElement(KernelProcedureBuilder builder, | |
177 KernelCompilationUnitElement unit, Map<Builder, Element> elements) { | |
178 assert(builder.procedure != null); | |
179 List<KernelParameterElement> parameters; | |
180 int i = 0; | |
181 if (builder.formals != null) { | |
182 parameters = new List<KernelParameterElement>(builder.formals.length); | |
183 for (KernelFormalParameterBuilder parameter in builder.formals) { | |
184 assert(parameter.declaration != null); | |
185 elements[parameter] = parameters[i++] = buildFormalParameter( | |
186 parameter.declaration, | |
187 isOptional: parameter.isOptional, | |
188 isNamed: parameter.isNamed); | |
189 } | |
190 } else { | |
191 parameters = new List<KernelParameterElement>(0); | |
192 } | |
193 elements[builder] = | |
194 new KernelFunctionElement(builder.procedure, unit, parameters); | |
195 } | |
196 | |
197 static KernelParameterElement buildFormalParameter( | |
198 VariableDeclaration parameter, | |
199 {bool isOptional: true, | |
200 bool isNamed: false}) { | |
201 ParameterKind kind = isOptional | |
202 ? (isNamed ? ParameterKind.NAMED : ParameterKind.POSITIONAL) | |
203 : ParameterKind.REQUIRED; | |
204 return new KernelParameterElement(parameter, kind); | |
205 } | |
206 } | |
207 | |
208 class KernelLibraryElement extends MockLibraryElement { | |
209 final KernelCompilationUnitElement definingCompilationUnit; | |
210 | |
211 KernelLibraryElement(this.definingCompilationUnit); | |
212 | |
213 FunctionElement get loadLibraryFunction => null; | |
214 } | |
215 | |
216 class KernelCompilationUnitElement extends MockCompilationUnitElement { | |
217 final LibraryBuilder builder; | |
218 | |
219 KernelLibraryElement library; | |
220 | |
221 KernelCompilationUnitElement(this.builder); | |
222 | |
223 KernelLibraryElement get enclosingElement => library; | |
224 | |
225 String get uri => "${builder.uri}"; | |
226 } | |
227 | |
228 class KernelFunctionElement extends MockFunctionElement { | |
229 final Procedure procedure; | |
230 | |
231 final KernelCompilationUnitElement enclosingElement; | |
232 | |
233 final List<KernelParameterElement> parameters; | |
234 | |
235 KernelFunctionElement(this.procedure, this.enclosingElement, this.parameters); | |
236 | |
237 KernelLibraryElement get library => enclosingElement.library; | |
238 } | |
239 | |
240 class KernelParameterElement extends MockParameterElement { | |
241 final VariableDeclaration declaration; | |
242 | |
243 final ParameterKind parameterKind; | |
244 | |
245 KernelParameterElement(this.declaration, this.parameterKind); | |
246 } | |
247 | |
248 /// Both an [Element] and [Builder] to using memory to store local elements in | |
249 /// [ElementStore]. | |
250 class AnalyzerLocalVariableElemment extends MockElement | |
251 implements LocalVariableElement { | |
252 final analyzer.VariableDeclaration variable; | |
253 | |
254 AnalyzerLocalVariableElemment(this.variable) | |
255 : super(ElementKind.LOCAL_VARIABLE); | |
256 | |
257 String get name => variable.name.name; | |
258 | |
259 bool get isFinal => false; // TODO(ahe): implement this. | |
260 | |
261 bool get isConst => false; // TODO(ahe): implement this. | |
262 | |
263 analyzer.VariableDeclaration get target => variable; | |
264 | |
265 get type => null; | |
266 | |
267 get constantValue => unsupported("constantValue", charOffset, fileUri); | |
268 | |
269 computeConstantValue() => | |
270 unsupported("computeConstantValue", charOffset, fileUri); | |
271 } | |
272 | |
273 /// Both an [Element] and [Builder] to using memory to store local elements in | |
274 /// [ElementStore]. | |
275 class AnalyzerParameterElement extends MockParameterElement { | |
276 final analyzer.FormalParameter parameter; | |
277 | |
278 AnalyzerParameterElement(this.parameter); | |
279 | |
280 String get name => parameter.identifier.name; | |
281 | |
282 bool get isFinal => false; // TODO(ahe): implement this. | |
283 | |
284 bool get isConst => false; // TODO(ahe): implement this. | |
285 | |
286 analyzer.FormalParameter get target => parameter; | |
287 } | |
288 | |
289 class KernelClassElement extends MockClassElement { | |
290 final KernelClassBuilder builder; | |
291 | |
292 KernelInterfaceType rawType; | |
293 | |
294 KernelClassElement(this.builder) { | |
295 rawType = new KernelInterfaceType(this); | |
296 } | |
297 } | |
298 | |
299 class KernelFunctionTypeAliasElement extends MockFunctionTypeAliasElement { | |
300 final KernelFunctionTypeAliasBuilder builder; | |
301 | |
302 KernelFunctionTypeAliasElement(this.builder); | |
303 | |
304 @override | |
305 analyzer.DartType get returnType { | |
306 return unsupported("returnType", charOffset, fileUri); | |
307 } | |
308 | |
309 @override | |
310 analyzer.FunctionType get type { | |
311 return unsupported("type", charOffset, fileUri); | |
312 } | |
313 | |
314 @override | |
315 List<TypeParameterElement> get typeParameters { | |
316 return unsupported("typeParameters", charOffset, fileUri); | |
317 } | |
318 } | |
319 | |
320 class KernelInterfaceType extends MockInterfaceType { | |
321 final KernelClassElement element; | |
322 | |
323 KernelInterfaceType(this.element); | |
324 | |
325 List<analyzer.DartType> get typeArguments => const <analyzer.DartType>[]; | |
326 } | |
OLD | NEW |