-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce related spans into tsserver protocol #24548
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -495,8 +495,8 @@ namespace ts.projectSystem { | |
checkNthEvent(session, server.toEvent(eventName, diagnostics), 0, isMostRecent); | ||
} | ||
|
||
function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray<string> = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}): protocol.Diagnostic { | ||
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, source: undefined }; | ||
function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray<string> = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}, relatedInformation?: protocol.DiagnosticRelatedInformation[]): protocol.Diagnostic { | ||
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, relatedInformation, source: undefined }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Should this new property be validated in some way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing has been modified to produce one yet, though we have a massive list courtesy of @DanielRosenwasser - this just makes it so we can start chipping that list away. |
||
} | ||
|
||
function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number, isMostRecent = true): void { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,7 +76,24 @@ namespace ts.server { | |
code: diag.code, | ||
category: diagnosticCategoryName(diag), | ||
reportsUnnecessary: diag.reportsUnnecessary, | ||
source: diag.source | ||
source: diag.source, | ||
relatedInformation: map(diag.relatedInformation, formatRelatedInformation), | ||
}; | ||
} | ||
|
||
function formatRelatedInformation(info: DiagnosticRelatedInformation): protocol.DiagnosticRelatedInformation { | ||
if (!info.file) { | ||
return { | ||
message: flattenDiagnosticMessageText(info.messageText, "\n") | ||
}; | ||
} | ||
return { | ||
span: { | ||
start: convertToLocation(getLineAndCharacterOfPosition(info.file, info.start!)), | ||
end: convertToLocation(getLineAndCharacterOfPosition(info.file, info.start! + info.length!)), // TODO: GH#18217 | ||
file: info.file.fileName | ||
}, | ||
message: flattenDiagnosticMessageText(info.messageText, "\n") | ||
}; | ||
} | ||
|
||
|
@@ -92,8 +109,19 @@ namespace ts.server { | |
const text = flattenDiagnosticMessageText(diag.messageText, "\n"); | ||
const { code, source } = diag; | ||
const category = diagnosticCategoryName(diag); | ||
return includeFileName ? { start, end, text, code, category, source, reportsUnnecessary: diag.reportsUnnecessary, fileName: diag.file && diag.file.fileName } : | ||
{ start, end, text, code, category, reportsUnnecessary: diag.reportsUnnecessary, source }; | ||
const common = { | ||
start, | ||
end, | ||
text, | ||
code, | ||
category, | ||
reportsUnnecessary: diag.reportsUnnecessary, | ||
source, | ||
relatedInformation: map(diag.relatedInformation, formatRelatedInformation), | ||
}; | ||
return includeFileName | ||
? { ...common, fileName: diag.file && diag.file.fileName } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to create an object just to inline it.. you can set |
||
: common; | ||
} | ||
|
||
export interface PendingErrorCheck { | ||
|
@@ -610,7 +638,8 @@ namespace ts.server { | |
category: diagnosticCategoryName(d), | ||
code: d.code, | ||
startLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start!)))!, // TODO: GH#18217 | ||
endLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start! + d.length!)))! // TODO: GH#18217 | ||
endLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start! + d.length!)))!, // TODO: GH#18217 | ||
relatedInformation: map(d.relatedInformation, formatRelatedInformation) | ||
})); | ||
} | ||
|
||
|
@@ -638,7 +667,8 @@ namespace ts.server { | |
source: d.source, | ||
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start!), // TODO: GH#18217 | ||
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start! + d.length!), | ||
reportsUnnecessary: d.reportsUnnecessary | ||
reportsUnnecessary: d.reportsUnnecessary, | ||
relatedInformation: map(d.relatedInformation, formatRelatedInformation), | ||
}); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I need more information about how these are intended to be used. Roslyn diagnostics support additional locations, but those locations don't have messages. We could create separate diagnostics but we would need a new code and category and I don't believe we'd be able to link them together. I think Roslyn more or less dropped this functionality (vs the old native compiler).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Secondary code locations and more information pertaining to specifically that location in the context of the diagnostic. (eg, "Defined here", "Declared here", "Replicated here", and so on. The additional spans also allow us to use those spans when calculating quick fixes - so we can, for example, know what we can suggest a cast at the site of an assignability error, but also suggest modifying the type the assignment is failing against (because it is mentioned as a related span). The only diagnostic set we currently do a similar thing with is the
esModuleInterop
import error, which we currently issue a secondary diagnostic for (so there's no obvious link between the two).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, this isn't a new concept and there is prior art, which is why vscode has basic support for them (and is looking to iterate on their UI) - rust makes good use of related spans in it's errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not saying that it's either novel or bad, just that it goes against the grain of the API we're using.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to sit down and design this feature.. there seems to be two uses cases,
x
is not assignable to string, and here is wherex
was declated