@@ -2097,7 +2097,6 @@ func (c *Checker) checkSourceFile(ctx context.Context, sourceFile *ast.SourceFil
2097
2097
c.renamedBindingElementsInTypes = nil
2098
2098
c.checkSourceElements(sourceFile.Statements.Nodes)
2099
2099
c.checkDeferredNodes(sourceFile)
2100
- c.checkJSDocNodes(sourceFile)
2101
2100
if ast.IsExternalOrCommonJSModule(sourceFile) {
2102
2101
c.checkExternalModuleExports(sourceFile.AsNode())
2103
2102
c.registerForUnusedIdentifiersCheck(sourceFile.AsNode())
@@ -2139,6 +2138,16 @@ func (c *Checker) checkSourceElement(node *ast.Node) bool {
2139
2138
}
2140
2139
2141
2140
func (c *Checker) checkSourceElementWorker(node *ast.Node) {
2141
+ if node.Flags&ast.NodeFlagsHasJSDoc != 0 {
2142
+ for _, jsdoc := range node.JSDoc(nil) {
2143
+ c.checkJSDocComments(jsdoc)
2144
+ if tags := jsdoc.AsJSDoc().Tags; tags != nil {
2145
+ for _, tag := range tags.Nodes {
2146
+ c.checkJSDocComments(tag)
2147
+ }
2148
+ }
2149
+ }
2150
+ }
2142
2151
kind := node.Kind
2143
2152
if kind >= ast.KindFirstStatement && kind <= ast.KindLastStatement {
2144
2153
flowNode := node.FlowNodeData().FlowNode
@@ -2331,48 +2340,29 @@ func (c *Checker) checkDeferredNode(node *ast.Node) {
2331
2340
c.currentNode = saveCurrentNode
2332
2341
}
2333
2342
2334
- func (c *Checker) checkJSDocNodes(sourceFile *ast.SourceFile) {
2335
- // !!!
2336
- // This performs minimal checking of JSDoc nodes to ensure that @link references to entities are recorded
2337
- // for purposes of checking unused identifiers. We pass down a location node because the binder doesn't currently
2338
- // set parent references in JSDoc nodes.
2339
- for location, jsdocs := range sourceFile.JSDocCache() {
2340
- for _, jsdoc := range jsdocs {
2341
- if c.isCanceled() {
2342
- return
2343
- }
2344
- c.checkJSDocComments(jsdoc, location)
2345
- tags := jsdoc.AsJSDoc().Tags
2346
- if tags != nil {
2347
- for _, tag := range tags.Nodes {
2348
- c.checkJSDocComments(tag, location)
2349
- }
2350
- }
2351
- }
2352
- }
2353
- }
2354
-
2355
- func (c *Checker) checkJSDocComments(node *ast.Node, location *ast.Node) {
2343
+ func (c *Checker) checkJSDocComments(node *ast.Node) {
2356
2344
for _, comment := range node.Comments() {
2357
- c.checkJSDocComment(comment, location )
2345
+ c.checkJSDocComment(comment)
2358
2346
}
2359
2347
}
2360
2348
2361
- func (c *Checker) checkJSDocComment(node *ast.Node, location *ast.Node) {
2349
+ func (c *Checker) checkJSDocComment(node *ast.Node) {
2350
+ // This performs minimal checking of JSDoc nodes to ensure that @link references to entities are recorded
2351
+ // for purposes of checking unused identifiers.
2362
2352
switch node.Kind {
2363
2353
case ast.KindJSDocLink, ast.KindJSDocLinkCode, ast.KindJSDocLinkPlain:
2364
- c.resolveJSDocMemberName(node.Name(), location )
2354
+ c.resolveJSDocMemberName(node.Name())
2365
2355
}
2366
2356
}
2367
2357
2368
- func (c *Checker) resolveJSDocMemberName(name *ast.Node, location *ast.Node ) *ast.Symbol {
2358
+ func (c *Checker) resolveJSDocMemberName(name *ast.Node) *ast.Symbol {
2369
2359
if name != nil && ast.IsEntityName(name) {
2370
2360
meaning := ast.SymbolFlagsType | ast.SymbolFlagsNamespace | ast.SymbolFlagsValue
2371
- if symbol := c.resolveEntityName(name, meaning, true /*ignoreErrors*/, true /*dontResolveAlias*/, location ); symbol != nil {
2361
+ if symbol := c.resolveEntityName(name, meaning, true /*ignoreErrors*/, true /*dontResolveAlias*/, nil ); symbol != nil {
2372
2362
return symbol
2373
2363
}
2374
2364
if ast.IsQualifiedName(name) {
2375
- if symbol := c.resolveJSDocMemberName(name.AsQualifiedName().Left, location ); symbol != nil {
2365
+ if symbol := c.resolveJSDocMemberName(name.AsQualifiedName().Left); symbol != nil {
2376
2366
var t *Type
2377
2367
if symbol.Flags&ast.SymbolFlagsValue != 0 {
2378
2368
proto := c.getPropertyOfType(c.getTypeOfSymbol(symbol), "prototype")
@@ -6410,6 +6400,36 @@ func (c *Checker) checkAliasSymbol(node *ast.Node) {
6410
6400
// otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
6411
6401
// in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
6412
6402
symbol = c.getMergedSymbol(core.OrElse(symbol.ExportSymbol, symbol))
6403
+ // A type-only import/export will already have a grammar error in a JS file, so no need to issue more errors within
6404
+ if ast.IsInJSFile(node) && target.Flags&ast.SymbolFlagsValue == 0 && !ast.IsTypeOnlyImportOrExportDeclaration(node) {
6405
+ errorNode := core.OrElse(node.PropertyNameOrName(), node)
6406
+ debug.Assert(node.Kind != ast.KindNamespaceExport)
6407
+ if ast.IsExportSpecifier(node) {
6408
+ diag := c.error(errorNode, diagnostics.Types_cannot_appear_in_export_declarations_in_JavaScript_files)
6409
+ if sourceSymbol := ast.GetSourceFileOfNode(node).AsNode().Symbol(); sourceSymbol != nil {
6410
+ if alreadyExportedSymbol := sourceSymbol.Exports[node.PropertyNameOrName().Text()]; alreadyExportedSymbol == target {
6411
+ if exportingDeclaration := core.Find(alreadyExportedSymbol.Declarations, ast.IsJSTypeAliasDeclaration); exportingDeclaration != nil {
6412
+ diag.AddRelatedInfo(NewDiagnosticForNode(exportingDeclaration, diagnostics.X_0_is_automatically_exported_here, alreadyExportedSymbol.Name))
6413
+ }
6414
+ }
6415
+ }
6416
+ } else {
6417
+ debug.Assert(node.Kind != ast.KindVariableDeclaration)
6418
+ specifierText := "..."
6419
+ if importDeclaration := ast.FindAncestor(node, ast.IsImportOrImportEqualsDeclaration); importDeclaration != nil {
6420
+ if moduleSpecifier := TryGetModuleSpecifierFromDeclaration(importDeclaration); moduleSpecifier != nil {
6421
+ specifierText = moduleSpecifier.Text()
6422
+ }
6423
+ }
6424
+ identifierText := symbol.Name
6425
+ if ast.IsIdentifier(errorNode) {
6426
+ identifierText = errorNode.Text()
6427
+ }
6428
+ importText := "import(\"" + specifierText + "\")." + identifierText
6429
+ c.error(errorNode, diagnostics.X_0_is_a_type_and_cannot_be_imported_in_JavaScript_files_Use_1_in_a_JSDoc_type_annotation, identifierText, importText)
6430
+ }
6431
+ return
6432
+ }
6413
6433
targetFlags := c.getSymbolFlags(target)
6414
6434
excludedMeanings := core.IfElse(symbol.Flags&(ast.SymbolFlagsValue|ast.SymbolFlagsExportValue) != 0, ast.SymbolFlagsValue, 0) |
6415
6435
core.IfElse(symbol.Flags&ast.SymbolFlagsType != 0, ast.SymbolFlagsType, 0) |
@@ -30460,7 +30480,7 @@ func (c *Checker) getSymbolOfNameOrPropertyAccessExpression(name *ast.Node) *ast
30460
30480
c.checkQualifiedName(name, CheckModeNormal)
30461
30481
}
30462
30482
if links.resolvedSymbol == nil && isJSDoc && ast.IsQualifiedName(name) {
30463
- return c.resolveJSDocMemberName(name, nil )
30483
+ return c.resolveJSDocMemberName(name)
30464
30484
}
30465
30485
return links.resolvedSymbol
30466
30486
}
0 commit comments