package org.elixir_lang.errorreport; import com.google.common.base.Joiner; import com.intellij.diagnostic.AttachmentFactory; import com.intellij.diagnostic.LogMessageEx; import com.intellij.openapi.diagnostic.Attachment; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Collections; public class Logger { /* * Public Static Methods */ /** * Logs error to the {@code klass}'s {@link com.intellij.openapi.diagnostic.Logger} instance with the given * {@code userMessage} and the text of {@code element} as the details and containing file of {@code element} as an * attachment * * @param klass Class whose logger to use * @param userMessage User message for * {@link com.intellij.diagnostic.LogMessageEx#createEvent(String, String, Attachment...)} * @param element element responsible for the error */ public static void error(@NotNull Class klass, @NotNull String userMessage, PsiElement element) { error(com.intellij.openapi.diagnostic.Logger.getInstance(klass), userMessage, element); } /** * Logs error {@link com.intellij.openapi.diagnostic.Logger} instance with the given {@code userMessage} and the * text of {@code element} as the details and containing file of {@code element} as an * attachment * * @param logger logger to which to log an error. * @param userMessage User message for * {@link com.intellij.diagnostic.LogMessageEx#createEvent(String, String, Attachment...)} * @param element element responsible for the error */ public static void error(@NotNull com.intellij.openapi.diagnostic.Logger logger, @NotNull String userMessage, @NotNull PsiElement element) { PsiFile containingFile = element.getContainingFile(); String fullUserMessage = fullUserMessage(userMessage, containingFile, element); String details = Joiner.on("\n").join(new Throwable().getStackTrace()); Collection<Attachment> attachmentCollection; VirtualFile virtualFile = containingFile.getVirtualFile(); if (virtualFile != null) { attachmentCollection = Collections.singletonList( AttachmentFactory.createAttachment(virtualFile) ); } else { attachmentCollection = Collections.emptyList(); } logger.error( LogMessageEx.createEvent( fullUserMessage, details, fullUserMessage, null, attachmentCollection ) ); } /* * Private Static Methods */ @NotNull private static String className(@NotNull PsiElement element) { return "\n" + "### Element Class Name\n" + '\n' + "```\n" + element.getClass().getName() + '\n' + "```\n"; } @NotNull private static String excerpt(@NotNull PsiFile containingFile, @NotNull PsiElement element) { StringBuilder excerptBuilder = new StringBuilder(); excerptBuilder.append('\n'); excerptBuilder.append("### Excerpt\n"); excerptBuilder.append('\n'); excerptBuilder.append("```\n"); excerptBuilder.append(element.getText()); excerptBuilder.append('\n'); excerptBuilder.append("```\n"); FileViewProvider fileViewProvider = containingFile.getViewProvider(); Document document = fileViewProvider.getDocument(); if (document != null) { TextRange textRange = element.getTextRange(); int startingLine = document.getLineNumber(textRange.getStartOffset()); int endingLine = document.getLineNumber(textRange.getEndOffset()); excerptBuilder.append(" Line(s) "); excerptBuilder.append(startingLine); excerptBuilder.append('-'); excerptBuilder.append(endingLine); VirtualFile virtualFile = containingFile.getVirtualFile(); if (virtualFile != null) { excerptBuilder.append(" in "); excerptBuilder.append(virtualFile.getPath()); } excerptBuilder.append("\n"); } return excerptBuilder.toString(); } private static String fullUserMessage(@NotNull String userMessage, @NotNull PsiFile containingFile, @NotNull PsiElement element) { return userMessage + "\n" + excerpt(containingFile, element) + "\n" + className(element); } }