[#922] Calculate correct position (end) for issues

Signed-off-by: Christian Dietrich <christian.dietrich@itemis.de>
This commit is contained in:
Christian Dietrich 2018-10-21 11:50:47 +02:00
parent ecd16a0a9e
commit d5a14ee24b
6 changed files with 194 additions and 38 deletions

View file

@ -38,6 +38,7 @@ class ValidatorTest extends AbstractTestLangLanguageServerTest {
assertEquals(1, range.end.line)
assertEquals(1, range.end.character)
}
@Test
def void testMultilineDiagnostic_02() {
'MyType1.testlang'.writeFile('''

View file

@ -104,6 +104,8 @@ import org.eclipse.xtext.util.internal.Log
import org.eclipse.xtext.validation.Issue
import static org.eclipse.xtext.diagnostics.Severity.*
import org.eclipse.xtext.validation.Issue.IssueExtension
import org.eclipse.lsp4j.Position
/**
* @author Sven Efftinge - Initial contribution and API
@ -319,19 +321,13 @@ import static org.eclipse.xtext.diagnostics.Severity.*
initialized.thenAccept([
val diagnostics = new PublishDiagnosticsParams => [
it.uri = toUriString(uri)
if (issues.isEmpty) {
diagnostics = #[]
} else {
diagnostics = workspaceManager.doRead(uri) [document, resource|
issues.filter[severity !== IGNORE].map[toDiagnostic(document, it)].toList
]
}
it.diagnostics = issues.filter[severity !== IGNORE].map[toDiagnostic].toList
]
client.publishDiagnostics(diagnostics)
])
}
private def Diagnostic toDiagnostic(Document document, Issue issue) {
private def Diagnostic toDiagnostic(Issue issue) {
new Diagnostic => [
code = issue.code
severity = switch issue.severity {
@ -341,11 +337,33 @@ import static org.eclipse.xtext.diagnostics.Severity.*
default: DiagnosticSeverity.Hint
}
message = issue.message
val start = document.getPosition(issue.offset)
val end = document.getPosition(issue.offset+issue.length)
val lineNumber = (issue.lineNumber ?: 1) - 1
val column = if ((issue.column ?: -1) == -1) {
0
} else {
issue.column - 1
}
val length = (issue.length ?: 0)
val endLineNumber = if (issue instanceof IssueExtension) {
(issue.endLineNumber ?: 1) - 1
} else {
lineNumber
}
val endColumn = if (issue instanceof IssueExtension) {
if ((issue.endColumn ?: -1) == -1) {
0
} else {
issue.endColumn - 1
}
} else {
column + length
}
range = new Range(
start,
end
new Position(lineNumber, column),
new Position(endLineNumber, endColumn)
)
]
}

View file

@ -512,22 +512,14 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
PublishDiagnosticsParams _publishDiagnosticsParams = new PublishDiagnosticsParams();
final Procedure1<PublishDiagnosticsParams> _function_1 = (PublishDiagnosticsParams it_1) -> {
it_1.setUri(this._uriExtensions.toUriString(uri));
boolean _isEmpty = IterableExtensions.isEmpty(issues);
if (_isEmpty) {
it_1.setDiagnostics(Collections.<Diagnostic>unmodifiableList(CollectionLiterals.<Diagnostic>newArrayList()));
} else {
final Function2<Document, XtextResource, List<Diagnostic>> _function_2 = (Document document, XtextResource resource) -> {
final Function1<Issue, Boolean> _function_3 = (Issue it_2) -> {
Severity _severity = it_2.getSeverity();
return Boolean.valueOf((_severity != Severity.IGNORE));
};
final Function1<Issue, Diagnostic> _function_4 = (Issue it_2) -> {
return this.toDiagnostic(document, it_2);
};
return IterableExtensions.<Diagnostic>toList(IterableExtensions.map(IterableExtensions.filter(issues, _function_3), _function_4));
};
it_1.setDiagnostics(this.workspaceManager.<List<Diagnostic>>doRead(uri, _function_2));
}
final Function1<Issue, Boolean> _function_2 = (Issue it_2) -> {
Severity _severity = it_2.getSeverity();
return Boolean.valueOf((_severity != Severity.IGNORE));
};
final Function1<Issue, Diagnostic> _function_3 = (Issue it_2) -> {
return this.toDiagnostic(it_2);
};
it_1.setDiagnostics(IterableExtensions.<Diagnostic>toList(IterableExtensions.map(IterableExtensions.filter(issues, _function_2), _function_3)));
};
final PublishDiagnosticsParams diagnostics = ObjectExtensions.<PublishDiagnosticsParams>operator_doubleArrow(_publishDiagnosticsParams, _function_1);
this.client.publishDiagnostics(diagnostics);
@ -535,7 +527,7 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
this.initialized.thenAccept(_function);
}
private Diagnostic toDiagnostic(final Document document, final Issue issue) {
private Diagnostic toDiagnostic(final Issue issue) {
Diagnostic _diagnostic = new Diagnostic();
final Procedure1<Diagnostic> _function = (Diagnostic it) -> {
it.setCode(issue.getCode());
@ -561,12 +553,77 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
}
it.setSeverity(_switchResult);
it.setMessage(issue.getMessage());
final Position start = document.getPosition((issue.getOffset()).intValue());
Integer _offset = issue.getOffset();
Integer _elvis = null;
Integer _lineNumber = issue.getLineNumber();
if (_lineNumber != null) {
_elvis = _lineNumber;
} else {
_elvis = Integer.valueOf(1);
}
final int lineNumber = ((_elvis).intValue() - 1);
int _xifexpression = (int) 0;
Integer _elvis_1 = null;
Integer _column = issue.getColumn();
if (_column != null) {
_elvis_1 = _column;
} else {
_elvis_1 = Integer.valueOf((-1));
}
boolean _equals = ((_elvis_1).intValue() == (-1));
if (_equals) {
_xifexpression = 0;
} else {
Integer _column_1 = issue.getColumn();
_xifexpression = ((_column_1).intValue() - 1);
}
final int column = _xifexpression;
Integer _elvis_2 = null;
Integer _length = issue.getLength();
int _plus = ((_offset).intValue() + (_length).intValue());
final Position end = document.getPosition(_plus);
Range _range = new Range(start, end);
if (_length != null) {
_elvis_2 = _length;
} else {
_elvis_2 = Integer.valueOf(0);
}
final Integer length = _elvis_2;
int _xifexpression_1 = (int) 0;
if ((issue instanceof Issue.IssueExtension)) {
Integer _elvis_3 = null;
Integer _endLineNumber = ((Issue.IssueExtension)issue).getEndLineNumber();
if (_endLineNumber != null) {
_elvis_3 = _endLineNumber;
} else {
_elvis_3 = Integer.valueOf(1);
}
_xifexpression_1 = ((_elvis_3).intValue() - 1);
} else {
_xifexpression_1 = lineNumber;
}
final int endLineNumber = _xifexpression_1;
int _xifexpression_2 = (int) 0;
if ((issue instanceof Issue.IssueExtension)) {
int _xifexpression_3 = (int) 0;
Integer _elvis_4 = null;
Integer _endColumn = ((Issue.IssueExtension)issue).getEndColumn();
if (_endColumn != null) {
_elvis_4 = _endColumn;
} else {
_elvis_4 = Integer.valueOf((-1));
}
boolean _equals_1 = ((_elvis_4).intValue() == (-1));
if (_equals_1) {
_xifexpression_3 = 0;
} else {
Integer _endColumn_1 = ((Issue.IssueExtension)issue).getEndColumn();
_xifexpression_3 = ((_endColumn_1).intValue() - 1);
}
_xifexpression_2 = _xifexpression_3;
} else {
_xifexpression_2 = (column + (length).intValue());
}
final int endColumn = _xifexpression_2;
Position _position = new Position(lineNumber, column);
Position _position_1 = new Position(endLineNumber, endColumn);
Range _range = new Range(_position, _position_1);
it.setRange(_range);
};
return ObjectExtensions.<Diagnostic>operator_doubleArrow(_diagnostic, _function);

View file

@ -50,6 +50,15 @@ public abstract class AbstractDiagnostic implements Diagnostic {
}
return 0;
}
public int getEndColumn() {
INode node = getNode();
if (node != null) {
LineAndColumn lineAndColumn = NodeModelUtils.getLineAndColumn(node, getOffset()+getLength());
return lineAndColumn.getColumn();
}
return 0;
}
@Override
public int getLine() {
@ -58,6 +67,13 @@ public abstract class AbstractDiagnostic implements Diagnostic {
return node.getStartLine();
return -1;
}
public int getEndLine() {
INode node = getNode();
if (node != null)
return node.getEndLine();
return -1;
}
@Override
public String getLocation() {

View file

@ -49,6 +49,17 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
*/
public Integer offset;
public Integer length;
/**
* 1-based line number.
* @since 2.19
*/
public Integer endLineNumber;
/**
* 1-based column.
* @since 2.19
*/
public Integer endColumn;
}
@Override
@ -59,7 +70,10 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
issue.setLineNumber(diagnostic.getLine());
issue.setColumn(diagnostic.getColumn());
issue.setMessage(diagnostic.getMessage());
// set default value
issue.setEndColumn(-1);
if (diagnostic instanceof org.eclipse.xtext.diagnostics.Diagnostic) {
org.eclipse.xtext.diagnostics.Diagnostic xtextDiagnostic = (org.eclipse.xtext.diagnostics.Diagnostic) diagnostic;
issue.setOffset(xtextDiagnostic.getOffset());
@ -70,6 +84,9 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
issue.setUriToProblem(castedDiagnostic.getUriToProblem());
issue.setCode(castedDiagnostic.getCode());
issue.setData(castedDiagnostic.getData());
issue.setEndLineNumber(castedDiagnostic.getEndLine());
issue.setEndColumn(castedDiagnostic.getEndColumn());
}
issue.setType(CheckType.FAST);
acceptor.accept(issue);
@ -83,13 +100,17 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
return;
IssueImpl issue = new Issue.IssueImpl();
issue.setSeverity(severity);
// set default value
issue.setColumn(-1);
issue.setEndColumn(-1);
IssueLocation locationData = getLocationData(diagnostic);
if (locationData != null) {
issue.setLineNumber(locationData.lineNumber);
issue.setColumn(locationData.column);
issue.setOffset(locationData.offset);
issue.setLength(locationData.length);
issue.setEndLineNumber(locationData.endLineNumber);
issue.setEndColumn(locationData.endColumn);
}
final EObject causer = getCauser(diagnostic);
if (causer != null)
@ -196,6 +217,9 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
LineAndColumn lineAndColumn = NodeModelUtils.getLineAndColumn(parserNode, castedDiagnostic.getOffset());
result.lineNumber = lineAndColumn.getLine();
result.column = lineAndColumn.getColumn();
LineAndColumn endLineAndColumn = NodeModelUtils.getLineAndColumn(parserNode, castedDiagnostic.getOffset() + castedDiagnostic.getLength());
result.endLineNumber = endLineAndColumn.getLine();
result.endColumn = endLineAndColumn.getColumn();
}
result.offset = castedDiagnostic.getOffset();
result.length = castedDiagnostic.getLength();
@ -244,6 +268,8 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
result.column = 1;
result.offset = 0;
result.length = 0;
result.endLineNumber = 1;
result.endColumn = 1;
return result;
}
@ -254,6 +280,8 @@ public class DiagnosticConverterImpl implements IDiagnosticConverter {
result.offset = nodeRegion.getOffset();
result.column = NodeModelUtils.getLineAndColumn(node, result.offset).getColumn();
result.length = nodeRegion.getLength();
result.endLineNumber = nodeRegion.getEndLineNumber();
result.endColumn = NodeModelUtils.getLineAndColumn(node, result.offset + result.length).getColumn();
return result;
}

View file

@ -18,6 +18,25 @@ import org.eclipse.xtext.diagnostics.Severity;
*/
public interface Issue {
/**
* @author Christian Dietrich - Initial contribution and API
* @since 2.19
*/
interface IssueExtension {
/**
* Returns the column in the end line of the issue. It's not the virtual column but literally
* the character offset in the column, e.g. tab ('\t') counts as one character.
* The first char in a line has column number 1, the number is one-based.
*
* If no column information is available, returns -1.
*/
Integer getEndColumn();
/**
* Returns the one-based end line number of the issue.
*/
Integer getEndLineNumber();
}
String CODE_KEY = "CODE_KEY";
String URI_KEY = "URI_KEY";
/**
@ -66,11 +85,11 @@ public interface Issue {
*/
String[] getData();
static class IssueImpl implements Issue {
static class IssueImpl implements Issue, IssueExtension {
private static Logger LOG = Logger.getLogger(IssueImpl.class);
private Integer length, lineNumber, offset, column;
private Integer length, lineNumber, offset, column, endLineNumber, endColumn;
private String code, message;
private boolean isSyntaxError = false;
private URI uriToProblem;
@ -198,5 +217,22 @@ public interface Issue {
result.append(" line : ").append(getLineNumber()).append(" column : ").append(getColumn()).append(")");
return result.toString();
}
public Integer getEndLineNumber() {
return endLineNumber;
}
public void setEndLineNumber(Integer endLineNumber) {
this.endLineNumber = endLineNumber;
}
public Integer getEndColumn() {
return endColumn;
}
public void setEndColumn(Integer endColumn) {
this.endColumn = endColumn;
}
}
}