Skip to content

Conversation

@DedSec256
Copy link
Contributor

No description provided.

@DedSec256 DedSec256 force-pushed the ber.a/summarizeJunie branch 2 times, most recently from e41f70a to 8870d07 Compare September 4, 2025 14:52
@DedSec256 DedSec256 marked this pull request as ready for review September 4, 2025 15:32
@DedSec256 DedSec256 requested a review from auduchinok September 4, 2025 15:49
public static string GetSourceName([CanBeNull] this IIdentifier identifier)
{
if (identifier == null) return SharedImplUtil.MISSING_DECLARATION_NAME;
return identifier.PrevSibling?.GetTokenType() == FSharpTokenType.QUOTE ? "'" + identifier.Name : identifier.Name;
Copy link
Member

Choose a reason for hiding this comment

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

I think it should be part of a IFSharpIdentifier implementation. We should probably not assume a particular tree structure here.

<Compile Include="Refactorings\IntroduceVarTest.fs" />
<Compile Include="Refactorings\InlineVarTest.fs" />
<Compile Include="TypeProviders\PrimitiveTypesBoxerTest.fs" />
<Compile Include="AICore\FSharpFileSummarizerTest.fs" />
Copy link
Member

Choose a reason for hiding this comment

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

What does the Core part mean in the context of the plugin tests? Is it going to be somehow different from other AI features?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be fair, this is a unit test that tests an implementation detail, not a feature

Copy link
Contributor Author

Choose a reason for hiding this comment

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

renamed

type private FileSummarizerVisitor() =
inherit TreeNodeVisitor<SummarizerContext>()

static let displayContext = emptyDisplayContext
Copy link
Member

Choose a reason for hiding this comment

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

Why is this binding needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's just a single DisplayContext for the entire FileSummarizerVisitor implementation which currently uses the default context. If we want to change the default behavior, it will be enough to change this value, rather than replace all emptyDisplayContext in this implementation.

Comment on lines +55 to +61
var members = TypeRepresentation switch
{
null => TypeMembersEnumerable,
IClassRepresentation classRepr => classRepr.TypeMembersEnumerable,
IInterfaceRepresentation interfaceRepr => interfaceRepr.TypeMembersEnumerable,
_ => TreeNodeEnumerable<ITypeBodyMemberDeclaration>.Empty
};
Copy link
Member

Choose a reason for hiding this comment

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

Do we need it as a part of PSI? Are there any other features, besides the AI summarization, that need it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought it might be useful. It's not used anywhere else except AI right now.
It also complements the existing TypeInheritMember API (which also seems to be used in only one feature)

public partial interface IFSharpTypeDeclaration
{
[CanBeNull] ITypeInherit TypeInheritMember { get; }
}

public ITypeInherit TypeInheritMember
{
get
{
ITypeInherit TryFindTypeInherit(TreeNodeEnumerable<ITypeBodyMemberDeclaration> memberDecls) =>
memberDecls.OfType<ITypeInherit>().SingleItem();
return TypeRepresentation switch
{
null => TryFindTypeInherit(TypeMembersEnumerable),
IClassRepresentation classRepr => TryFindTypeInherit(classRepr.TypeMembersEnumerable),
_ => null
};
}
}

But we can also leave it as the details of the AI Summarization implementation.

exception E1 of string
with member x.NewMessage = ""

type Record = {
Copy link
Member

Choose a reason for hiding this comment

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

Please try to split this file into multiple ones.

Comment on lines +124 to +71
let typeRepr = referencePat.GetFcsSymbol() |> formatFcsSymbolType
let representation = $"val {referencePat.GetFcsSymbol().DisplayName}: {typeRepr}"
context.AddEntity(binding, representation)
Copy link
Member

Choose a reason for hiding this comment

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

These tree lines are repeated several times, with the only difference being the representation string. Could you try extracting it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In fact, in all three cases the common code consists only in calling

context.AddEntity(binding, representation)

The rest of the code constructs a different from each other representation

let typeRepr = referencePat.GetFcsSymbol() |> formatFcsSymbolType
let representation = $"val {referencePat.GetFcsSymbol().DisplayName}: {typeRepr}"
context.AddEntity(binding, representation)
let typeRepr = constructor.GetFcsSymbol() |> formatFcsSymbolType
let representation = $"new: {typeRepr}"
context.AddEntity(constructor, representation)
let representation = $"member {memberDecl.SourceName}: {typeRepr}" + accessors
context.AddEntity(memberDecl, representation)

I'm not sure if there's anything can be done here, except to inline some variables.


override x.VisitNamedModuleDeclaration(moduleDecl, context) =
// Currently, we're not adding a top-level module to the scope to not duplicate its name in tokens
context.AddEntity(moduleDecl, "module " + moduleDecl.ClrName)
Copy link
Member

Choose a reason for hiding this comment

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

Are we sure we want to use Clr name instead of the F# source name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SourceName is not suitable, as we need a qualified name. Perhaps it's worth adding something like QualifiedName to INamedModuleDeclaration?

use _ = context.OpenScope(interfaceImpl, $"interface {interfaceRepr}")
x.VisitNode(interfaceImpl, context)

override x.VisitTopBinding(binding, context) =
Copy link
Member

Choose a reason for hiding this comment

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

We should really try to fix the hierarchy instead of adding more repeating code like this :(

@DedSec256 DedSec256 force-pushed the ber.a/summarizeJunie branch 3 times, most recently from fe6c6d6 to d9d5465 Compare September 8, 2025 15:27
^ Conflicts:
^	ReSharper.FSharp/src/FSharp/FSharp.Psi.Features/src/AICore/FSharpFileSummarizer.fs
@DedSec256 DedSec256 merged commit 6d04adf into main Sep 22, 2025
1 check passed
@DedSec256 DedSec256 deleted the ber.a/summarizeJunie branch September 23, 2025 15:05
mfilippov pushed a commit that referenced this pull request Sep 24, 2025
GitOrigin-RevId: 6d04adf

# Conflicts:
#	dotnet/Plugins/resharper-fsharp/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Stages/InferredTypeCodeVisionProvider.fs
#	dotnet/Plugins/resharper-fsharp/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs

GitOrigin-RevId: 68b10107ed9fc1f5e0a3bcadfa812d35f2d475cf
auduchinok pushed a commit that referenced this pull request Sep 24, 2025
GitOrigin-RevId: 6d04adf

# Conflicts:
#	dotnet/Plugins/resharper-fsharp/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Stages/InferredTypeCodeVisionProvider.fs
#	dotnet/Plugins/resharper-fsharp/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs

GitOrigin-RevId: 68b10107ed9fc1f5e0a3bcadfa812d35f2d475cf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants