making code greener and properly formatted

This commit is contained in:
Alex Tkachman
2012-08-15 17:08:43 +03:00
parent 813c7d0871
commit ca33712b00
83 changed files with 1353 additions and 866 deletions
+6
View File
@@ -23,7 +23,13 @@
</option> </option>
<envs /> <envs />
<patterns /> <patterns />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Run" /> <RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" /> <ConfigurationWrapper RunnerId="Run" />
<method /> <method />
</configuration> </configuration>
@@ -17,6 +17,10 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
@@ -24,11 +28,13 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
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.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.*; import org.jetbrains.jet.lang.resolve.calls.DefaultValueArgument;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.VarargValueArgument;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.asm4.*;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.List; import java.util.List;
@@ -47,11 +53,13 @@ public abstract class AnnotationCodegen {
} }
public void genAnnotations(Annotated annotated) { public void genAnnotations(Annotated annotated) {
if (annotated == null) if (annotated == null) {
return; return;
}
if (!(annotated instanceof DeclarationDescriptor)) if (!(annotated instanceof DeclarationDescriptor)) {
return; return;
}
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, (DeclarationDescriptor) annotated); PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, (DeclarationDescriptor) annotated);
@@ -63,12 +71,14 @@ public abstract class AnnotationCodegen {
modifierList = ((JetModifierListOwner) psiElement).getModifierList(); modifierList = ((JetModifierListOwner) psiElement).getModifierList();
} }
if (modifierList == null) if (modifierList == null) {
return; return;
}
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries(); List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
for (JetAnnotationEntry annotationEntry : annotationEntries) { for (JetAnnotationEntry annotationEntry : annotationEntries) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, annotationEntry.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall =
bindingContext.get(BindingContext.RESOLVED_CALL, annotationEntry.getCalleeExpression());
assert resolvedCall != null; assert resolvedCall != null;
AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry); AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry);
@@ -79,8 +89,10 @@ public abstract class AnnotationCodegen {
} }
} }
private void genAnnotation(ResolvedCall<? extends CallableDescriptor> resolvedCall, private void genAnnotation(
JetType type) { ResolvedCall<? extends CallableDescriptor> resolvedCall,
JetType type
) {
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper); RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper);
if (rp == RetentionPolicy.SOURCE) { if (rp == RetentionPolicy.SOURCE) {
@@ -140,7 +152,8 @@ public abstract class AnnotationCodegen {
if (call != null) { if (call != null) {
if (call.getResultingDescriptor() instanceof PropertyDescriptor) { if (call.getResultingDescriptor() instanceof PropertyDescriptor) {
PropertyDescriptor descriptor = (PropertyDescriptor) call.getResultingDescriptor(); PropertyDescriptor descriptor = (PropertyDescriptor) call.getResultingDescriptor();
annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(), descriptor.getName().getName()); annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(),
descriptor.getName().getName());
return; return;
} }
} }
@@ -162,7 +175,8 @@ public abstract class AnnotationCodegen {
} }
} }
if (IntrinsicMethods.KOTLIN_JAVA_CLASS_FUNCTION.equals(value)) { if (IntrinsicMethods.KOTLIN_JAVA_CLASS_FUNCTION.equals(value)) {
annotationVisitor.visit(keyName, typeMapper.mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE)); annotationVisitor.visit(keyName, typeMapper
.mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE));
return; return;
} }
else if (IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) { else if (IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) {
@@ -18,14 +18,12 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.asm4.Opcodes; import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import java.util.List; import java.util.List;
@@ -49,9 +47,11 @@ public class CallableMethod implements Callable {
@Nullable @Nullable
private final Type generateCalleeType; private final Type generateCalleeType;
public CallableMethod(@NotNull JvmClassName owner, @Nullable JvmClassName defaultImplOwner, @Nullable JvmClassName defaultImplParam, public CallableMethod(
@NotNull JvmClassName owner, @Nullable JvmClassName defaultImplOwner, @Nullable JvmClassName defaultImplParam,
JvmMethodSignature signature, int invokeOpcode, JvmMethodSignature signature, int invokeOpcode,
@Nullable JvmClassName thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType) { @Nullable JvmClassName thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType
) {
this.owner = owner; this.owner = owner;
this.defaultImplOwner = defaultImplOwner; this.defaultImplOwner = defaultImplOwner;
this.defaultImplParam = defaultImplParam; this.defaultImplParam = defaultImplParam;
@@ -93,7 +93,8 @@ public class CallableMethod implements Callable {
} }
void invoke(InstructionAdapter v) { void invoke(InstructionAdapter v) {
v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getSignature().getAsmMethod().getName(), getSignature().getAsmMethod().getDescriptor()); v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getSignature().getAsmMethod().getName(),
getSignature().getAsmMethod().getDescriptor());
} }
@Nullable @Nullable
@@ -112,8 +113,9 @@ public class CallableMethod implements Callable {
v.visitMethodInsn(Opcodes.INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc); v.visitMethodInsn(Opcodes.INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc);
} }
else { else {
if (getInvokeOpcode() != Opcodes.INVOKESTATIC) if (getInvokeOpcode() != Opcodes.INVOKESTATIC) {
desc = desc.replace("(", "(" + defaultImplParam.getDescriptor()); desc = desc.replace("(", "(" + defaultImplParam.getDescriptor());
}
v.visitMethodInsn(Opcodes.INVOKESTATIC, defaultImplOwner.getInternalName(), v.visitMethodInsn(Opcodes.INVOKESTATIC, defaultImplOwner.getInternalName(),
getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc); getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
} }
@@ -91,16 +91,17 @@ public abstract class ClassBodyCodegen {
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) { private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) {
boolean isAnnotation = origin instanceof JetClass && ((JetClass) origin).isAnnotation(); boolean isAnnotation = origin instanceof JetClass && ((JetClass) origin).isAnnotation();
OwnerKind kind = context.getContextKind();
for (JetParameter p : getPrimaryConstructorParameters()) { for (JetParameter p : getPrimaryConstructorParameters()) {
if (p.getValOrVarNode() != null) { if (p.getValOrVarNode() != null) {
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
if (propertyDescriptor != null) { if (propertyDescriptor != null) {
if (!isAnnotation) { if (!isAnnotation) {
propertyCodegen.generateBackingField(p, propertyDescriptor); propertyCodegen.generateBackingField(p, propertyDescriptor);
propertyCodegen.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p); propertyCodegen
.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p);
if (propertyDescriptor.isVar()) { if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p); propertyCodegen
.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p);
} }
} }
else { else {
@@ -21,11 +21,7 @@ package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.*;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
public abstract class ClassBuilder { public abstract class ClassBuilder {
public static class Concrete extends ClassBuilder { public static class Concrete extends ClassBuilder {
@@ -40,27 +36,33 @@ public abstract class ClassBuilder {
return v; return v;
} }
} }
public FieldVisitor newField(@Nullable PsiElement origin,
public FieldVisitor newField(
@Nullable PsiElement origin,
int access, int access,
String name, String name,
String desc, String desc,
@Nullable String signature, @Nullable String signature,
@Nullable Object value) { @Nullable Object value
) {
return getVisitor().visitField(access, name, desc, signature, value); return getVisitor().visitField(access, name, desc, signature, value);
} }
public MethodVisitor newMethod(@Nullable PsiElement origin, public MethodVisitor newMethod(
@Nullable PsiElement origin,
int access, int access,
String name, String name,
String desc, String desc,
@Nullable String signature, @Nullable String signature,
@Nullable String[] exceptions) { @Nullable String[] exceptions
) {
return getVisitor().visitMethod(access, name, desc, signature, exceptions); return getVisitor().visitMethod(access, name, desc, signature, exceptions);
} }
public AnnotationVisitor newAnnotation(PsiElement origin, public AnnotationVisitor newAnnotation(
String desc, String desc,
boolean visible) { boolean visible
) {
return getVisitor().visitAnnotation(desc, visible); return getVisitor().visitAnnotation(desc, visible);
} }
@@ -70,7 +72,15 @@ public abstract class ClassBuilder {
public abstract ClassVisitor getVisitor(); public abstract ClassVisitor getVisitor();
public void defineClass(PsiElement origin, int version, int access, String name, @Nullable String signature, String superName, String[] interfaces) { public void defineClass(
PsiElement origin,
int version,
int access,
String name,
@Nullable String signature,
String superName,
String[] interfaces
) {
getVisitor().visit(version, access & ~Opcodes.ACC_STATIC, name, signature, superName, interfaces); getVisitor().visit(version, access & ~Opcodes.ACC_STATIC, name, signature, superName, interfaces);
} }
@@ -17,7 +17,6 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.ClassWriter; import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.asm4.util.TraceClassVisitor; import org.jetbrains.asm4.util.TraceClassVisitor;
@@ -27,6 +26,7 @@ import java.io.StringWriter;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
public class ClassBuilderFactories { public class ClassBuilderFactories {
public static ClassBuilderFactory TEST = new ClassBuilderFactory() { public static ClassBuilderFactory TEST = new ClassBuilderFactory() {
@@ -17,11 +17,6 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.asm4.util.TraceClassVisitor;
import java.io.PrintWriter;
import java.io.StringWriter;
/** /**
* @author max * @author max
@@ -29,7 +24,10 @@ import java.io.StringWriter;
public interface ClassBuilderFactory { public interface ClassBuilderFactory {
@NotNull @NotNull
ClassBuilderMode getClassBuilderMode(); ClassBuilderMode getClassBuilderMode();
ClassBuilder newClassBuilder(); ClassBuilder newClassBuilder();
String asText(ClassBuilder builder); String asText(ClassBuilder builder);
byte[] asBytes(ClassBuilder builder); byte[] asBytes(ClassBuilder builder);
} }
@@ -20,10 +20,16 @@ package org.jetbrains.jet.codegen;
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
public enum ClassBuilderMode { public enum ClassBuilderMode {
/** Full function bodies */ /**
* Full function bodies
*/
FULL, FULL,
/** Only function signatures */ /**
* Only function signatures
*/
SIGNATURES, SIGNATURES,
/** Function with stub bodies: just throw exception */ /**
* Function with stub bodies: just throw exception
*/
STUBS, STUBS,
} }
@@ -17,7 +17,6 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 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.DeclarationDescriptor;
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;
@@ -18,9 +18,8 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.FqName;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*; import java.util.*;
@@ -49,7 +48,6 @@ public class ClassFileFactory {
} }
ClassBuilder newVisitor(String filePath) { ClassBuilder newVisitor(String filePath) {
state.getProgress().log("Emitting: " + filePath); state.getProgress().log("Emitting: " + filePath);
final ClassBuilder answer = builderFactory.newClassBuilder(); final ClassBuilder answer = builderFactory.newClassBuilder();
@@ -23,6 +23,12 @@ package org.jetbrains.jet.codegen;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.asm4.signature.SignatureWriter;
import org.jetbrains.jet.codegen.signature.BothSignatureWriter; import org.jetbrains.jet.codegen.signature.BothSignatureWriter;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
@@ -36,13 +42,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.asm4.signature.SignatureWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -98,10 +97,9 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
else { else {
receiverParameterType = null; receiverParameterType = null;
} }
final CallableMethod result = new CallableMethod( return new CallableMethod(
owner, null, null, descriptor, INVOKEVIRTUAL, owner, null, null, descriptor, INVOKEVIRTUAL,
getInternalClassName(fd), receiverParameterType, getInternalClassName(fd).getAsmType()); getInternalClassName(fd), receiverParameterType, getInternalClassName(fd).getAsmType());
return result;
} }
public JvmMethodSignature invokeSignature(FunctionDescriptor fd) { public JvmMethodSignature invokeSignature(FunctionDescriptor fd) {
@@ -118,6 +116,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
SignatureWriter signatureWriter = new SignatureWriter(); SignatureWriter signatureWriter = new SignatureWriter();
assert funDescriptor != null;
final List<ValueParameterDescriptor> parameters = funDescriptor.getValueParameters(); final List<ValueParameterDescriptor> parameters = funDescriptor.getValueParameters();
final JvmClassName funClass = getInternalClassName(funDescriptor); final JvmClassName funClass = getInternalClassName(funDescriptor);
signatureWriter.visitClassType(funClass.getInternalName()); signatureWriter.visitClassType(funClass.getInternalName());
@@ -142,9 +141,12 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
generateBridge(name.getInternalName(), funDescriptor, fun, cv); generateBridge(name.getInternalName(), funDescriptor, fun, cv);
captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun); captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun);
ClassDescriptor thisDescriptor = context.getThisDescriptor(); ClassDescriptor thisDescriptor = context.getThisDescriptor();
final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); final Type enclosingType = thisDescriptor == null
if (enclosingType == null) ? null
: state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE);
if (enclosingType == null) {
captureThis = null; captureThis = null;
}
final Method constructor = generateConstructor(funClass, fun, funDescriptor); final Method constructor = generateConstructor(funClass, fun, funDescriptor);
@@ -158,16 +160,14 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
cv.done(); cv.done();
final GeneratedAnonymousClassDescriptor answer = new GeneratedAnonymousClassDescriptor(name, constructor, captureThis, captureReceiver); final GeneratedAnonymousClassDescriptor answer =
new GeneratedAnonymousClassDescriptor(name, constructor, captureThis, captureReceiver);
for (DeclarationDescriptor descriptor : closure.keySet()) { for (DeclarationDescriptor descriptor : closure.keySet()) {
if (descriptor == funDescriptor) { if (descriptor == funDescriptor) {
continue; continue;
} }
if (descriptor instanceof VariableDescriptor) { if (descriptor instanceof VariableDescriptor || CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor); descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
answer.addArg(valueDescriptor.getOuterValue());
}
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor); final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
answer.addArg(valueDescriptor.getOuterValue()); answer.addArg(valueDescriptor.getOuterValue());
} }
@@ -204,7 +204,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) { private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name); ClassDescriptor function =
state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name);
final CodegenContexts.ClosureContext closureContext = context.intoClosure( final CodegenContexts.ClosureContext closureContext = context.intoClosure(
funDescriptor, function, name, this, state.getInjector().getJetTypeMapper()); funDescriptor, function, name, this, state.getInjector().getJetTypeMapper());
@@ -218,10 +219,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final JvmMethodSignature bridge = erasedInvokeSignature(funDescriptor); final JvmMethodSignature bridge = erasedInvokeSignature(funDescriptor);
final Method delegate = invokeSignature(funDescriptor).getAsmMethod(); final Method delegate = invokeSignature(funDescriptor).getAsmMethod();
if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor())) if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor())) {
return; return;
}
final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE | ACC_VOLATILE, "invoke", bridge.getAsmMethod().getDescriptor(), null, new String[0]); final MethodVisitor mv =
cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE | ACC_VOLATILE, "invoke", bridge.getAsmMethod().getDescriptor(), null,
new String[0]);
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv); StubCodegen.generateStubCode(mv);
} }
@@ -236,14 +240,16 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
int count = 1; int count = 1;
if (receiver.exists()) { if (receiver.exists()) {
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv); StackValue.onStack(JetTypeMapper.TYPE_OBJECT)
.upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv);
count++; count++;
} }
final List<ValueParameterDescriptor> params = funDescriptor.getValueParameters(); final List<ValueParameterDescriptor> params = funDescriptor.getValueParameters();
for (ValueParameterDescriptor param : params) { for (ValueParameterDescriptor param : params) {
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv); StackValue.onStack(JetTypeMapper.TYPE_OBJECT)
.upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv);
count++; count++;
} }
@@ -270,7 +276,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
argCount++; argCount++;
variableDescriptors.add(descriptor); variableDescriptors.add(descriptor);
} }
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
argCount++; argCount++;
variableDescriptors.add(descriptor); variableDescriptors.add(descriptor);
} }
@@ -308,8 +315,11 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
argTypes[i++] = type; argTypes[i++] = type;
} }
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)).getAsmType(); descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator()
.classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
.getAsmType();
argTypes[i++] = type; argTypes[i++] = type;
} }
} }
@@ -374,16 +384,6 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
} }
public static ClassDescriptor getInternalType(FunctionDescriptor descriptor) {
final int paramCount = descriptor.getValueParameters().size();
if (descriptor.getReceiverParameter().exists()) {
return JetStandardClasses.getReceiverFunction(paramCount);
}
else {
return JetStandardClasses.getFunction(paramCount);
}
}
private void appendType(SignatureWriter signatureWriter, JetType type, char variance) { private void appendType(SignatureWriter signatureWriter, JetType type, char variance) {
signatureWriter.visitTypeArgument(variance); signatureWriter.visitTypeArgument(variance);
@@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.*; import java.util.Collections;
import java.util.HashMap;
/* /*
* @author max * @author max
@@ -47,7 +47,12 @@ public abstract class CodegenContext {
protected Type outerWasUsed; protected Type outerWasUsed;
public CodegenContext(@NotNull DeclarationDescriptor contextDescriptor, OwnerKind contextKind, @Nullable CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) { public CodegenContext(
@NotNull DeclarationDescriptor contextDescriptor,
OwnerKind contextKind,
@Nullable CodegenContext parentContext,
@Nullable ObjectOrClosureCodegen closureCodegen
) {
this.contextDescriptor = contextDescriptor; this.contextDescriptor = contextDescriptor;
this.contextKind = contextKind; this.contextKind = contextKind;
this.parentContext = parentContext; this.parentContext = parentContext;
@@ -59,6 +64,7 @@ public abstract class CodegenContext {
public DeclarationDescriptor getClassOrNamespaceDescriptor() { public DeclarationDescriptor getClassOrNamespaceDescriptor() {
CodegenContext c = this; CodegenContext c = this;
while (true) { while (true) {
assert c != null;
DeclarationDescriptor contextDescriptor = c.getContextDescriptor(); DeclarationDescriptor contextDescriptor = c.getContextDescriptor();
if (!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) { if (!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) {
c = c.getParentContext(); c = c.getParentContext();
@@ -82,6 +88,7 @@ public abstract class CodegenContext {
return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression; return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression;
} }
@NotNull
public DeclarationDescriptor getContextDescriptor() { public DeclarationDescriptor getContextDescriptor() {
return contextDescriptor; return contextDescriptor;
} }
@@ -95,14 +102,19 @@ public abstract class CodegenContext {
} }
public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) {
return new CodegenContexts.NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(StackValue.none(), delegateTo)); return new CodegenContexts.NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo));
} }
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) { public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
return new CodegenContexts.ClassContext(descriptor, kind, this, typeMapper); return new CodegenContexts.ClassContext(descriptor, kind, this, typeMapper);
} }
public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) { public CodegenContext intoAnonymousClass(
@NotNull ObjectOrClosureCodegen closure,
ClassDescriptor descriptor,
OwnerKind kind,
JetTypeMapper typeMapper
) {
return new CodegenContexts.AnonymousClassContext(descriptor, kind, this, closure, typeMapper); return new CodegenContexts.AnonymousClassContext(descriptor, kind, this, closure, typeMapper);
} }
@@ -113,7 +125,8 @@ public abstract class CodegenContext {
public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) { public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
if (descriptor == null) { if (descriptor == null) {
descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true) descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true)
.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC); .initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
Visibilities.PUBLIC);
} }
return new CodegenContexts.ConstructorContext(descriptor, getContextKind(), this, typeMapper); return new CodegenContexts.ConstructorContext(descriptor, getContextKind(), this, typeMapper);
} }
@@ -122,7 +135,13 @@ public abstract class CodegenContext {
return new CodegenContexts.ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure); return new CodegenContexts.ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
} }
public CodegenContexts.ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, JvmClassName internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) { public CodegenContexts.ClosureContext intoClosure(
FunctionDescriptor funDescriptor,
ClassDescriptor classDescriptor,
JvmClassName internalClassName,
ClosureCodegen closureCodegen,
JetTypeMapper typeMapper
) {
return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper); return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
} }
@@ -151,7 +170,9 @@ public abstract class CodegenContext {
final ObjectOrClosureCodegen top = closure; final ObjectOrClosureCodegen top = closure;
if (top != null) { if (top != null) {
final StackValue answer = top.lookupInContext(d, result); final StackValue answer = top.lookupInContext(d, result);
if (answer != null) { return result == null ? answer : StackValue.composed(result, answer); } if (answer != null) {
return result == null ? answer : StackValue.composed(result, answer);
}
StackValue outer = getOuterExpression(null); StackValue outer = getOuterExpression(null);
result = result == null ? outer : StackValue.composed(result, outer); result = result == null ? outer : StackValue.composed(result, outer);
@@ -175,7 +196,9 @@ public abstract class CodegenContext {
} }
descriptor = descriptor.getOriginal(); descriptor = descriptor.getOriginal();
DeclarationDescriptor accessor = accessors.get(descriptor); DeclarationDescriptor accessor = accessors.get(descriptor);
if (accessor != null) { return accessor; } if (accessor != null) {
return accessor;
}
if (descriptor instanceof SimpleFunctionDescriptor) { if (descriptor instanceof SimpleFunctionDescriptor) {
accessor = new AccessorForFunctionDescriptor(descriptor, contextDescriptor, accessors.size()); accessor = new AccessorForFunctionDescriptor(descriptor, contextDescriptor, accessors.size());
@@ -18,21 +18,13 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -76,8 +68,10 @@ public class CodegenContexts {
throw new IllegalStateException(); throw new IllegalStateException();
} }
@NotNull @Override public Name getName() { @NotNull
return null; @Override
public Name getName() {
throw new IllegalStateException();
} }
} }
@@ -97,13 +91,17 @@ public class CodegenContexts {
return "ROOT"; return "ROOT";
} }
}; };
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT); protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
public abstract static class ReceiverContext extends CodegenContext { public abstract static class ReceiverContext extends CodegenContext {
final CallableDescriptor receiverDescriptor; final CallableDescriptor receiverDescriptor;
public ReceiverContext(CallableDescriptor contextDescriptor, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) { public ReceiverContext(
CallableDescriptor contextDescriptor,
OwnerKind contextKind,
CodegenContext parentContext,
@Nullable ObjectOrClosureCodegen closureCodegen
) {
super(contextDescriptor, contextKind, parentContext, closureCodegen); super(contextDescriptor, contextKind, parentContext, closureCodegen);
receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null; receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null;
} }
@@ -115,38 +113,40 @@ public class CodegenContexts {
} }
public static class MethodContext extends ReceiverContext { public static class MethodContext extends ReceiverContext {
@NotNull
private final FunctionDescriptor functionDescriptor;
public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) { public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null); super(contextType instanceof PropertyAccessorDescriptor
this.functionDescriptor = contextType; ? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty()
} : contextType, contextKind, parentContext, null);
@NotNull
public FunctionDescriptor getFunctionDescriptor() {
return functionDescriptor;
} }
@Override @Override
protected ClassDescriptor getThisDescriptor() { protected ClassDescriptor getThisDescriptor() {
//noinspection ConstantConditions
return getParentContext().getThisDescriptor(); return getParentContext().getThisDescriptor();
} }
@Override
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) { public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) {
//noinspection ConstantConditions
return getParentContext().lookupInContext(d, v, result); return getParentContext().lookupInContext(d, v, result);
} }
@Override
public Type enclosingClassType(JetTypeMapper typeMapper) { public Type enclosingClassType(JetTypeMapper typeMapper) {
//noinspection ConstantConditions
return getParentContext().enclosingClassType(typeMapper); return getParentContext().enclosingClassType(typeMapper);
} }
@Override @Override
public boolean isStatic() { public boolean isStatic() {
//noinspection ConstantConditions
return getParentContext().isStatic(); return getParentContext().isStatic();
} }
@Override
protected StackValue getOuterExpression(StackValue prefix) { protected StackValue getOuterExpression(StackValue prefix) {
//noinspection ConstantConditions
return getParentContext().getOuterExpression(prefix); return getParentContext().getOuterExpression(prefix);
} }
@@ -157,7 +157,12 @@ public class CodegenContexts {
} }
public static class ConstructorContext extends MethodContext { public static class ConstructorContext extends MethodContext {
public ConstructorContext(ConstructorDescriptor contextDescriptor, OwnerKind kind, CodegenContext parent, JetTypeMapper typeMapper) { public ConstructorContext(
ConstructorDescriptor contextDescriptor,
OwnerKind kind,
CodegenContext parent,
JetTypeMapper typeMapper
) {
super(contextDescriptor, kind, parent); super(contextDescriptor, kind, parent);
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
@@ -166,6 +171,7 @@ public class CodegenContexts {
: null; : null;
} }
@Override
protected StackValue getOuterExpression(StackValue prefix) { protected StackValue getOuterExpression(StackValue prefix) {
return outerExpression; return outerExpression;
} }
@@ -188,7 +194,8 @@ public class CodegenContexts {
@NotNull ClassDescriptor contextDescriptor, @NotNull ClassDescriptor contextDescriptor,
@NotNull OwnerKind contextKind, @NotNull OwnerKind contextKind,
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable ObjectOrClosureCodegen closureCodegen) { @Nullable ObjectOrClosureCodegen closureCodegen
) {
super(contextDescriptor, contextKind, parentContext, closureCodegen); super(contextDescriptor, contextKind, parentContext, closureCodegen);
this.classDescriptor = contextDescriptor; this.classDescriptor = contextDescriptor;
@@ -212,7 +219,12 @@ public class CodegenContexts {
} }
public static class ClassContext extends CodegenContext { public static class ClassContext extends CodegenContext {
public ClassContext(ClassDescriptor contextDescriptor, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) { public ClassContext(
ClassDescriptor contextDescriptor,
OwnerKind contextKind,
CodegenContext parentContext,
JetTypeMapper typeMapper
) {
super(contextDescriptor, contextKind, parentContext, null); super(contextDescriptor, contextKind, parentContext, null);
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
@@ -233,7 +245,13 @@ public class CodegenContexts {
} }
public static class AnonymousClassContext extends CodegenContext { public static class AnonymousClassContext extends CodegenContext {
public AnonymousClassContext(ClassDescriptor contextDescriptor, OwnerKind contextKind, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closure, JetTypeMapper typeMapper) { public AnonymousClassContext(
ClassDescriptor contextDescriptor,
OwnerKind contextKind,
CodegenContext parentContext,
@NotNull ObjectOrClosureCodegen closure,
JetTypeMapper typeMapper
) {
super(contextDescriptor, contextKind, parentContext, closure); super(contextDescriptor, contextKind, parentContext, closure);
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
@@ -260,9 +278,16 @@ public class CodegenContexts {
} }
public static class ClosureContext extends ReceiverContext { public static class ClosureContext extends ReceiverContext {
private ClassDescriptor classDescriptor; private final ClassDescriptor classDescriptor;
public ClosureContext(FunctionDescriptor contextDescriptor, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, JvmClassName internalClassName, JetTypeMapper typeMapper) { public ClosureContext(
FunctionDescriptor contextDescriptor,
ClassDescriptor classDescriptor,
CodegenContext parentContext,
@NotNull ObjectOrClosureCodegen closureCodegen,
JvmClassName internalClassName,
JetTypeMapper typeMapper
) {
super(contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen); super(contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen);
this.classDescriptor = classDescriptor; this.classDescriptor = classDescriptor;
@@ -277,6 +302,7 @@ public class CodegenContexts {
return classDescriptor; return classDescriptor;
} }
@NotNull
@Override @Override
public DeclarationDescriptor getContextDescriptor() { public DeclarationDescriptor getContextDescriptor() {
return classDescriptor; return classDescriptor;
@@ -25,12 +25,12 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collections;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Random; import java.util.Random;
/** /**
@@ -109,7 +109,9 @@ public class CodegenUtil {
} }
public static @NotNull BitSet getFlagsForVisibility(@NotNull Visibility visibility) { public static
@NotNull
BitSet getFlagsForVisibility(@NotNull Visibility visibility) {
BitSet flags = new BitSet(); BitSet flags = new BitSet();
if (visibility == Visibilities.INTERNAL) { if (visibility == Visibilities.INTERNAL) {
flags.set(JvmStdlibNames.FLAG_INTERNAL_BIT); flags.set(JvmStdlibNames.FLAG_INTERNAL_BIT);
@@ -56,7 +56,8 @@ public class CompilationException extends RuntimeException {
return ApplicationManager.getApplication().runReadAction(new Computable<String>() { return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override @Override
public String compute() { public String compute() {
StringBuilder message = new StringBuilder("Back-end (JVM) Internal error: ").append(CompilationException.super.getMessage()).append("\n"); StringBuilder message =
new StringBuilder("Back-end (JVM) Internal error: ").append(CompilationException.super.getMessage()).append("\n");
Throwable cause = getCause(); Throwable cause = getCause();
if (cause != null) { if (cause != null) {
String causeMessage = cause.getMessage(); String causeMessage = cause.getMessage();
@@ -17,10 +17,10 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.asm4.Type;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -31,7 +31,6 @@ import java.util.List;
*/ */
public class ConstructorFrameMap extends FrameMap { public class ConstructorFrameMap extends FrameMap {
private int myOuterThisIndex = -1; private int myOuterThisIndex = -1;
private int myTypeInfoIndex = -1;
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) { public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) {
enterTemp(); // this enterTemp(); // this
@@ -62,8 +61,4 @@ public class ConstructorFrameMap extends FrameMap {
public int getOuterThisIndex() { public int getOuterThisIndex() {
return myOuterThisIndex; return myOuterThisIndex;
} }
public int getTypeInfoIndex() {
return myTypeInfoIndex;
}
} }
@@ -24,6 +24,12 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
@@ -40,12 +46,6 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames; import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import java.util.*; import java.util.*;
@@ -132,12 +132,15 @@ public class FrameMap {
Collections.sort(descriptors, new Comparator<Tuple3<DeclarationDescriptor, Integer, Integer>>() { Collections.sort(descriptors, new Comparator<Tuple3<DeclarationDescriptor, Integer, Integer>>() {
@Override @Override
public int compare(Tuple3<DeclarationDescriptor, Integer, Integer> left, Tuple3<DeclarationDescriptor, Integer, Integer> right) { public int compare(
Tuple3<DeclarationDescriptor, Integer, Integer> left,
Tuple3<DeclarationDescriptor, Integer, Integer> right
) {
return left._2 - right._2; return left._2 - right._2;
} }
}); });
sb.append("size=" + myMaxIndex); sb.append("size=").append(myMaxIndex);
boolean first = true; boolean first = true;
for (Tuple3<DeclarationDescriptor, Integer, Integer> t : descriptors) { for (Tuple3<DeclarationDescriptor, Integer, Integer> t : descriptors) {
@@ -145,7 +148,7 @@ public class FrameMap {
sb.append(", "); sb.append(", ");
} }
first = false; first = false;
sb.append(t._1 + ",i=" + t._2 + ",s=" + t._3); sb.append(t._1).append(",i=").append(t._2).append(",s=").append(t._3);
} }
return sb.toString(); return sb.toString();
@@ -19,6 +19,11 @@ package org.jetbrains.jet.codegen;
import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
@@ -32,11 +37,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import java.util.*; import java.util.*;
@@ -61,13 +61,17 @@ public class FunctionCodegen {
public void gen(JetNamedFunction f) { public void gen(JetNamedFunction f) {
final SimpleFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f); final SimpleFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f);
assert functionDescriptor != null; assert functionDescriptor != null;
JvmMethodSignature method = state.getInjector().getJetTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature(); JvmMethodSignature method =
state.getInjector().getJetTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind())
.getSignature();
generateMethod(f, method, true, null, functionDescriptor); generateMethod(f, method, true, null, functionDescriptor);
} }
public void generateMethod(JetDeclarationWithBody f, public void generateMethod(
JetDeclarationWithBody f,
JvmMethodSignature jvmMethod, boolean needJetAnnotations, JvmMethodSignature jvmMethod, boolean needJetAnnotations,
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) { @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor
) {
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor); CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor);
@@ -75,34 +79,33 @@ public class FunctionCodegen {
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f); generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
} }
private void generatedMethod(JetExpression bodyExpressions, private void generatedMethod(
JetExpression bodyExpressions,
JvmMethodSignature jvmSignature, JvmMethodSignature jvmSignature,
boolean needJetAnnotations, @Nullable String propertyTypeSignature, boolean needJetAnnotations, @Nullable String propertyTypeSignature,
CodegenContexts.MethodContext context, CodegenContexts.MethodContext context,
FunctionDescriptor functionDescriptor, FunctionDescriptor functionDescriptor,
JetDeclarationWithBody fun JetDeclarationWithBody fun
) ) {
{
if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
throw new IllegalStateException("must not generate code for fake overrides"); throw new IllegalStateException("must not generate code for fake overrides");
} }
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters(); List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
List<TypeParameterDescriptor> typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters();
int flags = JetTypeMapper.getAccessModifiers(functionDescriptor, 0); int flags = JetTypeMapper.getAccessModifiers(functionDescriptor, 0);
if (!functionDescriptor.getValueParameters().isEmpty() if (!functionDescriptor.getValueParameters().isEmpty()
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1) && functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
.getVarargElementType() != null) .getVarargElementType() != null) {
{
flags |= ACC_VARARGS; flags |= ACC_VARARGS;
} }
Modality modality = functionDescriptor.getModality(); Modality modality = functionDescriptor.getModality();
if (modality == Modality.FINAL) { if (modality == Modality.FINAL) {
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof ClassDescriptor) || ((ClassDescriptor)containingDeclaration).getKind() != ClassKind.TRAIT) { if (!(containingDeclaration instanceof ClassDescriptor) ||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) {
flags |= ACC_FINAL; flags |= ACC_FINAL;
} }
} }
@@ -118,8 +121,9 @@ public class FunctionCodegen {
if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) { if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) {
boolean isStatic = kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind; boolean isStatic = kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind;
if (isStatic || kind == OwnerKind.TRAIT_IMPL) if (isStatic || kind == OwnerKind.TRAIT_IMPL) {
flags |= ACC_STATIC; flags |= ACC_STATIC;
}
boolean isAbstract = ( boolean isAbstract = (
modality == Modality.ABSTRACT modality == Modality.ABSTRACT
@@ -127,7 +131,9 @@ public class FunctionCodegen {
) && !isStatic && kind != OwnerKind.TRAIT_IMPL; ) && !isStatic && kind != OwnerKind.TRAIT_IMPL;
if (isAbstract) flags |= ACC_ABSTRACT; if (isAbstract) flags |= ACC_ABSTRACT;
final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), jvmSignature.getGenericsSignature(), null); final MethodVisitor mv =
v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(),
jvmSignature.getGenericsSignature(), null);
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(functionDescriptor); AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(functionDescriptor);
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
int start = 0; int start = 0;
@@ -197,23 +203,27 @@ public class FunctionCodegen {
FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper()); FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper());
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); ExpressionCodegen codegen =
new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state);
Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes(); Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes();
int add = 0; int add = 0;
if (kind == OwnerKind.TRAIT_IMPL) if (kind == OwnerKind.TRAIT_IMPL) {
add++; add++;
}
if (receiverParameter.exists()) if (receiverParameter.exists()) {
add++; add++;
}
for (int i = 0; i < paramDescrs.size(); i++) { for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i); ValueParameterDescriptor parameter = paramDescrs.get(i);
frameMap.enter(parameter, argTypes[i + add].getSize()); frameMap.enter(parameter, argTypes[i + add].getSize());
} }
if (!isStatic && (kind instanceof OwnerKind.DelegateKind) != (functionDescriptor.getKind() == FunctionDescriptor.Kind.DELEGATION)) { if (!isStatic &&
(kind instanceof OwnerKind.DelegateKind) != (functionDescriptor.getKind() == FunctionDescriptor.Kind.DELEGATION)) {
throw new IllegalStateException("mismatching kind in " + functionDescriptor); throw new IllegalStateException("mismatching kind in " + functionDescriptor);
} }
@@ -225,6 +235,7 @@ public class FunctionCodegen {
for (int i = 0, k = 0; i < argTypes.length; i++) { for (int i = 0, k = 0; i < argTypes.length; i++) {
Type argType = argTypes[i]; Type argType = argTypes[i];
iv.load(k, argType); iv.load(k, argType);
//noinspection AssignmentToForLoopParameter
k += argType.getSize(); k += argType.getSize();
} }
iv.invokestatic(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor()); iv.invokestatic(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor());
@@ -239,7 +250,8 @@ public class FunctionCodegen {
Type argType = argTypes[i]; Type argType = argTypes[i];
iv.load(i + 1, argType); iv.load(i + 1, argType);
} }
iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor()); iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(),
jvmSignature.getAsmMethod().getDescriptor());
iv.areturn(jvmSignature.getAsmMethod().getReturnType()); iv.areturn(jvmSignature.getAsmMethod().getReturnType());
} }
else { else {
@@ -253,11 +265,13 @@ public class FunctionCodegen {
mv.visitInsn(DUP); mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, sharedVarType.getInternalName(), "<init>", "()V"); mv.visitMethodInsn(INVOKESPECIAL, sharedVarType.getInternalName(), "<init>", "()V");
mv.visitVarInsn(localVarType.getOpcode(ILOAD), index); mv.visitVarInsn(localVarType.getOpcode(ILOAD), index);
mv.visitFieldInsn(PUTFIELD, sharedVarType.getInternalName(), "ref", StackValue.refType(localVarType).getDescriptor()); mv.visitFieldInsn(PUTFIELD, sharedVarType.getInternalName(), "ref",
StackValue.refType(localVarType).getDescriptor());
Label labelToDivideLocalVarForSharedVarVisibility = new Label(); Label labelToDivideLocalVarForSharedVarVisibility = new Label();
mv.visitLabel(labelToDivideLocalVarForSharedVarVisibility); mv.visitLabel(labelToDivideLocalVarForSharedVarVisibility);
mapLabelsToDivideLocalVarVisibilityForSharedVar.put(parameter.getName(), labelToDivideLocalVarForSharedVarVisibility); mapLabelsToDivideLocalVarVisibilityForSharedVar
.put(parameter.getName(), labelToDivideLocalVarForSharedVarVisibility);
mv.visitVarInsn(sharedVarType.getOpcode(ISTORE), index); mv.visitVarInsn(sharedVarType.getOpcode(ISTORE), index);
} }
@@ -282,7 +296,8 @@ public class FunctionCodegen {
// TODO: specify signature // TODO: specify signature
mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++); mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++);
} }
else if (fun instanceof JetFunctionLiteralExpression || CodegenUtil.isLocalFun(functionDescriptor, state.getBindingContext())) { else if (fun instanceof JetFunctionLiteralExpression ||
CodegenUtil.isLocalFun(functionDescriptor, state.getBindingContext())) {
Type type = state.getInjector().getJetTypeMapper().mapType( Type type = state.getInjector().getJetTypeMapper().mapType(
context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE); context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE);
mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++); mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++);
@@ -310,7 +325,8 @@ public class FunctionCodegen {
mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k); mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k);
k += Math.max(type.getSize(), sharedVarType.getSize()); k += Math.max(type.getSize(), sharedVarType.getSize());
} else { }
else {
mv.visitLocalVariable(parameter.getName().getName(), type.getDescriptor(), null, methodBegin, methodEnd, k); mv.visitLocalVariable(parameter.getName().getName(), type.getDescriptor(), null, methodBegin, methodEnd, k);
k += type.getSize(); k += type.getSize();
} }
@@ -326,7 +342,7 @@ public class FunctionCodegen {
generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind); generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind);
} }
public static void endVisit(MethodVisitor mv, String description, PsiElement method) { public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) {
try { try {
mv.visitMaxs(-1, -1); mv.visitMaxs(-1, -1);
} }
@@ -335,18 +351,30 @@ public class FunctionCodegen {
} }
catch (Throwable t) { catch (Throwable t) {
throw new CompilationException( throw new CompilationException(
"wrong code generated" + (description != null ? " for " + description : "") + t.getClass().getName() + " " + t.getMessage(), "wrong code generated" +
(description != null ? " for " + description : "") +
t.getClass().getName() +
" " +
t.getMessage(),
t, method); t, method);
} }
mv.visitEnd(); mv.visitEnd();
} }
static void generateBridgeIfNeeded(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { static void generateBridgeIfNeeded(
CodegenContext owner,
GenerationState state,
ClassBuilder v,
Method jvmSignature,
FunctionDescriptor functionDescriptor,
OwnerKind kind
) {
if (kind == OwnerKind.TRAIT_IMPL) { if (kind == OwnerKind.TRAIT_IMPL) {
return; return;
} }
Method method = state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod(); Method method =
state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod();
Queue<FunctionDescriptor> bfsQueue = new LinkedList<FunctionDescriptor>(); Queue<FunctionDescriptor> bfsQueue = new LinkedList<FunctionDescriptor>();
Set<FunctionDescriptor> visited = new HashSet<FunctionDescriptor>(); Set<FunctionDescriptor> visited = new HashSet<FunctionDescriptor>();
@@ -365,7 +393,8 @@ public class FunctionCodegen {
while (!bfsQueue.isEmpty()) { while (!bfsQueue.isEmpty()) {
FunctionDescriptor descriptor = bfsQueue.poll(); FunctionDescriptor descriptor = bfsQueue.poll();
if (descriptor.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { if (descriptor.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
Method overridden = state.getInjector().getJetTypeMapper().mapSignature(descriptor.getName(), descriptor.getOriginal()).getAsmMethod(); Method overridden =
state.getInjector().getJetTypeMapper().mapSignature(descriptor.getName(), descriptor.getOriginal()).getAsmMethod();
if (differentMethods(method, overridden)) { if (differentMethods(method, overridden)) {
bridgesToGenerate.add(overridden); bridgesToGenerate.add(overridden);
} }
@@ -386,7 +415,14 @@ public class FunctionCodegen {
} }
} }
static void generateDefaultIfNeeded(CodegenContexts.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) { static void generateDefaultIfNeeded(
CodegenContexts.MethodContext owner,
GenerationState state,
ClassBuilder v,
Method jvmSignature,
@Nullable FunctionDescriptor functionDescriptor,
OwnerKind kind
) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration(); DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if (kind != OwnerKind.TRAIT_IMPL) { if (kind != OwnerKind.TRAIT_IMPL) {
@@ -395,11 +431,12 @@ public class FunctionCodegen {
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), contextClass); PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), contextClass);
if (psiElement instanceof JetClass) { if (psiElement instanceof JetClass) {
JetClass element = (JetClass) psiElement; JetClass element = (JetClass) psiElement;
if (element.isTrait()) if (element.isTrait()) {
return; return;
} }
} }
} }
}
boolean needed = false; boolean needed = false;
if (functionDescriptor != null) { if (functionDescriptor != null) {
@@ -428,14 +465,19 @@ public class FunctionCodegen {
ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe()); ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe());
} }
else { else {
ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), MapTypeMode.IMPL)); ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper()
.mapType(((ClassDescriptor) contextClass).getDefaultType(),
MapTypeMode.IMPL));
} }
String descriptor = jvmSignature.getDescriptor().replace(")", "I)"); String descriptor = jvmSignature.getDescriptor().replace(")", "I)");
boolean isConstructor = "<init>".equals(jvmSignature.getName()); boolean isConstructor = "<init>".equals(jvmSignature.getName());
if (!isStatic && !isConstructor) if (!isStatic && !isConstructor) {
descriptor = descriptor.replace("(", "(" + ownerInternalName.getDescriptor()); descriptor = descriptor.replace("(", "(" + ownerInternalName.getDescriptor());
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null); }
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC),
isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX,
descriptor, null, null);
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv); StubCodegen.generateStubCode(mv);
@@ -503,7 +545,8 @@ public class FunctionCodegen {
Label loadArg = new Label(); Label loadArg = new Label();
iv.ifeq(loadArg); iv.ifeq(loadArg);
JetParameter jetParameter = (JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor); JetParameter jetParameter =
(JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor);
assert jetParameter != null; assert jetParameter != null;
codegen.gen(jetParameter.getDefaultValue(), t); codegen.gen(jetParameter.getDefaultValue(), t);
@@ -522,38 +565,52 @@ public class FunctionCodegen {
iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
} }
else { else {
if (!isConstructor) if (!isConstructor) {
iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
else }
else {
iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
} }
} }
}
else { else {
iv.invokestatic(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.invokestatic(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
} }
iv.areturn(jvmSignature.getReturnType()); iv.areturn(jvmSignature.getReturnType());
endVisit(mv, "default method", BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor)); endVisit(mv, "default method",
BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
mv.visitEnd(); mv.visitEnd();
} }
} }
} }
private static boolean differentMethods(Method method, Method overridden) { private static boolean differentMethods(Method method, Method overridden) {
if (!method.getReturnType().equals(overridden.getReturnType())) if (!method.getReturnType().equals(overridden.getReturnType())) {
return true; return true;
}
Type[] methodArgumentTypes = method.getArgumentTypes(); Type[] methodArgumentTypes = method.getArgumentTypes();
Type[] overriddenArgumentTypes = overridden.getArgumentTypes(); Type[] overriddenArgumentTypes = overridden.getArgumentTypes();
if (methodArgumentTypes.length != overriddenArgumentTypes.length) if (methodArgumentTypes.length != overriddenArgumentTypes.length) {
return true; return true;
for(int i = 0; i != methodArgumentTypes.length; ++i) }
if (!methodArgumentTypes[i].equals(overriddenArgumentTypes[i])) for (int i = 0; i != methodArgumentTypes.length; ++i) {
if (!methodArgumentTypes[i].equals(overriddenArgumentTypes[i])) {
return true; return true;
}
}
return false; return false;
} }
private static void generateBridge(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, Method overridden) { private static void generateBridge(
CodegenContext owner,
GenerationState state,
ClassBuilder v,
Method jvmSignature,
FunctionDescriptor functionDescriptor,
Method overridden
) {
int flags = ACC_PUBLIC | ACC_BRIDGE; // TODO. int flags = ACC_PUBLIC | ACC_BRIDGE; // TODO.
final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overridden.getDescriptor(), null, null); final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overridden.getDescriptor(), null, null);
@@ -584,21 +641,30 @@ public class FunctionCodegen {
iv.invokevirtual(state.getInjector().getJetTypeMapper().mapType( iv.invokevirtual(state.getInjector().getJetTypeMapper().mapType(
((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), MapTypeMode.VALUE).getInternalName(), ((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), MapTypeMode.VALUE).getInternalName(),
jvmSignature.getName(), jvmSignature.getDescriptor()); jvmSignature.getName(), jvmSignature.getDescriptor());
if (JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overridden.getReturnType())) if (JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overridden.getReturnType())) {
StackValue.valueOf(iv, jvmSignature.getReturnType()); StackValue.valueOf(iv, jvmSignature.getReturnType());
if (jvmSignature.getReturnType() == Type.VOID_TYPE) }
if (jvmSignature.getReturnType() == Type.VOID_TYPE) {
iv.aconst(null); iv.aconst(null);
}
iv.areturn(overridden.getReturnType()); iv.areturn(overridden.getReturnType());
endVisit(mv, "bridge method", BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor)); endVisit(mv, "bridge method",
BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
} }
} }
public void genDelegate(FunctionDescriptor functionDescriptor, CallableMemberDescriptor overriddenDescriptor, StackValue field) { public void genDelegate(FunctionDescriptor functionDescriptor, CallableMemberDescriptor overriddenDescriptor, StackValue field) {
JvmMethodSignature jvmMethodSignature = state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor); JvmMethodSignature jvmMethodSignature =
state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor);
genDelegate(functionDescriptor, overriddenDescriptor, field, jvmMethodSignature); genDelegate(functionDescriptor, overriddenDescriptor, field, jvmMethodSignature);
} }
public void genDelegate(CallableMemberDescriptor functionDescriptor, CallableMemberDescriptor overriddenDescriptor, StackValue field, JvmMethodSignature jvmMethodSignature) { public void genDelegate(
CallableMemberDescriptor functionDescriptor,
CallableMemberDescriptor overriddenDescriptor,
StackValue field,
JvmMethodSignature jvmMethodSignature
) {
Method method = jvmMethodSignature.getAsmMethod(); Method method = jvmMethodSignature.getAsmMethod();
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO. int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
@@ -629,11 +695,14 @@ public class FunctionCodegen {
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
field.put(field.type, iv); field.put(field.type, iv);
ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(); ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration();
String internalName = state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(); String internalName =
if (classDescriptor.getKind() == ClassKind.TRAIT) state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName();
if (classDescriptor.getKind() == ClassKind.TRAIT) {
iv.invokeinterface(internalName, method.getName(), method.getDescriptor()); iv.invokeinterface(internalName, method.getName(), method.getDescriptor());
else }
else {
iv.invokevirtual(internalName, method.getName(), method.getDescriptor()); iv.invokevirtual(internalName, method.getName(), method.getDescriptor());
}
iv.areturn(method.getReturnType()); iv.areturn(method.getReturnType());
endVisit(mv, "delegate method", BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), functionDescriptor)); endVisit(mv, "delegate method", BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), functionDescriptor));
} }
@@ -19,19 +19,19 @@
*/ */
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.Method; import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class GeneratedAnonymousClassDescriptor { public class GeneratedAnonymousClassDescriptor {
private final JvmClassName classname; private final JvmClassName classname;
private Method constructor; private final Method constructor;
private final Type captureThis; private final Type captureThis;
private final Type captureReceiver; private final Type captureReceiver;
private List<StackValue> args = new ArrayList<StackValue>(); private final List<StackValue> args = new ArrayList<StackValue>();
public GeneratedAnonymousClassDescriptor(JvmClassName classname, Method constructor, Type captureThis, Type captureReceiver) { public GeneratedAnonymousClassDescriptor(JvmClassName classname, Method constructor, Type captureThis, Type captureReceiver) {
this.classname = classname; this.classname = classname;
@@ -24,10 +24,6 @@ import org.jetbrains.annotations.NotNull;
public class GeneratedClassLoader extends ClassLoader { public class GeneratedClassLoader extends ClassLoader {
private ClassFileFactory state; private ClassFileFactory state;
public GeneratedClassLoader(@NotNull ClassFileFactory state) {
this(state, GeneratedClassLoader.class.getClassLoader());
}
public GeneratedClassLoader(@NotNull ClassFileFactory state, ClassLoader parentClassLoader) { public GeneratedClassLoader(@NotNull ClassFileFactory state, ClassLoader parentClassLoader) {
super(parentClassLoader); super(parentClassLoader);
this.state = state; this.state = state;
@@ -62,8 +62,10 @@ public class GenerationState {
this(builderFactory, Progress.DEAF, analyzeExhaust, files, BuiltinToJavaTypesMapping.ENABLED); this(builderFactory, Progress.DEAF, analyzeExhaust, files, BuiltinToJavaTypesMapping.ENABLED);
} }
public GenerationState(ClassBuilderFactory builderFactory, Progress progress, public GenerationState(
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping) { ClassBuilderFactory builderFactory, Progress progress,
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping
) {
this.progress = progress; this.progress = progress;
this.analyzeExhaust = exhaust; this.analyzeExhaust = exhaust;
this.files = files; this.files = files;
@@ -90,6 +92,7 @@ public class GenerationState {
return progress; return progress;
} }
@NotNull
public InjectorForJvmCodegen getInjector() { public InjectorForJvmCodegen getInjector() {
return injector; return injector;
} }
@@ -112,15 +115,17 @@ public class GenerationState {
} }
public ClassBuilder forClassImplementation(ClassDescriptor aClass) { public ClassBuilder forClassImplementation(ClassDescriptor aClass) {
return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ".class"); return getFactory().newVisitor(
getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ".class");
} }
public ClassBuilder forNamespacepart(String name, JetFile file) { public ClassBuilder forNamespacepart(String name) {
return getFactory().newVisitor(name + ".class"); return getFactory().newVisitor(name + ".class");
} }
public ClassBuilder forTraitImplementation(ClassDescriptor aClass) { public ClassBuilder forTraitImplementation(ClassDescriptor aClass) {
return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class"); return getFactory().newVisitor(
getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class");
} }
public Pair<JvmClassName, ClassBuilder> forAnonymousSubclass(JetExpression expression) { public Pair<JvmClassName, ClassBuilder> forAnonymousSubclass(JetExpression expression) {
@@ -142,7 +147,9 @@ public class GenerationState {
for (JetFile file : this.files) { for (JetFile file : this.files) {
if (file.isScript()) { if (file.isScript()) {
String name = ScriptNameUtil.classNameForScript(file); String name = ScriptNameUtil.classNameForScript(file);
injector.getClosureAnnotator().registerClassNameForScript(file.getScript(), JvmClassName.byInternalName(name)); JetScript script = file.getScript();
assert script != null;
injector.getClosureAnnotator().registerClassNameForScript(script, JvmClassName.byInternalName(name));
} }
} }
@@ -165,7 +172,8 @@ public class GenerationState {
@NotNull JetScript script, @NotNull JetScript script,
@NotNull JvmClassName className, @NotNull JvmClassName className,
@NotNull List<Pair<ScriptDescriptor, JvmClassName>> earlierScripts, @NotNull List<Pair<ScriptDescriptor, JvmClassName>> earlierScripts,
@NotNull CompilationErrorHandler errorHandler) { @NotNull CompilationErrorHandler errorHandler
) {
injector.getScriptCodegen().registerEarlierScripts(earlierScripts); injector.getScriptCodegen().registerEarlierScripts(earlierScripts);
injector.getClosureAnnotator().registerClassNameForScript(script, className); injector.getClosureAnnotator().registerClassNameForScript(script, className);
@@ -191,14 +199,18 @@ public class GenerationState {
closure.cv = nameAndVisitor.getSecond(); closure.cv = nameAndVisitor.getSecond();
closure.name = nameAndVisitor.getFirst(); closure.name = nameAndVisitor.getFirst();
final CodegenContext objectContext = closure.context.intoAnonymousClass( final CodegenContext objectContext = closure.context.intoAnonymousClass(
closure, analyzeExhaust.getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, injector.getJetTypeMapper()); closure, analyzeExhaust.getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION,
injector.getJetTypeMapper());
new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate(); new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate();
ConstructorDescriptor constructorDescriptor = analyzeExhaust.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration); ConstructorDescriptor constructorDescriptor = analyzeExhaust.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration);
assert constructorDescriptor != null;
CallableMethod callableMethod = injector.getJetTypeMapper().mapToCallableMethod( CallableMethod callableMethod = injector.getJetTypeMapper().mapToCallableMethod(
constructorDescriptor, OwnerKind.IMPLEMENTATION, injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration())); constructorDescriptor, OwnerKind.IMPLEMENTATION,
return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(), objectContext.outerWasUsed, null); injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration()));
return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(),
objectContext.outerWasUsed, null);
} }
public String createText() { public String createText() {
@@ -21,6 +21,11 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.signature.*; import org.jetbrains.jet.codegen.signature.*;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter;
@@ -38,16 +43,11 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.utils.BitSetUtils; import org.jetbrains.jet.utils.BitSetUtils;
import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
/** /**
* @author max * @author max
@@ -139,12 +139,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
access |= ACC_ENUM; access |= ACC_ENUM;
} }
List<String> interfaces = signature.getInterfaces();
v.defineClass(myClass, V1_6, v.defineClass(myClass, V1_6,
access, access,
signature.getName(), signature.getName(),
signature.getJavaGenericSignature(), signature.getJavaGenericSignature(),
signature.getSuperclassName(), signature.getSuperclassName(),
signature.getInterfaces().toArray(new String[0]) interfaces.toArray(new String[interfaces.size()])
); );
v.visitSource(myClass.getContainingFile().getName(), null); v.visitSource(myClass.getContainingFile().getName(), null);
@@ -185,7 +186,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor); AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor);
if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) { if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) {
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true); AnnotationVisitor annotationVisitor = v.newAnnotation(JvmStdlibNames.JET_CLASS.getDescriptor(), true);
annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature());
BitSet flags = CodegenUtil.getFlagsForVisibility(descriptor.getVisibility()); BitSet flags = CodegenUtil.getFlagsForVisibility(descriptor.getVisibility());
int flagsValue = BitSetUtils.toInt(flags); int flagsValue = BitSetUtils.toInt(flags);
@@ -286,6 +287,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
if (!CodegenUtil.isInterface(superClassDescriptor)) { if (!CodegenUtil.isInterface(superClassDescriptor)) {
superClassType = superType; superClassType = superType;
assert superClassDescriptor != null;
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
superCall = specifier; superCall = specifier;
} }
@@ -412,10 +414,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = MethodVisitor mv =
v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
PropertyGetterDescriptor getter = ((PropertyDescriptor) entry.getValue()).getGetter();
assert getter != null;
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(),
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
original, original,
((PropertyDescriptor) entry.getValue()).getGetter().getVisibility()); getter.getVisibility());
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv); StubCodegen.generateStubCode(mv);
} }
@@ -445,10 +449,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = MethodVisitor mv =
v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
PropertySetterDescriptor setter = ((PropertyDescriptor) entry.getValue()).getSetter();
assert setter != null;
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(),
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
original, original,
((PropertyDescriptor) entry.getValue()).getSetter().getVisibility()); setter.getVisibility());
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv); StubCodegen.generateStubCode(mv);
} }
@@ -506,6 +512,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
final JetClassObject classObject = getClassObject(); final JetClassObject classObject = getClassObject();
if (classObject != null) { if (classObject != null) {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
assert descriptor1 != null;
Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE).getInternalName()); Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE).getInternalName());
v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null); v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null);
@@ -513,6 +520,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override @Override
public void generate(InstructionAdapter v) { public void generate(InstructionAdapter v) {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
assert descriptor1 != null;
String name = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.IMPL).getInternalName(); String name = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.IMPL).getInternalName();
final Type classObjectType = Type.getObjectType(name); final Type classObjectType = Type.getObjectType(name);
v.anew(classObjectType); v.anew(classObjectType);
@@ -649,7 +657,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET,
((JetDelegatorToSuperCall) superCall).getCalleeExpression() ((JetDelegatorToSuperCall) superCall).getCalleeExpression()
.getConstructorReferenceExpression()); .getConstructorReferenceExpression());
if (declarationDescriptor instanceof ClassDescriptor) { if (declarationDescriptor instanceof ClassDescriptorFromSource) {
declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor(); declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor();
} }
ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor; ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor;
@@ -795,7 +803,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
k += closure.captureReceiver.getSize(); k += closure.captureReceiver.getSize();
} }
int l = 0;
for (DeclarationDescriptor varDescr : closure.closure.keySet()) { for (DeclarationDescriptor varDescr : closure.closure.keySet()) {
if (varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) { if (varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) {
Type sharedVarType = typeMapper.getSharedVarType(varDescr); Type sharedVarType = typeMapper.getSharedVarType(varDescr);
@@ -807,7 +814,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
k += StackValue.refType(sharedVarType).getSize(); k += StackValue.refType(sharedVarType).getSize();
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(),
"$" + varDescr.getName(), sharedVarType.getDescriptor()); "$" + varDescr.getName(), sharedVarType.getDescriptor());
l++;
} }
} }
} }
@@ -874,7 +880,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) { for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) {
CallableMemberDescriptor callableDescriptor = needDelegates.first;
if (needDelegates.second instanceof SimpleFunctionDescriptor) { if (needDelegates.second instanceof SimpleFunctionDescriptor) {
generateDelegationToTraitImpl((FunctionDescriptor) needDelegates.second, (FunctionDescriptor) needDelegates.first); generateDelegationToTraitImpl((FunctionDescriptor) needDelegates.second, (FunctionDescriptor) needDelegates.first);
} }
@@ -938,7 +943,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
aw.writePropertyType(jvmSignature.getKotlinReturnType()); aw.writePropertyType(jvmSignature.getKotlinReturnType());
} }
else { else {
aw.writeNullableReturnType(fun.getReturnType().isNullable()); JetType returnType = fun.getReturnType();
assert returnType != null;
aw.writeNullableReturnType(returnType.isNullable());
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
aw.writeReturnType(jvmSignature.getKotlinReturnType()); aw.writeReturnType(jvmSignature.getKotlinReturnType());
} }
@@ -1019,6 +1026,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
((JetDelegatorToSuperCall) superCall) ((JetDelegatorToSuperCall) superCall)
.getCalleeExpression() .getCalleeExpression()
.getConstructorReferenceExpression()); .getConstructorReferenceExpression());
assert superConstructor != null;
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION,
typeMapper.hasThis0(superConstructor.getContainingDeclaration())); typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
int nextVar = firstSuperArgument + 1; int nextVar = firstSuperArgument + 1;
@@ -1101,6 +1109,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext
.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); .get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
assert constructorDescriptor != null;
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper
.hasThis0(constructorDescriptor.getContainingDeclaration())); .hasThis0(constructorDescriptor.getContainingDeclaration()));
codegen.invokeMethodWithArguments(method, superCall, StackValue.none()); codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
@@ -20,6 +20,8 @@ import com.google.common.collect.Maps;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.signature.BothSignatureWriter; import org.jetbrains.jet.codegen.signature.BothSignatureWriter;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
@@ -42,12 +44,13 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames; import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames;
import org.jetbrains.jet.lang.types.lang.PrimitiveType; import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import org.jetbrains.jet.lang.types.ref.ClassName; import org.jetbrains.jet.lang.types.ref.ClassName;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.asm4.Opcodes.*;
@@ -122,6 +125,7 @@ public class JetTypeMapper {
@Nullable @Nullable
public Type get(@NotNull JetType type) { public Type get(@NotNull JetType type) {
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
assert classifier != null;
return asmTypes.get(new SpecialTypeKey(DescriptorUtils.getFQName(classifier), type.isNullable())); return asmTypes.get(new SpecialTypeKey(DescriptorUtils.getFQName(classifier), type.isNullable()));
} }
@@ -435,6 +439,7 @@ public class JetTypeMapper {
throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType); throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType);
} }
else if (kind == MapTypeMode.IMPL) { else if (kind == MapTypeMode.IMPL) {
//noinspection ConstantConditions
if (mapBuiltinsToJava) { if (mapBuiltinsToJava) {
// TODO: enable and fix tests // TODO: enable and fix tests
//throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType); //throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType);
@@ -756,7 +761,9 @@ public class JetTypeMapper {
} }
else { else {
signatureVisitor.writeReturnType(); signatureVisitor.writeReturnType();
mapReturnType(f.getReturnType(), signatureVisitor); JetType returnType = f.getReturnType();
assert returnType != null;
mapReturnType(returnType, signatureVisitor);
signatureVisitor.writeReturnTypeEnd(); signatureVisitor.writeReturnTypeEnd();
} }
return signatureVisitor.makeJvmMethodSignature(f.getName().getName()); return signatureVisitor.makeJvmMethodSignature(f.getName().getName());
@@ -847,7 +854,9 @@ public class JetTypeMapper {
signatureWriter.writeParametersEnd(); signatureWriter.writeParametersEnd();
signatureWriter.writeReturnType(); signatureWriter.writeReturnType();
mapReturnType(f.getReturnType(), signatureWriter); JetType returnType = f.getReturnType();
assert returnType != null;
mapReturnType(returnType, signatureWriter);
signatureWriter.writeReturnTypeEnd(); signatureWriter.writeReturnTypeEnd();
return signatureWriter.makeJvmMethodSignature(name.getName()); return signatureWriter.makeJvmMethodSignature(name.getName());
@@ -868,7 +877,7 @@ public class JetTypeMapper {
signatureWriter.writeParametersStart(); signatureWriter.writeParametersStart();
if (kind == OwnerKind.TRAIT_IMPL) { if (kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor; @SuppressWarnings("ConstantConditions") ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor;
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL); mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
@@ -20,12 +20,20 @@ package org.jetbrains.jet.codegen;
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
public enum MapTypeMode { public enum MapTypeMode {
/** jet.Int is mapped to Ljet/Int; */ /**
* jet.Int is mapped to Ljet/Int;
*/
IMPL, IMPL,
/** jet.Int is mapped to Ljet/Impl$TImpl; */ /**
* jet.Int is mapped to Ljet/Impl$TImpl;
*/
TRAIT_IMPL, TRAIT_IMPL,
/** jet.Int is mapped to I */ /**
* jet.Int is mapped to I
*/
VALUE, VALUE,
/** jet.Int is mapped to Ljava/lang/Integer; */ /**
* jet.Int is mapped to Ljava/lang/Integer;
*/
TYPE_PARAMETER, TYPE_PARAMETER,
} }
@@ -37,8 +37,10 @@ public class MemberCodegen {
} }
public void generateFunctionOrProperty(@NotNull JetTypeParameterListOwner functionOrProperty, public void generateFunctionOrProperty(
@NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) { @NotNull JetTypeParameterListOwner functionOrProperty,
@NotNull CodegenContext context, @NotNull ClassBuilder classBuilder
) {
FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state); FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state);
if (functionOrProperty instanceof JetNamedFunction) { if (functionOrProperty instanceof JetNamedFunction) {
try { try {
@@ -66,5 +68,4 @@ public class MemberCodegen {
throw new IllegalArgumentException("Unknown parameter: " + functionOrProperty); throw new IllegalArgumentException("Unknown parameter: " + functionOrProperty);
} }
} }
} }
@@ -18,10 +18,12 @@ package org.jetbrains.jet.codegen;
import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
@@ -32,11 +34,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.utils.Progress; import org.jetbrains.jet.utils.Progress;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.asm4.Opcodes.*;
@@ -50,9 +48,13 @@ public class NamespaceCodegen {
@NotNull private final FqName name; @NotNull private final FqName name;
private final GenerationState state; private final GenerationState state;
private final Collection<JetFile> files; private final Collection<JetFile> files;
private int nextMultiFile = 0;
public NamespaceCodegen(@NotNull ClassBuilderOnDemand v, @NotNull final FqName fqName, GenerationState state, Collection<JetFile> namespaceFiles) { public NamespaceCodegen(
@NotNull ClassBuilderOnDemand v,
@NotNull final FqName fqName,
GenerationState state,
Collection<JetFile> namespaceFiles
) {
checkAllFilesHaveSameNamespace(namespaceFiles); checkAllFilesHaveSameNamespace(namespaceFiles);
this.v = v; this.v = v;
@@ -77,7 +79,6 @@ public class NamespaceCodegen {
v.visitSource(sourceFile.getName(), null); v.visitSource(sourceFile.getName(), null);
} }
}); });
} }
public void generate(CompilationErrorHandler errorHandler, final Progress progress) { public void generate(CompilationErrorHandler errorHandler, final Progress progress) {
@@ -153,7 +154,7 @@ public class NamespaceCodegen {
String fname = containingFile.getName(); String fname = containingFile.getName();
fname = fname.substring(0, fname.lastIndexOf('.')); fname = fname.substring(0, fname.lastIndexOf('.'));
String className = name.child(Name.identifier("namespace$src$" + fname)).getFqName().replace('.', '/'); String className = name.child(Name.identifier("namespace$src$" + fname)).getFqName().replace('.', '/');
ClassBuilder builder = state.forNamespacepart(className, file); ClassBuilder builder = state.forNamespacepart(className);
builder.defineClass(containingFile, V1_6, builder.defineClass(containingFile, V1_6,
ACC_PUBLIC/*|ACC_SUPER*/, ACC_PUBLIC/*|ACC_SUPER*/,
@@ -169,11 +170,13 @@ public class NamespaceCodegen {
if (declaration instanceof JetNamedFunction) { if (declaration instanceof JetNamedFunction) {
{ {
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor); final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
state.getInjector().getMemberCodegen().generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, builder); state.getInjector().getMemberCodegen()
.generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, builder);
} }
{ {
final CodegenContext context = CodegenContexts.STATIC.intoNamespacePart(className, descriptor); final CodegenContext context = CodegenContexts.STATIC.intoNamespacePart(className, descriptor);
state.getInjector().getMemberCodegen().generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, v.getClassBuilder()); state.getInjector().getMemberCodegen()
.generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, v.getClassBuilder());
} }
} }
} }
@@ -234,7 +237,8 @@ public class NamespaceCodegen {
if (declaration instanceof JetProperty) { if (declaration instanceof JetProperty) {
final JetExpression initializer = ((JetProperty) declaration).getInitializer(); final JetExpression initializer = ((JetProperty) declaration).getInitializer();
if (initializer != null && !(initializer instanceof JetConstantExpression)) { if (initializer != null && !(initializer instanceof JetConstantExpression)) {
final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); final PropertyDescriptor descriptor =
(PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
assert descriptor != null; assert descriptor != null;
codegen.genToJVMStack(initializer); codegen.genToJVMStack(initializer);
StackValue.Property propValue = codegen.intermediateValueForProperty(descriptor, true, null); StackValue.Property propValue = codegen.intermediateValueForProperty(descriptor, true, null);
@@ -260,7 +264,6 @@ public class NamespaceCodegen {
if (initializer != null && !(initializer instanceof JetConstantExpression)) { if (initializer != null && !(initializer instanceof JetConstantExpression)) {
return true; return true;
} }
} }
} }
} }
@@ -17,13 +17,13 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@@ -40,7 +40,8 @@ public class ObjectOrClosureCodegen {
protected final CodegenContext context; protected final CodegenContext context;
protected ClassBuilder cv = null; protected ClassBuilder cv = null;
public JvmClassName name = null; public JvmClassName name = null;
protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>(); protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure =
new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
public JetDelegatorToSuperCall superCall; public JetDelegatorToSuperCall superCall;
public ObjectOrClosureCodegen(ExpressionCodegen exprContext, CodegenContext context, GenerationState state) { public ObjectOrClosureCodegen(ExpressionCodegen exprContext, CodegenContext context, GenerationState state) {
@@ -111,10 +112,12 @@ public class ObjectOrClosureCodegen {
CodegenContexts.ReceiverContext fcontext = (CodegenContexts.ReceiverContext) context; CodegenContexts.ReceiverContext fcontext = (CodegenContexts.ReceiverContext) context;
if (fcontext.getReceiverDescriptor() != fd) if (fcontext.getReceiverDescriptor() != fd) {
return null; return null;
}
Type type = state.getInjector().getJetTypeMapper().mapType(fcontext.getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE); Type type = state.getInjector().getJetTypeMapper()
.mapType(fcontext.getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE);
boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor; boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor;
StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type); StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type);
final String fieldName = "receiver$0"; final String fieldName = "receiver$0";
@@ -50,19 +50,13 @@ public class OwnerKind {
} }
public static class StaticDelegateKind extends OwnerKind { public static class StaticDelegateKind extends OwnerKind {
private final StackValue delegate;
private final String ownerClass; private final String ownerClass;
public StaticDelegateKind(StackValue delegate, String ownerClass) { public StaticDelegateKind(String ownerClass) {
super("staticDelegateKind"); super("staticDelegateKind");
this.delegate = delegate;
this.ownerClass = ownerClass; this.ownerClass = ownerClass;
} }
public StackValue getDelegate() {
return delegate;
}
public String getOwnerClass() { public String getOwnerClass() {
return ownerClass; return ownerClass;
} }
@@ -1,84 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance;
import java.util.ArrayList;
import java.util.List;
/**
* @author alex.tkachman
*
* Utility class used by back-end to
*/
public class ProjectionErasingJetType implements JetType {
private final JetType delegate;
private List<TypeProjection> arguments;
public ProjectionErasingJetType(JetType delegate) {
this.delegate = delegate;
arguments = new ArrayList<TypeProjection>();
for(TypeProjection tp : delegate.getArguments()) {
arguments.add(new TypeProjection(Variance.INVARIANT, tp.getType()));
}
}
@NotNull
@Override
public TypeConstructor getConstructor() {
return delegate.getConstructor();
}
@NotNull
@Override
public List<TypeProjection> getArguments() {
return arguments;
}
@Override
public boolean isNullable() {
return false;
}
@NotNull
@Override
public JetScope getMemberScope() {
return delegate.getMemberScope();
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
return delegate.getAnnotations();
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public boolean equals(Object obj) {
return ((obj instanceof ProjectionErasingJetType) && delegate.equals(((ProjectionErasingJetType)obj).delegate)) || delegate.equals(obj);
}
}
@@ -19,8 +19,13 @@ package org.jetbrains.jet.codegen;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.lang.descriptors.*; 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;
@@ -31,11 +36,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.BitSet; import java.util.BitSet;
@@ -63,8 +63,9 @@ public class PropertyCodegen {
} }
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL) { if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL) {
if (kind != OwnerKind.TRAIT_IMPL) if (kind != OwnerKind.TRAIT_IMPL) {
generateBackingField(p, propertyDescriptor); generateBackingField(p, propertyDescriptor);
}
generateGetter(p, propertyDescriptor); generateGetter(p, propertyDescriptor);
generateSetter(p, propertyDescriptor); generateSetter(p, propertyDescriptor);
} }
@@ -77,10 +78,12 @@ public class PropertyCodegen {
} }
public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) { public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) {
//noinspection ConstantConditions
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
if (CodegenUtil.isInterface(containingDeclaration)) if (CodegenUtil.isInterface(containingDeclaration)) {
return; return;
}
Object value = null; Object value = null;
final JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null; final JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null;
@@ -113,8 +116,10 @@ public class PropertyCodegen {
final JetPropertyAccessor getter = p.getGetter(); final JetPropertyAccessor getter = p.getGetter();
if (getter != null) { if (getter != null) {
if (getter.getBodyExpression() != null) { if (getter.getBodyExpression() != null) {
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind); JvmPropertyAccessorSignature signature =
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter()); state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind);
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
propertyDescriptor.getGetter());
} }
else if (isExternallyAccessible(propertyDescriptor)) { else if (isExternallyAccessible(propertyDescriptor)) {
generateDefaultGetter(p); generateDefaultGetter(p);
@@ -136,8 +141,11 @@ public class PropertyCodegen {
if (setter.getBodyExpression() != null) { if (setter.getBodyExpression() != null) {
final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
assert setterDescriptor != null; assert setterDescriptor != null;
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); JvmPropertyAccessorSignature signature =
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor); state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind);
assert signature != null;
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
setterDescriptor);
} }
else if (isExternallyAccessible(propertyDescriptor)) { else if (isExternallyAccessible(propertyDescriptor)) {
generateDefaultSetter(p); generateDefaultSetter(p);
@@ -151,7 +159,10 @@ public class PropertyCodegen {
private void generateDefaultGetter(JetProperty p) { private void generateDefaultGetter(JetProperty p) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p); final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
assert propertyDescriptor != null; assert propertyDescriptor != null;
int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? Opcodes.ACC_ABSTRACT : (propertyDescriptor.getModality() == Modality.FINAL ? Opcodes.ACC_FINAL : 0)); int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) |
(propertyDescriptor.getModality() == Modality.ABSTRACT
? Opcodes.ACC_ABSTRACT
: (propertyDescriptor.getModality() == Modality.FINAL ? Opcodes.ACC_FINAL : 0));
generateDefaultGetter(propertyDescriptor, flags, p); generateDefaultGetter(propertyDescriptor, flags, p);
} }
@@ -168,10 +179,12 @@ public class PropertyCodegen {
flags |= Opcodes.ACC_STATIC; flags |= Opcodes.ACC_STATIC;
} }
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration()); PsiElement psiElement =
BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration());
boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait(); boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait();
if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) {
flags |= Opcodes.ACC_ABSTRACT; flags |= Opcodes.ACC_ABSTRACT;
}
if (propertyDescriptor.getModality() == Modality.FINAL) { if (propertyDescriptor.getModality() == Modality.FINAL) {
flags |= Opcodes.ACC_FINAL; flags |= Opcodes.ACC_FINAL;
@@ -181,15 +194,17 @@ public class PropertyCodegen {
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor(); final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
String getterName = getterName(propertyDescriptor.getName()); String getterName = getterName(propertyDescriptor.getName());
MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null); MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(),
signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor, signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor,
propertyDescriptor.getGetter() == null getter == null
? propertyDescriptor.getVisibility() ? propertyDescriptor.getVisibility()
: propertyDescriptor.getGetter().getVisibility()); : getter.getVisibility());
if (propertyDescriptor.getGetter() != null) { if (getter != null) {
assert !propertyDescriptor.getGetter().hasBody(); //noinspection ConstantConditions
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor.getGetter()); assert !getter.hasBody();
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(getter);
} }
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) { if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
@@ -228,8 +243,10 @@ public class PropertyCodegen {
FunctionCodegen.endVisit(mv, "getter", origin); FunctionCodegen.endVisit(mv, "getter", origin);
} }
public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters, public static void generateJetPropertyAnnotation(
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility) { MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters,
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility
) {
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
Modality modality = propertyDescriptor.getModality(); Modality modality = propertyDescriptor.getModality();
BitSet flags = CodegenUtil.getFlagsForVisibility(visibility); BitSet flags = CodegenUtil.getFlagsForVisibility(visibility);
@@ -269,26 +286,29 @@ public class PropertyCodegen {
flags |= Opcodes.ACC_STATIC; flags |= Opcodes.ACC_STATIC;
} }
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration()); PsiElement psiElement =
BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration());
boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait(); boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait();
if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) {
flags |= Opcodes.ACC_ABSTRACT; flags |= Opcodes.ACC_ABSTRACT;
}
if (propertyDescriptor.getModality() == Modality.FINAL) { if (propertyDescriptor.getModality() == Modality.FINAL) {
flags |= Opcodes.ACC_FINAL; flags |= Opcodes.ACC_FINAL;
} }
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind);
assert signature != null;
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor(); final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null); MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null);
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
assert setter != null;
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(),
signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor, signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor,
propertyDescriptor.getSetter().getVisibility()); setter.getVisibility());
if (propertyDescriptor.getSetter() != null) { assert !setter.hasBody();
assert !propertyDescriptor.getSetter().hasBody(); AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(setter);
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor.getSetter());
}
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) { if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
if (propertyDescriptor.getModality() != Modality.ABSTRACT) { if (propertyDescriptor.getModality() != Modality.ABSTRACT) {
@@ -320,7 +340,8 @@ public class PropertyCodegen {
else { else {
iv.load(paramCode, type); iv.load(paramCode, type);
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
state.getInjector().getJetTypeMapper().getOwner(propertyDescriptor, kind).getInternalName(), propertyDescriptor.getName().getName(), state.getInjector().getJetTypeMapper().getOwner(propertyDescriptor, kind).getInternalName(),
propertyDescriptor.getName().getName(),
type.getDescriptor()); type.getDescriptor());
} }
@@ -340,11 +361,13 @@ public class PropertyCodegen {
} }
public void genDelegate(PropertyDescriptor declaration, PropertyDescriptor overriddenDescriptor, StackValue field) { public void genDelegate(PropertyDescriptor declaration, PropertyDescriptor overriddenDescriptor, StackValue field) {
JvmPropertyAccessorSignature jvmPropertyAccessorSignature = state.getInjector().getJetTypeMapper().mapGetterSignature(declaration, OwnerKind.IMPLEMENTATION); JvmPropertyAccessorSignature jvmPropertyAccessorSignature =
state.getInjector().getJetTypeMapper().mapGetterSignature(declaration, OwnerKind.IMPLEMENTATION);
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature()); functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature());
if (declaration.isVar()) { if (declaration.isVar()) {
jvmPropertyAccessorSignature = state.getInjector().getJetTypeMapper().mapSetterSignature(declaration, OwnerKind.IMPLEMENTATION); jvmPropertyAccessorSignature = state.getInjector().getJetTypeMapper().mapSetterSignature(declaration, OwnerKind.IMPLEMENTATION);
assert jvmPropertyAccessorSignature != null;
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature()); functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature());
} }
} }
@@ -19,19 +19,21 @@ package org.jetbrains.jet.codegen;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.java.JdkNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes; import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetScript;
import org.jetbrains.jet.lang.psi.JetTypeParameterListOwner;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.java.JdkNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.List; import java.util.List;
@@ -88,14 +90,15 @@ public class ScriptCodegen {
} }
public void generate(JetScript scriptDeclaration) { public void generate(JetScript scriptDeclaration) {
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration); ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
assert scriptDescriptor != null;
ClassDescriptor classDescriptorForScript = closureAnnotator.classDescriptorForScriptDescriptor(scriptDescriptor); ClassDescriptor classDescriptorForScript = closureAnnotator.classDescriptorForScriptDescriptor(scriptDescriptor);
CodegenContexts.ScriptContext context = (CodegenContexts.ScriptContext) CodegenContexts.STATIC.intoScript(scriptDescriptor, classDescriptorForScript); CodegenContexts.ScriptContext context =
(CodegenContexts.ScriptContext) CodegenContexts.STATIC.intoScript(scriptDescriptor, classDescriptorForScript);
JvmClassName className = closureAnnotator.classNameForClassDescriptor(classDescriptorForScript); JvmClassName className = closureAnnotator.classNameForClassDescriptor(classDescriptorForScript);
@@ -122,18 +125,21 @@ public class ScriptCodegen {
@NotNull ClassDescriptor classDescriptorForScript, @NotNull ClassDescriptor classDescriptorForScript,
@NotNull ClassBuilder classBuilder, @NotNull ClassBuilder classBuilder,
@NotNull CodegenContext context, @NotNull CodegenContext context,
@NotNull List<ScriptDescriptor> importedScripts) { @NotNull List<ScriptDescriptor> importedScripts
) {
Type blockType = jetTypeMapper.mapType(scriptDescriptor.getReturnType(), MapTypeMode.VALUE); Type blockType = jetTypeMapper.mapType(scriptDescriptor.getReturnType(), MapTypeMode.VALUE);
classBuilder.newField(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_FINAL, ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor(), null, null); classBuilder.newField(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME,
blockType.getDescriptor(), null, null);
JvmMethodSignature jvmSignature = jetTypeMapper.mapScriptSignature(scriptDescriptor, importedScripts); JvmMethodSignature jvmSignature = jetTypeMapper.mapScriptSignature(scriptDescriptor, importedScripts);
state.setScriptConstructorMethod(jvmSignature.getAsmMethod()); state.setScriptConstructorMethod(jvmSignature.getAsmMethod());
MethodVisitor mv = classBuilder.newMethod( MethodVisitor mv = classBuilder.newMethod(
scriptDeclaration, Opcodes.ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), null, null); scriptDeclaration, Opcodes.ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(),
null, null);
mv.visitCode(); mv.visitCode();
@@ -174,7 +180,8 @@ public class ScriptCodegen {
instructionAdapter.load(0, className.getAsmType()); instructionAdapter.load(0, className.getAsmType());
instructionAdapter.load(offset, earlierClassName.getAsmType()); instructionAdapter.load(offset, earlierClassName.getAsmType());
offset += earlierClassName.getAsmType().getSize(); offset += earlierClassName.getAsmType().getSize();
instructionAdapter.putfield(className.getInternalName(), getScriptFieldName(earlierScript), earlierClassName.getAsmType().getDescriptor()); instructionAdapter.putfield(className.getInternalName(), getScriptFieldName(earlierScript),
earlierClassName.getAsmType().getDescriptor());
} }
for (ValueParameterDescriptor parameter : scriptDescriptor.getValueParameters()) { for (ValueParameterDescriptor parameter : scriptDescriptor.getValueParameters()) {
@@ -185,10 +192,12 @@ public class ScriptCodegen {
instructionAdapter.putfield(className.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor()); instructionAdapter.putfield(className.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor());
} }
StackValue stackValue = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression()); StackValue stackValue =
new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression());
if (stackValue.type != Type.VOID_TYPE) { if (stackValue.type != Type.VOID_TYPE) {
stackValue.put(stackValue.type, instructionAdapter); stackValue.put(stackValue.type, instructionAdapter);
instructionAdapter.putfield(className.getInternalName(), ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor()); instructionAdapter
.putfield(className.getInternalName(), ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor());
} }
instructionAdapter.areturn(Type.VOID_TYPE); instructionAdapter.areturn(Type.VOID_TYPE);
@@ -227,7 +236,6 @@ public class ScriptCodegen {
List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList(); List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList();
for (Pair<ScriptDescriptor, JvmClassName> t : earlierScripts) { for (Pair<ScriptDescriptor, JvmClassName> t : earlierScripts) {
ScriptDescriptor earlierDescriptor = t.first; ScriptDescriptor earlierDescriptor = t.first;
JvmClassName earlierClassName = t.second;
earlierScriptDescriptors.add(earlierDescriptor); earlierScriptDescriptors.add(earlierDescriptor);
} }
this.earlierScripts = earlierScriptDescriptors; this.earlierScripts = earlierScriptDescriptors;
@@ -19,6 +19,11 @@ package org.jetbrains.jet.codegen;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
@@ -27,11 +32,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import java.util.List; import java.util.List;
@@ -130,7 +130,13 @@ public abstract class StackValue {
return new ArrayElement(type, unbox); return new ArrayElement(type, unbox);
} }
public static StackValue collectionElement(Type type, ResolvedCall<FunctionDescriptor> getter, ResolvedCall<FunctionDescriptor> setter, ExpressionCodegen codegen, GenerationState state) { public static StackValue collectionElement(
Type type,
ResolvedCall<FunctionDescriptor> getter,
ResolvedCall<FunctionDescriptor> setter,
ExpressionCodegen codegen,
GenerationState state
) {
return new CollectionElement(type, getter, setter, codegen, state); return new CollectionElement(type, getter, setter, codegen, state);
} }
@@ -138,7 +144,18 @@ public abstract class StackValue {
return new Field(type, owner, name, isStatic); return new Field(type, owner, name, isStatic);
} }
public static Property property(String name, JvmClassName methodOwner, JvmClassName methodOwnerParam, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter, int invokeOpcode) { public static Property property(
String name,
JvmClassName methodOwner,
JvmClassName methodOwnerParam,
Type type,
boolean isStatic,
boolean isInterface,
boolean isSuper,
@Nullable Method getter,
@Nullable Method setter,
int invokeOpcode
) {
return new Property(name, methodOwner, methodOwnerParam, getter, setter, isStatic, isInterface, isSuper, type, invokeOpcode); return new Property(name, methodOwner, methodOwnerParam, getter, setter, isStatic, isInterface, isSuper, type, invokeOpcode);
} }
@@ -213,11 +230,13 @@ public abstract class StackValue {
} }
protected static void pop(Type type, InstructionAdapter v) { protected static void pop(Type type, InstructionAdapter v) {
if (type.getSize() == 1) if (type.getSize() == 1) {
v.pop(); v.pop();
else }
else {
v.pop2(); v.pop2();
} }
}
protected void coerce(Type toType, InstructionAdapter v) { protected void coerce(Type toType, InstructionAdapter v) {
coerce(this.type, toType, v); coerce(this.type, toType, v);
@@ -233,15 +252,19 @@ public abstract class StackValue {
if (toType.getSort() == Type.OBJECT) { if (toType.getSort() == Type.OBJECT) {
putTuple0Instance(v); putTuple0Instance(v);
} }
else if (toType == Type.LONG_TYPE) else if (toType == Type.LONG_TYPE) {
v.lconst(0); v.lconst(0);
else if (toType == Type.FLOAT_TYPE) }
else if (toType == Type.FLOAT_TYPE) {
v.fconst(0); v.fconst(0);
else if (toType == Type.DOUBLE_TYPE) }
else if (toType == Type.DOUBLE_TYPE) {
v.dconst(0); v.dconst(0);
else }
else {
v.iconst(0); v.iconst(0);
} }
}
else if (toType.equals(JetTypeMapper.TUPLE0_TYPE) && !fromType.equals(JetTypeMapper.TUPLE0_TYPE)) { else if (toType.equals(JetTypeMapper.TUPLE0_TYPE) && !fromType.equals(JetTypeMapper.TUPLE0_TYPE)) {
pop(fromType, v); pop(fromType, v);
putTuple0Instance(v); putTuple0Instance(v);
@@ -253,9 +276,10 @@ public abstract class StackValue {
if (fromType.getSort() == Type.OBJECT && !toType.equals(JetTypeMapper.TYPE_OBJECT)) { if (fromType.getSort() == Type.OBJECT && !toType.equals(JetTypeMapper.TYPE_OBJECT)) {
v.checkcast(toType); v.checkcast(toType);
} }
else else {
box(fromType, toType, v); box(fromType, toType, v);
} }
}
else if (fromType.getSort() == Type.OBJECT && toType.getSort() <= Type.DOUBLE) { else if (fromType.getSort() == Type.OBJECT && toType.getSort() <= Type.DOUBLE) {
if (fromType.equals(JetTypeMapper.TYPE_OBJECT)) { if (fromType.equals(JetTypeMapper.TYPE_OBJECT)) {
if (toType.getSort() == Type.BOOLEAN) { if (toType.getSort() == Type.BOOLEAN) {
@@ -314,14 +338,22 @@ public abstract class StackValue {
return new PreIncrement(index, increment); return new PreIncrement(index, increment);
} }
public static StackValue receiver(ResolvedCall<? extends CallableDescriptor> resolvedCall, StackValue receiver, ExpressionCodegen codegen, @Nullable CallableMethod callableMethod, GenerationState state) { public static StackValue receiver(
if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists()) ResolvedCall<? extends CallableDescriptor> resolvedCall,
StackValue receiver,
ExpressionCodegen codegen,
@Nullable CallableMethod callableMethod,
GenerationState state
) {
if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists()) {
return new CallReceiver(resolvedCall, receiver, codegen, state, callableMethod); return new CallReceiver(resolvedCall, receiver, codegen, state, callableMethod);
}
return receiver; return receiver;
} }
private static class None extends StackValue { private static class None extends StackValue {
public static None INSTANCE = new None(); public static None INSTANCE = new None();
private None() { private None() {
super(Type.VOID_TYPE); super(Type.VOID_TYPE);
} }
@@ -396,19 +428,21 @@ public abstract class StackValue {
@Override @Override
public void put(Type type, InstructionAdapter v) { public void put(Type type, InstructionAdapter v) {
if (value instanceof Integer) if (value instanceof Integer) {
v.iconst((Integer) value); v.iconst((Integer) value);
else }
if (value instanceof Long) else if (value instanceof Long) {
v.lconst((Long) value); v.lconst((Long) value);
else }
if (value instanceof Float) else if (value instanceof Float) {
v.fconst((Float) value); v.fconst((Float) value);
else }
if (value instanceof Double) else if (value instanceof Double) {
v.dconst((Double) value); v.dconst((Double) value);
else }
else {
v.aconst(value); v.aconst(value);
}
coerce(type, v); coerce(type, v);
} }
@@ -449,9 +483,10 @@ public abstract class StackValue {
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type " + type); throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type " + type);
} }
putAsBoolean(v); putAsBoolean(v);
if(type != Type.BOOLEAN_TYPE) if (type != Type.BOOLEAN_TYPE) {
box(Type.BOOLEAN_TYPE, type, v); box(Type.BOOLEAN_TYPE, type, v);
} }
}
@Override @Override
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) { public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
@@ -522,9 +557,10 @@ public abstract class StackValue {
private Invert(StackValue operand) { private Invert(StackValue operand) {
super(Type.BOOLEAN_TYPE); super(Type.BOOLEAN_TYPE);
myOperand = operand; myOperand = operand;
if (myOperand.type != Type.BOOLEAN_TYPE) if (myOperand.type != Type.BOOLEAN_TYPE) {
throw new UnsupportedOperationException("operand of ! must be boolean"); throw new UnsupportedOperationException("operand of ! must be boolean");
} }
}
@Override @Override
public void put(Type type, InstructionAdapter v) { public void put(Type type, InstructionAdapter v) {
@@ -536,9 +572,10 @@ public abstract class StackValue {
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type"); throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
} }
putAsBoolean(v); putAsBoolean(v);
if(type != Type.BOOLEAN_TYPE) if (type != Type.BOOLEAN_TYPE) {
box(Type.BOOLEAN_TYPE, type, v); box(Type.BOOLEAN_TYPE, type, v);
} }
}
@Override @Override
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) { public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
@@ -571,6 +608,7 @@ public abstract class StackValue {
v.dup2(); // array and index v.dup2(); // array and index
} }
@Override
public int receiverSize() { public int receiverSize() {
return 2; return 2;
} }
@@ -587,7 +625,13 @@ public abstract class StackValue {
private final FunctionDescriptor setterDescriptor; private final FunctionDescriptor setterDescriptor;
private final FunctionDescriptor getterDescriptor; private final FunctionDescriptor getterDescriptor;
public CollectionElement(Type type, ResolvedCall<FunctionDescriptor> resolvedGetCall, ResolvedCall<FunctionDescriptor> resolvedSetCall, ExpressionCodegen codegen, GenerationState state) { public CollectionElement(
Type type,
ResolvedCall<FunctionDescriptor> resolvedGetCall,
ResolvedCall<FunctionDescriptor> resolvedSetCall,
ExpressionCodegen codegen,
GenerationState state
) {
super(type); super(type);
this.resolvedGetCall = resolvedGetCall; this.resolvedGetCall = resolvedGetCall;
this.resolvedSetCall = resolvedSetCall; this.resolvedSetCall = resolvedSetCall;
@@ -605,10 +649,12 @@ public abstract class StackValue {
if (getter == null) { if (getter == null) {
throw new UnsupportedOperationException("no getter specified"); throw new UnsupportedOperationException("no getter specified");
} }
if (getter instanceof CallableMethod) if (getter instanceof CallableMethod) {
((CallableMethod) getter).invoke(v); ((CallableMethod) getter).invoke(v);
else }
else {
((IntrinsicMethod) getter).generate(codegen, v, type, null, null, null, state); ((IntrinsicMethod) getter).generate(codegen, v, type, null, null, null, state);
}
coerce(type, v); coerce(type, v);
} }
@@ -628,10 +674,12 @@ public abstract class StackValue {
pop(returnType, v); pop(returnType, v);
} }
} }
else else {
((IntrinsicMethod) setter).generate(codegen, v, null, null, null, null, state); ((IntrinsicMethod) setter).generate(codegen, v, null, null, null, null, state);
} }
}
@Override
public int receiverSize() { public int receiverSize() {
if (isStandardStack(resolvedGetCall, 1) && isStandardStack(resolvedSetCall, 2)) { if (isStandardStack(resolvedGetCall, 1) && isStandardStack(resolvedSetCall, 2)) {
return 2; return 2;
@@ -774,31 +822,38 @@ public abstract class StackValue {
} }
private boolean isStandardStack(ResolvedCall call, int valueParamsSize) { private boolean isStandardStack(ResolvedCall call, int valueParamsSize) {
if (call == null) if (call == null) {
return true; return true;
}
for (TypeParameterDescriptor typeParameterDescriptor : call.getResultingDescriptor().getTypeParameters()) { for (TypeParameterDescriptor typeParameterDescriptor : call.getResultingDescriptor().getTypeParameters()) {
if (typeParameterDescriptor.isReified()) if (typeParameterDescriptor.isReified()) {
return false; return false;
} }
}
List<ValueParameterDescriptor> valueParameters = call.getResultingDescriptor().getValueParameters(); List<ValueParameterDescriptor> valueParameters = call.getResultingDescriptor().getValueParameters();
if (valueParameters.size() != valueParamsSize) if (valueParameters.size() != valueParamsSize) {
return false; return false;
}
for (ValueParameterDescriptor valueParameter : valueParameters) { for (ValueParameterDescriptor valueParameter : valueParameters) {
if (codegen.typeMapper.mapType(valueParameter.getType(), MapTypeMode.VALUE).getSize() != 1) if (codegen.typeMapper.mapType(valueParameter.getType(), MapTypeMode.VALUE).getSize() != 1) {
return false; return false;
} }
}
if (call.getThisObject().exists()) { if (call.getThisObject().exists()) {
if (call.getReceiverArgument().exists()) if (call.getReceiverArgument().exists()) {
return false; return false;
} }
}
else { else {
if (codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE).getSize() != 1) if (codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE)
.getSize() != 1) {
return false; return false;
} }
}
return true; return true;
} }
@@ -830,6 +885,7 @@ public abstract class StackValue {
} }
} }
@Override
public int receiverSize() { public int receiverSize() {
return isStatic ? 0 : 1; return isStatic ? 0 : 1;
} }
@@ -857,8 +913,10 @@ public abstract class StackValue {
private final boolean isSuper; private final boolean isSuper;
private final int invokeOpcode; private final int invokeOpcode;
public Property(@NotNull String name, @NotNull JvmClassName methodOwner, @NotNull JvmClassName methodOwnerParam, public Property(
Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type, int invokeOpcode) { @NotNull String name, @NotNull JvmClassName methodOwner, @NotNull JvmClassName methodOwnerParam,
Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type, int invokeOpcode
) {
super(type); super(type);
this.name = name; this.name = name;
this.methodOwner = methodOwner; this.methodOwner = methodOwner;
@@ -879,11 +937,14 @@ public abstract class StackValue {
@Override @Override
public void put(Type type, InstructionAdapter v) { public void put(Type type, InstructionAdapter v) {
if (isSuper && isInterface) { if (isSuper && isInterface) {
v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor())); assert getter != null;
v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), getter.getName(),
getter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor()));
} }
else { else {
if (getter == null) { if (getter == null) {
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner.getInternalName(), name, this.type.getDescriptor()); v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner.getInternalName(), name,
this.type.getDescriptor());
} }
else { else {
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor()); v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
@@ -895,10 +956,13 @@ public abstract class StackValue {
@Override @Override
public void store(Type topOfStackType, InstructionAdapter v) { public void store(Type topOfStackType, InstructionAdapter v) {
if (isSuper && isInterface) { if (isSuper && isInterface) {
v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor())); assert setter != null;
v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), setter.getName(),
setter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor()));
} }
else if (setter == null) { else if (setter == null) {
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, methodOwner.getInternalName(), name, this.type.getDescriptor()); v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, methodOwner.getInternalName(), name,
this.type.getDescriptor());
} }
else { else {
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor()); v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor());
@@ -912,6 +976,7 @@ public abstract class StackValue {
} }
} }
@Override
public int receiverSize() { public int receiverSize() {
return isStatic ? 0 : 1; return isStatic ? 0 : 1;
} }
@@ -1010,8 +1075,9 @@ public abstract class StackValue {
} }
public static Type refType(Type type) { public static Type refType(Type type) {
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
return JetTypeMapper.TYPE_OBJECT; return JetTypeMapper.TYPE_OBJECT;
}
return type; return type;
} }
@@ -1031,6 +1097,7 @@ public abstract class StackValue {
v.dup(); v.dup();
} }
@Override
public int receiverSize() { public int receiverSize() {
return 1; return 1;
} }
@@ -1135,20 +1202,27 @@ public abstract class StackValue {
private ResolvedCall<? extends CallableDescriptor> resolvedCall; private ResolvedCall<? extends CallableDescriptor> resolvedCall;
StackValue receiver; StackValue receiver;
private ExpressionCodegen codegen; private ExpressionCodegen codegen;
@NotNull
private final GenerationState state;
private CallableMethod callableMethod; private CallableMethod callableMethod;
public CallReceiver(ResolvedCall<? extends CallableDescriptor> resolvedCall, StackValue receiver, ExpressionCodegen codegen, @NotNull GenerationState state, CallableMethod callableMethod) { public CallReceiver(
ResolvedCall<? extends CallableDescriptor> resolvedCall,
StackValue receiver,
ExpressionCodegen codegen,
@NotNull GenerationState state,
CallableMethod callableMethod
) {
super(calcType(resolvedCall, codegen, callableMethod)); super(calcType(resolvedCall, codegen, callableMethod));
this.resolvedCall = resolvedCall; this.resolvedCall = resolvedCall;
this.receiver = receiver; this.receiver = receiver;
this.codegen = codegen; this.codegen = codegen;
this.state = state;
this.callableMethod = callableMethod; this.callableMethod = callableMethod;
} }
private static Type calcType(ResolvedCall<? extends CallableDescriptor> resolvedCall, ExpressionCodegen codegen, CallableMethod callableMethod) { private static Type calcType(
ResolvedCall<? extends CallableDescriptor> resolvedCall,
ExpressionCodegen codegen,
CallableMethod callableMethod
) {
ReceiverDescriptor thisObject = resolvedCall.getThisObject(); ReceiverDescriptor thisObject = resolvedCall.getThisObject();
ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument(); ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument();
@@ -1174,11 +1248,13 @@ public abstract class StackValue {
} }
else { else {
if (receiverArgument.exists()) { if (receiverArgument.exists()) {
if (callableMethod != null) if (callableMethod != null) {
return callableMethod.getReceiverClass(); return callableMethod.getReceiverClass();
else }
else {
return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE); return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE);
} }
}
else { else {
return Type.VOID_TYPE; return Type.VOID_TYPE;
} }
@@ -1197,7 +1273,8 @@ public abstract class StackValue {
codegen.generateFromResolvedCall(thisObject, callableMethod.getOwner().getAsmType()); codegen.generateFromResolvedCall(thisObject, callableMethod.getOwner().getAsmType());
} }
else { else {
codegen.generateFromResolvedCall(thisObject, codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE)); codegen.generateFromResolvedCall(thisObject, codegen.typeMapper
.mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE));
} }
genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter(), 1); genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter(), 1);
} }
@@ -1212,8 +1289,10 @@ public abstract class StackValue {
} }
} }
private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, private void genReceiver(
@Nullable ReceiverDescriptor receiverParameter, int depth) { InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type,
@Nullable ReceiverDescriptor receiverParameter, int depth
) {
if (receiver == StackValue.none()) { if (receiver == StackValue.none()) {
if (receiverParameter != null) { if (receiverParameter != null) {
Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
@@ -28,11 +28,12 @@ public class StubCodegen {
} }
public static void generateStubThrow(MethodVisitor mv) { public static void generateStubThrow(MethodVisitor mv) {
new InstructionAdapter(mv).anew(Type.getObjectType("java/lang/RuntimeException")); InstructionAdapter iv = new InstructionAdapter(mv);
new InstructionAdapter(mv).dup(); iv.anew(Type.getObjectType("java/lang/RuntimeException"));
new InstructionAdapter(mv).aconst("Stubs are for compiler only, do not add them to runtime classpath"); iv.dup();
new InstructionAdapter(mv).invokespecial("java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V"); iv.aconst("Stubs are for compiler only, do not add them to runtime classpath");
new InstructionAdapter(mv).athrow(); iv.invokespecial("java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
iv.athrow();
} }
public static void generateStubCode(MethodVisitor mv) { public static void generateStubCode(MethodVisitor mv) {
@@ -16,13 +16,13 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.asm4.Opcodes;
import java.util.List; import java.util.List;
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class ArrayGet implements IntrinsicMethod { public class ArrayGet implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
Type type = JetTypeMapper.correctElementType(receiver.type); Type type = JetTypeMapper.correctElementType(receiver.type);
@@ -18,19 +18,27 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
public class ArrayIndices implements IntrinsicMethod { public class ArrayIndices implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.arraylength(); v.arraylength();
v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;"); v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;");
@@ -41,10 +41,20 @@ import java.util.List;
*/ */
public class ArrayIterator implements IntrinsicMethod { public class ArrayIterator implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
JetCallExpression call = (JetCallExpression) element; JetCallExpression call = (JetCallExpression) element;
FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext().get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression()); FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext()
.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression());
assert funDescriptor != null;
ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal(); ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal();
if (JetStandardLibraryNames.ARRAY.is(containingDeclaration)) { if (JetStandardLibraryNames.ARRAY.is(containingDeclaration)) {
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;)Ljet/Iterator;"); v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;)Ljet/Iterator;");
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class ArraySet implements IntrinsicMethod { public class ArraySet implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
Type type = JetTypeMapper.correctElementType(receiver.type); Type type = JetTypeMapper.correctElementType(receiver.type);
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class ArraySize implements IntrinsicMethod { public class ArraySize implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.arraylength(); v.arraylength();
@@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -40,7 +40,15 @@ public class BinaryOp implements IntrinsicMethod {
} }
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
boolean nullable = expectedType.getSort() == Type.OBJECT; boolean nullable = expectedType.getSort() == Type.OBJECT;
if (nullable) { if (nullable) {
expectedType = JetTypeMapper.unboxType(expectedType); expectedType = JetTypeMapper.unboxType(expectedType);
@@ -19,12 +19,12 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,12 +33,21 @@ import java.util.List;
*/ */
public class CompareTo implements IntrinsicMethod { public class CompareTo implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
assert arguments != null; assert arguments != null;
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
codegen.gen(arguments.get(0), receiver.type); codegen.gen(arguments.get(0), receiver.type);
if (receiver.type == Type.BYTE_TYPE || receiver.type == Type.SHORT_TYPE || receiver.type == Type.CHAR_TYPE) if (receiver.type == Type.BYTE_TYPE || receiver.type == Type.SHORT_TYPE || receiver.type == Type.CHAR_TYPE) {
v.sub(Type.INT_TYPE); v.sub(Type.INT_TYPE);
}
else if (receiver.type == Type.INT_TYPE) { else if (receiver.type == Type.INT_TYPE) {
v.invokestatic("jet/runtime/Intrinsics", "compare", "(II)I"); v.invokestatic("jet/runtime/Intrinsics", "compare", "(II)I");
} }
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class Concat implements IntrinsicMethod { public class Concat implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
if (receiver == null || receiver == StackValue.none()) { // LHS + RHS if (receiver == null || receiver == StackValue.none()) { // LHS + RHS
codegen.generateStringBuilderConstructor(); codegen.generateStringBuilderConstructor();
codegen.invokeAppend(arguments.get(0)); // StringBuilder(LHS) codegen.invokeAppend(arguments.get(0)); // StringBuilder(LHS)
@@ -42,13 +42,15 @@ public class EmptyRange implements IntrinsicMethod {
} }
@Override @Override
public StackValue generate(ExpressionCodegen codegen, public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v, InstructionAdapter v,
@NotNull Type expectedType, @NotNull Type expectedType,
@Nullable PsiElement element, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, @Nullable List<JetExpression> arguments,
StackValue receiver, StackValue receiver,
@NotNull GenerationState state) { @NotNull GenerationState state
) {
JvmClassName name = JvmClassName.byFqNameWithoutInnerClasses(elementType.getRangeClassName().getFqName()); JvmClassName name = JvmClassName.byFqNameWithoutInnerClasses(elementType.getRangeClassName().getFqName());
v.getstatic(name.toString(), "EMPTY", "L" + name + ";"); v.getstatic(name.toString(), "EMPTY", "L" + name + ";");
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
@@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.types.JetType;
import java.util.List; import java.util.List;
@@ -36,13 +36,20 @@ import java.util.List;
*/ */
public class EnumValueOf implements IntrinsicMethod { public class EnumValueOf implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, public StackValue generate(
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state
) {
JetCallExpression call = (JetCallExpression) element; JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall =
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
assert resolvedCall != null;
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
JetType returnType = resultingDescriptor.getReturnType();
assert returnType != null;
Type type = state.getInjector().getJetTypeMapper().mapType( Type type = state.getInjector().getJetTypeMapper().mapType(
resultingDescriptor.getReturnType(), MapTypeMode.VALUE); returnType, MapTypeMode.VALUE);
assert arguments != null;
codegen.gen(arguments.get(0), JetTypeMapper.JL_STRING_TYPE); codegen.gen(arguments.get(0), JetTypeMapper.JL_STRING_TYPE);
v.invokestatic(type.getInternalName(), "valueOf", "(Ljava/lang/String;)" + type.getDescriptor()); v.invokestatic(type.getInternalName(), "valueOf", "(Ljava/lang/String;)" + type.getDescriptor());
StackValue.onStack(type).put(expectedType, v); StackValue.onStack(type).put(expectedType, v);
@@ -21,12 +21,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.MapTypeMode;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List; import java.util.List;
@@ -35,13 +39,19 @@ import java.util.List;
*/ */
public class EnumValues implements IntrinsicMethod { public class EnumValues implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, public StackValue generate(
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state
) {
JetCallExpression call = (JetCallExpression) element; JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall =
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
assert resolvedCall != null;
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
JetType returnType = resultingDescriptor.getReturnType();
assert returnType != null;
Type type = state.getInjector().getJetTypeMapper().mapType( Type type = state.getInjector().getJetTypeMapper().mapType(
resultingDescriptor.getReturnType(), MapTypeMode.VALUE); returnType, MapTypeMode.VALUE);
v.invokestatic(type.getElementType().getInternalName(), "values", "()" + type); v.invokestatic(type.getElementType().getInternalName(), "values", "()" + type);
StackValue.onStack(type).put(expectedType, v); StackValue.onStack(type).put(expectedType, v);
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
@@ -27,8 +29,6 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -37,7 +37,15 @@ import java.util.List;
*/ */
public class Equals implements IntrinsicMethod { public class Equals implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
boolean leftNullable = true; boolean leftNullable = true;
JetExpression rightExpr; JetExpression rightExpr;
@@ -47,14 +55,17 @@ public class Equals implements IntrinsicMethod {
JetExpression calleeExpression = jetCallExpression.getCalleeExpression(); JetExpression calleeExpression = jetCallExpression.getCalleeExpression();
if (calleeExpression != null) { if (calleeExpression != null) {
JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression); JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression);
if (leftType != null) if (leftType != null) {
leftNullable = leftType.isNullable(); leftNullable = leftType.isNullable();
} }
}
rightExpr = arguments.get(0); rightExpr = arguments.get(0);
} }
else { else {
JetExpression leftExpr = arguments.get(0); JetExpression leftExpr = arguments.get(0);
leftNullable = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, leftExpr).isNullable(); JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, leftExpr);
assert leftType != null;
leftNullable = leftType.isNullable();
codegen.gen(leftExpr).put(JetTypeMapper.TYPE_OBJECT, v); codegen.gen(leftExpr).put(JetTypeMapper.TYPE_OBJECT, v);
rightExpr = arguments.get(1); rightExpr = arguments.get(1);
} }
@@ -62,6 +73,9 @@ public class Equals implements IntrinsicMethod {
JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr); JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr);
codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v); codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v);
return codegen.generateEqualsForExpressionsOnStack(JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, rightType.isNullable()); assert rightType != null;
return codegen
.generateEqualsForExpressionsOnStack(JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable,
rightType.isNullable());
} }
} }
@@ -35,13 +35,15 @@ import java.util.List;
*/ */
public class HashCode implements IntrinsicMethod { public class HashCode implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v, InstructionAdapter v,
@NotNull Type expectedType, @NotNull Type expectedType,
@Nullable PsiElement element, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, @Nullable List<JetExpression> arguments,
StackValue receiver, StackValue receiver,
@NotNull GenerationState state) { @NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I"); v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I");
return StackValue.onStack(Type.INT_TYPE); return StackValue.onStack(Type.INT_TYPE);
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
@@ -25,11 +27,7 @@ import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -38,7 +36,15 @@ import java.util.List;
*/ */
public class IdentityEquals implements IntrinsicMethod { public class IdentityEquals implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
if (element instanceof JetCallExpression) { if (element instanceof JetCallExpression) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
codegen.gen(arguments.get(0)).put(JetTypeMapper.TYPE_OBJECT, v); codegen.gen(arguments.get(0)).put(JetTypeMapper.TYPE_OBJECT, v);
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
@@ -25,8 +27,6 @@ import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetParenthesizedExpression; import org.jetbrains.jet.lang.psi.JetParenthesizedExpression;
import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -41,7 +41,15 @@ public class Increment implements IntrinsicMethod {
} }
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
boolean nullable = expectedType.getSort() == Type.OBJECT; boolean nullable = expectedType.getSort() == Type.OBJECT;
if (nullable) { if (nullable) {
expectedType = JetTypeMapper.unboxType(expectedType); expectedType = JetTypeMapper.unboxType(expectedType);
@@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.Callable; import org.jetbrains.jet.codegen.Callable;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,6 +33,8 @@ import java.util.List;
* @author yole * @author yole
*/ */
public interface IntrinsicMethod extends Callable { public interface IntrinsicMethod extends Callable {
StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, StackValue generate(
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state); ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, @Nullable StackValue receiver, @NotNull GenerationState state
);
} }
@@ -20,10 +20,7 @@ import com.google.common.collect.ImmutableList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Opcodes; import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
@@ -196,20 +193,6 @@ public class IntrinsicMethods {
intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME.child(className), functionName, arity, implementation); intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME.child(className), functionName, arity, implementation);
} }
public IntrinsicMethod isIntrinsicMethod(DeclarationDescriptor descriptor) {
List<AnnotationDescriptor> annotations = descriptor.getAnnotations();
if (annotations != null) {
for (AnnotationDescriptor annotation : annotations) {
if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) {
String value = (String) annotation.getValueArguments().get(0).getValue();
IntrinsicMethod intrinsicMethod = namedMethods.get(value);
if (intrinsicMethod != null) { return intrinsicMethod; }
}
}
}
return null;
}
@Nullable @Nullable
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) { public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
IntrinsicMethod intrinsicMethod = intrinsicsMap.getIntrinsic(descriptor); IntrinsicMethod intrinsicMethod = intrinsicsMap.getIntrinsic(descriptor);
@@ -239,10 +222,14 @@ public class IntrinsicMethods {
List<AnnotationDescriptor> annotations = descriptor.getAnnotations(); List<AnnotationDescriptor> annotations = descriptor.getAnnotations();
if (annotations != null) { if (annotations != null) {
for (AnnotationDescriptor annotation : annotations) { for (AnnotationDescriptor annotation : annotations) {
if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) { ClassifierDescriptor classifierDescriptor = annotation.getType().getConstructor().getDeclarationDescriptor();
assert classifierDescriptor != null;
if ("Intrinsic".equals(classifierDescriptor.getName().getName())) {
String value = (String) annotation.getValueArguments().get(0).getValue(); String value = (String) annotation.getValueArguments().get(0).getValue();
intrinsicMethod = namedMethods.get(value); intrinsicMethod = namedMethods.get(value);
if (intrinsicMethod != null) { break; } if (intrinsicMethod != null) {
break;
}
} }
} }
} }
@@ -255,11 +242,13 @@ public class IntrinsicMethods {
if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) { if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
//noinspection ConstantConditions //noinspection ConstantConditions
if(containingDeclaration != null && containingDeclaration.getClassObjectDescriptor() != null && containingDeclaration.getClassObjectDescriptor().equals(descriptor)) { if (containingDeclaration != null &&
containingDeclaration.getClassObjectDescriptor() != null &&
containingDeclaration.getClassObjectDescriptor().equals(descriptor)) {
return true; return true;
} }
} }
} }
return false; //To change body of created methods use File | Settings | File Templates. return false;
} }
} }
@@ -70,7 +70,7 @@ class IntrinsicsMap {
} }
} }
private int valueParameterCountForKey(@NotNull CallableMemberDescriptor member) { private static int valueParameterCountForKey(@NotNull CallableMemberDescriptor member) {
if (member instanceof PropertyDescriptor) { if (member instanceof PropertyDescriptor) {
return -1; return -1;
} }
@@ -79,7 +79,7 @@ class IntrinsicsMap {
} }
} }
private Map<Key, IntrinsicMethod> intrinsicsMap = Maps.newHashMap(); private final Map<Key, IntrinsicMethod> intrinsicsMap = Maps.newHashMap();
/** /**
@@ -105,5 +105,4 @@ class IntrinsicsMap {
valueParameterCountForKey(descriptor)); valueParameterCountForKey(descriptor));
return intrinsicsMap.get(key); return intrinsicsMap.get(key);
} }
} }
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -34,7 +34,15 @@ import java.util.List;
*/ */
public class Inv implements IntrinsicMethod { public class Inv implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
boolean nullable = expectedType.getSort() == Type.OBJECT; boolean nullable = expectedType.getSort() == Type.OBJECT;
if (nullable) { if (nullable) {
expectedType = JetTypeMapper.unboxType(expectedType); expectedType = JetTypeMapper.unboxType(expectedType);
@@ -19,12 +19,12 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class IteratorIterator implements IntrinsicMethod { public class IteratorIterator implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
return receiver; return receiver;
} }
} }
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,26 +33,43 @@ import java.util.List;
*/ */
public class IteratorNext implements IntrinsicMethod { public class IteratorNext implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
String name; String name;
if (expectedType == Type.CHAR_TYPE) if (expectedType == Type.CHAR_TYPE) {
name = "Char"; name = "Char";
else if (expectedType == Type.BOOLEAN_TYPE) }
else if (expectedType == Type.BOOLEAN_TYPE) {
name = "Boolean"; name = "Boolean";
else if (expectedType == Type.BYTE_TYPE) }
else if (expectedType == Type.BYTE_TYPE) {
name = "Byte"; name = "Byte";
else if (expectedType == Type.SHORT_TYPE) }
else if (expectedType == Type.SHORT_TYPE) {
name = "Short"; name = "Short";
else if (expectedType == Type.INT_TYPE) }
else if (expectedType == Type.INT_TYPE) {
name = "Int"; name = "Int";
else if (expectedType == Type.LONG_TYPE) }
else if (expectedType == Type.LONG_TYPE) {
name = "Long"; name = "Long";
else if (expectedType == Type.FLOAT_TYPE) }
else if (expectedType == Type.FLOAT_TYPE) {
name = "Float"; name = "Float";
else if (expectedType == Type.DOUBLE_TYPE) }
else if (expectedType == Type.DOUBLE_TYPE) {
name = "Double"; name = "Double";
else }
else {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
}
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokevirtual("jet/" + name + "Iterator", "next" + name, "()" + expectedType.getDescriptor()); v.invokevirtual("jet/" + name + "Iterator", "next" + name, "()" + expectedType.getDescriptor());
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
@@ -19,6 +19,8 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
@@ -30,8 +32,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.VarargValueArgument; import org.jetbrains.jet.lang.resolve.calls.VarargValueArgument;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -41,15 +41,18 @@ import java.util.Map;
*/ */
public class JavaClassArray implements IntrinsicMethod { public class JavaClassArray implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v, InstructionAdapter v,
@NotNull Type expectedType, @NotNull Type expectedType,
@Nullable PsiElement element, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, @Nullable List<JetExpression> arguments,
StackValue receiver, StackValue receiver,
@NotNull GenerationState state) { @NotNull GenerationState state
) {
ResolvedCall<? extends CallableDescriptor> call = ResolvedCall<? extends CallableDescriptor> call =
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, ((JetCallExpression) element).getCalleeExpression()); codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, ((JetCallExpression) element).getCalleeExpression());
assert call != null;
Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> next = call.getValueArguments().entrySet().iterator().next(); Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> next = call.getValueArguments().entrySet().iterator().next();
codegen.genVarargs(next.getKey(), (VarargValueArgument) next.getValue()); codegen.genVarargs(next.getKey(), (VarargValueArgument) next.getValue());
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
@@ -19,15 +19,16 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List; import java.util.List;
@@ -36,13 +37,19 @@ import java.util.List;
*/ */
public class JavaClassFunction implements IntrinsicMethod { public class JavaClassFunction implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, public StackValue generate(
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state
) {
JetCallExpression call = (JetCallExpression) element; JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall =
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
assert resolvedCall != null;
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
JetType returnType = resultingDescriptor.getReturnType();
assert returnType != null;
Type type = state.getInjector().getJetTypeMapper().mapType( Type type = state.getInjector().getJetTypeMapper().mapType(
resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE); returnType.getArguments().get(0).getType(), MapTypeMode.VALUE);
JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type);
if (primitiveType != null) { if (primitiveType != null) {
v.getstatic(primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;"); v.getstatic(primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;");
@@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import java.util.List; import java.util.List;
@@ -35,7 +35,15 @@ import java.util.List;
*/ */
public class JavaClassProperty implements IntrinsicMethod { public class JavaClassProperty implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(receiver.type); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(receiver.type);
if (primitiveType != null) { if (primitiveType != null) {
@@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -34,8 +34,17 @@ import java.util.List;
*/ */
public class NewArray implements IntrinsicMethod { public class NewArray implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
codegen.generateNewArray((JetCallExpression) element, codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, (JetExpression) element)); ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
codegen.generateNewArray((JetCallExpression) element,
codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, (JetExpression) element));
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
} }
@@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -32,7 +32,15 @@ import java.util.List;
*/ */
public class Not implements IntrinsicMethod { public class Not implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
final StackValue stackValue; final StackValue stackValue;
if (arguments.size() == 1) { if (arguments.size() == 1) {
stackValue = codegen.gen(arguments.get(0)); stackValue = codegen.gen(arguments.get(0));
@@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -32,7 +32,15 @@ import java.util.List;
*/ */
public class NumberCast implements IntrinsicMethod { public class NumberCast implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(expectedType, v); receiver.put(expectedType, v);
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
@@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -39,9 +39,12 @@ public class PsiMethodCall implements IntrinsicMethod {
} }
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, public StackValue generate(
List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element,
final CallableMethod callableMethod = state.getInjector().getJetTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION); List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state
) {
final CallableMethod callableMethod =
state.getInjector().getJetTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION);
codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver); codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver);
return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType()); return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType());
} }
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -38,13 +38,22 @@ public class RangeTo implements IntrinsicMethod {
} }
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
if (arguments.size() == 1) { if (arguments.size() == 1) {
final Type leftType = receiver.type; final Type leftType = receiver.type;
final Type rightType = codegen.expressionType(arguments.get(0)); final Type rightType = codegen.expressionType(arguments.get(0));
receiver.put(Type.INT_TYPE, v); receiver.put(Type.INT_TYPE, v);
codegen.gen(arguments.get(0), rightType); codegen.gen(arguments.get(0), rightType);
v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); v.invokestatic("jet/runtime/Ranges", "rangeTo",
"(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor());
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
} }
else { else {
@@ -54,7 +63,8 @@ public class RangeTo implements IntrinsicMethod {
// if (JetTypeMapper.isIntPrimitive(leftType)) { // if (JetTypeMapper.isIntPrimitive(leftType)) {
codegen.gen(expression.getLeft(), leftType); codegen.gen(expression.getLeft(), leftType);
codegen.gen(expression.getRight(), rightType); codegen.gen(expression.getRight(), rightType);
v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); v.invokestatic("jet/runtime/Ranges", "rangeTo",
"(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor());
return StackValue.onStack(expectedType); return StackValue.onStack(expectedType);
// } // }
// else { // else {
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,11 +33,21 @@ import java.util.List;
*/ */
public class StringGetChar implements IntrinsicMethod { public class StringGetChar implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
if (receiver != null) ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
if (receiver != null) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
if (arguments != null) }
if (arguments != null) {
codegen.gen(arguments.get(0)).put(Type.INT_TYPE, v); codegen.gen(arguments.get(0)).put(Type.INT_TYPE, v);
}
v.invokeinterface("java/lang/CharSequence", "charAt", "(I)C"); v.invokeinterface("java/lang/CharSequence", "charAt", "(I)C");
return StackValue.onStack(Type.CHAR_TYPE); return StackValue.onStack(Type.CHAR_TYPE);
} }
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class StringLength implements IntrinsicMethod { public class StringLength implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokeinterface("java/lang/CharSequence", "length", "()I"); v.invokeinterface("java/lang/CharSequence", "length", "()I");
return StackValue.onStack(Type.INT_TYPE); return StackValue.onStack(Type.INT_TYPE);
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class StringPlus implements IntrinsicMethod { public class StringPlus implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
if (receiver == null || receiver == StackValue.none()) { if (receiver == null || receiver == StackValue.none()) {
codegen.gen(arguments.get(0)).put(JetTypeMapper.JL_STRING_TYPE, v); codegen.gen(arguments.get(0)).put(JetTypeMapper.JL_STRING_TYPE, v);
codegen.gen(arguments.get(1)).put(JetTypeMapper.TYPE_OBJECT, v); codegen.gen(arguments.get(1)).put(JetTypeMapper.TYPE_OBJECT, v);
@@ -19,21 +19,29 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class StupidSync implements IntrinsicMethod { public class StupidSync implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
codegen.pushMethodArguments((JetCallExpression) element, Arrays.asList(JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_FUNCTION0)); codegen.pushMethodArguments((JetCallExpression) element, Arrays.asList(JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_FUNCTION0));
v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;"); v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;");
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v); StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
@@ -18,6 +18,9 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
@@ -26,9 +29,6 @@ import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.asm4.Label;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -37,9 +37,18 @@ import java.util.List;
*/ */
public class Sure implements IntrinsicMethod { public class Sure implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
JetCallExpression call = (JetCallExpression) element; JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall =
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
assert resolvedCall != null; assert resolvedCall != null;
if (resolvedCall.getReceiverArgument().getType().isNullable()) { if (resolvedCall.getReceiverArgument().getType().isNullable()) {
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class ToString implements IntrinsicMethod { public class ToString implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v); receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokestatic("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;"); v.invokestatic("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
return StackValue.onStack(JetTypeMapper.JL_STRING_TYPE); return StackValue.onStack(JetTypeMapper.JL_STRING_TYPE);
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -33,7 +33,15 @@ import java.util.List;
*/ */
public class UnaryMinus implements IntrinsicMethod { public class UnaryMinus implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
PsiElement element,
List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
boolean nullable = expectedType.getSort() == Type.OBJECT; boolean nullable = expectedType.getSort() == Type.OBJECT;
if (nullable) { if (nullable) {
expectedType = JetTypeMapper.unboxType(expectedType); expectedType = JetTypeMapper.unboxType(expectedType);
@@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.List; import java.util.List;
@@ -34,13 +34,22 @@ import java.util.List;
*/ */
public class UnaryPlus implements IntrinsicMethod { public class UnaryPlus implements IntrinsicMethod {
@Override @Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
boolean nullable = expectedType.getSort() == Type.OBJECT; boolean nullable = expectedType.getSort() == Type.OBJECT;
if (nullable) { if (nullable) {
expectedType = JetTypeMapper.unboxType(expectedType); expectedType = JetTypeMapper.unboxType(expectedType);
} }
if (receiver != null && receiver != StackValue.none()) if (receiver != null && receiver != StackValue.none()) {
receiver.put(expectedType, v); receiver.put(expectedType, v);
}
else { else {
assert arguments != null; assert arguments != null;
codegen.gen(arguments.get(0), expectedType); codegen.gen(arguments.get(0), expectedType);
@@ -18,10 +18,12 @@ package org.jetbrains.jet.codegen.signature;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.asm4.signature.SignatureVisitor;
import org.jetbrains.asm4.signature.SignatureWriter;
import org.jetbrains.asm4.util.CheckSignatureAdapter;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils; import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.lang.types.Variance;
@@ -29,11 +31,6 @@ import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureVariance; import org.jetbrains.jet.rt.signature.JetSignatureVariance;
import org.jetbrains.jet.rt.signature.JetSignatureWriter; import org.jetbrains.jet.rt.signature.JetSignatureWriter;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.asm4.signature.SignatureVisitor;
import org.jetbrains.asm4.signature.SignatureWriter;
import org.jetbrains.asm4.util.CheckSignatureAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -48,8 +45,7 @@ public class BothSignatureWriter {
public enum Mode { public enum Mode {
METHOD(CheckSignatureAdapter.METHOD_SIGNATURE), METHOD(CheckSignatureAdapter.METHOD_SIGNATURE),
CLASS(CheckSignatureAdapter.CLASS_SIGNATURE), CLASS(CheckSignatureAdapter.CLASS_SIGNATURE),;
;
private final int asmType; private final int asmType;
@@ -119,7 +115,6 @@ public class BothSignatureWriter {
} }
private SignatureVisitor signatureVisitor() { private SignatureVisitor signatureVisitor() {
return !visitors.isEmpty() ? visitors.peek() : signatureVisitor; return !visitors.isEmpty() ? visitors.peek() : signatureVisitor;
} }
@@ -247,10 +242,14 @@ public class BothSignatureWriter {
private static JetSignatureVariance toJetSignatureVariance(Variance variance) { private static JetSignatureVariance toJetSignatureVariance(Variance variance) {
switch (variance) { switch (variance) {
case INVARIANT: return JetSignatureVariance.INVARIANT; case INVARIANT:
case IN_VARIANCE: return JetSignatureVariance.IN; return JetSignatureVariance.INVARIANT;
case OUT_VARIANCE: return JetSignatureVariance.OUT; case IN_VARIANCE:
default: throw new IllegalStateException(); return JetSignatureVariance.IN;
case OUT_VARIANCE:
return JetSignatureVariance.OUT;
default:
throw new IllegalStateException();
} }
} }
@@ -458,7 +457,6 @@ public class BothSignatureWriter {
} }
@NotNull @NotNull
public Method makeAsmMethod(String name) { public Method makeAsmMethod(String name) {
List<Type> jvmParameterTypes = new ArrayList<Type>(kotlinParameterTypes.size()); List<Type> jvmParameterTypes = new ArrayList<Type>(kotlinParameterTypes.size());
@@ -522,5 +520,4 @@ public class BothSignatureWriter {
return new JvmMethodSignature(makeAsmMethod(name), makeKotlinParameterTypes()); return new JvmMethodSignature(makeAsmMethod(name), makeKotlinParameterTypes());
} }
} }
} }
@@ -30,8 +30,10 @@ public class JvmClassSignature {
private final String javaGenericSignature; private final String javaGenericSignature;
private final String kotlinGenericSignature; private final String kotlinGenericSignature;
public JvmClassSignature(String name, String superclassName, List<String> interfaces, public JvmClassSignature(
@Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature) { String name, String superclassName, List<String> interfaces,
@Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature
) {
this.name = name; this.name = name;
this.superclassName = superclassName; this.superclassName = superclassName;
this.interfaces = interfaces; this.interfaces = interfaces;
@@ -16,8 +16,6 @@
package org.jetbrains.jet.codegen.signature; package org.jetbrains.jet.codegen.signature;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
@@ -31,7 +31,8 @@ public class JvmMethodParameterSignature {
private final JvmMethodParameterKind kind; private final JvmMethodParameterKind kind;
public JvmMethodParameterSignature( public JvmMethodParameterSignature(
@NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind) { @NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind
) {
this.asmType = asmType; this.asmType = asmType;
this.kotlinSignature = kotlinSignature; this.kotlinSignature = kotlinSignature;
this.kind = kind; this.kind = kind;
@@ -31,7 +31,9 @@ public class JvmMethodSignature {
@NotNull @NotNull
private final Method asmMethod; private final Method asmMethod;
/** Null when we don't care about type parameters */ /**
* Null when we don't care about type parameters
*/
private final String genericsSignature; private final String genericsSignature;
private final String kotlinTypeParameter; private final String kotlinTypeParameter;
@NotNull @NotNull
@@ -44,8 +46,13 @@ public class JvmMethodSignature {
*/ */
private final boolean genericsAvailable; private final boolean genericsAvailable;
public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature, public JvmMethodSignature(
@Nullable String kotlinTypeParameters, @NotNull List<JvmMethodParameterSignature> kotlinParameterTypes, @NotNull String kotlinReturnType) { @NotNull Method asmMethod,
@Nullable String genericsSignature,
@Nullable String kotlinTypeParameters,
@NotNull List<JvmMethodParameterSignature> kotlinParameterTypes,
@NotNull String kotlinReturnType
) {
this.asmMethod = asmMethod; this.asmMethod = asmMethod;
this.genericsSignature = genericsSignature; this.genericsSignature = genericsSignature;
this.kotlinTypeParameter = kotlinTypeParameters; this.kotlinTypeParameter = kotlinTypeParameters;
@@ -63,8 +70,13 @@ public class JvmMethodSignature {
this.genericsAvailable = false; this.genericsAvailable = false;
} }
public static JvmMethodSignature simple(@NotNull String methodName, @NotNull Type returnType, @NotNull List<JvmMethodParameterSignature> parameterSignatures) { public static JvmMethodSignature simple(
return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])), parameterSignatures); @NotNull String methodName,
@NotNull Type returnType,
@NotNull List<JvmMethodParameterSignature> parameterSignatures
) {
return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])),
parameterSignatures);
} }
@NotNull @NotNull
@@ -17,7 +17,6 @@
package org.jetbrains.jet.codegen.signature; package org.jetbrains.jet.codegen.signature;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
@@ -17,10 +17,10 @@
package org.jetbrains.jet.codegen.signature.kotlin; package org.jetbrains.jet.codegen.signature.kotlin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.utils.BitSetUtils;
import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.utils.BitSetUtils;
import java.util.BitSet; import java.util.BitSet;
@@ -17,9 +17,9 @@
package org.jetbrains.jet.codegen.signature.kotlin; package org.jetbrains.jet.codegen.signature.kotlin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov