Skip to content

Commit fd1dbb7

Browse files
authored
Nullable range and location (#135)
* Consider range and location as nullable
1 parent 2e219a1 commit fd1dbb7

10 files changed

+41
-30
lines changed

src/haxeLanguageServer/features/haxe/DiagnosticsFeature.hx

+13-5
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ class DiagnosticsFeature {
394394
}
395395
}
396396

397-
public function getArguments<T>(uri:DocumentUri, kind:DiagnosticKind<T>, range:Range):Null<T> {
397+
public function getArguments<T>(uri:DocumentUri, kind:DiagnosticKind<T>, range:Null<Range>):Null<T> {
398398
final map = diagnosticsArguments[uri];
399399
@:nullSafety(Off) // ?
400400
return if (map == null) null else map.get({code: kind, range: range});
@@ -460,19 +460,27 @@ private typedef HaxeDiagnosticResponse<T> = {
460460
final diagnostics:Array<HaxeDiagnostic<T>>;
461461
}
462462

463-
private typedef DiagnosticsMapKey = {code:Int, range:Range};
463+
private typedef DiagnosticsMapKey = {code:Int, ?range:Range};
464464

465465
private class DiagnosticsMap<T> extends BalancedTree<DiagnosticsMapKey, T> {
466466
override function compare(k1:DiagnosticsMapKey, k2:DiagnosticsMapKey) {
467+
if (k1.code != k2.code)
468+
return k1.code - k2.code;
469+
if (k1.range == null && k2.range == null)
470+
return 0;
471+
if (k1.range == null)
472+
return -1;
473+
if (k2.range == null)
474+
return 1;
475+
467476
final start1 = k1.range.start;
468477
final start2 = k2.range.start;
469478
final end1 = k1.range.end;
470479
final end2 = k2.range.end;
471480
inline function compare(i1, i2, e) {
472481
return i1 < i2 ? -1 : i1 > i2 ? 1 : e;
473482
}
474-
return compare(k1.code, k2.code,
475-
compare(start1.line, start2.line,
476-
compare(start1.character, start2.character, compare(end1.line, end2.line, compare(end1.character, end2.character, 0)))));
483+
return compare(start1.line, start2.line,
484+
compare(start1.character, start2.character, compare(end1.line, end2.line, compare(end1.character, end2.character, 0))));
477485
}
478486
}

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/ChangeFinalToVarAction.hx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class ChangeFinalToVarAction {
1212
return null;
1313
}
1414
final document = context.documents.getHaxe(params.textDocument.uri);
15-
if (document == null)
15+
if (document == null || diagnostic.range == null)
1616
return null;
1717
var tokenSource = new CancellationTokenSource();
1818

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/CompilerErrorActions.hx

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ class CompilerErrorActions {
1313
return actions;
1414
}
1515
final suggestionsRe = ~/\(Suggestions?: (.*)\)/;
16-
if (suggestionsRe.match(arg)) {
16+
if (suggestionsRe.match(arg) && diagnostic.range != null) {
1717
final suggestions = suggestionsRe.matched(1).split(",");
1818
// Haxe reports the entire expression, not just the field position, so we have to be a bit creative here.
19-
final range = diagnostic.range;
19+
final range = diagnostic.range.sure();
2020
final fieldRe = ~/has no field ([^ ]+) /;
2121
if (fieldRe.match(arg)) {
2222
range.start.character = range.end.character - fieldRe.matched(1).length;
@@ -34,7 +34,7 @@ class CompilerErrorActions {
3434
}
3535

3636
final invalidPackageRe = ~/Invalid package : ([\w.]*) should be ([\w.]*)/;
37-
if (invalidPackageRe.match(arg)) {
37+
if (invalidPackageRe.match(arg) && diagnostic.range != null) {
3838
final is = invalidPackageRe.matched(1);
3939
final shouldBe = invalidPackageRe.matched(2);
4040
final document = context.documents.getHaxe(params.textDocument.uri);
@@ -43,15 +43,15 @@ class CompilerErrorActions {
4343
actions.push({
4444
title: "Change to " + replacement,
4545
kind: CodeActionKind.QuickFix + ".auto",
46-
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range, newText: replacement}]),
46+
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range.sure(), newText: replacement}]),
4747
diagnostics: [diagnostic],
4848
isPreferred: true
4949
});
5050
}
5151
}
5252

