Merge remote branch 'origin/master'
This commit is contained in:
@@ -7,3 +7,4 @@ out
|
|||||||
.idea/dictionaries/yozh.xml
|
.idea/dictionaries/yozh.xml
|
||||||
.idea/codeStyleSettings.xml
|
.idea/codeStyleSettings.xml
|
||||||
.idea/workspace.xml
|
.idea/workspace.xml
|
||||||
|
tmp
|
||||||
|
|||||||
@@ -57,26 +57,18 @@ public class CodegenUtil {
|
|||||||
return (ClassDescriptor) outerDescriptor;
|
return (ClassDescriptor) outerDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasOuterTypeInfo(ClassDescriptor descriptor) {
|
public static boolean hasDerivedTypeInfoField(JetType type) {
|
||||||
ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(descriptor);
|
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||||
if(outerClassDescriptor == null)
|
if(hasTypeInfoField(jetType))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
if(outerClassDescriptor.getTypeConstructor().getParameters().size() > 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return hasOuterTypeInfo(outerClassDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) {
|
|
||||||
if(!exceptOwn) {
|
|
||||||
if(!isInterface(type))
|
|
||||||
if(hasTypeInfoField(type))
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
return false;
|
||||||
if(hasDerivedTypeInfoField(jetType, false))
|
}
|
||||||
|
|
||||||
|
public static boolean requireTypeInfoConstructorArg(JetType type) {
|
||||||
|
for (TypeParameterDescriptor parameter : type.getConstructor().getParameters()) {
|
||||||
|
if(parameter.isReified())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,22 +79,10 @@ public class CodegenUtil {
|
|||||||
if(isInterface(type))
|
if(isInterface(type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
|
if(requireTypeInfoConstructorArg(type))
|
||||||
for (TypeParameterDescriptor parameter : parameters) {
|
return true;
|
||||||
if(parameter.isReified())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
return hasDerivedTypeInfoField(type);
|
||||||
if(hasTypeInfoField(jetType))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor());
|
|
||||||
if(outerClassDescriptor == null || isClassObject(type.getConstructor().getDeclarationDescriptor()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return hasTypeInfoField(outerClassDescriptor.getDefaultType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FunctionDescriptor createInvoke(ExpressionAsFunctionDescriptor fd) {
|
public static FunctionDescriptor createInvoke(ExpressionAsFunctionDescriptor fd) {
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class ConstructorFrameMap extends FrameMap {
|
public class ConstructorFrameMap extends FrameMap {
|
||||||
private int myOuterThisIndex = -1;
|
private int myOuterThisIndex = -1;
|
||||||
private int myFirstTypeParameter = -1;
|
private int myTypeInfoIndex = -1;
|
||||||
private int myTypeParameterCount = 0;
|
|
||||||
|
|
||||||
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, ClassDescriptor classDescriptor, OwnerKind kind) {
|
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, ClassDescriptor classDescriptor, OwnerKind kind) {
|
||||||
enterTemp(); // this
|
enterTemp(); // this
|
||||||
@@ -27,15 +27,8 @@ public class ConstructorFrameMap extends FrameMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters();
|
if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) {
|
||||||
for (TypeParameterDescriptor parameter : parameters) {
|
myTypeInfoIndex = enterTemp();
|
||||||
if(parameter.isReified()) {
|
|
||||||
int index = enterTemp();
|
|
||||||
myTypeParameterCount++;
|
|
||||||
if(myFirstTypeParameter == -1) {
|
|
||||||
myFirstTypeParameter = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,11 +47,7 @@ public class ConstructorFrameMap extends FrameMap {
|
|||||||
return myOuterThisIndex;
|
return myOuterThisIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFirstTypeParameter() {
|
public int getTypeInfoIndex() {
|
||||||
return myFirstTypeParameter;
|
return myTypeInfoIndex;
|
||||||
}
|
|
||||||
|
|
||||||
public int getTypeParameterCount() {
|
|
||||||
return myTypeParameterCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -979,7 +979,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if (descriptor instanceof TypeParameterDescriptor) {
|
else if (descriptor instanceof TypeParameterDescriptor) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||||
loadTypeParameterTypeInfo(typeParameterDescriptor);
|
loadTypeParameterTypeInfo(typeParameterDescriptor, null);
|
||||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
v.invokevirtual("jet/typeinfo/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
||||||
v.checkcast(asmType(typeParameterDescriptor.getClassObjectType()));
|
v.checkcast(asmType(typeParameterDescriptor.getClassObjectType()));
|
||||||
|
|
||||||
@@ -2033,26 +2033,32 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
private void pushTypeArguments(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
private void pushTypeArguments(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
||||||
if(resolvedCall != null) {
|
if(resolvedCall != null) {
|
||||||
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
|
if(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor) {
|
||||||
CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
|
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor();
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) {
|
ClassDescriptor containingDeclaration = constructorDescriptor.getContainingDeclaration();
|
||||||
if(typeParameterDescriptor.isReified()) {
|
if(CodegenUtil.requireTypeInfoConstructorArg(containingDeclaration.getDefaultType())) {
|
||||||
JetType jetType = typeArguments.get(typeParameterDescriptor);
|
generateTypeInfo(containingDeclaration.getDefaultType(), resolvedCall.getTypeArguments());
|
||||||
generateTypeInfo(jetType);
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
|
||||||
|
CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) {
|
||||||
|
if(typeParameterDescriptor.isReified()) {
|
||||||
|
JetType jetType = typeArguments.get(typeParameterDescriptor);
|
||||||
|
generateTypeInfo(jetType, typeArguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
// for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
|
|
||||||
// pushTypeArgument(jetTypeArgument);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pushTypeArgument(JetTypeProjection jetTypeArgument) {
|
public void pushTypeArgument(JetTypeProjection jetTypeArgument) {
|
||||||
JetType typeArgument = bindingContext.get(BindingContext.TYPE, jetTypeArgument.getTypeReference());
|
JetType typeArgument = bindingContext.get(BindingContext.TYPE, jetTypeArgument.getTypeReference());
|
||||||
generateTypeInfo(typeArgument);
|
generateTypeInfo(typeArgument, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type generateJavaConstructorCall(JetCallExpression expression) {
|
private Type generateJavaConstructorCall(JetCallExpression expression) {
|
||||||
@@ -2091,7 +2097,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if(isArray) {
|
if(isArray) {
|
||||||
JetType elementType = typeMapper.getGenericsElementType(arrayType);
|
JetType elementType = typeMapper.getGenericsElementType(arrayType);
|
||||||
if(elementType != null) {
|
if(elementType != null) {
|
||||||
generateTypeInfo(elementType);
|
generateTypeInfo(elementType, null);
|
||||||
gen(args.get(0).getArgumentExpression(), Type.INT_TYPE);
|
gen(args.get(0).getArgumentExpression(), Type.INT_TYPE);
|
||||||
v.invokevirtual("jet/typeinfo/TypeInfo", "newArray", "(I)[Ljava/lang/Object;");
|
v.invokevirtual("jet/typeinfo/TypeInfo", "newArray", "(I)[Ljava/lang/Object;");
|
||||||
}
|
}
|
||||||
@@ -2195,7 +2201,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : getterDescriptor.getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameterDescriptor : getterDescriptor.getTypeParameters()) {
|
||||||
if(typeParameterDescriptor.isReified()) {
|
if(typeParameterDescriptor.isReified()) {
|
||||||
generateTypeInfo(resolvedGetCall.getTypeArguments().get(typeParameterDescriptor));
|
generateTypeInfo(resolvedGetCall.getTypeArguments().get(typeParameterDescriptor), null);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2215,7 +2221,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) {
|
||||||
if(typeParameterDescriptor.isReified()) {
|
if(typeParameterDescriptor.isReified()) {
|
||||||
generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor));
|
generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor), null);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2503,7 +2509,7 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
generateTypeInfo(jetType);
|
generateTypeInfo(jetType, null);
|
||||||
expressionToGen.put(TYPE_OBJECT, v);
|
expressionToGen.put(TYPE_OBJECT, v);
|
||||||
if (leaveExpressionOnStack) {
|
if (leaveExpressionOnStack) {
|
||||||
v.dupX1();
|
v.dupX1();
|
||||||
@@ -2512,7 +2518,7 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateTypeInfo(JetType jetType) {
|
public void generateTypeInfo(JetType jetType, Map<TypeParameterDescriptor, JetType> typeArguments) {
|
||||||
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
|
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
|
||||||
if(knownTypeInfo != null) {
|
if(knownTypeInfo != null) {
|
||||||
v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;");
|
v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;");
|
||||||
@@ -2521,7 +2527,7 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
|
|
||||||
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
||||||
loadTypeParameterTypeInfo((TypeParameterDescriptor) declarationDescriptor);
|
loadTypeParameterTypeInfo((TypeParameterDescriptor) declarationDescriptor, typeArguments);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2551,7 +2557,7 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
TypeProjection argument = arguments.get(i);
|
TypeProjection argument = arguments.get(i);
|
||||||
v.dup();
|
v.dup();
|
||||||
v.iconst(i);
|
v.iconst(i);
|
||||||
generateTypeInfo(argument.getType());
|
generateTypeInfo(argument.getType(), typeArguments);
|
||||||
genTypeInfoToProjection(v, argument.getProjectionKind());
|
genTypeInfoToProjection(v, argument.getProjectionKind());
|
||||||
v.astore(TYPE_OBJECT);
|
v.astore(TYPE_OBJECT);
|
||||||
}
|
}
|
||||||
@@ -2573,12 +2579,21 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
throw new UnsupportedOperationException(variance.toString());
|
throw new UnsupportedOperationException(variance.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadTypeParameterTypeInfo(TypeParameterDescriptor typeParameterDescriptor) {
|
private void loadTypeParameterTypeInfo(TypeParameterDescriptor typeParameterDescriptor, @Nullable Map<TypeParameterDescriptor, JetType> typeArguments) {
|
||||||
final StackValue value = typeParameterExpressions.get(typeParameterDescriptor);
|
final StackValue value = typeParameterExpressions.get(typeParameterDescriptor);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
value.put(TYPE_TYPEINFO, v);
|
value.put(TYPE_TYPEINFO, v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(typeArguments != null) {
|
||||||
|
JetType jetType = typeArguments.get(typeParameterDescriptor);
|
||||||
|
if(jetType != null && !jetType.equals(typeParameterDescriptor.getDefaultType())) {
|
||||||
|
generateTypeInfo(jetType, typeArguments);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
|
||||||
if (context.getThisDescriptor() != null) {
|
if (context.getThisDescriptor() != null) {
|
||||||
ClassDescriptor descriptor = context.getThisDescriptor();
|
ClassDescriptor descriptor = context.getThisDescriptor();
|
||||||
@@ -2589,8 +2604,13 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
if (containingDeclaration == context.getThisDescriptor()) {
|
if (containingDeclaration == context.getThisDescriptor()) {
|
||||||
if(!CodegenUtil.isInterface(descriptor)) {
|
if(!CodegenUtil.isInterface(descriptor)) {
|
||||||
if (CodegenUtil.hasTypeInfoField(defaultType)) {
|
if (CodegenUtil.hasTypeInfoField(defaultType)) {
|
||||||
v.load(0, TYPE_OBJECT);
|
if(!(context instanceof CodegenContext.ConstructorContext)) {
|
||||||
v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.load(0, TYPE_OBJECT);
|
||||||
|
v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v.load(((ConstructorFrameMap)myFrameMap).getTypeInfoIndex(), TYPE_OBJECT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
@@ -2603,11 +2623,11 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.load(0, TYPE_OBJECT);
|
v.load(0, TYPE_OBJECT);
|
||||||
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
|
||||||
while(descriptor != containingDeclaration) {
|
while(descriptor != containingDeclaration) {
|
||||||
descriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
descriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
||||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getOuterTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
v.invokeinterface("jet/JetObject", "getOuterObject", "()Ljet/JetObject;");
|
||||||
}
|
}
|
||||||
|
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||||
}
|
}
|
||||||
v.aconst(ownerType);
|
v.aconst(ownerType);
|
||||||
v.iconst(typeParameterDescriptor.getIndex());
|
v.iconst(typeParameterDescriptor.getIndex());
|
||||||
@@ -2737,7 +2757,7 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
|
|
||||||
v.anew(tupleType);
|
v.anew(tupleType);
|
||||||
v.dup();
|
v.dup();
|
||||||
generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression)));
|
generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression)), null);
|
||||||
for (JetExpression entry : entries) {
|
for (JetExpression entry : entries) {
|
||||||
gen(entry, TYPE_OBJECT);
|
gen(entry, TYPE_OBJECT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,12 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.StdlibNames;
|
import org.jetbrains.jet.lang.resolve.StdlibNames;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
|
||||||
import org.objectweb.asm.util.CheckSignatureAdapter;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -67,6 +62,13 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
int flags = ACC_PUBLIC; // TODO.
|
int flags = ACC_PUBLIC; // TODO.
|
||||||
|
|
||||||
|
if (!functionDescriptor.getValueParameters().isEmpty()
|
||||||
|
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
|
||||||
|
.getVarargElementType() != null)
|
||||||
|
{
|
||||||
|
flags |= ACC_VARARGS;
|
||||||
|
}
|
||||||
|
|
||||||
OwnerKind kind = context.getContextKind();
|
OwnerKind kind = context.getContextKind();
|
||||||
|
|
||||||
ReceiverDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
|
ReceiverDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject();
|
||||||
@@ -114,7 +116,7 @@ public class FunctionCodegen {
|
|||||||
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
|
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
|
||||||
av.visit(StdlibNames.JET_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
|
av.visit(StdlibNames.JET_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
|
||||||
if(parameterDescriptor.hasDefaultValue()) {
|
if(parameterDescriptor.hasDefaultValue()) {
|
||||||
av.visit(StdlibNames.JET_PARAMETER_HAS_DEFAULT_FIELD, true);
|
av.visit(StdlibNames.JET_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
|
||||||
}
|
}
|
||||||
if(parameterDescriptor.getOutType().isNullable()) {
|
if(parameterDescriptor.getOutType().isNullable()) {
|
||||||
av.visit(StdlibNames.JET_PARAMETER_NULLABLE_FIELD, true);
|
av.visit(StdlibNames.JET_PARAMETER_NULLABLE_FIELD, true);
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ import org.objectweb.asm.Opcodes;
|
|||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
import org.objectweb.asm.util.CheckSignatureAdapter;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -75,7 +78,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
? Opcodes.ACC_INTERFACE
|
? Opcodes.ACC_INTERFACE
|
||||||
: 0/*Opcodes.ACC_SUPER*/),
|
: 0/*Opcodes.ACC_SUPER*/),
|
||||||
jvmName(),
|
jvmName(),
|
||||||
null,
|
genericSignature(),
|
||||||
superClass,
|
superClass,
|
||||||
interfaces.toArray(new String[interfaces.size()])
|
interfaces.toArray(new String[interfaces.size()])
|
||||||
);
|
);
|
||||||
@@ -92,6 +95,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private String genericSignature() {
|
||||||
|
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
||||||
|
|
||||||
|
SignatureWriter signatureWriter = new SignatureWriter();
|
||||||
|
SignatureVisitor signatureVisitor = JetTypeMapper.DEBUG_SIGNATURE_WRITER
|
||||||
|
? new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, signatureWriter)
|
||||||
|
: signatureWriter;
|
||||||
|
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
||||||
|
signatureVisitor.visitFormalTypeParameter(typeParameter.getName());
|
||||||
|
SignatureVisitor classBoundVisitor = signatureVisitor.visitClassBound();
|
||||||
|
// TODO: wrong
|
||||||
|
JetTypeMapper.visitAsmType(classBoundVisitor, JetTypeMapper.TYPE_OBJECT);
|
||||||
|
}
|
||||||
|
SignatureVisitor superclassSignatureVisitor = signatureVisitor.visitSuperclass();
|
||||||
|
// TODO: wrong
|
||||||
|
superclassSignatureVisitor.visitClassType("java/lang/Object");
|
||||||
|
// TODO: add interfaces
|
||||||
|
superclassSignatureVisitor.visitEnd();
|
||||||
|
|
||||||
|
// TODO: return null if class is not generic and does not have generic superclasses
|
||||||
|
|
||||||
|
return signatureWriter.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private String jvmName() {
|
private String jvmName() {
|
||||||
return typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName();
|
return typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName();
|
||||||
}
|
}
|
||||||
@@ -277,8 +305,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType())) {
|
||||||
for (int n = typeParameters.size(); n > 0; n--) {
|
|
||||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,12 +364,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state);
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state);
|
||||||
|
|
||||||
for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) {
|
// for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) {
|
||||||
if(constructorDescriptor != null)
|
// if(constructorDescriptor != null)
|
||||||
codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
// codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||||
else
|
// else
|
||||||
codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
// codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||||
}
|
// }
|
||||||
|
|
||||||
String classname = typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName();
|
String classname = typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName();
|
||||||
final Type classType = Type.getType("L" + classname + ";");
|
final Type classType = Type.getType("L" + classname + ";");
|
||||||
@@ -371,7 +398,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||||
}
|
}
|
||||||
for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
|
for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
|
||||||
codegen.generateTypeInfo(typeParameterDescriptor.getType());
|
codegen.generateTypeInfo(typeParameterDescriptor.getType(), null);
|
||||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
}
|
}
|
||||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||||
@@ -419,10 +446,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
iv.load(frameMap.getOuterThisIndex(), type);
|
iv.load(frameMap.getOuterThisIndex(), type);
|
||||||
iv.putfield(classname, fieldName, interfaceDesc);
|
iv.putfield(classname, fieldName, interfaceDesc);
|
||||||
|
|
||||||
|
Type outerType = typeMapper.mapType(outerDescriptor.getDefaultType());
|
||||||
|
MethodVisitor outer = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getOuterObject", "()Ljet/JetObject;", null, null);
|
||||||
|
outer.visitCode();
|
||||||
|
outer.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
|
outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor());
|
||||||
|
outer.visitInsn(Opcodes.ARETURN);
|
||||||
|
outer.visitMaxs(0, 0);
|
||||||
|
outer.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CodegenUtil.hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
|
if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
|
||||||
generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
|
iv.load(frameMap.getTypeInfoIndex(), JetTypeMapper.TYPE_OBJECT);
|
||||||
|
iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(closure != null) {
|
if(closure != null) {
|
||||||
@@ -663,46 +701,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) {
|
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
|
||||||
|
|
||||||
iv.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION));
|
|
||||||
iv.iconst(0);
|
|
||||||
|
|
||||||
if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
|
|
||||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
|
||||||
iv.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(typeParamCount != 0) {
|
|
||||||
iv.iconst(typeParamCount);
|
|
||||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
|
||||||
|
|
||||||
for (int i = 0; i < typeParamCount; i++) {
|
|
||||||
iv.dup();
|
|
||||||
iv.iconst(i);
|
|
||||||
iv.load(firstTypeParameter + i, JetTypeMapper.TYPE_OBJECT);
|
|
||||||
iv.checkcast(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
|
||||||
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
|
|
||||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z[Ljet/typeinfo/TypeInfoProjection;)Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
|
|
||||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
|
|
||||||
iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
@@ -799,15 +797,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
JetType defaultType = descriptor.getDefaultType();
|
JetType defaultType = descriptor.getDefaultType();
|
||||||
if(CodegenUtil.hasTypeInfoField(defaultType)) {
|
if(CodegenUtil.requireTypeInfoConstructorArg(defaultType)) {
|
||||||
if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) {
|
if(!CodegenUtil.hasDerivedTypeInfoField(defaultType)) {
|
||||||
v.newField(myClass, Opcodes.ACC_PROTECTED, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
v.newField(myClass, Opcodes.ACC_PROTECTED, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
|
|
||||||
MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
InstructionAdapter iv = null;
|
|
||||||
if (v.generateCode()) {
|
if (v.generateCode()) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
@@ -819,7 +816,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null);
|
mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null);
|
||||||
if (v.generateCode()) {
|
if (v.generateCode()) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||||
@@ -856,14 +853,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
public void generate(InstructionAdapter v) {
|
public void generate(InstructionAdapter v) {
|
||||||
v.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION));
|
v.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||||
v.iconst(0);
|
v.iconst(0);
|
||||||
ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
||||||
if(outerClassDescriptor == null || CodegenUtil.isClassObject(descriptor)) {
|
|
||||||
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.getstatic(typeMapper.mapType(outerClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
|
||||||
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;");
|
|
||||||
}
|
|
||||||
v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ public class JetTypeMapper {
|
|||||||
public static final Type TYPE_FLOAT_ITERATOR = Type.getObjectType("jet/FloatIterator");
|
public static final Type TYPE_FLOAT_ITERATOR = Type.getObjectType("jet/FloatIterator");
|
||||||
public static final Type TYPE_DOUBLE_ITERATOR = Type.getObjectType("jet/DoubleIterator");
|
public static final Type TYPE_DOUBLE_ITERATOR = Type.getObjectType("jet/DoubleIterator");
|
||||||
|
|
||||||
|
public JetStandardLibrary getStandardLibrary() {
|
||||||
|
return standardLibrary;
|
||||||
|
}
|
||||||
|
|
||||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||||
this.standardLibrary = standardLibrary;
|
this.standardLibrary = standardLibrary;
|
||||||
this.bindingContext = bindingContext;
|
this.bindingContext = bindingContext;
|
||||||
@@ -234,10 +238,10 @@ public class JetTypeMapper {
|
|||||||
return mapType(jetType, kind, signatureVisitor, false);
|
return mapType(jetType, kind, signatureVisitor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable SignatureVisitor signatureVisitor, boolean typeParameter) {
|
@NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable SignatureVisitor signatureVisitor, boolean boxPrimitive) {
|
||||||
Type known = knowTypes.get(jetType);
|
Type known = knowTypes.get(jetType);
|
||||||
if (known != null) {
|
if (known != null) {
|
||||||
return mapKnownAsmType(jetType, known, signatureVisitor, typeParameter);
|
return mapKnownAsmType(jetType, known, signatureVisitor, boxPrimitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||||
@@ -249,8 +253,7 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
SignatureVisitor arraySignatureVisitor = signatureVisitor.visitArrayType();
|
SignatureVisitor arraySignatureVisitor = signatureVisitor.visitArrayType();
|
||||||
// TODO: box
|
mapType(memberType, kind, arraySignatureVisitor, true);
|
||||||
mapType(memberType, kind, arraySignatureVisitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isGenericsArray(jetType)) {
|
if (!isGenericsArray(jetType)) {
|
||||||
@@ -261,6 +264,9 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (JetStandardClasses.getAny().equals(descriptor)) {
|
if (JetStandardClasses.getAny().equals(descriptor)) {
|
||||||
|
if (signatureVisitor != null) {
|
||||||
|
visitAsmType(signatureVisitor, TYPE_OBJECT);
|
||||||
|
}
|
||||||
return TYPE_OBJECT;
|
return TYPE_OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +311,7 @@ public class JetTypeMapper {
|
|||||||
return asmType;
|
return asmType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitAsmType(SignatureVisitor visitor, Type asmType) {
|
public static void visitAsmType(SignatureVisitor visitor, Type asmType) {
|
||||||
switch (asmType.getSort()) {
|
switch (asmType.getSort()) {
|
||||||
case Type.OBJECT:
|
case Type.OBJECT:
|
||||||
visitor.visitClassType(asmType.getInternalName());
|
visitor.visitClassType(asmType.getInternalName());
|
||||||
@@ -377,7 +383,7 @@ public class JetTypeMapper {
|
|||||||
return asmType;
|
return asmType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean DEBUG_SIGNATURE_WRITER = true;
|
public static final boolean DEBUG_SIGNATURE_WRITER = true;
|
||||||
|
|
||||||
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) {
|
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) {
|
||||||
if(functionDescriptor == null)
|
if(functionDescriptor == null)
|
||||||
@@ -573,10 +579,8 @@ public class JetTypeMapper {
|
|||||||
parameterTypes.add(mapType(CodegenUtil.getOuterClassDescriptor(classDescriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
parameterTypes.add(mapType(CodegenUtil.getOuterClassDescriptor(classDescriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters();
|
if (CodegenUtil.requireTypeInfoConstructorArg(classDescriptor.getDefaultType())) {
|
||||||
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
parameterTypes.add(TYPE_TYPEINFO);
|
||||||
if(typeParameter.isReified())
|
|
||||||
parameterTypes.add(TYPE_TYPEINFO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : parameters) {
|
for (ValueParameterDescriptor parameter : parameters) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
@@ -145,7 +146,7 @@ public class NamespaceCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||||
if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor)) {
|
if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor) && !JetStandardClasses.getAny().equals(declarationDescriptor)) {
|
||||||
// TODO: we need some better checks here
|
// TODO: we need some better checks here
|
||||||
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -629,7 +630,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) {
|
for (TypeParameterDescriptor typeParameterDescriptor : setterDescriptor.getOriginal().getTypeParameters()) {
|
||||||
if(typeParameterDescriptor.isReified()) {
|
if(typeParameterDescriptor.isReified()) {
|
||||||
codegen.generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor));
|
codegen.generateTypeInfo(resolvedSetCall.getTypeArguments().get(typeParameterDescriptor), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1010,7 +1011,8 @@ public abstract class StackValue {
|
|||||||
return codegen.typeMapper.mapType(callableMethod.getReceiverClass());
|
return codegen.typeMapper.mapType(callableMethod.getReceiverClass());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return codegen.typeMapper.mapType(callableMethod.getThisType());
|
JetType thisType = callableMethod.getThisType();
|
||||||
|
return codegen.typeMapper.mapType(thisType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ import org.jetbrains.jet.codegen.ExpressionCodegen;
|
|||||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
import org.jetbrains.jet.codegen.StackValue;
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
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.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
@@ -30,7 +28,7 @@ public class ArrayIterator implements IntrinsicMethod {
|
|||||||
ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal();
|
ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal();
|
||||||
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
|
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
|
||||||
if(containingDeclaration.equals(standardLibrary.getArray())) {
|
if(containingDeclaration.equals(standardLibrary.getArray())) {
|
||||||
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType());
|
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType(), null);
|
||||||
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;");
|
||||||
return StackValue.onStack(JetTypeMapper.TYPE_ITERATOR);
|
return StackValue.onStack(JetTypeMapper.TYPE_ITERATOR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,4 @@ public class JavaPackageScope extends JetScopeImpl {
|
|||||||
private String getQualifiedName(String name) {
|
private String getQualifiedName(String name) {
|
||||||
return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name;
|
return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
@@ -24,6 +25,7 @@ public interface CallableDescriptor extends DeclarationDescriptor {
|
|||||||
/**
|
/**
|
||||||
* Method may return null for not yet fully initialized object or if error occurred.
|
* Method may return null for not yet fully initialized object or if error occurred.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
JetType getReturnType();
|
JetType getReturnType();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public interface DeclarationDescriptor extends Annotated, Named {
|
|||||||
@Nullable
|
@Nullable
|
||||||
DeclarationDescriptor getContainingDeclaration();
|
DeclarationDescriptor getContainingDeclaration();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
DeclarationDescriptor substitute(TypeSubstitutor substitutor);
|
DeclarationDescriptor substitute(TypeSubstitutor substitutor);
|
||||||
|
|
||||||
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
|
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
|
||||||
|
|||||||
@@ -2,14 +2,16 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Introduces a simple wrapper for internal scope.
|
||||||
|
*
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractScopeAdapter implements JetScope {
|
public abstract class AbstractScopeAdapter implements JetScope {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class StdlibNames {
|
|||||||
public static final String JET_PARAMETER_DESCRIPTOR = "Ljet/typeinfo/JetParameter;";
|
public static final String JET_PARAMETER_DESCRIPTOR = "Ljet/typeinfo/JetParameter;";
|
||||||
|
|
||||||
public static final String JET_PARAMETER_NAME_FIELD = "name";
|
public static final String JET_PARAMETER_NAME_FIELD = "name";
|
||||||
public static final String JET_PARAMETER_HAS_DEFAULT_FIELD = "hasDefault";
|
public static final String JET_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue";
|
||||||
public static final String JET_PARAMETER_NULLABLE_FIELD = "nullable";
|
public static final String JET_PARAMETER_NULLABLE_FIELD = "nullable";
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ public class CallResolver {
|
|||||||
@NotNull final JetReferenceExpression functionReference,
|
@NotNull final JetReferenceExpression functionReference,
|
||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
@NotNull JetType expectedType) {
|
@NotNull JetType expectedType) {
|
||||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(
|
||||||
|
scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
||||||
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +407,11 @@ public class CallResolver {
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing) {
|
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(
|
||||||
|
@NotNull BindingTrace trace,
|
||||||
|
@NotNull JetScope scope, @NotNull JetType expectedType,
|
||||||
|
@NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing
|
||||||
|
) {
|
||||||
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
||||||
D candidate = candidateCall.getCandidateDescriptor();
|
D candidate = candidateCall.getCandidateDescriptor();
|
||||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Stores candidates for call resolution.
|
||||||
|
*
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
/*package*/ class ResolutionTask<D extends CallableDescriptor> {
|
/*package*/ class ResolutionTask<D extends CallableDescriptor> {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
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.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
|
||||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||||
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -32,8 +32,11 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
||||||
Collection<ResolvedCallImpl<D>> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, Collection<ResolvedCallImpl<D>> local, Collection<ResolvedCallImpl<D>> nonlocal) {
|
@NotNull Collection<ResolvedCallImpl<D>> allDescriptors,
|
||||||
|
@NotNull DeclarationDescriptor containerOfTheCurrentLocality,
|
||||||
|
@NotNull Collection<ResolvedCallImpl<D>> local,
|
||||||
|
@NotNull Collection<ResolvedCallImpl<D>> nonlocal
|
||||||
|
) {
|
||||||
for (ResolvedCallImpl<D> resolvedCall : allDescriptors) {
|
for (ResolvedCallImpl<D> resolvedCall : allDescriptors) {
|
||||||
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
||||||
local.add(resolvedCall);
|
local.add(resolvedCall);
|
||||||
@@ -56,7 +59,9 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
@NotNull
|
||||||
|
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name,
|
||||||
|
@NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||||
|
|
||||||
ReceiverDescriptor explicitReceiver = call.getExplicitReceiver();
|
ReceiverDescriptor explicitReceiver = call.getExplicitReceiver();
|
||||||
|
|||||||
+2
-15
@@ -50,20 +50,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
JetReferenceExpression nameReference = valueArgument.getArgumentName().getReferenceExpression();
|
JetReferenceExpression nameReference = valueArgument.getArgumentName().getReferenceExpression();
|
||||||
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName());
|
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName());
|
||||||
if (valueParameterDescriptor == null) {
|
if (valueParameterDescriptor == null) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name");
|
|
||||||
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
|
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter");
|
|
||||||
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
||||||
}
|
}
|
||||||
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
||||||
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
||||||
}
|
}
|
||||||
if (somePositioned) {
|
if (somePositioned) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed");
|
|
||||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
|
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -71,7 +68,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
else {
|
else {
|
||||||
somePositioned = true;
|
somePositioned = true;
|
||||||
if (someNamed) {
|
if (someNamed) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed");
|
|
||||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement()));
|
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement()));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -89,13 +85,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
usedParameters.add(valueParameterDescriptor);
|
usedParameters.add(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -108,7 +102,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
||||||
|
|
||||||
if (valueParameters.isEmpty()) {
|
if (valueParameters.isEmpty()) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -124,13 +117,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
|
|
||||||
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||||
if (valueParameterDescriptor.getVarargElementType() != null) {
|
if (valueParameterDescriptor.getVarargElementType() != null) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list");
|
|
||||||
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
|
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -142,7 +133,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
|
|
||||||
for (int i = 1; i < functionLiteralArguments.size(); i++) {
|
for (int i = 1; i < functionLiteralArguments.size(); i++) {
|
||||||
JetExpression argument = functionLiteralArguments.get(i);
|
JetExpression argument = functionLiteralArguments.get(i);
|
||||||
// temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list");
|
|
||||||
temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument));
|
temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -176,7 +166,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() :
|
||||||
|
"Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -196,8 +187,4 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static <Descriptor extends CallableDescriptor> String getTooManyArgumentsMessage(Descriptor candidate) {
|
|
||||||
// return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -10,6 +10,28 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public interface ConstraintResolutionListener {
|
public interface ConstraintResolutionListener {
|
||||||
|
|
||||||
|
public static final ConstraintResolutionListener DO_NOTHING = new ConstraintResolutionListener() {
|
||||||
|
@Override
|
||||||
|
public void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Object message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(Object message) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue);
|
void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue);
|
||||||
void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue);
|
void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue);
|
||||||
void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors);
|
void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors);
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ public interface JetScope {
|
|||||||
@Nullable
|
@Nullable
|
||||||
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
|
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All visible descriptors from current scope.
|
||||||
|
*
|
||||||
|
* @return All visible descriptors from current scope.
|
||||||
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
Collection<DeclarationDescriptor> getAllDescriptors();
|
Collection<DeclarationDescriptor> getAllDescriptors();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.scopes;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public final class JetScopeUtils {
|
||||||
|
private JetScopeUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get receivers in order of locality, so that the closest (the most local) receiver goes first
|
||||||
|
* A wrapper for {@link JetScope#getImplicitReceiversHierarchy(java.util.List)}
|
||||||
|
*
|
||||||
|
* @param scope Scope for getting receivers hierarchy.
|
||||||
|
* @return receivers hierarchy.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static Collection<ReceiverDescriptor> getImplicitReceiversHierarchy(@NotNull JetScope scope) {
|
||||||
|
List<ReceiverDescriptor> descriptors = Lists.newArrayList();
|
||||||
|
scope.getImplicitReceiversHierarchy(descriptors);
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all extension descriptors among visible descriptors for current scope.
|
||||||
|
*
|
||||||
|
* @param scope Scope for query extensions.
|
||||||
|
* @return extension descriptors.
|
||||||
|
*/
|
||||||
|
public static Collection<CallableDescriptor> getAllExtensions(@NotNull JetScope scope) {
|
||||||
|
final Set<CallableDescriptor> result = Sets.newHashSet();
|
||||||
|
|
||||||
|
for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
|
||||||
|
if (descriptor instanceof CallableDescriptor) {
|
||||||
|
CallableDescriptor callDescriptor = (CallableDescriptor) descriptor;
|
||||||
|
if (callDescriptor.getReceiverParameter().exists()) {
|
||||||
|
result.add(callDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-2
@@ -12,9 +12,9 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
|||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
@@ -40,7 +40,8 @@ import java.util.Map;
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull JetType expectedReturnType,
|
@NotNull JetType expectedReturnType,
|
||||||
boolean namespacesAllowed) {
|
boolean namespacesAllowed) {
|
||||||
return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed);
|
return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists,
|
||||||
|
labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @NotNull
|
// @NotNull
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
class A() {}
|
class A() {}
|
||||||
|
|
||||||
open class B<T>() {
|
open class B<T>() {
|
||||||
fun isT (a : Any?) : Boolean {
|
fun isT (a : Any?) : Boolean {
|
||||||
return a is T
|
return a is T
|
||||||
@@ -167,7 +168,6 @@ fun t26 () : Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun box() : String {
|
fun box() : String {
|
||||||
/*
|
|
||||||
if(!t1()) {
|
if(!t1()) {
|
||||||
return "t1 failed"
|
return "t1 failed"
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,6 @@ fun box() : String {
|
|||||||
if(!t25()) {
|
if(!t25()) {
|
||||||
return "t25 failed"
|
return "t25 failed"
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if(!t26()) {
|
if(!t26()) {
|
||||||
return "t26 failed"
|
return "t26 failed"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class A() {
|
||||||
|
var x : Int = 0
|
||||||
|
|
||||||
|
var z = { () =>
|
||||||
|
x++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val a = A()
|
||||||
|
a.z() //problem is here
|
||||||
|
return if (a.x == 1) "OK" else "fail"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace foo
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import std.util.*
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val a = ArrayList<Int>();
|
||||||
|
a.add(1)
|
||||||
|
a.add(2)
|
||||||
|
return if((a.size == 2) && (a.get(1) == 2) && (a.get(0) == 1)) "OK" else "fail"
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
open class A<T> () {
|
open class A<out T> () {
|
||||||
fun plus(e: T) = B<T> (e)
|
fun plus(e: T) = B<T> (e)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,4 +6,6 @@ class B<T> (val e: T) : A<T>() {
|
|||||||
fun add() = B<T> (e)
|
fun add() = B<T> (e)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun box() = if( A<String>().plus("239").add().e == "239" ) "OK" else "fail"
|
fun box() : String {
|
||||||
|
return if(A<String>().plus("239").add().e == "239" ) "OK" else "fail"
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ class Box<T>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Inner2() : Inner() {
|
class Inner2() : Inner() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun inner() = Inner2()
|
fun inner() = Inner2()
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
class IntArray {
|
|
||||||
{
|
|
||||||
int[] r = namespace.doNothing(new int[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
fun doNothing(array: IntArray) = array
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
class Simple {
|
||||||
|
{
|
||||||
|
jet.typeinfo.TypeInfo blabla = null;
|
||||||
|
new Impossible<String>(blabla);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
class Impossible<P>()
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
class Any {
|
||||||
|
{
|
||||||
|
Object r = namespace.anyany(new Object(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// extra parameter is to preserve generic signature
|
||||||
|
fun anyany(a: Any, ignore: java.util.List<String>) = a
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
class ArrayOfIntArray {
|
||||||
|
{
|
||||||
|
int[][] a = new int[0][];
|
||||||
|
int[][] r = namespace.ohMy(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fun ohMy(p: Array<IntArray>) = p
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
class ArrayOfIntArray {
|
||||||
|
{
|
||||||
|
Integer[][] a = new Integer[0][];
|
||||||
|
Integer[][] r = namespace.ohMy(a, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// extra parameter is to make sure generic signature is generated
|
||||||
|
fun ohMy(p: Array<Array<Int>>, ignore: java.util.List<String>) = p
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
class IntArray {
|
||||||
|
{
|
||||||
|
int[] r = namespace.doNothing(new int[0], null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// extra parameter is to make sure generic signature is not erased
|
||||||
|
fun doNothing(array: IntArray, ignore: java.util.List<String>) = array
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
class IntArray {
|
||||||
|
{
|
||||||
|
Integer[] r = namespace.doNothing(new Integer[0], null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// extra parameter is to make sure generic signature is preserved
|
||||||
|
fun doNothing(array: Array<Int>, ignore: java.util.List<String>) = array
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
class Vararg {
|
||||||
|
{
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
List<String> r = namespace.gg(list, 3, 4, 5, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun gg(list: List<String>, vararg ints: Int) = list
|
||||||
@@ -24,7 +24,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
|
|
||||||
public void testArrayListInheritance() throws Exception {
|
public void testArrayListInheritance() throws Exception {
|
||||||
loadFile("classes/inheritingFromArrayList.jet");
|
loadFile("classes/inheritingFromArrayList.jet");
|
||||||
|
System.out.println(generateToText());
|
||||||
final Class aClass = loadClass("Foo", generateClassesInFile());
|
final Class aClass = loadClass("Foo", generateClassesInFile());
|
||||||
assertInstanceOf(aClass.newInstance(), List.class);
|
assertInstanceOf(aClass.newInstance(), List.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,10 @@ public class FunctionGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("regressions/kt395.jet");
|
blackBoxFile("regressions/kt395.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt785 () {
|
||||||
|
// blackBoxFile("regressions/kt785.jet");
|
||||||
|
}
|
||||||
|
|
||||||
public void testFunction () throws InvocationTargetException, IllegalAccessException {
|
public void testFunction () throws InvocationTargetException, IllegalAccessException {
|
||||||
blackBoxFile("functions/functionExpression.jet");
|
blackBoxFile("functions/functionExpression.jet");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ public class StdlibTest extends CodegenTestCase {
|
|||||||
blackBoxFile("regressions/kt528.kt");
|
blackBoxFile("regressions/kt528.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt789 () {
|
||||||
|
// blackBoxFile("regressions/kt789.jet");
|
||||||
|
}
|
||||||
|
|
||||||
public void testCollectionSize () throws Exception {
|
public void testCollectionSize () throws Exception {
|
||||||
loadText("import std.util.*; fun box() = if(java.util.Arrays.asList(0, 1, 2)?.size == 3) \"OK\" else \"fail\"");
|
loadText("import std.util.*; fun box() = if(java.util.Arrays.asList(0, 1, 2)?.size == 3) \"OK\" else \"fail\"");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ public class TypeInfoTest extends CodegenTestCase {
|
|||||||
|
|
||||||
public void testInner() throws Exception {
|
public void testInner() throws Exception {
|
||||||
blackBoxFile("typeInfo/inner.jet");
|
blackBoxFile("typeInfo/inner.jet");
|
||||||
// System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritance() throws Exception {
|
public void testInheritance() throws Exception {
|
||||||
@@ -148,4 +148,3 @@ public class TypeInfoTest extends CodegenTestCase {
|
|||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
abstract public class FList<T> {
|
||||||
|
abstract T getHead();
|
||||||
|
|
||||||
|
abstract FList<T> getTail();
|
||||||
|
|
||||||
|
abstract FList<T> plus(T element);
|
||||||
|
|
||||||
|
static class Empty<T> extends FList<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
T getHead() {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FList<T> getTail() {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FList<T> plus(T element) {
|
||||||
|
return new OneElementList<T>(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class OneElementList<T> extends FList<T> {
|
||||||
|
private T element;
|
||||||
|
|
||||||
|
public OneElementList(T element) {
|
||||||
|
super();
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
T getHead() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FList<T> getTail() {
|
||||||
|
return new Empty<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FList<T> plus(T element) {
|
||||||
|
return new StandardList<T>(element, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StandardList<T> extends FList<T> {
|
||||||
|
private T head;
|
||||||
|
private FList<T> tail;
|
||||||
|
|
||||||
|
public StandardList(T head, FList<T> tail) {
|
||||||
|
this.head = head;
|
||||||
|
this.tail = tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
T getHead() {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FList<T> getTail() {
|
||||||
|
return tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FList<T> plus(T element) {
|
||||||
|
return new StandardList<T>(element, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for(int k = 0; k != 10; ++k) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
FList<Integer> list = new Empty();
|
||||||
|
for(int i = 0; i != 5000000; ++i)
|
||||||
|
list = list.plus(i);
|
||||||
|
System.out.println(System.currentTimeMillis()-start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
namespace flist
|
||||||
|
|
||||||
|
abstract class FList<T> {
|
||||||
|
abstract val head : T
|
||||||
|
abstract val tail : FList<T>
|
||||||
|
|
||||||
|
abstract fun plus(element: T) : FList<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmptyFList<T>() : FList<T> {
|
||||||
|
override val head: T
|
||||||
|
get() = throw java.util.NoSuchElementException()
|
||||||
|
|
||||||
|
override val tail : EmptyFList<T>
|
||||||
|
get() = EmptyFList<T>()
|
||||||
|
|
||||||
|
override fun plus(element: T) : FList<T> = OneElementFList<T>(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneElementFList<T> (override val head: T): FList<T> {
|
||||||
|
override val tail : EmptyFList<T>
|
||||||
|
get() = EmptyFList<T>()
|
||||||
|
|
||||||
|
override fun plus(element: T) : FList<T> = StandardFList<T>(element, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class StandardFList<T> (override val head: T, override val tail: FList<T>) : FList<T> {
|
||||||
|
override fun plus(element: T) : FList<T> = StandardFList<T>(element, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> FList<T>.plus2(element: T): FList<T> =
|
||||||
|
when(this) {
|
||||||
|
is EmptyFList<T> => OneElementFList<T>(element)
|
||||||
|
else => StandardFList<T>(element, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> FList<T>.plus3(element: T) : FList<T> =
|
||||||
|
if(this is EmptyFList<*>)
|
||||||
|
OneElementFList<T>(element)
|
||||||
|
else
|
||||||
|
StandardFList<T>(element, this)
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
for(k in 0..3) {
|
||||||
|
val start0 = System.currentTimeMillis()
|
||||||
|
|
||||||
|
var flist0 : FList<Int> = EmptyFList<Int>()
|
||||||
|
for(i in 0..5000000)
|
||||||
|
flist0 = flist0 + i
|
||||||
|
|
||||||
|
System.out?.println(System.currentTimeMillis() - start0)
|
||||||
|
|
||||||
|
val start = System.currentTimeMillis()
|
||||||
|
|
||||||
|
var flist : FList<Int> = EmptyFList<Int>()
|
||||||
|
for(i in 0..5000000)
|
||||||
|
flist = flist.plus2(i)
|
||||||
|
|
||||||
|
System.out?.println(System.currentTimeMillis() - start)
|
||||||
|
|
||||||
|
val start2 = System.currentTimeMillis()
|
||||||
|
|
||||||
|
var flist2 : FList<Int> = EmptyFList<Int>()
|
||||||
|
for(i in 0..5000000)
|
||||||
|
flist2 = flist2.plus3(i)
|
||||||
|
|
||||||
|
System.out?.println(System.currentTimeMillis() - start2)
|
||||||
|
System.out?.println()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.plugin.completion;
|
package org.jetbrains.jet.plugin.completion;
|
||||||
|
|
||||||
import com.intellij.codeInsight.completion.*;
|
import com.intellij.codeInsight.completion.*;
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||||
import com.intellij.patterns.PlatformPatterns;
|
import com.intellij.patterns.PlatformPatterns;
|
||||||
import com.intellij.patterns.PsiElementPattern;
|
import com.intellij.patterns.PsiElementPattern;
|
||||||
@@ -11,6 +12,7 @@ import com.intellij.psi.filters.position.FilterPattern;
|
|||||||
import com.intellij.psi.filters.position.LeftNeighbour;
|
import com.intellij.psi.filters.position.LeftNeighbour;
|
||||||
import com.intellij.util.ProcessingContext;
|
import com.intellij.util.ProcessingContext;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.plugin.completion.handlers.JetKeywordInsertHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A keyword contributor for Kotlin
|
* A keyword contributor for Kotlin
|
||||||
@@ -22,6 +24,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
|
|||||||
|
|
||||||
private static class JetTopKeywordCompletionProvider extends CompletionProvider<CompletionParameters> {
|
private static class JetTopKeywordCompletionProvider extends CompletionProvider<CompletionParameters> {
|
||||||
|
|
||||||
|
private final static InsertHandler<LookupElement> KEYWORDS_INSERT_HANDLER = new JetKeywordInsertHandler();
|
||||||
|
|
||||||
private final static String[] COMPLETE_KEYWORD = new String[] {
|
private final static String[] COMPLETE_KEYWORD = new String[] {
|
||||||
"namespace", "as", "type", "class", "this", "super", "val", "var", "fun", "for", "null", "true",
|
"namespace", "as", "type", "class", "this", "super", "val", "var", "fun", "for", "null", "true",
|
||||||
"false", "is", "in", "throw", "return", "break", "continue", "object", "if", "try", "else", "while",
|
"false", "is", "in", "throw", "return", "break", "continue", "object", "if", "try", "else", "while",
|
||||||
@@ -39,11 +43,12 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
|
|||||||
@NotNull CompletionResultSet result) {
|
@NotNull CompletionResultSet result) {
|
||||||
|
|
||||||
for (String keyword : COMPLETE_KEYWORD) {
|
for (String keyword : COMPLETE_KEYWORD) {
|
||||||
result.addElement(LookupElementBuilder.create(keyword).setBold());
|
|
||||||
|
result.addElement(LookupElementBuilder.create(keyword).setInsertHandler(KEYWORDS_INSERT_HANDLER).setBold());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String softKeyword : COMPLETE_SOFT_KEYWORDS) {
|
for (String softKeyword : COMPLETE_SOFT_KEYWORDS) {
|
||||||
result.addElement(LookupElementBuilder.create(softKeyword));
|
result.addElement(LookupElementBuilder.create(softKeyword).setInsertHandler(KEYWORDS_INSERT_HANDLER));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.jetbrains.jet.plugin.completion.handlers;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.InsertHandler;
|
||||||
|
import com.intellij.codeInsight.completion.InsertionContext;
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts '()' after function proposal insert.
|
||||||
|
*
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
|
||||||
|
|
||||||
|
public enum CaretPosition { IN_BRACKETS, AFTER_BRACKETS }
|
||||||
|
|
||||||
|
private final CaretPosition caretPosition;
|
||||||
|
|
||||||
|
public JetFunctionInsertHandler(CaretPosition caretPosition) {
|
||||||
|
this.caretPosition = caretPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleInsert(InsertionContext context, LookupElement item) {
|
||||||
|
int startOffset = context.getStartOffset();
|
||||||
|
int lookupStringLength = item.getLookupString().length();
|
||||||
|
int endOffset = startOffset + lookupStringLength;
|
||||||
|
|
||||||
|
context.getDocument().insertString(endOffset, "()");
|
||||||
|
|
||||||
|
Editor editor = context.getEditor();
|
||||||
|
if (caretPosition == CaretPosition.IN_BRACKETS) {
|
||||||
|
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1);
|
||||||
|
} else {
|
||||||
|
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.jetbrains.jet.plugin.completion.handlers;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.codeInsight.completion.InsertHandler;
|
||||||
|
import com.intellij.codeInsight.completion.InsertionContext;
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
|
import com.intellij.openapi.editor.Document;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class JetKeywordInsertHandler implements InsertHandler<LookupElement> {
|
||||||
|
|
||||||
|
private final static Set<String> NO_SPACE_AFTER = Sets.newHashSet("this", "super", "This", "true", "false", "null");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleInsert(InsertionContext context, LookupElement item) {
|
||||||
|
String keyword = item.getLookupString();
|
||||||
|
|
||||||
|
// Add space after keyword
|
||||||
|
if (!NO_SPACE_AFTER.contains(keyword)) {
|
||||||
|
Editor editor = context.getEditor();
|
||||||
|
Document document = editor.getDocument();
|
||||||
|
|
||||||
|
int offset = context.getStartOffset() + keyword.length();
|
||||||
|
context.setAddCompletionChar(false);
|
||||||
|
document.insertString(offset, " ");
|
||||||
|
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.jetbrains.jet.plugin.references;
|
package org.jetbrains.jet.plugin.references;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||||
import com.intellij.openapi.util.Iconable;
|
import com.intellij.openapi.util.Iconable;
|
||||||
@@ -14,17 +17,34 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||||
|
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
class JetSimpleNameReference extends JetPsiReference {
|
class JetSimpleNameReference extends JetPsiReference {
|
||||||
|
|
||||||
|
private final static JetFunctionInsertHandler EMPTY_FUNCTION_HANDLER = new JetFunctionInsertHandler(
|
||||||
|
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
|
||||||
|
|
||||||
|
private final static JetFunctionInsertHandler PARAMS_FUNCTION_HANDLER = new JetFunctionInsertHandler(
|
||||||
|
JetFunctionInsertHandler.CaretPosition.IN_BRACKETS);
|
||||||
|
|
||||||
private final JetSimpleNameExpression myExpression;
|
private final JetSimpleNameExpression myExpression;
|
||||||
|
|
||||||
public JetSimpleNameReference(JetSimpleNameExpression jetSimpleNameExpression) {
|
public JetSimpleNameReference(JetSimpleNameExpression jetSimpleNameExpression) {
|
||||||
@@ -53,9 +73,14 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
||||||
JetFile file = (JetFile) myExpression.getContainingFile();
|
JetFile file = (JetFile) myExpression.getContainingFile();
|
||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
||||||
|
|
||||||
final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||||
if (expressionType != null) {
|
final JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
|
||||||
return collectLookupElements(bindingContext, expressionType.getMemberScope());
|
|
||||||
|
if (expressionType != null && resolutionScope != null) {
|
||||||
|
return collectLookupElements(bindingContext,
|
||||||
|
includeExternalCallableExtensions(expressionType.getMemberScope().getAllDescriptors(),
|
||||||
|
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -63,7 +88,8 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
||||||
JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression);
|
JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression);
|
||||||
if (resolutionScope != null) {
|
if (resolutionScope != null) {
|
||||||
return collectLookupElements(bindingContext, resolutionScope);
|
return collectLookupElements(bindingContext,
|
||||||
|
excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,17 +102,53 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
return myExpression.getReferencedNameElement().replace(element);
|
return myExpression.getReferencedNameElement().replace(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) {
|
private Iterable<DeclarationDescriptor> excludeNotCallableExtensions(
|
||||||
|
@NotNull Iterable<DeclarationDescriptor> descriptors, @NotNull final JetScope scope
|
||||||
|
) {
|
||||||
|
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
descriptorsSet.removeAll(
|
||||||
|
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||||
|
return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return descriptorsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<DeclarationDescriptor> includeExternalCallableExtensions(
|
||||||
|
@NotNull Iterable<DeclarationDescriptor> descriptors,
|
||||||
|
@NotNull final JetScope externalScope,
|
||||||
|
@NotNull final ReceiverDescriptor receiverDescriptor
|
||||||
|
) {
|
||||||
|
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
|
||||||
|
descriptorsSet.addAll(Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
||||||
|
new Predicate<CallableDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||||
|
return checkReceiverResolution(receiverDescriptor, callableDescriptor);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return descriptorsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) {
|
||||||
List<LookupElement> result = Lists.newArrayList();
|
List<LookupElement> result = Lists.newArrayList();
|
||||||
for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
|
|
||||||
|
for (final DeclarationDescriptor descriptor : descriptors) {
|
||||||
LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName());
|
LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName());
|
||||||
String typeText = "";
|
String typeText = "";
|
||||||
String tailText = "";
|
String tailText = "";
|
||||||
boolean tailTextGrayed = false;
|
boolean tailTextGrayed = false;
|
||||||
|
|
||||||
if (descriptor instanceof FunctionDescriptor) {
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||||
JetType returnType = functionDescriptor.getReturnType();
|
JetType returnType = functionDescriptor.getReturnType();
|
||||||
typeText = DescriptorRenderer.TEXT.renderType(returnType);
|
typeText = DescriptorRenderer.TEXT.renderType(returnType);
|
||||||
|
|
||||||
tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
|
tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String fun(ValueParameterDescriptor valueParameterDescriptor) {
|
public String fun(ValueParameterDescriptor valueParameterDescriptor) {
|
||||||
@@ -94,6 +156,14 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType());
|
DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType());
|
||||||
}
|
}
|
||||||
}, ",") + ")";
|
}, ",") + ")";
|
||||||
|
|
||||||
|
// TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>'
|
||||||
|
// TODO: Support omitting brackets for one argument functions
|
||||||
|
if (functionDescriptor.getValueParameters().isEmpty()) {
|
||||||
|
element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER);
|
||||||
|
} else {
|
||||||
|
element = element.setInsertHandler(PARAMS_FUNCTION_HANDLER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof VariableDescriptor) {
|
else if (descriptor instanceof VariableDescriptor) {
|
||||||
JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||||
@@ -117,4 +187,29 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
}
|
}
|
||||||
return result.toArray();
|
return result.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if receiver declaration could be resolved to call expected receiver.
|
||||||
|
*/
|
||||||
|
private static boolean checkReceiverResolution (
|
||||||
|
@NotNull ReceiverDescriptor expectedReceiver,
|
||||||
|
@NotNull CallableDescriptor receiverArgument
|
||||||
|
) {
|
||||||
|
ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
|
||||||
|
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
|
||||||
|
if (expectedReceiver.exists() && receiverParameter.exists()) {
|
||||||
|
constraintSystem.addSubtypingConstraint(expectedReceiver.getType(), receiverParameter.getType());
|
||||||
|
}
|
||||||
|
else if (expectedReceiver.exists() || receiverParameter.exists()) {
|
||||||
|
// Only one of receivers exist
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintSystemSolution solution = constraintSystem.solve();
|
||||||
|
return solution.getStatus().isSuccessful();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Test
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
fun methodName() {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class Some() {
|
||||||
|
fun methodName() {
|
||||||
|
this.<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.second() {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first, second
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.second() {
|
||||||
|
this.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first, second
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class SomeObject<T, U>() {
|
||||||
|
var field : T? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {}
|
||||||
|
class C {}
|
||||||
|
|
||||||
|
fun <T: Comparable<T>, U> SomeObject<T, U>.compareTo(other : SomeObject<T, U>) : Int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun some() {
|
||||||
|
val test = SomeObject<A, A>
|
||||||
|
test.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: compareTo
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun Some.simpleKotlinExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: simpleKotlinExtension
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun <T> java.lang.Iterable<T>.first() : T? {
|
||||||
|
return this.iterator()?.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args : Array<String>) {
|
||||||
|
val test = java.util.HashSet<Int>()
|
||||||
|
test.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fun <T> Some<T>.close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some<T>() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val s = Some<String>()
|
||||||
|
s.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: close
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fun Some.simpleKotlinExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val s = Some()
|
||||||
|
s.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: simpleKotlinExtension
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun test() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun other() {
|
||||||
|
te<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT: test
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun test() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun other() {
|
||||||
|
test()<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSERT: test
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun test(a: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun other() {
|
||||||
|
te<caret>
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun test(a: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun other() {
|
||||||
|
test(<caret>)
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.jetbrains.jet.completion;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class ExtensionsCompletionTest extends JetCompletionTestBase {
|
||||||
|
|
||||||
|
// public ExtensionsCompletionTest() {
|
||||||
|
// this("/completion/basic/extensions", "IrrelevantExtension");
|
||||||
|
// // this("/completion/basic/extensions", "InvalidTypeParameters");
|
||||||
|
// // this("/completion/basic/extensions", "ExtensionInExtensionThis");
|
||||||
|
// }
|
||||||
|
|
||||||
|
protected ExtensionsCompletionTest(@NotNull String path, @NotNull String name) {
|
||||||
|
super(path, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static TestSuite suite() {
|
||||||
|
TestSuite suite = new TestSuite();
|
||||||
|
|
||||||
|
JetTestCaseBuilder.appendTestsInDirectory(
|
||||||
|
PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/extensions", false,
|
||||||
|
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||||
|
return new ExtensionsCompletionTest(dataPath, name);
|
||||||
|
}
|
||||||
|
}, suite);
|
||||||
|
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,31 +12,9 @@ import java.io.File;
|
|||||||
* @author Nikolay.Krasko
|
* @author Nikolay.Krasko
|
||||||
*/
|
*/
|
||||||
public class JetBasicCompletionTest extends JetCompletionTestBase {
|
public class JetBasicCompletionTest extends JetCompletionTestBase {
|
||||||
private final String myPath;
|
|
||||||
private final String myName;
|
|
||||||
|
|
||||||
public JetBasicCompletionTest(@NotNull String path, @NotNull String name) {
|
protected JetBasicCompletionTest(@NotNull String path, @NotNull String name) {
|
||||||
myPath = path;
|
super(path, name);
|
||||||
myName = name;
|
|
||||||
|
|
||||||
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
|
||||||
setName("testCompletionExecute");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCompletionExecute() throws Exception {
|
|
||||||
doTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTestDataPath() {
|
|
||||||
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
|
||||||
File.separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "test" + myName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -20,6 +21,32 @@ import java.util.List;
|
|||||||
* @author Nikolay.Krasko
|
* @author Nikolay.Krasko
|
||||||
*/
|
*/
|
||||||
public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
||||||
|
private final String myPath;
|
||||||
|
private final String myName;
|
||||||
|
|
||||||
|
protected JetCompletionTestBase(@NotNull String path, @NotNull String name) {
|
||||||
|
myPath = path;
|
||||||
|
myName = name;
|
||||||
|
|
||||||
|
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
||||||
|
setName("testCompletionExecute");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCompletionExecute() throws Exception {
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
||||||
|
File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "test" + myName;
|
||||||
|
}
|
||||||
|
|
||||||
private CompletionType type;
|
private CompletionType type;
|
||||||
|
|
||||||
|
|||||||
@@ -15,31 +15,8 @@ import java.io.File;
|
|||||||
*/
|
*/
|
||||||
public class KeywordsCompletionTest extends JetCompletionTestBase {
|
public class KeywordsCompletionTest extends JetCompletionTestBase {
|
||||||
|
|
||||||
private final String myPath;
|
protected KeywordsCompletionTest(@NotNull String path, @NotNull String name) {
|
||||||
private final String myName;
|
super(path, name);
|
||||||
|
|
||||||
public KeywordsCompletionTest(@NotNull String path, @NotNull String name) {
|
|
||||||
myPath = path;
|
|
||||||
myName = name;
|
|
||||||
|
|
||||||
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
|
||||||
setName("testCompletionExecute");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCompletionExecute() throws Exception {
|
|
||||||
doTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTestDataPath() {
|
|
||||||
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
|
||||||
File.separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "test" + myName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.jetbrains.jet.completion.handlers;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.LightCompletionTestCase;
|
||||||
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class FunctionsHandlerTest extends LightCompletionTestCase {
|
||||||
|
|
||||||
|
public void testNoParamsFunction() {
|
||||||
|
configureByFile("NoParamsFunction.kt");
|
||||||
|
checkResultByFile("NoParamsFunction.kt.after");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFunctionWithParams() {
|
||||||
|
configureByFile("ParamsFunction.kt");
|
||||||
|
checkResultByFile("ParamsFunction.kt.after");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() +
|
||||||
|
File.separator;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.jetbrains.jet.completion.handlers;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.LightCompletionTestCase;
|
||||||
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class KeywordsHandlerTest extends LightCompletionTestCase {
|
||||||
|
|
||||||
|
public void testSpaceAfter() throws IOException {
|
||||||
|
configureFromFileText("Test.kt", "protecte<caret>");
|
||||||
|
complete();
|
||||||
|
checkResultByText("protected <caret>");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoSpaceAfter() throws IOException {
|
||||||
|
configureFromFileText("Test.kt", "nul<caret>");
|
||||||
|
complete();
|
||||||
|
checkResultByText("null<caret>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() +
|
||||||
|
File.separator;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,4 +23,9 @@ public class DefaultJetObject implements JetObject {
|
|||||||
public final TypeInfo<?> getTypeInfo() {
|
public final TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
|
|||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static IntRange count(int length) {
|
public static IntRange count(int length) {
|
||||||
return new IntRange(0, length);
|
return new IntRange(0, length);
|
||||||
}
|
}
|
||||||
@@ -95,5 +100,10 @@ public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObj
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import jet.typeinfo.TypeInfo;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public interface JetObject {
|
public interface JetObject {
|
||||||
TypeInfo<?> getTypeInfo();
|
TypeInfo<?> getTypeInfo();
|
||||||
|
JetObject getOuterObject();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
|||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static IntRange count(int length) {
|
public static IntRange count(int length) {
|
||||||
return new IntRange(0, length);
|
return new IntRange(0, length);
|
||||||
}
|
}
|
||||||
@@ -95,5 +100,10 @@ public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,4 +31,9 @@ public class Tuple0 implements JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,12 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return TypeInfo.getTypeInfo(GenericIterator.class, false, null, new TypeInfoProjection[] {(TypeInfoProjection) elementTypeInfo});
|
return TypeInfo.getTypeInfo(GenericIterator.class, false, new TypeInfoProjection[] {(TypeInfoProjection) elementTypeInfo});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +74,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteIterator iterator(byte[] array) {
|
public static ByteIterator iterator(byte[] array) {
|
||||||
@@ -99,6 +109,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShortIterator iterator(short[] array) {
|
public static ShortIterator iterator(short[] array) {
|
||||||
@@ -129,6 +144,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntIterator iterator(int[] array) {
|
public static IntIterator iterator(int[] array) {
|
||||||
@@ -159,6 +179,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LongIterator iterator(long[] array) {
|
public static LongIterator iterator(long[] array) {
|
||||||
@@ -189,6 +214,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FloatIterator iterator(float[] array) {
|
public static FloatIterator iterator(float[] array) {
|
||||||
@@ -219,6 +249,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DoubleIterator iterator(double[] array) {
|
public static DoubleIterator iterator(double[] array) {
|
||||||
@@ -249,6 +284,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CharIterator iterator(char[] array) {
|
public static CharIterator iterator(char[] array) {
|
||||||
@@ -279,6 +319,11 @@ public abstract class ArrayIterator<T> implements Iterator<T>, JetObject {
|
|||||||
public TypeInfo<?> getTypeInfo() {
|
public TypeInfo<?> getTypeInfo() {
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BooleanIterator iterator(boolean[] array) {
|
public static BooleanIterator iterator(boolean[] array) {
|
||||||
|
|||||||
@@ -79,14 +79,6 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
return new TypeInfoImpl<T>(klazz, nullable);
|
return new TypeInfoImpl<T>(klazz, nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> TypeInfo<T> getTypeInfo(Class<T> klazz, boolean nullable, TypeInfo outerTypeInfo) {
|
|
||||||
return new TypeInfoImpl<T>(klazz, nullable, outerTypeInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> TypeInfo<T> getTypeInfo(Class<T> klazz, boolean nullable, TypeInfo outerTypeInfo, TypeInfoProjection[] projections) {
|
|
||||||
return new TypeInfoImpl<T>(klazz, nullable, outerTypeInfo, projections);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> TypeInfo<T> getTypeInfo(Class<T> klazz, boolean nullable, TypeInfoProjection[] projections) {
|
public static <T> TypeInfo<T> getTypeInfo(Class<T> klazz, boolean nullable, TypeInfoProjection[] projections) {
|
||||||
return new TypeInfoImpl<T>(klazz, nullable, projections);
|
return new TypeInfoImpl<T>(klazz, nullable, projections);
|
||||||
}
|
}
|
||||||
@@ -99,15 +91,13 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
|
|
||||||
public abstract int getProjectionCount();
|
public abstract int getProjectionCount();
|
||||||
|
|
||||||
public abstract TypeInfo getOuterTypeInfo();
|
|
||||||
|
|
||||||
public abstract TypeInfoProjection getProjection(int index);
|
public abstract TypeInfoProjection getProjection(int index);
|
||||||
|
|
||||||
public abstract TypeInfo getArgumentType(Class klass, int index);
|
public abstract TypeInfo getArgumentType(Class klass, int index);
|
||||||
|
|
||||||
protected abstract TypeInfo substitute(List<TypeInfo> myVars);
|
protected abstract TypeInfo substitute(List<TypeInfo> myVars);
|
||||||
|
|
||||||
protected abstract TypeInfo substitute(TypeInfo outer, TypeInfoProjection[] projections);
|
protected abstract TypeInfo substitute(TypeInfoProjection[] projections);
|
||||||
|
|
||||||
private static class TypeInfoVar<T> extends TypeInfo<T> {
|
private static class TypeInfoVar<T> extends TypeInfo<T> {
|
||||||
final int varIndex;
|
final int varIndex;
|
||||||
@@ -151,11 +141,6 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeInfo getOuterTypeInfo() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeInfoProjection getProjection(int index) {
|
public TypeInfoProjection getProjection(int index) {
|
||||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||||
@@ -172,7 +157,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TypeInfo substitute(TypeInfo outer, TypeInfoProjection[] projections) {
|
protected TypeInfo substitute(TypeInfoProjection[] projections) {
|
||||||
return projections[varIndex].getType();
|
return projections[varIndex].getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +166,11 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
throw new UnsupportedOperationException("Abstract TypeInfo");
|
throw new UnsupportedOperationException("Abstract TypeInfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "T:" + signature.klazz.getName() + ":" + varIndex;
|
return "T:" + signature.klazz.getName() + ":" + varIndex;
|
||||||
@@ -192,22 +182,12 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
private final Signature signature;
|
private final Signature signature;
|
||||||
private final boolean nullable;
|
private final boolean nullable;
|
||||||
private final TypeInfoProjection[] projections;
|
private final TypeInfoProjection[] projections;
|
||||||
private final TypeInfo outerTypeInfo;
|
|
||||||
|
|
||||||
private TypeInfoImpl(Class<T> theClass, boolean nullable) {
|
private TypeInfoImpl(Class<T> theClass, boolean nullable) {
|
||||||
this(theClass, nullable, null, EMPTY);
|
this(theClass, nullable, EMPTY);
|
||||||
}
|
|
||||||
|
|
||||||
private TypeInfoImpl(Class<T> theClass, boolean nullable, TypeInfo outerTypeInfo) {
|
|
||||||
this(theClass, nullable, outerTypeInfo, EMPTY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeInfoImpl(Class<T> theClass, boolean nullable, TypeInfoProjection[] projections) {
|
private TypeInfoImpl(Class<T> theClass, boolean nullable, TypeInfoProjection[] projections) {
|
||||||
this(theClass, nullable, null, projections);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeInfoImpl(Class<T> theClass, boolean nullable, TypeInfo outerTypeInfo, TypeInfoProjection[] projections) {
|
|
||||||
this.outerTypeInfo = outerTypeInfo;
|
|
||||||
this.signature = Parser.parse(theClass);
|
this.signature = Parser.parse(theClass);
|
||||||
this.nullable = nullable;
|
this.nullable = nullable;
|
||||||
this.projections = projections;
|
this.projections = projections;
|
||||||
@@ -247,7 +227,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
if(klass == this.signature.klazz)
|
if(klass == this.signature.klazz)
|
||||||
return projections[index].getType();
|
return projections[index].getType();
|
||||||
else {
|
else {
|
||||||
return getSuperTypeInfo(klass).substitute(outerTypeInfo, projections).getArgumentType(klass, index);
|
return getSuperTypeInfo(klass).substitute(projections).getArgumentType(klass, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,14 +263,14 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TypeInfo substitute(TypeInfo outer, TypeInfoProjection[] prj) {
|
protected TypeInfo substitute(TypeInfoProjection[] prj) {
|
||||||
if(projections.length == 0)
|
if(projections.length == 0)
|
||||||
return new TypeInfoImpl(signature.klazz, nullable, EMPTY);
|
return new TypeInfoImpl(signature.klazz, nullable, EMPTY);
|
||||||
else {
|
else {
|
||||||
TypeInfoProjection [] proj = new TypeInfoProjection[projections.length];
|
TypeInfoProjection [] proj = new TypeInfoProjection[projections.length];
|
||||||
for(int i = 0; i != proj.length; ++i) {
|
for(int i = 0; i != proj.length; ++i) {
|
||||||
final int finalI = i;
|
final int finalI = i;
|
||||||
final TypeInfo substitute = projections[finalI].getType().substitute(outer, prj);
|
final TypeInfo substitute = projections[finalI].getType().substitute(prj);
|
||||||
proj[i] = new TypeInfoProjection(){
|
proj[i] = new TypeInfoProjection(){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -359,11 +339,6 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
return projections.length;
|
return projections.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TypeInfo getOuterTypeInfo() {
|
|
||||||
return outerTypeInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final String toString() {
|
public final String toString() {
|
||||||
StringBuilder sb = new StringBuilder().append(signature.klazz.getName());
|
StringBuilder sb = new StringBuilder().append(signature.klazz.getName());
|
||||||
@@ -388,6 +363,11 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JetObject getOuterObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public final boolean isSubtypeOf(TypeInfoImpl<?> superType) {
|
public final boolean isSubtypeOf(TypeInfoImpl<?> superType) {
|
||||||
if (nullable && !superType.nullable) {
|
if (nullable && !superType.nullable) {
|
||||||
return false;
|
return false;
|
||||||
@@ -410,7 +390,6 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Signature {
|
public static class Signature {
|
||||||
final Signature outer;
|
|
||||||
final Class klazz;
|
final Class klazz;
|
||||||
|
|
||||||
List<TypeInfoProjection> variables;
|
List<TypeInfoProjection> variables;
|
||||||
@@ -419,8 +398,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
|
|
||||||
final HashMap<Class,TypeInfo> superSignatures = new HashMap<Class,TypeInfo>();
|
final HashMap<Class,TypeInfo> superSignatures = new HashMap<Class,TypeInfo>();
|
||||||
|
|
||||||
public Signature(Signature outer, Class klazz) {
|
public Signature(Class klazz) {
|
||||||
this.outer = outer;
|
|
||||||
this.klazz = klazz;
|
this.klazz = klazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,7 +480,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
if(value != null) {
|
if(value != null) {
|
||||||
Parser parser = new Parser(value, klass.getClassLoader());
|
Parser parser = new Parser(value, klass.getClassLoader());
|
||||||
Class enclosingClass = klass.getEnclosingClass();
|
Class enclosingClass = klass.getEnclosingClass();
|
||||||
Signature signature = new Signature(parse(enclosingClass), klass);
|
Signature signature = new Signature(klass);
|
||||||
map.put(klass, signature);
|
map.put(klass, signature);
|
||||||
parser.parseVars(signature);
|
parser.parseVars(signature);
|
||||||
parser.parseTypes(signature);
|
parser.parseTypes(signature);
|
||||||
@@ -517,7 +495,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
// todo complete impl
|
// todo complete impl
|
||||||
|
|
||||||
java.lang.reflect.Type genericSuperclass = klass.getGenericSuperclass();
|
java.lang.reflect.Type genericSuperclass = klass.getGenericSuperclass();
|
||||||
Signature signature = new Signature(parse(klass.getEnclosingClass()), klass);
|
Signature signature = new Signature(klass);
|
||||||
|
|
||||||
TypeVariable[] typeParameters = klass.getTypeParameters();
|
TypeVariable[] typeParameters = klass.getTypeParameters();
|
||||||
if(typeParameters == null || typeParameters.length == 0) {
|
if(typeParameters == null || typeParameters.length == 0) {
|
||||||
@@ -682,14 +660,14 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
if(klazz.equals(signature.klazz.getName()))
|
if(klazz.equals(signature.klazz.getName()))
|
||||||
return new TypeInfoVar(signature, nullable, signature.varNames.get(name));
|
return new TypeInfoVar(signature, nullable, signature.varNames.get(name));
|
||||||
else {
|
else {
|
||||||
Signature sig = signature;
|
// Signature sig = signature;
|
||||||
while(!klazz.equals(sig.klazz.getName())) {
|
// while(!klazz.equals(sig.klazz.getName())) {
|
||||||
sig = sig.outer;
|
// sig = sig.outer;
|
||||||
if(sig == null)
|
// if(sig == null)
|
||||||
throw new IllegalStateException();
|
// throw new IllegalStateException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
return new TypeInfoVar(sig, nullable, sig.varNames.get(name));
|
throw new UnsupportedOperationException("outer type info does not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,7 +694,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
|
|
||||||
private static class ArraySignature extends Signature {
|
private static class ArraySignature extends Signature {
|
||||||
public ArraySignature(Class klass) {
|
public ArraySignature(Class klass) {
|
||||||
super(null, klass);
|
super(klass);
|
||||||
variables = new LinkedList<TypeInfoProjection>();
|
variables = new LinkedList<TypeInfoProjection>();
|
||||||
varNames = new HashMap<String, Integer>();
|
varNames = new HashMap<String, Integer>();
|
||||||
varNames.put("T", 0);
|
varNames.put("T", 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user