Skip to content

Feature implementation from commits 16ce71d..ed1c512 #1

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

Open
wants to merge 15 commits into
base: feature-base-branch-1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Herebyfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ export const packNativePreviewExtensions = task({

await fs.promises.copyFile("NOTICE.txt", path.join(thisExtensionDir, "NOTICE.txt"));

await $({ cwd: thisExtensionDir })`vsce package ${version} --pre-release --no-update-package-json --no-dependencies --out ${vsixPath} --target ${vscodeTarget}`;
await $({ cwd: thisExtensionDir })`vsce package ${version} --no-update-package-json --no-dependencies --out ${vsixPath} --target ${vscodeTarget}`;

if (options.forRelease) {
await $({ cwd: thisExtensionDir })`vsce generate-manifest --packagePath ${vsixPath} --out ${vsixManifestPath}`;
Expand Down
2 changes: 1 addition & 1 deletion _packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@
},
"dependencies": {
"@typescript/ast": "1.0.0",
"libsyncrpc": "github:microsoft/libsyncrpc#bb02d84"
"@typescript/libsyncrpc": "github:microsoft/libsyncrpc#8cdae454cc482536c5844bef83b796f95464da85"
}
}
2 changes: 1 addition & 1 deletion _packages/api/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SyncRpcChannel } from "libsyncrpc";
import { SyncRpcChannel } from "@typescript/libsyncrpc";
import type { FileSystem } from "./fs.ts";

