Refactor DescriptorUtils

Remove dependency on org.jetbrains.jet.lang.psi, move utilities closer to their
usages, add NotNull annotations, fix formatting, etc.
This commit is contained in:
Alexander Udalov
2013-08-21 22:15:15 +04:00
parent 8400d2b8cf
commit d0a9464504
12 changed files with 136 additions and 165 deletions
@@ -27,8 +27,11 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
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.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collections;
import java.util.List;
@@ -196,9 +199,26 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
private void generateRemoveInIterator() {
// generates stub 'remove' function for subclasses of Iterator to be compatible with java.util.Iterator
if (DescriptorUtils.isIteratorWithoutRemoveImpl(descriptor)) {
if (isIteratorWithoutRemoveImpl(descriptor)) {
MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, "remove", "()V", null, null);
genMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating method called on a Kotlin Iterator");
}
}
private static boolean isIteratorWithoutRemoveImpl(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor iteratorOfT = KotlinBuiltIns.getInstance().getIterator();
JetType iteratorOfAny =
TypeUtils.substituteParameters(iteratorOfT, Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()));
if (!JetTypeChecker.INSTANCE.isSubtypeOf(classDescriptor.getDefaultType(), iteratorOfAny)) {
return false;
}
for (FunctionDescriptor function : classDescriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier("remove"))) {
if (function.getValueParameters().isEmpty() && function.getTypeParameters().isEmpty()) {
return false;
}
}
return true;
}
}
@@ -251,7 +251,13 @@ public class CodegenUtil {
!specialTypeProperty &&
(accessorDescriptor == null ||
accessorDescriptor.isDefault() &&
(!DescriptorUtils.isExternallyAccessible(propertyDescriptor) || accessorDescriptor.getModality() == Modality.FINAL));
(!isExternallyAccessible(propertyDescriptor) || accessorDescriptor.getModality() == Modality.FINAL));
}
private static boolean isExternallyAccessible(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getVisibility() != Visibilities.PRIVATE ||
DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration()) ||
DescriptorUtils.isTopLevelDeclaration(propertyDescriptor);
}
@NotNull
@@ -467,11 +467,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private List<PropertyDescriptor> getDataProperties() {
ArrayList<PropertyDescriptor> result = Lists.newArrayList();
for (JetParameter parameter : getPrimaryConstructorParameters()) {
if (parameter.getValOrVarNode() == null) continue;
PropertyDescriptor propertyDescriptor = DescriptorUtils.getPropertyDescriptor(parameter, bindingContext);
result.add(propertyDescriptor);
if (parameter.getValOrVarNode() != null) {
result.add(bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter));
}
}
return result;
}
@@ -1107,9 +1105,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(),
context.getFieldName(DescriptorUtils.getPropertyDescriptor(parameter, bindingContext)),
type.getDescriptor());
PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
assert propertyDescriptor != null : "Property descriptor is not found for primary constructor parameter: " + parameter;
iv.putfield(classAsmType.getInternalName(), context.getFieldName(propertyDescriptor), type.getDescriptor());
}
curParam++;
}
@@ -1740,7 +1738,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CallableMemberDescriptor candidate = null;
for (CallableMemberDescriptor overriddenDeclaration : filteredOverriddenDeclarations) {
if (isKindOf(overriddenDeclaration.getContainingDeclaration(), ClassKind.TRAIT) &&
if (isTrait(overriddenDeclaration.getContainingDeclaration()) &&
overriddenDeclaration.getModality() != Modality.ABSTRACT) {
candidate = overriddenDeclaration;
count++;
@@ -34,7 +34,6 @@ 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.DescriptorFactory;
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;
@@ -82,7 +81,10 @@ public class PropertyCodegen extends GenerationStateAware {
}
public void gen(JetProperty p) {
PropertyDescriptor propertyDescriptor = DescriptorUtils.getPropertyDescriptor(p, bindingContext);
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, p);
assert variableDescriptor instanceof PropertyDescriptor : "Property should have a property descriptor: " + variableDescriptor;
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
assert kind instanceof OwnerKind.StaticDelegateKind || kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL
: "Generating property with a wrong kind (" + kind + "): " + propertyDescriptor;
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen.state;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -132,10 +133,9 @@ public class JetTypeMapper extends BindingTraceAware {
@NotNull DeclarationDescriptor descriptor,
boolean insideModule
) {
StringBuilder r = new StringBuilder();
List<DeclarationDescriptor> path = DescriptorUtils.getPathWithoutRootNsAndModule(namespace);
List<DeclarationDescriptor> path = getPathWithoutRootNsAndModule(namespace);
for (DeclarationDescriptor pathElement : path) {
NamespaceDescriptor ns = (NamespaceDescriptor) pathElement;
@@ -173,6 +173,20 @@ public class JetTypeMapper extends BindingTraceAware {
return JvmClassName.byInternalName(r.toString());
}
@NotNull
public static List<DeclarationDescriptor> getPathWithoutRootNsAndModule(@NotNull NamespaceDescriptor descriptor) {
List<DeclarationDescriptor> path = new ArrayList<DeclarationDescriptor>();
DeclarationDescriptor current = descriptor;
while (true) {
if (current instanceof NamespaceDescriptor && DescriptorUtils.isRootNamespace((NamespaceDescriptor) current)) {
return Lists.reverse(path);
}
path.add(current);
assert current != null : "Namespace must have a parent: " + descriptor;
current = current.getContainingDeclaration();
}
}
@NotNull
public Type mapReturnType(@NotNull JetType jetType) {
return mapReturnType(jetType, null);