Skip to content

Offer every open that resolves the name, and open type where a plain open cannot reach - #20501

Open
xperiandri wants to merge 36 commits into
dotnet:mainfrom
xperiandri:fix/add-open-type
Open

xperiandri wants to merge 36 commits into
dotnet:mainfrom
xperiandri:fix/add-open-type

Conversation

@xperiandri

@xperiandri xperiandri commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #20500.

For an unresolved File in File.ReadAllText "x", the "open namespace" fix offered open System.Net.WebRequestMethods, which does not compile (FS0039), and never System.IO.

  • When the candidate is a type, the fix now suggests open type instead of a plain open; a type inside a generic type is not offered, since open type would need type arguments.
  • All candidates are offered (up to five opens and three qualifications, System first, as in Roslyn) instead of just the first one found.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

✅ Release notes checked


✅ Found changes and release notes in following paths:

Warning

No PR link found in some release notes, please consider adding it.

Change path Release notes path Description
`src/Compiler` docs/release-notes/.FSharp.Compiler.Service/11.0.200.md No current pull request URL (#20501) found, please consider adding it

@xperiandri

xperiandri commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor Author
image image

@github-actions github-actions Bot added the ⚠️ Affects-Design-Time Tooling check: PR touches type providers or dependency manager label Sep 9, 2026
@github-actions

This comment has been minimized.

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 🕵️ AI review — verify independently.

|> Seq.toList
|> getSuggestionsAsCodeFixes context sourceText
|> Seq.tryHead))
|> getSuggestionsAsCodeFixes context sourceText))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 🕵️ [P2] Choosing N.M.FixTarget817 rewrites M.FixTarget817() to M.N.M() (FS0039). Replace the matching long-identifier prefix, not just the diagnostic span.

module Review
module M = let marker = ()
module N =
    module M =
        type FixTarget817() = class end
let x = M.FixTarget817()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xperiandri TODO - I think this hasnt been addressed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d6de3fc: the qualification now replaces the first identifier written (M) with the qualifier, not the diagnostic span, so M.FixTarget817() becomes N.M.FixTarget817(). Test: Qualifying a partly qualified name replaces what is written before the unresolved part.

@T-Gro T-Gro added the AI-reviewed PR reviewed by AI review council label Sep 10, 2026
@T-Gro
T-Gro self-requested a review September 10, 2026 12:33
@xperiandri
xperiandri force-pushed the fix/add-open-type branch 2 times, most recently from f7e3ac6 to f022596 Compare September 11, 2026 15:17

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖🕵️ Please shorten the description using this guidance. Focus on the problem and why the change is needed, in simplified technical English. Leave the implementation inventory to the Files tab and retain necessary caveats.

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Sep 15, 2026
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Design-Time
Affects-Design-Time: Changes IDE integration executed during design-time.

Generated by PR Tooling Safety Check · gpt56 1.7M · ◷

@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Sep 28, 2026
Copilot AI balanced review requested due to automatic review settings September 29, 2026 17:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Generic-type fixes can remain uncompilable, ordering and newline handling are inconsistent, and two public record constructors are broken.

Review effort: Balanced
Findings: 2 High severity · 3 Medium severity

Open (5)
What changed in this PR

Improves unresolved-name fixes by using syntax-aware insertion, offering multiple candidates, and choosing open type when necessary.

Changes:

  • Shares syntax-tree-based open insertion logic.
  • Adds ranked, capped open and qualification suggestions.
  • Tracks namespace/module reach and expands regression coverage.
File Description
AddOpenOnTopOnTests.fs Expands top-level placement and suggestion tests.
AddOpenOnTopOffTests.fs Updates nearest-scope placement tests.
RoslynHelpers.fs Centralizes open-declaration text changes.
AddOpenCodeFixProvider.fs Adds multiple, ranked open type and qualification fixes.
OpenDeclarationInsertionTests.fs Covers syntax-tree insertion positions.
FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl Updates the FCS API baseline.
ServiceParsedInputOps.fsi Exposes insertion and namespace-count metadata.
ServiceParsedInputOps.fs Computes syntax-aware insertion positions and namespace counts.
ServiceAssemblyContent.fsi Exposes openable identifier counts.
ServiceAssemblyContent.fs Tracks namespace/module reach while traversing symbols.
.VisualStudio/​18.vNext.md Documents editor fixes.
.FSharp.Compiler.Service/​11.0.200.md Documents FCS behavior and API changes.

