vendor tsgo
This commit is contained in:
217
tools/tsgo/internal/ls/displaypartswriter.go
Normal file
217
tools/tsgo/internal/ls/displaypartswriter.go
Normal file
@@ -0,0 +1,217 @@
|
||||
package ls
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/ast"
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/printer"
|
||||
"github.com/microsoft/typescript-go/internal/stringutil"
|
||||
)
|
||||
|
||||
var _ printer.EmitTextWriter = &displayPartsWriter{}
|
||||
|
||||
// displayPartsWriter implements EmitTextWriter and captures classified text runs
|
||||
// for VS colorized labels, while also building a plain string.
|
||||
// When vsCapability is false, only the plain string is built; runs are skipped.
|
||||
type displayPartsWriter struct {
|
||||
builder strings.Builder
|
||||
runs []*lsproto.VSClassifiedTextRun
|
||||
vsCapability bool
|
||||
lastWritten string
|
||||
}
|
||||
|
||||
func newDisplayPartsWriter(vsCapability bool) *displayPartsWriter {
|
||||
return &displayPartsWriter{vsCapability: vsCapability}
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) addRun(classification lsproto.ClassificationTypeName, text string) {
|
||||
if text == "" {
|
||||
return
|
||||
}
|
||||
if w.vsCapability {
|
||||
w.runs = append(w.runs, &lsproto.VSClassifiedTextRun{
|
||||
ClassificationTypeName: string(classification),
|
||||
Text: text,
|
||||
})
|
||||
}
|
||||
w.lastWritten = text
|
||||
w.builder.WriteString(text)
|
||||
}
|
||||
|
||||
// WriteClassified writes text with an explicit classification type.
|
||||
func (w *displayPartsWriter) WriteClassified(text string, classification lsproto.ClassificationTypeName) {
|
||||
w.addRun(classification, text)
|
||||
}
|
||||
|
||||
// WriteFrom copies the accumulated content from another displayPartsWriter.
|
||||
func (w *displayPartsWriter) WriteFrom(other *displayPartsWriter) {
|
||||
w.builder.WriteString(other.String())
|
||||
if w.vsCapability {
|
||||
w.runs = append(w.runs, other.GetRuns()...)
|
||||
}
|
||||
if other.lastWritten != "" {
|
||||
w.lastWritten = other.lastWritten
|
||||
}
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) GetRuns() []*lsproto.VSClassifiedTextRun {
|
||||
return w.runs
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) String() string {
|
||||
return w.builder.String()
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) Clear() {
|
||||
w.lastWritten = ""
|
||||
w.builder.Reset()
|
||||
w.runs = nil
|
||||
}
|
||||
|
||||
func (w displayPartsWriter) DecreaseIndent() {}
|
||||
|
||||
func (w displayPartsWriter) GetColumn() core.UTF16Offset { return 0 }
|
||||
|
||||
func (w displayPartsWriter) GetIndent() int { return 0 }
|
||||
|
||||
func (w displayPartsWriter) GetLine() int { return 0 }
|
||||
|
||||
func (w displayPartsWriter) GetTextPos() int {
|
||||
return w.builder.Len()
|
||||
}
|
||||
|
||||
func (w displayPartsWriter) HasTrailingComment() bool { return false }
|
||||
|
||||
func (w displayPartsWriter) HasTrailingWhitespace() bool {
|
||||
if w.builder.Len() == 0 {
|
||||
return false
|
||||
}
|
||||
ch, _ := utf8.DecodeLastRuneInString(w.lastWritten)
|
||||
if ch == utf8.RuneError {
|
||||
return false
|
||||
}
|
||||
return stringutil.IsWhiteSpaceLike(ch)
|
||||
}
|
||||
|
||||
func (w displayPartsWriter) IncreaseIndent() {}
|
||||
|
||||
func (w displayPartsWriter) IsAtStartOfLine() bool { return false }
|
||||
|
||||
func (w *displayPartsWriter) RawWrite(s string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameText, s)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) Write(s string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameText, s)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteComment(text string) {
|
||||
// Strada's writeComment uses unknownWrite → SymbolDisplayPartKind.text → "text"
|
||||
w.addRun(lsproto.ClassificationTypeNameText, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteKeyword(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameKeyword, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteLine() {
|
||||
w.addRun(lsproto.ClassificationTypeNameWhiteSpace, " ")
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteLineForce(force bool) {
|
||||
w.addRun(lsproto.ClassificationTypeNameWhiteSpace, " ")
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteLiteral(s string) {
|
||||
// Strada's writeLiteral → SymbolDisplayPartKind.stringLiteral → "string"
|
||||
w.addRun(lsproto.ClassificationTypeNameString, s)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteOperator(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameOperator, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteParameter(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameParameterName, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteProperty(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNamePropertyName, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WritePunctuation(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNamePunctuation, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteSpace(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameWhiteSpace, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteStringLiteral(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNameString, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteSymbol(text string, symbol *ast.Symbol) {
|
||||
classification := classificationForSymbol(symbol)
|
||||
w.addRun(classification, text)
|
||||
}
|
||||
|
||||
func (w *displayPartsWriter) WriteTrailingSemicolon(text string) {
|
||||
w.addRun(lsproto.ClassificationTypeNamePunctuation, text)
|
||||
}
|
||||
|
||||
// classificationForSymbol determines the Roslyn classification type name based on a symbol's flags.
|
||||
// Matches the Strada translation chain: displayPartKind() → GetClassificationName().
|
||||
func classificationForSymbol(symbol *ast.Symbol) lsproto.ClassificationTypeName {
|
||||
if symbol == nil {
|
||||
return lsproto.ClassificationTypeNameText
|
||||
}
|
||||
flags := symbol.Flags
|
||||
switch {
|
||||
case flags&ast.SymbolFlagsVariable != 0:
|
||||
if isFirstDeclarationOfSymbolParameter(symbol) {
|
||||
return lsproto.ClassificationTypeNameParameterName
|
||||
}
|
||||
return lsproto.ClassificationTypeNameLocalName
|
||||
case flags&ast.SymbolFlagsProperty != 0:
|
||||
return lsproto.ClassificationTypeNamePropertyName
|
||||
case flags&ast.SymbolFlagsGetAccessor != 0:
|
||||
return lsproto.ClassificationTypeNamePropertyName
|
||||
case flags&ast.SymbolFlagsSetAccessor != 0:
|
||||
return lsproto.ClassificationTypeNamePropertyName
|
||||
case flags&ast.SymbolFlagsEnumMember != 0:
|
||||
return lsproto.ClassificationTypeNameFieldName
|
||||
case flags&ast.SymbolFlagsFunction != 0:
|
||||
return lsproto.ClassificationTypeNameMethodName
|
||||
case flags&ast.SymbolFlagsClass != 0:
|
||||
return lsproto.ClassificationTypeNameClassName
|
||||
case flags&ast.SymbolFlagsInterface != 0:
|
||||
return lsproto.ClassificationTypeNameInterfaceName
|
||||
case flags&ast.SymbolFlagsEnum != 0:
|
||||
return lsproto.ClassificationTypeNameEnumName
|
||||
case flags&ast.SymbolFlagsModule != 0:
|
||||
return lsproto.ClassificationTypeNameModuleName
|
||||
case flags&ast.SymbolFlagsMethod != 0:
|
||||
return lsproto.ClassificationTypeNameMethodName
|
||||
case flags&ast.SymbolFlagsTypeParameter != 0:
|
||||
return lsproto.ClassificationTypeNameTypeParameterName
|
||||
case flags&ast.SymbolFlagsTypeAlias != 0:
|
||||
return lsproto.ClassificationTypeNameIdentifier
|
||||
case flags&ast.SymbolFlagsAlias != 0:
|
||||
return lsproto.ClassificationTypeNameIdentifier
|
||||
default:
|
||||
return lsproto.ClassificationTypeNameText
|
||||
}
|
||||
}
|
||||
|
||||
// isFirstDeclarationOfSymbolParameter checks if the symbol's first declaration is a parameter.
|
||||
func isFirstDeclarationOfSymbolParameter(symbol *ast.Symbol) bool {
|
||||
declarations := symbol.Declarations
|
||||
if len(declarations) == 0 {
|
||||
return false
|
||||
}
|
||||
return declarations[0].Kind == ast.KindParameter
|
||||
}
|
||||
Reference in New Issue
Block a user