vendor tsgo
This commit is contained in:
102
tools/tsgo/internal/transformers/inliners/constenum.go
Normal file
102
tools/tsgo/internal/transformers/inliners/constenum.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package inliners
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/ast"
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/debug"
|
||||
"github.com/microsoft/typescript-go/internal/jsnum"
|
||||
"github.com/microsoft/typescript-go/internal/printer"
|
||||
"github.com/microsoft/typescript-go/internal/scanner"
|
||||
"github.com/microsoft/typescript-go/internal/transformers"
|
||||
)
|
||||
|
||||
type ConstEnumInliningTransformer struct {
|
||||
transformers.Transformer
|
||||
compilerOptions *core.CompilerOptions
|
||||
currentSourceFile *ast.SourceFile
|
||||
emitResolver printer.EmitResolver
|
||||
}
|
||||
|
||||
func NewConstEnumInliningTransformer(opt *transformers.TransformOptions) *transformers.Transformer {
|
||||
compilerOptions := opt.CompilerOptions
|
||||
emitContext := opt.Context
|
||||
if compilerOptions.GetIsolatedModules() {
|
||||
debug.Fail("const enums are not inlined under isolated modules")
|
||||
}
|
||||
tx := &ConstEnumInliningTransformer{compilerOptions: compilerOptions, emitResolver: opt.EmitResolver}
|
||||
return tx.NewTransformer(tx.visit, emitContext)
|
||||
}
|
||||
|
||||
func (tx *ConstEnumInliningTransformer) visit(node *ast.Node) *ast.Node {
|
||||
switch node.Kind {
|
||||
case ast.KindPropertyAccessExpression, ast.KindElementAccessExpression:
|
||||
{
|
||||
parse := tx.EmitContext().ParseNode(node)
|
||||
if parse == nil {
|
||||
return tx.Visitor().VisitEachChild(node)
|
||||
}
|
||||
value := tx.emitResolver.GetConstantValue(parse)
|
||||
if value != nil {
|
||||
var replacement *ast.Node
|
||||
switch v := value.(type) {
|
||||
case jsnum.Number:
|
||||
if v.IsInf() {
|
||||
if v.Abs() == v {
|
||||
replacement = tx.Factory().NewIdentifier("Infinity")
|
||||
} else {
|
||||
replacement = tx.Factory().NewPrefixUnaryExpression(ast.KindMinusToken, tx.Factory().NewIdentifier("Infinity"))
|
||||
}
|
||||
} else if v.IsNaN() {
|
||||
replacement = tx.Factory().NewIdentifier("NaN")
|
||||
} else if v.Abs() == v {
|
||||
replacement = tx.Factory().NewNumericLiteral(v.String(), ast.TokenFlagsNone)
|
||||
} else {
|
||||
replacement = tx.Factory().NewPrefixUnaryExpression(ast.KindMinusToken, tx.Factory().NewNumericLiteral(v.Abs().String(), ast.TokenFlagsNone))
|
||||
}
|
||||
case string:
|
||||
replacement = tx.Factory().NewStringLiteral(v, ast.TokenFlagsNone)
|
||||
case jsnum.PseudoBigInt: // technically not supported by strada, and issues a checker error, handled here for completeness
|
||||
if v == (jsnum.PseudoBigInt{}) {
|
||||
replacement = tx.Factory().NewBigIntLiteral("0", ast.TokenFlagsNone)
|
||||
} else if !v.Negative {
|
||||
replacement = tx.Factory().NewBigIntLiteral(v.Base10Value, ast.TokenFlagsNone)
|
||||
} else {
|
||||
replacement = tx.Factory().NewPrefixUnaryExpression(ast.KindMinusToken, tx.Factory().NewBigIntLiteral(v.Base10Value, ast.TokenFlagsNone))
|
||||
}
|
||||
}
|
||||
|
||||
if tx.compilerOptions.RemoveComments.IsFalseOrUnknown() {
|
||||
original := tx.EmitContext().MostOriginal(node)
|
||||
if original != nil && !ast.NodeIsSynthesized(original) {
|
||||
originalText := scanner.GetTextOfNode(original)
|
||||
escapedText := safeMultiLineComment(originalText)
|
||||
tx.EmitContext().AddSyntheticTrailingComment(replacement, ast.KindMultiLineCommentTrivia, escapedText, false)
|
||||
}
|
||||
}
|
||||
return replacement
|
||||
}
|
||||
return tx.Visitor().VisitEachChild(node)
|
||||
}
|
||||
}
|
||||
return tx.Visitor().VisitEachChild(node)
|
||||
}
|
||||
|
||||
func safeMultiLineComment(text string) string {
|
||||
var b strings.Builder
|
||||
b.Grow(len(text) + 2)
|
||||
b.WriteByte(' ')
|
||||
for {
|
||||
i := strings.Index(text, "*/")
|
||||
if i < 0 {
|
||||
break
|
||||
}
|
||||
b.WriteString(text[:i])
|
||||
b.WriteString("*_/")
|
||||
text = text[i+2:]
|
||||
}
|
||||
b.WriteString(text)
|
||||
b.WriteByte(' ')
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user