5353
if (context.haxeServer.haxeVersion.major >= 4 // unsuitable error range before Haxe 4
54-
&& arg.contains("should be declared with 'override' since it is inherited from superclass")) {
54+
&& diagnostic.range != null && arg.contains("should be declared with 'override' since it is inherited from superclass")) {
5555
var pos = diagnostic.range.start;
5656
final document = context.documents.getHaxe(params.textDocument.uri);
5757
if (document.tokens != null) {

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/MissingArgumentsAction.hx

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class MissingArgumentsAction {
1818
return null;
1919
}
2020
final document = context.documents.getHaxe(params.textDocument.uri);
21-
if (document == null)
21+
if (document == null || diagnostic.range == null)
2222
return null;
2323
final tokenSource = new CancellationTokenSource();
2424

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/MissingFieldsActions.hx

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class MissingFieldsActions {
160160
final pos = getNewVariablePos(document, classToken, field.field.scope);
161161
if (pos != null)
162162
rangeFieldInsertion = pos.toRange();
163-
} else {
163+
} else if (diagnostic.range != null) {
164164
final funToken = tokens?.getTokenAtOffset(document.offsetAt(diagnostic.range.start));
165165
if (funToken != null) {
166166
final pos = getNewClassFunctionPos(document, classToken, funToken);

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/OrganizeImportActions.hx

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class OrganizeImportActions {
2929
final map = context.diagnostics.getArgumentsMap(uri);
3030
final removeUnusedFixes = if (map == null) [] else [
3131
for (key in map.keys()) {
32-
if (key.code == DiagnosticKind.DKUnusedImport) {
32+
if (key.code == DiagnosticKind.DKUnusedImport && key.range != null) {
3333
WorkspaceEditHelper.removeText(DocHelper.untrimRange(doc, key.range));
3434
}
3535
}

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/ParserErrorActions.hx

+10-10
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ class ParserErrorActions {
1414
return actions;
1515
}
1616

17-
if (arg.contains("modifier is not supported for module-level fields")) {
17+
if (arg.contains("modifier is not supported for module-level fields") && diagnostic.range != null) {
1818
final document = context.documents.getHaxe(params.textDocument.uri);
1919
final nextText = document.content.substr(document.offsetAt(diagnostic.range.end));
2020
final isAuto = nextText.split("{").length == nextText.split("}").length;
2121
final token = document?.tokens?.getTokenAtOffset(document.offsetAt(diagnostic.range.end));
22-
var range = diagnostic.range;
22+
var range = diagnostic.range.sure();
2323
if (token != null) {
2424
for (sib in [token.previousSibling, token.nextSibling]) {
2525
if (sib == null)
@@ -44,12 +44,12 @@ class ParserErrorActions {
4444
});
4545
}
4646

47-
if (arg.contains("`final var` is not supported, use `final` instead")) {
47+
if (arg.contains("`final var` is not supported, use `final` instead") && diagnostic.range != null) {
4848
final document = context.documents.getHaxe(params.textDocument.uri);
4949
actions.push({
5050
title: "Change to final",
5151
kind: CodeActionKind.QuickFix + ".auto",
52-
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range, newText: "final"}]),
52+
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range.sure(), newText: "final"}]),
5353
diagnostics: [diagnostic],
5454
isPreferred: true
5555
});
@@ -59,7 +59,7 @@ class ParserErrorActions {
5959
createMissingSemicolonAction(context, params, diagnostic, actions);
6060
}
6161

62-
if (arg.contains("Expected }")) {
62+
if (arg.contains("Expected }") && diagnostic.range != null) {
6363
final document = context.documents.getHaxe(params.textDocument.uri);
6464
final token = document?.tokens?.getTokenAtOffset(document.offsetAt(diagnostic.range.end));
6565
final prevToken = getPrevNonCommentSibling(token);
@@ -70,15 +70,15 @@ class ParserErrorActions {
7070
actions.push({
7171
title: "Remove redundant ;",
7272
kind: CodeActionKind.QuickFix + ".auto",
73-
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range, newText: ""}]),
73+
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range.sure(), newText: ""}]),
7474
diagnostics: [diagnostic],
7575
isPreferred: true
7676
});
7777
case [Comma, Comma]:
7878
actions.push({
7979
title: "Remove redundant ,",
8080
kind: CodeActionKind.QuickFix + ".auto",
81-
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range, newText: ""}]),
81+
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range.sure(), newText: ""}]),
8282
diagnostics: [diagnostic],
8383
isPreferred: true
8484
});
@@ -91,7 +91,7 @@ class ParserErrorActions {
9191
actions.push({
9292
title: "Replace ; with ,",
9393
kind: CodeActionKind.QuickFix + ".auto",
94-
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range, newText: ","}]),
94+
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range.sure(), newText: ","}]),
9595
diagnostics: [diagnostic],
9696
isPreferred: true
9797
});
@@ -113,7 +113,7 @@ class ParserErrorActions {
113113
}
114114
}
115115

