diff --git a/build.xml b/build.xml index dd13289ae3a..6b9761bf26b 100644 --- a/build.xml +++ b/build.xml @@ -21,7 +21,9 @@ + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java index 2665770d752..c95731ca4fe 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java @@ -65,6 +65,10 @@ public abstract class ClassBuilder { getVisitor().visitOuterClass(owner, name, desc); } + public void visitInnerClass(String name, String outerName, String innerName, int access) { + getVisitor().visitInnerClass(name, outerName, innerName, access); + } + public boolean generateCode() { return true; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 43f89484007..ac955d16cac 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -24,7 +24,6 @@ import org.objectweb.asm.commons.Method; import org.objectweb.asm.signature.SignatureWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -184,7 +183,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper()); FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state); JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor); - fc.generateMethod(body, jvmMethodSignature, null, funDescriptor); + fc.generateMethod(body, jvmMethodSignature, false, null, funDescriptor); return closureContext.outerWasUsed; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index 368b1915d9e..527e637243a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -36,6 +36,7 @@ public abstract class CodegenContext { private final DeclarationDescriptor contextType; private final OwnerKind contextKind; + @Nullable private final CodegenContext parentContext; public final ObjectOrClosureCodegen closure; @@ -142,6 +143,7 @@ public abstract class CodegenContext { return frameMap; } + @Nullable public CodegenContext getParentContext() { return parentContext; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index eacfd2e3308..16311b49ede 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -14,8 +14,8 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.*; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; -import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor; import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; @@ -1042,15 +1042,11 @@ public class ExpressionCodegen extends JetVisitor { } else { owner = typeMapper.getOwner(functionDescriptor, OwnerKind.IMPLEMENTATION); - if(containingDeclaration instanceof JavaClassDescriptor) { - isInterface = CodegenUtil.isInterface(containingDeclaration); + if (containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) { + isInterface = true; } else { - if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) - isInterface = true; - else { - isInterface = false; - } + isInterface = false; } } @@ -1096,23 +1092,30 @@ public class ExpressionCodegen extends JetVisitor { } } } - if(!(containingDeclaration instanceof JavaNamespaceDescriptor) && !(containingDeclaration instanceof JavaClassDescriptor)) + if(!(containingDeclaration instanceof JavaNamespaceDescriptor)) getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); else getter = null; + + if (propertyDescriptor.getGetter() == null) { + getter = null; + } } //noinspection ConstantConditions if (isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault())) { setter = null; } else { - if(!(containingDeclaration instanceof JavaNamespaceDescriptor) && !(containingDeclaration instanceof JavaClassDescriptor)) { + if(!(containingDeclaration instanceof JavaNamespaceDescriptor)) { JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null; } else { setter = null; } + if (propertyDescriptor.getSetter() == null) { + setter = null; + } } } @@ -2658,14 +2661,14 @@ If finally block is present, its last expression is the value of try expression. if (CodegenUtil.hasTypeInfoField(defaultType)) { if(!(context instanceof CodegenContext.ConstructorContext)) { v.load(0, TYPE_OBJECT); - v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/TypeInfo;"); + v.getfield(ownerType.getInternalName(), JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;"); } else { v.load(((ConstructorFrameMap)myFrameMap).getTypeInfoIndex(), TYPE_OBJECT); } } else { - v.getstatic(ownerType.getInternalName(), "$typeInfo", "Ljet/TypeInfo;"); + v.getstatic(ownerType.getInternalName(), JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;"); } } else { @@ -2677,7 +2680,7 @@ If finally block is present, its last expression is the value of try expression. v.load(0, TYPE_OBJECT); while(descriptor != containingDeclaration) { descriptor = CodegenUtil.getOuterClassDescriptor(descriptor); - v.invokeinterface(TYPE_JET_OBJECT.getInternalName(), "getOuterObject", "()Ljet/JetObject;"); + v.invokeinterface(TYPE_JET_OBJECT.getInternalName(), JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, "()Ljet/JetObject;"); } v.invokeinterface(TYPE_JET_OBJECT.getInternalName(), JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;"); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index d043a239822..77eff97f2d8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; @@ -44,21 +43,26 @@ public class FunctionCodegen { final NamedFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f); assert functionDescriptor != null; JvmMethodSignature method = typeMapper.mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature(); - generateMethod(f, method, null, functionDescriptor); + generateMethod(f, method, true, null, functionDescriptor); } - public void generateMethod(JetDeclarationWithBody f, JvmMethodSignature jvmMethod, @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) { + public void generateMethod(JetDeclarationWithBody f, + JvmMethodSignature jvmMethod, boolean needJetAnnotations, + @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) { + CodegenContext.MethodContext funContext = owner.intoFunction(functionDescriptor); final JetExpression bodyExpression = f.getBodyExpression(); - generatedMethod(bodyExpression, jvmMethod, propertyTypeSignature, funContext, functionDescriptor, f); + generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f); } private void generatedMethod(JetExpression bodyExpressions, - JvmMethodSignature jvmSignature, - @Nullable String propertyTypeSignature, - CodegenContext.MethodContext context, - FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun) + JvmMethodSignature jvmSignature, + boolean needJetAnnotations, @Nullable String propertyTypeSignature, + CodegenContext.MethodContext context, + FunctionDescriptor functionDescriptor, + JetDeclarationWithBody fun + ) { List paramDescrs = functionDescriptor.getValueParameters(); List typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters(); @@ -77,6 +81,10 @@ public class FunctionCodegen { } OwnerKind kind = context.getContextKind(); + + if (kind == OwnerKind.TRAIT_IMPL) { + needJetAnnotations = false; + } ReceiverDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject(); ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); @@ -92,62 +100,52 @@ public class FunctionCodegen { final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), jvmSignature.getGenericsSignature(), null); if(v.generateCode()) { int start = 0; - if(kind != OwnerKind.TRAIT_IMPL) { + if (needJetAnnotations) { if (functionDescriptor instanceof PropertyAccessorDescriptor) { PropertyCodegen.generateJetPropertyAnnotation(mv, propertyTypeSignature, jvmSignature.getKotlinTypeParameter()); } else if (functionDescriptor instanceof NamedFunctionDescriptor) { if (propertyTypeSignature != null) { throw new IllegalStateException(); } - AnnotationVisitor av = mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true); - if(functionDescriptor.getReturnType().isNullable()) { - av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true); - } - if (jvmSignature.getKotlinReturnType() != null) { - av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType()); - } - if (jvmSignature.getKotlinTypeParameter() != null) { - av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter()); - } - av.visitEnd(); + JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); + aw.writeKind(JvmStdlibNames.JET_METHOD_KIND_REGULAR); + aw.writeNullableReturnType(functionDescriptor.getReturnType().isNullable()); + aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); + aw.writeReturnType(jvmSignature.getKotlinReturnType()); + aw.visitEnd(); } else { throw new IllegalStateException(); } - } - if(kind == OwnerKind.TRAIT_IMPL) { - 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++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver"); - if(receiverParameter.getType().isNullable()) { - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); + if(receiverParameter.exists()) { + 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(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); + } + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true); + av.visitEnd(); } - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true); - av.visitEnd(); - } - for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - 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, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); - ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i); - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName()); - if(parameterDescriptor.hasDefaultValue()) { - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true); + for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { + AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true); + av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName()); + av.visitEnd(); } - if(parameterDescriptor.getOutType().isNullable()) { - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); + for(int i = 0; i != paramDescrs.size(); ++i) { + AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); + ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i); + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName()); + if(parameterDescriptor.hasDefaultValue()) { + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true); + } + if(parameterDescriptor.getOutType().isNullable()) { + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); + } + if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) { + av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start).getKotlinSignature()); + } + av.visitEnd(); } - if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) { - av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start).getKotlinSignature()); - } - av.visitEnd(); } } if (!isAbstract && v.generateCode()) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index fbbb9cf5279..fcd14691bb1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -7,6 +7,7 @@ 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.constants.CompileTimeConstant; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; @@ -94,6 +95,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null); } + for (ClassDescriptor innerClass : descriptor.getInnerClassesAndObjects()) { + // TODO: proper access + int innerClassAccess = Opcodes.ACC_PUBLIC; + if (innerClass.getModality() == Modality.FINAL) { + innerClassAccess |= Opcodes.ACC_FINAL; + } else if (innerClass.getModality() == Modality.ABSTRACT) { + innerClassAccess |= Opcodes.ACC_ABSTRACT; + } + // TODO: cache internal names + String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + v.visitInnerClass(innerClassInternalName, outerClassInernalName, innerClass.getName(), innerClassAccess); + } + if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) { AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true); annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); @@ -244,7 +259,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter()); - mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd(); if (v.generateCode()) { mv.visitCode(); @@ -268,7 +282,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter()); - mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true).visitEnd(); if (v.generateCode()) { mv.visitCode(); @@ -540,18 +553,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.putfield(classname, fieldName, interfaceDesc); Type outerType = typeMapper.mapType(outerDescriptor.getDefaultType()); - MethodVisitor outer = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getOuterObject", "()Ljet/JetObject;", null, null); + MethodVisitor outer = v.newMethod(myClass, Opcodes.ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, "()Ljet/JetObject;", null, null); outer.visitCode(); outer.visitVarInsn(Opcodes.ALOAD, 0); outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor()); outer.visitInsn(Opcodes.ARETURN); - FunctionCodegen.endVisit(outer, "getOuterObject", myClass); + FunctionCodegen.endVisit(outer, JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, myClass); } if (CodegenUtil.requireTypeInfoConstructorArg(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(frameMap.getTypeInfoIndex(), JetTypeMapper.TYPE_OBJECT); - iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$setTypeInfo", "(Ljet/TypeInfo;)V"); + iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), JvmAbi.SET_TYPE_INFO_METHOD, "(Ljet/TypeInfo;)V"); } if(closure != null) { @@ -887,7 +900,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType defaultType = descriptor.getDefaultType(); if(CodegenUtil.requireTypeInfoConstructorArg(defaultType)) { if(!CodegenUtil.hasDerivedTypeInfoField(defaultType)) { - v.newField(myClass, Opcodes.ACC_PROTECTED, "$typeInfo", "Ljet/TypeInfo;", null, null); + v.newField(myClass, Opcodes.ACC_PROTECTED, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;", null, null); MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null); if (v.generateCode()) { @@ -895,21 +908,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { InstructionAdapter iv = new InstructionAdapter(mv); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); iv.load(0, JetTypeMapper.TYPE_OBJECT); - iv.getfield(owner, "$typeInfo", "Ljet/TypeInfo;"); + iv.getfield(owner, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;"); iv.areturn(JetTypeMapper.TYPE_TYPEINFO); FunctionCodegen.endVisit(iv, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, myClass); } - mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/TypeInfo;)V", null, null); + mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, JvmAbi.SET_TYPE_INFO_METHOD, "(Ljet/TypeInfo;)V", null, null); if (v.generateCode()) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(1, JetTypeMapper.TYPE_OBJECT); - iv.putfield(owner, "$typeInfo", "Ljet/TypeInfo;"); + iv.putfield(owner, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;"); mv.visitInsn(Opcodes.RETURN); - FunctionCodegen.endVisit(iv, "$setTypeInfo", myClass); + FunctionCodegen.endVisit(iv, JvmAbi.SET_TYPE_INFO_METHOD, myClass); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetMethodAnnotationWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetMethodAnnotationWriter.java new file mode 100644 index 00000000000..fe7ee73716b --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetMethodAnnotationWriter.java @@ -0,0 +1,55 @@ +package org.jetbrains.jet.codegen; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.MethodVisitor; + +/** + * @author Stepan Koltsov + */ +public class JetMethodAnnotationWriter { + private final AnnotationVisitor av; + + private JetMethodAnnotationWriter(AnnotationVisitor av) { + this.av = av; + } + + public void writeKind(int kind) { + if (kind != JvmStdlibNames.JET_METHOD_KIND_DEFAULT) { + av.visit(JvmStdlibNames.JET_METHOD_KIND_FIELD, kind); + } + } + + public void writeTypeParameters(@NotNull String typeParameters) { + if (typeParameters.length() > 0) { + av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, typeParameters); + } + } + + public void writeReturnType(@NotNull String returnType) { + if (returnType.length() > 0) { + av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, returnType); + } + } + + public void writePropertyType(@NotNull String propertyType) { + if (propertyType.length() > 0) { + 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(); + } + + public static JetMethodAnnotationWriter visitAnnotation(MethodVisitor mv) { + return new JetMethodAnnotationWriter(mv.visitAnnotation(JvmStdlibNames.JET_METHOD.getDescriptor(), true)); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 9968ad4ebcb..ad5724d9ee8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -246,7 +246,11 @@ public class JetTypeMapper { DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); if (ErrorUtils.isError(descriptor)) { - return Type.getObjectType("error/NonExistentClass"); + Type asmType = Type.getObjectType("error/NonExistentClass"); + if (signatureVisitor != null) { + visitAsmType(signatureVisitor, asmType, true); + } + return asmType; } if (standardLibrary.getArray().equals(descriptor)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 31bc00c6667..63eb199e3e6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -6,7 +6,6 @@ import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.types.JetStandardClasses; @@ -152,9 +151,9 @@ public class NamespaceCodegen { } DeclarationDescriptor declarationDescriptor = jetType.getConstructor().getDeclarationDescriptor(); - if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !(declarationDescriptor instanceof JavaClassDescriptor) && !JetStandardClasses.getAny().equals(declarationDescriptor)) { + if(!jetType.equals(root) && jetType.getArguments().size() == 0 && !JetStandardClasses.getAny().equals(declarationDescriptor)) { // TODO: we need some better checks here - v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$typeInfo", "Ljet/TypeInfo;"); + v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;"); return; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 8ae216a3055..fefe4b7d5f5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -13,7 +13,6 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lexer.JetTokens; -import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -89,7 +88,7 @@ public class PropertyCodegen { if (getter != null) { if (getter.getBodyExpression() != null) { JvmPropertyAccessorSignature signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor, kind); - functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter()); + functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter()); } else if (!getter.hasModifier(JetTokens.PRIVATE_KEYWORD)) { generateDefaultGetter(p, getter); @@ -111,7 +110,7 @@ public class PropertyCodegen { final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); assert setterDescriptor != null; JvmPropertyAccessorSignature signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor, kind); - functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), signature.getPropertyTypeKotlinSignature(), setterDescriptor); + functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor); } else if (!p.hasModifier(JetTokens.PRIVATE_KEYWORD)) { generateDefaultSetter(p, setter); @@ -170,14 +169,11 @@ public class PropertyCodegen { } public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters) { - AnnotationVisitor annotationVisitor = mv.visitAnnotation(JvmStdlibNames.JET_PROPERTY.getDescriptor(), true); - if (kotlinType.length() > 0) { - annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_FIELD, kotlinType); - } - if (typeParameters.length() > 0) { - annotationVisitor.visit(JvmStdlibNames.JET_PROPERTY_TYPE_PARAMETERS_FIELD, typeParameters); - } - annotationVisitor.visitEnd(); + JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); + aw.writeKind(JvmStdlibNames.JET_METHOD_KIND_PROPERTY); + aw.writeTypeParameters(typeParameters); + aw.writePropertyType(kotlinType); + aw.visitEnd(); } private void generateDefaultSetter(JetProperty p, JetDeclaration declaration) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 0cae7cbf43f..4a545bc89a4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -744,7 +744,9 @@ public abstract class StackValue { static class Property extends StackValue { private final String name; + @Nullable private final Method getter; + @Nullable private final Method setter; public final String owner; private final boolean isStatic; diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java index 545a248242b..17193241a1f 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java @@ -7,9 +7,8 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.Processor; -import jet.ExtensionFunction0; -import jet.modules.IModuleBuilder; -import jet.modules.IModuleSetBuilder; +import jet.modules.AllModules; +import jet.modules.Module; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.ClassFileFactory; import org.jetbrains.jet.codegen.GeneratedClassLoader; @@ -19,7 +18,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.plugin.JetMainDetector; import java.io.*; -import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.List; @@ -174,13 +173,14 @@ public class CompileEnvironment { e.printStackTrace(); } - final IModuleSetBuilder moduleSetBuilder = loadModuleScript(moduleFile); - if (moduleSetBuilder == null) { - return; + final List modules = loadModuleScript(moduleFile); + + if (modules == null) { + throw new CompileEnvironmentException("Module script " + moduleFile + " compilation failed"); } final String directory = new File(moduleFile).getParent(); - for (IModuleBuilder moduleBuilder : moduleSetBuilder.getModules()) { + for (Module moduleBuilder : modules) { ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory); final String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath(); try { @@ -191,7 +191,7 @@ public class CompileEnvironment { } } - public IModuleSetBuilder loadModuleScript(String moduleFile) { + public List loadModuleScript(String moduleFile) { CompileSession scriptCompileSession = new CompileSession(myEnvironment); scriptCompileSession.addSources(moduleFile); scriptCompileSession.addStdLibSources(true); @@ -204,34 +204,25 @@ public class CompileEnvironment { return runDefineModules(moduleFile, factory); } - private static IModuleSetBuilder runDefineModules(String moduleFile, ClassFileFactory factory) { + private static List runDefineModules(String moduleFile, ClassFileFactory factory) { GeneratedClassLoader loader = new GeneratedClassLoader(factory); try { - Class moduleSetBuilderClass = loader.loadClass("kotlin.modules.ModuleSetBuilder"); - final IModuleSetBuilder moduleSetBuilder = (IModuleSetBuilder) moduleSetBuilderClass.newInstance(); - Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS); - final Field[] fields = namespaceClass.getDeclaredFields(); - boolean modulesDefined = false; - for (Field field : fields) { - if (field.getName().equals("modules")) { - field.setAccessible(true); - ExtensionFunction0 defineMudules = (ExtensionFunction0) field.get(null); - defineMudules.invoke(moduleSetBuilder); - modulesDefined = true; - break; - } + final Method method = namespaceClass.getDeclaredMethod("project"); + if (method == null) { + throw new CompileEnvironmentException("Module script " + moduleFile + " must define project() function"); } - if (!modulesDefined) { - throw new CompileEnvironmentException("Module script " + moduleFile + " must define a modules() property"); - } - return moduleSetBuilder; + + method.setAccessible(true); + method.invoke(null); + + return AllModules.modules; } catch (Exception e) { throw new CompileEnvironmentException(e); } } - public ClassFileFactory compileModule(IModuleBuilder moduleBuilder, String directory) { + public ClassFileFactory compileModule(Module moduleBuilder, String directory) { CompileSession moduleCompileSession = new CompileSession(myEnvironment); if (!"stdlib".equals(moduleBuilder.getModuleName())) { moduleCompileSession.addStdLibSources(false); diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java index 32e0bdf4a10..fa6bde47ce8 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/JetCoreEnvironment.java @@ -4,9 +4,6 @@ import com.intellij.core.JavaCoreEnvironment; import com.intellij.lang.java.JavaParserDefinition; import com.intellij.mock.MockApplication; import com.intellij.openapi.Disposable; -import com.intellij.openapi.extensions.Extensions; -import com.intellij.psi.PsiElementFinder; -import org.jetbrains.jet.asJava.JavaElementFinder; import org.jetbrains.jet.lang.parsing.JetParserDefinition; import org.jetbrains.jet.plugin.JetFileType; @@ -23,9 +20,11 @@ public class JetCoreEnvironment extends JavaCoreEnvironment { registerParserDefinition(new JavaParserDefinition()); registerParserDefinition(new JetParserDefinition()); +/* Extensions.getArea(myProject) .getExtensionPoint(PsiElementFinder.EP_NAME) .registerExtension(new JavaElementFinder(myProject)); +*/ } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java deleted file mode 100644 index 91508d3bda4..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassDescriptor.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.jetbrains.jet.lang.resolve.java; - -import com.google.common.collect.Sets; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.jet.lang.types.*; - -import java.util.*; - -/** - * @author abreslav - */ -public class JavaClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor { - - private TypeConstructor typeConstructor; - private JavaClassMembersScope unsubstitutedMemberScope; -// private JetType classObjectType; - private final Set constructors = Sets.newLinkedHashSet(); - private Modality modality; - private Visibility visibility; - private JetType superclassType; - private final ClassKind kind; - private ClassReceiver implicitReceiver; - - - public JavaClassDescriptor(DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind) { - super(containingDeclaration); - this.kind = kind; - } - - public void setTypeConstructor(TypeConstructor typeConstructor) { - this.typeConstructor = typeConstructor; - } - - public void setModality(Modality modality) { - this.modality = modality; - } - - public void setVisibility(Visibility visibility) { - this.visibility = visibility; - } - - public void setUnsubstitutedMemberScope(JavaClassMembersScope memberScope) { - this.unsubstitutedMemberScope = memberScope; - } - -// public void setClassObjectMemberScope(JavaClassMembersScope memberScope) { -// classObjectType = new JetTypeImpl( -// new TypeConstructorImpl( -// JavaDescriptorResolver.JAVA_CLASS_OBJECT, -// Collections.emptyList(), -// true, -// "Class object emulation for " + getName(), -// Collections.emptyList(), -// Collections.emptyList() -// ), -// memberScope -// ); -// } - - public void addConstructor(ConstructorDescriptor constructorDescriptor) { - this.constructors.add(constructorDescriptor); - } - - private TypeSubstitutor createTypeSubstitutor(List typeArguments) { - List parameters = getTypeConstructor().getParameters(); - Map context = TypeUtils.buildSubstitutionContext(parameters, typeArguments); - return TypeSubstitutor.create(context); - } - - @NotNull - @Override - public JetScope getMemberScope(List typeArguments) { - assert typeArguments.size() == typeConstructor.getParameters().size(); - - if (typeArguments.isEmpty()) return unsubstitutedMemberScope; - - TypeSubstitutor substitutor = createTypeSubstitutor(typeArguments); - return new SubstitutingScope(unsubstitutedMemberScope, substitutor); - } - - @NotNull - @Override - public JetType getSuperclassType() { - return superclassType; - } - - public void setSuperclassType(@NotNull JetType superclassType) { - this.superclassType = superclassType; - } - - @NotNull - @Override - public Set getConstructors() { - return constructors; - } - - @Override - public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { - return null; - } - - @Override - public boolean hasConstructors() { - return !constructors.isEmpty(); - } - - @NotNull - @Override - public TypeConstructor getTypeConstructor() { - return typeConstructor; - } - - @NotNull - @Override - public JetType getDefaultType() { - return TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope); - } - - @NotNull - @Override - public ClassDescriptor substitute(TypeSubstitutor substitutor) { - throw new UnsupportedOperationException(); // TODO - } - - @Override - public JetType getClassObjectType() { - return null; - } - - @Override - public ClassDescriptor getClassObjectDescriptor() { - return null; - } - - @Override - public boolean isClassObjectAValue() { - return false; - } - - @NotNull - @Override - public ClassKind getKind() { - return kind; - } - - @Override - @NotNull - public Modality getModality() { - return modality; - } - - @NotNull - @Override - public Visibility getVisibility() { - return visibility; - } - - @Override - public R accept(DeclarationDescriptorVisitor visitor, D data) { - return visitor.visitClassDescriptor(this, data); - } - - @Override - public String toString() { - return "java class " + typeConstructor; - } - - @NotNull - @Override - public ReceiverDescriptor getImplicitReceiver() { - if (implicitReceiver == null) { - implicitReceiver = new ClassReceiver(this); - } - return implicitReceiver; - } - - @Override - public ClassDescriptor getInnerClassOrObject(String name) { - return null; - } - - @NotNull - @Override - public Collection getInnerClassesAndObjects() { - return Collections.emptyList(); - } -} 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 7eb48c22982..80c8b72a9c9 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 @@ -83,6 +83,8 @@ public class JavaClassMembersScope implements JetScope { } allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(containingDeclaration, psiClass, staticMembers)); + + allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveInnerClasses(containingDeclaration, psiClass, staticMembers)); } return allDescriptors; } 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 eb58b956aac..feb5b6896aa 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 @@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.descriptors.MutableClassDescriptorLite; import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; @@ -50,7 +51,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeConstructorImpl; import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.Variance; @@ -132,12 +132,11 @@ public class JavaDescriptorResolver { private static abstract class ResolverScopeData { @Nullable private Set properties; - private boolean kotlin; + protected boolean kotlin; } private static class ResolverClassData extends ResolverScopeData { - private JavaClassDescriptor classDescriptor; - private boolean kotlin; + private MutableClassDescriptorLite classDescriptor; @NotNull public ClassDescriptor getClassDescriptor() { @@ -147,7 +146,6 @@ public class JavaDescriptorResolver { private static class ResolverNamespaceData extends ResolverScopeData { private JavaNamespaceDescriptor namespaceDescriptor; - private boolean kotlin; @NotNull public NamespaceDescriptor getNamespaceDescriptor() { @@ -233,8 +231,9 @@ public class JavaDescriptorResolver { String name = psiClass.getName(); ResolverClassData classData = new ResolverClassData(); - classData.classDescriptor = new JavaClassDescriptor( - resolveParentDescriptor(psiClass), psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS + ClassKind kind = psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS; + classData.classDescriptor = new MutableClassDescriptorLite( + resolveParentDescriptor(psiClass), kind ); classData.classDescriptor.setName(name); @@ -248,30 +247,26 @@ public class JavaDescriptorResolver { } List supertypes = new ArrayList(); + List typeParameters = resolveClassTypeParameters(psiClass, classData, new OuterClassTypeVariableResolver()); - classData.classDescriptor.setTypeConstructor(new TypeConstructorImpl( - classData.classDescriptor, - Collections.emptyList(), // TODO - // TODO - psiClass.hasModifierProperty(PsiModifier.FINAL), - name, - typeParameters, - supertypes - )); + classData.classDescriptor.setTypeParameterDescriptors(typeParameters); + classData.classDescriptor.setSupertypes(supertypes); + classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass)); classData.classDescriptor.setModality(Modality.convertFromFlags( psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(), !psiClass.hasModifierProperty(PsiModifier.FINAL)) ); - classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass)); + classData.classDescriptor.createTypeConstructor(); classDescriptorCache.put(psiClass.getQualifiedName(), classData); - classData.classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false)); + classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false)); - // UGLY HACK (Andrey Breslav is not sure what did he mean) initializeTypeParameters(psiClass); + // TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes supertypes.addAll(getSupertypes(psiClass)); + if (psiClass.isInterface()) { - classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object + //classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object } else { PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes(); @@ -279,7 +274,7 @@ public class JavaDescriptorResolver { JetType superclassType = extendsListTypes.length == 0 ? JetStandardClasses.getAnyType() : semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]); - classData.classDescriptor.setSuperclassType(superclassType); + //classData.classDescriptor.setSuperclassType(superclassType); } PsiMethod[] psiConstructors = psiClass.getConstructors(); @@ -296,7 +291,7 @@ public class JavaDescriptorResolver { false); constructorDescriptor.initialize(typeParameters, Collections.emptyList(), Modality.FINAL, classData.classDescriptor.getVisibility()); constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType()); - classData.classDescriptor.addConstructor(constructorDescriptor); + classData.classDescriptor.addConstructor(constructorDescriptor, null); semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor); } } @@ -322,7 +317,7 @@ public class JavaDescriptorResolver { constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors, Modality.FINAL, resolveVisibilityFromPsiModifiers(psiConstructor)); constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType()); - classData.classDescriptor.addConstructor(constructorDescriptor); + classData.classDescriptor.addConstructor(constructorDescriptor, null); semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor); } } @@ -442,7 +437,7 @@ public class JavaDescriptorResolver { * @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor) */ private List resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, - final JavaClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) { + final ClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) { final List r = new ArrayList(); class MyTypeVariableResolver implements TypeVariableResolver { @@ -892,7 +887,7 @@ public class JavaDescriptorResolver { if (psiMethod.getName().startsWith(JvmAbi.GETTER_PREFIX)) { // TODO: some java properties too - if (method.getJetProperty().isDefined()) { + if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { if (psiMethod.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) { continue; @@ -933,7 +928,7 @@ public class JavaDescriptorResolver { } } else if (psiMethod.getName().startsWith(JvmAbi.SETTER_PREFIX)) { - if (method.getJetProperty().isDefined()) { + if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { if (psiMethod.getParameterList().getParametersCount() == 0) { // TODO: report error properly throw new IllegalStateException(); @@ -995,7 +990,7 @@ public class JavaDescriptorResolver { ResolverScopeData scopeData; if (owner instanceof JavaNamespaceDescriptor) { scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName()); - } else if (owner instanceof JavaClassDescriptor) { + } else if (owner instanceof ClassDescriptor) { scopeData = classDescriptorCache.get(psiClass.getQualifiedName()); } else { throw new IllegalStateException(); @@ -1215,10 +1210,31 @@ public class JavaDescriptorResolver { } // TODO: ugly - if (method.getJetProperty().isDefined()) { + if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) { return null; } + if (kotlin) { + // TODO: unless maybe class explicitly extends Object + String ownerClassName = method.getPsiMethod().getContainingClass().getQualifiedName(); + if (ownerClassName.equals("java.lang.Object")) { + return null; + } + + if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD) && method.getParameters().size() == 0) { + return null; + } + + if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD) && method.getParameters().size() == 0) { + return null; + } + + // TODO: check signature + if (method.getName().equals(JvmAbi.SET_TYPE_INFO_METHOD)) { + return null; + } + } + DeclarationDescriptor classDescriptor; final List classTypeParameters; if (method.isStatic()) { @@ -1287,9 +1303,9 @@ public class JavaDescriptorResolver { @NotNull PsiMethodWrapper method, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeVariableResolver classTypeVariableResolver) { - if (method.getJetMethodOrProperty().typeParameters().length() > 0) { + if (method.getJetMethod().typeParameters().length() > 0) { List r = resolveMethodTypeParametersFromJetSignature( - method.getJetMethodOrProperty().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver); + method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver); initializeTypeParameters(method.getPsiMethod()); return r; } @@ -1300,7 +1316,7 @@ public class JavaDescriptorResolver { } /** - * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor) + * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, MutableClassDescriptorLite) */ private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, final FunctionDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver) @@ -1393,4 +1409,13 @@ public class JavaDescriptorResolver { public TypeParameterDescriptor resolveTypeParameter(PsiTypeParameter typeParameter) { return resolveTypeParameterInitialization(typeParameter).descriptor; } + + public List resolveInnerClasses(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { + PsiClass[] innerPsiClasses = psiClass.getInnerClasses(); + List r = new ArrayList(innerPsiClasses.length); + for (PsiClass innerPsiClass : innerPsiClasses) { + r.add(resolveClass(innerPsiClass)); + } + return r; + } } 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 index 28ec4c6a71a..0c4c96315e0 100644 --- 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 @@ -9,4 +9,6 @@ public class JvmAbi { public static final String GETTER_PREFIX = "get"; public static final String SETTER_PREFIX = "set"; public static final String PACKAGE_CLASS = "namespace"; + public static final String SET_TYPE_INFO_METHOD = "$setTypeInfo"; + public static final String TYPE_INFO_FIELD = "$typeInfo"; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java index 48ac6e69141..8f2ceea64de 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmStdlibNames.java @@ -24,15 +24,16 @@ public class JvmStdlibNames { public static final JvmClassName JET_METHOD = new JvmClassName("jet.runtime.typeinfo.JetMethod"); + public static final String JET_METHOD_KIND_FIELD = "kind"; public static final String JET_METHOD_NULLABLE_RETURN_TYPE_FIELD = "nullableReturnType"; public static final String JET_METHOD_RETURN_TYPE_FIELD = "returnType"; public static final String JET_METHOD_TYPE_PARAMETERS_FIELD = "typeParameters"; + public static final String JET_METHOD_PROPERTY_TYPE_FIELD = "propertyType"; + + public static final int JET_METHOD_KIND_REGULAR = 0; + public static final int JET_METHOD_KIND_PROPERTY = 1; + public static final int JET_METHOD_KIND_DEFAULT = JET_METHOD_KIND_REGULAR; - public static final JvmClassName JET_PROPERTY = new JvmClassName("jet.runtime.typeinfo.JetProperty"); - - public static final String JET_PROPERTY_TYPE_FIELD = "type"; - public static final String JET_PROPERTY_TYPE_PARAMETERS_FIELD = "typeParameters"; - public static final JvmClassName JET_CONSTRUCTOR = new JvmClassName("jet.runtime.typeinfo.JetConstructor"); /** @@ -50,6 +51,7 @@ public class JvmStdlibNames { public static final JvmClassName JET_OBJECT = new JvmClassName("jet.JetObject"); public static final String JET_OBJECT_GET_TYPEINFO_METHOD = "getTypeInfo"; + public static final String JET_OBJECT_GET_OUTER_OBJECT_METHOD = "getOuterObject"; private JvmStdlibNames() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java index 9e382597382..9e94bcd4169 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMemberWrapper.java @@ -23,5 +23,9 @@ public class PsiMemberWrapper { public boolean isPrivate() { return psiMember.hasModifierProperty(PsiModifier.PRIVATE); } + + public String getName() { + return psiMember.getName(); + } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java index 7fe74364e9b..911b3d6119b 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiMethodWrapper.java @@ -1,14 +1,11 @@ package org.jetbrains.jet.lang.resolve.java; -import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiParameter; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.java.kt.JetConstructorAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; -import org.jetbrains.jet.lang.resolve.java.kt.JetMethodOrPropertyAnnotation; -import org.jetbrains.jet.lang.resolve.java.kt.JetPropertyAnnotation; import java.util.ArrayList; import java.util.List; @@ -62,23 +59,6 @@ public class PsiMethodWrapper extends PsiMemberWrapper { return jetConstructor; } - private JetPropertyAnnotation jetProperty; - @NotNull - public JetPropertyAnnotation getJetProperty() { - if (jetProperty == null) { - jetProperty = JetPropertyAnnotation.get(getPsiMethod()); - } - return jetProperty; - } - - public JetMethodOrPropertyAnnotation getJetMethodOrProperty() { - if (getJetMethod().isDefined()) { - return getJetMethod(); - } else { - return getJetProperty(); - } - } - @NotNull public PsiMethod getPsiMethod() { return (PsiMethod) psiMember; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java index 2f4d954e21c..6a269b37932 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java @@ -9,11 +9,30 @@ import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; /** * @author Stepan Koltsov */ -public class JetMethodAnnotation extends JetMethodOrPropertyAnnotation { +public class JetMethodAnnotation extends PsiAnnotationWrapper { public JetMethodAnnotation(@Nullable PsiAnnotation psiAnnotation) { super(psiAnnotation); } + + private int kind; + private boolean kindInitialized; + public int kind() { + if (!kindInitialized) { + kind = getIntAttribute(JvmStdlibNames.JET_METHOD_KIND_FIELD, JvmStdlibNames.JET_METHOD_KIND_DEFAULT); + kindInitialized = true; + } + return kind; + } + + private String typeParameters; + @NotNull + public String typeParameters() { + if (typeParameters == null) { + typeParameters = getStringAttribute(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, ""); + } + return typeParameters; + } private String returnType; @NotNull @@ -34,7 +53,16 @@ public class JetMethodAnnotation extends JetMethodOrPropertyAnnotation { } return returnTypeNullable; } - + + private String propertyType; + @NotNull + public String propertyType() { + if (propertyType == null) { + propertyType = getStringAttribute(JvmStdlibNames.JET_METHOD_PROPERTY_TYPE_FIELD, ""); + } + return propertyType; + } + public static JetMethodAnnotation get(PsiMethod psiMethod) { return new JetMethodAnnotation(psiMethod.getModifierList().findAnnotation(JvmStdlibNames.JET_METHOD.getFqName())); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java deleted file mode 100644 index e21e5ab0680..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodOrPropertyAnnotation.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.jetbrains.jet.lang.resolve.java.kt; - -import com.intellij.psi.PsiAnnotation; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; - -/** - * @author Stepan Koltsov - */ -public abstract class JetMethodOrPropertyAnnotation extends PsiAnnotationWrapper { - protected JetMethodOrPropertyAnnotation(@Nullable PsiAnnotation psiAnnotation) { - super(psiAnnotation); - } - - private String typeParameters; - @NotNull - public String typeParameters() { - if (typeParameters == null) { - typeParameters = getStringAttribute(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, ""); - } - return typeParameters; - } - -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java deleted file mode 100644 index 3ca9a0031f7..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPropertyAnnotation.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.jetbrains.jet.lang.resolve.java.kt; - -import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiMethod; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; - -/** - * @author Stepan Koltsov - */ -public class JetPropertyAnnotation extends JetMethodOrPropertyAnnotation { - protected JetPropertyAnnotation(@Nullable PsiAnnotation psiAnnotation) { - super(psiAnnotation); - } - - @NotNull - public static JetPropertyAnnotation get(@NotNull PsiMethod psiMethod) { - return new JetPropertyAnnotation(psiMethod.getModifierList().findAnnotation(JvmStdlibNames.JET_PROPERTY.getFqName())); - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationUtils.java index ec611685b02..cae68d2cf2d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationUtils.java @@ -19,6 +19,11 @@ public class PsiAnnotationUtils { return getAttribute(annotation, field, defaultValue); } + public static int getIntAttribute(@Nullable PsiAnnotation annotation, @NotNull String field, int defaultValue) { + return getAttribute(annotation, field, defaultValue); + } + + @NotNull private static T getAttribute(@Nullable PsiAnnotation annotation, @NotNull String field, @NotNull T defaultValue) { if (annotation == null) { return defaultValue; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationWrapper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationWrapper.java index 005b49c587f..4ebb9f756cb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationWrapper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/PsiAnnotationWrapper.java @@ -33,4 +33,9 @@ public abstract class PsiAnnotationWrapper { protected boolean getBooleanAttribute(String name, boolean defaultValue) { return PsiAnnotationUtils.getBooleanAttribute(psiAnnotation, name, defaultValue); } + + protected int getIntAttribute(String name, int defaultValue) { + return PsiAnnotationUtils.getIntAttribute(psiAnnotation, name, defaultValue); + } + } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java index be9e36b7696..230e58fdf12 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java @@ -20,12 +20,6 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor @NotNull JetScope getMemberScope(List typeArguments); - /** - * @return the superclass for a class descriptor, and the required class fro a trait descriptor - */ - @NotNull - JetType getSuperclassType(); - @NotNull Set getConstructors(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java index 3335f7520f1..030fa7ba9d3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptorImpl.java @@ -20,7 +20,6 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl private JetScope memberDeclarations; private Set constructors; private ConstructorDescriptor primaryConstructor; - private JetType superclassType; private ReceiverDescriptor implicitReceiver; public ClassDescriptorImpl( @@ -50,7 +49,6 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl this.memberDeclarations = memberDeclarations; this.constructors = constructors; this.primaryConstructor = primaryConstructor; - this.superclassType = superclassType; return this; } @@ -86,12 +84,6 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl return new SubstitutingScope(memberDeclarations, TypeSubstitutor.create(substitutionContext)); } - @NotNull - @Override - public JetType getSuperclassType() { - return superclassType; - } - @NotNull @Override public JetType getDefaultType() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java index 70cf1405c27..adcd080266f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LazySubstitutingClassDescriptor.java @@ -81,15 +81,6 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { return new SubstitutingScope(memberScope, getSubstitutor()); } - @NotNull - @Override - public JetType getSuperclassType() { - if (superclassType == null) { - superclassType = getSubstitutor().substitute(original.getSuperclassType(), Variance.INVARIANT); - } - return superclassType; - } - @NotNull @Override public JetType getDefaultType() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 2368a139319..2a507aa783c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -1,11 +1,7 @@ package org.jetbrains.jet.lang.descriptors; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -14,42 +10,24 @@ import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.*; import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.resolve.DescriptorRenderer; import java.util.*; /** * @author abreslav */ -public class MutableClassDescriptor extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike { - private ConstructorDescriptor primaryConstructor; - private final Set constructors = Sets.newLinkedHashSet(); +public class MutableClassDescriptor extends MutableClassDescriptorLite { private final Set callableMembers = Sets.newHashSet(); private final Set properties = Sets.newHashSet(); private final Set functions = Sets.newHashSet(); - private List typeParameters = Lists.newArrayList(); - private Collection supertypes = Lists.newArrayList(); - private Map innerClassesAndObjects = Maps.newHashMap(); - private Modality modality; - private Visibility visibility; - private TypeConstructor typeConstructor; private final WritableScope scopeForMemberResolution; - private final WritableScope scopeForMemberLookup; // This scope contains type parameters but does not contain inner classes private final WritableScope scopeForSupertypeResolution; private final WritableScope scopeForInitializers; //contains members + primary constructor value parameters + map for backing fields - private MutableClassDescriptor classObjectDescriptor; - private JetType classObjectType; - private JetType defaultType; - private final ClassKind kind; - private JetType superclassType; - private ClassReceiver implicitReceiver; - public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) { - super(containingDeclaration); + super(containingDeclaration, kind); if (containingDeclaration instanceof ClassDescriptor || containingDeclaration instanceof NamespaceLike @@ -61,23 +39,22 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme } TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace); - this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup").changeLockLevel(WritableScope.LockLevel.BOTH); + + setScopeForMemberLookup(new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler).setDebugName("MemberLookup").changeLockLevel(WritableScope.LockLevel.BOTH)); this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler).setDebugName("SupertypeResolution").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler).setDebugName("MemberResolution").changeLockLevel(WritableScope.LockLevel.BOTH); this.scopeForInitializers = new WritableScopeImpl(scopeForMemberResolution, this, redeclarationHandler).setDebugName("Initializers").changeLockLevel(WritableScope.LockLevel.BOTH); - this.kind = kind; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { - if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE; - if (!isStatic(this.getContainingDeclaration())) { - return ClassObjectStatus.NOT_ALLOWED; + public ClassObjectStatus setClassObjectDescriptor(@NotNull final MutableClassDescriptor classObjectDescriptor) { + ClassObjectStatus r = super.setClassObjectDescriptor(classObjectDescriptor); + if (r != ClassObjectStatus.OK) { + return r; } - assert classObjectDescriptor.getKind() == ClassKind.OBJECT; - this.classObjectDescriptor = classObjectDescriptor; // Members of the class object are accessible from the class // The scope must be lazy, because classObjectDescriptor may not by fully built yet @@ -85,54 +62,23 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @NotNull @Override protected JetScope getWorkerScope() { - return MutableClassDescriptor.this.classObjectDescriptor.getDefaultType().getMemberScope(); + return classObjectDescriptor.getDefaultType().getMemberScope(); } @NotNull @Override public ReceiverDescriptor getImplicitReceiver() { - return MutableClassDescriptor.this.classObjectDescriptor.getImplicitReceiver(); + return classObjectDescriptor.getImplicitReceiver(); } } ); + return ClassObjectStatus.OK; } - private static boolean isStatic(DeclarationDescriptor declarationDescriptor) { - if (declarationDescriptor instanceof NamespaceDescriptor) { - return true; - } else if (declarationDescriptor instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; - return classDescriptor.getKind() == ClassKind.OBJECT || classDescriptor.getKind() == ClassKind.ENUM_CLASS; - } else { - return false; - } - } - @Override - @Nullable - public MutableClassDescriptor getClassObjectDescriptor() { - return classObjectDescriptor; - } - - public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { - assert this.primaryConstructor == null : "Primary constructor assigned twice " + this; - this.primaryConstructor = constructorDescriptor; - addConstructor(constructorDescriptor, trace); - } - - @Override - @Nullable - public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { - return primaryConstructor; - } - - public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { - assert constructorDescriptor.getContainingDeclaration() == this; - constructors.add(constructorDescriptor); - if (defaultType != null) { - ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); - } + public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @NotNull BindingTrace trace) { + super.addConstructor(constructorDescriptor, trace); if (constructorDescriptor.isPrimary()) { for (ValueParameterDescriptor valueParameterDescriptor : constructorDescriptor.getValueParameters()) { JetParameter parameter = (JetParameter) trace.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, valueParameterDescriptor); @@ -146,17 +92,17 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme @Override public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + super.addPropertyDescriptor(propertyDescriptor); properties.add(propertyDescriptor); callableMembers.add(propertyDescriptor); - scopeForMemberLookup.addPropertyDescriptor(propertyDescriptor); scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor); } @Override public void addFunctionDescriptor(@NotNull NamedFunctionDescriptor functionDescriptor) { + super.addFunctionDescriptor(functionDescriptor); functions.add(functionDescriptor); callableMembers.add(functionDescriptor); - scopeForMemberLookup.addFunctionDescriptor(functionDescriptor); scopeForMemberResolution.addFunctionDescriptor(functionDescriptor); } @@ -175,50 +121,15 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return callableMembers; } - @Override - public NamespaceDescriptorImpl getNamespace(String name) { - throw new UnsupportedOperationException("Classes do not define namespaces"); - } - - @Override - public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { - throw new UnsupportedOperationException("Classes do not define namespaces"); - } - @Override public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { - scopeForMemberLookup.addClassifierDescriptor(classDescriptor); + super.addClassifierDescriptor(classDescriptor); scopeForMemberResolution.addClassifierDescriptor(classDescriptor); - innerClassesAndObjects.put(classDescriptor.getName(), classDescriptor); - } - - @Override - @Nullable - public ClassDescriptor getInnerClassOrObject(String name) { - return innerClassesAndObjects.get(name); - } - - @Override - @NotNull - public Collection getInnerClassesAndObjects() { - return innerClassesAndObjects.values(); - } - - @Override - public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { - scopeForMemberLookup.addObjectDescriptor(objectDescriptor); - innerClassesAndObjects.put(objectDescriptor.getName(), objectDescriptor); - } - - public void addSupertype(@NotNull JetType supertype) { - if (!ErrorUtils.isErrorType(supertype)) { - supertypes.add(supertype); - } } public void setTypeParameterDescriptors(List typeParameters) { + super.setTypeParameterDescriptors(typeParameters); for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - this.typeParameters.add(typeParameterDescriptor); scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor); } scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); @@ -232,57 +143,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme scopeForMemberResolution.addLabeledDeclaration(this); } - @NotNull @Override - public TypeConstructor getTypeConstructor() { - return typeConstructor; - } - public void createTypeConstructor() { - assert typeConstructor == null : typeConstructor; - this.typeConstructor = new TypeConstructorImpl( - this, - Collections.emptyList(), // TODO : pass annotations from the class? - !modality.isOverridable(), - getName(), - typeParameters, - supertypes); + super.createTypeConstructor(); scopeForMemberResolution.setImplicitReceiver(new ClassReceiver(this)); - for (FunctionDescriptor functionDescriptor : constructors) { - ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); - } - } - - public void addSupertypesToScopeForMemberLookup() { - for (JetType supertype : supertypes) { - scopeForMemberLookup.importScope(supertype.getMemberScope()); - } - } - - @NotNull - @Override - public JetScope getMemberScope(List typeArguments) { - assert typeArguments.size() == typeConstructor.getParameters().size(); - if (typeArguments.isEmpty()) return scopeForMemberLookup; - - List typeParameters = getTypeConstructor().getParameters(); - Map substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments); - return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext)); - } - - @NotNull - @Override - public JetType getDefaultType() { - if (defaultType == null) { - defaultType = TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); - } - return defaultType; - } - - @NotNull - @Override - public Set getConstructors() { - return constructors; } @NotNull @@ -290,11 +154,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return scopeForSupertypeResolution; } - @NotNull - public JetScope getScopeForMemberLookup() { - return scopeForMemberLookup; - } - @NotNull public JetScope getScopeForMemberResolution() { return scopeForMemberResolution; @@ -305,101 +164,11 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme return scopeForInitializers; } - @NotNull - @Override - public ClassDescriptor substitute(TypeSubstitutor substitutor) { - if (substitutor.isEmpty()) { - return this; - } - return new LazySubstitutingClassDescriptor(this, substitutor); - } - - @Override - public JetType getClassObjectType() { - if (classObjectType == null && classObjectDescriptor != null) { - classObjectType = classObjectDescriptor.getDefaultType(); - } - return classObjectType; - } - - @Override - public boolean isClassObjectAValue() { - return true; - } - - @Override - public R accept(DeclarationDescriptorVisitor visitor, D data) { - return visitor.visitClassDescriptor(this, data); - } - - @Override - public boolean hasConstructors() { - return !constructors.isEmpty(); - } - - @NotNull - @Override - public ClassKind getKind() { - return kind; - } - - @NotNull - @Override - public JetType getSuperclassType() { - return superclassType; - } - - public void setSuperclassType(@NotNull JetType superclassType) { - this.superclassType = superclassType; - } - - - public void setModality(Modality modality) { - this.modality = modality; - } - - public void setVisibility(Visibility visibility) { - this.visibility = visibility; - } - - @Override - @NotNull - public Modality getModality() { - return modality; - } - - @NotNull - @Override - public Visibility getVisibility() { - return visibility; - } - - @Override - public String toString() { - return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; - } - - public Collection getSupertypes() { - return supertypes; - } - - @NotNull - @Override - public ReceiverDescriptor getImplicitReceiver() { - if (implicitReceiver == null) { - implicitReceiver = new ClassReceiver(this); - } - return implicitReceiver; - } - public void lockScopes() { + super.lockScopes(); scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); - scopeForMemberLookup.changeLockLevel(WritableScope.LockLevel.READING); scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING); scopeForInitializers.changeLockLevel(WritableScope.LockLevel.READING); - if (classObjectDescriptor != null) { - classObjectDescriptor.lockScopes(); - } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java new file mode 100644 index 00000000000..a9c3cb04b51 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptorLite.java @@ -0,0 +1,342 @@ +package org.jetbrains.jet.lang.descriptors; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.JetParameter; +import org.jetbrains.jet.lang.resolve.AbstractScopeAdapter; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; +import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeConstructor; +import org.jetbrains.jet.lang.types.TypeConstructorImpl; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.TypeSubstitutor; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author Stepan Koltsov + */ +public class MutableClassDescriptorLite extends MutableDeclarationDescriptor implements ClassDescriptor, NamespaceLike { + private ConstructorDescriptor primaryConstructor; + private final Set constructors = Sets.newLinkedHashSet(); + + private Map innerClassesAndObjects = Maps.newHashMap(); + + private List typeParameters; + private Collection supertypes = Lists.newArrayList(); + + private TypeConstructor typeConstructor; + + private Modality modality; + private Visibility visibility; + + private MutableClassDescriptor classObjectDescriptor; + private JetType classObjectType; + private JetType defaultType; + private final ClassKind kind; + + private JetScope scopeForMemberLookup; + + private ClassReceiver implicitReceiver; + + public MutableClassDescriptorLite(DeclarationDescriptor containingDeclaration, ClassKind kind) { + super(containingDeclaration); + this.kind = kind; + } + + + private static boolean isStatic(DeclarationDescriptor declarationDescriptor) { + if (declarationDescriptor instanceof NamespaceDescriptor) { + return true; + } else if (declarationDescriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; + return classDescriptor.getKind() == ClassKind.OBJECT || classDescriptor.getKind() == ClassKind.ENUM_CLASS; + } else { + return false; + } + } + + + + @Override + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) { + if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE; + if (!isStatic(this.getContainingDeclaration())) { + return ClassObjectStatus.NOT_ALLOWED; + } + assert classObjectDescriptor.getKind() == ClassKind.OBJECT; + this.classObjectDescriptor = classObjectDescriptor; + + return ClassObjectStatus.OK; + } + + + + + + @NotNull + @Override + public TypeConstructor getTypeConstructor() { + return typeConstructor; + } + + public void setScopeForMemberLookup(JetScope scopeForMemberLookup) { + this.scopeForMemberLookup = scopeForMemberLookup; + } + + public void createTypeConstructor() { + assert typeConstructor == null : typeConstructor; + this.typeConstructor = new TypeConstructorImpl( + this, + Collections.emptyList(), // TODO : pass annotations from the class? + !modality.isOverridable(), + getName(), + typeParameters, + supertypes); + for (FunctionDescriptor functionDescriptor : constructors) { + ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); + } + } + + private WritableScope getScopeForMemberLookupAsWritableScope() { + // hack + return (WritableScope) scopeForMemberLookup; + } + + public void addSupertypesToScopeForMemberLookup() { + for (JetType supertype : supertypes) { + getScopeForMemberLookupAsWritableScope().importScope(supertype.getMemberScope()); + } + } + + @NotNull + @Override + public JetScope getMemberScope(List typeArguments) { + assert typeArguments.size() == typeConstructor.getParameters().size(); + if (typeArguments.isEmpty()) return scopeForMemberLookup; + + List typeParameters = getTypeConstructor().getParameters(); + Map substitutionContext = TypeUtils.buildSubstitutionContext(typeParameters, typeArguments); + return new SubstitutingScope(scopeForMemberLookup, TypeSubstitutor.create(substitutionContext)); + } + + + @NotNull + @Override + public Set getConstructors() { + return constructors; + } + + @NotNull + public JetScope getScopeForMemberLookup() { + return scopeForMemberLookup; + } + + @NotNull + @Override + public ClassDescriptor substitute(TypeSubstitutor substitutor) { + if (substitutor.isEmpty()) { + return this; + } + return new LazySubstitutingClassDescriptor(this, substitutor); + } + + @Override + public JetType getClassObjectType() { + if (classObjectType == null && classObjectDescriptor != null) { + classObjectType = classObjectDescriptor.getDefaultType(); + } + return classObjectType; + } + + @Override + public boolean isClassObjectAValue() { + return true; + } + + + @Override + public boolean hasConstructors() { + return !constructors.isEmpty(); + } + + @NotNull + @Override + public ClassKind getKind() { + return kind; + } + + public void setModality(Modality modality) { + this.modality = modality; + } + + public void setVisibility(Visibility visibility) { + this.visibility = visibility; + } + + @Override + @NotNull + public Modality getModality() { + return modality; + } + + @NotNull + @Override + public Visibility getVisibility() { + return visibility; + } + + public Collection getSupertypes() { + return supertypes; + } + + public void setSupertypes(@NotNull Collection supertypes) { + this.supertypes = supertypes; + } + + + public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { + assert this.primaryConstructor == null : "Primary constructor assigned twice " + this; + this.primaryConstructor = constructorDescriptor; + addConstructor(constructorDescriptor, trace); + } + + @Override + @Nullable + public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { + return primaryConstructor; + } + + public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @Nullable BindingTrace trace) { + assert constructorDescriptor.getContainingDeclaration() == this; + constructors.add(constructorDescriptor); + if (defaultType != null) { + ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); + } + } + + @NotNull + @Override + public JetType getDefaultType() { + if (defaultType == null) { + defaultType = TypeUtils.makeUnsubstitutedType(this, scopeForMemberLookup); + } + return defaultType; + } + + @Override + @Nullable + public MutableClassDescriptor getClassObjectDescriptor() { + return classObjectDescriptor; + } + + @Override + public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(propertyDescriptor); + } + + @Override + public void addFunctionDescriptor(@NotNull NamedFunctionDescriptor functionDescriptor) { + getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(functionDescriptor); + } + + @Override + public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + throw new UnsupportedOperationException("Classes do not define namespaces"); + } + + @Override + public NamespaceDescriptorImpl getNamespace(String name) { + throw new UnsupportedOperationException("Classes do not define namespaces"); + } + + @Override + public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) { + getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor); + innerClassesAndObjects.put(classDescriptor.getName(), classDescriptor); + } + + @Override + @Nullable + public ClassDescriptor getInnerClassOrObject(String name) { + return innerClassesAndObjects.get(name); + } + + @Override + @NotNull + public Collection getInnerClassesAndObjects() { + return innerClassesAndObjects.values(); + } + + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptor objectDescriptor) { + getScopeForMemberLookupAsWritableScope().addObjectDescriptor(objectDescriptor); + innerClassesAndObjects.put(objectDescriptor.getName(), objectDescriptor); + } + + public void addSupertype(@NotNull JetType supertype) { + if (!ErrorUtils.isErrorType(supertype)) { + supertypes.add(supertype); + } + } + + public void setTypeParameterDescriptors(List typeParameters) { + if (this.typeParameters != null) { + throw new IllegalStateException(); + } + this.typeParameters = new ArrayList(); + for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { + this.typeParameters.add(typeParameterDescriptor); + } + } + + + public void lockScopes() { + getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING); + if (classObjectDescriptor != null) { + classObjectDescriptor.lockScopes(); + } + } + + + @NotNull + @Override + public ReceiverDescriptor getImplicitReceiver() { + if (implicitReceiver == null) { + implicitReceiver = new ClassReceiver(this); + } + return implicitReceiver; + } + + + @Override + public String toString() { + return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; + } + + @Override + public R accept(DeclarationDescriptorVisitor visitor, D data) { + return visitor.visitClassDescriptor(this, data); + } + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamedFunctionDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamedFunctionDescriptor.java index 803b2d0ade8..52668469719 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamedFunctionDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamedFunctionDescriptor.java @@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.descriptors; import org.jetbrains.annotations.NotNull; /** + * ... and also a closure + * * @author Stepan Koltsov */ public interface NamedFunctionDescriptor extends FunctionDescriptor { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 2ccace9af81..61a384889fd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -468,8 +468,9 @@ public class JetExpressionParsing extends AbstractJetParsing { */ protected boolean parseCallWithClosure() { boolean success = false; - while (!myBuilder.newlineBeforeCurrentToken() - && (at(LBRACE) +// while (!myBuilder.newlineBeforeCurrentToken() +// && (at(LBRACE) + while ((at(LBRACE) || atSet(LABELS) && lookahead(1) == LBRACE)) { if (!at(LBRACE)) { assert _atSet(LABELS); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 4c797de0114..852cf89e6f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -94,6 +94,7 @@ public class TypeHierarchyResolver { classObjectDescriptor.setName("class-object-for-" + klass.getName()); classObjectDescriptor.setModality(Modality.FINAL); classObjectDescriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(klass.getModifierList())); + classObjectDescriptor.setTypeParameterDescriptors(new ArrayList(0)); classObjectDescriptor.createTypeConstructor(); createPrimaryConstructorForObject(null, classObjectDescriptor); mutableClassDescriptor.setClassObjectDescriptor(classObjectDescriptor); @@ -243,6 +244,7 @@ public class TypeHierarchyResolver { MutableClassDescriptor descriptor = entry.getValue(); descriptor.setModality(Modality.FINAL); descriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(objectDeclaration.getModifierList())); + descriptor.setTypeParameterDescriptors(new ArrayList(0)); descriptor.createTypeConstructor(); } } diff --git a/compiler/testData/compiler/smoke/Smoke.kts b/compiler/testData/compiler/smoke/Smoke.kts index d9429cd1b65..179d700646e 100644 --- a/compiler/testData/compiler/smoke/Smoke.kts +++ b/compiler/testData/compiler/smoke/Smoke.kts @@ -1,6 +1,7 @@ import kotlin.modules.* -val modules = module("smoke") { - source files "Smoke.kt" - jar name System.getProperty("java.io.tmpdir") + "/smoke.jar" +fun project() { + module("smoke") { + sources += "Smoke.kt" + } } diff --git a/compiler/testData/diagnostics/tests/Builders.jet b/compiler/testData/diagnostics/tests/Builders.jet index 762d4d2fbf9..5d2f38686de 100644 --- a/compiler/testData/diagnostics/tests/Builders.jet +++ b/compiler/testData/diagnostics/tests/Builders.jet @@ -1,122 +1,157 @@ // FILE: a.kt // +JDK +/** + * This is an example of a Type-Safe Groovy-style Builder + * + * Builders are good for declaratively describing data in your code. + * In this example we show how to describe an HTML page in Kotlin. + * + * See this page for details: + * http://confluence.jetbrains.net/display/Kotlin/Type-safe+Groovy-style+builders + */ package html + import java.util.* - abstract class Factory { - abstract fun create() : T - } - - abstract class Element - - class TextElement(val text : String) : Element - - abstract class Tag(val name : String) : Element { - val children = ArrayList() - val attributes = HashMap() - - protected fun initTag(init : T.() -> Unit) : T - where class object T : Factory{ - val tag = T.create() - tag.init() - children.add(tag) - return tag - } - } - - abstract class TagWithText(name : String) : Tag(name) { - fun String.plus() { - children.add(TextElement(this)) - } - } - - class HTML() : TagWithText("html") { - class object : Factory { - override fun create() = HTML() - } - - fun head(init : Head.() -> Unit) = initTag(init) - - fun body(init : Body.() -> Unit) = initTag(init) - } - - class Head() : TagWithText("head") { - class object : Factory { - override fun create() = Head() - } - - fun title(init : Title.() -> Unit) = initTag(init) - } - - class Title() : TagWithText("title") - - abstract class BodyTag(name : String) : TagWithText(name) { - } - - class Body() : BodyTag("body") { - class object : Factory<Body> { - override fun create() = Body() - } - - fun b(init : B.() -> Unit) = initTag<B>(init) - fun p(init : P.() -> Unit) = initTag<P>(init) - fun h1(init : H1.() -> Unit) = initTag<H1>(init) - fun a(href : String, init : A.() -> Unit) { - val a = initTag<A>(init) - a.href = href - } - } - - class B() : BodyTag("b") - class P() : BodyTag("p") - class H1() : BodyTag("h1") - class A() : BodyTag("a") { - var href : String - get() = attributes["href"] - set(value) { attributes["href"] = value } - } - - fun Map<String, String>.set(key : String, value : String) = this.put(key, value) - - fun html(init : HTML.() -> Unit) : HTML { - val html = HTML() - html.init() - return html - } - -// FILE: b.kt - -package foo - -import html.* - -fun result(args : Array<String>) = - html { - head { - title {+"XML encoding with Groovy"} - } - body { - h1 {+"XML encoding with Groovy"} - p {+"this format can be used as an alternative markup to XML"} - - // an element with attributes and text content - a(href = "http://groovy.codehaus.org") {+"Groovy"} - - // mixed content - p { - +"This is some" - b {+"mixed"} - +"text. For more see the" - a(href = "http://groovy.codehaus.org") {+"Groovy"} - +"project" +fun main(args : Array<String>) { + val result = + html { + head { + title {+"XML encoding with Kotlin"} } - p {+"some text"} + body { + h1 {+"XML encoding with Kotlin"} + p {+"this format can be used as an alternative markup to XML"} - // content generated by - p { - for (arg in args) - +arg + // an element with attributes and text content + a(href = "http://jetbrains.com/kotlin") {+"Kotlin"} + + // mixed content + p { + +"This is some" + b {+"mixed"} + +"text. For more see the" + a(href = "http://jetbrains.com/kotlin") {+"Kotlin"} + +"project" + } + p {+"some text"} + + // content generated from command-line arguments + p { + +"Command line arguments were:" + ul { + for (arg in args) + li {+arg} + } + } } } + println(result) +} + +trait Element { + fun render(builder : StringBuilder, indent : String) + + fun toString() : String? { + val builder = StringBuilder() + render(builder, "") + return builder.toString() } +} + +class TextElement(val text : String) : Element { + override fun render(builder : StringBuilder, indent : String) { + builder.append("$indent$text\n") + } +} + +abstract class Tag(val name : String) : Element { + val children = ArrayList<Element>() + val attributes = HashMap<String, String>() + + protected fun initTag<T : Element>(tag : T, init : T.() -> Unit) : T { + tag.init() + children.add(tag) + return tag + } + + override fun render(builder : StringBuilder, indent : String) { + builder.append("$indent<$name${renderAttributes()}>\n") + for (c in children) { + c.render(builder, indent + " ") + } + builder.append("$indent</$name>\n") + } + + private fun renderAttributes() : String? { + val builder = StringBuilder() + for (a in attributes.keySet()) { + builder.append(" $a=\"${attributes[a]}\"") + } + return builder.toString() + } +} + +abstract class TagWithText(name : String) : Tag(name) { + fun String.plus() { + children.add(TextElement(this)) + } +} + +class HTML() : TagWithText("html") { + fun head(init : Head.() -> Unit) = initTag(Head(), init) + + fun body(init : Body.() -> Unit) = initTag(Body(), init) +} + +class Head() : TagWithText("head") { + fun title(init : Title.() -> Unit) = initTag(Title(), init) +} + +class Title() : TagWithText("title") + +abstract class BodyTag(name : String) : TagWithText(name) { + fun b(init : B.() -> Unit) = initTag(B(), init) + fun p(init : P.() -> Unit) = initTag(P(), init) + fun h1(init : H1.() -> Unit) = initTag(H1(), init) + fun ul(init : UL.() -> Unit) = initTag(UL(), init) + fun a(href : String, init : A.() -> Unit) { + val a = initTag(A(), init) + a.href = href + } +} + +class Body() : BodyTag("body") +class UL() : BodyTag("ul") { + fun li(init : LI.() -> Unit) = initTag(LI(), init) +} + +class B() : BodyTag("b") +class LI() : BodyTag("li") +class P() : BodyTag("p") +class H1() : BodyTag("h1") +class A() : BodyTag("a") { + public var href : String + get() = attributes["href"] + set(value) { + attributes["href"] = value + } +} + +fun html(init : HTML.() -> Unit) : HTML { + val html = HTML() + html.init() + return html +} + +// An excerpt from the Standard Library +fun <K, V> Map<K, V>.set(key : K, value : V) = this.put(key, value) + +fun println(message : Any?) { + System.out?.println(message) +} + +fun print(message : Any?) { + System.out?.print(message) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet index 32fc8be4b84..b190d98be31 100644 --- a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet +++ b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet @@ -53,7 +53,7 @@ fun f() : Int.() -> Unit = {} fun main1() { 1.{Int.() -> 1}(); - {1}() + {1}(); {(x : Int) -> x}(1) 1.{Int.(x : Int) -> x}(1) @l{1}() @@ -71,11 +71,11 @@ fun main1() { } fun test() { - {(x : Int) -> 1}<!NO_VALUE_FOR_PARAMETER!>()<!> + {(x : Int) -> 1}<!NO_VALUE_FOR_PARAMETER!>()<!>; <!MISSING_RECEIVER!>{Int.() -> 1}<!>() <!TYPE_MISMATCH!>"sd"<!>.{Int.() -> 1}() val i : Int? = null - i<!UNSAFE_CALL!>.<!>{Int.() -> 1}() + i<!UNSAFE_CALL!>.<!>{Int.() -> 1}(); {}<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>() 1<!UNNECESSARY_SAFE_CALL!>?.<!>{Int.() -> 1}() 1.<!NO_RECEIVER_ADMITTED!>{}<!>() diff --git a/compiler/testData/diagnostics/tests/regressions/kt306.jet b/compiler/testData/diagnostics/tests/regressions/kt306.jet index b78f2902f9d..cb4a4f182f5 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt306.jet +++ b/compiler/testData/diagnostics/tests/regressions/kt306.jet @@ -2,7 +2,7 @@ fun test() { {Foo.() -> - bar() + bar(); {Barr.() -> this.bar() bar() diff --git a/compiler/testData/psi/FunctionCalls.jet b/compiler/testData/psi/FunctionCalls.jet index 42161ea63ae..b3815710d1a 100644 --- a/compiler/testData/psi/FunctionCalls.jet +++ b/compiler/testData/psi/FunctionCalls.jet @@ -4,7 +4,7 @@ fun foo() { f<foo> (a) f {s} - f + f; {s} f { s @@ -12,14 +12,14 @@ fun foo() { f(a) { s } - f(a) + f(a); { s } f<a>(a) { s } - f<a>(a) + f<a>(a); { s } diff --git a/compiler/testData/psi/FunctionCalls.txt b/compiler/testData/psi/FunctionCalls.txt index 226682524cb..b008b1afe86 100644 --- a/compiler/testData/psi/FunctionCalls.txt +++ b/compiler/testData/psi/FunctionCalls.txt @@ -72,6 +72,7 @@ JetFile: FunctionCalls.jet PsiWhiteSpace('\n ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('f') + PsiElement(SEMICOLON)(';') PsiWhiteSpace('\n ') FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL @@ -124,6 +125,7 @@ JetFile: FunctionCalls.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') + PsiElement(SEMICOLON)(';') PsiWhiteSpace('\n ') FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL @@ -180,6 +182,7 @@ JetFile: FunctionCalls.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') + PsiElement(SEMICOLON)(';') PsiWhiteSpace('\n ') FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL diff --git a/compiler/testData/readClass/class/ClassInnerClass.kt b/compiler/testData/readClass/class/ClassInnerClass.kt new file mode 100644 index 00000000000..8cb974151c7 --- /dev/null +++ b/compiler/testData/readClass/class/ClassInnerClass.kt @@ -0,0 +1,6 @@ +package test + +class Outer { + class Inner { + } +} diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 22af0adfb4f..3740d7df4f8 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -15,7 +15,19 @@ import org.jetbrains.jet.codegen.PropertyCodegen; import org.jetbrains.jet.compiler.CompileEnvironment; import org.jetbrains.jet.compiler.JetCoreEnvironment; import org.jetbrains.jet.lang.JetSemanticServices; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -30,9 +42,17 @@ import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.plugin.JetLanguage; import org.junit.Assert; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; import java.io.File; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * @author Stepan Koltsov @@ -162,8 +182,8 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { StringBuilder sba = new StringBuilder(); StringBuilder sbb = new StringBuilder(); - new Serializer(sba).serializeContent((ClassDescriptor) a); - new Serializer(sbb).serializeContent((ClassDescriptor) b); + new FullContentSerialier(sba).serialize((ClassDescriptor) a); + new FullContentSerialier(sbb).serialize((ClassDescriptor) b); String as = sba.toString(); String bs = sbb.toString(); @@ -196,70 +216,6 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { this.sb = sb; } - private String serializeContent(ClassDescriptor klass) { - - serialize(klass.getModality()); - sb.append(" "); - - serialize(klass.getKind()); - sb.append(" "); - - serialize(klass); - - if (!klass.getTypeConstructor().getParameters().isEmpty()) { - sb.append("<"); - serializeCommaSeparated(klass.getTypeConstructor().getParameters()); - sb.append(">"); - } - - // TODO: supers - // TODO: constructors - - sb.append(" {\n"); - - List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(); - for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) { - typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType())); - } - - List<String> memberStrings = new ArrayList<String>(); - - for (ConstructorDescriptor constructor : klass.getConstructors()) { - StringBuilder constructorSb = new StringBuilder(); - new Serializer(constructorSb).serialize(constructor); - memberStrings.add(constructorSb.toString()); - } - - JetScope memberScope = klass.getMemberScope(typeArguments); - for (DeclarationDescriptor member : memberScope.getAllDescriptors()) { - // TODO - if (member.getName().equals("equals") || member.getName().equals("hashCode") - || member.getName().equals("wait") || member.getName().equals("notify") || member.getName().equals("notifyAll") - || member.getName().equals("toString") || member.getName().equals("getClass") - || member.getName().equals("clone") || member.getName().equals("finalize") - || member.getName().equals("getTypeInfo") || member.getName().equals("$setTypeInfo") || member.getName().equals("$typeInfo") - || member.getName().equals("getOuterObject") - ) - { - continue; - } - StringBuilder memberSb = new StringBuilder(); - new Serializer(memberSb).serialize(member); - memberStrings.add(memberSb.toString()); - } - - Collections.sort(memberStrings); - - for (String memberString : memberStrings) { - sb.append(" "); - sb.append(memberString); - sb.append("\n"); - } - - sb.append("}\n"); - return sb.toString(); - } - public void serialize(ClassKind kind) { switch (kind) { case CLASS: @@ -293,12 +249,12 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { sb.append("fun "); if (!fun.getTypeParameters().isEmpty()) { sb.append("<"); - serializeCommaSeparated(fun.getTypeParameters()); + new Serializer(sb).serializeCommaSeparated(fun.getTypeParameters()); sb.append(">"); } if (fun.getReceiverParameter().exists()) { - serialize(fun.getReceiverParameter()); + new Serializer(sb).serialize(fun.getReceiverParameter()); sb.append("."); } @@ -306,7 +262,7 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { sb.append("("); new ValueParameterSerializer(sb).serializeCommaSeparated(fun.getValueParameters()); sb.append("): "); - serialize(fun.getReturnType()); + new Serializer(sb).serialize(fun.getReturnType()); } public void serialize(ExtensionReceiver extensionReceiver) { @@ -320,12 +276,12 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { sb.append("val "); } if (prop.getReceiverParameter().exists()) { - serialize(prop.getReceiverParameter().getType()); + new Serializer(sb).serialize(prop.getReceiverParameter().getType()); sb.append("."); } sb.append(prop.getName()); sb.append(": "); - serialize(prop.getOutType()); + new Serializer(sb).serialize(prop.getOutType()); } public void serialize(ValueParameterDescriptor valueParameter) { @@ -493,7 +449,82 @@ public class ReadClassDataTest extends TestCaseWithTmpdir { sb.append(param.getName()); } } - + + private static class FullContentSerialier extends Serializer { + private FullContentSerialier(StringBuilder sb) { + super(sb); + } + + public void serialize(ClassDescriptor klass) { + + serialize(klass.getModality()); + sb.append(" "); + + serialize(klass.getKind()); + sb.append(" "); + + new Serializer(sb).serialize(klass); + + if (!klass.getTypeConstructor().getParameters().isEmpty()) { + sb.append("<"); + serializeCommaSeparated(klass.getTypeConstructor().getParameters()); + sb.append(">"); + } + + // TODO: supers + // TODO: constructors + + sb.append(" {\n"); + + List<TypeProjection> typeArguments = new ArrayList<TypeProjection>(); + for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) { + typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType())); + } + + List<String> memberStrings = new ArrayList<String>(); + + for (ConstructorDescriptor constructor : klass.getConstructors()) { + StringBuilder constructorSb = new StringBuilder(); + new Serializer(constructorSb).serialize(constructor); + memberStrings.add(constructorSb.toString()); + } + + JetScope memberScope = klass.getMemberScope(typeArguments); + for (DeclarationDescriptor member : memberScope.getAllDescriptors()) { + StringBuilder memberSb = new StringBuilder(); + new FullContentSerialier(memberSb).serialize(member); + memberStrings.add(memberSb.toString()); + } + + Collections.sort(memberStrings); + + for (String memberString : memberStrings) { + sb.append(indent(memberString)); + } + + sb.append("}\n"); + } + } + + + private static String indent(String string) { + try { + StringBuilder r = new StringBuilder(); + BufferedReader reader = new BufferedReader(new StringReader(string)); + for (;;) { + String line = reader.readLine(); + if (line == null) { + break; + } + r.append(" "); + r.append(line); + r.append("\n"); + } + return r.toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } public static Test suite() { return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readClass", true, new JetTestCaseBuilder.NamedTestFactory() { diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java index 31bba9535be..da1222b561c 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.compiler; -import jet.modules.IModuleBuilder; -import jet.modules.IModuleSetBuilder; +import jet.modules.Module; import junit.framework.TestCase; import org.jetbrains.jet.cli.KotlinCompiler; import org.jetbrains.jet.codegen.ClassFileFactory; @@ -37,9 +36,9 @@ public class CompileEnvironmentTest extends TestCase { environment.setJavaRuntime(activeRtJar); environment.initializeKotlinRuntime(); final String testDataDir = JetParsingTest.getTestDataDir() + "/compiler/smoke/"; - final IModuleSetBuilder setBuilder = environment.loadModuleScript(testDataDir + "Smoke.kts"); - assertEquals(1, setBuilder.getModules().size()); - final IModuleBuilder moduleBuilder = setBuilder.getModules().get(0); + final List<Module> modules = environment.loadModuleScript(testDataDir + "Smoke.kts"); + assertEquals(1, modules.size()); + final Module moduleBuilder = modules.get(0); final ClassFileFactory factory = environment.compileModule(moduleBuilder, testDataDir); assertNotNull(factory); assertNotNull(factory.asBytes("Smoke/namespace.class")); @@ -51,7 +50,7 @@ public class CompileEnvironmentTest extends TestCase { assertTrue(entries.contains("Smoke/namespace.class")); } - public void _testSmokeWithCompilerJar() throws IOException { + public void testSmokeWithCompilerJar() throws IOException { File tempFile = File.createTempFile("compilerTest", "compilerTest"); try { KotlinCompiler.main(Arrays.asList("-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts", "-jar", tempFile.getAbsolutePath()).toArray(new String[0])); diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 2423f13e90e..826947e6808 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -50,11 +50,16 @@ <lang.formatter language="jet" implementationClass="org.jetbrains.jet.plugin.formatter.JetFormattingModelBuilder"/> <lang.findUsagesProvider language="jet" implementationClass="org.jetbrains.jet.plugin.findUsages.JetFindUsagesProvider"/> <psi.referenceContributor language="jet" implementation="org.jetbrains.jet.plugin.references.JetReferenceContributor"/> + + <completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.GlobalMemberCompletionContributor"/> <completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/> + <completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/> + <annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.SoftKeywordsAnnotator"/> <annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.LabelsAnnotator"/> <annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.JetPsiChecker"/> <annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.DebugInfoAnnotator"/> + <documentationProvider implementation="org.jetbrains.jet.plugin.JetQuickDocumentationProvider"/> <configurationType implementation="org.jetbrains.jet.plugin.run.JetRunConfigurationType"/> <configurationProducer implementation="org.jetbrains.jet.plugin.run.JetRunConfigurationProducer"/> @@ -66,8 +71,8 @@ <codeInsight.implementMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.ImplementMethodsHandler"/> <codeInsight.overrideMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.OverrideMethodsHandler"/> - <java.elementFinder implementation="org.jetbrains.jet.asJava.JavaElementFinder"/> + <psi.treeChangePreprocessor implementation="org.jetbrains.jet.asJava.JetCodeBlockModificationListener"/> <toolWindow id="CodeWindow" diff --git a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java index e78bacac3ce..66314049b0f 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java @@ -6,7 +6,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; @@ -65,7 +64,7 @@ public class JetPluginUtil { JetScope libraryScope = standardLibrary.getLibraryScope(); DeclarationDescriptor declaration = type.getMemberScope().getContainingDeclaration(); - if (declaration instanceof JavaClassDescriptor || ErrorUtils.isError(declaration)) { + if (ErrorUtils.isError(declaration)) { return false; } while (!(declaration instanceof NamespaceDescriptor)) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java new file mode 100644 index 00000000000..edc38ff6d3c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.plugin.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; + +/** + * @author Nikolay Krasko + */ +public class GlobalMemberCompletionContributor extends CompletionContributor { + public GlobalMemberCompletionContributor() { + extend(CompletionType.CLASS_NAME, PlatformPatterns.psiElement(), + new CompletionProvider<CompletionParameters>() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, + @NotNull CompletionResultSet result) { + if (result.getPrefixMatcher().getPrefix().isEmpty()) { + return; + } + + final PsiElement position = parameters.getPosition(); + if (!(position.getContainingFile() instanceof JetFile)) { + return; + } + +// final PsiElement parent = position.getParent(); +// if (parent.getReference() instanceof JetSimpleName) + + return; + } + }); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java new file mode 100644 index 00000000000..9be048cc95a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -0,0 +1,75 @@ +package org.jetbrains.jet.plugin.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiElement; +import com.intellij.util.Consumer; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; + +/** + * @author Nikolay Krasko + */ +public class JetCompletionContributor extends CompletionContributor { + public JetCompletionContributor() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement(), + new CompletionProvider<CompletionParameters>() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, + final @NotNull CompletionResultSet _result) { + + if (_result.getPrefixMatcher().getPrefix().isEmpty()) { + return; + } + + final PsiElement position = parameters.getPosition(); + if (!(position.getContainingFile() instanceof JetFile)) { + return; + } + + CompletionResultSet result = _result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); + JavaClassNameCompletionContributor.addAllClasses(parameters, JavaCompletionSorting.addJavaSorting( + parameters, result), parameters.getInvocationCount() <= 1, new Consumer<LookupElement>() { + @Override + public void consume(LookupElement element) { + _result.addElement(element); + } + }); + } + }); + } + +// @Override +// public void beforeCompletion(@NotNull CompletionInitializationContext context) { +// final PsiFile file = context.getFile(); +// +// if (file instanceof JetFile) { +// autoImport(file, context.getStartOffset() - 1, context.getEditor()); +// } +// } +// +// private static void autoImport(final PsiFile file, int offset, final Editor editor) { +// final CharSequence text = editor.getDocument().getCharsSequence(); +// while (offset > 0 && Character.isJavaIdentifierPart(text.charAt(offset))) offset--; +// if (offset <= 0) return; +// +// while (offset > 0 && Character.isWhitespace(text.charAt(offset))) offset--; +// if (offset <= 0 || text.charAt(offset) != '.') return; +// +// offset--; +// +// while (offset > 0 && Character.isWhitespace(text.charAt(offset))) offset--; +// if (offset <= 0) return; +// +// final JetSimpleNameExpression nameExpression = +// PsiTreeUtil.findElementOfClassAtOffset(file, offset, JetSimpleNameExpression.class, false); +// if (nameExpression == null) return; +// +// final ImportClassFix importClassFix = new ImportClassFix(nameExpression); +// if (importClassFix.isAvailable(file.getProject(), editor, file)) { +// new ImportClassFix(nameExpression).invoke(file.getProject(), editor, file); +// } +// } +} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java index 0fbf10a8364..af001ad3809 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java @@ -118,7 +118,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor { @Override public boolean isAcceptable(Object element, PsiElement context) { //noinspection unchecked - return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true, JetBlockExpression.class) != null; + return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true, + JetBlockExpression.class, JetProperty.class) != null; } @Override diff --git a/idea/testData/completion/keywords/AfterClassProperty.kt b/idea/testData/completion/keywords/AfterClassProperty.kt new file mode 100644 index 00000000000..0b0fe0c590d --- /dev/null +++ b/idea/testData/completion/keywords/AfterClassProperty.kt @@ -0,0 +1,7 @@ +class MouseMovedEventArgs +{ + public val X : int = 0 + in<caret> +} + +// EXIST: internal \ No newline at end of file diff --git a/idea/testData/completion/keywords/InClassProperty.kt b/idea/testData/completion/keywords/InClassProperty.kt new file mode 100644 index 00000000000..8647c7d465e --- /dev/null +++ b/idea/testData/completion/keywords/InClassProperty.kt @@ -0,0 +1,6 @@ +class MouseMovedEventArgs +{ + public val X : int<caret> = 0 +} + +// ABSENT: internal \ No newline at end of file diff --git a/stdlib/ktSrc/modules/ModuleBuilder.kt b/stdlib/ktSrc/modules/ModuleBuilder.kt index 39097b7d818..487ef408f20 100644 --- a/stdlib/ktSrc/modules/ModuleBuilder.kt +++ b/stdlib/ktSrc/modules/ModuleBuilder.kt @@ -3,57 +3,35 @@ package kotlin.modules import java.util.* import jet.modules.* -fun moduleSet(description: ModuleSetBuilder.() -> Unit) = description - -fun module(name: String, description: ModuleBuilder.() -> Unit) = moduleSet { - module(name, description) -} - -class ModuleSetBuilder(): IModuleSetBuilder { - private val modules = ArrayList<IModuleBuilder?>() - - fun module(name: String, callback: ModuleBuilder.() -> Unit) { - val builder = ModuleBuilder(name) - builder.callback() - modules.add(builder) - } - - override fun getModules(): List<IModuleBuilder?>? = modules +fun module(name: String, callback: ModuleBuilder.() -> Unit) { + val builder = ModuleBuilder(name) + builder.callback() + AllModules.modules?.add(builder) } class SourcesBuilder(val parent: ModuleBuilder) { - fun files(pattern: String) { + fun plusAssign(pattern: String) { parent.addSourceFiles(pattern) } } class ClasspathBuilder(val parent: ModuleBuilder) { - fun entry(name: String) { + fun plusAssign(name: String) { parent.addClasspathEntry(name) } } -class JarBuilder(val parent: ModuleBuilder) { - fun name(jarName: String) { - parent.setJarName(jarName) - } -} - -open class ModuleBuilder(val name: String): IModuleBuilder { +open class ModuleBuilder(val name: String): Module { // http://youtrack.jetbrains.net/issue/KT-904 private val sourceFiles0: ArrayList<String?> = ArrayList<String?>() private val classpathRoots0: ArrayList<String?> = ArrayList<String?>() - var _jarName: String? = null - val source: SourcesBuilder + val sources: SourcesBuilder get() = SourcesBuilder(this) val classpath: ClasspathBuilder get() = ClasspathBuilder(this) - val jar: JarBuilder - get() = JarBuilder(this) - fun addSourceFiles(pattern: String) { sourceFiles0.add(pattern) } @@ -62,19 +40,8 @@ open class ModuleBuilder(val name: String): IModuleBuilder { classpathRoots0.add(name) } - fun setJarName(name: String) { - _jarName = name - } - override fun getSourceFiles(): List<String?>? = sourceFiles0 override fun getClasspathRoots(): List<String?>? = classpathRoots0 override fun getModuleName(): String? = name - override fun getJarName(): String? = _jarName - -} - -class ModuleBuilder2(name: String): ModuleBuilder(name) { - - } diff --git a/stdlib/src/jet/modules/AllModules.java b/stdlib/src/jet/modules/AllModules.java new file mode 100644 index 00000000000..52a4595b8ca --- /dev/null +++ b/stdlib/src/jet/modules/AllModules.java @@ -0,0 +1,10 @@ +/* + * @author max + */ +package jet.modules; + +import java.util.ArrayList; + +public class AllModules { + public static final ArrayList<Module> modules = new ArrayList<Module>(); +} diff --git a/stdlib/src/jet/modules/IModuleSetBuilder.java b/stdlib/src/jet/modules/IModuleSetBuilder.java deleted file mode 100644 index 7f5f03dc3d2..00000000000 --- a/stdlib/src/jet/modules/IModuleSetBuilder.java +++ /dev/null @@ -1,10 +0,0 @@ -package jet.modules; - -import java.util.List; - -/** - * @author yole - */ -public interface IModuleSetBuilder { - List<IModuleBuilder> getModules(); -} diff --git a/stdlib/src/jet/modules/IModuleBuilder.java b/stdlib/src/jet/modules/Module.java similarity index 74% rename from stdlib/src/jet/modules/IModuleBuilder.java rename to stdlib/src/jet/modules/Module.java index f455eb5fabc..649ffb25174 100644 --- a/stdlib/src/jet/modules/IModuleBuilder.java +++ b/stdlib/src/jet/modules/Module.java @@ -5,9 +5,8 @@ import java.util.List; /** * @author yole */ -public interface IModuleBuilder { +public interface Module { String getModuleName(); List<String> getSourceFiles(); List<String> getClasspathRoots(); - String getJarName(); } diff --git a/stdlib/src/jet/runtime/typeinfo/JetMethod.java b/stdlib/src/jet/runtime/typeinfo/JetMethod.java index 47d4c9bf07a..29059a9caad 100644 --- a/stdlib/src/jet/runtime/typeinfo/JetMethod.java +++ b/stdlib/src/jet/runtime/typeinfo/JetMethod.java @@ -17,6 +17,11 @@ import java.lang.annotation.Target; @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface JetMethod { + int KIND_REGULAR = 0; + int KIND_PROPERTY = 1; + + int kind() default KIND_REGULAR; + /** * @return type projections or empty */ @@ -37,4 +42,10 @@ public @interface JetMethod { * Return type type unless java type is correct Kotlin type. */ String returnType () default ""; + + /** + * If this is property. + * @return + */ + String propertyType() default ""; } diff --git a/stdlib/src/jet/runtime/typeinfo/JetProperty.java b/stdlib/src/jet/runtime/typeinfo/JetProperty.java deleted file mode 100644 index 2344ebe1fc4..00000000000 --- a/stdlib/src/jet/runtime/typeinfo/JetProperty.java +++ /dev/null @@ -1,17 +0,0 @@ -package jet.runtime.typeinfo; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Stepan Koltsov - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface JetProperty { - String type() default ""; - - String typeParameters() default ""; -}