private static void checkForUnexpectedErrors() { AnalyzeExhaust exhaust = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) getFile()); Collection<Diagnostic> diagnostics = exhaust.getBindingContext().getDiagnostics(); if (diagnostics.size() != 0) { String[] expectedErrorStrings = InTextDirectivesUtils.findListWithPrefix("// ERROR:", getFile().getText()); System.out.println(getFile().getText()); Collection<String> expectedErrors = new HashSet<String>(Arrays.asList(expectedErrorStrings)); StringBuilder builder = new StringBuilder(); boolean hasErrors = false; for (Diagnostic diagnostic : diagnostics) { if (diagnostic.getSeverity() == Severity.ERROR) { String errorText = IdeErrorMessages.RENDERER.render(diagnostic); if (!expectedErrors.contains(errorText)) { hasErrors = true; builder.append("// ERROR: ").append(errorText).append("\n"); } } } Assert.assertFalse( "There should be no unexpected errors after applying fix (Use \"// ERROR:\" directive): \n" + builder.toString(), hasErrors); } }
@SuppressWarnings({"unchecked", "ConstantConditions"}) private static void checkResolvedCallsInDiagnostics(BindingContext bindingContext) { Set<DiagnosticFactory> diagnosticsStoringResolvedCalls1 = Sets.<DiagnosticFactory>newHashSet( OVERLOAD_RESOLUTION_AMBIGUITY, NONE_APPLICABLE, CANNOT_COMPLETE_RESOLVE, UNRESOLVED_REFERENCE_WRONG_RECEIVER, ASSIGN_OPERATOR_AMBIGUITY, ITERATOR_AMBIGUITY); Set<DiagnosticFactory> diagnosticsStoringResolvedCalls2 = Sets.<DiagnosticFactory>newHashSet( COMPONENT_FUNCTION_AMBIGUITY, DELEGATE_SPECIAL_FUNCTION_AMBIGUITY, DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE); Diagnostics diagnostics = bindingContext.getDiagnostics(); for (Diagnostic diagnostic : diagnostics) { DiagnosticFactory factory = diagnostic.getFactory(); if (diagnosticsStoringResolvedCalls1.contains(factory)) { assertResolvedCallsAreCompleted( diagnostic, ((DiagnosticWithParameters1<PsiElement, Collection<? extends ResolvedCall<?>>>) diagnostic) .getA()); } if (diagnosticsStoringResolvedCalls2.contains(factory)) { assertResolvedCallsAreCompleted( diagnostic, ((DiagnosticWithParameters2<PsiElement, Object, Collection<? extends ResolvedCall<?>>>) diagnostic) .getB()); } } }
private static void assertResolvedCallsAreCompleted( @NotNull Diagnostic diagnostic, @NotNull Collection<? extends ResolvedCall<?>> resolvedCalls) { boolean allCallsAreCompleted = true; for (ResolvedCall<?> resolvedCall : resolvedCalls) { if (!((MutableResolvedCall<?>) resolvedCall).isCompleted()) { allCallsAreCompleted = false; } } PsiElement element = diagnostic.getPsiElement(); DiagnosticUtils.LineAndColumn lineAndColumn = DiagnosticUtils.getLineAndColumnInPsiFile( element.getContainingFile(), element.getTextRange()); assertTrue( "Resolved calls stored in " + diagnostic.getFactory().getName() + "\n" + "for '" + element.getText() + "'" + lineAndColumn + " are not completed", allCallsAreCompleted); }
/* * Add a quick fix if and return modified annotation. */ @Nullable private static Annotation registerQuickFix( @Nullable Annotation annotation, @NotNull Diagnostic diagnostic) { if (annotation == null) { return null; } Collection<JetIntentionActionFactory> intentionActionFactories = QuickFixes.getActionFactories(diagnostic.getFactory()); for (JetIntentionActionFactory intentionActionFactory : intentionActionFactories) { IntentionAction action = null; if (intentionActionFactory != null) { action = intentionActionFactory.createAction(diagnostic); } if (action != null) { annotation.registerFix(action); } } Collection<IntentionAction> actions = QuickFixes.getActions(diagnostic.getFactory()); for (IntentionAction action : actions) { annotation.registerFix(action); } return annotation; }
@NotNull private static String getMessage(@NotNull Diagnostic diagnostic) { if (ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isUnitTestMode()) { return "[" + diagnostic.getFactory().getName() + "] " + diagnostic.getMessage(); } return diagnostic.getMessage(); }
@Override public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) { for (HighlightingVisitor visitor : getBeforeAnalysisVisitors(holder)) { element.accept(visitor); } if (element instanceof JetFile) { JetFile file = (JetFile) element; try { BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext(); if (errorReportingEnabled) { Collection<Diagnostic> diagnostics = Sets.newLinkedHashSet(bindingContext.getDiagnostics()); Set<PsiElement> redeclarations = Sets.newHashSet(); for (Diagnostic diagnostic : diagnostics) { // This is needed because we have the same context for all files if (diagnostic.getPsiFile() != file) continue; registerDiagnosticAnnotations(diagnostic, redeclarations, holder); } } for (HighlightingVisitor visitor : getAfterAnalysisVisitor(holder, bindingContext)) { file.acceptChildren(visitor); } } catch (ProcessCanceledException e) { throw e; } catch (AssertionError e) { // For failing tests and to notify about idea internal error in -ea mode holder.createErrorAnnotation( element, e.getClass().getCanonicalName() + ": " + e.getMessage()); throw e; } catch (Throwable e) { // TODO holder.createErrorAnnotation( element, e.getClass().getCanonicalName() + ": " + e.getMessage()); e.printStackTrace(); } } }
private static void checkNoUnresolvedReferences(@NotNull final JetFile file) { AnalyzeExhaust exhaust = AnalyzerFacadeWithCache.analyzeFileWithCache(file); for (Diagnostic diagnostic : exhaust.getBindingContext().getDiagnostics()) { if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) { List<TextRange> textRanges = diagnostic.getTextRanges(); String diagnosticText = DefaultErrorMessages.RENDERER.render(diagnostic); if (diagnostic.getPsiFile() == file) { fail( diagnostic.getFactory().getName() + ": " + diagnosticText + " " + DiagnosticUtils.atLocation(file, textRanges.get(0))); } } } DebugInfoUtil.markDebugAnnotations( file, exhaust.getBindingContext(), new DebugInfoUtil.DebugInfoReporter() { @Override public void reportElementWithErrorType(@NotNull JetReferenceExpression expression) { // do nothing } @Override public void reportMissingUnresolved(@NotNull JetReferenceExpression expression) { // this may happen if incorrect psi transformations are done fail( expression.getText() + " is unresolved but not marked " + DiagnosticUtils.atLocation(file, expression.getTextRange())); } @Override public void reportUnresolvedWithTarget( @NotNull JetReferenceExpression expression, @NotNull String target) { // do nothing } }); }
private static void registerDiagnosticAnnotations( @NotNull Diagnostic diagnostic, @NotNull Set<PsiElement> redeclarations, @NotNull final AnnotationHolder holder) { List<TextRange> textRanges = diagnostic.getTextRanges(); if (diagnostic.getSeverity() == Severity.ERROR) { if (diagnostic.getFactory() == Errors.UNRESOLVED_IDE_TEMPLATE) { return; } if (diagnostic instanceof UnresolvedReferenceDiagnostic) { UnresolvedReferenceDiagnostic unresolvedReferenceDiagnostic = (UnresolvedReferenceDiagnostic) diagnostic; JetReferenceExpression referenceExpression = unresolvedReferenceDiagnostic.getPsiElement(); PsiReference reference = referenceExpression.getReference(); if (reference instanceof MultiRangeReference) { MultiRangeReference mrr = (MultiRangeReference) reference; for (TextRange range : mrr.getRanges()) { Annotation annotation = holder.createErrorAnnotation( range.shiftRight(referenceExpression.getTextOffset()), diagnostic.getMessage()); registerQuickFix(annotation, diagnostic); annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); } } else { for (TextRange textRange : textRanges) { Annotation annotation = holder.createErrorAnnotation(textRange, diagnostic.getMessage()); registerQuickFix(annotation, diagnostic); annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); } } return; } if (diagnostic.getFactory() == Errors.ILLEGAL_ESCAPE_SEQUENCE) { for (TextRange textRange : diagnostic.getTextRanges()) { Annotation annotation = holder.createErrorAnnotation(textRange, diagnostic.getMessage()); annotation.setTextAttributes(JetHighlightingColors.INVALID_STRING_ESCAPE); } } if (diagnostic instanceof RedeclarationDiagnostic) { RedeclarationDiagnostic redeclarationDiagnostic = (RedeclarationDiagnostic) diagnostic; registerQuickFix( markRedeclaration(redeclarations, redeclarationDiagnostic, holder), diagnostic); return; } // Generic annotation for (TextRange textRange : textRanges) { Annotation errorAnnotation = holder.createErrorAnnotation(textRange, getMessage(diagnostic)); registerQuickFix(errorAnnotation, diagnostic); if (diagnostic.getFactory() == Errors.INVISIBLE_REFERENCE) { errorAnnotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); } } } else if (diagnostic.getSeverity() == Severity.WARNING) { for (TextRange textRange : textRanges) { Annotation annotation = holder.createWarningAnnotation(textRange, getMessage(diagnostic)); registerQuickFix(annotation, diagnostic); if (diagnostic.getFactory() instanceof UnusedElementDiagnosticFactory) { annotation.setHighlightType(ProblemHighlightType.LIKE_UNUSED_SYMBOL); } } } }