more class and method signatures, use writer wrapper
(not yet complete) own writer will be used to write both java and kotlin signatures
This commit is contained in:
@@ -0,0 +1,211 @@
|
|||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
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.Stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public class BothSignatureWriter {
|
||||||
|
|
||||||
|
private static final boolean DEBUG_SIGNATURE_WRITER = true;
|
||||||
|
|
||||||
|
enum Mode {
|
||||||
|
METHOD(CheckSignatureAdapter.METHOD_SIGNATURE),
|
||||||
|
CLASS(CheckSignatureAdapter.CLASS_SIGNATURE),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int asmType;
|
||||||
|
|
||||||
|
Mode(int asmType) {
|
||||||
|
this.asmType = asmType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SignatureWriter signatureWriter = new SignatureWriter();
|
||||||
|
private final SignatureVisitor signatureVisitor;
|
||||||
|
private final Mode mode;
|
||||||
|
|
||||||
|
public BothSignatureWriter(Mode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
if (DEBUG_SIGNATURE_WRITER) {
|
||||||
|
signatureVisitor = new CheckSignatureAdapter(mode.asmType, signatureWriter);
|
||||||
|
} else {
|
||||||
|
signatureVisitor = signatureWriter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ignore when debugging is disabled
|
||||||
|
private Stack<SignatureVisitor> visitors = new Stack<SignatureVisitor>();
|
||||||
|
|
||||||
|
private void push(SignatureVisitor visitor) {
|
||||||
|
visitors.push(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pop() {
|
||||||
|
visitors.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private SignatureVisitor signatureVisitor() {
|
||||||
|
return !visitors.isEmpty() ? visitors.peek() : signatureVisitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkTopLevel() {
|
||||||
|
if (DEBUG_SIGNATURE_WRITER) {
|
||||||
|
if (!visitors.isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkMode(Mode mode) {
|
||||||
|
if (DEBUG_SIGNATURE_WRITER) {
|
||||||
|
if (mode != this.mode) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut
|
||||||
|
*/
|
||||||
|
public void writeAsmType(Type asmType) {
|
||||||
|
switch (asmType.getSort()) {
|
||||||
|
case Type.OBJECT:
|
||||||
|
writeClassBegin(asmType.getInternalName());
|
||||||
|
writeClassEnd();
|
||||||
|
return;
|
||||||
|
case Type.ARRAY:
|
||||||
|
writeArrayType();
|
||||||
|
writeAsmType(asmType.getElementType());
|
||||||
|
writeArrayEnd();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
String descriptor = asmType.getDescriptor();
|
||||||
|
if (descriptor.length() != 1) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
signatureVisitor().visitBaseType(descriptor.charAt(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeClassBegin(String internalName) {
|
||||||
|
signatureVisitor().visitClassType(internalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeClassEnd() {
|
||||||
|
signatureVisitor().visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeArrayType() {
|
||||||
|
push(signatureVisitor().visitArrayType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeArrayEnd() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTypeArgument(char c) {
|
||||||
|
push(signatureVisitor().visitTypeArgument(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTypeArgumentEnd() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTypeVariable(final String name) {
|
||||||
|
signatureVisitor().visitTypeVariable(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeFormalTypeParameter(final String name) {
|
||||||
|
checkTopLevel();
|
||||||
|
|
||||||
|
signatureVisitor().visitFormalTypeParameter(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeClassBound() {
|
||||||
|
push(signatureVisitor().visitClassBound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeClassBoundEnd() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInterfaceBound() {
|
||||||
|
push(signatureVisitor().visitInterfaceBound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInterfaceBoundEnd() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeParameterType() {
|
||||||
|
push(signatureVisitor().visitParameterType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeParameterTypeEnd() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeReturnType() {
|
||||||
|
push(signatureVisitor().visitReturnType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeReturnTypeEnd() {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeSuperclass() {
|
||||||
|
checkTopLevel();
|
||||||
|
checkMode(Mode.CLASS);
|
||||||
|
|
||||||
|
push(signatureVisitor().visitSuperclass());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeSuperclassEnd() {
|
||||||
|
pop();
|
||||||
|
if (!visitors.isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInterface() {
|
||||||
|
checkTopLevel();
|
||||||
|
checkMode(Mode.CLASS);
|
||||||
|
|
||||||
|
push(signatureVisitor().visitInterface());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInterfaceEnd() {
|
||||||
|
pop();
|
||||||
|
if (!visitors.isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String makeJavaString() {
|
||||||
|
if (!visitors.isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return signatureWriter.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String makeKotlinString() {
|
||||||
|
// TODO: not implemented yet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ 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.OverridingUtil;
|
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||||
|
import org.jetbrains.jet.lang.resolve.StdlibNames;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
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;
|
||||||
@@ -16,9 +17,6 @@ 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.*;
|
||||||
|
|
||||||
@@ -29,7 +27,9 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||||
private JetDelegationSpecifier superCall;
|
private JetDelegationSpecifier superCall;
|
||||||
private String superClass = "java/lang/Object";
|
private String superClass;
|
||||||
|
@Nullable // null means java/lang/Object
|
||||||
|
private JetType superClassType;
|
||||||
private final JetTypeMapper typeMapper;
|
private final JetTypeMapper typeMapper;
|
||||||
private final BindingContext bindingContext;
|
private final BindingContext bindingContext;
|
||||||
|
|
||||||
@@ -39,28 +39,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
bindingContext = state.getBindingContext();
|
bindingContext = state.getBindingContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> getSuperInterfaces(JetClassOrObject aClass) {
|
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
|
|
||||||
Set<String> superInterfaces = new LinkedHashSet<String>();
|
|
||||||
|
|
||||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
|
||||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
|
||||||
assert superType != null;
|
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
|
||||||
if(CodegenUtil.isInterface(superClassDescriptor)) {
|
|
||||||
superInterfaces.add(typeMapper.getFQName(superClassDescriptor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return superInterfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateDeclaration() {
|
protected void generateDeclaration() {
|
||||||
getSuperClass();
|
getSuperClass();
|
||||||
|
|
||||||
List<String> interfaces = new ArrayList<String>();
|
JvmClassSignature signature = signature();
|
||||||
interfaces.add(JetTypeMapper.TYPE_JET_OBJECT.getInternalName());
|
|
||||||
interfaces.addAll(getSuperInterfaces(myClass));
|
|
||||||
|
|
||||||
boolean isAbstract = false;
|
boolean isAbstract = false;
|
||||||
boolean isInterface = false;
|
boolean isInterface = false;
|
||||||
@@ -77,10 +60,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface
|
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface
|
||||||
? Opcodes.ACC_INTERFACE
|
? Opcodes.ACC_INTERFACE
|
||||||
: 0/*Opcodes.ACC_SUPER*/),
|
: 0/*Opcodes.ACC_SUPER*/),
|
||||||
jvmName(),
|
signature.getName(),
|
||||||
genericSignature(),
|
signature.getGenericSignature(),
|
||||||
superClass,
|
signature.getSuperclassName(),
|
||||||
interfaces.toArray(new String[interfaces.size()])
|
signature.getInterfaces().toArray(new String[0])
|
||||||
);
|
);
|
||||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||||
|
|
||||||
@@ -95,29 +78,56 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private JvmClassSignature signature() {
|
||||||
private String genericSignature() {
|
String genericSignature;
|
||||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
List<String> superInterfaces;
|
||||||
|
|
||||||
SignatureWriter signatureWriter = new SignatureWriter();
|
{
|
||||||
SignatureVisitor signatureVisitor = JetTypeMapper.DEBUG_SIGNATURE_WRITER
|
LinkedHashSet<String> superInterfacesLinkedHashSet = new LinkedHashSet<String>();
|
||||||
? new CheckSignatureAdapter(CheckSignatureAdapter.CLASS_SIGNATURE, signatureWriter)
|
|
||||||
: signatureWriter;
|
BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
|
||||||
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
|
||||||
signatureVisitor.visitFormalTypeParameter(typeParameter.getName());
|
|
||||||
SignatureVisitor classBoundVisitor = signatureVisitor.visitClassBound();
|
{ // type parameters
|
||||||
// TODO: wrong
|
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
||||||
JetTypeMapper.visitAsmType(classBoundVisitor, JetTypeMapper.TYPE_OBJECT);
|
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();
|
||||||
}
|
}
|
||||||
SignatureVisitor superclassSignatureVisitor = signatureVisitor.visitSuperclass();
|
return new JvmClassSignature(jvmName(), superClass, superInterfaces, genericSignature);
|
||||||
// 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() {
|
||||||
@@ -125,6 +135,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void getSuperClass() {
|
protected void getSuperClass() {
|
||||||
|
superClass = "java/lang/Object";
|
||||||
|
superClassType = null;
|
||||||
|
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
||||||
|
|
||||||
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
||||||
@@ -136,6 +149,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
assert superType != null;
|
assert superType != null;
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
if(!CodegenUtil.isInterface(superClassDescriptor)) {
|
if(!CodegenUtil.isInterface(superClassDescriptor)) {
|
||||||
|
superClassType = superType;
|
||||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
||||||
superCall = specifier;
|
superCall = specifier;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ import org.jetbrains.jet.lexer.JetTokens;
|
|||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
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.*;
|
||||||
|
|
||||||
@@ -165,10 +162,10 @@ public class JetTypeMapper {
|
|||||||
return mapReturnType(jetType, null);
|
return mapReturnType(jetType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapReturnType(final JetType jetType, @Nullable SignatureVisitor signatureVisitor) {
|
@NotNull private Type mapReturnType(final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||||
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
|
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
signatureVisitor.visitBaseType('V');
|
signatureVisitor.writeAsmType(Type.VOID_TYPE);
|
||||||
}
|
}
|
||||||
return Type.VOID_TYPE;
|
return Type.VOID_TYPE;
|
||||||
}
|
}
|
||||||
@@ -226,10 +223,10 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapType(final JetType jetType) {
|
@NotNull public Type mapType(final JetType jetType) {
|
||||||
return mapType(jetType, (SignatureVisitor) null);
|
return mapType(jetType, (BothSignatureWriter) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapType(JetType jetType, @Nullable SignatureVisitor signatureVisitor) {
|
@NotNull private Type mapType(JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||||
return mapType(jetType, OwnerKind.IMPLEMENTATION, signatureVisitor);
|
return mapType(jetType, OwnerKind.IMPLEMENTATION, signatureVisitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,11 +234,11 @@ public class JetTypeMapper {
|
|||||||
return mapType(jetType, kind, null);
|
return mapType(jetType, kind, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable SignatureVisitor signatureVisitor) {
|
@NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable BothSignatureWriter signatureVisitor) {
|
||||||
return mapType(jetType, kind, signatureVisitor, false);
|
return mapType(jetType, kind, signatureVisitor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable SignatureVisitor signatureVisitor, boolean boxPrimitive) {
|
@NotNull public Type mapType(JetType jetType, OwnerKind kind, @Nullable BothSignatureWriter signatureVisitor, boolean boxPrimitive) {
|
||||||
Type known = knowTypes.get(jetType);
|
Type known = knowTypes.get(jetType);
|
||||||
if (known != null) {
|
if (known != null) {
|
||||||
return mapKnownAsmType(jetType, known, signatureVisitor, boxPrimitive);
|
return mapKnownAsmType(jetType, known, signatureVisitor, boxPrimitive);
|
||||||
@@ -260,8 +257,9 @@ public class JetTypeMapper {
|
|||||||
JetType memberType = jetType.getArguments().get(0).getType();
|
JetType memberType = jetType.getArguments().get(0).getType();
|
||||||
|
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
SignatureVisitor arraySignatureVisitor = signatureVisitor.visitArrayType();
|
signatureVisitor.writeArrayType();
|
||||||
mapType(memberType, kind, arraySignatureVisitor, true);
|
mapType(memberType, kind, signatureVisitor, true);
|
||||||
|
signatureVisitor.writeArrayEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isGenericsArray(jetType)) {
|
if (!isGenericsArray(jetType)) {
|
||||||
@@ -284,13 +282,14 @@ public class JetTypeMapper {
|
|||||||
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
|
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
|
||||||
|
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
signatureVisitor.visitClassType(asmType.getInternalName());
|
signatureVisitor.writeClassBegin(asmType.getInternalName());
|
||||||
for (TypeProjection proj : jetType.getArguments()) {
|
for (TypeProjection proj : jetType.getArguments()) {
|
||||||
// TODO: +-
|
// TODO: +-
|
||||||
SignatureVisitor argumentSignatureVisitor = signatureVisitor.visitTypeArgument('=');
|
signatureVisitor.writeTypeArgument('=');
|
||||||
mapType(proj.getType(), kind, argumentSignatureVisitor, true);
|
mapType(proj.getType(), kind, signatureVisitor, true);
|
||||||
|
signatureVisitor.writeTypeArgumentEnd();
|
||||||
}
|
}
|
||||||
signatureVisitor.visitEnd();
|
signatureVisitor.writeClassEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
return asmType;
|
return asmType;
|
||||||
@@ -299,7 +298,7 @@ public class JetTypeMapper {
|
|||||||
if (descriptor instanceof TypeParameterDescriptor) {
|
if (descriptor instanceof TypeParameterDescriptor) {
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
||||||
signatureVisitor.visitTypeVariable(typeParameterDescriptor.getName());
|
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
return mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
||||||
@@ -308,7 +307,7 @@ public class JetTypeMapper {
|
|||||||
throw new UnsupportedOperationException("Unknown type " + jetType);
|
throw new UnsupportedOperationException("Unknown type " + jetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable SignatureVisitor signatureVisitor, boolean genericTypeParameter) {
|
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean genericTypeParameter) {
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
if (genericTypeParameter) {
|
if (genericTypeParameter) {
|
||||||
visitAsmType(signatureVisitor, boxType(asmType));
|
visitAsmType(signatureVisitor, boxType(asmType));
|
||||||
@@ -319,23 +318,8 @@ public class JetTypeMapper {
|
|||||||
return asmType;
|
return asmType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void visitAsmType(SignatureVisitor visitor, Type asmType) {
|
public static void visitAsmType(BothSignatureWriter visitor, Type asmType) {
|
||||||
switch (asmType.getSort()) {
|
visitor.writeAsmType(asmType);
|
||||||
case Type.OBJECT:
|
|
||||||
visitor.visitClassType(asmType.getInternalName());
|
|
||||||
visitor.visitEnd();
|
|
||||||
return;
|
|
||||||
case Type.ARRAY:
|
|
||||||
SignatureVisitor elementSignatureVisitor = visitor.visitArrayType();
|
|
||||||
visitAsmType(elementSignatureVisitor, asmType.getElementType());
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
String descriptor = asmType.getDescriptor();
|
|
||||||
if (descriptor.length() != 1) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
visitor.visitBaseType(descriptor.charAt(0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type unboxType(final Type type) {
|
public static Type unboxType(final Type type) {
|
||||||
@@ -391,8 +375,6 @@ public class JetTypeMapper {
|
|||||||
return asmType;
|
return asmType;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
return null;
|
return null;
|
||||||
@@ -456,22 +438,12 @@ public class JetTypeMapper {
|
|||||||
needGenericSignature = false;
|
needGenericSignature = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SignatureWriter signatureWriter = null;
|
BothSignatureWriter signatureVisitor = null;
|
||||||
SignatureVisitor signatureVisitor = null;
|
|
||||||
if (needGenericSignature) {
|
if (needGenericSignature) {
|
||||||
signatureWriter = new SignatureWriter();
|
signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
|
||||||
signatureVisitor = DEBUG_SIGNATURE_WRITER ? new CheckSignatureAdapter(CheckSignatureAdapter.METHOD_SIGNATURE, signatureWriter) : signatureWriter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : f.getTypeParameters()) {
|
writeFormalTypeParameters(f.getTypeParameters(), signatureVisitor);
|
||||||
if (signatureVisitor != null) {
|
|
||||||
signatureVisitor.visitFormalTypeParameter(typeParameterDescriptor.getName());
|
|
||||||
SignatureVisitor classBoundVisitor = signatureVisitor.visitClassBound();
|
|
||||||
// TODO: wrong base
|
|
||||||
visitAsmType(classBoundVisitor, TYPE_OBJECT);
|
|
||||||
// TODO: interfaces
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter();
|
final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter();
|
||||||
final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType();
|
final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType();
|
||||||
@@ -489,24 +461,98 @@ public class JetTypeMapper {
|
|||||||
parameterTypes.add(type);
|
parameterTypes.add(type);
|
||||||
}
|
}
|
||||||
if (receiverType != null) {
|
if (receiverType != null) {
|
||||||
parameterTypes.add(mapType(receiverType, signatureVisitor != null ? signatureVisitor.visitParameterType() : null));
|
if (signatureVisitor != null) {
|
||||||
|
signatureVisitor.writeParameterType();
|
||||||
|
}
|
||||||
|
parameterTypes.add(mapType(receiverType, signatureVisitor));
|
||||||
|
if (signatureVisitor != null) {
|
||||||
|
signatureVisitor.writeParameterTypeEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
|
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
|
||||||
if(parameterDescriptor.isReified()) {
|
if(parameterDescriptor.isReified()) {
|
||||||
parameterTypes.add(TYPE_TYPEINFO);
|
parameterTypes.add(TYPE_TYPEINFO);
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
visitAsmType(signatureVisitor.visitParameterType(), TYPE_TYPEINFO);
|
signatureVisitor.writeParameterType();
|
||||||
|
visitAsmType(signatureVisitor, TYPE_TYPEINFO);
|
||||||
|
signatureVisitor.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ValueParameterDescriptor parameter : parameters) {
|
for (ValueParameterDescriptor parameter : parameters) {
|
||||||
Type type = mapType(parameter.getOutType(), signatureVisitor != null ? signatureVisitor.visitParameterType() : null);
|
if (signatureVisitor != null) {
|
||||||
|
signatureVisitor.writeParameterType();
|
||||||
|
}
|
||||||
|
Type type = mapType(parameter.getOutType(), signatureVisitor);
|
||||||
|
if (signatureVisitor != null) {
|
||||||
|
signatureVisitor.writeParameterTypeEnd();
|
||||||
|
}
|
||||||
valueParameterTypes.add(type);
|
valueParameterTypes.add(type);
|
||||||
parameterTypes.add(type);
|
parameterTypes.add(type);
|
||||||
}
|
}
|
||||||
Type returnType = f instanceof ConstructorDescriptor ? Type.VOID_TYPE : mapReturnType(f.getReturnType(), signatureVisitor != null ? signatureVisitor.visitReturnType() : null);
|
Type returnType;
|
||||||
|
if (f instanceof ConstructorDescriptor) {
|
||||||
|
returnType = Type.VOID_TYPE;
|
||||||
|
if (signatureVisitor != null) {
|
||||||
|
signatureVisitor.writeReturnType();
|
||||||
|
visitAsmType(signatureVisitor, Type.VOID_TYPE);
|
||||||
|
signatureVisitor.writeReturnTypeEnd();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (signatureVisitor != null) {
|
||||||
|
signatureVisitor.writeReturnType();
|
||||||
|
returnType = mapReturnType(f.getReturnType(), signatureVisitor);
|
||||||
|
signatureVisitor.writeReturnTypeEnd();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
returnType = mapReturnType(f.getReturnType(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
Method method = new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
Method method = new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||||
return new JvmMethodSignature(method, signatureWriter != null ? signatureWriter.toString() : null);
|
return new JvmMethodSignature(method, signatureVisitor != null ? signatureVisitor.makeJavaString() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void writeFormalTypeParameters(List<TypeParameterDescriptor> typeParameters, BothSignatureWriter signatureVisitor) {
|
||||||
|
if (signatureVisitor == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||||
|
writeFormalTypeParameter(typeParameterDescriptor, signatureVisitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) {
|
||||||
|
signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName());
|
||||||
|
|
||||||
|
classBound:
|
||||||
|
{
|
||||||
|
signatureVisitor.writeClassBound();
|
||||||
|
|
||||||
|
for (JetType jetType : typeParameterDescriptor.getUpperBounds()) {
|
||||||
|
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
|
||||||
|
if (!CodegenUtil.isInterface(jetType)) {
|
||||||
|
mapType(jetType, signatureVisitor);
|
||||||
|
break classBound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// "extends Object" seems to be not optional according to ClassFileFormat-Java5.pdf
|
||||||
|
}
|
||||||
|
signatureVisitor.writeClassBoundEnd();
|
||||||
|
|
||||||
|
for (JetType jetType : typeParameterDescriptor.getUpperBounds()) {
|
||||||
|
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
|
||||||
|
if (CodegenUtil.isInterface(jetType)) {
|
||||||
|
signatureVisitor.writeInterfaceBound();
|
||||||
|
mapType(jetType, signatureVisitor);
|
||||||
|
signatureVisitor.writeInterfaceBoundEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JvmMethodSignature mapSignature(String name, FunctionDescriptor f) {
|
public JvmMethodSignature mapSignature(String name, FunctionDescriptor f) {
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Stepan Koltsov
|
||||||
|
*/
|
||||||
|
public class JvmClassSignature {
|
||||||
|
private final String name;
|
||||||
|
private final String superclassName;
|
||||||
|
private final List<String> interfaces;
|
||||||
|
private final String genericSignature;
|
||||||
|
|
||||||
|
public JvmClassSignature(String name, String superclassName, List<String> interfaces, String genericSignature) {
|
||||||
|
this.name = name;
|
||||||
|
this.superclassName = superclassName;
|
||||||
|
this.interfaces = interfaces;
|
||||||
|
this.genericSignature = genericSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSuperclassName() {
|
||||||
|
return superclassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getInterfaces() {
|
||||||
|
return interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGenericSignature() {
|
||||||
|
return genericSignature;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ public class StdlibNames {
|
|||||||
public static final String JET_METHOD_NULLABLE_RETURN_TYPE_FIELD = "nullableReturnType";
|
public static final String JET_METHOD_NULLABLE_RETURN_TYPE_FIELD = "nullableReturnType";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String JET_OBJECT_INTERNAL = "jet/JetObject";
|
||||||
public static final String JET_OBJECT_CLASS = "jet.JetObject";
|
public static final String JET_OBJECT_CLASS = "jet.JetObject";
|
||||||
public static final String JET_OBJECT_DESCRIPTOR = "Ljet/JetObject;";
|
public static final String JET_OBJECT_DESCRIPTOR = "Ljet/JetObject;";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class ExtendsAbstractListT {
|
||||||
|
{
|
||||||
|
Mine<String> mine = null;
|
||||||
|
java.util.List<String> list = mine;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
abstract class Mine<T>() : java.util.AbstractList<T>()
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
class PlainExtendsListString {
|
||||||
|
{
|
||||||
|
Mine mine = null;
|
||||||
|
java.util.List<String> list = mine;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
abstract class Mine : java.util.List<String>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
class ImplementsMapPP {
|
||||||
|
{
|
||||||
|
Mine<String, Integer> mine = null;
|
||||||
|
java.util.Map<Integer, String> map = mine;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
abstract class Mine<P1, P2> : java.util.Map<P2, P1>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
class Question {
|
||||||
|
// id2 is to prevent java type parameter type inference
|
||||||
|
static <T> T id2(T p) { return p; }
|
||||||
|
{
|
||||||
|
java.util.List<String> s = id2(namespace.id((jet.typeinfo.TypeInfo) null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import java.util.List
|
||||||
|
|
||||||
|
fun <P1 : List<String>> id(p: P1) = p
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
class Question {
|
||||||
|
// id2 is to prevent java type parameter type inference
|
||||||
|
static <T> T id2(T p) { return p; }
|
||||||
|
{
|
||||||
|
String s = id2(namespace.id((jet.typeinfo.TypeInfo) null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fun <T : String> id(p: T) = p
|
||||||
Reference in New Issue
Block a user