Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlin.js.translate.utils.BindingUtils Maven / Gradle / Ivy
/*
* Copyright 2010-2015 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.kotlin.js.translate.utils;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.utils.ErrorReportingUtils.message;
import static org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET;
import static org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_SET;
/**
* This class contains some code related to BindingContext use. Intention is not to pollute other classes.
* Every call to BindingContext.get() is supposed to be wrapped by this utility class.
*/
public final class BindingUtils {
private BindingUtils() {
}
@NotNull
static private
D getDescriptorForExpression(@NotNull BindingContext context, @NotNull E expression, Class descriptorClass) {
DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
assert descriptor != null;
assert descriptorClass.isInstance(descriptor)
: message(expression, expression.toString() + " expected to have of type" + descriptorClass.toString());
//noinspection unchecked
return (D) descriptor;
}
@NotNull
public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context,
@NotNull KtClassOrObject declaration) {
return BindingContextUtils.getNotNull(context, BindingContext.CLASS, declaration);
}
@NotNull
public static FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
@NotNull KtDeclarationWithBody declaration) {
return getDescriptorForExpression(context, declaration, FunctionDescriptor.class);
}
@NotNull
public static PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context,
@NotNull KtProperty declaration) {
return getDescriptorForExpression(context, declaration, PropertyDescriptor.class);
}
@NotNull
private static KtParameter getParameterForDescriptor(@NotNull ValueParameterDescriptor descriptor) {
PsiElement result = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
assert result instanceof KtParameter : message(descriptor, "ValueParameterDescriptor should have corresponding JetParameter");
return (KtParameter) result;
}
public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull KtClassOrObject classDeclaration) {
ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration);
List superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(classDescriptor);
return (JsDescriptorUtils.findAncestorClass(superclassDescriptors) != null);
}
@NotNull
public static KotlinType getTypeByReference(@NotNull BindingContext context,
@NotNull KtTypeReference typeReference) {
return BindingContextUtils.getNotNull(context, BindingContext.TYPE, typeReference);
}
@NotNull
public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
@NotNull KtTypeReference typeReference) {
return DescriptorUtils.getClassDescriptorForType(getTypeByReference(context, typeReference));
}
@Nullable
public static PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context,
@NotNull KtParameter parameter) {
return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
}
@Nullable
public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
@NotNull KtReferenceExpression reference) {
if (BindingContextUtils.isExpressionWithValidReference(reference, context)) {
return BindingContextUtils.getNotNull(context, BindingContext.REFERENCE_TARGET, reference);
}
return null;
}
@Nullable
public static DeclarationDescriptor getNullableDescriptorForReferenceExpression(@NotNull BindingContext context,
@NotNull KtReferenceExpression reference) {
return context.get(BindingContext.REFERENCE_TARGET, reference);
}
public static boolean isVariableReassignment(@NotNull BindingContext context, @NotNull KtExpression expression) {
return BindingContextUtils.getNotNull(context, BindingContext.VARIABLE_REASSIGNMENT, expression);
}
@Nullable
public static CallableDescriptor getCallableDescriptorForOperationExpression(
@NotNull BindingContext context,
@NotNull KtOperationExpression expression
) {
KtSimpleNameExpression operationReference = expression.getOperationReference();
DeclarationDescriptor descriptorForReferenceExpression =
getNullableDescriptorForReferenceExpression(context, operationReference);
if (descriptorForReferenceExpression == null) return null;
assert descriptorForReferenceExpression instanceof CallableDescriptor :
message(operationReference, "Operation should resolve to callable descriptor");
return (CallableDescriptor) descriptorForReferenceExpression;
}
@NotNull
public static DeclarationDescriptor getDescriptorForElement(@NotNull BindingContext context,
@NotNull PsiElement element) {
return BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element);
}
@Nullable
public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull KtExpression expression) {
CompileTimeConstant> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, context);
if (compileTimeValue != null) {
return getCompileTimeValue(context, expression, compileTimeValue);
}
return null;
}
@Nullable
public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull KtExpression expression, @NotNull CompileTimeConstant> constant) {
KotlinType expectedType = context.getType(expression);
return constant.getValue(expectedType == null ? TypeUtils.NO_EXPECTED_TYPE : expectedType);
}
@NotNull
public static KtExpression getDefaultArgument(@NotNull ValueParameterDescriptor parameterDescriptor) {
ValueParameterDescriptor descriptorWhichDeclaresDefaultValue =
getOriginalDescriptorWhichDeclaresDefaultValue(parameterDescriptor);
KtParameter psiParameter = getParameterForDescriptor(descriptorWhichDeclaresDefaultValue);
KtExpression defaultValue = psiParameter.getDefaultValue();
assert defaultValue != null : message(parameterDescriptor, "No default value found in PSI");
return defaultValue;
}
private static ValueParameterDescriptor getOriginalDescriptorWhichDeclaresDefaultValue(
@NotNull ValueParameterDescriptor parameterDescriptor
) {
ValueParameterDescriptor result = parameterDescriptor;
assert DescriptorUtilsKt.hasDefaultValue(result) : message(parameterDescriptor, "Unsupplied parameter must have default value");
// TODO: this seems incorrect, as the default value may come from _not the first_ overridden parameter
while (!result.declaresDefaultValue()) {
result = result.getOverriddenDescriptors().iterator().next();
}
return result;
}
@NotNull
public static ResolvedCall getIteratorFunction(@NotNull BindingContext context,
@NotNull KtExpression rangeExpression) {
return BindingContextUtils.getNotNull(context, BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL, rangeExpression);
}
@NotNull
public static ResolvedCall getNextFunction(@NotNull BindingContext context,
@NotNull KtExpression rangeExpression) {
return BindingContextUtils.getNotNull(context, BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, rangeExpression);
}
@NotNull
public static ResolvedCall getHasNextCallable(@NotNull BindingContext context,
@NotNull KtExpression rangeExpression) {
return BindingContextUtils.getNotNull(context, BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, rangeExpression);
}
@NotNull
public static KotlinType getTypeForExpression(@NotNull BindingContext context,
@NotNull KtExpression expression) {
return BindingContextUtils.getTypeNotNull(context, expression);
}
@NotNull
public static ResolvedCall getResolvedCallForArrayAccess(@NotNull BindingContext context,
@NotNull KtArrayAccessExpression arrayAccessExpression,
boolean isGet) {
return BindingContextUtils.getNotNull(context, isGet ? INDEXED_LVALUE_GET : INDEXED_LVALUE_SET, arrayAccessExpression);
}
}