rewrite owner when copying FunctionDescriptor from supertype scope
that fixes invocation: >>> StringBuilder.length() that was compiled to >>> invokevirtual CharSequence.length() and now compiles to >>> invokevirtual StringBuilder.length() Essentially patch rewrites FunctionDescriptor.containingDeclaration when FunctionDescriptor is copied to subclass scope. FunctionDescriptor now has kind field that can be * DECLARATION (for "real" function, maybe abstract) * DELEGATION * FAKE_OVERRIDE (created for functions from supertypes) All tests pass although some parts of code are buggy and ugly. Random comments about this patch: * FunctionDescriptor.overrides point to function descriptors of supertype scopes * Filling of memberScope with supertypes is moved to OverrideResolver * ExpressionCodegen.intermediateValueForProperty must be rewritten * Patch adds not nice REDECLARATION reports (see compiler/testData/diagnostics/tests/*). Will be fixed later.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
@@ -16,24 +17,38 @@ import java.util.List;
|
|||||||
* @author alex.tkacman
|
* @author alex.tkacman
|
||||||
*/
|
*/
|
||||||
public class CallableMethod implements Callable {
|
public class CallableMethod implements Callable {
|
||||||
private String owner;
|
@NotNull
|
||||||
|
private final String owner;
|
||||||
|
@NotNull
|
||||||
|
private final String defaultImplOwner;
|
||||||
|
@NotNull
|
||||||
|
private final String defaultImplParam;
|
||||||
private final JvmMethodSignature signature;
|
private final JvmMethodSignature signature;
|
||||||
private int invokeOpcode;
|
private final int invokeOpcode;
|
||||||
private ClassDescriptor thisClass = null;
|
private ClassDescriptor thisClass = null;
|
||||||
|
|
||||||
private CallableDescriptor receiverFunction = null;
|
private CallableDescriptor receiverFunction = null;
|
||||||
private Type generateCalleeType = null;
|
private Type generateCalleeType = null;
|
||||||
|
|
||||||
public CallableMethod(String owner, JvmMethodSignature signature, int invokeOpcode) {
|
public CallableMethod(@NotNull String owner, @NotNull String defaultImplOwner, @NotNull String defaultImplParam,
|
||||||
|
JvmMethodSignature signature, int invokeOpcode) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
this.defaultImplOwner = defaultImplOwner;
|
||||||
|
this.defaultImplParam = defaultImplParam;
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.invokeOpcode = invokeOpcode;
|
this.invokeOpcode = invokeOpcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public String getOwner() {
|
public String getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getDefaultImplParam() {
|
||||||
|
return defaultImplParam;
|
||||||
|
}
|
||||||
|
|
||||||
public JvmMethodSignature getSignature() {
|
public JvmMethodSignature getSignature() {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
@@ -75,16 +90,20 @@ public class CallableMethod implements Callable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void invokeWithDefault(InstructionAdapter v, int mask) {
|
public void invokeWithDefault(InstructionAdapter v, int mask) {
|
||||||
|
if (defaultImplOwner.length() == 0 || defaultImplParam.length() == 0) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
v.iconst(mask);
|
v.iconst(mask);
|
||||||
String desc = getSignature().getAsmMethod().getDescriptor().replace(")", "I)");
|
String desc = getSignature().getAsmMethod().getDescriptor().replace(")", "I)");
|
||||||
if("<init>".equals(getSignature().getAsmMethod().getName())) {
|
if("<init>".equals(getSignature().getAsmMethod().getName())) {
|
||||||
v.visitMethodInsn(Opcodes.INVOKESPECIAL, getOwner(), "<init>", desc);
|
v.visitMethodInsn(Opcodes.INVOKESPECIAL, defaultImplOwner, "<init>", desc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
|
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
|
||||||
desc = desc.replace("(", "(L" + getOwner() + ";");
|
desc = desc.replace("(", "(L" + defaultImplParam + ";");
|
||||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + JvmAbi.TRAIT_IMPL_SUFFIX
|
v.visitMethodInsn(Opcodes.INVOKESTATIC, defaultImplOwner,
|
||||||
: getOwner(), getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
|
getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
|
public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
|
||||||
JvmMethodSignature descriptor = erasedInvokeSignature(fd);
|
JvmMethodSignature descriptor = erasedInvokeSignature(fd);
|
||||||
String owner = getInternalClassName(fd);
|
String owner = getInternalClassName(fd);
|
||||||
final CallableMethod result = new CallableMethod(owner, descriptor, INVOKEVIRTUAL);
|
final CallableMethod result = new CallableMethod(owner, "", "", descriptor, INVOKEVIRTUAL);
|
||||||
if (fd.getReceiverParameter().exists()) {
|
if (fd.getReceiverParameter().exists()) {
|
||||||
result.setNeedsReceiver(fd);
|
result.setNeedsReceiver(fd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,8 +211,9 @@ public abstract class CodegenContext {
|
|||||||
|
|
||||||
if(descriptor instanceof NamedFunctionDescriptor) {
|
if(descriptor instanceof NamedFunctionDescriptor) {
|
||||||
NamedFunctionDescriptorImpl myAccessor = new NamedFunctionDescriptorImpl(contextType,
|
NamedFunctionDescriptorImpl myAccessor = new NamedFunctionDescriptorImpl(contextType,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
descriptor.getName() + "$bridge$" + accessors.size());
|
descriptor.getName() + "$bridge$" + accessors.size(),
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
FunctionDescriptor fd = (NamedFunctionDescriptor) descriptor;
|
FunctionDescriptor fd = (NamedFunctionDescriptor) descriptor;
|
||||||
myAccessor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
myAccessor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
||||||
fd.getExpectedThisObject(),
|
fd.getExpectedThisObject(),
|
||||||
@@ -231,7 +232,8 @@ public abstract class CodegenContext {
|
|||||||
pd.getVisibility(),
|
pd.getVisibility(),
|
||||||
pd.isVar(),
|
pd.isVar(),
|
||||||
pd.isObjectDeclaration(),
|
pd.isObjectDeclaration(),
|
||||||
pd.getName() + "$bridge$" + accessors.size()
|
pd.getName() + "$bridge$" + accessors.size(),
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
|
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
|
||||||
myAccessor.setType(pd.getOutType(), Collections.<TypeParameterDescriptor>emptyList(), pd.getExpectedThisObject(), receiverType);
|
myAccessor.setType(pd.getOutType(), Collections.<TypeParameterDescriptor>emptyList(), pd.getExpectedThisObject(), receiverType);
|
||||||
@@ -239,13 +241,13 @@ public abstract class CodegenContext {
|
|||||||
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
|
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
|
||||||
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
|
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
|
||||||
myAccessor.getVisibility(),
|
myAccessor.getVisibility(),
|
||||||
false, false);
|
false, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
pgd.initialize(myAccessor.getOutType());
|
pgd.initialize(myAccessor.getOutType());
|
||||||
|
|
||||||
PropertySetterDescriptor psd = new PropertySetterDescriptor(
|
PropertySetterDescriptor psd = new PropertySetterDescriptor(
|
||||||
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
|
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
|
||||||
myAccessor.getVisibility(),
|
myAccessor.getVisibility(),
|
||||||
false, false);
|
false, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
myAccessor.initialize(pgd, psd);
|
myAccessor.initialize(pgd, psd);
|
||||||
accessor = myAccessor;
|
accessor = myAccessor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ public class CodegenUtil {
|
|||||||
NamedFunctionDescriptorImpl invokeDescriptor = new NamedFunctionDescriptorImpl(
|
NamedFunctionDescriptorImpl invokeDescriptor = new NamedFunctionDescriptorImpl(
|
||||||
fd.getExpectedThisObject().exists() ? JetStandardClasses.getReceiverFunction(arity) : JetStandardClasses.getFunction(arity),
|
fd.getExpectedThisObject().exists() ? JetStandardClasses.getReceiverFunction(arity) : JetStandardClasses.getFunction(arity),
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
"invoke");
|
"invoke",
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
|
|
||||||
invokeDescriptor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
invokeDescriptor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
||||||
fd.getExpectedThisObject(),
|
fd.getExpectedThisObject(),
|
||||||
|
|||||||
@@ -36,7 +36,16 @@ public class CompilationException extends RuntimeException {
|
|||||||
col = -1;
|
col = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Internal error: (" + (line+1) + "," + col + ") " + (getCause().getMessage() != null ? getCause().getMessage() : getCause().toString()) + "\n@" + getCause().getStackTrace()[0].getFileName() + ":" + getCause().getStackTrace()[0].getLineNumber();
|
String s2 = getCause().getMessage() != null ? getCause().getMessage() : getCause().toString();
|
||||||
|
return "Internal error: (" + (line+1) + "," + col + ") " + s2 + "\n@" + where();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String where() {
|
||||||
|
if (getCause().getStackTrace().length > 0) {
|
||||||
|
return getCause().getStackTrace()[0].getFileName() + ":" + getCause().getStackTrace()[0].getLineNumber();
|
||||||
|
} else {
|
||||||
|
return "far away in cyberspace";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -983,7 +983,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else if (descriptor instanceof PropertyDescriptor) {
|
else if (descriptor instanceof PropertyDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
|
|
||||||
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
PsiElement declaration = null;
|
||||||
|
if (((PropertyDescriptor) descriptor).getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
|
declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||||
|
}
|
||||||
if (declaration instanceof JetObjectDeclarationName) {
|
if (declaration instanceof JetObjectDeclarationName) {
|
||||||
// todo: we have property here but not in containing class/namespace
|
// todo: we have property here but not in containing class/namespace
|
||||||
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(declaration, JetObjectDeclaration.class);
|
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(declaration, JetObjectDeclaration.class);
|
||||||
@@ -1013,7 +1016,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
|
final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
|
||||||
if(!directToField && resolvedCall != null && !isSuper) {
|
if(!directToField && resolvedCall != null && !isSuper) {
|
||||||
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic? receiver.type : Type.getObjectType(iValue.owner), v);
|
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic? receiver.type : Type.getObjectType(iValue.methodOwner), v);
|
||||||
pushTypeArguments(resolvedCall);
|
pushTypeArguments(resolvedCall);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1097,7 +1100,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void invokeFunctionNoParams(FunctionDescriptor functionDescriptor, Type type, InstructionAdapter v) {
|
public void invokeFunctionNoParams(FunctionDescriptor functionDescriptor, Type type, InstructionAdapter v) {
|
||||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = functionDescriptor.getOriginal().getContainingDeclaration();
|
||||||
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
||||||
functionDescriptor = functionDescriptor.getOriginal();
|
functionDescriptor = functionDescriptor.getOriginal();
|
||||||
String owner;
|
String owner;
|
||||||
@@ -1190,18 +1193,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int invokeOpcode;
|
||||||
|
|
||||||
String owner;
|
String owner;
|
||||||
|
String ownerParam;
|
||||||
boolean isInterface;
|
boolean isInterface;
|
||||||
if (isInsideClass || isStatic) {
|
if (isInsideClass || isStatic || propertyDescriptor.getGetter() == null) {
|
||||||
owner = typeMapper.getOwner(propertyDescriptor, contextKind());
|
owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind());
|
||||||
isInterface = false;
|
isInterface = false;
|
||||||
|
invokeOpcode = isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
|
||||||
isInterface = CodegenUtil.isInterface(containingDeclaration);
|
isInterface = CodegenUtil.isInterface(containingDeclaration);
|
||||||
|
// TODO ugly
|
||||||
|
CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind());
|
||||||
|
invokeOpcode = callableMethod.getInvokeOpcode();
|
||||||
|
owner = callableMethod.getOwner();
|
||||||
|
ownerParam = callableMethod.getDefaultImplParam();
|
||||||
}
|
}
|
||||||
|
|
||||||
return StackValue.property(propertyDescriptor.getName(), owner, asmType(propertyDescriptor.getOutType()), isStatic, isInterface, isSuper, getter, setter);
|
return StackValue.property(propertyDescriptor.getName(), owner, ownerParam, asmType(propertyDescriptor.getOutType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1442,13 +1453,18 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
private int pushMethodArguments(@NotNull ResolvedCall resolvedCall, List<Type> valueParameterTypes) {
|
private int pushMethodArguments(@NotNull ResolvedCall resolvedCall, List<Type> valueParameterTypes) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
|
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
|
||||||
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
|
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
|
||||||
|
|
||||||
|
if (fd.getValueParameters().size() != valueArguments.size()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
|
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) {
|
for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) {
|
||||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor);
|
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor.getIndex());
|
||||||
if(resolvedValueArgument instanceof ExpressionValueArgument) {
|
if(resolvedValueArgument instanceof ExpressionValueArgument) {
|
||||||
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
|
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
|
||||||
gen(valueArgument.getExpression(), valueParameterTypes.get(index));
|
gen(valueArgument.getExpression(), valueParameterTypes.get(index));
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -405,7 +408,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
signatureWriter.writeVoidReturn();
|
signatureWriter.writeVoidReturn();
|
||||||
|
|
||||||
constructorMethod = signatureWriter.makeJvmMethodSignature("<init>");
|
constructorMethod = signatureWriter.makeJvmMethodSignature("<init>");
|
||||||
callableMethod = new CallableMethod("", constructorMethod, INVOKESPECIAL);
|
callableMethod = new CallableMethod("", "", "", constructorMethod, INVOKESPECIAL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
||||||
@@ -651,62 +654,65 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
private void generateTraitMethods(ExpressionCodegen codegen) {
|
private void generateTraitMethods(ExpressionCodegen codegen) {
|
||||||
if(!(myClass instanceof JetClass) || ((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))
|
if(!(myClass instanceof JetClass) || ((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) {
|
||||||
|
CallableMemberDescriptor callableDescriptor = needDelegates.first;
|
||||||
|
FunctionDescriptor fun = (FunctionDescriptor) needDelegates.second;
|
||||||
|
generateDelegationToTraitImpl(codegen, fun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (CallableDescriptor callableDescriptor : OverridingUtil.getEffectiveMembers(descriptor)) {
|
private void generateDelegationToTraitImpl(ExpressionCodegen codegen, FunctionDescriptor fun) {
|
||||||
if(callableDescriptor instanceof FunctionDescriptor) {
|
DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration();
|
||||||
FunctionDescriptor fun = (FunctionDescriptor) callableDescriptor;
|
if(containingDeclaration instanceof ClassDescriptor) {
|
||||||
DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration();
|
ClassDescriptor declaration = (ClassDescriptor) containingDeclaration;
|
||||||
if(containingDeclaration instanceof ClassDescriptor) {
|
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaration);
|
||||||
ClassDescriptor declaration = (ClassDescriptor) containingDeclaration;
|
if(psiElement instanceof JetClass) {
|
||||||
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaration);
|
JetClass jetClass = (JetClass) psiElement;
|
||||||
if(psiElement instanceof JetClass) {
|
if(jetClass.isTrait()) {
|
||||||
JetClass jetClass = (JetClass) psiElement;
|
int flags = ACC_PUBLIC; // TODO.
|
||||||
if(jetClass.isTrait()) {
|
|
||||||
int flags = ACC_PUBLIC; // TODO.
|
|
||||||
|
|
||||||
Method function = typeMapper.mapSignature(fun.getName(), fun).getAsmMethod();
|
Method function = typeMapper.mapSignature(fun.getName(), fun).getAsmMethod();
|
||||||
Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal()).getAsmMethod();
|
Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal()).getAsmMethod();
|
||||||
|
|
||||||
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
|
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
|
||||||
if (v.generateCode()) {
|
if (v.generateCode()) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
codegen.generateThisOrOuter(descriptor);
|
codegen.generateThisOrOuter(descriptor);
|
||||||
|
|
||||||
Type[] argTypes = function.getArgumentTypes();
|
Type[] argTypes = function.getArgumentTypes();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||||
Type argType = argTypes[i];
|
Type argType = argTypes[i];
|
||||||
iv.load(reg, argType);
|
iv.load(reg, argType);
|
||||||
//noinspection AssignmentToForLoopParameter
|
//noinspection AssignmentToForLoopParameter
|
||||||
reg += argType.getSize();
|
reg += argType.getSize();
|
||||||
}
|
|
||||||
|
|
||||||
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext);
|
|
||||||
Type type = typeMapper.mapType(jetType);
|
|
||||||
if(type.getInternalName().equals("java/lang/Object")) {
|
|
||||||
jetType = declaration.getDefaultType();
|
|
||||||
type = typeMapper.mapType(jetType);
|
|
||||||
}
|
|
||||||
|
|
||||||
String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor());
|
|
||||||
iv.invokestatic(typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName(), function.getName(), fdescriptor);
|
|
||||||
if(function.getReturnType().getSort() == Type.OBJECT) {
|
|
||||||
iv.checkcast(function.getReturnType());
|
|
||||||
}
|
|
||||||
iv.areturn(function.getReturnType());
|
|
||||||
FunctionCodegen.endVisit(iv, "trait method", bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fun));
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext);
|
||||||
|
Type type = typeMapper.mapType(jetType);
|
||||||
|
if(type.getInternalName().equals("java/lang/Object")) {
|
||||||
|
jetType = declaration.getDefaultType();
|
||||||
|
type = typeMapper.mapType(jetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor());
|
||||||
|
iv.invokestatic(typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName(), function.getName(), fdescriptor);
|
||||||
|
if(function.getReturnType().getSort() == Type.OBJECT) {
|
||||||
|
iv.checkcast(function.getReturnType());
|
||||||
|
}
|
||||||
|
iv.areturn(function.getReturnType());
|
||||||
|
FunctionCodegen.endVisit(iv, "trait method", bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fun));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionCodegen.generateBridgeIfNeeded(context, state, v, function, fun, kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClassDescriptor getOuterClassDescriptor() {
|
private ClassDescriptor getOuterClassDescriptor() {
|
||||||
if (myClass.getParent() instanceof JetClassObject) {
|
if (myClass.getParent() instanceof JetClassObject) {
|
||||||
@@ -891,7 +897,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
codegen.gen(initializer, type);
|
codegen.gen(initializer, type);
|
||||||
// @todo write directly to the field. Fix test excloset.jet::test6
|
// @todo write directly to the field. Fix test excloset.jet::test6
|
||||||
String owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
String owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(propertyDescriptor.getOutType()), false, false, false, null, null).store(iv);
|
StackValue.property(propertyDescriptor.getName(), owner, owner, typeMapper.mapType(propertyDescriptor.getOutType()), false, false, false, null, null, 0).store(iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -998,4 +1004,43 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return pairs of descriptors. First is member of this that should be implemented by delegating to trait,
|
||||||
|
* second is member of trait that contain implementation.
|
||||||
|
*/
|
||||||
|
public static List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) {
|
||||||
|
List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> r = Lists.newArrayList();
|
||||||
|
|
||||||
|
root:
|
||||||
|
for (DeclarationDescriptor decl : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||||
|
if (!(decl instanceof CallableMemberDescriptor)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) decl;
|
||||||
|
if (callableMemberDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<CallableMemberDescriptor> overridenDeclarations = OverridingUtil.getOverridenDeclarations(callableMemberDescriptor);
|
||||||
|
for (CallableMemberDescriptor overridenDeclaration : overridenDeclarations) {
|
||||||
|
if (overridenDeclaration.getModality() != Modality.ABSTRACT) {
|
||||||
|
if (!CodegenUtil.isInterface(overridenDeclaration.getContainingDeclaration())) {
|
||||||
|
continue root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CallableMemberDescriptor overridenDeclaration : overridenDeclarations) {
|
||||||
|
if (overridenDeclaration.getModality() != Modality.ABSTRACT) {
|
||||||
|
r.add(Pair.create(callableMemberDescriptor, overridenDeclaration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,11 @@ public class JetTypeMapper {
|
|||||||
kind = OwnerKind.IMPLEMENTATION;
|
kind = OwnerKind.IMPLEMENTATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
owner = mapType(classDescriptor.getDefaultType(), kind).getInternalName();
|
Type asmType = mapType(classDescriptor.getDefaultType(), kind);
|
||||||
|
if (asmType.getSort() != Type.OBJECT) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
owner = asmType.getInternalName();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration);
|
throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration);
|
||||||
@@ -118,11 +122,11 @@ public class JetTypeMapper {
|
|||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapReturnType(final JetType jetType) {
|
@NotNull public Type mapReturnType(@NotNull final JetType jetType) {
|
||||||
return mapReturnType(jetType, null);
|
return mapReturnType(jetType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapReturnType(final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
@NotNull private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||||
if (jetType.equals(JetStandardClasses.getUnitType())) {
|
if (jetType.equals(JetStandardClasses.getUnitType())) {
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
signatureVisitor.writeAsmType(Type.VOID_TYPE, false);
|
signatureVisitor.writeAsmType(Type.VOID_TYPE, false);
|
||||||
@@ -355,9 +359,11 @@ public class JetTypeMapper {
|
|||||||
if(functionDescriptor == null)
|
if(functionDescriptor == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
|
final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration();
|
||||||
JvmMethodSignature descriptor = mapSignature(functionDescriptor.getOriginal(), true, kind);
|
JvmMethodSignature descriptor = mapSignature(functionDescriptor.getOriginal(), true, kind);
|
||||||
String owner;
|
String owner;
|
||||||
|
String ownerForDefaultImpl;
|
||||||
|
String ownerForDefaultParam;
|
||||||
int invokeOpcode;
|
int invokeOpcode;
|
||||||
ClassDescriptor thisClass;
|
ClassDescriptor thisClass;
|
||||||
if (functionParent instanceof NamespaceDescriptor) {
|
if (functionParent instanceof NamespaceDescriptor) {
|
||||||
@@ -367,6 +373,7 @@ public class JetTypeMapper {
|
|||||||
namespace = ((JavaNamespaceDescriptor) functionParent).isNamespace();
|
namespace = ((JavaNamespaceDescriptor) functionParent).isNamespace();
|
||||||
}
|
}
|
||||||
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(functionParent), namespace);
|
owner = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(functionParent), namespace);
|
||||||
|
ownerForDefaultImpl = ownerForDefaultParam = owner;
|
||||||
invokeOpcode = INVOKESTATIC;
|
invokeOpcode = INVOKESTATIC;
|
||||||
thisClass = null;
|
thisClass = null;
|
||||||
}
|
}
|
||||||
@@ -374,28 +381,50 @@ public class JetTypeMapper {
|
|||||||
assert !superCall;
|
assert !superCall;
|
||||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||||
owner = mapType(containingClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
owner = mapType(containingClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||||
|
ownerForDefaultImpl = ownerForDefaultParam = owner;
|
||||||
invokeOpcode = INVOKESPECIAL;
|
invokeOpcode = INVOKESPECIAL;
|
||||||
thisClass = null;
|
thisClass = null;
|
||||||
}
|
}
|
||||||
else if (functionParent instanceof ClassDescriptor) {
|
else if (functionParent instanceof ClassDescriptor) {
|
||||||
|
|
||||||
|
FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
|
||||||
|
|
||||||
|
ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
|
||||||
|
ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration();
|
||||||
|
|
||||||
|
boolean originalIsInterface = CodegenUtil.isInterface(declarationOwner);
|
||||||
|
boolean currentIsInterface = CodegenUtil.isInterface(currentOwner);
|
||||||
|
|
||||||
|
ClassDescriptor receiver;
|
||||||
|
if (currentIsInterface && !originalIsInterface) {
|
||||||
|
receiver = declarationOwner;
|
||||||
|
} else {
|
||||||
|
receiver = currentOwner;
|
||||||
|
}
|
||||||
|
|
||||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||||
boolean isInterface = CodegenUtil.isInterface(containingClass);
|
boolean isInterface = originalIsInterface && currentIsInterface;
|
||||||
OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION;
|
OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION;
|
||||||
Type type = mapType(containingClass.getDefaultType(), kind1);
|
Type type = mapType(receiver.getDefaultType(), OwnerKind.IMPLEMENTATION);
|
||||||
owner = type.getInternalName();
|
owner = type.getInternalName();
|
||||||
|
ownerForDefaultParam = mapType(((ClassDescriptor) declarationOwner).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||||
|
ownerForDefaultImpl = ownerForDefaultParam
|
||||||
|
+ (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : "");
|
||||||
|
|
||||||
invokeOpcode = isInterface
|
invokeOpcode = isInterface
|
||||||
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
|
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
|
||||||
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
|
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
|
||||||
if(isInterface && superCall) {
|
if(isInterface && superCall) {
|
||||||
descriptor = mapSignature(functionDescriptor.getOriginal(), false, OwnerKind.TRAIT_IMPL);
|
descriptor = mapSignature(functionDescriptor, false, OwnerKind.TRAIT_IMPL);
|
||||||
|
owner += JvmAbi.TRAIT_IMPL_SUFFIX;
|
||||||
}
|
}
|
||||||
thisClass = (ClassDescriptor) functionParent;
|
thisClass = receiver;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("unknown function parent");
|
throw new UnsupportedOperationException("unknown function parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode);
|
final CallableMethod result = new CallableMethod(owner, ownerForDefaultImpl, ownerForDefaultParam, descriptor, invokeOpcode);
|
||||||
result.setNeedsThis(thisClass);
|
result.setNeedsThis(thisClass);
|
||||||
if(functionDescriptor.getReceiverParameter().exists()) {
|
if(functionDescriptor.getReceiverParameter().exists()) {
|
||||||
result.setNeedsReceiver(functionDescriptor);
|
result.setNeedsReceiver(functionDescriptor);
|
||||||
@@ -403,6 +432,17 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static FunctionDescriptor findAnyDeclaration(@NotNull FunctionDescriptor function) {
|
||||||
|
//if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
|
if (function.getOverriddenDescriptors().isEmpty()) {
|
||||||
|
return function;
|
||||||
|
} else {
|
||||||
|
// TODO: prefer class to interface
|
||||||
|
return findAnyDeclaration(function.getOverriddenDescriptors().iterator().next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, OwnerKind kind) {
|
private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, OwnerKind kind) {
|
||||||
|
|
||||||
@@ -676,7 +716,7 @@ public class JetTypeMapper {
|
|||||||
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
|
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
|
||||||
final JvmMethodSignature method = mapConstructorSignature(descriptor);
|
final JvmMethodSignature method = mapConstructorSignature(descriptor);
|
||||||
String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), kind).getInternalName();
|
String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), kind).getInternalName();
|
||||||
return new CallableMethod(owner, method, INVOKESPECIAL);
|
return new CallableMethod(owner, owner, owner, method, INVOKESPECIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getAccessModifiers(DeclarationDescriptorWithVisibility p, int defaultFlags) {
|
public static int getAccessModifiers(DeclarationDescriptorWithVisibility p, int defaultFlags) {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
|
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -106,8 +105,8 @@ public abstract class StackValue {
|
|||||||
return new Field(type, owner, name, isStatic);
|
return new Field(type, owner, name, isStatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Property property(String name, String owner, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter) {
|
public static Property property(String name, String methodOwner, String methodOwnerParam, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter, int invokeOpcode) {
|
||||||
return new Property(name, owner, getter, setter, isStatic, isInterface, isSuper, type);
|
return new Property(name, methodOwner, methodOwnerParam, getter, setter, isStatic, isInterface, isSuper, type, invokeOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue expression(Type type, JetExpression expression, ExpressionCodegen generator) {
|
public static StackValue expression(Type type, JetExpression expression, ExpressionCodegen generator) {
|
||||||
@@ -770,38 +769,50 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class Property extends StackValue {
|
static class Property extends StackValue {
|
||||||
|
@NotNull
|
||||||
private final String name;
|
private final String name;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Method getter;
|
private final Method getter;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Method setter;
|
private final Method setter;
|
||||||
public final String owner;
|
@NotNull
|
||||||
|
public final String methodOwner;
|
||||||
|
@NotNull
|
||||||
|
private final String methodOwnerParam;
|
||||||
private final boolean isStatic;
|
private final boolean isStatic;
|
||||||
private final boolean isInterface;
|
private final boolean isInterface;
|
||||||
private boolean isSuper;
|
private final boolean isSuper;
|
||||||
|
private final int invokeOpcode;
|
||||||
|
|
||||||
public Property(String name, String owner, Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type) {
|
public Property(@NotNull String name, @NotNull String methodOwner, @NotNull String methodOwnerParam, Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type, int invokeOpcode) {
|
||||||
super(type);
|
super(type);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.owner = owner;
|
this.methodOwner = methodOwner;
|
||||||
|
this.methodOwnerParam = methodOwnerParam;
|
||||||
this.getter = getter;
|
this.getter = getter;
|
||||||
this.setter = setter;
|
this.setter = setter;
|
||||||
isStatic = aStatic;
|
isStatic = aStatic;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.isSuper = isSuper;
|
this.isSuper = isSuper;
|
||||||
|
this.invokeOpcode = invokeOpcode;
|
||||||
|
if (invokeOpcode == 0) {
|
||||||
|
if (setter != null || getter != null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
if(isSuper && isInterface) {
|
if(isSuper && isInterface) {
|
||||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
|
v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner, getter.getName(), getter.getDescriptor().replace("(", "(L" + methodOwnerParam + ";"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (getter == null) {
|
if (getter == null) {
|
||||||
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, owner, name, this.type.getDescriptor());
|
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner, name, this.type.getDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isSuper ? Opcodes.INVOKESPECIAL : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, getter.getName(), getter.getDescriptor());
|
v.visitMethodInsn(invokeOpcode, methodOwner, getter.getName(), getter.getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coerce(type, v);
|
coerce(type, v);
|
||||||
@@ -810,14 +821,14 @@ public abstract class StackValue {
|
|||||||
@Override
|
@Override
|
||||||
public void store(InstructionAdapter v) {
|
public void store(InstructionAdapter v) {
|
||||||
if(isSuper && isInterface) {
|
if(isSuper && isInterface) {
|
||||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
|
v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner, setter.getName(), setter.getDescriptor().replace("(", "(L" + methodOwnerParam + ";"));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (setter == null) {
|
if (setter == null) {
|
||||||
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, this.type.getDescriptor());
|
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, methodOwner, name, this.type.getDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isSuper ? Opcodes.INVOKESPECIAL : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, setter.getName(), setter.getDescriptor());
|
v.visitMethodInsn(invokeOpcode, methodOwner, setter.getName(), setter.getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ public class IntrinsicMethods {
|
|||||||
private static final IntrinsicMethod INC = new Increment(1);
|
private static final IntrinsicMethod INC = new Increment(1);
|
||||||
private static final IntrinsicMethod DEC = new Increment(-1);
|
private static final IntrinsicMethod DEC = new Increment(-1);
|
||||||
|
|
||||||
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
private static final List<String> PRIMITIVE_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||||
|
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||||
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||||
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
|
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
|
||||||
public static final Equals EQUALS = new Equals();
|
public static final Equals EQUALS = new Equals();
|
||||||
@@ -56,17 +57,20 @@ public class IntrinsicMethods {
|
|||||||
List<String> primitiveCastMethods = ImmutableList.of("dbl", "flt", "lng", "int", "chr", "sht", "byt");
|
List<String> primitiveCastMethods = ImmutableList.of("dbl", "flt", "lng", "int", "chr", "sht", "byt");
|
||||||
for (String method : primitiveCastMethods) {
|
for (String method : primitiveCastMethods) {
|
||||||
declareIntrinsicProperty("Number", method, NUMBER_CAST);
|
declareIntrinsicProperty("Number", method, NUMBER_CAST);
|
||||||
|
for (String type : PRIMITIVE_NUMBER_TYPES) {
|
||||||
|
declareIntrinsicProperty(type, method, NUMBER_CAST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String type : PRIMITIVE_NUMBER_TYPES) {
|
for (String type : PRIMITIVE_NUMBER_TYPES) {
|
||||||
declareIntrinsicFunction(type, "plus", 0, UNARY_PLUS);
|
declareIntrinsicFunction(type, "plus", 0, UNARY_PLUS, false);
|
||||||
declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS);
|
declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS, false);
|
||||||
declareIntrinsicFunction(type, "inv", 0, INV);
|
declareIntrinsicFunction(type, "inv", 0, INV, false);
|
||||||
declareIntrinsicFunction(type, "rangeTo", 1, UP_TO);
|
declareIntrinsicFunction(type, "rangeTo", 1, UP_TO, false);
|
||||||
declareIntrinsicFunction(type, "upto", 1, UP_TO);
|
declareIntrinsicFunction(type, "upto", 1, UP_TO, false);
|
||||||
declareIntrinsicFunction(type, "downto", 1, DOWN_TO);
|
declareIntrinsicFunction(type, "downto", 1, DOWN_TO, false);
|
||||||
declareIntrinsicFunction(type, "inc", 0, INC);
|
declareIntrinsicFunction(type, "inc", 0, INC, false);
|
||||||
declareIntrinsicFunction(type, "dec", 0, DEC);
|
declareIntrinsicFunction(type, "dec", 0, DEC, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<FunctionDescriptor> typeInfoFunctionGroup = stdlib.getTypeInfoFunctions();
|
final Set<FunctionDescriptor> typeInfoFunctionGroup = stdlib.getTypeInfoFunctions();
|
||||||
@@ -85,10 +89,11 @@ public class IntrinsicMethods {
|
|||||||
declareBinaryOp("or", Opcodes.IOR);
|
declareBinaryOp("or", Opcodes.IOR);
|
||||||
declareBinaryOp("xor", Opcodes.IXOR);
|
declareBinaryOp("xor", Opcodes.IXOR);
|
||||||
|
|
||||||
declareIntrinsicFunction("Boolean", "not", 0, new Not());
|
declareIntrinsicFunction("Boolean", "not", 0, new Not(), true);
|
||||||
|
|
||||||
declareIntrinsicFunction("String", "plus", 1, new Concat());
|
declareIntrinsicFunction("String", "plus", 1, new Concat(), true);
|
||||||
declareIntrinsicFunction("CharSequence", "get", 1, new StringGetChar());
|
declareIntrinsicFunction("CharSequence", "get", 1, new StringGetChar(), true);
|
||||||
|
declareIntrinsicFunction("String", "get", 1, new StringGetChar(), true);
|
||||||
|
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
|
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
|
||||||
@@ -99,22 +104,23 @@ public class IntrinsicMethods {
|
|||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 2, new StupidSync());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("synchronized"), 2, new StupidSync());
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("iterator"), 0, new IteratorIterator());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("iterator"), 0, new IteratorIterator());
|
||||||
|
|
||||||
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("IntIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("IntIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("LongIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("LongIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("CharIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("CharIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("BooleanIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("BooleanIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("FloatIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("FloatIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
declareIntrinsicFunction("DoubleIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("DoubleIterator", "next", 0, ITERATOR_NEXT, false);
|
||||||
|
|
||||||
for (String type : PRIMITIVE_NUMBER_TYPES) {
|
for (String type : PRIMITIVE_TYPES) {
|
||||||
declareIntrinsicFunction(type, "compareTo", 1, new CompareTo());
|
declareIntrinsicFunction(type, "compareTo", 1, new CompareTo(), false);
|
||||||
}
|
}
|
||||||
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
||||||
//
|
//
|
||||||
declareIntrinsicStringMethods();
|
declareIntrinsicStringMethods();
|
||||||
declareIntrinsicProperty("CharSequence", "length", new StringLength());
|
declareIntrinsicProperty("CharSequence", "length", new StringLength());
|
||||||
|
declareIntrinsicProperty("String", "length", new StringLength());
|
||||||
|
|
||||||
declareArrayMethods();
|
declareArrayMethods();
|
||||||
}
|
}
|
||||||
@@ -127,8 +133,8 @@ public class IntrinsicMethods {
|
|||||||
|
|
||||||
declareIntrinsicProperty("Array", "size", ARRAY_SIZE);
|
declareIntrinsicProperty("Array", "size", ARRAY_SIZE);
|
||||||
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
|
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
|
||||||
declareIntrinsicFunction("Array", "set", 2, ARRAY_SET);
|
declareIntrinsicFunction("Array", "set", 2, ARRAY_SET, true);
|
||||||
declareIntrinsicFunction("Array", "get", 1, ARRAY_GET);
|
declareIntrinsicFunction("Array", "get", 1, ARRAY_GET, true);
|
||||||
declareIterator(myStdLib.getArray());
|
declareIterator(myStdLib.getArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,8 +142,8 @@ public class IntrinsicMethods {
|
|||||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||||
declareIntrinsicProperty(primitiveType.getArrayTypeName(), "size", ARRAY_SIZE);
|
declareIntrinsicProperty(primitiveType.getArrayTypeName(), "size", ARRAY_SIZE);
|
||||||
declareIntrinsicProperty(primitiveType.getArrayTypeName(), "indices", ARRAY_INDICES);
|
declareIntrinsicProperty(primitiveType.getArrayTypeName(), "indices", ARRAY_INDICES);
|
||||||
declareIntrinsicFunction(primitiveType.getArrayTypeName(), "set", 2, ARRAY_SET);
|
declareIntrinsicFunction(primitiveType.getArrayTypeName(), "set", 2, ARRAY_SET, true);
|
||||||
declareIntrinsicFunction(primitiveType.getArrayTypeName(), "get", 1, ARRAY_GET);
|
declareIntrinsicFunction(primitiveType.getArrayTypeName(), "get", 1, ARRAY_GET, true);
|
||||||
declareIterator(myStdLib.getPrimitiveArrayClassDescriptor(primitiveType));
|
declareIterator(myStdLib.getPrimitiveArrayClassDescriptor(primitiveType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,8 +179,8 @@ public class IntrinsicMethods {
|
|||||||
|
|
||||||
private void declareBinaryOp(String methodName, int opcode) {
|
private void declareBinaryOp(String methodName, int opcode) {
|
||||||
BinaryOp op = new BinaryOp(opcode);
|
BinaryOp op = new BinaryOp(opcode);
|
||||||
for (String type : PRIMITIVE_NUMBER_TYPES) {
|
for (String type : PRIMITIVE_TYPES) {
|
||||||
declareIntrinsicFunction(type, methodName, 1, op);
|
declareIntrinsicFunction(type, methodName, 1, op, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,12 +192,12 @@ public class IntrinsicMethods {
|
|||||||
myMethods.put(property.getOriginal(), implementation);
|
myMethods.put(property.getOriginal(), implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) {
|
private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation, boolean original) {
|
||||||
JetScope memberScope = getClassMemberScope(className);
|
JetScope memberScope = getClassMemberScope(className);
|
||||||
final Set<FunctionDescriptor> group = memberScope.getFunctions(functionName);
|
final Set<FunctionDescriptor> group = memberScope.getFunctions(functionName);
|
||||||
for (FunctionDescriptor descriptor : group) {
|
for (FunctionDescriptor descriptor : group) {
|
||||||
if (className.equals(descriptor.getContainingDeclaration().getName()) && descriptor.getValueParameters().size() == arity) {
|
if (className.equals(descriptor.getContainingDeclaration().getName()) && descriptor.getValueParameters().size() == arity) {
|
||||||
myMethods.put(descriptor.getOriginal(), implementation);
|
myMethods.put(original ? descriptor.getOriginal() : descriptor, implementation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -1045,15 +1045,16 @@ public class JavaDescriptorResolver {
|
|||||||
resolveVisibilityFromPsiModifiers(anyMember.getMember().psiMember),
|
resolveVisibilityFromPsiModifiers(anyMember.getMember().psiMember),
|
||||||
isVar,
|
isVar,
|
||||||
false,
|
false,
|
||||||
propertyName);
|
propertyName,
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
|
|
||||||
PropertyGetterDescriptor getterDescriptor = null;
|
PropertyGetterDescriptor getterDescriptor = null;
|
||||||
PropertySetterDescriptor setterDescriptor = null;
|
PropertySetterDescriptor setterDescriptor = null;
|
||||||
if (members.getter != null) {
|
if (members.getter != null) {
|
||||||
getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false);
|
getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
}
|
}
|
||||||
if (members.setter != null) {
|
if (members.setter != null) {
|
||||||
setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false);
|
setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyDescriptor.initialize(getterDescriptor, setterDescriptor);
|
propertyDescriptor.initialize(getterDescriptor, setterDescriptor);
|
||||||
@@ -1111,7 +1112,7 @@ public class JavaDescriptorResolver {
|
|||||||
getterDescriptor.initialize(propertyType);
|
getterDescriptor.initialize(propertyType);
|
||||||
}
|
}
|
||||||
if (setterDescriptor != null) {
|
if (setterDescriptor != null) {
|
||||||
// TODO: initialize
|
setterDescriptor.initialize(new ValueParameterDescriptorImpl(setterDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), "p0"/*TODO*/, false, propertyDescriptor.getOutType(), false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.getMember().psiMember, propertyDescriptor);
|
semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.getMember().psiMember, propertyDescriptor);
|
||||||
@@ -1337,7 +1338,8 @@ public class JavaDescriptorResolver {
|
|||||||
NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl(
|
NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl(
|
||||||
owner,
|
owner,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
method.getName()
|
method.getName(),
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl);
|
methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl);
|
||||||
|
|
||||||
|
|||||||
+17
-1
@@ -12,6 +12,22 @@ public interface CallableMemberDescriptor extends CallableDescriptor, MemberDesc
|
|||||||
@Override
|
@Override
|
||||||
Set<? extends CallableMemberDescriptor> getOverriddenDescriptors();
|
Set<? extends CallableMemberDescriptor> getOverriddenDescriptors();
|
||||||
|
|
||||||
|
public enum Kind {
|
||||||
|
DECLARATION,
|
||||||
|
FAKE_OVERRIDE,
|
||||||
|
DELEGATION,
|
||||||
|
;
|
||||||
|
|
||||||
|
public boolean isReal() {
|
||||||
|
return this == DECLARATION || this == DELEGATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a real function or function projection.
|
||||||
|
*/
|
||||||
|
Kind getKind();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
CallableMemberDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract);
|
CallableMemberDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -19,12 +19,12 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
|||||||
private final boolean isPrimary;
|
private final boolean isPrimary;
|
||||||
|
|
||||||
public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull List<AnnotationDescriptor> annotations, boolean isPrimary) {
|
public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull List<AnnotationDescriptor> annotations, boolean isPrimary) {
|
||||||
super(containingDeclaration, annotations, "<init>");
|
super(containingDeclaration, annotations, "<init>", Kind.DECLARATION);
|
||||||
this.isPrimary = isPrimary;
|
this.isPrimary = isPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull ConstructorDescriptor original, @NotNull List<AnnotationDescriptor> annotations, boolean isPrimary) {
|
public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull ConstructorDescriptor original, @NotNull List<AnnotationDescriptor> annotations, boolean isPrimary) {
|
||||||
super(containingDeclaration, original, annotations, "<init>");
|
super(containingDeclaration, original, annotations, "<init>", Kind.DECLARATION);
|
||||||
this.isPrimary = isPrimary;
|
this.isPrimary = isPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,10 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal) {
|
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
|
||||||
|
if (kind != Kind.DECLARATION) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
return new ConstructorDescriptorImpl(
|
return new ConstructorDescriptorImpl(
|
||||||
(ClassDescriptor) newOwner,
|
(ClassDescriptor) newOwner,
|
||||||
this,
|
this,
|
||||||
@@ -95,7 +98,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ConstructorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public ConstructorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
throw new UnsupportedOperationException("Constructors should not be copied for overriding");
|
throw new UnsupportedOperationException("Constructors should not be copied for overriding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,5 +26,5 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract);
|
FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides);
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-11
@@ -31,24 +31,29 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
|
|
||||||
protected Modality modality;
|
protected Modality modality;
|
||||||
protected Visibility visibility;
|
protected Visibility visibility;
|
||||||
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet();
|
protected final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet();
|
||||||
private final FunctionDescriptor original;
|
private final FunctionDescriptor original;
|
||||||
|
private final Kind kind;
|
||||||
|
|
||||||
protected FunctionDescriptorImpl(
|
protected FunctionDescriptorImpl(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
@NotNull String name) {
|
@NotNull String name,
|
||||||
|
Kind kind) {
|
||||||
super(containingDeclaration, annotations, name);
|
super(containingDeclaration, annotations, name);
|
||||||
this.original = this;
|
this.original = this;
|
||||||
|
this.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FunctionDescriptorImpl(
|
protected FunctionDescriptorImpl(
|
||||||
@NotNull DeclarationDescriptor containigDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@NotNull FunctionDescriptor original,
|
@NotNull FunctionDescriptor original,
|
||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
@NotNull String name) {
|
@NotNull String name,
|
||||||
super(containigDeclaration, annotations, name);
|
Kind kind) {
|
||||||
|
super(containingDeclaration, annotations, name);
|
||||||
this.original = original;
|
this.original = original;
|
||||||
|
this.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionDescriptorImpl initialize(
|
public FunctionDescriptorImpl initialize(
|
||||||
@@ -146,17 +151,22 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
return original == this ? this : original.getOriginal();
|
return original == this ? this : original.getOriginal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Kind getKind() {
|
||||||
|
return kind;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final FunctionDescriptor substitute(TypeSubstitutor originalSubstitutor) {
|
public final FunctionDescriptor substitute(TypeSubstitutor originalSubstitutor) {
|
||||||
if (originalSubstitutor.isEmpty()) {
|
if (originalSubstitutor.isEmpty()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, true);
|
return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, true, true, getKind());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FunctionDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
|
protected FunctionDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
|
||||||
DeclarationDescriptor newOwner, Modality newModality, boolean preserveOriginal) {
|
DeclarationDescriptor newOwner, Modality newModality, boolean preserveOriginal, boolean copyOverrides, Kind kind) {
|
||||||
FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, preserveOriginal);
|
FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, preserveOriginal, kind);
|
||||||
|
|
||||||
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
|
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
|
||||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
|
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
|
||||||
@@ -197,13 +207,15 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
newModality,
|
newModality,
|
||||||
visibility
|
visibility
|
||||||
);
|
);
|
||||||
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
|
if (copyOverrides) {
|
||||||
substitutedDescriptor.addOverriddenFunction(overriddenFunction);
|
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
|
||||||
|
substitutedDescriptor.addOverriddenFunction(overriddenFunction.substitute(substitutor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return substitutedDescriptor;
|
return substitutedDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal);
|
protected abstract FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ public class FunctionDescriptorUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static List<ValueParameterDescriptor> getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, TypeSubstitutor substitutor) {
|
public static List<ValueParameterDescriptor> getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) {
|
||||||
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
|
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
|
||||||
List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters();
|
List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters();
|
||||||
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
|
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
|
||||||
|
|||||||
+1
-7
@@ -104,17 +104,11 @@ public class MutableClassDescriptorLite extends MutableDeclarationDescriptor imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WritableScope getScopeForMemberLookupAsWritableScope() {
|
public WritableScope getScopeForMemberLookupAsWritableScope() {
|
||||||
// hack
|
// hack
|
||||||
return (WritableScope) scopeForMemberLookup;
|
return (WritableScope) scopeForMemberLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSupertypesToScopeForMemberLookup() {
|
|
||||||
for (JetType supertype : supertypes) {
|
|
||||||
getScopeForMemberLookupAsWritableScope().importScope(supertype.getMemberScope());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
|
public JetScope getMemberScope(List<TypeProjection> typeArguments) {
|
||||||
|
|||||||
+5
-1
@@ -11,5 +11,9 @@ public interface NamedFunctionDescriptor extends FunctionDescriptor {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
NamedFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract);
|
NamedFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
NamedFunctionDescriptor getOriginal();
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-10
@@ -1,6 +1,5 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
@@ -13,12 +12,21 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class NamedFunctionDescriptorImpl extends FunctionDescriptorImpl implements NamedFunctionDescriptor {
|
public class NamedFunctionDescriptorImpl extends FunctionDescriptorImpl implements NamedFunctionDescriptor {
|
||||||
|
|
||||||
public NamedFunctionDescriptorImpl(@NotNull DeclarationDescriptor containingDeclaration, @NotNull List<AnnotationDescriptor> annotations, @NotNull String name) {
|
public NamedFunctionDescriptorImpl(
|
||||||
super(containingDeclaration, annotations, name);
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
|
@NotNull String name,
|
||||||
|
Kind kind) {
|
||||||
|
super(containingDeclaration, annotations, name, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamedFunctionDescriptorImpl(@NotNull DeclarationDescriptor containingDeclaration, @NotNull NamedFunctionDescriptor original, @NotNull List<AnnotationDescriptor> annotations, @NotNull String name) {
|
private NamedFunctionDescriptorImpl(
|
||||||
super(containingDeclaration, original, annotations, name);
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
|
@NotNull NamedFunctionDescriptor original,
|
||||||
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
|
@NotNull String name,
|
||||||
|
Kind kind) {
|
||||||
|
super(containingDeclaration, original, annotations, name, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -28,26 +36,28 @@ public class NamedFunctionDescriptorImpl extends FunctionDescriptorImpl implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal) {
|
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
|
||||||
if (preserveOriginal) {
|
if (preserveOriginal) {
|
||||||
return new NamedFunctionDescriptorImpl(
|
return new NamedFunctionDescriptorImpl(
|
||||||
newOwner,
|
newOwner,
|
||||||
getOriginal(),
|
getOriginal(),
|
||||||
// TODO : safeSubstitute
|
// TODO : safeSubstitute
|
||||||
getAnnotations(),
|
getAnnotations(),
|
||||||
getName());
|
getName(),
|
||||||
|
kind);
|
||||||
} else {
|
} else {
|
||||||
return new NamedFunctionDescriptorImpl(
|
return new NamedFunctionDescriptorImpl(
|
||||||
newOwner,
|
newOwner,
|
||||||
// TODO : safeSubstitute
|
// TODO : safeSubstitute
|
||||||
getAnnotations(),
|
getAnnotations(),
|
||||||
getName());
|
getName(),
|
||||||
|
kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public NamedFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public NamedFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
return (NamedFunctionDescriptor) doSubstitute(TypeSubstitutor.EMPTY, newOwner, DescriptorUtils.convertModality(modality, makeNonAbstract), false);
|
return (NamedFunctionDescriptor) doSubstitute(TypeSubstitutor.EMPTY, newOwner, DescriptorUtils.convertModality(modality, makeNonAbstract), false, copyOverrides, kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-2
@@ -20,6 +20,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
|||||||
private final Modality modality;
|
private final Modality modality;
|
||||||
private final Visibility visibility;
|
private final Visibility visibility;
|
||||||
private final PropertyDescriptor correspondingProperty;
|
private final PropertyDescriptor correspondingProperty;
|
||||||
|
private final Kind kind;
|
||||||
|
|
||||||
public PropertyAccessorDescriptor(
|
public PropertyAccessorDescriptor(
|
||||||
@NotNull Modality modality,
|
@NotNull Modality modality,
|
||||||
@@ -28,13 +29,15 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
|||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
boolean hasBody,
|
boolean hasBody,
|
||||||
boolean isDefault) {
|
boolean isDefault,
|
||||||
|
Kind kind) {
|
||||||
super(correspondingProperty.getContainingDeclaration(), annotations, name);
|
super(correspondingProperty.getContainingDeclaration(), annotations, name);
|
||||||
this.modality = modality;
|
this.modality = modality;
|
||||||
this.visibility = visibility;
|
this.visibility = visibility;
|
||||||
this.correspondingProperty = correspondingProperty;
|
this.correspondingProperty = correspondingProperty;
|
||||||
this.hasBody = hasBody;
|
this.hasBody = hasBody;
|
||||||
this.isDefault = isDefault;
|
this.isDefault = isDefault;
|
||||||
|
this.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasBody() {
|
public boolean hasBody() {
|
||||||
@@ -45,6 +48,11 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
|||||||
return isDefault;
|
return isDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Kind getKind() {
|
||||||
|
return kind;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PropertyAccessorDescriptor getOriginal() {
|
public PropertyAccessorDescriptor getOriginal() {
|
||||||
@@ -94,7 +102,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
throw new UnsupportedOperationException("Accessors must be copied by the corresponding property");
|
throw new UnsupportedOperationException("Accessors must be copied by the corresponding property");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
private final boolean isObject;
|
private final boolean isObject;
|
||||||
private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet();
|
private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet();
|
||||||
private final PropertyDescriptor original;
|
private final PropertyDescriptor original;
|
||||||
|
private final Kind kind;
|
||||||
|
|
||||||
private ReceiverDescriptor expectedThisObject;
|
private ReceiverDescriptor expectedThisObject;
|
||||||
private ReceiverDescriptor receiver;
|
private ReceiverDescriptor receiver;
|
||||||
@@ -46,6 +47,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
this.isVar = false;
|
this.isVar = false;
|
||||||
this.isObject = false;
|
this.isObject = false;
|
||||||
this.original = null;
|
this.original = null;
|
||||||
|
this.kind = Kind.DECLARATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyDescriptor(
|
private PropertyDescriptor(
|
||||||
@@ -56,13 +58,15 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
@NotNull Visibility visibility,
|
@NotNull Visibility visibility,
|
||||||
boolean isVar,
|
boolean isVar,
|
||||||
boolean isObject,
|
boolean isObject,
|
||||||
@NotNull String name) {
|
@NotNull String name,
|
||||||
|
Kind kind) {
|
||||||
super(containingDeclaration, annotations, name);
|
super(containingDeclaration, annotations, name);
|
||||||
this.isVar = isVar;
|
this.isVar = isVar;
|
||||||
this.isObject = isObject;
|
this.isObject = isObject;
|
||||||
this.modality = modality;
|
this.modality = modality;
|
||||||
this.visibility = visibility;
|
this.visibility = visibility;
|
||||||
this.original = original == null ? this : original.getOriginal();
|
this.original = original == null ? this : original.getOriginal();
|
||||||
|
this.kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyDescriptor(
|
public PropertyDescriptor(
|
||||||
@@ -72,8 +76,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
@NotNull Visibility visibility,
|
@NotNull Visibility visibility,
|
||||||
boolean isVar,
|
boolean isVar,
|
||||||
boolean isObject,
|
boolean isObject,
|
||||||
@NotNull String name) {
|
@NotNull String name,
|
||||||
this(null, containingDeclaration, annotations, modality, visibility, isVar, isObject, name);
|
Kind kind) {
|
||||||
|
this(null, containingDeclaration, annotations, modality, visibility, isVar, isObject, name, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyDescriptor(
|
public PropertyDescriptor(
|
||||||
@@ -86,9 +91,10 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
@Nullable JetType receiverType,
|
@Nullable JetType receiverType,
|
||||||
@NotNull ReceiverDescriptor expectedThisObject,
|
@NotNull ReceiverDescriptor expectedThisObject,
|
||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
@NotNull JetType outType
|
@NotNull JetType outType,
|
||||||
|
Kind kind
|
||||||
) {
|
) {
|
||||||
this(containingDeclaration, annotations, modality, visibility, isVar, isObject, name);
|
this(containingDeclaration, annotations, modality, visibility, isVar, isObject, name, kind);
|
||||||
setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
|
setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +177,13 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
if (originalSubstitutor.isEmpty()) {
|
if (originalSubstitutor.isEmpty()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
PropertyDescriptor substitutedDescriptor = new PropertyDescriptor(this, getContainingDeclaration(), getAnnotations(), getModality(), getVisibility(), isVar(), isObjectDeclaration(), getName());
|
return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, true, true, getKind());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PropertyDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
|
||||||
|
DeclarationDescriptor newOwner, Modality newModality, boolean preserveOriginal, boolean copyOverrides, Kind kind) {
|
||||||
|
PropertyDescriptor substitutedDescriptor = new PropertyDescriptor(preserveOriginal ? getOriginal() : this, newOwner,
|
||||||
|
getAnnotations(), newModality, getVisibility(), isVar(), isObjectDeclaration(), getName(), kind);
|
||||||
|
|
||||||
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
|
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
|
||||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
|
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
|
||||||
@@ -202,6 +214,36 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
|
|
||||||
substitutedDescriptor.setType(outType, substitutedTypeParameters, substitutedExpectedThisObject, substitutedReceiverType);
|
substitutedDescriptor.setType(outType, substitutedTypeParameters, substitutedExpectedThisObject, substitutedReceiverType);
|
||||||
|
|
||||||
|
PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor(
|
||||||
|
substitutedDescriptor, Lists.newArrayList(getter.getAnnotations()),
|
||||||
|
DescriptorUtils.convertModality(getter.getModality(), false), getter.getVisibility(),
|
||||||
|
getter.hasBody(), getter.isDefault(), kind);
|
||||||
|
if (newGetter != null) {
|
||||||
|
JetType returnType = getter.getReturnType();
|
||||||
|
newGetter.initialize(returnType != null ? substitutor.substitute(returnType, Variance.OUT_VARIANCE) : null);
|
||||||
|
}
|
||||||
|
PropertySetterDescriptor newSetter = setter == null ? null : new PropertySetterDescriptor(
|
||||||
|
substitutedDescriptor, Lists.newArrayList(setter.getAnnotations()), DescriptorUtils.convertModality(setter.getModality(), false), setter.getVisibility(),
|
||||||
|
setter.hasBody(), setter.isDefault(), kind);
|
||||||
|
if (newSetter != null) {
|
||||||
|
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(newSetter, setter, substitutor);
|
||||||
|
if (substitutedValueParameters == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (substitutedValueParameters.size() != 1) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
newSetter.initialize(substitutedValueParameters.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
substitutedDescriptor.initialize(newGetter, newSetter);
|
||||||
|
|
||||||
|
if (copyOverrides) {
|
||||||
|
for (PropertyDescriptor propertyDescriptor : overriddenProperties) {
|
||||||
|
substitutedDescriptor.addOverriddenDescriptor(propertyDescriptor.substitute(substitutor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return substitutedDescriptor;
|
return substitutedDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +258,11 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Kind getKind() {
|
||||||
|
return kind;
|
||||||
|
}
|
||||||
|
|
||||||
public void addOverriddenDescriptor(PropertyDescriptor overridden) {
|
public void addOverriddenDescriptor(PropertyDescriptor overridden) {
|
||||||
overriddenProperties.add(overridden);
|
overriddenProperties.add(overridden);
|
||||||
}
|
}
|
||||||
@@ -228,30 +275,8 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
return doSubstitute(TypeSubstitutor.EMPTY, newOwner, DescriptorUtils.convertModality(modality, makeNonAbstract), false, copyOverrides, kind);
|
||||||
newOwner,
|
|
||||||
Lists.newArrayList(getAnnotations()),
|
|
||||||
DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar, isObject,
|
|
||||||
getName());
|
|
||||||
|
|
||||||
propertyDescriptor.setType(getOutType(), DescriptorUtils.copyTypeParameters(propertyDescriptor, getTypeParameters()), expectedThisObject, receiver.exists() ? receiver.getType() : null);
|
|
||||||
|
|
||||||
PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor(
|
|
||||||
propertyDescriptor, Lists.newArrayList(getter.getAnnotations()),
|
|
||||||
DescriptorUtils.convertModality(getter.getModality(), makeNonAbstract), getter.getVisibility(),
|
|
||||||
getter.hasBody(), getter.isDefault());
|
|
||||||
if (newGetter != null) {
|
|
||||||
newGetter.initialize(getter.getReturnType());
|
|
||||||
}
|
|
||||||
PropertySetterDescriptor newSetter = setter == null ? null : new PropertySetterDescriptor(
|
|
||||||
propertyDescriptor, Lists.newArrayList(setter.getAnnotations()), DescriptorUtils.convertModality(setter.getModality(), makeNonAbstract), setter.getVisibility(),
|
|
||||||
setter.hasBody(), setter.isDefault());
|
|
||||||
if (newSetter != null) {
|
|
||||||
newSetter.initialize(setter.getValueParameters().get(0).copy(newSetter));
|
|
||||||
}
|
|
||||||
propertyDescriptor.initialize(newGetter, newSetter);
|
|
||||||
return propertyDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PropertyDescriptor createDummy() {
|
public static PropertyDescriptor createDummy() {
|
||||||
|
|||||||
+2
-2
@@ -18,9 +18,9 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
private JetType returnType;
|
private JetType returnType;
|
||||||
|
|
||||||
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations,
|
public PropertyGetterDescriptor(@NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations,
|
||||||
@NotNull Modality modality, @NotNull Visibility visibility, boolean hasBody, boolean isDefault)
|
@NotNull Modality modality, @NotNull Visibility visibility, boolean hasBody, boolean isDefault, Kind kind)
|
||||||
{
|
{
|
||||||
super(modality, visibility, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody, isDefault);
|
super(modality, visibility, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody, isDefault, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(JetType returnType) {
|
public void initialize(JetType returnType) {
|
||||||
|
|||||||
+6
-2
@@ -22,8 +22,9 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
@NotNull Modality modality,
|
@NotNull Modality modality,
|
||||||
@NotNull Visibility visibility,
|
@NotNull Visibility visibility,
|
||||||
boolean hasBody,
|
boolean hasBody,
|
||||||
boolean isDefault) {
|
boolean isDefault,
|
||||||
super(modality, visibility, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault);
|
Kind kind) {
|
||||||
|
super(modality, visibility, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(@NotNull ValueParameterDescriptor parameter) {
|
public void initialize(@NotNull ValueParameterDescriptor parameter) {
|
||||||
@@ -45,6 +46,9 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<ValueParameterDescriptor> getValueParameters() {
|
public List<ValueParameterDescriptor> getValueParameters() {
|
||||||
|
if (parameter == null) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
return Collections.singletonList(parameter);
|
return Collections.singletonList(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -238,7 +238,8 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl implement
|
|||||||
@NotNull
|
@NotNull
|
||||||
public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
|
public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
|
||||||
TypeParameterDescriptor copy = new TypeParameterDescriptor(newOwner, Lists.newArrayList(getAnnotations()), reified, variance, getName(), index);
|
TypeParameterDescriptor copy = new TypeParameterDescriptor(newOwner, Lists.newArrayList(getAnnotations()), reified, variance, getName(), index);
|
||||||
|
copy.upperBounds.addAll(this.upperBounds);
|
||||||
copy.initialized = this.initialized;
|
copy.initialized = this.initialized;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -21,7 +21,7 @@ public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
|
|||||||
private final VariableDescriptor variableDescriptor;
|
private final VariableDescriptor variableDescriptor;
|
||||||
|
|
||||||
private VariableAsFunctionDescriptor(VariableDescriptor variableDescriptor) {
|
private VariableAsFunctionDescriptor(VariableDescriptor variableDescriptor) {
|
||||||
super(variableDescriptor.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), variableDescriptor.getName());
|
super(variableDescriptor.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), variableDescriptor.getName(), Kind.DECLARATION);
|
||||||
this.variableDescriptor = variableDescriptor;
|
this.variableDescriptor = variableDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,12 +31,12 @@ public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public VariableAsFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public VariableAsFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
throw new UnsupportedOperationException("Should not be copied for overriding");
|
throw new UnsupportedOperationException("Should not be copied for overriding");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal) {
|
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.jet.util.Box;
|
|||||||
import org.jetbrains.jet.util.slicedmap.*;
|
import org.jetbrains.jet.util.slicedmap.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jetbrains.jet.util.slicedmap.RewritePolicy.DO_NOTHING;
|
import static org.jetbrains.jet.util.slicedmap.RewritePolicy.DO_NOTHING;
|
||||||
|
|
||||||
@@ -65,6 +66,9 @@ public interface BindingContext {
|
|||||||
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>(DO_NOTHING) {
|
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>(DO_NOTHING) {
|
||||||
@Override
|
@Override
|
||||||
public Boolean computeValue(SlicedMap map, PropertyDescriptor propertyDescriptor, Boolean backingFieldRequired, boolean valueNotFound) {
|
public Boolean computeValue(SlicedMap map, PropertyDescriptor propertyDescriptor, Boolean backingFieldRequired, boolean valueNotFound) {
|
||||||
|
if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
backingFieldRequired = valueNotFound ? false : backingFieldRequired;
|
backingFieldRequired = valueNotFound ? false : backingFieldRequired;
|
||||||
assert backingFieldRequired != null;
|
assert backingFieldRequired != null;
|
||||||
PsiElement declarationPsiElement = map.get(DESCRIPTOR_TO_DECLARATION, propertyDescriptor);
|
PsiElement declarationPsiElement = map.get(DESCRIPTOR_TO_DECLARATION, propertyDescriptor);
|
||||||
@@ -105,6 +109,18 @@ public interface BindingContext {
|
|||||||
Slices.KeyNormalizer<DeclarationDescriptor> DECLARATION_DESCRIPTOR_NORMALIZER = new Slices.KeyNormalizer<DeclarationDescriptor>() {
|
Slices.KeyNormalizer<DeclarationDescriptor> DECLARATION_DESCRIPTOR_NORMALIZER = new Slices.KeyNormalizer<DeclarationDescriptor>() {
|
||||||
@Override
|
@Override
|
||||||
public DeclarationDescriptor normalize(DeclarationDescriptor declarationDescriptor) {
|
public DeclarationDescriptor normalize(DeclarationDescriptor declarationDescriptor) {
|
||||||
|
if (declarationDescriptor instanceof CallableMemberDescriptor) {
|
||||||
|
CallableMemberDescriptor callable = (CallableMemberDescriptor) declarationDescriptor;
|
||||||
|
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
|
Set<? extends CallableMemberDescriptor> overriddenDescriptors = callable.getOverriddenDescriptors();
|
||||||
|
if (overriddenDescriptors.size() != 1) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"cannot find declaration: fake descriptor" +
|
||||||
|
" has more then one overriden descriptor: " + declarationDescriptor);
|
||||||
|
}
|
||||||
|
return normalize(overriddenDescriptors.iterator().next());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
|
if (declarationDescriptor instanceof VariableAsFunctionDescriptor) {
|
||||||
VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
|
VariableAsFunctionDescriptor descriptor = (VariableAsFunctionDescriptor) declarationDescriptor;
|
||||||
return descriptor.getVariableDescriptor().getOriginal();
|
return descriptor.getVariableDescriptor().getOriginal();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
@@ -45,7 +45,7 @@ public class DelegationResolver {
|
|||||||
if (declarationDescriptor instanceof PropertyDescriptor) {
|
if (declarationDescriptor instanceof PropertyDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) declarationDescriptor;
|
||||||
if (propertyDescriptor.getModality().isOverridable()) {
|
if (propertyDescriptor.getModality().isOverridable()) {
|
||||||
PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true);
|
PropertyDescriptor copy = propertyDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true);
|
||||||
classDescriptor.addPropertyDescriptor(copy);
|
classDescriptor.addPropertyDescriptor(copy);
|
||||||
context.getTrace().record(DELEGATED, copy);
|
context.getTrace().record(DELEGATED, copy);
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ public class DelegationResolver {
|
|||||||
else if (declarationDescriptor instanceof NamedFunctionDescriptor) {
|
else if (declarationDescriptor instanceof NamedFunctionDescriptor) {
|
||||||
NamedFunctionDescriptor functionDescriptor = (NamedFunctionDescriptor) declarationDescriptor;
|
NamedFunctionDescriptor functionDescriptor = (NamedFunctionDescriptor) declarationDescriptor;
|
||||||
if (functionDescriptor.getModality().isOverridable()) {
|
if (functionDescriptor.getModality().isOverridable()) {
|
||||||
NamedFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true);
|
NamedFunctionDescriptor copy = functionDescriptor.copy(classDescriptor, true, CallableMemberDescriptor.Kind.DELEGATION, true);
|
||||||
classDescriptor.addFunctionDescriptor(copy);
|
classDescriptor.addFunctionDescriptor(copy);
|
||||||
context.getTrace().record(DELEGATED, copy);
|
context.getTrace().record(DELEGATED, copy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,8 @@ public class DescriptorResolver {
|
|||||||
final NamedFunctionDescriptorImpl functionDescriptor = new NamedFunctionDescriptorImpl(
|
final NamedFunctionDescriptorImpl functionDescriptor = new NamedFunctionDescriptorImpl(
|
||||||
containingDescriptor,
|
containingDescriptor,
|
||||||
annotationResolver.resolveAnnotations(scope, function.getModifierList()),
|
annotationResolver.resolveAnnotations(scope, function.getModifierList()),
|
||||||
JetPsiUtil.safeName(function.getName())
|
JetPsiUtil.safeName(function.getName()),
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function descriptor header scope");
|
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function descriptor header scope");
|
||||||
innerScope.addLabeledDeclaration(functionDescriptor);
|
innerScope.addLabeledDeclaration(functionDescriptor);
|
||||||
@@ -470,7 +471,8 @@ public class DescriptorResolver {
|
|||||||
visibility,
|
visibility,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
JetPsiUtil.safeName(objectDeclaration.getName())
|
JetPsiUtil.safeName(objectDeclaration.getName()),
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
propertyDescriptor.setType(classDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), ReceiverDescriptor.NO_RECEIVER);
|
propertyDescriptor.setType(classDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), ReceiverDescriptor.NO_RECEIVER);
|
||||||
propertyDescriptor.initialize(createDefaultGetter(propertyDescriptor), null);
|
propertyDescriptor.initialize(createDefaultGetter(propertyDescriptor), null);
|
||||||
@@ -527,7 +529,8 @@ public class DescriptorResolver {
|
|||||||
resolveVisibilityFromModifiers(property.getModifierList()),
|
resolveVisibilityFromModifiers(property.getModifierList()),
|
||||||
isVar,
|
isVar,
|
||||||
false,
|
false,
|
||||||
JetPsiUtil.safeName(property.getName())
|
JetPsiUtil.safeName(property.getName()),
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
|
|
||||||
List<TypeParameterDescriptor> typeParameterDescriptors;
|
List<TypeParameterDescriptor> typeParameterDescriptors;
|
||||||
@@ -677,7 +680,7 @@ public class DescriptorResolver {
|
|||||||
setterDescriptor = new PropertySetterDescriptor(
|
setterDescriptor = new PropertySetterDescriptor(
|
||||||
propertyDescriptor, annotations, resolveModalityFromModifiers(setter.getModifierList(), propertyDescriptor.getModality()),
|
propertyDescriptor, annotations, resolveModalityFromModifiers(setter.getModifierList(), propertyDescriptor.getModality()),
|
||||||
resolveVisibilityFromModifiers(setter.getModifierList(), propertyDescriptor.getVisibility()),
|
resolveVisibilityFromModifiers(setter.getModifierList(), propertyDescriptor.getVisibility()),
|
||||||
setter.getBodyExpression() != null, false);
|
setter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
if (parameter != null) {
|
if (parameter != null) {
|
||||||
|
|
||||||
// This check is redundant: the parser does not allow a default value, but we'll keep it just in case
|
// This check is redundant: the parser does not allow a default value, but we'll keep it just in case
|
||||||
@@ -731,7 +734,7 @@ public class DescriptorResolver {
|
|||||||
setterDescriptor = new PropertySetterDescriptor(
|
setterDescriptor = new PropertySetterDescriptor(
|
||||||
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
|
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
|
||||||
propertyDescriptor.getVisibility(),
|
propertyDescriptor.getVisibility(),
|
||||||
false, true);
|
false, true, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
setterDescriptor.initializeDefault();
|
setterDescriptor.initializeDefault();
|
||||||
return setterDescriptor;
|
return setterDescriptor;
|
||||||
}
|
}
|
||||||
@@ -757,7 +760,7 @@ public class DescriptorResolver {
|
|||||||
getterDescriptor = new PropertyGetterDescriptor(
|
getterDescriptor = new PropertyGetterDescriptor(
|
||||||
propertyDescriptor, annotations, resolveModalityFromModifiers(getter.getModifierList(), propertyDescriptor.getModality()),
|
propertyDescriptor, annotations, resolveModalityFromModifiers(getter.getModifierList(), propertyDescriptor.getModality()),
|
||||||
resolveVisibilityFromModifiers(getter.getModifierList(), propertyDescriptor.getVisibility()),
|
resolveVisibilityFromModifiers(getter.getModifierList(), propertyDescriptor.getVisibility()),
|
||||||
getter.getBodyExpression() != null, false);
|
getter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
getterDescriptor.initialize(returnType);
|
getterDescriptor.initialize(returnType);
|
||||||
trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
|
trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
|
||||||
}
|
}
|
||||||
@@ -773,7 +776,7 @@ public class DescriptorResolver {
|
|||||||
getterDescriptor = new PropertyGetterDescriptor(
|
getterDescriptor = new PropertyGetterDescriptor(
|
||||||
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
|
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
|
||||||
propertyDescriptor.getVisibility(),
|
propertyDescriptor.getVisibility(),
|
||||||
false, true);
|
false, true, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
return getterDescriptor;
|
return getterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,7 +848,8 @@ public class DescriptorResolver {
|
|||||||
resolveVisibilityFromModifiers(parameter.getModifierList()),
|
resolveVisibilityFromModifiers(parameter.getModifierList()),
|
||||||
isMutable,
|
isMutable,
|
||||||
false,
|
false,
|
||||||
name == null ? "<no name>" : name
|
name == null ? "<no name>" : name,
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
|
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.util.containers.MultiMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.util.CommonSuppliers;
|
import org.jetbrains.jet.util.CommonSuppliers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -34,46 +37,205 @@ public class OverrideResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void process() {
|
public void process() {
|
||||||
bindOverrides();
|
generateOverrides();
|
||||||
checkOverrides();
|
checkOverrides();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindOverrides() {
|
/**
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
* Generate fake overrides and add overriden descriptors to existing descriptors.
|
||||||
bindOverridesInAClass(entry.getValue());
|
*/
|
||||||
}
|
private void generateOverrides() {
|
||||||
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
Set<MutableClassDescriptor> ourClasses = new HashSet<MutableClassDescriptor>();
|
||||||
bindOverridesInAClass(entry.getValue());
|
ourClasses.addAll(context.getClasses().values());
|
||||||
|
ourClasses.addAll(context.getObjects().values());
|
||||||
|
|
||||||
|
Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
|
||||||
|
|
||||||
|
for (MutableClassDescriptor clazz : ourClasses) {
|
||||||
|
generateOverridesInAClass(clazz, processed, ourClasses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindOverridesInAClass(MutableClassDescriptor classDescriptor) {
|
private void generateOverridesInAClass(final MutableClassDescriptor classDescriptor, Set<ClassifierDescriptor> processed, Set<MutableClassDescriptor> ourClasses) {
|
||||||
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
if (!processed.add(classDescriptor)) {
|
||||||
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
return;
|
||||||
Collection<FunctionDescriptor> overridden = findFunctionsOverridableBy(declaredFunction, supertype);
|
}
|
||||||
for (FunctionDescriptor functionDescriptor : overridden) {
|
|
||||||
((FunctionDescriptorImpl) declaredFunction).addOverriddenFunction(functionDescriptor);
|
// avoid processing stdlib classes twice
|
||||||
}
|
if (!ourClasses.contains(classDescriptor)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
|
ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
|
||||||
|
if (superclass instanceof MutableClassDescriptor) {
|
||||||
|
generateOverridesInAClass((MutableClassDescriptor) superclass, processed, ourClasses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
|
List<NamedFunctionDescriptor> functionsFromSupertypes = getDescriptorsFromSupertypes(classDescriptor, NamedFunctionDescriptor.class);
|
||||||
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
List<PropertyDescriptor> propertiesFromSupertypes = getDescriptorsFromSupertypes(classDescriptor, PropertyDescriptor.class);
|
||||||
Collection<PropertyDescriptor> overridden = findPropertiesOverridableBy(propertyDescriptor, supertype);
|
|
||||||
for (PropertyDescriptor descriptor : overridden) {
|
MultiMap<String, NamedFunctionDescriptor> functionsFromSupertypesByName = groupDescriptorsByName(functionsFromSupertypes);
|
||||||
propertyDescriptor.addOverriddenDescriptor(descriptor);
|
MultiMap<String, PropertyDescriptor> propertiesFromSupertypesByName = groupDescriptorsByName(propertiesFromSupertypes);
|
||||||
|
|
||||||
|
MultiMap<String, NamedFunctionDescriptor> functionsFromCurrentByName = groupDescriptorsByName(classDescriptor.getFunctions());
|
||||||
|
MultiMap<String, PropertyDescriptor> propertiesFromCurrentByName = groupDescriptorsByName(classDescriptor.getProperties());
|
||||||
|
|
||||||
|
Set<String> functionNames = new HashSet<String>();
|
||||||
|
functionNames.addAll(functionsFromSupertypesByName.keySet());
|
||||||
|
functionNames.addAll(functionsFromCurrentByName.keySet());
|
||||||
|
|
||||||
|
Set<String> propertyNames = new HashSet<String>();
|
||||||
|
propertyNames.addAll(propertiesFromSupertypesByName.keySet());
|
||||||
|
propertyNames.addAll(propertiesFromCurrentByName.keySet());
|
||||||
|
|
||||||
|
|
||||||
|
for (String functionName : functionNames) {
|
||||||
|
generateOverridesInFunctionGroup(functionName,
|
||||||
|
functionsFromSupertypesByName.get(functionName),
|
||||||
|
functionsFromCurrentByName.get(functionName),
|
||||||
|
classDescriptor,
|
||||||
|
new DescriptorSink<NamedFunctionDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public void addToScope(NamedFunctionDescriptor fakeOverride) {
|
||||||
|
classDescriptor.getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(fakeOverride);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String propertyName : propertyNames) {
|
||||||
|
generateOverridesInPropertyGroup(propertyName,
|
||||||
|
propertiesFromSupertypesByName.get(propertyName),
|
||||||
|
propertiesFromCurrentByName.get(propertyName),
|
||||||
|
classDescriptor,
|
||||||
|
new DescriptorSink<PropertyDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public void addToScope(PropertyDescriptor fakeOverride) {
|
||||||
|
classDescriptor.getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(fakeOverride);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DescriptorSink<D extends CallableMemberDescriptor> {
|
||||||
|
void addToScope(D fakeOverride);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateOverridesInFunctionGroup(
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull Collection<NamedFunctionDescriptor> functionsFromSupertypes,
|
||||||
|
@NotNull Collection<NamedFunctionDescriptor> functionsFromCurrent,
|
||||||
|
@NotNull ClassDescriptor current,
|
||||||
|
@NotNull DescriptorSink<NamedFunctionDescriptor> sink) {
|
||||||
|
|
||||||
|
List<NamedFunctionDescriptor> fakeOverrides = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (NamedFunctionDescriptor functionFromSupertype : functionsFromSupertypes) {
|
||||||
|
|
||||||
|
boolean overrides = false;
|
||||||
|
|
||||||
|
for (NamedFunctionDescriptor functionFromCurrent : functionsFromCurrent) {
|
||||||
|
if (OverridingUtil.isOverridableBy(functionFromSupertype, functionFromCurrent).isSuccess()) {
|
||||||
|
((FunctionDescriptorImpl) functionFromCurrent).addOverriddenFunction(functionFromSupertype);
|
||||||
|
overrides = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (NamedFunctionDescriptor fakeOverride : fakeOverrides) {
|
||||||
|
if (OverridingUtil.isOverridableBy(functionFromSupertype, fakeOverride).isSuccess()) {
|
||||||
|
((FunctionDescriptorImpl) fakeOverride).addOverriddenFunction(functionFromSupertype);
|
||||||
|
overrides = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!overrides) {
|
||||||
|
NamedFunctionDescriptor fakeOverride = functionFromSupertype.copy(current, false, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
|
||||||
|
((FunctionDescriptorImpl) fakeOverride).addOverriddenFunction(functionFromSupertype);
|
||||||
|
|
||||||
|
fakeOverrides.add(fakeOverride);
|
||||||
|
|
||||||
|
sink.addToScope(fakeOverride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void generateOverridesInPropertyGroup(
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull Collection<PropertyDescriptor> propertiesFromSupertypes,
|
||||||
|
@NotNull Collection<PropertyDescriptor> propertiesFromCurrent,
|
||||||
|
@NotNull ClassDescriptor current,
|
||||||
|
@NotNull DescriptorSink<PropertyDescriptor> sink) {
|
||||||
|
|
||||||
|
List<PropertyDescriptor> fakeOverrides = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (PropertyDescriptor propertyFromSupertype : propertiesFromSupertypes) {
|
||||||
|
boolean overrides = false;
|
||||||
|
for (PropertyDescriptor propertyFromCurrent : propertiesFromCurrent) {
|
||||||
|
if (OverridingUtil.isOverridableBy(propertyFromSupertype, propertyFromCurrent).isSuccess()) {
|
||||||
|
propertyFromCurrent.addOverriddenDescriptor(propertyFromSupertype);
|
||||||
|
overrides = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PropertyDescriptor fakeOverride : fakeOverrides) {
|
||||||
|
if (OverridingUtil.isOverridableBy(propertyFromSupertype, fakeOverride).isSuccess()) {
|
||||||
|
((PropertyDescriptor) fakeOverride).addOverriddenDescriptor(propertyFromSupertype);
|
||||||
|
overrides = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!overrides) {
|
||||||
|
PropertyDescriptor fakeOverride = propertyFromSupertype.copy(current, false, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
|
||||||
|
fakeOverride.addOverriddenDescriptor(propertyFromSupertype);
|
||||||
|
|
||||||
|
fakeOverrides.add(fakeOverride);
|
||||||
|
|
||||||
|
sink.addToScope(fakeOverride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static <T extends DeclarationDescriptor> MultiMap<String, T> groupDescriptorsByName(Collection<T> properties) {
|
||||||
|
MultiMap<String, T> r = new MultiMap<String, T>();
|
||||||
|
for (T property : properties) {
|
||||||
|
r.putValue(property.getName(), property);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static <T extends DeclarationDescriptor> List<T> getDescriptorsFromSupertypes(
|
||||||
|
ClassDescriptor classDescriptor, Class<T> descriptorClass) {
|
||||||
|
Set<T> r = Sets.newHashSet();
|
||||||
|
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||||
|
r.addAll(getDescriptorsOfType(supertype.getMemberScope(), descriptorClass));
|
||||||
|
}
|
||||||
|
return new ArrayList<T>(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends DeclarationDescriptor> List<T> getDescriptorsOfType(
|
||||||
|
JetScope scope, Class<T> descriptorClass) {
|
||||||
|
List<T> r = Lists.newArrayList();
|
||||||
|
for (DeclarationDescriptor decl : scope.getAllDescriptors()) {
|
||||||
|
if (descriptorClass.isInstance(decl)) {
|
||||||
|
r.add((T) decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Collection<FunctionDescriptor> findFunctionsOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) {
|
private Collection<FunctionDescriptor> findFunctionsOverridableBy(@NotNull FunctionDescriptor declaredFunction, @NotNull JetType supertype) {
|
||||||
List<FunctionDescriptor> result = Lists.newArrayList();
|
List<FunctionDescriptor> result = Lists.newArrayList();
|
||||||
|
List<FunctionDescriptor> result2 = Lists.newArrayList();
|
||||||
Set<FunctionDescriptor> functionGroup = supertype.getMemberScope().getFunctions(declaredFunction.getName());
|
Set<FunctionDescriptor> functionGroup = supertype.getMemberScope().getFunctions(declaredFunction.getName());
|
||||||
for (FunctionDescriptor functionDescriptor : functionGroup) {
|
for (FunctionDescriptor functionDescriptor : functionGroup) {
|
||||||
if (OverridingUtil.isOverridableBy(functionDescriptor, declaredFunction).isSuccess()) {
|
if (OverridingUtil.isOverridableBy(functionDescriptor, declaredFunction).isSuccess()) {
|
||||||
result.add(functionDescriptor);
|
result.add(functionDescriptor);
|
||||||
|
} else {
|
||||||
|
result2.add(functionDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -172,37 +334,32 @@ public class OverrideResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl) {
|
public static void collectMissingImplementations(MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl) {
|
||||||
// Everything from supertypes
|
|
||||||
Map<CallableMemberDescriptor, CallableMemberDescriptor> implementedWithDelegationBy = Maps.newHashMap();
|
for (DeclarationDescriptor descriptor : classDescriptor.getScopeForMemberLookup().getAllDescriptors()) {
|
||||||
Multimap<CallableMemberDescriptor, CallableMemberDescriptor> factoredMembers = collectSuperMethods(classDescriptor);
|
if (descriptor instanceof CallableMemberDescriptor) {
|
||||||
|
collectMissingImplementations((CallableMemberDescriptor) descriptor, abstractNoImpl, manyImpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (CallableMemberDescriptor key : factoredMembers.keySet()) {
|
private static void collectMissingImplementations(CallableMemberDescriptor descriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl) {
|
||||||
Collection<CallableMemberDescriptor> mutuallyOverridable = factoredMembers.get(key);
|
if (descriptor.getKind().isReal()) {
|
||||||
|
if (descriptor.getModality() == Modality.ABSTRACT) {
|
||||||
int implementationCount = 0;
|
//abstractNoImpl.add(descriptor);
|
||||||
for (CallableMemberDescriptor member : mutuallyOverridable) {
|
}
|
||||||
if (member.getModality() != Modality.ABSTRACT) {
|
} else {
|
||||||
implementationCount++;
|
Collection<CallableMemberDescriptor> overridenDeclarations = OverridingUtil.getOverridenDeclarations(descriptor);
|
||||||
|
if (overridenDeclarations.size() == 0) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
} else if (overridenDeclarations.size() == 1) {
|
||||||
|
CallableMemberDescriptor single = overridenDeclarations.iterator().next();
|
||||||
|
if (single.getModality() == Modality.ABSTRACT) {
|
||||||
|
abstractNoImpl.add(single);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
manyImpl.addAll(overridenDeclarations);
|
||||||
if (implementationCount == 0) {
|
|
||||||
abstractNoImpl.addAll(mutuallyOverridable);
|
|
||||||
}
|
|
||||||
else if (implementationCount > 1) {
|
|
||||||
manyImpl.addAll(mutuallyOverridable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Members actually present (declared) in the class
|
|
||||||
Set<CallableMemberDescriptor> actuallyOverridden = Sets.newHashSet(implementedWithDelegationBy.keySet());
|
|
||||||
for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
|
|
||||||
actuallyOverridden.addAll(member.getOverriddenDescriptors());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Those to be overridden that are actually not
|
|
||||||
abstractNoImpl.removeAll(actuallyOverridden);
|
|
||||||
manyImpl.removeAll(actuallyOverridden);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Multimap<CallableMemberDescriptor, CallableMemberDescriptor> collectSuperMethods(MutableClassDescriptor classDescriptor) {
|
public static Multimap<CallableMemberDescriptor, CallableMemberDescriptor> collectSuperMethods(MutableClassDescriptor classDescriptor) {
|
||||||
@@ -242,6 +399,10 @@ public class OverrideResolver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
JetModifierList modifierList = member.getModifierList();
|
JetModifierList modifierList = member.getModifierList();
|
||||||
ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
|
ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
|
||||||
boolean hasOverrideModifier = overrideNode != null;
|
boolean hasOverrideModifier = overrideNode != null;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.google.common.collect.BiMap;
|
|||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -21,21 +22,6 @@ public class OverridingUtil {
|
|||||||
private OverridingUtil() {
|
private OverridingUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<CallableDescriptor> getEffectiveMembers(@NotNull ClassDescriptor classDescriptor) {
|
|
||||||
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
|
|
||||||
Set<CallableDescriptor> allMembers = Sets.newLinkedHashSet();
|
|
||||||
for (DeclarationDescriptor descriptor : allDescriptors) {
|
|
||||||
assert !(descriptor instanceof ConstructorDescriptor);
|
|
||||||
if (descriptor instanceof CallableDescriptor && descriptor instanceof MemberDescriptor) {
|
|
||||||
CallableDescriptor callableDescriptor = (CallableDescriptor) descriptor;
|
|
||||||
if (((MemberDescriptor) descriptor).getModality() != Modality.ABSTRACT) {
|
|
||||||
allMembers.add(callableDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filterOverrides(allMembers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> Set<D> filterOverrides(Set<D> candidateSet) {
|
public static <D extends CallableDescriptor> Set<D> filterOverrides(Set<D> candidateSet) {
|
||||||
return filterOverrides(candidateSet, Function.ID);
|
return filterOverrides(candidateSet, Function.ID);
|
||||||
}
|
}
|
||||||
@@ -198,6 +184,30 @@ public class OverridingUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get overriden descriptors that are declarations or delegations.
|
||||||
|
*
|
||||||
|
* @see CallableMemberDescriptor.Kind#isReal()
|
||||||
|
*/
|
||||||
|
public static Collection<CallableMemberDescriptor> getOverridenDeclarations(CallableMemberDescriptor descriptor) {
|
||||||
|
Map<ClassDescriptor, CallableMemberDescriptor> result = Maps.newHashMap();
|
||||||
|
getOverridenDeclarations(descriptor, result);
|
||||||
|
return result.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getOverridenDeclarations(CallableMemberDescriptor descriptor, Map<ClassDescriptor, CallableMemberDescriptor> r) {
|
||||||
|
if (descriptor.getKind().isReal()) {
|
||||||
|
r.put((ClassDescriptor) descriptor.getContainingDeclaration(), descriptor);
|
||||||
|
} else {
|
||||||
|
if (descriptor.getOverriddenDescriptors().isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
for (CallableMemberDescriptor overriden : descriptor.getOverriddenDescriptors()) {
|
||||||
|
getOverridenDeclarations(overriden, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class OverrideCompatibilityInfo {
|
public static class OverrideCompatibilityInfo {
|
||||||
|
|
||||||
private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(true, "SUCCESS");
|
private static final OverrideCompatibilityInfo SUCCESS = new OverrideCompatibilityInfo(true, "SUCCESS");
|
||||||
|
|||||||
@@ -8,7 +8,13 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.lang.Configuration;
|
import org.jetbrains.jet.lang.Configuration;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorImpl;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.NamespaceLike;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
||||||
@@ -66,8 +72,8 @@ public class TopDownAnalyzer {
|
|||||||
new TypeHierarchyResolver(context).process(outerScope, owner, declarations);
|
new TypeHierarchyResolver(context).process(outerScope, owner, declarations);
|
||||||
new DeclarationResolver(context).process();
|
new DeclarationResolver(context).process();
|
||||||
new DelegationResolver(context).process();
|
new DelegationResolver(context).process();
|
||||||
lockScopes(context);
|
|
||||||
new OverrideResolver(context).process();
|
new OverrideResolver(context).process();
|
||||||
|
lockScopes(context);
|
||||||
new OverloadResolver(context).process();
|
new OverloadResolver(context).process();
|
||||||
if (!context.analyzingBootstrapLibrary()) {
|
if (!context.analyzingBootstrapLibrary()) {
|
||||||
new BodyResolver(context).resolveBehaviorDeclarationBodies();
|
new BodyResolver(context).resolveBehaviorDeclarationBodies();
|
||||||
@@ -79,6 +85,7 @@ public class TopDownAnalyzer {
|
|||||||
context.printDebugOutput(System.out);
|
context.printDebugOutput(System.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void lockScopes(TopDownAnalysisContext context) {
|
private static void lockScopes(TopDownAnalysisContext context) {
|
||||||
for (MutableClassDescriptor mutableClassDescriptor : context.getClasses().values()) {
|
for (MutableClassDescriptor mutableClassDescriptor : context.getClasses().values()) {
|
||||||
mutableClassDescriptor.lockScopes();
|
mutableClassDescriptor.lockScopes();
|
||||||
|
|||||||
@@ -57,9 +57,6 @@ public class TypeHierarchyResolver {
|
|||||||
checkSupertypesForConsistency();
|
checkSupertypesForConsistency();
|
||||||
// computeSuperclasses();
|
// computeSuperclasses();
|
||||||
|
|
||||||
// Add supertypes to resolution scopes of classes
|
|
||||||
addSupertypesToScopes();
|
|
||||||
|
|
||||||
checkTypesInClassHeaders(); // Check bounds in the types used in generic bounds and supertype lists
|
checkTypesInClassHeaders(); // Check bounds in the types used in generic bounds and supertype lists
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,15 +437,6 @@ public class TypeHierarchyResolver {
|
|||||||
public abstract boolean removeNeeded(JetType subject, JetType other);
|
public abstract boolean removeNeeded(JetType subject, JetType other);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSupertypesToScopes() {
|
|
||||||
for (MutableClassDescriptor mutableClassDescriptor : context.getClasses().values()) {
|
|
||||||
mutableClassDescriptor.addSupertypesToScopeForMemberLookup();
|
|
||||||
}
|
|
||||||
for (MutableClassDescriptor mutableClassDescriptor : context.getObjects().values()) {
|
|
||||||
mutableClassDescriptor.addSupertypesToScopeForMemberLookup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkTypesInClassHeaders() {
|
private void checkTypesInClassHeaders() {
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
|
||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
|
|||||||
+3
-8
@@ -1,32 +1,27 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.calls;
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class ExpressionAsFunctionDescriptor extends FunctionDescriptorImpl {
|
public class ExpressionAsFunctionDescriptor extends FunctionDescriptorImpl {
|
||||||
public ExpressionAsFunctionDescriptor(DeclarationDescriptor containingDeclaration, String name) {
|
public ExpressionAsFunctionDescriptor(DeclarationDescriptor containingDeclaration, String name) {
|
||||||
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), name);
|
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), name, Kind.DECLARATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal) {
|
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +34,10 @@ public interface ResolvedCall<D extends CallableDescriptor> {
|
|||||||
@NotNull
|
@NotNull
|
||||||
Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments();
|
Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments();
|
||||||
|
|
||||||
|
/** Values (arguments) for value parameters indexed by parameter index */
|
||||||
|
@NotNull
|
||||||
|
List<ResolvedValueArgument> getValueArgumentsByIndex();
|
||||||
|
|
||||||
/** What's substituted for type parameters */
|
/** What's substituted for type parameters */
|
||||||
@NotNull
|
@NotNull
|
||||||
Map<TypeParameterDescriptor, JetType> getTypeArguments();
|
Map<TypeParameterDescriptor, JetType> getTypeArguments();
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -143,6 +144,29 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements ResolvedC
|
|||||||
return valueArguments;
|
return valueArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
|
||||||
|
List<ResolvedValueArgument> arguments = new ArrayList<ResolvedValueArgument>(candidateDescriptor.getValueParameters().size());
|
||||||
|
for (int i = 0; i < candidateDescriptor.getValueParameters().size(); ++i) {
|
||||||
|
arguments.add(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : valueArguments.entrySet()) {
|
||||||
|
if (arguments.set(entry.getKey().getIndex(), entry.getValue()) != null) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object o : arguments) {
|
||||||
|
if (o == null) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
public void argumentHasNoType() {
|
public void argumentHasNoType() {
|
||||||
this.someArgumentHasNoType = true;
|
this.someArgumentHasNoType = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-1
@@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.psi.*;
|
|||||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -31,7 +32,10 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet();
|
Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet();
|
||||||
|
|
||||||
D candidate = candidateCall.getCandidateDescriptor();
|
D candidate = candidateCall.getCandidateDescriptor();
|
||||||
List<ValueParameterDescriptor> valueParameters = candidate.getValueParameters();
|
|
||||||
|
D base = getDescriptorForValueArgumentsResolving(candidate);
|
||||||
|
|
||||||
|
List<ValueParameterDescriptor> valueParameters = base.getValueParameters();
|
||||||
|
|
||||||
Map<String, ValueParameterDescriptor> parameterByName = Maps.newHashMap();
|
Map<String, ValueParameterDescriptor> parameterByName = Maps.newHashMap();
|
||||||
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||||
@@ -187,4 +191,30 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descriptor used to resolve parameter names and default parameter values.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
private static <D extends CallableDescriptor> D getDescriptorForValueArgumentsResolving(D descriptor) {
|
||||||
|
Set<D> allBases = new HashSet<D>();
|
||||||
|
getAllDescriptorsForValueArgumentsResolving(descriptor, allBases);
|
||||||
|
|
||||||
|
if (allBases.size() == 1) {
|
||||||
|
return allBases.iterator().next();
|
||||||
|
} else {
|
||||||
|
// TODO remove parameter names and parameter default values
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <D extends CallableDescriptor> void getAllDescriptorsForValueArgumentsResolving(D descriptor, Set<D> dest) {
|
||||||
|
if (descriptor.getOverriddenDescriptors().isEmpty()) {
|
||||||
|
dest.add(descriptor);
|
||||||
|
} else {
|
||||||
|
for (CallableDescriptor overriden : descriptor.getOverriddenDescriptors()) {
|
||||||
|
getAllDescriptorsForValueArgumentsResolving((D) overriden, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,4 +79,4 @@ public interface JetScope {
|
|||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result);
|
void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,8 @@ public class ErrorUtils {
|
|||||||
null,
|
null,
|
||||||
ReceiverDescriptor.NO_RECEIVER,
|
ReceiverDescriptor.NO_RECEIVER,
|
||||||
"<ERROR PROPERTY>",
|
"<ERROR PROPERTY>",
|
||||||
ERROR_PROPERTY_TYPE);
|
ERROR_PROPERTY_TYPE,
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
|
private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
|
||||||
|
|
||||||
private static NamedFunctionDescriptor createErrorFunction(ErrorScope ownerScope) {
|
private static NamedFunctionDescriptor createErrorFunction(ErrorScope ownerScope) {
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ public class JetStandardClasses {
|
|||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
true, Variance.OUT_VARIANCE, "T" + (j + 1), j);
|
true, Variance.OUT_VARIANCE, "T" + (j + 1), j);
|
||||||
parameters.add(typeParameterDescriptor);
|
parameters.add(typeParameterDescriptor);
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, false, "_" + (j + 1));
|
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, false, "_" + (j + 1), CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER);
|
propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER);
|
||||||
PropertyGetterDescriptor getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, true);
|
PropertyGetterDescriptor getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibility.PUBLIC, false, true, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
getterDescriptor.initialize(typeParameterDescriptor.getDefaultType());
|
getterDescriptor.initialize(typeParameterDescriptor.getDefaultType());
|
||||||
propertyDescriptor.initialize(getterDescriptor, null);
|
propertyDescriptor.initialize(getterDescriptor, null);
|
||||||
writableScope.addPropertyDescriptor(propertyDescriptor);
|
writableScope.addPropertyDescriptor(propertyDescriptor);
|
||||||
|
|||||||
+3
-4
@@ -9,7 +9,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
|||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Stepan Koltsov
|
* @author Stepan Koltsov
|
||||||
@@ -20,18 +19,18 @@ public class NamedFunctionDescriptorErrorImpl extends NamedFunctionDescriptorImp
|
|||||||
private final ErrorUtils.ErrorScope ownerScope;
|
private final ErrorUtils.ErrorScope ownerScope;
|
||||||
|
|
||||||
public NamedFunctionDescriptorErrorImpl(ErrorUtils.ErrorScope ownerScope) {
|
public NamedFunctionDescriptorErrorImpl(ErrorUtils.ErrorScope ownerScope) {
|
||||||
super(ErrorUtils.getErrorClass(), Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>");
|
super(ErrorUtils.getErrorClass(), Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>", Kind.DECLARATION);
|
||||||
this.ownerScope = ownerScope;
|
this.ownerScope = ownerScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal) {
|
protected FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public NamedFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
public NamedFunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract, Kind kind, boolean copyOverrides) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -112,7 +112,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
||||||
JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef();
|
JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef();
|
||||||
NamedFunctionDescriptorImpl functionDescriptor = new NamedFunctionDescriptorImpl(
|
NamedFunctionDescriptorImpl functionDescriptor = new NamedFunctionDescriptorImpl(
|
||||||
context.scope.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), "<anonymous>");
|
context.scope.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), "<anonymous>", CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
|
|
||||||
List<ValueParameterDescriptor> valueParameterDescriptors = createValueParameterDescriptors(context, functionLiteral, functionDescriptor, functionTypeExpected);
|
List<ValueParameterDescriptor> valueParameterDescriptors = createValueParameterDescriptors(context, functionLiteral, functionDescriptor, functionTypeExpected);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class C() : B() {
|
|||||||
this.b = 123
|
this.b = 123
|
||||||
super.b = 23
|
super.b = 23
|
||||||
<!VAL_REASSIGNMENT!>this.c<!> = 34
|
<!VAL_REASSIGNMENT!>this.c<!> = 34
|
||||||
super.c = 3535 //repeat for 'c'
|
<!VAL_REASSIGNMENT!>super.c<!> = 3535 //repeat for 'c'
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>getInt()<!> = 12
|
<!VARIABLE_EXPECTED!>getInt()<!> = 12
|
||||||
}
|
}
|
||||||
@@ -140,4 +140,4 @@ fun Array<Int>.checkThis() {
|
|||||||
|
|
||||||
abstract class Ab {
|
abstract class Ab {
|
||||||
abstract fun getArray() : Array<Int>
|
abstract fun getArray() : Array<Int>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package override.generics
|
||||||
|
|
||||||
|
abstract class MyAbstractClass<T> {
|
||||||
|
abstract val <!REDECLARATION!>pr<!> : T
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MyLegalAbstractClass2<T>(t : T) : MyAbstractClass<Int>() {
|
||||||
|
val <R> <!REDECLARATION!>pr<!> : T = t
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ trait MyTrait<T> {
|
|||||||
|
|
||||||
abstract class MyAbstractClass<T> {
|
abstract class MyAbstractClass<T> {
|
||||||
abstract fun bar(t: T) : T
|
abstract fun bar(t: T) : T
|
||||||
abstract val pr : T
|
abstract val <!REDECLARATION, REDECLARATION, REDECLARATION!>pr<!> : T
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MyProps<T> {
|
trait MyProps<T> {
|
||||||
@@ -43,7 +43,7 @@ abstract class MyAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {
|
|||||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalGenericClass1<!><T> : MyTrait<T>, MyAbstractClass<T>() {}
|
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalGenericClass1<!><T> : MyTrait<T>, MyAbstractClass<T>() {}
|
||||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalGenericClass2<!><T, R>(r : R) : MyTrait<T>, MyAbstractClass<R>() {
|
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalGenericClass2<!><T, R>(r : R) : MyTrait<T>, MyAbstractClass<R>() {
|
||||||
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(r: R) = r
|
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(r: R) = r
|
||||||
<!NOTHING_TO_OVERRIDE!>override<!> val <T> pr : R = r
|
<!NOTHING_TO_OVERRIDE!>override<!> val <T> <!REDECLARATION!>pr<!> : R = r
|
||||||
}
|
}
|
||||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass1<!> : MyTrait<Int>, MyAbstractClass<String>() {}
|
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass1<!> : MyTrait<Int>, MyAbstractClass<String>() {}
|
||||||
abstract class MyLegalAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {}
|
abstract class MyLegalAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {}
|
||||||
@@ -51,10 +51,10 @@ abstract class MyLegalAbstractClass1 : MyTrait<Int>, MyAbstractClass<String>() {
|
|||||||
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass2<!><T>(t : T) : MyTrait<Int>, MyAbstractClass<Int>() {
|
class <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>MyIllegalClass2<!><T>(t : T) : MyTrait<Int>, MyAbstractClass<Int>() {
|
||||||
fun foo(t: T) = t
|
fun foo(t: T) = t
|
||||||
fun bar(t: T) = t
|
fun bar(t: T) = t
|
||||||
val <R> pr : T = t
|
val <R> <!REDECLARATION!>pr<!> : T = t
|
||||||
}
|
}
|
||||||
abstract class MyLegalAbstractClass2<T>(t : T) : MyTrait<Int>, MyAbstractClass<Int>() {
|
abstract class MyLegalAbstractClass2<T>(t : T) : MyTrait<Int>, MyAbstractClass<Int>() {
|
||||||
fun foo(t: T) = t
|
fun foo(t: T) = t
|
||||||
fun bar(t: T) = t
|
fun bar(t: T) = t
|
||||||
val <R> pr : T = t
|
val <R> <!REDECLARATION!>pr<!> : T = t
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// NamedFunctionDescriptor.substitute substitutes "overrides"
|
||||||
|
// this test checks it does it properly
|
||||||
|
|
||||||
|
trait Foo<P> {
|
||||||
|
fun quux(p: P, q: Int = 17) = 18
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bar<Q> : Foo<Q>
|
||||||
|
|
||||||
|
abstract class Baz() : Bar<String>
|
||||||
|
|
||||||
|
fun zz(b: Baz) = b.quux("a")
|
||||||
@@ -11,7 +11,7 @@ fun f9(a : A?) {
|
|||||||
a?.<error descr="Unresolved reference: bar">bar</error>()
|
a?.<error descr="Unresolved reference: bar">bar</error>()
|
||||||
if (a is B) {
|
if (a is B) {
|
||||||
<info descr="Automatically cast to B">a</info>.bar()
|
<info descr="Automatically cast to B">a</info>.bar()
|
||||||
<info descr="Automatically cast to A">a</info>.foo()
|
<info descr="Automatically cast to B">a</info>.foo()
|
||||||
}
|
}
|
||||||
a?.foo()
|
a?.foo()
|
||||||
a?.<error descr="Unresolved reference: bar">bar</error>()
|
a?.<error descr="Unresolved reference: bar">bar</error>()
|
||||||
@@ -26,7 +26,7 @@ fun f9(a : A?) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
<info descr="Automatically cast to B">a</info>.bar()
|
<info descr="Automatically cast to B">a</info>.bar()
|
||||||
<info descr="Automatically cast to A">a</info>.foo()
|
<info descr="Automatically cast to B">a</info>.foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun f10(a : A?) {
|
fun f10(a : A?) {
|
||||||
@@ -77,7 +77,7 @@ fun f12(a : A?) {
|
|||||||
b?.foo()
|
b?.foo()
|
||||||
}
|
}
|
||||||
if (a is val b is B) {
|
if (a is val b is B) {
|
||||||
<info descr="Automatically cast to A">b</info>.foo()
|
<info descr="Automatically cast to B">b</info>.foo()
|
||||||
<info descr="Automatically cast to B">a</info>.bar()
|
<info descr="Automatically cast to B">a</info>.bar()
|
||||||
<info descr="Automatically cast to B">b</info>.bar()
|
<info descr="Automatically cast to B">b</info>.bar()
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ fun f12(a : A?) {
|
|||||||
|
|
||||||
fun f13(a : A?) {
|
fun f13(a : A?) {
|
||||||
if (a is val c is B) {
|
if (a is val c is B) {
|
||||||
<info descr="Automatically cast to A">c</info>.foo()
|
<info descr="Automatically cast to B">c</info>.foo()
|
||||||
<info descr="Automatically cast to B">c</info>.bar()
|
<info descr="Automatically cast to B">c</info>.bar()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -99,13 +99,13 @@ fun f13(a : A?) {
|
|||||||
<error descr="Unresolved reference: c">c</error>.bar()
|
<error descr="Unresolved reference: c">c</error>.bar()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<info descr="Automatically cast to A">a</info>.foo()
|
<info descr="Automatically cast to B">a</info>.foo()
|
||||||
<error descr="Unresolved reference: c">c</error>.bar()
|
<error descr="Unresolved reference: c">c</error>.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
a?.foo()
|
a?.foo()
|
||||||
if (a is val c is B && <info descr="Automatically cast to A">a</info>.foo() == #() && <info descr="Automatically cast to B">c</info>.bar() == #()) {
|
if (a is val c is B && <info descr="Automatically cast to B">a</info>.foo() == #() && <info descr="Automatically cast to B">c</info>.bar() == #()) {
|
||||||
<info descr="Automatically cast to A">c</info>.foo()
|
<info descr="Automatically cast to B">c</info>.foo()
|
||||||
<info descr="Automatically cast to B">c</info>.bar()
|
<info descr="Automatically cast to B">c</info>.bar()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -250,4 +250,4 @@ fun foo(var a: Any): Int {
|
|||||||
return <error descr="[AUTOCAST_IMPOSSIBLE] Automatic cast to Int is impossible, because a could have changed since the is-check">a</error>
|
return <error descr="[AUTOCAST_IMPOSSIBLE] Automatic cast to Int is impossible, because a could have changed since the is-check">a</error>
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user