Comment on lines +40 to +42
/// How many leading `CleanedIdents` a plain `open` reaches: the namespace plus the enclosing
/// F# modules. Idents past it name types, whose contents `open type` brings into scope instead.
OpenableIdentCount: int

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, and it did not need to change: 7fdc34a drops OpenableIdentCount and reads what the suggested open names from AssemblySymbol.Symbol, walking its declaring entities. AssemblySymbol is as on main.

Comment on lines +166 to +169
/// How many leading idents of the entity's full name that namespace covers. Compare it with
/// `AssemblySymbol.OpenableIdentCount` to tell a namespace a plain `open` reaches from a type,
/// which only `open type` opens.
NamespaceIdentCount: int

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field stays: Namespace is relative to the current scope, so which namespace, module or type it names cannot be recovered from it. 7fdc34a moves the release note to ### Changed and says that code constructing the record has to pass it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please preserve source and binary compatibility here. Do not merge this with a public record shape break. An intentional break would need separate explicit release-owner approval and documented handling.

Auto-resolved by the GitHub Copilot app.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 80e5c8b: InsertionContextEntity and AssemblySymbol are exactly as on main, so the surface-area baseline has no diff and the release note about the new field is gone. The count of idents that Namespace covers, which the editor needs to tell open from open type, now comes with the context from an internal function, ParsedInput.TryFindInsertionContextAt, visible to FSharp.Editor and the FCS tests only. TryFindInsertionContext keeps its public signature and behaviour.

Comment on lines +63 to +67
let openDeclaration (entity: InsertionContextEntity) openableIdentCount ns =
if entity.NamespaceIdentCount > openableIdentCount then
$"open type {ns}"
else
$"open {ns}"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ecbc332: when the type to open is generic, no open type is offered; the qualifications still are. Covered by Doesn't offer to open a generic type.

|> Seq.filter (fun (entity, _, _) -> not (entity.LastIdent.StartsWith "op_")) // Don't include qualified operator names. The resultant codefix won't compile because it won't be an infix operator anymore.
|> Seq.map (fun (entity, _, _) -> entity.FullRelativeName, entity.Qualifier)
|> Seq.distinct
|> Seq.sort

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6aaa651: the qualifications are ordered like the opens before the list is cut, so for WriteLine all three are System ones. Covered by Offers the System qualifications first.

Comment on lines +251 to +254
let lineBreak =
match line.Text.ToString(TextSpan(line.End, line.EndIncludingLineBreak - line.End)) with
| "" -> Environment.NewLine
| breakChars -> breakChars

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #20500 (34c331e), which this PR is stacked on.

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 🕵️ Re-reviewed all recent changes as of b33f201; LGTM

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 🕵️ Re-reviewed all recent changes as of 853849e; LGTM

xperiandri and others added 3 commits October 10, 2026 23:39
The "open namespace" code fix and the completion that adds an open both
decided where the declaration goes by recognizing a module header in the
text of a line — `line.StartsWith "module" && not (line.EndsWith "=")` —
followed by arithmetic that assumed a blank line under that header. Every
shape the spelling missed put the open where it does not compile:
`[<AutoOpen>] module Ns.Name` written on one line read as an implicit
module and took the open above the module declaration, and a header with
no blank line under it took the open below the first declaration, leaving
the identifier as unresolved as before.

InsertionContext.Pos now means one thing for every ScopeKind — the first
line inside the scope — taken from the leading keyword the trivia records,
the name it introduces and, for a nested module, the `=`. Attributes and
doc comments sit above that line by construction, so no spelling has to be
recognized. AdjustInsertionPoint keeps only the cosmetic step of stepping
over the blank line under a header, and the editor's two insertion paths
now share one implementation, which also follows the file's own line
endings instead of the host's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The formatting-check CI job flagged AddOpenCodeFixProvider.fs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The insertion point is a position, and the change was applied at the start
of its line. That is the same thing whenever what precedes the declaration
on that line is whitespace, and something else entirely when it is not:

    (* header
    *) let x = StringBuilder()

Here the scope's first declaration is on the line that closes the comment,
so the open went between `(* header` and `*)`, inside the comment, leaving
the name as unresolved as it was. Whether the old code got this right was
luck of the same kind: it snapped an implicit module to line 1 and so wrote
above the comment here, but wrote inside it when the comment closed on a
line of its own.

