Skip to content
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

Total ordering of types #200

Merged
merged 10 commits into from
Jan 8, 2025
2 changes: 1 addition & 1 deletion internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -5654,14 +5654,14 @@ type SourceFile struct {
IsDeclarationFile bool
IsBound bool
ModuleReferencesProcessed bool
HasNoDefaultLib bool
UsesUriStyleNodeCoreModules core.Tristate
SymbolCount int
ClassifiableNames core.Set[string]
Imports []*LiteralLikeNode // []LiteralLikeNode
ModuleAugmentations []*ModuleName // []ModuleName
PatternAmbientModules []PatternAmbientModule
AmbientModuleNames []string
HasNoDefaultLib bool
jsdocCache map[*Node][]*Node
Pragmas []Pragma
ReferencedFiles []*FileReference
Expand Down
12 changes: 5 additions & 7 deletions internal/ast/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,15 +821,13 @@ func WalkUpParenthesizedTypes(node *TypeNode) *Node {

// Walks up the parents of a node to find the containing SourceFile
func GetSourceFileOfNode(node *Node) *SourceFile {
for {
if node == nil {
return nil
}
if node.Kind == KindSourceFile {
return node.AsSourceFile()
}
for node.Parent != nil {
node = node.Parent
}
if node.Kind == KindSourceFile {
return node.AsSourceFile()
}
return nil
}

// Walks up the parents of a node to find the ancestor that matches the callback
Expand Down
30 changes: 18 additions & 12 deletions internal/compiler/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ type Checker struct {
host CompilerHost
compilerOptions *core.CompilerOptions
files []*ast.SourceFile
fileIndexMap map[*ast.SourceFile]int
compareSymbolsFunc func(*ast.Symbol, *ast.Symbol) int
typeCount uint32
symbolCount uint32
totalInstantiationCount uint32
Expand Down Expand Up @@ -732,6 +734,8 @@ func NewChecker(program *Program) *Checker {
c.host = program.host
c.compilerOptions = program.compilerOptions
c.files = program.files
c.fileIndexMap = createFileIndexMap(c.files)
c.compareSymbolsFunc = c.compareSymbols // Closure optimization
c.languageVersion = c.compilerOptions.GetEmitScriptTarget()
c.moduleKind = c.compilerOptions.GetEmitModuleKind()
c.legacyDecorators = c.compilerOptions.ExperimentalDecorators == core.TSTrue
Expand Down Expand Up @@ -862,7 +866,7 @@ func NewChecker(program *Program) *Checker {
c.emptyStringType = c.getStringLiteralType("")
c.zeroType = c.getNumberLiteralType(0)
c.zeroBigIntType = c.getBigIntLiteralType(PseudoBigInt{negative: false, base10Value: "0"})
c.typeofType = c.getUnionType(core.Map(slices.Collect(maps.Keys(typeofNEFacts)), c.getStringLiteralType))
c.typeofType = c.getUnionType(core.Map(slices.Sorted(maps.Keys(typeofNEFacts)), c.getStringLiteralType))
c.flowLoopCache = make(map[FlowLoopKey]*Type)
c.flowNodeReachable = make(map[*ast.FlowNode]bool)
c.flowNodePostSuper = make(map[*ast.FlowNode]bool)
Expand Down Expand Up @@ -903,6 +907,14 @@ func NewChecker(program *Program) *Checker {
return c
}

func createFileIndexMap(files []*ast.SourceFile) map[*ast.SourceFile]int {
result := make(map[*ast.SourceFile]int)
for i, file := range files {
result[file] = i
}
return result
}

func (c *Checker) reportUnreliableWorker(t *Type) *Type {
if c.outofbandVarianceMarkerHandler != nil && (t == c.markerSuperType || t == c.markerSubType || t == c.markerOtherType) {
c.outofbandVarianceMarkerHandler(true /*onlyUnreliable*/)
Expand Down Expand Up @@ -15109,7 +15121,7 @@ func (c *Checker) getNamedMembers(members ast.SymbolTable) []*ast.Symbol {
result = append(result, symbol)
}
}
sortSymbols(result)
c.sortSymbols(result)
return result
}

Expand Down Expand Up @@ -17861,6 +17873,7 @@ func (c *Checker) newType(flags TypeFlags, objectFlags ObjectFlags, data TypeDat
t.flags = flags
t.objectFlags = objectFlags &^ (ObjectFlagsCouldContainTypeVariablesComputed | ObjectFlagsCouldContainTypeVariables | ObjectFlagsMembersResolved)
t.id = TypeId(c.typeCount)
t.checker = c
t.data = data
return t
}
Expand Down Expand Up @@ -18601,14 +18614,7 @@ func (c *Checker) addTypeToUnion(typeSet []*Type, includes TypeFlags, t *Type) (
includes |= TypeFlagsIncludesNonWideningType
}
} else {
var index int
var ok bool
if len(typeSet) != 0 && t.id > typeSet[len(typeSet)-1].id {
index = len(typeSet)
} else {
index, ok = slices.BinarySearchFunc(typeSet, t, compareTypeIds)
}
if !ok {
if index, ok := slices.BinarySearchFunc(typeSet, t, compareTypes); !ok {
typeSet = slices.Insert(typeSet, index, t)
}
}
Expand Down Expand Up @@ -19350,12 +19356,12 @@ func (c *Checker) removeType(t *Type, targetType *Type) *Type {
}

func containsType(types []*Type, t *Type) bool {
_, ok := slices.BinarySearchFunc(types, t, compareTypeIds)
_, ok := slices.BinarySearchFunc(types, t, compareTypes)
return ok
}

func insertType(types []*Type, t *Type) ([]*Type, bool) {
if i, ok := slices.BinarySearchFunc(types, t, compareTypeIds); !ok {
if i, ok := slices.BinarySearchFunc(types, t, compareTypes); !ok {
return slices.Insert(types, i, t), true
}
return types, false
Expand Down
52 changes: 43 additions & 9 deletions internal/compiler/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,31 @@ package compiler

import "github.com/microsoft/typescript-go/internal/core"

// TypeMapperKind

type TypeMapperKind int32

const (
TypeMapperKindUnknown TypeMapperKind = iota
TypeMapperKindSimple
TypeMapperKindArray
TypeMapperKindMerged
)

// TypeMapper

type TypeMapper struct {
data TypeMapperData
}

func (m *TypeMapper) Map(t *Type) *Type { return m.data.Map(t) }
func (m *TypeMapper) Map(t *Type) *Type { return m.data.Map(t) }
func (m *TypeMapper) Kind() TypeMapperKind { return m.data.Kind() }

// TypeMapperData

type TypeMapperData interface {
Map(t *Type) *Type
Kind() TypeMapperKind
}

// Factory functions
Expand Down Expand Up @@ -70,10 +83,19 @@ func (c *Checker) newBackreferenceMapper(context *InferenceContext, index int) *
return newArrayToSingleTypeMapper(typeParameters, c.unknownType)
}

// TypeMapperBase

type TypeMapperBase struct {
TypeMapper
}

func (m *TypeMapperBase) Map(t *Type) *Type { return t }
func (m *TypeMapperBase) Kind() TypeMapperKind { return TypeMapperKindUnknown }

// SimpleTypeMapper

type SimpleTypeMapper struct {
TypeMapper
TypeMapperBase
source *Type
target *Type
}
Expand All @@ -93,10 +115,14 @@ func (m *SimpleTypeMapper) Map(t *Type) *Type {
return t
}

func (m *SimpleTypeMapper) Kind() TypeMapperKind {
return TypeMapperKindSimple
}

// ArrayTypeMapper

type ArrayTypeMapper struct {
TypeMapper
TypeMapperBase
sources []*Type
targets []*Type
}
Expand All @@ -118,10 +144,14 @@ func (m *ArrayTypeMapper) Map(t *Type) *Type {
return t
}

func (m *ArrayTypeMapper) Kind() TypeMapperKind {
return TypeMapperKindArray
}

// ArrayToSingleTypeMapper

type ArrayToSingleTypeMapper struct {
TypeMapper
TypeMapperBase
sources []*Type
target *Type
}
Expand All @@ -146,7 +176,7 @@ func (m *ArrayToSingleTypeMapper) Map(t *Type) *Type {
// DeferredTypeMapper

type DeferredTypeMapper struct {
TypeMapper
TypeMapperBase
sources []*Type
targets []func() *Type
}
Expand All @@ -171,7 +201,7 @@ func (m *DeferredTypeMapper) Map(t *Type) *Type {
// FunctionTypeMapper

type FunctionTypeMapper struct {
TypeMapper
TypeMapperBase
fn func(*Type) *Type
}

Expand All @@ -189,7 +219,7 @@ func (m *FunctionTypeMapper) Map(t *Type) *Type {
// MergedTypeMapper

type MergedTypeMapper struct {
TypeMapper
TypeMapperBase
m1 *TypeMapper
m2 *TypeMapper
}
Expand All @@ -206,10 +236,14 @@ func (m *MergedTypeMapper) Map(t *Type) *Type {
return m.m2.Map(m.m1.Map(t))
}

func (m *MergedTypeMapper) Kind() TypeMapperKind {
return TypeMapperKindMerged
}

// CompositeTypeMapper

type CompositeTypeMapper struct {
TypeMapper
TypeMapperBase
c *Checker
m1 *TypeMapper
m2 *TypeMapper
Expand All @@ -235,7 +269,7 @@ func (m *CompositeTypeMapper) Map(t *Type) *Type {
// InferenceTypeMapper

type InferenceTypeMapper struct {
TypeMapper
TypeMapperBase
c *Checker
n *InferenceContext
fixing bool
Expand Down
37 changes: 26 additions & 11 deletions internal/compiler/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func (p *Printer) printType(t *Type) {
}

func (p *Printer) printTypeNoAlias(t *Type) {
p.depth++
switch {
case t.flags&TypeFlagsIntrinsic != 0:
p.print(t.AsIntrinsicType().intrinsicName)
Expand All @@ -138,14 +139,13 @@ func (p *Printer) printTypeNoAlias(t *Type) {
case t.flags&TypeFlagsSubstitution != 0:
p.printType(t.AsSubstitutionType().baseType)
}
p.depth--
}

func (p *Printer) printRecursive(t *Type, f func(*Printer, *Type)) {
if !p.printing.Has(t) && p.depth < 10 {
p.printing.Add(t)
p.depth++
f(p, t)
p.depth--
p.printing.Delete(t)
} else {
p.print("???")
Expand Down Expand Up @@ -282,22 +282,37 @@ func (p *Printer) printTupleType(t *Type) {
tail := false
p.print("[")
elementInfos := t.TargetTupleType().elementInfos
for i, t := range p.c.getTypeArguments(t) {
typeArguments := p.c.getTypeArguments(t)
for i, info := range elementInfos {
t := typeArguments[i]
if tail {
p.print(", ")
}
info := elementInfos[i]
if info.flags&ElementFlagsVariable != 0 {
p.print("...")
}
if info.flags&ElementFlagsOptional != 0 {
p.printTypeEx(t, ast.TypePrecedencePostfix)
p.print("?")
} else if info.flags&ElementFlagsRest != 0 {
p.printTypeEx(t, ast.TypePrecedencePostfix)
p.print("[]")
if info.labeledDeclaration != nil {
p.print(info.labeledDeclaration.Name().Text())
if info.flags&ElementFlagsOptional != 0 {
p.print("?")
}
p.print(": ")
if info.flags&ElementFlagsRest != 0 {
p.printTypeEx(t, ast.TypePrecedencePostfix)
p.print("[]")
} else {
p.printType(t)
}
} else {
p.printType(t)
if info.flags&ElementFlagsOptional != 0 {
p.printTypeEx(t, ast.TypePrecedencePostfix)
p.print("?")
} else if info.flags&ElementFlagsRest != 0 {
p.printTypeEx(t, ast.TypePrecedencePostfix)
p.print("[]")
} else {
p.printType(t)
}
}
tail = true
}
Expand Down
Loading
Loading