Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,12 +1,17 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.signature.JetSignatureWriter;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureAdapter;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
import org.objectweb.asm.util.CheckSignatureAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
@@ -27,13 +32,31 @@ public class BothSignatureWriter {
|
||||
this.asmType = asmType;
|
||||
}
|
||||
}
|
||||
|
||||
private enum State {
|
||||
START,
|
||||
TYPE_PARAMETERS,
|
||||
|
||||
PARAMETERS,
|
||||
RETURN_TYPE,
|
||||
METHOD_END,
|
||||
|
||||
SUPERS,
|
||||
CLASS_END,
|
||||
}
|
||||
|
||||
private final SignatureWriter signatureWriter = new SignatureWriter();
|
||||
private final SignatureVisitor signatureVisitor;
|
||||
|
||||
private final JetSignatureWriter jetSignatureWriter = new JetSignatureWriter();
|
||||
private JetSignatureWriter jetSignatureWriter;
|
||||
|
||||
private String kotlinClassSignature;
|
||||
|
||||
private List<String> kotlinParameterTypes = new ArrayList<String>();
|
||||
private String kotlinReturnType;
|
||||
|
||||
private final Mode mode;
|
||||
private State state = State.START;
|
||||
|
||||
public BothSignatureWriter(Mode mode) {
|
||||
this.mode = mode;
|
||||
@@ -76,20 +99,37 @@ public class BothSignatureWriter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkState(State state) {
|
||||
if (DEBUG_SIGNATURE_WRITER) {
|
||||
if (state != this.state) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (jetSignatureWriter != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
checkTopLevel();
|
||||
}
|
||||
}
|
||||
|
||||
private void transitionState(State from, State to) {
|
||||
checkState(from);
|
||||
state = to;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut
|
||||
*/
|
||||
public void writeAsmType(Type asmType) {
|
||||
public void writeAsmType(Type asmType, boolean nullable) {
|
||||
switch (asmType.getSort()) {
|
||||
case Type.OBJECT:
|
||||
writeClassBegin(asmType.getInternalName());
|
||||
writeClassBegin(asmType.getInternalName(), nullable);
|
||||
writeClassEnd();
|
||||
return;
|
||||
case Type.ARRAY:
|
||||
writeArrayType();
|
||||
writeAsmType(asmType.getElementType());
|
||||
writeArrayType(nullable);
|
||||
writeAsmType(asmType.getElementType(), false);
|
||||
writeArrayEnd();
|
||||
return;
|
||||
default:
|
||||
@@ -97,20 +137,31 @@ public class BothSignatureWriter {
|
||||
if (descriptor.length() != 1) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
signatureVisitor().visitBaseType(descriptor.charAt(0));
|
||||
writeBaseType(descriptor.charAt(0), nullable);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeClassBegin(String internalName) {
|
||||
|
||||
private void writeBaseType(char c, boolean nullable) {
|
||||
if (nullable) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
signatureVisitor().visitBaseType(c);
|
||||
jetSignatureWriter.visitBaseType(c, nullable);
|
||||
}
|
||||
|
||||
public void writeClassBegin(String internalName, boolean nullable) {
|
||||
signatureVisitor().visitClassType(internalName);
|
||||
jetSignatureWriter.visitClassType(internalName, nullable);
|
||||
}
|
||||
|
||||
public void writeClassEnd() {
|
||||
signatureVisitor().visitEnd();
|
||||
jetSignatureWriter.visitEnd();
|
||||
}
|
||||
|
||||
public void writeArrayType() {
|
||||
public void writeArrayType(boolean nullable) {
|
||||
push(signatureVisitor().visitArrayType());
|
||||
jetSignatureWriter.visitArrayType(nullable);
|
||||
}
|
||||
|
||||
public void writeArrayEnd() {
|
||||
@@ -119,24 +170,39 @@ public class BothSignatureWriter {
|
||||
|
||||
public void writeTypeArgument(char c) {
|
||||
push(signatureVisitor().visitTypeArgument(c));
|
||||
jetSignatureWriter.visitTypeArgument(c);
|
||||
}
|
||||
|
||||
public void writeTypeArgumentEnd() {
|
||||
pop();
|
||||
}
|
||||
|
||||
public void writeTypeVariable(final String name) {
|
||||
public void writeTypeVariable(final String name, boolean nullable) {
|
||||
signatureVisitor().visitTypeVariable(name);
|
||||
jetSignatureWriter.visitTypeVariable(name, nullable);
|
||||
}
|
||||
|
||||
public void writeFormalTypeParameter(final String name) {
|
||||
checkTopLevel();
|
||||
|
||||
signatureVisitor().visitFormalTypeParameter(name);
|
||||
jetSignatureWriter.visitFormalTypeParameter(name);
|
||||
}
|
||||
|
||||
public void writerFormalTypeParametersStart() {
|
||||
checkTopLevel();
|
||||
transitionState(State.START, State.TYPE_PARAMETERS);
|
||||
jetSignatureWriter = new JetSignatureWriter();
|
||||
}
|
||||
|
||||
public void writeFormalTypeParametersEnd() {
|
||||
jetSignatureWriter = null;
|
||||
checkState(State.TYPE_PARAMETERS);
|
||||
}
|
||||
|
||||
public void writeClassBound() {
|
||||
push(signatureVisitor().visitClassBound());
|
||||
jetSignatureWriter.visitClassBound();
|
||||
}
|
||||
|
||||
public void writeClassBoundEnd() {
|
||||
@@ -145,33 +211,75 @@ public class BothSignatureWriter {
|
||||
|
||||
public void writeInterfaceBound() {
|
||||
push(signatureVisitor().visitInterfaceBound());
|
||||
jetSignatureWriter.visitInterfaceBound();
|
||||
}
|
||||
|
||||
public void writeInterfaceBoundEnd() {
|
||||
pop();
|
||||
}
|
||||
|
||||
public void writeParametersStart() {
|
||||
transitionState(State.TYPE_PARAMETERS, State.PARAMETERS);
|
||||
}
|
||||
|
||||
public void writeParametersEnd() {
|
||||
checkState(State.PARAMETERS);
|
||||
}
|
||||
|
||||
public void writeParameterType() {
|
||||
push(signatureVisitor().visitParameterType());
|
||||
jetSignatureWriter = new JetSignatureWriter();
|
||||
//jetSignatureWriter.visitParameterType();
|
||||
}
|
||||
|
||||
public void writeParameterTypeEnd() {
|
||||
pop();
|
||||
String signature = jetSignatureWriter.toString();
|
||||
kotlinParameterTypes.add(signature);
|
||||
|
||||
if (DEBUG_SIGNATURE_WRITER) {
|
||||
new JetSignatureReader(signature).acceptTypeOnly(new JetSignatureAdapter());
|
||||
}
|
||||
|
||||
jetSignatureWriter = null;
|
||||
}
|
||||
|
||||
public void writeReturnType() {
|
||||
transitionState(State.PARAMETERS, State.RETURN_TYPE);
|
||||
|
||||
jetSignatureWriter = new JetSignatureWriter();
|
||||
|
||||
push(signatureVisitor().visitReturnType());
|
||||
//jetSignatureWriter.visitReturnType();
|
||||
}
|
||||
|
||||
public void writeReturnTypeEnd() {
|
||||
pop();
|
||||
|
||||
kotlinReturnType = jetSignatureWriter.toString();
|
||||
|
||||
if (DEBUG_SIGNATURE_WRITER) {
|
||||
new JetSignatureReader(kotlinReturnType).acceptTypeOnly(new JetSignatureAdapter());
|
||||
}
|
||||
|
||||
jetSignatureWriter = null;
|
||||
transitionState(State.RETURN_TYPE, State.METHOD_END);
|
||||
}
|
||||
|
||||
public void writeSupersStart() {
|
||||
transitionState(State.TYPE_PARAMETERS, State.SUPERS);
|
||||
jetSignatureWriter = new JetSignatureWriter();
|
||||
}
|
||||
|
||||
public void writeSupersEnd() {
|
||||
kotlinClassSignature = jetSignatureWriter.toString();
|
||||
jetSignatureWriter = null;
|
||||
transitionState(State.SUPERS, State.CLASS_END);
|
||||
}
|
||||
|
||||
public void writeSuperclass() {
|
||||
checkTopLevel();
|
||||
checkMode(Mode.CLASS);
|
||||
|
||||
push(signatureVisitor().visitSuperclass());
|
||||
jetSignatureWriter.visitSuperclass();
|
||||
}
|
||||
|
||||
public void writeSuperclassEnd() {
|
||||
@@ -186,6 +294,7 @@ public class BothSignatureWriter {
|
||||
checkMode(Mode.CLASS);
|
||||
|
||||
push(signatureVisitor().visitInterface());
|
||||
jetSignatureWriter.visitInterface();
|
||||
}
|
||||
|
||||
public void writeInterfaceEnd() {
|
||||
@@ -200,16 +309,31 @@ public class BothSignatureWriter {
|
||||
|
||||
@Nullable
|
||||
public String makeJavaString() {
|
||||
if (!visitors.isEmpty()) {
|
||||
if (state != State.METHOD_END && state != State.CLASS_END) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
checkTopLevel();
|
||||
// TODO: return null if not generic
|
||||
return signatureWriter.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> makeKotlinSignatures() {
|
||||
checkState(State.METHOD_END);
|
||||
// TODO: return nulls if equal to #makeJavaString
|
||||
return kotlinParameterTypes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String makeKotlinString() {
|
||||
// TODO: not implemented yet
|
||||
return null;
|
||||
public String makeKotlinReturnTypeSignature() {
|
||||
checkState(State.METHOD_END);
|
||||
return kotlinReturnType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String makeKotlinClassSignature() {
|
||||
checkState(State.CLASS_END);
|
||||
return kotlinClassSignature;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
|
||||
Method descriptor = erasedInvokeSignature(fd);
|
||||
String owner = getInternalClassName(fd);
|
||||
final CallableMethod result = new CallableMethod(owner, new JvmMethodSignature(descriptor, null), INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
|
||||
final CallableMethod result = new CallableMethod(owner, new JvmMethodSignature(descriptor, null, null, null), INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
|
||||
if (fd.getReceiverParameter().exists()) {
|
||||
result.setNeedsReceiver(fd);
|
||||
}
|
||||
@@ -165,7 +165,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
|
||||
final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper());
|
||||
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
||||
fc.generateMethod(body, new JvmMethodSignature(invokeSignature(funDescriptor), null), funDescriptor);
|
||||
fc.generateMethod(body, new JvmMethodSignature(invokeSignature(funDescriptor), null, null, null), funDescriptor);
|
||||
return closureContext.outerWasUsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,9 @@ public class FunctionCodegen {
|
||||
if(functionDescriptor.getReturnType().isNullable()) {
|
||||
av.visit(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
|
||||
}
|
||||
if (jvmSignature.getKotlinReturnType() != null) {
|
||||
av.visit(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
@@ -121,6 +124,9 @@ public class FunctionCodegen {
|
||||
if(parameterDescriptor.getOutType().isNullable()) {
|
||||
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
|
||||
}
|
||||
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
|
||||
av.visit(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i));
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
? Opcodes.ACC_INTERFACE
|
||||
: 0/*Opcodes.ACC_SUPER*/),
|
||||
signature.getName(),
|
||||
signature.getGenericSignature(),
|
||||
signature.getJavaGenericSignature(),
|
||||
signature.getSuperclassName(),
|
||||
signature.getInterfaces().toArray(new String[0])
|
||||
);
|
||||
@@ -77,57 +77,55 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
annotationVisitor.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private JvmClassSignature signature() {
|
||||
String genericSignature;
|
||||
List<String> superInterfaces;
|
||||
|
||||
{
|
||||
LinkedHashSet<String> superInterfacesLinkedHashSet = new LinkedHashSet<String>();
|
||||
LinkedHashSet<String> superInterfacesLinkedHashSet = new LinkedHashSet<String>();
|
||||
|
||||
BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
|
||||
BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
|
||||
|
||||
|
||||
{ // type parameters
|
||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
||||
typeMapper.writeFormalTypeParameters(typeParameters, signatureVisitor);
|
||||
}
|
||||
|
||||
|
||||
{ // superclass
|
||||
signatureVisitor.writeSuperclass();
|
||||
if (superClassType == null) {
|
||||
signatureVisitor.writeClassBegin(superClass);
|
||||
signatureVisitor.writeClassEnd();
|
||||
} else {
|
||||
typeMapper.mapType(superClassType, OwnerKind.IMPLEMENTATION, signatureVisitor, true);
|
||||
}
|
||||
signatureVisitor.writeSuperclassEnd();
|
||||
}
|
||||
|
||||
|
||||
{ // superinterfaces
|
||||
superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT_INTERNAL);
|
||||
|
||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (CodegenUtil.isInterface(superClassDescriptor)) {
|
||||
signatureVisitor.writeInterface();
|
||||
Type jvmName = typeMapper.mapType(superType, OwnerKind.IMPLEMENTATION, signatureVisitor, true);
|
||||
signatureVisitor.writeInterfaceEnd();
|
||||
superInterfacesLinkedHashSet.add(jvmName.getInternalName());
|
||||
}
|
||||
}
|
||||
|
||||
superInterfaces = new ArrayList<String>(superInterfacesLinkedHashSet);
|
||||
}
|
||||
|
||||
// TODO: null if class is not generic and does not have generic superclasses
|
||||
genericSignature = signatureVisitor.makeJavaString();
|
||||
{ // type parameters
|
||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
||||
typeMapper.writeFormalTypeParameters(typeParameters, signatureVisitor);
|
||||
}
|
||||
return new JvmClassSignature(jvmName(), superClass, superInterfaces, genericSignature);
|
||||
|
||||
signatureVisitor.writeSupersStart();
|
||||
|
||||
{ // superclass
|
||||
signatureVisitor.writeSuperclass();
|
||||
if (superClassType == null) {
|
||||
signatureVisitor.writeClassBegin(superClass, false);
|
||||
signatureVisitor.writeClassEnd();
|
||||
} else {
|
||||
typeMapper.mapType(superClassType, OwnerKind.IMPLEMENTATION, signatureVisitor, true);
|
||||
}
|
||||
signatureVisitor.writeSuperclassEnd();
|
||||
}
|
||||
|
||||
|
||||
{ // superinterfaces
|
||||
superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT_INTERNAL);
|
||||
|
||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (CodegenUtil.isInterface(superClassDescriptor)) {
|
||||
signatureVisitor.writeInterface();
|
||||
Type jvmName = typeMapper.mapType(superType, OwnerKind.IMPLEMENTATION, signatureVisitor, true);
|
||||
signatureVisitor.writeInterfaceEnd();
|
||||
superInterfacesLinkedHashSet.add(jvmName.getInternalName());
|
||||
}
|
||||
}
|
||||
|
||||
superInterfaces = new ArrayList<String>(superInterfacesLinkedHashSet);
|
||||
}
|
||||
|
||||
signatureVisitor.writeSupersEnd();
|
||||
|
||||
return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), signatureVisitor.makeKotlinClassSignature());
|
||||
}
|
||||
|
||||
private String jvmName() {
|
||||
@@ -324,7 +322,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
constructorMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
callableMethod = new CallableMethod("", new JvmMethodSignature(constructorMethod, null) /* TODO */, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
callableMethod = new CallableMethod("", new JvmMethodSignature(constructorMethod, null, null, null) /* TODO */, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
}
|
||||
else {
|
||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
||||
|
||||
@@ -165,13 +165,13 @@ public class JetTypeMapper {
|
||||
@NotNull private Type mapReturnType(final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeAsmType(Type.VOID_TYPE);
|
||||
signatureVisitor.writeAsmType(Type.VOID_TYPE, false);
|
||||
}
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
if (jetType.equals(JetStandardClasses.getNullableNothingType())) {
|
||||
if (signatureVisitor != null) {
|
||||
visitAsmType(signatureVisitor, TYPE_OBJECT);
|
||||
visitAsmType(signatureVisitor, TYPE_OBJECT, false);
|
||||
}
|
||||
return TYPE_OBJECT;
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public class JetTypeMapper {
|
||||
JetType memberType = jetType.getArguments().get(0).getType();
|
||||
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeArrayType();
|
||||
signatureVisitor.writeArrayType(jetType.isNullable());
|
||||
mapType(memberType, kind, signatureVisitor, true);
|
||||
signatureVisitor.writeArrayEnd();
|
||||
}
|
||||
@@ -271,7 +271,7 @@ public class JetTypeMapper {
|
||||
|
||||
if (JetStandardClasses.getAny().equals(descriptor)) {
|
||||
if (signatureVisitor != null) {
|
||||
visitAsmType(signatureVisitor, TYPE_OBJECT);
|
||||
visitAsmType(signatureVisitor, TYPE_OBJECT, jetType.isNullable());
|
||||
}
|
||||
return TYPE_OBJECT;
|
||||
}
|
||||
@@ -282,7 +282,7 @@ public class JetTypeMapper {
|
||||
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
|
||||
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeClassBegin(asmType.getInternalName());
|
||||
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable());
|
||||
for (TypeProjection proj : jetType.getArguments()) {
|
||||
// TODO: +-
|
||||
signatureVisitor.writeTypeArgument('=');
|
||||
@@ -298,7 +298,7 @@ public class JetTypeMapper {
|
||||
if (descriptor instanceof TypeParameterDescriptor) {
|
||||
if (signatureVisitor != null) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
||||
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName());
|
||||
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable());
|
||||
}
|
||||
|
||||
return mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
||||
@@ -310,16 +310,16 @@ public class JetTypeMapper {
|
||||
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean genericTypeParameter) {
|
||||
if (signatureVisitor != null) {
|
||||
if (genericTypeParameter) {
|
||||
visitAsmType(signatureVisitor, boxType(asmType));
|
||||
visitAsmType(signatureVisitor, boxType(asmType), jetType.isNullable());
|
||||
} else {
|
||||
visitAsmType(signatureVisitor, asmType);
|
||||
visitAsmType(signatureVisitor, asmType, jetType.isNullable());
|
||||
}
|
||||
}
|
||||
return asmType;
|
||||
}
|
||||
|
||||
public static void visitAsmType(BothSignatureWriter visitor, Type asmType) {
|
||||
visitor.writeAsmType(asmType);
|
||||
public static void visitAsmType(BothSignatureWriter visitor, Type asmType, boolean nullable) {
|
||||
visitor.writeAsmType(asmType, nullable);
|
||||
}
|
||||
|
||||
public static Type unboxType(final Type type) {
|
||||
@@ -469,12 +469,16 @@ public class JetTypeMapper {
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
}
|
||||
}
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeParametersStart();
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
|
||||
if(parameterDescriptor.isReified()) {
|
||||
parameterTypes.add(TYPE_TYPEINFO);
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeParameterType();
|
||||
visitAsmType(signatureVisitor, TYPE_TYPEINFO);
|
||||
visitAsmType(signatureVisitor, TYPE_TYPEINFO, false);
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
}
|
||||
}
|
||||
@@ -490,12 +494,17 @@ public class JetTypeMapper {
|
||||
valueParameterTypes.add(type);
|
||||
parameterTypes.add(type);
|
||||
}
|
||||
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeParametersEnd();
|
||||
}
|
||||
|
||||
Type returnType;
|
||||
if (f instanceof ConstructorDescriptor) {
|
||||
returnType = Type.VOID_TYPE;
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeReturnType();
|
||||
visitAsmType(signatureVisitor, Type.VOID_TYPE);
|
||||
visitAsmType(signatureVisitor, Type.VOID_TYPE, false);
|
||||
signatureVisitor.writeReturnTypeEnd();
|
||||
}
|
||||
} else {
|
||||
@@ -509,7 +518,12 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
Method method = new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
return new JvmMethodSignature(method, signatureVisitor != null ? signatureVisitor.makeJavaString() : null);
|
||||
if (signatureVisitor == null) {
|
||||
return new JvmMethodSignature(method, null, null, null);
|
||||
} else {
|
||||
return new JvmMethodSignature(method, signatureVisitor.makeJavaString(),
|
||||
signatureVisitor.makeKotlinSignatures(), signatureVisitor.makeKotlinReturnTypeSignature());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -518,9 +532,11 @@ public class JetTypeMapper {
|
||||
return;
|
||||
}
|
||||
|
||||
signatureVisitor.writerFormalTypeParametersStart();
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||
writeFormalTypeParameter(typeParameterDescriptor, signatureVisitor);
|
||||
}
|
||||
signatureVisitor.writeFormalTypeParametersEnd();
|
||||
}
|
||||
|
||||
private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) {
|
||||
@@ -567,7 +583,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
Type returnType = mapReturnType(f.getReturnType());
|
||||
// TODO: proper generic signature
|
||||
return new JvmMethodSignature(new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()])), null);
|
||||
return new JvmMethodSignature(new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()])), null, null, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -592,7 +608,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
// TODO: proper generic signature
|
||||
return new JvmMethodSignature(new Method(name, returnType, params.toArray(new Type[params.size()])), null);
|
||||
return new JvmMethodSignature(new Method(name, returnType, params.toArray(new Type[params.size()])), null, null, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -622,7 +638,7 @@ public class JetTypeMapper {
|
||||
params.add(mapType(inType));
|
||||
|
||||
// TODO: proper generic signature
|
||||
return new JvmMethodSignature(new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])), null);
|
||||
return new JvmMethodSignature(new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])), null, null, null);
|
||||
}
|
||||
|
||||
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) {
|
||||
@@ -644,7 +660,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
Method method = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
return new JvmMethodSignature(method, null); // TODO: generics signature
|
||||
return new JvmMethodSignature(method, null, null, null); // TODO: generics signature
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -9,13 +12,16 @@ public class JvmClassSignature {
|
||||
private final String name;
|
||||
private final String superclassName;
|
||||
private final List<String> interfaces;
|
||||
private final String genericSignature;
|
||||
private final String javaGenericSignature;
|
||||
private final String kotlinGenericSignature;
|
||||
|
||||
public JvmClassSignature(String name, String superclassName, List<String> interfaces, String genericSignature) {
|
||||
public JvmClassSignature(String name, String superclassName, List<String> interfaces,
|
||||
@Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature) {
|
||||
this.name = name;
|
||||
this.superclassName = superclassName;
|
||||
this.interfaces = interfaces;
|
||||
this.genericSignature = genericSignature;
|
||||
this.javaGenericSignature = javaGenericSignature;
|
||||
this.kotlinGenericSignature = kotlinGenericSignature;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -30,7 +36,11 @@ public class JvmClassSignature {
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
public String getGenericSignature() {
|
||||
return genericSignature;
|
||||
public String getJavaGenericSignature() {
|
||||
return javaGenericSignature;
|
||||
}
|
||||
|
||||
public String getKotlinGenericSignature() {
|
||||
return kotlinGenericSignature;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
@@ -12,10 +14,16 @@ public class JvmMethodSignature {
|
||||
private final Method asmMethod;
|
||||
/** Null when we don't care about type parameters */
|
||||
private final String genericsSignature;
|
||||
// TODO: type parameters
|
||||
private final List<String> kotlinParameterTypes;
|
||||
private final String kotlinReturnType;
|
||||
|
||||
public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature) {
|
||||
public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature,
|
||||
@Nullable List<String> kotlinParameterTypes, @Nullable String kotlinReturnType) {
|
||||
this.asmMethod = asmMethod;
|
||||
this.genericsSignature = genericsSignature;
|
||||
this.kotlinParameterTypes = kotlinParameterTypes;
|
||||
this.kotlinReturnType = kotlinReturnType;
|
||||
}
|
||||
|
||||
public Method getAsmMethod() {
|
||||
@@ -25,4 +33,12 @@ public class JvmMethodSignature {
|
||||
public String getGenericsSignature() {
|
||||
return genericsSignature;
|
||||
}
|
||||
|
||||
public List<String> getKotlinParameterTypes() {
|
||||
return kotlinParameterTypes;
|
||||
}
|
||||
|
||||
public String getKotlinReturnType() {
|
||||
return kotlinReturnType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,10 @@ public class SignatureUtil {
|
||||
|
||||
private static void genTypeParams(JetClass type, StringBuilder sb) {
|
||||
List<JetTypeParameter> parameters = type.getTypeParameterList().getParameters();
|
||||
if (parameters.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
sb.append('<');
|
||||
for(JetTypeParameter param : parameters) {
|
||||
sb.append("T");
|
||||
Variance variance = param.getVariance();
|
||||
@@ -78,5 +82,6 @@ public class SignatureUtil {
|
||||
sb.append(param.getName());
|
||||
sb.append(";");
|
||||
}
|
||||
sb.append('>');
|
||||
}
|
||||
}
|
||||
|
||||
+25
-2
@@ -360,6 +360,7 @@ public class JavaDescriptorResolver {
|
||||
|
||||
boolean changeNullable = false;
|
||||
boolean nullable = true;
|
||||
String typeFromAnnotation = null;
|
||||
|
||||
// TODO: must be very slow, make it lazy?
|
||||
String name = parameter.getName() != null ? parameter.getName() : "p" + i;
|
||||
@@ -383,10 +384,20 @@ public class JavaDescriptorResolver {
|
||||
nullable = false;
|
||||
changeNullable = true;
|
||||
}
|
||||
|
||||
PsiLiteralExpression signatureExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD);
|
||||
if (signatureExpression != null) {
|
||||
typeFromAnnotation = (String) signatureExpression.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JetType outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
||||
JetType outType;
|
||||
if (typeFromAnnotation != null) {
|
||||
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation);
|
||||
} else {
|
||||
outType = semanticServices.getTypeTransformer().transformToType(psiType);
|
||||
}
|
||||
return new ValueParameterDescriptorImpl(
|
||||
containingDeclaration,
|
||||
i,
|
||||
@@ -509,6 +520,8 @@ public class JavaDescriptorResolver {
|
||||
private JetType makeReturnType(PsiType returnType, PsiMethod method) {
|
||||
boolean changeNullable = false;
|
||||
boolean nullable = true;
|
||||
|
||||
String returnTypeFromAnnotation = null;
|
||||
|
||||
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
|
||||
if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD_CLASS)) {
|
||||
@@ -520,9 +533,19 @@ public class JavaDescriptorResolver {
|
||||
nullable = false;
|
||||
changeNullable = true;
|
||||
}
|
||||
|
||||
PsiLiteralExpression returnTypeExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD);
|
||||
if (returnTypeExpression != null) {
|
||||
returnTypeFromAnnotation = (String) returnTypeExpression.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
JetType transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
|
||||
JetType transformedType;
|
||||
if (returnTypeFromAnnotation != null) {
|
||||
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation);
|
||||
} else {
|
||||
transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
|
||||
}
|
||||
if (changeNullable) {
|
||||
return TypeUtils.makeNullableAsSpecified(transformedType, nullable);
|
||||
} else {
|
||||
|
||||
+15
@@ -6,6 +6,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureVisitor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -57,6 +59,19 @@ public class JavaTypeTransformer {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType transformToType(@NotNull String kotlinSignature) {
|
||||
final JetType[] r = new JetType[1];
|
||||
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(resolver, standardLibrary) {
|
||||
@Override
|
||||
protected void done(@NotNull JetType jetType) {
|
||||
r[0] = jetType;
|
||||
}
|
||||
};
|
||||
new JetSignatureReader(kotlinSignature).acceptType(reader);
|
||||
return r[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType transformToType(@NotNull PsiType javaType) {
|
||||
return javaType.accept(new PsiTypeVisitor<JetType>() {
|
||||
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
package org.jetbrains.jet.lang.resolve.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader;
|
||||
import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureVisitor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor {
|
||||
|
||||
private final JavaDescriptorResolver javaDescriptorResolver;
|
||||
private final JetStandardLibrary jetStandardLibrary;
|
||||
|
||||
public JetTypeJetSignatureReader(JavaDescriptorResolver javaDescriptorResolver, JetStandardLibrary jetStandardLibrary) {
|
||||
this.javaDescriptorResolver = javaDescriptorResolver;
|
||||
this.jetStandardLibrary = jetStandardLibrary;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void visitFormalTypeParameter(String name) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitClassBound() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterfaceBound() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitSuperclass() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterface() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitParameterType() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitReturnType() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitExceptionType() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private JetType getPrimitiveType(char descriptor, boolean nullable) {
|
||||
if (!nullable) {
|
||||
switch (descriptor) {
|
||||
case 'Z':
|
||||
return jetStandardLibrary.getBooleanType();
|
||||
case 'C':
|
||||
return jetStandardLibrary.getCharType();
|
||||
case 'B':
|
||||
return jetStandardLibrary.getByteType();
|
||||
case 'S':
|
||||
return jetStandardLibrary.getShortType();
|
||||
case 'I':
|
||||
return jetStandardLibrary.getIntType();
|
||||
case 'F':
|
||||
return jetStandardLibrary.getFloatType();
|
||||
case 'J':
|
||||
return jetStandardLibrary.getLongType();
|
||||
case 'D':
|
||||
return jetStandardLibrary.getDoubleType();
|
||||
case 'V':
|
||||
return JetStandardClasses.getUnitType();
|
||||
}
|
||||
} else {
|
||||
switch (descriptor) {
|
||||
case 'Z':
|
||||
return jetStandardLibrary.getNullableBooleanType();
|
||||
case 'C':
|
||||
return jetStandardLibrary.getNullableCharType();
|
||||
case 'B':
|
||||
return jetStandardLibrary.getNullableByteType();
|
||||
case 'S':
|
||||
return jetStandardLibrary.getNullableShortType();
|
||||
case 'I':
|
||||
return jetStandardLibrary.getNullableIntType();
|
||||
case 'F':
|
||||
return jetStandardLibrary.getNullableFloatType();
|
||||
case 'J':
|
||||
return jetStandardLibrary.getNullableLongType();
|
||||
case 'D':
|
||||
return jetStandardLibrary.getNullableDoubleType();
|
||||
case 'V':
|
||||
throw new IllegalStateException("incorrect signature: nullable void");
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("incorrect signature");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBaseType(char descriptor, boolean nullable) {
|
||||
done(getPrimitiveType(descriptor, nullable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeVariable(String name, boolean nullable) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitArrayType(boolean nullable) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
|
||||
private ClassDescriptor classDescriptor;
|
||||
private boolean nullable;
|
||||
private List<TypeProjection> typeArguments;
|
||||
|
||||
@Override
|
||||
public void visitClassType(String name, boolean nullable) {
|
||||
String ourName = name.replace('/', '.');
|
||||
this.classDescriptor = javaDescriptorResolver.resolveClass(ourName);
|
||||
if (this.classDescriptor == null) {
|
||||
throw new IllegalStateException("class not found by name: " + ourName); // TODO: wrong exception
|
||||
}
|
||||
this.nullable = nullable;
|
||||
this.typeArguments = new ArrayList<TypeProjection>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClassType(String name, boolean nullable) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeArgument() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private static Variance parseVariance(char wildcard) {
|
||||
switch (wildcard) {
|
||||
case '=': return Variance.INVARIANT;
|
||||
case '+': return Variance.OUT_VARIANCE;
|
||||
case '-': return Variance.IN_VARIANCE;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitTypeArgument(final char wildcard) {
|
||||
return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) {
|
||||
|
||||
@Override
|
||||
protected void done(@NotNull JetType jetType) {
|
||||
typeArguments.add(new TypeProjection(parseVariance(wildcard), jetType));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
JetType jetType = new JetTypeImpl(
|
||||
Collections.<AnnotationDescriptor>emptyList(),
|
||||
classDescriptor.getTypeConstructor(),
|
||||
nullable,
|
||||
typeArguments,
|
||||
ErrorUtils.getErrorScope());
|
||||
done(jetType);
|
||||
}
|
||||
|
||||
protected abstract void done(@NotNull JetType jetType);
|
||||
}
|
||||
@@ -13,6 +13,7 @@ public class StdlibNames {
|
||||
public static final String JET_VALUE_PARAMETER_NAME_FIELD = "name";
|
||||
public static final String JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue";
|
||||
public static final String JET_VALUE_PARAMETER_NULLABLE_FIELD = "nullable";
|
||||
public static final String JET_VALUE_PARAMETER_TYPE_FIELD = "type";
|
||||
|
||||
|
||||
public static final String JET_TYPE_PARAMETER_CLASS = "jet.typeinfo.JetTypeParameter";
|
||||
@@ -25,6 +26,7 @@ public class StdlibNames {
|
||||
public static final String JET_METHOD_DESCRIPTOR = "Ljet/typeinfo/JetMethod;";
|
||||
|
||||
public static final String JET_METHOD_NULLABLE_RETURN_TYPE_FIELD = "nullableReturnType";
|
||||
public static final String JET_METHOD_RETURN_TYPE_FIELD = "returnType";
|
||||
|
||||
|
||||
public static final String JET_OBJECT_INTERNAL = "jet/JetObject";
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.signature;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class JetSignatureAdapter implements JetSignatureVisitor {
|
||||
@Override
|
||||
public void visitFormalTypeParameter(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitClassBound() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterfaceBound() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitSuperclass() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitInterface() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitParameterType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitReturnType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitExceptionType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBaseType(char descriptor, boolean nullable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeVariable(String name, boolean nullable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitArrayType(boolean nullable) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassType(String name, boolean nullable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClassType(String name, boolean nullable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeArgument() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSignatureVisitor visitTypeArgument(char wildcard) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -1,4 +1,4 @@
|
||||
package org.jetbrains.jet.codegen.signature;
|
||||
package org.jetbrains.jet.lang.resolve.java.signature;
|
||||
|
||||
import org.objectweb.asm.signature.SignatureReader;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
@@ -60,6 +60,17 @@ public class JetSignatureReader {
|
||||
}
|
||||
}
|
||||
|
||||
public int acceptType(JetSignatureVisitor v) {
|
||||
return parseType(this.signature, 0, v);
|
||||
}
|
||||
|
||||
public void acceptTypeOnly(JetSignatureVisitor v) {
|
||||
int r = acceptType(v);
|
||||
if (r != signature.length()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int parseType(
|
||||
final String signature,
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.jetbrains.jet.codegen.signature;
|
||||
package org.jetbrains.jet.lang.resolve.java.signature;
|
||||
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.jetbrains.jet.codegen.signature;
|
||||
package org.jetbrains.jet.lang.resolve.java.signature;
|
||||
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
@@ -95,7 +95,7 @@ public class ErrorUtils {
|
||||
true, Collections.<TypeParameterDescriptor>emptyList(), Collections.<JetType>emptyList(), getErrorScope(), ERROR_CONSTRUCTOR_GROUP, ERROR_CONSTRUCTOR);
|
||||
}
|
||||
|
||||
private static JetScope getErrorScope() {
|
||||
public static JetScope getErrorScope() {
|
||||
return ERROR_SCOPE;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType {
|
||||
private final boolean nullable;
|
||||
private JetScope memberScope;
|
||||
|
||||
public JetTypeImpl(List<AnnotationDescriptor> annotations, TypeConstructor constructor, boolean nullable, List<TypeProjection> arguments, JetScope memberScope) {
|
||||
public JetTypeImpl(List<AnnotationDescriptor> annotations, TypeConstructor constructor, boolean nullable, @NotNull List<TypeProjection> arguments, JetScope memberScope) {
|
||||
super(annotations);
|
||||
this.constructor = constructor;
|
||||
this.nullable = nullable;
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.junit.Assert;
|
||||
|
||||
@@ -156,9 +158,23 @@ public class ReadClassDataTest extends UsefulTestCase {
|
||||
for (int i = 0; i < a.getValueParameters().size(); ++i) {
|
||||
compareAnything(ValueParameterDescriptor.class, a.getValueParameters().get(i), b.getValueParameters().get(i));
|
||||
}
|
||||
Assert.assertEquals(a.getReturnType(), b.getReturnType());
|
||||
compareTypes(a.getReturnType(), b.getReturnType());
|
||||
System.out.println("fun " + a.getName() + "(...): " + a.getReturnType());
|
||||
}
|
||||
|
||||
private void compareAnything(Object a, Object b) {
|
||||
if (a instanceof JetType || b instanceof JetType) {
|
||||
compareTypes((JetType) a, (JetType) b);
|
||||
} else {
|
||||
Assert.assertEquals(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
private void compareTypes(JetType a, JetType b) {
|
||||
// cannot just call a.equals(b) because "a" and "b" were created in different environments,
|
||||
// TypeConstructor does not override equals()
|
||||
Assert.assertEquals(a.toString(), b.toString());
|
||||
}
|
||||
|
||||
private <T> void compareAnything(Class<T> clazz, T a, T b) {
|
||||
System.out.println("Comparing " + clazz);
|
||||
@@ -182,7 +198,7 @@ public class ReadClassDataTest extends UsefulTestCase {
|
||||
System.out.println(method.getName());
|
||||
Object ap = invoke(method, a);
|
||||
Object bp = invoke(method, b);
|
||||
Assert.assertEquals(ap, bp);
|
||||
compareAnything(ap, bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ public class JetFunctionInsertHandler implements InsertHandler<LookupElement> {
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context, LookupElement item) {
|
||||
if (context.getCompletionChar() == '(') {
|
||||
context.setAddCompletionChar(false);
|
||||
}
|
||||
|
||||
int startOffset = context.getStartOffset();
|
||||
int lookupStringLength = item.getLookupString().length();
|
||||
int endOffset = startOffset + lookupStringLength;
|
||||
|
||||
@@ -17,12 +17,16 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.*;
|
||||
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.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.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||
@@ -105,6 +109,7 @@ class JetSimpleNameReference extends JetPsiReference {
|
||||
@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
|
||||
@@ -121,6 +126,11 @@ class JetSimpleNameReference extends JetPsiReference {
|
||||
@NotNull final JetScope externalScope,
|
||||
@NotNull final ReceiverDescriptor receiverDescriptor
|
||||
) {
|
||||
// It's impossible to add extension function for namespace
|
||||
if (receiverDescriptor.getType() instanceof NamespaceType) {
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||
|
||||
descriptorsSet.addAll(Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
||||
@@ -138,7 +148,7 @@ class JetSimpleNameReference extends JetPsiReference {
|
||||
List<LookupElement> result = Lists.newArrayList();
|
||||
|
||||
for (final DeclarationDescriptor descriptor : descriptors) {
|
||||
LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName());
|
||||
LookupElementBuilder element = LookupElementBuilder.create(descriptor, descriptor.getName());
|
||||
String typeText = "";
|
||||
String tailText = "";
|
||||
boolean tailTextGrayed = false;
|
||||
@@ -155,6 +165,7 @@ class JetSimpleNameReference extends JetPsiReference {
|
||||
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
|
||||
@@ -175,6 +186,7 @@ class JetSimpleNameReference extends JetPsiReference {
|
||||
else {
|
||||
typeText = DescriptorRenderer.TEXT.render(descriptor);
|
||||
}
|
||||
|
||||
element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText);
|
||||
|
||||
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal());
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace Test.MyTest
|
||||
|
||||
class A {
|
||||
class object {
|
||||
public fun testOther() {
|
||||
|
||||
}
|
||||
|
||||
public fun testOther(a: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
public fun testOther(a: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testMy() {
|
||||
A.test<caret>
|
||||
}
|
||||
|
||||
// EXIST: testOther
|
||||
// NUMBER: 3
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Test.MyTest
|
||||
|
||||
fun test() {
|
||||
Test.<caret>
|
||||
}
|
||||
|
||||
// EXIST: MyTest
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Test.MyTest
|
||||
|
||||
class A {
|
||||
class object {
|
||||
public fun testOther(a: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
public fun testOther(a: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testMy() {
|
||||
A.testOther<caret>
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Test.MyTest
|
||||
|
||||
class A {
|
||||
class object {
|
||||
public fun testOther(a: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
public fun testOther(a: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testMy() {
|
||||
A.testOther()
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -59,6 +60,11 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
||||
|
||||
assertContainsItems(itemsShouldExist(getFile().getText()));
|
||||
assertNotContainItems(itemsShouldAbsent(getFile().getText()));
|
||||
|
||||
Integer itemsNumber = getExpectedNumber(getFile().getText());
|
||||
if (itemsNumber != null) {
|
||||
assertEquals(itemsNumber.intValue(), myItems.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,6 +91,16 @@ public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
||||
return findListWithPrefix("// ABSENT:", fileText);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Integer getExpectedNumber(String fileText) {
|
||||
final String[] numberStrings = findListWithPrefix("// NUMBER:", fileText);
|
||||
if (numberStrings.length > 0) {
|
||||
return Integer.parseInt(numberStrings[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] findListWithPrefix(String prefix, String fileText) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
|
||||
@@ -20,6 +20,14 @@ public class FunctionsHandlerTest extends LightCompletionTestCase {
|
||||
checkResultByFile("ParamsFunction.kt.after");
|
||||
}
|
||||
|
||||
public void testSingleBrackets() {
|
||||
configureByFile("SingleBrackets.kt");
|
||||
type('(');
|
||||
checkResultByFile("SingleBrackets.kt.after");
|
||||
}
|
||||
|
||||
// public void
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return new File(PluginTestCaseBase.getTestDataPathBase(), "/completion/handlers/").getPath() +
|
||||
|
||||
@@ -26,4 +26,9 @@ public @interface JetMethod {
|
||||
* @return is this type returnTypeNullable
|
||||
*/
|
||||
boolean nullableReturnType() default false;
|
||||
|
||||
/**
|
||||
* Return type type unless java type is correct Kotlin type.
|
||||
*/
|
||||
String returnType () default "";
|
||||
}
|
||||
|
||||
@@ -34,4 +34,9 @@ public @interface JetValueParameter {
|
||||
* @return if this parameter has default value
|
||||
*/
|
||||
boolean hasDefaultValue () default false;
|
||||
|
||||
/**
|
||||
* @return type unless Java type is correct Kotlin type.
|
||||
*/
|
||||
String type() default "";
|
||||
}
|
||||
|
||||
@@ -536,13 +536,20 @@ public abstract class TypeInfo<T> implements JetObject {
|
||||
}
|
||||
|
||||
public void parseVars(Signature signature) {
|
||||
while(cur < string.length && string[cur] == 'T') {
|
||||
if(signature.variables == null) {
|
||||
signature.variables = new LinkedList<TypeInfoProjection>();
|
||||
signature.varNames = new HashMap<String, Integer>();
|
||||
if (cur < string.length && string[cur] == '<') {
|
||||
cur++;
|
||||
while(cur < string.length && string[cur] != '>') {
|
||||
if(signature.variables == null) {
|
||||
signature.variables = new LinkedList<TypeInfoProjection>();
|
||||
signature.varNames = new HashMap<String, Integer>();
|
||||
}
|
||||
if (string[cur] != 'T') {
|
||||
throw new IllegalStateException(new String(string));
|
||||
}
|
||||
cur++;
|
||||
signature.variables.add(parseVar(signature));
|
||||
}
|
||||
cur++;
|
||||
signature.variables.add(parseVar(signature));
|
||||
}
|
||||
signature.variables = signature.variables == null ? Collections.<TypeInfoProjection>emptyList() : signature.variables;
|
||||
signature.varNames = signature.varNames == null ? Collections.<String,Integer>emptyMap() : signature.varNames;
|
||||
|
||||
Reference in New Issue
Block a user