Skip to content

Commit ebb79f8

Browse files
authored
Multiple fixes to checker (#822)
1 parent 2e36e7d commit ebb79f8

File tree

160 files changed

+1533
-3073
lines changed

Some content is hidden

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

160 files changed

+1533
-3073
lines changed

internal/ast/ast.go

+4
Original file line numberDiff line numberDiff line change
@@ -9501,6 +9501,10 @@ func (node *JSDocImportTag) Clone(f NodeFactoryCoercible) *Node {
95019501
return cloneNode(f.AsNodeFactory().NewJSDocImportTag(node.TagName, node.ImportClause, node.ModuleSpecifier, node.Attributes, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
95029502
}
95039503

9504+
func IsJSDocImportTag(node *Node) bool {
9505+
return node.Kind == KindJSDocImportTag
9506+
}
9507+
95049508
// JSDocCallbackTag
95059509
type JSDocCallbackTag struct {
95069510
JSDocTagBase

internal/ast/diagnostic.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ func (d *Diagnostic) AddRelatedInfo(relatedInformation *Diagnostic) *Diagnostic
6060
return d
6161
}
6262

63+
func (d *Diagnostic) Clone() *Diagnostic {
64+
result := *d
65+
return &result
66+
}
67+
6368
func NewDiagnostic(file *SourceFile, loc core.TextRange, message *diagnostics.Message, args ...any) *Diagnostic {
6469
return &Diagnostic{
6570
file: file,
@@ -137,12 +142,16 @@ func getDiagnosticPath(d *Diagnostic) string {
137142
}
138143

139144
func EqualDiagnostics(d1, d2 *Diagnostic) bool {
145+
return EqualDiagnosticsNoRelatedInfo(d1, d2) &&
146+
slices.EqualFunc(d1.RelatedInformation(), d2.RelatedInformation(), EqualDiagnostics)
147+
}
148+
149+
func EqualDiagnosticsNoRelatedInfo(d1, d2 *Diagnostic) bool {
140150
return getDiagnosticPath(d1) == getDiagnosticPath(d2) &&
141151
d1.Loc() == d2.Loc() &&
142152
d1.Code() == d2.Code() &&
143153
d1.Message() == d2.Message() &&
144-
slices.EqualFunc(d1.MessageChain(), d2.MessageChain(), equalMessageChain) &&
145-
slices.EqualFunc(d1.RelatedInformation(), d2.RelatedInformation(), EqualDiagnostics)
154+
slices.EqualFunc(d1.MessageChain(), d2.MessageChain(), equalMessageChain)
146155
}
147156

148157
func equalMessageChain(c1, c2 *Diagnostic) bool {

internal/binder/binder.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2846,7 +2846,7 @@ func GetErrorRangeForNode(sourceFile *ast.SourceFile, node *ast.Node) core.TextR
28462846
return scanner.GetRangeOfTokenAtPosition(sourceFile, node.Pos())
28472847
}
28482848
pos := errorNode.Pos()
2849-
if !ast.NodeIsMissing(errorNode) {
2849+
if !ast.NodeIsMissing(errorNode) && !ast.IsJsxText(errorNode) {
28502850
pos = scanner.SkipTrivia(sourceFile.Text(), pos)
28512851
}
28522852
return core.NewTextRange(pos, errorNode.End())

internal/checker/checker.go

+45-24
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,7 @@ func (c *Checker) initializeChecker() {
12571257
c.autoArrayType = c.newAnonymousType(nil, nil, nil, nil, nil)
12581258
}
12591259
c.globalReadonlyArrayType = c.getGlobalType("ReadonlyArray", 1 /*arity*/, false /*reportErrors*/)
1260-
if c.globalReadonlyArrayType == nil {
1260+
if c.globalReadonlyArrayType == c.emptyGenericType {
12611261
c.globalReadonlyArrayType = c.globalArrayType
12621262
}
12631263
c.anyReadonlyArrayType = c.createTypeFromGenericGlobalType(c.globalReadonlyArrayType, []*Type{c.anyType})
@@ -5028,7 +5028,7 @@ func (c *Checker) checkImportAttributes(declaration *ast.Node) {
50285028
if importAttributesType != c.emptyObjectType {
50295029
c.checkTypeAssignableTo(c.getTypeFromImportAttributes(node), c.getNullableType(importAttributesType, TypeFlagsUndefined), node, nil)
50305030
}
5031-
isTypeOnly := ast.IsTypeOnlyImportOrExportDeclaration(declaration)
5031+
isTypeOnly := isExclusivelyTypeOnlyImportOrExport(declaration)
50325032
override := c.getResolutionModeOverride(node.AsImportAttributes(), isTypeOnly)
50335033
isImportAttributes := node.AsImportAttributes().Token == ast.KindWithKeyword
50345034
if isTypeOnly && override != core.ResolutionModeNone {
@@ -5066,6 +5066,22 @@ func (c *Checker) checkImportAttributes(declaration *ast.Node) {
50665066
}
50675067
}
50685068

5069+
func isExclusivelyTypeOnlyImportOrExport(node *ast.Node) bool {
5070+
switch node.Kind {
5071+
case ast.KindExportDeclaration:
5072+
return node.AsExportDeclaration().IsTypeOnly
5073+
case ast.KindImportDeclaration:
5074+
if importClause := node.AsImportDeclaration().ImportClause; importClause != nil {
5075+
return importClause.AsImportClause().IsTypeOnly
5076+
}
5077+
case ast.KindJSDocImportTag:
5078+
if importClause := node.AsJSDocImportTag().ImportClause; importClause != nil {
5079+
return importClause.AsImportClause().IsTypeOnly
5080+
}
5081+
}
5082+
return false
5083+
}
5084+
50695085
func (c *Checker) getTypeFromImportAttributes(node *ast.Node) *Type {
50705086
links := c.typeNodeLinks.Get(node)
50715087
if links.resolvedType == nil {
@@ -5787,7 +5803,7 @@ func (c *Checker) getIterationTypesOfGeneratorFunctionReturnType(t *Type, isAsyn
57875803
if result.hasTypes() {
57885804
return result
57895805
}
5790-
return c.getIterationTypesOfIterator(t, resolver, nil /*errorNode*/)
5806+
return c.getIterationTypesOfIterator(t, resolver, nil /*errorNode*/, nil /*diagnosticOutput*/)
57915807
}
57925808

57935809
// Gets the requested "iteration type" from an `Iterable`-like or `AsyncIterable`-like type.
@@ -5853,14 +5869,15 @@ func (c *Checker) getIterationTypesOfIterableWorker(t *Type, use IterationUse, e
58535869
return iterationTypes
58545870
}
58555871
}
5872+
var diags []*ast.Diagnostic
58565873
if use&IterationUseAllowsAsyncIterablesFlag != 0 {
5857-
iterationTypes := c.getIterationTypesOfIterableSlow(t, c.asyncIterationTypesResolver, errorNode)
5874+
iterationTypes := c.getIterationTypesOfIterableSlow(t, c.asyncIterationTypesResolver, errorNode, &diags)
58585875
if iterationTypes.hasTypes() {
58595876
return iterationTypes
58605877
}
58615878
}
58625879
if use&IterationUseAllowsSyncIterablesFlag != 0 {
5863-
iterationTypes := c.getIterationTypesOfIterableSlow(t, c.syncIterationTypesResolver, errorNode)
5880+
iterationTypes := c.getIterationTypesOfIterableSlow(t, c.syncIterationTypesResolver, errorNode, &diags)
58645881
if iterationTypes.hasTypes() {
58655882
if use&IterationUseAllowsAsyncIterablesFlag != 0 {
58665883
return c.getAsyncFromSyncIterationTypes(iterationTypes, errorNode)
@@ -5869,7 +5886,10 @@ func (c *Checker) getIterationTypesOfIterableWorker(t *Type, use IterationUse, e
58695886
}
58705887
}
58715888
if errorNode != nil {
5872-
c.reportTypeNotIterableError(errorNode, t, use&IterationUseAllowsAsyncIterablesFlag != 0)
5889+
diagnostic := c.reportTypeNotIterableError(errorNode, t, use&IterationUseAllowsAsyncIterablesFlag != 0)
5890+
for _, d := range diags {
5891+
diagnostic.AddRelatedInfo(d)
5892+
}
58735893
}
58745894
return IterationTypes{}
58755895
}
@@ -5977,15 +5997,15 @@ func (c *Checker) getAsyncFromSyncIterationTypes(iterationTypes IterationTypes,
59775997
//
59785998
// NOTE: You probably don't want to call this directly and should be calling
59795999
// `getIterationTypesOfIterable` instead.
5980-
func (c *Checker) getIterationTypesOfIterableSlow(t *Type, r *IterationTypesResolver, errorNode *ast.Node) IterationTypes {
6000+
func (c *Checker) getIterationTypesOfIterableSlow(t *Type, r *IterationTypesResolver, errorNode *ast.Node, diagnosticOutput *[]*ast.Diagnostic) IterationTypes {
59816001
if method := c.getPropertyOfType(t, c.getPropertyNameForKnownSymbolName(r.iteratorSymbolName)); method != nil && method.Flags&ast.SymbolFlagsOptional == 0 {
59826002
methodType := c.getTypeOfSymbol(method)
59836003
if IsTypeAny(methodType) {
59846004
return IterationTypes{c.anyType, c.anyType, c.anyType}
59856005
}
59866006
if signatures := c.getSignaturesOfType(methodType, SignatureKindCall); len(signatures) != 0 {
59876007
iteratorType := c.getIntersectionType(core.Map(signatures, c.getReturnTypeOfSignature))
5988-
return c.getIterationTypesOfIteratorWorker(iteratorType, r, errorNode)
6008+
return c.getIterationTypesOfIteratorWorker(iteratorType, r, errorNode, diagnosticOutput)
59896009
}
59906010
}
59916011
return IterationTypes{}
@@ -5995,8 +6015,8 @@ func (c *Checker) getIterationTypesOfIterableSlow(t *Type, r *IterationTypesReso
59956015
//
59966016
// If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes` with non-nil
59976017
// members is returned. Otherwise, a default `IterationTypes{}` is returned.
5998-
func (c *Checker) getIterationTypesOfIterator(t *Type, r *IterationTypesResolver, errorNode *ast.Node) IterationTypes {
5999-
return c.getIterationTypesOfIteratorWorker(t, r, errorNode)
6018+
func (c *Checker) getIterationTypesOfIterator(t *Type, r *IterationTypesResolver, errorNode *ast.Node, diagnosticOutput *[]*ast.Diagnostic) IterationTypes {
6019+
return c.getIterationTypesOfIteratorWorker(t, r, errorNode, diagnosticOutput)
60006020
}
60016021

60026022
// Gets the *yield*, *return*, and *next* types from an `Iterator`-like or `AsyncIterator`-like type.
@@ -6005,15 +6025,15 @@ func (c *Checker) getIterationTypesOfIterator(t *Type, r *IterationTypesResolver
60056025
// members is returned. Otherwise, a default `IterationTypes{}` is returned.
60066026
//
60076027
// NOTE: You probably don't want to call this directly and should be calling `getIterationTypesOfIterator` instead.
6008-
func (c *Checker) getIterationTypesOfIteratorWorker(t *Type, r *IterationTypesResolver, errorNode *ast.Node) IterationTypes {
6028+
func (c *Checker) getIterationTypesOfIteratorWorker(t *Type, r *IterationTypesResolver, errorNode *ast.Node, diagnosticOutput *[]*ast.Diagnostic) IterationTypes {
60096029
if IsTypeAny(t) {
60106030
return IterationTypes{c.anyType, c.anyType, c.anyType}
60116031
}
60126032
iterationTypes := c.getIterationTypesOfIteratorFast(t, r)
60136033
if iterationTypes.hasTypes() {
60146034
return iterationTypes
60156035
}
6016-
return c.getIterationTypesOfIteratorSlow(t, r, errorNode)
6036+
return c.getIterationTypesOfIteratorSlow(t, r, errorNode, diagnosticOutput)
60176037
}
60186038

60196039
func (c *Checker) getIterationTypesOfIteratorFast(t *Type, r *IterationTypesResolver) IterationTypes {
@@ -6043,15 +6063,15 @@ func (c *Checker) getIterationTypesOfIteratorFast(t *Type, r *IterationTypesReso
60436063
return IterationTypes{}
60446064
}
60456065

6046-
func (c *Checker) getIterationTypesOfIteratorSlow(t *Type, r *IterationTypesResolver, errorNode *ast.Node) IterationTypes {
6066+
func (c *Checker) getIterationTypesOfIteratorSlow(t *Type, r *IterationTypesResolver, errorNode *ast.Node, diagnosticOutput *[]*ast.Diagnostic) IterationTypes {
60476067
return c.combineIterationTypes([]IterationTypes{
6048-
c.getIterationTypesOfMethod(t, r, "next", errorNode),
6049-
c.getIterationTypesOfMethod(t, r, "return", errorNode),
6050-
c.getIterationTypesOfMethod(t, r, "throw", errorNode),
6068+
c.getIterationTypesOfMethod(t, r, "next", errorNode, diagnosticOutput),
6069+
c.getIterationTypesOfMethod(t, r, "return", errorNode, diagnosticOutput),
6070+
c.getIterationTypesOfMethod(t, r, "throw", errorNode, diagnosticOutput),
60516071
})
60526072
}
60536073

6054-
func (c *Checker) getIterationTypesOfMethod(t *Type, resolver *IterationTypesResolver, methodName string, errorNode *ast.Node) IterationTypes {
6074+
func (c *Checker) getIterationTypesOfMethod(t *Type, resolver *IterationTypesResolver, methodName string, errorNode *ast.Node, diagnosticOutput *[]*ast.Diagnostic) IterationTypes {
60556075
method := c.getPropertyOfType(t, methodName)
60566076
// Ignore 'return' or 'throw' if they are missing.
60576077
if method == nil && methodName != "next" {
@@ -6076,7 +6096,7 @@ func (c *Checker) getIterationTypesOfMethod(t *Type, resolver *IterationTypesRes
60766096
if len(methodSignatures) == 0 {
60776097
if errorNode != nil {
60786098
diagnostic := core.IfElse(methodName == "next", resolver.mustHaveANextMethodDiagnostic, resolver.mustBeAMethodDiagnostic)
6079-
c.error(errorNode, diagnostic, methodName)
6099+
c.reportDiagnostic(NewDiagnosticForNode(errorNode, diagnostic, methodName), diagnosticOutput)
60806100
}
60816101
return IterationTypes{}
60826102
}
@@ -6143,7 +6163,7 @@ func (c *Checker) getIterationTypesOfMethod(t *Type, resolver *IterationTypesRes
61436163
iterationTypes := c.getIterationTypesOfIteratorResult(resolvedMethodReturnType)
61446164
if !iterationTypes.hasTypes() {
61456165
if errorNode != nil {
6146-
c.error(errorNode, resolver.mustHaveAValueDiagnostic, methodName)
6166+
c.reportDiagnostic(NewDiagnosticForNode(errorNode, resolver.mustHaveAValueDiagnostic, methodName), diagnosticOutput)
61476167
}
61486168
yieldType = c.anyType
61496169
returnTypes = append(returnTypes, c.anyType)
@@ -6209,7 +6229,7 @@ func (c *Checker) isIteratorResult(t *Type, kind IterationTypeKind) bool {
62096229
return c.isTypeAssignableTo(core.IfElse(kind == IterationTypeKindYield, c.falseType, c.trueType), doneType)
62106230
}
62116231

6212-
func (c *Checker) reportTypeNotIterableError(errorNode *ast.Node, t *Type, allowAsyncIterables bool) {
6232+
func (c *Checker) reportTypeNotIterableError(errorNode *ast.Node, t *Type, allowAsyncIterables bool) *ast.Diagnostic {
62136233
var message *diagnostics.Message
62146234
if allowAsyncIterables {
62156235
message = diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
@@ -6221,7 +6241,7 @@ func (c *Checker) reportTypeNotIterableError(errorNode *ast.Node, t *Type, allow
62216241
errorNode.Parent.Expression() == errorNode &&
62226242
c.getGlobalAsyncIterableType() != c.emptyGenericType &&
62236243
c.isTypeAssignableTo(t, c.createTypeFromGenericGlobalType(c.getGlobalAsyncIterableType(), []*Type{c.anyType, c.anyType, c.anyType})))
6224-
c.errorAndMaybeSuggestAwait(errorNode, suggestAwait, message, c.TypeToString(t))
6244+
return c.errorAndMaybeSuggestAwait(errorNode, suggestAwait, message, c.TypeToString(t))
62256245
}
62266246

62276247
func (c *Checker) getIterationDiagnosticDetails(use IterationUse, inputType *Type, allowsStrings bool, downlevelIteration bool) (*diagnostics.Message, bool) {
@@ -13129,11 +13149,12 @@ func (c *Checker) errorOrSuggestion(isError bool, location *ast.Node, message *d
1312913149
c.addErrorOrSuggestion(isError, NewDiagnosticForNode(location, message, args...))
1313013150
}
1313113151

13132-
func (c *Checker) errorAndMaybeSuggestAwait(location *ast.Node, maybeMissingAwait bool, message *diagnostics.Message, args ...any) {
13152+
func (c *Checker) errorAndMaybeSuggestAwait(location *ast.Node, maybeMissingAwait bool, message *diagnostics.Message, args ...any) *ast.Diagnostic {
1313313153
diagnostic := c.error(location, message, args...)
1313413154
if maybeMissingAwait {
1313513155
diagnostic.AddRelatedInfo(createDiagnosticForNode(location, diagnostics.Did_you_forget_to_use_await))
1313613156
}
13157+
return diagnostic
1313713158
}
1313813159

1313913160
func (c *Checker) addErrorOrSuggestion(isError bool, diagnostic *ast.Diagnostic) {
@@ -13656,8 +13677,8 @@ func (c *Checker) checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(nod
1365613677
diagnostics.X_0_was_imported_here)
1365713678
// TODO: how to get name for export *?
1365813679
name := "*"
13659-
if typeOnlyDeclaration.Kind == ast.KindImportDeclaration {
13660-
name = getNameFromImportDeclaration(typeOnlyDeclaration).AsIdentifier().Text
13680+
if !ast.IsExportDeclaration(typeOnlyDeclaration) {
13681+
name = getNameFromImportDeclaration(typeOnlyDeclaration).Text()
1366113682
}
1366213683
c.error(decl.ModuleReference, message).AddRelatedInfo(createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name))
1366313684
}

0 commit comments

Comments
 (0)