diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index 8554c14276a..f1220cea7f4 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -1143,32 +1143,36 @@ func GetRootDeclaration(node *Node) *Node { return node } -func getCombinedFlags[T ~uint32](node *Node, getFlags func(*Node) T) T { +func GetCombinedModifierFlags(node *Node) ModifierFlags { node = GetRootDeclaration(node) - flags := getFlags(node) + flags := node.ModifierFlags() if node.Kind == KindVariableDeclaration { node = node.Parent } if node != nil && node.Kind == KindVariableDeclarationList { - flags |= getFlags(node) + flags |= node.ModifierFlags() node = node.Parent } if node != nil && node.Kind == KindVariableStatement { - flags |= getFlags(node) + flags |= node.ModifierFlags() } return flags } -func GetCombinedModifierFlags(node *Node) ModifierFlags { - return getCombinedFlags(node, (*Node).ModifierFlags) -} - func GetCombinedNodeFlags(node *Node) NodeFlags { - return getCombinedFlags(node, getNodeFlags) -} - -func getNodeFlags(node *Node) NodeFlags { - return node.Flags + node = GetRootDeclaration(node) + flags := node.Flags + if node.Kind == KindVariableDeclaration { + node = node.Parent + } + if node != nil && node.Kind == KindVariableDeclarationList { + flags |= node.Flags + node = node.Parent + } + if node != nil && node.Kind == KindVariableStatement { + flags |= node.Flags + } + return flags } // Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of an `await using` declaration. diff --git a/internal/ast/utilities_bench_test.go b/internal/ast/utilities_bench_test.go new file mode 100644 index 00000000000..30e4465ba1b --- /dev/null +++ b/internal/ast/utilities_bench_test.go @@ -0,0 +1,48 @@ +package ast_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/ast" + "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/parser" + "github.com/microsoft/typescript-go/internal/testutil/fixtures" + "github.com/microsoft/typescript-go/internal/tspath" + "github.com/microsoft/typescript-go/internal/vfs/osvfs" +) + +func BenchmarkGetCombinedFlags(b *testing.B) { + for _, f := range fixtures.BenchFixtures { + b.Run(f.Name(), func(b *testing.B) { + f.SkipIfNotExist(b) + + fileName := tspath.GetNormalizedAbsolutePath(f.Path(), "/") + path := tspath.ToPath(fileName, "/", osvfs.FS().UseCaseSensitiveFileNames()) + sourceText := f.ReadFile(b) + scriptKind := core.GetScriptKindFromFileName(fileName) + + sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: fileName, + Path: path, + }, sourceText, scriptKind) + + var decls []*ast.Node + var collect ast.Visitor + collect = func(n *ast.Node) bool { + if ast.IsDeclaration(n) { + decls = append(decls, n) + } + n.ForEachChild(collect) + return false + } + sourceFile.AsNode().ForEachChild(collect) + + for b.Loop() { + for _, n := range decls { + _ = ast.GetCombinedNodeFlags(n) + _ = ast.GetCombinedModifierFlags(n) + } + } + }) + } +}