001 /* 002 * Copyright 2010-2013 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.jetbrains.k2js.translate.utils; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.jet.lang.descriptors.*; 022 import org.jetbrains.jet.lang.psi.JetExpression; 023 import org.jetbrains.jet.lang.resolve.BindingContext; 024 import org.jetbrains.jet.lang.resolve.DescriptorUtils; 025 import org.jetbrains.jet.lang.resolve.name.Name; 026 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; 027 import org.jetbrains.jet.lang.types.JetType; 028 import org.jetbrains.jet.lang.types.expressions.OperatorConventions; 029 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; 030 import org.jetbrains.k2js.translate.context.TranslationContext; 031 032 import java.util.List; 033 import java.util.Set; 034 035 import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getSuperclassDescriptors; 036 import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; 037 038 public final class JsDescriptorUtils { 039 040 private JsDescriptorUtils() { 041 } 042 043 private static int valueParametersCount(@NotNull FunctionDescriptor functionDescriptor) { 044 return functionDescriptor.getValueParameters().size(); 045 } 046 047 public static boolean hasParameters(@NotNull FunctionDescriptor functionDescriptor) { 048 return (valueParametersCount(functionDescriptor) > 0); 049 } 050 051 public static boolean isCompareTo(@NotNull FunctionDescriptor functionDescriptor) { 052 return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO)); 053 } 054 055 public static boolean isConstructorDescriptor(@NotNull CallableDescriptor descriptor) { 056 return (descriptor instanceof ConstructorDescriptor); 057 } 058 059 @Nullable 060 public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) { 061 for (ClassDescriptor descriptor : superclassDescriptors) { 062 if (descriptor.getKind() == ClassKind.CLASS || descriptor.getKind() == ClassKind.ENUM_CLASS) { 063 return descriptor; 064 } 065 } 066 return null; 067 } 068 069 @Nullable 070 public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) { 071 return findAncestorClass(getSuperclassDescriptors(classDescriptor)); 072 } 073 074 @NotNull 075 public static DeclarationDescriptor getContainingDeclaration(@NotNull DeclarationDescriptor descriptor) { 076 DeclarationDescriptor containing = descriptor.getContainingDeclaration(); 077 assert containing != null : "Should be called on objects that have containing declaration."; 078 return containing; 079 } 080 081 public static boolean isExtension(@NotNull CallableDescriptor functionDescriptor) { 082 return (functionDescriptor.getReceiverParameter() != null); 083 } 084 085 //TODO: why callable descriptor 086 @Nullable 087 public static DeclarationDescriptor getExpectedThisDescriptor(@NotNull CallableDescriptor callableDescriptor) { 088 ReceiverParameterDescriptor expectedThisObject = callableDescriptor.getExpectedThisObject(); 089 if (expectedThisObject == null) { 090 return null; 091 } 092 return getDeclarationDescriptorForReceiver(expectedThisObject.getValue()); 093 } 094 095 @NotNull 096 public static DeclarationDescriptor getDeclarationDescriptorForReceiver 097 (@NotNull ReceiverValue receiverParameter) { 098 DeclarationDescriptor declarationDescriptor = 099 receiverParameter.getType().getConstructor().getDeclarationDescriptor(); 100 //TODO: WHY assert? 101 assert declarationDescriptor != null; 102 return declarationDescriptor.getOriginal(); 103 } 104 105 @Nullable 106 public static DeclarationDescriptor getExpectedReceiverDescriptor(@NotNull CallableDescriptor callableDescriptor) { 107 ReceiverParameterDescriptor receiverParameter = callableDescriptor.getReceiverParameter(); 108 if (receiverParameter == null) { 109 return null; 110 } 111 return getDeclarationDescriptorForReceiver(receiverParameter.getValue()); 112 } 113 114 //TODO: maybe we have similar routine 115 @Nullable 116 public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) { 117 DeclarationDescriptor containing = descriptor.getContainingDeclaration(); 118 while (containing != null) { 119 if (containing instanceof ClassDescriptor && !isClassObject(containing)) { 120 return (ClassDescriptor) containing; 121 } 122 containing = containing.getContainingDeclaration(); 123 } 124 return null; 125 } 126 127 @Nullable 128 public static FunctionDescriptor getOverriddenDescriptor(@NotNull FunctionDescriptor functionDescriptor) { 129 Set<? extends FunctionDescriptor> overriddenDescriptors = functionDescriptor.getOverriddenDescriptors(); 130 if (overriddenDescriptors.isEmpty()) { 131 return null; 132 } 133 else { 134 //TODO: for now translator can't deal with multiple inheritance good enough 135 return overriddenDescriptors.iterator().next(); 136 } 137 } 138 139 private static boolean isDefaultAccessor(@Nullable PropertyAccessorDescriptor accessorDescriptor) { 140 return accessorDescriptor == null || accessorDescriptor.isDefault(); 141 } 142 143 public static boolean isAsPrivate(@NotNull PropertyDescriptor propertyDescriptor) { 144 return isExtension(propertyDescriptor) || 145 !isDefaultAccessor(propertyDescriptor.getGetter()) || 146 !isDefaultAccessor(propertyDescriptor.getSetter()); 147 } 148 149 public static boolean isStandardDeclaration(@NotNull DeclarationDescriptor descriptor) { 150 NamespaceDescriptor namespace = getContainingNamespace(descriptor); 151 if (namespace == null) { 152 return false; 153 } 154 return namespace.equals(KotlinBuiltIns.getInstance().getBuiltInsScope().getContainingDeclaration()); 155 } 156 157 @Nullable 158 public static NamespaceDescriptor getContainingNamespace(@NotNull DeclarationDescriptor descriptor) { 159 return DescriptorUtils.getParentOfType(descriptor, NamespaceDescriptor.class); 160 } 161 162 @Nullable 163 public static Name getNameIfStandardType(@NotNull JetExpression expression, @NotNull TranslationContext context) { 164 JetType type = context.bindingContext().get(BindingContext.EXPRESSION_TYPE, expression); 165 return type != null ? getNameIfStandardType(type) : null; 166 } 167 168 @Nullable 169 public static Name getNameIfStandardType(@NotNull JetType type) { 170 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 171 if (descriptor != null && descriptor.getContainingDeclaration() == KotlinBuiltIns.getInstance().getBuiltInsPackage()) { 172 return descriptor.getName(); 173 } 174 175 return null; 176 } 177 }