KT-1865 Calls with default argument values are generated incorrectly

#KT-1865 Fixed
This commit is contained in:
pTalanov
2012-05-05 16:51:24 +04:00
parent 68680f702b
commit ea6076f638
4 changed files with 73 additions and 48 deletions
@@ -125,4 +125,8 @@ public final class MiscTest extends AbstractExpressionTest {
public void testExtensionLiteralCalledInsideExtensionFunction() throws Exception { public void testExtensionLiteralCalledInsideExtensionFunction() throws Exception {
checkFooBoxIsTrue("extensionLiteralCalledInsideExtensionFunction.kt"); checkFooBoxIsTrue("extensionLiteralCalledInsideExtensionFunction.kt");
} }
public void testKt1865() throws Exception {
checkFooBoxIsTrue("KT-1865.kt");
}
} }
@@ -51,20 +51,20 @@ public abstract class AbstractCallExpressionTranslator extends AbstractTranslato
protected final CallType callType; protected final CallType callType;
protected AbstractCallExpressionTranslator(@NotNull JetCallExpression expression, protected AbstractCallExpressionTranslator(@NotNull JetCallExpression expression,
@Nullable JsExpression receiver, @Nullable JsExpression receiver,
@NotNull CallType type, @NotNull TranslationContext context) { @NotNull CallType type, @NotNull TranslationContext context) {
super(context); super(context);
this.expression = expression; this.expression = expression;
this.resolvedCall = getResolvedCallForCallExpression(bindingContext(), expression); this.resolvedCall = getResolvedCallForCallExpression(bindingContext(), expression);
this.receiver = receiver; this.receiver = receiver;
callType = type; this.callType = type;
} }
abstract public boolean shouldWrapVarargInArray(); abstract public boolean shouldWrapVarargInArray();
@NotNull @NotNull
protected List<JsExpression> translateSingleArgument(@NotNull ResolvedValueArgument actualArgument, protected List<JsExpression> translateSingleArgument(@NotNull ResolvedValueArgument actualArgument,
@NotNull ValueParameterDescriptor parameterDescriptor) { @NotNull ValueParameterDescriptor parameterDescriptor) {
List<ValueArgument> valueArguments = actualArgument.getArguments(); List<ValueArgument> valueArguments = actualArgument.getArguments();
if (actualArgument instanceof VarargValueArgument) { if (actualArgument instanceof VarargValueArgument) {
return translateVarargArgument(valueArguments); return translateVarargArgument(valueArguments);
@@ -55,41 +55,41 @@ public final class BindingUtils {
DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
assert descriptor != null; assert descriptor != null;
assert descriptorClass.isInstance(descriptor) assert descriptorClass.isInstance(descriptor)
: expression.toString() + " expected to have of type" + descriptorClass.toString(); : expression.toString() + " expected to have of type" + descriptorClass.toString();
//noinspection unchecked //noinspection unchecked
return (D)descriptor; return (D) descriptor;
} }
@NotNull @NotNull
public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context, public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context,
@NotNull JetClassOrObject declaration) { @NotNull JetClassOrObject declaration) {
return getDescriptorForExpression(context, declaration, ClassDescriptor.class); return getDescriptorForExpression(context, declaration, ClassDescriptor.class);
} }
@NotNull @NotNull
public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context, public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
@NotNull JetFile declaration) { @NotNull JetFile declaration) {
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor namespaceDescriptor =
context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration)); context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, JetPsiUtil.getFQName(declaration));
assert namespaceDescriptor != null : "File should have a namespace descriptor."; assert namespaceDescriptor != null : "File should have a namespace descriptor.";
return namespaceDescriptor; return namespaceDescriptor;
} }
@NotNull @NotNull
public static FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context, public static FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
@NotNull JetDeclarationWithBody declaration) { @NotNull JetDeclarationWithBody declaration) {
return getDescriptorForExpression(context, declaration, FunctionDescriptor.class); return getDescriptorForExpression(context, declaration, FunctionDescriptor.class);
} }
@NotNull @NotNull
public static PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context, public static PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context,
@NotNull JetProperty declaration) { @NotNull JetProperty declaration) {
return getDescriptorForExpression(context, declaration, PropertyDescriptor.class); return getDescriptorForExpression(context, declaration, PropertyDescriptor.class);
} }
@NotNull @NotNull
public static JetClass getClassForDescriptor(@NotNull BindingContext context, public static JetClass getClassForDescriptor(@NotNull BindingContext context,
@NotNull ClassDescriptor descriptor) { @NotNull ClassDescriptor descriptor) {
JetClass result = (JetClass) BindingContextUtils.classDescriptorToDeclaration(context, descriptor); JetClass result = (JetClass) BindingContextUtils.classDescriptorToDeclaration(context, descriptor);
if (result == null) { if (result == null) {
throw new IllegalStateException("JetClass not found for " + descriptor); throw new IllegalStateException("JetClass not found for " + descriptor);
@@ -99,15 +99,15 @@ public final class BindingUtils {
@NotNull @NotNull
public static JetFunction getFunctionForDescriptor(@NotNull BindingContext context, public static JetFunction getFunctionForDescriptor(@NotNull BindingContext context,
@NotNull SimpleFunctionDescriptor descriptor) { @NotNull SimpleFunctionDescriptor descriptor) {
PsiElement result = BindingContextUtils.callableDescriptorToDeclaration(context, descriptor); PsiElement result = BindingContextUtils.callableDescriptorToDeclaration(context, descriptor);
assert result instanceof JetFunction : "SimpleFunctionDescriptor should have declaration of type JetFunction"; assert result instanceof JetFunction : "SimpleFunctionDescriptor should have declaration of type JetFunction";
return (JetFunction)result; return (JetFunction) result;
} }
@NotNull @NotNull
public static List<JetDeclaration> getDeclarationsForNamespace(@NotNull BindingContext bindingContext, public static List<JetDeclaration> getDeclarationsForNamespace(@NotNull BindingContext bindingContext,
@NotNull NamespaceDescriptor namespace) { @NotNull NamespaceDescriptor namespace) {
List<JetDeclaration> declarations = new ArrayList<JetDeclaration>(); List<JetDeclaration> declarations = new ArrayList<JetDeclaration>();
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespace)) { for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespace)) {
if (descriptor instanceof NamespaceDescriptor) { if (descriptor instanceof NamespaceDescriptor) {
@@ -123,22 +123,22 @@ public final class BindingUtils {
@Nullable @Nullable
private static JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context, private static JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context,
@NotNull DeclarationDescriptor descriptor) { @NotNull DeclarationDescriptor descriptor) {
PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor); PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor);
if (result == null) { if (result == null) {
//TODO: never get there //TODO: never get there
return null; return null;
} }
assert result instanceof JetDeclaration : "Descriptor should correspond to an element."; assert result instanceof JetDeclaration : "Descriptor should correspond to an element.";
return (JetDeclaration)result; return (JetDeclaration) result;
} }
@NotNull @NotNull
private static JetParameter getParameterForDescriptor(@NotNull BindingContext context, private static JetParameter getParameterForDescriptor(@NotNull BindingContext context,
@NotNull ValueParameterDescriptor descriptor) { @NotNull ValueParameterDescriptor descriptor) {
PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor); PsiElement result = BindingContextUtils.descriptorToDeclaration(context, descriptor);
assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter."; assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter.";
return (JetParameter)result; return (JetParameter) result;
} }
public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) { public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) {
@@ -155,7 +155,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static JetType getTypeByReference(@NotNull BindingContext context, public static JetType getTypeByReference(@NotNull BindingContext context,
@NotNull JetTypeReference typeReference) { @NotNull JetTypeReference typeReference) {
JetType result = context.get(BindingContext.TYPE, typeReference); JetType result = context.get(BindingContext.TYPE, typeReference);
assert result != null : "TypeReference should reference a type"; assert result != null : "TypeReference should reference a type";
return result; return result;
@@ -163,29 +163,29 @@ public final class BindingUtils {
@NotNull @NotNull
public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context, public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
@NotNull JetTypeReference typeReference) { @NotNull JetTypeReference typeReference) {
return getClassDescriptorForType(getTypeByReference(context, typeReference)); return getClassDescriptorForType(getTypeByReference(context, typeReference));
} }
@Nullable @Nullable
public static PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context, public static PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context,
@NotNull JetParameter parameter) { @NotNull JetParameter parameter) {
return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
} }
@Nullable @Nullable
public static JetProperty getPropertyForDescriptor(@NotNull BindingContext context, public static JetProperty getPropertyForDescriptor(@NotNull BindingContext context,
@NotNull PropertyDescriptor property) { @NotNull PropertyDescriptor property) {
PsiElement result = BindingContextUtils.descriptorToDeclaration(context, property); PsiElement result = BindingContextUtils.descriptorToDeclaration(context, property);
if (!(result instanceof JetProperty)) { if (!(result instanceof JetProperty)) {
return null; return null;
} }
return (JetProperty)result; return (JetProperty) result;
} }
@NotNull @NotNull
public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context, public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
@NotNull JetReferenceExpression reference) { @NotNull JetReferenceExpression reference) {
DeclarationDescriptor referencedDescriptor = getNullableDescriptorForReferenceExpression(context, reference); DeclarationDescriptor referencedDescriptor = getNullableDescriptorForReferenceExpression(context, reference);
assert referencedDescriptor != null : "Reference expression must reference a descriptor."; assert referencedDescriptor != null : "Reference expression must reference a descriptor.";
return referencedDescriptor; return referencedDescriptor;
@@ -194,7 +194,7 @@ public final class BindingUtils {
//TODO: remove? //TODO: remove?
@Nullable @Nullable
public static DeclarationDescriptor getNullableDescriptorForReferenceExpression(@NotNull BindingContext context, public static DeclarationDescriptor getNullableDescriptorForReferenceExpression(@NotNull BindingContext context,
@NotNull JetReferenceExpression reference) { @NotNull JetReferenceExpression reference) {
return context.get(BindingContext.REFERENCE_TARGET, reference); return context.get(BindingContext.REFERENCE_TARGET, reference);
} }
@@ -204,7 +204,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context, public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
@NotNull JetExpression expression) { @NotNull JetExpression expression) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression); ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression);
assert resolvedCall != null : "Must resolve to a call."; assert resolvedCall != null : "Must resolve to a call.";
return resolvedCall; return resolvedCall;
@@ -212,18 +212,18 @@ public final class BindingUtils {
@NotNull @NotNull
public static ResolvedCall<?> getResolvedCallForProperty(@NotNull BindingContext context, public static ResolvedCall<?> getResolvedCallForProperty(@NotNull BindingContext context,
@NotNull JetExpression expression) { @NotNull JetExpression expression) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression); ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression);
assert resolvedCall != null : "Must resolve to a call."; assert resolvedCall != null : "Must resolve to a call.";
if (resolvedCall instanceof VariableAsFunctionResolvedCall) { if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
return ((VariableAsFunctionResolvedCall)resolvedCall).getVariableCall(); return ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall();
} }
return resolvedCall; return resolvedCall;
} }
@NotNull @NotNull
public static ResolvedCall<?> getResolvedCallForCallExpression(@NotNull BindingContext context, public static ResolvedCall<?> getResolvedCallForCallExpression(@NotNull BindingContext context,
@NotNull JetCallExpression expression) { @NotNull JetCallExpression expression) {
JetExpression calleeExpression = PsiUtils.getCallee(expression); JetExpression calleeExpression = PsiUtils.getCallee(expression);
return getResolvedCall(context, calleeExpression); return getResolvedCall(context, calleeExpression);
} }
@@ -237,20 +237,20 @@ public final class BindingUtils {
@Nullable @Nullable
public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context, public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context,
@NotNull JetOperationExpression expression) { @NotNull JetOperationExpression expression) {
DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression
(context, expression.getOperationReference()); (context, expression.getOperationReference());
if (descriptorForReferenceExpression == null) return null; if (descriptorForReferenceExpression == null) return null;
assert descriptorForReferenceExpression instanceof FunctionDescriptor assert descriptorForReferenceExpression instanceof FunctionDescriptor
: "Operation should resolve to function descriptor."; : "Operation should resolve to function descriptor.";
return (FunctionDescriptor)descriptorForReferenceExpression; return (FunctionDescriptor) descriptorForReferenceExpression;
} }
@NotNull @NotNull
public static DeclarationDescriptor getDescriptorForElement(@NotNull BindingContext context, public static DeclarationDescriptor getDescriptorForElement(@NotNull BindingContext context,
@NotNull PsiElement element) { @NotNull PsiElement element) {
DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
assert descriptor != null : element + " doesn't have a descriptor."; assert descriptor != null : element + " doesn't have a descriptor.";
return descriptor; return descriptor;
@@ -267,17 +267,27 @@ public final class BindingUtils {
@NotNull @NotNull
public static JetExpression getDefaultArgument(@NotNull BindingContext context, public static JetExpression getDefaultArgument(@NotNull BindingContext context,
@NotNull ValueParameterDescriptor parameterDescriptor) { @NotNull ValueParameterDescriptor parameterDescriptor) {
assert parameterDescriptor.hasDefaultValue() : "Unsupplied parameter must have default value."; ValueParameterDescriptor descriptorWhichDeclaresDefaultValue = getOriginalDescriptorWhichDeclaresDefaultValue(parameterDescriptor);
JetParameter psiParameter = getParameterForDescriptor(context, parameterDescriptor); JetParameter psiParameter = getParameterForDescriptor(context, descriptorWhichDeclaresDefaultValue);
JetExpression defaultValue = psiParameter.getDefaultValue(); JetExpression defaultValue = psiParameter.getDefaultValue();
assert defaultValue != null : "No default value found in PSI."; assert defaultValue != null : "No default value found in PSI.";
return defaultValue; return defaultValue;
} }
private static ValueParameterDescriptor getOriginalDescriptorWhichDeclaresDefaultValue(
@NotNull ValueParameterDescriptor parameterDescriptor) {
ValueParameterDescriptor result = parameterDescriptor;
assert result.hasDefaultValue() : "Unsupplied parameter must have default value.";
while (!result.declaresDefaultValue()) {
result = result.getOverriddenDescriptors().iterator().next();
}
return result;
}
@NotNull @NotNull
public static FunctionDescriptor getIteratorFunction(@NotNull BindingContext context, public static FunctionDescriptor getIteratorFunction(@NotNull BindingContext context,
@NotNull JetExpression rangeExpression) { @NotNull JetExpression rangeExpression) {
FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_ITERATOR, rangeExpression); FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_ITERATOR, rangeExpression);
assert functionDescriptor != null : "Range expression must have a descriptor for iterator function."; assert functionDescriptor != null : "Range expression must have a descriptor for iterator function.";
return functionDescriptor; return functionDescriptor;
@@ -285,7 +295,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static FunctionDescriptor getNextFunction(@NotNull BindingContext context, public static FunctionDescriptor getNextFunction(@NotNull BindingContext context,
@NotNull JetExpression rangeExpression) { @NotNull JetExpression rangeExpression) {
FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_NEXT, rangeExpression); FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_NEXT, rangeExpression);
assert functionDescriptor != null : "Range expression must have a descriptor for next function."; assert functionDescriptor != null : "Range expression must have a descriptor for next function.";
return functionDescriptor; return functionDescriptor;
@@ -293,7 +303,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static CallableDescriptor getHasNextCallable(@NotNull BindingContext context, public static CallableDescriptor getHasNextCallable(@NotNull BindingContext context,
@NotNull JetExpression rangeExpression) { @NotNull JetExpression rangeExpression) {
CallableDescriptor hasNextDescriptor = context.get(BindingContext.LOOP_RANGE_HAS_NEXT, rangeExpression); CallableDescriptor hasNextDescriptor = context.get(BindingContext.LOOP_RANGE_HAS_NEXT, rangeExpression);
assert hasNextDescriptor != null : "Range expression must have a descriptor for hasNext function or property."; assert hasNextDescriptor != null : "Range expression must have a descriptor for hasNext function or property.";
return hasNextDescriptor; return hasNextDescriptor;
@@ -301,7 +311,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static PropertyDescriptor getPropertyDescriptorForObjectDeclaration(@NotNull BindingContext context, public static PropertyDescriptor getPropertyDescriptorForObjectDeclaration(@NotNull BindingContext context,
@NotNull JetObjectDeclarationName name) { @NotNull JetObjectDeclarationName name) {
PropertyDescriptor propertyDescriptor = context.get(BindingContext.OBJECT_DECLARATION, name); PropertyDescriptor propertyDescriptor = context.get(BindingContext.OBJECT_DECLARATION, name);
assert propertyDescriptor != null; assert propertyDescriptor != null;
return propertyDescriptor; return propertyDescriptor;
@@ -309,7 +319,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static Set<NamespaceDescriptor> getAllNonNativeNamespaceDescriptors(@NotNull BindingContext context, public static Set<NamespaceDescriptor> getAllNonNativeNamespaceDescriptors(@NotNull BindingContext context,
@NotNull List<JetFile> files) { @NotNull List<JetFile> files) {
Set<NamespaceDescriptor> descriptorSet = Sets.newHashSet(); Set<NamespaceDescriptor> descriptorSet = Sets.newHashSet();
for (JetFile file : files) { for (JetFile file : files) {
//TODO: can't be //TODO: can't be
@@ -323,7 +333,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static JetType getTypeForExpression(@NotNull BindingContext context, public static JetType getTypeForExpression(@NotNull BindingContext context,
@NotNull JetExpression expression) { @NotNull JetExpression expression) {
JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression);
assert type != null; assert type != null;
return type; return type;
@@ -331,8 +341,8 @@ public final class BindingUtils {
@NotNull @NotNull
public static ResolvedCall<FunctionDescriptor> getResolvedCallForArrayAccess(@NotNull BindingContext context, public static ResolvedCall<FunctionDescriptor> getResolvedCallForArrayAccess(@NotNull BindingContext context,
@NotNull JetArrayAccessExpression arrayAccessExpression, @NotNull JetArrayAccessExpression arrayAccessExpression,
boolean isGet) { boolean isGet) {
ResolvedCall<FunctionDescriptor> resolvedCall = context.get(isGet ResolvedCall<FunctionDescriptor> resolvedCall = context.get(isGet
? INDEXED_LVALUE_GET ? INDEXED_LVALUE_GET
: INDEXED_LVALUE_SET, arrayAccessExpression); : INDEXED_LVALUE_SET, arrayAccessExpression);
@@ -341,9 +351,9 @@ public final class BindingUtils {
} }
public static ConstructorDescriptor getConstructor(@NotNull BindingContext bindingContext, public static ConstructorDescriptor getConstructor(@NotNull BindingContext bindingContext,
@NotNull JetClassOrObject declaration) { @NotNull JetClassOrObject declaration) {
ConstructorDescriptor primaryConstructor = ConstructorDescriptor primaryConstructor =
getClassDescriptor(bindingContext, declaration).getUnsubstitutedPrimaryConstructor(); getClassDescriptor(bindingContext, declaration).getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null : "Traits do not have initialize methods."; assert primaryConstructor != null : "Traits do not have initialize methods.";
return primaryConstructor; return primaryConstructor;
} }
@@ -0,0 +1,11 @@
package foo
open class A {
open fun foo(a : Int = 1) = a
}
class B : A() {
override fun foo(a : Int) = a + 1
}
fun box() = (B().foo() == 2)