use of org.jetbrains.kotlin.descriptors.CallableDescriptor in project kotlin by JetBrains.
the class DebugInfoUtil method markDebugAnnotations.
public static void markDebugAnnotations(@NotNull PsiElement root, @NotNull final BindingContext bindingContext, @NotNull final DebugInfoReporter debugInfoReporter) {
final Map<KtReferenceExpression, DiagnosticFactory<?>> markedWithErrorElements = Maps.newHashMap();
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
DiagnosticFactory<?> factory = diagnostic.getFactory();
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
markedWithErrorElements.put((KtReferenceExpression) diagnostic.getPsiElement(), factory);
} else if (factory == Errors.SUPER_IS_NOT_AN_EXPRESSION || factory == Errors.SUPER_NOT_AVAILABLE) {
KtSuperExpression superExpression = (KtSuperExpression) diagnostic.getPsiElement();
markedWithErrorElements.put(superExpression.getInstanceReference(), factory);
} else if (factory == Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
markedWithErrorElements.put((KtSimpleNameExpression) diagnostic.getPsiElement(), factory);
} else if (factory == Errors.UNSUPPORTED) {
for (KtReferenceExpression reference : PsiTreeUtil.findChildrenOfType(diagnostic.getPsiElement(), KtReferenceExpression.class)) {
markedWithErrorElements.put(reference, factory);
}
}
}
root.acceptChildren(new KtTreeVisitorVoid() {
@Override
public void visitForExpression(@NotNull KtForExpression expression) {
KtExpression range = expression.getLoopRange();
reportIfDynamicCall(range, range, LOOP_RANGE_ITERATOR_RESOLVED_CALL);
reportIfDynamicCall(range, range, LOOP_RANGE_HAS_NEXT_RESOLVED_CALL);
reportIfDynamicCall(range, range, LOOP_RANGE_NEXT_RESOLVED_CALL);
super.visitForExpression(expression);
}
@Override
public void visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration destructuringDeclaration) {
for (KtDestructuringDeclarationEntry entry : destructuringDeclaration.getEntries()) {
reportIfDynamicCall(entry, entry, COMPONENT_RESOLVED_CALL);
}
super.visitDestructuringDeclaration(destructuringDeclaration);
}
@Override
public void visitProperty(@NotNull KtProperty property) {
VariableDescriptor descriptor = bindingContext.get(VARIABLE, property);
if (descriptor instanceof PropertyDescriptor && property.getDelegate() != null) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
reportIfDynamicCall(property.getDelegate(), propertyDescriptor, PROVIDE_DELEGATE_RESOLVED_CALL);
reportIfDynamicCall(property.getDelegate(), propertyDescriptor.getGetter(), DELEGATED_PROPERTY_RESOLVED_CALL);
reportIfDynamicCall(property.getDelegate(), propertyDescriptor.getSetter(), DELEGATED_PROPERTY_RESOLVED_CALL);
}
super.visitProperty(property);
}
@Override
public void visitThisExpression(@NotNull KtThisExpression expression) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(expression, bindingContext);
if (resolvedCall != null) {
reportIfDynamic(expression, resolvedCall.getResultingDescriptor(), debugInfoReporter);
}
super.visitThisExpression(expression);
}
@Override
public void visitReferenceExpression(@NotNull KtReferenceExpression expression) {
super.visitReferenceExpression(expression);
if (!BindingContextUtils.isExpressionWithValidReference(expression, bindingContext)) {
return;
}
IElementType referencedNameElementType = null;
if (expression instanceof KtSimpleNameExpression) {
KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) expression;
IElementType elementType = expression.getNode().getElementType();
if (elementType == KtNodeTypes.OPERATION_REFERENCE) {
referencedNameElementType = nameExpression.getReferencedNameElementType();
if (EXCLUDED.contains(referencedNameElementType)) {
return;
}
}
if (elementType == KtNodeTypes.LABEL || nameExpression.getReferencedNameElementType() == KtTokens.THIS_KEYWORD) {
return;
}
}
debugInfoReporter.preProcessReference(expression);
String target = null;
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
if (declarationDescriptor != null) {
target = declarationDescriptor.toString();
reportIfDynamic(expression, declarationDescriptor, debugInfoReporter);
}
if (target == null) {
PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression);
if (labelTarget != null) {
target = labelTarget.getText();
}
}
if (target == null) {
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
if (declarationDescriptors != null) {
target = "[" + declarationDescriptors.size() + " descriptors]";
}
}
if (target == null) {
Collection<? extends PsiElement> labelTargets = bindingContext.get(AMBIGUOUS_LABEL_TARGET, expression);
if (labelTargets != null) {
target = "[" + labelTargets.size() + " elements]";
}
}
if (MAY_BE_UNRESOLVED.contains(referencedNameElementType)) {
return;
}
boolean resolved = target != null;
boolean markedWithError = markedWithErrorElements.containsKey(expression);
if (expression instanceof KtArrayAccessExpression && markedWithErrorElements.containsKey(((KtArrayAccessExpression) expression).getArrayExpression())) {
// if 'foo' in 'foo[i]' is unresolved it means 'foo[i]' is unresolved (otherwise 'foo[i]' is marked as 'missing unresolved')
markedWithError = true;
}
KotlinType expressionType = bindingContext.getType(expression);
DiagnosticFactory<?> factory = markedWithErrorElements.get(expression);
if (declarationDescriptor != null && (ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) {
if (factory != Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
debugInfoReporter.reportElementWithErrorType(expression);
}
}
if (resolved && markedWithError) {
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(factory)) {
debugInfoReporter.reportUnresolvedWithTarget(expression, target);
}
} else if (!resolved && !markedWithError) {
debugInfoReporter.reportMissingUnresolved(expression);
}
}
private <E extends KtElement, K, D extends CallableDescriptor> boolean reportIfDynamicCall(E element, K key, WritableSlice<K, ResolvedCall<D>> slice) {
ResolvedCall<D> resolvedCall = bindingContext.get(slice, key);
if (resolvedCall != null) {
return reportIfDynamic(element, resolvedCall.getResultingDescriptor(), debugInfoReporter);
}
return false;
}
});
}
use of org.jetbrains.kotlin.descriptors.CallableDescriptor in project kotlin by JetBrains.
the class SourceNavigationHelper method convertPropertyOrFunction.
@Nullable
private static KtNamedDeclaration convertPropertyOrFunction(@NotNull KtNamedDeclaration declaration, @NotNull NavigationKind navigationKind) {
if (declaration instanceof KtPrimaryConstructor) {
KtClassOrObject sourceClassOrObject = findClassOrObject(((KtPrimaryConstructor) declaration).getContainingClassOrObject(), navigationKind);
KtPrimaryConstructor primaryConstructor = sourceClassOrObject != null ? sourceClassOrObject.getPrimaryConstructor() : null;
return primaryConstructor != null ? primaryConstructor : sourceClassOrObject;
}
String memberNameAsString = declaration.getName();
if (memberNameAsString == null) {
LOG.debug("JetSourceNavigationHelper.convertPropertyOrFunction(): null name for declaration " + declaration);
return null;
}
Name memberName = Name.identifier(memberNameAsString);
PsiElement decompiledContainer = declaration.getParent();
Collection<KtNamedDeclaration> candidates;
if (decompiledContainer instanceof KtFile) {
candidates = getInitialTopLevelCandidates(declaration, navigationKind);
} else if (decompiledContainer instanceof KtClassBody) {
KtClassOrObject decompiledClassOrObject = (KtClassOrObject) decompiledContainer.getParent();
KtClassOrObject sourceClassOrObject = findClassOrObject(decompiledClassOrObject, navigationKind);
//noinspection unchecked
candidates = sourceClassOrObject == null ? Collections.<KtNamedDeclaration>emptyList() : getInitialMemberCandidates(sourceClassOrObject, memberName, (Class<KtNamedDeclaration>) declaration.getClass());
if (candidates.isEmpty()) {
if (declaration instanceof KtProperty && sourceClassOrObject instanceof KtClass) {
return findSpecialProperty(memberName, (KtClass) sourceClassOrObject);
}
}
} else {
throw new IllegalStateException("Unexpected container of " + (navigationKind == NavigationKind.CLASS_FILES_TO_SOURCES ? "decompiled" : "source") + " declaration: " + decompiledContainer.getClass().getSimpleName());
}
if (candidates.isEmpty()) {
return null;
}
candidates = filterByOrderEntries(declaration, candidates);
if (!forceResolve) {
candidates = filterByReceiverPresenceAndParametersCount(declaration, candidates);
if (candidates.size() <= 1) {
return candidates.isEmpty() ? null : candidates.iterator().next();
}
if (!haveRenamesInImports(getContainingFiles(candidates))) {
candidates = filterByReceiverAndParameterTypes(declaration, candidates);
if (candidates.size() <= 1) {
return candidates.isEmpty() ? null : candidates.iterator().next();
}
}
}
KotlinCodeAnalyzer analyzer = createAnalyzer(candidates, declaration.getProject());
for (KtNamedDeclaration candidate : candidates) {
//noinspection unchecked
CallableDescriptor candidateDescriptor = (CallableDescriptor) analyzer.resolveToDescriptor(candidate);
if (receiversMatch(declaration, candidateDescriptor) && valueParametersTypesMatch(declaration, candidateDescriptor) && typeParametersMatch((KtTypeParameterListOwner) declaration, candidateDescriptor.getTypeParameters())) {
return candidate;
}
}
return null;
}
use of org.jetbrains.kotlin.descriptors.CallableDescriptor in project kotlin by JetBrains.
the class QuickFixUtil method getDeclarationReturnType.
@Nullable
public static KotlinType getDeclarationReturnType(KtNamedDeclaration declaration) {
PsiFile file = declaration.getContainingFile();
if (!(file instanceof KtFile))
return null;
DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration, BodyResolveMode.FULL);
if (!(descriptor instanceof CallableDescriptor))
return null;
KotlinType type = ((CallableDescriptor) descriptor).getReturnType();
if (type instanceof DeferredType) {
type = ((DeferredType) type).getDelegate();
}
return type;
}
use of org.jetbrains.kotlin.descriptors.CallableDescriptor in project kotlin by JetBrains.
the class TailRecursionCodegen method generateTailRecursion.
public void generateTailRecursion(ResolvedCall<?> resolvedCall) {
CallableDescriptor fd = CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(resolvedCall.getResultingDescriptor());
assert fd instanceof FunctionDescriptor : "Resolved call doesn't refer to the function descriptor: " + fd;
CallableMethod callable = (CallableMethod) codegen.resolveToCallable((FunctionDescriptor) fd, false, resolvedCall);
List<ResolvedValueArgument> arguments = resolvedCall.getValueArgumentsByIndex();
if (arguments == null) {
throw new IllegalStateException("Failed to arrange value arguments by index: " + fd);
}
if (((FunctionDescriptor) fd).isSuspend()) {
AsmUtil.pop(v, callable.getValueParameters().get(callable.getValueParameters().size() - 1).getAsmType());
}
assignParameterValues(fd, callable, arguments);
if (callable.getExtensionReceiverType() != null) {
if (resolvedCall.getExtensionReceiver() != fd.getExtensionReceiverParameter().getValue()) {
StackValue expression = context.getReceiverExpression(codegen.typeMapper);
expression.store(StackValue.onStack(callable.getExtensionReceiverType()), v, true);
} else {
AsmUtil.pop(v, callable.getExtensionReceiverType());
}
}
if (callable.getDispatchReceiverType() != null) {
AsmUtil.pop(v, callable.getDispatchReceiverType());
}
v.goTo(context.getMethodStartLabel());
}
use of org.jetbrains.kotlin.descriptors.CallableDescriptor in project kotlin by JetBrains.
the class JsInliner method reportInlineCycle.
private void reportInlineCycle(@NotNull JsInvocation call, @NotNull JsFunction calledFunction) {
MetadataProperties.setInlineStrategy(call, InlineStrategy.NOT_INLINE);
Iterator<JsCallInfo> it = inlineCallInfos.descendingIterator();
while (it.hasNext()) {
JsCallInfo callInfo = it.next();
PsiElement psiElement = MetadataProperties.getPsiElement(callInfo.call);
CallableDescriptor descriptor = MetadataProperties.getDescriptor(callInfo.call);
if (psiElement != null && descriptor != null) {
trace.report(Errors.INLINE_CALL_CYCLE.on(psiElement, descriptor));
}
if (callInfo.containingFunction == calledFunction) {
break;
}
}
}
Aggregations