| OLD | NEW |
| (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 } | |
| OLD | NEW |