Introduce VariableDescriptorForObject interface

Add implementations
Use this interface instead of CLASS_OBJECT_DECLARATION key in BindingContext
This commit is contained in:
Pavel V. Talanov
2013-07-03 16:39:54 +04:00
committed by Alexander Udalov
parent dc5bc1488c
commit a57f74c278
16 changed files with 209 additions and 98 deletions
@@ -1639,12 +1639,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert descriptor != null;
if (descriptor instanceof VariableDescriptor) {
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
ClassDescriptor objectClassDescriptor = getBindingContext().get(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor);
if (objectClassDescriptor != null) {
return genObjectClassInstance(variableDescriptor, objectClassDescriptor);
}
if (descriptor instanceof VariableDescriptorForObject) {
VariableDescriptorForObject variableDescriptor = (VariableDescriptorForObject) descriptor;
ClassDescriptor objectClassDescriptor = variableDescriptor.getObjectClass();
return genObjectClassInstance(variableDescriptor, objectClassDescriptor);
}
int index = lookupLocalIndex(descriptor);
@@ -181,32 +181,7 @@ public final class JavaPropertyResolver {
kind = DescriptorKindUtils.flagsToKind(methodAnnotation.kind());
}
boolean isEnumEntry = psiData.getCharacteristicPsi() instanceof PsiEnumConstant;
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
DescriptorResolverUtils.resolveModality(characteristicMember.getMember(),
isFinal || isEnumEntry || psiData.isPropertyForNamedObject()),
visibility,
isVar,
propertyName,
kind);
//TODO: this is a hack to indicate that this enum entry is an object
// class descriptor for enum entries is not used by backends so for now this should be safe to use
// remove this when JavaDescriptorResolver gets rewritten
if (isEnumEntry) {
assert DescriptorUtils.isEnumClassObject(owner) : "Enum entries should be put into class object of enum only: " + owner;
ClassDescriptorImpl dummyClassDescriptorForEnumEntryObject =
new ClassDescriptorImpl(owner, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, propertyName);
dummyClassDescriptorForEnumEntryObject.initialize(
true,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptyList(), JetScope.EMPTY,
Collections.<ConstructorDescriptor>emptySet(), null,
false);
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, dummyClassDescriptorForEnumEntryObject);
}
PropertyDescriptorImpl propertyDescriptor = createPropertyDescriptor(owner, propertyName, psiData, isFinal, isVar, visibility, kind);
PropertyGetterDescriptorImpl getterDescriptor = resolveGetter(visibility, kind, getter, propertyDescriptor);
PropertySetterDescriptorImpl setterDescriptor = resolveSetter(psiData, kind, propertyDescriptor);
@@ -221,7 +196,6 @@ public final class JavaPropertyResolver {
JetType propertyType = getPropertyType(psiData, characteristicMember, typeVariableResolverForPropertyInternals);
JetType receiverType = getReceiverType(characteristicMember, typeVariableResolverForPropertyInternals);
propertyType = getAlternativeSignatureData(isVar, characteristicMember, propertyDescriptor, propertyType);
propertyDescriptor.setType(
@@ -236,8 +210,6 @@ public final class JavaPropertyResolver {
trace.record(BindingContext.VARIABLE, psiData.getCharacteristicPsi(), propertyDescriptor);
}
recordObjectDeclarationClassIfNeeded(psiData, owner, propertyDescriptor, propertyType);
if (scopeData.getDeclarationOrigin() == JAVA) {
trace.record(JavaBindingContext.IS_DECLARED_IN_JAVA, propertyDescriptor);
}
@@ -255,6 +227,62 @@ public final class JavaPropertyResolver {
return propertyDescriptor;
}
@NotNull
private PropertyDescriptorImpl createPropertyDescriptor(
@NotNull ClassOrNamespaceDescriptor owner,
@NotNull Name propertyName,
@NotNull PropertyPsiData psiData,
boolean isFinal,
boolean isVar,
@NotNull Visibility visibility,
@NotNull CallableMemberDescriptor.Kind kind
) {
boolean isEnumEntry = psiData.getCharacteristicPsi() instanceof PsiEnumConstant;
if (isEnumEntry) {
assert !isVar && isFinal : "Enum entries should be final and immutable.";
assert DescriptorUtils.isEnumClassObject(owner) : "Enum entries should be put into class object of enum only: " + owner;
//TODO: this is a hack to indicate that this enum entry is an object
// class descriptor for enum entries is not used by backends so for now this should be safe to use
ClassDescriptorImpl dummyClassDescriptorForEnumEntryObject =
new ClassDescriptorImpl(owner, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, propertyName);
dummyClassDescriptorForEnumEntryObject.initialize(
true,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptyList(), JetScope.EMPTY,
Collections.<ConstructorDescriptor>emptySet(), null,
false);
return new PropertyDescriptorForObjectImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
visibility,
propertyName,
dummyClassDescriptorForEnumEntryObject);
}
else if (psiData.isPropertyForNamedObject() && owner instanceof NamespaceDescriptor) {
//TODO: support nested classes and objects
assert !isVar && isFinal : "Objects should be final and immutable.";
ClassDescriptor objectClass = ((NamespaceDescriptor) owner).getMemberScope().getObjectDescriptor(propertyName);
assert objectClass != null;
return new PropertyDescriptorForObjectImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
visibility,
propertyName,
objectClass);
}
else {
return new PropertyDescriptorImpl(
owner,
annotationResolver.resolveAnnotations(psiData.getCharacteristicPsi()),
DescriptorResolverUtils.resolveModality(psiData.getCharacteristicMember().getMember(),
isFinal || psiData.isPropertyForNamedObject()),
visibility,
isVar,
propertyName,
kind);
}
}
@NotNull
private JetType getAlternativeSignatureData(
boolean isVar,
@@ -307,24 +335,6 @@ public final class JavaPropertyResolver {
}
}
private void recordObjectDeclarationClassIfNeeded(
PropertyPsiData psiData,
DeclarationDescriptor realOwner,
PropertyDescriptor propertyDescriptor,
JetType propertyType
) {
if (!psiData.isPropertyForNamedObject()) {
return;
}
ClassDescriptor objectDescriptor = (ClassDescriptor) propertyType.getConstructor().getDeclarationDescriptor();
assert objectDescriptor != null;
assert objectDescriptor.getKind() == ClassKind.OBJECT;
assert objectDescriptor.getContainingDeclaration() == realOwner;
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, objectDescriptor);
}
@Nullable
private PropertyGetterDescriptorImpl resolveGetter(
Visibility visibility,
@@ -418,9 +428,11 @@ public final class JavaPropertyResolver {
return null;
}
if (!characteristicMember.getReceiverType().getTypeString().isEmpty()) {
return semanticServices.getTypeTransformer().transformToType(characteristicMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals);
return semanticServices.getTypeTransformer()
.transformToType(characteristicMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals);
}
return semanticServices.getTypeTransformer().transformToType(characteristicMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals);
return semanticServices.getTypeTransformer()
.transformToType(characteristicMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals);
}
private static int getNumberOfNonExtensionProperties(@NotNull Collection<PropertyPsiData> propertyPsiDataCollection) {
@@ -295,9 +295,9 @@ public class DeserializedClassDescriptor extends ClassDescriptorBase implements
}
private void createEnumEntry(@NotNull MutableClassDescriptor enumClassObject, @NotNull Name name) {
PropertyDescriptorImpl property = new PropertyDescriptorImpl(enumClassObject, Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL, Visibilities.PUBLIC, false, name,
CallableMemberDescriptor.Kind.DECLARATION);
PropertyDescriptorImpl property = new PropertyDescriptorForObjectImpl(enumClassObject,
Collections.<AnnotationDescriptor>emptyList(),
Visibilities.PUBLIC, name, this);
property.setType(getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(),
enumClassObject.getThisAsReceiverParameter(), NO_RECEIVER_PARAMETER);
@@ -18,10 +18,7 @@ package org.jetbrains.jet.lang.cfg;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
@@ -90,11 +87,11 @@ public final class WhenChecker {
if (reference == null) return false;
DeclarationDescriptor target = trace.get(BindingContext.REFERENCE_TARGET, reference);
if (!(target instanceof VariableDescriptor)) {
if (!(target instanceof VariableDescriptorForObject)) {
return false;
}
ClassDescriptor classDescriptor = trace.get(BindingContext.OBJECT_DECLARATION_CLASS, (VariableDescriptor) target);
ClassDescriptor classDescriptor = ((VariableDescriptorForObject) target).getObjectClass();
return classDescriptor == enumEntry;
}
@@ -0,0 +1,24 @@
/*
* 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.lang.descriptors;
import org.jetbrains.annotations.NotNull;
public interface VariableDescriptorForObject extends VariableDescriptor {
@NotNull
ClassDescriptor getObjectClass();
}
@@ -0,0 +1,47 @@
/*
* 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.lang.descriptors.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptorForObject;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
public class LocalVariableDescriptorForObject extends LocalVariableDescriptor implements VariableDescriptorForObject {
private final ClassDescriptor objectClass;
public LocalVariableDescriptorForObject(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull Name name,
@NotNull ClassDescriptor objectClass
) {
super(containingDeclaration, annotations, name, objectClass.getDefaultType(), false);
this.objectClass = objectClass;
}
@NotNull
@Override
public ClassDescriptor getObjectClass() {
return objectClass;
}
}
@@ -0,0 +1,46 @@
/*
* 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.lang.descriptors.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
public class PropertyDescriptorForObjectImpl extends PropertyDescriptorImpl implements VariableDescriptorForObject {
private final ClassDescriptor objectClass;
public PropertyDescriptorForObjectImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull Visibility visibility,
@NotNull Name name,
@NotNull ClassDescriptor objectClass
) {
super(containingDeclaration, annotations, Modality.FINAL, visibility, false, name, Kind.DECLARATION);
this.objectClass = objectClass;
}
@NotNull
@Override
public ClassDescriptor getObjectClass() {
return objectClass;
}
}
@@ -142,8 +142,6 @@ public interface BindingContext {
WritableSlice<Box<DeferredType>, Boolean> DEFERRED_TYPE = Slices.createCollectiveSetSlice();
WritableSlice<VariableDescriptor, ClassDescriptor> OBJECT_DECLARATION_CLASS = Slices.createSimpleSlice();
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>(DO_NOTHING) {
@Override
public Boolean computeValue(
@@ -840,19 +840,16 @@ public class DescriptorResolver {
@NotNull ClassDescriptor classDescriptor, BindingTrace trace
) {
JetModifierList modifierList = objectDeclaration.getModifierList();
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorForObjectImpl(
containingDeclaration,
annotationResolver.getResolvedAnnotations(modifierList, trace),
Modality.FINAL,
resolveVisibilityFromModifiers(objectDeclaration, getDefaultVisibilityForObjectPropertyDescriptor(classDescriptor)),
false,
JetPsiUtil.safeName(objectDeclaration.getName()),
CallableMemberDescriptor.Kind.DECLARATION
classDescriptor
);
propertyDescriptor.setType(getTypeForObjectDeclaration(classDescriptor), Collections.<TypeParameterDescriptor>emptyList(),
getExpectedThisObjectIfNeeded(containingDeclaration), NO_RECEIVER_PARAMETER);
propertyDescriptor.initialize(null, null);
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, classDescriptor);
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
if (nameAsDeclaration != null) {
trace.record(BindingContext.OBJECT_DECLARATION, nameAsDeclaration, propertyDescriptor);
@@ -878,13 +875,11 @@ public class DescriptorResolver {
@NotNull JetClassOrObject objectDeclaration,
@NotNull ClassDescriptor classDescriptor, BindingTrace trace
) {
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptorForObject(
containingDeclaration,
annotationResolver.getResolvedAnnotations(objectDeclaration.getModifierList(), trace),
JetPsiUtil.safeName(objectDeclaration.getName()),
classDescriptor.getDefaultType(),
/*isVar =*/ false);
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor, classDescriptor);
classDescriptor);
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
if (nameAsDeclaration != null) {
trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor);
@@ -325,8 +325,7 @@ public class QualifiedExpressionResolver {
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
return (descriptor instanceof NamespaceDescriptor) ||
(descriptor instanceof ClassifierDescriptor) ||
((descriptor instanceof PropertyDescriptor) &&
(trace.get(BindingContext.OBJECT_DECLARATION_CLASS, ((PropertyDescriptor) descriptor)) != null));
(descriptor instanceof VariableDescriptorForObject);
}
}));
}
@@ -25,7 +25,7 @@ Object.<init>():ConstructorDescriptor
Object.nestedFunc:SimpleFunctionDescriptor
Object.this:ReceiverParameterDescriptor
Object:ClassDescriptor
Outer.Object:PropertyDescriptor
Outer.Object:VariableDescriptorForObject
Outer.this:ReceiverParameterDescriptor
Outer:ClassDescriptor
T1:TypeParameterDescriptor
@@ -46,11 +46,11 @@ func.this:ReceiverParameterDescriptor
innerTest.<get-prop>:PropertyGetterDescriptor
innerTest.<get-propVar>:PropertyGetterDescriptor
innerTest.<set-propVar>:PropertySetterDescriptor
innerTest.Object:PropertyDescriptor
innerTest.Object:VariableDescriptorForObject
innerTest.func:SimpleFunctionDescriptor
innerTest.prop:PropertyDescriptor
innerTest.propVar:PropertyDescriptor
innerTest:NamespaceDescriptor
prop.this:ReceiverParameterDescriptor
prop.this:ReceiverParameterDescriptor
test:NamespaceDescriptor
test:NamespaceDescriptor
@@ -254,10 +254,9 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture {
@NotNull
private ClassDescriptor getLocalObjectDescriptor(@NotNull String name) {
for (ClassDescriptor descriptor : context.getSliceContents(BindingContext.OBJECT_DECLARATION_CLASS).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
ClassDescriptor localClassDescriptor = getLocalClassDescriptor(name);
if (localClassDescriptor.getKind() == ClassKind.OBJECT) {
return localClassDescriptor;
}
fail("Failed to find local object " + name);
@@ -33,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.MemberComparator;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import org.jetbrains.jet.renderer.DescriptorRendererBuilder;
@@ -84,7 +83,7 @@ public class DecompiledDataFactory {
if (nd != null) {
for (DeclarationDescriptor member : sortDeclarations(nd.getMemberScope().getAllDescriptors())) {
if (member instanceof ClassDescriptor || member instanceof NamespaceDescriptor
|| isNamedObjectProperty(member, bindingContext)) {
|| isNamedObjectProperty(member)) {
continue;
}
appendDescriptor(member, "");
@@ -159,7 +158,7 @@ public class DecompiledDataFactory {
if (member instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) member).getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
continue;
}
if (isNamedObjectProperty(member, bindingContext)) {
if (isNamedObjectProperty(member)) {
continue;
}
@@ -201,10 +200,10 @@ public class DecompiledDataFactory {
}
}
private static boolean isNamedObjectProperty(@NotNull DeclarationDescriptor descriptor, BindingContext bindingContext) {
if (descriptor instanceof PropertyDescriptor) {
ClassDescriptor objectDeclaration = bindingContext.get(BindingContext.OBJECT_DECLARATION_CLASS, (PropertyDescriptor) descriptor);
if (objectDeclaration != null && objectDeclaration.getKind() == ClassKind.OBJECT) {
private static boolean isNamedObjectProperty(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof PropertyDescriptor && descriptor instanceof VariableDescriptorForObject) {
ClassDescriptor objectClass = ((VariableDescriptorForObject) descriptor).getObjectClass();
if (objectClass.getKind() == ClassKind.OBJECT) {
return true;
}
}
@@ -225,7 +225,7 @@ public final class StaticContext {
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
String propertyName = accessorDescriptor.getCorrespondingProperty().getName().asString();
if (isObjectDeclaration(bindingContext, accessorDescriptor.getCorrespondingProperty())) {
if (isObjectDeclaration(accessorDescriptor.getCorrespondingProperty())) {
return declareName(descriptor, propertyName);
}
@@ -195,7 +195,7 @@ public final class CallTranslator extends AbstractTranslator {
private boolean isObjectAccessor(@NotNull PropertyAccessorDescriptor propertyAccessorDescriptor) {
PropertyDescriptor correspondingProperty = propertyAccessorDescriptor.getCorrespondingProperty();
return isObjectDeclaration(bindingContext(), correspondingProperty);
return isObjectDeclaration(correspondingProperty);
}
@NotNull
@@ -264,10 +264,7 @@ public final class BindingUtils {
return bindingContext.get(BindingContext.FUNCTION, function);
}
public static boolean isObjectDeclaration(
@NotNull BindingContext bindingContext,
@NotNull PropertyDescriptor propertyDescriptor
) {
return bindingContext.get(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor) != null;
public static boolean isObjectDeclaration(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor instanceof VariableDescriptorForObject;
}
}