Skip to content

Feature implementation from commits 9fb6cec..fa5d50b #2

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-2
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
6 changes: 5 additions & 1 deletion internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2927,8 +2927,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 |= SubtreeContainsES2019
}
return res
}

func (node *CatchClause) propagateSubtreeFacts() SubtreeFacts {
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
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 @@ -1611,7 +1610,7 @@ func IsEffectiveExternalModule(node *SourceFile, compilerOptions *core.CompilerO
}

func isCommonJSContainingModuleKind(kind core.ModuleKind) bool {
return kind == core.ModuleKindCommonJS || kind == core.ModuleKindNode16 || kind == core.ModuleKindNodeNext
return kind == core.ModuleKindCommonJS || core.ModuleKindNode16 <= kind && kind <= core.ModuleKindNodeNext
}

func IsExternalModuleIndicator(node *Statement) bool {
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
62 changes: 40 additions & 22 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -7352,7 +7352,9 @@ func (c *Checker) checkExpressionWorker(node *ast.Node, checkMode CheckMode) *Ty
case ast.KindNullKeyword:
return c.nullWideningType
case ast.KindStringLiteral, ast.KindNoSubstitutionTemplateLiteral:
// !!! Handle blockedStringType
if c.isSkipDirectInferenceNode(node) {
return c.blockedStringType
}
return c.getFreshTypeOfLiteralType(c.getStringLiteralType(node.Text()))
case ast.KindNumericLiteral:
c.checkGrammarNumericLiteral(node.AsNumericLiteral())
Expand Down Expand Up @@ -14482,14 +14484,24 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri
mode = c.program.GetDefaultResolutionModeForFile(importingSourceFile)
}

var sourceFile *ast.SourceFile
resolvedModule := c.program.GetResolvedModule(importingSourceFile, moduleReference, mode)
if resolvedModule.IsResolved() {

var resolutionDiagnostic *diagnostics.Message
if errorNode != nil && resolvedModule.IsResolved() {
resolutionDiagnostic = module.GetResolutionDiagnostic(c.compilerOptions, resolvedModule, importingSourceFile)
}

var sourceFile *ast.SourceFile
if resolvedModule.IsResolved() && (resolutionDiagnostic == nil || resolutionDiagnostic == diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set) {
sourceFile = c.program.GetSourceFileForResolvedModule(resolvedModule.ResolvedFileName)
}

if sourceFile != nil {
// !!!
// If there's a resolutionDiagnostic we need to report it even if a sourceFile is found.
if resolutionDiagnostic != nil {
c.error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.ResolvedFileName)
}

if errorNode != nil {
if resolvedModule.ResolvedUsingTsExtension && tspath.IsDeclarationFileName(moduleReference) {
if ast.FindAncestor(location, ast.IsEmittableImport) != nil {
Expand Down Expand Up @@ -14577,7 +14589,7 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri

if sourceFile.Symbol != nil {
if errorNode != nil {
if resolvedModule.IsExternalLibraryImport && !(tspath.ExtensionIsTs(resolvedModule.Extension) || resolvedModule.Extension == tspath.ExtensionJson) {
if resolvedModule.IsExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.Extension) {
c.errorOnImplicitAnyModule(false /*isError*/, errorNode, mode, resolvedModule, moduleReference)
}
if c.moduleKind == core.ModuleKindNode16 || c.moduleKind == core.ModuleKindNode18 {
Expand Down Expand Up @@ -14633,7 +14645,7 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri
return nil
}

if resolvedModule.IsResolved() && !(tspath.ExtensionIsTs(resolvedModule.Extension) || resolvedModule.Extension == tspath.ExtensionJson) {
if resolvedModule.IsResolved() && !resolutionExtensionIsTSOrJson(resolvedModule.Extension) && resolutionDiagnostic == nil || resolutionDiagnostic == diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type {
if isForAugmentation {
c.error(
errorNode,
Expand All @@ -14648,7 +14660,6 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri
}

if moduleNotFoundError != nil {

// See if this was possibly a projectReference redirect
if resolvedModule.IsResolved() {
redirect := c.program.GetOutputAndProjectReference(tspath.ToPath(resolvedModule.ResolvedFileName, c.program.GetCurrentDirectory(), c.program.UseCaseSensitiveFileNames()))
Expand All @@ -14663,29 +14674,36 @@ func (c *Checker) resolveExternalModule(location *ast.Node, moduleReference stri
}
}

// !!!
isExtensionlessRelativePathImport := tspath.PathIsRelative(moduleReference) && !tspath.HasExtension(moduleReference)
resolutionIsNode16OrNext := c.moduleResolutionKind == core.ModuleResolutionKindNode16 || c.moduleResolutionKind == core.ModuleResolutionKindNodeNext
if !c.compilerOptions.GetResolveJsonModule() && tspath.FileExtensionIs(moduleReference, tspath.ExtensionJson) {
c.error(errorNode, diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference)
} else if mode == core.ResolutionModeESM && resolutionIsNode16OrNext && isExtensionlessRelativePathImport {
absoluteRef := tspath.GetNormalizedAbsolutePath(moduleReference, tspath.GetDirectoryPath(importingSourceFile.FileName()))
if suggestedExt := c.getSuggestedImportExtension(absoluteRef); suggestedExt != "" {
c.error(errorNode, diagnostics.Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_node16_or_nodenext_Did_you_mean_0, moduleReference+suggestedExt)
if resolutionDiagnostic != nil {
c.error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.ResolvedFileName)
} else {
isExtensionlessRelativePathImport := tspath.PathIsRelative(moduleReference) && !tspath.HasExtension(moduleReference)
resolutionIsNode16OrNext := c.moduleResolutionKind == core.ModuleResolutionKindNode16 || c.moduleResolutionKind == core.ModuleResolutionKindNodeNext
if !c.compilerOptions.GetResolveJsonModule() && tspath.FileExtensionIs(moduleReference, tspath.ExtensionJson) {
c.error(errorNode, diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference)
} else if mode == core.ResolutionModeESM && resolutionIsNode16OrNext && isExtensionlessRelativePathImport {
absoluteRef := tspath.GetNormalizedAbsolutePath(moduleReference, tspath.GetDirectoryPath(importingSourceFile.FileName()))
if suggestedExt := c.getSuggestedImportExtension(absoluteRef); suggestedExt != "" {
c.error(errorNode, diagnostics.Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_node16_or_nodenext_Did_you_mean_0, moduleReference+suggestedExt)
} else {
c.error(errorNode, diagnostics.Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_node16_or_nodenext_Consider_adding_an_extension_to_the_import_path)
}
} else if resolvedModule != nil && resolvedModule.AlternateResult != "" {
errorInfo := c.createModuleNotFoundChain(resolvedModule, errorNode, moduleReference, mode, moduleReference)
c.diagnostics.Add(NewDiagnosticChainForNode(errorInfo, errorNode, moduleNotFoundError, moduleReference))
} else {
c.error(errorNode, diagnostics.Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_node16_or_nodenext_Consider_adding_an_extension_to_the_import_path)
c.error(errorNode, moduleNotFoundError, moduleReference)
}
} else if resolvedModule != nil && resolvedModule.AlternateResult != "" {
errorInfo := c.createModuleNotFoundChain(resolvedModule, errorNode, moduleReference, mode, moduleReference)
c.diagnostics.Add(NewDiagnosticChainForNode(errorInfo, errorNode, moduleNotFoundError, moduleReference))
} else {
c.error(errorNode, moduleNotFoundError, moduleReference)
}
}

return nil
}

func resolutionExtensionIsTSOrJson(ext string) bool {
return tspath.ExtensionIsTs(ext) || ext == tspath.ExtensionJson
}

func (c *Checker) getSuggestedImportSource(moduleReference string, tsExtension string, mode core.ResolutionMode) string {
importSourceWithoutExtension := tspath.RemoveExtension(moduleReference, tsExtension)

Expand Down
23 changes: 7 additions & 16 deletions internal/checker/emitresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,12 +900,10 @@ func (r *emitResolver) CreateLiteralConstValue(emitContext *printer.EmitContext,
if t.flags&TypeFlagsLiteral == 0 {
return nil // non-literal type
}
literalValue := t.AsLiteralType().value
switch literalValue.(type) {
switch value := t.AsLiteralType().value.(type) {
case string:
return emitContext.Factory.NewStringLiteral(literalValue.(string))
return emitContext.Factory.NewStringLiteral(value)
case jsnum.Number:
value := literalValue.(jsnum.Number)
if value.Abs() != value {
// negative
return emitContext.Factory.NewPrefixUnaryExpression(
Expand All @@ -915,20 +913,13 @@ func (r *emitResolver) CreateLiteralConstValue(emitContext *printer.EmitContext,
}
return emitContext.Factory.NewNumericLiteral(value.String())
case jsnum.PseudoBigInt:
value := literalValue.(jsnum.PseudoBigInt)
if value.Negative {
// negative
return emitContext.Factory.NewPrefixUnaryExpression(
ast.KindMinusToken,
emitContext.Factory.NewBigIntLiteral(value.Base10Value),
)
}
return emitContext.Factory.NewNumericLiteral(value.Base10Value)
return emitContext.Factory.NewBigIntLiteral(pseudoBigIntToString(value) + "n")
case bool:
if literalValue.(bool) {
return emitContext.Factory.NewKeywordExpression(ast.KindTrueKeyword)
kind := ast.KindFalseKeyword
if value {
kind = ast.KindTrueKeyword
}
return emitContext.Factory.NewKeywordExpression(ast.KindFalseKeyword)
return emitContext.Factory.NewKeywordExpression(kind)
}
panic("unhandled literal const value kind")
}
Expand Down
2 changes: 1 addition & 1 deletion internal/checker/nodebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func (b *NodeBuilder) EmitContext() *printer.EmitContext {
}

func (b *NodeBuilder) enterContext(enclosingDeclaration *ast.Node, flags nodebuilder.Flags, internalFlags nodebuilder.InternalFlags, tracker nodebuilder.SymbolTracker) {
b.ctxStack = append(b.ctxStack, b.impl.ctx)
b.impl.ctx = &NodeBuilderContext{
tracker: tracker,
flags: flags,
Expand All @@ -36,7 +37,6 @@ func (b *NodeBuilder) enterContext(enclosingDeclaration *ast.Node, flags nodebui
tracker = NewSymbolTrackerImpl(b.impl.ctx, nil, b.host)
b.impl.ctx.tracker = tracker
}
b.ctxStack = append(b.ctxStack, b.impl.ctx)
}

func (b *NodeBuilder) popContext() {
Expand Down
Loading