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

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

Issue 2829033002: Rename KernelWorldBuilder to KernelElementBuilder (Closed)
Patch Set: Rename to KernelToElementMap Created 3 years, 8 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/types.dart ('k') | pkg/compiler/lib/src/library_loader.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.world_builder;
6
7 import 'package:kernel/ast.dart' as ir;
8
9 import '../common.dart';
10 import '../common/resolution.dart';
11 import '../compile_time_constants.dart';
12 import '../constants/constant_system.dart';
13 import '../constants/constructors.dart';
14 import '../constants/evaluation.dart';
15 import '../constants/expressions.dart';
16 import '../constants/values.dart';
17 import '../common_elements.dart';
18 import '../elements/elements.dart';
19 import '../elements/entities.dart';
20 import '../elements/types.dart';
21 import '../js_backend/constant_system_javascript.dart';
22 import '../js_backend/native_data.dart';
23 import '../js_backend/no_such_method_registry.dart';
24 import '../native/native.dart' as native;
25 import '../native/resolver.dart';
26 import '../ordered_typeset.dart';
27 import '../ssa/kernel_impact.dart';
28 import '../universe/call_structure.dart';
29 import '../universe/world_builder.dart';
30 import '../util/util.dart' show Link, LinkBuilder;
31 import 'element_adapter.dart';
32 import 'elements.dart';
33
34 part 'native_basic_data.dart';
35 part 'native_class_resolver.dart';
36 part 'no_such_method_resolver.dart';
37 part 'types.dart';
38
39 /// World builder used for creating elements and types corresponding to Kernel
40 /// IR nodes.
41 // TODO(johnniwinther): Implement [ResolutionWorldBuilder].
42 class KernelWorldBuilder extends KernelElementAdapterMixin {
43 CommonElements _commonElements;
44 native.BehaviorBuilder _nativeBehaviorBuilder;
45 final DiagnosticReporter reporter;
46 ElementEnvironment _elementEnvironment;
47 DartTypeConverter _typeConverter;
48 KernelConstantEnvironment _constantEnvironment;
49 _KernelDartTypes _types;
50
51 /// Library environment. Used for fast lookup.
52 KEnv _env;
53
54 /// List of library environments by `KLibrary.libraryIndex`. This is used for
55 /// fast lookup into library classes and members.
56 List<KLibraryEnv> _libraryEnvs = <KLibraryEnv>[];
57
58 /// List of class environments by `KClass.classIndex`. This is used for
59 /// fast lookup into class members.
60 List<KClassEnv> _classEnvs = <KClassEnv>[];
61
62 Map<ir.Library, KLibrary> _libraryMap = <ir.Library, KLibrary>{};
63 Map<ir.Class, KClass> _classMap = <ir.Class, KClass>{};
64 Map<ir.TypeParameter, KTypeVariable> _typeVariableMap =
65 <ir.TypeParameter, KTypeVariable>{};
66
67 // TODO(johnniwinther): Change this to a list of 'KMemberData' class if we
68 // need more data for members.
69 List<ir.Member> _memberList = <ir.Member>[];
70
71 Map<ir.Member, KConstructor> _constructorMap = <ir.Member, KConstructor>{};
72 Map<KConstructor, ConstantConstructor> _constructorConstantMap =
73 <KConstructor, ConstantConstructor>{};
74
75 Map<ir.Procedure, KFunction> _methodMap = <ir.Procedure, KFunction>{};
76
77 Map<ir.Field, KField> _fieldMap = <ir.Field, KField>{};
78 Map<KField, ConstantExpression> _fieldConstantMap =
79 <KField, ConstantExpression>{};
80
81 Map<ir.TreeNode, KLocalFunction> _localFunctionMap =
82 <ir.TreeNode, KLocalFunction>{};
83
84 KernelWorldBuilder(this.reporter, ir.Program program)
85 : _env = new KEnv(program) {
86 _elementEnvironment = new KernelElementEnvironment(this);
87 _commonElements = new CommonElements(_elementEnvironment);
88 _constantEnvironment = new KernelConstantEnvironment(this);
89 _nativeBehaviorBuilder =
90 new KernelBehaviorBuilder(_commonElements, _constantEnvironment);
91 _types = new _KernelDartTypes(this);
92 _typeConverter = new DartTypeConverter(this);
93 }
94
95 KMethod get _mainFunction {
96 return _env.program.mainMethod != null
97 ? _getMethod(_env.program.mainMethod)
98 : null;
99 }
100
101 KLibrary get _mainLibrary {
102 return _env.program.mainMethod != null
103 ? _getLibrary(_env.program.mainMethod.enclosingLibrary)
104 : null;
105 }
106
107 Iterable<LibraryEntity> get _libraries {
108 if (_env.length != _libraryMap.length) {
109 // Create a [KLibrary] for each library.
110 _env.forEachLibrary((KLibraryEnv env) {
111 _getLibrary(env.library, env);
112 });
113 }
114 return _libraryMap.values;
115 }
116
117 @override
118 CommonElements get commonElements => _commonElements;
119
120 @override
121 ElementEnvironment get elementEnvironment => _elementEnvironment;
122
123 ConstantEnvironment get constantEnvironment => _constantEnvironment;
124
125 DartTypes get types => _types;
126
127 @override
128 native.BehaviorBuilder get nativeBehaviorBuilder => _nativeBehaviorBuilder;
129
130 LibraryEntity lookupLibrary(Uri uri) {
131 KLibraryEnv libraryEnv = _env.lookupLibrary(uri);
132 return _getLibrary(libraryEnv.library, libraryEnv);
133 }
134
135 KLibrary _getLibrary(ir.Library node, [KLibraryEnv libraryEnv]) {
136 return _libraryMap.putIfAbsent(node, () {
137 Uri canonicalUri = node.importUri;
138 _libraryEnvs.add(libraryEnv ?? _env.lookupLibrary(canonicalUri));
139 String name = node.name;
140 if (name == null) {
141 // Use the file name as script name.
142 String path = canonicalUri.path;
143 name = path.substring(path.lastIndexOf('/') + 1);
144 }
145 return new KLibrary(_libraryMap.length, name, canonicalUri);
146 });
147 }
148
149 MemberEntity lookupLibraryMember(KLibrary library, String name,
150 {bool setter: false}) {
151 KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
152 ir.Member member = libraryEnv.lookupMember(name, setter: setter);
153 return member != null ? getMember(member) : null;
154 }
155
156 ClassEntity lookupClass(KLibrary library, String name) {
157 KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
158 KClassEnv classEnv = libraryEnv.lookupClass(name);
159 if (classEnv != null) {
160 return _getClass(classEnv.cls, classEnv);
161 }
162 return null;
163 }
164
165 void _forEachClass(KLibrary library, void f(ClassEntity cls)) {
166 KLibraryEnv libraryEnv = _libraryEnvs[library.libraryIndex];
167 libraryEnv.forEachClass((KClassEnv classEnv) {
168 f(_getClass(classEnv.cls, classEnv));
169 });
170 }
171
172 MemberEntity lookupClassMember(KClass cls, String name,
173 {bool setter: false}) {
174 KClassEnv classEnv = _classEnvs[cls.classIndex];
175 ir.Member member = classEnv.lookupMember(name, setter: setter);
176 return member != null ? getMember(member) : null;
177 }
178
179 ConstructorEntity lookupConstructor(KClass cls, String name) {
180 KClassEnv classEnv = _classEnvs[cls.classIndex];
181 ir.Member member = classEnv.lookupConstructor(name);
182 return member != null ? getConstructor(member) : null;
183 }
184
185 KClass _getClass(ir.Class node, [KClassEnv classEnv]) {
186 return _classMap.putIfAbsent(node, () {
187 KLibrary library = _getLibrary(node.enclosingLibrary);
188 if (classEnv == null) {
189 classEnv = _libraryEnvs[library.libraryIndex].lookupClass(node.name);
190 }
191 _classEnvs.add(classEnv);
192 return new KClass(library, _classMap.length, node.name,
193 isAbstract: node.isAbstract);
194 });
195 }
196
197 Iterable<ConstantExpression> _getClassMetadata(KClass cls) {
198 return _classEnvs[cls.classIndex].getMetadata(this);
199 }
200
201 KTypeVariable _getTypeVariable(ir.TypeParameter node) {
202 return _typeVariableMap.putIfAbsent(node, () {
203 if (node.parent is ir.Class) {
204 ir.Class cls = node.parent;
205 int index = cls.typeParameters.indexOf(node);
206 return new KTypeVariable(_getClass(cls), node.name, index);
207 }
208 if (node.parent is ir.FunctionNode) {
209 ir.FunctionNode func = node.parent;
210 int index = func.typeParameters.indexOf(node);
211 if (func.parent is ir.Constructor) {
212 ir.Constructor constructor = func.parent;
213 ir.Class cls = constructor.enclosingClass;
214 return _getTypeVariable(cls.typeParameters[index]);
215 }
216 if (func.parent is ir.Procedure) {
217 ir.Procedure procedure = func.parent;
218 if (procedure.kind == ir.ProcedureKind.Factory) {
219 ir.Class cls = procedure.enclosingClass;
220 return _getTypeVariable(cls.typeParameters[index]);
221 } else {
222 return new KTypeVariable(_getMethod(procedure), node.name, index);
223 }
224 }
225 }
226 throw new UnsupportedError('Unsupported type parameter type node $node.');
227 });
228 }
229
230 ParameterStructure _getParameterStructure(ir.FunctionNode node) {
231 // TODO(johnniwinther): Cache the computed function type.
232 int requiredParameters = node.requiredParameterCount;
233 int positionalParameters = node.positionalParameters.length;
234 List<String> namedParameters =
235 node.namedParameters.map((p) => p.name).toList()..sort();
236 return new ParameterStructure(
237 requiredParameters, positionalParameters, namedParameters);
238 }
239
240 KConstructor _getConstructor(ir.Member node) {
241 return _constructorMap.putIfAbsent(node, () {
242 int memberIndex = _memberList.length;
243 KConstructor constructor;
244 KClass enclosingClass = _getClass(node.enclosingClass);
245 Name name = getName(node.name);
246 bool isExternal = node.isExternal;
247
248 if (node is ir.Constructor) {
249 constructor = new KGenerativeConstructor(memberIndex, enclosingClass,
250 name, _getParameterStructure(node.function),
251 isExternal: isExternal, isConst: node.isConst);
252 } else if (node is ir.Procedure) {
253 constructor = new KFactoryConstructor(memberIndex, enclosingClass, name,
254 _getParameterStructure(node.function),
255 isExternal: isExternal, isConst: node.isConst);
256 } else {
257 // TODO(johnniwinther): Convert `node.location` to a [SourceSpan].
258 throw new SpannableAssertionFailure(
259 NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}.");
260 }
261 _memberList.add(node);
262 return constructor;
263 });
264 }
265
266 KFunction _getMethod(ir.Procedure node) {
267 return _methodMap.putIfAbsent(node, () {
268 int memberIndex = _memberList.length;
269 KLibrary library;
270 KClass enclosingClass;
271 if (node.enclosingClass != null) {
272 enclosingClass = _getClass(node.enclosingClass);
273 library = enclosingClass.library;
274 } else {
275 library = _getLibrary(node.enclosingLibrary);
276 }
277 Name name = getName(node.name);
278 bool isStatic = node.isStatic;
279 bool isExternal = node.isExternal;
280 bool isAbstract = node.isAbstract;
281 KFunction function;
282 switch (node.kind) {
283 case ir.ProcedureKind.Factory:
284 throw new UnsupportedError("Cannot create method from factory.");
285 case ir.ProcedureKind.Getter:
286 function = new KGetter(memberIndex, library, enclosingClass, name,
287 isStatic: isStatic,
288 isExternal: isExternal,
289 isAbstract: isAbstract);
290 break;
291 case ir.ProcedureKind.Method:
292 case ir.ProcedureKind.Operator:
293 function = new KMethod(memberIndex, library, enclosingClass, name,
294 _getParameterStructure(node.function),
295 isStatic: isStatic,
296 isExternal: isExternal,
297 isAbstract: isAbstract);
298 break;
299 case ir.ProcedureKind.Setter:
300 function = new KSetter(
301 memberIndex, library, enclosingClass, getName(node.name).setter,
302 isStatic: isStatic,
303 isExternal: isExternal,
304 isAbstract: isAbstract);
305 break;
306 }
307 _memberList.add(node);
308 return function;
309 });
310 }
311
312 KField _getField(ir.Field node) {
313 return _fieldMap.putIfAbsent(node, () {
314 int memberIndex = _memberList.length;
315 KLibrary library;
316 KClass enclosingClass;
317 if (node.enclosingClass != null) {
318 enclosingClass = _getClass(node.enclosingClass);
319 library = enclosingClass.library;
320 } else {
321 library = _getLibrary(node.enclosingLibrary);
322 }
323 Name name = getName(node.name);
324 bool isStatic = node.isStatic;
325 _memberList.add(node);
326 return new KField(memberIndex, library, enclosingClass, name,
327 isStatic: isStatic,
328 isAssignable: node.isMutable,
329 isConst: node.isConst);
330 });
331 }
332
333 KLocalFunction _getLocal(ir.TreeNode node) {
334 return _localFunctionMap.putIfAbsent(node, () {
335 MemberEntity memberContext;
336 Entity executableContext;
337 ir.TreeNode parent = node.parent;
338 while (parent != null) {
339 if (parent is ir.Member) {
340 executableContext = memberContext = getMember(parent);
341 break;
342 }
343 if (parent is ir.FunctionDeclaration ||
344 parent is ir.FunctionExpression) {
345 KLocalFunction localFunction = _getLocal(parent);
346 executableContext = localFunction;
347 memberContext = localFunction.memberContext;
348 break;
349 }
350 parent = parent.parent;
351 }
352 String name;
353 FunctionType functionType;
354 if (node is ir.FunctionDeclaration) {
355 name = node.variable.name;
356 functionType = getFunctionType(node.function);
357 } else if (node is ir.FunctionExpression) {
358 functionType = getFunctionType(node.function);
359 }
360 return new KLocalFunction(
361 name, memberContext, executableContext, functionType);
362 });
363 }
364
365 @override
366 DartType getDartType(ir.DartType type) => _typeConverter.convert(type);
367
368 @override
369 InterfaceType createInterfaceType(
370 ir.Class cls, List<ir.DartType> typeArguments) {
371 return new InterfaceType(getClass(cls), getDartTypes(typeArguments));
372 }
373
374 @override
375 InterfaceType getInterfaceType(ir.InterfaceType type) =>
376 _typeConverter.convert(type);
377
378 @override
379 List<DartType> getDartTypes(List<ir.DartType> types) {
380 // TODO(johnniwinther): Add the type argument to the list literal when we
381 // no longer use resolution types.
382 List<DartType> list = /*<DartType>*/ [];
383 types.forEach((ir.DartType type) {
384 list.add(getDartType(type));
385 });
386 return list;
387 }
388
389 void _ensureThisAndRawType(KClass cls, KClassEnv env) {
390 if (env.thisType == null) {
391 ir.Class node = env.cls;
392 // TODO(johnniwinther): Add the type argument to the list literal when we
393 // no longer use resolution types.
394 if (node.typeParameters.isEmpty) {
395 env.thisType =
396 env.rawType = new InterfaceType(cls, const/*<DartType>*/ []);
397 } else {
398 env.thisType = new InterfaceType(
399 cls,
400 new List/*<DartType>*/ .generate(node.typeParameters.length,
401 (int index) {
402 return new TypeVariableType(
403 _getTypeVariable(node.typeParameters[index]));
404 }));
405 env.rawType = new InterfaceType(
406 cls,
407 new List/*<DartType>*/ .filled(
408 node.typeParameters.length, const DynamicType()));
409 }
410 }
411 }
412
413 InterfaceType _getThisType(KClass cls) {
414 KClassEnv env = _classEnvs[cls.classIndex];
415 _ensureThisAndRawType(cls, env);
416 return env.thisType;
417 }
418
419 InterfaceType _getRawType(KClass cls) {
420 KClassEnv env = _classEnvs[cls.classIndex];
421 _ensureThisAndRawType(cls, env);
422 return env.rawType;
423 }
424
425 void _ensureSupertypes(KClass cls, KClassEnv env) {
426 if (env.orderedTypeSet == null) {
427 _ensureThisAndRawType(cls, env);
428
429 ir.Class node = env.cls;
430
431 if (node.supertype == null) {
432 env.orderedTypeSet = new OrderedTypeSet.singleton(env.thisType);
433 } else {
434 InterfaceType processSupertype(ir.Supertype node) {
435 InterfaceType type = _typeConverter.visitSupertype(node);
436 KClass superclass = type.element;
437 KClassEnv env = _classEnvs[superclass.classIndex];
438 _ensureSupertypes(superclass, env);
439 return type;
440 }
441
442 env.supertype = processSupertype(node.supertype);
443 LinkBuilder<InterfaceType> linkBuilder =
444 new LinkBuilder<InterfaceType>();
445 if (node.mixedInType != null) {
446 linkBuilder.addLast(processSupertype(node.mixedInType));
447 }
448 node.implementedTypes.forEach((ir.Supertype supertype) {
449 linkBuilder.addLast(processSupertype(supertype));
450 });
451 Link<InterfaceType> interfaces = linkBuilder.toLink();
452 OrderedTypeSetBuilder setBuilder =
453 new _KernelOrderedTypeSetBuilder(this, cls);
454 env.orderedTypeSet =
455 setBuilder.createOrderedTypeSet(env.supertype, interfaces);
456 }
457 }
458 }
459
460 OrderedTypeSet _getOrderedTypeSet(KClass cls) {
461 KClassEnv env = _classEnvs[cls.classIndex];
462 _ensureSupertypes(cls, env);
463 return env.orderedTypeSet;
464 }
465
466 int _getHierarchyDepth(KClass cls) {
467 KClassEnv env = _classEnvs[cls.classIndex];
468 _ensureSupertypes(cls, env);
469 return env.orderedTypeSet.maxDepth;
470 }
471
472 InterfaceType _substByContext(InterfaceType type, InterfaceType context) {
473 return type.subst(
474 context.typeArguments, _getThisType(context.element).typeArguments);
475 }
476
477 InterfaceType _getSuperType(KClass cls) {
478 KClassEnv env = _classEnvs[cls.classIndex];
479 _ensureSupertypes(cls, env);
480 return env.supertype;
481 }
482
483 void _forEachSupertype(KClass cls, void f(InterfaceType supertype)) {
484 KClassEnv env = _classEnvs[cls.classIndex];
485 _ensureSupertypes(cls, env);
486 env.orderedTypeSet.supertypes.forEach(f);
487 }
488
489 void _forEachClassMember(
490 KClass cls, void f(ClassEntity cls, MemberEntity member)) {
491 KClassEnv env = _classEnvs[cls.classIndex];
492 env.forEachMember((ir.Member member) {
493 f(cls, getMember(member));
494 });
495 _ensureSupertypes(cls, env);
496 if (env.supertype != null) {
497 _forEachClassMember(env.supertype.element, f);
498 }
499 }
500
501 @override
502 FunctionType getFunctionType(ir.FunctionNode node) {
503 DartType returnType = getDartType(node.returnType);
504 List<DartType> parameterTypes = /*<DartType>*/ [];
505 List<DartType> optionalParameterTypes = /*<DartType>*/ [];
506 for (ir.VariableDeclaration variable in node.positionalParameters) {
507 if (parameterTypes.length == node.requiredParameterCount) {
508 optionalParameterTypes.add(getDartType(variable.type));
509 } else {
510 parameterTypes.add(getDartType(variable.type));
511 }
512 }
513 List<String> namedParameters = <String>[];
514 List<DartType> namedParameterTypes = /*<DartType>*/ [];
515 List<ir.VariableDeclaration> sortedNamedParameters =
516 node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
517 for (ir.VariableDeclaration variable in sortedNamedParameters) {
518 namedParameters.add(variable.name);
519 namedParameterTypes.add(getDartType(variable.type));
520 }
521 return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
522 namedParameters, namedParameterTypes);
523 }
524
525 LibraryEntity getLibrary(ir.Library node) => _getLibrary(node);
526
527 ir.Library getKernelLibrary(KLibrary entity) =>
528 _libraryEnvs[entity.libraryIndex].library;
529
530 ir.Class getKernelClass(KClass entity) => _classEnvs[entity.classIndex].cls;
531
532 @override
533 Local getLocalFunction(ir.TreeNode node) => _getLocal(node);
534
535 @override
536 ClassEntity getClass(ir.Class node) => _getClass(node);
537
538 @override
539 FieldEntity getField(ir.Field node) => _getField(node);
540
541 TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
542 _getTypeVariable(node);
543
544 @override
545 FunctionEntity getMethod(ir.Procedure node) => _getMethod(node);
546
547 @override
548 MemberEntity getMember(ir.Member node) {
549 if (node is ir.Field) {
550 return _getField(node);
551 } else if (node is ir.Constructor) {
552 return _getConstructor(node);
553 } else if (node is ir.Procedure) {
554 if (node.kind == ir.ProcedureKind.Factory) {
555 return _getConstructor(node);
556 } else {
557 return _getMethod(node);
558 }
559 }
560 throw new UnsupportedError("Unexpected member: $node");
561 }
562
563 @override
564 FunctionEntity getConstructor(ir.Member node) => _getConstructor(node);
565
566 ConstantConstructor _getConstructorConstant(KConstructor constructor) {
567 return _constructorConstantMap.putIfAbsent(constructor, () {
568 ir.Member node = _memberList[constructor.memberIndex];
569 if (node is ir.Constructor && node.isConst) {
570 return new Constantifier(this).computeConstantConstructor(node);
571 }
572 throw new SpannableAssertionFailure(
573 constructor,
574 "Unexpected constructor $constructor in "
575 "KernelWorldBuilder._getConstructorConstant");
576 });
577 }
578
579 ConstantExpression _getFieldConstant(KField field) {
580 return _fieldConstantMap.putIfAbsent(field, () {
581 ir.Field node = _memberList[field.memberIndex];
582 if (node.isConst) {
583 return new Constantifier(this).visit(node.initializer);
584 }
585 throw new SpannableAssertionFailure(
586 field,
587 "Unexpected field $field in "
588 "KernelWorldBuilder._getConstructorConstant");
589 });
590 }
591
592 ResolutionImpact computeWorldImpact(KMember member) {
593 ir.Member node = _memberList[member.memberIndex];
594 return buildKernelImpact(node, this);
595 }
596 }
597
598 /// Environment for fast lookup of program libraries.
599 class KEnv {
600 final ir.Program program;
601
602 Map<Uri, KLibraryEnv> _libraryMap;
603
604 KEnv(this.program);
605
606 void _ensureLibraryMap() {
607 if (_libraryMap == null) {
608 _libraryMap = <Uri, KLibraryEnv>{};
609 for (ir.Library library in program.libraries) {
610 _libraryMap[library.importUri] = new KLibraryEnv(library);
611 }
612 }
613 }
614
615 /// Return the [KLibraryEnv] for the library with the canonical [uri].
616 KLibraryEnv lookupLibrary(Uri uri) {
617 _ensureLibraryMap();
618 return _libraryMap[uri];
619 }
620
621 /// Calls [f] for each library in this environment.
622 void forEachLibrary(void f(KLibraryEnv library)) {
623 _ensureLibraryMap();
624 _libraryMap.values.forEach(f);
625 }
626
627 /// Returns the number of libraries in this environment.
628 int get length {
629 _ensureLibraryMap();
630 return _libraryMap.length;
631 }
632 }
633
634 /// Environment for fast lookup of library classes and members.
635 // TODO(johnniwinther): Add member lookup.
636 class KLibraryEnv {
637 final ir.Library library;
638
639 Map<String, KClassEnv> _classMap;
640 Map<String, ir.Member> _memberMap;
641 Map<String, ir.Member> _setterMap;
642
643 KLibraryEnv(this.library);
644
645 void _ensureClassMap() {
646 if (_classMap == null) {
647 _classMap = <String, KClassEnv>{};
648 for (ir.Class cls in library.classes) {
649 _classMap[cls.name] = new KClassEnv(cls);
650 }
651 }
652 }
653
654 /// Return the [KClassEnv] for the class [name] in [library].
655 KClassEnv lookupClass(String name) {
656 _ensureClassMap();
657 return _classMap[name];
658 }
659
660 /// Calls [f] for each class in this library.
661 void forEachClass(void f(KClassEnv cls)) {
662 _ensureClassMap();
663 _classMap.values.forEach(f);
664 }
665
666 /// Return the [ir.Member] for the member [name] in [library].
667 ir.Member lookupMember(String name, {bool setter: false}) {
668 if (_memberMap == null) {
669 _memberMap = <String, ir.Member>{};
670 _setterMap = <String, ir.Member>{};
671 for (ir.Member member in library.members) {
672 if (member is ir.Procedure) {
673 if (member.kind == ir.ProcedureKind.Setter) {
674 _setterMap[member.name.name] = member;
675 } else {
676 _memberMap[member.name.name] = member;
677 }
678 } else if (member is ir.Field) {
679 _memberMap[member.name.name] = member;
680 if (member.isMutable) {
681 _setterMap[member.name.name] = member;
682 }
683 } else {
684 throw new SpannableAssertionFailure(
685 NO_LOCATION_SPANNABLE, "Unexpected library member node: $member");
686 }
687 }
688 }
689 return _memberMap[name];
690 }
691 }
692
693 /// Environment for fast lookup of class members.
694 // TODO(johnniwinther): Add member lookup.
695 class KClassEnv {
696 final ir.Class cls;
697
698 InterfaceType thisType;
699 InterfaceType rawType;
700 InterfaceType supertype;
701 OrderedTypeSet orderedTypeSet;
702
703 Map<String, ir.Member> _constructorMap;
704 Map<String, ir.Member> _memberMap;
705 Map<String, ir.Member> _setterMap;
706
707 Iterable<ConstantExpression> _metadata;
708
709 KClassEnv(this.cls);
710
711 void _ensureMaps() {
712 if (_memberMap == null) {
713 _memberMap = <String, ir.Member>{};
714 _setterMap = <String, ir.Member>{};
715 _constructorMap = <String, ir.Member>{};
716 for (ir.Member member in cls.members) {
717 if (member is ir.Constructor ||
718 member is ir.Procedure && member.kind == ir.ProcedureKind.Factory) {
719 _constructorMap[member.name.name] = member;
720 } else if (member is ir.Procedure) {
721 if (member.kind == ir.ProcedureKind.Setter) {
722 _setterMap[member.name.name] = member;
723 } else {
724 _memberMap[member.name.name] = member;
725 }
726 } else if (member is ir.Field) {
727 _memberMap[member.name.name] = member;
728 if (member.isMutable) {
729 _setterMap[member.name.name] = member;
730 }
731 _memberMap[member.name.name] = member;
732 } else {
733 throw new SpannableAssertionFailure(
734 NO_LOCATION_SPANNABLE, "Unexpected class member node: $member");
735 }
736 }
737 }
738 }
739
740 /// Return the [ir.Member] for the member [name] in [library].
741 ir.Member lookupMember(String name, {bool setter: false}) {
742 _ensureMaps();
743 return setter ? _setterMap[name] : _memberMap[name];
744 }
745
746 /// Return the [ir.Member] for the member [name] in [library].
747 ir.Member lookupConstructor(String name) {
748 _ensureMaps();
749 return _constructorMap[name];
750 }
751
752 void forEachMember(f(ir.Member member)) {
753 _ensureMaps();
754 _memberMap.values.forEach(f);
755 }
756
757 Iterable<ConstantExpression> getMetadata(KernelWorldBuilder worldBuilder) {
758 if (_metadata == null) {
759 _metadata = worldBuilder.getMetadata(cls.annotations);
760 }
761 return _metadata;
762 }
763 }
764
765 class KernelElementEnvironment implements ElementEnvironment {
766 final KernelWorldBuilder worldBuilder;
767
768 KernelElementEnvironment(this.worldBuilder);
769
770 @override
771 DartType get dynamicType => const DynamicType();
772
773 @override
774 LibraryEntity get mainLibrary => worldBuilder._mainLibrary;
775
776 @override
777 FunctionEntity get mainFunction => worldBuilder._mainFunction;
778
779 @override
780 Iterable<LibraryEntity> get libraries => worldBuilder._libraries;
781
782 @override
783 InterfaceType getThisType(ClassEntity cls) {
784 return worldBuilder._getThisType(cls);
785 }
786
787 @override
788 InterfaceType getRawType(ClassEntity cls) {
789 return worldBuilder._getRawType(cls);
790 }
791
792 @override
793 DartType getTypeVariableBound(TypeVariableEntity typeVariable) {
794 throw new UnimplementedError(
795 'KernelElementEnvironment.getTypeVariableBound');
796 }
797
798 @override
799 InterfaceType createInterfaceType(
800 ClassEntity cls, List<DartType> typeArguments) {
801 return new InterfaceType(cls, typeArguments);
802 }
803
804 @override
805 bool isSubtype(DartType a, DartType b) {
806 return worldBuilder.types.isSubtype(a, b);
807 }
808
809 @override
810 FunctionType getFunctionType(KFunction function) {
811 throw new UnimplementedError('KernelElementEnvironment.getFunctionType');
812 }
813
814 @override
815 FunctionType getLocalFunctionType(KLocalFunction function) {
816 return function.functionType;
817 }
818
819 @override
820 DartType getUnaliasedType(DartType type) => type;
821
822 @override
823 ConstructorEntity lookupConstructor(ClassEntity cls, String name,
824 {bool required: false}) {
825 ConstructorEntity constructor = worldBuilder.lookupConstructor(cls, name);
826 if (constructor == null && required) {
827 throw new SpannableAssertionFailure(
828 CURRENT_ELEMENT_SPANNABLE,
829 "The constructor '$name' was not found in class '${cls.name}' "
830 "in library ${cls.library.canonicalUri}.");
831 }
832 return constructor;
833 }
834
835 @override
836 MemberEntity lookupClassMember(ClassEntity cls, String name,
837 {bool setter: false, bool required: false}) {
838 MemberEntity member =
839 worldBuilder.lookupClassMember(cls, name, setter: setter);
840 if (member == null && required) {
841 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
842 "The member '$name' was not found in ${cls.name}.");
843 }
844 return member;
845 }
846
847 @override
848 ClassEntity getSuperClass(ClassEntity cls) {
849 return worldBuilder._getSuperType(cls)?.element;
850 }
851
852 @override
853 void forEachSupertype(ClassEntity cls, void f(InterfaceType supertype)) {
854 worldBuilder._forEachSupertype(cls, f);
855 }
856
857 @override
858 void forEachMixin(ClassEntity cls, void f(ClassEntity mixin)) {
859 throw new UnimplementedError('KernelElementEnvironment.forEachMixin');
860 }
861
862 @override
863 void forEachClassMember(
864 ClassEntity cls, void f(ClassEntity declarer, MemberEntity member)) {
865 worldBuilder._forEachClassMember(cls, f);
866 }
867
868 @override
869 MemberEntity lookupLibraryMember(LibraryEntity library, String name,
870 {bool setter: false, bool required: false}) {
871 MemberEntity member =
872 worldBuilder.lookupLibraryMember(library, name, setter: setter);
873 if (member == null && required) {
874 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
875 "The member '${name}' was not found in library '${library.name}'.");
876 }
877 return member;
878 }
879
880 @override
881 ClassEntity lookupClass(LibraryEntity library, String name,
882 {bool required: false}) {
883 ClassEntity cls = worldBuilder.lookupClass(library, name);
884 if (cls == null && required) {
885 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
886 "The class '$name' was not found in library '${library.name}'.");
887 }
888 return cls;
889 }
890
891 @override
892 void forEachClass(KLibrary library, void f(ClassEntity cls)) {
893 worldBuilder._forEachClass(library, f);
894 }
895
896 @override
897 LibraryEntity lookupLibrary(Uri uri, {bool required: false}) {
898 LibraryEntity library = worldBuilder.lookupLibrary(uri);
899 if (library == null && required) {
900 throw new SpannableAssertionFailure(
901 CURRENT_ELEMENT_SPANNABLE, "The library '$uri' was not found.");
902 }
903 return library;
904 }
905
906 @override
907 CallStructure getCallStructure(KFunction function) {
908 ir.Member member = worldBuilder._memberList[function.memberIndex];
909 ir.FunctionNode functionNode;
910 if (member is ir.Procedure) {
911 functionNode = member.function;
912 } else if (member is ir.Constructor) {
913 functionNode = member.function;
914 } else {
915 throw new SpannableAssertionFailure(
916 function, "Unexpected function node ${member} for $function.");
917 }
918 return new CallStructure(
919 functionNode.positionalParameters.length +
920 functionNode.namedParameters.length,
921 functionNode.namedParameters.map((d) => d.name).toList());
922 }
923
924 @override
925 bool isDeferredLoadLibraryGetter(KMember member) {
926 // TODO(johnniwinther): Support these.
927 return false;
928 }
929 }
930
931 /// Visitor that converts kernel dart types into [DartType].
932 class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
933 final KernelWorldBuilder elementAdapter;
934 bool topLevel = true;
935
936 DartTypeConverter(this.elementAdapter);
937
938 DartType convert(ir.DartType type) {
939 topLevel = true;
940 return type.accept(this);
941 }
942
943 /// Visit a inner type.
944 DartType visitType(ir.DartType type) {
945 topLevel = false;
946 return type.accept(this);
947 }
948
949 InterfaceType visitSupertype(ir.Supertype node) {
950 ClassEntity cls = elementAdapter.getClass(node.classNode);
951 return new InterfaceType(cls, visitTypes(node.typeArguments));
952 }
953
954 List<DartType> visitTypes(List<ir.DartType> types) {
955 topLevel = false;
956 return new List.generate(
957 types.length, (int index) => types[index].accept(this));
958 }
959
960 @override
961 DartType visitTypeParameterType(ir.TypeParameterType node) {
962 return new TypeVariableType(elementAdapter.getTypeVariable(node.parameter));
963 }
964
965 @override
966 DartType visitFunctionType(ir.FunctionType node) {
967 return new FunctionType(
968 visitType(node.returnType),
969 visitTypes(node.positionalParameters
970 .take(node.requiredParameterCount)
971 .toList()),
972 visitTypes(node.positionalParameters
973 .skip(node.requiredParameterCount)
974 .toList()),
975 node.namedParameters.map((n) => n.name).toList(),
976 node.namedParameters.map((n) => visitType(n.type)).toList());
977 }
978
979 @override
980 DartType visitInterfaceType(ir.InterfaceType node) {
981 ClassEntity cls = elementAdapter.getClass(node.classNode);
982 return new InterfaceType(cls, visitTypes(node.typeArguments));
983 }
984
985 @override
986 DartType visitVoidType(ir.VoidType node) {
987 return const VoidType();
988 }
989
990 @override
991 DartType visitDynamicType(ir.DynamicType node) {
992 return const DynamicType();
993 }
994
995 @override
996 DartType visitInvalidType(ir.InvalidType node) {
997 if (topLevel) {
998 throw new UnimplementedError(
999 "Outermost invalid types not currently supported");
1000 }
1001 // Nested invalid types are treated as `dynamic`.
1002 return const DynamicType();
1003 }
1004 }
1005
1006 /// [native.BehaviorBuilder] for kernel based elements.
1007 class KernelBehaviorBuilder extends native.BehaviorBuilder {
1008 final CommonElements commonElements;
1009 final ConstantEnvironment constants;
1010
1011 KernelBehaviorBuilder(
1012 this.commonElements,
1013 this.constants,
1014 );
1015
1016 @override
1017 bool get trustJSInteropTypeAnnotations {
1018 throw new UnimplementedError(
1019 "KernelNativeBehaviorComputer.trustJSInteropTypeAnnotations");
1020 }
1021
1022 @override
1023 DiagnosticReporter get reporter {
1024 throw new UnimplementedError("KernelNativeBehaviorComputer.reporter");
1025 }
1026
1027 @override
1028 NativeData get nativeData {
1029 throw new UnimplementedError("KernelNativeBehaviorComputer.nativeData");
1030 }
1031 }
1032
1033 /// Constant environment mapping [ConstantExpression]s to [ConstantValue]s using
1034 /// [_EvaluationEnvironment] for the evaluation.
1035 class KernelConstantEnvironment implements ConstantEnvironment {
1036 KernelWorldBuilder _worldBuilder;
1037 Map<ConstantExpression, ConstantValue> _valueMap =
1038 <ConstantExpression, ConstantValue>{};
1039
1040 KernelConstantEnvironment(this._worldBuilder);
1041
1042 @override
1043 ConstantSystem get constantSystem => const JavaScriptConstantSystem();
1044
1045 @override
1046 ConstantValue getConstantValueForVariable(VariableElement element) {
1047 throw new UnimplementedError(
1048 "KernelConstantEnvironment.getConstantValueForVariable");
1049 }
1050
1051 @override
1052 ConstantValue getConstantValue(ConstantExpression expression) {
1053 return _valueMap.putIfAbsent(expression, () {
1054 return expression.evaluate(
1055 new _EvaluationEnvironment(_worldBuilder), constantSystem);
1056 });
1057 }
1058
1059 @override
1060 bool hasConstantValue(ConstantExpression expression) {
1061 throw new UnimplementedError("KernelConstantEnvironment.hasConstantValue");
1062 }
1063 }
1064
1065 /// Evaluation environment used for computing [ConstantValue]s for
1066 /// kernel based [ConstantExpression]s.
1067 class _EvaluationEnvironment implements Environment {
1068 final KernelWorldBuilder _worldBuilder;
1069
1070 _EvaluationEnvironment(this._worldBuilder);
1071
1072 @override
1073 CommonElements get commonElements {
1074 throw new UnimplementedError("_EvaluationEnvironment.commonElements");
1075 }
1076
1077 @override
1078 InterfaceType substByContext(InterfaceType base, InterfaceType target) {
1079 if (base.typeArguments.isNotEmpty) {
1080 throw new UnimplementedError("_EvaluationEnvironment.substByContext");
1081 }
1082 return base;
1083 }
1084
1085 @override
1086 ConstantConstructor getConstructorConstant(ConstructorEntity constructor) {
1087 return _worldBuilder._getConstructorConstant(constructor);
1088 }
1089
1090 @override
1091 ConstantExpression getFieldConstant(FieldEntity field) {
1092 return _worldBuilder._getFieldConstant(field);
1093 }
1094
1095 @override
1096 ConstantExpression getLocalConstant(Local local) {
1097 throw new UnimplementedError("_EvaluationEnvironment.getLocalConstant");
1098 }
1099
1100 @override
1101 String readFromEnvironment(String name) {
1102 throw new UnimplementedError("_EvaluationEnvironment.readFromEnvironment");
1103 }
1104 }
1105
1106 class KernelResolutionWorldBuilder extends KernelResolutionWorldBuilderBase {
1107 final KernelWorldBuilder worldBuilder;
1108
1109 KernelResolutionWorldBuilder(
1110 this.worldBuilder,
1111 NativeBasicData nativeBasicData,
1112 SelectorConstraintsStrategy selectorConstraintsStrategy)
1113 : super(worldBuilder.elementEnvironment, worldBuilder.commonElements,
1114 nativeBasicData, selectorConstraintsStrategy);
1115
1116 @override
1117 Iterable<InterfaceType> getSupertypes(ClassEntity cls) {
1118 return worldBuilder._getOrderedTypeSet(cls).supertypes;
1119 }
1120
1121 @override
1122 ClassEntity getSuperClass(ClassEntity cls) {
1123 return worldBuilder._getSuperType(cls)?.element;
1124 }
1125
1126 @override
1127 bool implementsFunction(ClassEntity cls) {
1128 // TODO(johnniwinther): Implement this.
1129 return false;
1130 }
1131
1132 @override
1133 int getHierarchyDepth(ClassEntity cls) {
1134 return worldBuilder._getHierarchyDepth(cls);
1135 }
1136
1137 @override
1138 ClassEntity getAppliedMixin(ClassEntity cls) {
1139 // TODO(johnniwinther): Implement this.
1140 return null;
1141 }
1142
1143 @override
1144 bool validateClass(ClassEntity cls) => true;
1145
1146 @override
1147 bool checkClass(ClassEntity cls) => true;
1148 }
1149
1150 // Interface for testing equivalence of Kernel-based entities.
1151 class WorldDeconstructionForTesting {
1152 final KernelWorldBuilder builder;
1153
1154 WorldDeconstructionForTesting(this.builder);
1155
1156 Uri getLibraryUri(KLibrary library) {
1157 return builder._libraryEnvs[library.libraryIndex].library.importUri;
1158 }
1159
1160 KLibrary getLibraryForClass(KClass cls) {
1161 KClassEnv env = builder._classEnvs[cls.classIndex];
1162 return builder.getLibrary(env.cls.enclosingLibrary);
1163 }
1164
1165 KLibrary _getLibrary<E>(E member, Map<ir.Member, E> map) {
1166 ir.Library library;
1167 map.forEach((ir.Member node, E other) {
1168 if (library == null && member == other) {
1169 library = node.enclosingLibrary;
1170 }
1171 });
1172 if (library == null) {
1173 throw new ArgumentError("No library found for $member");
1174 }
1175 return builder._getLibrary(library);
1176 }
1177
1178 KLibrary getLibraryForFunction(KFunction function) =>
1179 _getLibrary(function, builder._methodMap);
1180
1181 KLibrary getLibraryForField(KField field) =>
1182 _getLibrary(field, builder._fieldMap);
1183
1184 KClass getSuperclassForClass(KClass cls) {
1185 KClassEnv env = builder._classEnvs[cls.classIndex];
1186 ir.Supertype supertype = env.cls.supertype;
1187 if (supertype == null) return null;
1188 return builder.getClass(supertype.classNode);
1189 }
1190
1191 InterfaceType getMixinTypeForClass(KClass cls) {
1192 KClassEnv env = builder._classEnvs[cls.classIndex];
1193 ir.Supertype mixedInType = env.cls.mixedInType;
1194 if (mixedInType == null) return null;
1195 return builder.createInterfaceType(
1196 mixedInType.classNode, mixedInType.typeArguments);
1197 }
1198 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/types.dart ('k') | pkg/compiler/lib/src/library_loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698