diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index c1e9900dd87..97ab2f79a53 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -53,7 +53,6 @@ import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.JvmAbi; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor; import org.jetbrains.jet.lang.resolve.name.Name; @@ -1327,10 +1326,9 @@ public class ExpressionCodegen extends JetVisitor implem assert constructorDescriptor != null; CallableMethod constructor = typeMapper.mapToCallableMethod(constructorDescriptor, closure); - JvmClassName name = bindingContext.get(FQN, constructorDescriptor.getContainingDeclaration()); - assert name != null; + Type type = bindingContext.get(ASM_TYPE, constructorDescriptor.getContainingDeclaration()); + assert type != null; - Type type = name.getAsmType(); v.anew(type); v.dup(); Method cons = constructor.getSignature().getAsmMethod(); @@ -1352,7 +1350,7 @@ public class ExpressionCodegen extends JetVisitor implem pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes)); } - v.invokespecial(name.getInternalName(), "", cons.getDescriptor()); + v.invokespecial(type.getInternalName(), "", cons.getDescriptor()); return StackValue.onStack(type); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java index 1ce43f2907a..93933e61cf6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinCodegenFacade.java @@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetScript; import org.jetbrains.jet.lang.resolve.ScriptNameUtil; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import java.util.Collection; @@ -45,7 +44,7 @@ public class KotlinCodegenFacade { String name = ScriptNameUtil.classNameForScript(file); JetScript script = file.getScript(); assert script != null; - registerClassNameForScript(state.getBindingTrace(), script, JvmClassName.byInternalName(name)); + registerClassNameForScript(state.getBindingTrace(), script, Type.getObjectType(name)); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index c599d0c514d..6e8c015c711 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -34,7 +34,6 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import javax.inject.Inject; import java.util.Collections; @@ -69,18 +68,16 @@ public class ScriptCodegen extends MemberCodegen { ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor); assert classDescriptorForScript != null; - ScriptContext context = - (ScriptContext) CodegenContext.STATIC - .intoScript(scriptDescriptor, classDescriptorForScript); + ScriptContext context = (ScriptContext) CodegenContext.STATIC.intoScript(scriptDescriptor, classDescriptorForScript); - JvmClassName className = bindingContext.get(FQN, classDescriptorForScript); - assert className != null; + Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript); + assert classType != null; - ClassBuilder classBuilder = classFileFactory.newVisitor(className.getAsmType(), scriptDeclaration.getContainingFile()); + ClassBuilder classBuilder = classFileFactory.newVisitor(classType, scriptDeclaration.getContainingFile()); classBuilder.defineClass(scriptDeclaration, V1_6, ACC_PUBLIC, - className.getInternalName(), + classType.getInternalName(), null, "java/lang/Object", new String[0]); @@ -120,13 +117,13 @@ public class ScriptCodegen extends MemberCodegen { InstructionAdapter instructionAdapter = new InstructionAdapter(mv); - JvmClassName className = bindingContext.get(FQN, classDescriptorForScript); - assert className != null; + Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript); + assert classType != null; - instructionAdapter.load(0, className.getAsmType()); + instructionAdapter.load(0, classType); instructionAdapter.invokespecial("java/lang/Object", "", "()V"); - instructionAdapter.load(0, className.getAsmType()); + instructionAdapter.load(0, classType); FrameMap frameMap = context.prepareFrame(typeMapper); @@ -152,25 +149,25 @@ public class ScriptCodegen extends MemberCodegen { for (ScriptDescriptor earlierScript : importedScripts) { Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript); - instructionAdapter.load(0, className.getAsmType()); + instructionAdapter.load(0, classType); instructionAdapter.load(offset, earlierClassType); offset += earlierClassType.getSize(); - instructionAdapter.putfield(className.getInternalName(), getScriptFieldName(earlierScript), earlierClassType.getDescriptor()); + instructionAdapter.putfield(classType.getInternalName(), getScriptFieldName(earlierScript), earlierClassType.getDescriptor()); } for (ValueParameterDescriptor parameter : scriptDescriptor.getValueParameters()) { Type parameterType = typeMapper.mapType(parameter.getType()); - instructionAdapter.load(0, className.getAsmType()); + instructionAdapter.load(0, classType); instructionAdapter.load(offset, parameterType); offset += parameterType.getSize(); - instructionAdapter.putfield(className.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor()); + instructionAdapter.putfield(classType.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor()); } StackValue stackValue = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression()); if (stackValue.type != Type.VOID_TYPE) { stackValue.put(stackValue.type, instructionAdapter); - instructionAdapter.putfield(className.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, + instructionAdapter.putfield(classType.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor()); } @@ -204,8 +201,7 @@ public class ScriptCodegen extends MemberCodegen { ScriptDescriptor earlierDescriptor = t.first; Type earlierClassName = t.second; - registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, - JvmClassName.byInternalName(earlierClassName.getInternalName())); + registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassName); } List earlierScriptDescriptors = Lists.newArrayList(); @@ -243,7 +239,7 @@ public class ScriptCodegen extends MemberCodegen { @NotNull CompilationErrorHandler errorHandler ) { registerEarlierScripts(earlierScripts); - registerClassNameForScript(state.getBindingTrace(), script, JvmClassName.byInternalName(classType.getInternalName())); + registerClassNameForScript(state.getBindingTrace(), script, classType); state.beforeCompile(); KotlinCodegenFacade.generateNamespace( diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index 3ecfdef2cad..2079b7261d9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -22,6 +22,7 @@ import com.intellij.psi.tree.TokenSet; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.SamCodegenUtil; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -153,9 +154,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { super.visitEnumEntry(enumEntry); } else { - JvmClassName jvmClassName = bindingTrace.get(FQN, peekFromStack(classStack)); - assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, jvmClassName); - bindingTrace.record(FQN, descriptor, jvmClassName); + Type asmType = bindingTrace.get(ASM_TYPE, peekFromStack(classStack)); + assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, asmType); + bindingTrace.record(ASM_TYPE, descriptor, asmType); } } @@ -231,7 +232,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { classStack.push(classDescriptor); //noinspection ConstantConditions - nameStack.push(bindingContext.get(FQN, classDescriptor).getInternalName()); + nameStack.push(bindingContext.get(ASM_TYPE, classDescriptor).getInternalName()); super.visitObjectLiteralExpression(expression); nameStack.pop(); classStack.pop(); @@ -286,7 +287,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { boolean functionLiteral ) { CodegenBinding.recordClosure(bindingTrace, element, classDescriptor, peekFromStack(classStack), - JvmClassName.byInternalName(name), functionLiteral); + Type.getObjectType(name), functionLiteral); } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java index e0a840c9d66..a6040d03aa3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java @@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.java.JvmAbi; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -52,7 +51,7 @@ public class CodegenBinding { public static final WritableSlice CLASS_FOR_SCRIPT = Slices.createSimpleSlice(); - public static final WritableSlice FQN = Slices.createSimpleSlice(); + public static final WritableSlice ASM_TYPE = Slices.createSimpleSlice(); public static final WritableSlice ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice(); @@ -82,7 +81,7 @@ public class CodegenBinding { public static Type asmTypeForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) { ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor); //noinspection ConstantConditions - return fqn(bindingContext, classDescriptor); + return asmType(bindingContext, classDescriptor); } @NotNull @@ -109,9 +108,9 @@ public class CodegenBinding { } @NotNull - private static Type fqn(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor descriptor) { + private static Type asmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor descriptor) { //noinspection ConstantConditions - return bindingContext.get(FQN, descriptor).getAsmType(); + return bindingContext.get(ASM_TYPE, descriptor); } @NotNull @@ -128,25 +127,25 @@ public class CodegenBinding { return asmTypeForAnonymousClass(bindingContext, functionDescriptor); } - return fqn(bindingContext, descriptor); + return asmType(bindingContext, descriptor); } @NotNull public static Type asmTypeForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull FunctionDescriptor descriptor) { ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, descriptor); - return fqn(bindingContext, classDescriptor); + return asmType(bindingContext, classDescriptor); } public static void registerClassNameForScript( BindingTrace bindingTrace, @NotNull ScriptDescriptor scriptDescriptor, - @NotNull JvmClassName className + @NotNull Type asmType ) { ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl( scriptDescriptor, Collections.emptyList(), Modality.FINAL, - Name.special("")); + Name.special("")); classDescriptor.initialize( false, Collections.emptyList(), @@ -156,7 +155,7 @@ public class CodegenBinding { null, false); - recordClosure(bindingTrace, null, classDescriptor, null, className, false); + recordClosure(bindingTrace, null, classDescriptor, null, asmType, false); bindingTrace.record(CLASS_FOR_SCRIPT, scriptDescriptor, classDescriptor); } @@ -200,7 +199,7 @@ public class CodegenBinding { @Nullable JetElement element, ClassDescriptor classDescriptor, @Nullable ClassDescriptor enclosing, - JvmClassName name, + Type asmType, boolean functionLiteral ) { JetDelegatorToSuperCall superCall = findSuperCall(bindingTrace.getBindingContext(), element); @@ -219,8 +218,8 @@ public class CodegenBinding { MutableClosure closure = new MutableClosure(superCall, enclosing, enclosingReceiver); - assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, classDescriptor, name); - bindingTrace.record(FQN, classDescriptor, name); + assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, classDescriptor, asmType); + bindingTrace.record(ASM_TYPE, classDescriptor, asmType); bindingTrace.record(CLOSURE, classDescriptor, closure); // TODO: this is temporary before we have proper inner classes @@ -249,13 +248,13 @@ public class CodegenBinding { public static void registerClassNameForScript( BindingTrace bindingTrace, @NotNull JetScript jetScript, - @NotNull JvmClassName className + @NotNull Type asmType ) { ScriptDescriptor descriptor = bindingTrace.getBindingContext().get(SCRIPT, jetScript); if (descriptor == null) { throw new IllegalStateException("Descriptor is not found for PSI " + jetScript); } - registerClassNameForScript(bindingTrace, descriptor, className); + registerClassNameForScript(bindingTrace, descriptor, asmType); } @NotNull @@ -324,22 +323,22 @@ public class CodegenBinding { } @NotNull - public static JvmClassName getJvmInternalName(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) { + public static Type getAsmType(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) { descriptor = descriptor.getOriginal(); - JvmClassName alreadyComputedName = bindingTrace.getBindingContext().get(FQN, descriptor); - if (alreadyComputedName != null) { - return alreadyComputedName; + Type alreadyComputedType = bindingTrace.getBindingContext().get(ASM_TYPE, descriptor); + if (alreadyComputedType != null) { + return alreadyComputedType; } - JvmClassName name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor)); + Type asmType = Type.getObjectType(getAsmTypeImpl(bindingTrace, descriptor)); - assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, name); - bindingTrace.record(FQN, descriptor, name); - return name; + assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, asmType); + bindingTrace.record(ASM_TYPE, descriptor, asmType); + return asmType; } @NotNull - private static String getJvmInternalFQNameImpl(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) { + private static String getAsmTypeImpl(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof FunctionDescriptor) { throw new IllegalStateException("requested fq name for function: " + descriptor); } @@ -357,7 +356,7 @@ public class CodegenBinding { return descriptor.getName().getIdentifier(); } - String containerInternalName = getJvmInternalName(bindingTrace, container).getInternalName(); + String containerInternalName = getAsmType(bindingTrace, container).getInternalName(); if (descriptor instanceof ClassDescriptor && container instanceof ClassDescriptor) { ClassDescriptor klass = (ClassDescriptor) descriptor; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java index 0d64a33154a..b91bcc78fd4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.NamespaceCodegen; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; @@ -30,7 +31,6 @@ import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; -import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.util.slicedmap.WritableSlice; @@ -38,18 +38,19 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice; import java.util.Collection; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; +import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName; public final class PsiCodegenPredictor { private PsiCodegenPredictor() { } public static boolean checkPredictedNameFromPsi( - @NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor, JvmClassName nameFromDescriptors + @NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor, @Nullable Type nameFromDescriptors ) { PsiElement element = descriptorToDeclaration(bindingTrace.getBindingContext(), descriptor); if (element instanceof JetDeclaration) { - JvmClassName classNameFromPsi = getPredefinedJvmClassName((JetDeclaration) element); - assert classNameFromPsi == null || classNameFromPsi.equals(nameFromDescriptors) : + String classNameFromPsi = getPredefinedJvmInternalName((JetDeclaration) element); + assert classNameFromPsi == null || Type.getObjectType(classNameFromPsi).equals(nameFromDescriptors) : String.format("Invalid algorithm for getting qualified name from psi! Predicted: %s, actual %s\n" + "Element: %s", classNameFromPsi, nameFromDescriptors, element.getText()); } @@ -57,97 +58,79 @@ public final class PsiCodegenPredictor { return true; } - @Nullable - public static JvmClassName getPredefinedJvmClassName(@NotNull JetFile jetFile, boolean withNamespace) { - String packageName = jetFile.getPackageName(); - if (packageName == null) { - return null; - } - - JvmClassName packageJvmName = JvmClassName.byFqNameWithoutInnerClasses(packageName); - return !withNamespace ? packageJvmName : addPackageClass(packageJvmName); - } - /** * TODO: Finish this method for all cases. Now it's only used and tested in JetLightClass. * * @return null if no prediction can be done. */ @Nullable - public static JvmClassName getPredefinedJvmClassName(@NotNull JetDeclaration declaration) { + public static String getPredefinedJvmInternalName(@NotNull JetDeclaration declaration) { // TODO: Method won't work for declarations inside class objects // TODO: Method won't give correct class name for traits implementations JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(declaration, JetDeclaration.class); if (parentDeclaration instanceof JetClassObject) { assert declaration instanceof JetObjectDeclaration : "Only object declarations can be children of JetClassObject: " + declaration; - return getPredefinedJvmClassName(parentDeclaration); + return getPredefinedJvmInternalName(parentDeclaration); } - JvmClassName parentClassName = parentDeclaration != null ? - getPredefinedJvmClassName(parentDeclaration) : - getPredefinedJvmClassName((JetFile) declaration.getContainingFile(), false); - if (parentClassName == null) { - return null; + String parentInternalName; + if (parentDeclaration != null) { + parentInternalName = getPredefinedJvmInternalName(parentDeclaration); + if (parentInternalName == null) { + return null; + } + } + else { + String packageName = ((JetFile) declaration.getContainingFile()).getPackageName(); + if (packageName == null) { + return null; + } + parentInternalName = JvmClassName.byFqNameWithoutInnerClasses(packageName).getInternalName(); } if (declaration instanceof JetClassObject) { // Get parent and assign Class object prefix - return JvmClassName.byInternalName(parentClassName.getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX); + return parentInternalName + JvmAbi.CLASS_OBJECT_SUFFIX; } - if (declaration instanceof JetNamedDeclaration) { - if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) || - declaration instanceof JetEnumEntry) { - // Other subclasses are not valid for class name prediction. - // For example EnumEntry, JetFunctionLiteral - return null; - } - - JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) declaration; - Name name = namedDeclaration.getNameAsName(); - if (name == null) { - return null; - } - - FqName fqName = parentClassName.getFqName(); - - if (declaration instanceof JetNamedFunction) { - if (parentDeclaration == null) { - JvmClassName packageClass = addPackageClass(parentClassName); - return JvmClassName.byInternalName(packageClass.getInternalName() + "$" + name.asString()); - } - - if (!(parentDeclaration instanceof JetClass || parentDeclaration instanceof JetObjectDeclaration)) { - // Can't generate predefined name for internal functions - return null; - } - } - - // NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not - // namespace$propertyName$ClassName - if (declaration instanceof JetProperty) { - return JvmClassName.byInternalName(parentClassName.getInternalName() + "$" + name.asString()); - } - - if (fqName.isRoot()) { - return JvmClassName.byInternalName(name.asString()); - } - - return JvmClassName.byInternalName(parentDeclaration == null ? - parentClassName.getInternalName() + "/" + name.asString() : - parentClassName.getInternalName() + "$" + name.asString()); + if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) || + declaration instanceof JetEnumEntry) { + // Other subclasses are not valid for class name prediction. + // For example EnumEntry, JetFunctionLiteral + return null; } - return null; - } + JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) declaration; + Name name = namedDeclaration.getNameAsName(); + if (name == null) { + return null; + } - private static JvmClassName addPackageClass(JvmClassName packageName) { - FqName name = packageName.getFqName(); - String packageClassName = PackageClassUtils.getPackageClassName(name); - return name.isRoot() ? - JvmClassName.byFqNameWithoutInnerClasses(packageClassName) : - JvmClassName.byInternalName(packageName.getInternalName() + "/" + packageClassName); + if (declaration instanceof JetNamedFunction) { + if (parentDeclaration == null) { + FqName fqName = JvmClassName.byInternalName(parentInternalName).getFqName(); + JvmClassName packageClass = JvmClassName.byFqNameWithoutInnerClasses(getPackageClassFqName(fqName)); + return packageClass.getInternalName() + "$" + name.asString(); + } + + if (!(parentDeclaration instanceof JetClass || parentDeclaration instanceof JetObjectDeclaration)) { + // Can't generate predefined name for internal functions + return null; + } + } + + // NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not + // namespace$propertyName$ClassName + if (declaration instanceof JetProperty) { + return parentInternalName + "$" + name.asString(); + } + + if (parentInternalName.isEmpty()) { + return name.asString(); + } + + return parentInternalName + (parentDeclaration == null ? "/" : "$") + name.asString(); } @Nullable @@ -166,7 +149,7 @@ public final class PsiCodegenPredictor { public static JetFile getFileForCodegenNamedClass( @NotNull BindingContext context, @NotNull Collection allNamespaceFiles, - @NotNull final JvmClassName className + @NotNull final String classInternalName ) { final Ref resultingDescriptor = Ref.create(); @@ -174,8 +157,8 @@ public final class PsiCodegenPredictor { @Override public void record(WritableSlice slice, K key, V value) { super.record(slice, key, value); - if (slice == CodegenBinding.FQN && key instanceof DeclarationDescriptor) { - if (className.equals(value)) { + if (slice == CodegenBinding.ASM_TYPE && key instanceof DeclarationDescriptor && value instanceof Type) { + if (classInternalName.equals(((Type) value).getInternalName())) { resultingDescriptor.set((DeclarationDescriptor) key); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index 8d47e7f9c3f..57bbc35d9c3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -29,7 +29,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import java.util.Collections; import java.util.HashMap; @@ -278,7 +277,7 @@ public abstract class CodegenContext { ClassDescriptor enclosingClass = getEnclosingClass(); outerExpression = enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor) ? StackValue.field(typeMapper.mapType(enclosingClass), - CodegenBinding.getJvmInternalName(typeMapper.getBindingTrace(), classDescriptor).getAsmType(), + CodegenBinding.getAsmType(typeMapper.getBindingTrace(), classDescriptor), CAPTURED_THIS_FIELD, false) : null; @@ -295,8 +294,7 @@ public abstract class CodegenContext { for (LocalLookup.LocalLookupCase aCase : LocalLookup.LocalLookupCase.values()) { if (aCase.isCase(d, state)) { - JvmClassName className = state.getBindingContext().get(FQN, getThisDescriptor()); - Type classType = className == null ? null : className.getAsmType(); + Type classType = state.getBindingContext().get(ASM_TYPE, getThisDescriptor()); StackValue innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType); if (innerValue == null) { break; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index 9ab6b431b60..4c0450cb628 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -334,13 +334,13 @@ public class JetTypeMapper extends BindingTraceAware { } if (descriptor instanceof ClassDescriptor) { - JvmClassName name = getJvmInternalName(bindingTrace, descriptor); + Type descriptorAsmType = getAsmType(bindingTrace, descriptor); Type asmType; if (kind == JetTypeMapperMode.TRAIT_IMPL) { - asmType = Type.getObjectType(name.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX); + asmType = Type.getObjectType(descriptorAsmType.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX); } else { - asmType = name.getAsmType(); + asmType = descriptorAsmType; } writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java index 452948c4650..9fac5ce2157 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java @@ -43,8 +43,8 @@ import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker; import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -66,10 +66,10 @@ public class KotlinLightClassForExplicitDeclaration extends AbstractLightClass i return null; } - JvmClassName jvmClassName = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject); - if (jvmClassName == null) return null; + String jvmInternalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject); + if (jvmInternalName == null) return null; - return new KotlinLightClassForExplicitDeclaration(manager, jvmClassName.getFqName(), classOrObject); + return new KotlinLightClassForExplicitDeclaration(manager, JvmClassName.byInternalName(jvmInternalName).getFqName(), classOrObject); } private final FqName classFqName; // FqName of (possibly inner) class diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index c4849a53cab..e706458d0c8 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -36,11 +36,10 @@ import com.intellij.util.PathUtil; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod; import org.jetbrains.jet.lang.resolve.java.JvmAbi; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; +import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.utils.ExceptionUtils; @@ -235,12 +234,11 @@ public class LightClassUtil { if (parent instanceof JetFile) { // top-level declaration - JvmClassName jvmName = PsiCodegenPredictor.getPredefinedJvmClassName((JetFile) parent, true); - if (jvmName != null) { + FqName fqName = getPackageClassNameForFile((JetFile) parent); + if (fqName != null) { Project project = declaration.getProject(); - String fqName = jvmName.getFqName().asString(); - return JavaElementFinder.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)); + return JavaElementFinder.getInstance(project).findClass(fqName.asString(), GlobalSearchScope.allScope(project)); } } else if (parent instanceof JetClassBody) { @@ -251,6 +249,12 @@ public class LightClassUtil { return null; } + @Nullable + private static FqName getPackageClassNameForFile(@NotNull JetFile jetFile) { + String packageName = jetFile.getPackageName(); + return packageName == null ? null : PackageClassUtils.getPackageClassFqName(new FqName(packageName)); + } + private static PropertyAccessorsPsiMethods extractPropertyAccessors( @NotNull JetDeclaration jetDeclaration, @Nullable PsiMethod specialGetter, @Nullable PsiMethod specialSetter diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java index d6f85fafa52..756cabfe6df 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java @@ -375,11 +375,11 @@ public class JetSourceNavigationHelper { @Nullable public static PsiClass getOriginalClass(@NotNull JetClassOrObject classOrObject) { // Copied from JavaPsiImplementationHelperImpl:getOriginalClass() - JvmClassName className = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject); - if (className == null) { + String internalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject); + if (internalName == null) { return null; } - String fqName = className.getFqName().asString(); + String fqName = JvmClassName.byInternalName(internalName).getFqName().asString(); JetFile file = (JetFile) classOrObject.getContainingFile(); diff --git a/idea/src/org/jetbrains/jet/plugin/util/DebuggerUtils.java b/idea/src/org/jetbrains/jet/plugin/util/DebuggerUtils.java index b090f2737a4..c3cb66bdf15 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/DebuggerUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/util/DebuggerUtils.java @@ -74,7 +74,7 @@ public class DebuggerUtils { // we may actually need to analyze the project in order to find a file which produces this class AnalyzeExhaust analyzeExhaust = AnalyzerFacadeWithCache.analyzeFileWithCache(anyFile); - return PsiCodegenPredictor.getFileForCodegenNamedClass(analyzeExhaust.getBindingContext(), allNamespaceFiles, className); + return PsiCodegenPredictor.getFileForCodegenNamedClass(analyzeExhaust.getBindingContext(), allNamespaceFiles, className.getInternalName()); } @NotNull