vendor tsgo
This commit is contained in:
227
tools/tsgo/internal/printer/textwriter.go
Normal file
227
tools/tsgo/internal/printer/textwriter.go
Normal file
@@ -0,0 +1,227 @@
|
||||
package printer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/ast"
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/stringutil"
|
||||
)
|
||||
|
||||
var _ EmitTextWriter = &textWriter{}
|
||||
|
||||
type textWriter struct {
|
||||
newLine string
|
||||
indentSize int
|
||||
builder strings.Builder
|
||||
lastWritten string
|
||||
indent int
|
||||
lineStart bool
|
||||
lineCount int
|
||||
linePos int
|
||||
hasTrailingCommentState bool
|
||||
}
|
||||
|
||||
func (w *textWriter) Clear() {
|
||||
*w = textWriter{newLine: w.newLine, indentSize: w.indentSize, lineStart: true}
|
||||
}
|
||||
|
||||
func (w *textWriter) Grow(n int) {
|
||||
w.builder.Grow(n)
|
||||
}
|
||||
|
||||
func (w *textWriter) DecreaseIndent() {
|
||||
w.indent--
|
||||
}
|
||||
|
||||
// GetColumn returns the column position measured in UTF-16 code units
|
||||
// for source map compatibility.
|
||||
func (w *textWriter) GetColumn() core.UTF16Offset {
|
||||
if w.lineStart {
|
||||
return core.UTF16Offset(w.indent * w.indentSize)
|
||||
}
|
||||
// Count UTF-16 code units from the last line start.
|
||||
// For ASCII-only output (the common case), this equals the byte count.
|
||||
return core.UTF16Len(w.builder.String()[w.linePos:])
|
||||
}
|
||||
|
||||
func (w *textWriter) GetIndent() int {
|
||||
return w.indent
|
||||
}
|
||||
|
||||
func (w *textWriter) GetLine() int {
|
||||
return w.lineCount
|
||||
}
|
||||
|
||||
func (w *textWriter) String() string {
|
||||
return w.builder.String()
|
||||
}
|
||||
|
||||
func (w *textWriter) GetTextPos() int {
|
||||
return w.builder.Len()
|
||||
}
|
||||
|
||||
func (w textWriter) HasTrailingComment() bool {
|
||||
return w.hasTrailingCommentState
|
||||
}
|
||||
|
||||
func (w *textWriter) 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 *textWriter) IncreaseIndent() {
|
||||
w.indent++
|
||||
}
|
||||
|
||||
func (w *textWriter) IsAtStartOfLine() bool {
|
||||
return w.lineStart
|
||||
}
|
||||
|
||||
func (w *textWriter) RawWrite(s string) {
|
||||
if s != "" {
|
||||
w.builder.WriteString(s)
|
||||
w.lastWritten = s
|
||||
w.hasTrailingCommentState = false
|
||||
}
|
||||
w.updateLineCountAndPosFor(s)
|
||||
}
|
||||
|
||||
func (w *textWriter) updateLineCountAndPosFor(s string) {
|
||||
var count int
|
||||
var lastLineStart core.TextPos
|
||||
|
||||
for lineStart := range core.ComputeECMALineStartsSeq(s) {
|
||||
count++
|
||||
lastLineStart = lineStart
|
||||
}
|
||||
|
||||
if count > 1 {
|
||||
w.lineCount += count - 1
|
||||
curLen := w.builder.Len()
|
||||
w.linePos = curLen - len(s) + int(lastLineStart)
|
||||
w.lineStart = (w.linePos - curLen) == 0
|
||||
return
|
||||
}
|
||||
w.lineStart = false
|
||||
}
|
||||
|
||||
const defaultIndentSize = 4
|
||||
|
||||
// GetDefaultIndentSize returns the default indent size (4 spaces) used when no specific indent size is configured.
|
||||
func GetDefaultIndentSize() int {
|
||||
return defaultIndentSize
|
||||
}
|
||||
|
||||
func getIndentString(indent int, indentSize int) string {
|
||||
if indent == 0 {
|
||||
return ""
|
||||
}
|
||||
// TODO: This is cached in tsc - should it be cached here?
|
||||
return strings.Repeat(" ", indent*indentSize)
|
||||
}
|
||||
|
||||
func (w *textWriter) writeText(s string) {
|
||||
if s != "" {
|
||||
if w.lineStart {
|
||||
w.builder.WriteString(getIndentString(w.indent, w.indentSize))
|
||||
w.lineStart = false
|
||||
}
|
||||
w.builder.WriteString(s)
|
||||
w.lastWritten = s
|
||||
w.updateLineCountAndPosFor(s)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *textWriter) Write(s string) {
|
||||
if s != "" {
|
||||
w.hasTrailingCommentState = false
|
||||
}
|
||||
w.writeText(s)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteComment(text string) {
|
||||
if text != "" {
|
||||
w.hasTrailingCommentState = true
|
||||
}
|
||||
w.writeText(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteKeyword(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) writeLineRaw() {
|
||||
w.builder.WriteString(w.newLine)
|
||||
w.lastWritten = w.newLine
|
||||
w.lineCount++
|
||||
w.linePos = w.builder.Len()
|
||||
w.lineStart = true
|
||||
w.hasTrailingCommentState = false
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteLine() {
|
||||
if !w.lineStart {
|
||||
w.writeLineRaw()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteLineForce(force bool) {
|
||||
if !w.lineStart || force {
|
||||
w.writeLineRaw()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteLiteral(s string) {
|
||||
w.Write(s)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteOperator(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteParameter(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteProperty(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WritePunctuation(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteSpace(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteStringLiteral(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteSymbol(text string, symbol *ast.Symbol) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteTrailingSemicolon(text string) {
|
||||
w.Write(text)
|
||||
}
|
||||
|
||||
func NewTextWriter(newLine string, indentSize int) EmitTextWriter {
|
||||
if indentSize <= 0 {
|
||||
indentSize = 4
|
||||
}
|
||||
var w textWriter
|
||||
w.newLine = newLine
|
||||
w.indentSize = indentSize
|
||||
w.Clear()
|
||||
return &w
|
||||
}
|
||||
Reference in New Issue
Block a user