-
Notifications
You must be signed in to change notification settings - Fork 646
Signature help implementation #861
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
Changes from 28 commits
f7b2484
202e970
fff762c
cbdb32b
5d8476c
dcd021f
473fbed
0d73105
d68643b
ed043a8
e8c5dae
0c01e98
7acd18e
4a359ec
0ccbd20
151f03a
85cdb01
a22ab20
e57cf78
50a3bbe
4bc1228
f415ca2
ace6765
e836eb1
31bfa2a
aafc78f
1bf462c
8f34a4f
7a4c633
d8db5cc
9c81431
628f4b4
0ff32ac
7469666
e621d71
7792a6e
21b43cd
c61cf81
5b1f838
98de4c1
093ff05
8fca88c
09d531a
ddb78d2
9a3b8f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -585,7 +585,8 @@ func (p *Printer) printSignature(sig *Signature, returnSeparator string) { | |
p.printType(p.c.getTypeOfSymbol(sig.thisParameter)) | ||
tail = true | ||
} | ||
expandedParameters := p.c.GetExpandedParameters(sig) | ||
skipUnionExpanding := true | ||
expandedParameters := p.c.getExpandedParameters(sig, &skipUnionExpanding)[0] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once the parameter is a regular |
||
// If the expanded parameter list had a variadic in a non-trailing position, don't expand it | ||
parameters := core.IfElse(core.Some(expandedParameters, func(s *ast.Symbol) bool { | ||
return s != expandedParameters[len(expandedParameters)-1] && s.CheckFlags&ast.CheckFlagsRestParameter != 0 | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,6 +6,7 @@ import ( | |||||||||||||||
|
||||||||||||||||
"github.com/microsoft/typescript-go/internal/ast" | ||||||||||||||||
"github.com/microsoft/typescript-go/internal/core" | ||||||||||||||||
"github.com/microsoft/typescript-go/internal/printer" | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
func (c *Checker) GetSymbolsInScope(location *ast.Node, meaning ast.SymbolFlags) []*ast.Symbol { | ||||||||||||||||
|
@@ -481,3 +482,50 @@ func (c *Checker) GetJsxIntrinsicTagNamesAt(location *ast.Node) []*ast.Symbol { | |||||||||||||||
func (c *Checker) GetContextualTypeForJsxAttribute(attribute *ast.JsxAttributeLike) *Type { | ||||||||||||||||
return c.getContextualTypeForJsxAttribute(attribute, ContextFlagsNone) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (c *Checker) runWithoutResolvedSignatureCaching(node *ast.Node, fn func() *Signature) *Signature { | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I added this function already (the version you shared with me earlier, but made generic) in one of the completion PRs. |
||||||||||||||||
ancestorNode := ast.FindAncestor(node, func(n *ast.Node) bool { | ||||||||||||||||
return ast.IsCallLikeOrFunctionLikeExpression(n) | ||||||||||||||||
}) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
if ancestorNode != nil { | ||||||||||||||||
cachedResolvedSignatures := make(map[*SignatureLinks]*Signature) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might just do two slices here instead of a map, but this might be cleaner. Either way, I would just add a comment like
Suggested change
|
||||||||||||||||
cachedTypes := make(map[*ValueSymbolLinks]*Type) | ||||||||||||||||
for ancestorNode != nil { | ||||||||||||||||
signatureLinks := c.signatureLinks.Get(ancestorNode) | ||||||||||||||||
cachedResolvedSignatures[signatureLinks] = signatureLinks.resolvedSignature | ||||||||||||||||
signatureLinks.resolvedSignature = nil | ||||||||||||||||
if ast.IsFunctionExpressionOrArrowFunction(ancestorNode) { | ||||||||||||||||
symbolLinks := c.valueSymbolLinks.Get(c.getSymbolOfDeclaration(ancestorNode)) | ||||||||||||||||
resolvedType := symbolLinks.resolvedType | ||||||||||||||||
cachedTypes[symbolLinks] = resolvedType | ||||||||||||||||
symbolLinks.resolvedType = nil | ||||||||||||||||
} | ||||||||||||||||
ancestorNode = ast.FindAncestor(ancestorNode.Parent, ast.IsCallLikeOrFunctionLikeExpression) | ||||||||||||||||
} | ||||||||||||||||
result := fn() | ||||||||||||||||
for signatureLinks, resolvedSignature := range cachedResolvedSignatures { | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
signatureLinks.resolvedSignature = resolvedSignature | ||||||||||||||||
} | ||||||||||||||||
for symbolLinks, resolvedType := range cachedTypes { | ||||||||||||||||
symbolLinks.resolvedType = resolvedType | ||||||||||||||||
} | ||||||||||||||||
return result | ||||||||||||||||
} | ||||||||||||||||
return fn() | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (c *Checker) getResolvedSignatureWorker(node *ast.Node, candidatesOutArray *[]*Signature, checkMode CheckMode, argumentCount int) *Signature { | ||||||||||||||||
parsedNode := printer.NewEmitContext().ParseNode(node) | ||||||||||||||||
c.apparentArgumentCount = &argumentCount | ||||||||||||||||
andrewbranch marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
var res *Signature = nil | ||||||||||||||||
andrewbranch marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
if parsedNode != nil { | ||||||||||||||||
res = c.getResolvedSignature(parsedNode, candidatesOutArray, checkMode) | ||||||||||||||||
} | ||||||||||||||||
return res | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (c *Checker) GetResolvedSignatureForSignatureHelp(node *ast.Node, candidatesOutArray *[]*Signature, argumentCount int) *Signature { | ||||||||||||||||
return c.runWithoutResolvedSignatureCaching(node, func() *Signature { | ||||||||||||||||
return c.getResolvedSignatureWorker(node, candidatesOutArray, CheckModeIsForSignatureHelp, argumentCount) | ||||||||||||||||
}) | ||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -546,6 +546,10 @@ func (t *Type) Flags() TypeFlags { | |
return t.flags | ||
} | ||
|
||
func (t *Type) ObjectFlags() ObjectFlags { | ||
return t.objectFlags | ||
} | ||
|
||
// Casts for concrete struct types | ||
|
||
func (t *Type) AsIntrinsicType() *IntrinsicType { return t.data.(*IntrinsicType) } | ||
|
@@ -886,6 +890,8 @@ type TupleElementInfo struct { | |
labeledDeclaration *ast.Node // NamedTupleMember | ParameterDeclaration | nil | ||
} | ||
|
||
func (t *TupleElementInfo) TupleElementFlags() ElementFlags { return t.flags } | ||
|
||
type TupleType struct { | ||
InterfaceType | ||
elementInfos []TupleElementInfo | ||
|
@@ -895,6 +901,15 @@ type TupleType struct { | |
readonly bool | ||
} | ||
|
||
func (t *TupleType) FixedLength() int { return t.fixedLength } | ||
func (t *TupleType) ElementFlags() []ElementFlags { | ||
elementFlags := make([]ElementFlags, len(t.elementInfos)) | ||
for i, info := range t.elementInfos { | ||
elementFlags[i] = info.flags | ||
} | ||
return elementFlags | ||
} | ||
|
||
// SingleSignatureType | ||
|
||
type SingleSignatureType struct { | ||
|
@@ -1094,6 +1109,38 @@ type Signature struct { | |
composite *CompositeSignature | ||
} | ||
|
||
func (s *Signature) TypeParameters() []*Type { | ||
if len(s.typeParameters) == 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think here and below, this can also just be |
||
return nil | ||
} | ||
return s.typeParameters | ||
} | ||
|
||
func (s *Signature) Declaration() *ast.Node { | ||
return s.declaration | ||
} | ||
|
||
func (s *Signature) Parameters() []*ast.Symbol { | ||
if len(s.parameters) == 0 { | ||
return nil | ||
} | ||
return s.parameters | ||
} | ||
|
||
func (s *Signature) Target() *Signature { | ||
if s.target == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and the method below could just be |
||
return nil | ||
} | ||
return s.target | ||
} | ||
|
||
func (s *Signature) ThisParameter() *ast.Symbol { | ||
if s.thisParameter == nil { | ||
return nil | ||
} | ||
return s.thisParameter | ||
} | ||
|
||
type CompositeSignature struct { | ||
isUnion bool // True for union, false for intersection | ||
signatures []*Signature // Individual signatures | ||
|
Uh oh!
There was an error while loading. Please reload this page.