Search in sources :

Example 1 with DiagnosticFactory

use of org.jetbrains.kotlin.diagnostics.DiagnosticFactory 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 DiagnosticFactory

use of org.jetbrains.kotlin.diagnostics.DiagnosticFactory in project kotlin by JetBrains.

the class AbstractDiagnosticMessageTest method doTest.

public void doTest(String filePath) throws Exception {
    File file = new File(filePath);
    String fileName = file.getName();
    String fileData = KotlinTestUtils.doLoadFile(file);
    Map<String, String> directives = KotlinTestUtils.parseDirectives(fileData);
    int diagnosticNumber = getDiagnosticNumber(directives);
    final Set<DiagnosticFactory<?>> diagnosticFactories = getDiagnosticFactories(directives);
    MessageType messageType = getMessageTypeDirective(directives);
    String explicitLanguageVersion = InTextDirectivesUtils.findStringWithPrefixes(fileData, "// LANGUAGE_VERSION:");
    LanguageVersion version = explicitLanguageVersion == null ? null : LanguageVersion.fromVersionString(explicitLanguageVersion);
    KtFile psiFile = KotlinTestUtils.createFile(fileName, KotlinTestUtils.doLoadFile(getTestDataPath(), fileName), getProject());
    AnalysisResult analysisResult = analyze(psiFile, version);
    BindingContext bindingContext = analysisResult.getBindingContext();
    List<Diagnostic> diagnostics = ContainerUtil.filter(bindingContext.getDiagnostics().all(), new Condition<Diagnostic>() {

        @Override
        public boolean value(Diagnostic diagnostic) {
            return diagnosticFactories.contains(diagnostic.getFactory());
        }
    });
    assertEquals("Expected diagnostics number mismatch:", diagnosticNumber, diagnostics.size());
    int index = 1;
    String name = FileUtil.getNameWithoutExtension(fileName);
    for (Diagnostic diagnostic : diagnostics) {
        String readableDiagnosticText;
        String extension;
        if (messageType != MessageType.TEXT && IdeErrorMessages.hasIdeSpecificMessage(diagnostic)) {
            readableDiagnosticText = FormatHtmlUtilKt.formatHtml(IdeErrorMessages.render(diagnostic));
            extension = MessageType.HTML.extension;
        } else {
            readableDiagnosticText = DefaultErrorMessages.render(diagnostic);
            extension = MessageType.TEXT.extension;
        }
        String errorMessageFileName = name + index;
        String path = getTestDataPath() + "/" + errorMessageFileName + "." + extension;
        String actualText = "<!-- " + errorMessageFileName + " -->\n" + readableDiagnosticText;
        assertSameLinesWithFile(path, actualText);
        index++;
    }
}
Also used : Diagnostic(org.jetbrains.kotlin.diagnostics.Diagnostic) BindingContext(org.jetbrains.kotlin.resolve.BindingContext) AnalysisResult(org.jetbrains.kotlin.analyzer.AnalysisResult) DiagnosticFactory(org.jetbrains.kotlin.diagnostics.DiagnosticFactory) LanguageVersion(org.jetbrains.kotlin.config.LanguageVersion) KtFile(org.jetbrains.kotlin.psi.KtFile) KtFile(org.jetbrains.kotlin.psi.KtFile) File(java.io.File)

Aggregations

Diagnostic (org.jetbrains.kotlin.diagnostics.Diagnostic)2 DiagnosticFactory (org.jetbrains.kotlin.diagnostics.DiagnosticFactory)2 PsiElement (com.intellij.psi.PsiElement)1 IElementType (com.intellij.psi.tree.IElementType)1 File (java.io.File)1 Collection (java.util.Collection)1 AnalysisResult (org.jetbrains.kotlin.analyzer.AnalysisResult)1 LanguageVersion (org.jetbrains.kotlin.config.LanguageVersion)1 CallableDescriptor (org.jetbrains.kotlin.descriptors.CallableDescriptor)1 DeclarationDescriptor (org.jetbrains.kotlin.descriptors.DeclarationDescriptor)1 PropertyDescriptor (org.jetbrains.kotlin.descriptors.PropertyDescriptor)1 VariableDescriptor (org.jetbrains.kotlin.descriptors.VariableDescriptor)1 KtFile (org.jetbrains.kotlin.psi.KtFile)1 BindingContext (org.jetbrains.kotlin.resolve.BindingContext)1 ResolvedCall (org.jetbrains.kotlin.resolve.calls.model.ResolvedCall)1 KotlinType (org.jetbrains.kotlin.types.KotlinType)1