Search in sources :

Example 1 with CallableDescriptor

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;
        }
    });
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) Diagnostic(org.jetbrains.kotlin.diagnostics.Diagnostic) VariableDescriptor(org.jetbrains.kotlin.descriptors.VariableDescriptor) CallableDescriptor(org.jetbrains.kotlin.descriptors.CallableDescriptor) PsiElement(com.intellij.psi.PsiElement) PropertyDescriptor(org.jetbrains.kotlin.descriptors.PropertyDescriptor) DiagnosticFactory(org.jetbrains.kotlin.diagnostics.DiagnosticFactory) IElementType(com.intellij.psi.tree.IElementType) ResolvedCall(org.jetbrains.kotlin.resolve.calls.model.ResolvedCall) DeclarationDescriptor(org.jetbrains.kotlin.descriptors.DeclarationDescriptor) Collection(java.util.Collection)

Example 2 with CallableDescriptor

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;
}
Also used : KotlinCodeAnalyzer(org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer) FqName(org.jetbrains.kotlin.name.FqName) Name(org.jetbrains.kotlin.name.Name) PsiClass(com.intellij.psi.PsiClass) LightClassUtilsKt.toLightClass(org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass) CallableDescriptor(org.jetbrains.kotlin.descriptors.CallableDescriptor) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with CallableDescriptor

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;
}
Also used : DeferredType(org.jetbrains.kotlin.types.DeferredType) DeclarationDescriptor(org.jetbrains.kotlin.descriptors.DeclarationDescriptor) KotlinType(org.jetbrains.kotlin.types.KotlinType) PsiFile(com.intellij.psi.PsiFile) CallableDescriptor(org.jetbrains.kotlin.descriptors.CallableDescriptor) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with CallableDescriptor

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());
}
Also used : FunctionDescriptor(org.jetbrains.kotlin.descriptors.FunctionDescriptor) CallableDescriptor(org.jetbrains.kotlin.descriptors.CallableDescriptor)

Example 5 with CallableDescriptor

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;
        }
    }
}
Also used : CallableDescriptor(org.jetbrains.kotlin.descriptors.CallableDescriptor) PsiElement(com.intellij.psi.PsiElement)

Aggregations

CallableDescriptor (org.jetbrains.kotlin.descriptors.CallableDescriptor)5 PsiElement (com.intellij.psi.PsiElement)3 Nullable (org.jetbrains.annotations.Nullable)2 DeclarationDescriptor (org.jetbrains.kotlin.descriptors.DeclarationDescriptor)2 KotlinType (org.jetbrains.kotlin.types.KotlinType)2 PsiClass (com.intellij.psi.PsiClass)1 PsiFile (com.intellij.psi.PsiFile)1 IElementType (com.intellij.psi.tree.IElementType)1 Collection (java.util.Collection)1 LightClassUtilsKt.toLightClass (org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass)1 FunctionDescriptor (org.jetbrains.kotlin.descriptors.FunctionDescriptor)1 PropertyDescriptor (org.jetbrains.kotlin.descriptors.PropertyDescriptor)1 VariableDescriptor (org.jetbrains.kotlin.descriptors.VariableDescriptor)1 Diagnostic (org.jetbrains.kotlin.diagnostics.Diagnostic)1 DiagnosticFactory (org.jetbrains.kotlin.diagnostics.DiagnosticFactory)1 FqName (org.jetbrains.kotlin.name.FqName)1 Name (org.jetbrains.kotlin.name.Name)1 ResolvedCall (org.jetbrains.kotlin.resolve.calls.model.ResolvedCall)1 KotlinCodeAnalyzer (org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer)1 DeferredType (org.jetbrains.kotlin.types.DeferredType)1