Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -23,7 +23,13 @@
|
||||
</option>
|
||||
<envs />
|
||||
<patterns />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
<option name="TRANSPORT" value="0" />
|
||||
<option name="LOCAL" value="true" />
|
||||
</RunnerSettings>
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Debug" />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method />
|
||||
</configuration>
|
||||
|
||||
@@ -51,12 +51,15 @@ public final class TipsManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<DeclarationDescriptor> getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) {
|
||||
public static Collection<DeclarationDescriptor> getReferenceVariants(
|
||||
@NotNull final JetSimpleNameExpression expression,
|
||||
@NotNull final BindingContext context
|
||||
) {
|
||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||
if (receiverExpression != null) {
|
||||
// Process as call expression
|
||||
final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
|
||||
if (expressionType != null && resolutionScope != null) {
|
||||
if (!(expressionType instanceof NamespaceType)) {
|
||||
@@ -116,7 +119,7 @@ public final class TipsManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<DeclarationDescriptor> getReferenceVariants(JetNamespaceHeader expression, BindingContext context) {
|
||||
public static Collection<DeclarationDescriptor> getPackageReferenceVariants(JetSimpleNameExpression expression, BindingContext context) {
|
||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
if (resolutionScope != null) {
|
||||
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors());
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
*/
|
||||
public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl {
|
||||
public AccessorForFunctionDescriptor(DeclarationDescriptor descriptor, DeclarationDescriptor containingDeclaration, int index) {
|
||||
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(),
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
*/
|
||||
public class AccessorForPropertyDescriptor extends PropertyDescriptor {
|
||||
public AccessorForPropertyDescriptor(PropertyDescriptor pd, DeclarationDescriptor containingDeclaration, int index) {
|
||||
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC,
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
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.lang.descriptors.*;
|
||||
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.resolve.BindingContext;
|
||||
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.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.asm4.*;
|
||||
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
@@ -47,28 +53,32 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
public void genAnnotations(Annotated annotated) {
|
||||
if (annotated == null)
|
||||
if (annotated == null) {
|
||||
return;
|
||||
|
||||
if (!(annotated instanceof DeclarationDescriptor))
|
||||
}
|
||||
|
||||
if (!(annotated instanceof DeclarationDescriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, (DeclarationDescriptor) annotated);
|
||||
|
||||
JetModifierList modifierList = null;
|
||||
if (annotated instanceof ConstructorDescriptor && psiElement instanceof JetClass) {
|
||||
modifierList = ((JetClass)psiElement).getPrimaryConstructorModifierList();
|
||||
modifierList = ((JetClass) psiElement).getPrimaryConstructorModifierList();
|
||||
}
|
||||
else if (psiElement instanceof JetModifierListOwner) {
|
||||
modifierList = ((JetModifierListOwner) psiElement).getModifierList();
|
||||
}
|
||||
|
||||
if (modifierList == null)
|
||||
if (modifierList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
|
||||
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;
|
||||
|
||||
AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry);
|
||||
@@ -79,8 +89,10 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void genAnnotation(ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||
JetType type) {
|
||||
private void genAnnotation(
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||
JetType type
|
||||
) {
|
||||
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper);
|
||||
if (rp == RetentionPolicy.SOURCE) {
|
||||
@@ -117,7 +129,7 @@ public abstract class AnnotationCodegen {
|
||||
visitor.visitEnd();
|
||||
}
|
||||
else {
|
||||
assert valueArguments.size() == 1 : "Number of arguments on " + keyName + " = " + valueArguments.size(); // todo
|
||||
assert valueArguments.size() == 1 : "Number of arguments on " + keyName + " = " + valueArguments.size(); // todo
|
||||
JetExpression expression = valueArguments.get(0).getArgumentExpression();
|
||||
genAnnotationExpressionValue(annotationVisitor, keyName, expression);
|
||||
}
|
||||
@@ -125,7 +137,7 @@ public abstract class AnnotationCodegen {
|
||||
|
||||
private void genAnnotationExpressionValue(AnnotationVisitor annotationVisitor, String keyName, JetExpression expression) {
|
||||
CompileTimeConstant<?> compileTimeConstant =
|
||||
bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression);
|
||||
bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression);
|
||||
|
||||
if (compileTimeConstant != null) {
|
||||
Object value = compileTimeConstant.getValue();
|
||||
@@ -134,40 +146,42 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
if (expression instanceof JetDotQualifiedExpression) {
|
||||
JetDotQualifiedExpression qualifiedExpression = (JetDotQualifiedExpression)expression;
|
||||
JetDotQualifiedExpression qualifiedExpression = (JetDotQualifiedExpression) expression;
|
||||
ResolvedCall<? extends CallableDescriptor> call =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, qualifiedExpression.getSelectorExpression());
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, qualifiedExpression.getSelectorExpression());
|
||||
if (call != null) {
|
||||
if (call.getResultingDescriptor() instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor descriptor = (PropertyDescriptor)call.getResultingDescriptor();
|
||||
annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(), descriptor.getName().getName());
|
||||
PropertyDescriptor descriptor = (PropertyDescriptor) call.getResultingDescriptor();
|
||||
annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(),
|
||||
descriptor.getName().getName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (expression instanceof JetCallExpression) {
|
||||
JetCallExpression callExpression = (JetCallExpression)expression;
|
||||
JetCallExpression callExpression = (JetCallExpression) expression;
|
||||
ResolvedCall<? extends CallableDescriptor> call =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression());
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression());
|
||||
if (call != null) {
|
||||
List<AnnotationDescriptor> annotations = call.getResultingDescriptor().getOriginal().getAnnotations();
|
||||
String value = null;
|
||||
if (annotations != null) {
|
||||
for (AnnotationDescriptor annotation : annotations) {
|
||||
if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) {
|
||||
if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) {
|
||||
value = (String) annotation.getValueArguments().get(0).getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) {
|
||||
AnnotationVisitor visitor = annotationVisitor.visitArray(keyName);
|
||||
VarargValueArgument next = (VarargValueArgument)call.getValueArguments().values().iterator().next();
|
||||
VarargValueArgument next = (VarargValueArgument) call.getValueArguments().values().iterator().next();
|
||||
for (ValueArgument argument : next.getArguments()) {
|
||||
genAnnotationExpressionValue(visitor, null, argument.getArgumentExpression());
|
||||
}
|
||||
@@ -175,9 +189,9 @@ public abstract class AnnotationCodegen {
|
||||
return;
|
||||
}
|
||||
else if (call.getResultingDescriptor() instanceof ConstructorDescriptor) {
|
||||
ConstructorDescriptor descriptor = (ConstructorDescriptor)call.getResultingDescriptor();
|
||||
ConstructorDescriptor descriptor = (ConstructorDescriptor) call.getResultingDescriptor();
|
||||
AnnotationVisitor visitor = annotationVisitor.visitAnnotation(keyName, typeMapper
|
||||
.mapType(descriptor.getContainingDeclaration().getDefaultType(), MapTypeMode.VALUE).getDescriptor());
|
||||
.mapType(descriptor.getContainingDeclaration().getDefaultType(), MapTypeMode.VALUE).getDescriptor());
|
||||
getAnnotation(call, visitor);
|
||||
visitor.visitEnd();
|
||||
return;
|
||||
|
||||
@@ -18,14 +18,12 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.Type;
|
||||
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;
|
||||
|
||||
@@ -49,9 +47,11 @@ public class CallableMethod implements Callable {
|
||||
@Nullable
|
||||
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,
|
||||
@Nullable JvmClassName thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType) {
|
||||
@Nullable JvmClassName thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType
|
||||
) {
|
||||
this.owner = owner;
|
||||
this.defaultImplOwner = defaultImplOwner;
|
||||
this.defaultImplParam = defaultImplParam;
|
||||
@@ -93,7 +93,8 @@ public class CallableMethod implements Callable {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -108,14 +109,15 @@ public class CallableMethod implements Callable {
|
||||
|
||||
v.iconst(mask);
|
||||
String desc = getSignature().getAsmMethod().getDescriptor().replace(")", "I)");
|
||||
if("<init>".equals(getSignature().getAsmMethod().getName())) {
|
||||
if ("<init>".equals(getSignature().getAsmMethod().getName())) {
|
||||
v.visitMethodInsn(Opcodes.INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc);
|
||||
}
|
||||
else {
|
||||
if (getInvokeOpcode() != Opcodes.INVOKESTATIC)
|
||||
if (getInvokeOpcode() != Opcodes.INVOKESTATIC) {
|
||||
desc = desc.replace("(", "(" + defaultImplParam.getDescriptor());
|
||||
}
|
||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, defaultImplOwner.getInternalName(),
|
||||
getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
|
||||
getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,17 +90,18 @@ public abstract class ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) {
|
||||
boolean isAnnotation = origin instanceof JetClass && ((JetClass)origin).isAnnotation();
|
||||
OwnerKind kind = context.getContextKind();
|
||||
boolean isAnnotation = origin instanceof JetClass && ((JetClass) origin).isAnnotation();
|
||||
for (JetParameter p : getPrimaryConstructorParameters()) {
|
||||
if (p.getValOrVarNode() != null) {
|
||||
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
|
||||
if (propertyDescriptor != null) {
|
||||
if (!isAnnotation) {
|
||||
propertyCodegen.generateBackingField(p, propertyDescriptor);
|
||||
propertyCodegen.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p);
|
||||
propertyCodegen
|
||||
.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p);
|
||||
if (propertyDescriptor.isVar()) {
|
||||
propertyCodegen.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p);
|
||||
propertyCodegen
|
||||
.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -121,7 +122,7 @@ public abstract class ClassBodyCodegen {
|
||||
|
||||
private void generateStaticInitializer() {
|
||||
if (staticInitializerChunks.size() > 0) {
|
||||
final MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | Opcodes.ACC_STATIC,"<clinit>", "()V", null, null);
|
||||
final MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
|
||||
@@ -21,11 +21,7 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.AnnotationVisitor;
|
||||
import org.jetbrains.asm4.ClassVisitor;
|
||||
import org.jetbrains.asm4.FieldVisitor;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.asm4.*;
|
||||
|
||||
public abstract class ClassBuilder {
|
||||
public static class Concrete extends ClassBuilder {
|
||||
@@ -40,27 +36,33 @@ public abstract class ClassBuilder {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
public FieldVisitor newField(@Nullable PsiElement origin,
|
||||
int access,
|
||||
String name,
|
||||
String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable Object value) {
|
||||
|
||||
public FieldVisitor newField(
|
||||
@Nullable PsiElement origin,
|
||||
int access,
|
||||
String name,
|
||||
String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable Object value
|
||||
) {
|
||||
return getVisitor().visitField(access, name, desc, signature, value);
|
||||
}
|
||||
|
||||
public MethodVisitor newMethod(@Nullable PsiElement origin,
|
||||
int access,
|
||||
String name,
|
||||
String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable String[] exceptions) {
|
||||
public MethodVisitor newMethod(
|
||||
@Nullable PsiElement origin,
|
||||
int access,
|
||||
String name,
|
||||
String desc,
|
||||
@Nullable String signature,
|
||||
@Nullable String[] exceptions
|
||||
) {
|
||||
return getVisitor().visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
|
||||
public AnnotationVisitor newAnnotation(PsiElement origin,
|
||||
String desc,
|
||||
boolean visible) {
|
||||
|
||||
public AnnotationVisitor newAnnotation(
|
||||
String desc,
|
||||
boolean visible
|
||||
) {
|
||||
return getVisitor().visitAnnotation(desc, visible);
|
||||
}
|
||||
|
||||
@@ -70,7 +72,15 @@ public abstract class ClassBuilder {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.asm4.ClassVisitor;
|
||||
import org.jetbrains.asm4.ClassWriter;
|
||||
import org.jetbrains.asm4.util.TraceClassVisitor;
|
||||
|
||||
@@ -27,6 +26,7 @@ import java.io.StringWriter;
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
public class ClassBuilderFactories {
|
||||
|
||||
public static ClassBuilderFactory TEST = new ClassBuilderFactory() {
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
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
|
||||
@@ -29,7 +24,10 @@ import java.io.StringWriter;
|
||||
public interface ClassBuilderFactory {
|
||||
@NotNull
|
||||
ClassBuilderMode getClassBuilderMode();
|
||||
|
||||
ClassBuilder newClassBuilder();
|
||||
|
||||
String asText(ClassBuilder builder);
|
||||
|
||||
byte[] asBytes(ClassBuilder builder);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,19 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public enum ClassBuilderMode {
|
||||
/** Full function bodies */
|
||||
/**
|
||||
* Full function bodies
|
||||
*/
|
||||
FULL,
|
||||
/** Only function signatures */
|
||||
/**
|
||||
* Only function signatures
|
||||
*/
|
||||
SIGNATURES,
|
||||
/** Function with stub bodies: just throw exception */
|
||||
/**
|
||||
* Function with stub bodies: just throw exception
|
||||
*/
|
||||
STUBS,
|
||||
}
|
||||
|
||||
@@ -56,32 +56,44 @@ public class ClassCodegen {
|
||||
// different for the case when we compute closures
|
||||
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
|
||||
}
|
||||
|
||||
|
||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
||||
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
||||
if (declaration instanceof JetClass) {
|
||||
if (declaration instanceof JetEnumEntry && !state.getInjector().getClosureAnnotator().enumEntryNeedSubclass(
|
||||
(JetEnumEntry) declaration)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
generate(contextForInners, (JetClass) declaration);
|
||||
}
|
||||
if (declaration instanceof JetClassObject) {
|
||||
generate(contextForInners, ((JetClassObject)declaration).getObjectDeclaration());
|
||||
generate(contextForInners, ((JetClassObject) declaration).getObjectDeclaration());
|
||||
}
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
|
||||
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
|
||||
}
|
||||
|
||||
|
||||
classBuilder.done();
|
||||
}
|
||||
|
||||
private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors, ClassBuilder classBuilder) {
|
||||
private void generateImplementation(
|
||||
CodegenContext context,
|
||||
JetClassOrObject aClass,
|
||||
OwnerKind kind,
|
||||
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors,
|
||||
ClassBuilder classBuilder
|
||||
) {
|
||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||
CodegenContext classContext = context.intoClass(descriptor, kind, jetTypeMapper);
|
||||
classContext.copyAccessors(accessors);
|
||||
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate();
|
||||
|
||||
if (aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
|
||||
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
||||
ClassBuilder traitBuilder = state.forTraitImplementation(descriptor);
|
||||
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state).generate();
|
||||
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state)
|
||||
.generate();
|
||||
traitBuilder.done();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,8 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.name.FqName;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
@@ -49,7 +48,6 @@ public class ClassFileFactory {
|
||||
}
|
||||
|
||||
|
||||
|
||||
ClassBuilder newVisitor(String filePath) {
|
||||
state.getProgress().log("Emitting: " + filePath);
|
||||
final ClassBuilder answer = builderFactory.newClassBuilder();
|
||||
|
||||
@@ -42,14 +42,16 @@ public class ClosureAnnotator {
|
||||
private final Map<String, Integer> anonymousSubclassesCount = new HashMap<String, Integer>();
|
||||
private final Map<ScriptDescriptor, JvmClassName> classNameForScript = new HashMap<ScriptDescriptor, JvmClassName>();
|
||||
private final Set<JvmClassName> scriptClassNames = new HashSet<JvmClassName>();
|
||||
private final Map<DeclarationDescriptor, ClassDescriptorImpl> classesForFunctions = new HashMap<DeclarationDescriptor, ClassDescriptorImpl>();
|
||||
private final Map<DeclarationDescriptor,ClassDescriptor> enclosing = new HashMap<DeclarationDescriptor, ClassDescriptor>();
|
||||
private final Map<DeclarationDescriptor, ClassDescriptorImpl> classesForFunctions =
|
||||
new HashMap<DeclarationDescriptor, ClassDescriptorImpl>();
|
||||
private final Map<DeclarationDescriptor, ClassDescriptor> enclosing = new HashMap<DeclarationDescriptor, ClassDescriptor>();
|
||||
|
||||
private final MultiMap<FqName, JetFile> namespaceName2MultiNamespaceFiles = MultiMap.create();
|
||||
private final MultiMap<FqName, JetFile> namespaceName2Files = MultiMap.create();
|
||||
|
||||
private BindingContext bindingContext;
|
||||
private List<JetFile> files;
|
||||
private final Map<ClassDescriptor, Boolean> enumEntryNeedSubclass = new HashMap<ClassDescriptor, Boolean>();
|
||||
|
||||
@Inject
|
||||
public void setBindingContext(BindingContext bindingContext) {
|
||||
@@ -81,7 +83,10 @@ public class ClosureAnnotator {
|
||||
classDescriptor.initialize(
|
||||
false,
|
||||
Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.singleton((funDescriptor.getReceiverParameter().exists() ? JetStandardClasses.getReceiverFunction(arity) : JetStandardClasses.getFunction(arity)).getDefaultType()), JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||
Collections.singleton((funDescriptor.getReceiverParameter().exists()
|
||||
? JetStandardClasses.getReceiverFunction(arity)
|
||||
: JetStandardClasses.getFunction(arity)).getDefaultType()), JetScope.EMPTY,
|
||||
Collections.<ConstructorDescriptor>emptySet(), null);
|
||||
classesForFunctions.put(funDescriptor, classDescriptor);
|
||||
}
|
||||
return classDescriptor;
|
||||
@@ -169,7 +174,7 @@ public class ClosureAnnotator {
|
||||
|
||||
ArrayList<JetFile> namespaceFiles = new ArrayList<JetFile>();
|
||||
for (JetFile jetFile : entry.getValue()) {
|
||||
ArrayList<JetDeclaration> fileFunctions = new ArrayList<JetDeclaration>();
|
||||
Collection<JetDeclaration> fileFunctions = new ArrayList<JetDeclaration>();
|
||||
for (JetDeclaration declaration : jetFile.getDeclarations()) {
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
fileFunctions.add(declaration);
|
||||
@@ -181,7 +186,7 @@ public class ClosureAnnotator {
|
||||
}
|
||||
}
|
||||
|
||||
if(namespaceFiles.size() > 1) {
|
||||
if (namespaceFiles.size() > 1) {
|
||||
for (JetFile namespaceFile : namespaceFiles) {
|
||||
namespaceName2MultiNamespaceFiles.putValue(entry.getKey(), namespaceFile);
|
||||
}
|
||||
@@ -214,12 +219,27 @@ public class ClosureAnnotator {
|
||||
}
|
||||
|
||||
public boolean hasThis0(ClassDescriptor classDescriptor) {
|
||||
if (DescriptorUtils.isClassObject(classDescriptor)) { return false; }
|
||||
if (DescriptorUtils.isClassObject(classDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
if (classDescriptor.getKind() == ClassKind.ENUM_CLASS || classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClassDescriptor other = enclosing.get(classDescriptor);
|
||||
return other != null;
|
||||
}
|
||||
|
||||
public boolean enumEntryNeedSubclass(JetEnumEntry enumEntry) {
|
||||
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry);
|
||||
return enumEntryNeedSubclass.get(descriptor);
|
||||
}
|
||||
|
||||
public boolean enumEntryNeedSubclass(ClassDescriptor enumEntry) {
|
||||
Boolean aBoolean = enumEntryNeedSubclass.get(enumEntry);
|
||||
return aBoolean != null && aBoolean;
|
||||
}
|
||||
|
||||
private class MyJetVisitorVoid extends JetVisitorVoid {
|
||||
private final LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
|
||||
private final LinkedList<String> nameStack = new LinkedList<String>();
|
||||
@@ -266,6 +286,7 @@ public class ClosureAnnotator {
|
||||
@Override
|
||||
public void visitJetFile(JetFile file) {
|
||||
if (file.isScript()) {
|
||||
//noinspection ConstantConditions
|
||||
nameStack.push(classNameForScriptPsi(file.getScript()).getInternalName());
|
||||
}
|
||||
else {
|
||||
@@ -275,10 +296,18 @@ public class ClosureAnnotator {
|
||||
nameStack.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
||||
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry);
|
||||
enumEntryNeedSubclass.put(descriptor, !enumEntry.getDeclarations().isEmpty());
|
||||
super.visitEnumEntry(enumEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassObject(JetClassObject classObject) {
|
||||
JvmClassName name = recordClassObject(classObject);
|
||||
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
|
||||
assert classDescriptor != null;
|
||||
recordEnclosing(classDescriptor);
|
||||
recordName(classDescriptor, name);
|
||||
classStack.push(classDescriptor);
|
||||
@@ -303,7 +332,9 @@ public class ClosureAnnotator {
|
||||
if (classDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||
nameStack.push(base.isEmpty() ? classDescriptor.getName().getName() : base + '/' + classDescriptor.getName());
|
||||
}
|
||||
else { nameStack.push(base + '$' + classDescriptor.getName()); }
|
||||
else {
|
||||
nameStack.push(base + '$' + classDescriptor.getName());
|
||||
}
|
||||
super.visitObjectDeclaration(declaration);
|
||||
nameStack.pop();
|
||||
classStack.pop();
|
||||
@@ -321,7 +352,9 @@ public class ClosureAnnotator {
|
||||
if (classDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||
nameStack.push(base.isEmpty() ? classDescriptor.getName().getName() : base + '/' + classDescriptor.getName());
|
||||
}
|
||||
else { nameStack.push(base + '$' + classDescriptor.getName()); }
|
||||
else {
|
||||
nameStack.push(base + '$' + classDescriptor.getName());
|
||||
}
|
||||
super.visitClass(klass);
|
||||
nameStack.pop();
|
||||
classStack.pop();
|
||||
@@ -347,7 +380,8 @@ public class ClosureAnnotator {
|
||||
@Override
|
||||
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
||||
JvmClassName name = recordAnonymousClass(expression.getFunctionLiteral());
|
||||
FunctionDescriptor declarationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
|
||||
FunctionDescriptor declarationDescriptor =
|
||||
(FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
|
||||
// working around a problem with shallow analysis
|
||||
if (declarationDescriptor == null) return;
|
||||
ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(declarationDescriptor, name);
|
||||
@@ -368,7 +402,8 @@ public class ClosureAnnotator {
|
||||
|
||||
@Override
|
||||
public void visitNamedFunction(JetNamedFunction function) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
FunctionDescriptor functionDescriptor =
|
||||
(FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
// working around a problem with shallow analysis
|
||||
if (functionDescriptor == null) return;
|
||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||
@@ -379,7 +414,9 @@ public class ClosureAnnotator {
|
||||
}
|
||||
else if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||
String peek = nameStack.peek();
|
||||
if (peek.isEmpty()) { peek = "namespace"; }
|
||||
if (peek.isEmpty()) {
|
||||
peek = "namespace";
|
||||
}
|
||||
else {
|
||||
peek += "/namespace";
|
||||
}
|
||||
|
||||
@@ -23,6 +23,12 @@ package org.jetbrains.jet.codegen;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.JvmMethodParameterKind;
|
||||
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.scopes.receivers.ReceiverDescriptor;
|
||||
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.List;
|
||||
@@ -59,26 +58,26 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
|
||||
public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) {
|
||||
|
||||
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
|
||||
|
||||
|
||||
signatureWriter.writeFormalTypeParametersStart();
|
||||
signatureWriter.writeFormalTypeParametersEnd();
|
||||
|
||||
|
||||
boolean isExtensionFunction = fd.getReceiverParameter().exists();
|
||||
int paramCount = fd.getValueParameters().size();
|
||||
if (isExtensionFunction) {
|
||||
paramCount++;
|
||||
}
|
||||
|
||||
|
||||
signatureWriter.writeParametersStart();
|
||||
|
||||
|
||||
for (int i = 0; i < paramCount; ++i) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
signatureWriter.writeAsmType(JetTypeMapper.TYPE_OBJECT, true);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
signatureWriter.writeReturnType();
|
||||
@@ -98,10 +97,9 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
else {
|
||||
receiverParameterType = null;
|
||||
}
|
||||
final CallableMethod result = new CallableMethod(
|
||||
return new CallableMethod(
|
||||
owner, null, null, descriptor, INVOKEVIRTUAL,
|
||||
getInternalClassName(fd), receiverParameterType, getInternalClassName(fd).getAsmType());
|
||||
return result;
|
||||
}
|
||||
|
||||
public JvmMethodSignature invokeSignature(FunctionDescriptor fd) {
|
||||
@@ -118,6 +116,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
|
||||
SignatureWriter signatureWriter = new SignatureWriter();
|
||||
|
||||
assert funDescriptor != null;
|
||||
final List<ValueParameterDescriptor> parameters = funDescriptor.getValueParameters();
|
||||
final JvmClassName funClass = getInternalClassName(funDescriptor);
|
||||
signatureWriter.visitClassType(funClass.getInternalName());
|
||||
@@ -142,9 +141,12 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
generateBridge(name.getInternalName(), funDescriptor, fun, cv);
|
||||
captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun);
|
||||
ClassDescriptor thisDescriptor = context.getThisDescriptor();
|
||||
final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
||||
if (enclosingType == null)
|
||||
final Type enclosingType = thisDescriptor == null
|
||||
? null
|
||||
: state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
||||
if (enclosingType == null) {
|
||||
captureThis = null;
|
||||
}
|
||||
|
||||
final Method constructor = generateConstructor(funClass, fun, funDescriptor);
|
||||
|
||||
@@ -158,16 +160,14 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
|
||||
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()) {
|
||||
if (descriptor == funDescriptor) {
|
||||
continue;
|
||||
}
|
||||
if (descriptor instanceof VariableDescriptor) {
|
||||
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
|
||||
answer.addArg(valueDescriptor.getOuterValue());
|
||||
}
|
||||
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||
if (descriptor instanceof VariableDescriptor || CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
|
||||
descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||
final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor);
|
||||
answer.addArg(valueDescriptor.getOuterValue());
|
||||
}
|
||||
@@ -204,7 +204,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
|
||||
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(
|
||||
funDescriptor, function, name, this, state.getInjector().getJetTypeMapper());
|
||||
@@ -218,10 +219,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
final JvmMethodSignature bridge = erasedInvokeSignature(funDescriptor);
|
||||
final Method delegate = invokeSignature(funDescriptor).getAsmMethod();
|
||||
|
||||
if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor()))
|
||||
if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor())) {
|
||||
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) {
|
||||
StubCodegen.generateStubCode(mv);
|
||||
}
|
||||
@@ -236,14 +240,16 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
int count = 1;
|
||||
if (receiver.exists()) {
|
||||
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++;
|
||||
}
|
||||
|
||||
final List<ValueParameterDescriptor> params = funDescriptor.getValueParameters();
|
||||
for (ValueParameterDescriptor param : params) {
|
||||
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++;
|
||||
}
|
||||
|
||||
@@ -261,7 +267,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
argCount += (captureReceiver != null ? 1 : 0);
|
||||
|
||||
ArrayList<DeclarationDescriptor> variableDescriptors = new ArrayList<DeclarationDescriptor>();
|
||||
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||
if (descriptor == funDescriptor) {
|
||||
continue;
|
||||
@@ -270,7 +276,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
argCount++;
|
||||
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++;
|
||||
variableDescriptors.add(descriptor);
|
||||
}
|
||||
@@ -308,8 +315,11 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
argTypes[i++] = type;
|
||||
}
|
||||
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||
final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)).getAsmType();
|
||||
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
|
||||
descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||
final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator()
|
||||
.classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
|
||||
.getAsmType();
|
||||
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) {
|
||||
signatureWriter.visitTypeArgument(variance);
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.annotations.AnnotationDescriptor;
|
||||
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
|
||||
@@ -39,26 +39,32 @@ public abstract class CodegenContext {
|
||||
private final OwnerKind contextKind;
|
||||
@Nullable
|
||||
private final CodegenContext parentContext;
|
||||
public final ObjectOrClosureCodegen closure;
|
||||
public final ObjectOrClosureCodegen closure;
|
||||
|
||||
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
||||
|
||||
protected StackValue outerExpression;
|
||||
|
||||
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.contextKind = contextKind;
|
||||
this.parentContext = parentContext;
|
||||
closure = closureCodegen;
|
||||
}
|
||||
|
||||
protected abstract ClassDescriptor getThisDescriptor ();
|
||||
protected abstract ClassDescriptor getThisDescriptor();
|
||||
|
||||
public DeclarationDescriptor getClassOrNamespaceDescriptor() {
|
||||
CodegenContext c = this;
|
||||
while(true) {
|
||||
while (true) {
|
||||
assert c != null;
|
||||
DeclarationDescriptor contextDescriptor = c.getContextDescriptor();
|
||||
if (!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) {
|
||||
c = c.getParentContext();
|
||||
@@ -82,6 +88,7 @@ public abstract class CodegenContext {
|
||||
return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DeclarationDescriptor getContextDescriptor() {
|
||||
return contextDescriptor;
|
||||
}
|
||||
@@ -95,14 +102,19 @@ public abstract class CodegenContext {
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -113,7 +125,8 @@ public abstract class CodegenContext {
|
||||
public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
|
||||
if (descriptor == null) {
|
||||
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);
|
||||
}
|
||||
@@ -122,7 +135,13 @@ public abstract class CodegenContext {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -151,7 +170,9 @@ public abstract class CodegenContext {
|
||||
final ObjectOrClosureCodegen top = closure;
|
||||
if (top != null) {
|
||||
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);
|
||||
result = result == null ? outer : StackValue.composed(result, outer);
|
||||
@@ -171,17 +192,19 @@ public abstract class CodegenContext {
|
||||
|
||||
DeclarationDescriptor getAccessor(DeclarationDescriptor descriptor) {
|
||||
if (accessors == null) {
|
||||
accessors = new HashMap<DeclarationDescriptor,DeclarationDescriptor>();
|
||||
accessors = new HashMap<DeclarationDescriptor, DeclarationDescriptor>();
|
||||
}
|
||||
descriptor = descriptor.getOriginal();
|
||||
DeclarationDescriptor accessor = accessors.get(descriptor);
|
||||
if (accessor != null) { return accessor; }
|
||||
if (accessor != null) {
|
||||
return accessor;
|
||||
}
|
||||
|
||||
if (descriptor instanceof SimpleFunctionDescriptor) {
|
||||
accessor = new AccessorForFunctionDescriptor(descriptor, contextDescriptor, accessors.size());
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor,accessors.size());
|
||||
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessors.size());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
@@ -201,7 +224,7 @@ public abstract class CodegenContext {
|
||||
public void copyAccessors(HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
|
||||
if (accessors != null) {
|
||||
if (this.accessors == null) {
|
||||
this.accessors = new HashMap<DeclarationDescriptor,DeclarationDescriptor>();
|
||||
this.accessors = new HashMap<DeclarationDescriptor, DeclarationDescriptor>();
|
||||
}
|
||||
this.accessors.putAll(accessors);
|
||||
}
|
||||
|
||||
@@ -18,21 +18,13 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||
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.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -76,8 +68,10 @@ public class CodegenContexts {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull @Override public Name getName() {
|
||||
return null;
|
||||
@NotNull
|
||||
@Override
|
||||
public Name getName() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,13 +91,17 @@ public class CodegenContexts {
|
||||
return "ROOT";
|
||||
}
|
||||
};
|
||||
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
|
||||
protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
|
||||
|
||||
public abstract static class ReceiverContext extends CodegenContext {
|
||||
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);
|
||||
receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null;
|
||||
}
|
||||
@@ -114,39 +112,41 @@ public class CodegenContexts {
|
||||
}
|
||||
}
|
||||
|
||||
public static class MethodContext extends ReceiverContext {
|
||||
@NotNull
|
||||
private final FunctionDescriptor functionDescriptor;
|
||||
public static class MethodContext extends ReceiverContext {
|
||||
|
||||
public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
|
||||
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
|
||||
this.functionDescriptor = contextType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionDescriptor getFunctionDescriptor() {
|
||||
return functionDescriptor;
|
||||
super(contextType instanceof PropertyAccessorDescriptor
|
||||
? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty()
|
||||
: contextType, contextKind, parentContext, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().getThisDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().lookupInContext(d, v, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type enclosingClassType(JetTypeMapper typeMapper) {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().enclosingClassType(typeMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().isStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackValue getOuterExpression(StackValue prefix) {
|
||||
//noinspection ConstantConditions
|
||||
return getParentContext().getOuterExpression(prefix);
|
||||
}
|
||||
|
||||
@@ -157,15 +157,21 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? local1
|
||||
: null;
|
||||
? local1
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StackValue getOuterExpression(StackValue prefix) {
|
||||
return outerExpression;
|
||||
}
|
||||
@@ -188,7 +194,8 @@ public class CodegenContexts {
|
||||
@NotNull ClassDescriptor contextDescriptor,
|
||||
@NotNull OwnerKind contextKind,
|
||||
@Nullable CodegenContext parentContext,
|
||||
@Nullable ObjectOrClosureCodegen closureCodegen) {
|
||||
@Nullable ObjectOrClosureCodegen closureCodegen
|
||||
) {
|
||||
super(contextDescriptor, contextKind, parentContext, closureCodegen);
|
||||
|
||||
this.classDescriptor = contextDescriptor;
|
||||
@@ -212,13 +219,18 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false)
|
||||
: null;
|
||||
? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,14 +245,20 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextDescriptor.getDefaultType(), MapTypeMode.IMPL);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, JvmClassName.byType(owner), "this$0", false)
|
||||
: null;
|
||||
? StackValue.field(type, JvmClassName.byType(owner), "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -260,16 +278,23 @@ public class CodegenContexts {
|
||||
}
|
||||
|
||||
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);
|
||||
this.classDescriptor = classDescriptor;
|
||||
|
||||
final Type type = enclosingClassType(typeMapper);
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, internalClassName, "this$0", false)
|
||||
: null;
|
||||
? StackValue.field(type, internalClassName, "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,6 +302,7 @@ public class CodegenContexts {
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DeclarationDescriptor getContextDescriptor() {
|
||||
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.java.JvmStdlibNames;
|
||||
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.lang.JetStandardClasses;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
@@ -64,20 +64,20 @@ public class CodegenUtil {
|
||||
CallableMemberDescriptor.Kind.DECLARATION);
|
||||
|
||||
invokeDescriptor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
||||
fd.getExpectedThisObject(),
|
||||
Collections.<TypeParameterDescriptorImpl>emptyList(),
|
||||
fd.getValueParameters(),
|
||||
fd.getReturnType(),
|
||||
Modality.FINAL,
|
||||
Visibilities.PUBLIC,
|
||||
/*isInline = */false
|
||||
fd.getExpectedThisObject(),
|
||||
Collections.<TypeParameterDescriptorImpl>emptyList(),
|
||||
fd.getValueParameters(),
|
||||
fd.getReturnType(),
|
||||
Modality.FINAL,
|
||||
Visibilities.PUBLIC,
|
||||
/*isInline = */false
|
||||
);
|
||||
return invokeDescriptor;
|
||||
}
|
||||
|
||||
public static boolean isNonLiteralObject(JetClassOrObject myClass) {
|
||||
return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral() &&
|
||||
!(myClass.getParent() instanceof JetClassObject);
|
||||
!(myClass.getParent() instanceof JetClassObject);
|
||||
}
|
||||
|
||||
public static boolean isLocalFun(DeclarationDescriptor fd, BindingContext bindingContext) {
|
||||
@@ -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();
|
||||
if (visibility == Visibilities.INTERNAL) {
|
||||
flags.set(JvmStdlibNames.FLAG_INTERNAL_BIT);
|
||||
|
||||
@@ -25,7 +25,7 @@ public interface CompilationErrorHandler {
|
||||
@Override
|
||||
public void reportException(Throwable exception, String fileUrl) {
|
||||
if (exception instanceof RuntimeException) {
|
||||
throw (RuntimeException)exception;
|
||||
throw (RuntimeException) exception;
|
||||
}
|
||||
throw new IllegalStateException(exception);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
* @author abreslav
|
||||
*/
|
||||
* @author alex.tkachman
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompilationException extends RuntimeException {
|
||||
private final PsiElement element;
|
||||
|
||||
@@ -56,7 +56,8 @@ public class CompilationException extends RuntimeException {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
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();
|
||||
if (cause != null) {
|
||||
String causeMessage = cause.getMessage();
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -31,7 +31,6 @@ import java.util.List;
|
||||
*/
|
||||
public class ConstructorFrameMap extends FrameMap {
|
||||
private int myOuterThisIndex = -1;
|
||||
private int myTypeInfoIndex = -1;
|
||||
|
||||
public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) {
|
||||
enterTemp(); // this
|
||||
@@ -43,14 +42,16 @@ public class ConstructorFrameMap extends FrameMap {
|
||||
|
||||
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
|
||||
|
||||
if(descriptor != null && descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS) {
|
||||
if (descriptor != null &&
|
||||
(descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS ||
|
||||
descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_ENTRY)) {
|
||||
enterTemp(); // name
|
||||
enterTemp(); // ordinal
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> paramDescrs = descriptor != null
|
||||
? descriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>emptyList();
|
||||
? descriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>emptyList();
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||
enter(parameter, explicitArgTypes.get(i).getSize());
|
||||
@@ -60,8 +61,4 @@ public class ConstructorFrameMap extends FrameMap {
|
||||
public int getOuterThisIndex() {
|
||||
return myOuterThisIndex;
|
||||
}
|
||||
|
||||
public int getTypeInfoIndex() {
|
||||
return myTypeInfoIndex;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -132,12 +132,15 @@ public class FrameMap {
|
||||
|
||||
Collections.sort(descriptors, new Comparator<Tuple3<DeclarationDescriptor, Integer, Integer>>() {
|
||||
@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;
|
||||
}
|
||||
});
|
||||
|
||||
sb.append("size=" + myMaxIndex);
|
||||
sb.append("size=").append(myMaxIndex);
|
||||
|
||||
boolean first = true;
|
||||
for (Tuple3<DeclarationDescriptor, Integer, Integer> t : descriptors) {
|
||||
@@ -145,7 +148,7 @@ public class FrameMap {
|
||||
sb.append(", ");
|
||||
}
|
||||
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();
|
||||
|
||||
@@ -19,6 +19,11 @@ package org.jetbrains.jet.codegen;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.kotlin.JetMethodAnnotationWriter;
|
||||
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.name.Name;
|
||||
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.*;
|
||||
|
||||
@@ -61,13 +61,17 @@ public class FunctionCodegen {
|
||||
public void gen(JetNamedFunction f) {
|
||||
final SimpleFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f);
|
||||
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);
|
||||
}
|
||||
|
||||
public void generateMethod(JetDeclarationWithBody f,
|
||||
public void generateMethod(
|
||||
JetDeclarationWithBody f,
|
||||
JvmMethodSignature jvmMethod, boolean needJetAnnotations,
|
||||
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
|
||||
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor
|
||||
) {
|
||||
|
||||
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor);
|
||||
|
||||
@@ -75,40 +79,39 @@ public class FunctionCodegen {
|
||||
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
|
||||
}
|
||||
|
||||
private void generatedMethod(JetExpression bodyExpressions,
|
||||
private void generatedMethod(
|
||||
JetExpression bodyExpressions,
|
||||
JvmMethodSignature jvmSignature,
|
||||
boolean needJetAnnotations, @Nullable String propertyTypeSignature,
|
||||
CodegenContexts.MethodContext context,
|
||||
FunctionDescriptor functionDescriptor,
|
||||
JetDeclarationWithBody fun
|
||||
)
|
||||
{
|
||||
) {
|
||||
if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
throw new IllegalStateException("must not generate code for fake overrides");
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
List<TypeParameterDescriptor> typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters();
|
||||
|
||||
int flags = JetTypeMapper.getAccessModifiers(functionDescriptor, 0);
|
||||
|
||||
|
||||
if (!functionDescriptor.getValueParameters().isEmpty()
|
||||
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
|
||||
.getVarargElementType() != null)
|
||||
{
|
||||
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
|
||||
.getVarargElementType() != null) {
|
||||
flags |= ACC_VARARGS;
|
||||
}
|
||||
|
||||
Modality modality = functionDescriptor.getModality();
|
||||
if (modality == Modality.FINAL) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
OwnerKind kind = context.getContextKind();
|
||||
|
||||
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
needJetAnnotations = false;
|
||||
}
|
||||
@@ -118,16 +121,19 @@ public class FunctionCodegen {
|
||||
|
||||
if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) {
|
||||
boolean isStatic = kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind;
|
||||
if (isStatic || kind == OwnerKind.TRAIT_IMPL)
|
||||
if (isStatic || kind == OwnerKind.TRAIT_IMPL) {
|
||||
flags |= ACC_STATIC;
|
||||
}
|
||||
|
||||
boolean isAbstract = (
|
||||
modality == Modality.ABSTRACT
|
||||
|| CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration())
|
||||
) && !isStatic && kind != OwnerKind.TRAIT_IMPL;
|
||||
modality == Modality.ABSTRACT
|
||||
|| CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration())
|
||||
) && !isStatic && kind != OwnerKind.TRAIT_IMPL;
|
||||
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);
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
|
||||
int start = 0;
|
||||
@@ -169,7 +175,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
for(int i = 0; i != paramDescrs.size(); ++i) {
|
||||
for (int i = 0; i != paramDescrs.size(); ++i) {
|
||||
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
|
||||
AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(parameterDescriptor);
|
||||
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start);
|
||||
@@ -191,29 +197,33 @@ public class FunctionCodegen {
|
||||
|
||||
if (!isAbstract && state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
|
||||
Label methodBegin = new Label();
|
||||
mv.visitLabel(methodBegin);
|
||||
|
||||
|
||||
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();
|
||||
int add = 0;
|
||||
|
||||
if (kind == OwnerKind.TRAIT_IMPL)
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
add++;
|
||||
}
|
||||
|
||||
if (receiverParameter.exists())
|
||||
if (receiverParameter.exists()) {
|
||||
add++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < paramDescrs.size(); 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);
|
||||
}
|
||||
|
||||
@@ -225,6 +235,7 @@ public class FunctionCodegen {
|
||||
for (int i = 0, k = 0; i < argTypes.length; i++) {
|
||||
Type argType = argTypes[i];
|
||||
iv.load(k, argType);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
k += argType.getSize();
|
||||
}
|
||||
iv.invokestatic(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor());
|
||||
@@ -239,7 +250,8 @@ public class FunctionCodegen {
|
||||
Type argType = argTypes[i];
|
||||
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());
|
||||
}
|
||||
else {
|
||||
@@ -253,11 +265,13 @@ public class FunctionCodegen {
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, sharedVarType.getInternalName(), "<init>", "()V");
|
||||
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();
|
||||
mv.visitLabel(labelToDivideLocalVarForSharedVarVisibility);
|
||||
mapLabelsToDivideLocalVarVisibilityForSharedVar.put(parameter.getName(), labelToDivideLocalVarForSharedVarVisibility);
|
||||
mapLabelsToDivideLocalVarVisibilityForSharedVar
|
||||
.put(parameter.getName(), labelToDivideLocalVarForSharedVarVisibility);
|
||||
|
||||
mv.visitVarInsn(sharedVarType.getOpcode(ISTORE), index);
|
||||
}
|
||||
@@ -265,7 +279,7 @@ public class FunctionCodegen {
|
||||
|
||||
codegen.returnExpression(bodyExpressions);
|
||||
}
|
||||
|
||||
|
||||
Label methodEnd = new Label();
|
||||
mv.visitLabel(methodEnd);
|
||||
|
||||
@@ -282,7 +296,8 @@ public class FunctionCodegen {
|
||||
// TODO: specify signature
|
||||
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(
|
||||
context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE);
|
||||
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);
|
||||
k += Math.max(type.getSize(), sharedVarType.getSize());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
mv.visitLocalVariable(parameter.getName().getName(), type.getDescriptor(), null, methodBegin, methodEnd, k);
|
||||
k += type.getSize();
|
||||
}
|
||||
@@ -326,7 +342,7 @@ public class FunctionCodegen {
|
||||
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 {
|
||||
mv.visitMaxs(-1, -1);
|
||||
}
|
||||
@@ -335,18 +351,30 @@ public class FunctionCodegen {
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new CompilationException(
|
||||
"wrong code generated" + (description != null ? " for " + description : "") + t.getClass().getName() + " " + t.getMessage(),
|
||||
t, method);
|
||||
"wrong code generated" +
|
||||
(description != null ? " for " + description : "") +
|
||||
t.getClass().getName() +
|
||||
" " +
|
||||
t.getMessage(),
|
||||
t, method);
|
||||
}
|
||||
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) {
|
||||
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>();
|
||||
Set<FunctionDescriptor> visited = new HashSet<FunctionDescriptor>();
|
||||
@@ -365,7 +393,8 @@ public class FunctionCodegen {
|
||||
while (!bfsQueue.isEmpty()) {
|
||||
FunctionDescriptor descriptor = bfsQueue.poll();
|
||||
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)) {
|
||||
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();
|
||||
|
||||
if (kind != OwnerKind.TRAIT_IMPL) {
|
||||
@@ -395,8 +431,9 @@ public class FunctionCodegen {
|
||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), contextClass);
|
||||
if (psiElement instanceof JetClass) {
|
||||
JetClass element = (JetClass) psiElement;
|
||||
if (element.isTrait())
|
||||
if (element.isTrait()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,14 +465,19 @@ public class FunctionCodegen {
|
||||
ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe());
|
||||
}
|
||||
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());
|
||||
if (!isStatic && !isConstructor)
|
||||
if (!isStatic && !isConstructor) {
|
||||
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);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubCode(mv);
|
||||
@@ -469,7 +511,7 @@ public class FunctionCodegen {
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize();
|
||||
frameMap.enter(paramDescrs.get(i),size);
|
||||
frameMap.enter(paramDescrs.get(i), size);
|
||||
var += size;
|
||||
}
|
||||
|
||||
@@ -503,7 +545,8 @@ public class FunctionCodegen {
|
||||
Label loadArg = new Label();
|
||||
iv.ifeq(loadArg);
|
||||
|
||||
JetParameter jetParameter = (JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor);
|
||||
JetParameter jetParameter =
|
||||
(JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor);
|
||||
assert jetParameter != null;
|
||||
codegen.gen(jetParameter.getDefaultValue(), t);
|
||||
|
||||
@@ -522,10 +565,12 @@ public class FunctionCodegen {
|
||||
iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||
}
|
||||
else {
|
||||
if (!isConstructor)
|
||||
if (!isConstructor) {
|
||||
iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||
else
|
||||
}
|
||||
else {
|
||||
iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -534,26 +579,38 @@ public class FunctionCodegen {
|
||||
|
||||
iv.areturn(jvmSignature.getReturnType());
|
||||
|
||||
endVisit(mv, "default method", BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
|
||||
endVisit(mv, "default method",
|
||||
BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean differentMethods(Method method, Method overridden) {
|
||||
if (!method.getReturnType().equals(overridden.getReturnType()))
|
||||
if (!method.getReturnType().equals(overridden.getReturnType())) {
|
||||
return true;
|
||||
}
|
||||
Type[] methodArgumentTypes = method.getArgumentTypes();
|
||||
Type[] overriddenArgumentTypes = overridden.getArgumentTypes();
|
||||
if (methodArgumentTypes.length != overriddenArgumentTypes.length)
|
||||
if (methodArgumentTypes.length != overriddenArgumentTypes.length) {
|
||||
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 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.
|
||||
|
||||
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(
|
||||
((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), MapTypeMode.VALUE).getInternalName(),
|
||||
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());
|
||||
if (jvmSignature.getReturnType() == Type.VOID_TYPE)
|
||||
}
|
||||
if (jvmSignature.getReturnType() == Type.VOID_TYPE) {
|
||||
iv.aconst(null);
|
||||
}
|
||||
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) {
|
||||
JvmMethodSignature jvmMethodSignature = state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor);
|
||||
JvmMethodSignature jvmMethodSignature =
|
||||
state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor);
|
||||
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();
|
||||
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
|
||||
|
||||
@@ -629,11 +695,14 @@ public class FunctionCodegen {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
field.put(field.type, iv);
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration();
|
||||
String internalName = state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName();
|
||||
if (classDescriptor.getKind() == ClassKind.TRAIT)
|
||||
String internalName =
|
||||
state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName();
|
||||
if (classDescriptor.getKind() == ClassKind.TRAIT) {
|
||||
iv.invokeinterface(internalName, method.getName(), method.getDescriptor());
|
||||
else
|
||||
}
|
||||
else {
|
||||
iv.invokevirtual(internalName, method.getName(), method.getDescriptor());
|
||||
}
|
||||
iv.areturn(method.getReturnType());
|
||||
endVisit(mv, "delegate method", BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), functionDescriptor));
|
||||
}
|
||||
|
||||
+3
-3
@@ -19,19 +19,19 @@
|
||||
*/
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.Method;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeneratedAnonymousClassDescriptor {
|
||||
private final JvmClassName classname;
|
||||
private Method constructor;
|
||||
private final Method constructor;
|
||||
private final Type captureThis;
|
||||
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) {
|
||||
this.classname = classname;
|
||||
|
||||
@@ -19,15 +19,11 @@ package org.jetbrains.jet.codegen;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
* @author yole
|
||||
*/
|
||||
public class GeneratedClassLoader extends ClassLoader {
|
||||
private ClassFileFactory state;
|
||||
|
||||
public GeneratedClassLoader(@NotNull ClassFileFactory state) {
|
||||
this(state, GeneratedClassLoader.class.getClassLoader());
|
||||
}
|
||||
|
||||
public GeneratedClassLoader(@NotNull ClassFileFactory state, ClassLoader parentClassLoader) {
|
||||
super(parentClassLoader);
|
||||
this.state = state;
|
||||
|
||||
@@ -62,8 +62,10 @@ public class GenerationState {
|
||||
this(builderFactory, Progress.DEAF, analyzeExhaust, files, BuiltinToJavaTypesMapping.ENABLED);
|
||||
}
|
||||
|
||||
public GenerationState(ClassBuilderFactory builderFactory, Progress progress,
|
||||
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping) {
|
||||
public GenerationState(
|
||||
ClassBuilderFactory builderFactory, Progress progress,
|
||||
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping
|
||||
) {
|
||||
this.progress = progress;
|
||||
this.analyzeExhaust = exhaust;
|
||||
this.files = files;
|
||||
@@ -90,6 +92,7 @@ public class GenerationState {
|
||||
return progress;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InjectorForJvmCodegen getInjector() {
|
||||
return injector;
|
||||
}
|
||||
@@ -112,15 +115,17 @@ public class GenerationState {
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -142,7 +147,9 @@ public class GenerationState {
|
||||
for (JetFile file : this.files) {
|
||||
if (file.isScript()) {
|
||||
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 JvmClassName className,
|
||||
@NotNull List<Pair<ScriptDescriptor, JvmClassName>> earlierScripts,
|
||||
@NotNull CompilationErrorHandler errorHandler) {
|
||||
@NotNull CompilationErrorHandler errorHandler
|
||||
) {
|
||||
|
||||
injector.getScriptCodegen().registerEarlierScripts(earlierScripts);
|
||||
injector.getClosureAnnotator().registerClassNameForScript(script, className);
|
||||
@@ -191,14 +199,18 @@ public class GenerationState {
|
||||
closure.cv = nameAndVisitor.getSecond();
|
||||
closure.name = nameAndVisitor.getFirst();
|
||||
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();
|
||||
|
||||
ConstructorDescriptor constructorDescriptor = analyzeExhaust.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration);
|
||||
assert constructorDescriptor != null;
|
||||
CallableMethod callableMethod = injector.getJetTypeMapper().mapToCallableMethod(
|
||||
constructorDescriptor, OwnerKind.IMPLEMENTATION, injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(), objectContext.outerWasUsed, null);
|
||||
constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(),
|
||||
objectContext.outerWasUsed, null);
|
||||
}
|
||||
|
||||
public String createText() {
|
||||
@@ -207,10 +219,10 @@ public class GenerationState {
|
||||
final ClassFileFactory factory = getFactory();
|
||||
List<String> files = factory.files();
|
||||
for (String file : files) {
|
||||
// if (!file.startsWith("kotlin/")) {
|
||||
answer.append("@").append(file).append('\n');
|
||||
answer.append(factory.asText(file));
|
||||
// }
|
||||
// if (!file.startsWith("kotlin/")) {
|
||||
answer.append("@").append(file).append('\n');
|
||||
answer.append(factory.asText(file));
|
||||
// }
|
||||
}
|
||||
|
||||
return answer.toString();
|
||||
|
||||
@@ -21,6 +21,11 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.kotlin.JetMethodAnnotationWriter;
|
||||
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.lexer.JetTokens;
|
||||
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 static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
|
||||
import static org.jetbrains.asm4.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -84,8 +84,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (myClass instanceof JetClass) {
|
||||
JetClass jetClass = (JetClass) myClass;
|
||||
if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD))
|
||||
isAbstract = true;
|
||||
if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
|
||||
isAbstract = true;
|
||||
}
|
||||
if (jetClass.isTrait()) {
|
||||
isAbstract = true;
|
||||
isInterface = true;
|
||||
@@ -129,14 +130,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
access |= ACC_ANNOTATION;
|
||||
}
|
||||
if (isEnum) {
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (declaration instanceof JetEnumEntry) {
|
||||
if (state.getInjector().getClosureAnnotator().enumEntryNeedSubclass((JetEnumEntry) declaration)) {
|
||||
access &= ~ACC_FINAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
access |= ACC_ENUM;
|
||||
}
|
||||
List<String> interfaces = signature.getInterfaces();
|
||||
v.defineClass(myClass, V1_6,
|
||||
access,
|
||||
access,
|
||||
signature.getName(),
|
||||
signature.getJavaGenericSignature(),
|
||||
signature.getSuperclassName(),
|
||||
signature.getInterfaces().toArray(new String[0])
|
||||
interfaces.toArray(new String[interfaces.size()])
|
||||
);
|
||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||
|
||||
@@ -170,13 +179,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (descriptor.getClassObjectDescriptor() != null) {
|
||||
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
|
||||
String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||
v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, innerClassAccess);
|
||||
v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME,
|
||||
innerClassAccess);
|
||||
}
|
||||
|
||||
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor);
|
||||
|
||||
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());
|
||||
BitSet flags = CodegenUtil.getFlagsForVisibility(descriptor.getVisibility());
|
||||
int flagsValue = BitSetUtils.toInt(flags);
|
||||
@@ -209,7 +219,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
|
||||
typeMapper.writeFormalTypeParameters(typeParameters, signatureVisitor);
|
||||
}
|
||||
|
||||
|
||||
signatureVisitor.writeSupersStart();
|
||||
|
||||
{ // superclass
|
||||
@@ -242,10 +252,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
superInterfaces = new ArrayList<String>(superInterfacesLinkedHashSet);
|
||||
}
|
||||
|
||||
|
||||
signatureVisitor.writeSupersEnd();
|
||||
|
||||
return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), signatureVisitor.makeKotlinClassSignature());
|
||||
return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(),
|
||||
signatureVisitor.makeKotlinClassSignature());
|
||||
}
|
||||
|
||||
private String jvmName() {
|
||||
@@ -261,8 +272,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
||||
|
||||
if (myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
||||
if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (kind != OwnerKind.IMPLEMENTATION) {
|
||||
throw new IllegalStateException("must be impl to reach this code: " + kind);
|
||||
@@ -275,16 +287,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (!CodegenUtil.isInterface(superClassDescriptor)) {
|
||||
superClassType = superType;
|
||||
assert superClassDescriptor != null;
|
||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||
superCall = specifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(superClassType == null) {
|
||||
if (myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||
if (superClassType == null) {
|
||||
if (descriptor.getKind() == ClassKind.ENUM_CLASS) {
|
||||
superClassType = JetStandardLibrary.getInstance().getEnumType(descriptor.getDefaultType());
|
||||
superClass = typeMapper.mapType(superClassType,MapTypeMode.VALUE).getInternalName();
|
||||
superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName();
|
||||
}
|
||||
if (descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
superClassType = descriptor.getTypeConstructor().getSupertypes().iterator().next();
|
||||
superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,10 +317,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
catch (CompilationException e) {
|
||||
throw e;
|
||||
}
|
||||
catch(ProcessCanceledException e) {
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
}
|
||||
catch(RuntimeException e) {
|
||||
catch (RuntimeException e) {
|
||||
throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e);
|
||||
}
|
||||
|
||||
@@ -315,18 +332,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateEnumMethods() {
|
||||
if(myEnumConstants.size() > 0) {
|
||||
if (myEnumConstants.size() > 0) {
|
||||
{
|
||||
Type type = typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL);
|
||||
Type type =
|
||||
typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL);
|
||||
|
||||
MethodVisitor mv =
|
||||
v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(),MapTypeMode.VALUE).getInternalName(), VALUES, type.getDescriptor());
|
||||
mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), VALUES,
|
||||
type.getDescriptor());
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;");
|
||||
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
||||
mv.visitInsn(ARETURN);
|
||||
FunctionCodegen.endVisit(mv,"values()",myClass);
|
||||
FunctionCodegen.endVisit(mv, "values()", myClass);
|
||||
}
|
||||
{
|
||||
Type type = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL);
|
||||
@@ -339,7 +358,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
|
||||
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
||||
mv.visitInsn(ARETURN);
|
||||
FunctionCodegen.endVisit(mv,"values()",myClass);
|
||||
FunctionCodegen.endVisit(mv, "values()", myClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,10 +412,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
|
||||
MethodVisitor mv =
|
||||
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(),
|
||||
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
|
||||
original, ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility());
|
||||
original,
|
||||
getter.getVisibility());
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubCode(mv);
|
||||
}
|
||||
@@ -406,25 +429,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
if (original.getVisibility() == Visibilities.PRIVATE)
|
||||
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getReturnType().getDescriptor());
|
||||
else
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor());
|
||||
if (original.getVisibility() == Visibilities.PRIVATE) {
|
||||
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(),
|
||||
originalMethod.getReturnType().getDescriptor());
|
||||
}
|
||||
else {
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(),
|
||||
originalMethod.getName(), originalMethod.getDescriptor());
|
||||
}
|
||||
|
||||
iv.areturn(method.getReturnType());
|
||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||
}
|
||||
}
|
||||
|
||||
if (bridge.isVar())
|
||||
{
|
||||
if (bridge.isVar()) {
|
||||
Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||
MethodVisitor mv =
|
||||
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(),
|
||||
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
|
||||
original, ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility());
|
||||
original,
|
||||
setter.getVisibility());
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubCode(mv);
|
||||
}
|
||||
@@ -441,10 +471,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argType.getSize();
|
||||
}
|
||||
if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL)
|
||||
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getArgumentTypes()[0].getDescriptor());
|
||||
else
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor());
|
||||
if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) {
|
||||
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(),
|
||||
originalMethod.getArgumentTypes()[0].getDescriptor());
|
||||
}
|
||||
else {
|
||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(),
|
||||
originalMethod.getName(), originalMethod.getDescriptor());
|
||||
}
|
||||
|
||||
iv.areturn(method.getReturnType());
|
||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||
@@ -471,7 +505,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getDescriptor());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +512,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
final JetClassObject classObject = getClassObject();
|
||||
if (classObject != null) {
|
||||
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
|
||||
assert descriptor1 != null;
|
||||
Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE).getInternalName());
|
||||
v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null);
|
||||
|
||||
@@ -486,6 +520,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
|
||||
assert descriptor1 != null;
|
||||
String name = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||
final Type classObjectType = Type.getObjectType(name);
|
||||
v.anew(classObjectType);
|
||||
@@ -500,9 +535,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
protected void generatePrimaryConstructor() {
|
||||
if (myClass instanceof JetClass) {
|
||||
JetClass aClass = (JetClass)myClass;
|
||||
if (aClass.isTrait())
|
||||
JetClass aClass = (JetClass) myClass;
|
||||
if (aClass.isTrait()) {
|
||||
return;
|
||||
}
|
||||
if (aClass.isAnnotation()) {
|
||||
return;
|
||||
}
|
||||
@@ -521,27 +557,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
boolean hasThis0 = typeMapper.hasThis0(descriptor);
|
||||
if (constructorDescriptor == null) {
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
|
||||
|
||||
|
||||
signatureWriter.writeFormalTypeParametersStart();
|
||||
signatureWriter.writeFormalTypeParametersEnd();
|
||||
|
||||
|
||||
signatureWriter.writeParametersStart();
|
||||
|
||||
|
||||
if (hasThis0) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
|
||||
typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
typeMapper
|
||||
.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter,
|
||||
MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
|
||||
signatureWriter.writeVoidReturn();
|
||||
|
||||
constructorMethod = signatureWriter.makeJvmMethodSignature("<init>");
|
||||
callableMethod = new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null, null);
|
||||
callableMethod =
|
||||
new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null,
|
||||
null);
|
||||
}
|
||||
else {
|
||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind,
|
||||
typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
constructorMethod = callableMethod.getSignature();
|
||||
}
|
||||
|
||||
@@ -566,22 +607,28 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
ObjectOrClosureCodegen closure = context.closure;
|
||||
int firstSuperArgument = -1;
|
||||
final LinkedList<JvmMethodParameterSignature> consArgTypes = new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
||||
final LinkedList<JvmMethodParameterSignature> consArgTypes =
|
||||
new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
||||
|
||||
int insert = 0;
|
||||
if (closure != null) {
|
||||
if (closure.captureThis != null) {
|
||||
if (!hasThis0)
|
||||
consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()), "", JvmMethodParameterKind.THIS0));
|
||||
if (!hasThis0) {
|
||||
consArgTypes.add(insert,
|
||||
new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()),
|
||||
"", JvmMethodParameterKind.THIS0));
|
||||
}
|
||||
insert++;
|
||||
}
|
||||
else {
|
||||
if (hasThis0)
|
||||
if (hasThis0) {
|
||||
insert++;
|
||||
}
|
||||
}
|
||||
|
||||
if (closure.captureReceiver != null)
|
||||
if (closure.captureReceiver != null) {
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER));
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
|
||||
if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
||||
@@ -591,7 +638,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
type = sharedVarType;
|
||||
}
|
||||
else {
|
||||
type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE);
|
||||
type = state.getInjector().getJetTypeMapper()
|
||||
.mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE);
|
||||
}
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR));
|
||||
}
|
||||
@@ -603,16 +651,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||
if (superCall instanceof JetDelegatorToSuperCall) {
|
||||
if (closure != null)
|
||||
if (closure != null) {
|
||||
closure.superCall = (JetDelegatorToSuperCall) superCall;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||
}
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||
((JetDelegatorToSuperCall) superCall).getCalleeExpression()
|
||||
.getConstructorReferenceExpression());
|
||||
if (declarationDescriptor instanceof ClassDescriptorFromSource) {
|
||||
declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor();
|
||||
}
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor;
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper
|
||||
.hasThis0(superConstructor.getContainingDeclaration()));
|
||||
firstSuperArgument = insert;
|
||||
for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR));
|
||||
}
|
||||
}
|
||||
@@ -621,7 +673,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
int flags = JetTypeMapper.getAccessModifiers(constructorDescriptor, 0);
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null);
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(),
|
||||
constructorMethod.getGenericsSignature(), null);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
|
||||
|
||||
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
|
||||
@@ -632,7 +685,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
jetConstructorVisitor.visitEnd();
|
||||
|
||||
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(constructorDescriptor);
|
||||
|
||||
if (constructorDescriptor != null) {
|
||||
@@ -642,13 +695,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
i++;
|
||||
}
|
||||
|
||||
if(myClass instanceof JetClass && ((JetClass)myClass).hasModifier(JetTokens.ENUM_KEYWORD)) {
|
||||
if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
i += 2;
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
|
||||
AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(valueParameter);
|
||||
JetValueParameterAnnotationWriter jetValueParameterAnnotation = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
|
||||
JetValueParameterAnnotationWriter jetValueParameterAnnotation =
|
||||
JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
|
||||
jetValueParameterAnnotation.writeName(valueParameter.getName().getName());
|
||||
jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
|
||||
jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i));
|
||||
@@ -665,20 +719,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
mv.visitCode();
|
||||
|
||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
||||
? constructorDescriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>emptyList();
|
||||
? constructorDescriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>emptyList();
|
||||
|
||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, hasThis0);
|
||||
|
||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state);
|
||||
|
||||
// for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) {
|
||||
// if (constructorDescriptor != null)
|
||||
// codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
// else
|
||||
// codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
// }
|
||||
// for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) {
|
||||
// if (constructorDescriptor != null)
|
||||
// codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
// else
|
||||
// codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO));
|
||||
// }
|
||||
|
||||
Type classType = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL);
|
||||
JvmClassName classname = JvmClassName.byType(classType);
|
||||
@@ -694,7 +748,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (superCall == null) {
|
||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||
if(descriptor.getKind() == ClassKind.ENUM_CLASS) {
|
||||
if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
iv.load(1, JetTypeMapper.JL_STRING_TYPE);
|
||||
iv.load(2, Type.INT_TYPE);
|
||||
iv.invokespecial(superClass, "<init>", "(Ljava/lang/String;I)V");
|
||||
@@ -711,14 +765,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (typeMapper.hasThis0(superClassDescriptor)) {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
parameterTypes.add(typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE));
|
||||
parameterTypes.add(typeMapper.mapType(
|
||||
typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE));
|
||||
}
|
||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "<init>", superCallMethod.getDescriptor());
|
||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "<init>",
|
||||
superCallMethod.getDescriptor());
|
||||
}
|
||||
else {
|
||||
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument);
|
||||
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||
((JetDelegatorToSuperCall) superCall)
|
||||
.getCalleeExpression()
|
||||
.getConstructorReferenceExpression());
|
||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap,
|
||||
firstSuperArgument);
|
||||
}
|
||||
|
||||
final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor);
|
||||
@@ -738,11 +798,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (closure.captureReceiver != null) {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(1, closure.captureReceiver);
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor());
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0",
|
||||
closure.captureReceiver.getDescriptor());
|
||||
k += closure.captureReceiver.getSize();
|
||||
}
|
||||
|
||||
int l = 0;
|
||||
for (DeclarationDescriptor varDescr : closure.closure.keySet()) {
|
||||
if (varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) {
|
||||
Type sharedVarType = typeMapper.getSharedVarType(varDescr);
|
||||
@@ -752,16 +812,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(k, StackValue.refType(sharedVarType));
|
||||
k += StackValue.refType(sharedVarType).getSize();
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor());
|
||||
l++;
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(),
|
||||
"$" + varDescr.getName(), sharedVarType.getDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier == superCall)
|
||||
if (specifier == superCall) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||
iv.load(0, classType);
|
||||
@@ -779,8 +840,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
JetClass superClass = (JetClass) BindingContextUtils.classDescriptorToDeclaration(bindingContext, superClassDescriptor);
|
||||
final CodegenContext delegateContext = context.intoClass(superClassDescriptor,
|
||||
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
|
||||
typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()), state.getInjector().getJetTypeMapper());
|
||||
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname,
|
||||
delegateField, false),
|
||||
typeMapper.mapType(superClassDescriptor
|
||||
.getDefaultType(),
|
||||
MapTypeMode.IMPL)
|
||||
.getInternalName()),
|
||||
state.getInjector().getJetTypeMapper());
|
||||
generateDelegates(superClass, delegateContext, field);
|
||||
}
|
||||
}
|
||||
@@ -803,15 +869,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
mv.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(mv, "constructor", myClass);
|
||||
|
||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
|
||||
OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
|
||||
private void generateTraitMethods() {
|
||||
if (myClass instanceof JetClass && (((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD)))
|
||||
if (myClass instanceof JetClass &&
|
||||
(((JetClass) myClass).isTrait() || ((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))) {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) {
|
||||
CallableMemberDescriptor callableDescriptor = needDelegates.first;
|
||||
if (needDelegates.second instanceof SimpleFunctionDescriptor) {
|
||||
generateDelegationToTraitImpl((FunctionDescriptor) needDelegates.second, (FunctionDescriptor) needDelegates.first);
|
||||
}
|
||||
@@ -843,11 +911,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) fun).getCorrespondingProperty();
|
||||
if (fun instanceof PropertyGetterDescriptor) {
|
||||
function = typeMapper.mapGetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
functionOriginal = typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
functionOriginal =
|
||||
typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature()
|
||||
.getAsmMethod();
|
||||
}
|
||||
else if (fun instanceof PropertySetterDescriptor) {
|
||||
function = typeMapper.mapSetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
functionOriginal = typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
functionOriginal =
|
||||
typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature()
|
||||
.getAsmMethod();
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Accessor is neither getter, nor setter, what is it?");
|
||||
@@ -861,15 +933,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
|
||||
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(fun);
|
||||
|
||||
JvmMethodSignature jvmSignature = typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature();
|
||||
JvmMethodSignature jvmSignature =
|
||||
typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature();
|
||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||
BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(fun.getVisibility());
|
||||
if (fun instanceof PropertyAccessorDescriptor) {
|
||||
kotlinFlags.set(JvmStdlibNames.FLAG_PROPERTY_BIT);
|
||||
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
||||
aw.writePropertyType(jvmSignature.getKotlinReturnType());
|
||||
} else {
|
||||
aw.writeNullableReturnType(fun.getReturnType().isNullable());
|
||||
}
|
||||
else {
|
||||
JetType returnType = fun.getReturnType();
|
||||
assert returnType != null;
|
||||
aw.writeNullableReturnType(returnType.isNullable());
|
||||
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
||||
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
||||
}
|
||||
@@ -882,7 +958,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
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);
|
||||
codegen.generateThisOrOuter(descriptor); // ??? wouldn't it be a good idea to put it?
|
||||
|
||||
Type[] argTypes = function.getArgumentTypes();
|
||||
@@ -904,10 +981,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
type = typeMapper.mapType(jetType, MapTypeMode.IMPL);
|
||||
}
|
||||
|
||||
String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor());
|
||||
Type type1 = typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL);
|
||||
String fdescriptor = functionOriginal.getDescriptor().replace("(", "(" + type.getDescriptor());
|
||||
Type type1 =
|
||||
typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL);
|
||||
iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor);
|
||||
if (function.getReturnType().getSort() == Type.OBJECT && !function.getReturnType().equals(functionOriginal.getReturnType())) {
|
||||
if (function.getReturnType().getSort() == Type.OBJECT &&
|
||||
!function.getReturnType().equals(functionOriginal.getReturnType())) {
|
||||
iv.checkcast(function.getReturnType());
|
||||
}
|
||||
iv.areturn(function.getReturnType());
|
||||
@@ -919,28 +998,39 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||
ConstructorDescriptor constructorDescriptor,
|
||||
ConstructorFrameMap frameMap, int firstSuperArgument) {
|
||||
private void generateDelegatorToConstructorCall(
|
||||
InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||
ConstructorDescriptor constructorDescriptor,
|
||||
ConstructorFrameMap frameMap, int firstSuperArgument
|
||||
) {
|
||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||
|
||||
iv.load(0, TYPE_OBJECT);
|
||||
if(classDecl.getKind() == ClassKind.ENUM_CLASS) {
|
||||
if (classDecl.getKind() == ClassKind.ENUM_CLASS || classDecl.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(2, Type.INT_TYPE);
|
||||
}
|
||||
|
||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL));
|
||||
iv.load(frameMap.getOuterThisIndex(),
|
||||
typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL));
|
||||
}
|
||||
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
CallableMethod method = typeMapper
|
||||
.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
|
||||
if (myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
||||
int nextVar = firstSuperArgument+1;
|
||||
for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
if (myClass instanceof JetObjectDeclaration &&
|
||||
superCall instanceof JetDelegatorToSuperCall &&
|
||||
((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||
((JetDelegatorToSuperCall) superCall)
|
||||
.getCalleeExpression()
|
||||
.getConstructorReferenceExpression());
|
||||
assert superConstructor != null;
|
||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION,
|
||||
typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
||||
int nextVar = firstSuperArgument + 1;
|
||||
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||
iv.load(nextVar, t);
|
||||
nextVar += t.getSize();
|
||||
}
|
||||
@@ -998,8 +1088,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.dup();
|
||||
iv.iconst(ordinal);
|
||||
|
||||
// TODO type and constructor parameters
|
||||
String implClass = typeMapper.mapType(myType, MapTypeMode.IMPL).getInternalName();
|
||||
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, enumConstant);
|
||||
String implClass = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||
|
||||
final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
|
||||
if (delegationSpecifiers.size() > 1) {
|
||||
@@ -1012,12 +1102,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.aconst(enumConstant.getName());
|
||||
iv.iconst(ordinal);
|
||||
|
||||
if (delegationSpecifiers.size() == 1) {
|
||||
if (delegationSpecifiers.size() == 1 && !state.getInjector().getClosureAnnotator().enumEntryNeedSubclass(enumConstant)) {
|
||||
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext
|
||||
.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||
assert constructorDescriptor != null;
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper
|
||||
.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||
codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
|
||||
}
|
||||
else {
|
||||
@@ -1028,14 +1121,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.invokespecial(implClass, "<init>", "(Ljava/lang/String;I)V");
|
||||
}
|
||||
iv.dup();
|
||||
iv.putstatic(implClass, enumConstant.getName(), "L" + implClass + ";");
|
||||
iv.putstatic(myAsmType.getInternalName(), enumConstant.getName(), "L" + myAsmType.getInternalName() + ";");
|
||||
iv.astore(TYPE_OBJECT);
|
||||
}
|
||||
iv.putstatic(myAsmType.getInternalName(), "$VALUES", arrayAsmType.getDescriptor());
|
||||
}
|
||||
|
||||
public static void generateInitializers(@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List<JetDeclaration> declarations,
|
||||
@NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper) {
|
||||
public static void generateInitializers(
|
||||
@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List<JetDeclaration> declarations,
|
||||
@NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper
|
||||
) {
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||
@@ -1048,34 +1143,44 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Object value = compileTimeValue.getValue();
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
|
||||
if (JetTypeMapper.isPrimitive(type)) {
|
||||
if ( !propertyDescriptor.getType().isNullable() && value instanceof Number) {
|
||||
if (type == Type.INT_TYPE && ((Number)value).intValue() == 0)
|
||||
if (!propertyDescriptor.getType().isNullable() && value instanceof Number) {
|
||||
if (type == Type.INT_TYPE && ((Number) value).intValue() == 0) {
|
||||
continue;
|
||||
if (type == Type.BYTE_TYPE && ((Number)value).byteValue() == 0)
|
||||
}
|
||||
if (type == Type.BYTE_TYPE && ((Number) value).byteValue() == 0) {
|
||||
continue;
|
||||
if (type == Type.LONG_TYPE && ((Number)value).longValue() == 0L)
|
||||
}
|
||||
if (type == Type.LONG_TYPE && ((Number) value).longValue() == 0L) {
|
||||
continue;
|
||||
if (type == Type.SHORT_TYPE && ((Number)value).shortValue() == 0)
|
||||
}
|
||||
if (type == Type.SHORT_TYPE && ((Number) value).shortValue() == 0) {
|
||||
continue;
|
||||
if (type == Type.DOUBLE_TYPE && ((Number)value).doubleValue() == 0d)
|
||||
}
|
||||
if (type == Type.DOUBLE_TYPE && ((Number) value).doubleValue() == 0d) {
|
||||
continue;
|
||||
if (type == Type.FLOAT_TYPE && ((Number)value).byteValue() == 0f)
|
||||
}
|
||||
if (type == Type.FLOAT_TYPE && ((Number) value).byteValue() == 0f) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean)value))
|
||||
if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean) value)) {
|
||||
continue;
|
||||
if (type == Type.CHAR_TYPE && value instanceof Character && ((Character)value) == 0)
|
||||
}
|
||||
if (type == Type.CHAR_TYPE && value instanceof Character && ((Character) value) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value == null)
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
Type type = codegen.expressionType(initializer);
|
||||
if (propertyDescriptor.getType().isNullable())
|
||||
if (propertyDescriptor.getType().isNullable()) {
|
||||
type = JetTypeMapper.boxType(type);
|
||||
}
|
||||
codegen.gen(initializer, type);
|
||||
// @todo write directly to the field. Fix test excloset.jet::test6
|
||||
JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
@@ -1083,7 +1188,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
StackValue.property(propertyDescriptor.getName().getName(), owner, owner,
|
||||
propType, false, false, false, null, null, 0).store(propType, iv);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (declaration instanceof JetClassInitializer) {
|
||||
@@ -1105,7 +1209,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) {
|
||||
if (overriddenDescriptor.getContainingDeclaration() == classDescriptor) {
|
||||
if (declaration instanceof PropertyDescriptor) {
|
||||
propertyCodegen.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field);
|
||||
propertyCodegen
|
||||
.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field);
|
||||
}
|
||||
else if (declaration instanceof SimpleFunctionDescriptor) {
|
||||
functionCodegen.genDelegate((SimpleFunctionDescriptor) declaration, overriddenDescriptor, field);
|
||||
@@ -1129,7 +1234,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
*/
|
||||
public static List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) {
|
||||
List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> r = Lists.newArrayList();
|
||||
|
||||
|
||||
root:
|
||||
for (DeclarationDescriptor decl : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||
if (!(decl instanceof CallableMemberDescriptor)) {
|
||||
@@ -1141,7 +1246,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
continue;
|
||||
}
|
||||
|
||||
Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor);
|
||||
Collection<CallableMemberDescriptor> overriddenDeclarations =
|
||||
OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor);
|
||||
for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) {
|
||||
if (overriddenDeclaration.getModality() != Modality.ABSTRACT) {
|
||||
if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) {
|
||||
@@ -1149,7 +1255,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) {
|
||||
if (overriddenDeclaration.getModality() != Modality.ABSTRACT) {
|
||||
r.add(Pair.create(callableMemberDescriptor, overriddenDeclaration));
|
||||
@@ -1159,5 +1265,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.google.common.collect.Maps;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.JvmMethodParameterKind;
|
||||
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.PrimitiveType;
|
||||
import org.jetbrains.jet.lang.types.ref.ClassName;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.asm4.Type;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
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.*;
|
||||
|
||||
@@ -122,6 +125,7 @@ public class JetTypeMapper {
|
||||
@Nullable
|
||||
public Type get(@NotNull JetType type) {
|
||||
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||
assert classifier != null;
|
||||
return asmTypes.get(new SpecialTypeKey(DescriptorUtils.getFQName(classifier), type.isNullable()));
|
||||
}
|
||||
|
||||
@@ -306,11 +310,13 @@ public class JetTypeMapper {
|
||||
return JvmClassName.byInternalName(r.toString());
|
||||
}
|
||||
|
||||
@NotNull public Type mapReturnType(@NotNull final JetType jetType) {
|
||||
@NotNull
|
||||
public Type mapReturnType(@NotNull final JetType jetType) {
|
||||
return mapReturnType(jetType, null);
|
||||
}
|
||||
|
||||
@NotNull private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||
@NotNull
|
||||
private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||
if (jetType.equals(JetStandardClasses.getUnitType())) {
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeAsmType(Type.VOID_TYPE, false);
|
||||
@@ -375,7 +381,12 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
else if (klass.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
return getJvmInternalFQName(klass.getContainingDeclaration());
|
||||
if (closureAnnotator.enumEntryNeedSubclass(klass)) {
|
||||
return getJvmInternalFQName(klass.getContainingDeclaration()) + "$" + klass.getName().getName();
|
||||
}
|
||||
else {
|
||||
return getJvmInternalFQName(klass.getContainingDeclaration());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,6 +439,7 @@ public class JetTypeMapper {
|
||||
throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType);
|
||||
}
|
||||
else if (kind == MapTypeMode.IMPL) {
|
||||
//noinspection ConstantConditions
|
||||
if (mapBuiltinsToJava) {
|
||||
// TODO: enable and fix tests
|
||||
//throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType);
|
||||
@@ -462,13 +474,13 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor
|
||||
&& JetStandardLibraryNames.ARRAY.is((ClassDescriptor) descriptor)
|
||||
&& mapBuiltinsToJava) {
|
||||
&& JetStandardLibraryNames.ARRAY.is((ClassDescriptor) descriptor)
|
||||
&& mapBuiltinsToJava) {
|
||||
if (jetType.getArguments().size() != 1) {
|
||||
throw new UnsupportedOperationException("arrays must have one type argument");
|
||||
}
|
||||
JetType memberType = jetType.getArguments().get(0).getType();
|
||||
|
||||
|
||||
if (signatureVisitor != null) {
|
||||
signatureVisitor.writeArrayType(jetType.isNullable());
|
||||
mapType(memberType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
|
||||
@@ -511,7 +523,8 @@ public class JetTypeMapper {
|
||||
|
||||
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
||||
if (signatureVisitor != null) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
||||
TypeParameterDescriptor typeParameterDescriptor =
|
||||
(TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
||||
assert typeParameterDescriptor != null;
|
||||
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable(), type);
|
||||
}
|
||||
@@ -584,11 +597,13 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) {
|
||||
if (functionDescriptor == null) { return null; }
|
||||
if (functionDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration();
|
||||
|
||||
while(functionDescriptor.getKind()==CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
while (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
functionDescriptor = functionDescriptor.getOverriddenDescriptors().iterator().next();
|
||||
}
|
||||
|
||||
@@ -614,11 +629,12 @@ public class JetTypeMapper {
|
||||
thisClass = null;
|
||||
}
|
||||
else if (functionParent instanceof ScriptDescriptor) {
|
||||
thisClass = owner = ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent);
|
||||
thisClass = owner =
|
||||
ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent);
|
||||
invokeOpcode = INVOKEVIRTUAL;
|
||||
}
|
||||
else if (functionParent instanceof ClassDescriptor) {
|
||||
|
||||
|
||||
FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
|
||||
|
||||
ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
|
||||
@@ -647,8 +663,8 @@ public class JetTypeMapper {
|
||||
ownerForDefaultParam.getInternalName() + (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
|
||||
|
||||
invokeOpcode = isInterface
|
||||
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
|
||||
: (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL));
|
||||
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
|
||||
: (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL));
|
||||
if (isInterface && superCall) {
|
||||
descriptor = mapSignature(functionDescriptor, false, OwnerKind.TRAIT_IMPL);
|
||||
owner = JvmClassName.byInternalName(owner.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
|
||||
@@ -673,7 +689,9 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
private static boolean isAccessor(FunctionDescriptor functionDescriptor) {
|
||||
return functionDescriptor instanceof AccessorForFunctionDescriptor || functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || functionDescriptor instanceof AccessorForPropertyDescriptor.Setter;
|
||||
return functionDescriptor instanceof AccessorForFunctionDescriptor ||
|
||||
functionDescriptor instanceof AccessorForPropertyDescriptor.Getter ||
|
||||
functionDescriptor instanceof AccessorForPropertyDescriptor.Setter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -689,11 +707,11 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, OwnerKind kind) {
|
||||
|
||||
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
needGenericSignature = false;
|
||||
}
|
||||
|
||||
|
||||
BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, needGenericSignature);
|
||||
|
||||
writeFormalTypeParameters(f.getTypeParameters(), signatureVisitor);
|
||||
@@ -704,9 +722,9 @@ public class JetTypeMapper {
|
||||
|
||||
signatureVisitor.writeParametersStart();
|
||||
|
||||
if(isAccessor(f)) {
|
||||
if (isAccessor(f)) {
|
||||
signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE);
|
||||
mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE);
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
@@ -714,11 +732,11 @@ public class JetTypeMapper {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
|
||||
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration);
|
||||
Type type = mapType(jetType, MapTypeMode.VALUE);
|
||||
if(type.getInternalName().equals("java/lang/Object")) {
|
||||
if (type.getInternalName().equals("java/lang/Object")) {
|
||||
jetType = containingDeclaration.getDefaultType();
|
||||
type = mapType(jetType, MapTypeMode.VALUE);
|
||||
}
|
||||
|
||||
|
||||
signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
signatureVisitor.writeAsmType(type, jetType.isNullable());
|
||||
signatureVisitor.writeParameterTypeEnd();
|
||||
@@ -743,7 +761,9 @@ public class JetTypeMapper {
|
||||
}
|
||||
else {
|
||||
signatureVisitor.writeReturnType();
|
||||
mapReturnType(f.getReturnType(), signatureVisitor);
|
||||
JetType returnType = f.getReturnType();
|
||||
assert returnType != null;
|
||||
mapReturnType(returnType, signatureVisitor);
|
||||
signatureVisitor.writeReturnTypeEnd();
|
||||
}
|
||||
return signatureVisitor.makeJvmMethodSignature(f.getName().getName());
|
||||
@@ -763,7 +783,8 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) {
|
||||
signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), typeParameterDescriptor.isReified());
|
||||
signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(),
|
||||
typeParameterDescriptor.isReified());
|
||||
|
||||
classBound:
|
||||
{
|
||||
@@ -799,23 +820,22 @@ public class JetTypeMapper {
|
||||
signatureVisitor.writeInterfaceBoundEnd();
|
||||
}
|
||||
}
|
||||
|
||||
signatureVisitor.writeFormalTypeParameterEnd();
|
||||
|
||||
signatureVisitor.writeFormalTypeParameterEnd();
|
||||
}
|
||||
|
||||
public JvmMethodSignature mapSignature(Name name, FunctionDescriptor f) {
|
||||
final ReceiverDescriptor receiver = f.getReceiverParameter();
|
||||
|
||||
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
|
||||
|
||||
|
||||
writeFormalTypeParameters(f.getTypeParameters(), signatureWriter);
|
||||
|
||||
signatureWriter.writeParametersStart();
|
||||
|
||||
if(isAccessor(f)) {
|
||||
if (isAccessor(f)) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
@@ -832,15 +852,17 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
|
||||
signatureWriter.writeReturnType();
|
||||
mapReturnType(f.getReturnType(), signatureWriter);
|
||||
JetType returnType = f.getReturnType();
|
||||
assert returnType != null;
|
||||
mapReturnType(returnType, signatureWriter);
|
||||
signatureWriter.writeReturnTypeEnd();
|
||||
|
||||
|
||||
return signatureWriter.makeJvmMethodSignature(name.getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
|
||||
final DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration();
|
||||
boolean isAnnotation = parentDescriptor instanceof ClassDescriptor &&
|
||||
@@ -854,16 +876,17 @@ public class JetTypeMapper {
|
||||
|
||||
signatureWriter.writeParametersStart();
|
||||
|
||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor;
|
||||
if (kind == OwnerKind.TRAIT_IMPL) {
|
||||
@SuppressWarnings("ConstantConditions") ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor;
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
else {
|
||||
if(descriptor instanceof AccessorForPropertyDescriptor) {
|
||||
if (descriptor instanceof AccessorForPropertyDescriptor) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter,
|
||||
MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
}
|
||||
@@ -893,7 +916,7 @@ public class JetTypeMapper {
|
||||
|
||||
// TODO: generics signature is not always needed
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true);
|
||||
|
||||
|
||||
writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter);
|
||||
|
||||
JetType outType = descriptor.getType();
|
||||
@@ -908,9 +931,10 @@ public class JetTypeMapper {
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
else {
|
||||
if(descriptor instanceof AccessorForPropertyDescriptor) {
|
||||
if (descriptor instanceof AccessorForPropertyDescriptor) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||
mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter,
|
||||
MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
}
|
||||
@@ -924,19 +948,20 @@ public class JetTypeMapper {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(outType, signatureWriter, MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
|
||||
signatureWriter.writeVoidReturn();
|
||||
|
||||
JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name);
|
||||
return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1));
|
||||
return new JvmPropertyAccessorSignature(jvmMethodSignature,
|
||||
jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1));
|
||||
}
|
||||
|
||||
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, boolean hasThis0) {
|
||||
|
||||
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true);
|
||||
|
||||
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getOriginal().getValueParameters();
|
||||
|
||||
// constructor type parmeters are fake
|
||||
@@ -947,11 +972,12 @@ public class JetTypeMapper {
|
||||
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (hasThis0) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
|
||||
mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter,
|
||||
MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
if(containingDeclaration.getKind() == ClassKind.ENUM_CLASS) {
|
||||
if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_NAME);
|
||||
mapType(JetStandardLibrary.getInstance().getStringType(), signatureWriter, MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
@@ -965,9 +991,9 @@ public class JetTypeMapper {
|
||||
mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
|
||||
signatureWriter.writeParametersEnd();
|
||||
|
||||
|
||||
signatureWriter.writeVoidReturn();
|
||||
|
||||
return signatureWriter.makeJvmMethodSignature("<init>");
|
||||
@@ -983,7 +1009,8 @@ public class JetTypeMapper {
|
||||
|
||||
for (ScriptDescriptor importedScript : importedScripts) {
|
||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||
mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
||||
mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter,
|
||||
MapTypeMode.VALUE);
|
||||
signatureWriter.writeParameterTypeEnd();
|
||||
}
|
||||
|
||||
@@ -1044,39 +1071,42 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> allJvmNames(JetClassOrObject jetClass) {
|
||||
Set<String> result = new HashSet<String>();
|
||||
@Nullable
|
||||
public String getJvmInternalName(JetClassOrObject jetClass) {
|
||||
final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass);
|
||||
if (classDescriptor != null) {
|
||||
result.add(mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName());
|
||||
if (classDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
return mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||
}
|
||||
|
||||
private static boolean isForceReal(JvmClassName className) {
|
||||
return JvmPrimitiveType.getByWrapperClass(className) != null
|
||||
|| className.getFqName().getFqName().equals("java.lang.String")
|
||||
|| className.getFqName().getFqName().equals("java.lang.CharSequence")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Object")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Number")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Enum")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Comparable");
|
||||
|| className.getFqName().getFqName().equals("java.lang.String")
|
||||
|| className.getFqName().getFqName().equals("java.lang.CharSequence")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Object")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Number")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Enum")
|
||||
|| className.getFqName().getFqName().equals("java.lang.Comparable");
|
||||
}
|
||||
|
||||
public static boolean isGenericsArray(JetType type) {
|
||||
return JetStandardLibraryNames.ARRAY.is(type) && type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||
return JetStandardLibraryNames.ARRAY.is(type) &&
|
||||
type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||
}
|
||||
|
||||
public Type getSharedVarType(DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||
return StackValue
|
||||
.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||
}
|
||||
else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||
return closureAnnotator.classNameForAnonymousClass((JetElement) psiElement).getAsmType();
|
||||
}
|
||||
else if (descriptor instanceof FunctionDescriptor) {
|
||||
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||
return StackValue
|
||||
.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) {
|
||||
JetType outType = ((VariableDescriptor) descriptor).getType();
|
||||
|
||||
@@ -20,12 +20,20 @@ package org.jetbrains.jet.codegen;
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public enum MapTypeMode {
|
||||
/** jet.Int is mapped to Ljet/Int; */
|
||||
/**
|
||||
* jet.Int is mapped to Ljet/Int;
|
||||
*/
|
||||
IMPL,
|
||||
/** jet.Int is mapped to Ljet/Impl$TImpl; */
|
||||
/**
|
||||
* jet.Int is mapped to Ljet/Impl$TImpl;
|
||||
*/
|
||||
TRAIT_IMPL,
|
||||
/** jet.Int is mapped to I */
|
||||
/**
|
||||
* jet.Int is mapped to I
|
||||
*/
|
||||
VALUE,
|
||||
/** jet.Int is mapped to Ljava/lang/Integer; */
|
||||
/**
|
||||
* jet.Int is mapped to Ljava/lang/Integer;
|
||||
*/
|
||||
TYPE_PARAMETER,
|
||||
}
|
||||
|
||||
@@ -37,8 +37,10 @@ public class MemberCodegen {
|
||||
}
|
||||
|
||||
|
||||
public void generateFunctionOrProperty(@NotNull JetTypeParameterListOwner functionOrProperty,
|
||||
@NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) {
|
||||
public void generateFunctionOrProperty(
|
||||
@NotNull JetTypeParameterListOwner functionOrProperty,
|
||||
@NotNull CodegenContext context, @NotNull ClassBuilder classBuilder
|
||||
) {
|
||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state);
|
||||
if (functionOrProperty instanceof JetNamedFunction) {
|
||||
try {
|
||||
@@ -66,5 +68,4 @@ public class MemberCodegen {
|
||||
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.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
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.PropertyDescriptor;
|
||||
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.Name;
|
||||
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 static org.jetbrains.asm4.Opcodes.*;
|
||||
@@ -50,9 +48,13 @@ public class NamespaceCodegen {
|
||||
@NotNull private final FqName name;
|
||||
private final GenerationState state;
|
||||
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);
|
||||
|
||||
this.v = v;
|
||||
@@ -77,7 +79,6 @@ public class NamespaceCodegen {
|
||||
v.visitSource(sourceFile.getName(), null);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void generate(CompilationErrorHandler errorHandler, final Progress progress) {
|
||||
@@ -101,7 +102,7 @@ public class NamespaceCodegen {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if(errorHandler != null) errorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl());
|
||||
if (errorHandler != null) errorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl());
|
||||
DiagnosticUtils.throwIfRunningOnServer(e);
|
||||
if (ApplicationManager.getApplication().isInternal()) {
|
||||
e.printStackTrace();
|
||||
@@ -151,17 +152,17 @@ public class NamespaceCodegen {
|
||||
if (k > 0) {
|
||||
PsiFile containingFile = file.getContainingFile();
|
||||
String fname = containingFile.getName();
|
||||
fname = fname.substring(0,fname.lastIndexOf('.'));
|
||||
String className = name.child(Name.identifier("namespace$src$" + fname)).getFqName().replace('.','/');
|
||||
ClassBuilder builder = state.forNamespacepart(className, file);
|
||||
fname = fname.substring(0, fname.lastIndexOf('.'));
|
||||
String className = name.child(Name.identifier("namespace$src$" + fname)).getFqName().replace('.', '/');
|
||||
ClassBuilder builder = state.forNamespacepart(className);
|
||||
|
||||
builder.defineClass(containingFile, V1_6,
|
||||
ACC_PUBLIC/*|ACC_SUPER*/,
|
||||
className,
|
||||
null,
|
||||
//"jet/lang/Namespace",
|
||||
"java/lang/Object",
|
||||
new String[0]
|
||||
ACC_PUBLIC/*|ACC_SUPER*/,
|
||||
className,
|
||||
null,
|
||||
//"jet/lang/Namespace",
|
||||
"java/lang/Object",
|
||||
new String[0]
|
||||
);
|
||||
builder.visitSource(containingFile.getName(), null);
|
||||
|
||||
@@ -169,11 +170,13 @@ public class NamespaceCodegen {
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
{
|
||||
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);
|
||||
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) {
|
||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||
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;
|
||||
codegen.genToJVMStack(initializer);
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(descriptor, true, null);
|
||||
@@ -260,7 +264,6 @@ public class NamespaceCodegen {
|
||||
if (initializer != null && !(initializer instanceof JetConstantExpression)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
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.psi.JetDelegatorToSuperCall;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
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.Map;
|
||||
@@ -40,7 +40,8 @@ public class ObjectOrClosureCodegen {
|
||||
protected final CodegenContext context;
|
||||
protected ClassBuilder cv = 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 ObjectOrClosureCodegen(ExpressionCodegen exprContext, CodegenContext context, GenerationState state) {
|
||||
@@ -69,8 +70,8 @@ public class ObjectOrClosureCodegen {
|
||||
StackValue outerValue = StackValue.local(idx, type);
|
||||
final String fieldName = "$" + vd.getName();
|
||||
StackValue innerValue = sharedVarType != null
|
||||
? StackValue.fieldForSharedVar(localType, name, fieldName)
|
||||
: StackValue.field(type, name, fieldName, false);
|
||||
? StackValue.fieldForSharedVar(localType, name, fieldName)
|
||||
: StackValue.field(type, name, fieldName, false);
|
||||
|
||||
cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null);
|
||||
|
||||
@@ -111,10 +112,12 @@ public class ObjectOrClosureCodegen {
|
||||
|
||||
CodegenContexts.ReceiverContext fcontext = (CodegenContexts.ReceiverContext) context;
|
||||
|
||||
if (fcontext.getReceiverDescriptor() != fd)
|
||||
if (fcontext.getReceiverDescriptor() != fd) {
|
||||
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;
|
||||
StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type);
|
||||
final String fieldName = "receiver$0";
|
||||
@@ -134,7 +137,7 @@ public class ObjectOrClosureCodegen {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConst () {
|
||||
public boolean isConst() {
|
||||
return captureThis == null && captureReceiver == null && closure.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,19 +50,13 @@ public class OwnerKind {
|
||||
}
|
||||
|
||||
public static class StaticDelegateKind extends OwnerKind {
|
||||
private final StackValue delegate;
|
||||
private final String ownerClass;
|
||||
|
||||
public StaticDelegateKind(StackValue delegate, String ownerClass) {
|
||||
public StaticDelegateKind(String ownerClass) {
|
||||
super("staticDelegateKind");
|
||||
this.delegate = delegate;
|
||||
this.ownerClass = ownerClass;
|
||||
}
|
||||
|
||||
public StackValue getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public String getOwnerClass() {
|
||||
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.psi.PsiElement;
|
||||
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.kotlin.JetMethodAnnotationWriter;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
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.name.Name;
|
||||
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;
|
||||
|
||||
@@ -62,9 +62,10 @@ public class PropertyCodegen {
|
||||
throw new UnsupportedOperationException("expect a property to have a property descriptor");
|
||||
}
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind ==OwnerKind.TRAIT_IMPL ) {
|
||||
if (kind != OwnerKind.TRAIT_IMPL)
|
||||
if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL) {
|
||||
if (kind != OwnerKind.TRAIT_IMPL) {
|
||||
generateBackingField(p, propertyDescriptor);
|
||||
}
|
||||
generateGetter(p, propertyDescriptor);
|
||||
generateSetter(p, propertyDescriptor);
|
||||
}
|
||||
@@ -77,13 +78,15 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) {
|
||||
//noinspection ConstantConditions
|
||||
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
if (CodegenUtil.isInterface(containingDeclaration))
|
||||
if (CodegenUtil.isInterface(containingDeclaration)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = null;
|
||||
final JetExpression initializer = p instanceof JetProperty ? ((JetProperty)p).getInitializer() : null;
|
||||
final JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null;
|
||||
if (initializer != null) {
|
||||
if (initializer instanceof JetConstantExpression) {
|
||||
CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer);
|
||||
@@ -113,8 +116,10 @@ public class PropertyCodegen {
|
||||
final JetPropertyAccessor getter = p.getGetter();
|
||||
if (getter != null) {
|
||||
if (getter.getBodyExpression() != null) {
|
||||
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter());
|
||||
JvmPropertyAccessorSignature signature =
|
||||
state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
|
||||
propertyDescriptor.getGetter());
|
||||
}
|
||||
else if (isExternallyAccessible(propertyDescriptor)) {
|
||||
generateDefaultGetter(p);
|
||||
@@ -136,8 +141,11 @@ public class PropertyCodegen {
|
||||
if (setter.getBodyExpression() != null) {
|
||||
final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
|
||||
assert setterDescriptor != null;
|
||||
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor);
|
||||
JvmPropertyAccessorSignature signature =
|
||||
state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
assert signature != null;
|
||||
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
|
||||
setterDescriptor);
|
||||
}
|
||||
else if (isExternallyAccessible(propertyDescriptor)) {
|
||||
generateDefaultSetter(p);
|
||||
@@ -151,7 +159,10 @@ public class PropertyCodegen {
|
||||
private void generateDefaultGetter(JetProperty p) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -168,10 +179,12 @@ public class PropertyCodegen {
|
||||
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();
|
||||
if (isTrait && !(kind instanceof OwnerKind.DelegateKind))
|
||||
if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) {
|
||||
flags |= Opcodes.ACC_ABSTRACT;
|
||||
}
|
||||
|
||||
if (propertyDescriptor.getModality() == Modality.FINAL) {
|
||||
flags |= Opcodes.ACC_FINAL;
|
||||
@@ -181,19 +194,21 @@ public class PropertyCodegen {
|
||||
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
|
||||
String getterName = getterName(propertyDescriptor.getName());
|
||||
MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null);
|
||||
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(),
|
||||
signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor,
|
||||
propertyDescriptor.getGetter() == null
|
||||
? propertyDescriptor.getVisibility()
|
||||
: propertyDescriptor.getGetter().getVisibility());
|
||||
getter == null
|
||||
? propertyDescriptor.getVisibility()
|
||||
: getter.getVisibility());
|
||||
|
||||
if (propertyDescriptor.getGetter() != null) {
|
||||
assert !propertyDescriptor.getGetter().hasBody();
|
||||
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor.getGetter());
|
||||
if (getter != null) {
|
||||
//noinspection ConstantConditions
|
||||
assert !getter.hasBody();
|
||||
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(getter);
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
|
||||
if (propertyDescriptor.getModality() != Modality.ABSTRACT) {
|
||||
if (propertyDescriptor.getModality() != Modality.ABSTRACT) {
|
||||
mv.visitCode();
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubThrow(mv);
|
||||
@@ -228,8 +243,10 @@ public class PropertyCodegen {
|
||||
FunctionCodegen.endVisit(mv, "getter", origin);
|
||||
}
|
||||
|
||||
public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters,
|
||||
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility) {
|
||||
public static void generateJetPropertyAnnotation(
|
||||
MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters,
|
||||
@NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility
|
||||
) {
|
||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||
Modality modality = propertyDescriptor.getModality();
|
||||
BitSet flags = CodegenUtil.getFlagsForVisibility(visibility);
|
||||
@@ -269,29 +286,32 @@ public class PropertyCodegen {
|
||||
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();
|
||||
if (isTrait && !(kind instanceof OwnerKind.DelegateKind))
|
||||
if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) {
|
||||
flags |= Opcodes.ACC_ABSTRACT;
|
||||
}
|
||||
|
||||
if (propertyDescriptor.getModality() == Modality.FINAL) {
|
||||
flags |= Opcodes.ACC_FINAL;
|
||||
}
|
||||
|
||||
JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind);
|
||||
assert signature != null;
|
||||
final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor();
|
||||
MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null);
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
assert setter != null;
|
||||
generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(),
|
||||
signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor,
|
||||
propertyDescriptor.getSetter().getVisibility());
|
||||
setter.getVisibility());
|
||||
|
||||
if (propertyDescriptor.getSetter() != null) {
|
||||
assert !propertyDescriptor.getSetter().hasBody();
|
||||
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor.getSetter());
|
||||
}
|
||||
assert !setter.hasBody();
|
||||
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(setter);
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
|
||||
if (propertyDescriptor.getModality() != Modality.ABSTRACT) {
|
||||
if (propertyDescriptor.getModality() != Modality.ABSTRACT) {
|
||||
mv.visitCode();
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||
StubCodegen.generateStubThrow(mv);
|
||||
@@ -320,8 +340,9 @@ public class PropertyCodegen {
|
||||
else {
|
||||
iv.load(paramCode, type);
|
||||
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
|
||||
state.getInjector().getJetTypeMapper().getOwner(propertyDescriptor, kind).getInternalName(), propertyDescriptor.getName().getName(),
|
||||
type.getDescriptor());
|
||||
state.getInjector().getJetTypeMapper().getOwner(propertyDescriptor, kind).getInternalName(),
|
||||
propertyDescriptor.getName().getName(),
|
||||
type.getDescriptor());
|
||||
}
|
||||
|
||||
iv.visitInsn(Opcodes.RETURN);
|
||||
@@ -340,11 +361,13 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
if (declaration.isVar()) {
|
||||
jvmPropertyAccessorSignature = state.getInjector().getJetTypeMapper().mapSetterSignature(declaration, OwnerKind.IMPLEMENTATION);
|
||||
assert jvmPropertyAccessorSignature != null;
|
||||
functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,19 +19,21 @@ package org.jetbrains.jet.codegen;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
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.Opcodes;
|
||||
import org.jetbrains.asm4.Type;
|
||||
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 java.util.List;
|
||||
@@ -88,30 +90,31 @@ public class ScriptCodegen {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void generate(JetScript scriptDeclaration) {
|
||||
|
||||
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
|
||||
|
||||
assert scriptDescriptor != null;
|
||||
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);
|
||||
|
||||
ClassBuilder classBuilder = classFileFactory.newVisitor(className.getInternalName() + ".class");
|
||||
classBuilder.defineClass(scriptDeclaration,
|
||||
Opcodes.V1_6,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
className.getInternalName(),
|
||||
null,
|
||||
JdkNames.JL_OBJECT.getInternalName(),
|
||||
new String[0]);
|
||||
Opcodes.V1_6,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
className.getInternalName(),
|
||||
null,
|
||||
JdkNames.JL_OBJECT.getInternalName(),
|
||||
new String[0]);
|
||||
|
||||
genMembers(scriptDeclaration, context, classBuilder);
|
||||
genFieldsForParameters(scriptDescriptor, classBuilder);
|
||||
genConstructor(scriptDeclaration, scriptDescriptor, classDescriptorForScript, classBuilder,
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()), earlierScripts);
|
||||
context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()), earlierScripts);
|
||||
|
||||
classBuilder.done();
|
||||
}
|
||||
@@ -122,18 +125,21 @@ public class ScriptCodegen {
|
||||
@NotNull ClassDescriptor classDescriptorForScript,
|
||||
@NotNull ClassBuilder classBuilder,
|
||||
@NotNull CodegenContext context,
|
||||
@NotNull List<ScriptDescriptor> importedScripts) {
|
||||
@NotNull List<ScriptDescriptor> importedScripts
|
||||
) {
|
||||
|
||||
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);
|
||||
|
||||
state.setScriptConstructorMethod(jvmSignature.getAsmMethod());
|
||||
|
||||
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();
|
||||
|
||||
@@ -157,7 +163,7 @@ public class ScriptCodegen {
|
||||
|
||||
for (int i = 0; i < scriptDescriptor.getValueParameters().size(); i++) {
|
||||
ValueParameterDescriptor parameter = scriptDescriptor.getValueParameters().get(i);
|
||||
frameMap.enter(parameter, argTypes[i+add].getSize());
|
||||
frameMap.enter(parameter, argTypes[i + add].getSize());
|
||||
}
|
||||
|
||||
ImplementationBodyCodegen.generateInitializers(
|
||||
@@ -174,7 +180,8 @@ public class ScriptCodegen {
|
||||
instructionAdapter.load(0, className.getAsmType());
|
||||
instructionAdapter.load(offset, earlierClassName.getAsmType());
|
||||
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()) {
|
||||
@@ -185,10 +192,12 @@ public class ScriptCodegen {
|
||||
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) {
|
||||
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);
|
||||
@@ -227,7 +236,6 @@ public class ScriptCodegen {
|
||||
List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList();
|
||||
for (Pair<ScriptDescriptor, JvmClassName> t : earlierScripts) {
|
||||
ScriptDescriptor earlierDescriptor = t.first;
|
||||
JvmClassName earlierClassName = t.second;
|
||||
earlierScriptDescriptors.add(earlierDescriptor);
|
||||
}
|
||||
this.earlierScripts = earlierScriptDescriptors;
|
||||
|
||||
@@ -19,6 +19,11 @@ package org.jetbrains.jet.codegen;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.lang.descriptors.*;
|
||||
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.scopes.receivers.ReceiverDescriptor;
|
||||
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;
|
||||
|
||||
@@ -69,8 +69,8 @@ public abstract class StackValue {
|
||||
* This method is called to put the value on the top of the JVM stack if <code>depth</code> other values have been put on the
|
||||
* JVM stack after this value was generated.
|
||||
*
|
||||
* @param type the type as which the value should be put
|
||||
* @param v the visitor used to generate the instructions
|
||||
* @param type the type as which the value should be put
|
||||
* @param v the visitor used to generate the instructions
|
||||
* @param depth the number of new values put onto the stack
|
||||
*/
|
||||
public void moveToTopOfStack(Type type, InstructionAdapter v, int depth) {
|
||||
@@ -130,7 +130,13 @@ public abstract class StackValue {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -138,7 +144,18 @@ public abstract class StackValue {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -213,10 +230,12 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
protected static void pop(Type type, InstructionAdapter v) {
|
||||
if (type.getSize() == 1)
|
||||
if (type.getSize() == 1) {
|
||||
v.pop();
|
||||
else
|
||||
}
|
||||
else {
|
||||
v.pop2();
|
||||
}
|
||||
}
|
||||
|
||||
protected void coerce(Type toType, InstructionAdapter v) {
|
||||
@@ -233,28 +252,33 @@ public abstract class StackValue {
|
||||
if (toType.getSort() == Type.OBJECT) {
|
||||
putTuple0Instance(v);
|
||||
}
|
||||
else if (toType == Type.LONG_TYPE)
|
||||
else if (toType == Type.LONG_TYPE) {
|
||||
v.lconst(0);
|
||||
else if (toType == Type.FLOAT_TYPE)
|
||||
}
|
||||
else if (toType == Type.FLOAT_TYPE) {
|
||||
v.fconst(0);
|
||||
else if (toType == Type.DOUBLE_TYPE)
|
||||
}
|
||||
else if (toType == Type.DOUBLE_TYPE) {
|
||||
v.dconst(0);
|
||||
else
|
||||
}
|
||||
else {
|
||||
v.iconst(0);
|
||||
}
|
||||
}
|
||||
else if (toType.equals(JetTypeMapper.TUPLE0_TYPE) && !fromType.equals(JetTypeMapper.TUPLE0_TYPE)) {
|
||||
pop(fromType, v);
|
||||
putTuple0Instance(v);
|
||||
}
|
||||
else if (toType.getSort() == Type.OBJECT && fromType.equals(JetTypeMapper.TYPE_OBJECT) || toType.getSort() == Type.ARRAY) {
|
||||
v.checkcast(toType);
|
||||
v.checkcast(toType);
|
||||
}
|
||||
else if (toType.getSort() == Type.OBJECT) {
|
||||
if (fromType.getSort() == Type.OBJECT && !toType.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||
v.checkcast(toType);
|
||||
}
|
||||
else
|
||||
else {
|
||||
box(fromType, toType, v);
|
||||
}
|
||||
}
|
||||
else if (fromType.getSort() == Type.OBJECT && toType.getSort() <= Type.DOUBLE) {
|
||||
if (fromType.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||
@@ -314,14 +338,22 @@ public abstract class StackValue {
|
||||
return new PreIncrement(index, increment);
|
||||
}
|
||||
|
||||
public static StackValue receiver(ResolvedCall<? extends CallableDescriptor> resolvedCall, StackValue receiver, ExpressionCodegen codegen, @Nullable CallableMethod callableMethod, GenerationState state) {
|
||||
if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists())
|
||||
public static StackValue receiver(
|
||||
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 receiver;
|
||||
}
|
||||
|
||||
private static class None extends StackValue {
|
||||
public static None INSTANCE = new None();
|
||||
|
||||
private None() {
|
||||
super(Type.VOID_TYPE);
|
||||
}
|
||||
@@ -396,19 +428,21 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
if (value instanceof Integer)
|
||||
if (value instanceof Integer) {
|
||||
v.iconst((Integer) value);
|
||||
else
|
||||
if (value instanceof Long)
|
||||
}
|
||||
else if (value instanceof Long) {
|
||||
v.lconst((Long) value);
|
||||
else
|
||||
if (value instanceof Float)
|
||||
}
|
||||
else if (value instanceof Float) {
|
||||
v.fconst((Float) value);
|
||||
else
|
||||
if (value instanceof Double)
|
||||
}
|
||||
else if (value instanceof Double) {
|
||||
v.dconst((Double) value);
|
||||
else
|
||||
}
|
||||
else {
|
||||
v.aconst(value);
|
||||
}
|
||||
coerce(type, v);
|
||||
}
|
||||
|
||||
@@ -449,8 +483,9 @@ public abstract class StackValue {
|
||||
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type " + type);
|
||||
}
|
||||
putAsBoolean(v);
|
||||
if(type != Type.BOOLEAN_TYPE)
|
||||
box(Type.BOOLEAN_TYPE,type,v);
|
||||
if (type != Type.BOOLEAN_TYPE) {
|
||||
box(Type.BOOLEAN_TYPE, type, v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -522,8 +557,9 @@ public abstract class StackValue {
|
||||
private Invert(StackValue operand) {
|
||||
super(Type.BOOLEAN_TYPE);
|
||||
myOperand = operand;
|
||||
if (myOperand.type != Type.BOOLEAN_TYPE)
|
||||
if (myOperand.type != Type.BOOLEAN_TYPE) {
|
||||
throw new UnsupportedOperationException("operand of ! must be boolean");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -536,8 +572,9 @@ public abstract class StackValue {
|
||||
throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type");
|
||||
}
|
||||
putAsBoolean(v);
|
||||
if(type != Type.BOOLEAN_TYPE)
|
||||
box(Type.BOOLEAN_TYPE,type,v);
|
||||
if (type != Type.BOOLEAN_TYPE) {
|
||||
box(Type.BOOLEAN_TYPE, type, v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -571,6 +608,7 @@ public abstract class StackValue {
|
||||
v.dup2(); // array and index
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiverSize() {
|
||||
return 2;
|
||||
}
|
||||
@@ -587,7 +625,13 @@ public abstract class StackValue {
|
||||
private final FunctionDescriptor setterDescriptor;
|
||||
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);
|
||||
this.resolvedGetCall = resolvedGetCall;
|
||||
this.resolvedSetCall = resolvedSetCall;
|
||||
@@ -605,10 +649,12 @@ public abstract class StackValue {
|
||||
if (getter == null) {
|
||||
throw new UnsupportedOperationException("no getter specified");
|
||||
}
|
||||
if (getter instanceof CallableMethod)
|
||||
((CallableMethod)getter).invoke(v);
|
||||
else
|
||||
((IntrinsicMethod)getter).generate(codegen, v, type, null, null, null, state);
|
||||
if (getter instanceof CallableMethod) {
|
||||
((CallableMethod) getter).invoke(v);
|
||||
}
|
||||
else {
|
||||
((IntrinsicMethod) getter).generate(codegen, v, type, null, null, null, state);
|
||||
}
|
||||
coerce(type, v);
|
||||
}
|
||||
|
||||
@@ -621,17 +667,19 @@ public abstract class StackValue {
|
||||
CallableMethod method = (CallableMethod) setter;
|
||||
Method asmMethod = method.getSignature().getAsmMethod();
|
||||
Type[] argumentTypes = asmMethod.getArgumentTypes();
|
||||
coerce(topOfStackType, argumentTypes[argumentTypes.length-1], v);
|
||||
coerce(topOfStackType, argumentTypes[argumentTypes.length - 1], v);
|
||||
method.invoke(v);
|
||||
Type returnType = asmMethod.getReturnType();
|
||||
if (returnType != Type.VOID_TYPE) {
|
||||
pop(returnType, v);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
((IntrinsicMethod) setter).generate(codegen, v, null, null, null, null, state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiverSize() {
|
||||
if (isStandardStack(resolvedGetCall, 1) && isStandardStack(resolvedSetCall, 2)) {
|
||||
return 2;
|
||||
@@ -650,27 +698,27 @@ public abstract class StackValue {
|
||||
int size = 0;
|
||||
int lastIndex = frame.enterTemp();
|
||||
frame.leaveTemp();
|
||||
|
||||
|
||||
// indexes
|
||||
List<ValueParameterDescriptor> valueParameters = resolvedGetCall.getResultingDescriptor().getValueParameters();
|
||||
int firstParamIndex = -1;
|
||||
for(int i = valueParameters.size()-1; i >= 0; --i) {
|
||||
for (int i = valueParameters.size() - 1; i >= 0; --i) {
|
||||
Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE);
|
||||
int sz = type.getSize();
|
||||
frame.enterTemp(sz);
|
||||
lastIndex += sz;
|
||||
size += sz;
|
||||
v.store((firstParamIndex = lastIndex)-sz, type);
|
||||
v.store((firstParamIndex = lastIndex) - sz, type);
|
||||
}
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = resolvedGetCall.getResultingDescriptor().getTypeParameters();
|
||||
int firstTypeParamIndex = -1;
|
||||
for(int i = typeParameters.size()-1; i >= 0; --i) {
|
||||
for (int i = typeParameters.size() - 1; i >= 0; --i) {
|
||||
if (typeParameters.get(i).isReified()) {
|
||||
frame.enterTemp();
|
||||
lastIndex++;
|
||||
size++;
|
||||
v.store(firstTypeParamIndex = lastIndex-1, JetTypeMapper.TYPE_OBJECT);
|
||||
v.store(firstTypeParamIndex = lastIndex - 1, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,7 +730,7 @@ public abstract class StackValue {
|
||||
frame.enterTemp(sz);
|
||||
lastIndex += sz;
|
||||
size += sz;
|
||||
v.store((receiverIndex = lastIndex)-sz, type);
|
||||
v.store((receiverIndex = lastIndex) - sz, type);
|
||||
}
|
||||
|
||||
ReceiverDescriptor thisObject = resolvedGetCall.getThisObject();
|
||||
@@ -691,17 +739,17 @@ public abstract class StackValue {
|
||||
frame.enterTemp();
|
||||
lastIndex++;
|
||||
size++;
|
||||
v.store((thisIndex = lastIndex)-1, JetTypeMapper.TYPE_OBJECT);
|
||||
v.store((thisIndex = lastIndex) - 1, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
|
||||
// for setter
|
||||
|
||||
int realReceiverIndex;
|
||||
int realReceiverIndex;
|
||||
Type realReceiverType;
|
||||
if (thisIndex != -1) {
|
||||
if (receiverIndex != -1) {
|
||||
realReceiverIndex = receiverIndex;
|
||||
realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
|
||||
realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
|
||||
}
|
||||
else {
|
||||
realReceiverIndex = thisIndex;
|
||||
@@ -710,7 +758,7 @@ public abstract class StackValue {
|
||||
}
|
||||
else {
|
||||
if (receiverIndex != -1) {
|
||||
realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
|
||||
realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
|
||||
realReceiverIndex = receiverIndex;
|
||||
}
|
||||
else {
|
||||
@@ -734,38 +782,38 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
int index = firstParamIndex;
|
||||
for(int i = 0; i != valueParameters.size(); ++i) {
|
||||
for (int i = 0; i != valueParameters.size(); ++i) {
|
||||
Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE);
|
||||
int sz = type.getSize();
|
||||
v.load(index-sz, type);
|
||||
v.load(index - sz, type);
|
||||
index -= sz;
|
||||
}
|
||||
|
||||
// restoring original
|
||||
if (thisIndex != -1) {
|
||||
v.load(thisIndex-1, JetTypeMapper.TYPE_OBJECT);
|
||||
v.load(thisIndex - 1, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
|
||||
if (receiverIndex != -1) {
|
||||
Type type = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
|
||||
v.load(receiverIndex-type.getSize(), type);
|
||||
v.load(receiverIndex - type.getSize(), type);
|
||||
}
|
||||
|
||||
if (firstTypeParamIndex != -1) {
|
||||
index = firstTypeParamIndex;
|
||||
for(int i = 0; i != typeParameters.size(); ++i) {
|
||||
for (int i = 0; i != typeParameters.size(); ++i) {
|
||||
if (typeParameters.get(i).isReified()) {
|
||||
v.load(index-1, JetTypeMapper.TYPE_OBJECT);
|
||||
v.load(index - 1, JetTypeMapper.TYPE_OBJECT);
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
index = firstParamIndex;
|
||||
for(int i = 0; i != valueParameters.size(); ++i) {
|
||||
for (int i = 0; i != valueParameters.size(); ++i) {
|
||||
Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE);
|
||||
int sz = type.getSize();
|
||||
v.load(index-sz, type);
|
||||
v.load(index - sz, type);
|
||||
index -= sz;
|
||||
}
|
||||
|
||||
@@ -774,30 +822,37 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
private boolean isStandardStack(ResolvedCall call, int valueParamsSize) {
|
||||
if (call == null)
|
||||
if (call == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : call.getResultingDescriptor().getTypeParameters()) {
|
||||
if (typeParameterDescriptor.isReified())
|
||||
if (typeParameterDescriptor.isReified()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> valueParameters = call.getResultingDescriptor().getValueParameters();
|
||||
if (valueParameters.size() != valueParamsSize)
|
||||
if (valueParameters.size() != valueParamsSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (call.getThisObject().exists()) {
|
||||
if (call.getReceiverArgument().exists())
|
||||
if (call.getReceiverArgument().exists()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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 true;
|
||||
@@ -830,6 +885,7 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiverSize() {
|
||||
return isStatic ? 0 : 1;
|
||||
}
|
||||
@@ -857,8 +913,10 @@ public abstract class StackValue {
|
||||
private final boolean isSuper;
|
||||
private final int invokeOpcode;
|
||||
|
||||
public Property(@NotNull String name, @NotNull JvmClassName methodOwner, @NotNull JvmClassName methodOwnerParam,
|
||||
Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type, int invokeOpcode) {
|
||||
public Property(
|
||||
@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);
|
||||
this.name = name;
|
||||
this.methodOwner = methodOwner;
|
||||
@@ -879,15 +937,18 @@ public abstract class StackValue {
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
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 {
|
||||
if (getter == null) {
|
||||
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner.getInternalName(), name, this.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
||||
}
|
||||
if (getter == null) {
|
||||
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner.getInternalName(), name,
|
||||
this.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
||||
}
|
||||
}
|
||||
coerce(type, v);
|
||||
}
|
||||
@@ -895,10 +956,13 @@ public abstract class StackValue {
|
||||
@Override
|
||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||
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) {
|
||||
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 {
|
||||
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor());
|
||||
@@ -912,6 +976,7 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiverSize() {
|
||||
return isStatic ? 0 : 1;
|
||||
}
|
||||
@@ -975,7 +1040,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
public static Type sharedTypeForType(Type type) {
|
||||
switch(type.getSort()) {
|
||||
switch (type.getSort()) {
|
||||
case Type.OBJECT:
|
||||
case Type.ARRAY:
|
||||
return JetTypeMapper.TYPE_SHARED_VAR;
|
||||
@@ -1010,8 +1075,9 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
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 type;
|
||||
}
|
||||
@@ -1031,6 +1097,7 @@ public abstract class StackValue {
|
||||
v.dup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int receiverSize() {
|
||||
return 1;
|
||||
}
|
||||
@@ -1135,20 +1202,27 @@ public abstract class StackValue {
|
||||
private ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
||||
StackValue receiver;
|
||||
private ExpressionCodegen codegen;
|
||||
@NotNull
|
||||
private final GenerationState state;
|
||||
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));
|
||||
this.resolvedCall = resolvedCall;
|
||||
this.receiver = receiver;
|
||||
this.codegen = codegen;
|
||||
this.state = state;
|
||||
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 receiverArgument = resolvedCall.getReceiverArgument();
|
||||
|
||||
@@ -1174,10 +1248,12 @@ public abstract class StackValue {
|
||||
}
|
||||
else {
|
||||
if (receiverArgument.exists()) {
|
||||
if (callableMethod != null)
|
||||
if (callableMethod != null) {
|
||||
return callableMethod.getReceiverClass();
|
||||
else
|
||||
}
|
||||
else {
|
||||
return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Type.VOID_TYPE;
|
||||
@@ -1197,7 +1273,8 @@ public abstract class StackValue {
|
||||
codegen.generateFromResolvedCall(thisObject, callableMethod.getOwner().getAsmType());
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -1212,8 +1289,10 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type,
|
||||
@Nullable ReceiverDescriptor receiverParameter, int depth) {
|
||||
private void genReceiver(
|
||||
InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type,
|
||||
@Nullable ReceiverDescriptor receiverParameter, int depth
|
||||
) {
|
||||
if (receiver == StackValue.none()) {
|
||||
if (receiverParameter != null) {
|
||||
Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
|
||||
|
||||
@@ -28,11 +28,12 @@ public class StubCodegen {
|
||||
}
|
||||
|
||||
public static void generateStubThrow(MethodVisitor mv) {
|
||||
new InstructionAdapter(mv).anew(Type.getObjectType("java/lang/RuntimeException"));
|
||||
new InstructionAdapter(mv).dup();
|
||||
new InstructionAdapter(mv).aconst("Stubs are for compiler only, do not add them to runtime classpath");
|
||||
new InstructionAdapter(mv).invokespecial("java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
|
||||
new InstructionAdapter(mv).athrow();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.anew(Type.getObjectType("java/lang/RuntimeException"));
|
||||
iv.dup();
|
||||
iv.aconst("Stubs are for compiler only, do not add them to runtime classpath");
|
||||
iv.invokespecial("java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
|
||||
iv.athrow();
|
||||
}
|
||||
|
||||
public static void generateStubCode(MethodVisitor mv) {
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class ArrayGet implements IntrinsicMethod {
|
||||
@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);
|
||||
Type type = JetTypeMapper.correctElementType(receiver.type);
|
||||
|
||||
|
||||
@@ -18,19 +18,27 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayIndices implements IntrinsicMethod {
|
||||
@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);
|
||||
v.arraylength();
|
||||
v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;");
|
||||
|
||||
@@ -41,10 +41,20 @@ import java.util.List;
|
||||
*/
|
||||
public class ArrayIterator implements IntrinsicMethod {
|
||||
@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);
|
||||
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();
|
||||
if (JetStandardLibraryNames.ARRAY.is(containingDeclaration)) {
|
||||
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 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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class ArraySet implements IntrinsicMethod {
|
||||
@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);
|
||||
Type type = JetTypeMapper.correctElementType(receiver.type);
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class ArraySize implements IntrinsicMethod {
|
||||
@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);
|
||||
v.arraylength();
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
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;
|
||||
|
||||
@@ -40,7 +40,15 @@ public class BinaryOp implements IntrinsicMethod {
|
||||
}
|
||||
|
||||
@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;
|
||||
if (nullable) {
|
||||
expectedType = JetTypeMapper.unboxType(expectedType);
|
||||
|
||||
@@ -19,12 +19,12 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,12 +33,21 @@ import java.util.List;
|
||||
*/
|
||||
public class CompareTo implements IntrinsicMethod {
|
||||
@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;
|
||||
receiver.put(receiver.type, v);
|
||||
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);
|
||||
}
|
||||
else if (receiver.type == Type.INT_TYPE) {
|
||||
v.invokestatic("jet/runtime/Intrinsics", "compare", "(II)I");
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class Concat implements IntrinsicMethod {
|
||||
@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
|
||||
codegen.generateStringBuilderConstructor();
|
||||
codegen.invokeAppend(arguments.get(0)); // StringBuilder(LHS)
|
||||
|
||||
@@ -42,13 +42,15 @@ public class EmptyRange implements IntrinsicMethod {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen,
|
||||
public StackValue generate(
|
||||
ExpressionCodegen codegen,
|
||||
InstructionAdapter v,
|
||||
@NotNull Type expectedType,
|
||||
@Nullable PsiElement element,
|
||||
@Nullable List<JetExpression> arguments,
|
||||
StackValue receiver,
|
||||
@NotNull GenerationState state) {
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
JvmClassName name = JvmClassName.byFqNameWithoutInnerClasses(elementType.getRangeClassName().getFqName());
|
||||
v.getstatic(name.toString(), "EMPTY", "L" + name + ";");
|
||||
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.resolve.BindingContext;
|
||||
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;
|
||||
|
||||
@@ -36,15 +36,22 @@ import java.util.List;
|
||||
*/
|
||||
public class EnumValueOf implements IntrinsicMethod {
|
||||
@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
|
||||
) {
|
||||
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();
|
||||
JetType returnType = resultingDescriptor.getReturnType();
|
||||
assert returnType != null;
|
||||
Type type = state.getInjector().getJetTypeMapper().mapType(
|
||||
resultingDescriptor.getReturnType(), MapTypeMode.VALUE);
|
||||
codegen.gen(arguments.get(0),JetTypeMapper.JL_STRING_TYPE);
|
||||
v.invokestatic(type.getInternalName(),"valueOf","(Ljava/lang/String;)" + type.getDescriptor());
|
||||
returnType, MapTypeMode.VALUE);
|
||||
assert arguments != null;
|
||||
codegen.gen(arguments.get(0), JetTypeMapper.JL_STRING_TYPE);
|
||||
v.invokestatic(type.getInternalName(), "valueOf", "(Ljava/lang/String;)" + type.getDescriptor());
|
||||
StackValue.onStack(type).put(expectedType, v);
|
||||
return StackValue.onStack(expectedType);
|
||||
}
|
||||
|
||||
@@ -21,12 +21,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
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.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.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -35,13 +39,19 @@ import java.util.List;
|
||||
*/
|
||||
public class EnumValues implements IntrinsicMethod {
|
||||
@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
|
||||
) {
|
||||
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();
|
||||
JetType returnType = resultingDescriptor.getReturnType();
|
||||
assert returnType != null;
|
||||
Type type = state.getInjector().getJetTypeMapper().mapType(
|
||||
resultingDescriptor.getReturnType(), MapTypeMode.VALUE);
|
||||
returnType, MapTypeMode.VALUE);
|
||||
v.invokestatic(type.getElementType().getInternalName(), "values", "()" + type);
|
||||
StackValue.onStack(type).put(expectedType, v);
|
||||
return StackValue.onStack(expectedType);
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
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.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -37,7 +37,15 @@ import java.util.List;
|
||||
*/
|
||||
public class Equals implements IntrinsicMethod {
|
||||
@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;
|
||||
JetExpression rightExpr;
|
||||
@@ -47,14 +55,17 @@ public class Equals implements IntrinsicMethod {
|
||||
JetExpression calleeExpression = jetCallExpression.getCalleeExpression();
|
||||
if (calleeExpression != null) {
|
||||
JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression);
|
||||
if (leftType != null)
|
||||
if (leftType != null) {
|
||||
leftNullable = leftType.isNullable();
|
||||
}
|
||||
}
|
||||
rightExpr = arguments.get(0);
|
||||
}
|
||||
else {
|
||||
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);
|
||||
rightExpr = arguments.get(1);
|
||||
}
|
||||
@@ -62,6 +73,9 @@ public class Equals implements IntrinsicMethod {
|
||||
JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr);
|
||||
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 {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen,
|
||||
public StackValue generate(
|
||||
ExpressionCodegen codegen,
|
||||
InstructionAdapter v,
|
||||
@NotNull Type expectedType,
|
||||
@Nullable PsiElement element,
|
||||
@Nullable List<JetExpression> arguments,
|
||||
StackValue receiver,
|
||||
@NotNull GenerationState state) {
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I");
|
||||
return StackValue.onStack(Type.INT_TYPE);
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
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.JetCallExpression;
|
||||
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.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -38,14 +36,22 @@ import java.util.List;
|
||||
*/
|
||||
public class IdentityEquals implements IntrinsicMethod {
|
||||
@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) {
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
codegen.gen(arguments.get(0)).put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
}
|
||||
else {
|
||||
assert element instanceof JetBinaryExpression;
|
||||
JetBinaryExpression e = (JetBinaryExpression)element;
|
||||
JetBinaryExpression e = (JetBinaryExpression) element;
|
||||
codegen.gen(e.getLeft()).put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
codegen.gen(e.getRight()).put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
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.JetParenthesizedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,15 +41,23 @@ public class Increment implements IntrinsicMethod {
|
||||
}
|
||||
|
||||
@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;
|
||||
if (nullable) {
|
||||
expectedType = JetTypeMapper.unboxType(expectedType);
|
||||
}
|
||||
if (arguments.size() > 0) {
|
||||
JetExpression operand = arguments.get(0);
|
||||
while(operand instanceof JetParenthesizedExpression) {
|
||||
operand = ((JetParenthesizedExpression)operand).getExpression();
|
||||
while (operand instanceof JetParenthesizedExpression) {
|
||||
operand = ((JetParenthesizedExpression) operand).getExpression();
|
||||
}
|
||||
if (operand instanceof JetReferenceExpression) {
|
||||
final int index = codegen.indexOfLocal((JetReferenceExpression) operand);
|
||||
@@ -58,8 +66,8 @@ public class Increment implements IntrinsicMethod {
|
||||
}
|
||||
}
|
||||
StackValue value = codegen.genQualified(receiver, operand);
|
||||
value. dupReceiver(v);
|
||||
value. dupReceiver(v);
|
||||
value.dupReceiver(v);
|
||||
value.dupReceiver(v);
|
||||
|
||||
value.put(expectedType, v);
|
||||
plusMinus(v, expectedType);
|
||||
|
||||
@@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.util.List;
|
||||
* @author yole
|
||||
*/
|
||||
public interface IntrinsicMethod extends Callable {
|
||||
StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
|
||||
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state);
|
||||
StackValue generate(
|
||||
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.Nullable;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
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.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
@@ -141,8 +138,8 @@ public class IntrinsicMethods {
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
declareIntrinsicFunction(type.getTypeName(), Name.identifier("compareTo"), 1, new CompareTo());
|
||||
}
|
||||
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
||||
//
|
||||
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
||||
//
|
||||
declareIntrinsicProperty(Name.identifier("CharSequence"), Name.identifier("length"), new StringLength());
|
||||
declareIntrinsicProperty(Name.identifier("String"), Name.identifier("length"), new StringLength());
|
||||
|
||||
@@ -196,20 +193,6 @@ public class IntrinsicMethods {
|
||||
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
|
||||
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
|
||||
IntrinsicMethod intrinsicMethod = intrinsicsMap.getIntrinsic(descriptor);
|
||||
@@ -226,11 +209,11 @@ public class IntrinsicMethods {
|
||||
}
|
||||
}
|
||||
|
||||
if(isEnumClassObject(functionDescriptor.getContainingDeclaration())) {
|
||||
if("values".equals(functionDescriptor.getName().getName())) {
|
||||
if (isEnumClassObject(functionDescriptor.getContainingDeclaration())) {
|
||||
if ("values".equals(functionDescriptor.getName().getName())) {
|
||||
return ENUM_VALUES;
|
||||
}
|
||||
if("valueOf".equals(functionDescriptor.getName().getName())) {
|
||||
if ("valueOf".equals(functionDescriptor.getName().getName())) {
|
||||
return ENUM_VALUE_OF;
|
||||
}
|
||||
}
|
||||
@@ -239,10 +222,14 @@ public class IntrinsicMethods {
|
||||
List<AnnotationDescriptor> annotations = descriptor.getAnnotations();
|
||||
if (annotations != null) {
|
||||
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();
|
||||
intrinsicMethod = namedMethods.get(value);
|
||||
if (intrinsicMethod != null) { break; }
|
||||
if (intrinsicMethod != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,16 +237,18 @@ public class IntrinsicMethods {
|
||||
}
|
||||
|
||||
private static boolean isEnumClassObject(DeclarationDescriptor declaration) {
|
||||
if(declaration instanceof ClassDescriptor) {
|
||||
if (declaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor descriptor = (ClassDescriptor) declaration;
|
||||
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||
//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 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) {
|
||||
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));
|
||||
return intrinsicsMap.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -34,7 +34,15 @@ import java.util.List;
|
||||
*/
|
||||
public class Inv implements IntrinsicMethod {
|
||||
@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;
|
||||
if (nullable) {
|
||||
expectedType = JetTypeMapper.unboxType(expectedType);
|
||||
|
||||
@@ -19,12 +19,12 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class IteratorIterator implements IntrinsicMethod {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,26 +33,43 @@ import java.util.List;
|
||||
*/
|
||||
public class IteratorNext implements IntrinsicMethod {
|
||||
@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;
|
||||
if (expectedType == Type.CHAR_TYPE)
|
||||
if (expectedType == Type.CHAR_TYPE) {
|
||||
name = "Char";
|
||||
else if (expectedType == Type.BOOLEAN_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.BOOLEAN_TYPE) {
|
||||
name = "Boolean";
|
||||
else if (expectedType == Type.BYTE_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.BYTE_TYPE) {
|
||||
name = "Byte";
|
||||
else if (expectedType == Type.SHORT_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.SHORT_TYPE) {
|
||||
name = "Short";
|
||||
else if (expectedType == Type.INT_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.INT_TYPE) {
|
||||
name = "Int";
|
||||
else if (expectedType == Type.LONG_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.LONG_TYPE) {
|
||||
name = "Long";
|
||||
else if (expectedType == Type.FLOAT_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.FLOAT_TYPE) {
|
||||
name = "Float";
|
||||
else if (expectedType == Type.DOUBLE_TYPE)
|
||||
}
|
||||
else if (expectedType == Type.DOUBLE_TYPE) {
|
||||
name = "Double";
|
||||
else
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
v.invokevirtual("jet/" + name + "Iterator", "next" + name, "()" + expectedType.getDescriptor());
|
||||
return StackValue.onStack(expectedType);
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.GenerationState;
|
||||
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.ResolvedValueArgument;
|
||||
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.Map;
|
||||
@@ -41,17 +41,20 @@ import java.util.Map;
|
||||
*/
|
||||
public class JavaClassArray implements IntrinsicMethod {
|
||||
@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
|
||||
) {
|
||||
ResolvedCall<? extends CallableDescriptor> call =
|
||||
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, ((JetCallExpression)element).getCalleeExpression());
|
||||
Map.Entry<ValueParameterDescriptor,ResolvedValueArgument> next = call.getValueArguments().entrySet().iterator().next();
|
||||
codegen.genVarargs(next.getKey(), (VarargValueArgument)next.getValue());
|
||||
codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, ((JetCallExpression) element).getCalleeExpression());
|
||||
assert call != null;
|
||||
Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> next = call.getValueArguments().entrySet().iterator().next();
|
||||
codegen.genVarargs(next.getKey(), (VarargValueArgument) next.getValue());
|
||||
return StackValue.onStack(expectedType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,16 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
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.types.JetType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -36,13 +37,19 @@ import java.util.List;
|
||||
*/
|
||||
public class JavaClassFunction implements IntrinsicMethod {
|
||||
@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
|
||||
) {
|
||||
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();
|
||||
JetType returnType = resultingDescriptor.getReturnType();
|
||||
assert returnType != null;
|
||||
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);
|
||||
if (primitiveType != null) {
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
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 java.util.List;
|
||||
@@ -35,7 +35,15 @@ import java.util.List;
|
||||
*/
|
||||
public class JavaClassProperty implements IntrinsicMethod {
|
||||
@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);
|
||||
JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(receiver.type);
|
||||
if (primitiveType != null) {
|
||||
|
||||
@@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -34,8 +34,17 @@ import java.util.List;
|
||||
*/
|
||||
public class NewArray implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(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));
|
||||
public StackValue generate(
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,7 +32,15 @@ import java.util.List;
|
||||
*/
|
||||
public class Not implements IntrinsicMethod {
|
||||
@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;
|
||||
if (arguments.size() == 1) {
|
||||
stackValue = codegen.gen(arguments.get(0));
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,7 +32,15 @@ import java.util.List;
|
||||
*/
|
||||
public class NumberCast implements IntrinsicMethod {
|
||||
@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);
|
||||
return StackValue.onStack(expectedType);
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.lang.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,9 +39,12 @@ public class PsiMethodCall implements IntrinsicMethod {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element,
|
||||
List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
|
||||
final CallableMethod callableMethod = state.getInjector().getJetTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION);
|
||||
public StackValue generate(
|
||||
ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element,
|
||||
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);
|
||||
return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType());
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -38,28 +38,38 @@ public class RangeTo implements IntrinsicMethod {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
|
||||
if (arguments.size()==1) {
|
||||
public StackValue generate(
|
||||
ExpressionCodegen codegen,
|
||||
InstructionAdapter v,
|
||||
@NotNull Type expectedType,
|
||||
PsiElement element,
|
||||
List<JetExpression> arguments,
|
||||
StackValue receiver,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
if (arguments.size() == 1) {
|
||||
final Type leftType = receiver.type;
|
||||
final Type rightType = codegen.expressionType(arguments.get(0));
|
||||
receiver.put(Type.INT_TYPE, v);
|
||||
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);
|
||||
}
|
||||
else {
|
||||
JetBinaryExpression expression = (JetBinaryExpression) element;
|
||||
final Type leftType = codegen.expressionType(expression.getLeft());
|
||||
final Type rightType = codegen.expressionType(expression.getRight());
|
||||
// if (JetTypeMapper.isIntPrimitive(leftType)) {
|
||||
codegen.gen(expression.getLeft(), leftType);
|
||||
codegen.gen(expression.getRight(), rightType);
|
||||
v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor());
|
||||
return StackValue.onStack(expectedType);
|
||||
// }
|
||||
// else {
|
||||
// throw new UnsupportedOperationException("ranges are only supported for int objects");
|
||||
// }
|
||||
// if (JetTypeMapper.isIntPrimitive(leftType)) {
|
||||
codegen.gen(expression.getLeft(), leftType);
|
||||
codegen.gen(expression.getRight(), rightType);
|
||||
v.invokestatic("jet/runtime/Ranges", "rangeTo",
|
||||
"(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor());
|
||||
return StackValue.onStack(expectedType);
|
||||
// }
|
||||
// else {
|
||||
// throw new UnsupportedOperationException("ranges are only supported for int objects");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,11 +33,21 @@ import java.util.List;
|
||||
*/
|
||||
public class StringGetChar implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
|
||||
if (receiver != null)
|
||||
public StackValue generate(
|
||||
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);
|
||||
if (arguments != null)
|
||||
}
|
||||
if (arguments != null) {
|
||||
codegen.gen(arguments.get(0)).put(Type.INT_TYPE, v);
|
||||
}
|
||||
v.invokeinterface("java/lang/CharSequence", "charAt", "(I)C");
|
||||
return StackValue.onStack(Type.CHAR_TYPE);
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class StringLength implements IntrinsicMethod {
|
||||
@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);
|
||||
v.invokeinterface("java/lang/CharSequence", "length", "()I");
|
||||
return StackValue.onStack(Type.INT_TYPE);
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class StringPlus implements IntrinsicMethod {
|
||||
@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()) {
|
||||
codegen.gen(arguments.get(0)).put(JetTypeMapper.JL_STRING_TYPE, v);
|
||||
codegen.gen(arguments.get(1)).put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
|
||||
@@ -19,22 +19,30 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
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.List;
|
||||
|
||||
public class StupidSync implements IntrinsicMethod {
|
||||
@Override
|
||||
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));
|
||||
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));
|
||||
v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;");
|
||||
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v);
|
||||
return StackValue.onStack(expectedType);
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
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.resolve.BindingContext;
|
||||
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;
|
||||
|
||||
@@ -37,11 +37,20 @@ import java.util.List;
|
||||
*/
|
||||
public class Sure implements IntrinsicMethod {
|
||||
@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;
|
||||
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;
|
||||
if (resolvedCall.getReceiverArgument().getType().isNullable()) {
|
||||
if (resolvedCall.getReceiverArgument().getType().isNullable()) {
|
||||
receiver.put(receiver.type, v);
|
||||
v.dup();
|
||||
Label ok = new Label();
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class ToString implements IntrinsicMethod {
|
||||
@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);
|
||||
v.invokestatic("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
|
||||
return StackValue.onStack(JetTypeMapper.JL_STRING_TYPE);
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,15 @@ import java.util.List;
|
||||
*/
|
||||
public class UnaryMinus implements IntrinsicMethod {
|
||||
@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;
|
||||
if (nullable) {
|
||||
expectedType = JetTypeMapper.unboxType(expectedType);
|
||||
|
||||
@@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -34,13 +34,22 @@ import java.util.List;
|
||||
*/
|
||||
public class UnaryPlus implements IntrinsicMethod {
|
||||
@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;
|
||||
if (nullable) {
|
||||
expectedType = JetTypeMapper.unboxType(expectedType);
|
||||
}
|
||||
if (receiver != null && receiver != StackValue.none())
|
||||
if (receiver != null && receiver != StackValue.none()) {
|
||||
receiver.put(expectedType, v);
|
||||
}
|
||||
else {
|
||||
assert arguments != null;
|
||||
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.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.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.name.Name;
|
||||
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.JetSignatureVariance;
|
||||
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.List;
|
||||
@@ -48,9 +45,8 @@ public class BothSignatureWriter {
|
||||
|
||||
public enum Mode {
|
||||
METHOD(CheckSignatureAdapter.METHOD_SIGNATURE),
|
||||
CLASS(CheckSignatureAdapter.CLASS_SIGNATURE),
|
||||
;
|
||||
|
||||
CLASS(CheckSignatureAdapter.CLASS_SIGNATURE),;
|
||||
|
||||
private final int asmType;
|
||||
|
||||
Mode(int asmType) {
|
||||
@@ -70,18 +66,18 @@ public class BothSignatureWriter {
|
||||
SUPERS,
|
||||
CLASS_END,
|
||||
}
|
||||
|
||||
|
||||
private final SignatureWriter signatureWriter = new SignatureWriter();
|
||||
private final SignatureVisitor signatureVisitor;
|
||||
|
||||
private JetSignatureWriter jetSignatureWriter;
|
||||
|
||||
|
||||
private String kotlinClassParameters;
|
||||
private String kotlinClassSignature;
|
||||
|
||||
|
||||
private List<JvmMethodParameterSignature> kotlinParameterTypes = new ArrayList<JvmMethodParameterSignature>();
|
||||
private String kotlinReturnType;
|
||||
|
||||
|
||||
private int jvmCurrentTypeArrayLevel;
|
||||
private Type jvmCurrentType;
|
||||
private Type jvmReturnType;
|
||||
@@ -119,11 +115,10 @@ public class BothSignatureWriter {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private SignatureVisitor signatureVisitor() {
|
||||
return !visitors.isEmpty() ? visitors.peek() : signatureVisitor;
|
||||
}
|
||||
|
||||
|
||||
private void checkTopLevel() {
|
||||
if (DEBUG_SIGNATURE_WRITER) {
|
||||
if (!visitors.isEmpty()) {
|
||||
@@ -131,7 +126,7 @@ public class BothSignatureWriter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkMode(Mode mode) {
|
||||
if (DEBUG_SIGNATURE_WRITER) {
|
||||
if (mode != this.mode) {
|
||||
@@ -139,7 +134,7 @@ public class BothSignatureWriter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkState(State state) {
|
||||
if (DEBUG_SIGNATURE_WRITER) {
|
||||
if (state != this.state) {
|
||||
@@ -151,7 +146,7 @@ public class BothSignatureWriter {
|
||||
checkTopLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void transitionState(State from, State to) {
|
||||
checkState(from);
|
||||
state = to;
|
||||
@@ -207,7 +202,7 @@ public class BothSignatureWriter {
|
||||
writeAsmType0(Type.VOID_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String makeArrayPrefix() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < jvmCurrentTypeArrayLevel; ++i) {
|
||||
@@ -215,7 +210,7 @@ public class BothSignatureWriter {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private void writeAsmType0(Type type) {
|
||||
if (jvmCurrentType == null) {
|
||||
jvmCurrentType = Type.getType(makeArrayPrefix() + type.getDescriptor());
|
||||
@@ -240,17 +235,21 @@ public class BothSignatureWriter {
|
||||
++jvmCurrentTypeArrayLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeArrayEnd() {
|
||||
pop();
|
||||
}
|
||||
|
||||
|
||||
private static JetSignatureVariance toJetSignatureVariance(Variance variance) {
|
||||
switch (variance) {
|
||||
case INVARIANT: return JetSignatureVariance.INVARIANT;
|
||||
case IN_VARIANCE: return JetSignatureVariance.IN;
|
||||
case OUT_VARIANCE: return JetSignatureVariance.OUT;
|
||||
default: throw new IllegalStateException();
|
||||
case INVARIANT:
|
||||
return JetSignatureVariance.INVARIANT;
|
||||
case IN_VARIANCE:
|
||||
return JetSignatureVariance.IN;
|
||||
case OUT_VARIANCE:
|
||||
return JetSignatureVariance.OUT;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +259,7 @@ public class BothSignatureWriter {
|
||||
jetSignatureWriter.visitTypeArgument(jsVariance);
|
||||
generic = true;
|
||||
}
|
||||
|
||||
|
||||
public void writeTypeArgumentEnd() {
|
||||
pop();
|
||||
}
|
||||
@@ -280,7 +279,7 @@ public class BothSignatureWriter {
|
||||
|
||||
generic = true;
|
||||
}
|
||||
|
||||
|
||||
public void writeFormalTypeParameterEnd() {
|
||||
jetSignatureWriter.visitFormalTypeParameterEnd();
|
||||
}
|
||||
@@ -309,7 +308,7 @@ public class BothSignatureWriter {
|
||||
push(signatureVisitor().visitClassBound());
|
||||
jetSignatureWriter.visitClassBound();
|
||||
}
|
||||
|
||||
|
||||
public void writeClassBoundEnd() {
|
||||
pop();
|
||||
}
|
||||
@@ -322,7 +321,7 @@ public class BothSignatureWriter {
|
||||
public void writeInterfaceBoundEnd() {
|
||||
pop();
|
||||
}
|
||||
|
||||
|
||||
public void writeParametersStart() {
|
||||
transitionState(State.TYPE_PARAMETERS, State.PARAMETERS);
|
||||
|
||||
@@ -351,7 +350,7 @@ public class BothSignatureWriter {
|
||||
|
||||
//jetSignatureWriter.visitParameterType();
|
||||
}
|
||||
|
||||
|
||||
public void writeParameterTypeEnd() {
|
||||
pop();
|
||||
|
||||
@@ -386,10 +385,10 @@ public class BothSignatureWriter {
|
||||
push(signatureVisitor().visitReturnType());
|
||||
//jetSignatureWriter.visitReturnType();
|
||||
}
|
||||
|
||||
|
||||
public void writeReturnTypeEnd() {
|
||||
pop();
|
||||
|
||||
|
||||
kotlinReturnType = jetSignatureWriter.toString();
|
||||
|
||||
if (jvmCurrentType == null) {
|
||||
@@ -407,13 +406,13 @@ public class BothSignatureWriter {
|
||||
jetSignatureWriter = null;
|
||||
transitionState(State.RETURN_TYPE, State.METHOD_END);
|
||||
}
|
||||
|
||||
|
||||
public void writeVoidReturn() {
|
||||
writeReturnType();
|
||||
writeAsmType(Type.VOID_TYPE, false);
|
||||
writeReturnTypeEnd();
|
||||
}
|
||||
|
||||
|
||||
public void writeSupersStart() {
|
||||
transitionState(State.TYPE_PARAMETERS, State.SUPERS);
|
||||
jetSignatureWriter = new JetSignatureWriter();
|
||||
@@ -434,7 +433,7 @@ public class BothSignatureWriter {
|
||||
push(signatureVisitor().visitSuperclass());
|
||||
jetSignatureWriter.visitSuperclass();
|
||||
}
|
||||
|
||||
|
||||
public void writeSuperclassEnd() {
|
||||
pop();
|
||||
if (!visitors.isEmpty()) {
|
||||
@@ -458,7 +457,6 @@ public class BothSignatureWriter {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
public Method makeAsmMethod(String name) {
|
||||
List<Type> jvmParameterTypes = new ArrayList<Type>(kotlinParameterTypes.size());
|
||||
@@ -476,7 +474,7 @@ public class BothSignatureWriter {
|
||||
checkTopLevel();
|
||||
return generic ? signatureWriter.toString() : null;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public List<JvmMethodParameterSignature> makeKotlinParameterTypes() {
|
||||
checkState(State.METHOD_END);
|
||||
@@ -489,7 +487,7 @@ public class BothSignatureWriter {
|
||||
checkState(State.METHOD_END);
|
||||
return kotlinReturnType;
|
||||
}
|
||||
|
||||
|
||||
public String makeKotlinMethodTypeParameters() {
|
||||
checkState(State.METHOD_END);
|
||||
return kotlinClassParameters;
|
||||
@@ -522,5 +520,4 @@ public class BothSignatureWriter {
|
||||
return new JvmMethodSignature(makeAsmMethod(name), makeKotlinParameterTypes());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +30,10 @@ public class JvmClassSignature {
|
||||
private final String javaGenericSignature;
|
||||
private final String kotlinGenericSignature;
|
||||
|
||||
public JvmClassSignature(String name, String superclassName, List<String> interfaces,
|
||||
@Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature) {
|
||||
public JvmClassSignature(
|
||||
String name, String superclassName, List<String> interfaces,
|
||||
@Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature
|
||||
) {
|
||||
this.name = name;
|
||||
this.superclassName = superclassName;
|
||||
this.interfaces = interfaces;
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.jetbrains.jet.codegen.signature;
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
|
||||
+2
-1
@@ -31,7 +31,8 @@ public class JvmMethodParameterSignature {
|
||||
private final JvmMethodParameterKind kind;
|
||||
|
||||
public JvmMethodParameterSignature(
|
||||
@NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind) {
|
||||
@NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind
|
||||
) {
|
||||
this.asmType = asmType;
|
||||
this.kotlinSignature = kotlinSignature;
|
||||
this.kind = kind;
|
||||
|
||||
@@ -31,7 +31,9 @@ public class JvmMethodSignature {
|
||||
|
||||
@NotNull
|
||||
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 kotlinTypeParameter;
|
||||
@NotNull
|
||||
@@ -44,8 +46,13 @@ public class JvmMethodSignature {
|
||||
*/
|
||||
private final boolean genericsAvailable;
|
||||
|
||||
public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature,
|
||||
@Nullable String kotlinTypeParameters, @NotNull List<JvmMethodParameterSignature> kotlinParameterTypes, @NotNull String kotlinReturnType) {
|
||||
public JvmMethodSignature(
|
||||
@NotNull Method asmMethod,
|
||||
@Nullable String genericsSignature,
|
||||
@Nullable String kotlinTypeParameters,
|
||||
@NotNull List<JvmMethodParameterSignature> kotlinParameterTypes,
|
||||
@NotNull String kotlinReturnType
|
||||
) {
|
||||
this.asmMethod = asmMethod;
|
||||
this.genericsSignature = genericsSignature;
|
||||
this.kotlinTypeParameter = kotlinTypeParameters;
|
||||
@@ -53,7 +60,7 @@ public class JvmMethodSignature {
|
||||
this.kotlinReturnType = kotlinReturnType;
|
||||
this.genericsAvailable = true;
|
||||
}
|
||||
|
||||
|
||||
public JvmMethodSignature(@NotNull Method asmMethod, @NotNull List<JvmMethodParameterSignature> kotlinParameterTypes) {
|
||||
this.asmMethod = asmMethod;
|
||||
this.genericsSignature = null;
|
||||
@@ -62,11 +69,16 @@ public class JvmMethodSignature {
|
||||
this.kotlinReturnType = "";
|
||||
this.genericsAvailable = false;
|
||||
}
|
||||
|
||||
public static JvmMethodSignature simple(@NotNull String methodName, @NotNull Type returnType, @NotNull List<JvmMethodParameterSignature> parameterSignatures) {
|
||||
return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])), parameterSignatures);
|
||||
|
||||
public static JvmMethodSignature simple(
|
||||
@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
|
||||
private static List<Type> getTypes(@NotNull List<JvmMethodParameterSignature> signatures) {
|
||||
List<Type> r = new ArrayList<Type>(signatures.size());
|
||||
@@ -103,12 +115,12 @@ public class JvmMethodSignature {
|
||||
checkGenericsAvailable();
|
||||
return kotlinParameterTypes;
|
||||
}
|
||||
|
||||
|
||||
public int getParameterCount() {
|
||||
// TODO: slow
|
||||
return asmMethod.getArgumentTypes().length;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public String getKotlinParameterType(int i) {
|
||||
checkGenericsAvailable();
|
||||
@@ -125,7 +137,7 @@ public class JvmMethodSignature {
|
||||
checkGenericsAvailable();
|
||||
return kotlinReturnType;
|
||||
}
|
||||
|
||||
|
||||
public List<Type> getValueParameterTypes() {
|
||||
List<Type> r = new ArrayList<Type>(kotlinParameterTypes.size());
|
||||
for (JvmMethodParameterSignature p : kotlinParameterTypes) {
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.jet.codegen.signature;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
|
||||
+4
-4
@@ -17,10 +17,10 @@
|
||||
package org.jetbrains.jet.codegen.signature.kotlin;
|
||||
|
||||
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.MethodVisitor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.utils.BitSetUtils;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
@@ -58,13 +58,13 @@ public class JetMethodAnnotationWriter {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_PROPERTY_TYPE_FIELD, propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeNullableReturnType(boolean nullableReturnType) {
|
||||
if (nullableReturnType) {
|
||||
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, nullableReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visitEnd() {
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,9 +17,9 @@
|
||||
package org.jetbrains.jet.codegen.signature.kotlin;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.asm4.AnnotationVisitor;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.codeInsight.BaseExternalAnnotationsManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 14 August 2012
|
||||
*/
|
||||
public class CoreExternalAnnotationsManager extends BaseExternalAnnotationsManager {
|
||||
static {
|
||||
// This is an ugly workaround for JDOM 1.1 used from application started from Ant 1.8 without forking
|
||||
System.setProperty("javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
|
||||
}
|
||||
|
||||
private final List<VirtualFile> externalAnnotationsRoots = new ArrayList<VirtualFile>();
|
||||
|
||||
public CoreExternalAnnotationsManager(@NotNull PsiManager psiManager) {
|
||||
super(psiManager);
|
||||
}
|
||||
|
||||
public void addExternalAnnotationsRoot(VirtualFile externalAnnotationsRoot) {
|
||||
externalAnnotationsRoots.add(externalAnnotationsRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasAnyAnnotationsRoots() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile) {
|
||||
return externalAnnotationsRoots;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void annotateExternally(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQName, @NotNull PsiFile fromFile,
|
||||
PsiNameValuePair[] value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deannotate(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationPlace chooseAnnotationsPlace(@NotNull PsiElement element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.core.CoreJavaFileManager;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.core.JavaCoreProjectEnvironment;
|
||||
@@ -36,13 +37,10 @@ import org.jetbrains.jet.asJava.JavaElementFinder;
|
||||
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
||||
import org.jetbrains.jet.config.CommonConfigurationKeys;
|
||||
import org.jetbrains.jet.config.CompilerConfiguration;
|
||||
import org.jetbrains.jet.lang.parsing.JetParser;
|
||||
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
|
||||
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.extAnnotations.CoreAnnotationsProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
import org.jetbrains.jet.utils.PathUtil;
|
||||
@@ -60,7 +58,7 @@ public class JetCoreEnvironment {
|
||||
private final JavaCoreProjectEnvironment projectEnvironment;
|
||||
private final List<JetFile> sourceFiles = new ArrayList<JetFile>();
|
||||
|
||||
private final CoreAnnotationsProvider annotationsProvider;
|
||||
private final CoreExternalAnnotationsManager annotationsManager;
|
||||
|
||||
private final CompilerConfiguration configuration;
|
||||
|
||||
@@ -89,8 +87,8 @@ public class JetCoreEnvironment {
|
||||
.getExtensionPoint(PsiElementFinder.EP_NAME)
|
||||
.registerExtension(new JavaElementFinder(project));
|
||||
|
||||
annotationsProvider = new CoreAnnotationsProvider();
|
||||
project.registerService(ExternalAnnotationsProvider.class, annotationsProvider);
|
||||
annotationsManager = new CoreExternalAnnotationsManager(project.getComponent(PsiManager.class));
|
||||
project.registerService(ExternalAnnotationsManager.class, annotationsManager);
|
||||
|
||||
for (File path : configuration.getList(JVMConfigurationKeys.CLASSPATH_KEY)) {
|
||||
addToClasspath(path);
|
||||
@@ -123,7 +121,7 @@ public class JetCoreEnvironment {
|
||||
}
|
||||
|
||||
private void addExternalAnnotationsRoot(VirtualFile root) {
|
||||
annotationsProvider.addExternalAnnotationsRoot(root);
|
||||
annotationsManager.addExternalAnnotationsRoot(root);
|
||||
}
|
||||
|
||||
private void addSources(File file) {
|
||||
|
||||
+1
-7
@@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
|
||||
import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DelegationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
||||
@@ -80,7 +79,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
private OverloadingConflictResolver overloadingConflictResolver;
|
||||
private ImportsResolver importsResolver;
|
||||
private ScriptHeaderResolver scriptHeaderResolver;
|
||||
private DelegationResolver delegationResolver;
|
||||
private OverloadResolver overloadResolver;
|
||||
private OverrideResolver overrideResolver;
|
||||
private TypeHierarchyResolver typeHierarchyResolver;
|
||||
@@ -120,7 +118,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
||||
this.importsResolver = new ImportsResolver();
|
||||
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
||||
this.delegationResolver = new DelegationResolver();
|
||||
this.overloadResolver = new OverloadResolver();
|
||||
this.overrideResolver = new OverrideResolver();
|
||||
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
||||
@@ -132,7 +129,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
||||
this.topDownAnalyzer.setContext(topDownAnalysisContext);
|
||||
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||
this.topDownAnalyzer.setDelegationResolver(delegationResolver);
|
||||
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||
this.topDownAnalyzer.setNamespaceFactory(namespaceFactory);
|
||||
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||
@@ -144,6 +140,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||
|
||||
this.bodyResolver.setCallResolver(callResolver);
|
||||
this.bodyResolver.setContext(topDownAnalysisContext);
|
||||
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
|
||||
this.bodyResolver.setDeclarationsChecker(declarationsChecker);
|
||||
this.bodyResolver.setDescriptorResolver(descriptorResolver);
|
||||
@@ -213,9 +210,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
scriptHeaderResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||
scriptHeaderResolver.setTrace(bindingTrace);
|
||||
|
||||
delegationResolver.setContext(topDownAnalysisContext);
|
||||
delegationResolver.setTrace(bindingTrace);
|
||||
|
||||
overloadResolver.setContext(topDownAnalysisContext);
|
||||
overloadResolver.setTrace(bindingTrace);
|
||||
|
||||
|
||||
+3
-3
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
@@ -31,7 +32,6 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||
import org.jetbrains.jet.lang.resolve.constants.StringValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
@@ -1617,7 +1617,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
result.addAll(Arrays.asList(list.getAnnotations()));
|
||||
}
|
||||
|
||||
PsiAnnotation[] externalAnnotations = ExternalAnnotationsProvider.getInstance(owner.getProject()).findExternalAnnotations(owner);
|
||||
PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner);
|
||||
if (externalAnnotations != null) {
|
||||
result.addAll(Arrays.asList(externalAnnotations));
|
||||
}
|
||||
@@ -1635,6 +1635,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
|
||||
}
|
||||
}
|
||||
|
||||
return ExternalAnnotationsProvider.getInstance(owner.getProject()).findExternalAnnotation(owner, fqName);
|
||||
return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, fqName);
|
||||
}
|
||||
}
|
||||
|
||||
-203
@@ -1,203 +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.lang.resolve.java.extAnnotations;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This class is copied from IDEA.
|
||||
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 6/26/12
|
||||
*/
|
||||
@Deprecated
|
||||
public class ClassUtil {
|
||||
private ClassUtil() {}
|
||||
|
||||
public static void formatClassName(@NotNull final PsiClass aClass, final StringBuilder buf) {
|
||||
final String qName = aClass.getQualifiedName();
|
||||
if (qName != null) {
|
||||
buf.append(qName);
|
||||
}
|
||||
else {
|
||||
final PsiClass parentClass = getContainerClass(aClass);
|
||||
if (parentClass != null) {
|
||||
formatClassName(parentClass, buf);
|
||||
buf.append("$");
|
||||
buf.append(getNonQualifiedClassIdx(aClass));
|
||||
final String name = aClass.getName();
|
||||
if (name != null) {
|
||||
buf.append(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getContainerClass(final PsiClass aClass) {
|
||||
PsiElement parent = aClass.getContext();
|
||||
while (parent != null && !(parent instanceof PsiClass)) {
|
||||
parent = parent.getContext();
|
||||
}
|
||||
return (PsiClass)parent;
|
||||
}
|
||||
|
||||
public static int getNonQualifiedClassIdx(@NotNull final PsiClass psiClass) {
|
||||
final int[] result = {-1};
|
||||
final PsiClass containingClass = getContainerClass(psiClass);
|
||||
if (containingClass != null) {
|
||||
containingClass.accept(new JavaRecursiveElementVisitor() {
|
||||
private int myCurrentIdx = 0;
|
||||
|
||||
@Override public void visitElement(PsiElement element) {
|
||||
if (result[0] == -1) {
|
||||
super.visitElement(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitClass(PsiClass aClass) {
|
||||
super.visitClass(aClass);
|
||||
if (aClass.getQualifiedName() == null) {
|
||||
myCurrentIdx++;
|
||||
if (psiClass == aClass) {
|
||||
result[0] = myCurrentIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
public static PsiClass findNonQualifiedClassByIndex(final String indexName, @NotNull final PsiClass containingClass,
|
||||
final boolean jvmCompatible) {
|
||||
String prefix = getDigitPrefix(indexName);
|
||||
final int idx = prefix.length() > 0 ? Integer.parseInt(prefix) : -1;
|
||||
final String name = prefix.length() < indexName.length() ? indexName.substring(prefix.length()) : null;
|
||||
final PsiClass[] result = new PsiClass[1];
|
||||
containingClass.accept(new JavaRecursiveElementVisitor() {
|
||||
private int myCurrentIdx = 0;
|
||||
|
||||
@Override public void visitElement(PsiElement element) {
|
||||
if (result[0] == null) {
|
||||
super.visitElement(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitClass(PsiClass aClass) {
|
||||
if (!jvmCompatible) {
|
||||
super.visitClass(aClass);
|
||||
if (aClass.getQualifiedName() == null) {
|
||||
myCurrentIdx++;
|
||||
if (myCurrentIdx == idx && Comparing.strEqual(name, aClass.getName())) {
|
||||
result[0] = aClass;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (aClass == containingClass) {
|
||||
super.visitClass(aClass);
|
||||
return;
|
||||
}
|
||||
if (Comparing.strEqual(name, aClass.getName())) {
|
||||
myCurrentIdx++;
|
||||
if (myCurrentIdx == idx || idx == -1) {
|
||||
result[0] = aClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitTypeParameter(final PsiTypeParameter classParameter) {
|
||||
if (!jvmCompatible) {
|
||||
super.visitTypeParameter(classParameter);
|
||||
}
|
||||
else {
|
||||
visitElement(classParameter);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private static String getDigitPrefix(final String indexName) {
|
||||
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
for (int i = 0; i < indexName.length(); i++) {
|
||||
final char c = indexName.charAt(i);
|
||||
if (Character.isDigit(c)) {
|
||||
builder.append(c);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(builder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static PsiClass findPsiClass(final PsiManager psiManager,
|
||||
String externalName,
|
||||
PsiClass psiClass,
|
||||
boolean jvmCompatible) {
|
||||
return findPsiClass(psiManager, externalName, psiClass, jvmCompatible, GlobalSearchScope.allScope(psiManager.getProject()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass findPsiClass(final PsiManager psiManager,
|
||||
String externalName,
|
||||
@Nullable PsiClass psiClass,
|
||||
boolean jvmCompatible,
|
||||
final GlobalSearchScope scope) {
|
||||
final int topIdx = externalName.indexOf('$');
|
||||
if (topIdx > -1) {
|
||||
if (psiClass == null) {
|
||||
psiClass = JavaPsiFacade.getInstance(psiManager.getProject())
|
||||
.findClass(externalName.substring(0, topIdx), scope);
|
||||
}
|
||||
if (psiClass == null) return null;
|
||||
externalName = externalName.substring(topIdx + 1);
|
||||
return findSubclass(psiManager, externalName, psiClass, jvmCompatible);
|
||||
} else {
|
||||
return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(externalName, scope);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass findSubclass(final PsiManager psiManager,
|
||||
final String externalName,
|
||||
final PsiClass psiClass,
|
||||
final boolean jvmCompatible) {
|
||||
final int nextIdx = externalName.indexOf('$');
|
||||
if (nextIdx > -1) {
|
||||
final PsiClass anonymousClass = findNonQualifiedClassByIndex(externalName.substring(0, nextIdx), psiClass, jvmCompatible);
|
||||
if (anonymousClass == null) return null;
|
||||
return findPsiClass(psiManager, externalName.substring(nextIdx), anonymousClass, jvmCompatible);
|
||||
}
|
||||
else {
|
||||
return findNonQualifiedClassByIndex(externalName, psiClass, jvmCompatible);
|
||||
}
|
||||
}
|
||||
}
|
||||
-316
@@ -1,316 +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.lang.resolve.java.extAnnotations;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.containers.ConcurrentWeakHashMap;
|
||||
import com.intellij.util.containers.ConcurrentWeakValueHashMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* This class is copied from IDEA.
|
||||
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 6/26/12
|
||||
*/
|
||||
@Deprecated
|
||||
public class CoreAnnotationsProvider extends ExternalAnnotationsProvider {
|
||||
static {
|
||||
// This is an ugly workaround for JDOM 1.1 used from application started from Ant 1.8 without forking
|
||||
System.setProperty("javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + CoreAnnotationsProvider.class.getName());
|
||||
@NotNull private static final List<PsiFile> NULL = new ArrayList<PsiFile>();
|
||||
@NotNull private final ConcurrentMap<String, List<PsiFile>>
|
||||
myExternalAnnotations = new ConcurrentWeakValueHashMap<String, List<PsiFile>>();
|
||||
|
||||
private List<VirtualFile> externalAnnotationsRoots = new ArrayList<VirtualFile>();
|
||||
|
||||
public CoreAnnotationsProvider() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getExternalName(PsiModifierListOwner listOwner, boolean showParamName) {
|
||||
return PsiFormatUtil.getExternalName(listOwner, showParamName, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getFQN(String packageName, @Nullable VirtualFile virtualFile) {
|
||||
if (virtualFile == null) return null;
|
||||
return StringUtil.getQualifiedName(packageName, virtualFile.getNameWithoutExtension());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static String getNormalizedExternalName(@NotNull PsiModifierListOwner owner) {
|
||||
String externalName = getExternalName(owner, true);
|
||||
if (externalName != null) {
|
||||
if (owner instanceof PsiParameter && owner.getParent() instanceof PsiParameterList) {
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(owner, PsiMethod.class);
|
||||
if (method != null) {
|
||||
externalName =
|
||||
externalName.substring(0, externalName.lastIndexOf(' ') + 1) + method.getParameterList().getParameterIndex((PsiParameter)owner);
|
||||
}
|
||||
}
|
||||
final int idx = externalName.indexOf('(');
|
||||
if (idx == -1) return externalName;
|
||||
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
final int rightIdx = externalName.indexOf(')');
|
||||
final String[] params = externalName.substring(idx + 1, rightIdx).split(",");
|
||||
buf.append(externalName.substring(0, idx + 1));
|
||||
for (String param : params) {
|
||||
param = param.trim();
|
||||
final int spaceIdx = param.indexOf(' ');
|
||||
buf.append(spaceIdx > -1 ? param.substring(0, spaceIdx) : param).append(", ");
|
||||
}
|
||||
return StringUtil.trimEnd(buf.toString(), ", ") + externalName.substring(rightIdx);
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(buf);
|
||||
}
|
||||
}
|
||||
return externalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiAnnotation findExternalAnnotation(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) {
|
||||
return collectExternalAnnotations(listOwner).get(annotationFQN);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiAnnotation[] findExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) {
|
||||
final Map<String, PsiAnnotation> result = collectExternalAnnotations(listOwner);
|
||||
return result.isEmpty() ? null : result.values().toArray(new PsiAnnotation[result.size()]);
|
||||
}
|
||||
|
||||
private final Map<PsiModifierListOwner, Map<String, PsiAnnotation>> cache = new ConcurrentWeakHashMap<PsiModifierListOwner, Map<String, PsiAnnotation>>();
|
||||
@NotNull
|
||||
private Map<String, PsiAnnotation> collectExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) {
|
||||
Map<String, PsiAnnotation> map = cache.get(listOwner);
|
||||
if (map == null) {
|
||||
map = doCollect(listOwner);
|
||||
cache.put(listOwner, map);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public void addExternalAnnotationsRoot(VirtualFile externalAnnotationsRoot) {
|
||||
externalAnnotationsRoots.add(externalAnnotationsRoot);
|
||||
}
|
||||
|
||||
private Map<PsiFile, MultiMap<String, AnnotationData>> annotationsFileToData = new HashMap<PsiFile, MultiMap<String, AnnotationData>>();
|
||||
private Map<PsiFile, Long> annotationsFileToModificationStamp = new HashMap<PsiFile, Long>();
|
||||
@NotNull
|
||||
private MultiMap<String, AnnotationData> getDataFromFile(@NotNull PsiFile file) {
|
||||
if (annotationsFileToData.containsKey(file) && file.getModificationStamp() == annotationsFileToModificationStamp.get(file)) {
|
||||
return annotationsFileToData.get(file);
|
||||
}
|
||||
else {
|
||||
MultiMap<String, AnnotationData> data = new MultiMap<String, AnnotationData>();
|
||||
annotationsFileToData.put(file, data);
|
||||
annotationsFileToModificationStamp.put(file, file.getModificationStamp());
|
||||
|
||||
Document document;
|
||||
try {
|
||||
//noinspection ConstantConditions
|
||||
document = JDOMUtil.loadDocument(escapeAttributes(StreamUtil.readText(file.getVirtualFile().getInputStream())));
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
return data;
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
LOG.error(e);
|
||||
return data;
|
||||
}
|
||||
Element rootElement = document.getRootElement();
|
||||
if (rootElement == null) return data;
|
||||
|
||||
//noinspection unchecked
|
||||
for (Element element : (List<Element>) rootElement.getChildren()) {
|
||||
String ownerName = element.getAttributeValue("name");
|
||||
if (ownerName == null) continue;
|
||||
//noinspection unchecked
|
||||
for (Element annotationElement : (List<Element>) element.getChildren()) {
|
||||
String annotationFQN = annotationElement.getAttributeValue("name");
|
||||
StringBuilder buf = new StringBuilder();
|
||||
//noinspection unchecked
|
||||
for (Element annotationParameter : (List<Element>) annotationElement.getChildren()) {
|
||||
buf.append(",");
|
||||
String nameValue = annotationParameter.getAttributeValue("name");
|
||||
if (nameValue != null) {
|
||||
buf.append(nameValue).append("=");
|
||||
}
|
||||
buf.append(annotationParameter.getAttributeValue("val"));
|
||||
}
|
||||
String annotationText = "@" + annotationFQN + (buf.length() > 0 ? "(" + StringUtil.trimStart(buf.toString(), ",") + ")" : "");
|
||||
data.putValue(ownerName, new AnnotationData(annotationFQN, annotationText));
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, PsiAnnotation> doCollect(@NotNull PsiModifierListOwner listOwner) {
|
||||
final List<PsiFile> files = findExternalAnnotationsFiles(listOwner);
|
||||
if (files == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, PsiAnnotation> result = new HashMap<String, PsiAnnotation>();
|
||||
String externalName = getExternalName(listOwner, false);
|
||||
String oldExternalName = getNormalizedExternalName(listOwner);
|
||||
|
||||
for (PsiFile file : files) {
|
||||
if (!file.isValid()) continue;
|
||||
MultiMap<String, AnnotationData> fileData = getDataFromFile(file);
|
||||
for (AnnotationData annotationData : ContainerUtil.concat(fileData.get(externalName), fileData.get(oldExternalName))) {
|
||||
try {
|
||||
result.put(annotationData.annotationClassFqName,
|
||||
JavaPsiFacade.getInstance(listOwner.getProject()).getElementFactory().createAnnotationFromText(
|
||||
annotationData.annotationText, null));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<PsiFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) {
|
||||
final PsiFile containingFile = listOwner.getContainingFile();
|
||||
if (!(containingFile instanceof PsiJavaFile)) {
|
||||
return null;
|
||||
}
|
||||
final PsiJavaFile javaFile = (PsiJavaFile)containingFile;
|
||||
final String packageName = javaFile.getPackageName();
|
||||
final VirtualFile virtualFile = containingFile.getVirtualFile();
|
||||
String fqn = getFQN(packageName, virtualFile);
|
||||
if (fqn == null) return null;
|
||||
final List<PsiFile> files = myExternalAnnotations.get(fqn);
|
||||
if (files == NULL) return null;
|
||||
if (files != null) {
|
||||
for (Iterator<PsiFile> it = files.iterator(); it.hasNext();) {
|
||||
if (!it.next().isValid()) it.remove();
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
if (virtualFile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<PsiFile> possibleAnnotationsXmls = new ArrayList<PsiFile>();
|
||||
for (VirtualFile root : externalAnnotationsRoots) {
|
||||
final VirtualFile ext = root.findFileByRelativePath(packageName.replace(".", "/") + "/" + "annotations.xml");
|
||||
if (ext == null) continue;
|
||||
final PsiFile psiFile = listOwner.getManager().findFile(ext);
|
||||
possibleAnnotationsXmls.add(psiFile);
|
||||
}
|
||||
if (!possibleAnnotationsXmls.isEmpty()) {
|
||||
myExternalAnnotations.put(fqn, possibleAnnotationsXmls);
|
||||
return possibleAnnotationsXmls;
|
||||
}
|
||||
myExternalAnnotations.put(fqn, NULL);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// This method is used for legacy reasons.
|
||||
// Old external annotations sometimes are bad XML: they have "<" and ">" characters in attributes values. To prevent SAX parser from
|
||||
// failing, we escape attributes values.
|
||||
@NotNull
|
||||
private static String escapeAttributes(@NotNull String invalidXml) {
|
||||
// We assume that XML has single- and double-quote characters only for attribute values, therefore we don't any complex parsing,
|
||||
// just split by ['"] regexp instead
|
||||
|
||||
// For PERFORMANCE REASONS this is written by hand instead of using regular expressions
|
||||
// This implementation turned out to be too slow:
|
||||
// String[] split = invalidXml.split("[\"\']");
|
||||
// assert split.length % 2 == 1;
|
||||
// for (int i = 1; i < split.length; i += 2) {
|
||||
// split[i] = split[i].replace("<", "<").replace(">", ">");
|
||||
// }
|
||||
// return StringUtil.join(split, "\"");
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean inQuotes = false;
|
||||
for (int i = 0; i < invalidXml.length(); i++) {
|
||||
char c = invalidXml.charAt(i);
|
||||
switch (c) {
|
||||
case '\'':
|
||||
case '\"':
|
||||
inQuotes = !inQuotes;
|
||||
sb.append('\"');
|
||||
break;
|
||||
case '<':
|
||||
if (inQuotes) {
|
||||
sb.append("<");
|
||||
}
|
||||
else {
|
||||
sb.append(c);
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (inQuotes) {
|
||||
sb.append(">");
|
||||
}
|
||||
else {
|
||||
sb.append(c);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sb.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static class AnnotationData {
|
||||
public String annotationClassFqName;
|
||||
public String annotationText;
|
||||
|
||||
private AnnotationData(String annotationClassFqName, String annotationText) {
|
||||
this.annotationClassFqName = annotationClassFqName;
|
||||
this.annotationText = annotationText;
|
||||
}
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +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.lang.resolve.java.extAnnotations;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 6/26/12
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ExternalAnnotationsProvider {
|
||||
@Nullable
|
||||
public abstract PsiAnnotation findExternalAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN);
|
||||
|
||||
@Nullable
|
||||
public abstract PsiAnnotation[] findExternalAnnotations(@NotNull PsiModifierListOwner listOwner);
|
||||
|
||||
public static ExternalAnnotationsProvider getInstance(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, ExternalAnnotationsProvider.class);
|
||||
}
|
||||
}
|
||||
-235
@@ -1,235 +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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 28-Oct-2008
|
||||
*/
|
||||
package org.jetbrains.jet.lang.resolve.java.extAnnotations;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.Function;
|
||||
|
||||
/**
|
||||
* This class is copied from IDEA.
|
||||
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 6/26/12
|
||||
*/
|
||||
@Deprecated
|
||||
public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisitor {
|
||||
private final StringBuilder myBuf;
|
||||
|
||||
public PsiExpressionTrimRenderer(final StringBuilder buf) {
|
||||
myBuf = buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(final PsiExpression expression) {
|
||||
myBuf.append(expression.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInstanceOfExpression(final PsiInstanceOfExpression expression) {
|
||||
expression.getOperand().accept(this);
|
||||
myBuf.append(" ").append(PsiKeyword.INSTANCEOF).append(" ");
|
||||
final PsiTypeElement checkType = expression.getCheckType();
|
||||
if (checkType != null) {
|
||||
myBuf.append(checkType.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParenthesizedExpression(final PsiParenthesizedExpression expression) {
|
||||
myBuf.append("(");
|
||||
final PsiExpression expr = expression.getExpression();
|
||||
if (expr != null) {
|
||||
expr.accept(this);
|
||||
}
|
||||
myBuf.append(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeCastExpression(final PsiTypeCastExpression expression) {
|
||||
final PsiTypeElement castType = expression.getCastType();
|
||||
if (castType != null) {
|
||||
myBuf.append("(").append(castType.getText()).append(")");
|
||||
}
|
||||
final PsiExpression operand = expression.getOperand();
|
||||
if (operand != null) {
|
||||
operand.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArrayAccessExpression(final PsiArrayAccessExpression expression) {
|
||||
expression.getArrayExpression().accept(this);
|
||||
myBuf.append("[");
|
||||
final PsiExpression indexExpression = expression.getIndexExpression();
|
||||
if (indexExpression != null) {
|
||||
indexExpression.accept(this);
|
||||
}
|
||||
myBuf.append("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrefixExpression(final PsiPrefixExpression expression) {
|
||||
myBuf.append(expression.getOperationSign().getText());
|
||||
final PsiExpression operand = expression.getOperand();
|
||||
if (operand != null) {
|
||||
operand.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPostfixExpression(final PsiPostfixExpression expression) {
|
||||
expression.getOperand().accept(this);
|
||||
myBuf.append(expression.getOperationSign().getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPolyadicExpression(PsiPolyadicExpression expression) {
|
||||
PsiExpression[] operands = expression.getOperands();
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
PsiExpression operand = operands[i];
|
||||
if (i != 0) {
|
||||
PsiJavaToken token = expression.getTokenBeforeOperand(operand);
|
||||
myBuf.append(" ").append(token.getText()).append(" ");
|
||||
}
|
||||
operand.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConditionalExpression(final PsiConditionalExpression expression) {
|
||||
expression.getCondition().accept(this);
|
||||
|
||||
myBuf.append(" ? ");
|
||||
final PsiExpression thenExpression = expression.getThenExpression();
|
||||
if (thenExpression != null) {
|
||||
thenExpression.accept(this);
|
||||
}
|
||||
|
||||
myBuf.append(" : ");
|
||||
final PsiExpression elseExpression = expression.getElseExpression();
|
||||
if (elseExpression != null) {
|
||||
elseExpression.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(final PsiAssignmentExpression expression) {
|
||||
expression.getLExpression().accept(this);
|
||||
myBuf.append(expression.getOperationSign().getText());
|
||||
final PsiExpression rExpression = expression.getRExpression();
|
||||
if (rExpression != null) {
|
||||
rExpression.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(final PsiReferenceExpression expr) {
|
||||
final PsiExpression qualifierExpression = expr.getQualifierExpression();
|
||||
if (qualifierExpression != null) {
|
||||
qualifierExpression.accept(this);
|
||||
myBuf.append(".");
|
||||
}
|
||||
myBuf.append(expr.getReferenceName());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(final PsiMethodCallExpression expr) {
|
||||
expr.getMethodExpression().accept(this);
|
||||
expr.getArgumentList().accept(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(final PsiArrayInitializerExpression expression) {
|
||||
myBuf.append("{");
|
||||
boolean first = true;
|
||||
for (PsiExpression expr : expression.getInitializers()) {
|
||||
if (!first) {
|
||||
myBuf.append(", ");
|
||||
}
|
||||
first = false;
|
||||
expr.accept(this);
|
||||
}
|
||||
myBuf.append("}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpressionList(final PsiExpressionList list) {
|
||||
final PsiExpression[] args = list.getExpressions();
|
||||
if (args.length > 0) {
|
||||
myBuf.append("(...)");
|
||||
}
|
||||
else {
|
||||
myBuf.append("()");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(final PsiNewExpression expr) {
|
||||
final PsiAnonymousClass anonymousClass = expr.getAnonymousClass();
|
||||
|
||||
final PsiExpressionList argumentList = expr.getArgumentList();
|
||||
|
||||
if (anonymousClass != null) {
|
||||
myBuf.append(PsiKeyword.NEW).append(" ").append(anonymousClass.getBaseClassType().getPresentableText());
|
||||
if (argumentList != null) argumentList.accept(this);
|
||||
myBuf.append(" {...}");
|
||||
}
|
||||
else {
|
||||
final PsiJavaCodeReferenceElement reference = expr.getClassReference();
|
||||
if (reference != null) {
|
||||
myBuf.append(PsiKeyword.NEW).append(" ").append(reference.getText());
|
||||
|
||||
final PsiExpression[] arrayDimensions = expr.getArrayDimensions();
|
||||
final PsiType type = expr.getType();
|
||||
final int dimensions = type != null ? type.getArrayDimensions() : arrayDimensions.length;
|
||||
if (arrayDimensions.length > 0) myBuf.append("[");
|
||||
for (int i = 0, arrayDimensionsLength = arrayDimensions.length; i < dimensions; i++) {
|
||||
final PsiExpression dimension = i < arrayDimensionsLength ? arrayDimensions[i] : null;
|
||||
if (i > 0) myBuf.append("][");
|
||||
if (dimension != null) {
|
||||
dimension.accept(this);
|
||||
}
|
||||
}
|
||||
if (arrayDimensions.length > 0) myBuf.append("]");
|
||||
|
||||
if (argumentList != null) {
|
||||
argumentList.accept(this);
|
||||
}
|
||||
|
||||
final PsiArrayInitializerExpression arrayInitializer = expr.getArrayInitializer();
|
||||
if (arrayInitializer != null) {
|
||||
arrayInitializer.accept(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myBuf.append(expr.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String render(PsiExpression expression) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
expression.accept(new PsiExpressionTrimRenderer(buf));
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
-360
@@ -1,360 +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.lang.resolve.java.extAnnotations;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This class is copied from IDEA.
|
||||
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 6/26/12
|
||||
*/
|
||||
@Deprecated
|
||||
public class PsiFormatUtil extends PsiFormatUtilBase {
|
||||
@MagicConstant(flags = {SHOW_MODIFIERS, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_MODIFIERS, SHOW_INITIALIZER, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES})
|
||||
public @interface FormatVariableOptions {}
|
||||
|
||||
public static String formatVariable(PsiVariable variable, @FormatVariableOptions int options, PsiSubstitutor substitutor){
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
formatVariable(variable, options, substitutor,buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
private static void formatVariable(PsiVariable variable,
|
||||
@FormatVariableOptions int options,
|
||||
PsiSubstitutor substitutor,
|
||||
@NotNull StringBuilder buffer){
|
||||
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) == 0){
|
||||
formatModifiers(variable, options,buffer);
|
||||
}
|
||||
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) == 0){
|
||||
appendSpaceIfNeeded(buffer);
|
||||
buffer.append(formatType(variable.getType(), options, substitutor));
|
||||
}
|
||||
if (variable instanceof PsiField && (options & SHOW_CONTAINING_CLASS) != 0){
|
||||
PsiClass aClass = ((PsiField)variable).getContainingClass();
|
||||
if (aClass != null){
|
||||
String className = aClass.getName();
|
||||
if (className != null) {
|
||||
appendSpaceIfNeeded(buffer);
|
||||
if ((options & SHOW_FQ_NAME) != 0){
|
||||
String qName = aClass.getQualifiedName();
|
||||
if (qName != null){
|
||||
buffer.append(qName);
|
||||
}
|
||||
else{
|
||||
buffer.append(className);
|
||||
}
|
||||
}
|
||||
else{
|
||||
buffer.append(className);
|
||||
}
|
||||
buffer.append('.');
|
||||
}
|
||||
}
|
||||
if ((options & SHOW_NAME) != 0){
|
||||
buffer.append(variable.getName());
|
||||
}
|
||||
}
|
||||
else{
|
||||
if ((options & SHOW_NAME) != 0){
|
||||
String name = variable.getName();
|
||||
if (StringUtil.isNotEmpty(name)){
|
||||
appendSpaceIfNeeded(buffer);
|
||||
buffer.append(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) != 0){
|
||||
if ((options & SHOW_NAME) != 0 && variable.getName() != null){
|
||||
buffer.append(':');
|
||||
}
|
||||
buffer.append(formatType(variable.getType(), options, substitutor));
|
||||
}
|
||||
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) != 0){
|
||||
formatModifiers(variable, options,buffer);
|
||||
}
|
||||
if ((options & SHOW_INITIALIZER) != 0){
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null){
|
||||
buffer.append(" = ");
|
||||
String text = PsiExpressionTrimRenderer.render(initializer);
|
||||
int index1 = text.lastIndexOf('\n');
|
||||
if (index1 < 0) index1 = text.length();
|
||||
int index2 = text.lastIndexOf('\r');
|
||||
if (index2 < 0) index2 = text.length();
|
||||
int index = Math.min(index1, index2);
|
||||
buffer.append(text.substring(0, index));
|
||||
if (index < text.length()) {
|
||||
buffer.append(" ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MagicConstant(flags = {SHOW_MODIFIERS, MODIFIERS_AFTER, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_PARAMETERS, SHOW_THROWS, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES})
|
||||
public @interface FormatMethodOptions {}
|
||||
|
||||
private static void formatMethod(PsiMethod method, PsiSubstitutor substitutor, @FormatMethodOptions int options, @FormatVariableOptions int parameterOptions, int maxParametersToShow, StringBuilder buffer){
|
||||
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) == 0){
|
||||
formatModifiers(method, options,buffer);
|
||||
}
|
||||
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) == 0){
|
||||
PsiType type = method.getReturnType();
|
||||
if (type != null){
|
||||
appendSpaceIfNeeded(buffer);
|
||||
buffer.append(formatType(type, options, substitutor));
|
||||
}
|
||||
}
|
||||
if ((options & SHOW_CONTAINING_CLASS) != 0){
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if (aClass != null){
|
||||
appendSpaceIfNeeded(buffer);
|
||||
String name = aClass.getName();
|
||||
if (name != null) {
|
||||
if ((options & SHOW_FQ_NAME) != 0){
|
||||
String qName = aClass.getQualifiedName();
|
||||
if (qName != null){
|
||||
buffer.append(qName);
|
||||
}
|
||||
else{
|
||||
buffer.append(name);
|
||||
}
|
||||
}
|
||||
else{
|
||||
buffer.append(name);
|
||||
}
|
||||
buffer.append('.');
|
||||
}
|
||||
}
|
||||
if ((options & SHOW_NAME) != 0){
|
||||
buffer.append(method.getName());
|
||||
}
|
||||
}
|
||||
else{
|
||||
if ((options & SHOW_NAME) != 0){
|
||||
appendSpaceIfNeeded(buffer);
|
||||
buffer.append(method.getName());
|
||||
}
|
||||
}
|
||||
if ((options & SHOW_PARAMETERS) != 0){
|
||||
buffer.append('(');
|
||||
PsiParameter[] parms = method.getParameterList().getParameters();
|
||||
for(int i = 0; i < Math.min(parms.length, maxParametersToShow); i++) {
|
||||
PsiParameter parm = parms[i];
|
||||
if (i > 0){
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(formatVariable(parm, parameterOptions, substitutor));
|
||||
}
|
||||
if(parms.length > maxParametersToShow) {
|
||||
buffer.append (", ...");
|
||||
}
|
||||
buffer.append(')');
|
||||
}
|
||||
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) != 0){
|
||||
PsiType type = method.getReturnType();
|
||||
if (type != null){
|
||||
if (buffer.length() > 0){
|
||||
buffer.append(':');
|
||||
}
|
||||
buffer.append(formatType(type, options, substitutor));
|
||||
}
|
||||
}
|
||||
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) != 0){
|
||||
formatModifiers(method, options,buffer);
|
||||
}
|
||||
if ((options & SHOW_THROWS) != 0){
|
||||
String throwsText = formatReferenceList(method.getThrowsList(), options);
|
||||
if (!throwsText.isEmpty()){
|
||||
appendSpaceIfNeeded(buffer);
|
||||
//noinspection HardCodedStringLiteral
|
||||
buffer.append("throws ");
|
||||
buffer.append(throwsText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void formatModifiers(PsiElement element, int options, StringBuilder buffer) throws IllegalArgumentException{
|
||||
PsiModifierList list;
|
||||
boolean isInterface = false;
|
||||
if (element instanceof PsiVariable){
|
||||
list = ((PsiVariable)element).getModifierList();
|
||||
}
|
||||
else if (element instanceof PsiMethod){
|
||||
list = ((PsiMethod)element).getModifierList();
|
||||
}
|
||||
else if (element instanceof PsiClass){
|
||||
isInterface = ((PsiClass)element).isInterface();
|
||||
list = ((PsiClass)element).getModifierList();
|
||||
if (list == null) return;
|
||||
}
|
||||
else if (element instanceof PsiClassInitializer){
|
||||
list = ((PsiClassInitializer)element).getModifierList();
|
||||
if (list == null) return;
|
||||
}
|
||||
else{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (list == null) return;
|
||||
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||
? list.hasExplicitModifier(PsiModifier.PUBLIC)
|
||||
: list.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
appendModifier(buffer, PsiModifier.PUBLIC);
|
||||
}
|
||||
|
||||
if (list.hasModifierProperty(PsiModifier.PROTECTED)){
|
||||
appendModifier(buffer, PsiModifier.PROTECTED);
|
||||
}
|
||||
if (list.hasModifierProperty(PsiModifier.PRIVATE)){
|
||||
appendModifier(buffer, PsiModifier.PRIVATE);
|
||||
}
|
||||
|
||||
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||
? list.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)
|
||||
: list.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
|
||||
if (element instanceof PsiClass && element.getParent() instanceof PsiDeclarationStatement) {// local class
|
||||
appendModifier(buffer, "local");
|
||||
}
|
||||
else {
|
||||
appendModifier(buffer, PsiBundle.visibilityPresentation(PsiModifier.PACKAGE_LOCAL));
|
||||
}
|
||||
}
|
||||
|
||||
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||
? list.hasExplicitModifier(PsiModifier.STATIC)
|
||||
: list.hasModifierProperty(PsiModifier.STATIC)) appendModifier(buffer, PsiModifier.STATIC);
|
||||
|
||||
if (!isInterface && //cls modifier list
|
||||
((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||
? list.hasExplicitModifier(PsiModifier.ABSTRACT)
|
||||
: list.hasModifierProperty(PsiModifier.ABSTRACT))) appendModifier(buffer, PsiModifier.ABSTRACT);
|
||||
|
||||
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||
? list.hasExplicitModifier(PsiModifier.FINAL)
|
||||
: list.hasModifierProperty(PsiModifier.FINAL)) appendModifier(buffer, PsiModifier.FINAL);
|
||||
|
||||
if (list.hasModifierProperty(PsiModifier.NATIVE) && (options & JAVADOC_MODIFIERS_ONLY) == 0){
|
||||
appendModifier(buffer, PsiModifier.NATIVE);
|
||||
}
|
||||
if (list.hasModifierProperty(PsiModifier.SYNCHRONIZED) && (options & JAVADOC_MODIFIERS_ONLY) == 0){
|
||||
appendModifier(buffer, PsiModifier.SYNCHRONIZED);
|
||||
}
|
||||
if (list.hasModifierProperty(PsiModifier.STRICTFP) && (options & JAVADOC_MODIFIERS_ONLY) == 0){
|
||||
appendModifier(buffer, PsiModifier.STRICTFP);
|
||||
}
|
||||
if (list.hasModifierProperty(PsiModifier.TRANSIENT) &&
|
||||
element instanceof PsiVariable // javac 5 puts transient attr for methods
|
||||
){
|
||||
appendModifier(buffer, PsiModifier.TRANSIENT);
|
||||
}
|
||||
if (list.hasModifierProperty(PsiModifier.VOLATILE)){
|
||||
appendModifier(buffer, PsiModifier.VOLATILE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendModifier(final StringBuilder buffer, final String modifier) {
|
||||
appendSpaceIfNeeded(buffer);
|
||||
buffer.append(modifier);
|
||||
}
|
||||
|
||||
public static String formatReferenceList(PsiReferenceList list, int options){
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
PsiJavaCodeReferenceElement[] refs = list.getReferenceElements();
|
||||
for(int i = 0; i < refs.length; i++) {
|
||||
PsiJavaCodeReferenceElement ref = refs[i];
|
||||
if (i > 0){
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(formatReference(ref, options));
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String formatType(PsiType type, int options, @NotNull PsiSubstitutor substitutor){
|
||||
type = substitutor.substitute(type);
|
||||
if ((options & SHOW_RAW_TYPE) != 0) {
|
||||
type = TypeConversionUtil.erasure(type);
|
||||
} else if ((options & SHOW_RAW_NON_TOP_TYPE) != 0) {
|
||||
if (!(PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter)) {
|
||||
final boolean preserveEllipsis = type instanceof PsiEllipsisType;
|
||||
type = TypeConversionUtil.erasure(type);
|
||||
if (preserveEllipsis && type instanceof PsiArrayType) {
|
||||
type = new PsiEllipsisType(((PsiArrayType)type).getComponentType());
|
||||
}
|
||||
}
|
||||
}
|
||||
return (options & SHOW_FQ_CLASS_NAMES) == 0 ? type.getPresentableText() : type.getInternalCanonicalText();
|
||||
}
|
||||
|
||||
public static String formatReference(PsiJavaCodeReferenceElement ref, int options){
|
||||
return (options & SHOW_FQ_CLASS_NAMES) == 0 ? ref.getText() : ref.getCanonicalText();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getExternalName(PsiModifierListOwner owner, final boolean showParamName, int maxParamsToShow) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
if (owner instanceof PsiClass) {
|
||||
ClassUtil.formatClassName((PsiClass)owner, builder);
|
||||
return builder.toString();
|
||||
}
|
||||
final PsiClass psiClass = PsiTreeUtil.getParentOfType(owner, PsiClass.class, false);
|
||||
if (psiClass == null) return null;
|
||||
ClassUtil.formatClassName(psiClass, builder);
|
||||
if (owner instanceof PsiMethod) {
|
||||
builder.append(" ");
|
||||
formatMethod((PsiMethod)owner, PsiSubstitutor.EMPTY,
|
||||
SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES,
|
||||
showParamName ? SHOW_NAME | SHOW_TYPE | SHOW_FQ_CLASS_NAMES : SHOW_TYPE | SHOW_FQ_CLASS_NAMES, maxParamsToShow, builder);
|
||||
}
|
||||
else if (owner instanceof PsiField) {
|
||||
builder.append(" ").append(((PsiField)owner).getName());
|
||||
}
|
||||
else if (owner instanceof PsiParameter) {
|
||||
final PsiElement declarationScope = ((PsiParameter)owner).getDeclarationScope();
|
||||
if (!(declarationScope instanceof PsiMethod)) {
|
||||
return null;
|
||||
}
|
||||
final PsiMethod psiMethod = (PsiMethod)declarationScope;
|
||||
|
||||
builder.append(" ");
|
||||
formatMethod(psiMethod, PsiSubstitutor.EMPTY,
|
||||
SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES,
|
||||
showParamName ? SHOW_NAME | SHOW_TYPE | SHOW_FQ_CLASS_NAMES : SHOW_TYPE | SHOW_FQ_CLASS_NAMES, maxParamsToShow, builder);
|
||||
builder.append(" ");
|
||||
|
||||
if (showParamName) {
|
||||
formatVariable((PsiVariable)owner, SHOW_NAME, PsiSubstitutor.EMPTY, builder);
|
||||
}
|
||||
else {
|
||||
builder.append(psiMethod.getParameterList().getParameterIndex((PsiParameter)owner));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +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.lang.resolve.java.extAnnotations;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
|
||||
/**
|
||||
* This class is copied from IDEA.
|
||||
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 6/26/12
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class PsiFormatUtilBase {
|
||||
|
||||
public static final int SHOW_NAME = 0x0001; // variable, method, class
|
||||
public static final int SHOW_TYPE = 0x0002; // variable, method
|
||||
public static final int TYPE_AFTER = 0x0004; // variable, method
|
||||
public static final int SHOW_MODIFIERS = 0x0008; // variable, method, class
|
||||
public static final int MODIFIERS_AFTER = 0x0010; // variable, method, class
|
||||
public static final int SHOW_REDUNDANT_MODIFIERS = 0x0020; // variable, method, class, modifier list
|
||||
public static final int SHOW_PACKAGE_LOCAL = 0x0040; // variable, method, class, modifier list
|
||||
public static final int SHOW_INITIALIZER = 0x0080; // variable
|
||||
public static final int SHOW_PARAMETERS = 0x0100; // method
|
||||
public static final int SHOW_THROWS = 0x0200; // method
|
||||
public static final int SHOW_EXTENDS_IMPLEMENTS = 0x0400; // class
|
||||
public static final int SHOW_FQ_NAME = 0x0800; // class, field, method
|
||||
public static final int SHOW_CONTAINING_CLASS = 0x1000; // field, method
|
||||
public static final int SHOW_FQ_CLASS_NAMES = 0x2000; // variable, method, class
|
||||
public static final int JAVADOC_MODIFIERS_ONLY = 0x4000; // field, method, class
|
||||
public static final int SHOW_ANONYMOUS_CLASS_VERBOSE = 0x8000; // class
|
||||
public static final int SHOW_RAW_TYPE = 0x10000; //type
|
||||
public static final int SHOW_RAW_NON_TOP_TYPE = 0x20000;
|
||||
public static final int MAX_PARAMS_TO_SHOW = 7;
|
||||
|
||||
protected static void appendSpaceIfNeeded(StringBuilder buffer) {
|
||||
if (buffer.length() != 0 && !StringUtil.endsWithChar(buffer, ' ')) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,10 +49,11 @@ public class AnalyzerFacadeForEverything {
|
||||
|
||||
InjectorForBodyResolve injector = new InjectorForBodyResolve(
|
||||
project, topDownAnalysisParameters,
|
||||
new ObservableBindingTrace(traceContext));
|
||||
new ObservableBindingTrace(traceContext),
|
||||
bodiesResolveContext);
|
||||
|
||||
try {
|
||||
injector.getBodyResolver().resolveBodies(bodiesResolveContext);
|
||||
injector.getBodyResolver().resolveBodies();
|
||||
return AnalyzeExhaust.success(traceContext.getBindingContext());
|
||||
} finally {
|
||||
injector.destroy();
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.resolve.BodyResolver;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
@@ -42,6 +43,7 @@ public class InjectorForBodyResolve {
|
||||
private final Project project;
|
||||
private final TopDownAnalysisParameters topDownAnalysisParameters;
|
||||
private final BindingTrace bindingTrace;
|
||||
private final BodiesResolveContext bodiesResolveContext;
|
||||
private CallResolver callResolver;
|
||||
private DescriptorResolver descriptorResolver;
|
||||
private AnnotationResolver annotationResolver;
|
||||
@@ -57,12 +59,14 @@ public class InjectorForBodyResolve {
|
||||
public InjectorForBodyResolve(
|
||||
@NotNull Project project,
|
||||
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
|
||||
@NotNull BindingTrace bindingTrace
|
||||
@NotNull BindingTrace bindingTrace,
|
||||
@NotNull BodiesResolveContext bodiesResolveContext
|
||||
) {
|
||||
this.bodyResolver = new BodyResolver();
|
||||
this.project = project;
|
||||
this.topDownAnalysisParameters = topDownAnalysisParameters;
|
||||
this.bindingTrace = bindingTrace;
|
||||
this.bodiesResolveContext = bodiesResolveContext;
|
||||
this.callResolver = new CallResolver();
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
this.annotationResolver = new AnnotationResolver();
|
||||
@@ -76,6 +80,7 @@ public class InjectorForBodyResolve {
|
||||
this.topDownAnalysisContext = new TopDownAnalysisContext();
|
||||
|
||||
this.bodyResolver.setCallResolver(callResolver);
|
||||
this.bodyResolver.setContext(bodiesResolveContext);
|
||||
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
|
||||
this.bodyResolver.setDeclarationsChecker(declarationsChecker);
|
||||
this.bodyResolver.setDescriptorResolver(descriptorResolver);
|
||||
@@ -138,4 +143,8 @@ public class InjectorForBodyResolve {
|
||||
return this.bindingTrace;
|
||||
}
|
||||
|
||||
public BodiesResolveContext getBodiesResolveContext() {
|
||||
return this.bodiesResolveContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
|
||||
import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
||||
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DelegationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
||||
@@ -72,7 +71,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
private OverloadingConflictResolver overloadingConflictResolver;
|
||||
private ImportsResolver importsResolver;
|
||||
private ScriptHeaderResolver scriptHeaderResolver;
|
||||
private DelegationResolver delegationResolver;
|
||||
private OverloadResolver overloadResolver;
|
||||
private OverrideResolver overrideResolver;
|
||||
private TypeHierarchyResolver typeHierarchyResolver;
|
||||
@@ -107,7 +105,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
this.overloadingConflictResolver = new OverloadingConflictResolver();
|
||||
this.importsResolver = new ImportsResolver();
|
||||
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
||||
this.delegationResolver = new DelegationResolver();
|
||||
this.overloadResolver = new OverloadResolver();
|
||||
this.overrideResolver = new OverrideResolver();
|
||||
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
||||
@@ -116,7 +113,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
||||
this.topDownAnalyzer.setContext(topDownAnalysisContext);
|
||||
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||
this.topDownAnalyzer.setDelegationResolver(delegationResolver);
|
||||
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||
this.topDownAnalyzer.setNamespaceFactory(namespaceFactory);
|
||||
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||
@@ -128,6 +124,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||
|
||||
this.bodyResolver.setCallResolver(callResolver);
|
||||
this.bodyResolver.setContext(topDownAnalysisContext);
|
||||
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
|
||||
this.bodyResolver.setDeclarationsChecker(declarationsChecker);
|
||||
this.bodyResolver.setDescriptorResolver(descriptorResolver);
|
||||
@@ -184,9 +181,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
scriptHeaderResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||
scriptHeaderResolver.setTrace(bindingTrace);
|
||||
|
||||
delegationResolver.setContext(topDownAnalysisContext);
|
||||
delegationResolver.setTrace(bindingTrace);
|
||||
|
||||
overloadResolver.setContext(topDownAnalysisContext);
|
||||
overloadResolver.setTrace(bindingTrace);
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.jet.lang.diagnostics;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
@@ -34,7 +33,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.PositioningStrategies.*;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
|
||||
@@ -121,7 +119,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<JetModifierListOwner, SimpleFunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = DiagnosticFactory1.create(ERROR, ABSTRACT_MODIFIER);
|
||||
|
||||
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT);
|
||||
SimpleDiagnosticFactory<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = SimpleDiagnosticFactory.create(ERROR, positionModifier(JetTokens.OPEN_KEYWORD));
|
||||
SimpleDiagnosticFactory<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = SimpleDiagnosticFactory.create(WARNING, positionModifier(JetTokens.OPEN_KEYWORD));
|
||||
|
||||
SimpleDiagnosticFactory<JetNamedDeclaration> PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = SimpleDiagnosticFactory.create(ERROR, NAMED_ELEMENT);
|
||||
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(NON_MEMBER_ABSTRACT_FUNCTION, "Function ''{0}'' is not a class or trait member and cannot be abstract", NAME);
|
||||
|
||||
MAP.put(NON_MEMBER_FUNCTION_NO_BODY, "Function ''{0}'' must have a body", NAME);
|
||||
MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "Non-final member in a final class");
|
||||
MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "\"open\" has no effect in a final class");
|
||||
|
||||
MAP.put(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, "Public or protected member should have specified type");
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user