Reload rendrer when application changes (for tests)

This commit is contained in:
Alexey Tsvetkov
2014-12-12 20:43:31 +03:00
parent c78b199c0a
commit 669cbb203b
15 changed files with 97 additions and 40 deletions
@@ -90,7 +90,7 @@ public final class AnalyzerWithCompilerReport {
render = ((MyDiagnostic)diagnostic).message; render = ((MyDiagnostic)diagnostic).message;
} }
else { else {
render = DefaultErrorMessages.RENDERER.render(diagnostic); render = DefaultErrorMessages.render(diagnostic);
} }
PsiFile file = diagnostic.getPsiFile(); PsiFile file = diagnostic.getPsiFile();
messageCollector.report(convertSeverity(diagnostic.getSeverity()), render, messageCollector.report(convertSeverity(diagnostic.getSeverity()), render,
@@ -611,7 +611,7 @@ public class CheckerTestUtil {
@NotNull @NotNull
public static TextDiagnostic asTextDiagnostic(@NotNull Diagnostic diagnostic) { public static TextDiagnostic asTextDiagnostic(@NotNull Diagnostic diagnostic) {
DiagnosticRenderer renderer = getRenderer(diagnostic); DiagnosticRenderer renderer = DefaultErrorMessages.getRendererForDiagnostic(diagnostic);
String diagnosticName = diagnostic.getFactory().getName(); String diagnosticName = diagnostic.getFactory().getName();
if (renderer instanceof AbstractDiagnosticWithParametersRenderer) { if (renderer instanceof AbstractDiagnosticWithParametersRenderer) {
//noinspection unchecked //noinspection unchecked
@@ -627,17 +627,6 @@ public class CheckerTestUtil {
return new TextDiagnostic(diagnosticName, null); return new TextDiagnostic(diagnosticName, null);
} }
@Nullable
private static DiagnosticRenderer getRenderer(@NotNull Diagnostic diagnostic) {
for (DiagnosticFactoryToRendererMap map : DefaultErrorMessages.MAPS) {
DiagnosticRenderer renderer = map.get(diagnostic.getFactory());
if (renderer != null)
return renderer;
}
return null;
}
@NotNull @NotNull
private final String name; private final String name;
@Nullable @Nullable
@@ -35,7 +35,7 @@ public interface DiagnosticSink {
if (diagnostic.getSeverity() == Severity.ERROR) { if (diagnostic.getSeverity() == Severity.ERROR) {
PsiFile psiFile = diagnostic.getPsiFile(); PsiFile psiFile = diagnostic.getPsiFile();
List<TextRange> textRanges = diagnostic.getTextRanges(); List<TextRange> textRanges = diagnostic.getTextRanges();
String diagnosticText = DefaultErrorMessages.RENDERER.render(diagnostic); String diagnosticText = DefaultErrorMessages.render(diagnostic);
throw new IllegalStateException(diagnostic.getFactory().getName() + ": " + diagnosticText + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0))); throw new IllegalStateException(diagnostic.getFactory().getName() + ": " + diagnosticText + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
} }
} }
@@ -17,11 +17,15 @@
package org.jetbrains.jet.lang.diagnostics.rendering; package org.jetbrains.jet.lang.diagnostics.rendering;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.extensions.Extensions;
import kotlin.Function1; import kotlin.Function1;
import kotlin.KotlinPackage; import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory; import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
@@ -54,9 +58,42 @@ public class DefaultErrorMessages {
} }
private static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap(); private static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap();
public static final List<DiagnosticFactoryToRendererMap> MAPS = ImmutableList.<DiagnosticFactoryToRendererMap>builder() private static List<DiagnosticFactoryToRendererMap> maps = null;
.addAll( private static Application application = ApplicationManager.getApplication();
KotlinPackage.map( private static DispatchingDiagnosticRenderer renderer = null;
@NotNull
public static String render(@NotNull Diagnostic diagnostic) {
return getRenderer().render(diagnostic);
}
@NotNull
private static DiagnosticRenderer<Diagnostic> getRenderer() {
boolean mapsChanged = resetMapsIfNeeded();
// Renderer is changed in tests only
if (renderer == null || mapsChanged) {
renderer = new DispatchingDiagnosticRenderer(maps);
}
return renderer;
}
private static boolean resetMapsIfNeeded() {
boolean needToResetMaps = maps == null;
Application newApp = ApplicationManager.getApplication();
if (application != newApp) {
assert newApp.isUnitTestMode(): "Expected application switch only in tests";
application = newApp;
needToResetMaps = true;
}
if (!needToResetMaps) return false;
maps = ImmutableList.<DiagnosticFactoryToRendererMap>builder()
.addAll(
KotlinPackage.map(
Extensions.getExtensions(Extension.EP_NAME), Extensions.getExtensions(Extension.EP_NAME),
new Function1<Extension, DiagnosticFactoryToRendererMap>() { new Function1<Extension, DiagnosticFactoryToRendererMap>() {
@Override @Override
@@ -64,15 +101,27 @@ public class DefaultErrorMessages {
return extension.getMap(); return extension.getMap();
} }
} }
) )
) )
.add(MAP) .add(MAP)
.build(); .build();
public static final DiagnosticRenderer<Diagnostic> RENDERER = new DispatchingDiagnosticRenderer(MAPS); return true;
}
@TestOnly
@Nullable
public static DiagnosticRenderer getRendererForDiagnostic(@NotNull Diagnostic diagnostic) {
for (DiagnosticFactoryToRendererMap map : maps) {
DiagnosticRenderer renderer = map.get(diagnostic.getFactory());
if (renderer != null) return renderer;
}
return null;
}
static { static {
MAP.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", ELEMENT_TEXT); MAP.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", ELEMENT_TEXT);
MAP.put(INVISIBLE_REFERENCE, "Cannot access ''{0}'': it is ''{1}'' in ''{2}''", NAME, TO_STRING, NAME); MAP.put(INVISIBLE_REFERENCE, "Cannot access ''{0}'': it is ''{1}'' in ''{2}''", NAME, TO_STRING, NAME);
@@ -568,6 +617,8 @@ public class DefaultErrorMessages {
} }
} }
} }
resetMapsIfNeeded();
} }
private DefaultErrorMessages() { private DefaultErrorMessages() {
@@ -22,9 +22,10 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import java.util.List; import java.util.List;
public class DispatchingDiagnosticRenderer implements DiagnosticRenderer<Diagnostic> { public class DispatchingDiagnosticRenderer implements DiagnosticRenderer<Diagnostic> {
@NotNull
private final List<DiagnosticFactoryToRendererMap> maps; private final List<DiagnosticFactoryToRendererMap> maps;
public DispatchingDiagnosticRenderer(List<DiagnosticFactoryToRendererMap> maps) { public DispatchingDiagnosticRenderer(@NotNull List<DiagnosticFactoryToRendererMap> maps) {
this.maps = maps; this.maps = maps;
} }
@@ -233,7 +233,7 @@ public class JetTestUtils {
@Override @Override
public void report(@NotNull Diagnostic diagnostic) { public void report(@NotNull Diagnostic diagnostic) {
if (diagnostic.getSeverity() == Severity.ERROR) { if (diagnostic.getSeverity() == Severity.ERROR) {
throw new IllegalStateException(DefaultErrorMessages.RENDERER.render(diagnostic)); throw new IllegalStateException(DefaultErrorMessages.render(diagnostic));
} }
} }
}; };
@@ -148,7 +148,7 @@ public class TypeSubstitutorTest extends KotlinTestWithEnvironment {
new Function<Diagnostic, String>() { new Function<Diagnostic, String>() {
@Override @Override
public String fun(Diagnostic diagnostic) { public String fun(Diagnostic diagnostic) {
return DefaultErrorMessages.RENDERER.render(diagnostic); return DefaultErrorMessages.render(diagnostic);
} }
}, },
"\n")); "\n"));
@@ -16,12 +16,12 @@
package org.jetbrains.jet.plugin.highlighter; package org.jetbrains.jet.plugin.highlighter;
import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages; import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages;
import org.jetbrains.jet.lang.diagnostics.rendering.DiagnosticFactoryToRendererMap; import org.jetbrains.jet.lang.diagnostics.rendering.DiagnosticFactoryToRendererMap;
import org.jetbrains.jet.lang.diagnostics.rendering.DiagnosticRenderer; import org.jetbrains.jet.lang.diagnostics.rendering.DiagnosticRenderer;
import org.jetbrains.jet.lang.diagnostics.rendering.DispatchingDiagnosticRenderer;
import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRenderer;
import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
@@ -38,8 +38,24 @@ import static org.jetbrains.jet.plugin.highlighter.IdeRenderers.*;
* @see DefaultErrorMessages * @see DefaultErrorMessages
*/ */
public class IdeErrorMessages { public class IdeErrorMessages {
public static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap(); private static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap();
public static final DiagnosticRenderer<Diagnostic> RENDERER = new DispatchingDiagnosticRenderer(ContainerUtil.concat(false, DefaultErrorMessages.MAPS, MAP));
@NotNull
public static String render(@NotNull Diagnostic diagnostic) {
DiagnosticRenderer renderer = MAP.get(diagnostic.getFactory());
if (renderer != null) {
//noinspection unchecked
return renderer.render(diagnostic);
}
return DefaultErrorMessages.render(diagnostic);
}
@TestOnly
public static boolean hasIdeSpecificMessage(@NotNull Diagnostic diagnostic) {
return MAP.get(diagnostic.getFactory()) != null;
}
static { static {
MAP.put(TYPE_MISMATCH, "<html>Type mismatch.<table><tr><td>Required:</td><td>{0}</td></tr><tr><td>Found:</td><td>{1}</td></tr></table></html>", MAP.put(TYPE_MISMATCH, "<html>Type mismatch.<table><tr><td>Required:</td><td>{0}</td></tr><tr><td>Found:</td><td>{1}</td></tr></table></html>",
@@ -183,7 +183,7 @@ public open class JetPsiChecker : Annotator, HighlightRangeExtension {
} }
private fun getMessage(diagnostic: Diagnostic): String { private fun getMessage(diagnostic: Diagnostic): String {
var message = IdeErrorMessages.RENDERER.render(diagnostic) var message = IdeErrorMessages.render(diagnostic)
if (KotlinInternalMode.enabled || ApplicationManager.getApplication().isUnitTestMode()) { if (KotlinInternalMode.enabled || ApplicationManager.getApplication().isUnitTestMode()) {
val factoryName = diagnostic.getFactory().getName() val factoryName = diagnostic.getFactory().getName()
if (message.startsWith("<html>")) { if (message.startsWith("<html>")) {
@@ -200,7 +200,7 @@ public open class JetPsiChecker : Annotator, HighlightRangeExtension {
} }
private fun getDefaultMessage(diagnostic: Diagnostic): String { private fun getDefaultMessage(diagnostic: Diagnostic): String {
val message = DefaultErrorMessages.RENDERER.render(diagnostic) val message = DefaultErrorMessages.render(diagnostic)
if (KotlinInternalMode.enabled || ApplicationManager.getApplication().isUnitTestMode()) { if (KotlinInternalMode.enabled || ApplicationManager.getApplication().isUnitTestMode()) {
return "[${diagnostic.getFactory().getName()}] $message" return "[${diagnostic.getFactory().getName()}] $message"
} }
@@ -288,7 +288,7 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
val bindingContext = analysisResult.bindingContext val bindingContext = analysisResult.bindingContext
bindingContext.getDiagnostics().firstOrNull { it.getSeverity() == Severity.ERROR }?.let { bindingContext.getDiagnostics().firstOrNull { it.getSeverity() == Severity.ERROR }?.let {
throw EvaluateExceptionUtil.createEvaluateException(DefaultErrorMessages.RENDERER.render(it)) throw EvaluateExceptionUtil.createEvaluateException(DefaultErrorMessages.render(it))
} }
analysisResult analysisResult
@@ -83,7 +83,7 @@ public class QuickFixFactoryForTypeMismatchError extends JetIntentionActionsFact
} }
} }
else { else {
LOG.error("Unexpected diagnostic: " + DefaultErrorMessages.RENDERER.render(diagnostic)); LOG.error("Unexpected diagnostic: " + DefaultErrorMessages.render(diagnostic));
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -58,7 +58,7 @@ public class DirectiveBasedActionUtils {
@Override @Override
public String apply(@Nullable Diagnostic diagnostic) { public String apply(@Nullable Diagnostic diagnostic) {
assert (diagnostic != null); assert (diagnostic != null);
return IdeErrorMessages.RENDERER.render(diagnostic); return IdeErrorMessages.render(diagnostic);
} }
}); });
@@ -101,7 +101,7 @@ public abstract class AbstractInsertImportOnPasteTest extends JetLightCodeInsigh
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) { if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
List<TextRange> textRanges = diagnostic.getTextRanges(); List<TextRange> textRanges = diagnostic.getTextRanges();
String diagnosticText = DefaultErrorMessages.RENDERER.render(diagnostic); String diagnosticText = DefaultErrorMessages.render(diagnostic);
if (diagnostic.getPsiFile() == file) { if (diagnostic.getPsiFile() == file) {
fail(diagnostic.getFactory().getName() + ": " + diagnosticText + " " fail(diagnostic.getFactory().getName() + ": " + diagnosticText + " "
+ DiagnosticUtils.atLocation(file, textRanges.get(0))); + DiagnosticUtils.atLocation(file, textRanges.get(0)));
@@ -99,12 +99,12 @@ public abstract class AbstractDiagnosticMessageTest extends JetLiteFixture {
for (Diagnostic diagnostic : diagnostics) { for (Diagnostic diagnostic : diagnostics) {
String readableDiagnosticText; String readableDiagnosticText;
String extension; String extension;
if (messageType != MessageType.TEXT && IdeErrorMessages.MAP.get(diagnostic.getFactory()) != null) { if (messageType != MessageType.TEXT && IdeErrorMessages.hasIdeSpecificMessage(diagnostic)) {
readableDiagnosticText = formatHtml(IdeErrorMessages.RENDERER.render(diagnostic)); readableDiagnosticText = formatHtml(IdeErrorMessages.render(diagnostic));
extension = MessageType.HTML.extension; extension = MessageType.HTML.extension;
} }
else { else {
readableDiagnosticText = DefaultErrorMessages.RENDERER.render(diagnostic); readableDiagnosticText = DefaultErrorMessages.render(diagnostic);
extension = MessageType.TEXT.extension; extension = MessageType.TEXT.extension;
} }
String errorMessageFileName = name + index; String errorMessageFileName = name + index;
@@ -77,7 +77,7 @@ public abstract class AbstractJavaToKotlinConverterTest : LightCodeInsightFixtur
val diagnostics = jetFile.analyzeFullyAndGetResult().bindingContext.getDiagnostics() val diagnostics = jetFile.analyzeFullyAndGetResult().bindingContext.getDiagnostics()
val errors = diagnostics.filter { it.getSeverity() == Severity.ERROR } val errors = diagnostics.filter { it.getSeverity() == Severity.ERROR }
if (errors.isEmpty()) return jetFile.getText() if (errors.isEmpty()) return jetFile.getText()
val header = errors.map { "// ERROR: " + DefaultErrorMessages.RENDERER.render(it).replace('\n', ' ') }.joinToString("\n", postfix = "\n") val header = errors.map { "// ERROR: " + DefaultErrorMessages.render(it).replace('\n', ' ') }.joinToString("\n", postfix = "\n")
return header + jetFile.getText() return header + jetFile.getText()
} }
} }