Skip to content

Commit 4874e98

Browse files
jakebaileyahejlsbergjohnfav03
authored
Reapply #1951 and #1960 after bad merge (#1964)
Co-authored-by: Anders Hejlsberg <andersh@microsoft.com> Co-authored-by: John Favret <64748847+johnfav03@users.noreply.github.com>
1 parent a4fa408 commit 4874e98

File tree

41 files changed

+151
-452
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+151
-452
lines changed

internal/ast/ast.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2353,6 +2353,9 @@ func IsArrayLiteralOrObjectLiteralDestructuringPattern(node *Node) bool {
23532353

23542354
func accessKind(node *Node) AccessKind {
23552355
parent := node.Parent
2356+
if parent == nil {
2357+
return AccessKindRead
2358+
}
23562359
switch parent.Kind {
23572360
case KindParenthesizedExpression:
23582361
return accessKind(parent)
@@ -2404,8 +2407,9 @@ func accessKind(node *Node) AccessKind {
24042407
return AccessKindWrite
24052408
}
24062409
return AccessKindRead
2410+
default:
2411+
return AccessKindRead
24072412
}
2408-
return AccessKindRead
24092413
}
24102414

24112415
func reverseAccessKind(a AccessKind) AccessKind {

internal/ast/utilities.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ func IsClassElement(node *Node) bool {
571571
return false
572572
}
573573

574-
func isMethodOrAccessor(node *Node) bool {
574+
func IsMethodOrAccessor(node *Node) bool {
575575
switch node.Kind {
576576
case KindMethodDeclaration, KindGetAccessor, KindSetAccessor:
577577
return true
@@ -580,7 +580,7 @@ func isMethodOrAccessor(node *Node) bool {
580580
}
581581

582582
func IsPrivateIdentifierClassElementDeclaration(node *Node) bool {
583-
return (IsPropertyDeclaration(node) || isMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name())
583+
return (IsPropertyDeclaration(node) || IsMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name())
584584
}
585585

586586
func IsObjectLiteralOrClassExpressionMethodOrAccessor(node *Node) bool {

internal/checker/checker.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19101,11 +19101,9 @@ func (c *Checker) getSignaturesOfSymbol(symbol *ast.Symbol) []*Signature {
1910119101
}
1910219102
// If this is a function or method declaration, get the signature from the @type tag for the sake of optional parameters.
1910319103
// Exclude contextually-typed kinds because we already apply the @type tag to the context, plus applying it here to the initializer would suppress checks that the two are compatible.
19104-
if ast.IsFunctionExpressionOrArrowFunction(decl) || ast.IsObjectLiteralMethod(decl) {
19105-
if sig := c.getSignatureOfFullSignatureType(decl); sig != nil {
19106-
result = append(result, sig)
19107-
continue
19108-
}
19104+
if sig := c.getSignatureOfFullSignatureType(decl); sig != nil {
19105+
result = append(result, sig)
19106+
continue
1910919107
}
1911019108
result = append(result, c.getSignatureFromDeclaration(decl))
1911119109
}
@@ -19123,6 +19121,14 @@ func (c *Checker) getSignatureFromDeclaration(declaration *ast.Node) *Signature
1912319121
minArgumentCount := 0
1912419122
hasThisParameter := false
1912519123
iife := ast.GetImmediatelyInvokedFunctionExpression(declaration)
19124+
isUntypedSignatureInJSFile := iife == nil &&
19125+
ast.IsInJSFile(declaration) &&
19126+
(ast.IsFunctionExpression(declaration) || ast.IsArrowFunction(declaration) || ast.IsMethodOrAccessor(declaration) || ast.IsFunctionDeclaration(declaration) || ast.IsConstructorDeclaration(declaration)) &&
19127+
core.Every(declaration.Parameters(), func(param *ast.Node) bool { return param.Type() == nil }) &&
19128+
c.getContextualType(declaration, ContextFlagsSignature) == nil
19129+
if isUntypedSignatureInJSFile {
19130+
flags |= SignatureFlagsIsUntypedSignatureInJSFile
19131+
}
1912619132
for i, param := range declaration.Parameters() {
1912719133
paramSymbol := param.Symbol()
1912819134
typeNode := param.Type()
@@ -19343,7 +19349,7 @@ func (c *Checker) getReturnTypeFromAnnotation(declaration *ast.Node) *Type {
1934319349
}
1934419350

1934519351
func (c *Checker) getSignatureOfFullSignatureType(node *ast.Node) *Signature {
19346-
if ast.IsInJSFile(node) && ast.IsFunctionLike(node) && node.FunctionLikeData().FullSignature != nil {
19352+
if ast.IsInJSFile(node) && (ast.IsFunctionDeclaration(node) || ast.IsMethodDeclaration(node) || ast.IsFunctionExpressionOrArrowFunction(node)) && node.FunctionLikeData().FullSignature != nil {
1934719353
return c.getSingleCallSignature(c.getTypeFromTypeNode(node.FunctionLikeData().FullSignature))
1934819354
}
1934919355
return nil

internal/checker/emitresolver.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,20 @@ func (r *emitResolver) IsImplementationOfOverload(node *ast.SignatureDeclaration
458458
// function foo(a: any) { // This is implementation of the overloads
459459
// return a;
460460
// }
461-
return len(signaturesOfSymbol) > 1 ||
462-
// If there is single signature for the symbol, it is overload if that signature isn't coming from the node
463-
// e.g.: function foo(a: string): string;
464-
// function foo(a: any) { // This is implementation of the overloads
465-
// return a;
466-
// }
467-
(len(signaturesOfSymbol) == 1 && signaturesOfSymbol[0].declaration != node)
461+
if len(signaturesOfSymbol) > 1 {
462+
return true
463+
}
464+
// If there is single signature for the symbol, it is overload if that signature isn't coming from the node
465+
// e.g.: function foo(a: string): string;
466+
// function foo(a: any) { // This is implementation of the overloads
467+
// return a;
468+
// }
469+
if len(signaturesOfSymbol) == 1 {
470+
declaration := signaturesOfSymbol[0].declaration
471+
if declaration != node && declaration.Flags&ast.NodeFlagsJSDoc == 0 {
472+
return true
473+
}
474+
}
468475
}
469476
return false
470477
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package fourslash_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/microsoft/typescript-go/internal/fourslash"
7+
"github.com/microsoft/typescript-go/internal/testutil"
8+
)
9+
10+
func TestDocumentHighlightReferenceDirective(t *testing.T) {
11+
t.Parallel()
12+
13+
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
14+
const content = `// @Filename: /a.ts
15+
/// <reference path="[|./b.ts|]" />
16+
17+
const x = 1;
18+
19+
// @filename: b.ts
20+
export type Foo = number;
21+
`
22+
f := fourslash.NewFourslash(t, nil /*capabilities*/, content)
23+
f.VerifyBaselineDocumentHighlights(t, nil /*preferences*/, f.Ranges()[0])
24+
}

internal/ls/documenthighlights.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,13 @@ func (l *LanguageService) getSemanticDocumentHighlights(ctx context.Context, pos
5656
if referenceEntries == nil {
5757
return nil
5858
}
59+
5960
var highlights []*lsproto.DocumentHighlight
6061
for _, entry := range referenceEntries {
6162
for _, ref := range entry.references {
62-
if ref.node != nil {
63-
fileName, highlight := l.toDocumentHighlight(ref)
64-
if fileName == sourceFile.FileName() {
65-
highlights = append(highlights, highlight)
66-
}
63+
fileName, highlight := l.toDocumentHighlight(ref)
64+
if fileName == sourceFile.FileName() {
65+
highlights = append(highlights, highlight)
6766
}
6867
}
6968
}

internal/ls/findallreferences.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ func (l *LanguageService) getReferencedSymbolsForNode(ctx context.Context, posit
625625
}
626626

627627
if moduleSymbol := checker.GetMergedSymbol(resolvedRef.file.Symbol); moduleSymbol != nil {
628-
return getReferencedSymbolsForModule(ctx, program, moduleSymbol /*excludeImportTypeOfExportEquals*/, false, sourceFiles, sourceFilesSet)
628+
return l.getReferencedSymbolsForModule(ctx, program, moduleSymbol /*excludeImportTypeOfExportEquals*/, false, sourceFiles, sourceFilesSet)
629629
}
630630

631631
// !!! not implemented
@@ -673,7 +673,7 @@ func (l *LanguageService) getReferencedSymbolsForNode(ctx context.Context, posit
673673
}
674674

675675
if symbol.Name == ast.InternalSymbolNameExportEquals {
676-
return getReferencedSymbolsForModule(ctx, program, symbol.Parent, false /*excludeImportTypeOfExportEquals*/, sourceFiles, sourceFilesSet)
676+
return l.getReferencedSymbolsForModule(ctx, program, symbol.Parent, false /*excludeImportTypeOfExportEquals*/, sourceFiles, sourceFilesSet)
677677
}
678678

679679
moduleReferences := l.getReferencedSymbolsForModuleIfDeclaredBySourceFile(ctx, symbol, program, sourceFiles, checker, options, sourceFilesSet) // !!! cancellationToken
@@ -700,7 +700,7 @@ func (l *LanguageService) getReferencedSymbolsForModuleIfDeclaredBySourceFile(ct
700700
}
701701
exportEquals := symbol.Exports[ast.InternalSymbolNameExportEquals]
702702
// If exportEquals != nil, we're about to add references to `import("mod")` anyway, so don't double-count them.
703-
moduleReferences := getReferencedSymbolsForModule(ctx, program, symbol, exportEquals != nil, sourceFiles, sourceFilesSet)
703+
moduleReferences := l.getReferencedSymbolsForModule(ctx, program, symbol, exportEquals != nil, sourceFiles, sourceFilesSet)
704704
if exportEquals == nil || !sourceFilesSet.Has(moduleSourceFileName) {
705705
return moduleReferences
706706
}
@@ -1021,7 +1021,7 @@ func getMergedAliasedSymbolOfNamespaceExportDeclaration(node *ast.Node, symbol *
10211021
return nil
10221022
}
10231023

1024-
func getReferencedSymbolsForModule(ctx context.Context, program *compiler.Program, symbol *ast.Symbol, excludeImportTypeOfExportEquals bool, sourceFiles []*ast.SourceFile, sourceFilesSet *collections.Set[string]) []*SymbolAndEntries {
1024+
func (l *LanguageService) getReferencedSymbolsForModule(ctx context.Context, program *compiler.Program, symbol *ast.Symbol, excludeImportTypeOfExportEquals bool, sourceFiles []*ast.SourceFile, sourceFilesSet *collections.Set[string]) []*SymbolAndEntries {
10251025
debug.Assert(symbol.ValueDeclaration != nil)
10261026

10271027
checker, done := program.GetTypeChecker(ctx)
@@ -1062,10 +1062,11 @@ func getReferencedSymbolsForModule(ctx context.Context, program *compiler.Progra
10621062
}
10631063
return newNodeEntry(rangeNode)
10641064
case ModuleReferenceKindReference:
1065-
// <reference path> or <reference types>
1066-
// We can't easily create a proper range entry here without access to LanguageService,
1067-
// but we can create a node-based entry pointing to the source file which will be resolved later
1068-
return newNodeEntry(reference.referencingFile.AsNode())
1065+
return &referenceEntry{
1066+
kind: entryKindRange,
1067+
fileName: reference.referencingFile.FileName(),
1068+
textRange: l.createLspRangeFromBounds(reference.ref.Pos(), reference.ref.End(), reference.referencingFile),
1069+
}
10691070
}
10701071
return nil
10711072
})

testdata/baselines/reference/conformance/jsdocTypeParameterTagConflict.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @param {2} a
77
*/
88
export function conflictingParam(a) { return true }
9-
>conflictingParam : (a: 2) => true
9+
>conflictingParam : (a: 1) => true
1010
>a : 2
1111
>true : true
1212

@@ -15,7 +15,7 @@ export function conflictingParam(a) { return true }
1515
* @return {false}
1616
*/
1717
export function conflictingReturn(b) { return false }
18-
>conflictingReturn : (b: 3) => false
18+
>conflictingReturn : (b: 3) => true
1919
>b : 3
2020
>false : false
2121

@@ -26,7 +26,7 @@ export function conflictingReturn(b) { return false }
2626
* @return {false}
2727
*/
2828
export function conflictingBoth(d) { return false }
29-
>conflictingBoth : (d: 5) => false
29+
>conflictingBoth : (c: 4) => true
3030
>d : 5
3131
>false : false
3232

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// === documentHighlights ===
2+
// === /a.ts ===
3+
// /// <reference path="/*HIGHLIGHTS*/[|./b.ts|]" />
4+
//
5+
// const x = 1;
6+
//

testdata/baselines/reference/submodule/compiler/argumentsObjectCreatesRestForJs.errors.txt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
main.js(3,9): error TS2554: Expected 0 arguments, but got 3.
2-
main.js(5,1): error TS2554: Expected 2 arguments, but got 0.
3-
main.js(6,16): error TS2554: Expected 2 arguments, but got 3.
2+
main.js(6,16): error TS2554: Expected 0-2 arguments, but got 3.
43

54

6-
==== main.js (3 errors) ====
5+
==== main.js (2 errors) ====
76
function allRest() { arguments; }
87
allRest();
98
allRest(1, 2, 3);
109
~~~~~~~
1110
!!! error TS2554: Expected 0 arguments, but got 3.
1211
function someRest(x, y) { arguments; }
1312
someRest(); // x and y are still optional because they are in a JS file
14-
~~~~~~~~
15-
!!! error TS2554: Expected 2 arguments, but got 0.
16-
!!! related TS6210 main.js:4:19: An argument for 'x' was not provided.
1713
someRest(1, 2, 3);
1814
~
19-
!!! error TS2554: Expected 2 arguments, but got 3.
15+
!!! error TS2554: Expected 0-2 arguments, but got 3.
2016

2117
/**
2218
* @param {number} x - a thing

0 commit comments

Comments
 (0)