116-
if (arg.contains("Expected , or ]")) {
116+
if (arg.contains("Expected , or ]") && diagnostic.range != null) {
117117
final document = context.documents.getHaxe(params.textDocument.uri);
118118
final errRange:Null<Range> = getMissingSemicolonPos(document, diagnostic.range.start);
119119
if (errRange != null) {
@@ -136,7 +136,7 @@ class ParserErrorActions {
136136

137137
static function createMissingSemicolonAction(context:Context, params:CodeActionParams, diagnostic:Diagnostic, actions:Array<CodeAction>):Void {
138138
final document = context.documents.getHaxe(params.textDocument.uri);
139-
final errRange = getMissingSemicolonPos(document, diagnostic.range.start.translate(0, 1));
139+
final errRange = Safety.let(diagnostic.range, range -> getMissingSemicolonPos(document, range.start.translate(0, 1)));
140140
if (errRange == null)
141141
return;
142142
final errRange:Range = errRange;

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/UnresolvedIdentifierActions.hx

+6-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class UnresolvedIdentifierActions {
2626

2727
static function createUnresolvedImportActions(context:Context, params:CodeActionParams, diagnostic:Diagnostic, arg, importCount:Int):Array<CodeAction> {
2828
final doc = context.documents.getHaxe(params.textDocument.uri);
29-
if (doc == null) {
29+
if (doc == null || diagnostic.range == null) {
3030
return [];
3131
}
3232
final preferredStyle = context.config.user.codeGeneration.imports.style;
@@ -55,7 +55,7 @@ class UnresolvedIdentifierActions {
5555
kind: QuickFix,
5656
edit: WorkspaceEditHelper.create(context, params, [
5757
{
58-
range: diagnostic.range,
58+
range: diagnostic.range.sure(),
5959
newText: arg.name
6060
}
6161
]),
@@ -66,11 +66,14 @@ class UnresolvedIdentifierActions {
6666
}
6767

6868
static function createTypoActions(context:Context, params:CodeActionParams, diagnostic:Diagnostic, arg):Array<CodeAction> {
69+
if (diagnostic.range == null)
70+
return [];
71+
6972
return [
7073
{
7174
title: "Change to " + arg.name,
7275
kind: QuickFix,
73-
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range, newText: arg.name}]),
76+
edit: WorkspaceEditHelper.create(context, params, [{range: diagnostic.range.sure(), newText: arg.name}]),
7477
diagnostics: [diagnostic]
7578
}
7679
];

src/haxeLanguageServer/features/haxe/codeAction/diagnostics/UnusedImportActions.hx

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class UnusedImportActions {
99
return [];
1010
}
1111
final doc = context.documents.getHaxe(params.textDocument.uri);
12-
if (doc == null) {
12+
if (doc == null || diagnostic.range == null) {
1313
return [];
1414
}
1515
return [
@@ -18,7 +18,7 @@ class UnusedImportActions {
1818
kind: QuickFix,
1919
edit: WorkspaceEditHelper.create(context, params, [
2020
{
21-
range: DocHelper.untrimRange(doc, diagnostic.range),
21+
range: DocHelper.untrimRange(doc, diagnostic.range.sure()),
2222
newText: ""
2323
}
2424
]),

src/haxeLanguageServer/features/haxe/completion/PostfixCompletion.hx

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class PostfixCompletion {
4646
}
4747

4848
final type = subject.item.type;
49-
if (type == null) {
49+
if (type == null || subject.range == null) {
5050
return [];
5151
}
5252
final type = type.removeNulls().type;

0 commit comments

Comments
 (0)