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:
Denis Zharkov
2015-03-26 18:02:30 +03:00
parent b939530a5c
commit 418034add3
50 changed files with 690 additions and 162 deletions
@@ -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;
}
}
@@ -33,9 +33,6 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor {
@NotNull
JetScope getScopeForInitializerResolution();
@NotNull
JetScope getScopeForSecondaryConstructorHeaderResolution();
@NotNull
JetScope getScopeForMemberLookup();
@@ -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
@@ -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()
}
@@ -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
@@ -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
@@ -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);
}
@@ -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());
}
}
}
@@ -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))
}
}
@@ -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
}
}
@@ -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))
}
}
@@ -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
}
}
@@ -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())
}
}
@@ -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
}
@@ -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(""))
}
}
@@ -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
}
@@ -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)
}
@@ -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
}
}
@@ -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())
}
@@ -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
}
@@ -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<!>))
}
@@ -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
}
@@ -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)
}
@@ -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
}
@@ -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<!>)
}
@@ -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
}
@@ -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())
}
@@ -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
}
@@ -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())
}
@@ -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
}
@@ -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)
}
@@ -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
}
@@ -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))
}
}
@@ -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
}
}
@@ -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)
}
}
@@ -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
}
}
@@ -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) = ""
@@ -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")
@@ -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
@@ -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