Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: pkg/compiler/lib/src/kernel/env.dart

Issue 2964683003: Split implementation of KernelToElementMapImpl (Closed)
Patch Set: Updated cf. comments Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/kernel/elements.dart ('k') | pkg/compiler/lib/src/kernel/kelements.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2017, 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 dart2js.kernel.env;
6
7 import 'package:kernel/ast.dart' as ir;
8 import 'package:kernel/clone.dart';
9 import 'package:kernel/type_algebra.dart';
10
11 import '../common.dart';
12 import '../common/resolution.dart';
13 import '../constants/constructors.dart';
14 import '../constants/expressions.dart';
15 import '../constants/values.dart';
16 import '../elements/entities.dart';
17 import '../elements/types.dart';
18 import '../ordered_typeset.dart';
19 import '../ssa/kernel_impact.dart';
20 import 'element_map.dart';
21 import 'element_map_impl.dart';
22 import 'element_map_mixins.dart';
23
24 /// Environment for fast lookup of program libraries.
25 class ProgramEnv {
26 final Set<ir.Program> programs = new Set<ir.Program>();
27
28 Map<Uri, LibraryEnv> _libraryMap;
29
30 /// TODO(johnniwinther): Handle arbitrary load order if needed.
31 ir.Member get mainMethod => programs.first?.mainMethod;
32
33 void addProgram(ir.Program program) {
34 if (programs.add(program)) {
35 if (_libraryMap != null) {
36 _addLibraries(program);
37 }
38 }
39 }
40
41 void _addLibraries(ir.Program program) {
42 for (ir.Library library in program.libraries) {
43 _libraryMap[library.importUri] = new LibraryEnv(library);
44 }
45 }
46
47 void _ensureLibraryMap() {
48 if (_libraryMap == null) {
49 _libraryMap = <Uri, LibraryEnv>{};
50 for (ir.Program program in programs) {
51 _addLibraries(program);
52 }
53 }
54 }
55
56 /// Return the [LibraryEnv] for the library with the canonical [uri].
57 LibraryEnv lookupLibrary(Uri uri) {
58 _ensureLibraryMap();
59 return _libraryMap[uri];
60 }
61
62 /// Calls [f] for each library in this environment.
63 void forEachLibrary(void f(LibraryEnv library)) {
64 _ensureLibraryMap();
65 _libraryMap.values.forEach(f);
66 }
67
68 /// Returns the number of libraries in this environment.
69 int get length {
70 _ensureLibraryMap();
71 return _libraryMap.length;
72 }
73 }
74
75 /// Environment for fast lookup of library classes and members.
76 class LibraryEnv {
77 final ir.Library library;
78
79 Map<String, ClassEnv> _classMap;
80 Map<String, ir.Member> _memberMap;
81 Map<String, ir.Member> _setterMap;
82
83 LibraryEnv(this.library);
84
85 void _ensureClassMap() {
86 if (_classMap == null) {
87 _classMap = <String, ClassEnv>{};
88 for (ir.Class cls in library.classes) {
89 _classMap[cls.name] = new ClassEnv(cls);
90 }
91 }
92 }
93
94 /// Return the [ClassEnv] for the class [name] in [library].
95 ClassEnv lookupClass(String name) {
96 _ensureClassMap();
97 return _classMap[name];
98 }
99
100 /// Calls [f] for each class in this library.
101 void forEachClass(void f(ClassEnv cls)) {
102 _ensureClassMap();
103 _classMap.values.forEach(f);
104 }
105
106 void _ensureMemberMaps() {
107 if (_memberMap == null) {
108 _memberMap = <String, ir.Member>{};
109 _setterMap = <String, ir.Member>{};
110 for (ir.Member member in library.members) {
111 if (member is ir.Procedure) {
112 if (member.kind == ir.ProcedureKind.Setter) {
113 _setterMap[member.name.name] = member;
114 } else {
115 _memberMap[member.name.name] = member;
116 }
117 } else if (member is ir.Field) {
118 _memberMap[member.name.name] = member;
119 if (member.isMutable) {
120 _setterMap[member.name.name] = member;
121 }
122 } else {
123 throw new SpannableAssertionFailure(
124 NO_LOCATION_SPANNABLE, "Unexpected library member node: $member");
125 }
126 }
127 }
128 }
129
130 /// Return the [ir.Member] for the member [name] in [library].
131 ir.Member lookupMember(String name, {bool setter: false}) {
132 _ensureMemberMaps();
133 return setter ? _setterMap[name] : _memberMap[name];
134 }
135
136 void forEachMember(void f(ir.Member member)) {
137 _ensureMemberMaps();
138 _memberMap.values.forEach(f);
139 for (ir.Member member in _setterMap.values) {
140 if (member is ir.Procedure) {
141 f(member);
142 } else {
143 // Skip fields; these are also in _memberMap.
144 }
145 }
146 }
147 }
148
149 /// Environment for fast lookup of class members.
150 class ClassEnv {
151 final ir.Class cls;
152 bool isMixinApplication;
153 final bool isUnnamedMixinApplication;
154
155 InterfaceType thisType;
156 InterfaceType rawType;
157 InterfaceType supertype;
158 InterfaceType mixedInType;
159 List<InterfaceType> interfaces;
160 OrderedTypeSet orderedTypeSet;
161
162 Map<String, ir.Member> _constructorMap;
163 Map<String, ir.Member> _memberMap;
164 Map<String, ir.Member> _setterMap;
165
166 Iterable<ConstantValue> _metadata;
167
168 ClassEnv(this.cls)
169 // TODO(johnniwinther): Change this to use a property on [cls] when such
170 // is added to kernel.
171 : isUnnamedMixinApplication =
172 cls.name.contains('+') || cls.name.contains('&');
173
174 /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
175 ir.Constructor _buildForwardingConstructor(
176 CloneVisitor cloner, ir.Constructor superclassConstructor) {
177 var superFunction = superclassConstructor.function;
178
179 // We keep types and default values for the parameters but always mark the
180 // parameters as final (since we just forward them to the super
181 // constructor).
182 ir.VariableDeclaration cloneVariable(ir.VariableDeclaration variable) {
183 ir.VariableDeclaration clone = cloner.clone(variable);
184 clone.isFinal = true;
185 return clone;
186 }
187
188 // Build a [FunctionNode] which has the same parameters as the one in the
189 // superclass constructor.
190 var positionalParameters =
191 superFunction.positionalParameters.map(cloneVariable).toList();
192 var namedParameters =
193 superFunction.namedParameters.map(cloneVariable).toList();
194 var function = new ir.FunctionNode(new ir.EmptyStatement(),
195 positionalParameters: positionalParameters,
196 namedParameters: namedParameters,
197 requiredParameterCount: superFunction.requiredParameterCount,
198 returnType: const ir.VoidType());
199
200 // Build a [SuperInitializer] which takes all positional/named parameters
201 // and forward them to the super class constructor.
202 var positionalArguments = <ir.Expression>[];
203 for (var variable in positionalParameters) {
204 positionalArguments.add(new ir.VariableGet(variable));
205 }
206 var namedArguments = <ir.NamedExpression>[];
207 for (var variable in namedParameters) {
208 namedArguments.add(
209 new ir.NamedExpression(variable.name, new ir.VariableGet(variable)));
210 }
211 var superInitializer = new ir.SuperInitializer(superclassConstructor,
212 new ir.Arguments(positionalArguments, named: namedArguments));
213
214 // Assemble the constructor.
215 return new ir.Constructor(function,
216 name: superclassConstructor.name,
217 initializers: <ir.Initializer>[superInitializer]);
218 }
219
220 void _ensureMaps() {
221 if (_memberMap == null) {
222 _memberMap = <String, ir.Member>{};
223 _setterMap = <String, ir.Member>{};
224 _constructorMap = <String, ir.Member>{};
225
226 void addMembers(ir.Class c, {bool includeStatic}) {
227 for (ir.Member member in c.members) {
228 if (member is ir.Constructor ||
229 member is ir.Procedure &&
230 member.kind == ir.ProcedureKind.Factory) {
231 if (!includeStatic) continue;
232 _constructorMap[member.name.name] = member;
233 } else if (member is ir.Procedure) {
234 if (!includeStatic && member.isStatic) continue;
235 if (member.kind == ir.ProcedureKind.Setter) {
236 _setterMap[member.name.name] = member;
237 } else {
238 _memberMap[member.name.name] = member;
239 }
240 } else if (member is ir.Field) {
241 if (!includeStatic && member.isStatic) continue;
242 _memberMap[member.name.name] = member;
243 if (member.isMutable) {
244 _setterMap[member.name.name] = member;
245 }
246 _memberMap[member.name.name] = member;
247 } else {
248 throw new SpannableAssertionFailure(
249 NO_LOCATION_SPANNABLE, "Unexpected class member node: $member");
250 }
251 }
252 }
253
254 if (cls.mixedInClass != null) {
255 addMembers(cls.mixedInClass, includeStatic: false);
256 }
257 addMembers(cls, includeStatic: true);
258
259 if (isUnnamedMixinApplication && _constructorMap.isEmpty) {
260 // Unnamed mixin applications have no constructors when read from .dill.
261 // For each generative constructor in the superclass we make a
262 // corresponding forwarding constructor in the subclass.
263 //
264 // This code is copied from
265 // 'package:kernel/transformations/mixin_full_resolution.dart'
266 var superclassSubstitution = getSubstitutionMap(cls.supertype);
267 var superclassCloner =
268 new CloneVisitor(typeSubstitution: superclassSubstitution);
269 for (var superclassConstructor in cls.superclass.constructors) {
270 var forwardingConstructor = _buildForwardingConstructor(
271 superclassCloner, superclassConstructor);
272 cls.addMember(forwardingConstructor);
273 _constructorMap[forwardingConstructor.name.name] =
274 forwardingConstructor;
275 }
276 }
277 }
278 }
279
280 /// Return the [ir.Member] for the member [name] in [library].
281 ir.Member lookupMember(String name, {bool setter: false}) {
282 _ensureMaps();
283 return setter ? _setterMap[name] : _memberMap[name];
284 }
285
286 /// Return the [ir.Member] for the member [name] in [library].
287 ir.Member lookupConstructor(String name) {
288 _ensureMaps();
289 return _constructorMap[name];
290 }
291
292 void forEachMember(void f(ir.Member member)) {
293 _ensureMaps();
294 _memberMap.values.forEach(f);
295 for (ir.Member member in _setterMap.values) {
296 if (member is ir.Procedure) {
297 f(member);
298 } else {
299 // Skip fields; these are also in _memberMap.
300 }
301 }
302 }
303
304 void forEachConstructor(void f(ir.Member member)) {
305 _ensureMaps();
306 _constructorMap.values.forEach(f);
307 }
308
309 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
310 return _metadata ??= elementMap.getMetadata(cls.annotations);
311 }
312 }
313
314 class MemberData {
315 final ir.Member node;
316 Iterable<ConstantValue> _metadata;
317
318 MemberData(this.node);
319
320 ResolutionImpact getWorldImpact(KernelToElementMapForImpact elementMap) {
321 return buildKernelImpact(node, elementMap);
322 }
323
324 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
325 return _metadata ??= elementMap.getMetadata(node.annotations);
326 }
327 }
328
329 class FunctionData extends MemberData {
330 final ir.FunctionNode functionNode;
331 FunctionType _type;
332
333 FunctionData(ir.Member node, this.functionNode) : super(node);
334
335 FunctionType getFunctionType(KernelToElementMapBase elementMap) {
336 return _type ??= elementMap.getFunctionType(functionNode);
337 }
338
339 void forEachParameter(KernelToElementMapForBuilding elementMap,
340 void f(DartType type, String name, ConstantValue defaultValue)) {
341 void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
342 DartType type = elementMap.getDartType(node.type);
343 String name = node.name;
344 ConstantValue defaultValue;
345 if (isOptional) {
346 if (node.initializer != null) {
347 defaultValue = elementMap.getConstantValue(node.initializer);
348 } else {
349 defaultValue = new NullConstantValue();
350 }
351 }
352 f(type, name, defaultValue);
353 }
354
355 for (int i = 0; i < functionNode.positionalParameters.length; i++) {
356 handleParameter(functionNode.positionalParameters[i],
357 isOptional: i < functionNode.requiredParameterCount);
358 }
359 functionNode.namedParameters.toList()
360 ..sort(namedOrdering)
361 ..forEach(handleParameter);
362 }
363 }
364
365 class ConstructorData extends FunctionData {
366 ConstantConstructor _constantConstructor;
367
368 ConstructorData(ir.Member node, ir.FunctionNode functionNode)
369 : super(node, functionNode);
370
371 ConstantConstructor getConstructorConstant(
372 KernelToElementMapBase elementMap, ConstructorEntity constructor) {
373 if (_constantConstructor == null) {
374 if (node is ir.Constructor && constructor.isConst) {
375 _constantConstructor =
376 new Constantifier(elementMap).computeConstantConstructor(node);
377 } else {
378 throw new SpannableAssertionFailure(
379 constructor,
380 "Unexpected constructor $constructor in "
381 "KernelWorldBuilder._getConstructorConstant");
382 }
383 }
384 return _constantConstructor;
385 }
386 }
387
388 class FieldData extends MemberData {
389 ConstantExpression _constant;
390
391 FieldData(ir.Field node) : super(node);
392
393 ir.Field get node => super.node;
394
395 ConstantExpression getFieldConstant(
396 KernelToElementMapBase elementMap, FieldEntity field) {
397 if (_constant == null) {
398 if (node.isConst) {
399 _constant = new Constantifier(elementMap).visit(node.initializer);
400 } else {
401 throw new SpannableAssertionFailure(
402 field,
403 "Unexpected field $field in "
404 "KernelWorldBuilder._getConstructorConstant");
405 }
406 }
407 return _constant;
408 }
409 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/elements.dart ('k') | pkg/compiler/lib/src/kernel/kelements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698