What precedes the declaration is trivia that has to stay where it is, so
the line is broken at the declaration instead, and the declaration keeps
its column - moving it to the start of the line would put the open the
implicit module now begins with offside of it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 19, 2026
Port of the dotnet#20500 compaction (fix/add-open-placement 1eff620..9e488ea)
to all-fixes, in the form the stack's merge into dotnet#20501 gave it
(6682313..529c3f7):

- Name the open placement instead of commenting it
- Run the open placement cases as theories

The attribute-on-header cases live once in the new AddOpenOnTopSharedTests.fs,
which gets its Compile line in FSharp.Editor.Tests.fsproj. The release note
bullets of dotnet#20500 and dotnet#20501 are the shortened ones; all-fixes has no
compiler-service bullet for dotnet#20500, so none is added, and it has no duplicate
of the "Improve Find All References" bullet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 19, 2026
Port of the dotnet#20501 compaction (fix/add-open-type 6682313..db6709e) to
all-fixes, without the merge of dotnet#20500's head (the previous commit):

- Say in names what the open suggestions comment on
- Run the open type and every-candidate cases as theories

The comments on the suggestion caps, the System-first order, the qualifier span,
the entity lookup, the open versus open type decision and the operator filter
are gone. The provider keeps the extension member code that all-fixes has from
dotnet#20670; it is the one dotnet#20670's merge of this head resolved to
(642c00c..7f44dba). The release note bullets of dotnet#20501 were shortened
with the previous commit, as the stack's merge of dotnet#20500 shortens them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 19, 2026
Port of the dotnet#20670 compaction (fix/add-open-extension-members
642c00c..32a3ec1) to all-fixes. The part of that range which merges the
compacted dotnet#20501 head came with the previous two commits; this one carries what
is specific to the extension member code fix:

- Find the extension opens in flat helpers named for what they find
- Run the extension member cases as theories

The release note bullet of dotnet#20670 is the shortened one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 🕵️ Re-reviewed all recent changes as of db6709e; 1 finding


doRange NestedModule fullIdent moduleKeywordLine moduleBodyIndentation
List.iter (walkSynModuleDecl fullIdent) decls
if headerLine <= currentLine && not useMayBeInModuleAttribute then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 🕵️ [P2] Nearest-scope open type System.Console escapes the attributed module and breaks sibling ReadLine() (FS0193)

// AlwaysPlaceOpensAtTopLevel = false; apply open type System.Console to WriteLine
module Top
module Original =
    let ReadLine () = 123
open Original
[<System.Obsolete>] module M = let x = WriteLine "hi"
let number: int = ReadLine()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #20500 (6a7a4f7), which this PR is stacked on. The code fix and the completion now give the position of the use rather than its line, and a use after the start of the body of a nested module declared on one line is inside that module even when an attribute shares the line. For this example open type System.Console goes into M, so ReadLine() below keeps resolving to Original; a use in the attribute still stays outside. Covered here by Offers open type inside a nested module declared on one line with an attribute for a use in its body, with open System and completion counterparts in #20500.

xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
…he integration branch

The add-open branches link their release notes to PRs dotnet#20500 and dotnet#20501 and
check the shared-line case through the multi-suggestion fixture dotnet#20501 moved
the tests to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
Port of the dotnet#20500 compaction (fix/add-open-placement 1eff620..9e488ea)
to all-fixes, in the form the stack's merge into dotnet#20501 gave it
(6682313..529c3f7):

- Name the open placement instead of commenting it
- Run the open placement cases as theories

The attribute-on-header cases live once in the new AddOpenOnTopSharedTests.fs,
which gets its Compile line in FSharp.Editor.Tests.fsproj. The release note
bullets of dotnet#20500 and dotnet#20501 are the shortened ones; all-fixes has no
compiler-service bullet for dotnet#20500, so none is added, and it has no duplicate
of the "Improve Find All References" bullet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
Port of the dotnet#20501 compaction (fix/add-open-type 6682313..db6709e) to
all-fixes, without the merge of dotnet#20500's head (the previous commit):

- Say in names what the open suggestions comment on
- Run the open type and every-candidate cases as theories

