refactoring and cleanup

This commit is contained in:
Alex Tkachman
2011-11-05 16:48:35 +01:00
parent 11ef183597
commit 34b5fc3169
13 changed files with 377 additions and 562 deletions
@@ -1,7 +1,6 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@@ -12,14 +11,13 @@ import java.util.List;
/**
* @author yole
* @author alex.tkacman
*/
public class CallableMethod implements Callable {
private String owner;
private final Method signature;
private final int invokeOpcode;
private int invokeOpcode;
private final List<Type> valueParameterTypes;
private boolean acceptsTypeArguments = false;
private boolean ownerFromCall = false;
private DeclarationDescriptor thisClass = null;
private DeclarationDescriptor receiverClass = null;
private Type generateCalleeType = null;
@@ -35,10 +33,6 @@ public class CallableMethod implements Callable {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Method getSignature() {
return signature;
}
@@ -51,14 +45,6 @@ public class CallableMethod implements Callable {
return valueParameterTypes;
}
public boolean acceptsTypeArguments() {
return acceptsTypeArguments;
}
public void setAcceptsTypeArguments(boolean acceptsTypeArguments) {
this.acceptsTypeArguments = acceptsTypeArguments;
}
public void setNeedsReceiver(@Nullable DeclarationDescriptor receiverClass) {
this.receiverClass = receiverClass;
}
@@ -67,14 +53,6 @@ public class CallableMethod implements Callable {
this.thisClass = receiverClass;
}
public boolean isOwnerFromCall() {
return ownerFromCall;
}
public void setOwnerFromCall(boolean ownerFromCall) {
this.ownerFromCall = ownerFromCall;
}
void invoke(InstructionAdapter v) {
v.visitMethodInsn(getInvokeOpcode(), getOwner(), getSignature().getName(), getSignature().getDescriptor());
}
@@ -106,5 +84,4 @@ public class CallableMethod implements Callable {
public DeclarationDescriptor getThisClass() {
return thisClass;
}
}
@@ -21,8 +21,8 @@ public class ClassBuilder {
int access,
String name,
String desc,
String signature,
Object value) {
@Nullable String signature,
@Nullable Object value) {
return v.visitField(access, name, desc, signature, value);
}
@@ -49,11 +49,11 @@ public class ClassBuilder {
return v;
}
public void defineClass(int version, int access, String name, String signature, String superName, String[] interfaces) {
public void defineClass(int version, int access, String name, @Nullable String signature, String superName, String[] interfaces) {
v.visit(version, access, name, signature, superName, interfaces);
}
public void visitSource(String name, String debug) {
public void visitSource(String name, @Nullable String debug) {
v.visitSource(name, debug);
}
}
@@ -1,5 +1,6 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
@@ -61,7 +62,7 @@ public class ClassContext {
return new ClassContext(descriptor, OwnerKind.NAMESPACE, null, this, null);
}
public ClassContext intoClass(FunctionOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) {
public ClassContext intoClass(@Nullable FunctionOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) {
final StackValue thisValue;
thisValue = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
@@ -3,8 +3,10 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Type;
import java.util.List;
/**
* @author abreslav
@@ -62,4 +64,38 @@ public class CodegenUtil {
return hasOuterTypeInfo(outerClassDescriptor);
}
public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) {
if(!exceptOwn) {
if(!isInterface(type))
if(hasTypeInfoField(type))
return true;
}
for (JetType jetType : type.getConstructor().getSupertypes()) {
if(hasDerivedTypeInfoField(jetType, false))
return true;
}
return false;
}
public static boolean hasTypeInfoField(JetType type) {
List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
for (TypeParameterDescriptor parameter : parameters) {
if(parameter.isReified())
return true;
}
for (JetType jetType : type.getConstructor().getSupertypes()) {
if(hasTypeInfoField(jetType))
return true;
}
ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor());
if(outerClassDescriptor == null)
return false;
return hasTypeInfoField(outerClassDescriptor.getDefaultType());
}
}
@@ -760,9 +760,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
if (declaration instanceof PsiField) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
PsiField psiField = (PsiField) declaration;
final String owner = JetTypeMapper.jvmName(psiField.getContainingClass());
final Type fieldType = JetTypeMapper.psiTypeToAsm(psiField.getType());
final String owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
final Type fieldType = typeMapper.mapType(propertyDescriptor.getReturnType());
final boolean isStatic = psiField.hasModifierProperty(PsiModifier.STATIC);
if (!isStatic) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
@@ -825,6 +826,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration();
if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) {
// I hope it happens only in case of required super class for traits
assert propReceiverDescriptor != null;
v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType()));
}
}
@@ -895,9 +897,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else {
owner = typeMapper.getOwner(functionDescriptor, OwnerKind.IMPLEMENTATION);
if(containingDeclaration instanceof JavaClassDescriptor) {
PsiClass psiElement = (PsiClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration);
assert psiElement != null;
isInterface = psiElement.isInterface();
isInterface = CodegenUtil.isInterface(containingDeclaration);
}
else {
if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT)
@@ -970,7 +970,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private StackValue invokeFunction(JetCallExpression expression, DeclarationDescriptor fd, StackValue receiver) {
Callable callableMethod = resolveToCallable(fd);
boolean superCall = false;
if (expression.getParent() instanceof JetQualifiedExpression) {
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
if(receiverExpression instanceof JetSuperExpression) {
superCall = true;
}
}
Callable callableMethod = resolveToCallable(fd, superCall);
return invokeCallable(fd, callableMethod, expression, receiver);
}
@@ -1002,22 +1010,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.none();
}
private Callable resolveToCallable(DeclarationDescriptor fd) {
private Callable resolveToCallable(DeclarationDescriptor fd, boolean superCall) {
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(fd);
if (intrinsic != null) {
return intrinsic;
}
PsiElement declarationPsiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fd);
CallableMethod callableMethod;
if (declarationPsiElement instanceof PsiMethod || declarationPsiElement instanceof JetNamedFunction) {
callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement, null);
}
else if (fd instanceof VariableAsFunctionDescriptor) {
if (fd instanceof VariableAsFunctionDescriptor) {
assert !superCall;
callableMethod = asCallableMethod((FunctionDescriptor) fd);
}
else if (fd instanceof FunctionDescriptor) {
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, null);
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, superCall, OwnerKind.IMPLEMENTATION);
}
else {
throw new UnsupportedOperationException("can't resolve declaration to callable: " + fd);
@@ -1042,10 +1047,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (calleeType != null && expression instanceof JetCallExpression) {
gen(expression.getCalleeExpression(), calleeType);
}
if (callableMethod.isOwnerFromCall()) {
setOwnerFromCall(callableMethod, expression);
}
if (callableMethod.isNeedsThis()) {
if(callableMethod.isNeedsReceiver()) {
generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);
@@ -1053,7 +1055,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else {
if (receiver == StackValue.none()) {
generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);;
generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);
}
else {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
@@ -1071,28 +1073,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
if (callableMethod.acceptsTypeArguments()) {
pushTypeArguments(expression);
}
pushTypeArguments(expression);
if(mask == 0)
callableMethod.invoke(v);
else
callableMethod.invokeWithDefault(v, mask);
}
private void setOwnerFromCall(CallableMethod callableMethod, JetCallElement expression) {
if (expression.getParent() instanceof JetQualifiedExpression) {
final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiver);
assert expressionType != null;
DeclarationDescriptor declarationDescriptor = expressionType.getConstructor().getDeclarationDescriptor();
PsiElement ownerDeclaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declarationDescriptor);
if (ownerDeclaration instanceof PsiClass) {
callableMethod.setOwner(typeMapper.mapType(expressionType).getInternalName());
}
}
}
private static JetExpression getReceiverForSelector(PsiElement expression) {
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
@@ -1362,7 +1349,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
final Callable callable = resolveToCallable(op);
final Callable callable = resolveToCallable(op, false);
if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
return intrinsic.generate(this, v, expressionType(expression), expression,
@@ -1388,6 +1375,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else {
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert op != null;
leftValue.put(typeMapper.mapType(op.getValueParameters().get(0).getOutType()), v);
genToJVMStack(expression.getRight());
v.swap();
@@ -1647,7 +1635,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private StackValue generateAugmentedAssignment(JetBinaryExpression expression) {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
final Callable callable = resolveToCallable(op);
final Callable callable = resolveToCallable(op, false);
final JetExpression lhs = expression.getLeft();
// if(lhs instanceof JetArrayAccessExpression) {
@@ -1726,7 +1714,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
@Override
public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationSign());
final Callable callable = resolveToCallable(op);
final Callable callable = resolveToCallable(op, false);
if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
return intrinsic.generate(this, v, expressionType(expression), expression,
@@ -1831,11 +1819,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, constructorDescriptor);
Type type;
if (declaration instanceof PsiMethod) {
type = generateJavaConstructorCall(expression, (PsiMethod) declaration);
type = generateJavaConstructorCall(expression);
}
else if (constructorDescriptor instanceof ConstructorDescriptor) {
//noinspection ConstantConditions
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
assert expressionType != null;
type = typeMapper.mapType(expressionType, OwnerKind.IMPLEMENTATION);
if (type.getSort() == Type.ARRAY) {
generateNewArray(expression, expressionType);
@@ -1856,7 +1845,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else {
// this$0 need to be put on stack
v.dup();
v.load(0, JetTypeMapper.jetImplementationType(classDecl));
v.load(0, typeMapper.jetImplementationType(classDecl));
}
}
else {
@@ -1875,19 +1864,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private void pushTypeArguments(JetCallElement expression) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
JetExpression calleeExpression = expression.getCalleeExpression();
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression);
if(resolvedCall != null) {
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) {
JetType jetType = typeArguments.get(typeParameterDescriptor);
generateTypeInfo(jetType);
if(typeParameterDescriptor.isReified()) {
JetType jetType = typeArguments.get(typeParameterDescriptor);
generateTypeInfo(jetType);
}
}
}
else {
for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
pushTypeArgument(jetTypeArgument);
}
throw new UnsupportedOperationException();
// for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) {
// pushTypeArgument(jetTypeArgument);
// }
}
}
@@ -1896,12 +1889,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
generateTypeInfo(typeArgument);
}
private Type generateJavaConstructorCall(JetCallExpression expression, PsiMethod constructor) {
PsiClass javaClass = constructor.getContainingClass();
Type type = JetTypeMapper.psiClassType(javaClass);
private Type generateJavaConstructorCall(JetCallExpression expression) {
FunctionDescriptor descriptor = (FunctionDescriptor) resolveCalleeDescriptor(expression);
ClassDescriptor javaClass = (ClassDescriptor) descriptor.getContainingDeclaration();
Type type = typeMapper.mapType(javaClass.getDefaultType());
v.anew(type);
v.dup();
final CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(constructor);
final CallableMethod callableMethod = typeMapper.mapToCallableMethod(descriptor, false, OwnerKind.IMPLEMENTATION);
invokeMethodWithArguments(callableMethod, expression, StackValue.none());
return type;
}
@@ -1984,14 +1978,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
gen(array, arrayType);
final List<JetExpression> indices = expression.getIndexExpressions();
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
assert operationDescriptor != null;
if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && operationDescriptor.getValueParameters().get(0).getOutType().equals(state.getStandardLibrary().getIntType())) {
for (JetExpression index : indices) {
gen(index, Type.INT_TYPE);
}
assert type != null;
if(state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) {
JetType elementType = type.getArguments().get(0).getType();
Type notBoxed = typeMapper.mapType(elementType);
Type boxed = JetTypeMapper.boxType(notBoxed);
return StackValue.arrayElement(notBoxed, true);
}
else {
@@ -1999,28 +1994,30 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
else {
CallableMethod accessor = typeMapper.mapToCallableMethod(operationDescriptor, OwnerKind.IMPLEMENTATION);
CallableMethod accessor = typeMapper.mapToCallableMethod(operationDescriptor, false, OwnerKind.IMPLEMENTATION);
boolean isGetter = accessor.getSignature().getName().equals("get");
ResolvedCall<FunctionDescriptor> resolvedSetCall = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression);
FunctionDescriptor setterDescriptor = resolvedSetCall == null ? null : resolvedSetCall.getResultingDescriptor();
CallableMethod setter = resolvedSetCall == null ? null : typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION);
CallableMethod setter = resolvedSetCall == null ? null : typeMapper.mapToCallableMethod(setterDescriptor, false, OwnerKind.IMPLEMENTATION);
ResolvedCall<FunctionDescriptor> resolvedGetCall = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression);
FunctionDescriptor getterDescriptor = resolvedGetCall == null ? null : resolvedGetCall.getResultingDescriptor();
CallableMethod getter = resolvedGetCall == null ? null : typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION);
CallableMethod getter = resolvedGetCall == null ? null : typeMapper.mapToCallableMethod(getterDescriptor, false, OwnerKind.IMPLEMENTATION);
Type asmType;
Type[] argumentTypes = accessor.getSignature().getArgumentTypes();
int index = 0;
if(isGetter) {
assert getterDescriptor != null;
if(getterDescriptor.getReceiverParameter().exists()) {
index++;
}
asmType = accessor.getSignature().getReturnType();
}
else {
assert setterDescriptor != null;
if(setterDescriptor.getReceiverParameter().exists()) {
index++;
}
@@ -2035,46 +2032,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
public void _derefArray(JetType type) {
if (state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) {
JetType elementType = type.getArguments().get(0).getType();
JetStandardLibrary standardLibrary = state.getStandardLibrary();
if (elementType.equals(standardLibrary.getIntType())) {
v.getfield("jet/arrays/JetIntArray", "array", "[I");
}
else if (elementType.equals(standardLibrary.getLongType())) {
v.getfield("jet/arrays/JetLongArray", "array", "[J");
}
else if (elementType.equals(standardLibrary.getShortType())) {
v.getfield("jet/arrays/JetShortArray", "array", "[S");
}
else if (elementType.equals(standardLibrary.getByteType())) {
v.getfield("jet/arrays/JetByteArray", "array", "[B");
}
else if (elementType.equals(standardLibrary.getCharType())) {
v.getfield("jet/arrays/JetCharArray", "array", "[C");
}
else if (elementType.equals(standardLibrary.getFloatType())) {
v.getfield("jet/arrays/JetFloatArray", "array", "[F");
}
else if (elementType.equals(standardLibrary.getDoubleType())) {
v.getfield("jet/arrays/JetDoubleArray", "array", "[D");
}
else if (elementType.equals(standardLibrary.getBooleanType())) {
v.getfield("jet/arrays/JetBooleanArray", "array", "[Z");
}
else {
if(typeMapper.isGenericsArray(type)) {
v.visitTypeInsn(Opcodes.CHECKCAST, "jet/arrays/JetArray");
}
else {
v.getfield("jet/arrays/JetGenericArray", "array", "[Ljava/lang/Object;");
v.visitTypeInsn(Opcodes.CHECKCAST, "[" + typeMapper.mapType(elementType).getDescriptor());
}
}
}
}
@Override
public StackValue visitThrowExpression(JetThrowExpression expression, StackValue receiver) {
gen(expression.getThrownExpression(), JetTypeMapper.TYPE_OBJECT);
@@ -2326,7 +2283,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return;
}
if(!typeMapper.hasTypeInfoField(jetType) && !(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetType.getConstructor().getDeclarationDescriptor()) instanceof PsiClass)) {
if(!CodegenUtil.hasTypeInfoField(jetType) && !(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetType.getConstructor().getDeclarationDescriptor()) instanceof PsiClass)) {
// TODO: we need some better checks here
v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
return;
@@ -2383,12 +2340,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
if (context.getContextClass() instanceof ClassDescriptor) {
ClassDescriptor descriptor = (ClassDescriptor) context.getContextClass();
assert containingDeclaration != null;
JetType defaultType = ((ClassDescriptor)containingDeclaration).getDefaultType();
Type ownerType = typeMapper.mapType(defaultType);
ownerType = JetTypeMapper.boxType(ownerType);
if (containingDeclaration == context.getContextClass()) {
if(!CodegenUtil.isInterface(descriptor)) {
if (typeMapper.hasTypeInfoField(defaultType)) {
if (CodegenUtil.hasTypeInfoField(defaultType)) {
v.load(0, JetTypeMapper.TYPE_OBJECT);
v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
}
@@ -33,8 +33,9 @@ public class FunctionCodegen {
}
public void gen(JetNamedFunction f) {
Method method = state.getTypeMapper().mapToCallableMethod(f, owner.getContextKind()).getSignature();
final FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f);
assert functionDescriptor != null;
Method method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature();
generateMethod(f, method, functionDescriptor);
}
@@ -105,9 +106,7 @@ public class FunctionCodegen {
iv.areturn(jvmSignature.getReturnType());
}
else {
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
for (ValueParameterDescriptor parameter : paramDescrs) {
Type sharedVarType = codegen.getSharedVarType(parameter);
Type localVarType = state.getTypeMapper().mapType(parameter.getOutType());
if (sharedVarType != null) {
@@ -253,6 +252,7 @@ public class FunctionCodegen {
iv.ifeq(loadArg);
JetParameter jetParameter = (JetParameter) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, parameterDescriptor);
assert jetParameter != null;
codegen.gen(jetParameter.getDefaultValue(), t);
endArg = new Label();
@@ -270,7 +270,8 @@ public class FunctionCodegen {
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
iv.load(var++, JetTypeMapper.TYPE_OBJECT);
if(typeParameterDescriptor.isReified())
iv.load(var++, JetTypeMapper.TYPE_OBJECT);
}
if(!isStatic) {
@@ -40,12 +40,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
PsiElement superPsi = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
if (superPsi instanceof PsiClass) {
PsiClass psiClass = (PsiClass) superPsi;
String fqn = psiClass.getQualifiedName();
assert fqn != null;
if (psiClass.isInterface()) {
superInterfaces.add(fqn.replace('.', '/'));
}
@@ -55,7 +57,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
while (psiClass != null) {
for (PsiClass ifs : psiClass.getInterfaces()) {
superInterfaces.add(ifs.getQualifiedName().replace('.', '/'));
String qualifiedName = ifs.getQualifiedName();
assert qualifiedName != null;
superInterfaces.add(qualifiedName.replace('.', '/'));
}
psiClass = psiClass.getSuperClass();
}
@@ -67,7 +71,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
else {
if(superPsi == null || ((JetClass)superPsi).isTrait())
superInterfaces.add(JetTypeMapper.jvmNameForInterface(superClassDescriptor));
superInterfaces.add(state.getTypeMapper().jvmNameForImplementation(superClassDescriptor, OwnerKind.IMPLEMENTATION));
}
}
return superInterfaces;
@@ -127,6 +131,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) {
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
if (declaration != null) {
@@ -161,12 +166,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
generateGetTypeInfo();
//genGetSuperTypesTypeInfo();
}
private void generateFieldForObjectInstance() {
if (isNonLiteralObject()) {
Type type = JetTypeMapper.jetImplementationType(descriptor);
Type type = state.getTypeMapper().jetImplementationType(descriptor);
v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null);
staticInitializerChunks.add(new CodeChunk() {
@@ -176,7 +180,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.anew(Type.getObjectType(name));
v.dup();
v.invokespecial(name, "<init>", "()V");
v.putstatic(name, "$instance", JetTypeMapper.jetImplementationType(descriptor).getDescriptor());
v.putstatic(name, "$instance", state.getTypeMapper().jetImplementationType(descriptor).getDescriptor());
}
});
@@ -272,7 +276,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
for (JetDeclaration declaration : myClass.getDeclarations()) {
if (declaration instanceof JetFunction) {
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, declaration).getOverriddenDescriptors());
FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, declaration);
assert functionDescriptor != null;
overridden.addAll(functionDescriptor.getOverriddenDescriptors());
}
}
@@ -284,6 +290,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
else {
JetType superType = state.getBindingContext().get(BindingContext.TYPE, superCall.getTypeReference());
List<Type> parameterTypes = new ArrayList<Type>();
assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
if (CodegenUtil.hasThis0(superClassDescriptor)) {
iv.load(1, JetTypeMapper.TYPE_OBJECT);
@@ -313,9 +320,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
String delegateField = "$delegate_" + n;
Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor);
Type fieldType = state.getTypeMapper().jetImplementationType(superClassDescriptor);
String fieldDesc = fieldType.getDescriptor();
v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
iv.putfield(classname, delegateField, fieldDesc);
@@ -323,14 +331,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
JetClass superClass = (JetClass) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
final ClassContext delegateContext = context.intoClass(null, superClassDescriptor,
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
state.getTypeMapper().jvmNameForImplementation(superClassDescriptor, OwnerKind.IMPLEMENTATION)));
generateDelegates(superClass, delegateContext, overridden);
}
}
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) {
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
final Type type = state.getTypeMapper().jetImplementationType(outerDescriptor);
String interfaceDesc = type.getDescriptor();
final String fieldName = "this$0";
v.newField(myClass, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
@@ -339,7 +347,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.putfield(classname, fieldName, interfaceDesc);
}
if (state.getTypeMapper().hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
if (CodegenUtil.hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) {
generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv);
}
@@ -450,14 +458,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorDescriptor constructorDescriptor,
ConstructorFrameMap frameMap) {
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDecl);
Type type;
if (declaration instanceof PsiClass) {
type = JetTypeMapper.psiClassType((PsiClass) declaration);
}
else {
type = JetTypeMapper.jetImplementationType(classDecl);
}
type = state.getTypeMapper().jetImplementationType(classDecl);
iv.load(0, type);
@@ -671,7 +673,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (declaration instanceof JetProperty) {
propertyCodegen.gen((JetProperty) declaration);
}
else if (declaration instanceof JetFunction) {
else if (declaration instanceof JetNamedFunction) {
if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, declaration))) {
functionCodegen.gen((JetNamedFunction) declaration);
}
@@ -706,8 +708,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
return;
JetType defaultType = descriptor.getDefaultType();
if(state.getTypeMapper().hasTypeInfoField(defaultType)) {
if(!state.getTypeMapper().hasDerivedTypeInfoField(defaultType, true)) {
if(CodegenUtil.hasTypeInfoField(defaultType)) {
if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) {
v.newField(myClass, Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null);
MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null);
@@ -773,51 +775,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateClassObject(JetClassObject declaration) {
state.forClass().generate(context, declaration.getObjectDeclaration());
}
private void genGetSuperTypesTypeInfo() {
if(!(myClass instanceof JetClass) || ((JetClass)myClass).isTrait()) {
return;
}
String sig = getGetSuperTypesTypeInfoSignature(descriptor.getDefaultType());
final MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
"$$getSuperTypesTypeInfo",
sig,
null /* TODO */,
null);
mv.visitCode();
InstructionAdapter v = new InstructionAdapter(mv);
ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state);
v.load(0, JetTypeMapper.TYPE_OBJECT);
int k = 1;
for (TypeParameterDescriptor parameterDescriptor : descriptor.getTypeConstructor().getParameters()) {
codegen.addTypeParameter(parameterDescriptor, StackValue.local(k++, JetTypeMapper.TYPE_TYPEINFO));
}
for(JetType superType : descriptor.getTypeConstructor().getSupertypes()) {
for (TypeProjection typeProjection : superType.getArguments()) {
codegen.generateTypeInfo(typeProjection.getType());
}
v.invokestatic(state.getTypeMapper().mapType(superType).getInternalName(), "$$getSuperTypesTypeInfo", getGetSuperTypesTypeInfoSignature(superType));
}
v.areturn(Type.VOID_TYPE);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private static String getGetSuperTypesTypeInfoSignature(JetType type) {
List<TypeParameterDescriptor> typeParameters = type.getConstructor().getParameters();
StringBuilder sb = new StringBuilder("(Ljava/util/Set;");
for(TypeParameterDescriptor tp : typeParameters)
sb.append("Ljet/typeinfo/TypeInfo;");
sb.append(")V");
return sb.toString();
}
}
@@ -15,7 +15,6 @@ import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.*;
@@ -57,7 +56,9 @@ public class JetTypeMapper {
private final Map<JetExpression, String> classNamesForAnonymousClasses = new HashMap<JetExpression, String>();
private final Map<String, Integer> anonymousSubclassesCount = new HashMap<String, Integer>();
private final HashMap<JetType,String> knowTypes = new HashMap<JetType, String>();
private final HashMap<JetType,String> knowTypeNames = new HashMap<JetType, String>();
private final HashMap<JetType,Type> knowTypes = new HashMap<JetType, Type>();
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
@@ -75,14 +76,7 @@ public class JetTypeMapper {
this.standardLibrary = standardLibrary;
this.bindingContext = bindingContext;
initKnownTypes();
}
static String jvmName(PsiClass psiClass) {
final String qName = psiClass.getQualifiedName();
if (qName == null) {
throw new UnsupportedOperationException("can't evaluate JVM name for anonymous class " + psiClass);
}
return qName.replace(".", "/");
initKnownTypeNames();
}
public static boolean isIntPrimitive(Type type) {
@@ -102,68 +96,6 @@ public class JetTypeMapper {
|| type == Type.VOID_TYPE;
}
static Type psiTypeToAsm(PsiType type) {
if(type instanceof PsiArrayType) {
PsiArrayType psiArrayType = (PsiArrayType) type;
return Type.getType("[" + psiTypeToAsm(psiArrayType.getComponentType()).getDescriptor());
}
if (type instanceof PsiPrimitiveType) {
if (type == PsiType.VOID) {
return Type.VOID_TYPE;
}
if (type == PsiType.INT) {
return Type.INT_TYPE;
}
if (type == PsiType.LONG) {
return Type.LONG_TYPE;
}
if (type == PsiType.BOOLEAN) {
return Type.BOOLEAN_TYPE;
}
if (type == PsiType.BYTE) {
return Type.BYTE_TYPE;
}
if (type == PsiType.SHORT) {
return Type.SHORT_TYPE;
}
if (type == PsiType.CHAR) {
return Type.CHAR_TYPE;
}
if (type == PsiType.FLOAT) {
return Type.FLOAT_TYPE;
}
if (type == PsiType.DOUBLE) {
return Type.DOUBLE_TYPE;
}
}
if (type instanceof PsiClassType) {
PsiClass psiClass = ((PsiClassType) type).resolve();
if (psiClass instanceof PsiTypeParameter) {
final PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
if (extendsListTypes.length > 0) {
throw new UnsupportedOperationException("should return common supertype");
}
return TYPE_OBJECT;
}
if (psiClass == null) {
throw new UnsupportedOperationException("unresolved PsiClassType: " + type);
}
return psiClassType(psiClass);
}
throw new UnsupportedOperationException("don't know how to map type " + type + " to ASM");
}
static Method getMethodDescriptor(PsiMethod method) {
Type returnType = method.isConstructor() ? Type.VOID_TYPE : psiTypeToAsm(method.getReturnType());
PsiParameter[] parameters = method.getParameterList().getParameters();
Type[] parameterTypes = new Type[parameters.length];
for (int i = 0; i < parameters.length; i++) {
parameterTypes[i] = psiTypeToAsm(parameters[i].getType());
}
return new Method(method.isConstructor() ? "<init>" : method.getName(), Type.getMethodDescriptor(returnType, parameterTypes));
}
public static Type getBoxedType(final Type type) {
switch (type.getSort()) {
case Type.BYTE:
@@ -186,44 +118,8 @@ public class JetTypeMapper {
return type;
}
public boolean hasTypeInfoField(JetType type) {
if(type.getConstructor().getParameters().size() > 0) {
if(!(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, type.getConstructor().getDeclarationDescriptor()) instanceof PsiClass))
return true;
}
for (JetType jetType : type.getConstructor().getSupertypes()) {
if(hasTypeInfoField(jetType))
return true;
}
ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor());
if(outerClassDescriptor == null)
return false;
return hasTypeInfoField(outerClassDescriptor.getDefaultType());
}
public boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) {
if(!exceptOwn) {
if(!CodegenUtil.isInterface(type))
if(hasTypeInfoField(type))
return true;
}
for (JetType jetType : type.getConstructor().getSupertypes()) {
if(hasDerivedTypeInfoField(jetType, false))
return true;
}
return false;
}
public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetClass);
if (declaration instanceof PsiClass) {
return jvmName((PsiClass) declaration);
}
if (declaration instanceof JetObjectDeclaration && ((JetObjectDeclaration) declaration).isObjectLiteral()) {
final PsiElement parent = declaration.getParent();
if (parent instanceof JetClassObject) {
@@ -245,15 +141,15 @@ public class JetTypeMapper {
return jvmName(descriptor, OwnerKind.IMPLEMENTATION);
}
private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
private String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
if (jetClass.getKind() == ClassKind.OBJECT) {
return jvmNameForImplementation(jetClass);
return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION);
}
else if (kind == OwnerKind.IMPLEMENTATION) {
return jvmNameForImplementation(jetClass);
return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION);
}
else if (kind == OwnerKind.TRAIT_IMPL) {
return jvmNameForTraitImpl(jetClass);
return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION) + "$$TImpl";
}
else {
assert false : "Unsuitable kind";
@@ -268,16 +164,8 @@ public class JetTypeMapper {
return Type.getType("L" + jvmName(jetClass, kind) + ";");
}
static Type psiClassType(PsiClass psiClass) {
return Type.getType("L" + jvmName(psiClass) + ";");
}
static Type jetInterfaceType(ClassDescriptor classDescriptor) {
return Type.getType("L" + jvmNameForInterface(classDescriptor) + ";");
}
static Type jetImplementationType(ClassDescriptor classDescriptor) {
return Type.getType("L" + jvmNameForImplementation(classDescriptor) + ";");
Type jetImplementationType(ClassDescriptor classDescriptor) {
return Type.getType("L" + jvmNameForImplementation(classDescriptor, OwnerKind.IMPLEMENTATION) + ";");
}
public static String jvmName(JetNamespace namespace) {
@@ -288,30 +176,22 @@ public class JetTypeMapper {
return NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(namespace));
}
public static String jvmNameForInterface(ClassDescriptor descriptor) {
return DescriptorRenderer.getFQName(descriptor).replace('.', '/');
}
public static String jvmNameForImplementation(ClassDescriptor descriptor) {
return jvmNameForInterface(descriptor);
}
private static String jvmNameForTraitImpl(ClassDescriptor descriptor) {
return jvmNameForInterface(descriptor) + "$$TImpl";
public String jvmNameForImplementation(ClassDescriptor descriptor, OwnerKind kind) {
return mapType(descriptor.getDefaultType(), kind).getInternalName();
}
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
String owner;
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptorImpl) {
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof NamespaceDescriptor) {
owner = jvmName((NamespaceDescriptor) containingDeclaration);
}
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
else if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
if (kind instanceof OwnerKind.DelegateKind) {
kind = OwnerKind.IMPLEMENTATION;
}
else {
assert classDescriptor != null;
if (classDescriptor.getKind() == ClassKind.OBJECT) {
kind = OwnerKind.IMPLEMENTATION;
}
@@ -319,23 +199,19 @@ public class JetTypeMapper {
owner = jvmName(classDescriptor, kind);
}
else {
throw new UnsupportedOperationException("don't know how to generate owner for parent " + descriptor.getContainingDeclaration());
throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration);
}
return owner;
}
@NotNull public Type mapReturnType(@NotNull final JetType jetType, OwnerKind kind) {
@NotNull public Type mapReturnType(final JetType jetType) {
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
return Type.VOID_TYPE;
}
if (jetType.equals(JetStandardClasses.getNullableNothingType())) {
return TYPE_OBJECT;
}
return mapType(jetType, kind);
}
@NotNull public Type mapReturnType(final JetType jetType) {
return mapReturnType(jetType, OwnerKind.IMPLEMENTATION);
return mapType(jetType, OwnerKind.IMPLEMENTATION);
}
@NotNull public Type mapType(final JetType jetType) {
@@ -343,85 +219,9 @@ public class JetTypeMapper {
}
@NotNull public Type mapType(@NotNull final JetType jetType, OwnerKind kind) {
if (jetType.equals(JetStandardClasses.getNothingType()) || jetType.equals(JetStandardClasses.getNullableNothingType())) {
return TYPE_NOTHING;
}
if (jetType.equals(standardLibrary.getIntType())) {
return Type.INT_TYPE;
}
if (jetType.equals(standardLibrary.getNullableIntType())) {
return JL_INTEGER_TYPE;
}
if (jetType.equals(standardLibrary.getLongType())) {
return Type.LONG_TYPE;
}
if (jetType.equals(standardLibrary.getNullableLongType())) {
return JL_LONG_TYPE;
}
if (jetType.equals(standardLibrary.getShortType())) {
return Type.SHORT_TYPE;
}
if (jetType.equals(standardLibrary.getNullableShortType())) {
return JL_SHORT_TYPE;
}
if (jetType.equals(standardLibrary.getByteType())) {
return Type.BYTE_TYPE;
}
if (jetType.equals(standardLibrary.getNullableByteType())) {
return JL_BYTE_TYPE;
}
if (jetType.equals(standardLibrary.getCharType())) {
return Type.CHAR_TYPE;
}
if (jetType.equals(standardLibrary.getNullableCharType())) {
return JL_CHAR_TYPE;
}
if (jetType.equals(standardLibrary.getFloatType())) {
return Type.FLOAT_TYPE;
}
if (jetType.equals(standardLibrary.getNullableFloatType())) {
return JL_FLOAT_TYPE;
}
if (jetType.equals(standardLibrary.getDoubleType())) {
return Type.DOUBLE_TYPE;
}
if (jetType.equals(standardLibrary.getNullableDoubleType())) {
return JL_DOUBLE_TYPE;
}
if (jetType.equals(standardLibrary.getBooleanType())) {
return Type.BOOLEAN_TYPE;
}
if (jetType.equals(standardLibrary.getNullableBooleanType())) {
return JL_BOOLEAN_TYPE;
}
if(jetType.equals(standardLibrary.getByteArrayType())){
return ARRAY_BYTE_TYPE;
}
if(jetType.equals(standardLibrary.getShortArrayType())){
return ARRAY_SHORT_TYPE;
}
if(jetType.equals(standardLibrary.getIntArrayType())){
return ARRAY_INT_TYPE;
}
if(jetType.equals(standardLibrary.getLongArrayType())){
return ARRAY_LONG_TYPE;
}
if(jetType.equals(standardLibrary.getFloatArrayType())){
return ARRAY_FLOAT_TYPE;
}
if(jetType.equals(standardLibrary.getDoubleArrayType())){
return ARRAY_DOUBLE_TYPE;
}
if(jetType.equals(standardLibrary.getCharArrayType())){
return ARRAY_CHAR_TYPE;
}
if(jetType.equals(standardLibrary.getBooleanArrayType())){
return ARRAY_BOOL_TYPE;
}
if (jetType.equals(standardLibrary.getStringType()) || jetType.equals(standardLibrary.getNullableStringType())) {
return Type.getType(String.class);
}
Type known = knowTypes.get(jetType);
if(known != null)
return known;
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
if (standardLibrary.getArray().equals(descriptor)) {
@@ -439,7 +239,10 @@ public class JetTypeMapper {
}
if (descriptor instanceof ClassDescriptor) {
return Type.getObjectType(jvmName((ClassDescriptor) descriptor, kind));
String name = DescriptorRenderer.getFQName(descriptor).replace('.', '/');
if(name.startsWith("<java_root>"))
name = name.substring("<java_root>".length()+1);
return Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
}
if (descriptor instanceof TypeParameterDescriptor) {
@@ -503,6 +306,54 @@ public class JetTypeMapper {
}
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) {
if(functionDescriptor == null)
return null;
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List<Type> valueParameterTypes = new ArrayList<Type>();
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
String owner;
int invokeOpcode;
ClassDescriptor thisClass;
if (functionParent instanceof NamespaceDescriptor) {
assert !superCall;
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
invokeOpcode = Opcodes.INVOKESTATIC;
thisClass = null;
}
else if (functionDescriptor instanceof ConstructorDescriptor) {
assert !superCall;
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION);
invokeOpcode = Opcodes.INVOKESPECIAL;
thisClass = null;
}
else if (functionParent instanceof ClassDescriptor) {
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
boolean isInterface = CodegenUtil.isInterface(containingClass);
owner = jvmName(containingClass, isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION);
invokeOpcode = isInterface
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
if(isInterface && superCall) {
descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, OwnerKind.TRAIT_IMPL);
}
thisClass = containingClass;
}
else {
throw new UnsupportedOperationException("unknown function parent");
}
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes);
result.setNeedsThis(thisClass);
if(functionDescriptor.getReceiverParameter().exists()) {
result.setNeedsReceiver(functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor());
}
return result;
}
private Method mapSignature(FunctionDescriptor f, List<Type> valueParameterTypes, OwnerKind kind) {
final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter();
final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType();
@@ -527,95 +378,15 @@ public class JetTypeMapper {
valueParameterTypes.add(type);
parameterTypes.add(type);
}
for (int n = f.getTypeParameters().size(); n > 0; n--) {
parameterTypes.add(TYPE_TYPEINFO);
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
if(parameterDescriptor.isReified()) {
parameterTypes.add(TYPE_TYPEINFO);
}
}
Type returnType = mapReturnType(f.getReturnType());
Type returnType = f instanceof ConstructorDescriptor ? Type.VOID_TYPE : mapReturnType(f.getReturnType());
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
}
public CallableMethod mapToCallableMethod(PsiNamedElement declaration, OwnerKind kind) {
if (declaration instanceof PsiMethod) {
return mapToCallableMethod((PsiMethod) declaration);
}
if (!(declaration instanceof JetNamedFunction)) {
throw new UnsupportedOperationException("unknown declaration type " + declaration);
}
JetNamedFunction f = (JetNamedFunction) declaration;
final FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
assert functionDescriptor != null;
return mapToCallableMethod(functionDescriptor, kind);
}
static CallableMethod mapToCallableMethod(PsiMethod method) {
final PsiClass containingClass = method.getContainingClass();
String owner = jvmName(containingClass);
Method signature = getMethodDescriptor(method);
List<Type> valueParameterTypes = new ArrayList<Type>();
Collections.addAll(valueParameterTypes, signature.getArgumentTypes());
int opcode;
boolean ownerFromCall = false;
DeclarationDescriptor thisClass = null;
if (method.isConstructor()) {
opcode = Opcodes.INVOKESPECIAL;
}
else if (method.hasModifierProperty(PsiModifier.STATIC)) {
opcode = Opcodes.INVOKESTATIC;
}
else {
assert containingClass != null;
if (containingClass.isInterface()) {
opcode = Opcodes.INVOKEINTERFACE;
}
else {
opcode = Opcodes.INVOKEVIRTUAL;
}
ownerFromCall = true;
thisClass = JetStandardClasses.getAny(); // todo - this is hack, correct descriptor needed
}
final CallableMethod result = new CallableMethod(owner, signature, opcode, valueParameterTypes);
result.setNeedsThis(thisClass);
result.setOwnerFromCall(ownerFromCall);
return result;
}
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
if(functionDescriptor == null)
return null;
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List<Type> valueParameterTypes = new ArrayList<Type>();
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
String owner;
int invokeOpcode;
ClassDescriptor thisClass;
if (functionParent instanceof NamespaceDescriptor) {
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
invokeOpcode = Opcodes.INVOKESTATIC;
thisClass = null;
}
else if (functionParent instanceof ClassDescriptor) {
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION);
invokeOpcode = CodegenUtil.isInterface(containingClass)
? Opcodes.INVOKEINTERFACE
: Opcodes.INVOKEVIRTUAL;
thisClass = containingClass;
}
else {
throw new UnsupportedOperationException("unknown function parent");
}
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes);
result.setAcceptsTypeArguments(true);
result.setNeedsThis(thisClass);
if(functionDescriptor.getReceiverParameter().exists()) {
result.setNeedsReceiver(functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor());
}
return result;
}
public Method mapSignature(String name, FunctionDescriptor f) {
final ReceiverDescriptor receiver = f.getReceiverParameter();
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
@@ -666,6 +437,7 @@ public class JetTypeMapper {
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[0]);
else {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null;
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[] { mapType(containingDeclaration.getDefaultType()) });
}
}
@@ -681,6 +453,7 @@ public class JetTypeMapper {
}
else {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null;
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { mapType(containingDeclaration.getDefaultType()), paramType });
}
}
@@ -713,9 +486,7 @@ public class JetTypeMapper {
List<Type> valueParameterTypes = new ArrayList<Type>();
final Method method = mapConstructorSignature(descriptor, valueParameterTypes);
String owner = jvmName(descriptor.getContainingDeclaration(), kind);
final CallableMethod result = new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes);
result.setAcceptsTypeArguments(!(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getContainingDeclaration()) instanceof PsiClass));
return result;
return new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes);
}
static int getAccessModifiers(JetDeclaration p, int defaultFlags) {
@@ -746,7 +517,7 @@ public class JetTypeMapper {
}
else {
ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container);
baseName = jvmNameForInterface(aClass);
baseName = jvmNameForImplementation(aClass, OwnerKind.IMPLEMENTATION);
}
Integer count = anonymousSubclassesCount.get(baseName);
@@ -768,40 +539,90 @@ public class JetTypeMapper {
return result;
}
private void initKnownTypes() {
knowTypes.put(standardLibrary.getIntType(), "INT_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableIntType(), "NULLABLE_INT_TYPE_INFO");
knowTypes.put(standardLibrary.getLongType(), "LONG_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableLongType(), "NULLABLE_LONG_TYPE_INFO");
knowTypes.put(standardLibrary.getShortType(),"SHORT_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableShortType(),"NULLABLE_SHORT_TYPE_INFO");
knowTypes.put(standardLibrary.getByteType(),"BYTE_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableByteType(),"NULLABLE_BYTE_TYPE_INFO");
knowTypes.put(standardLibrary.getCharType(),"CHAR_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableCharType(),"NULLABLE_CHAR_TYPE_INFO");
knowTypes.put(standardLibrary.getFloatType(),"FLOAT_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableFloatType(),"NULLABLE_FLOAT_TYPE_INFO");
knowTypes.put(standardLibrary.getDoubleType(),"DOUBLE_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableDoubleType(),"NULLABLE_DOUBLE_TYPE_INFO");
knowTypes.put(standardLibrary.getBooleanType(),"BOOLEAN_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableBooleanType(),"NULLABLE_BOOLEAN_TYPE_INFO");
knowTypes.put(standardLibrary.getStringType(),"STRING_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableStringType(),"NULLABLE_STRING_TYPE_INFO");
knowTypes.put(standardLibrary.getTuple0Type(),"TUPLE0_TYPE_INFO");
knowTypes.put(standardLibrary.getNullableTuple0Type(),"NULLABLE_TUPLE0_TYPE_INFO");
private void initKnownTypeNames() {
knowTypeNames.put(standardLibrary.getIntType(), "INT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableIntType(), "NULLABLE_INT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getLongType(), "LONG_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableLongType(), "NULLABLE_LONG_TYPE_INFO");
knowTypeNames.put(standardLibrary.getShortType(),"SHORT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableShortType(),"NULLABLE_SHORT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getByteType(),"BYTE_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableByteType(),"NULLABLE_BYTE_TYPE_INFO");
knowTypeNames.put(standardLibrary.getCharType(),"CHAR_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableCharType(),"NULLABLE_CHAR_TYPE_INFO");
knowTypeNames.put(standardLibrary.getFloatType(),"FLOAT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableFloatType(),"NULLABLE_FLOAT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getDoubleType(),"DOUBLE_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableDoubleType(),"NULLABLE_DOUBLE_TYPE_INFO");
knowTypeNames.put(standardLibrary.getBooleanType(),"BOOLEAN_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableBooleanType(),"NULLABLE_BOOLEAN_TYPE_INFO");
knowTypeNames.put(standardLibrary.getStringType(),"STRING_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableStringType(),"NULLABLE_STRING_TYPE_INFO");
knowTypeNames.put(standardLibrary.getTuple0Type(),"TUPLE0_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableTuple0Type(),"NULLABLE_TUPLE0_TYPE_INFO");
knowTypes.put(standardLibrary.getIntArrayType(), "INT_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getLongArrayType(), "LONG_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getShortArrayType(),"SHORT_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getByteArrayType(),"BYTE_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getCharArrayType(),"CHAR_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getFloatArrayType(),"FLOAT_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getDoubleArrayType(),"DOUBLE_ARRAY_TYPE_INFO");
knowTypes.put(standardLibrary.getBooleanArrayType(),"BOOLEAN_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getIntArrayType(), "INT_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getLongArrayType(), "LONG_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getShortArrayType(),"SHORT_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getByteArrayType(),"BYTE_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getCharArrayType(),"CHAR_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getFloatArrayType(),"FLOAT_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getDoubleArrayType(),"DOUBLE_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getBooleanArrayType(),"BOOLEAN_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableIntArrayType(), "INT_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableLongArrayType(), "LONG_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableShortArrayType(),"SHORT_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableByteArrayType(),"BYTE_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableCharArrayType(),"CHAR_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableFloatArrayType(),"FLOAT_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableDoubleArrayType(),"DOUBLE_ARRAY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableBooleanArrayType(),"BOOLEAN_ARRAY_TYPE_INFO");
}
private void initKnownTypes() {
knowTypes.put(JetStandardClasses.getNothingType(), TYPE_NOTHING);
knowTypes.put(JetStandardClasses.getNullableNothingType(), TYPE_NOTHING);
knowTypes.put(standardLibrary.getIntType(), Type.INT_TYPE);
knowTypes.put(standardLibrary.getNullableIntType(), JL_INTEGER_TYPE);
knowTypes.put(standardLibrary.getLongType(), Type.LONG_TYPE);
knowTypes.put(standardLibrary.getNullableLongType(), JL_LONG_TYPE);
knowTypes.put(standardLibrary.getShortType(),Type.SHORT_TYPE);
knowTypes.put(standardLibrary.getNullableShortType(),JL_SHORT_TYPE);
knowTypes.put(standardLibrary.getByteType(),Type.BYTE_TYPE);
knowTypes.put(standardLibrary.getNullableByteType(),JL_BYTE_TYPE);
knowTypes.put(standardLibrary.getCharType(),Type.CHAR_TYPE);
knowTypes.put(standardLibrary.getNullableCharType(),JL_CHAR_TYPE);
knowTypes.put(standardLibrary.getFloatType(),Type.FLOAT_TYPE);
knowTypes.put(standardLibrary.getNullableFloatType(),JL_FLOAT_TYPE);
knowTypes.put(standardLibrary.getDoubleType(),Type.DOUBLE_TYPE);
knowTypes.put(standardLibrary.getNullableDoubleType(),JL_DOUBLE_TYPE);
knowTypes.put(standardLibrary.getBooleanType(),Type.BOOLEAN_TYPE);
knowTypes.put(standardLibrary.getNullableBooleanType(),JL_BOOLEAN_TYPE);
knowTypes.put(standardLibrary.getStringType(),JL_STRING_TYPE);
knowTypes.put(standardLibrary.getNullableStringType(),JL_STRING_TYPE);
knowTypes.put(standardLibrary.getIntArrayType(), ARRAY_INT_TYPE);
knowTypes.put(standardLibrary.getLongArrayType(), ARRAY_LONG_TYPE);
knowTypes.put(standardLibrary.getShortArrayType(),ARRAY_SHORT_TYPE);
knowTypes.put(standardLibrary.getByteArrayType(),ARRAY_BYTE_TYPE);
knowTypes.put(standardLibrary.getCharArrayType(),ARRAY_CHAR_TYPE);
knowTypes.put(standardLibrary.getFloatArrayType(),ARRAY_FLOAT_TYPE);
knowTypes.put(standardLibrary.getDoubleArrayType(),ARRAY_DOUBLE_TYPE);
knowTypes.put(standardLibrary.getBooleanArrayType(),ARRAY_BOOL_TYPE);
knowTypes.put(standardLibrary.getNullableIntArrayType(), ARRAY_INT_TYPE);
knowTypes.put(standardLibrary.getNullableLongArrayType(), ARRAY_LONG_TYPE);
knowTypes.put(standardLibrary.getNullableShortArrayType(),ARRAY_SHORT_TYPE);
knowTypes.put(standardLibrary.getNullableByteArrayType(),ARRAY_BYTE_TYPE);
knowTypes.put(standardLibrary.getNullableCharArrayType(),ARRAY_CHAR_TYPE);
knowTypes.put(standardLibrary.getNullableFloatArrayType(),ARRAY_FLOAT_TYPE);
knowTypes.put(standardLibrary.getNullableDoubleArrayType(),ARRAY_DOUBLE_TYPE);
knowTypes.put(standardLibrary.getNullableBooleanArrayType(),ARRAY_BOOL_TYPE);
}
public String isKnownTypeInfo(JetType jetType) {
return knowTypes.get(jetType);
return knowTypeNames.get(jetType);
}
public boolean isGenericsArray(JetType type) {
@@ -196,6 +196,11 @@ public class NamespaceCodegen {
if (fqName.length() == 0) {
return "namespace";
}
return fqName.replace('.', '/') + "/namespace";
String name = fqName.replace('.', '/') + "/namespace";
if(name.startsWith("<java_root>")) {
name = name.substring("<java_root>".length() + 1, name.length() - ".namespace".length());
}
return name;
}
}
@@ -132,7 +132,7 @@ public class IntrinsicMethods {
final PsiMethod[] methods = stringPsiClass.findMethodsByName(stringMember.getName(), false);
for (PsiMethod method : methods) {
if (method.getParameterList().getParametersCount() == stringMethod.getValueParameters().size()) {
myMethods.put(stringMethod, new PsiMethodCall(method));
myMethods.put(stringMethod, new PsiMethodCall(stringMethod));
}
}
}
@@ -1,10 +1,11 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import org.jetbrains.jet.codegen.CallableMethod;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.OwnerKind;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.objectweb.asm.Type;
@@ -14,18 +15,19 @@ import java.util.List;
/**
* @author yole
* @author alex.tkachman
*/
public class PsiMethodCall implements IntrinsicMethod {
private final PsiMethod myMethod;
private final FunctionDescriptor myMethod;
public PsiMethodCall(PsiMethod method) {
public PsiMethodCall(FunctionDescriptor method) {
myMethod = method;
}
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element,
List<JetExpression> arguments, StackValue receiver) {
final CallableMethod callableMethod = codegen.getTypeMapper().mapToCallableMethod(myMethod, null);
final CallableMethod callableMethod = codegen.getTypeMapper().mapToCallableMethod(myMethod, false, OwnerKind.IMPLEMENTATION);
codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver);
return StackValue.onStack(callableMethod.getSignature().getReturnType());
}
@@ -102,6 +102,15 @@ public class JetStandardLibrary {
private JetType doubleArrayType;
private JetType booleanArrayType;
private JetType nullableByteArrayType;
private JetType nullableCharArrayType;
private JetType nullableShortArrayType;
private JetType nullableIntArrayType;
private JetType nullableLongArrayType;
private JetType nullableFloatArrayType;
private JetType nullableDoubleArrayType;
private JetType nullableBooleanArrayType;
public JetType getTuple0Type() {
return tuple0Type;
}
@@ -167,8 +176,21 @@ public class JetStandardLibrary {
this.floatType = new JetTypeImpl(getFloat());
this.doubleType = new JetTypeImpl(getDouble());
this.booleanType = new JetTypeImpl(getBoolean());
this.stringType = new JetTypeImpl(getString());
this.nullableStringType = TypeUtils.makeNullable(stringType);
this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0));
this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type);
this.nullableByteType = TypeUtils.makeNullable(byteType);
this.nullableCharType = TypeUtils.makeNullable(charType);
this.nullableShortType = TypeUtils.makeNullable(shortType);
this.nullableIntType = TypeUtils.makeNullable(intType);
this.nullableLongType = TypeUtils.makeNullable(longType);
this.nullableFloatType = TypeUtils.makeNullable(floatType);
this.nullableDoubleType = TypeUtils.makeNullable(doubleType);
this.nullableBooleanType = TypeUtils.makeNullable(booleanType);
this.byteArrayClass = (ClassDescriptor) libraryScope.getClassifier("ByteArray");
this.charArrayClass = (ClassDescriptor) libraryScope.getClassifier("CharArray");
@@ -188,16 +210,14 @@ public class JetStandardLibrary {
this.doubleArrayType = new JetTypeImpl(doubleArrayClass);
this.booleanArrayType = new JetTypeImpl(booleanArrayClass);
this.nullableByteType = TypeUtils.makeNullable(byteType);
this.nullableCharType = TypeUtils.makeNullable(charType);
this.nullableShortType = TypeUtils.makeNullable(shortType);
this.nullableIntType = TypeUtils.makeNullable(intType);
this.nullableLongType = TypeUtils.makeNullable(longType);
this.nullableFloatType = TypeUtils.makeNullable(floatType);
this.nullableDoubleType = TypeUtils.makeNullable(doubleType);
this.nullableBooleanType = TypeUtils.makeNullable(booleanType);
this.nullableStringType = TypeUtils.makeNullable(stringType);
this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type);
this.nullableByteArrayType = TypeUtils.makeNullable(byteArrayType);
this.nullableCharArrayType = TypeUtils.makeNullable(charArrayType);
this.nullableShortArrayType = TypeUtils.makeNullable(shortArrayType);
this.nullableIntArrayType = TypeUtils.makeNullable(intArrayType);
this.nullableLongArrayType = TypeUtils.makeNullable(longArrayType);
this.nullableFloatArrayType = TypeUtils.makeNullable(floatArrayType);
this.nullableDoubleArrayType = TypeUtils.makeNullable(doubleArrayType);
this.nullableBooleanArrayType = TypeUtils.makeNullable(booleanArrayType);
}
}
@@ -501,4 +521,36 @@ public class JetStandardLibrary {
initStdClasses();
return booleanArrayClass;
}
public JetType getNullableByteArrayType() {
return nullableByteArrayType;
}
public JetType getNullableCharArrayType() {
return nullableCharArrayType;
}
public JetType getNullableShortArrayType() {
return nullableShortArrayType;
}
public JetType getNullableIntArrayType() {
return nullableIntArrayType;
}
public JetType getNullableLongArrayType() {
return nullableLongArrayType;
}
public JetType getNullableFloatArrayType() {
return nullableFloatArrayType;
}
public JetType getNullableDoubleArrayType() {
return nullableDoubleArrayType;
}
public JetType getNullableBooleanArrayType() {
return nullableBooleanArrayType;
}
}
@@ -1,13 +1,20 @@
class N() : java.util.ArrayList<String>() {
override fun add(el: String) : Boolean {
super.add(el)
return super.add(el + el)
import java.util.ArrayList
trait Tr {
fun extra() : String = "_"
}
class N() : ArrayList<Any>(), Tr {
override fun add(el: Any) : Boolean {
super<ArrayList>.add(el)
return super<ArrayList>.add(el.toString() + super<Tr>.extra() + el + extra())
}
override fun extra() : String = super<Tr>.extra() + super<Tr>.extra()
}
fun box(): String {
val n = N()
n.add("239")
if (n.get(0) == "239" && n.get(1) == "239239") return "OK";
if (n.get(0) == "239" && n.get(1) == "239_239__") return "OK";
return "fail";
}