adjust error column position according to tab size from the current code style (IDEA-161153)

This commit is contained in:
Eugene Zhuravlev
2017-11-20 16:22:48 +01:00
parent 2fd6200e0f
commit 036ecf2e20
2 changed files with 55 additions and 1 deletions
@@ -22,6 +22,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.util.TripleFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,6 +35,8 @@ public final class CompilerMessageImpl implements CompilerMessage {
private final VirtualFile myFile;
private final int myRow;
private final int myColumn;
@NotNull
private TripleFunction<CompilerMessage, Integer, Integer, Integer> myColumnAdjuster = (msg, line, col) -> col;
public CompilerMessageImpl(Project project, CompilerMessageCategory category, String message) {
this(project, category, message, null, -1, -1, null);
@@ -55,6 +58,10 @@ public final class CompilerMessageImpl implements CompilerMessage {
myFile = file;
}
public void setColumnAdjuster(@NotNull TripleFunction<CompilerMessage, Integer, Integer, Integer> columnAdjuster) {
myColumnAdjuster = columnAdjuster;
}
@NotNull
@Override
public CompilerMessageCategory getCategory() {
@@ -75,7 +82,7 @@ public final class CompilerMessageImpl implements CompilerMessage {
if (virtualFile != null && virtualFile.isValid()) {
final int line = getLine() - 1; // editor lines are zero-based
if (line >= 0) {
return myNavigatable = new OpenFileDescriptor(myProject, virtualFile, line, Math.max(0, getColumn()-1));
return myNavigatable = new OpenFileDescriptor(myProject, virtualFile, line, myColumnAdjuster.fun(this, line, Math.max(0, getColumn()-1))) ;
}
}
return null;
@@ -15,10 +15,16 @@
*/
package com.intellij.compiler.impl;
import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.compiler.CompilerMessageImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompilerMessage;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.pom.Navigatable;
@@ -32,11 +38,15 @@ import java.util.*;
* Date: 27-Jan-16
*/
public class MessagesContainer {
private static final int JAVAC_TAB_SIZE = 8;
private final Project myProject;
private final Map<CompilerMessageCategory, Collection<CompilerMessage>> myMessages = new EnumMap<>(CompilerMessageCategory.class);
private final int myTabSize;
public MessagesContainer(Project project) {
myProject = project;
myTabSize = CodeStyleFacade.getInstance().getTabSize(StdFileTypes.JAVA);
}
@NotNull
@@ -52,11 +62,48 @@ public class MessagesContainer {
public CompilerMessage addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum, Navigatable navigatable) {
CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findFileByUrl(url), lineNum, columnNum, navigatable);
if (addMessage(msg)) {
msg.setColumnAdjuster((m, line, col) -> adjustColumn(m, line, col));
return msg;
}
return null;
}
private int adjustColumn(final CompilerMessage m, final int line, final int col) {
if (myTabSize != JAVAC_TAB_SIZE && line >= 1) {
// javac uses hard-coded tab size 8 chars. So recalculate only if project's codestyle is different
final VirtualFile file = m.getVirtualFile();
if (file != null && file.isValid()) {
final Document doc = FileDocumentManager.getInstance().getDocument(file);
if (doc != null) {
final int tabCount = ApplicationManager.getApplication().runReadAction((Computable<Integer>)() -> {
final CharSequence seq = doc.getCharsSequence();
int tcount = 0;
final int start = doc.getLineStartOffset(line);
final int end = doc.getLineEndOffset(line);
int charsExpanded = 0;
for (int i = start; i< end; i++) {
if (seq.charAt(i) == '\t') {
charsExpanded += JAVAC_TAB_SIZE;
tcount++;
}
else {
charsExpanded += 1;
}
if (charsExpanded >= col) {
break; // consider only those tabs that are located before the given column number
}
}
return tcount;
});
if (tabCount > 0) {
return Math.max(0, col + tabCount * (myTabSize - JAVAC_TAB_SIZE));
}
}
}
}
return col;
}
public boolean addMessage(CompilerMessage msg) {
Collection<CompilerMessage> messages = myMessages.computeIfAbsent(msg.getCategory(), k -> new LinkedHashSet<>());
return messages.add(msg);