The comments on the suggestion caps, the System-first order, the qualifier span,
the entity lookup, the open versus open type decision and the operator filter
are gone. The provider keeps the extension member code that all-fixes has from
dotnet#20670; it is the one dotnet#20670's merge of this head resolved to
(642c00c..7f44dba). The release note bullets of dotnet#20501 were shortened
with the previous commit, as the stack's merge of dotnet#20500 shortens them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
Port of the dotnet#20670 compaction (fix/add-open-extension-members
642c00c..32a3ec1) to all-fixes. The part of that range which merges the
compacted dotnet#20501 head came with the previous two commits; this one carries what
is specific to the extension member code fix:

- Find the extension opens in flat helpers named for what they find
- Run the extension member cases as theories

The release note bullet of dotnet#20670 is the shortened one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
dotnet#20719 pinned the spacing the Add Open fix and the completion commit produced when it merged: no blank line between a header and the open added under it, and the completion path and the code fix disagreeing about a nested module. dotnet#20500 and dotnet#20501 place the open from the syntax tree for both paths and keep one blank line between a non-blank line above and the open, so the expected texts gain that line. The open an applied-case test is about is looked up by its message, since the provider offers several and lists System first. One row stays skipped: the operator (=) matches static op_Equality of five System types, which fill the five offered opens ahead of open Candidates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
…he integration branch

The add-open branches link their release notes to PRs dotnet#20500 and dotnet#20501 and
check the shared-line case through the multi-suggestion fixture dotnet#20501 moved
the tests to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
Port of the dotnet#20500 compaction (fix/add-open-placement 1eff620..9e488ea)
to all-fixes, in the form the stack's merge into dotnet#20501 gave it
(6682313..529c3f7):

- Name the open placement instead of commenting it
- Run the open placement cases as theories

The attribute-on-header cases live once in the new AddOpenOnTopSharedTests.fs,
which gets its Compile line in FSharp.Editor.Tests.fsproj. The release note
bullets of dotnet#20500 and dotnet#20501 are the shortened ones; all-fixes has no
compiler-service bullet for dotnet#20500, so none is added, and it has no duplicate
of the "Improve Find All References" bullet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
Port of the dotnet#20501 compaction (fix/add-open-type 6682313..db6709e) to
all-fixes, without the merge of dotnet#20500's head (the previous commit):

- Say in names what the open suggestions comment on
- Run the open type and every-candidate cases as theories

The comments on the suggestion caps, the System-first order, the qualifier span,
the entity lookup, the open versus open type decision and the operator filter
are gone. The provider keeps the extension member code that all-fixes has from
dotnet#20670; it is the one dotnet#20670's merge of this head resolved to
(642c00c..7f44dba). The release note bullets of dotnet#20501 were shortened
with the previous commit, as the stack's merge of dotnet#20500 shortens them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
Port of the dotnet#20670 compaction (fix/add-open-extension-members
642c00c..32a3ec1) to all-fixes. The part of that range which merges the
compacted dotnet#20501 head came with the previous two commits; this one carries what
is specific to the extension member code fix:

- Find the extension opens in flat helpers named for what they find
- Run the extension member cases as theories

The release note bullet of dotnet#20670 is the shortened one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 23, 2026
dotnet#20719 pinned the spacing the Add Open fix and the completion commit produced when it merged: no blank line between a header and the open added under it, and the completion path and the code fix disagreeing about a nested module. dotnet#20500 and dotnet#20501 place the open from the syntax tree for both paths and keep one blank line between a non-blank line above and the open, so the expected texts gain that line. The open an applied-case test is about is looked up by its message, since the provider offers several and lists System first. One row stays skipped: the operator (=) matches static op_Equality of five System types, which fill the five offered opens ahead of open Candidates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri and others added 9 commits October 29, 2026 20:50
The conflicts were in the add-open code fix and OpenDeclarationHelper, which
main had also changed for active-pattern cases. The code fix keeps main's
catalogue handling and calls the shared change builder; main's
getInsertionPosition is dropped, since the insertion context now already
names the first line inside the scope.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ion of the use

A block comment that runs on from a module or namespace header made the line
below the header start inside the comment, so the open was written into it
and the name stayed unresolved:

    module Top (* header
    *)
    let x = Console.WriteLine 42

The header now ends where such a comment does, and a declaration that begins
on that line is entered at its own position, as one declared on the header's
line already was.

