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 @Nullable 056 public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) { 057 for (ClassDescriptor descriptor : superclassDescriptors) { 058 if (descriptor.getKind() == ClassKind.CLASS || descriptor.getKind() == ClassKind.ENUM_CLASS) { 059 return descriptor; 060 } 061 } 062 return null; 063 } 064 065 @Nullable 066 public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) { 067 return findAncestorClass(getSuperclassDescriptors(classDescriptor)); 068 } 069 070 @NotNull 071 public static DeclarationDescriptor getContainingDeclaration(@NotNull DeclarationDescriptor descriptor) { 072 DeclarationDescriptor containing = descriptor.getContainingDeclaration(); 073 assert containing != null : "Should be called on objects that have containing declaration."; 074 return containing; 075 } 076 077 public static boolean isExtension(@NotNull CallableDescriptor functionDescriptor) { 078 return (functionDescriptor.getReceiverParameter() != null); 079 } 080 081 //TODO: why callable descriptor 082 @Nullable 083 public static DeclarationDescriptor getExpectedThisDescriptor(@NotNull CallableDescriptor callableDescriptor) { 084 ReceiverParameterDescriptor expectedThisObject = callableDescriptor.getExpectedThisObject(); 085 if (expectedThisObject == null) { 086 return null; 087 } 088 return getDeclarationDescriptorForReceiver(expectedThisObject.getValue()); 089 } 090 091 @NotNull 092 public static DeclarationDescriptor getDeclarationDescriptorForReceiver 093 (@NotNull ReceiverValue receiverParameter) { 094 DeclarationDescriptor declarationDescriptor = 095 receiverParameter.getType().getConstructor().getDeclarationDescriptor(); 096 //TODO: WHY assert? 097 assert declarationDescriptor != null; 098 return declarationDescriptor.getOriginal(); 099 } 100 101 @Nullable 102 public static DeclarationDescriptor getExpectedReceiverDescriptor(@NotNull CallableDescriptor callableDescriptor) { 103 ReceiverParameterDescriptor receiverParameter = callableDescriptor.getReceiverParameter(); 104 if (receiverParameter == null) { 105 return null; 106 } 107 return getDeclarationDescriptorForReceiver(receiverParameter.getValue()); 108 } 109 110 //TODO: maybe we have similar routine 111 @Nullable 112 public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) { 113 DeclarationDescriptor containing = descriptor.getContainingDeclaration(); 114 while (containing != null) { 115 if (containing instanceof ClassDescriptor && !isClassObject(containing)) { 116 return (ClassDescriptor) containing; 117 } 118 containing = containing.getContainingDeclaration(); 119 } 120 return null; 121 } 122 123 @Nullable 124 public static FunctionDescriptor getOverriddenDescriptor(@NotNull FunctionDescriptor functionDescriptor) { 125 Set<? extends FunctionDescriptor> overriddenDescriptors = functionDescriptor.getOverriddenDescriptors(); 126 if (overriddenDescriptors.isEmpty()) { 127 return null; 128 } 129 else { 130 //TODO: for now translator can't deal with multiple inheritance good enough 131 return overriddenDescriptors.iterator().next(); 132 } 133 } 134 135 private static boolean isDefaultAccessor(@Nullable PropertyAccessorDescriptor accessorDescriptor) { 136 return accessorDescriptor == null || accessorDescriptor.isDefault(); 137 } 138 139 public static boolean isSimpleFinalProperty(@NotNull PropertyDescriptor propertyDescriptor) { 140 return !isExtension(propertyDescriptor) && 141 isDefaultAccessor(propertyDescriptor.getGetter()) && 142 isDefaultAccessor(propertyDescriptor.getSetter()) && 143 !propertyDescriptor.getModality().isOverridable(); 144 } 145 146 public static boolean isStandardDeclaration(@NotNull DeclarationDescriptor descriptor) { 147 NamespaceDescriptor namespace = getContainingNamespace(descriptor); 148 if (namespace == null) { 149 return false; 150 } 151 return namespace.equals(KotlinBuiltIns.getInstance().getBuiltInsScope().getContainingDeclaration()); 152 } 153 154 @Nullable 155 public static NamespaceDescriptor getContainingNamespace(@NotNull DeclarationDescriptor descriptor) { 156 return DescriptorUtils.getParentOfType(descriptor, NamespaceDescriptor.class); 157 } 158 159 @Nullable 160 public static Name getNameIfStandardType(@NotNull JetExpression expression, @NotNull TranslationContext context) { 161 JetType type = context.bindingContext().get(BindingContext.EXPRESSION_TYPE, expression); 162 return type != null ? getNameIfStandardType(type) : null; 163 } 164 165 @Nullable 166 public static Name getNameIfStandardType(@NotNull JetType type) { 167 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 168 if (descriptor != null && descriptor.getContainingDeclaration() == KotlinBuiltIns.getInstance().getBuiltInsPackage()) { 169 return descriptor.getName(); 170 } 171 172 return null; 173 } 174 }