From c27885b74f1e6d20e872583012b9fc4d1f33bb8a Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 20 Dec 2011 10:28:47 +0300 Subject: [PATCH 01/11] Stable classnames for object declarations whose type is exposed to java clients. --- .../jetbrains/jet/codegen/JetTypeMapper.java | 61 ++++++++++++++++++- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index ef2cef70364..7bcb0463f3c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.codegen; +import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import jet.JetObject; import jet.typeinfo.TypeInfo; @@ -180,7 +181,39 @@ public class JetTypeMapper { } private HashMap> naming = new HashMap>(); - + + private String getStableNameForObject(JetObjectDeclaration object, DeclarationDescriptor descriptor) { + String local = getLocalNameForObject(object); + if (local == null) return null; + + DeclarationDescriptor containingClass = getContainingClass(descriptor); + if (containingClass != null) { + return getFQName(containingClass) + "$" + local; + } + else { + return getFQName(getContainingNamespace(descriptor)) + "/" + local; + } + } + + private static String getLocalNameForObject(JetObjectDeclaration object) { + PsiElement parent = object.getParent(); + if (parent instanceof JetObjectLiteralExpression) { + PsiElement expressionParent = parent.getParent(); + + if (expressionParent instanceof JetProperty) { + JetProperty property = (JetProperty) expressionParent; + if (property.getInitializer() == parent) { + return property.getName(); + } + } + } + else if (parent instanceof JetClassObject) { + return "$ClassObject"; + } + + return null; + } + public String getFQName(DeclarationDescriptor descriptor) { descriptor = descriptor.getOriginal(); @@ -200,7 +233,17 @@ public class JetTypeMapper { name = map.get(descriptor); if(name == null) { - name = getFQName(container) + "$" + (map.size()+1); + PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); + if (declaration instanceof JetObjectDeclaration) { + String stable = getStableNameForObject((JetObjectDeclaration) declaration, descriptor); + if (stable != null) { + name = stable; + } + } + + if (name == null) { + name = getFQName(container) + "$" + (map.size()+1); + } map.put(descriptor, name); } return name; @@ -222,7 +265,19 @@ public class JetTypeMapper { return name; } - + + private static ClassDescriptor getContainingClass(DeclarationDescriptor descriptor) { + DeclarationDescriptor parent = descriptor.getContainingDeclaration(); + if (parent == null || parent instanceof ClassDescriptor) return (ClassDescriptor) parent; + return getContainingClass(parent); + } + + private static NamespaceDescriptor getContainingNamespace(DeclarationDescriptor descriptor) { + DeclarationDescriptor parent = descriptor.getContainingDeclaration(); + if (parent == null || parent instanceof NamespaceDescriptor) return (NamespaceDescriptor) parent; + return getContainingNamespace(parent); + } + @NotNull public Type mapType(final JetType jetType) { return mapType(jetType, (BothSignatureWriter) null); } From 914b5487b4a81e46bc1dc01c909900b38e965900 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 22:39:14 +0400 Subject: [PATCH 02/11] one more ext function test --- compiler/testData/readClass/fun/ExtFunInClass.kt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 compiler/testData/readClass/fun/ExtFunInClass.kt diff --git a/compiler/testData/readClass/fun/ExtFunInClass.kt b/compiler/testData/readClass/fun/ExtFunInClass.kt new file mode 100644 index 00000000000..c339935326e --- /dev/null +++ b/compiler/testData/readClass/fun/ExtFunInClass.kt @@ -0,0 +1,5 @@ +namespace test + +class ExtFunInClass { + fun Int.shuffle() = 1 +} From 6830adc359d697984cf487cbe1539b33b7af0a41 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 23:00:07 +0400 Subject: [PATCH 03/11] minor issue in JavaDescriptorResolver @JetParameterValue reader --- .../jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 6948e7ac5fe..afaa5e5f76e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -636,7 +636,7 @@ public class JavaDescriptorResolver { PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD); if (receiverExpression != null) { - receiver = true; + receiver = (Boolean) receiverExpression.getValue(); } From 6bee77715dbd60dbc336cc9abadad3d884e515c3 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 23:00:12 +0400 Subject: [PATCH 04/11] reading functions with default args --- .../jet/lang/resolve/java/JavaDescriptorResolver.java | 8 +++++++- compiler/testData/readClass/fun/FunDefaultArg.kt | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/readClass/fun/FunDefaultArg.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index afaa5e5f76e..ef308c3f8d3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -608,6 +608,7 @@ public class JavaDescriptorResolver { String typeFromAnnotation = null; boolean receiver = false; + boolean hasDefaultValue = false; // TODO: must be very slow, make it lazy? String name = parameter.getName() != null ? parameter.getName() : "p" + i; @@ -638,6 +639,11 @@ public class JavaDescriptorResolver { if (receiverExpression != null) { receiver = (Boolean) receiverExpression.getValue(); } + + PsiLiteralExpression hasDefaultValueExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD); + if (hasDefaultValueExpression != null) { + hasDefaultValue = (Boolean) hasDefaultValueExpression.getValue(); + } } else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) { @@ -661,7 +667,7 @@ public class JavaDescriptorResolver { name, null, // TODO : review changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType, - false, + hasDefaultValue, varargElementType )); } diff --git a/compiler/testData/readClass/fun/FunDefaultArg.kt b/compiler/testData/readClass/fun/FunDefaultArg.kt new file mode 100644 index 00000000000..e4cda07d87b --- /dev/null +++ b/compiler/testData/readClass/fun/FunDefaultArg.kt @@ -0,0 +1,3 @@ +namespace test + +fun funDefaultArg(p: Int, q: Int = 17, r: Int = 18) = 19 From c858de758ec43b89a683bf41e86730581569880d Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 23:28:46 +0400 Subject: [PATCH 05/11] reading varargs generics do not work yet: === fun

varargGeneric(a: Int, vararg b: P) = 1 === --- .../resolve/java/JetTypeJetSignatureReader.java | 16 ++++++++++++++-- .../readClass/fun/FunVarargCharSequence.kt | 3 +++ compiler/testData/readClass/fun/FunVarargInt.kt | 3 +++ .../org/jetbrains/jet/ReadClassDataTest.java | 6 ++++-- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/readClass/fun/FunVarargCharSequence.kt create mode 100644 compiler/testData/readClass/fun/FunVarargInt.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 64bf4d30633..2984dc9e057 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -1,17 +1,18 @@ package org.jetbrains.jet.lang.resolve.java; -import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeImpl; import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.Variance; +import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import java.util.ArrayList; import java.util.Collections; @@ -119,6 +120,17 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd }; } + @Override + public JetSignatureVisitor visitArrayType(final boolean nullable) { + return new JetTypeJetSignatureReader(javaDescriptorResolver, jetStandardLibrary) { + @Override + protected void done(@NotNull JetType jetType) { + JetType arrayType = TypeUtils.makeNullableAsSpecified(jetStandardLibrary.getArrayType(jetType), nullable); + JetTypeJetSignatureReader.this.done(arrayType); + } + }; + } + @Override public void visitEnd() { JetType jetType = new JetTypeImpl( diff --git a/compiler/testData/readClass/fun/FunVarargCharSequence.kt b/compiler/testData/readClass/fun/FunVarargCharSequence.kt new file mode 100644 index 00000000000..4d1f154c1e7 --- /dev/null +++ b/compiler/testData/readClass/fun/FunVarargCharSequence.kt @@ -0,0 +1,3 @@ +namespace test + +fun varargCharSequence(a: Int, vararg b: java.lang.CharSequence) = 1 diff --git a/compiler/testData/readClass/fun/FunVarargInt.kt b/compiler/testData/readClass/fun/FunVarargInt.kt new file mode 100644 index 00000000000..5b51bb4cb3d --- /dev/null +++ b/compiler/testData/readClass/fun/FunVarargInt.kt @@ -0,0 +1,3 @@ +namespace test + +fun varargInt(a: Int, vararg b: Int) = 1 diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 04458738032..c653d33579d 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -256,11 +256,13 @@ public class ReadClassDataTest extends UsefulTestCase { } private void serialize(ValueParameterDescriptor valueParameter, StringBuilder sb) { + if (valueParameter.getVarargElementType() != null) { + sb.append("vararg "); + } sb.append(valueParameter.getName()); sb.append(": "); if (valueParameter.getVarargElementType() != null) { - sb.append("vararg "); - serialize(valueParameter.getVarargElementType()); + serialize(valueParameter.getVarargElementType(), sb); } else { serialize(valueParameter.getOutType(), sb); } From 0655a5de8566b6e253bb01e9f7146c41a644696a Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 21 Dec 2011 00:07:00 +0400 Subject: [PATCH 06/11] reading abstract and final modifiers from binary classes --- .../jet/codegen/FunctionCodegen.java | 4 ++++ .../codegen/ImplementationBodyCodegen.java | 24 +++++++++++++++---- .../readClass/fun/ModifierAbstract.kt | 5 ++++ .../testData/readClass/fun/ModifierOpen.kt | 5 ++++ .../org/jetbrains/jet/ReadClassDataTest.java | 13 +++++++++- 5 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/readClass/fun/ModifierAbstract.kt create mode 100644 compiler/testData/readClass/fun/ModifierOpen.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index c8c9f3dee79..8ea5e7fd350 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -68,6 +68,10 @@ public class FunctionCodegen { { flags |= ACC_VARARGS; } + + if (functionDescriptor.getModality() == Modality.FINAL) { + flags |= ACC_FINAL; + } OwnerKind kind = context.getContextKind(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 852b12ac22e..f1535c8f16a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -47,19 +47,33 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { boolean isAbstract = false; boolean isInterface = false; + boolean isFinal = false; if(myClass instanceof JetClass) { - if(((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD)) + JetClass jetClass = (JetClass) myClass; + if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) isAbstract = true; - if(((JetClass) myClass).isTrait()) { + if (jetClass.isTrait()) { isAbstract = true; isInterface = true; } + if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD)) { + isFinal = true; + } } + int access = 0; + access |= Opcodes.ACC_PUBLIC; + if (isAbstract) { + access |= Opcodes.ACC_ABSTRACT; + } + if (isInterface) { + access |= Opcodes.ACC_INTERFACE; // ACC_SUPER + } + if (isFinal) { + access |= Opcodes.ACC_FINAL; + } v.defineClass(myClass, Opcodes.V1_6, - Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface - ? Opcodes.ACC_INTERFACE - : 0/*Opcodes.ACC_SUPER*/), + access, signature.getName(), signature.getJavaGenericSignature(), signature.getSuperclassName(), diff --git a/compiler/testData/readClass/fun/ModifierAbstract.kt b/compiler/testData/readClass/fun/ModifierAbstract.kt new file mode 100644 index 00000000000..3800def1fad --- /dev/null +++ b/compiler/testData/readClass/fun/ModifierAbstract.kt @@ -0,0 +1,5 @@ +namespace test + +abstract class ModifierAbstract { + abstract fun abs(): Int +} diff --git a/compiler/testData/readClass/fun/ModifierOpen.kt b/compiler/testData/readClass/fun/ModifierOpen.kt new file mode 100644 index 00000000000..e9f15a08e07 --- /dev/null +++ b/compiler/testData/readClass/fun/ModifierOpen.kt @@ -0,0 +1,5 @@ +namespace test + +open class ModifierOpen { + open fun abs() = 1 +} diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index c653d33579d..e8fbc7679c6 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -146,6 +146,10 @@ public class ReadClassDataTest extends UsefulTestCase { private String serializeContent(ClassDescriptor klass) { StringBuilder sb = new StringBuilder(); + + serialize(klass.getModality(), sb); + sb.append(" "); + serialize(klass.getKind(), sb); sb.append(" "); @@ -221,6 +225,9 @@ public class ReadClassDataTest extends UsefulTestCase { private void serialize(FunctionDescriptor fun, StringBuilder sb) { + serialize(fun.getModality(), sb); + sb.append(" "); + sb.append("fun "); if (!fun.getTypeParameters().isEmpty()) { sb.append("<"); @@ -278,7 +285,11 @@ public class ReadClassDataTest extends UsefulTestCase { sb.append(variance); sb.append(' '); } - } + } + + private void serialize(Modality modality, StringBuilder sb) { + sb.append(modality.name().toLowerCase()); + } private void serialize(JetType type, StringBuilder sb) { serialize(type.getConstructor().getDeclarationDescriptor(), sb); From f04e470f03c44082e0d50b7a85181da58b07ee9f Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 21 Dec 2011 00:34:43 +0400 Subject: [PATCH 07/11] rename StdlibNames --- .../jet/codegen/FunctionCodegen.java | 34 +++++++++---------- .../codegen/ImplementationBodyCodegen.java | 8 ++--- .../resolve/java/JavaDescriptorResolver.java | 29 ++++++++-------- .../{StdlibNames.java => JvmStdlibNames.java} | 4 +-- 4 files changed, 37 insertions(+), 38 deletions(-) rename compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/{StdlibNames.java => JvmStdlibNames.java} (95%) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 8ea5e7fd350..43e49fa233b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -6,7 +6,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.java.StdlibNames; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Label; @@ -92,48 +92,48 @@ public class FunctionCodegen { if(kind != OwnerKind.TRAIT_IMPL) { AnnotationVisitor av = mv.visitAnnotation(JetTypeMapper.JET_METHOD_TYPE.getDescriptor(), true); if(functionDescriptor.getReturnType().isNullable()) { - av.visit(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true); + av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true); } if (jvmSignature.getKotlinReturnType() != null) { - av.visit(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType()); + av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType()); } if (jvmSignature.getKotlinTypeParameter() != null) { - av.visit(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter()); + av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter()); } av.visitEnd(); } if(kind == OwnerKind.TRAIT_IMPL) { - AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); - av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self"); + AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self"); av.visitEnd(); } if(receiverParameter.exists()) { - AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); - av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver"); + AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver"); if(receiverParameter.getType().isNullable()) { - av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); } - av.visit(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true); av.visitEnd(); } for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true); - av.visit(StdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName()); + AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true); + av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName()); av.visitEnd(); } for(int i = 0; i != paramDescrs.size(); ++i) { - AnnotationVisitor av = mv.visitParameterAnnotation(i + start, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); + AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i); - av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName()); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName()); if(parameterDescriptor.hasDefaultValue()) { - av.visit(StdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true); } if(parameterDescriptor.getOutType().isNullable()) { - av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); } if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) { - av.visit(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i)); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i)); } av.visitEnd(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index f1535c8f16a..494742a8192 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -6,7 +6,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.OverridingUtil; -import org.jetbrains.jet.lang.resolve.java.StdlibNames; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; @@ -86,8 +86,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) { - AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, StdlibNames.JET_CLASS.getDescriptor(), true); - annotationVisitor.visit(StdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); + AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true); + annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); annotationVisitor.visitEnd(); } } @@ -120,7 +120,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { { // superinterfaces - superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT.getInternalName()); + superInterfacesLinkedHashSet.add(JvmStdlibNames.JET_OBJECT.getInternalName()); for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) { JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index ef308c3f8d3..44a39908bee 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -9,7 +9,6 @@ import com.intellij.psi.*; import com.intellij.psi.search.DelegatingGlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope; import jet.typeinfo.TypeInfoVariance; -import org.eclipse.jdt.internal.core.JavaModelManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -234,8 +233,8 @@ public class JavaDescriptorResolver { private List resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor) { for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) { - if (annotation.getQualifiedName().equals(StdlibNames.JET_CLASS.getFqName())) { - PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_CLASS_SIGNATURE); + if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_CLASS.getFqName())) { + PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_CLASS_SIGNATURE); if (attributeValue != null) { String typeParametersString = (String) attributeValue.getValue(); if (typeParametersString != null) { @@ -614,13 +613,13 @@ public class JavaDescriptorResolver { String name = parameter.getName() != null ? parameter.getName() : "p" + i; for (PsiAnnotation annotation : parameter.getModifierList().getAnnotations()) { - if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER.getFqName())) { - PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD); + if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_VALUE_PARAMETER.getFqName())) { + PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD); if (nameExpression != null) { name = (String) nameExpression.getValue(); } - PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD); + PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD); if (nullableExpression != null) { nullable = (Boolean) nullableExpression.getValue(); } else { @@ -629,24 +628,24 @@ public class JavaDescriptorResolver { changeNullable = true; } - PsiLiteralExpression signatureExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD); + PsiLiteralExpression signatureExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD); if (signatureExpression != null) { typeFromAnnotation = (String) signatureExpression.getValue(); } - PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD); + PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD); if (receiverExpression != null) { receiver = (Boolean) receiverExpression.getValue(); } - PsiLiteralExpression hasDefaultValueExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD); + PsiLiteralExpression hasDefaultValueExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD); if (hasDefaultValueExpression != null) { hasDefaultValue = (Boolean) hasDefaultValueExpression.getValue(); } - } else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) { + } else if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_TYPE_PARAMETER.getFqName())) { return JvmMethodParameterMeaning.typeInfo(new Object()); } } @@ -782,8 +781,8 @@ public class JavaDescriptorResolver { private List resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) { for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) { - if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD.getFqName())) { - PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD); + if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) { + PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD); if (attributeValue != null) { String typeParametersString = (String) attributeValue.getValue(); if (typeParametersString != null) { @@ -828,8 +827,8 @@ public class JavaDescriptorResolver { String returnTypeFromAnnotation = null; for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) { - if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD.getFqName())) { - PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD); + if (annotation.getQualifiedName().equals(JvmStdlibNames.JET_METHOD.getFqName())) { + PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD); if (nullableExpression != null) { nullable = (Boolean) nullableExpression.getValue(); } else { @@ -838,7 +837,7 @@ public class JavaDescriptorResolver { changeNullable = true; } - PsiLiteralExpression returnTypeExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD); + PsiLiteralExpression returnTypeExpression = (PsiLiteralExpression) annotation.findAttributeValue(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD); if (returnTypeExpression != null) { returnTypeFromAnnotation = (String) returnTypeExpression.getValue(); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java similarity index 95% rename from compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java rename to compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java index 285ffe54b3c..f94405a8214 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java @@ -5,7 +5,7 @@ import org.objectweb.asm.Type; /** * @author Stepan Koltsov */ -public class StdlibNames { +public class JvmStdlibNames { public static final JvmClassName JET_VALUE_PARAMETER = new JvmClassName("jet.typeinfo.JetValueParameter"); @@ -36,6 +36,6 @@ public class StdlibNames { public static final JvmClassName JET_OBJECT = new JvmClassName("jet.JetObject"); - private StdlibNames() { + private JvmStdlibNames() { } } From 6aca83b74b8afc5118114bdfb6a9f5b7fd432058 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 21 Dec 2011 00:34:47 +0400 Subject: [PATCH 08/11] JvmAbi class with JVM-related Kotlin constants --- .../src/org/jetbrains/jet/codegen/CallableMethod.java | 7 +++---- .../src/org/jetbrains/jet/codegen/FunctionCodegen.java | 3 ++- .../src/org/jetbrains/jet/codegen/JetTypeMapper.java | 3 ++- .../src/org/jetbrains/jet/codegen/StackValue.java | 5 +++-- .../src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java | 9 +++++++++ 5 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java index ffffaffb1ec..f93b818b852 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -3,13 +3,11 @@ package org.jetbrains.jet.codegen; 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.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.types.JetType; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; -import org.objectweb.asm.commons.Method; import java.util.List; @@ -87,7 +85,8 @@ public class CallableMethod implements Callable { else { if(getInvokeOpcode() != Opcodes.INVOKESTATIC) desc = desc.replace("(", "(L" + getOwner() + ";"); - v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getAsmMethod().getName() + "$default", desc); + v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + JvmAbi.TRAIT_IMPL_SUFFIX + : getOwner(), getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 43e49fa233b..a1b241edd99 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -6,6 +6,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.objectweb.asm.AnnotationVisitor; @@ -304,7 +305,7 @@ public class FunctionCodegen { boolean isConstructor = "".equals(jvmSignature.getName()); if(!isStatic && !isConstructor) descriptor = descriptor.replace("(","(L" + ownerInternalName + ";"); - final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "" : jvmSignature.getName() + "$default", descriptor, null, null); + final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null); InstructionAdapter iv = new InstructionAdapter(mv); if (v.generateCode()) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 7bcb0463f3c..12dbbe2a4cd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lexer.JetTokens; @@ -335,7 +336,7 @@ public class JetTypeMapper { if (descriptor instanceof ClassDescriptor) { String name = getFQName(descriptor); - Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : "")); + Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); if (signatureVisitor != null) { signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index f9167601b55..e797dadb554 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -6,6 +6,7 @@ import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; @@ -754,7 +755,7 @@ public abstract class StackValue { @Override public void put(Type type, InstructionAdapter v) { if(isSuper && isInterface) { - v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";")); + v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";")); } else { if (getter == null) { @@ -770,7 +771,7 @@ public abstract class StackValue { @Override public void store(InstructionAdapter v) { if(isSuper && isInterface) { - v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";")); + v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";")); } else { if (setter == null) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java new file mode 100644 index 00000000000..0cb5f676a08 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java @@ -0,0 +1,9 @@ +package org.jetbrains.jet.lang.resolve.java; + +/** + * @author Stepan Koltsov + */ +public class JvmAbi { + public static final String TRAIT_IMPL_SUFFIX = "$$TImpl"; + public static final String DEFAULT_PARAMS_IMPL_SUFFIX = "$default"; +} From ad795d958fbffc821c596b613c7b06f8b79153f5 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 21 Dec 2011 00:34:50 +0400 Subject: [PATCH 09/11] check $$TImpl class is not visible through JavaDescriptorResolver --- .../lang/resolve/java/JavaClassMembersScope.java | 5 ++++- .../resolve/java/JavaDescriptorResolver.java | 16 +++++++++++++++- .../jet/lang/resolve/java/JavaPackageScope.java | 5 ++++- .../lang/resolve/java/JavaTypeTransformer.java | 3 +++ .../org/jetbrains/jet/ReadClassDataTest.java | 3 +++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index c46e086ab25..d32a0457bac 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -106,7 +106,10 @@ public class JavaClassMembersScope implements JetScope { for (PsiClass innerClass : psiClass.getAllInnerClasses()) { if (name.equals(innerClass.getName())) { if (innerClass.hasModifierProperty(PsiModifier.STATIC) != staticMembers) return null; - return semanticServices.getDescriptorResolver().resolveClass(innerClass); + ClassDescriptor classDescriptor = semanticServices.getDescriptorResolver().resolveClass(innerClass); + if (classDescriptor != null) { + return classDescriptor; + } } } return null; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 44a39908bee..549a4b9e0ed 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -106,9 +106,14 @@ public class JavaDescriptorResolver { this.semanticServices = semanticServices; } - @NotNull + @Nullable public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) { String qualifiedName = psiClass.getQualifiedName(); + + if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { + // TODO: only if -$$TImpl class is created by Kotlin + return null; + } // First, let's check that this is a real Java class, not a Java's view on a Kotlin class: ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName); @@ -127,6 +132,12 @@ public class JavaDescriptorResolver { @Nullable public ClassDescriptor resolveClass(@NotNull String qualifiedName) { + + if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { + // TODO: only if -$$TImpl class is created by Kotlin + return null; + } + // First, let's check that this is a real Java class, not a Java's view on a Kotlin class: ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName); if (kotlinClassDescriptor != null) { @@ -753,6 +764,9 @@ public class JavaDescriptorResolver { return functionDescriptor; } DeclarationDescriptor classDescriptor = method.hasModifierProperty(PsiModifier.STATIC) ? resolveNamespace(method.getContainingClass()) : resolveClass(method.getContainingClass()); + if (classDescriptor == null) { + return null; + } PsiParameter[] parameters = method.getParameterList().getParameters(); FunctionDescriptorImpl functionDescriptorImpl = new FunctionDescriptorImpl( owner, diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index 098b8ec6bdf..45613dcb978 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -94,7 +94,10 @@ public class JavaPackageScope extends JetScopeImpl { } if (psiClass.hasModifierProperty(PsiModifier.PUBLIC)) { - allDescriptors.add(descriptorResolver.resolveClass(psiClass)); + ClassDescriptor classDescriptor = descriptorResolver.resolveClass(psiClass); + if (classDescriptor != null) { + allDescriptors.add(classDescriptor); + } } } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 4aed6ee493d..fde7a02232c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -94,6 +94,9 @@ public class JavaTypeTransformer { } ClassDescriptor descriptor = resolver.resolveClass(psiClass); + if (descriptor == null) { + return ErrorUtils.createErrorType("Unresolve java class: " + classType.getPresentableText()); + } List arguments = Lists.newArrayList(); if (classType.isRaw()) { diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index e8fbc7679c6..9714d54f0c3 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.types.JetType; @@ -123,6 +124,8 @@ public class ReadClassDataTest extends UsefulTestCase { if (ad instanceof ClassifierDescriptor) { ClassifierDescriptor bd = nsb.getMemberScope().getClassifier(ad.getName()); compareClassifiers((ClassifierDescriptor) ad, bd); + + Assert.assertNull(nsb.getMemberScope().getClassifier(ad.getName() + JvmAbi.TRAIT_IMPL_SUFFIX)); } else if (ad instanceof FunctionDescriptor) { Set functions = nsb.getMemberScope().getFunctions(ad.getName()); Assert.assertTrue(functions.size() >= 1); From 4fb7d95247496cd0187524d7cfb382f2ddb357ef Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 21 Dec 2011 10:05:26 +0200 Subject: [PATCH 10/11] commented test for KT-857 --- compiler/testData/codegen/regressions/kt857.jet | 7 +++++++ compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java | 4 ++++ 2 files changed, 11 insertions(+) create mode 100644 compiler/testData/codegen/regressions/kt857.jet diff --git a/compiler/testData/codegen/regressions/kt857.jet b/compiler/testData/codegen/regressions/kt857.jet new file mode 100644 index 00000000000..1b8598b8a5b --- /dev/null +++ b/compiler/testData/codegen/regressions/kt857.jet @@ -0,0 +1,7 @@ +namespace container_test + +class Container(var t : T) { + fun getT() : T = t +} + +fun box() = Container("OK").getT() diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 9312dadc793..89b4e450d8a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -235,4 +235,8 @@ public class ClassGenTest extends CodegenTestCase { public void testKt707 () throws Exception { blackBoxFile("regressions/kt707.jet"); } + + public void testKt857 () throws Exception { +// blackBoxFile("regressions/kt857.jet"); + } } From a279d27318e6f128a78bb929cd72fb390762c27a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 21 Dec 2011 10:49:58 +0400 Subject: [PATCH 11/11] Cache collection of jet files for scope --- .../jet/plugin/java/JavaElementFinder.java | 83 +++++++++++++------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java index adf84a87b4c..fe2513823e0 100644 --- a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java +++ b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java @@ -9,7 +9,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.psi.*; import com.intellij.psi.impl.file.PsiPackageImpl; import com.intellij.psi.search.GlobalSearchScope; @@ -18,18 +18,40 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.JetFileType; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class JavaElementFinder extends PsiElementFinder { private final Project project; private final PsiManager psiManager; + private WeakHashMap> jetFiles = new WeakHashMap>(); + public JavaElementFinder(Project project) { this.project = project; psiManager = PsiManager.getInstance(project); + + // Monitoring for files instead of collecting them each time + VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() { + @Override + public void fileCreated(VirtualFileEvent event) { + invalidateJetFilesCache(); + } + + @Override + public void fileDeleted(VirtualFileEvent event) { + invalidateJetFilesCache(); + } + + @Override + public void fileMoved(VirtualFileMoveEvent event) { + invalidateJetFilesCache(); + } + + @Override + public void fileCopied(VirtualFileCopyEvent event) { + invalidateJetFilesCache(); + } + }); } @Override @@ -45,7 +67,7 @@ public class JavaElementFinder extends PsiElementFinder { if (qualifiedName.startsWith("java.")) return PsiClass.EMPTY_ARRAY; List answer = new SmartList(); - final List filesInScope = collectProjectFiles(project, scope); + final List filesInScope = collectProjectJetFiles(project, scope); for (JetFile file : filesInScope) { JetNamespace rootNamespace = file.getRootNamespace(); final String packageName = JetPsiUtil.getFQName(rootNamespace); @@ -71,7 +93,7 @@ public class JavaElementFinder extends PsiElementFinder { Set answer = new HashSet(); String packageFQN = psiPackage.getQualifiedName(); - for (JetFile psiFile : collectProjectFiles(project, GlobalSearchScope.allScope(project))) { + for (JetFile psiFile : collectProjectJetFiles(project, GlobalSearchScope.allScope(project))) { final JetNamespace rootNamespace = psiFile.getRootNamespace(); if (packageFQN.equals(JetPsiUtil.getFQName(rootNamespace))) { answer.add("namespace"); @@ -93,7 +115,7 @@ public class JavaElementFinder extends PsiElementFinder { @Override public PsiPackage findPackage(@NotNull String qualifiedName) { - final List psiFiles = collectProjectFiles(project, GlobalSearchScope.allScope(project)); + final List psiFiles = collectProjectJetFiles(project, GlobalSearchScope.allScope(project)); for (JetFile psiFile : psiFiles) { if (qualifiedName.equals(JetPsiUtil.getFQName(psiFile.getRootNamespace()))) { @@ -108,7 +130,7 @@ public class JavaElementFinder extends PsiElementFinder { @Override public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { List answer = new SmartList(); - final List filesInScope = collectProjectFiles(project, scope); + final List filesInScope = collectProjectJetFiles(project, scope); String packageFQN = psiPackage.getQualifiedName(); for (JetFile file : filesInScope) { final JetNamespace rootNamespace = file.getRootNamespace(); @@ -125,31 +147,40 @@ public class JavaElementFinder extends PsiElementFinder { return answer.toArray(new PsiClass[answer.size()]); } + private synchronized void invalidateJetFilesCache() { + jetFiles.clear(); + } - private static List collectProjectFiles(final Project project, @NotNull final GlobalSearchScope scope) { - final List answer = new ArrayList(); + private synchronized List collectProjectJetFiles(final Project project, @NotNull final GlobalSearchScope scope) { + List cachedFiles = jetFiles.get(scope); + + if (cachedFiles == null) { + final List answer = new ArrayList(); + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - final PsiManager psiManager = PsiManager.getInstance(project); + VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots(); - VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots(); - CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() { - @Override - protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { - final FileType fileType = fileTypeManager.getFileTypeByFile(file); - if (fileType != JetFileType.INSTANCE) return; + CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() { + @Override + protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { + final FileType fileType = fileTypeManager.getFileTypeByFile(file); + if (fileType != JetFileType.INSTANCE) return; - if (scope.accept(file)) { - final PsiFile psiFile = psiManager.findFile(file); - if (psiFile instanceof JetFile) { - answer.add((JetFile) psiFile); + if (scope.accept(file)) { + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile instanceof JetFile) { + answer.add((JetFile) psiFile); + } } } - } - }); + }); - return answer; + cachedFiles = answer; + jetFiles.put(scope, answer); + } + + return cachedFiles; } }