A nested module declared on one line with an attribute was kept out for any
use on its line, because the code fix and the completion gave a line only.
The attribute can hold the use, and then the open must stay outside, but so
can the body, and then it must not: the open escaped the module and
changed what a name outside resolved to. The code fix and the completion
now give the position of the use, and only a use before the body counts as
in the attribute. FindNearestPointToInsertOpenDeclaration and
TryFindInsertionContext keep taking a line and behave as before.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The conflicts were in the add-open code fix and the entity construction,
where main had added the active-pattern handling and identifier formatting.
The code fix keeps both: main's catalogue and active-pattern entities, with
the symbol each candidate came from carried along for the open type decision.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…open

Main's active-pattern tests encoded two spacings that the code fix and the
completion each had: the code fix left no blank line between an adjacent
header and the open, the completion left none between a header and an open
placed under a blank line. Both now go through one change builder, so the
open always gets a blank line above it and below it, and
InsertionContext.Pos names the first line inside a namespace instead of its
header line.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nt internally

InsertionContextEntity gained a field, which changes the constructor of a
public record for binary and source clients alike. The count says how many
leading idents of the entity's full name its Namespace covers, and the
editor needs it to tell a namespace or module, which a plain open reaches,
from a type, which only open type does. It now comes with the internal
TryFindInsertionContextAt, next to the context, and the public record and
TryFindInsertionContext are exactly what they were.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e body is unresolved

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The provider offers several opens, System first, so the one a test is about
need not be the first. One row stays skipped: the operator (=) matches static
op_Equality of five System types, which fill the five offered opens ahead of
open Candidates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 29, 2026
The conflicts were in the add-open code fix, where this branch had split the
work into small helpers and dotnet#20501 had moved the entity construction and the
active-pattern handling of main. The helpers now build the same name
candidates dotnet#20501 does, each with the symbol it came from and the count of
idents its namespace covers, and a member access still looks for extension
members instead.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 29, 2026
…he integration branch

The add-open branches link their release notes to PRs dotnet#20500 and dotnet#20501 and
check the shared-line case through the multi-suggestion fixture dotnet#20501 moved
the tests to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 29, 2026
Port of the dotnet#20500 compaction (fix/add-open-placement 1eff620..9e488ea)
to all-fixes, in the form the stack's merge into dotnet#20501 gave it
(6682313..529c3f7):

- Name the open placement instead of commenting it
- Run the open placement cases as theories

The attribute-on-header cases live once in the new AddOpenOnTopSharedTests.fs,
which gets its Compile line in FSharp.Editor.Tests.fsproj. The release note
bullets of dotnet#20500 and dotnet#20501 are the shortened ones; all-fixes has no
compiler-service bullet for dotnet#20500, so none is added, and it has no duplicate
of the "Improve Find All References" bullet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 29, 2026
Port of the dotnet#20501 compaction (fix/add-open-type 6682313..db6709e) to
all-fixes, without the merge of dotnet#20500's head (the previous commit):

- Say in names what the open suggestions comment on
- Run the open type and every-candidate cases as theories

The comments on the suggestion caps, the System-first order, the qualifier span,
the entity lookup, the open versus open type decision and the operator filter
are gone. The provider keeps the extension member code that all-fixes has from
dotnet#20670; it is the one dotnet#20670's merge of this head resolved to
(642c00c..7f44dba). The release note bullets of dotnet#20501 were shortened
with the previous commit, as the stack's merge of dotnet#20500 shortens them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 29, 2026
Port of the dotnet#20670 compaction (fix/add-open-extension-members
642c00c..32a3ec1) to all-fixes. The part of that range which merges the
compacted dotnet#20501 head came with the previous two commits; this one carries what
is specific to the extension member code fix:

- Find the extension opens in flat helpers named for what they find
- Run the extension member cases as theories

The release note bullet of dotnet#20670 is the shortened one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
xperiandri added a commit to xperiandri/fsharp that referenced this pull request Oct 29, 2026
dotnet#20719 pinned the spacing the Add Open fix and the completion commit produced when it merged: no blank line between a header and the open added under it, and the completion path and the code fix disagreeing about a nested module. dotnet#20500 and dotnet#20501 place the open from the syntax tree for both paths and keep one blank line between a non-blank line above and the open, so the expected texts gain that line. The open an applied-case test is about is looked up by its message, since the provider offers several and lists System first. One row stays skipped: the operator (=) matches static op_Equality of five System types, which fill the five offered opens ahead of open Candidates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Merging dotnet#20500 into this branch kept both the old and the reworded note,
because the release notes merge with the union driver.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚠️ Affects-Design-Time Tooling check: PR touches type providers or dependency manager AI-reviewed PR reviewed by AI review council AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

3 participants