Refactoring: store information about registered redeclaration errors for element
This commit is contained in:
@@ -26,7 +26,6 @@ import com.intellij.lang.annotation.Annotator;
|
|||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
import com.intellij.openapi.util.Ref;
|
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.psi.MultiRangeReference;
|
import com.intellij.psi.MultiRangeReference;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
@@ -116,9 +115,9 @@ public class JetPsiChecker implements Annotator, HighlightRangeExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (JetPluginUtil.isInSource(element, /* includeLibrarySources = */ false)) {
|
if (JetPluginUtil.isInSource(element, /* includeLibrarySources = */ false)) {
|
||||||
Ref<Boolean> isMarkedWithRedeclaration = Ref.create(false);
|
ElementAnnotator elementAnnotator = new ElementAnnotator(element, holder);
|
||||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics().forElement(element)) {
|
for (Diagnostic diagnostic : bindingContext.getDiagnostics().forElement(element)) {
|
||||||
registerDiagnosticAnnotations(element, diagnostic, holder, isMarkedWithRedeclaration);
|
elementAnnotator.registerDiagnosticAnnotations(diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,141 +132,150 @@ public class JetPsiChecker implements Annotator, HighlightRangeExtension {
|
|||||||
return file instanceof JetFile;
|
return file instanceof JetFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerDiagnosticAnnotations(
|
private static class ElementAnnotator {
|
||||||
@NotNull PsiElement element, @NotNull Diagnostic diagnostic,
|
@NotNull private final PsiElement element;
|
||||||
@NotNull AnnotationHolder holder, Ref<Boolean> isMarkedWithRedeclaration
|
@NotNull private final AnnotationHolder holder;
|
||||||
) {
|
|
||||||
if (!diagnostic.isValid()) return;
|
|
||||||
|
|
||||||
assert diagnostic.getPsiElement() == element;
|
private boolean isMarkedWithRedeclaration;
|
||||||
|
|
||||||
List<TextRange> textRanges = diagnostic.getTextRanges();
|
ElementAnnotator(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
||||||
if (diagnostic.getSeverity() == Severity.ERROR) {
|
this.element = element;
|
||||||
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
|
this.holder = holder;
|
||||||
JetReferenceExpression referenceExpression = (JetReferenceExpression)diagnostic.getPsiElement();
|
}
|
||||||
PsiReference reference = referenceExpression.getReference();
|
|
||||||
if (reference instanceof MultiRangeReference) {
|
void registerDiagnosticAnnotations(@NotNull Diagnostic diagnostic) {
|
||||||
MultiRangeReference mrr = (MultiRangeReference)reference;
|
if (!diagnostic.isValid()) return;
|
||||||
for (TextRange range : mrr.getRanges()) {
|
|
||||||
Annotation annotation = holder.createErrorAnnotation(range.shiftRight(referenceExpression.getTextOffset()), getDefaultMessage(diagnostic));
|
assert diagnostic.getPsiElement() == element;
|
||||||
setUpAnnotation(diagnostic, annotation, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
|
||||||
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
|
if (diagnostic.getSeverity() == Severity.ERROR) {
|
||||||
|
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
|
||||||
|
JetReferenceExpression referenceExpression = (JetReferenceExpression)diagnostic.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()), getDefaultMessage(diagnostic));
|
||||||
|
setUpAnnotation(diagnostic, annotation, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
for (TextRange textRange : textRanges) {
|
||||||
|
Annotation annotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
|
||||||
|
setUpAnnotation(diagnostic, annotation, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
for (TextRange textRange : textRanges) {
|
if (diagnostic.getFactory() == Errors.ILLEGAL_ESCAPE) {
|
||||||
|
for (TextRange textRange : diagnostic.getTextRanges()) {
|
||||||
Annotation annotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
|
Annotation annotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
|
||||||
setUpAnnotation(diagnostic, annotation, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
annotation.setTooltip(getMessage(diagnostic));
|
||||||
|
annotation.setTextAttributes(JetHighlightingColors.INVALID_STRING_ESCAPE);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
if (!isMarkedWithRedeclaration && Errors.REDECLARATION_DIAGNOSTICS.contains(diagnostic.getFactory())) {
|
||||||
}
|
isMarkedWithRedeclaration = true;
|
||||||
|
Annotation annotation = holder.createErrorAnnotation(diagnostic.getTextRanges().get(0), "");
|
||||||
if (diagnostic.getFactory() == Errors.ILLEGAL_ESCAPE) {
|
setUpAnnotation(diagnostic, annotation, null);
|
||||||
for (TextRange textRange : diagnostic.getTextRanges()) {
|
return;
|
||||||
Annotation annotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
|
|
||||||
annotation.setTooltip(getMessage(diagnostic));
|
|
||||||
annotation.setTextAttributes(JetHighlightingColors.INVALID_STRING_ESCAPE);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isMarkedWithRedeclaration.get() && Errors.REDECLARATION_DIAGNOSTICS.contains(diagnostic.getFactory())) {
|
// Generic annotation
|
||||||
isMarkedWithRedeclaration.set(true);
|
for (TextRange textRange : textRanges) {
|
||||||
Annotation annotation = holder.createErrorAnnotation(diagnostic.getTextRanges().get(0), "");
|
Annotation errorAnnotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
|
||||||
setUpAnnotation(diagnostic, annotation, null);
|
setUpAnnotation(diagnostic, errorAnnotation,
|
||||||
return;
|
diagnostic.getFactory() == Errors.INVISIBLE_REFERENCE
|
||||||
}
|
|
||||||
|
|
||||||
// Generic annotation
|
|
||||||
for (TextRange textRange : textRanges) {
|
|
||||||
Annotation errorAnnotation = holder.createErrorAnnotation(textRange, getDefaultMessage(diagnostic));
|
|
||||||
setUpAnnotation(diagnostic, errorAnnotation,
|
|
||||||
diagnostic.getFactory() == Errors.INVISIBLE_REFERENCE
|
|
||||||
? ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
|
? ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
|
||||||
: null);
|
: null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (diagnostic.getSeverity() == Severity.WARNING) {
|
||||||
else if (diagnostic.getSeverity() == Severity.WARNING) {
|
for (TextRange textRange : textRanges) {
|
||||||
for (TextRange textRange : textRanges) {
|
Annotation annotation = holder.createWarningAnnotation(textRange, getDefaultMessage(diagnostic));
|
||||||
Annotation annotation = holder.createWarningAnnotation(textRange, getDefaultMessage(diagnostic));
|
setUpAnnotation(diagnostic, annotation,
|
||||||
setUpAnnotation(diagnostic, annotation,
|
Errors.UNUSED_ELEMENT_DIAGNOSTICS.contains(diagnostic.getFactory())
|
||||||
Errors.UNUSED_ELEMENT_DIAGNOSTICS.contains(diagnostic.getFactory())
|
|
||||||
? ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
? ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
||||||
: null);
|
: null);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setUpAnnotation(Diagnostic diagnostic, Annotation annotation, @Nullable ProblemHighlightType highlightType) {
|
|
||||||
annotation.setTooltip(getMessage(diagnostic));
|
|
||||||
registerQuickFix(annotation, diagnostic);
|
|
||||||
|
|
||||||
if (highlightType != null) {
|
|
||||||
annotation.setHighlightType(highlightType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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<JetIntentionActionsFactory> intentionActionsFactories = QuickFixes.getActionsFactories(diagnostic.getFactory());
|
|
||||||
for (JetIntentionActionsFactory intentionActionsFactory : intentionActionsFactories) {
|
|
||||||
if (intentionActionsFactory != null) {
|
|
||||||
for (IntentionAction action: intentionActionsFactory.createActions(diagnostic)) {
|
|
||||||
annotation.registerFix(action);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<IntentionAction> actions = QuickFixes.getActions(diagnostic.getFactory());
|
private static void setUpAnnotation(Diagnostic diagnostic, Annotation annotation, @Nullable ProblemHighlightType highlightType) {
|
||||||
for (IntentionAction action : actions) {
|
annotation.setTooltip(getMessage(diagnostic));
|
||||||
annotation.registerFix(action);
|
registerQuickFix(annotation, diagnostic);
|
||||||
}
|
|
||||||
|
|
||||||
// Making warnings suppressable
|
if (highlightType != null) {
|
||||||
if (diagnostic.getSeverity() == Severity.WARNING) {
|
annotation.setHighlightType(highlightType);
|
||||||
annotation.setProblemGroup(new KotlinSuppressableWarningProblemGroup(diagnostic.getFactory()));
|
|
||||||
|
|
||||||
List<Annotation.QuickFixInfo> fixes = annotation.getQuickFixes();
|
|
||||||
if (fixes == null || fixes.isEmpty()) {
|
|
||||||
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
|
|
||||||
annotation.registerFix(new EmptyIntentionAction(diagnostic.getFactory().getName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return annotation;
|
/*
|
||||||
}
|
* Add a quick fix if and return modified annotation.
|
||||||
|
*/
|
||||||
@NotNull
|
@Nullable
|
||||||
private static String getMessage(@NotNull Diagnostic diagnostic) {
|
private static Annotation registerQuickFix(@Nullable Annotation annotation, @NotNull Diagnostic diagnostic) {
|
||||||
String message = IdeErrorMessages.RENDERER.render(diagnostic);
|
if (annotation == null) {
|
||||||
if (ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isUnitTestMode()) {
|
return null;
|
||||||
String factoryName = diagnostic.getFactory().getName();
|
|
||||||
if (message.startsWith("<html>")) {
|
|
||||||
message = String.format("<html>[%s] %s", factoryName, message.substring("<html>".length()));
|
|
||||||
} else {
|
|
||||||
message = String.format("[%s] %s", factoryName, message);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!message.startsWith("<html>")) {
|
|
||||||
message = "<html><body>" + XmlStringUtil.escapeString(message) + "</body></html>";
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
Collection<JetIntentionActionsFactory> intentionActionsFactories = QuickFixes.getActionsFactories(diagnostic.getFactory());
|
||||||
private static String getDefaultMessage(@NotNull Diagnostic diagnostic) {
|
for (JetIntentionActionsFactory intentionActionsFactory : intentionActionsFactories) {
|
||||||
String message = DefaultErrorMessages.RENDERER.render(diagnostic);
|
if (intentionActionsFactory != null) {
|
||||||
if (ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isUnitTestMode()) {
|
for (IntentionAction action: intentionActionsFactory.createActions(diagnostic)) {
|
||||||
return String.format("[%s] %s", diagnostic.getFactory().getName(), message);
|
annotation.registerFix(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<IntentionAction> actions = QuickFixes.getActions(diagnostic.getFactory());
|
||||||
|
for (IntentionAction action : actions) {
|
||||||
|
annotation.registerFix(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Making warnings suppressable
|
||||||
|
if (diagnostic.getSeverity() == Severity.WARNING) {
|
||||||
|
annotation.setProblemGroup(new KotlinSuppressableWarningProblemGroup(diagnostic.getFactory()));
|
||||||
|
|
||||||
|
List<Annotation.QuickFixInfo> fixes = annotation.getQuickFixes();
|
||||||
|
if (fixes == null || fixes.isEmpty()) {
|
||||||
|
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
|
||||||
|
annotation.registerFix(new EmptyIntentionAction(diagnostic.getFactory().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return annotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getMessage(@NotNull Diagnostic diagnostic) {
|
||||||
|
String message = IdeErrorMessages.RENDERER.render(diagnostic);
|
||||||
|
if (ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
|
String factoryName = diagnostic.getFactory().getName();
|
||||||
|
if (message.startsWith("<html>")) {
|
||||||
|
message = String.format("<html>[%s] %s", factoryName, message.substring("<html>".length()));
|
||||||
|
} else {
|
||||||
|
message = String.format("[%s] %s", factoryName, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!message.startsWith("<html>")) {
|
||||||
|
message = "<html><body>" + XmlStringUtil.escapeString(message) + "</body></html>";
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getDefaultMessage(@NotNull Diagnostic diagnostic) {
|
||||||
|
String message = DefaultErrorMessages.RENDERER.render(diagnostic);
|
||||||
|
if (ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
|
return String.format("[%s] %s", diagnostic.getFactory().getName(), message);
|
||||||
|
}
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user