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

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

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

Powered by Google App Engine
This is Rietveld 408576698