Record resolved delegated constructor in trace

This commit is contained in:
Denis Zharkov
2015-02-12 18:38:59 +03:00
parent 7f20c4a237
commit 5388bd7cdc
2 changed files with 31 additions and 3 deletions
@@ -205,6 +205,8 @@ public interface BindingContext {
*/
WritableSlice<PsiElement, SimpleFunctionDescriptor> FUNCTION = Slices.<PsiElement, SimpleFunctionDescriptor>sliceBuilder().build();
WritableSlice<PsiElement, ConstructorDescriptor> CONSTRUCTOR = Slices.<PsiElement, ConstructorDescriptor>sliceBuilder().build();
WritableSlice<ConstructorDescriptor, ResolvedCall<ConstructorDescriptor>> CONSTRUCTOR_RESOLVED_DELEGATION_CALL =
Slices.<ConstructorDescriptor, ResolvedCall<ConstructorDescriptor>>sliceBuilder().build();
WritableSlice<PsiElement, VariableDescriptor> VARIABLE = Slices.<PsiElement, VariableDescriptor>sliceBuilder().build();
WritableSlice<JetParameter, VariableDescriptor> VALUE_PARAMETER = Slices.<JetParameter, VariableDescriptor>sliceBuilder().build();
WritableSlice<JetPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR =
@@ -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.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
@@ -43,9 +44,9 @@ import java.util.*;
import static org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.resolve.BindingContext.CONSTRUCTOR_RESOLVED_DELEGATION_CALL;
import static org.jetbrains.kotlin.resolve.BindingContext.DEFERRED_TYPE;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.kotlin.types.TypeUtils.dependsOnTypeConstructors;
public class BodyResolver {
private ScriptBodyResolver scriptBodyResolverResolver;
@@ -162,10 +163,15 @@ public class BodyResolver {
if (call == null || call.getCalleeExpression() == null) return;
JetType superClassType = DescriptorUtils.getSuperClassType(descriptor.getContainingDeclaration());
callResolver.resolveFunctionCall(
OverloadResolutionResults<?> results = callResolver.resolveFunctionCall(
trace, scope,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
superClassType != null ? superClassType : NO_EXPECTED_TYPE, c.getOuterDataFlowInfo(), false);
superClassType != null ? superClassType : NO_EXPECTED_TYPE,
c.getOuterDataFlowInfo(), false);
if (results.isSuccess()) {
recordConstructorDelegationCall(trace, descriptor, results.getResultingCall());
}
}
public void resolveBodies(@NotNull BodiesResolveContext c) {
@@ -201,6 +207,7 @@ public class BodyResolver {
final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap();
final ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1];
JetVisitorVoid visitor = new JetVisitorVoid() {
private void recordSupertype(JetTypeReference typeReference, JetType supertype) {
if (supertype == null) return;
@@ -256,6 +263,13 @@ public class BodyResolver {
if (classDescriptor.getKind() == ClassKind.TRAIT) {
trace.report(CONSTRUCTOR_IN_TRAIT.on(elementToMark));
}
// allow only one delegating constructor
if (primaryConstructorDelegationCall[0] == null) {
primaryConstructorDelegationCall[0] = results.getResultingCall();
}
else {
primaryConstructorDelegationCall[0] = null;
}
}
}
else {
@@ -303,9 +317,21 @@ public class BodyResolver {
? Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor())
: Collections.<TypeConstructor>emptySet();
if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]);
}
checkSupertypeList(descriptor, supertypes, parentEnum);
}
private static void recordConstructorDelegationCall(
@NotNull BindingTrace trace,
@NotNull ConstructorDescriptor constructor,
@NotNull ResolvedCall<?> call
) {
//noinspection unchecked
trace.record(CONSTRUCTOR_RESOLVED_DELEGATION_CALL, constructor, (ResolvedCall<ConstructorDescriptor>) call);
}
// allowedFinalSupertypes typically contains a enum type of which supertypeOwner is an entry
private void checkSupertypeList(
@NotNull ClassDescriptor supertypeOwner,