From a4bd86d7796ae39b355b8781a05aef2127be3394 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 20:13:09 +0400 Subject: [PATCH 1/5] remove outdated noise --- .../jet/lang/resolve/java/JavaDescriptorResolver.java | 4 ---- 1 file changed, 4 deletions(-) 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 d5a4365ce9d..5be1fbe1b2d 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 @@ -555,10 +555,6 @@ public class JavaDescriptorResolver { // TODO: must be very slow, make it lazy? String name = parameter.getName() != null ? parameter.getName() : "p" + i; for (PsiAnnotation annotation : parameter.getModifierList().getAnnotations()) { - // TODO: softcode annotation name - - PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); - attributes.toString(); if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER.getFqName())) { PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD); From b48d4b4ab1fd768aeb0be27adfdfdd3af304cf0d Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 20:13:13 +0400 Subject: [PATCH 2/5] remove weird call to get this --- .../jet/lang/resolve/java/JavaDescriptorResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 5be1fbe1b2d..14a934a3a16 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 @@ -691,8 +691,8 @@ public class JavaDescriptorResolver { null, DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), typeParameters, - semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters), - semanticServices.getDescriptorResolver().makeReturnType(returnType, method), + resolveParameterDescriptors(functionDescriptorImpl, parameters), + makeReturnType(returnType, method), Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)), resolveVisibilityFromPsiModifiers(method) ); From d9ceda77430fd01c68fb117df92c908747e06961 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 20:13:16 +0400 Subject: [PATCH 3/5] reading extension functions from binary classes --- .../jet/codegen/FunctionCodegen.java | 1 + .../resolve/java/JavaDescriptorResolver.java | 120 ++++++++++++++---- .../jet/lang/resolve/java/StdlibNames.java | 1 + compiler/testData/readClass/fun/ExtFun.kt | 3 + .../org/jetbrains/jet/ReadClassDataTest.java | 11 ++ .../src/jet/typeinfo/JetValueParameter.java | 5 + 6 files changed, 116 insertions(+), 25 deletions(-) create mode 100644 compiler/testData/readClass/fun/ExtFun.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 85eab7d6335..c8c9f3dee79 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -110,6 +110,7 @@ public class FunctionCodegen { if(receiverParameter.getType().isNullable()) { av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); } + av.visit(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true); av.visitEnd(); } for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { 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 14a934a3a16..6948e7ac5fe 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,6 +9,7 @@ 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.*; @@ -214,7 +215,11 @@ public class JavaDescriptorResolver { classDescriptor, Collections.emptyList(), // TODO false); - constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL, + ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()); + if (valueParameterDescriptors.receiverType != null) { + throw new IllegalStateException(); + } + constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors, Modality.FINAL, resolveVisibilityFromPsiModifiers(constructor)); constructorDescriptor.setReturnType(classDescriptor.getDefaultType()); classDescriptor.addConstructor(constructorDescriptor); @@ -522,21 +527,71 @@ public class JavaDescriptorResolver { semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor); return namespaceDescriptor; } + + private static class ValueParameterDescriptors { + private final JetType receiverType; + private final List descriptors; - public List resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) { - List result = new ArrayList(); - for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { - PsiParameter parameter = parameters[i]; - ValueParameterDescriptor valueParameterDescriptor = resolveParameterDescriptor(containingDeclaration, i, parameter); - if (valueParameterDescriptor != null) { - result.add(valueParameterDescriptor); - } + private ValueParameterDescriptors(@Nullable JetType receiverType, List descriptors) { + this.receiverType = receiverType; + this.descriptors = descriptors; } - return result; } - @Nullable - private ValueParameterDescriptor resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) { + public ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration, PsiParameter[] parameters) { + List result = new ArrayList(); + JetType receiverType = null; + for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { + PsiParameter parameter = parameters[i]; + JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i, parameter); + if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) { + // TODO + } else if (meaning.kind == JvmMethodParameterKind.REGULAR) { + result.add(meaning.valueParameterDescriptor); + } else if (meaning.kind == JvmMethodParameterKind.RECEIVER) { + if (receiverType != null) { + throw new IllegalStateException("more then one receiver"); + } + receiverType = meaning.receiverType; + } + } + return new ValueParameterDescriptors(receiverType, result); + } + + private enum JvmMethodParameterKind { + REGULAR, + RECEIVER, + TYPE_INFO, + } + + private static class JvmMethodParameterMeaning { + private final JvmMethodParameterKind kind; + private final JetType receiverType; + private final ValueParameterDescriptor valueParameterDescriptor; + private final Object typeInfo; + + private JvmMethodParameterMeaning(JvmMethodParameterKind kind, JetType receiverType, ValueParameterDescriptor valueParameterDescriptor, Object typeInfo) { + this.kind = kind; + this.receiverType = receiverType; + this.valueParameterDescriptor = valueParameterDescriptor; + this.typeInfo = typeInfo; + } + + public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) { + return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null, null); + } + + public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) { + return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor, null); + } + + public static JvmMethodParameterMeaning typeInfo(@NotNull Object typeInfo) { + return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null, typeInfo); + } + } + + @NotNull + private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) { PsiType psiType = parameter.getType(); JetType varargElementType; @@ -552,6 +607,8 @@ public class JavaDescriptorResolver { boolean nullable = true; String typeFromAnnotation = null; + boolean receiver = false; + // TODO: must be very slow, make it lazy? String name = parameter.getName() != null ? parameter.getName() : "p" + i; for (PsiAnnotation annotation : parameter.getModifierList().getAnnotations()) { @@ -575,8 +632,16 @@ public class JavaDescriptorResolver { if (signatureExpression != null) { typeFromAnnotation = (String) signatureExpression.getValue(); } + + + PsiLiteralExpression receiverExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD); + if (receiverExpression != null) { + receiver = true; + } + + } else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) { - return null; + return JvmMethodParameterMeaning.typeInfo(new Object()); } } @@ -586,16 +651,20 @@ public class JavaDescriptorResolver { } else { outType = semanticServices.getTypeTransformer().transformToType(psiType); } - return new ValueParameterDescriptorImpl( - containingDeclaration, - i, - Collections.emptyList(), // TODO - name, - null, // TODO : review - changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType, - false, - varargElementType - ); + if (receiver) { + return JvmMethodParameterMeaning.receiver(outType); + } else { + return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl( + containingDeclaration, + i, + Collections.emptyList(), // TODO + name, + null, // TODO : review + changeNullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType, + false, + varargElementType + )); + } } public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) { @@ -687,11 +756,12 @@ public class JavaDescriptorResolver { ); methodDescriptorCache.put(method, functionDescriptorImpl); List typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl); + ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, parameters); functionDescriptorImpl.initialize( - null, + valueParameterDescriptors.receiverType, DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), typeParameters, - resolveParameterDescriptors(functionDescriptorImpl, parameters), + valueParameterDescriptors.descriptors, makeReturnType(returnType, method), Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL)), resolveVisibilityFromPsiModifiers(method) 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/StdlibNames.java index dd071b38631..285ffe54b3c 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/StdlibNames.java @@ -13,6 +13,7 @@ public class StdlibNames { public static final String JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue"; public static final String JET_VALUE_PARAMETER_NULLABLE_FIELD = "nullable"; public static final String JET_VALUE_PARAMETER_TYPE_FIELD = "type"; + public static final String JET_VALUE_PARAMETER_RECEIVER_FIELD = "receiver"; public static final JvmClassName JET_TYPE_PARAMETER = new JvmClassName("jet.typeinfo.JetTypeParameter"); diff --git a/compiler/testData/readClass/fun/ExtFun.kt b/compiler/testData/readClass/fun/ExtFun.kt new file mode 100644 index 00000000000..f894ea8a631 --- /dev/null +++ b/compiler/testData/readClass/fun/ExtFun.kt @@ -0,0 +1,3 @@ +namespace test + +fun Int.shuffle() = 1 diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 8960f3ccc53..04458738032 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -23,6 +23,7 @@ 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.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.Variance; @@ -226,6 +227,12 @@ public class ReadClassDataTest extends UsefulTestCase { serializeCommaSeparated(fun.getTypeParameters(), sb); sb.append(">"); } + + if (fun.getReceiverParameter().exists()) { + serialize(fun.getReceiverParameter(), sb); + sb.append("."); + } + sb.append(fun.getName()); sb.append("("); serializeCommaSeparated(fun.getValueParameters(), sb); @@ -233,6 +240,10 @@ public class ReadClassDataTest extends UsefulTestCase { serialize(fun.getReturnType(), sb); } + private void serialize(ExtensionReceiver extensionReceiver, StringBuilder sb) { + serialize(extensionReceiver.getType(), sb); + } + private void serialize(PropertyDescriptor prop, StringBuilder sb) { if (prop.isVar()) { sb.append("var "); diff --git a/stdlib/src/jet/typeinfo/JetValueParameter.java b/stdlib/src/jet/typeinfo/JetValueParameter.java index db0a4f52605..cc3b7aebbf0 100644 --- a/stdlib/src/jet/typeinfo/JetValueParameter.java +++ b/stdlib/src/jet/typeinfo/JetValueParameter.java @@ -35,6 +35,11 @@ public @interface JetValueParameter { */ boolean hasDefaultValue () default false; + /** + * @return if this parameter is receiver + */ + boolean receiver() default false; + /** * @return type unless Java type is correct Kotlin type. */ From 7deb8b8cdcd9fdda682fa0c1ee1ac8ba152d038b Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 20:14:05 +0400 Subject: [PATCH 4/5] ignore my local tests --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1af2e47cf73..852cf881b6e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ out .idea/codeStyleSettings.xml .idea/workspace.xml tmp +*TestMy.java From 02111687d217ffa280b716fba5523a378d6d549c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Tue, 20 Dec 2011 20:15:42 +0400 Subject: [PATCH 5/5] missing Trait test in ReadClassDataTest --- compiler/testData/readClass/class/Trait.kt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 compiler/testData/readClass/class/Trait.kt diff --git a/compiler/testData/readClass/class/Trait.kt b/compiler/testData/readClass/class/Trait.kt new file mode 100644 index 00000000000..b984afa34b0 --- /dev/null +++ b/compiler/testData/readClass/class/Trait.kt @@ -0,0 +1,3 @@ +namespace test + +trait Trtrtr