| 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 js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/backend_api.dart' | 8 import '../common/backend_api.dart' |
| 9 show ForeignResolver, NativeRegistry, ImpactTransformer; | 9 show ForeignResolver, NativeRegistry, ImpactTransformer; |
| 10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // but may be inlined in a loop. | 102 // but may be inlined in a loop. |
| 103 static const int _mayInlineInLoopMustNotOutside = 1; | 103 static const int _mayInlineInLoopMustNotOutside = 1; |
| 104 // The function can be inlined in a loop, but not outside. | 104 // The function can be inlined in a loop, but not outside. |
| 105 static const int _canInlineInLoopMustNotOutside = 2; | 105 static const int _canInlineInLoopMustNotOutside = 2; |
| 106 // May-inline means that we know that it can be inlined inside a loop, but | 106 // May-inline means that we know that it can be inlined inside a loop, but |
| 107 // don't know about the general case yet. | 107 // don't know about the general case yet. |
| 108 static const int _canInlineInLoopMayInlineOutside = 3; | 108 static const int _canInlineInLoopMayInlineOutside = 3; |
| 109 static const int _canInline = 4; | 109 static const int _canInline = 4; |
| 110 static const int _mustInline = 5; | 110 static const int _mustInline = 5; |
| 111 | 111 |
| 112 final Map<MethodElement, int> _cachedDecisions = | 112 final Map<FunctionEntity, int> _cachedDecisions = |
| 113 new Map<MethodElement, int>(); | 113 new Map<FunctionEntity, int>(); |
| 114 | 114 |
| 115 /// Returns the current cache decision. This should only be used for testing. | 115 /// Returns the current cache decision. This should only be used for testing. |
| 116 int getCurrentCacheDecisionForTesting(Element element) { | 116 int getCurrentCacheDecisionForTesting(Element element) { |
| 117 return _cachedDecisions[element]; | 117 return _cachedDecisions[element]; |
| 118 } | 118 } |
| 119 | 119 |
| 120 // Returns `true`/`false` if we have a cached decision. | 120 // Returns `true`/`false` if we have a cached decision. |
| 121 // Returns `null` otherwise. | 121 // Returns `null` otherwise. |
| 122 bool canInline(MethodElement element, {bool insideLoop}) { | 122 bool canInline(FunctionEntity element, {bool insideLoop}) { |
| 123 int decision = _cachedDecisions[element]; | 123 int decision = _cachedDecisions[element]; |
| 124 | 124 |
| 125 if (decision == null) { | 125 if (decision == null) { |
| 126 // These synthetic elements are not yet present when we initially compute | 126 // These synthetic elements are not yet present when we initially compute |
| 127 // this cache from metadata annotations, so look for their parent. | 127 // this cache from metadata annotations, so look for their parent. |
| 128 if (element is ConstructorBodyElement) { | 128 if (element is ConstructorBodyElement) { |
| 129 ConstructorBodyElement body = element; | 129 ConstructorBodyElement body = element; |
| 130 decision = _cachedDecisions[body.constructor]; | 130 decision = _cachedDecisions[body.constructor]; |
| 131 } | 131 } |
| 132 if (decision == null) { | 132 if (decision == null) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 case _canInline: | 167 case _canInline: |
| 168 case _mustInline: | 168 case _mustInline: |
| 169 return true; | 169 return true; |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 // Quiet static checker. | 173 // Quiet static checker. |
| 174 return null; | 174 return null; |
| 175 } | 175 } |
| 176 | 176 |
| 177 void markAsInlinable(MethodElement element, {bool insideLoop}) { | 177 void markAsInlinable(FunctionEntity element, {bool insideLoop}) { |
| 178 int oldDecision = _cachedDecisions[element]; | 178 int oldDecision = _cachedDecisions[element]; |
| 179 | 179 |
| 180 if (oldDecision == null) { | 180 if (oldDecision == null) { |
| 181 oldDecision = _unknown; | 181 oldDecision = _unknown; |
| 182 } | 182 } |
| 183 | 183 |
| 184 if (insideLoop) { | 184 if (insideLoop) { |
| 185 switch (oldDecision) { | 185 switch (oldDecision) { |
| 186 case _mustNotInline: | 186 case _mustNotInline: |
| 187 throw new SpannableAssertionFailure( | 187 throw new SpannableAssertionFailure( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 break; | 222 break; |
| 223 | 223 |
| 224 case _canInline: | 224 case _canInline: |
| 225 case _mustInline: | 225 case _mustInline: |
| 226 // Do nothing. | 226 // Do nothing. |
| 227 break; | 227 break; |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 | 231 |
| 232 void markAsNonInlinable(MethodElement element, {bool insideLoop: true}) { | 232 void markAsNonInlinable(FunctionEntity element, {bool insideLoop: true}) { |
| 233 int oldDecision = _cachedDecisions[element]; | 233 int oldDecision = _cachedDecisions[element]; |
| 234 | 234 |
| 235 if (oldDecision == null) { | 235 if (oldDecision == null) { |
| 236 oldDecision = _unknown; | 236 oldDecision = _unknown; |
| 237 } | 237 } |
| 238 | 238 |
| 239 if (insideLoop) { | 239 if (insideLoop) { |
| 240 switch (oldDecision) { | 240 switch (oldDecision) { |
| 241 case _canInlineInLoopMustNotOutside: | 241 case _canInlineInLoopMustNotOutside: |
| 242 case _canInlineInLoopMayInlineOutside: | 242 case _canInlineInLoopMayInlineOutside: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 | 280 |
| 281 case _mayInlineInLoopMustNotOutside: | 281 case _mayInlineInLoopMustNotOutside: |
| 282 case _canInlineInLoopMustNotOutside: | 282 case _canInlineInLoopMustNotOutside: |
| 283 case _mustNotInline: | 283 case _mustNotInline: |
| 284 // Do nothing. | 284 // Do nothing. |
| 285 break; | 285 break; |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 | 289 |
| 290 void markAsMustInline(MethodElement element) { | 290 void markAsMustInline(FunctionEntity element) { |
| 291 _cachedDecisions[element] = _mustInline; | 291 _cachedDecisions[element] = _mustInline; |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 | 294 |
| 295 enum SyntheticConstantKind { | 295 enum SyntheticConstantKind { |
| 296 DUMMY_INTERCEPTOR, | 296 DUMMY_INTERCEPTOR, |
| 297 EMPTY_VALUE, | 297 EMPTY_VALUE, |
| 298 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. | 298 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. |
| 299 NAME | 299 NAME |
| 300 } | 300 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 | 343 |
| 344 Namer get namer { | 344 Namer get namer { |
| 345 assert(invariant(NO_LOCATION_SPANNABLE, _namer != null, | 345 assert(invariant(NO_LOCATION_SPANNABLE, _namer != null, |
| 346 message: "Namer has not been created yet.")); | 346 message: "Namer has not been created yet.")); |
| 347 return _namer; | 347 return _namer; |
| 348 } | 348 } |
| 349 | 349 |
| 350 /** | 350 /** |
| 351 * Set of classes whose `operator ==` methods handle `null` themselves. | 351 * Set of classes whose `operator ==` methods handle `null` themselves. |
| 352 */ | 352 */ |
| 353 final Set<ClassElement> specialOperatorEqClasses = new Set<ClassElement>(); | 353 final Set<ClassEntity> specialOperatorEqClasses = new Set<ClassEntity>(); |
| 354 | 354 |
| 355 List<CompilerTask> get tasks { | 355 List<CompilerTask> get tasks { |
| 356 List<CompilerTask> result = functionCompiler.tasks; | 356 List<CompilerTask> result = functionCompiler.tasks; |
| 357 result.add(emitter); | 357 result.add(emitter); |
| 358 result.add(patchResolverTask); | 358 result.add(patchResolverTask); |
| 359 result.add(kernelTask); | 359 result.add(kernelTask); |
| 360 return result; | 360 return result; |
| 361 } | 361 } |
| 362 | 362 |
| 363 final RuntimeTypesNeedBuilder _rtiNeedBuilder; | 363 final RuntimeTypesNeedBuilder _rtiNeedBuilder; |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 if (class_.isSubclassOf(commonElements.jsArrayClass)) | 718 if (class_.isSubclassOf(commonElements.jsArrayClass)) |
| 719 return commonElements.jsArrayClass; | 719 return commonElements.jsArrayClass; |
| 720 return class_; | 720 return class_; |
| 721 } | 721 } |
| 722 | 722 |
| 723 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { | 723 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { |
| 724 return specialOperatorEqClasses.contains(operatorEqfunction.enclosingClass); | 724 return specialOperatorEqClasses.contains(operatorEqfunction.enclosingClass); |
| 725 } | 725 } |
| 726 | 726 |
| 727 void validateInterceptorImplementsAllObjectMethods( | 727 void validateInterceptorImplementsAllObjectMethods( |
| 728 ClassElement interceptorClass) { | 728 ClassEntity interceptorClass) { |
| 729 if (interceptorClass == null) return; | 729 if (interceptorClass == null) return; |
| 730 interceptorClass.ensureResolved(resolution); | 730 ClassEntity objectClass = commonElements.objectClass; |
| 731 ClassElement objectClass = commonElements.objectClass; | 731 compiler.elementEnvironment.forEachClassMember(objectClass, |
| 732 objectClass.forEachMember((_, Element member) { | 732 (_, MemberEntity member) { |
| 733 if (member.isGenerativeConstructor) return; | 733 if (member.isConstructor) return; |
| 734 Element interceptorMember = interceptorClass.lookupMember(member.name); | 734 MemberEntity interceptorMember = compiler.elementEnvironment |
| 735 .lookupClassMember(interceptorClass, member.name); |
| 735 // Interceptors must override all Object methods due to calling convention | 736 // Interceptors must override all Object methods due to calling convention |
| 736 // differences. | 737 // differences. |
| 737 assert(invariant(interceptorMember, | 738 assert(invariant(interceptorMember, |
| 738 interceptorMember.enclosingClass == interceptorClass, | 739 interceptorMember.enclosingClass == interceptorClass, |
| 739 message: | 740 message: |
| 740 "Member ${member.name} not overridden in ${interceptorClass}. " | 741 "Member ${member.name} not overridden in ${interceptorClass}. " |
| 741 "Found $interceptorMember from " | 742 "Found $interceptorMember from " |
| 742 "${interceptorMember.enclosingClass}.")); | 743 "${interceptorMember.enclosingClass}.")); |
| 743 }); | 744 }); |
| 744 } | 745 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 | 824 |
| 824 ResolutionEnqueuer createResolutionEnqueuer( | 825 ResolutionEnqueuer createResolutionEnqueuer( |
| 825 CompilerTask task, Compiler compiler) { | 826 CompilerTask task, Compiler compiler) { |
| 826 _nativeBasicData = | 827 _nativeBasicData = |
| 827 nativeBasicDataBuilder.close(compiler.elementEnvironment); | 828 nativeBasicDataBuilder.close(compiler.elementEnvironment); |
| 828 _nativeResolutionEnqueuer = new native.NativeResolutionEnqueuer( | 829 _nativeResolutionEnqueuer = new native.NativeResolutionEnqueuer( |
| 829 compiler.options, | 830 compiler.options, |
| 830 compiler.elementEnvironment, | 831 compiler.elementEnvironment, |
| 831 commonElements, | 832 commonElements, |
| 832 backendUsageBuilder, | 833 backendUsageBuilder, |
| 833 compiler.frontEndStrategy.createNativeClassResolver(nativeBasicData)); | 834 compiler.frontEndStrategy.createNativeClassFinder(nativeBasicData)); |
| 834 _nativeData = new NativeDataImpl(nativeBasicData); | 835 _nativeData = new NativeDataImpl(nativeBasicData); |
| 835 _customElementsResolutionAnalysis = compiler.frontEndStrategy | 836 _customElementsResolutionAnalysis = compiler.frontEndStrategy |
| 836 .createCustomElementsResolutionAnalysis( | 837 .createCustomElementsResolutionAnalysis( |
| 837 nativeBasicData, backendUsageBuilder); | 838 nativeBasicData, backendUsageBuilder); |
| 838 impactTransformer = new JavaScriptImpactTransformer( | 839 impactTransformer = new JavaScriptImpactTransformer( |
| 839 compiler.options, | 840 compiler.options, |
| 840 compiler.elementEnvironment, | 841 compiler.elementEnvironment, |
| 841 commonElements, | 842 commonElements, |
| 842 impacts, | 843 impacts, |
| 843 nativeBasicData, | 844 nativeBasicData, |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 /// Called when code generation has been completed. | 1163 /// Called when code generation has been completed. |
| 1163 void onCodegenEnd() { | 1164 void onCodegenEnd() { |
| 1164 sourceInformationStrategy.onComplete(); | 1165 sourceInformationStrategy.onComplete(); |
| 1165 tracer.close(); | 1166 tracer.close(); |
| 1166 } | 1167 } |
| 1167 | 1168 |
| 1168 // Does this element belong in the output | 1169 // Does this element belong in the output |
| 1169 bool shouldOutput(Element element) => true; | 1170 bool shouldOutput(Element element) => true; |
| 1170 | 1171 |
| 1171 /// Returns `true` if the `native` pseudo keyword is supported for [library]. | 1172 /// Returns `true` if the `native` pseudo keyword is supported for [library]. |
| 1172 bool canLibraryUseNative(LibraryElement library) { | 1173 bool canLibraryUseNative(LibraryEntity library) { |
| 1173 return native.maybeEnableNative(compiler, library); | 1174 return native.maybeEnableNative(compiler, library); |
| 1174 } | 1175 } |
| 1175 | 1176 |
| 1176 bool isTargetSpecificLibrary(LibraryElement library) { | 1177 bool isTargetSpecificLibrary(LibraryElement library) { |
| 1177 Uri canonicalUri = library.canonicalUri; | 1178 Uri canonicalUri = library.canonicalUri; |
| 1178 if (canonicalUri == Uris.dart__js_helper || | 1179 if (canonicalUri == Uris.dart__js_helper || |
| 1179 canonicalUri == Uris.dart__interceptors) { | 1180 canonicalUri == Uris.dart__interceptors) { |
| 1180 return true; | 1181 return true; |
| 1181 } | 1182 } |
| 1182 return false; | 1183 return false; |
| 1183 } | 1184 } |
| 1184 | 1185 |
| 1185 /// Process backend specific annotations. | 1186 /// Process backend specific annotations. |
| 1186 void processAnnotations( | 1187 void processAnnotations( |
| 1187 MemberElement element, ClosedWorldRefiner closedWorldRefiner) { | 1188 MemberElement element, ClosedWorldRefiner closedWorldRefiner) { |
| 1188 if (element.isMalformed) { | 1189 if (element.isMalformed) { |
| 1189 // Elements that are marked as malformed during parsing or resolution | 1190 // Elements that are marked as malformed during parsing or resolution |
| 1190 // might be registered here. These should just be ignored. | 1191 // might be registered here. These should just be ignored. |
| 1191 return; | 1192 return; |
| 1192 } | 1193 } |
| 1193 | 1194 |
| 1194 MemberElement implementation = element.implementation; | |
| 1195 if (element.isFunction || element.isConstructor) { | 1195 if (element.isFunction || element.isConstructor) { |
| 1196 if (annotations.noInline(implementation)) { | 1196 MethodElement method = element.implementation; |
| 1197 inlineCache.markAsNonInlinable(implementation); | 1197 if (annotations.noInline(method)) { |
| 1198 inlineCache.markAsNonInlinable(method); |
| 1198 } | 1199 } |
| 1199 } | 1200 } |
| 1201 if (element.isField) return; |
| 1202 MethodElement method = element; |
| 1200 | 1203 |
| 1201 LibraryElement library = element.library; | 1204 LibraryElement library = method.library; |
| 1202 if (!library.isPlatformLibrary && !canLibraryUseNative(library)) return; | 1205 if (!library.isPlatformLibrary && !canLibraryUseNative(library)) return; |
| 1203 bool hasNoInline = false; | 1206 bool hasNoInline = false; |
| 1204 bool hasForceInline = false; | 1207 bool hasForceInline = false; |
| 1205 bool hasNoThrows = false; | 1208 bool hasNoThrows = false; |
| 1206 bool hasNoSideEffects = false; | 1209 bool hasNoSideEffects = false; |
| 1207 for (MetadataAnnotation metadata in element.implementation.metadata) { | 1210 for (MetadataAnnotation metadata in method.implementation.metadata) { |
| 1208 metadata.ensureResolved(resolution); | 1211 metadata.ensureResolved(resolution); |
| 1209 ConstantValue constantValue = | 1212 ConstantValue constantValue = |
| 1210 compiler.constants.getConstantValue(metadata.constant); | 1213 compiler.constants.getConstantValue(metadata.constant); |
| 1211 if (!constantValue.isConstructedObject) continue; | 1214 if (!constantValue.isConstructedObject) continue; |
| 1212 ObjectConstantValue value = constantValue; | 1215 ObjectConstantValue value = constantValue; |
| 1213 ClassElement cls = value.type.element; | 1216 ClassElement cls = value.type.element; |
| 1214 if (cls == commonElements.forceInlineClass) { | 1217 if (cls == commonElements.forceInlineClass) { |
| 1215 hasForceInline = true; | 1218 hasForceInline = true; |
| 1216 if (VERBOSE_OPTIMIZER_HINTS) { | 1219 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1217 reporter.reportHintMessage( | 1220 reporter.reportHintMessage( |
| 1218 element, MessageKind.GENERIC, {'text': "Must inline"}); | 1221 method, MessageKind.GENERIC, {'text': "Must inline"}); |
| 1219 } | 1222 } |
| 1220 inlineCache.markAsMustInline(element); | 1223 inlineCache.markAsMustInline(method); |
| 1221 } else if (cls == commonElements.noInlineClass) { | 1224 } else if (cls == commonElements.noInlineClass) { |
| 1222 hasNoInline = true; | 1225 hasNoInline = true; |
| 1223 if (VERBOSE_OPTIMIZER_HINTS) { | 1226 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1224 reporter.reportHintMessage( | 1227 reporter.reportHintMessage( |
| 1225 element, MessageKind.GENERIC, {'text': "Cannot inline"}); | 1228 method, MessageKind.GENERIC, {'text': "Cannot inline"}); |
| 1226 } | 1229 } |
| 1227 inlineCache.markAsNonInlinable(element); | 1230 inlineCache.markAsNonInlinable(method); |
| 1228 } else if (cls == commonElements.noThrowsClass) { | 1231 } else if (cls == commonElements.noThrowsClass) { |
| 1229 hasNoThrows = true; | 1232 hasNoThrows = true; |
| 1230 if (!Elements.isStaticOrTopLevelFunction(element) && | 1233 if (!Elements.isStaticOrTopLevelFunction(method) && |
| 1231 !element.isFactoryConstructor) { | 1234 !method.isFactoryConstructor) { |
| 1232 reporter.internalError( | 1235 reporter.internalError( |
| 1233 element, | 1236 method, |
| 1234 "@NoThrows() is currently limited to top-level" | 1237 "@NoThrows() is currently limited to top-level" |
| 1235 " or static functions and factory constructors."); | 1238 " or static functions and factory constructors."); |
| 1236 } | 1239 } |
| 1237 if (VERBOSE_OPTIMIZER_HINTS) { | 1240 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1238 reporter.reportHintMessage( | 1241 reporter.reportHintMessage( |
| 1239 element, MessageKind.GENERIC, {'text': "Cannot throw"}); | 1242 method, MessageKind.GENERIC, {'text': "Cannot throw"}); |
| 1240 } | 1243 } |
| 1241 closedWorldRefiner.registerCannotThrow(element); | 1244 closedWorldRefiner.registerCannotThrow(method); |
| 1242 } else if (cls == commonElements.noSideEffectsClass) { | 1245 } else if (cls == commonElements.noSideEffectsClass) { |
| 1243 hasNoSideEffects = true; | 1246 hasNoSideEffects = true; |
| 1244 if (VERBOSE_OPTIMIZER_HINTS) { | 1247 if (VERBOSE_OPTIMIZER_HINTS) { |
| 1245 reporter.reportHintMessage( | 1248 reporter.reportHintMessage( |
| 1246 element, MessageKind.GENERIC, {'text': "Has no side effects"}); | 1249 method, MessageKind.GENERIC, {'text': "Has no side effects"}); |
| 1247 } | 1250 } |
| 1248 closedWorldRefiner.registerSideEffectsFree(element); | 1251 closedWorldRefiner.registerSideEffectsFree(method); |
| 1249 } | 1252 } |
| 1250 } | 1253 } |
| 1251 if (hasForceInline && hasNoInline) { | 1254 if (hasForceInline && hasNoInline) { |
| 1252 reporter.internalError( | 1255 reporter.internalError( |
| 1253 element, "@ForceInline() must not be used with @NoInline."); | 1256 method, "@ForceInline() must not be used with @NoInline."); |
| 1254 } | 1257 } |
| 1255 if (hasNoThrows && !hasNoInline) { | 1258 if (hasNoThrows && !hasNoInline) { |
| 1256 reporter.internalError( | 1259 reporter.internalError( |
| 1257 element, "@NoThrows() should always be combined with @NoInline."); | 1260 method, "@NoThrows() should always be combined with @NoInline."); |
| 1258 } | 1261 } |
| 1259 if (hasNoSideEffects && !hasNoInline) { | 1262 if (hasNoSideEffects && !hasNoInline) { |
| 1260 reporter.internalError(element, | 1263 reporter.internalError( |
| 1261 "@NoSideEffects() should always be combined with @NoInline."); | 1264 method, "@NoSideEffects() should always be combined with @NoInline."); |
| 1262 } | 1265 } |
| 1263 } | 1266 } |
| 1264 | 1267 |
| 1265 MethodElement helperForBadMain() => commonElements.badMain; | 1268 MethodElement helperForBadMain() => commonElements.badMain; |
| 1266 | 1269 |
| 1267 MethodElement helperForMissingMain() => commonElements.missingMain; | 1270 MethodElement helperForMissingMain() => commonElements.missingMain; |
| 1268 | 1271 |
| 1269 MethodElement helperForMainArity() => commonElements.mainHasTooManyParameters; | 1272 MethodElement helperForMainArity() => commonElements.mainHasTooManyParameters; |
| 1270 | 1273 |
| 1271 /// Enable deferred loading. Returns `true` if the backend supports deferred | 1274 /// Enable deferred loading. Returns `true` if the backend supports deferred |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 | 1451 |
| 1449 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { | 1452 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { |
| 1450 return !selector.isGetter; | 1453 return !selector.isGetter; |
| 1451 } | 1454 } |
| 1452 | 1455 |
| 1453 /// Returns `true` if [member] is called from a subclass via `super`. | 1456 /// Returns `true` if [member] is called from a subclass via `super`. |
| 1454 bool isAliasedSuperMember(MemberEntity member) { | 1457 bool isAliasedSuperMember(MemberEntity member) { |
| 1455 return _aliasedSuperMembers.contains(member); | 1458 return _aliasedSuperMembers.contains(member); |
| 1456 } | 1459 } |
| 1457 } | 1460 } |
| OLD | NEW |