From aec6deae9f0369d62c6dd451d712d6264cb5335b Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 13 Jun 2013 13:48:08 +0400 Subject: [PATCH] Rename fields on name clashing #KT-3663 Fixed #KT-3664 Fixed --- .../jet/codegen/ExpressionCodegen.java | 32 +++++--- .../codegen/ImplementationBodyCodegen.java | 17 +++-- .../jetbrains/jet/codegen/MemberCodegen.java | 5 +- .../jet/codegen/NamespaceCodegen.java | 30 ++++---- .../jet/codegen/PropertyCodegen.java | 17 +++-- .../jetbrains/jet/codegen/ScriptCodegen.java | 3 +- .../org/jetbrains/jet/codegen/StackValue.java | 25 ++++--- .../jet/codegen/context/ClassContext.java | 2 +- .../jet/codegen/context/CodegenContext.java | 4 +- .../codegen/context/FieldOwnerContext.java | 73 +++++++++++++++++++ .../jet/codegen/context/NamespaceContext.java | 2 +- .../jet/codegen/context/ScriptContext.java | 2 +- .../jet/lang/resolve/java/JvmAbi.java | 15 ++++ .../jet/lang/resolve/DescriptorUtils.java | 10 +++ 14 files changed, 177 insertions(+), 60 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 490a6ce26f1..41d1dd24b84 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -51,6 +51,7 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; 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.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; @@ -1569,7 +1570,7 @@ public class ExpressionCodegen extends JetVisitor implem JetExpression r = getReceiverForSelector(expression); boolean isSuper = r instanceof JetSuperExpression; propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); - StackValue.Property iValue = + StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (directToField) { receiver = StackValue.receiverWithoutReceiverArgument(receiver); @@ -1678,7 +1679,7 @@ public class ExpressionCodegen extends JetVisitor implem } @NotNull - public StackValue.Property intermediateValueForProperty( + public StackValue intermediateValueForProperty( @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression @@ -1686,7 +1687,7 @@ public class ExpressionCodegen extends JetVisitor implem return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, MethodKind.GENERAL); } - public StackValue.Property intermediateValueForProperty( + public StackValue.StackValueWithSimpleReceiver intermediateValueForProperty( @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression, @@ -1754,7 +1755,9 @@ public class ExpressionCodegen extends JetVisitor implem callableSetter = null; } else { - callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); + callableSetter = typeMapper + .mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, + isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); } } } @@ -1765,20 +1768,25 @@ public class ExpressionCodegen extends JetVisitor implem propertyDescriptor = unwrapFakeOverride(propertyDescriptor); if (callableMethod == null) { - owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, context.getContextKind(), isInsideModule); + owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, + context.getContextKind(), isInsideModule); } else { owner = callableMethod.getOwner(); } - if (isDelegatedProperty && forceField) { - return StackValue.property(propertyDescriptor, owner, typeMapper.mapType(delegateType), - isStatic, true, callableGetter, callableSetter, state); - } - else { - return StackValue.property(propertyDescriptor, owner, typeMapper.mapType(propertyDescriptor.getOriginal().getType()), - isStatic, false, callableGetter, callableSetter, state); + String name; + if (propertyDescriptor.getContainingDeclaration() == backingFieldContext.getContextDescriptor()) { + assert backingFieldContext instanceof FieldOwnerContext : "Actual context is " + backingFieldContext + " but should be instance of FieldOwnerContext" ; + name = ((FieldOwnerContext) backingFieldContext).getFieldName(propertyDescriptor, isDelegatedProperty); + } else { + name = JvmAbi.getDefaultPropertyName(propertyDescriptor.getName(), isDelegatedProperty, propertyDescriptor.getReceiverParameter() != null); } + + return StackValue.property(propertyDescriptor, owner, + typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()), + isStatic, name, callableGetter, callableSetter, state); + } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 388592e71d4..952a8768944 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -471,8 +471,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (JetParameter parameter : getPrimaryConstructorParameters()) { if (parameter.getValOrVarNode() == null) continue; - PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); - assert propertyDescriptor != null; + PropertyDescriptor propertyDescriptor = DescriptorUtils.getPropertyDescriptor(parameter, bindingContext); result.add(propertyDescriptor); } @@ -860,7 +859,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { InstructionAdapter iv = codegen.v; boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); - StackValue.Property property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); + StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); if (!forceField) { iv.load(0, OBJECT_TYPE); } @@ -879,7 +878,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { @Override public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); - StackValue.Property property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); + StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); InstructionAdapter iv = codegen.v; Type[] argTypes = signature.getAsmMethod().getArgumentTypes(); @@ -955,7 +954,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (classObjectPropertiesToCopy != null) { for (PropertyDescriptor propertyDescriptor : classObjectPropertiesToCopy) { - v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, propertyDescriptor.getName().asString(), typeMapper.mapType(propertyDescriptor).getDescriptor(), null, null); + v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, context.getFieldName(propertyDescriptor), typeMapper.mapType(propertyDescriptor).getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { ExpressionCodegen codegen = createOrGetClInitCodegen(); @@ -1048,7 +1047,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generatePrimaryConstructorImpl( @Nullable ConstructorDescriptor constructorDescriptor, - @NotNull final ExpressionCodegen codegen, + @NotNull ExpressionCodegen codegen, @Nullable MutableClosure closure ) { List paramDescrs = constructorDescriptor != null @@ -1096,7 +1095,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Type type = typeMapper.mapType(descriptor); iv.load(0, classAsmType); iv.load(codegen.myFrameMap.getIndex(descriptor), type); - iv.putfield(classAsmType.getInternalName(), descriptor.getName().asString(), type.getDescriptor()); + iv.putfield(classAsmType.getInternalName(), + context.getFieldName(DescriptorUtils.getPropertyDescriptor(parameter, bindingContext)), + type.getDescriptor()); } curParam++; } @@ -1609,7 +1610,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType jetType = getPropertyOrDelegateType(bindingContext, property, propertyDescriptor); - StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER); + StackValue.StackValueWithSimpleReceiver propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER); if (!propValue.isStatic) { codegen.v.load(0, OBJECT_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 41ecee8aaed..255b476a9de 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -27,8 +28,6 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.ErrorUtils; -import java.util.List; - public class MemberCodegen extends GenerationStateAware { @@ -46,7 +45,7 @@ public class MemberCodegen extends GenerationStateAware { } public void genFunctionOrProperty( - CodegenContext context, + @NotNull FieldOwnerContext context, @NotNull JetTypeParameterListOwner functionOrProperty, @NotNull ClassBuilder classBuilder ) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index f8c59f92bc9..2a47158c56b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -27,6 +27,7 @@ import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -147,22 +148,20 @@ public class NamespaceCodegen extends MemberCodegen { ); builder.visitSource(file.getName(), null); + FieldOwnerContext nameSpaceContext = + CodegenContext.STATIC.intoNamespace(descriptor); + + FieldOwnerContext nameSpacePart = + CodegenContext.STATIC.intoNamespacePart(className, descriptor); + for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) { - { - CodegenContext context = - CodegenContext.STATIC.intoNamespace(descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, builder); - } - { - CodegenContext context = - CodegenContext.STATIC.intoNamespacePart(className, descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); - } + genFunctionOrProperty(nameSpaceContext, (JetTypeParameterListOwner) declaration, builder); + genFunctionOrProperty(nameSpacePart, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } } - generateStaticInitializers(descriptor, builder, file); + generateStaticInitializers(descriptor, builder, file, nameSpaceContext); builder.done(); } @@ -206,7 +205,12 @@ public class NamespaceCodegen extends MemberCodegen { } } - private void generateStaticInitializers(NamespaceDescriptor descriptor, @NotNull ClassBuilder builder, @NotNull JetFile file) { + private void generateStaticInitializers( + NamespaceDescriptor descriptor, + @NotNull ClassBuilder builder, + @NotNull JetFile file, + @NotNull FieldOwnerContext context + ) { List properties = collectPropertiesToInitialize(file); if (properties.isEmpty()) return; @@ -223,7 +227,7 @@ public class NamespaceCodegen extends MemberCodegen { clInit.initialize(null, null, Collections.emptyList(), Collections.emptyList(), null, null, Visibilities.PRIVATE, false); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC.intoFunction(clInit), state); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context.intoFunction(clInit), state); for (JetDeclaration declaration : properties) { ImplementationBodyCodegen. diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 46b6820effd..60b33ddbeb4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -17,15 +17,14 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.FieldVisitor; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; @@ -41,7 +40,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.JvmAbi; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; import org.jetbrains.jet.lang.resolve.name.Name; @@ -63,7 +61,7 @@ public class PropertyCodegen extends GenerationStateAware { private final ClassBuilder v; @NotNull - private final CodegenContext context; + private final FieldOwnerContext context; @Nullable private MemberCodegen classBodyCodegen; @@ -72,7 +70,7 @@ public class PropertyCodegen extends GenerationStateAware { private final OwnerKind kind; public PropertyCodegen( - @NotNull CodegenContext context, + @NotNull FieldOwnerContext context, @NotNull ClassBuilder v, @NotNull FunctionCodegen functionCodegen, @Nullable MemberCodegen classBodyCodegen @@ -145,9 +143,12 @@ public class PropertyCodegen extends GenerationStateAware { ClassBuilder builder = v; + FieldOwnerContext backingFieldContext = context; if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) { modifiers |= ACC_STATIC | getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate); - builder = getParentBodyCodegen(classBodyCodegen).v; + ImplementationBodyCodegen codegen = getParentBodyCodegen(classBodyCodegen); + builder = codegen.v; + backingFieldContext = codegen.context; } else { if (kind != OwnerKind.NAMESPACE || isDelegate) { modifiers |= ACC_PRIVATE; @@ -159,7 +160,7 @@ public class PropertyCodegen extends GenerationStateAware { parentBodyCodegen.addClassObjectPropertyToCopy(propertyDescriptor); } - String name = isDelegate ? JvmAbi.getPropertyDelegateName(propertyDescriptor.getName()) : propertyDescriptor.getName().asString(); + String name = backingFieldContext.getFieldName(propertyDescriptor, isDelegate); return builder.newField(element, modifiers, name, type.getDescriptor(), null, defaultValue); @@ -333,7 +334,7 @@ public class PropertyCodegen extends GenerationStateAware { iv.load(0, OBJECT_TYPE); } - StackValue.Property delegatedProperty = codegen.intermediateValueForProperty(property, true, null); + StackValue delegatedProperty = codegen.intermediateValueForProperty(property, true, null); StackValue lastValue = codegen.invokeFunction(call, delegatedProperty, resolvedCall); if (lastValue.type != Type.VOID_TYPE) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index e7323990991..8d18cb286b1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -24,6 +24,7 @@ import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.context.ScriptContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; @@ -196,7 +197,7 @@ public class ScriptCodegen extends MemberCodegen { } } - private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) { + private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull FieldOwnerContext context, @NotNull ClassBuilder classBuilder) { for (JetDeclaration decl : scriptDeclaration.getDeclarations()) { genFunctionOrProperty(context, (JetTypeParameterListOwner) decl, classBuilder); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 55b37b180b6..db0639e04af 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -116,10 +116,12 @@ public abstract class StackValue { return new Invert(stackValue); } + @NotNull public static StackValue arrayElement(Type type, boolean unbox) { return new ArrayElement(type, unbox); } + @NotNull public static StackValue collectionElement( Type type, ResolvedCall getter, @@ -135,19 +137,21 @@ public abstract class StackValue { return new Field(type, owner, name, isStatic); } + @NotNull public static Property property( - PropertyDescriptor descriptor, - JvmClassName methodOwner, - Type type, + @NotNull PropertyDescriptor descriptor, + @NotNull JvmClassName methodOwner, + @NotNull Type type, boolean isStatic, - boolean isDelegated, + @NotNull String name, @Nullable CallableMethod getter, @Nullable CallableMethod setter, GenerationState state ) { - return new Property(descriptor, methodOwner, getter, setter, isStatic, isDelegated, type, state); + return new Property(descriptor, methodOwner, getter, setter, isStatic, name, type, state); } + @NotNull public static StackValue expression(Type type, JetExpression expression, ExpressionCodegen generator) { return new Expression(type, expression, generator); } @@ -870,12 +874,13 @@ public abstract class StackValue { private final PropertyDescriptor descriptor; @NotNull private final GenerationState state; - private final boolean isDelegated; + + private final String name; public Property( @NotNull PropertyDescriptor descriptor, @NotNull JvmClassName methodOwner, @Nullable CallableMethod getter, @Nullable CallableMethod setter, boolean isStatic, - boolean isDelegated, @NotNull Type type, @NotNull GenerationState state + @NotNull String name, @NotNull Type type, @NotNull GenerationState state ) { super(type, isStatic); this.methodOwner = methodOwner; @@ -883,7 +888,7 @@ public abstract class StackValue { this.setter = setter; this.descriptor = descriptor; this.state = state; - this.isDelegated = isDelegated; + this.name = name; } @Override @@ -913,7 +918,7 @@ public abstract class StackValue { } private String getPropertyName() { - return isDelegated ? JvmAbi.getPropertyDelegateName(descriptor.getName()) : descriptor.getName().asString(); + return name; } } @@ -1244,7 +1249,7 @@ public abstract class StackValue { } } - private abstract static class StackValueWithSimpleReceiver extends StackValue { + public abstract static class StackValueWithSimpleReceiver extends StackValue { protected final boolean isStatic; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java index 6b99c7baaf5..5116ca78745 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java @@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLOSURE; -public class ClassContext extends CodegenContext { +public class ClassContext extends FieldOwnerContext { public ClassContext( @NotNull JetTypeMapper typeMapper, 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 efd84a550fa..32bd32ac879 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -147,12 +147,12 @@ public abstract class CodegenContext { } @NotNull - public CodegenContext intoNamespace(@NotNull NamespaceDescriptor descriptor) { + public FieldOwnerContext intoNamespace(@NotNull NamespaceDescriptor descriptor) { return new NamespaceContext(descriptor, this, OwnerKind.NAMESPACE); } @NotNull - public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { + public FieldOwnerContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { return new NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java new file mode 100644 index 00000000000..ece881dda9e --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen.context; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.OwnerKind; +import org.jetbrains.jet.codegen.binding.MutableClosure; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; + +import java.util.HashMap; +import java.util.Map; + +public abstract class FieldOwnerContext extends CodegenContext { + + //default property name -> map bytecode name> + private Map> fieldNames = new HashMap>(); + + public FieldOwnerContext( + @NotNull T contextDescriptor, + @NotNull OwnerKind contextKind, + @Nullable CodegenContext parentContext, + @Nullable MutableClosure closure, + @Nullable ClassDescriptor thisDescriptor, + @Nullable LocalLookup expressionCodegen + ) { + super(contextDescriptor, contextKind, parentContext, closure, thisDescriptor, expressionCodegen); + } + + public String getFieldName(PropertyDescriptor descriptor) { + return getFieldName(descriptor, false); + } + + public String getFieldName(PropertyDescriptor descriptor, boolean isDelegated) { + assert descriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE; + boolean isExtension = descriptor.getReceiverParameter() != null; + + return getFieldName(descriptor, isDelegated, isExtension); + } + + private String getFieldName(PropertyDescriptor descriptor, boolean isDelegated, boolean isExtension) { + descriptor = descriptor.getOriginal(); + String defaultPropertyName = JvmAbi.getDefaultPropertyName(descriptor.getName(), isDelegated, isExtension); + + Map descriptor2Name = fieldNames.get(defaultPropertyName); + if (descriptor2Name == null) { + descriptor2Name = new HashMap(); + fieldNames.put(defaultPropertyName, descriptor2Name); + } + + String actualName = descriptor2Name.get(descriptor); + if (actualName == null) { + actualName = descriptor2Name.isEmpty() ? defaultPropertyName : defaultPropertyName + "$" + descriptor2Name.size(); + descriptor2Name.put(descriptor, actualName); + } + return actualName; + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java index cf4e893f093..f492af72ae5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -public class NamespaceContext extends CodegenContext { +public class NamespaceContext extends FieldOwnerContext { public NamespaceContext(@NotNull NamespaceDescriptor contextDescriptor, @Nullable CodegenContext parent, @NotNull OwnerKind kind) { super(contextDescriptor, kind, parent, null, null, null); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java index 18ad481bf9b..e88efbf9556 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java @@ -23,7 +23,7 @@ import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; -public class ScriptContext extends CodegenContext { +public class ScriptContext extends FieldOwnerContext { @NotNull private final ScriptDescriptor scriptDescriptor; 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 aa592f4dd02..35e1e2c48cb 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 @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -59,6 +60,20 @@ public class JvmAbi { return name.asString() + DELEGATED_PROPERTY_NAME_POSTFIX; } + + public static String getDefaultPropertyName(Name propertyName, boolean isDelegated, boolean isExtensionProperty) { + if (isDelegated) { + return getPropertyDelegateName(propertyName); + } + + String name = propertyName.asString(); + if (isExtensionProperty) { + name += "$ext"; + } + return name; + + } + private JvmAbi() { } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index ede955951da..fba14d1131c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetFunction; +import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -586,4 +587,13 @@ public class DescriptorUtils { } return (PropertyDescriptor) descriptor; } + + + @NotNull + public static PropertyDescriptor getPropertyDescriptor(@NotNull JetParameter constructorParameter, @NotNull BindingContext bindingContext) { + assert constructorParameter.getValOrVarNode() != null; + PropertyDescriptor descriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, constructorParameter); + assert descriptor != null; + return descriptor; + } }