export interface ClientOptions {
Expand Down
43 changes: 24 additions & 19 deletions internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1999,10 +1999,8 @@ func (node *Token) Clone(f NodeFactoryCoercible) *Node {

func (node *Token) computeSubtreeFacts() SubtreeFacts {
switch node.Kind {
case KindAsyncKeyword:
return SubtreeContainsES2017 | SubtreeContainsES2018
case KindUsingKeyword:
return SubtreeContainsESNext
return SubtreeContainsUsing
case KindPublicKeyword,
KindPrivateKeyword,
KindProtectedKeyword,
Expand All @@ -2029,11 +2027,11 @@ func (node *Token) computeSubtreeFacts() SubtreeFacts {
case KindAccessorKeyword:
return SubtreeContainsClassFields
case KindAsteriskAsteriskToken, KindAsteriskAsteriskEqualsToken:
return SubtreeContainsES2016
return SubtreeContainsExponentiationOperator
case KindQuestionQuestionToken, KindQuestionDotToken:
return SubtreeContainsES2020
return SubtreeContainsOptionalChaining
case KindQuestionQuestionEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken:
return SubtreeContainsES2021
return SubtreeContainsLogicalAssignments
}
return SubtreeFactsNone
}
Expand Down Expand Up @@ -2927,8 +2925,12 @@ func (node *CatchClause) Clone(f NodeFactoryCoercible) *Node {
}

func (node *CatchClause) computeSubtreeFacts() SubtreeFacts {
return propagateSubtreeFacts(node.VariableDeclaration) |
res := propagateSubtreeFacts(node.VariableDeclaration) |
propagateSubtreeFacts(node.Block)
if node.VariableDeclaration == nil {
res |= SubtreeContainsMissingCatchClauseVariable
}
return res
}

func (node *CatchClause) propagateSubtreeFacts() SubtreeFacts {
Expand Down Expand Up @@ -3220,7 +3222,7 @@ func (node *VariableDeclarationList) Clone(f NodeFactoryCoercible) *Node {

func (node *VariableDeclarationList) computeSubtreeFacts() SubtreeFacts {
return propagateNodeListSubtreeFacts(node.Declarations, propagateSubtreeFacts) |
core.IfElse(node.Flags&NodeFlagsUsing != 0, SubtreeContainsESNext, SubtreeFactsNone)
core.IfElse(node.Flags&NodeFlagsUsing != 0, SubtreeContainsUsing, SubtreeFactsNone)
}

func (node *VariableDeclarationList) propagateSubtreeFacts() SubtreeFacts {
Expand Down Expand Up @@ -3512,8 +3514,8 @@ func (node *FunctionDeclaration) computeSubtreeFacts() SubtreeFacts {
propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) |
propagateEraseableSyntaxSubtreeFacts(node.Type) |
propagateSubtreeFacts(node.Body) |
core.IfElse(isAsync && isGenerator, SubtreeContainsES2018, SubtreeFactsNone) |
core.IfElse(isAsync && !isGenerator, SubtreeContainsES2017, SubtreeFactsNone)
core.IfElse(isAsync && isGenerator, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) |
core.IfElse(isAsync && !isGenerator, SubtreeContainsAnyAwait, SubtreeFactsNone)
}
}

Expand Down Expand Up @@ -5215,8 +5217,8 @@ func (node *MethodDeclaration) computeSubtreeFacts() SubtreeFacts {
propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) |
propagateSubtreeFacts(node.Body) |
propagateEraseableSyntaxSubtreeFacts(node.Type) |
core.IfElse(isAsync && isGenerator, SubtreeContainsES2018, SubtreeFactsNone) |
core.IfElse(isAsync && !isGenerator, SubtreeContainsES2017, SubtreeFactsNone)
core.IfElse(isAsync && isGenerator, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) |
core.IfElse(isAsync && !isGenerator, SubtreeContainsAnyAwait, SubtreeFactsNone)
}
}

Expand Down Expand Up @@ -5520,7 +5522,7 @@ func (node *BigIntLiteral) Clone(f NodeFactoryCoercible) *Node {
}

func (node *BigIntLiteral) computeSubtreeFacts() SubtreeFacts {
return SubtreeContainsES2020
return SubtreeFactsNone // `bigint` is not downleveled in any way
}

func IsBigIntLiteral(node *Node) bool {
Expand Down Expand Up @@ -5798,7 +5800,7 @@ func (node *ArrowFunction) computeSubtreeFacts() SubtreeFacts {
propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) |
propagateEraseableSyntaxSubtreeFacts(node.Type) |
propagateSubtreeFacts(node.Body) |
core.IfElse(node.ModifierFlags()&ModifierFlagsAsync != 0, SubtreeContainsES2017, SubtreeFactsNone)
core.IfElse(node.ModifierFlags()&ModifierFlagsAsync != 0, SubtreeContainsAnyAwait, SubtreeFactsNone)
}

func (node *ArrowFunction) propagateSubtreeFacts() SubtreeFacts {
Expand Down Expand Up @@ -5868,8 +5870,8 @@ func (node *FunctionExpression) computeSubtreeFacts() SubtreeFacts {
propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) |
propagateEraseableSyntaxSubtreeFacts(node.Type) |
propagateSubtreeFacts(node.Body) |
core.IfElse(isAsync && isGenerator, SubtreeContainsES2018, SubtreeFactsNone) |
core.IfElse(isAsync && !isGenerator, SubtreeContainsES2017, SubtreeFactsNone)
core.IfElse(isAsync && isGenerator, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) |
core.IfElse(isAsync && !isGenerator, SubtreeContainsAnyAwait, SubtreeFactsNone)
}

func (node *FunctionExpression) propagateSubtreeFacts() SubtreeFacts {
Expand Down Expand Up @@ -6279,8 +6281,7 @@ func (node *MetaProperty) Name() *DeclarationName {
}

func (node *MetaProperty) computeSubtreeFacts() SubtreeFacts {
return propagateSubtreeFacts(node.name) |
core.IfElse(node.KeywordToken == KindImportKeyword, SubtreeContainsES2020, SubtreeFactsNone)
return propagateSubtreeFacts(node.name) // `import.meta` is not downleveled in any way
}

func IsMetaProperty(node *Node) bool {
Expand Down Expand Up @@ -6939,7 +6940,7 @@ func (node *AwaitExpression) Clone(f NodeFactoryCoercible) *Node {
}

func (node *AwaitExpression) computeSubtreeFacts() SubtreeFacts {
return propagateSubtreeFacts(node.Expression) | SubtreeContainsES2017 | SubtreeContainsES2018 | SubtreeContainsAwait
return propagateSubtreeFacts(node.Expression) | SubtreeContainsAwait
}

func IsAwaitExpression(node *Node) bool {
Expand Down Expand Up @@ -9624,6 +9625,10 @@ func (node *JSDocAugmentsTag) Clone(f NodeFactoryCoercible) *Node {
return cloneNode(f.AsNodeFactory().NewJSDocAugmentsTag(node.TagName, node.ClassName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocAugmentsTag(node *Node) bool {
return node.Kind == KindJSDocAugmentsTag
}

// JSDocSatisfiesTag
type JSDocSatisfiesTag struct {
JSDocTagBase
Expand Down
2 changes: 0 additions & 2 deletions internal/ast/nodeflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ const (
NodeFlagsJsonFile NodeFlags = 1 << 25 // If node was parsed in a Json
NodeFlagsDeprecated NodeFlags = 1 << 26 // If has '@deprecated' JSDoc tag

NodeFlagsSkipDirectInference NodeFlags = 1 << 27 // If the node should skip direct type inference.

NodeFlagsBlockScoped = NodeFlagsLet | NodeFlagsConst | NodeFlagsUsing
NodeFlagsConstant = NodeFlagsConst | NodeFlagsUsing
NodeFlagsAwaitUsing = NodeFlagsConst | NodeFlagsUsing // Variable declaration (NOTE: on a single node these flags would otherwise be mutually exclusive)
Expand Down
33 changes: 24 additions & 9 deletions internal/ast/subtreefacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@ type SubtreeFacts int32

const (
// Facts
// - Flags used to indicate that a node or subtree contains syntax specific to a particular ECMAScript variant.
// - Flags used to indicate that a node or subtree contains syntax relevant to a specific transform

SubtreeContainsTypeScript SubtreeFacts = 1 << iota
SubtreeContainsJsx
SubtreeContainsESNext
SubtreeContainsES2022
SubtreeContainsES2021
SubtreeContainsES2020
SubtreeContainsES2019
SubtreeContainsES2018
SubtreeContainsES2017
SubtreeContainsES2016
SubtreeContainsESDecorators
SubtreeContainsUsing
SubtreeContainsClassStaticBlocks
SubtreeContainsESClassFields
SubtreeContainsLogicalAssignments
SubtreeContainsNullishCoalescing
SubtreeContainsOptionalChaining
SubtreeContainsMissingCatchClauseVariable
SubtreeContainsESObjectRestOrSpread
SubtreeContainsForAwaitOrAsyncGenerator
SubtreeContainsAnyAwait
SubtreeContainsExponentiationOperator

// Markers
// - Flags used to indicate that a node or subtree contains a particular kind of syntax.
Expand All @@ -37,6 +41,17 @@ const (
SubtreeFactsComputed // NOTE: This should always be last
SubtreeFactsNone SubtreeFacts = 0

// Aliases (unused, for documentation purposes only - correspond to combinations in transformers/estransforms/definitions.go)

SubtreeContainsESNext = SubtreeContainsESDecorators | SubtreeContainsUsing
SubtreeContainsES2022 = SubtreeContainsClassStaticBlocks | SubtreeContainsESClassFields
SubtreeContainsES2021 = SubtreeContainsLogicalAssignments
SubtreeContainsES2020 = SubtreeContainsNullishCoalescing | SubtreeContainsOptionalChaining
SubtreeContainsES2019 = SubtreeContainsMissingCatchClauseVariable
SubtreeContainsES2018 = SubtreeContainsESObjectRestOrSpread | SubtreeContainsForAwaitOrAsyncGenerator
SubtreeContainsES2017 = SubtreeContainsAnyAwait
SubtreeContainsES2016 = SubtreeContainsExponentiationOperator

// Scope Exclusions
// - Bitmasks that exclude flags from propagating out of a specific context
// into the subtree flags of their container.
Expand Down
5 changes: 2 additions & 3 deletions internal/ast/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,7 @@ func newParentInChildrenSetter() func(node *Node) bool {
}

state.visit = func(node *Node) bool {
if state.parent != nil && node.Parent != state.parent {
// Avoid data races on no-ops
if state.parent != nil {
node.Parent = state.parent
}
saveParent := state.parent
Expand Down Expand Up @@ -3033,7 +3032,7 @@ func IsJSDocSingleCommentNode(node *Node) bool {
}

func IsValidTypeOnlyAliasUseSite(useSite *Node) bool {
return useSite.Flags&NodeFlagsAmbient != 0 ||
return useSite.Flags&(NodeFlagsAmbient|NodeFlagsJSDoc) != 0 ||
IsPartOfTypeQuery(useSite) ||
isIdentifierInNonEmittingHeritageClause(useSite) ||
isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite) ||
Expand Down
42 changes: 0 additions & 42 deletions internal/binder/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ type Binder struct {
unreachableFlow *ast.FlowNode
reportedUnreachableFlow *ast.FlowNode

parent *ast.Node
container *ast.Node
thisContainer *ast.Node
blockScopeContainer *ast.Node
Expand Down Expand Up @@ -211,9 +210,6 @@ func (b *Binder) declareSymbolEx(symbolTable ast.SymbolTable, parent *ast.Symbol
} else if !(includes&ast.SymbolFlagsVariable != 0 && symbol.Flags&ast.SymbolFlagsAssignment != 0 ||
includes&ast.SymbolFlagsAssignment != 0 && symbol.Flags&ast.SymbolFlagsVariable != 0) {
// Assignment declarations are allowed to merge with variables, no matter what other flags they have.
if node.Name() != nil {
setParent(node.Name(), node)
}
// Report errors every position with duplicate declaration
// Report errors on previous encountered declarations
var message *diagnostics.Message
Expand Down Expand Up @@ -584,9 +580,6 @@ func (b *Binder) bind(node *ast.Node) bool {
if node == nil {
return false
}
if node.Parent == nil || node.Parent.Flags&ast.NodeFlagsReparsed != 0 {
node.Parent = b.parent
}
saveInStrictMode := b.inStrictMode
// Even though in the AST the jsdoc @typedef node belongs to the current node,
// its symbol might be in the same scope with the current node's symbol. Consider:
Expand Down Expand Up @@ -731,9 +724,7 @@ func (b *Binder) bind(node *ast.Node) bool {
// children, as an optimization we don't process those.
thisNodeOrAnySubnodesHasError := node.Flags&ast.NodeFlagsThisNodeHasError != 0
if node.Kind > ast.KindLastToken {
saveParent := b.parent
saveSeenParseError := b.seenParseError
b.parent = node
b.seenParseError = false
containerFlags := GetContainerFlags(node)
if containerFlags == ContainerFlagsNone {
Expand All @@ -744,15 +735,7 @@ func (b *Binder) bind(node *ast.Node) bool {
if b.seenParseError {
thisNodeOrAnySubnodesHasError = true
}
b.parent = saveParent
b.seenParseError = saveSeenParseError
} else {
saveParent := b.parent
if node.Kind == ast.KindEndOfFile {
b.parent = node
}
b.setJSDocParents(node)
b.parent = saveParent
}
if thisNodeOrAnySubnodesHasError {
node.Flags |= ast.NodeFlagsThisNodeOrAnySubNodesHasError
Expand All @@ -762,16 +745,6 @@ func (b *Binder) bind(node *ast.Node) bool {
return false
}

func (b *Binder) setJSDocParents(node *ast.Node) {
for _, jsdoc := range node.JSDoc(b.file) {
setParent(jsdoc, node)
if jsdoc.Kind != ast.KindJSDocImportTag {
// JSDocImportTag children have parents set during parsing for module resolution purposes.
ast.SetParentInChildren(jsdoc)
}
}
}

func (b *Binder) bindPropertyWorker(node *ast.Node) {
isAutoAccessor := ast.IsAutoAccessorPropertyDeclaration(node)
includes := core.IfElse(isAutoAccessor, ast.SymbolFlagsAccessor, ast.SymbolFlagsProperty)
Expand Down Expand Up @@ -868,9 +841,6 @@ func (b *Binder) bindExportDeclaration(node *ast.Node) {
// All export * declarations are collected in an __export symbol
b.declareSymbol(ast.GetExports(b.container.Symbol()), b.container.Symbol(), node, ast.SymbolFlagsExportStar, ast.SymbolFlagsNone)
} else if ast.IsNamespaceExport(decl.ExportClause) {
// declareSymbol walks up parents to find name text, parent _must_ be set
// but won't be set by the normal binder walk until `bindChildren` later on.
setParent(decl.ExportClause, node)
b.declareSymbol(ast.GetExports(b.container.Symbol()), b.container.Symbol(), decl.ExportClause, ast.SymbolFlagsAlias, ast.SymbolFlagsAliasExcludes)
}
}
Expand Down Expand Up @@ -981,7 +951,6 @@ func (b *Binder) bindClassLikeDeclaration(node *ast.Node) {
prototypeSymbol := b.newSymbol(ast.SymbolFlagsProperty|ast.SymbolFlagsPrototype, "prototype")
symbolExport := ast.GetExports(symbol)[prototypeSymbol.Name]
if symbolExport != nil {
setParent(name, node)
b.errorOnNode(symbolExport.Declarations[0], diagnostics.Duplicate_identifier_0, ast.SymbolName(prototypeSymbol))
}
ast.GetExports(symbol)[prototypeSymbol.Name] = prototypeSymbol
Expand Down Expand Up @@ -1026,9 +995,6 @@ func (b *Binder) bindExpandoPropertyAssignment(node *ast.Node) {
symbol = b.lookupEntity(parent, b.container)
}
if symbol = getInitializerSymbol(symbol); symbol != nil {
// Fix up parent pointers since we're going to use these nodes before we bind into them
setParent(expr.Left, node)
setParent(expr.Right, node)
if ast.HasDynamicName(node) {
b.bindAnonymousDeclaration(node, ast.SymbolFlagsProperty|ast.SymbolFlagsAssignment, ast.InternalSymbolNameComputed)
addLateBoundAssignmentDeclarationToSymbol(node, symbol)
Expand Down Expand Up @@ -1599,7 +1565,6 @@ func (b *Binder) bindChildren(node *ast.Node) {
// and set it before we descend into nodes that could actually be part of an assignment pattern.
b.inAssignmentPattern = false
if b.checkUnreachable(node) {
b.setJSDocParents(node)
b.bindEachChild(node)
b.inAssignmentPattern = saveInAssignmentPattern
return
Expand All @@ -1611,7 +1576,6 @@ func (b *Binder) bindChildren(node *ast.Node) {
hasFlowNodeData.FlowNode = b.currentFlow
}
}
b.setJSDocParents(node)
switch node.Kind {
case ast.KindWhileStatement:
b.bindWhileStatement(node)
Expand Down Expand Up @@ -2800,12 +2764,6 @@ func (b *Binder) addDiagnostic(diagnostic *ast.Diagnostic) {
b.file.SetBindDiagnostics(append(b.file.BindDiagnostics(), diagnostic))
}

func setParent(child *ast.Node, parent *ast.Node) {
if child != nil {
child.Parent = parent
}
}

func isSignedNumericLiteral(node *ast.Node) bool {
if node.Kind == ast.KindPrefixUnaryExpression {
node := node.AsPrefixUnaryExpression()
Expand Down
Loading