提交 b86625a4 编写于 作者: S Stepan Koltsov

writing my signatures

上级 4f16b5da
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 writeSuperclass() {
checkTopLevel();
checkMode(Mode.CLASS);
public void writeSupersEnd() {
kotlinClassSignature = jetSignatureWriter.toString();
jetSignatureWriter = null;
transitionState(State.SUPERS, State.CLASS_END);
}
public void writeSuperclass() {
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 makeKotlinReturnTypeSignature() {
checkState(State.METHOD_END);
return kotlinReturnType;
}
@Nullable
public String makeKotlinString() {
// TODO: not implemented yet
return null;
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);
}
{ // type parameters
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
typeMapper.writeFormalTypeParameters(typeParameters, signatureVisitor);
}
signatureVisitor.writeSupersStart();
{ // superclass
signatureVisitor.writeSuperclass();
if (superClassType == null) {
signatureVisitor.writeClassBegin(superClass);
signatureVisitor.writeClassEnd();
} else {
typeMapper.mapType(superClassType, OwnerKind.IMPLEMENTATION, signatureVisitor, true);
}
signatureVisitor.writeSuperclassEnd();
{ // 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);
{ // 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());
}
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();
superInterfaces = new ArrayList<String>(superInterfacesLinkedHashSet);
}
return new JvmClassSignature(jvmName(), superClass, superInterfaces, genericSignature);
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) {
......
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;
}
}
......@@ -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 {
......
......@@ -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>() {
......
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";
......
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() {
}
}
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,
......
package org.jetbrains.jet.codegen.signature;
package org.jetbrains.jet.lang.resolve.java.signature;
import org.objectweb.asm.signature.SignatureVisitor;
......
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;
......
......@@ -158,7 +158,7 @@ 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());
}
......
......@@ -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 "";
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册