From 018a1f8c85ebaa18b3a61b82667c72bb509ff142 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Tue, 28 Aug 2012 21:27:43 +0300 Subject: [PATCH] some cleanup of JetTypeMapper - some methods not relevant directly to type mapping made static and moved to CodegenBinding or CodegenUtil - naked bindingContext field shielded by getter - injectors regenerated in order to have injection logic more natural --- .../jet/codegen/AnnotationCodegen.java | 2 +- .../jet/codegen/ClassBodyCodegen.java | 7 +- .../jetbrains/jet/codegen/ClosureCodegen.java | 13 +- .../jetbrains/jet/codegen/CodegenUtil.java | 32 ++++ .../jet/codegen/ExpressionCodegen.java | 27 ++-- .../jet/codegen/FunctionCodegen.java | 11 +- .../codegen/ImplementationBodyCodegen.java | 27 ++-- .../jetbrains/jet/codegen/JetTypeMapper.java | 146 ++++-------------- .../jet/codegen/PropertyCodegen.java | 13 +- .../jetbrains/jet/codegen/StubCodegen.java | 6 +- .../context/CodegenAnnotatingVisitor.java | 27 ++-- .../jet/codegen/context/CodegenBinding.java | 90 +++++++++++ .../jet/codegen/context/CodegenContext.java | 6 +- .../jet/di/InjectorForJetTypeMapper.java | 2 +- .../jet/di/InjectorForJvmCodegen.java | 2 +- .../plugin/debugger/JetPositionManager.java | 8 +- 16 files changed, 233 insertions(+), 186 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index 56ee53e1e05..47bb9327a8c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -51,7 +51,7 @@ public abstract class AnnotationCodegen { private AnnotationCodegen(JetTypeMapper mapper) { typeMapper = mapper; - bindingContext = typeMapper.bindingContext; + bindingContext = typeMapper.getBindingContext(); } public void genAnnotations(Annotated annotated) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 0aad7b03584..a055c4d2616 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; /** * @author max @@ -100,10 +101,10 @@ public abstract class ClassBodyCodegen { if (!isAnnotation) { propertyCodegen.generateBackingField(p, propertyDescriptor); propertyCodegen - .generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p); + .generateDefaultGetter(propertyDescriptor, getAccessModifiers(propertyDescriptor, 0), p); if (propertyDescriptor.isVar()) { propertyCodegen - .generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p); + .generateDefaultSetter(propertyDescriptor, getAccessModifiers(propertyDescriptor, 0), p); } } else { @@ -144,7 +145,7 @@ public abstract class ClassBodyCodegen { // generates stub 'remove' function for subclasses of Iterator to be compatible with java.util.Iterator if (DescriptorUtils.isIteratorWithoutRemoveImpl(descriptor)) { final MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, "remove", "()V", null, null); - CodegenUtil.generateMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating method called on a Kotlin Iterator"); + generateMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating method called on a Kotlin Iterator"); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index b68c03c52ff..4206f751319 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -46,6 +46,7 @@ import java.util.ArrayList; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.context.CodegenBinding.classNameForAnonymousClass; import static org.jetbrains.jet.codegen.context.CodegenBinding.isLocalNamedFun; @@ -82,7 +83,7 @@ public class ClosureCodegen { assert funDescriptor != null; final List parameters = funDescriptor.getValueParameters(); - final JvmClassName funClass = CodegenUtil.getInternalClassName(funDescriptor); + final JvmClassName funClass = getInternalClassName(funDescriptor); signatureWriter.visitClassType(funClass.getInternalName()); for (ValueParameterDescriptor parameter : parameters) { appendType(signatureWriter, parameter.getType(), '='); @@ -107,11 +108,11 @@ public class ClosureCodegen { constructor = generateConstructor(funClass, fun, cv, closure); - if (CodegenUtil.isConst(closure)) { + if (isConst(closure)) { generateConstInstance(fun, cv); } - CodegenUtil.generateClosureFields(closure, cv, state.getInjector().getJetTypeMapper()); + generateClosureFields(closure, cv, state.getInjector().getJetTypeMapper()); cv.done(); @@ -168,7 +169,7 @@ public class ClosureCodegen { JetExpression fun, ClassBuilder cv ) { - final JvmMethodSignature bridge = CodegenUtil.erasedInvokeSignature(funDescriptor); + final JvmMethodSignature bridge = erasedInvokeSignature(funDescriptor); final Method delegate = typeMapper.invokeSignature(funDescriptor).getAsmMethod(); if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor())) { @@ -262,11 +263,11 @@ public class ClosureCodegen { final ClassDescriptor captureThis = closure.getCaptureThis(); if (captureThis != null) { final Type type = typeMapper.mapType(captureThis.getDefaultType(), MapTypeMode.VALUE); - args.add(new Pair(CodegenUtil.THIS$0, type)); + args.add(new Pair(THIS$0, type)); } final ClassifierDescriptor captureReceiver = closure.getCaptureReceiver(); if (captureReceiver != null) { - args.add(new Pair(CodegenUtil.RECEIVER$0, + args.add(new Pair(RECEIVER$0, typeMapper.mapType(captureReceiver.getDefaultType(), MapTypeMode.VALUE))); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 4eba9b6dbcb..906337d2c1a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.name.Name; @@ -223,4 +224,35 @@ public class CodegenUtil { public static T peekFromStack(Stack stack) { return stack.empty() ? null : stack.peek(); } + + public static int getAccessModifiers(@NotNull MemberDescriptor p, int defaultFlags) { + DeclarationDescriptor declaration = p.getContainingDeclaration(); + if (isInterface(declaration)) { + return ACC_PUBLIC; + } + if (p.getVisibility() == Visibilities.PUBLIC) { + return ACC_PUBLIC; + } + else if (p.getVisibility() == Visibilities.PROTECTED) { + return ACC_PROTECTED; + } + else if (p.getVisibility() == Visibilities.PRIVATE) { + if (DescriptorUtils.isClassObject(declaration)) { + return defaultFlags; + } + if (p.getContainingDeclaration() instanceof NamespaceDescriptor) { + return 0; + } + return ACC_PRIVATE; + } + else if (p.getVisibility() == Visibilities.INTERNAL) { + return ACC_PUBLIC; + } + else { + if (p.getVisibility() == Visibilities.INHERITED) { + throw new IllegalStateException("'inherited' visibility is unresolved on code generation stage"); + } + return defaultFlags; + } + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 8993ed1dffb..880611c8c4e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -55,6 +55,7 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.*; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.JetTypeMapper.*; import static org.jetbrains.jet.codegen.context.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; @@ -153,7 +154,7 @@ public class ExpressionCodegen extends JetVisitor implem assert provided instanceof ClassDescriptor; - if (!CodegenUtil.isInterface(provided) && CodegenUtil.isInterface(required)) { + if (!isInterface(provided) && isInterface(required)) { inner.put(OBJECT_TYPE, v); final Type type = asmType(required.getDefaultType()); v.checkcast(type); @@ -1019,7 +1020,7 @@ public class ExpressionCodegen extends JetVisitor implem final JvmClassName className = closureCodegen.name; final Type asmType = className.getAsmType(); final String internalName = className.getInternalName(); - if (CodegenUtil.isConst(closure)) { + if (isConst(closure)) { v.invokestatic(internalName, "$getInstance", "()" + className.getDescriptor()); } else { @@ -1355,8 +1356,8 @@ public class ExpressionCodegen extends JetVisitor implem receiver.put(receiverType != null && !isSuper ? asmType(receiverType) : OBJECT_TYPE, v); if (receiverType != null) { ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); - if (!CodegenUtil.isInterface(propReceiverDescriptor) && - CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { + if (!isInterface(propReceiverDescriptor) && + isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { v.checkcast(asmType(propReceiverDescriptor.getDefaultType())); } } @@ -1503,7 +1504,7 @@ public class ExpressionCodegen extends JetVisitor implem PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel()); ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); - if (!CodegenUtil.isInterface(containingDeclaration)) { + if (!isInterface(containingDeclaration)) { if (enclosed != null && enclosed != context.getThisDescriptor()) { CodegenContext c = context; while (c.getContextDescriptor() != enclosed) { @@ -1563,11 +1564,11 @@ public class ExpressionCodegen extends JetVisitor implem : INVOKEVIRTUAL; } else { - isInterface = CodegenUtil.isInterface(containingDeclaration) || overridesTrait; + isInterface = isInterface(containingDeclaration) || overridesTrait; // TODO ugly CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind()); invokeOpcode = callableMethod.getInvokeOpcode(); - owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration()) + owner = isFakeOverride && !overridesTrait && !isInterface(initialDescriptor.getContainingDeclaration()) ? JvmClassName.byType(typeMapper.mapType( ((ClassDescriptor) initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)) : callableMethod.getOwner(); @@ -1605,7 +1606,7 @@ public class ExpressionCodegen extends JetVisitor implem if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { final Set overriddenDescriptors = propertyDescriptor.getOverriddenDescriptors(); for (CallableMemberDescriptor descriptor : overriddenDescriptors) { - if (CodegenUtil.isInterface(descriptor.getContainingDeclaration())) { + if (isInterface(descriptor.getContainingDeclaration())) { return true; } } @@ -1661,7 +1662,7 @@ public class ExpressionCodegen extends JetVisitor implem JetSuperExpression superExpression = (JetSuperExpression) receiverExpression; PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel()); ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); - if (!CodegenUtil.isInterface(fd.getContainingDeclaration())) { + if (!isInterface(fd.getContainingDeclaration())) { if (enclosed == null) { enclosed = (ClassDescriptor) fd.getContainingDeclaration(); } @@ -1747,7 +1748,7 @@ public class ExpressionCodegen extends JetVisitor implem // callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd); //} if (isCallAsFunctionObject(fd)) { - SimpleFunctionDescriptor invoke = CodegenUtil.createInvoke(fd); + SimpleFunctionDescriptor invoke = createInvoke(fd); callableMethod = typeMapper.asCallableMethod(invoke); } else { @@ -1934,7 +1935,7 @@ public class ExpressionCodegen extends JetVisitor implem public StackValue generateThisOrOuter(@NotNull final ClassDescriptor calleeContainingClass) { PsiElement psiElement = classDescriptorToDeclaration(bindingContext, calleeContainingClass); - boolean isObject = psiElement instanceof JetClassOrObject && CodegenUtil.isNonLiteralObject((JetClassOrObject) psiElement); + boolean isObject = psiElement instanceof JetClassOrObject && isNonLiteralObject((JetClassOrObject) psiElement); CodegenContext cur = context; Type type = asmType(calleeContainingClass.getDefaultType()); @@ -2109,7 +2110,7 @@ public class ExpressionCodegen extends JetVisitor implem public int indexOfLocal(JetReferenceExpression lhs) { final DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, lhs); - if (typeMapper.isVarCapturedInClosure(declarationDescriptor)) { + if (isVarCapturedInClosure(typeMapper.getBindingContext(), declarationDescriptor)) { return -1; } return lookupLocalIndex(declarationDescriptor); @@ -2639,7 +2640,7 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue invokeOperation(JetOperationExpression expression, FunctionDescriptor op, CallableMethod callable) { int functionLocalIndex = lookupLocalIndex(op); if (functionLocalIndex >= 0) { - stackValueForLocal(op, functionLocalIndex).put(CodegenUtil.getInternalClassName(op).getAsmType(), v); + stackValueForLocal(op, functionLocalIndex).put(getInternalClassName(op).getAsmType(), v); } ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index a361d930f1d..8239dbcd055 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -42,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.*; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.context.CodegenBinding.isLocalFun; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; @@ -97,7 +98,7 @@ public class FunctionCodegen { List paramDescrs = functionDescriptor.getValueParameters(); - int flags = JetTypeMapper.getAccessModifiers(functionDescriptor, 0); + int flags = getAccessModifiers(functionDescriptor, 0); if (!functionDescriptor.getValueParameters().isEmpty() && functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1) @@ -131,7 +132,7 @@ public class FunctionCodegen { boolean isAbstract = ( modality == Modality.ABSTRACT - || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()) + || isInterface(functionDescriptor.getContainingDeclaration()) ) && !isStatic && kind != OwnerKind.TRAIT_IMPL; if (isAbstract) flags |= ACC_ABSTRACT; @@ -153,8 +154,8 @@ public class FunctionCodegen { throw new IllegalStateException(); } JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); - BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(functionDescriptor.getVisibility()); - if (CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()) && modality != Modality.ABSTRACT) { + BitSet kotlinFlags = getFlagsForVisibility(functionDescriptor.getVisibility()); + if (isInterface(functionDescriptor.getContainingDeclaration()) && modality != Modality.ABSTRACT) { kotlinFlags.set(modality == Modality.FINAL ? JvmStdlibNames.FLAG_FORCE_FINAL_BIT : JvmStdlibNames.FLAG_FORCE_OPEN_BIT); @@ -324,7 +325,7 @@ public class FunctionCodegen { Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(parameter); mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, k); - String nameForSharedVar = CodegenUtil.generateTmpVariableName(localVariableNames); + String nameForSharedVar = generateTmpVariableName(localVariableNames); localVariableNames.add(nameForSharedVar); mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index a506fd96739..29737967e95 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -49,6 +49,7 @@ import org.jetbrains.jet.utils.BitSetUtils; import java.util.*; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.JetTypeMapper.OBJECT_TYPE; import static org.jetbrains.jet.codegen.context.CodegenBinding.eclosingClassDescriptor; import static org.jetbrains.jet.codegen.context.CodegenBinding.enumEntryNeedSubclass; @@ -202,7 +203,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) { AnnotationVisitor annotationVisitor = v.newAnnotation(JvmStdlibNames.JET_CLASS.getDescriptor(), true); annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); - BitSet flags = CodegenUtil.getFlagsForVisibility(descriptor.getVisibility()); + BitSet flags = getFlagsForVisibility(descriptor.getVisibility()); int flagsValue = BitSetUtils.toInt(flags); if (JvmStdlibNames.FLAGS_DEFAULT_VALUE != flagsValue) { annotationVisitor.visit(JvmStdlibNames.JET_CLASS_FLAGS_FIELD, flagsValue); @@ -257,7 +258,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); - if (CodegenUtil.isInterface(superClassDescriptor)) { + if (isInterface(superClassDescriptor)) { signatureVisitor.writeInterface(); Type jvmName = typeMapper.mapType(superType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeInterfaceEnd(); @@ -301,7 +302,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); assert superClassDescriptor != null; - if (!CodegenUtil.isInterface(superClassDescriptor)) { + if (!isInterface(superClassDescriptor)) { superClassType = superType; superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); superCall = specifier; @@ -345,7 +346,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { generateEnumMethods(); - CodegenUtil.generateClosureFields(context.closure, v, state.getInjector().getJetTypeMapper()); + generateClosureFields(context.closure, v, state.getInjector().getJetTypeMapper()); } private void generateEnumMethods() { @@ -506,7 +507,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateFieldForObjectInstance() { - if (CodegenUtil.isNonLiteralObject(myClass)) { + if (isNonLiteralObject(myClass)) { Type type = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE); v.newField(myClass, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, "$instance", type.getDescriptor(), null, null); @@ -568,14 +569,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JvmMethodSignature constructorMethod = callableMethod.getSignature(); assert constructorDescriptor != null; - int flags = JetTypeMapper.getAccessModifiers(constructorDescriptor, 0); + int flags = getAccessModifiers(constructorDescriptor, 0); final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null); if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return; AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true); - int flagsValue = BitSetUtils.toInt(CodegenUtil.getFlagsForVisibility(constructorDescriptor.getVisibility())); + int flagsValue = BitSetUtils.toInt(getFlagsForVisibility(constructorDescriptor.getVisibility())); if (JvmStdlibNames.FLAGS_DEFAULT_VALUE != flagsValue) { jetConstructorVisitor.visit(JvmStdlibNames.JET_CLASS_FLAGS_FIELD, flagsValue); } @@ -629,11 +630,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (hasThis0) { final Type type = typeMapper - .mapType(eclosingClassDescriptor(typeMapper.bindingContext, descriptor).getDefaultType(), MapTypeMode.VALUE); + .mapType(eclosingClassDescriptor(typeMapper.getBindingContext(), descriptor).getDefaultType(), MapTypeMode.VALUE); String interfaceDesc = type.getDescriptor(); iv.load(0, classType); iv.load(frameMap.getOuterThisIndex(), type); - iv.putfield(classname.getInternalName(), CodegenUtil.THIS$0, interfaceDesc); + iv.putfield(classname.getInternalName(), THIS$0, interfaceDesc); } if (closure != null) { @@ -644,7 +645,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, JetTypeMapper.OBJECT_TYPE); final Type asmType = typeMapper.mapType(captureReceiver.getDefaultType(), MapTypeMode.IMPL); iv.load(1, asmType); - iv.putfield(internalName, CodegenUtil.RECEIVER$0, asmType.getDescriptor()); + iv.putfield(internalName, RECEIVER$0, asmType.getDescriptor()); k += asmType.getSize(); } @@ -706,7 +707,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (typeMapper.hasThis0(superClassDescriptor)) { iv.load(1, JetTypeMapper.OBJECT_TYPE); parameterTypes.add(typeMapper.mapType( - eclosingClassDescriptor(typeMapper.bindingContext, descriptor).getDefaultType(), MapTypeMode.VALUE)); + eclosingClassDescriptor(typeMapper.getBindingContext(), descriptor).getDefaultType(), MapTypeMode.VALUE)); } Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); //noinspection ConstantConditions @@ -962,7 +963,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JvmMethodSignature jvmSignature = typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature(); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); - BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(fun.getVisibility()); + BitSet kotlinFlags = getFlagsForVisibility(fun.getVisibility()); if (fun instanceof PropertyAccessorDescriptor) { kotlinFlags.set(JvmStdlibNames.FLAG_PROPERTY_BIT); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); @@ -1299,7 +1300,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor); for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) { if (overriddenDeclaration.getModality() != Modality.ABSTRACT) { - if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) { + if (!isInterface(overriddenDeclaration.getContainingDeclaration())) { continue root; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index eeef19d5bcf..f8b6ea978ba 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.name.Name; @@ -44,6 +45,7 @@ import java.util.List; import java.util.Map; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.context.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; @@ -77,13 +79,15 @@ public class JetTypeMapper { public static final Type JET_SHARED_LONG_TYPE = Type.getObjectType("jet/runtime/SharedVar$Long"); public static final Type JET_SHARED_BOOLEAN_TYPE = Type.getObjectType("jet/runtime/SharedVar$Boolean"); - public BindingContext bindingContext; + private BindingContext bindingContext; private boolean mapBuiltinsToJava; private ClassBuilderMode classBuilderMode; + private BindingTrace bindingTrace; @Inject - public void setBindingContext(BindingContext bindingContext) { - this.bindingContext = bindingContext; + public void setBindingTrace(BindingTrace bindingTrace) { + this.bindingTrace = bindingTrace; + this.bindingContext = bindingTrace.getBindingContext(); } @Inject @@ -107,6 +111,14 @@ public class JetTypeMapper { return bindingContext.get(CLOSURE, classDescriptor); } + public BindingTrace getBindingTrace() { + return bindingTrace; + } + + public BindingContext getBindingContext() { + return bindingContext; + } + public static boolean isIntPrimitive(Type type) { return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE; } @@ -259,70 +271,6 @@ public class JetTypeMapper { return null; } - public JvmClassName getJvmClassName(ClassDescriptor classDescriptor) { - return JvmClassName.byInternalName(getJvmInternalFQName(classDescriptor)); - } - - @NotNull - private String getJvmInternalFQName(@NotNull DeclarationDescriptor descriptor) { - descriptor = descriptor.getOriginal(); - - if (descriptor instanceof FunctionDescriptor) { - throw new IllegalStateException("requested fq name for function: " + descriptor); - } - - if (descriptor.getContainingDeclaration() instanceof ModuleDescriptor || descriptor instanceof ScriptDescriptor) { - return ""; - } - - if (descriptor instanceof ModuleDescriptor) { - throw new IllegalStateException("missed something"); - } - - if (descriptor instanceof ClassDescriptor) { - ClassDescriptor klass = (ClassDescriptor) descriptor; - if (klass.getKind() == ClassKind.OBJECT || klass.getKind() == ClassKind.CLASS_OBJECT) { - if (klass.getContainingDeclaration() instanceof ClassDescriptor) { - ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration(); - if (containingKlass.getKind() == ClassKind.ENUM_CLASS) { - return getJvmInternalFQName(containingKlass); - } - else { - return getJvmInternalFQName(containingKlass) + JvmAbi.CLASS_OBJECT_SUFFIX; - } - } - } - else if (klass.getKind() == ClassKind.ENUM_ENTRY) { - if (enumEntryNeedSubclass(bindingContext, klass)) { - return getJvmInternalFQName(klass.getContainingDeclaration()) + "$" + klass.getName().getName(); - } - else { - return getJvmInternalFQName(klass.getContainingDeclaration()); - } - } - - JvmClassName name = classNameForClassDescriptor(bindingContext, (ClassDescriptor) descriptor); - if (name != null) { - return name.getInternalName(); - } - } - - DeclarationDescriptor container = descriptor.getContainingDeclaration(); - - if (container == null) { - throw new IllegalStateException("descriptor has no container: " + descriptor); - } - - Name name = descriptor.getName(); - - String baseName = getJvmInternalFQName(container); - if (!baseName.isEmpty()) { - return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier(); - } - - return name.getIdentifier(); - } - @NotNull public Type mapType(@NotNull final JetType jetType, @NotNull MapTypeMode kind) { return mapType(jetType, null, kind); @@ -410,8 +358,14 @@ public class JetTypeMapper { } if (descriptor instanceof ClassDescriptor) { - JvmClassName name = getJvmClassName((ClassDescriptor) descriptor); - Type asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); + JvmClassName name = getJvmClassName(bindingTrace, (ClassDescriptor) descriptor); + Type asmType; + if (kind == MapTypeMode.TRAIT_IMPL) { + asmType = Type.getObjectType(name.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX); + } + else { + asmType = name.getAsmType(); + } boolean forceReal = KotlinToJavaTypesMap.getInstance().isForceReal(name); writeGenericType(jetType, signatureVisitor, asmType, forceReal); @@ -537,8 +491,8 @@ public class JetTypeMapper { ClassDescriptor currentOwner = (ClassDescriptor) functionParent; ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration(); - boolean originalIsInterface = CodegenUtil.isInterface(declarationOwner); - boolean currentIsInterface = CodegenUtil.isInterface(currentOwner); + boolean originalIsInterface = isInterface(declarationOwner); + boolean currentIsInterface = isInterface(currentOwner); boolean isAccessor = isAccessor(functionDescriptor); @@ -689,7 +643,7 @@ public class JetTypeMapper { for (JetType jetType : typeParameterDescriptor.getUpperBounds()) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { - if (!CodegenUtil.isInterface(jetType)) { + if (!isInterface(jetType)) { mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); break classBound; } @@ -705,7 +659,7 @@ public class JetTypeMapper { for (JetType jetType : typeParameterDescriptor.getUpperBounds()) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { - if (CodegenUtil.isInterface(jetType)) { + if (isInterface(jetType)) { signatureVisitor.writeInterfaceBound(); mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeInterfaceBoundEnd(); @@ -979,37 +933,6 @@ public class JetTypeMapper { } - public static int getAccessModifiers(@NotNull MemberDescriptor p, int defaultFlags) { - DeclarationDescriptor declaration = p.getContainingDeclaration(); - if (CodegenUtil.isInterface(declaration)) { - return ACC_PUBLIC; - } - if (p.getVisibility() == Visibilities.PUBLIC) { - return ACC_PUBLIC; - } - else if (p.getVisibility() == Visibilities.PROTECTED) { - return ACC_PROTECTED; - } - else if (p.getVisibility() == Visibilities.PRIVATE) { - if (DescriptorUtils.isClassObject(declaration)) { - return defaultFlags; - } - if (p.getContainingDeclaration() instanceof NamespaceDescriptor) { - return 0; - } - return ACC_PRIVATE; - } - else if (p.getVisibility() == Visibilities.INTERNAL) { - return ACC_PUBLIC; - } - else { - if (p.getVisibility() == Visibilities.INHERITED) { - throw new IllegalStateException("'inherited' visibility is unresolved on code generation stage"); - } - return defaultFlags; - } - } - private static boolean isGenericsArray(JetType type) { return JetStandardLibrary.getInstance().isArray(type) && type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; @@ -1028,27 +951,20 @@ public class JetTypeMapper { return StackValue .sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } - else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) { + else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(bindingContext, descriptor)) { JetType outType = ((VariableDescriptor) descriptor).getType(); return StackValue.sharedTypeForType(mapType(outType, MapTypeMode.VALUE)); } return null; } - public boolean isVarCapturedInClosure(DeclarationDescriptor descriptor) { - if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false; - VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor; - return Boolean.TRUE.equals(bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor)) && - variableDescriptor.isVar(); - } - protected JvmMethodSignature invokeSignature(FunctionDescriptor fd) { return mapSignature(Name.identifier("invoke"), fd); } public CallableMethod asCallableMethod(FunctionDescriptor fd) { - JvmMethodSignature descriptor = CodegenUtil.erasedInvokeSignature(fd); - JvmClassName owner = CodegenUtil.getInternalClassName(fd); + JvmMethodSignature descriptor = erasedInvokeSignature(fd); + JvmClassName owner = getInternalClassName(fd); Type receiverParameterType; if (fd.getReceiverParameter().exists()) { receiverParameterType = mapType(fd.getOriginal().getReceiverParameter().getType(), MapTypeMode.VALUE); @@ -1058,6 +974,6 @@ public class JetTypeMapper { } return new CallableMethod( owner, null, null, descriptor, INVOKEVIRTUAL, - CodegenUtil.getInternalClassName(fd), receiverParameterType, CodegenUtil.getInternalClassName(fd).getAsmType()); + getInternalClassName(fd), receiverParameterType, getInternalClassName(fd).getAsmType()); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index a5589150946..b0a14f14b55 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -39,6 +39,7 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import java.util.BitSet; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; /** @@ -83,7 +84,7 @@ public class PropertyCodegen { //noinspection ConstantConditions if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); - if (CodegenUtil.isInterface(containingDeclaration)) { + if (isInterface(containingDeclaration)) { return; } @@ -160,7 +161,7 @@ public class PropertyCodegen { private void generateDefaultGetter(JetProperty p) { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p); assert propertyDescriptor != null; - int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | + int flags = getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? ACC_ABSTRACT : (propertyDescriptor.getModality() == Modality.FINAL ? ACC_FINAL : 0)); @@ -249,9 +250,9 @@ public class PropertyCodegen { ) { JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); Modality modality = propertyDescriptor.getModality(); - BitSet flags = CodegenUtil.getFlagsForVisibility(visibility); + BitSet flags = getFlagsForVisibility(visibility); flags.set(JvmStdlibNames.FLAG_PROPERTY_BIT); - if (CodegenUtil.isInterface(propertyDescriptor.getContainingDeclaration()) && modality != Modality.ABSTRACT) { + if (isInterface(propertyDescriptor.getContainingDeclaration()) && modality != Modality.ABSTRACT) { flags.set(modality == Modality.FINAL ? JvmStdlibNames.FLAG_FORCE_FINAL_BIT : JvmStdlibNames.FLAG_FORCE_OPEN_BIT); @@ -266,9 +267,9 @@ public class PropertyCodegen { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p); assert propertyDescriptor != null; - int modifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0); + int modifiers = getAccessModifiers(propertyDescriptor, 0); PropertySetterDescriptor setter = propertyDescriptor.getSetter(); - int flags = setter == null ? modifiers : JetTypeMapper.getAccessModifiers(setter, modifiers); + int flags = setter == null ? modifiers : getAccessModifiers(setter, modifiers); flags |= (propertyDescriptor.getModality() == Modality.ABSTRACT ? ACC_ABSTRACT : 0); generateDefaultSetter(propertyDescriptor, flags, p); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java index f09df8e9c11..9fb32d0f2e6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java @@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen; import org.jetbrains.asm4.MethodVisitor; +import static org.jetbrains.jet.codegen.CodegenUtil.*; + /** * @author Stepan Koltsov */ @@ -29,10 +31,10 @@ public class StubCodegen { } public static void generateStubThrow(MethodVisitor mv) { - CodegenUtil.generateThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); + generateThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); } public static void generateStubCode(MethodVisitor mv) { - CodegenUtil.generateMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); + generateMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenAnnotatingVisitor.java index a59174edb9e..39dc06e214a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenAnnotatingVisitor.java @@ -33,6 +33,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.context.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; @@ -74,7 +75,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { } private String inventAnonymousClassName(JetElement declaration) { - String top = CodegenUtil.peekFromStack(nameStack); + String top = peekFromStack(nameStack); Integer cnt = anonymousSubclassesCount.get(top); if (cnt == null) { cnt = 0; @@ -133,7 +134,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { bindingTrace.record(ENUM_ENTRY_CLASS_NEED_SUBCLASS, descriptor); classStack.push(descriptor); - nameStack.push(CodegenUtil.peekFromStack(nameStack) + "$" + descriptor.getName().getName()); + nameStack.push(peekFromStack(nameStack) + "$" + descriptor.getName().getName()); super.visitEnumEntry(enumEntry); nameStack.pop(); classStack.pop(); @@ -148,8 +149,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { ClassDescriptor classDescriptor = bindingContext.get(CLASS, classObject.getObjectDeclaration()); assert classDescriptor != null; - JvmClassName name = JvmClassName.byInternalName(CodegenUtil.peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX); - recordClosure(bindingTrace, classObject, classDescriptor, CodegenUtil.peekFromStack(classStack), name, false); + JvmClassName name = JvmClassName.byInternalName(peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX); + recordClosure(bindingTrace, classObject, classDescriptor, peekFromStack(classStack), name, false); classStack.push(classDescriptor); nameStack.push(name.getInternalName()); @@ -169,7 +170,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { if (classDescriptor == null) return; String name = getName(classDescriptor); - recordClosure(bindingTrace, declaration, classDescriptor, CodegenUtil.peekFromStack(classStack), JvmClassName.byInternalName(name), false); + recordClosure(bindingTrace, declaration, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); nameStack.push(name); @@ -186,7 +187,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { if (classDescriptor == null) return; String name = getName(classDescriptor); - recordClosure(bindingTrace, klass, classDescriptor, CodegenUtil.peekFromStack(classStack), JvmClassName.byInternalName(name), false); + recordClosure(bindingTrace, klass, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); nameStack.push(name); @@ -196,7 +197,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { } private String getName(ClassDescriptor classDescriptor) { - String base = CodegenUtil.peekFromStack(nameStack); + String base = peekFromStack(nameStack); return classDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor ? base.isEmpty() ? classDescriptor.getName() .getName() : base + '/' + classDescriptor.getName() : base + '$' + classDescriptor.getName(); } @@ -211,7 +212,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { } final String name = inventAnonymousClassName(expression.getObjectDeclaration()); - recordClosure(bindingTrace, expression.getObjectDeclaration(), classDescriptor, CodegenUtil.peekFromStack(classStack), JvmClassName.byInternalName(name), false); + recordClosure(bindingTrace, expression.getObjectDeclaration(), classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); nameStack.push(classNameForClassDescriptor(bindingContext, classDescriptor).getInternalName()); @@ -229,7 +230,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { String name = inventAnonymousClassName(expression); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor); - recordClosure(bindingTrace, expression, classDescriptor, CodegenUtil.peekFromStack(classStack), JvmClassName.byInternalName(name), true); + recordClosure(bindingTrace, expression, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), true); classStack.push(classDescriptor); nameStack.push(name); @@ -240,7 +241,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { @Override public void visitProperty(JetProperty property) { - nameStack.push(CodegenUtil.peekFromStack(nameStack) + '$' + property.getName()); + nameStack.push(peekFromStack(nameStack) + '$' + property.getName()); super.visitProperty(property); nameStack.pop(); } @@ -253,12 +254,12 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { if (functionDescriptor == null) return; DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); if (containingDeclaration instanceof ClassDescriptor) { - nameStack.push(CodegenUtil.peekFromStack(nameStack) + '$' + function.getName()); + nameStack.push(peekFromStack(nameStack) + '$' + function.getName()); super.visitNamedFunction(function); nameStack.pop(); } else if (containingDeclaration instanceof NamespaceDescriptor) { - String peek = CodegenUtil.peekFromStack(nameStack); + String peek = peekFromStack(nameStack); if (peek.isEmpty()) { peek = "namespace"; } @@ -272,7 +273,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { else { String name = inventAnonymousClassName(function); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor); - recordClosure(bindingTrace, function, classDescriptor, CodegenUtil.peekFromStack(classStack), JvmClassName.byInternalName(name), true); + recordClosure(bindingTrace, function, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), true); classStack.push(classDescriptor); nameStack.push(name); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenBinding.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenBinding.java index a92a2028bf6..11911fed87e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenBinding.java @@ -26,6 +26,7 @@ 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.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -49,6 +50,8 @@ public class CodegenBinding { public static final WritableSlice CLASS_FOR_FUNCTION = Slices.createSimpleSlice(); + public static final WritableSlice FQN = Slices.createSimpleSlice(); + public static final WritableSlice SCRIPT_NAMES = Slices.createSimpleSetSlice(); public static final WritableSlice ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice(); @@ -242,4 +245,91 @@ public class CodegenBinding { } return false; } + + public static JvmClassName getJvmClassName(BindingTrace bindingTrace, ClassDescriptor classDescriptor) { + classDescriptor = (ClassDescriptor) classDescriptor.getOriginal(); + final JvmClassName name = bindingTrace.getBindingContext().get(FQN, classDescriptor); + if(name != null) { + return name; + } + + return getJvmInternalName(bindingTrace, classDescriptor); + } + + @NotNull + private static JvmClassName getJvmInternalName(BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) { + descriptor = descriptor.getOriginal(); + JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor); + if(name != null) { + return name; + } + + name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor)); + bindingTrace.record(FQN, descriptor, name); + return name; + } + + private static String getJvmInternalFQNameImpl(BindingTrace bindingTrace, DeclarationDescriptor descriptor) { + if (descriptor instanceof FunctionDescriptor) { + throw new IllegalStateException("requested fq name for function: " + descriptor); + } + + if (descriptor.getContainingDeclaration() instanceof ModuleDescriptor || descriptor instanceof ScriptDescriptor) { + return ""; + } + + if (descriptor instanceof ModuleDescriptor) { + throw new IllegalStateException("missed something"); + } + + if (descriptor instanceof ClassDescriptor) { + ClassDescriptor klass = (ClassDescriptor) descriptor; + if (klass.getKind() == ClassKind.OBJECT || klass.getKind() == ClassKind.CLASS_OBJECT) { + if (klass.getContainingDeclaration() instanceof ClassDescriptor) { + ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration(); + if (containingKlass.getKind() == ClassKind.ENUM_CLASS) { + return getJvmInternalName(bindingTrace, containingKlass).getInternalName(); + } + else { + return getJvmInternalName(bindingTrace, containingKlass).getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX; + } + } + } + else if (klass.getKind() == ClassKind.ENUM_ENTRY) { + if (enumEntryNeedSubclass(bindingTrace.getBindingContext(), klass)) { + return getJvmInternalName(bindingTrace, klass.getContainingDeclaration()).getInternalName() + "$" + klass.getName().getName(); + } + else { + return getJvmInternalName(bindingTrace, klass.getContainingDeclaration()).getInternalName(); + } + } + + JvmClassName name = classNameForClassDescriptor(bindingTrace.getBindingContext(), (ClassDescriptor) descriptor); + if (name != null) { + return name.getInternalName(); + } + } + + DeclarationDescriptor container = descriptor.getContainingDeclaration(); + + if (container == null) { + throw new IllegalStateException("descriptor has no container: " + descriptor); + } + + Name name = descriptor.getName(); + + String baseName = getJvmInternalName(bindingTrace, container).getInternalName(); + if (!baseName.isEmpty()) { + return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier(); + } + + return name.getIdentifier(); + } + + public static boolean isVarCapturedInClosure(BindingContext bindingContext, DeclarationDescriptor descriptor) { + if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false; + VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor; + return Boolean.TRUE.equals(bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor)) && + variableDescriptor.isVar(); + } } 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 17adc7a302c..a3d2bf6ec97 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -180,7 +180,7 @@ public abstract class CodegenContext { ) { final JetTypeMapper typeMapper = expressionCodegen.getState().getInjector().getJetTypeMapper(); return new ClosureContext(typeMapper, funDescriptor, - typeMapper.bindingContext.get(CLASS_FOR_FUNCTION, funDescriptor), + typeMapper.getBindingContext().get(CLASS_FOR_FUNCTION, funDescriptor), this, expressionCodegen); } @@ -258,8 +258,8 @@ public abstract class CodegenContext { final ClassDescriptor enclosingClass = getEnclosingClass(); outerExpression = enclosingClass != null ? StackValue - .field(typeMapper.mapType(enclosingClass.getDefaultType(), MapTypeMode.VALUE), typeMapper.getJvmClassName( - classDescriptor), CodegenUtil.THIS$0, + .field(typeMapper.mapType(enclosingClass.getDefaultType(), MapTypeMode.VALUE), CodegenBinding.getJvmClassName( + typeMapper.getBindingTrace(), classDescriptor), CodegenUtil.THIS$0, false) : null; } diff --git a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java index b3247c943f8..9c0eaaf3041 100644 --- a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java @@ -48,7 +48,7 @@ public class InjectorForJetTypeMapper { this.builtinToJavaTypesMapping = BuiltinToJavaTypesMapping.ENABLED; this.classBuilderMode = ClassBuilderMode.FULL; - this.jetTypeMapper.setBindingContext(bindingContext); + this.jetTypeMapper.setBindingTrace(bindingTrace); this.jetTypeMapper.setBuiltinToJavaTypesMapping(builtinToJavaTypesMapping); this.jetTypeMapper.setClassBuilderMode(classBuilderMode); diff --git a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java index 7714aab46b5..a069e0cc887 100644 --- a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java @@ -77,7 +77,7 @@ public class InjectorForJvmCodegen { this.classFileFactory = new ClassFileFactory(); this.memberCodegen = new MemberCodegen(); - this.jetTypeMapper.setBindingContext(bindingContext); + this.jetTypeMapper.setBindingTrace(bindingTrace); this.jetTypeMapper.setBuiltinToJavaTypesMapping(builtinToJavaTypesMapping); this.jetTypeMapper.setClassBuilderMode(classBuilderMode); diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index fe9fed7c733..2bab4197e12 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -146,7 +146,7 @@ public class JetPositionManager implements PositionManager { result.set(getJvmInternalNameForImpl(typeMapper, (JetClassOrObject) element)); } else if (element instanceof JetFunctionLiteralExpression) { - result.set(classNameForAnonymousClass(typeMapper.bindingContext, + result.set(classNameForAnonymousClass(typeMapper.getBindingContext(), (JetFunctionLiteralExpression) element).getInternalName()); } else if (element instanceof JetNamedFunction) { @@ -155,14 +155,14 @@ public class JetPositionManager implements PositionManager { result.set(getJvmInternalNameForImpl(typeMapper, (JetClassOrObject) parent)); } else if (parent instanceof JetFunctionLiteralExpression || parent instanceof JetNamedFunction) { - result.set(classNameForAnonymousClass(typeMapper.bindingContext, + result.set(classNameForAnonymousClass(typeMapper.getBindingContext(), (JetElement) element).getInternalName()); } } if (result.isNull()) { FqName fqName = JetPsiUtil.getFQName(namespace); - boolean multiFileNamespace = isMultiFileNamespace(typeMapper.bindingContext, fqName); + boolean multiFileNamespace = isMultiFileNamespace(typeMapper.getBindingContext(), fqName); String namespaceInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(fqName).getInternalName(); if (multiFileNamespace) { result.set(NamespaceCodegen.getMultiFileNamespaceInternalName(namespaceInternalName, namespace)); @@ -179,7 +179,7 @@ public class JetPositionManager implements PositionManager { @Nullable private static String getJvmInternalNameForImpl(JetTypeMapper typeMapper, JetClassOrObject jetClass) { - final ClassDescriptor classDescriptor = typeMapper.bindingContext.get(BindingContext.CLASS, jetClass); + final ClassDescriptor classDescriptor = typeMapper.getBindingContext().get(BindingContext.CLASS, jetClass); if (classDescriptor == null) { return null; }