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);
@@ -24,12 +24,12 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
@@ -341,13 +341,10 @@ public class AnnotationResolver {
}
private static boolean isEnumProperty(@NotNull PropertyDescriptor descriptor) {
if (DescriptorUtils.isKindOf(descriptor.getType(), ClassKind.ENUM_CLASS)) {
DeclarationDescriptor enumClassObject = descriptor.getContainingDeclaration();
if (DescriptorUtils.isKindOf(enumClassObject, ClassKind.CLASS_OBJECT)) {
return DescriptorUtils.isKindOf(enumClassObject.getContainingDeclaration(), ClassKind.ENUM_CLASS);
}
}
return false;
ClassifierDescriptor classifier = descriptor.getType().getConstructor().getDeclarationDescriptor();
return classifier != null &&
DescriptorUtils.isEnumClass(classifier) &&
DescriptorUtils.isEnumClassObject(descriptor.getContainingDeclaration());
}
@NotNull
@@ -1083,14 +1083,14 @@ public class DescriptorResolver {
}
@Nullable
private JetType transformAnonymousTypeIfNeeded(
private static JetType transformAnonymousTypeIfNeeded(
@NotNull DeclarationDescriptorWithVisibility descriptor,
@NotNull JetNamedDeclaration declaration,
@NotNull JetType type,
@NotNull BindingTrace trace
) {
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
if (!DescriptorUtils.isAnonymous(classifierDescriptor)) {
if (classifierDescriptor == null || !DescriptorUtils.isAnonymous(classifierDescriptor)) {
return type;
}
@@ -24,17 +24,12 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
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;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -45,6 +40,8 @@ import java.util.*;
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
public class DescriptorUtils {
private DescriptorUtils() {
}
@NotNull
public static <D extends CallableDescriptor> D substituteBounds(@NotNull D functionDescriptor) {
@@ -59,7 +56,8 @@ public class DescriptorUtils {
return substitutedFunction;
}
public static Modality convertModality(Modality modality, boolean makeNonAbstract) {
@NotNull
public static Modality convertModality(@NotNull Modality modality, boolean makeNonAbstract) {
if (makeNonAbstract && modality == Modality.ABSTRACT) return Modality.OPEN;
return modality;
}
@@ -126,7 +124,7 @@ public class DescriptorUtils {
return FqName.ROOT.toUnsafe();
}
}
throw new IllegalStateException("descriptor is not module descriptor and has null containingDeclaration: " + containingDeclaration);
throw new IllegalStateException("descriptor is not module descriptor and has null containingDeclaration: " + descriptor);
}
if (containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.CLASS_OBJECT) {
@@ -143,8 +141,8 @@ public class DescriptorUtils {
}
public static boolean isInSameModule(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) {
ModuleDescriptor parentModule = DescriptorUtils.getParentOfType(first, ModuleDescriptorImpl.class, false);
ModuleDescriptor fromModule = DescriptorUtils.getParentOfType(second, ModuleDescriptorImpl.class, false);
ModuleDescriptor parentModule = getParentOfType(first, ModuleDescriptorImpl.class, false);
ModuleDescriptor fromModule = getParentOfType(second, ModuleDescriptorImpl.class, false);
assert parentModule != null && fromModule != null;
return parentModule.equals(fromModule);
}
@@ -153,7 +151,7 @@ public class DescriptorUtils {
public static DeclarationDescriptor findTopLevelParent(@NotNull DeclarationDescriptor declarationDescriptor) {
DeclarationDescriptor descriptor = declarationDescriptor;
if (declarationDescriptor instanceof PropertyAccessorDescriptor) {
descriptor = ((PropertyAccessorDescriptor)descriptor).getCorrespondingProperty();
descriptor = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
}
while (!(descriptor == null || isTopLevelDeclaration(descriptor))) {
descriptor = descriptor.getContainingDeclaration();
@@ -162,12 +160,19 @@ public class DescriptorUtils {
}
@Nullable
public static <D extends DeclarationDescriptor> D getParentOfType(@Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass) {
public static <D extends DeclarationDescriptor> D getParentOfType(
@Nullable DeclarationDescriptor descriptor,
@NotNull Class<D> aClass
) {
return getParentOfType(descriptor, aClass, true);
}
@Nullable
public static <D extends DeclarationDescriptor> D getParentOfType(@Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass, boolean strict) {
public static <D extends DeclarationDescriptor> D getParentOfType(
@Nullable DeclarationDescriptor descriptor,
@NotNull Class<D> aClass,
boolean strict
) {
if (descriptor == null) return null;
if (strict) {
descriptor = descriptor.getContainingDeclaration();
@@ -182,7 +187,11 @@ public class DescriptorUtils {
return null;
}
public static boolean isAncestor(@Nullable DeclarationDescriptor ancestor, @NotNull DeclarationDescriptor declarationDescriptor, boolean strict) {
public static boolean isAncestor(
@Nullable DeclarationDescriptor ancestor,
@NotNull DeclarationDescriptor declarationDescriptor,
boolean strict
) {
if (ancestor == null) return false;
DeclarationDescriptor descriptor = strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor;
while (descriptor != null) {
@@ -192,23 +201,6 @@ public class DescriptorUtils {
return false;
}
@NotNull
public static JetType getFunctionExpectedReturnType(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) {
JetType expectedType;
if (function instanceof JetFunction) {
if (((JetFunction) function).getReturnTypeRef() != null || ((JetFunction) function).hasBlockBody()) {
expectedType = descriptor.getReturnType();
}
else {
expectedType = TypeUtils.NO_EXPECTED_TYPE;
}
}
else {
expectedType = descriptor.getReturnType();
}
return expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE;
}
public static boolean isSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal());
}
@@ -226,7 +218,7 @@ public class DescriptorUtils {
return false;
}
public static void addSuperTypes(JetType type, Set<JetType> set) {
public static void addSuperTypes(@NotNull JetType type, @NotNull Set<JetType> set) {
set.add(type);
for (JetType jetType : type.getConstructor().getSupertypes()) {
@@ -238,19 +230,6 @@ public class DescriptorUtils {
return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor;
}
@NotNull
public static List<DeclarationDescriptor> getPathWithoutRootNsAndModule(@NotNull DeclarationDescriptor descriptor) {
List<DeclarationDescriptor> path = Lists.newArrayList();
DeclarationDescriptor current = descriptor;
while (true) {
if (current instanceof NamespaceDescriptor && isRootNamespace((NamespaceDescriptor) current)) {
return Lists.reverse(path);
}
path.add(current);
current = current.getContainingDeclaration();
}
}
public static boolean isFunctionLiteral(@NotNull FunctionDescriptor descriptor) {
return descriptor instanceof AnonymousFunctionDescriptor;
}
@@ -259,7 +238,7 @@ public class DescriptorUtils {
return isKindOf(descriptor, ClassKind.CLASS_OBJECT);
}
public static boolean isAnonymous(@Nullable ClassifierDescriptor descriptor) {
public static boolean isAnonymous(@NotNull ClassifierDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.OBJECT) && descriptor.getName().isSpecial();
}
@@ -275,20 +254,16 @@ public class DescriptorUtils {
return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS);
}
public static boolean isTrait(@NotNull DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.TRAIT);
}
public static boolean isClass(@NotNull DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.CLASS);
}
public static boolean isKindOf(@NotNull JetType jetType, @NotNull ClassKind classKind) {
ClassifierDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
return isKindOf(descriptor, classKind);
}
public static boolean isKindOf(@Nullable DeclarationDescriptor descriptor, @NotNull ClassKind classKind) {
if (descriptor instanceof ClassDescriptor) {
return ((ClassDescriptor) descriptor).getKind() == classKind;
}
return false;
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == classKind;
}
@NotNull
@@ -311,11 +286,10 @@ public class DescriptorUtils {
@NotNull
public static ClassDescriptor getClassDescriptorForTypeConstructor(@NotNull TypeConstructor typeConstructor) {
DeclarationDescriptor superClassDescriptor =
typeConstructor.getDeclarationDescriptor();
assert superClassDescriptor instanceof ClassDescriptor
: "Superclass descriptor of a type should be of type ClassDescriptor";
return (ClassDescriptor)superClassDescriptor;
ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
assert descriptor instanceof ClassDescriptor
: "Classifier descriptor of a type should be of type ClassDescriptor: " + typeConstructor;
return (ClassDescriptor) descriptor;
}
public static boolean isAny(@NotNull DeclarationDescriptor superClassDescriptor) {
@@ -338,24 +312,6 @@ public class DescriptorUtils {
return false;
}
public static boolean isIteratorWithoutRemoveImpl(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor iteratorOfT = KotlinBuiltIns.getInstance().getIterator();
JetType iteratorOfAny = TypeUtils.substituteParameters(iteratorOfT, Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()));
boolean isIterator = JetTypeChecker.INSTANCE.isSubtypeOf(classDescriptor.getDefaultType(), iteratorOfAny);
boolean hasRemove = hasMethod(classDescriptor, Name.identifier("remove"));
return isIterator && !hasRemove;
}
private static boolean hasMethod(ClassDescriptor classDescriptor, Name name) {
Collection<FunctionDescriptor> removeFunctions = classDescriptor.getDefaultType().getMemberScope().getFunctions(name);
for (FunctionDescriptor function : removeFunctions) {
if (function.getValueParameters().isEmpty() && function.getTypeParameters().isEmpty()) {
return true;
}
}
return false;
}
@NotNull
public static Name getClassObjectName(@NotNull Name className) {
return Name.special("<class-object-for-" + className.asString() + ">");
@@ -438,35 +394,10 @@ public class DescriptorUtils {
return receiverParameterDescriptor.getType();
}
@NotNull
public static ReceiverValue safeGetValue(@Nullable ReceiverParameterDescriptor receiverParameterDescriptor) {
if (receiverParameterDescriptor == null) {
return ReceiverValue.NO_RECEIVER;
}
return receiverParameterDescriptor.getValue();
}
public static boolean isExternallyAccessible(PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getVisibility() != Visibilities.PRIVATE || isClassObject(propertyDescriptor.getContainingDeclaration())
|| isTopLevelDeclaration(propertyDescriptor);
}
@NotNull
public static JetType getVarargParameterType(@NotNull JetType elementType) {
return getVarargParameterType(elementType, Variance.INVARIANT);
}
@NotNull
public static JetType getVarargParameterType(@NotNull JetType elementType, @NotNull Variance projectionKind) {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
JetType primitiveArrayType = builtIns.getPrimitiveArrayJetTypeByPrimitiveJetType(elementType);
if (primitiveArrayType != null) {
return primitiveArrayType;
}
else {
return builtIns.getArrayType(projectionKind, elementType);
}
JetType primitiveArrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(elementType);
return primitiveArrayType != null ? primitiveArrayType : KotlinBuiltIns.getInstance().getArrayType(Variance.INVARIANT, elementType);
}
@NotNull
@@ -536,24 +467,6 @@ public class DescriptorUtils {
return allSuperclasses;
}
@NotNull
public static PropertyDescriptor getPropertyDescriptor(@NotNull JetProperty property, @NotNull BindingContext bindingContext) {
VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, property);
if (!(descriptor instanceof PropertyDescriptor)) {
throw new UnsupportedOperationException("expect a property to have a property descriptor");
}
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;
}
/**
* @return true iff {@code descriptor}'s first non-class container is a namespace
*/
@@ -384,8 +384,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
}
if (result != null) {
if (DescriptorUtils.isKindOf(thisType, ClassKind.TRAIT)) {
if (DescriptorUtils.isKindOf(result, ClassKind.CLASS)) {
if (DescriptorUtils.isTrait(thisType.getConstructor().getDeclarationDescriptor())) {
if (DescriptorUtils.isClass(result.getConstructor().getDeclarationDescriptor())) {
context.trace.report(SUPERCLASS_NOT_ACCESSIBLE_FROM_TRAIT.on(expression));
}
}
@@ -542,7 +542,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
}
if (containingFunctionDescriptor != null) {
expectedType = DescriptorUtils.getFunctionExpectedReturnType(containingFunctionDescriptor, (JetElement) containingFunction);
expectedType = getFunctionExpectedReturnType(containingFunctionDescriptor, (JetElement) containingFunction);
}
}
else {
@@ -554,7 +554,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
else if (labelTargetElement != null) {
SimpleFunctionDescriptor functionDescriptor = context.trace.get(FUNCTION, labelTargetElement);
if (functionDescriptor != null) {
expectedType = DescriptorUtils.getFunctionExpectedReturnType(functionDescriptor, labelTargetElement);
expectedType = getFunctionExpectedReturnType(functionDescriptor, labelTargetElement);
if (functionDescriptor != containingFunctionDescriptor) {
// Qualified, non-local
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
@@ -593,4 +593,21 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
context.labelResolver.resolveLabel(expression, context);
return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getNothingType(), expression, context, context.dataFlowInfo);
}
@NotNull
private static JetType getFunctionExpectedReturnType(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) {
JetType expectedType;
if (function instanceof JetFunction) {
if (((JetFunction) function).getReturnTypeRef() != null || ((JetFunction) function).hasBlockBody()) {
expectedType = descriptor.getReturnType();
}
else {
expectedType = TypeUtils.NO_EXPECTED_TYPE;
}
}
else {
expectedType = descriptor.getReturnType();
}
return expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE;
}
}
@@ -32,6 +32,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
@@ -42,7 +43,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.plugin.JetBundle;
import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening;
@@ -219,8 +219,8 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction {
) {
assert !ErrorUtils.isErrorType(exprType) : "Unexpected error type: " + namedDeclaration.getText();
TypeConstructor constructor = exprType.getConstructor();
boolean isAnonymous = DescriptorUtils.isAnonymous(constructor.getDeclarationDescriptor());
ClassifierDescriptor descriptor = exprType.getConstructor().getDeclarationDescriptor();
boolean isAnonymous = descriptor != null && DescriptorUtils.isAnonymous(descriptor);
Set<JetType> allSupertypes = TypeUtils.getAllSupertypes(exprType);
List<JetType> types = isAnonymous ? new ArrayList<JetType>() : Lists.newArrayList(exprType);
@@ -21,15 +21,16 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.k2js.translate.context.TranslationContext;
import java.util.Arrays;
@@ -107,8 +108,8 @@ public final class CallBuilder {
private CallTranslator finish() {
if (resolvedCall == null) {
assert descriptor != null;
resolvedCall = ResolvedCallImpl.create(ResolutionCandidate.create(descriptor, DescriptorUtils.safeGetValue(descriptor.getExpectedThisObject()),
DescriptorUtils.safeGetValue(descriptor.getReceiverParameter()),
resolvedCall = ResolvedCallImpl.create(ResolutionCandidate.create(descriptor, safeGetValue(descriptor.getExpectedThisObject()),
safeGetValue(descriptor.getReceiverParameter()),
ExplicitReceiverKind.THIS_OBJECT, false),
TemporaryBindingTrace.create(new BindingTraceContext(), "trace to resolve call (in js)"),
TracingStrategy.EMPTY,
@@ -121,10 +122,13 @@ public final class CallBuilder {
return new CallTranslator(receiver, callee, args, resolvedCall, descriptor, callType, context);
}
@NotNull
private static ReceiverValue safeGetValue(@Nullable ReceiverParameterDescriptor descriptor) {
return descriptor == null ? ReceiverValue.NO_RECEIVER : descriptor.getValue();
}
@NotNull
public JsExpression translate() {
return finish().translate();
}
}