mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
[#922] Calculate correct position (end) for issues
Signed-off-by: Christian Dietrich <christian.dietrich@itemis.de>
This commit is contained in:
parent
ecd16a0a9e
commit
d5a14ee24b
6 changed files with 194 additions and 38 deletions
|
@ -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('''
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue