Merge branch 'master' of ssh://git.labs.intellij.net/jet
This commit is contained in:
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -72,7 +73,7 @@ public class ClassContext {
|
||||
thisIdx++;
|
||||
}
|
||||
|
||||
final boolean hasReceiver = descriptor.getReceiverType() != null;
|
||||
final boolean hasReceiver = descriptor.getReceiver().exists();
|
||||
if (hasReceiver) {
|
||||
thisIdx++;
|
||||
}
|
||||
@@ -102,12 +103,12 @@ public class ClassContext {
|
||||
return frameMap;
|
||||
}
|
||||
|
||||
private JetType receiverType() {
|
||||
return contextType instanceof FunctionDescriptor ? ((FunctionDescriptor) contextType).getReceiverType() : null;
|
||||
private ReceiverDescriptor receiver() {
|
||||
return contextType instanceof FunctionDescriptor ? ((FunctionDescriptor) contextType).getReceiver() : ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
private boolean hasReceiver() {
|
||||
return receiverType() != null;
|
||||
return receiver().exists();
|
||||
}
|
||||
|
||||
public ClassContext getParentContext() {
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
@@ -41,7 +42,7 @@ public class ClosureCodegen {
|
||||
}
|
||||
|
||||
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
|
||||
boolean isExtensionFunction = fd.getReceiverType() != null;
|
||||
boolean isExtensionFunction = fd.getReceiver().exists();
|
||||
int paramCount = fd.getValueParameters().size();
|
||||
if (isExtensionFunction) {
|
||||
paramCount++;
|
||||
@@ -150,11 +151,11 @@ public class ClosureCodegen {
|
||||
|
||||
iv.load(0, Type.getObjectType(className));
|
||||
|
||||
final JetType receiverType = funDescriptor.getReceiverType();
|
||||
final ReceiverDescriptor receiver = funDescriptor.getReceiver();
|
||||
int count = 1;
|
||||
if (receiverType != null) {
|
||||
if (receiver.exists()) {
|
||||
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(receiverType), iv);
|
||||
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(receiver.getType()), iv);
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -228,7 +229,7 @@ public class ClosureCodegen {
|
||||
|
||||
public static String getInternalClassName(FunctionDescriptor descriptor) {
|
||||
final int paramCount = descriptor.getValueParameters().size();
|
||||
if (descriptor.getReceiverType() != null) {
|
||||
if (descriptor.getReceiver().exists()) {
|
||||
return "jet/ExtensionFunction" + paramCount;
|
||||
}
|
||||
else {
|
||||
@@ -249,7 +250,7 @@ public class ClosureCodegen {
|
||||
Method descriptor = erasedInvokeSignature(fd);
|
||||
String owner = getInternalClassName(fd);
|
||||
final CallableMethod result = new CallableMethod(owner, descriptor, Opcodes.INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
|
||||
if (fd.getReceiverType() != null) {
|
||||
if (fd.getReceiver().exists()) {
|
||||
result.setNeedsReceiver(null);
|
||||
}
|
||||
result.requestGenerateCallee(Type.getObjectType(getInternalClassName(fd)));
|
||||
|
||||
@@ -82,17 +82,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
typeParameterExpressions.put(typeParameter, expression);
|
||||
}
|
||||
|
||||
static void loadTypeInfo(JetTypeMapper typeMapper, ClassDescriptor descriptor, InstructionAdapter v) {
|
||||
String owner = typeMapper.jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
|
||||
public StackValue genQualified(StackValue receiver, JetElement selector) {
|
||||
markLineNumber(selector);
|
||||
return selector.visit(this, receiver);
|
||||
@@ -2033,9 +2022,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
||||
if (containingDeclaration == contextType() && contextType() instanceof ClassDescriptor) {
|
||||
loadTypeInfo(typeMapper, (ClassDescriptor) contextType(), v);
|
||||
ClassDescriptor descriptor = (ClassDescriptor) contextType();
|
||||
JetType defaultType = descriptor.getDefaultType();
|
||||
Type ownerType = typeMapper.mapType(defaultType);
|
||||
ownerType = JetTypeMapper.boxType(ownerType);
|
||||
if(!typeMapper.isInterface(descriptor)) {
|
||||
if (descriptor.getTypeConstructor().getParameters().size() > 0) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
else {
|
||||
v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
v.aconst(ownerType);
|
||||
v.iconst(typeParameterDescriptor.getIndex());
|
||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getArgumentType", "(I)Ljet/typeinfo/TypeInfo;");
|
||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getArgumentType", "(Ljava/lang/Class;I)Ljet/typeinfo/TypeInfo;");
|
||||
return;
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know what this type parameter resolves to");
|
||||
|
||||
@@ -141,7 +141,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticParts() {
|
||||
generateFieldForTypeInfo();
|
||||
generateFieldForObjectInstance();
|
||||
generateFieldForClassObject();
|
||||
|
||||
@@ -156,25 +155,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
//genGetSuperTypesTypeInfo();
|
||||
}
|
||||
|
||||
private void generateFieldForTypeInfo() {
|
||||
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||
return;
|
||||
|
||||
final boolean typeInfoIsStatic = descriptor.getTypeConstructor().getParameters().size() == 0;
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | (typeInfoIsStatic ? Opcodes.ACC_STATIC : 0), "$typeInfo",
|
||||
"Ljet/typeinfo/TypeInfo;", null, null);
|
||||
if (typeInfoIsStatic) {
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFieldForObjectInstance() {
|
||||
if (isNonLiteralObject()) {
|
||||
Type type = JetTypeMapper.jetImplementationType(descriptor);
|
||||
@@ -397,6 +377,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
else if(psiElement instanceof PsiClass) {
|
||||
// todo
|
||||
PsiClass psiClass = (PsiClass) psiElement;
|
||||
}
|
||||
}
|
||||
@@ -550,7 +531,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
|
||||
iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
iv.invokevirtual(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V");
|
||||
}
|
||||
|
||||
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
||||
@@ -648,21 +629,79 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||
return;
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC,
|
||||
"getTypeInfo",
|
||||
"()Ljet/typeinfo/TypeInfo;",
|
||||
null /* TODO */,
|
||||
null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
ExpressionCodegen.loadTypeInfo(state.getTypeMapper(), descriptor, v);
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
JetType defaultType = descriptor.getDefaultType();
|
||||
if(isParametrizedClass(defaultType)) {
|
||||
if(!hasDerivedTypeInfoField(defaultType, true)) {
|
||||
v.visitField(Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
|
||||
MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
|
||||
mv = v.visitMethod(Opcodes.ACC_PROTECTED|Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null);
|
||||
mv.visitCode();
|
||||
iv = new InstructionAdapter(mv);
|
||||
owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
else {
|
||||
if(descriptor.getTypeConstructor().getParameters().isEmpty()) {
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
});
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
});
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||
mv.visitCode();
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
v.getstatic(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
v.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateClassObject(JetClassObject declaration) {
|
||||
state.forClass().generate(context, declaration.getObjectDeclaration());
|
||||
state.forClass().generate(context, declaration.getObjectDeclaration());
|
||||
}
|
||||
|
||||
private void genGetSuperTypesTypeInfo() {
|
||||
@@ -710,4 +749,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isParametrizedClass(JetType type) {
|
||||
if(type.getConstructor().getParameters().size() > 0)
|
||||
return true;
|
||||
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(isParametrizedClass(jetType))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) {
|
||||
if(!exceptOwn) {
|
||||
if(!state.getTypeMapper().isInterface((ClassDescriptor) type.getConstructor().getDeclarationDescriptor()))
|
||||
if(isParametrizedClass(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||
if(hasDerivedTypeInfoField(jetType, false))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
@@ -514,11 +515,11 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
public Method mapSignature(String name, FunctionDescriptor f) {
|
||||
final JetType receiverType = f.getReceiverType();
|
||||
final ReceiverDescriptor receiver = f.getReceiver();
|
||||
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
if (receiverType != null) {
|
||||
parameterTypes.add(mapType(receiverType));
|
||||
if (receiver.exists()) {
|
||||
parameterTypes.add(mapType(receiver.getType()));
|
||||
}
|
||||
for (ValueParameterDescriptor parameter : parameters) {
|
||||
parameterTypes.add(mapType(parameter.getOutType()));
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
@@ -42,7 +43,7 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return JetStandardClasses.getAnyType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,9 +61,4 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||
private String jvmName() {
|
||||
return state.getTypeMapper().jvmName(descriptor, OwnerKind.TRAIT_IMPL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void genNamedFunction(JetNamedFunction declaration, FunctionCodegen functionCodegen) {
|
||||
super.genNamedFunction(declaration, functionCodegen); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -5,6 +5,8 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -23,6 +25,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
|
||||
private Modality modality;
|
||||
private JetType superclassType;
|
||||
private final ClassKind kind;
|
||||
private ClassReceiver implicitReceiver;
|
||||
|
||||
|
||||
public JavaClassDescriptor(DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind) {
|
||||
@@ -155,4 +158,13 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
|
||||
public String toString() {
|
||||
return "java class " + typeConstructor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
if (implicitReceiver == null) {
|
||||
implicitReceiver = new ClassReceiver(this);
|
||||
}
|
||||
return implicitReceiver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ trait Range<in T : Comparable<T>> {
|
||||
fun contains(item : T) : Boolean
|
||||
}
|
||||
|
||||
class IntRange<T : Comparable<T>> : Range<T>, Iterable<T> {
|
||||
class IntRange<T : Comparable<T>>(val start : Int, val end : Int) : Range<T>, Iterable<T> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
|
||||
@@ -12,8 +13,8 @@ import java.util.Set;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface CallableDescriptor extends DeclarationDescriptor {
|
||||
@Nullable
|
||||
JetType getReceiverType();
|
||||
@NotNull
|
||||
ReceiverDescriptor getReceiver();
|
||||
|
||||
@NotNull
|
||||
List<TypeParameterDescriptor> getTypeParameters();
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
@@ -53,4 +54,7 @@ public interface ClassDescriptor extends ClassifierDescriptor {
|
||||
|
||||
@NotNull
|
||||
Modality getModality();
|
||||
|
||||
@NotNull
|
||||
ReceiverDescriptor getImplicitReceiver();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -21,6 +23,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
||||
private FunctionGroup constructors;
|
||||
private ConstructorDescriptor primaryConstructor;
|
||||
private JetType superclassType;
|
||||
private ReceiverDescriptor implicitReceiver;
|
||||
|
||||
public ClassDescriptorImpl(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@@ -151,4 +154,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
||||
public Modality getModality() {
|
||||
return Modality.FINAL;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
if (implicitReceiver == null) {
|
||||
implicitReceiver = new ClassReceiver(this);
|
||||
}
|
||||
return implicitReceiver;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -5,6 +5,8 @@ import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
@@ -13,6 +15,8 @@ import org.jetbrains.jet.lang.types.Variance;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
@@ -21,7 +25,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
private List<TypeParameterDescriptor> typeParameters;
|
||||
private List<ValueParameterDescriptor> unsubstitutedValueParameters;
|
||||
private JetType unsubstitutedReturnType;
|
||||
private JetType receiverType;
|
||||
private ReceiverDescriptor receiver;
|
||||
|
||||
private Modality modality;
|
||||
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet();
|
||||
@@ -49,11 +53,11 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@Nullable JetType unsubstitutedReturnType,
|
||||
@Nullable Modality modality) {
|
||||
this.receiverType = receiverType;
|
||||
this.typeParameters = typeParameters;
|
||||
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
|
||||
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
||||
this.modality = modality;
|
||||
this.receiver = receiverType == null ? NO_RECEIVER : new ExtensionReceiver(this, receiverType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -61,9 +65,10 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReceiverType() {
|
||||
return receiverType;
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -116,10 +121,9 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
|
||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
|
||||
|
||||
JetType receiverType = getReceiverType();
|
||||
JetType substitutedReceiverType = null;
|
||||
if (receiverType != null) {
|
||||
substitutedReceiverType = substitutor.substitute(receiverType, Variance.IN_VARIANCE);
|
||||
if (receiver != NO_RECEIVER) {
|
||||
substitutedReceiverType = substitutor.substitute(getReceiver().getType(), Variance.IN_VARIANCE);
|
||||
if (substitutedReceiverType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+6
-5
@@ -5,11 +5,12 @@ import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionCallableReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -97,9 +98,9 @@ public class FunctionDescriptorUtil {
|
||||
@NotNull
|
||||
public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
|
||||
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function inner scope");
|
||||
JetType receiverType = descriptor.getReceiverType();
|
||||
if (receiverType != null) {
|
||||
parameterScope.setImplicitReceiver(new ExtensionCallableReceiver(descriptor));
|
||||
ReceiverDescriptor receiver = descriptor.getReceiver();
|
||||
if (receiver.exists()) {
|
||||
parameterScope.setImplicitReceiver(receiver);
|
||||
}
|
||||
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
|
||||
parameterScope.addTypeParameterDescriptor(typeParameter);
|
||||
|
||||
+7
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -94,6 +95,12 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FunctionGroup getConstructors() {
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
@@ -38,6 +39,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
private JetType defaultType;
|
||||
private final ClassKind kind;
|
||||
private JetType superclassType;
|
||||
private ClassReceiver implicitReceiver;
|
||||
|
||||
// public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
|
||||
// this(trace, containingDeclaration, outerScope, ClassKind.CLASS);
|
||||
@@ -293,4 +295,13 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
public Collection<JetType> getSupertypes() {
|
||||
return supertypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
if (implicitReceiver == null) {
|
||||
implicitReceiver = new ClassReceiver(this);
|
||||
}
|
||||
return implicitReceiver;
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -15,6 +15,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
||||
private final boolean hasBody;
|
||||
private final boolean isDefault;
|
||||
private final Modality modality;
|
||||
private final PropertyDescriptor correspondingProperty;
|
||||
|
||||
protected PropertyAccessorDescriptor(
|
||||
@NotNull Modality modality,
|
||||
@@ -24,6 +25,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
||||
boolean hasBody,
|
||||
boolean isDefault) {
|
||||
super(correspondingProperty.getContainingDeclaration(), annotations, name);
|
||||
this.correspondingProperty = correspondingProperty;
|
||||
this.modality = modality;
|
||||
this.hasBody = hasBody;
|
||||
this.isDefault = isDefault;
|
||||
@@ -60,4 +62,9 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
||||
public Modality getModality() {
|
||||
return modality;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PropertyDescriptor getCorrespondingProperty() {
|
||||
return correspondingProperty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
@@ -17,7 +19,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
|
||||
private final Modality modality;
|
||||
private final boolean isVar;
|
||||
private final JetType receiverType;
|
||||
private final ReceiverDescriptor receiver;
|
||||
private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0);
|
||||
private final PropertyDescriptor original;
|
||||
private PropertyGetterDescriptor getter;
|
||||
@@ -38,7 +40,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
// assert outType != null;
|
||||
this.isVar = isVar;
|
||||
this.modality = modality;
|
||||
this.receiverType = receiverType;
|
||||
this.receiver = receiverType == null ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(this, receiverType);
|
||||
this.original = original == null ? this : original.getOriginal();
|
||||
}
|
||||
|
||||
@@ -83,9 +85,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
return typeParemeters;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetType getReceiverType() {
|
||||
return receiverType;
|
||||
@NotNull
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -125,10 +127,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
|
||||
if (inType == null && outType == null) {
|
||||
return null; // TODO : tell the user that the property was projected out
|
||||
}
|
||||
JetType receiverType = getReceiverType();
|
||||
return new PropertyDescriptor(
|
||||
this,
|
||||
receiverType == null ? null : substitutor.substitute(receiverType, Variance.IN_VARIANCE),
|
||||
receiver.exists() ? substitutor.substitute(receiver.getType(), Variance.IN_VARIANCE) : null,
|
||||
inType,
|
||||
outType
|
||||
);
|
||||
|
||||
+4
-2
@@ -4,6 +4,7 @@ import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -32,9 +33,10 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
||||
overriddenGetters.add(overriddenGetter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReceiverType() {
|
||||
return null; // TODO
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return getCorrespondingProperty().getReceiver();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+4
-2
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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;
|
||||
|
||||
@@ -41,9 +42,10 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
||||
overriddenSetters.add(overriddenSetter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReceiverType() {
|
||||
return null; // TODO
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return getCorrespondingProperty().getReceiver();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+4
-2
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -71,9 +72,10 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReceiverType() {
|
||||
return null;
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -106,9 +106,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
COLON_AS(COLON, AS_KEYWORD, AS_SAFE) {
|
||||
@Override
|
||||
public JetNodeType parseRightHandSide(IElementType operation, JetExpressionParsing parser) {
|
||||
parser.myBuilder.disableJoiningComplexTokens();
|
||||
parser.myJetParsing.parseTypeRef();
|
||||
parser.myBuilder.enableJoiningComplexTokens();
|
||||
return BINARY_WITH_TYPE;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
@@ -46,7 +47,7 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) {
|
||||
JetType jetType = typeInferrer.getCallResolver().resolveCall(trace, scope, null, entryElement, NO_EXPECTED_TYPE);
|
||||
JetType jetType = typeInferrer.getCallResolver().resolveCall(trace, scope, ReceiverDescriptor.NO_RECEIVER, entryElement, NO_EXPECTED_TYPE);
|
||||
descriptor.setAnnotationType(jetType == null ? ErrorUtils.createErrorType("Unresolved annotation type") : jetType);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.util.slicedmap.*;
|
||||
|
||||
@@ -17,6 +18,8 @@ import java.util.Collection;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface BindingContext {
|
||||
WritableSlice<JetElement, ReceiverDescriptor> RECEIVER = Slices.createSimpleSlice("RECEIVER");
|
||||
|
||||
WritableSlice<JetAnnotationEntry, AnnotationDescriptor> ANNOTATION = Slices.createSimpleSlice("ANNOTATION");
|
||||
WritableSlice<JetExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = Slices.createSimpleSlice("COMPILE_TIME_VALUE");
|
||||
WritableSlice<JetTypeReference, JetType> TYPE = Slices.createSimpleSlice("TYPE");
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionCallableReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
@@ -275,7 +275,7 @@ public class BodyResolver {
|
||||
JetTypeReference typeReference = call.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||
JetType supertype = typeInferrer.getCallResolver().resolveCall(context.getTrace(), scopeForConstructor, null, call, NO_EXPECTED_TYPE);
|
||||
JetType supertype = typeInferrer.getCallResolver().resolveCall(context.getTrace(), scopeForConstructor, ReceiverDescriptor.NO_RECEIVER, call, NO_EXPECTED_TYPE);
|
||||
if (supertype != null) {
|
||||
recordSupertype(typeReference, supertype);
|
||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
||||
@@ -460,7 +460,7 @@ public class BodyResolver {
|
||||
|
||||
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(),
|
||||
functionInnerScope,
|
||||
null, call, NO_EXPECTED_TYPE);
|
||||
ReceiverDescriptor.NO_RECEIVER, call, NO_EXPECTED_TYPE);
|
||||
// call.getThisReference(),
|
||||
// classDescriptor,
|
||||
// classDescriptor.getDefaultType(),
|
||||
@@ -575,9 +575,9 @@ public class BodyResolver {
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
|
||||
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
||||
}
|
||||
JetType receiverType = propertyDescriptor.getReceiverType();
|
||||
if (receiverType != null) {
|
||||
result.setImplicitReceiver(new ExtensionCallableReceiver(propertyDescriptor));
|
||||
ReceiverDescriptor receiver = propertyDescriptor.getReceiver();
|
||||
if (receiver.exists()) {
|
||||
result.setImplicitReceiver(receiver);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -799,15 +799,15 @@ public class BodyResolver {
|
||||
boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT;
|
||||
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
|
||||
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
|
||||
PsiElement classElement = context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDescriptor);
|
||||
assert classElement instanceof JetModifierListOwner;
|
||||
if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) {
|
||||
PsiElement classElement = context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDescriptor);
|
||||
assert classElement instanceof JetModifierListOwner;
|
||||
context.getTrace().report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(functionOrPropertyAccessor, abstractNode, functionDescriptor.getName(), classDescriptor, (JetModifierListOwner) classElement));
|
||||
}
|
||||
if (hasAbstractModifier && inTrait && !isPropertyAccessor) {
|
||||
context.getTrace().report(REDUNDANT_ABSTRACT.on(functionOrPropertyAccessor, abstractNode));
|
||||
}
|
||||
if (function.getBodyExpression() != null && hasAbstractModifier) { //TODO
|
||||
if (function.getBodyExpression() != null && hasAbstractModifier) {
|
||||
context.getTrace().report(ABSTRACT_FUNCTION_WITH_BODY.on(functionOrPropertyAccessor, abstractNode, functionDescriptor));
|
||||
}
|
||||
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null && !isPropertyAccessor) {
|
||||
|
||||
@@ -21,7 +21,7 @@ public class DescriptorUtils {
|
||||
|
||||
@Override
|
||||
public Boolean visitFunctionDescriptor(FunctionDescriptor descriptor, Void data) {
|
||||
return descriptor.getReceiverType() != null;
|
||||
return descriptor.getReceiver().exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,7 +31,7 @@ public class DescriptorUtils {
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, Void data) {
|
||||
return descriptor.getReceiverType() != null;
|
||||
return descriptor.getReceiver().exists();
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.inference.ConstraintSystem;
|
||||
|
||||
@@ -20,7 +21,9 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.RECEIVER;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||
|
||||
/**
|
||||
@@ -42,11 +45,11 @@ public class CallResolver {
|
||||
public VariableDescriptor resolveSimpleProperty(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull final JetSimpleNameExpression nameExpression,
|
||||
@NotNull JetType expectedType) {
|
||||
Call call = CallMaker.makePropertyCall(nameExpression);
|
||||
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, nameExpression.getReferencedName());
|
||||
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = PROPERTY_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, nameExpression.getReferencedName());
|
||||
return resolveCallToDescriptor(trace, scope, call, nameExpression.getNode(), expectedType, prioritizedTasks, nameExpression);
|
||||
}
|
||||
|
||||
@@ -55,11 +58,11 @@ public class CallResolver {
|
||||
public JetType resolveCall(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull JetCallElement call,
|
||||
@NotNull JetType expectedType
|
||||
) {
|
||||
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, receiverType, call, expectedType);
|
||||
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, receiver, call, expectedType);
|
||||
return functionDescriptor == null ? null : functionDescriptor.getReturnType();
|
||||
}
|
||||
|
||||
@@ -70,11 +73,11 @@ public class CallResolver {
|
||||
@NotNull final Call call,
|
||||
@NotNull final JetReferenceExpression functionReference,
|
||||
@NotNull String name,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull JetType expectedType) {
|
||||
// TODO : autocasts
|
||||
// TODO : nullability
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, name);
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, name);
|
||||
return resolveCallToDescriptor(trace, scope, call, functionReference.getNode(), expectedType, tasks, functionReference);
|
||||
}
|
||||
|
||||
@@ -82,7 +85,7 @@ public class CallResolver {
|
||||
public FunctionDescriptor resolveSimpleCallToFunctionDescriptor(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScope scope,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull final JetCallElement call,
|
||||
@NotNull JetType expectedType
|
||||
) {
|
||||
@@ -97,7 +100,7 @@ public class CallResolver {
|
||||
String name = expression.getReferencedName();
|
||||
if (name == null) return checkArgumentTypesAndFail(trace, scope, call);
|
||||
|
||||
prioritizedTasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiverType, call, name);
|
||||
prioritizedTasks = FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, receiver, call, name);
|
||||
ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() {
|
||||
@Override
|
||||
public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
|
||||
@@ -120,7 +123,7 @@ public class CallResolver {
|
||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||
ASTNode reportAbsenceOn = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode();
|
||||
if (calleeExpression instanceof JetConstructorCalleeExpression) {
|
||||
assert receiverType == null;
|
||||
assert receiver == NO_RECEIVER;
|
||||
|
||||
prioritizedTasks = Lists.newArrayList();
|
||||
|
||||
@@ -141,7 +144,7 @@ public class CallResolver {
|
||||
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
}
|
||||
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
|
||||
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(constructors, NO_RECEIVER, call));
|
||||
}
|
||||
else {
|
||||
// trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
|
||||
@@ -162,7 +165,7 @@ public class CallResolver {
|
||||
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
|
||||
return checkArgumentTypesAndFail(trace, scope, call);
|
||||
}
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, null, call));
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(constructors, NO_RECEIVER, call));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Type argument inference not implemented for " + call.getText());
|
||||
@@ -190,45 +193,11 @@ public class CallResolver {
|
||||
OverloadResolutionResult<D> resultForFirstNonemptyCandidateSet = null;
|
||||
TracingStrategy tracing = new TracingStrategy() {
|
||||
@Override
|
||||
public void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor) {
|
||||
public void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor) {
|
||||
trace.record(REFERENCE_TARGET, reference, descriptor);
|
||||
trace.record(RECEIVER, reference, receiver);
|
||||
}
|
||||
|
||||
// public void reportOverallResolutionError(@NotNull BindingTrace trace, @NotNull String message) {
|
||||
// trace.getErrorHandler().genericError(callNode, message);
|
||||
// }
|
||||
//
|
||||
// public void reportWrongTypeArguments(@NotNull BindingTrace trace, @NotNull String message) {
|
||||
// JetTypeArgumentList typeArgumentList = call.getTypeArgumentList();
|
||||
// if (typeArgumentList != null) {
|
||||
// trace.getErrorHandler().genericError(typeArgumentList.getNode(), message);
|
||||
// }
|
||||
// else {
|
||||
// reportOverallResolutionError(trace, message);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void reportWrongValueArguments(@NotNull BindingTrace trace, @NotNull String message) {
|
||||
// ASTNode node;
|
||||
//
|
||||
// JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||
// if (valueArgumentList != null) {
|
||||
// node = valueArgumentList.getNode();
|
||||
// }
|
||||
// else if (!call.getFunctionLiteralArguments().isEmpty()) {
|
||||
// node = call.getFunctionLiteralArguments().get(0).getNode();
|
||||
// }
|
||||
// else {
|
||||
// node = callNode;
|
||||
// }
|
||||
//
|
||||
// trace.getErrorHandler().genericError(node, message);
|
||||
// }
|
||||
//
|
||||
// public void reportErrorOnReference(BindingTrace trace, String message) {
|
||||
// trace.getErrorHandler().genericError(reference.getNode(), message);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates) {
|
||||
trace.record(AMBIGUOUS_REFERENCE_TARGET, reference, candidates);
|
||||
@@ -257,8 +226,8 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType) {
|
||||
trace.report(MISSING_RECEIVER.on(reference, candidateReceiverType));
|
||||
public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver) {
|
||||
trace.report(MISSING_RECEIVER.on(reference, expectedReceiver.getType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -340,7 +309,7 @@ public class CallResolver {
|
||||
traces.put(candidate, temporaryTrace);
|
||||
JetTypeInferrer.Services temporaryServices = typeInferrer.getServices(temporaryTrace);
|
||||
|
||||
tracing.bindReference(temporaryTrace, candidate);
|
||||
tracing.bindReference(temporaryTrace, task.getReceiver(), candidate);
|
||||
|
||||
if (ErrorUtils.isError(candidate)) {
|
||||
successfulCandidates.put(candidate, candidate);
|
||||
@@ -394,10 +363,10 @@ public class CallResolver {
|
||||
|
||||
checkReceiverAbsence(task, tracing, candidate, temporaryTrace);
|
||||
// Error is already reported if something is missing
|
||||
JetType receiverType = task.getReceiverType();
|
||||
JetType candidateReceiverType = candidate.getReceiverType();
|
||||
if (receiverType != null && candidateReceiverType != null) {
|
||||
constraintSystem.addSubtypingConstraint(receiverType, candidateReceiverType);
|
||||
ReceiverDescriptor receiver = task.getReceiver();
|
||||
ReceiverDescriptor candidateReceiver = candidate.getReceiver();
|
||||
if (receiver != NO_RECEIVER && candidateReceiver != NO_RECEIVER) {
|
||||
constraintSystem.addSubtypingConstraint(receiver.getType(), candidateReceiver.getType());
|
||||
}
|
||||
|
||||
if (expectedType != NO_EXPECTED_TYPE) {
|
||||
@@ -508,28 +477,28 @@ public class CallResolver {
|
||||
|
||||
private <D extends CallableDescriptor> boolean checkReceiver(ResolutionTask<D> task, TracingStrategy tracing, D candidate, TemporaryBindingTrace temporaryTrace) {
|
||||
if (!checkReceiverAbsence(task, tracing, candidate, temporaryTrace)) return false;
|
||||
JetType receiverType = task.getReceiverType();
|
||||
JetType candidateReceiverType = candidate.getReceiverType();
|
||||
if (receiverType != null
|
||||
&& candidateReceiverType != null
|
||||
&& !semanticServices.getTypeChecker().isSubtypeOf(receiverType, candidateReceiverType)) {
|
||||
tracing.missingReceiver(temporaryTrace, candidateReceiverType);
|
||||
ReceiverDescriptor receiver = task.getReceiver();
|
||||
ReceiverDescriptor candidateReceiver = candidate.getReceiver();
|
||||
if (receiver != NO_RECEIVER
|
||||
&& candidateReceiver != NO_RECEIVER
|
||||
&& !semanticServices.getTypeChecker().isSubtypeOf(receiver.getType(), candidateReceiver.getType())) {
|
||||
tracing.missingReceiver(temporaryTrace, candidateReceiver);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> boolean checkReceiverAbsence(ResolutionTask<D> task, TracingStrategy tracing, D candidate, TemporaryBindingTrace temporaryTrace) {
|
||||
JetType receiverType = task.getReceiverType();
|
||||
JetType candidateReceiverType = candidate.getReceiverType();
|
||||
if (receiverType != null) {
|
||||
if (candidateReceiverType == null) {
|
||||
ReceiverDescriptor receiver = task.getReceiver();
|
||||
ReceiverDescriptor candidateReceiver = candidate.getReceiver();
|
||||
if (receiver != NO_RECEIVER) {
|
||||
if (candidateReceiver == NO_RECEIVER) {
|
||||
tracing.noReceiverAllowed(temporaryTrace);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (candidateReceiverType != null) {
|
||||
tracing.missingReceiver(temporaryTrace, candidateReceiverType);
|
||||
else if (candidateReceiver != NO_RECEIVER) {
|
||||
tracing.missingReceiver(temporaryTrace, candidateReceiver);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -658,8 +627,8 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public OverloadResolutionResult<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull String name, @NotNull List<JetType> parameterTypes) {
|
||||
List<FunctionDescriptor> result = findCandidatesByExactSignature(scope, receiverType, name, parameterTypes);
|
||||
public OverloadResolutionResult<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
|
||||
List<FunctionDescriptor> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
|
||||
|
||||
BindingTraceContext trace = new BindingTraceContext();
|
||||
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(trace);
|
||||
@@ -672,25 +641,25 @@ public class CallResolver {
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, candidates, Collections.<FunctionDescriptor>emptySet(), Collections.<FunctionDescriptor>emptySet(), traces);
|
||||
}
|
||||
|
||||
private List<FunctionDescriptor> findCandidatesByExactSignature(JetScope scope, JetType receiverType, String name, List<JetType> parameterTypes) {
|
||||
private List<FunctionDescriptor> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver, String name, List<JetType> parameterTypes) {
|
||||
List<FunctionDescriptor> result = Lists.newArrayList();
|
||||
if (receiverType != null) {
|
||||
if (receiver != NO_RECEIVER) {
|
||||
Set<FunctionDescriptor> extensionFunctionDescriptors = scope.getFunctionGroup(name).getFunctionDescriptors();
|
||||
List<FunctionDescriptor> nonlocal = Lists.newArrayList();
|
||||
List<FunctionDescriptor> local = Lists.newArrayList();
|
||||
TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctionDescriptors, scope.getContainingDeclaration(), local, nonlocal);
|
||||
|
||||
|
||||
if (findExtensionFunctions(local, receiverType, parameterTypes, result)) {
|
||||
if (findExtensionFunctions(local, receiver, parameterTypes, result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Set<FunctionDescriptor> functionDescriptors = receiverType.getMemberScope().getFunctionGroup(name).getFunctionDescriptors();
|
||||
Set<FunctionDescriptor> functionDescriptors = receiver.getType().getMemberScope().getFunctionGroup(name).getFunctionDescriptors();
|
||||
if (lookupExactSignature(functionDescriptors, parameterTypes, result)) {
|
||||
return result;
|
||||
|
||||
}
|
||||
findExtensionFunctions(nonlocal, receiverType, parameterTypes, result);
|
||||
findExtensionFunctions(nonlocal, receiver, parameterTypes, result);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
@@ -702,7 +671,7 @@ public class CallResolver {
|
||||
private boolean lookupExactSignature(Set<FunctionDescriptor> candidates, List<JetType> parameterTypes, List<FunctionDescriptor> result) {
|
||||
boolean found = false;
|
||||
for (FunctionDescriptor functionDescriptor : candidates) {
|
||||
if (functionDescriptor.getReceiverType() != null) continue;
|
||||
if (functionDescriptor.getReceiver() != NO_RECEIVER) continue;
|
||||
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
|
||||
if (!checkValueParameters(functionDescriptor, parameterTypes)) continue;
|
||||
result.add(functionDescriptor);
|
||||
@@ -711,13 +680,13 @@ public class CallResolver {
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean findExtensionFunctions(Collection<FunctionDescriptor> candidates, JetType receiverType, List<JetType> parameterTypes, List<FunctionDescriptor> result) {
|
||||
private boolean findExtensionFunctions(Collection<FunctionDescriptor> candidates, ReceiverDescriptor receiver, List<JetType> parameterTypes, List<FunctionDescriptor> result) {
|
||||
boolean found = false;
|
||||
for (FunctionDescriptor functionDescriptor : candidates) {
|
||||
JetType functionReceiverType = functionDescriptor.getReceiverType();
|
||||
if (functionReceiverType == null) continue;
|
||||
ReceiverDescriptor functionReceiver = functionDescriptor.getReceiver();
|
||||
if (functionReceiver == NO_RECEIVER) continue;
|
||||
if (!functionDescriptor.getTypeParameters().isEmpty()) continue;
|
||||
if (!semanticServices.getTypeChecker().isSubtypeOf(receiverType, functionReceiverType)) continue;
|
||||
if (!semanticServices.getTypeChecker().isSubtypeOf(receiver.getType(), functionReceiver.getType())) continue;
|
||||
if (!checkValueParameters(functionDescriptor, parameterTypes))continue;
|
||||
result.add(functionDescriptor);
|
||||
found = true;
|
||||
@@ -744,7 +713,7 @@ public class CallResolver {
|
||||
Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
|
||||
for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor functionDescriptor = iterator.next();
|
||||
if (functionDescriptor.getReceiverType() != null) {
|
||||
if (functionDescriptor.getReceiver() != NO_RECEIVER) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
@@ -756,10 +725,11 @@ public class CallResolver {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
Set<FunctionDescriptor> members = Sets.newHashSet(receiverType.getMemberScope().getFunctionGroup(name).getFunctionDescriptors());
|
||||
addConstructors(receiverType.getMemberScope(), name, members);
|
||||
addVariableAsFunction(receiverType.getMemberScope(), name, members, false);
|
||||
protected Collection<FunctionDescriptor> getMembersByName(@NotNull ReceiverDescriptor receiver, String name) {
|
||||
JetScope receiverScope = receiver.getType().getMemberScope();
|
||||
Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctionGroup(name).getFunctionDescriptors());
|
||||
addConstructors(receiverScope, name, members);
|
||||
addVariableAsFunction(receiverScope, name, members, false);
|
||||
return members;
|
||||
}
|
||||
|
||||
@@ -769,7 +739,7 @@ public class CallResolver {
|
||||
Set<FunctionDescriptor> extensionFunctions = Sets.newHashSet(scope.getFunctionGroup(name).getFunctionDescriptors());
|
||||
for (Iterator<FunctionDescriptor> iterator = extensionFunctions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor descriptor = iterator.next();
|
||||
if (descriptor.getReceiverType() == null) {
|
||||
if (descriptor.getReceiver() == NO_RECEIVER) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
@@ -779,8 +749,8 @@ public class CallResolver {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ResolutionTask<FunctionDescriptor> createTask(JetType receiverType, Call call, Collection<FunctionDescriptor> candidates) {
|
||||
return new ResolutionTask<FunctionDescriptor>(candidates, receiverType, call);
|
||||
protected ResolutionTask<FunctionDescriptor> createTask(@NotNull ReceiverDescriptor receiver, Call call, Collection<FunctionDescriptor> candidates) {
|
||||
return new ResolutionTask<FunctionDescriptor>(candidates, receiver, call);
|
||||
}
|
||||
|
||||
private void addConstructors(JetScope scope, String name, Collection<FunctionDescriptor> functions) {
|
||||
@@ -793,11 +763,11 @@ public class CallResolver {
|
||||
|
||||
private void addVariableAsFunction(JetScope scope, String name, Set<FunctionDescriptor> functions, boolean receiverNeeded) {
|
||||
VariableDescriptor variable = scope.getVariable(name);
|
||||
if (variable != null && variable.getReceiverType() == null) {
|
||||
if (variable != null && variable.getReceiver() == NO_RECEIVER) {
|
||||
JetType outType = variable.getOutType();
|
||||
if (outType != null && JetStandardClasses.isFunctionType(outType)) {
|
||||
VariableAsFunctionDescriptor functionDescriptor = VariableAsFunctionDescriptor.create(variable);
|
||||
if ((functionDescriptor.getReceiverType() != null) == receiverNeeded) {
|
||||
if ((functionDescriptor.getReceiver() != NO_RECEIVER) == receiverNeeded) {
|
||||
functions.add(functionDescriptor);
|
||||
}
|
||||
}
|
||||
@@ -811,7 +781,7 @@ public class CallResolver {
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
VariableDescriptor variable = scope.getVariable(name);
|
||||
if (variable != null && variable.getReceiverType() == null) {
|
||||
if (variable != null && variable.getReceiver() == NO_RECEIVER) {
|
||||
return Collections.singleton(variable);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
@@ -819,8 +789,8 @@ public class CallResolver {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
VariableDescriptor variable = receiverType.getMemberScope().getVariable(name);
|
||||
protected Collection<VariableDescriptor> getMembersByName(@NotNull ReceiverDescriptor receiver, String name) {
|
||||
VariableDescriptor variable = receiver.getType().getMemberScope().getVariable(name);
|
||||
if (variable != null) {
|
||||
return Collections.singleton(variable);
|
||||
}
|
||||
@@ -831,7 +801,7 @@ public class CallResolver {
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
VariableDescriptor variable = scope.getVariable(name);
|
||||
if (variable != null && variable.getReceiverType() != null) {
|
||||
if (variable != null && variable.getReceiver() != NO_RECEIVER) {
|
||||
return Collections.singleton(variable);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
@@ -839,8 +809,8 @@ public class CallResolver {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected ResolutionTask<VariableDescriptor> createTask(JetType receiverType, Call call, Collection<VariableDescriptor> candidates) {
|
||||
return new ResolutionTask<VariableDescriptor>(candidates, receiverType, call);
|
||||
protected ResolutionTask<VariableDescriptor> createTask(@NotNull ReceiverDescriptor receiver, Call call, Collection<VariableDescriptor> candidates) {
|
||||
return new ResolutionTask<VariableDescriptor>(candidates, receiver, call);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+5
-4
@@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
@@ -59,10 +60,10 @@ import java.util.Set;
|
||||
if (overrides(f, g)) return true;
|
||||
if (overrides(g, f)) return false;
|
||||
|
||||
JetType receiverTypeOfF = f.getReceiverType();
|
||||
JetType receiverTypeOfG = g.getReceiverType();
|
||||
if (receiverTypeOfF != null && receiverTypeOfG != null) {
|
||||
if (!typeMoreSpecific(receiverTypeOfF, receiverTypeOfG)) return false;
|
||||
ReceiverDescriptor receiverOfF = f.getReceiver();
|
||||
ReceiverDescriptor receiverOfG = g.getReceiver();
|
||||
if (f.getReceiver().exists() && g.getReceiver().exists()) {
|
||||
if (!typeMoreSpecific(receiverOfF.getType(), receiverOfG.getType())) return false;
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> fParams = f.getValueParameters();
|
||||
|
||||
@@ -8,9 +8,9 @@ import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeProjection;
|
||||
import org.jetbrains.jet.lang.psi.ValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
*/
|
||||
/*package*/ class ResolutionTask<Descriptor extends CallableDescriptor> {
|
||||
private final Collection<Descriptor> candidates;
|
||||
private final JetType receiverType;
|
||||
private final ReceiverDescriptor receiver;
|
||||
private final List<JetTypeProjection> typeArguments;
|
||||
private final List<? extends ValueArgument> valueArguments;
|
||||
private final List<JetExpression> functionLiteralArguments;
|
||||
@@ -27,12 +27,12 @@ import java.util.List;
|
||||
|
||||
public ResolutionTask(
|
||||
@NotNull Collection<Descriptor> candidates,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull List<JetTypeProjection> typeArguments,
|
||||
@NotNull List<? extends ValueArgument> valueArguments,
|
||||
@NotNull List<JetExpression> functionLiteralArguments) {
|
||||
this.candidates = candidates;
|
||||
this.receiverType = receiverType;
|
||||
this.receiver = receiver;
|
||||
this.typeArguments = typeArguments;
|
||||
this.valueArguments = valueArguments;
|
||||
this.functionLiteralArguments = functionLiteralArguments;
|
||||
@@ -40,10 +40,10 @@ import java.util.List;
|
||||
|
||||
public ResolutionTask(
|
||||
@NotNull Collection<Descriptor> candidates,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull Call call
|
||||
) {
|
||||
this(candidates, receiverType, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
|
||||
this(candidates, receiver, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -51,9 +51,9 @@ import java.util.List;
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetType getReceiverType() {
|
||||
return receiverType;
|
||||
@NotNull
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
@@ -10,7 +9,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -64,33 +62,33 @@ import java.util.List;
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @Nullable JetType receiverType, @NotNull Call call, @NotNull String name) {
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull Call call, @NotNull String name) {
|
||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||
doComputeTasks(scope, receiverType, call, name, result);
|
||||
doComputeTasks(scope, receiver, call, name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void doComputeTasks(JetScope scope, JetType receiverType, Call call, String name, List<ResolutionTask<D>> result) {
|
||||
List<ReceiverDescriptor> receivers = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(receivers);
|
||||
if (receiverType != null) {
|
||||
private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, Call call, String name, List<ResolutionTask<D>> result) {
|
||||
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(implicitReceivers);
|
||||
if (receiver != ReceiverDescriptor.NO_RECEIVER) {
|
||||
Collection<D> extensionFunctions = getExtensionsByName(scope, name);
|
||||
List<D> nonlocals = Lists.newArrayList();
|
||||
List<D> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
Collection<D> members = getMembersByName(receiverType, name);
|
||||
Collection<D> members = getMembersByName(receiver, name);
|
||||
|
||||
addTask(result, receiverType, call, locals);
|
||||
addTask(result, null, call, members);
|
||||
addTask(result, receiver, call, locals);
|
||||
addTask(result, ReceiverDescriptor.NO_RECEIVER, call, members);
|
||||
|
||||
for (ReceiverDescriptor receiver : receivers) {
|
||||
Collection<D> memberExtensions = getExtensionsByName(receiver.getReceiverType().getMemberScope(), name);
|
||||
addTask(result, receiverType, call, memberExtensions);
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||
addTask(result, receiver, call, memberExtensions);
|
||||
}
|
||||
|
||||
addTask(result, receiverType, call, nonlocals);
|
||||
addTask(result, receiver, call, nonlocals);
|
||||
}
|
||||
else {
|
||||
Collection<D> functions = getNonExtensionsByName(scope, name);
|
||||
@@ -100,13 +98,13 @@ import java.util.List;
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
addTask(result, receiverType, call, locals);
|
||||
addTask(result, receiver, call, locals);
|
||||
|
||||
for (ReceiverDescriptor receiver : receivers) {
|
||||
doComputeTasks(scope, receiver.getReceiverType(), call, name, result);
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
doComputeTasks(scope, implicitReceiver, call, name, result);
|
||||
}
|
||||
|
||||
addTask(result, receiverType, call, nonlocals);
|
||||
addTask(result, receiver, call, nonlocals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,17 +112,17 @@ import java.util.List;
|
||||
protected abstract Collection<D> getNonExtensionsByName(JetScope scope, String name);
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getMembersByName(@NotNull JetType receiverType, String name);
|
||||
protected abstract Collection<D> getMembersByName(@NotNull ReceiverDescriptor receiver, String name);
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getExtensionsByName(JetScope scope, String name);
|
||||
|
||||
private void addTask(@NotNull List<ResolutionTask<D>> result, @Nullable JetType receiverType, @NotNull Call call, @NotNull Collection<D> candidates) {
|
||||
private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull ReceiverDescriptor receiver, @NotNull Call call, @NotNull Collection<D> candidates) {
|
||||
if (candidates.isEmpty()) return;
|
||||
result.add(createTask(receiverType, call, candidates));
|
||||
result.add(createTask(receiver, call, candidates));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract ResolutionTask<D> createTask(JetType receiverType, Call call, Collection<D> candidates);
|
||||
protected abstract ResolutionTask<D> createTask(ReceiverDescriptor receiver, Call call, Collection<D> candidates);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
@@ -15,7 +15,7 @@ import java.util.Set;
|
||||
/*package*/ interface TracingStrategy {
|
||||
TracingStrategy EMPTY = new TracingStrategy() {
|
||||
@Override
|
||||
public void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor) {}
|
||||
public void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor) {}
|
||||
|
||||
@Override
|
||||
public void unresolvedReference(@NotNull BindingTrace trace) {}
|
||||
@@ -24,7 +24,7 @@ import java.util.Set;
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates) {}
|
||||
|
||||
@Override
|
||||
public void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType) {}
|
||||
public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver) {}
|
||||
|
||||
@Override
|
||||
public void noReceiverAllowed(@NotNull BindingTrace trace) {}
|
||||
@@ -48,13 +48,13 @@ import java.util.Set;
|
||||
public void typeInferenceFailed(@NotNull BindingTrace trace) {}
|
||||
};
|
||||
|
||||
void bindReference(@NotNull BindingTrace trace, @NotNull CallableDescriptor descriptor);
|
||||
void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor);
|
||||
|
||||
void unresolvedReference(@NotNull BindingTrace trace);
|
||||
|
||||
<D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates);
|
||||
|
||||
void missingReceiver(@NotNull BindingTrace trace, @NotNull JetType candidateReceiverType);
|
||||
void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver);
|
||||
|
||||
void noReceiverAllowed(@NotNull BindingTrace trace);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.jetbrains.jet.lang.resolve.scopes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -30,5 +30,5 @@ public interface WritableScope extends JetScope {
|
||||
|
||||
void importScope(@NotNull JetScope imported);
|
||||
|
||||
void setImplicitReceiver(@NotNull ImplicitReceiverDescriptor implicitReceiver);
|
||||
void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.*;
|
||||
@@ -36,7 +35,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
private Map<String, List<DeclarationDescriptor>> labelsToDescriptors;
|
||||
|
||||
@Nullable
|
||||
private ImplicitReceiverDescriptor implicitReceiver;
|
||||
private ReceiverDescriptor implicitReceiver;
|
||||
|
||||
public WritableScopeImpl(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull RedeclarationHandler redeclarationHandler) {
|
||||
super(scope, redeclarationHandler);
|
||||
@@ -275,7 +274,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitReceiver(@NotNull ImplicitReceiverDescriptor implicitReceiver) {
|
||||
public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) {
|
||||
if (this.implicitReceiver != null) {
|
||||
throw new UnsupportedOperationException("Receiver redeclared");
|
||||
}
|
||||
@@ -284,7 +283,7 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
|
||||
@Override
|
||||
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
|
||||
if (implicitReceiver != null && implicitReceiver != ReceiverDescriptor.NO_RECEIVER) {
|
||||
if (implicitReceiver != null && implicitReceiver.exists()) {
|
||||
result.add(implicitReceiver);
|
||||
}
|
||||
super.getImplicitReceiversHierarchy(result);
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -147,7 +146,7 @@ public class WriteThroughScope extends WritableScopeWithImports {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitReceiver(@NotNull ImplicitReceiverDescriptor implicitReceiver) {
|
||||
public void setImplicitReceiver(@NotNull ReceiverDescriptor implicitReceiver) {
|
||||
writableWorker.setImplicitReceiver(implicitReceiver);
|
||||
}
|
||||
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public abstract class AbstractReceiverDescriptor implements ReceiverDescriptor {
|
||||
protected final JetType receiverType;
|
||||
|
||||
public AbstractReceiverDescriptor(@NotNull JetType receiverType) {
|
||||
this.receiverType = receiverType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JetType getType() {
|
||||
return receiverType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+6
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
|
||||
/**
|
||||
@@ -10,4 +11,9 @@ public class ClassReceiver extends ImplicitReceiverDescriptor {
|
||||
public ClassReceiver(ClassDescriptor classDescriptor) {
|
||||
super(classDescriptor, classDescriptor.getDefaultType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitClassReceiver(this, data);
|
||||
}
|
||||
}
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ExplicitReceiver implements ReceiverDescriptor {
|
||||
|
||||
private final JetType type;
|
||||
|
||||
public ExplicitReceiver(@NotNull JetType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReceiverType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ExpressionReceiver extends AbstractReceiverDescriptor implements ReceiverDescriptor {
|
||||
|
||||
private final JetExpression expression;
|
||||
|
||||
public ExpressionReceiver(@NotNull JetExpression expression, @NotNull JetType type) {
|
||||
super(type);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetExpression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitExpressionReceiver(this, data);
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ExtensionCallableReceiver extends ImplicitReceiverDescriptor {
|
||||
|
||||
public ExtensionCallableReceiver(CallableDescriptor callableDescriptor) {
|
||||
super(callableDescriptor, callableDescriptor.getReceiverType());
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ExtensionReceiver extends ImplicitReceiverDescriptor {
|
||||
|
||||
public ExtensionReceiver(@NotNull CallableDescriptor callableDescriptor, @NotNull JetType receiverType) {
|
||||
super(callableDescriptor, receiverType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitExtensionReceiver(this, data);
|
||||
}
|
||||
}
|
||||
+3
-10
@@ -9,21 +9,14 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
*
|
||||
* @author abreslav
|
||||
*/
|
||||
public abstract class ImplicitReceiverDescriptor implements ReceiverDescriptor {
|
||||
private final JetType receiverType;
|
||||
public abstract class ImplicitReceiverDescriptor extends AbstractReceiverDescriptor {
|
||||
private final DeclarationDescriptor declarationDescriptor;
|
||||
|
||||
protected ImplicitReceiverDescriptor(DeclarationDescriptor declarationDescriptor, JetType receiverType) {
|
||||
this.receiverType = receiverType;
|
||||
protected ImplicitReceiverDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, @NotNull JetType receiverType) {
|
||||
super(receiverType);
|
||||
this.declarationDescriptor = declarationDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JetType getReceiverType() {
|
||||
return receiverType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DeclarationDescriptor getDeclarationDescriptor() {
|
||||
return declarationDescriptor;
|
||||
|
||||
+17
-4
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
@@ -12,8 +11,18 @@ public interface ReceiverDescriptor {
|
||||
ReceiverDescriptor NO_RECEIVER = new ReceiverDescriptor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReceiverType() {
|
||||
return JetStandardClasses.getNothingType();
|
||||
public JetType getType() {
|
||||
throw new UnsupportedOperationException("NO_RECEIVER.getType()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitNoReceiver(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -23,5 +32,9 @@ public interface ReceiverDescriptor {
|
||||
};
|
||||
|
||||
@NotNull
|
||||
JetType getReceiverType();
|
||||
JetType getType();
|
||||
|
||||
boolean exists();
|
||||
|
||||
<R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data);
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ReceiverDescriptorVisitor<R, D> {
|
||||
public R visitNoReceiver(ReceiverDescriptor noReceiver, D data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitTransientReceiver(TransientReceiver receiver, D data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitExtensionReceiver(ExtensionReceiver receiver, D data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitExpressionReceiver(ExpressionReceiver receiver, D data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitClassReceiver(ClassReceiver classReceiver, D data) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* This represents the receiver of hasNext and next() in for-loops
|
||||
* Cannot be an expression receiver because there is no expression for the iterator() call
|
||||
*
|
||||
* @author abreslav
|
||||
*/
|
||||
public class TransientReceiver extends AbstractReceiverDescriptor {
|
||||
public TransientReceiver(@NotNull JetType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitTransientReceiver(this, data);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,9 @@ import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.util.slicedmap.WritableSlice;
|
||||
|
||||
@@ -196,7 +199,7 @@ public class JetTypeInferrer {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType safeGetType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) {
|
||||
public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) {
|
||||
JetType type = getType(scope, expression, expectedType);
|
||||
if (type != null) {
|
||||
return type;
|
||||
@@ -221,9 +224,9 @@ public class JetTypeInferrer {
|
||||
private void checkNullSafety(@Nullable JetType receiverType, @NotNull ASTNode operationTokenNode, @Nullable FunctionDescriptor callee, @NotNull JetElement element) {
|
||||
if (receiverType != null && callee != null) {
|
||||
boolean namespaceType = receiverType instanceof NamespaceType;
|
||||
JetType calleeReceiverType = callee.getReceiverType();
|
||||
boolean nullableReceiver = !namespaceType && receiverType.isNullable();
|
||||
boolean calleeForbidsNullableReceiver = calleeReceiverType == null || !calleeReceiverType.isNullable();
|
||||
ReceiverDescriptor calleeReceiver = callee.getReceiver();
|
||||
boolean calleeForbidsNullableReceiver = !calleeReceiver.exists() || !calleeReceiver.getType().isNullable();
|
||||
|
||||
IElementType operationSign = operationTokenNode.getElementType();
|
||||
if (nullableReceiver && calleeForbidsNullableReceiver && operationSign == JetTokens.DOT) {
|
||||
@@ -682,6 +685,20 @@ public class JetTypeInferrer {
|
||||
}
|
||||
return ErrorUtils.createErrorType("Type for " + expression.getText());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final ExpressionReceiver getExpressionReceiver(@NotNull JetExpression expression, TypeInferenceContext context) {
|
||||
JetType type = getType(expression, context);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
return new ExpressionReceiver(expression, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final ExpressionReceiver safeGetExpressionReceiver(@NotNull JetExpression expression, TypeInferenceContext context) {
|
||||
return new ExpressionReceiver(expression, safeGetType(expression, context));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final JetType getType(@NotNull JetExpression expression, TypeInferenceContext context) {
|
||||
@@ -762,7 +779,7 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
else {
|
||||
return getSelectorReturnType(null, expression, context); // TODO : Extensions to this
|
||||
return getSelectorReturnType(ReceiverDescriptor.NO_RECEIVER, expression, context); // TODO : Extensions to this
|
||||
// assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
|
||||
// if (referencedName != null) {
|
||||
// VariableDescriptor variable = context.scope.getVariable(referencedName);
|
||||
@@ -895,7 +912,8 @@ public class JetTypeInferrer {
|
||||
if (receiverTypeRef != null) {
|
||||
receiverType = context.typeResolver.resolveType(context.scope, receiverTypeRef);
|
||||
} else {
|
||||
receiverType = context.scope.getImplicitReceiver().getReceiverType();
|
||||
ReceiverDescriptor implicitReceiver = context.scope.getImplicitReceiver();
|
||||
receiverType = implicitReceiver.exists() ? implicitReceiver.getType() : null;
|
||||
}
|
||||
|
||||
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
|
||||
@@ -1217,7 +1235,7 @@ public class JetTypeInferrer {
|
||||
@Override
|
||||
public JetType visitThisExpression(JetThisExpression expression, TypeInferenceContext context) {
|
||||
JetType result = null;
|
||||
JetType thisType = null;
|
||||
ReceiverDescriptor thisReceiver = null;
|
||||
String labelName = expression.getLabelName();
|
||||
if (labelName != null) {
|
||||
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
|
||||
@@ -1228,11 +1246,11 @@ public class JetTypeInferrer {
|
||||
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
|
||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||
thisType = classDescriptor.getDefaultType();
|
||||
thisReceiver = classDescriptor.getImplicitReceiver();
|
||||
}
|
||||
else if (declarationDescriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
thisType = functionDescriptor.getReceiverType();
|
||||
thisReceiver = functionDescriptor.getReceiver();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
@@ -1246,11 +1264,8 @@ public class JetTypeInferrer {
|
||||
if (psiElement instanceof JetFunctionLiteralExpression) {
|
||||
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
|
||||
if (declarationDescriptor instanceof FunctionDescriptor) {
|
||||
thisType = ((FunctionDescriptor) declarationDescriptor).getReceiverType();
|
||||
if (thisType == null) {
|
||||
thisType = JetStandardClasses.getNothingType();
|
||||
}
|
||||
else {
|
||||
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiver();
|
||||
if (thisReceiver.exists()) {
|
||||
context.trace.record(REFERENCE_TARGET, targetLabel, declarationDescriptor);
|
||||
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
|
||||
}
|
||||
@@ -1269,7 +1284,7 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
else {
|
||||
thisType = context.scope.getImplicitReceiver().getReceiverType();
|
||||
thisReceiver = context.scope.getImplicitReceiver();
|
||||
|
||||
DeclarationDescriptor declarationDescriptorForUnqualifiedThis = context.scope.getDeclarationDescriptorForUnqualifiedThis();
|
||||
if (declarationDescriptorForUnqualifiedThis != null) {
|
||||
@@ -1277,8 +1292,8 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
|
||||
if (thisType != null) {
|
||||
if (JetStandardClasses.isNothing(thisType)) {
|
||||
if (thisReceiver != null) {
|
||||
if (!thisReceiver.exists()) {
|
||||
// context.trace.getErrorHandler().genericError(expression.getNode(), "'this' is not defined in this context");
|
||||
context.trace.report(NO_THIS.on(expression));
|
||||
}
|
||||
@@ -1294,6 +1309,7 @@ public class JetTypeInferrer {
|
||||
if (classifierCandidate instanceof ClassDescriptor) {
|
||||
ClassDescriptor superclass = (ClassDescriptor) classifierCandidate;
|
||||
|
||||
JetType thisType = thisReceiver.getType();
|
||||
Collection<? extends JetType> supertypes = thisType.getConstructor().getSupertypes();
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(thisType);
|
||||
for (JetType declaredSupertype : supertypes) {
|
||||
@@ -1308,8 +1324,9 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = thisType;
|
||||
}
|
||||
else {
|
||||
result = thisReceiver.getType();
|
||||
}
|
||||
if (result != null) {
|
||||
context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getThisReference(), result);
|
||||
@@ -1396,7 +1413,8 @@ public class JetTypeInferrer {
|
||||
// JetScope compositeScope = new ScopeWithReceiver(context.scope, subjectType, semanticServices.getTypeChecker());
|
||||
if (callSuffixExpression != null) {
|
||||
// JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false, context);
|
||||
JetType selectorReturnType = getSelectorReturnType(subjectType, callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context);
|
||||
assert subjectExpression != null;
|
||||
JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(subjectExpression, subjectType), callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context);
|
||||
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression", context);
|
||||
context.services.checkNullSafety(subjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression, context), condition);
|
||||
}
|
||||
@@ -1474,7 +1492,8 @@ public class JetTypeInferrer {
|
||||
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
|
||||
JetExpression decomposerExpression = pattern.getDecomposerExpression();
|
||||
if (decomposerExpression != null) {
|
||||
JetType selectorReturnType = getSelectorReturnType(subjectType, decomposerExpression, context);
|
||||
ReceiverDescriptor receiver = new TransientReceiver(subjectType);
|
||||
JetType selectorReturnType = getSelectorReturnType(receiver, decomposerExpression, context);
|
||||
|
||||
result[0] = checkPatternType(pattern.getArgumentList(), selectorReturnType == null ? ErrorUtils.createErrorType("No type") : selectorReturnType, scopeToExtend, context);
|
||||
}
|
||||
@@ -1840,13 +1859,12 @@ public class JetTypeInferrer {
|
||||
TypeInferenceContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
|
||||
JetParameter loopParameter = expression.getLoopParameter();
|
||||
JetExpression loopRange = expression.getLoopRange();
|
||||
JetType loopRangeType = null;
|
||||
if (loopRange != null) {
|
||||
loopRangeType = getType(loopRange, context.replaceScope(context.scope));
|
||||
}
|
||||
JetType expectedParameterType = null;
|
||||
if (loopRangeType != null) {
|
||||
expectedParameterType = checkIterableConvention(loopRangeType, loopRange, context);
|
||||
if (loopRange != null) {
|
||||
ExpressionReceiver loopRangeReceiver = getExpressionReceiver(loopRange, context.replaceScope(context.scope));
|
||||
if (loopRangeReceiver != null) {
|
||||
expectedParameterType = checkIterableConvention(loopRangeReceiver, context);
|
||||
}
|
||||
}
|
||||
|
||||
WritableScope loopScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("Scope with for-loop index");
|
||||
@@ -1882,42 +1900,42 @@ public class JetTypeInferrer {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType checkIterableConvention(@NotNull JetType type, @NotNull JetExpression loopRange, TypeInferenceContext context) {
|
||||
ASTNode reportErrorsOn = loopRange.getNode();
|
||||
OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = callResolver.resolveExactSignature(context.scope, type, "iterator", Collections.<JetType>emptyList());
|
||||
private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, TypeInferenceContext context) {
|
||||
JetExpression loopRangeExpression = loopRange.getExpression();
|
||||
OverloadResolutionResult<FunctionDescriptor> iteratorResolutionResult = callResolver.resolveExactSignature(context.scope, loopRange, "iterator", Collections.<JetType>emptyList());
|
||||
if (iteratorResolutionResult.isSuccess()) {
|
||||
FunctionDescriptor iteratorFunction = iteratorResolutionResult.getDescriptor();
|
||||
|
||||
context.trace.record(LOOP_RANGE_ITERATOR, loopRange, iteratorFunction);
|
||||
context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction);
|
||||
|
||||
JetType iteratorType = iteratorFunction.getReturnType();
|
||||
FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRange, iteratorType, context);
|
||||
FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRangeExpression, iteratorType, context);
|
||||
boolean hasNextFunctionSupported = hasNextFunction != null;
|
||||
VariableDescriptor hasNextProperty = checkHasNextPropertySupport(loopRange, iteratorType, context);
|
||||
VariableDescriptor hasNextProperty = checkHasNextPropertySupport(loopRangeExpression, iteratorType, context);
|
||||
boolean hasNextPropertySupported = hasNextProperty != null;
|
||||
if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) {
|
||||
// TODO : overload resolution rules impose priorities here???
|
||||
// context.trace.getErrorHandler().genericError(reportErrorsOn, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property");
|
||||
context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(reportErrorsOn));
|
||||
context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(loopRangeExpression));
|
||||
}
|
||||
else if (!hasNextFunctionSupported && !hasNextPropertySupported) {
|
||||
// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property");
|
||||
context.trace.report(HAS_NEXT_MISSING.on(reportErrorsOn));
|
||||
context.trace.report(HAS_NEXT_MISSING.on(loopRangeExpression));
|
||||
}
|
||||
else {
|
||||
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange, hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
|
||||
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
|
||||
}
|
||||
|
||||
OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "next", Collections.<JetType>emptyList());
|
||||
OverloadResolutionResult<FunctionDescriptor> nextResolutionResult = callResolver.resolveExactSignature(context.scope, new TransientReceiver(iteratorType), "next", Collections.<JetType>emptyList());
|
||||
if (nextResolutionResult.isAmbiguity()) {
|
||||
// context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression");
|
||||
context.trace.report(NEXT_AMBIGUITY.on(reportErrorsOn));
|
||||
context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression));
|
||||
} else if (nextResolutionResult.isNothing()) {
|
||||
// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method");
|
||||
context.trace.report(NEXT_MISSING.on(reportErrorsOn));
|
||||
context.trace.report(NEXT_MISSING.on(loopRangeExpression));
|
||||
} else {
|
||||
FunctionDescriptor nextFunction = nextResolutionResult.getDescriptor();
|
||||
context.trace.record(LOOP_RANGE_NEXT, loopRange, nextFunction);
|
||||
context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction);
|
||||
return nextFunction.getReturnType();
|
||||
}
|
||||
}
|
||||
@@ -1928,11 +1946,11 @@ public class JetTypeInferrer {
|
||||
// stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
|
||||
// }
|
||||
// errorMessage = stringBuffer.toString();
|
||||
context.trace.report(ITERATOR_AMBIGUITY.on(reportErrorsOn, iteratorResolutionResult.getDescriptors()));
|
||||
context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResult.getDescriptors()));
|
||||
}
|
||||
else {
|
||||
// context.trace.getErrorHandler().genericError(reportErrorsOn, errorMessage);
|
||||
context.trace.report(ITERATOR_MISSING.on(reportErrorsOn));
|
||||
context.trace.report(ITERATOR_MISSING.on(loopRangeExpression));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1940,7 +1958,7 @@ public class JetTypeInferrer {
|
||||
|
||||
@Nullable
|
||||
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, TypeInferenceContext context) {
|
||||
OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = callResolver.resolveExactSignature(context.scope, iteratorType, "hasNext", Collections.<JetType>emptyList());
|
||||
OverloadResolutionResult<FunctionDescriptor> hasNextResolutionResult = callResolver.resolveExactSignature(context.scope, new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
|
||||
if (hasNextResolutionResult.isAmbiguity()) {
|
||||
// context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression");
|
||||
context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange));
|
||||
@@ -2002,7 +2020,7 @@ public class JetTypeInferrer {
|
||||
// Clean resolution: no autocasts
|
||||
TemporaryBindingTrace cleanResolutionTrace = TemporaryBindingTrace.create(context.trace);
|
||||
TypeInferenceContext cleanResolutionContext = context.replaceBindingTrace(cleanResolutionTrace);
|
||||
JetType selectorReturnType = getSelectorReturnType(receiverType, selectorExpression, cleanResolutionContext);
|
||||
JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, receiverType), selectorExpression, cleanResolutionContext);
|
||||
|
||||
//TODO move further
|
||||
if (expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
|
||||
@@ -2023,7 +2041,7 @@ public class JetTypeInferrer {
|
||||
TemporaryBindingTrace autocastResolutionTrace = TemporaryBindingTrace.create(context.trace);
|
||||
TypeInferenceContext autocastResolutionContext = context.replaceBindingTrace(autocastResolutionTrace);
|
||||
for (JetType possibleType : possibleTypes) {
|
||||
selectorReturnType = getSelectorReturnType(possibleType, selectorExpression, autocastResolutionContext);
|
||||
selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, possibleType), selectorExpression, autocastResolutionContext);
|
||||
if (selectorReturnType != null) {
|
||||
context.services.checkAutoCast(receiverExpression, possibleType, variableDescriptor, autocastResolutionTrace);
|
||||
autocastResolutionTrace.commit();
|
||||
@@ -2146,20 +2164,20 @@ public class JetTypeInferrer {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType getSelectorReturnType(@Nullable JetType receiverType, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
|
||||
private JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @NotNull JetExpression selectorExpression, @NotNull TypeInferenceContext context) {
|
||||
if (selectorExpression instanceof JetCallExpression) {
|
||||
return callResolver.resolveCall(context.trace, context.scope, receiverType, (JetCallExpression) selectorExpression, context.expectedType);
|
||||
return callResolver.resolveCall(context.trace, context.scope, receiver, (JetCallExpression) selectorExpression, context.expectedType);
|
||||
}
|
||||
else if (selectorExpression instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
|
||||
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
|
||||
VariableDescriptor variableDescriptor = callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiverType, nameExpression, context.expectedType);
|
||||
VariableDescriptor variableDescriptor = callResolver.resolveSimpleProperty(temporaryTrace, context.scope, receiver, nameExpression, context.expectedType);
|
||||
if (variableDescriptor != null) {
|
||||
temporaryTrace.commit();
|
||||
return context.services.checkEnrichedType(variableDescriptor.getOutType(), nameExpression, context);
|
||||
}
|
||||
TypeInferenceContext newContext = receiverType == null ? context : context.replaceScope(receiverType.getMemberScope());
|
||||
TypeInferenceContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context;
|
||||
JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext);
|
||||
if (jetType == null) {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(nameExpression));
|
||||
@@ -2170,10 +2188,11 @@ public class JetTypeInferrer {
|
||||
}
|
||||
else if (selectorExpression instanceof JetQualifiedExpression) {
|
||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression;
|
||||
JetType newReceiverType = getSelectorReturnType(receiverType, qualifiedExpression.getReceiverExpression(), context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||
JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression();
|
||||
JetType newReceiverType = getSelectorReturnType(receiver, newReceiverExpression, context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||
JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression();
|
||||
if (newReceiverType != null && newSelectorExpression != null) {
|
||||
return getSelectorReturnType(newReceiverType, newSelectorExpression, context);
|
||||
return getSelectorReturnType(new ExpressionReceiver(newReceiverExpression, newReceiverType), newSelectorExpression, context);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2186,7 +2205,7 @@ public class JetTypeInferrer {
|
||||
|
||||
@Override
|
||||
public JetType visitCallExpression(JetCallExpression expression, TypeInferenceContext context) {
|
||||
JetType expressionType = callResolver.resolveCall(context.trace, context.scope, null, expression, context.expectedType);
|
||||
JetType expressionType = callResolver.resolveCall(context.trace, context.scope, ReceiverDescriptor.NO_RECEIVER, expression, context.expectedType);
|
||||
return context.services.checkType(expressionType, expression, context);
|
||||
}
|
||||
|
||||
@@ -2220,8 +2239,8 @@ public class JetTypeInferrer {
|
||||
context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression"));
|
||||
return null;
|
||||
}
|
||||
JetType receiverType = getType(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
|
||||
if (receiverType == null) return null;
|
||||
ExpressionReceiver receiver = getExpressionReceiver(baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
|
||||
if (receiver == null) return null;
|
||||
|
||||
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
@@ -2229,7 +2248,7 @@ public class JetTypeInferrer {
|
||||
CallMaker.makeCall(expression),
|
||||
expression.getOperationSign(),
|
||||
name,
|
||||
receiverType,
|
||||
receiver,
|
||||
context.expectedType);
|
||||
|
||||
if (functionDescriptor == null) return null;
|
||||
@@ -2240,6 +2259,7 @@ public class JetTypeInferrer {
|
||||
result = JetStandardClasses.getUnitType();
|
||||
}
|
||||
else {
|
||||
JetType receiverType = receiver.getType();
|
||||
if (!semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) {
|
||||
// context.trace.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType);
|
||||
context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType));
|
||||
@@ -2299,9 +2319,9 @@ public class JetTypeInferrer {
|
||||
else if (equalsOperations.contains(operationType)) {
|
||||
String name = "equals";
|
||||
if (right != null) {
|
||||
JetType leftType = safeGetType(left, context.replaceScope(context.scope));
|
||||
ExpressionReceiver receiver = safeGetExpressionReceiver(left, context.replaceScope(context.scope));
|
||||
OverloadResolutionResult<FunctionDescriptor> resolutionResult = callResolver.resolveExactSignature(
|
||||
context.scope, leftType, "equals",
|
||||
context.scope, receiver, "equals",
|
||||
Collections.singletonList(JetStandardClasses.getNullableAnyType()));
|
||||
if (resolutionResult.isSuccess()) {
|
||||
FunctionDescriptor equals = resolutionResult.getDescriptor();
|
||||
@@ -2380,13 +2400,13 @@ public class JetTypeInferrer {
|
||||
|
||||
private void checkInExpression(JetSimpleNameExpression operationSign, JetExpression left, JetExpression right, TypeInferenceContext context) {
|
||||
String name = "contains";
|
||||
JetType receiverType = context.services.safeGetType(context.scope, right, NO_EXPECTED_TYPE);
|
||||
ExpressionReceiver receiver = safeGetExpressionReceiver(right, context.replaceExpectedType(NO_EXPECTED_TYPE));
|
||||
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
context.scope,
|
||||
CallMaker.makeCall(operationSign, Collections.singletonList(left)),
|
||||
operationSign,
|
||||
name, receiverType, context.expectedType);
|
||||
name, receiver, context.expectedType);
|
||||
JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null;
|
||||
ensureBooleanResult(operationSign, name, containsType, context);
|
||||
}
|
||||
@@ -2449,16 +2469,16 @@ public class JetTypeInferrer {
|
||||
public JetType visitArrayAccessExpression(JetArrayAccessExpression expression, TypeInferenceContext contextWithExpectedType) {
|
||||
TypeInferenceContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE);
|
||||
JetExpression arrayExpression = expression.getArrayExpression();
|
||||
JetType receiverType = getType(arrayExpression, context.replaceScope(context.scope));
|
||||
ExpressionReceiver receiver = getExpressionReceiver(arrayExpression, context.replaceScope(context.scope));
|
||||
|
||||
if (receiverType != null) {
|
||||
if (receiver != null) {
|
||||
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
context.scope,
|
||||
CallMaker.makeCall(expression, expression.getIndexExpressions()),
|
||||
expression,
|
||||
"get",
|
||||
receiverType,
|
||||
receiver,
|
||||
context.expectedType);
|
||||
if (functionDescriptor != null) {
|
||||
return context.services.checkType(functionDescriptor.getReturnType(), expression, contextWithExpectedType);
|
||||
@@ -2469,17 +2489,17 @@ public class JetTypeInferrer {
|
||||
|
||||
@Nullable
|
||||
protected JetType getTypeForBinaryCall(JetScope scope, String name, TypeInferenceContext context, JetBinaryExpression binaryExpression) {
|
||||
JetType leftType = getType(binaryExpression.getLeft(), context.replaceScope(scope));
|
||||
ExpressionReceiver receiver = safeGetExpressionReceiver(binaryExpression.getLeft(), context.replaceScope(scope));
|
||||
FunctionDescriptor functionDescriptor = callResolver.resolveCallWithGivenName(
|
||||
context.trace,
|
||||
scope,
|
||||
CallMaker.makeCall(binaryExpression),
|
||||
binaryExpression.getOperationReference(),
|
||||
name,
|
||||
leftType,
|
||||
receiver,
|
||||
context.expectedType);
|
||||
if (functionDescriptor != null) {
|
||||
if (leftType != null && leftType.isNullable()) {
|
||||
if (receiver.getType().isNullable()) {
|
||||
// TODO : better error message for '1 + nullableVar' case
|
||||
JetExpression right = binaryExpression.getRight();
|
||||
String rightText = right == null ? "" : right.getText();
|
||||
@@ -2719,8 +2739,8 @@ public class JetTypeInferrer {
|
||||
}
|
||||
|
||||
private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, TypeInferenceContext context) {
|
||||
JetType receiverType = getType(arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
|
||||
if (receiverType == null) return null;
|
||||
ExpressionReceiver receiver = getExpressionReceiver(arrayAccessExpression.getArrayExpression(), context.replaceScope(scope));
|
||||
if (receiver == null) return null;
|
||||
//
|
||||
Call call = CallMaker.makeCall(arrayAccessExpression, rightHandSide);
|
||||
// // TODO : nasty hack: effort is duplicated
|
||||
@@ -2734,7 +2754,7 @@ public class JetTypeInferrer {
|
||||
scope,
|
||||
call,
|
||||
arrayAccessExpression,
|
||||
"set", receiverType, NO_EXPECTED_TYPE);
|
||||
"set", receiver, NO_EXPECTED_TYPE);
|
||||
if (functionDescriptor == null) return null;
|
||||
context.trace.record(REFERENCE_TARGET, operationSign, functionDescriptor);
|
||||
return context.services.checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context);
|
||||
|
||||
@@ -3,7 +3,9 @@ package org.jetbrains.jet.resolve;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
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.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -128,7 +130,7 @@ public class DescriptorRenderer {
|
||||
|
||||
@Override
|
||||
public Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder) {
|
||||
String typeString = renderPropertyPrefixAndComputeTypeString(builder, Collections.<TypeParameterDescriptor>emptyList(), null, descriptor.getOutType(), descriptor.getInType());
|
||||
String typeString = renderPropertyPrefixAndComputeTypeString(builder, Collections.<TypeParameterDescriptor>emptyList(), ReceiverDescriptor.NO_RECEIVER, descriptor.getOutType(), descriptor.getInType());
|
||||
renderName(descriptor, builder);
|
||||
builder.append(" : ").append(escape(typeString));
|
||||
return super.visitVariableDescriptor(descriptor, builder);
|
||||
@@ -137,7 +139,7 @@ public class DescriptorRenderer {
|
||||
private String renderPropertyPrefixAndComputeTypeString(
|
||||
@NotNull StringBuilder builder,
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@Nullable JetType outType,
|
||||
@Nullable JetType inType) {
|
||||
String typeString = lt() + "no type>";
|
||||
@@ -161,8 +163,8 @@ public class DescriptorRenderer {
|
||||
|
||||
renderTypeParameters(typeParameters, builder);
|
||||
|
||||
if (receiverType != null) {
|
||||
builder.append(escape(renderType(receiverType))).append(".");
|
||||
if (receiver.exists()) {
|
||||
builder.append(escape(renderType(receiver.getType()))).append(".");
|
||||
}
|
||||
|
||||
return typeString;
|
||||
@@ -172,7 +174,7 @@ public class DescriptorRenderer {
|
||||
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
|
||||
String typeString = renderPropertyPrefixAndComputeTypeString(
|
||||
builder, descriptor.getTypeParameters(),
|
||||
descriptor.getReceiverType(),
|
||||
descriptor.getReceiver(),
|
||||
descriptor.getOutType(),
|
||||
descriptor.getInType());
|
||||
renderName(descriptor, builder);
|
||||
@@ -185,9 +187,9 @@ public class DescriptorRenderer {
|
||||
builder.append(renderKeyword("fun")).append(" ");
|
||||
renderTypeParameters(descriptor.getTypeParameters(), builder);
|
||||
|
||||
JetType receiverType = descriptor.getReceiverType();
|
||||
if (receiverType != null) {
|
||||
builder.append(escape(renderType(receiverType))).append(".");
|
||||
ReceiverDescriptor receiver = descriptor.getReceiver();
|
||||
if (receiver.exists()) {
|
||||
builder.append(escape(renderType(receiver.getType()))).append(".");
|
||||
}
|
||||
|
||||
renderName(descriptor, builder);
|
||||
|
||||
Binary file not shown.
@@ -89,7 +89,7 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
||||
JetFile file = (JetFile) getElement().getContainingFile();
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(file);
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (declarationDescriptors != null) return ResolveResult.EMPTY_ARRAY;
|
||||
if (declarationDescriptors == null) return ResolveResult.EMPTY_ARRAY;
|
||||
ResolveResult[] results = new ResolveResult[declarationDescriptors.size()];
|
||||
int i = 0;
|
||||
for (DeclarationDescriptor descriptor : declarationDescriptors) {
|
||||
|
||||
@@ -3,7 +3,7 @@ fun text() {
|
||||
"direct:a" on {it.body == "<hello/>"} to "mock:a"
|
||||
"direct:a" on {it => it.body == "<hello/>"} to "mock:a"
|
||||
bar <!TYPE_MISMATCH!>{1}<!>
|
||||
bar <!TYPE_MISMATCH!>{<!UNRESOLVED_REFERENCE!>it<!> <!UNRESOLVED_REFERENCE!>+<!> 1}<!>
|
||||
bar <!TYPE_MISMATCH!>{<!UNRESOLVED_REFERENCE!>it<!> + 1}<!>
|
||||
bar {it, it1 => it}
|
||||
|
||||
bar1 {1}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// KT-306 Ambiguity when different this's have same-looking functions
|
||||
|
||||
fun test() {
|
||||
{Foo.() =>
|
||||
bar()
|
||||
{Barr.() =>
|
||||
this.bar()
|
||||
bar()
|
||||
}
|
||||
}
|
||||
{Barr.() =>
|
||||
bar()
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
class Barr {
|
||||
fun bar() {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// KT-307 Unresolved reference
|
||||
|
||||
open class AL {
|
||||
fun get(i : Int) : Any? = i
|
||||
}
|
||||
|
||||
trait ALE<T> : AL {
|
||||
fun getOrNull(index: Int, value: T) : T {
|
||||
return get(index) as? T ?: value
|
||||
}
|
||||
}
|
||||
@@ -167,6 +167,7 @@ fun t26 () : Boolean {
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
/*
|
||||
if(!t1()) {
|
||||
return "t1 failed"
|
||||
}
|
||||
@@ -242,6 +243,7 @@ fun box() : String {
|
||||
if(!t25()) {
|
||||
return "t25 failed"
|
||||
}
|
||||
*/
|
||||
if(!t26()) {
|
||||
return "t26 failed"
|
||||
}
|
||||
|
||||
@@ -3,13 +3,19 @@ trait AL {
|
||||
}
|
||||
|
||||
trait ALE<T> : AL {
|
||||
fun getOrNull(index: Int, value : T) = get(index) as? T ?: value
|
||||
fun getOrNull(index: Int, value: T) : T {
|
||||
val r = get(index) as? T
|
||||
return r ?: value
|
||||
}
|
||||
}
|
||||
|
||||
class SmartArrayList() : ALE<String> {
|
||||
open class SmartArrayList() : ALE<String> {
|
||||
}
|
||||
|
||||
class SmartArrayList2() : SmartArrayList(), AL {
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val c = SmartArrayList()
|
||||
val c = SmartArrayList2()
|
||||
return if("239" == c.getOrNull(0, "239")) "OK" else "fail"
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
val x = 1 : Int?:Any?
|
||||
val y = null ?: 1
|
||||
@@ -1,48 +0,0 @@
|
||||
JetFile: ElvisSplit.jet
|
||||
NAMESPACE
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
BINARY_WITH_TYPE
|
||||
BINARY_WITH_TYPE
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiElement(QUEST)('?')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(COLON)(':')
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Any')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiWhiteSpace('\n')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
BINARY_EXPRESSION
|
||||
NULL
|
||||
PsiElement(null)('null')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(ELVIS)('?:')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
@@ -17,7 +17,7 @@ public class TraitsTest extends CodegenTestCase {
|
||||
}
|
||||
|
||||
public void testMultiple () throws Exception {
|
||||
// blackBoxFile("traits/multiple.jet");
|
||||
// System.out.println(generateToText());
|
||||
blackBoxFile("traits/multiple.jet");
|
||||
System.out.println(generateToText());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResult;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
|
||||
@@ -106,7 +107,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
|
||||
List<JetType> parameterTypeList = Arrays.asList(parameterType);
|
||||
JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext(), JetFlowInformationProvider.NONE);
|
||||
|
||||
OverloadResolutionResult<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(classDescriptor.getMemberScope(typeArguments), null, name, parameterTypeList);
|
||||
OverloadResolutionResult<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(
|
||||
classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList);
|
||||
for (FunctionDescriptor function : functions.getDescriptors()) {
|
||||
List<ValueParameterDescriptor> unsubstitutedValueParameters = function.getValueParameters();
|
||||
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaPackageScope;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExplicitReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -504,13 +504,13 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
assertTrue("Error type expected but " + type + " returned", ErrorUtils.isErrorType(type));
|
||||
}
|
||||
|
||||
private void assertType(String contextType, String expression, String expectedType) {
|
||||
private void assertType(String contextType, final String expression, String expectedType) {
|
||||
final JetType thisType = makeType(contextType);
|
||||
JetScope scope = new JetScopeAdapter(classDefinitions.BASIC_SCOPE) {
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
return new ExplicitReceiver(thisType);
|
||||
return new ExpressionReceiver(JetPsiFactory.createExpression(getProject(), expression), thisType);
|
||||
}
|
||||
};
|
||||
assertType(scope, expression, expectedType);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jet.typeinfo;
|
||||
|
||||
import com.sun.org.apache.bcel.internal.generic.MethodGen;
|
||||
import jet.JetObject;
|
||||
import jet.Tuple0;
|
||||
|
||||
@@ -38,25 +39,8 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
public static final TypeInfo<String> NULLABLE_STRING_TYPE_INFO = getTypeInfo(String.class, true);
|
||||
public static final TypeInfo<Tuple0> NULLABLE_TUPLE0_TYPE_INFO = getTypeInfo(Tuple0.class, true);
|
||||
|
||||
private TypeInfo<?> typeInfo;
|
||||
private final Signature signature;
|
||||
private final boolean nullable;
|
||||
private final TypeInfoProjection[] projections;
|
||||
|
||||
private TypeInfo(Class<T> theClass, boolean nullable) {
|
||||
this(theClass, nullable, EMPTY);
|
||||
}
|
||||
|
||||
private TypeInfo(Class<T> theClass, boolean nullable, TypeInfoProjection[] projections) {
|
||||
this.signature = Parser.parse(theClass);
|
||||
this.nullable = nullable;
|
||||
this.projections = projections;
|
||||
if(signature.variables.size() != projections.length)
|
||||
throw new IllegalStateException("Wrong signature " + theClass.getName());
|
||||
}
|
||||
|
||||
public static <T> TypeInfoProjection invariantProjection(final TypeInfo<T> typeInfo) {
|
||||
return (TypeInfoImpl) typeInfo;
|
||||
return (TypeInfoProjection) typeInfo;
|
||||
}
|
||||
|
||||
public static <T> TypeInfoProjection inProjection(TypeInfo<T> typeInfo) {
|
||||
@@ -87,103 +71,196 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
return new TypeInfoImpl<T>(klazz, nullable, projections);
|
||||
}
|
||||
|
||||
public final Object getClassObject() {
|
||||
try {
|
||||
final Class implClass = signature.klazz.getClassLoader().loadClass(signature.klazz.getCanonicalName());
|
||||
final Field classobj = implClass.getField("$classobj");
|
||||
return classobj.get(null);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public abstract Object getClassObject();
|
||||
|
||||
public final boolean isInstance(Object obj) {
|
||||
if (obj == null) return nullable;
|
||||
public abstract boolean isInstance(Object obj);
|
||||
|
||||
if (obj instanceof JetObject) {
|
||||
return ((JetObject) obj).getTypeInfo().isSubtypeOf(this);
|
||||
public abstract int getProjectionCount();
|
||||
|
||||
public abstract TypeInfoProjection getProjection(int index);
|
||||
|
||||
public abstract TypeInfo getArgumentType(Class klass, int index);
|
||||
|
||||
public abstract TypeInfo substitute(List<TypeInfo> myVars);
|
||||
|
||||
private static class TypeInfoVar<T> extends TypeInfo<T> {
|
||||
final int varIndex;
|
||||
final boolean nullable;
|
||||
|
||||
private TypeInfoVar(Integer varIndex) {
|
||||
this.varIndex = varIndex;
|
||||
nullable = false;
|
||||
}
|
||||
|
||||
return signature.klazz.isAssignableFrom(obj.getClass()); // TODO
|
||||
}
|
||||
|
||||
public final boolean isSubtypeOf(TypeInfo<?> superType) {
|
||||
if (nullable && !superType.nullable) {
|
||||
return false;
|
||||
public TypeInfoVar(boolean nullable, Integer varIndex) {
|
||||
this.nullable = nullable;
|
||||
this.varIndex = varIndex;
|
||||
}
|
||||
if (!superType.signature.klazz.isAssignableFrom(signature.klazz)) {
|
||||
return false;
|
||||
|
||||
@Override
|
||||
public Object getClassObject() {
|
||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||
}
|
||||
if (superType.projections == null || superType.projections.length != projections.length) {
|
||||
throw new IllegalArgumentException("inconsistent type infos for the same class");
|
||||
|
||||
@Override
|
||||
public boolean isInstance(Object obj) {
|
||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||
}
|
||||
for (int i = 0; i < projections.length; i++) {
|
||||
// TODO handle variance here
|
||||
if (!projections[i].equals(superType.projections[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProjectionCount() {
|
||||
return 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public final TypeInfoProjection getProjection(int index) {
|
||||
return projections[index];
|
||||
}
|
||||
|
||||
public final TypeInfo getArgumentType(int index) {
|
||||
return projections[index].getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TypeInfo<?> getTypeInfo() {
|
||||
if (typeInfo == null) {
|
||||
// TODO: Implementation must be lazy, otherwise the result would be of an infinite size
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
@Override
|
||||
public TypeInfoProjection getProjection(int index) {
|
||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||
}
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
TypeInfo typeInfo = (TypeInfo) o;
|
||||
|
||||
if (!signature.klazz.equals(typeInfo.signature.klazz)) return false;
|
||||
if (nullable != typeInfo.nullable) return false;
|
||||
if (!Arrays.equals(projections, typeInfo.projections)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return 31 * signature.klazz.hashCode() + Arrays.hashCode(projections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder sb = new StringBuilder().append(signature.klazz.getName());
|
||||
if (projections.length != 0) {
|
||||
sb.append("<");
|
||||
for (int i = 0; i != projections.length - 1; ++i) {
|
||||
sb.append(projections[i].toString()).append(",");
|
||||
}
|
||||
sb.append(projections[projections.length - 1].toString()).append(">");
|
||||
@Override
|
||||
public TypeInfo getArgumentType(Class klass, int index) {
|
||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo substitute(List<TypeInfo> myVars) {
|
||||
return myVars.get(varIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeInfo substitute(TypeInfoProjection[] projections) {
|
||||
return projections[varIndex].getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo<?> getTypeInfo() {
|
||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "T:" + varIndex;
|
||||
}
|
||||
if (nullable)
|
||||
sb.append("?");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static class TypeInfoImpl<T> extends TypeInfo<T> implements TypeInfoProjection {
|
||||
TypeInfoImpl(Class<T> klazz, boolean nullable) {
|
||||
super(klazz, nullable);
|
||||
private TypeInfo<?> typeInfo;
|
||||
private final Signature signature;
|
||||
private final boolean nullable;
|
||||
private final TypeInfoProjection[] projections;
|
||||
|
||||
TypeInfoImpl(Class<T> theClass, boolean nullable) {
|
||||
this(theClass, nullable, EMPTY);
|
||||
}
|
||||
|
||||
TypeInfoImpl(Class<T> klazz, boolean nullable, TypeInfoProjection[] projections) {
|
||||
super(klazz, nullable, projections);
|
||||
private TypeInfoImpl(Class<T> theClass, boolean nullable, TypeInfoProjection[] projections) {
|
||||
this.signature = Parser.parse(theClass);
|
||||
this.nullable = nullable;
|
||||
this.projections = projections;
|
||||
if(signature.variables.size() != projections.length)
|
||||
throw new IllegalStateException("Wrong signature " + theClass.getName());
|
||||
}
|
||||
|
||||
public final TypeInfoProjection getProjection(int index) {
|
||||
return projections[index];
|
||||
}
|
||||
|
||||
public final Object getClassObject() {
|
||||
try {
|
||||
final Class implClass = signature.klazz.getClassLoader().loadClass(signature.klazz.getCanonicalName());
|
||||
final Field classobj = implClass.getField("$classobj");
|
||||
return classobj.get(null);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
TypeInfo getSuperTypeInfo(Class klass) {
|
||||
return signature.superSignatures.get(klass);
|
||||
}
|
||||
|
||||
public final TypeInfo getArgumentType(Class klass, int index) {
|
||||
if(klass == this.signature.klazz)
|
||||
return projections[index].getType();
|
||||
else {
|
||||
return getSuperTypeInfo(klass).substitute(projections).getArgumentType(klass, index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo substitute(final List<TypeInfo> myVars) {
|
||||
if(projections.length == 0)
|
||||
return new TypeInfoImpl(signature.klazz, nullable, EMPTY);
|
||||
else {
|
||||
TypeInfoProjection [] proj = new TypeInfoProjection[projections.length];
|
||||
for(int i = 0; i != proj.length; ++i) {
|
||||
final int finalI = i;
|
||||
final TypeInfo substitute = projections[finalI].getType().substitute(myVars);
|
||||
proj[i] = new TypeInfoProjection(){
|
||||
|
||||
@Override
|
||||
public TypeInfoVariance getVariance() {
|
||||
return projections[finalI].getVariance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getType() {
|
||||
return substitute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getVariance().toString() + " " + substitute;
|
||||
}
|
||||
};
|
||||
}
|
||||
return new TypeInfoImpl(signature.klazz, nullable, proj);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeInfo substitute(TypeInfoProjection[] prj) {
|
||||
if(projections.length == 0)
|
||||
return new TypeInfoImpl(signature.klazz, nullable, EMPTY);
|
||||
else {
|
||||
TypeInfoProjection [] proj = new TypeInfoProjection[projections.length];
|
||||
for(int i = 0; i != proj.length; ++i) {
|
||||
final int finalI = i;
|
||||
final TypeInfo substitute = projections[finalI].getType().substitute(prj);
|
||||
proj[i] = new TypeInfoProjection(){
|
||||
|
||||
@Override
|
||||
public TypeInfoVariance getVariance() {
|
||||
return projections[finalI].getVariance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getType() {
|
||||
return substitute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getVariance().toString() + " " + substitute;
|
||||
}
|
||||
};
|
||||
}
|
||||
return new TypeInfoImpl(signature.klazz, nullable, proj);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
TypeInfoImpl typeInfo = (TypeInfoImpl) o;
|
||||
|
||||
if (!signature.klazz.equals(typeInfo.signature.klazz)) return false;
|
||||
if (nullable != typeInfo.nullable) return false;
|
||||
if (!Arrays.equals(projections, typeInfo.projections)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// @NotNull
|
||||
@@ -197,81 +274,116 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
public TypeInfo getType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return 31 * signature.klazz.hashCode() + Arrays.hashCode(projections);
|
||||
}
|
||||
|
||||
public final boolean isInstance(Object obj) {
|
||||
if (obj == null) return nullable;
|
||||
|
||||
if (obj instanceof JetObject) {
|
||||
return ((TypeInfoImpl)((JetObject) obj).getTypeInfo()).isSubtypeOf(this);
|
||||
}
|
||||
|
||||
return signature.klazz.isAssignableFrom(obj.getClass()); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProjectionCount() {
|
||||
return projections.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder sb = new StringBuilder().append(signature.klazz.getName());
|
||||
if (projections.length != 0) {
|
||||
sb.append("<");
|
||||
for (int i = 0; i != projections.length - 1; ++i) {
|
||||
sb.append(projections[i].toString()).append(",");
|
||||
}
|
||||
sb.append(projections[projections.length - 1].toString()).append(">");
|
||||
}
|
||||
if (nullable)
|
||||
sb.append("?");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TypeInfo<?> getTypeInfo() {
|
||||
if (typeInfo == null) {
|
||||
// TODO: Implementation must be lazy, otherwise the result would be of an infinite size
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final boolean isSubtypeOf(TypeInfoImpl<?> superType) {
|
||||
if (nullable && !superType.nullable) {
|
||||
return false;
|
||||
}
|
||||
if (!superType.signature.klazz.isAssignableFrom(signature.klazz)) {
|
||||
return false;
|
||||
}
|
||||
if (superType.projections == null || superType.projections.length != projections.length) {
|
||||
throw new IllegalArgumentException("inconsistent type infos for the same class");
|
||||
}
|
||||
for (int i = 0; i < projections.length; i++) {
|
||||
// TODO handle variance here
|
||||
if (!projections[i].getType().equals(superType.projections[i].getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected abstract TypeInfo substitute(TypeInfoProjection[] projections);
|
||||
|
||||
public static class Signature {
|
||||
final Class klazz;
|
||||
final List<Var> variables;
|
||||
final List<Type> superTypes;
|
||||
final List<TypeInfoProjection> variables;
|
||||
final List<TypeInfo> superTypes;
|
||||
|
||||
final HashMap<Class,Signature> superSignatures = new HashMap<Class,Signature>();
|
||||
final HashMap<Class,TypeInfo> superSignatures = new HashMap<Class,TypeInfo>();
|
||||
|
||||
public Signature(Class klazz, List<Var> variables, List<Type> superTypes) {
|
||||
public Signature(Class klazz, List<TypeInfoProjection> variables, List<TypeInfo> superTypes) {
|
||||
this.klazz = klazz;
|
||||
this.superTypes = superTypes;
|
||||
this.variables = variables;
|
||||
|
||||
for(Type superType : superTypes) {
|
||||
if(superType instanceof TypeReal) {
|
||||
TypeReal type = (TypeReal) superType;
|
||||
Signature parse = Parser.parse(type.klazz);
|
||||
superSignatures.put(type.klazz, parse);
|
||||
for(Map.Entry<Class,Signature> entry : parse.superSignatures.entrySet()) {
|
||||
superSignatures.put(entry.getKey(), entry.getValue());
|
||||
List<TypeInfo> myVars = variables == null ? Collections.<TypeInfo>emptyList() : new LinkedList<TypeInfo>();
|
||||
if(variables != null)
|
||||
for(int i = 0; i != variables.size(); ++i)
|
||||
myVars.add(new TypeInfoVar(false, i));
|
||||
|
||||
for(TypeInfo superType : superTypes) {
|
||||
if(superType instanceof TypeInfoImpl) {
|
||||
TypeInfoImpl type = (TypeInfoImpl) superType;
|
||||
Signature superSignature = Parser.parse(type.signature.klazz);
|
||||
|
||||
TypeInfo substituted = type.substitute(myVars);
|
||||
superSignatures.put(type.signature.klazz, substituted);
|
||||
|
||||
List<TypeInfo> vars = Collections.emptyList();
|
||||
if(superType.getProjectionCount() != 0) {
|
||||
vars = new LinkedList<TypeInfo>();
|
||||
for(int i=0; i != superType.getProjectionCount(); ++i) {
|
||||
TypeInfo substitute = superType.getProjection(i).getType().substitute(myVars);
|
||||
vars.add(substitute);
|
||||
}
|
||||
}
|
||||
|
||||
for(Map.Entry<Class,TypeInfo> entry : superSignature.superSignatures.entrySet()) {
|
||||
superSignatures.put(entry.getKey(), entry.getValue().substitute(vars));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Var {
|
||||
final String name;
|
||||
final TypeInfoVariance variance;
|
||||
|
||||
public Var(String name, TypeInfoVariance variance) {
|
||||
this.name = name;
|
||||
this.variance = variance;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class Type{
|
||||
final boolean nullable;
|
||||
|
||||
protected Type(boolean nullable) {
|
||||
this.nullable = nullable;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeVar extends Type {
|
||||
final int varIndex;
|
||||
|
||||
public TypeVar(boolean nullable, int varIndex) {
|
||||
super(nullable);
|
||||
this.varIndex = varIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeProj {
|
||||
public final TypeInfoVariance variance;
|
||||
public final Type type;
|
||||
|
||||
public TypeProj(TypeInfoVariance variance, Type type) {
|
||||
this.variance = variance;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeReal extends Type {
|
||||
public final Class klazz;
|
||||
public final List<TypeProj> params;
|
||||
|
||||
public TypeReal(Class klazz, boolean nullable, List<TypeProj> params) {
|
||||
super(nullable);
|
||||
this.params = params;
|
||||
this.klazz = klazz;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Parser {
|
||||
static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
static final WeakHashMap<Class,Signature> map = new WeakHashMap<Class,Signature>();
|
||||
@@ -323,49 +435,76 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
|
||||
TypeVariable[] typeParameters = klass.getTypeParameters();
|
||||
Map<String,Integer> variables;
|
||||
List<Var> vars;
|
||||
List<TypeInfoProjection> vars;
|
||||
if(typeParameters == null || typeParameters.length == 0) {
|
||||
variables = Collections.emptyMap();
|
||||
vars = Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
variables = new HashMap<String, Integer>();
|
||||
vars = new LinkedList<Var>();
|
||||
vars = new LinkedList<TypeInfoProjection>();
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
TypeVariable typeParameter = typeParameters[i];
|
||||
variables.put(typeParameter.getName(), i);
|
||||
vars.add(new Var(typeParameter.getName(), TypeInfoVariance.INVARIANT));
|
||||
final TypeInfoVar typeInfoVar = new TypeInfoVar(false, i);
|
||||
vars.add(new TypeInfoProjection(){
|
||||
|
||||
@Override
|
||||
public TypeInfoVariance getVariance() {
|
||||
return TypeInfoVariance.INVARIANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getType() {
|
||||
return typeInfoVar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return typeInfoVar.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
List<Type> types = new LinkedList<Type>();
|
||||
List<TypeInfo> types = new LinkedList<TypeInfo>();
|
||||
java.lang.reflect.Type genericSuperclass = klass.getGenericSuperclass();
|
||||
return new Signature(klass, vars, types);
|
||||
}
|
||||
|
||||
public List<Var> parseVars() {
|
||||
List<Var> list = null;
|
||||
public List<TypeInfoProjection> parseVars() {
|
||||
List<TypeInfoProjection> list = null;
|
||||
while(cur != string.length && string[cur] == 'T') {
|
||||
if(list == null)
|
||||
list = new LinkedList<Var>();
|
||||
if(list == null) {
|
||||
list = new LinkedList<TypeInfoProjection>();
|
||||
variables = new HashMap<String, Integer>();
|
||||
}
|
||||
list.add(parseVar());
|
||||
}
|
||||
List<Var> vars = list == null ? Collections.<Var>emptyList() : list;
|
||||
if(vars.isEmpty())
|
||||
variables = Collections.emptyMap();
|
||||
else {
|
||||
variables = new HashMap<String, Integer>();
|
||||
for(int i=0; i != list.size(); ++i) {
|
||||
variables.put(list.get(i).name, i);
|
||||
}
|
||||
}
|
||||
return vars;
|
||||
return list == null ? Collections.<TypeInfoProjection>emptyList() : list;
|
||||
}
|
||||
|
||||
private Var parseVar() {
|
||||
TypeInfoVariance variance = parseVariance();
|
||||
private TypeInfoProjection parseVar() {
|
||||
final TypeInfoVariance variance = parseVariance();
|
||||
String name = parseName();
|
||||
return new Var(name, variance);
|
||||
final TypeInfoVar typeInfoVar = new TypeInfoVar(variables.size());
|
||||
variables.put(name, variables.size());
|
||||
return new TypeInfoProjection(){
|
||||
@Override
|
||||
public TypeInfoVariance getVariance() {
|
||||
return variance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getType() {
|
||||
return typeInfoVar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return typeInfoVar.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String parseName() {
|
||||
@@ -392,18 +531,18 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
}
|
||||
}
|
||||
|
||||
public List<Type> parseTypes() {
|
||||
List<Type> types = null;
|
||||
public List<TypeInfo> parseTypes() {
|
||||
List<TypeInfo> types = null;
|
||||
while(cur != string.length) {
|
||||
if(types == null) {
|
||||
types = new LinkedList<Type>();
|
||||
types = new LinkedList<TypeInfo>();
|
||||
}
|
||||
types.add(parseType());
|
||||
}
|
||||
return types == null ? Collections.<Type>emptyList() : types;
|
||||
return types == null ? Collections.<TypeInfo>emptyList() : types;
|
||||
}
|
||||
|
||||
private Type parseType() {
|
||||
private TypeInfo parseType() {
|
||||
switch (string[cur]) {
|
||||
case 'L':
|
||||
String name = parseName();
|
||||
@@ -413,13 +552,13 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
List<TypeProj> proj = null;
|
||||
List<TypeInfoProjection> proj = null;
|
||||
boolean nullable = false;
|
||||
if(cur != string.length && string[cur] == '<') {
|
||||
cur++;
|
||||
while(string[cur] != '>') {
|
||||
if(proj == null)
|
||||
proj = new LinkedList<TypeProj>();
|
||||
proj = new LinkedList<TypeInfoProjection>();
|
||||
proj.add(parseProjection());
|
||||
}
|
||||
cur++;
|
||||
@@ -428,7 +567,9 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
cur++;
|
||||
nullable = true;
|
||||
}
|
||||
return new TypeReal(aClass, nullable, proj == null ? Collections.<TypeProj>emptyList() : proj);
|
||||
if(proj == null)
|
||||
proj = Collections.emptyList();
|
||||
return new TypeInfoImpl(aClass, nullable,proj.toArray(new TypeInfoProjection[proj.size()]));
|
||||
|
||||
case 'T':
|
||||
return parseTypeVar();
|
||||
@@ -438,7 +579,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
}
|
||||
}
|
||||
|
||||
private Type parseTypeVar() {
|
||||
private TypeInfo parseTypeVar() {
|
||||
String name = parseName();
|
||||
boolean nullable = false;
|
||||
if(string[cur] == '?') {
|
||||
@@ -446,13 +587,28 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
cur++;
|
||||
}
|
||||
|
||||
return new TypeVar(nullable, variables.get(name));
|
||||
return new TypeInfoVar(nullable, variables.get(name));
|
||||
}
|
||||
|
||||
private TypeProj parseProjection() {
|
||||
TypeInfoVariance variance = parseVariance();
|
||||
Type type = parseType();
|
||||
return new TypeProj(variance, type);
|
||||
private TypeInfoProjection parseProjection() {
|
||||
final TypeInfoVariance variance = parseVariance();
|
||||
final TypeInfo type = parseType();
|
||||
return new TypeInfoProjection(){
|
||||
@Override
|
||||
public TypeInfoVariance getVariance() {
|
||||
return variance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package jet.typeinfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user