Cleanup: apply "cascade if..." inspection (+ some others)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
9c06739594
commit
1d2017b0fc
@@ -292,14 +292,10 @@ fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingConte
|
||||
val dataFlow = DataFlowValueFactory.createDataFlowValue(expression!!, ktType, bindingContext, descriptor)
|
||||
val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow)
|
||||
return stableTypes.firstNotNullResult {
|
||||
if (KotlinBuiltIns.isDoubleOrNullableDouble(it)) {
|
||||
TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it))
|
||||
}
|
||||
else if (KotlinBuiltIns.isFloatOrNullableFloat(it)) {
|
||||
TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
|
||||
}
|
||||
else {
|
||||
null
|
||||
when {
|
||||
KotlinBuiltIns.isDoubleOrNullableDouble(it) -> TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it))
|
||||
KotlinBuiltIns.isFloatOrNullableFloat(it) -> TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,18 +83,16 @@ private fun ExpressionCodegen.createOptimizedForLoopGeneratorOrNull(
|
||||
private fun getLoopRangeResolvedCall(forExpression: KtForExpression, bindingContext: BindingContext): ResolvedCall<out CallableDescriptor>? {
|
||||
val loopRange = KtPsiUtil.deparenthesize(forExpression.loopRange)
|
||||
|
||||
if (loopRange is KtQualifiedExpression) {
|
||||
val qualifiedExpression = loopRange as KtQualifiedExpression?
|
||||
val selector = qualifiedExpression!!.selectorExpression
|
||||
if (selector is KtCallExpression || selector is KtSimpleNameExpression) {
|
||||
return selector.getResolvedCall(bindingContext)
|
||||
when (loopRange) {
|
||||
is KtQualifiedExpression -> {
|
||||
val qualifiedExpression = loopRange as KtQualifiedExpression?
|
||||
val selector = qualifiedExpression!!.selectorExpression
|
||||
if (selector is KtCallExpression || selector is KtSimpleNameExpression) {
|
||||
return selector.getResolvedCall(bindingContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (loopRange is KtSimpleNameExpression || loopRange is KtCallExpression) {
|
||||
return loopRange.getResolvedCall(bindingContext)
|
||||
}
|
||||
else if (loopRange is KtBinaryExpression) {
|
||||
return loopRange.operationReference.getResolvedCall(bindingContext)
|
||||
is KtSimpleNameExpression, is KtCallExpression -> return loopRange.getResolvedCall(bindingContext)
|
||||
is KtBinaryExpression -> return loopRange.operationReference.getResolvedCall(bindingContext)
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@@ -610,14 +610,10 @@ class PsiInlineCodegen(
|
||||
|
||||
override fun putClosureParametersOnStack(next: LambdaInfo, functionReferenceReceiver: StackValue?) {
|
||||
activeLambda = next
|
||||
if (next is ExpressionLambda) {
|
||||
codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver)
|
||||
}
|
||||
else if (next is DefaultLambda) {
|
||||
rememberCapturedForDefaultLambda(next)
|
||||
}
|
||||
else {
|
||||
throw RuntimeException("Unknown lambda: $next")
|
||||
when (next) {
|
||||
is ExpressionLambda -> codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver)
|
||||
is DefaultLambda -> rememberCapturedForDefaultLambda(next)
|
||||
else -> throw RuntimeException("Unknown lambda: $next")
|
||||
}
|
||||
activeLambda = null
|
||||
}
|
||||
|
||||
+19
-15
@@ -408,23 +408,27 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
sourceFile
|
||||
)
|
||||
|
||||
if (descriptor is ScriptDescriptor) {
|
||||
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
|
||||
return parent.intoScript(
|
||||
descriptor,
|
||||
earlierScripts ?: emptyList(),
|
||||
descriptor as ClassDescriptor, state.typeMapper
|
||||
)
|
||||
}
|
||||
else if (descriptor is ClassDescriptor) {
|
||||
val kind = if (DescriptorUtils.isInterface(descriptor)) OwnerKind.DEFAULT_IMPLS else OwnerKind.IMPLEMENTATION
|
||||
return parent.intoClass(descriptor, kind, state)
|
||||
}
|
||||
else if (descriptor is FunctionDescriptor) {
|
||||
return parent.intoFunction(descriptor)
|
||||
return when (descriptor) {
|
||||
is ScriptDescriptor -> {
|
||||
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
|
||||
parent.intoScript(
|
||||
descriptor,
|
||||
earlierScripts ?: emptyList(),
|
||||
descriptor as ClassDescriptor, state.typeMapper
|
||||
)
|
||||
}
|
||||
is ClassDescriptor -> {
|
||||
val kind = if (DescriptorUtils.isInterface(descriptor)) OwnerKind.DEFAULT_IMPLS else OwnerKind.IMPLEMENTATION
|
||||
parent.intoClass(descriptor, kind, state)
|
||||
}
|
||||
is FunctionDescriptor -> {
|
||||
parent.intoFunction(descriptor)
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("Couldn't build context for " + descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
throw IllegalStateException("Couldn't build context for " + descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,33 +171,35 @@ private fun getInlineName(
|
||||
typeMapper: KotlinTypeMapper,
|
||||
fileClassesProvider: JvmFileClassesProvider
|
||||
): String {
|
||||
if (currentDescriptor is PackageFragmentDescriptor) {
|
||||
val file = DescriptorToSourceUtils.getContainingFile(codegenContext.contextDescriptor)
|
||||
when (currentDescriptor) {
|
||||
is PackageFragmentDescriptor -> {
|
||||
val file = DescriptorToSourceUtils.getContainingFile(codegenContext.contextDescriptor)
|
||||
|
||||
val implementationOwnerType: Type? =
|
||||
if (file == null) {
|
||||
CodegenContextUtil.getImplementationOwnerClassType(codegenContext)
|
||||
}
|
||||
else fileClassesProvider.getFileClassType(file)
|
||||
val implementationOwnerType: Type? =
|
||||
if (file == null) {
|
||||
CodegenContextUtil.getImplementationOwnerClassType(codegenContext)
|
||||
}
|
||||
else fileClassesProvider.getFileClassType(file)
|
||||
|
||||
if (implementationOwnerType == null) {
|
||||
val contextDescriptor = codegenContext.contextDescriptor
|
||||
throw RuntimeException(
|
||||
"Couldn't find declaration for " +
|
||||
contextDescriptor.containingDeclaration!!.name + "." + contextDescriptor.name +
|
||||
"; context: " + codegenContext
|
||||
)
|
||||
if (implementationOwnerType == null) {
|
||||
val contextDescriptor = codegenContext.contextDescriptor
|
||||
throw RuntimeException(
|
||||
"Couldn't find declaration for " +
|
||||
contextDescriptor.containingDeclaration!!.name + "." + contextDescriptor.name +
|
||||
"; context: " + codegenContext
|
||||
)
|
||||
}
|
||||
|
||||
return implementationOwnerType.internalName
|
||||
}
|
||||
|
||||
return implementationOwnerType.internalName
|
||||
}
|
||||
else if (currentDescriptor is ClassifierDescriptor) {
|
||||
return typeMapper.mapType(currentDescriptor).internalName
|
||||
}
|
||||
else if (currentDescriptor is FunctionDescriptor) {
|
||||
val descriptor = typeMapper.bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, currentDescriptor)
|
||||
if (descriptor != null) {
|
||||
return typeMapper.mapType(descriptor).internalName
|
||||
is ClassifierDescriptor -> {
|
||||
return typeMapper.mapType(currentDescriptor).internalName
|
||||
}
|
||||
is FunctionDescriptor -> {
|
||||
val descriptor = typeMapper.bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, currentDescriptor)
|
||||
if (descriptor != null) {
|
||||
return typeMapper.mapType(descriptor).internalName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,21 +43,23 @@ object JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
|
||||
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
|
||||
val type = receiver.type
|
||||
if (type == Type.VOID_TYPE) {
|
||||
receiver.put(Type.VOID_TYPE, v)
|
||||
StackValue.unit().put(UNIT_TYPE, v)
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
else if (isPrimitive(type)) {
|
||||
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
|
||||
receiver.put(type, v)
|
||||
AsmUtil.pop(v, type)
|
||||
when {
|
||||
type == Type.VOID_TYPE -> {
|
||||
receiver.put(Type.VOID_TYPE, v)
|
||||
StackValue.unit().put(UNIT_TYPE, v)
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
isPrimitive(type) -> {
|
||||
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
|
||||
receiver.put(type, v)
|
||||
AsmUtil.pop(v, type)
|
||||
}
|
||||
v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
else -> {
|
||||
receiver.put(type, v)
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
else {
|
||||
receiver.put(type, v)
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
|
||||
return getType(Class::class.java)
|
||||
|
||||
@@ -1123,15 +1123,10 @@ class ControlFlowInformationProvider private constructor(
|
||||
kind
|
||||
}
|
||||
else {
|
||||
if (check(kind, existingKind, IN_TRY, TAIL_CALL)) {
|
||||
IN_TRY
|
||||
}
|
||||
else if (check(kind, existingKind, IN_TRY, NON_TAIL)) {
|
||||
IN_TRY
|
||||
}
|
||||
else {
|
||||
// TAIL_CALL, NON_TAIL
|
||||
NON_TAIL
|
||||
when {
|
||||
check(kind, existingKind, IN_TRY, TAIL_CALL) -> IN_TRY
|
||||
check(kind, existingKind, IN_TRY, NON_TAIL) -> IN_TRY
|
||||
else -> NON_TAIL // TAIL_CALL, NON_TAIL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,15 +107,17 @@ class UnreachableCodeImpl(
|
||||
currentTextRange, element ->
|
||||
|
||||
val elementRange = element.textRange!!
|
||||
if (currentTextRange == null) {
|
||||
elementRange
|
||||
}
|
||||
else if (currentTextRange.endOffset == elementRange.startOffset) {
|
||||
currentTextRange.union(elementRange)
|
||||
}
|
||||
else {
|
||||
result.add(currentTextRange)
|
||||
elementRange
|
||||
when {
|
||||
currentTextRange == null -> {
|
||||
elementRange
|
||||
}
|
||||
currentTextRange.endOffset == elementRange.startOffset -> {
|
||||
currentTextRange.union(elementRange)
|
||||
}
|
||||
else -> {
|
||||
result.add(currentTextRange)
|
||||
elementRange
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastRange != null) {
|
||||
|
||||
+5
-1
@@ -47,4 +47,8 @@ class SyntheticFieldDescriptor private constructor(
|
||||
}
|
||||
|
||||
val DeclarationDescriptor.referencedProperty: PropertyDescriptor?
|
||||
get() = if (this is SyntheticFieldDescriptor) this.propertyDescriptor else if (this is PropertyDescriptor) this else null
|
||||
get() = when (this) {
|
||||
is SyntheticFieldDescriptor -> this.propertyDescriptor
|
||||
is PropertyDescriptor -> this
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -458,7 +458,11 @@ object Renderers {
|
||||
|
||||
private fun renderTypeBounds(typeBounds: TypeBounds, short: Boolean): String {
|
||||
val renderBound = { bound: Bound ->
|
||||
val arrow = if (bound.kind == LOWER_BOUND) ">: " else if (bound.kind == UPPER_BOUND) "<: " else ":= "
|
||||
val arrow = when (bound.kind) {
|
||||
LOWER_BOUND -> ">: "
|
||||
UPPER_BOUND -> "<: "
|
||||
else -> ":= "
|
||||
}
|
||||
val renderer = if (short) DescriptorRenderer.SHORT_NAMES_IN_TYPES else DescriptorRenderer.FQ_NAMES_IN_TYPES
|
||||
val renderedBound = arrow + renderer.renderType(bound.constrainingType) + if (!bound.isProper) "*" else ""
|
||||
if (short) renderedBound else renderedBound + '(' + bound.position + ')'
|
||||
|
||||
@@ -202,32 +202,28 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
||||
(descriptor as? ClassDescriptor)?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER
|
||||
is KtDestructuringDeclarationEntry -> TargetLists.T_LOCAL_VARIABLE
|
||||
is KtProperty -> {
|
||||
if (annotated.isLocal)
|
||||
TargetLists.T_LOCAL_VARIABLE
|
||||
else if (annotated.isMember)
|
||||
TargetLists.T_MEMBER_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||
else
|
||||
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||
when {
|
||||
annotated.isLocal -> TargetLists.T_LOCAL_VARIABLE
|
||||
annotated.isMember -> TargetLists.T_MEMBER_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||
else -> TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
|
||||
}
|
||||
}
|
||||
is KtParameter -> {
|
||||
val destructuringDeclaration = annotated.destructuringDeclaration
|
||||
if (destructuringDeclaration != null)
|
||||
TargetLists.T_DESTRUCTURING_DECLARATION
|
||||
else if (annotated.hasValOrVar())
|
||||
TargetLists.T_VALUE_PARAMETER_WITH_VAL
|
||||
else
|
||||
TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
|
||||
when {
|
||||
destructuringDeclaration != null -> TargetLists.T_DESTRUCTURING_DECLARATION
|
||||
annotated.hasValOrVar() -> TargetLists.T_VALUE_PARAMETER_WITH_VAL
|
||||
else -> TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
|
||||
}
|
||||
}
|
||||
is KtConstructor<*> -> TargetLists.T_CONSTRUCTOR
|
||||
is KtFunction -> {
|
||||
if (ExpressionTypingUtils.isFunctionExpression(descriptor))
|
||||
TargetLists.T_FUNCTION_EXPRESSION
|
||||
else if (annotated.isLocal)
|
||||
TargetLists.T_LOCAL_FUNCTION
|
||||
else if (annotated.parent is KtClassOrObject || annotated.parent is KtClassBody)
|
||||
TargetLists.T_MEMBER_FUNCTION
|
||||
else
|
||||
TargetLists.T_TOP_LEVEL_FUNCTION
|
||||
when {
|
||||
ExpressionTypingUtils.isFunctionExpression(descriptor) -> TargetLists.T_FUNCTION_EXPRESSION
|
||||
annotated.isLocal -> TargetLists.T_LOCAL_FUNCTION
|
||||
annotated.parent is KtClassOrObject || annotated.parent is KtClassBody -> TargetLists.T_MEMBER_FUNCTION
|
||||
else -> TargetLists.T_TOP_LEVEL_FUNCTION
|
||||
}
|
||||
}
|
||||
is KtTypeAlias -> TargetLists.T_TYPEALIAS
|
||||
is KtPropertyAccessor -> if (annotated.isGetter) TargetLists.T_PROPERTY_GETTER else TargetLists.T_PROPERTY_SETTER
|
||||
@@ -266,18 +262,20 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
|
||||
}
|
||||
|
||||
fun T_MEMBER_PROPERTY(backingField: Boolean, delegate: Boolean) =
|
||||
targetList(if (backingField) MEMBER_PROPERTY_WITH_BACKING_FIELD
|
||||
else if (delegate) MEMBER_PROPERTY_WITH_DELEGATE
|
||||
else MEMBER_PROPERTY_WITHOUT_FIELD_OR_DELEGATE,
|
||||
MEMBER_PROPERTY, PROPERTY) {
|
||||
targetList(when {
|
||||
backingField -> MEMBER_PROPERTY_WITH_BACKING_FIELD
|
||||
delegate -> MEMBER_PROPERTY_WITH_DELEGATE
|
||||
else -> MEMBER_PROPERTY_WITHOUT_FIELD_OR_DELEGATE
|
||||
}, MEMBER_PROPERTY, PROPERTY) {
|
||||
propertyTargets(backingField, delegate)
|
||||
}
|
||||
|
||||
fun T_TOP_LEVEL_PROPERTY(backingField: Boolean, delegate: Boolean) =
|
||||
targetList(if (backingField) TOP_LEVEL_PROPERTY_WITH_BACKING_FIELD
|
||||
else if (delegate) TOP_LEVEL_PROPERTY_WITH_DELEGATE
|
||||
else TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE,
|
||||
TOP_LEVEL_PROPERTY, PROPERTY) {
|
||||
targetList(when {
|
||||
backingField -> TOP_LEVEL_PROPERTY_WITH_BACKING_FIELD
|
||||
delegate -> TOP_LEVEL_PROPERTY_WITH_DELEGATE
|
||||
else -> TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE
|
||||
}, TOP_LEVEL_PROPERTY, PROPERTY) {
|
||||
propertyTargets(backingField, delegate)
|
||||
}
|
||||
|
||||
|
||||
@@ -418,19 +418,19 @@ class DeclarationsChecker(
|
||||
FiniteBoundRestrictionChecker.check(aClass, classDescriptor, trace)
|
||||
NonExpansiveInheritanceRestrictionChecker.check(aClass, classDescriptor, trace)
|
||||
|
||||
if (aClass.isInterface()) {
|
||||
checkConstructorInInterface(aClass)
|
||||
checkMethodsOfAnyInInterface(classDescriptor)
|
||||
if (aClass.isLocal && classDescriptor.containingDeclaration !is ClassDescriptor) {
|
||||
trace.report(LOCAL_INTERFACE_NOT_ALLOWED.on(aClass, classDescriptor))
|
||||
when {
|
||||
aClass.isInterface() -> {
|
||||
checkConstructorInInterface(aClass)
|
||||
checkMethodsOfAnyInInterface(classDescriptor)
|
||||
if (aClass.isLocal && classDescriptor.containingDeclaration !is ClassDescriptor) {
|
||||
trace.report(LOCAL_INTERFACE_NOT_ALLOWED.on(aClass, classDescriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (classDescriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
checkAnnotationClassWithBody(aClass)
|
||||
checkValOnAnnotationParameter(aClass)
|
||||
}
|
||||
else if (aClass is KtEnumEntry) {
|
||||
checkEnumEntry(aClass, classDescriptor)
|
||||
classDescriptor.kind == ClassKind.ANNOTATION_CLASS -> {
|
||||
checkAnnotationClassWithBody(aClass)
|
||||
checkValOnAnnotationParameter(aClass)
|
||||
}
|
||||
aClass is KtEnumEntry -> checkEnumEntry(aClass, classDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,17 +692,11 @@ class DeclarationsChecker(
|
||||
val delegate = property.delegate
|
||||
val isHeader = propertyDescriptor.isHeader
|
||||
if (initializer != null) {
|
||||
if (inInterface) {
|
||||
trace.report(PROPERTY_INITIALIZER_IN_INTERFACE.on(initializer))
|
||||
}
|
||||
else if (isHeader) {
|
||||
trace.report(HEADER_PROPERTY_INITIALIZER.on(initializer))
|
||||
}
|
||||
else if (!backingFieldRequired) {
|
||||
trace.report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer))
|
||||
}
|
||||
else if (property.receiverTypeReference != null) {
|
||||
trace.report(EXTENSION_PROPERTY_WITH_BACKING_FIELD.on(initializer))
|
||||
when {
|
||||
inInterface -> trace.report(PROPERTY_INITIALIZER_IN_INTERFACE.on(initializer))
|
||||
isHeader -> trace.report(HEADER_PROPERTY_INITIALIZER.on(initializer))
|
||||
!backingFieldRequired -> trace.report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer))
|
||||
property.receiverTypeReference != null -> trace.report(EXTENSION_PROPERTY_WITH_BACKING_FIELD.on(initializer))
|
||||
}
|
||||
}
|
||||
else if (delegate != null) {
|
||||
|
||||
@@ -69,12 +69,11 @@ open class DelegatingBindingTrace(
|
||||
private val bindingContext = MyBindingContext()
|
||||
|
||||
init {
|
||||
this.mutableDiagnostics = if (filter.ignoreDiagnostics)
|
||||
null
|
||||
else if (withParentDiagnostics)
|
||||
MutableDiagnosticsWithSuppression(bindingContext, parentContext.diagnostics)
|
||||
else
|
||||
MutableDiagnosticsWithSuppression(bindingContext)
|
||||
this.mutableDiagnostics = when {
|
||||
filter.ignoreDiagnostics -> null
|
||||
withParentDiagnostics -> MutableDiagnosticsWithSuppression(bindingContext, parentContext.diagnostics)
|
||||
else -> MutableDiagnosticsWithSuppression(bindingContext)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(parentContext: BindingContext,
|
||||
|
||||
@@ -122,14 +122,13 @@ class FunctionDescriptorResolver(
|
||||
assert(function.typeReference == null) {
|
||||
"Return type must be initialized early for function: " + function.text + ", at: " + DiagnosticUtils.atLocation(function) }
|
||||
|
||||
val returnType = if (function.hasBlockBody()) {
|
||||
builtIns.unitType
|
||||
}
|
||||
else if (function.hasBody()) {
|
||||
descriptorResolver.inferReturnTypeFromExpressionBody(trace, scope, dataFlowInfo, function, functionDescriptor)
|
||||
}
|
||||
else {
|
||||
ErrorUtils.createErrorType("No type, no body")
|
||||
val returnType = when {
|
||||
function.hasBlockBody() ->
|
||||
builtIns.unitType
|
||||
function.hasBody() ->
|
||||
descriptorResolver.inferReturnTypeFromExpressionBody(trace, scope, dataFlowInfo, function, functionDescriptor)
|
||||
else ->
|
||||
ErrorUtils.createErrorType("No type, no body")
|
||||
}
|
||||
functionDescriptor.setReturnType(returnType)
|
||||
}
|
||||
|
||||
@@ -340,14 +340,10 @@ object ModifierCheckerCore {
|
||||
checkCompatibility(trace, first, second, list.owner, incorrectNodes)
|
||||
}
|
||||
if (second !in incorrectNodes) {
|
||||
if (!checkTarget(trace, second, actualTargets)) {
|
||||
incorrectNodes += second
|
||||
}
|
||||
else if (!checkParent(trace, second, parentDescriptor)) {
|
||||
incorrectNodes += second
|
||||
}
|
||||
else if (!checkLanguageLevelSupport(trace, second, languageVersionSettings, actualTargets)) {
|
||||
incorrectNodes += second
|
||||
when {
|
||||
!checkTarget(trace, second, actualTargets) -> incorrectNodes += second
|
||||
!checkParent(trace, second, parentDescriptor) -> incorrectNodes += second
|
||||
!checkLanguageLevelSupport(trace, second, languageVersionSettings, actualTargets) -> incorrectNodes += second
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,15 +568,17 @@ class QualifiedExpressionResolver {
|
||||
) {
|
||||
if (descriptors.size > 1) {
|
||||
val visibleDescriptors = descriptors.filter { isVisible(it, shouldBeVisibleFrom, position) }
|
||||
if (visibleDescriptors.isEmpty()) {
|
||||
val descriptor = descriptors.first() as DeclarationDescriptorWithVisibility
|
||||
trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor))
|
||||
}
|
||||
else if (visibleDescriptors.size > 1) {
|
||||
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, visibleDescriptors)
|
||||
}
|
||||
else {
|
||||
storeResult(trace, referenceExpression, visibleDescriptors.single(), null, position, isQualifier)
|
||||
when {
|
||||
visibleDescriptors.isEmpty() -> {
|
||||
val descriptor = descriptors.first() as DeclarationDescriptorWithVisibility
|
||||
trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor))
|
||||
}
|
||||
visibleDescriptors.size > 1 -> {
|
||||
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, visibleDescriptors)
|
||||
}
|
||||
else -> {
|
||||
storeResult(trace, referenceExpression, visibleDescriptors.single(), null, position, isQualifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+15
-13
@@ -155,21 +155,23 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
|
||||
val varDescriptor: CallableDescriptor?
|
||||
val receiverExpression: KtExpression?
|
||||
if (receiver is ExpressionReceiver) {
|
||||
receiverExpression = receiver.expression
|
||||
varDescriptor = getCalleeDescriptor(context, receiverExpression, true)
|
||||
}
|
||||
else if (receiver is ExtensionReceiver) {
|
||||
val extension = receiver.declarationDescriptor
|
||||
when (receiver) {
|
||||
is ExpressionReceiver -> {
|
||||
receiverExpression = receiver.expression
|
||||
varDescriptor = getCalleeDescriptor(context, receiverExpression, true)
|
||||
}
|
||||
is ExtensionReceiver -> {
|
||||
val extension = receiver.declarationDescriptor
|
||||
|
||||
varDescriptor = extension.extensionReceiverParameter
|
||||
assert(varDescriptor != null) { "Extension should have receiverParameterDescriptor: " + extension }
|
||||
varDescriptor = extension.extensionReceiverParameter
|
||||
assert(varDescriptor != null) { "Extension should have receiverParameterDescriptor: " + extension }
|
||||
|
||||
receiverExpression = expression
|
||||
}
|
||||
else {
|
||||
varDescriptor = null
|
||||
receiverExpression = null
|
||||
receiverExpression = expression
|
||||
}
|
||||
else -> {
|
||||
varDescriptor = null
|
||||
receiverExpression = null
|
||||
}
|
||||
}
|
||||
|
||||
if (inlinableParameters.contains(varDescriptor)) {
|
||||
|
||||
@@ -50,18 +50,18 @@ fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(
|
||||
if (resultingDescriptor.dispatchReceiverParameter == null || dispatchReceiverValue == null) return true
|
||||
|
||||
var dispatchReceiverDescriptor: DeclarationDescriptor? = null
|
||||
if (dispatchReceiverValue is ImplicitReceiver) {
|
||||
// foo() -- implicit receiver
|
||||
dispatchReceiverDescriptor = dispatchReceiverValue.declarationDescriptor
|
||||
}
|
||||
else if (dispatchReceiverValue is ClassValueReceiver) {
|
||||
dispatchReceiverDescriptor = dispatchReceiverValue.classQualifier.descriptor
|
||||
}
|
||||
else if (dispatchReceiverValue is ExpressionReceiver) {
|
||||
val expression = KtPsiUtil.deparenthesize(dispatchReceiverValue.expression)
|
||||
if (expression is KtThisExpression) {
|
||||
// this.foo() -- explicit receiver
|
||||
dispatchReceiverDescriptor = context.get(BindingContext.REFERENCE_TARGET, expression.instanceReference)
|
||||
when (dispatchReceiverValue) {
|
||||
is ImplicitReceiver -> // foo() -- implicit receiver
|
||||
dispatchReceiverDescriptor = dispatchReceiverValue.declarationDescriptor
|
||||
is ClassValueReceiver -> {
|
||||
dispatchReceiverDescriptor = dispatchReceiverValue.classQualifier.descriptor
|
||||
}
|
||||
is ExpressionReceiver -> {
|
||||
val expression = KtPsiUtil.deparenthesize(dispatchReceiverValue.expression)
|
||||
if (expression is KtThisExpression) {
|
||||
// this.foo() -- explicit receiver
|
||||
dispatchReceiverDescriptor = context.get(BindingContext.REFERENCE_TARGET, expression.instanceReference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -283,9 +283,11 @@ internal class DelegatingDataFlowInfo private constructor(
|
||||
private fun Set<KotlinType>.containsNothing() = any { KotlinBuiltIns.isNothing(it) }
|
||||
|
||||
private fun Set<KotlinType>.intersect(other: Set<KotlinType>) =
|
||||
if (other.containsNothing()) this
|
||||
else if (this.containsNothing()) other
|
||||
else Sets.intersection(this, other)
|
||||
when {
|
||||
other.containsNothing() -> this
|
||||
this.containsNothing() -> other
|
||||
else -> Sets.intersection(this, other)
|
||||
}
|
||||
|
||||
override fun or(other: DataFlowInfo): DataFlowInfo {
|
||||
if (other === DataFlowInfo.EMPTY) return DataFlowInfo.EMPTY
|
||||
|
||||
+4
-8
@@ -145,14 +145,10 @@ abstract class KotlinSuppressCache {
|
||||
var suppressor: Suppressor? = suppressors[annotated]
|
||||
if (suppressor == null) {
|
||||
val strings = getSuppressingStrings(annotated)
|
||||
if (strings.isEmpty()) {
|
||||
suppressor = EmptySuppressor(annotated)
|
||||
}
|
||||
else if (strings.size == 1) {
|
||||
suppressor = SingularSuppressor(annotated, strings.iterator().next())
|
||||
}
|
||||
else {
|
||||
suppressor = MultiSuppressor(annotated, strings)
|
||||
suppressor = when {
|
||||
strings.isEmpty() -> EmptySuppressor(annotated)
|
||||
strings.size == 1 -> SingularSuppressor(annotated, strings.iterator().next())
|
||||
else -> MultiSuppressor(annotated, strings)
|
||||
}
|
||||
suppressors.put(annotated, suppressor)
|
||||
}
|
||||
|
||||
+35
-33
@@ -169,46 +169,48 @@ protected constructor(
|
||||
val declarations = declarationProvider.getDeclarations(kindFilter, nameFilter)
|
||||
val result = LinkedHashSet<DeclarationDescriptor>(declarations.size)
|
||||
for (declaration in declarations) {
|
||||
if (declaration is KtClassOrObject) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(classDescriptors(name))
|
||||
when (declaration) {
|
||||
is KtClassOrObject -> {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(classDescriptors(name))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (declaration is KtFunction) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedFunctions(name, location))
|
||||
is KtFunction -> {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedFunctions(name, location))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (declaration is KtProperty) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedVariables(name, location))
|
||||
is KtProperty -> {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedVariables(name, location))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (declaration is KtParameter) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedVariables(name, location))
|
||||
is KtParameter -> {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedVariables(name, location))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (declaration is KtTypeAlias) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedTypeAliasDescriptors(name, location))
|
||||
is KtTypeAlias -> {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(getContributedTypeAliasDescriptors(name, location))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (declaration is KtScript) {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(classDescriptors(name))
|
||||
is KtScript -> {
|
||||
val name = declaration.nameAsSafeName
|
||||
if (nameFilter(name)) {
|
||||
result.addAll(classDescriptors(name))
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> {
|
||||
// MultiDeclarations are not supported on global level
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unsupported declaration kind: " + declaration)
|
||||
}
|
||||
else if (declaration is KtDestructuringDeclaration) {
|
||||
// MultiDeclarations are not supported on global level
|
||||
}
|
||||
else throw IllegalArgumentException("Unsupported declaration kind: " + declaration)
|
||||
}
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
@@ -137,44 +137,45 @@ object LabelResolver {
|
||||
|
||||
val declarationsByLabel = context.scope.getDeclarationsByLabel(labelName)
|
||||
val size = declarationsByLabel.size
|
||||
if (size == 1) {
|
||||
val declarationDescriptor = declarationsByLabel.single()
|
||||
val thisReceiver = when (declarationDescriptor) {
|
||||
is ClassDescriptor -> declarationDescriptor.thisAsReceiverParameter
|
||||
is FunctionDescriptor -> declarationDescriptor.extensionReceiverParameter
|
||||
is PropertyDescriptor -> declarationDescriptor.extensionReceiverParameter
|
||||
else -> throw UnsupportedOperationException("Unsupported descriptor: " + declarationDescriptor) // TODO
|
||||
}
|
||||
|
||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor) ?: error("No PSI element for descriptor: " + declarationDescriptor)
|
||||
context.trace.record(LABEL_TARGET, targetLabel, element)
|
||||
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||
|
||||
if (declarationDescriptor is ClassDescriptor) {
|
||||
if (!DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, targetLabel, declarationDescriptor)) {
|
||||
return LabeledReceiverResolutionResult.labelResolutionFailed()
|
||||
when (size) {
|
||||
1 -> {
|
||||
val declarationDescriptor = declarationsByLabel.single()
|
||||
val thisReceiver = when (declarationDescriptor) {
|
||||
is ClassDescriptor -> declarationDescriptor.thisAsReceiverParameter
|
||||
is FunctionDescriptor -> declarationDescriptor.extensionReceiverParameter
|
||||
is PropertyDescriptor -> declarationDescriptor.extensionReceiverParameter
|
||||
else -> throw UnsupportedOperationException("Unsupported descriptor: " + declarationDescriptor) // TODO
|
||||
}
|
||||
}
|
||||
|
||||
return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver)
|
||||
}
|
||||
else if (size == 0) {
|
||||
val element = resolveNamedLabel(labelName, targetLabel, context.trace)
|
||||
val declarationDescriptor = context.trace.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, element]
|
||||
if (declarationDescriptor is FunctionDescriptor) {
|
||||
val thisReceiver = declarationDescriptor.extensionReceiverParameter
|
||||
if (thisReceiver != null) {
|
||||
context.trace.record(LABEL_TARGET, targetLabel, element)
|
||||
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor)
|
||||
?: error("No PSI element for descriptor: " + declarationDescriptor)
|
||||
context.trace.record(LABEL_TARGET, targetLabel, element)
|
||||
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||
|
||||
if (declarationDescriptor is ClassDescriptor) {
|
||||
if (!DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, targetLabel, declarationDescriptor)) {
|
||||
return LabeledReceiverResolutionResult.labelResolutionFailed()
|
||||
}
|
||||
}
|
||||
|
||||
return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver)
|
||||
}
|
||||
else {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel, targetLabel))
|
||||
0 -> {
|
||||
val element = resolveNamedLabel(labelName, targetLabel, context.trace)
|
||||
val declarationDescriptor = context.trace.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, element]
|
||||
if (declarationDescriptor is FunctionDescriptor) {
|
||||
val thisReceiver = declarationDescriptor.extensionReceiverParameter
|
||||
if (thisReceiver != null) {
|
||||
context.trace.record(LABEL_TARGET, targetLabel, element)
|
||||
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||
}
|
||||
return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver)
|
||||
}
|
||||
else {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel, targetLabel))
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel)
|
||||
else -> BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel)
|
||||
}
|
||||
return LabeledReceiverResolutionResult.labelResolutionFailed()
|
||||
}
|
||||
|
||||
+11
-7
@@ -38,9 +38,11 @@ object SenselessComparisonChecker {
|
||||
getNullability: (DataFlowValue) -> Nullability
|
||||
) {
|
||||
val expr =
|
||||
if (KtPsiUtil.isNullConstant(left)) right
|
||||
else if (KtPsiUtil.isNullConstant(right)) left
|
||||
else return
|
||||
when {
|
||||
KtPsiUtil.isNullConstant(left) -> right
|
||||
KtPsiUtil.isNullConstant(right) -> left
|
||||
else -> return
|
||||
}
|
||||
|
||||
val type = getType(expr)
|
||||
if (type == null || type.isError) return
|
||||
@@ -52,10 +54,12 @@ object SenselessComparisonChecker {
|
||||
val nullability = getNullability(value)
|
||||
|
||||
val expressionIsAlways =
|
||||
if (nullability == Nullability.NULL) equality
|
||||
else if (nullability == Nullability.NOT_NULL) !equality
|
||||
else if (nullability == Nullability.IMPOSSIBLE) false
|
||||
else return
|
||||
when (nullability) {
|
||||
Nullability.NULL -> equality
|
||||
Nullability.NOT_NULL -> !equality
|
||||
Nullability.IMPOSSIBLE -> false
|
||||
else -> return
|
||||
}
|
||||
|
||||
context.trace.report(Errors.SENSELESS_COMPARISON.on(expression, expression, expressionIsAlways))
|
||||
}
|
||||
|
||||
+18
-22
@@ -632,22 +632,20 @@ class ExpressionCodegen(
|
||||
|
||||
val stackElement = data.peek()
|
||||
|
||||
if (stackElement is TryInfo) {
|
||||
//noinspection ConstantConditions
|
||||
genFinallyBlockOrGoto(stackElement, null, afterBreakContinueLabel, data)
|
||||
}
|
||||
else if (stackElement is LoopInfo) {
|
||||
val loop = expression.loop
|
||||
//noinspection ConstantConditions
|
||||
if (loop == stackElement.loop) {
|
||||
val label = if (expression is IrBreak) stackElement.breakLabel else stackElement.continueLabel
|
||||
mv.fixStackAndJump(label)
|
||||
mv.mark(afterBreakContinueLabel)
|
||||
return
|
||||
when (stackElement) {
|
||||
is TryInfo -> //noinspection ConstantConditions
|
||||
genFinallyBlockOrGoto(stackElement, null, afterBreakContinueLabel, data)
|
||||
is LoopInfo -> {
|
||||
val loop = expression.loop
|
||||
//noinspection ConstantConditions
|
||||
if (loop == stackElement.loop) {
|
||||
val label = if (expression is IrBreak) stackElement.breakLabel else stackElement.continueLabel
|
||||
mv.fixStackAndJump(label)
|
||||
mv.mark(afterBreakContinueLabel)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
|
||||
else -> throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
|
||||
}
|
||||
|
||||
data.pop()
|
||||
@@ -829,14 +827,12 @@ class ExpressionCodegen(
|
||||
private fun doFinallyOnReturn(afterReturnLabel: Label, data: BlockInfo) {
|
||||
if (!data.isEmpty()) {
|
||||
val stackElement = data.peek()
|
||||
if (stackElement is TryInfo) {
|
||||
genFinallyBlockOrGoto(stackElement, null, afterReturnLabel, data)
|
||||
}
|
||||
else if (stackElement is LoopInfo) {
|
||||
when (stackElement) {
|
||||
is TryInfo -> genFinallyBlockOrGoto(stackElement, null, afterReturnLabel, data)
|
||||
is LoopInfo -> {
|
||||
|
||||
}
|
||||
else {
|
||||
throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
|
||||
}
|
||||
|
||||
data.pop()
|
||||
|
||||
+12
-10
@@ -163,16 +163,18 @@ class StatementGenerator(
|
||||
}
|
||||
else {
|
||||
val label = expression.getTargetLabel()
|
||||
if (label != null) {
|
||||
val labelTarget = getOrFail(BindingContext.LABEL_TARGET, label)
|
||||
val labelTargetDescriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, labelTarget)
|
||||
labelTargetDescriptor as CallableDescriptor
|
||||
}
|
||||
else if (ExpressionTypingUtils.isFunctionLiteral(scopeOwner)) {
|
||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(scopeOwner, true).first
|
||||
}
|
||||
else {
|
||||
scopeOwnerAsCallable()
|
||||
when {
|
||||
label != null -> {
|
||||
val labelTarget = getOrFail(BindingContext.LABEL_TARGET, label)
|
||||
val labelTargetDescriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, labelTarget)
|
||||
labelTargetDescriptor as CallableDescriptor
|
||||
}
|
||||
ExpressionTypingUtils.isFunctionLiteral(scopeOwner) -> {
|
||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(scopeOwner, true).first
|
||||
}
|
||||
else -> {
|
||||
scopeOwnerAsCallable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-18
@@ -168,25 +168,27 @@ private fun <C : Candidate> createSimpleProcessor(
|
||||
classValueReceiver: Boolean,
|
||||
collectCandidates: CandidatesCollector
|
||||
) : ScopeTowerProcessor<C> {
|
||||
if (explicitReceiver is ReceiverValueWithSmartCastInfo) {
|
||||
return ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
|
||||
}
|
||||
else if (explicitReceiver is QualifierReceiver) {
|
||||
val qualifierProcessor = QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
|
||||
if (!classValueReceiver) return qualifierProcessor
|
||||
|
||||
// todo enum entry, object.
|
||||
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor
|
||||
return CompositeScopeTowerProcessor(
|
||||
qualifierProcessor,
|
||||
ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates)
|
||||
)
|
||||
}
|
||||
else {
|
||||
assert(explicitReceiver == null) {
|
||||
"Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})"
|
||||
return when (explicitReceiver) {
|
||||
is ReceiverValueWithSmartCastInfo -> {
|
||||
ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
|
||||
}
|
||||
is QualifierReceiver -> {
|
||||
val qualifierProcessor = QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
|
||||
if (!classValueReceiver) return qualifierProcessor
|
||||
|
||||
// todo enum entry, object.
|
||||
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor
|
||||
CompositeScopeTowerProcessor(
|
||||
qualifierProcessor,
|
||||
ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
assert(explicitReceiver == null) {
|
||||
"Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})"
|
||||
}
|
||||
NoExplicitReceiverScopeTowerProcessor(context, collectCandidates)
|
||||
}
|
||||
return NoExplicitReceiverScopeTowerProcessor(context, collectCandidates)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user