Prohibit instance access before super call
- Before this change members just left unresolved as they were absent in the specific scope named scopeForSecondaryConstructorHeaderResolution that created just to prohibit such accesses. - Now they are resolved the same way as other members, but diagnostic is repored by in-place injected CallChecker - Drop obsolete type of class scope #KT-6995 Fixed
This commit is contained in:
@@ -57,6 +57,7 @@ import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.ResolvedCallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
@@ -830,7 +831,7 @@ public class JetFlowInformationProvider {
|
||||
// }
|
||||
// }
|
||||
boolean sameDispatchReceiver =
|
||||
PseudocodeUtil.isThisOrNoDispatchReceiver(resolvedCall, trace.getBindingContext());
|
||||
ResolvedCallUtilPackage.hasThisOrNoDispatchReceiver(resolvedCall, trace.getBindingContext());
|
||||
|
||||
TailRecursionKind kind = isTail && sameDispatchReceiver ? TAIL_CALL : NON_TAIL;
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ import org.jetbrains.kotlin.cfg.JetControlFlowProcessor;
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction;
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*;
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.VariableDeclarationInstruction;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -31,9 +29,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver;
|
||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.ResolvedCallUtilPackage;
|
||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice;
|
||||
import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
|
||||
|
||||
@@ -105,37 +101,6 @@ public class PseudocodeUtil {
|
||||
"AccessTarget.Declaration has no receivers and it's not BlackBox, so it should be Call";
|
||||
|
||||
ResolvedCall<?> accessResolvedCall = ((AccessTarget.Call) accessTarget).getResolvedCall();
|
||||
return isThisOrNoDispatchReceiver(accessResolvedCall, bindingContext);
|
||||
return ResolvedCallUtilPackage.hasThisOrNoDispatchReceiver(accessResolvedCall, bindingContext);
|
||||
}
|
||||
|
||||
public static boolean isThisOrNoDispatchReceiver(
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
// it returns true if call has no dispatch receiver (e.g. resulting descriptor is top-level function or local variable)
|
||||
// or call receiver is effectively `this` instance (explicitly or implicitly) of resulting descriptor
|
||||
// class A(other: A) {
|
||||
// val x
|
||||
// val y = other.x // return false for `other.x` as it's receiver is not `this`
|
||||
// }
|
||||
ReceiverParameterDescriptor dispatchReceiverParameter = resolvedCall.getResultingDescriptor().getDispatchReceiverParameter();
|
||||
ReceiverValue dispatchReceiverValue = resolvedCall.getDispatchReceiver();
|
||||
if (dispatchReceiverParameter == null || !dispatchReceiverValue.exists()) return true;
|
||||
|
||||
DeclarationDescriptor classDescriptor = null;
|
||||
if (dispatchReceiverValue instanceof ThisReceiver) {
|
||||
// foo() -- implicit receiver
|
||||
classDescriptor = ((ThisReceiver) dispatchReceiverValue).getDeclarationDescriptor();
|
||||
}
|
||||
else if (dispatchReceiverValue instanceof ExpressionReceiver) {
|
||||
JetExpression expression = JetPsiUtil.deparenthesize(((ExpressionReceiver) dispatchReceiverValue).getExpression());
|
||||
if (expression instanceof JetThisExpression) {
|
||||
// this.foo() -- explicit receiver
|
||||
JetThisExpression thisExpression = (JetThisExpression) expression;
|
||||
classDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, thisExpression.getInstanceReference());
|
||||
}
|
||||
}
|
||||
return dispatchReceiverParameter.getContainingDeclaration() == classDescriptor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-3
@@ -33,9 +33,6 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor {
|
||||
@NotNull
|
||||
JetScope getScopeForInitializerResolution();
|
||||
|
||||
@NotNull
|
||||
JetScope getScopeForSecondaryConstructorHeaderResolution();
|
||||
|
||||
@NotNull
|
||||
JetScope getScopeForMemberLookup();
|
||||
|
||||
|
||||
-10
@@ -57,7 +57,6 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
||||
private final WritableScope scopeForMemberResolution;
|
||||
// This scope contains type parameters but does not contain inner classes
|
||||
private final WritableScope scopeForSupertypeResolution;
|
||||
private final WritableScope scopeForSecondaryConstructorHeaderResolution;
|
||||
private WritableScope scopeForInitializers; //contains members + primary constructor value parameters + map for backing fields
|
||||
private JetScope scopeForMemberLookup;
|
||||
private final JetScope staticScope = new StaticScopeForKotlinClass(this);
|
||||
@@ -84,8 +83,6 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
||||
.changeLockLevel(WritableScope.LockLevel.BOTH);
|
||||
this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution")
|
||||
.changeLockLevel(WritableScope.LockLevel.BOTH);
|
||||
this.scopeForSecondaryConstructorHeaderResolution =
|
||||
new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "SecondaryConstructorHeaderResolution ");
|
||||
|
||||
if (kind == ClassKind.TRAIT) {
|
||||
setUpScopeForInitializers(this);
|
||||
@@ -93,7 +90,6 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
||||
|
||||
scopeForMemberResolution.importScope(staticScope);
|
||||
scopeForMemberResolution.addLabeledDeclaration(this);
|
||||
scopeForSecondaryConstructorHeaderResolution.importScope(staticScope);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -293,12 +289,6 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
||||
return getWritableScopeForInitializers();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getScopeForSecondaryConstructorHeaderResolution() {
|
||||
return scopeForSecondaryConstructorHeaderResolution;
|
||||
}
|
||||
|
||||
private void setUpScopeForInitializers(@NotNull DeclarationDescriptor containingDeclaration) {
|
||||
this.scopeForInitializers = new WritableScopeImpl(
|
||||
scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Initializers")
|
||||
|
||||
@@ -171,6 +171,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetConstructorDelegationCall> EXPLICIT_DELEGATION_CALL_REQUIRED =
|
||||
DiagnosticFactory0.create(ERROR, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
|
||||
DiagnosticFactory1<PsiElement, DeclarationDescriptor> INSTANCE_ACCESS_BEFORE_SUPER_CALL = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
// Trait-specific
|
||||
|
||||
DiagnosticFactory0<JetModifierListOwner> ABSTRACT_MODIFIER_IN_TRAIT = DiagnosticFactory0
|
||||
|
||||
+2
@@ -400,6 +400,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXPLICIT_DELEGATION_CALL_REQUIRED,
|
||||
"Explicit 'this' or 'super' call is required. There is no constructor in superclass that can be called without arguments");
|
||||
|
||||
MAP.put(INSTANCE_ACCESS_BEFORE_SUPER_CALL, "Cannot access ''{0}'' before superclass constructor has been called", NAME);
|
||||
|
||||
MAP.put(INIT_KEYWORD_BEFORE_CLASS_INITIALIZER_EXPECTED, "Expecting 'init' keyword before class initializer");
|
||||
|
||||
MAP.put(ILLEGAL_SELECTOR, "Expression ''{0}'' cannot be a selector (occur after a dot)", STRING);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.kotlin.util.Box;
|
||||
import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
|
||||
@@ -142,22 +144,20 @@ public class BodyResolver {
|
||||
@NotNull final BindingTrace trace,
|
||||
@NotNull final JetSecondaryConstructor constructor,
|
||||
@NotNull final ConstructorDescriptor descriptor,
|
||||
@NotNull JetScope bodyDeclaringScope
|
||||
@NotNull JetScope declaringScope
|
||||
) {
|
||||
AnnotationResolver.resolveAnnotationsArguments(constructor.getModifierList(), trace);
|
||||
assert descriptor.getContainingDeclaration() instanceof ClassDescriptorWithResolutionScopes
|
||||
: "When resolving body it should be class descriptor with resolution scopes";
|
||||
|
||||
ClassDescriptorWithResolutionScopes classDescriptor = (ClassDescriptorWithResolutionScopes) descriptor.getContainingDeclaration();
|
||||
|
||||
resolveFunctionBody(c, trace, constructor, descriptor, bodyDeclaringScope,
|
||||
classDescriptor.getScopeForSecondaryConstructorHeaderResolution(),
|
||||
final CallChecker callChecker = new ConstructorHeaderCallChecker(descriptor, expressionTypingServices.getCallChecker());
|
||||
resolveFunctionBody(c, trace, constructor, descriptor, declaringScope,
|
||||
new Function1<JetScope, DataFlowInfo>() {
|
||||
@Override
|
||||
public DataFlowInfo invoke(@NotNull JetScope headerInnerScope) {
|
||||
return resolveSecondaryConstructorDelegationCall(c, trace, headerInnerScope, constructor, descriptor);
|
||||
return resolveSecondaryConstructorDelegationCall(c, trace, headerInnerScope, constructor, descriptor,
|
||||
callChecker);
|
||||
}
|
||||
});
|
||||
},
|
||||
callChecker);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -166,11 +166,13 @@ public class BodyResolver {
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull JetSecondaryConstructor constructor,
|
||||
@NotNull ConstructorDescriptor descriptor
|
||||
@NotNull ConstructorDescriptor descriptor,
|
||||
@NotNull CallChecker callChecker
|
||||
) {
|
||||
OverloadResolutionResults<?> results = callResolver.resolveConstructorDelegationCall(
|
||||
trace, scope, c.getOuterDataFlowInfo(),
|
||||
descriptor, constructor.getDelegationCall());
|
||||
descriptor, constructor.getDelegationCall(),
|
||||
callChecker);
|
||||
|
||||
if (results != null && results.isSingleResult()) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = results.getResultingCall();
|
||||
@@ -715,30 +717,29 @@ public class BodyResolver {
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetDeclarationWithBody function,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull JetScope bodyDeclaringScope,
|
||||
@Nullable JetScope headerDeclaringScope,
|
||||
@Nullable Function1<JetScope, DataFlowInfo> beforeBlockBody
|
||||
@NotNull JetScope scope,
|
||||
@Nullable Function1<JetScope, DataFlowInfo> beforeBlockBody,
|
||||
@Nullable CallChecker callChecker
|
||||
) {
|
||||
JetScope headerInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(
|
||||
headerDeclaringScope == null ? bodyDeclaringScope : headerDeclaringScope, functionDescriptor, trace);
|
||||
JetScope innerScope = FunctionDescriptorUtil.getFunctionInnerScope(scope, functionDescriptor, trace);
|
||||
List<JetParameter> valueParameters = function.getValueParameters();
|
||||
List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
|
||||
|
||||
expressionTypingServices.resolveValueParameters(valueParameters, valueParameterDescriptors, headerInnerScope,
|
||||
c.getOuterDataFlowInfo(), trace);
|
||||
expressionTypingServices.resolveValueParameters(
|
||||
valueParameters, valueParameterDescriptors,
|
||||
ExpressionTypingContext.newContext(
|
||||
expressionTypingServices, trace, innerScope, c.getOuterDataFlowInfo(), NO_EXPECTED_TYPE, callChecker)
|
||||
);
|
||||
|
||||
DataFlowInfo dataFlowInfo = null;
|
||||
|
||||
if (beforeBlockBody != null) {
|
||||
dataFlowInfo = beforeBlockBody.invoke(headerInnerScope);
|
||||
dataFlowInfo = beforeBlockBody.invoke(innerScope);
|
||||
}
|
||||
|
||||
JetScope bodyInnerScope = headerDeclaringScope == null ? headerInnerScope :
|
||||
FunctionDescriptorUtil.getFunctionInnerScope(bodyDeclaringScope, functionDescriptor, trace);
|
||||
|
||||
if (function.hasBody()) {
|
||||
expressionTypingServices.checkFunctionReturnType(
|
||||
bodyInnerScope, function, functionDescriptor, dataFlowInfo != null ? dataFlowInfo : c.getOuterDataFlowInfo(), null, trace);
|
||||
innerScope, function, functionDescriptor, dataFlowInfo != null ? dataFlowInfo : c.getOuterDataFlowInfo(), null, trace);
|
||||
}
|
||||
|
||||
assert functionDescriptor.getReturnType() != null;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.JetConstructorDelegationCall
|
||||
import org.jetbrains.kotlin.psi.JetInstanceExpressionWithLabel
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.hasImplicitThisOrSuperDispatchReceiver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
|
||||
|
||||
|
||||
public class ConstructorHeaderCallChecker(constructor: ConstructorDescriptor, private val wrapped: CallChecker) : CallChecker {
|
||||
private val containingClass = constructor.getContainingDeclaration()
|
||||
|
||||
override fun <F : CallableDescriptor?> check(resolvedCall: ResolvedCall<F>, context: BasicCallResolutionContext) {
|
||||
if (resolvedCall.getStatus().isSuccess() &&
|
||||
resolvedCall.hasImplicitThisOrSuperDispatchReceiver(context.trace.getBindingContext()) &&
|
||||
containingClass == resolvedCall.getResultingDescriptor().getOwnerForEffectiveDispatchReceiverParameter()
|
||||
) {
|
||||
reportError(context, resolvedCall)
|
||||
}
|
||||
else {
|
||||
val callElement = resolvedCall.getCall().getCallElement()
|
||||
if (callElement is JetInstanceExpressionWithLabel) {
|
||||
val descriptor = context.trace.get(BindingContext.REFERENCE_TARGET, callElement.getInstanceReference())
|
||||
if (containingClass == descriptor) {
|
||||
reportError(context, resolvedCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wrapped.check(resolvedCall, context)
|
||||
}
|
||||
|
||||
private fun reportError(context: BasicCallResolutionContext, resolvedCall: ResolvedCall<*>) {
|
||||
context.trace.report(
|
||||
Errors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.on(context.call.getCalleeExpression(), resolvedCall.getResultingDescriptor()))
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||
@@ -301,7 +302,7 @@ public class CallResolver {
|
||||
public OverloadResolutionResults<FunctionDescriptor> resolveConstructorDelegationCall(
|
||||
@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull ConstructorDescriptor constructorDescriptor,
|
||||
@NotNull JetConstructorDelegationCall call
|
||||
@NotNull JetConstructorDelegationCall call, @NotNull CallChecker callChecker
|
||||
) {
|
||||
// Method returns `null` when there is nothing to resolve in trivial cases like `null` call expression or
|
||||
// when super call should be conventional enum constructor and super call should be empty
|
||||
@@ -311,7 +312,7 @@ public class CallResolver {
|
||||
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
|
||||
NO_EXPECTED_TYPE,
|
||||
dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED,
|
||||
expressionTypingServices.getCallChecker(), expressionTypingServices.getAdditionalTypeChecker(), false);
|
||||
callChecker, expressionTypingServices.getAdditionalTypeChecker(), false);
|
||||
|
||||
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.resolvedCallUtil
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.JetPsiUtil
|
||||
import org.jetbrains.kotlin.psi.JetSuperExpression
|
||||
import org.jetbrains.kotlin.psi.JetThisExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
|
||||
|
||||
// it returns true if call has no dispatch receiver (e.g. resulting descriptor is top-level function or local variable)
|
||||
// or call receiver is effectively `this` instance (explicitly or implicitly) of resulting descriptor
|
||||
// class A(other: A) {
|
||||
// val x
|
||||
// val y = other.x // return false for `other.x` as it's receiver is not `this`
|
||||
// }
|
||||
public fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(context: BindingContext): Boolean =
|
||||
hasThisOrNoDispatchReceiver(context, true, true)
|
||||
|
||||
public fun ResolvedCall<*>.hasImplicitThisOrSuperDispatchReceiver(context: BindingContext): Boolean =
|
||||
hasThisOrNoDispatchReceiver(context, false, false)
|
||||
|
||||
private fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(
|
||||
context: BindingContext,
|
||||
returnForNoReceiver: Boolean,
|
||||
considerExplicitReceivers: Boolean
|
||||
): Boolean {
|
||||
val dispatchReceiverValue = getDispatchReceiver()
|
||||
if (getResultingDescriptor().getDispatchReceiverParameter() == null || !dispatchReceiverValue.exists()) return returnForNoReceiver
|
||||
|
||||
var dispatchReceiverDescriptor: DeclarationDescriptor? = null
|
||||
if (dispatchReceiverValue is ThisReceiver) {
|
||||
// foo() -- implicit receiver
|
||||
dispatchReceiverDescriptor = dispatchReceiverValue.getDeclarationDescriptor()
|
||||
}
|
||||
else if (dispatchReceiverValue is ExpressionReceiver && considerExplicitReceivers) {
|
||||
val expression = JetPsiUtil.deparenthesize(dispatchReceiverValue.getExpression())
|
||||
if (expression is JetThisExpression) {
|
||||
// this.foo() -- explicit receiver
|
||||
dispatchReceiverDescriptor = context.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference())
|
||||
}
|
||||
}
|
||||
|
||||
return dispatchReceiverDescriptor == getResultingDescriptor().getOwnerForEffectiveDispatchReceiverParameter()
|
||||
}
|
||||
|
||||
-25
@@ -92,7 +92,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
private final NotNullLazyValue<JetScope> scopeForClassHeaderResolution;
|
||||
private final NotNullLazyValue<JetScope> scopeForMemberDeclarationResolution;
|
||||
private final NotNullLazyValue<JetScope> scopeForPropertyInitializerResolution;
|
||||
private final NotNullLazyValue<JetScope> scopeForSecondaryConstructorHeaderResolution;
|
||||
|
||||
private final NullableLazyValue<Void> forceResolveAllContents;
|
||||
private final boolean isCompanionObject;
|
||||
@@ -212,12 +211,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
return computeScopeForPropertyInitializerResolution();
|
||||
}
|
||||
});
|
||||
this.scopeForSecondaryConstructorHeaderResolution = storageManager.createLazyValue(new Function0<JetScope>() {
|
||||
@Override
|
||||
public JetScope invoke() {
|
||||
return computeScopeForSecondaryConstructorHeaderResolution();
|
||||
}
|
||||
});
|
||||
this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(new Function0<Void>() {
|
||||
@Override
|
||||
public Void invoke() {
|
||||
@@ -335,24 +328,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
scope, getScopeForMemberDeclarationResolution());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getScopeForSecondaryConstructorHeaderResolution() {
|
||||
return scopeForSecondaryConstructorHeaderResolution.invoke();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private JetScope computeScopeForSecondaryConstructorHeaderResolution() {
|
||||
return new ChainedScope(
|
||||
this,
|
||||
"ScopeForSecondaryConstructorHeaderResolution: " + getName(),
|
||||
getScopeForClassHeaderResolution(),
|
||||
getCompanionObjectScope(),
|
||||
DescriptorUtils.getStaticNestedClassesScope(this),
|
||||
getStaticScope()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -305,7 +305,7 @@ public open class LazyClassMemberScope(
|
||||
|
||||
return classOrObject.getSecondaryConstructors().map { constructor ->
|
||||
val descriptor = c.functionDescriptorResolver.resolveSecondaryConstructorDescriptor(
|
||||
thisDescriptor.getScopeForSecondaryConstructorHeaderResolution(), thisDescriptor, constructor, trace
|
||||
thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, constructor, trace
|
||||
)
|
||||
setDeferredReturnType(descriptor)
|
||||
descriptor
|
||||
|
||||
+15
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.types.expressions;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.StatementFilter;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker;
|
||||
@@ -39,10 +40,23 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
|
||||
@NotNull JetScope scope,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull JetType expectedType
|
||||
) {
|
||||
return newContext(expressionTypingServices, trace, scope, dataFlowInfo, expectedType, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ExpressionTypingContext newContext(
|
||||
@NotNull ExpressionTypingServices expressionTypingServices,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull JetType expectedType,
|
||||
@Nullable CallChecker callChecker
|
||||
) {
|
||||
return newContext(trace, scope, dataFlowInfo, expectedType,
|
||||
ContextDependency.INDEPENDENT, new ResolutionResultsCacheImpl(),
|
||||
expressionTypingServices.getCallChecker(), expressionTypingServices.getAdditionalTypeChecker(),
|
||||
callChecker != null ? callChecker : expressionTypingServices.getCallChecker(),
|
||||
expressionTypingServices.getAdditionalTypeChecker(),
|
||||
StatementFilter.NONE, false);
|
||||
}
|
||||
|
||||
|
||||
+17
-8
@@ -403,30 +403,39 @@ public class ExpressionTypingServices {
|
||||
@NotNull JetScope declaringScope,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
resolveValueParameters(
|
||||
valueParameters, valueParameterDescriptors,
|
||||
ExpressionTypingContext.newContext(this, trace, declaringScope, dataFlowInfo, NO_EXPECTED_TYPE));
|
||||
}
|
||||
|
||||
public void resolveValueParameters(
|
||||
@NotNull List<JetParameter> valueParameters,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameterDescriptors,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
for (int i = 0; i < valueParameters.size(); i++) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = valueParameterDescriptors.get(i);
|
||||
JetParameter jetParameter = valueParameters.get(i);
|
||||
|
||||
AnnotationResolver.resolveAnnotationsArguments(jetParameter.getModifierList(), trace);
|
||||
AnnotationResolver.resolveAnnotationsArguments(jetParameter.getModifierList(), context.trace);
|
||||
|
||||
resolveDefaultValue(declaringScope, valueParameterDescriptor, jetParameter, dataFlowInfo, trace);
|
||||
resolveDefaultValue(valueParameterDescriptor, jetParameter, context);
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveDefaultValue(
|
||||
@NotNull JetScope declaringScope,
|
||||
@NotNull ValueParameterDescriptor valueParameterDescriptor,
|
||||
@NotNull JetParameter jetParameter,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull BindingTrace trace
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
if (valueParameterDescriptor.hasDefaultValue()) {
|
||||
JetExpression defaultValue = jetParameter.getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), dataFlowInfo, trace);
|
||||
if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(declaringScope))) {
|
||||
ConstantExpressionEvaluator.evaluate(defaultValue, trace, valueParameterDescriptor.getType());
|
||||
getTypeInfo(defaultValue, context.replaceExpectedType(valueParameterDescriptor.getType()));
|
||||
if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(context.scope))) {
|
||||
ConstantExpressionEvaluator.evaluate(
|
||||
defaultValue, context.trace, valueParameterDescriptor.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
open class Base<T>(p: Any?) {
|
||||
fun foo1(t: T) {}
|
||||
}
|
||||
|
||||
class D: Base<Int>("") {
|
||||
inner class B : Base<String> {
|
||||
constructor() : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo1<!>(""))
|
||||
constructor(x: Int) : super(foo1(1))
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package
|
||||
|
||||
internal open class Base</*0*/ T> {
|
||||
public constructor Base</*0*/ T>(/*0*/ p: kotlin.Any?)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo1(/*0*/ t: T): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal final class D : Base<kotlin.Int> {
|
||||
public constructor D()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final override /*1*/ /*fake_override*/ fun foo1(/*0*/ t: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
internal final inner class B : Base<kotlin.String> {
|
||||
public constructor B()
|
||||
public constructor B(/*0*/ x: kotlin.Int)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final override /*1*/ /*fake_override*/ fun foo1(/*0*/ t: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
open class Base<T>(p: Any?) {
|
||||
fun foo1(t: T) {}
|
||||
}
|
||||
|
||||
class D: Base<Int>(1) {
|
||||
inner class B : Base<Int> {
|
||||
constructor() : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo1<!>(1))
|
||||
constructor(x: Int) : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this@B<!>.foo1(1))
|
||||
constructor(x: Int, y: Int) : super(this@D.foo1(1))
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package
|
||||
|
||||
internal open class Base</*0*/ T> {
|
||||
public constructor Base</*0*/ T>(/*0*/ p: kotlin.Any?)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo1(/*0*/ t: T): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal final class D : Base<kotlin.Int> {
|
||||
public constructor D()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final override /*1*/ /*fake_override*/ fun foo1(/*0*/ t: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
internal final inner class B : Base<kotlin.Int> {
|
||||
public constructor B()
|
||||
public constructor B(/*0*/ x: kotlin.Int)
|
||||
public constructor B(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final override /*1*/ /*fake_override*/ fun foo1(/*0*/ t: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class Base(p: Any?) {
|
||||
fun foo1() {}
|
||||
}
|
||||
|
||||
fun Base.foo() {
|
||||
class B : Base {
|
||||
constructor() : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo1<!>())
|
||||
constructor(x: Int) : super(this@foo.foo1())
|
||||
constructor(x: Int, y: Int) : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this@B<!>.foo1())
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun Base.foo(): kotlin.Unit
|
||||
|
||||
internal open class Base {
|
||||
public constructor Base(/*0*/ p: kotlin.Any?)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo1(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class Base<T>(p: Any?) {
|
||||
fun foo1(t: T) {}
|
||||
}
|
||||
|
||||
fun Base<Int>.foo() {
|
||||
class B : Base<String> {
|
||||
constructor() : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo1<!>(""))
|
||||
constructor(x: Int) : super(foo1(1))
|
||||
constructor(x: Int, y: Int) : super(this@foo.foo1(12))
|
||||
constructor(x: Int, y: Int, z: Int) : super(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this@B<!>.foo1(""))
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun Base<kotlin.Int>.foo(): kotlin.Unit
|
||||
|
||||
internal open class Base</*0*/ T> {
|
||||
public constructor Base</*0*/ T>(/*0*/ p: kotlin.Any?)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo1(/*0*/ t: T): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
fun foo(x: Outer) = 1
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
val prop = 1
|
||||
}
|
||||
|
||||
constructor(x: Int)
|
||||
constructor(x: Int, y: Int, z: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>Inner<!>().prop + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.Inner().prop) :
|
||||
this(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>Inner<!>().prop + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.Inner().prop)
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ x: Outer): kotlin.Int
|
||||
|
||||
internal final class Outer {
|
||||
public constructor Outer(/*0*/ x: kotlin.Int)
|
||||
public constructor Outer(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
internal final inner class Inner {
|
||||
public constructor Inner()
|
||||
internal final val prop: kotlin.Int = 1
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class A {
|
||||
fun foo() = 1
|
||||
constructor(x: Int)
|
||||
constructor(x: Int, y: Int, z: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo()) :
|
||||
this(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo())
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal final class A {
|
||||
public constructor A(/*0*/ x: kotlin.Int)
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
fun foo(x: A) = 1
|
||||
|
||||
class A {
|
||||
constructor(x: Int)
|
||||
constructor(x: Int, y: Int, z: Int = x + foo(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>) + foo(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this@A<!>)) :
|
||||
this(x + foo(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>) + foo(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this@A<!>))
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ x: A): kotlin.Int
|
||||
|
||||
internal final class A {
|
||||
public constructor A(/*0*/ x: kotlin.Int)
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class A {
|
||||
val prop = 1
|
||||
constructor(x: Int)
|
||||
constructor(x: Int, y: Int, z: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop) :
|
||||
this(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop)
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal final class A {
|
||||
public constructor A(/*0*/ x: kotlin.Int)
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
internal final val prop: kotlin.Int = 1
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B(x: Int)
|
||||
class A : B {
|
||||
val prop = 1
|
||||
constructor(x: Int, y: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL, UNINITIALIZED_VARIABLE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNINITIALIZED_VARIABLE!>prop<!>) :
|
||||
super(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL, UNINITIALIZED_VARIABLE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNINITIALIZED_VARIABLE!>prop<!>)
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package
|
||||
|
||||
internal final class A : B {
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...)
|
||||
internal final val prop: kotlin.Int = 1
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal open class B {
|
||||
public constructor B(/*0*/ x: kotlin.Int)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B(x: Int) {
|
||||
fun foo() = 1
|
||||
}
|
||||
class A : B {
|
||||
constructor(x: Int, y: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo()) :
|
||||
super(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo())
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package
|
||||
|
||||
internal final class A : B {
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal open class B {
|
||||
public constructor B(/*0*/ x: kotlin.Int)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B(x: Int) {
|
||||
open fun foo() = 1
|
||||
}
|
||||
class A : B {
|
||||
override fun foo() = 2
|
||||
constructor(x: Int, y: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo()) :
|
||||
super(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo())
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package
|
||||
|
||||
internal final class A : B {
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal open override /*1*/ fun foo(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal open class B {
|
||||
public constructor B(/*0*/ x: kotlin.Int)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal open fun foo(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B(val prop: Int)
|
||||
class A : B {
|
||||
constructor(x: Int, y: Int = x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.prop) :
|
||||
super(x + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.prop)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package
|
||||
|
||||
internal final class A : B {
|
||||
public constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...)
|
||||
internal final override /*1*/ /*fake_override*/ val prop: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal open class B {
|
||||
public constructor B(/*0*/ prop: kotlin.Int)
|
||||
internal final val prop: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
fun foo(x: Outer) = 1
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
constructor(x: Int)
|
||||
constructor(x: Int, y: Int, z: Int = x + foo(this@Outer)) : this(x + foo(this@Outer))
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ x: Outer): kotlin.Int
|
||||
|
||||
internal final class Outer {
|
||||
public constructor Outer()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
internal final inner class Inner {
|
||||
public constructor Inner(/*0*/ x: kotlin.Int)
|
||||
public constructor Inner(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class Outer {
|
||||
val prop = 1
|
||||
inner class Inner {
|
||||
constructor(x: Int)
|
||||
constructor(x: Int, y: Int, z: Int = x + prop + this@Outer.prop) : this(x + prop + this@Outer.prop)
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package
|
||||
|
||||
internal final class Outer {
|
||||
public constructor Outer()
|
||||
internal final val prop: kotlin.Int = 1
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
internal final inner class Inner {
|
||||
public constructor Inner(/*0*/ x: kotlin.Int)
|
||||
public constructor Inner(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B(open val parentProperty: String)
|
||||
class A : B {
|
||||
val myProp: String = ""
|
||||
override val parentProperty: String = ""
|
||||
constructor(arg: String = <!UNRESOLVED_REFERENCE!>myProp<!>): super(<!UNRESOLVED_REFERENCE!>myProp<!>)
|
||||
constructor(x1: String, arg: String = <!NO_THIS!>this<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>myProp<!>): super(<!NO_THIS!>this<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>myProp<!>)
|
||||
constructor(x1: String, x2: String, arg: String = <!UNRESOLVED_REFERENCE!>parentProperty<!>): super(<!UNRESOLVED_REFERENCE!>parentProperty<!>)
|
||||
constructor(x1: String, x2: String, x3: String, arg: String = <!SUPER_NOT_AVAILABLE!>super<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>parentProperty<!>): super(<!SUPER_NOT_AVAILABLE!>super<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>parentProperty<!>)
|
||||
constructor(x1: String, x2: String, x3: String, x4: String, arg: String = foo(<!NO_THIS!>this<!>)): super(foo(<!NO_THIS!>this<!>))
|
||||
constructor(x1: String, x2: String, x3: String, x4: String, x5: String, arg: String = foo(this<!UNRESOLVED_REFERENCE!>@A<!>)): super(foo(this<!UNRESOLVED_REFERENCE!>@A<!>))
|
||||
}
|
||||
fun foo(x: A) = ""
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ x: A): kotlin.String
|
||||
|
||||
internal final class A : B {
|
||||
public constructor A(/*0*/ arg: kotlin.String = ...)
|
||||
public constructor A(/*0*/ x1: kotlin.String, /*1*/ arg: kotlin.String = ...)
|
||||
public constructor A(/*0*/ x1: kotlin.String, /*1*/ x2: kotlin.String, /*2*/ arg: kotlin.String = ...)
|
||||
public constructor A(/*0*/ x1: kotlin.String, /*1*/ x2: kotlin.String, /*2*/ x3: kotlin.String, /*3*/ arg: kotlin.String = ...)
|
||||
public constructor A(/*0*/ x1: kotlin.String, /*1*/ x2: kotlin.String, /*2*/ x3: kotlin.String, /*3*/ x4: kotlin.String, /*4*/ arg: kotlin.String = ...)
|
||||
public constructor A(/*0*/ x1: kotlin.String, /*1*/ x2: kotlin.String, /*2*/ x3: kotlin.String, /*3*/ x4: kotlin.String, /*4*/ x5: kotlin.String, /*5*/ arg: kotlin.String = ...)
|
||||
internal final val myProp: kotlin.String = ""
|
||||
internal open override /*1*/ val parentProperty: kotlin.String = ""
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
internal open class B {
|
||||
public constructor B(/*0*/ parentProperty: kotlin.String)
|
||||
internal open val parentProperty: kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -10569,6 +10569,9 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/secondaryConstructors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({
|
||||
SecondaryConstructors.HeaderCallChecker.class,
|
||||
})
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SecondaryConstructors extends AbstractJetDiagnosticsTest {
|
||||
public void testAllFilesPresentInSecondaryConstructors() throws Exception {
|
||||
@@ -10719,12 +10722,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberAccessBeforeSuperCall.kt")
|
||||
public void testMemberAccessBeforeSuperCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/memberAccessBeforeSuperCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nestedExtendsInner.kt")
|
||||
public void testNestedExtendsInner() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/nestedExtendsInner.kt");
|
||||
@@ -10838,6 +10835,99 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/varargsInDelegationCallToSecondary.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class HeaderCallChecker extends AbstractJetDiagnosticsTest {
|
||||
@TestMetadata("accessBaseGenericFromInnerExtendingSameBase.kt")
|
||||
public void testAccessBaseGenericFromInnerExtendingSameBase() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/accessBaseGenericFromInnerExtendingSameBase.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("accessBaseGenericFromInnerExtendingSameBase2.kt")
|
||||
public void testAccessBaseGenericFromInnerExtendingSameBase2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/accessBaseGenericFromInnerExtendingSameBase2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("accessBaseWithSameExtension.kt")
|
||||
public void testAccessBaseWithSameExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/accessBaseWithSameExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("accessGenericBaseWithSameExtension.kt")
|
||||
public void testAccessGenericBaseWithSameExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/accessGenericBaseWithSameExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInHeaderCallChecker() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("innerInstanceCreation.kt")
|
||||
public void testInnerInstanceCreation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/innerInstanceCreation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberFunAccess.kt")
|
||||
public void testMemberFunAccess() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/memberFunAccess.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("passingInstance.kt")
|
||||
public void testPassingInstance() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/passingInstance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccess.kt")
|
||||
public void testPropertyAccess() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/propertyAccess.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessUnitialized.kt")
|
||||
public void testPropertyAccessUnitialized() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/propertyAccessUnitialized.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superFunAccess.kt")
|
||||
public void testSuperFunAccess() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccess.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superFunAccessOverriden.kt")
|
||||
public void testSuperFunAccessOverriden() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superFunAccessOverriden.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superPropertyAccess.kt")
|
||||
public void testSuperPropertyAccess() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/superPropertyAccess.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("usingOuterInstance.kt")
|
||||
public void testUsingOuterInstance() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/usingOuterInstance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("usingOuterProperty.kt")
|
||||
public void testUsingOuterProperty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/headerCallChecker/usingOuterProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/senselessComparison")
|
||||
|
||||
+10
@@ -216,6 +216,16 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
|
||||
ReceiverParameterDescriptor substitutedExpectedThis = null;
|
||||
if (dispatchReceiverParameter != null) {
|
||||
// When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
|
||||
// E.g.
|
||||
// class Base { fun foo() }
|
||||
// class Derived : Base
|
||||
// val x: Base
|
||||
// if (x is Derived) {
|
||||
// // `x` shouldn't be marked as smart-cast
|
||||
// // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
|
||||
// x.foo()
|
||||
// }
|
||||
substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
|
||||
if (substitutedExpectedThis == null) {
|
||||
return null;
|
||||
|
||||
@@ -98,4 +98,29 @@ public fun ClassDescriptor.getSuperClassNotAny(): ClassDescriptor? {
|
||||
public fun ClassDescriptor.getSuperClassOrAny(): ClassDescriptor = getSuperClassNotAny() ?: KotlinBuiltIns.getInstance().getAny()
|
||||
|
||||
public val ClassDescriptor.secondaryConstructors: List<ConstructorDescriptor>
|
||||
get() = getConstructors().filterNot { it.isPrimary() }
|
||||
get() = getConstructors().filterNot { it.isPrimary() }
|
||||
|
||||
/**
|
||||
* Returns containing declaration of dispatch receiver for callable adjusted to fake-overridden cases
|
||||
*
|
||||
* open class A {
|
||||
* fun foo() = 1
|
||||
* }
|
||||
* class B : A()
|
||||
*
|
||||
* for A.foo -> returns A (dispatch receiver parameter is A)
|
||||
* for B.foo -> returns B (dispatch receiver parameter is still A, but it's fake-overridden in B, so it's containing declaration is B)
|
||||
*
|
||||
* class Outer {
|
||||
* inner class Inner()
|
||||
* }
|
||||
*
|
||||
* for constructor of Outer.Inner -> returns Outer (dispatch receiver parameter is Outer, but it's containing declaration is Inner)
|
||||
*
|
||||
*/
|
||||
public fun CallableDescriptor.getOwnerForEffectiveDispatchReceiverParameter(): DeclarationDescriptor? {
|
||||
if (this is CallableMemberDescriptor && getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
return getContainingDeclaration()
|
||||
}
|
||||
return getDispatchReceiverParameter()?.getContainingDeclaration()
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@ class A(val prop: Int, arg: Int) {
|
||||
fun foo() = 1
|
||||
}
|
||||
|
||||
// EXIST: topLevel, abc
|
||||
// ABSENT: arg, local, prop, another, foo
|
||||
// EXIST: topLevel, abc, prop, another, foo
|
||||
// ABSENT: arg, local
|
||||
|
||||
@@ -9,5 +9,5 @@ class A(val prop: Int, arg: Int) {
|
||||
fun foo() = 1
|
||||
}
|
||||
|
||||
// EXIST: abc, topLevel
|
||||
// ABSENT: arg, local, prop, another, foo
|
||||
// EXIST: abc, topLevel, prop, another, foo
|
||||
// ABSENT: arg, local
|
||||
|
||||
+2
-2
@@ -9,5 +9,5 @@ class A(val prop: Int, arg: Int) {
|
||||
fun foo() = 1
|
||||
}
|
||||
|
||||
// EXIST: abc, topLevel, x
|
||||
// ABSENT: arg, local, prop, another, foo
|
||||
// EXIST: abc, topLevel, x, prop, another, foo
|
||||
// ABSENT: arg, local
|
||||
|
||||
Reference in New Issue
Block a user