Skip to content
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
1 change: 1 addition & 0 deletions .executor-pid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
33492
1 change: 1 addition & 0 deletions src/Compiler/Service/SemanticClassification.fs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ module TcResolutionsExtensions =
| ItemOccurrence.UseInType
| ItemOccurrence.UseInAttribute
| ItemOccurrence.Use
| ItemOccurrence.InvalidUse
| ItemOccurrence.Binding
| ItemOccurrence.Pattern
| ItemOccurrence.Open -> Some()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,74 @@ type Animal =
(7, 2, 8) // s.IsCircle && s.IsSquare — two on same line
(12, 1, 7) // t.IsIdent — RequireQualifiedAccess
(17, 1, 5) ] // this.IsCat — self-referential member

/// (#18009 regression) Static method on a generic type with a *qualified* type argument
/// must still classify the type name as a type.
[<Fact>]
let ``Static method on generic type should classify type name as type`` () =
let source =
"""
module Test

type MyType<'T> =
static member S = 1

let _ = MyType<int>.S
let _ = MyType<System.Int32>.S
"""

let items = getClassifications source

let isMyTypeRefOnLine line (item: SemanticClassificationItem) =
item.Type = SemanticClassificationType.ReferenceType
&& item.Range.StartLine = line
&& item.Range.StartColumn = 8
&& item.Range.EndColumn = 14

let unqualified = items |> Array.filter (isMyTypeRefOnLine 7)
Assert.True(
unqualified.Length = 1,
sprintf
"Expected exactly one ReferenceType classification for MyType on line 7, got: %A"
(items |> Array.filter (fun i -> i.Range.StartLine = 7)
|> Array.map (fun i -> i.Range.StartColumn, i.Range.EndColumn, i.Type))
)

let qualified = items |> Array.filter (isMyTypeRefOnLine 8)
Assert.True(
qualified.Length = 1,
sprintf
"Expected exactly one ReferenceType classification for MyType on line 8, got: %A"
(items |> Array.filter (fun i -> i.Range.StartLine = 8)
|> Array.map (fun i -> i.Range.StartColumn, i.Range.EndColumn, i.Type))
)

/// (#18009 follow-up) Accepting ItemOccurrence.InvalidUse in LegitTypeOccurrence must
/// not cause unresolved identifiers to be classified as types.
[<Fact>]
let ``Undeclared identifier in expression position is not classified as a type`` () =
let source =
"""
module Test

let _ = NotDeclaredAnywhere.S
"""

let items = getClassifications source

let badSpans =
items
|> Array.filter (fun item ->
item.Range.StartLine = 4
&& item.Range.StartColumn = 8
&& item.Range.EndColumn = 27
&& (item.Type = SemanticClassificationType.ReferenceType
|| item.Type = SemanticClassificationType.ValueType
|| item.Type = SemanticClassificationType.Type))

Assert.True(
badSpans.Length = 0,
sprintf
"Undeclared identifier should not be classified as a type, but found: %A"
(badSpans |> Array.map (fun i -> i.Range.StartColumn, i.Range.EndColumn, i.Type))
)
Loading