Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.world; | 5 library dart2js.world; |
| 6 | 6 |
| 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; | 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show BackendClasses; | 8 import 'common/backend_api.dart' show BackendClasses; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'constants/constant_system.dart'; | 10 import 'constants/constant_system.dart'; |
| 11 import 'common_elements.dart' show CommonElements; | 11 import 'common_elements.dart' show CommonElements; |
| 12 import 'elements/entities.dart'; | 12 import 'elements/entities.dart'; |
| 13 import 'elements/elements.dart' | 13 import 'elements/elements.dart' |
| 14 show | 14 show |
| 15 ClassElement, | 15 ClassElement, |
| 16 Element, | 16 Element, |
| 17 FunctionElement, | |
| 18 MemberElement, | 17 MemberElement, |
| 19 MixinApplicationElement, | 18 MixinApplicationElement, |
| 20 TypedefElement; | 19 TypedefElement; |
| 21 import 'elements/resolution_types.dart'; | 20 import 'elements/resolution_types.dart'; |
| 22 import 'elements/types.dart'; | 21 import 'elements/types.dart'; |
| 23 import 'js_backend/backend.dart' show JavaScriptBackend; | 22 import 'js_backend/backend.dart' show JavaScriptBackend; |
| 24 import 'js_backend/interceptor_data.dart' show InterceptorData; | 23 import 'js_backend/interceptor_data.dart' show InterceptorData; |
| 25 import 'js_backend/native_data.dart' show NativeData; | 24 import 'js_backend/native_data.dart' show NativeData; |
| 26 import 'ordered_typeset.dart'; | 25 import 'ordered_typeset.dart'; |
| 27 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; | 26 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 /// Returns the single [Element] that matches a call to [selector] on a | 291 /// Returns the single [Element] that matches a call to [selector] on a |
| 293 /// receiver of type [mask]. If multiple targets exist, `null` is returned. | 292 /// receiver of type [mask]. If multiple targets exist, `null` is returned. |
| 294 MemberEntity locateSingleElement(Selector selector, TypeMask mask); | 293 MemberEntity locateSingleElement(Selector selector, TypeMask mask); |
| 295 | 294 |
| 296 /// Returns the single field that matches a call to [selector] on a | 295 /// Returns the single field that matches a call to [selector] on a |
| 297 /// receiver of type [mask]. If multiple targets exist or the single target | 296 /// receiver of type [mask]. If multiple targets exist or the single target |
| 298 /// is not a field, `null` is returned. | 297 /// is not a field, `null` is returned. |
| 299 FieldEntity locateSingleField(Selector selector, TypeMask mask); | 298 FieldEntity locateSingleField(Selector selector, TypeMask mask); |
| 300 | 299 |
| 301 /// Returns the side effects of executing [element]. | 300 /// Returns the side effects of executing [element]. |
| 302 SideEffects getSideEffectsOfElement(Element element); | 301 SideEffects getSideEffectsOfElement(Entity element); |
| 303 | 302 |
| 304 /// Returns the side effects of calling [selector] on a receiver of type | 303 /// Returns the side effects of calling [selector] on a receiver of type |
| 305 /// [mask]. | 304 /// [mask]. |
| 306 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask); | 305 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask); |
| 307 | 306 |
| 308 /// Returns `true` if [element] is guaranteed not to throw an exception. | 307 /// Returns `true` if [element] is guaranteed not to throw an exception. |
| 309 bool getCannotThrow(Element element); | 308 bool getCannotThrow(Entity element); |
| 310 | 309 |
| 311 /// Returns `true` if [element] is called in a loop. | 310 /// Returns `true` if [element] is called in a loop. |
| 312 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? | 311 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? |
| 313 bool isCalledInLoop(Element element); | 312 bool isCalledInLoop(Entity element); |
| 314 | 313 |
| 315 /// Returns `true` if [element] might be passed to `Function.apply`. | 314 /// Returns `true` if [element] might be passed to `Function.apply`. |
| 316 // TODO(johnniwinther): Is this 'passed invocation target` or | 315 // TODO(johnniwinther): Is this 'passed invocation target` or |
| 317 // `passed as argument`? | 316 // `passed as argument`? |
| 318 bool getMightBePassedToApply(Element element); | 317 bool getMightBePassedToApply(Entity element); |
| 319 | 318 |
| 320 /// Returns a string representation of the closed world. | 319 /// Returns a string representation of the closed world. |
| 321 /// | 320 /// |
| 322 /// If [cls] is provided, the dump will contain only classes related to [cls]. | 321 /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| 323 String dump([ClassEntity cls]); | 322 String dump([ClassEntity cls]); |
| 324 } | 323 } |
| 325 | 324 |
| 326 /// Interface for computing side effects and uses of elements. This is used | 325 /// Interface for computing side effects and uses of elements. This is used |
| 327 /// during type inference to compute the [ClosedWorld] for code generation. | 326 /// during type inference to compute the [ClosedWorld] for code generation. |
| 328 abstract class ClosedWorldRefiner { | 327 abstract class ClosedWorldRefiner { |
| 329 /// The closed world being refined. | 328 /// The closed world being refined. |
| 330 ClosedWorld get closedWorld; | 329 ClosedWorld get closedWorld; |
| 331 | 330 |
| 332 /// Registers the side [effects] of executing [element]. | 331 /// Registers the side [effects] of executing [element]. |
| 333 void registerSideEffects(Element element, SideEffects effects); | 332 void registerSideEffects(Entity element, SideEffects effects); |
| 334 | 333 |
| 335 /// Registers the executing of [element] as without side effects. | 334 /// Registers the executing of [element] as without side effects. |
| 336 void registerSideEffectsFree(Element element); | 335 void registerSideEffectsFree(Entity element); |
| 337 | 336 |
| 338 /// Returns the currently known side effects of executing [element]. | 337 /// Returns the currently known side effects of executing [element]. |
| 339 SideEffects getCurrentlyKnownSideEffects(Element element); | 338 SideEffects getCurrentlyKnownSideEffects(Entity element); |
| 340 | 339 |
| 341 /// Registers that [element] might be passed to `Function.apply`. | 340 /// Registers that [element] might be passed to `Function.apply`. |
| 342 // TODO(johnniwinther): Is this 'passed invocation target` or | 341 // TODO(johnniwinther): Is this 'passed invocation target` or |
| 343 // `passed as argument`? | 342 // `passed as argument`? |
| 344 void registerMightBePassedToApply(Element element); | 343 void registerMightBePassedToApply(Entity element); |
| 345 | 344 |
| 346 /// Returns `true` if [element] might be passed to `Function.apply` given the | 345 /// Returns `true` if [element] might be passed to `Function.apply` given the |
| 347 /// currently inferred information. | 346 /// currently inferred information. |
| 348 bool getCurrentlyKnownMightBePassedToApply(Element element); | 347 bool getCurrentlyKnownMightBePassedToApply(Entity element); |
| 349 | 348 |
| 350 /// Registers that [element] is called in a loop. | 349 /// Registers that [element] is called in a loop. |
| 351 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? | 350 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? |
| 352 void addFunctionCalledInLoop(Element element); | 351 void addFunctionCalledInLoop(Entity element); |
| 353 | 352 |
| 354 /// Registers that [element] is guaranteed not to throw an exception. | 353 /// Registers that [element] is guaranteed not to throw an exception. |
| 355 void registerCannotThrow(Element element); | 354 void registerCannotThrow(Entity element); |
| 356 | 355 |
| 357 /// Adds the closure class [cls] to the inference world. The class is | 356 /// Adds the closure class [cls] to the inference world. The class is |
| 358 /// considered directly instantiated. | 357 /// considered directly instantiated. |
| 359 void registerClosureClass(ClassElement cls); | 358 void registerClosureClass(ClassElement cls); |
| 360 } | 359 } |
| 361 | 360 |
| 362 abstract class OpenWorld implements World { | 361 abstract class OpenWorld implements World { |
| 363 /// Called to add [cls] to the set of known classes. | 362 /// Called to add [cls] to the set of known classes. |
| 364 /// | 363 /// |
| 365 /// This ensures that class hierarchy queries can be performed on [cls] and | 364 /// This ensures that class hierarchy queries can be performed on [cls] and |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; | 401 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; |
| 403 | 402 |
| 404 // We keep track of subtype and subclass relationships in four | 403 // We keep track of subtype and subclass relationships in four |
| 405 // distinct sets to make class hierarchy analysis faster. | 404 // distinct sets to make class hierarchy analysis faster. |
| 406 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes; | 405 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes; |
| 407 final Map<ClassEntity, ClassSet> _classSets; | 406 final Map<ClassEntity, ClassSet> _classSets; |
| 408 | 407 |
| 409 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache = | 408 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache = |
| 410 <ClassEntity, Map<ClassEntity, bool>>{}; | 409 <ClassEntity, Map<ClassEntity, bool>>{}; |
| 411 | 410 |
| 412 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 411 final Set<Entity> _functionsCalledInLoop = new Set<Entity>(); |
| 413 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 412 final Map<Entity, SideEffects> _sideEffects = new Map<Entity, SideEffects>(); |
| 414 | 413 |
| 415 final Set<Element> sideEffectsFreeElements = new Set<Element>(); | 414 final Set<Entity> _sideEffectsFreeElements = new Set<Entity>(); |
| 416 | 415 |
| 417 final Set<Element> elementsThatCannotThrow = new Set<Element>(); | 416 final Set<Entity> _elementsThatCannotThrow = new Set<Entity>(); |
| 418 | 417 |
| 419 final Set<Element> functionsThatMightBePassedToApply = | 418 final Set<Entity> _functionsThatMightBePassedToApply = new Set<Entity>(); |
| 420 new Set<FunctionElement>(); | |
| 421 | 419 |
| 422 CommonMasks _commonMasks; | 420 CommonMasks _commonMasks; |
| 423 | 421 |
| 424 final CommonElements commonElements; | 422 final CommonElements commonElements; |
| 425 | 423 |
| 426 final ResolutionWorldBuilder _resolverWorld; | 424 final ResolutionWorldBuilder _resolverWorld; |
| 427 | 425 |
| 428 ClosedWorldBase( | 426 ClosedWorldBase( |
| 429 {JavaScriptBackend backend, | 427 {JavaScriptBackend backend, |
| 430 this.commonElements, | 428 this.commonElements, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 463 } | 461 } |
| 464 | 462 |
| 465 ConstantSystem get constantSystem => _backend.constantSystem; | 463 ConstantSystem get constantSystem => _backend.constantSystem; |
| 466 | 464 |
| 467 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { | 465 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { |
| 468 Map<ClassEntity, TypeMask> cachedMasks = | 466 Map<ClassEntity, TypeMask> cachedMasks = |
| 469 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; | 467 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; |
| 470 return cachedMasks.putIfAbsent(base, createMask); | 468 return cachedMasks.putIfAbsent(base, createMask); |
| 471 } | 469 } |
| 472 | 470 |
| 471 bool _checkEntity(Entity element); | |
| 472 | |
| 473 bool _checkClass(ClassEntity cls); | 473 bool _checkClass(ClassEntity cls); |
| 474 | 474 |
| 475 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); | 475 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); |
| 476 | 476 |
| 477 @override | 477 @override |
| 478 bool isInstantiated(ClassEntity cls) { | 478 bool isInstantiated(ClassEntity cls) { |
| 479 assert(_checkClass(cls)); | 479 assert(_checkClass(cls)); |
| 480 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 480 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
| 481 return node != null && node.isInstantiated; | 481 return node != null && node.isInstantiated; |
| 482 } | 482 } |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 assert(selector.isCall); | 895 assert(selector.isCall); |
| 896 sideEffects.setAllSideEffects(); | 896 sideEffects.setAllSideEffects(); |
| 897 sideEffects.setDependsOnSomething(); | 897 sideEffects.setDependsOnSomething(); |
| 898 } | 898 } |
| 899 } else { | 899 } else { |
| 900 sideEffects.add(getSideEffectsOfElement(e)); | 900 sideEffects.add(getSideEffectsOfElement(e)); |
| 901 } | 901 } |
| 902 } | 902 } |
| 903 return sideEffects; | 903 return sideEffects; |
| 904 } | 904 } |
| 905 | |
| 906 SideEffects getSideEffectsOfElement(Entity element) { | |
|
Emily Fortuna
2017/04/12 18:07:18
getSideEffectsOfEntity?
Johnni Winther
2017/04/18 07:36:08
I'll stick with the name for now. I think needs to
| |
| 907 assert(_checkEntity(element)); | |
| 908 return _sideEffects.putIfAbsent(element, () { | |
| 909 return new SideEffects(); | |
| 910 }); | |
| 911 } | |
| 912 | |
| 913 @override | |
| 914 SideEffects getCurrentlyKnownSideEffects(Entity element) { | |
| 915 return getSideEffectsOfElement(element); | |
| 916 } | |
| 917 | |
| 918 void registerSideEffects(Entity element, SideEffects effects) { | |
| 919 assert(_checkEntity(element)); | |
| 920 if (_sideEffectsFreeElements.contains(element)) return; | |
| 921 _sideEffects[element] = effects; | |
| 922 } | |
| 923 | |
| 924 void registerSideEffectsFree(Entity element) { | |
| 925 assert(_checkEntity(element)); | |
| 926 _sideEffects[element] = new SideEffects.empty(); | |
| 927 _sideEffectsFreeElements.add(element); | |
| 928 } | |
| 929 | |
| 930 void addFunctionCalledInLoop(Entity element) { | |
| 931 assert(_checkEntity(element)); | |
| 932 _functionsCalledInLoop.add(element); | |
| 933 } | |
| 934 | |
| 935 bool isCalledInLoop(Entity element) { | |
| 936 assert(_checkEntity(element)); | |
| 937 return _functionsCalledInLoop.contains(element); | |
| 938 } | |
| 939 | |
| 940 void registerCannotThrow(Entity element) { | |
| 941 assert(_checkEntity(element)); | |
| 942 _elementsThatCannotThrow.add(element); | |
| 943 } | |
| 944 | |
| 945 bool getCannotThrow(Entity element) { | |
| 946 return _elementsThatCannotThrow.contains(element); | |
| 947 } | |
| 948 | |
| 949 void registerMightBePassedToApply(Entity element) { | |
| 950 _functionsThatMightBePassedToApply.add(element); | |
| 951 } | |
| 952 | |
| 953 bool getMightBePassedToApply(Entity element) { | |
| 954 // We have to check whether the element we look at was created after | |
| 955 // type inference ran. This is currently only the case for the call | |
| 956 // method of function classes that were generated for function | |
| 957 // expressions. In such a case, we have to look at the original | |
| 958 // function expressions's element. | |
| 959 // TODO(herhut): Generate classes for function expressions earlier. | |
| 960 if (element is SynthesizedCallMethodElementX) { | |
| 961 return getMightBePassedToApply(element.expression); | |
| 962 } | |
| 963 return _functionsThatMightBePassedToApply.contains(element); | |
| 964 } | |
| 965 | |
| 966 @override | |
| 967 bool getCurrentlyKnownMightBePassedToApply(Entity element) { | |
| 968 return getMightBePassedToApply(element); | |
| 969 } | |
| 905 } | 970 } |
| 906 | 971 |
| 907 class ClosedWorldImpl extends ClosedWorldBase { | 972 class ClosedWorldImpl extends ClosedWorldBase { |
| 908 ClosedWorldImpl( | 973 ClosedWorldImpl( |
| 909 {JavaScriptBackend backend, | 974 {JavaScriptBackend backend, |
| 910 CommonElements commonElements, | 975 CommonElements commonElements, |
| 911 ResolutionWorldBuilder resolutionWorldBuilder, | 976 ResolutionWorldBuilder resolutionWorldBuilder, |
| 912 FunctionSetBuilder functionSetBuilder, | 977 FunctionSetBuilder functionSetBuilder, |
| 913 Iterable<TypedefElement> allTypedefs, | 978 Iterable<TypedefElement> allTypedefs, |
| 914 Map<ClassEntity, Set<ClassEntity>> mixinUses, | 979 Map<ClassEntity, Set<ClassEntity>> mixinUses, |
| 915 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, | 980 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, |
| 916 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, | 981 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, |
| 917 Map<ClassEntity, ClassSet> classSets}) | 982 Map<ClassEntity, ClassSet> classSets}) |
| 918 : super( | 983 : super( |
| 919 backend: backend, | 984 backend: backend, |
| 920 commonElements: commonElements, | 985 commonElements: commonElements, |
| 921 resolutionWorldBuilder: resolutionWorldBuilder, | 986 resolutionWorldBuilder: resolutionWorldBuilder, |
| 922 functionSetBuilder: functionSetBuilder, | 987 functionSetBuilder: functionSetBuilder, |
| 923 allTypedefs: allTypedefs, | 988 allTypedefs: allTypedefs, |
| 924 mixinUses: mixinUses, | 989 mixinUses: mixinUses, |
| 925 typesImplementedBySubclasses: typesImplementedBySubclasses, | 990 typesImplementedBySubclasses: typesImplementedBySubclasses, |
| 926 classHierarchyNodes: classHierarchyNodes, | 991 classHierarchyNodes: classHierarchyNodes, |
| 927 classSets: classSets); | 992 classSets: classSets); |
| 928 | 993 |
| 929 bool _checkClass(ClassElement cls) => cls.isDeclaration; | 994 bool _checkClass(ClassElement cls) => cls.isDeclaration; |
| 995 bool _checkEntity(Element element) => element.isDeclaration; | |
| 930 | 996 |
| 931 bool _checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { | 997 bool _checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { |
| 932 return invariant(cls, cls.isDeclaration, | 998 return invariant(cls, cls.isDeclaration, |
| 933 message: '$cls must be the declaration.') && | 999 message: '$cls must be the declaration.') && |
| 934 invariant(cls, cls.isResolved, | 1000 invariant(cls, cls.isResolved, |
| 935 message: | 1001 message: |
| 936 '$cls must be resolved.') /* && | 1002 '$cls must be resolved.') /* && |
| 937 // TODO(johnniwinther): Reinsert this or similar invariant. Currently | 1003 // TODO(johnniwinther): Reinsert this or similar invariant. Currently |
| 938 // various call sites use uninstantiated classes for isSubtypeOf or | 1004 // various call sites use uninstantiated classes for isSubtypeOf or |
| 939 // isSubclassOf. Some are valid, some are not. Work out better invariants | 1005 // isSubclassOf. Some are valid, some are not. Work out better invariants |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1145 | 1211 |
| 1146 SideEffects getSideEffectsOfElement(Element element) { | 1212 SideEffects getSideEffectsOfElement(Element element) { |
| 1147 // The type inferrer (where the side effects are being computed), | 1213 // The type inferrer (where the side effects are being computed), |
| 1148 // does not see generative constructor bodies because they are | 1214 // does not see generative constructor bodies because they are |
| 1149 // created by the backend. Also, it does not make any distinction | 1215 // created by the backend. Also, it does not make any distinction |
| 1150 // between a constructor and its body for side effects. This | 1216 // between a constructor and its body for side effects. This |
| 1151 // implies that currently, the side effects of a constructor body | 1217 // implies that currently, the side effects of a constructor body |
| 1152 // contain the side effects of the initializers. | 1218 // contain the side effects of the initializers. |
| 1153 assert(!element.isGenerativeConstructorBody); | 1219 assert(!element.isGenerativeConstructorBody); |
| 1154 assert(!element.isField); | 1220 assert(!element.isField); |
| 1155 return sideEffects.putIfAbsent(element.declaration, () { | 1221 return super.getSideEffectsOfElement(element); |
| 1156 return new SideEffects(); | |
| 1157 }); | |
| 1158 } | |
| 1159 | |
| 1160 @override | |
| 1161 SideEffects getCurrentlyKnownSideEffects(Element element) { | |
| 1162 return getSideEffectsOfElement(element); | |
| 1163 } | |
| 1164 | |
| 1165 void registerSideEffects(Element element, SideEffects effects) { | |
| 1166 if (sideEffectsFreeElements.contains(element)) return; | |
| 1167 sideEffects[element.declaration] = effects; | |
| 1168 } | |
| 1169 | |
| 1170 void registerSideEffectsFree(Element element) { | |
| 1171 sideEffects[element.declaration] = new SideEffects.empty(); | |
| 1172 sideEffectsFreeElements.add(element); | |
| 1173 } | |
| 1174 | |
| 1175 void addFunctionCalledInLoop(Element element) { | |
| 1176 functionsCalledInLoop.add(element.declaration); | |
| 1177 } | |
| 1178 | |
| 1179 bool isCalledInLoop(Element element) { | |
| 1180 return functionsCalledInLoop.contains(element.declaration); | |
| 1181 } | |
| 1182 | |
| 1183 void registerCannotThrow(Element element) { | |
| 1184 elementsThatCannotThrow.add(element); | |
| 1185 } | |
| 1186 | |
| 1187 bool getCannotThrow(Element element) { | |
| 1188 return elementsThatCannotThrow.contains(element); | |
| 1189 } | |
| 1190 | |
| 1191 void registerMightBePassedToApply(Element element) { | |
| 1192 functionsThatMightBePassedToApply.add(element); | |
| 1193 } | |
| 1194 | |
| 1195 bool getMightBePassedToApply(Element element) { | |
| 1196 // We have to check whether the element we look at was created after | |
| 1197 // type inference ran. This is currently only the case for the call | |
| 1198 // method of function classes that were generated for function | |
| 1199 // expressions. In such a case, we have to look at the original | |
| 1200 // function expressions's element. | |
| 1201 // TODO(herhut): Generate classes for function expressions earlier. | |
| 1202 if (element is SynthesizedCallMethodElementX) { | |
| 1203 return getMightBePassedToApply(element.expression); | |
| 1204 } | |
| 1205 return functionsThatMightBePassedToApply.contains(element); | |
| 1206 } | |
| 1207 | |
| 1208 @override | |
| 1209 bool getCurrentlyKnownMightBePassedToApply(Element element) { | |
| 1210 return getMightBePassedToApply(element); | |
| 1211 } | 1222 } |
| 1212 } | 1223 } |
| OLD | NEW |