Skip to content
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

Signature tweak to the grammar. #527

Merged
merged 3 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ open JetBrains.DocumentModel
open JetBrains.ReSharper.Feature.Services.CodeCompletion
open JetBrains.ReSharper.Feature.Services.CodeCompletion.Impl
open JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure
open JetBrains.ReSharper.Plugins.FSharp
open JetBrains.ReSharper.Plugins.FSharp.Psi
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.CodeCompletion
Expand Down Expand Up @@ -53,7 +54,7 @@ type FSharpReparseContext(fsFile: IFSharpFile, treeTextRange: TreeTextRange) =
let document = documentFactory.CreateSimpleDocumentFromText(source, moniker)

// todo: reparse as sig?
let parser = fsFile.GetFSharpLanguageService().CreateParser(document, fsFile.GetSourceFile(), true)
let parser = fsFile.GetFSharpLanguageService().CreateParser(document, fsFile.GetSourceFile(), FSharpProjectFileType.FsExtension)
let newFile =
try
let newFile =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.LanguageService

open System.Runtime.InteropServices
open FSharp.Compiler.Symbols
open FSharp.Compiler.Syntax
open JetBrains.Diagnostics
Expand All @@ -19,7 +20,8 @@ open JetBrains.ReSharper.Psi.Naming
open JetBrains.ReSharper.Psi.Tree
open JetBrains.ReSharper.Resources.Shell

type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: IPsiSourceFile, psiModule: IPsiModule) =
type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: IPsiSourceFile, psiModule: IPsiModule,
[<Optional; DefaultParameterValue(null)>] extension: string) =
let [<Literal>] moniker = "F# element factory"

let getNamingService () =
Expand All @@ -31,14 +33,19 @@ type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: I

let createFile source =
let document = createDocument source
let parser = languageService.CreateParser(document, sourceFile)
let parser = languageService.CreateParser(document, sourceFile, extension)

let fsFile = parser.ParseFSharpFile(noCache = true, StandaloneDocument = document)
SandBox.CreateSandBoxFor(fsFile, psiModule)
fsFile

let createFileWithModule source =
createFile $"module X
{source}
"

let getModuleDeclaration source =
let fsFile = createFile source
let fsFile = createFileWithModule source
fsFile.ModuleDeclarations.First()

let getModuleMember source =
Expand Down Expand Up @@ -395,3 +402,25 @@ type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: I
let source = $"member val P = 3 with {accessors}"
let t = getTypeDecl source
t.MemberDeclarations[0].As<IAutoPropertyDeclaration>().AccessorsClause

member this.CreateEmptyFile() = createFile ""

member this.CreateModule(name) =
let file = createFile $"module {name}"
file.ModuleDeclarations.[0] :?> INamedModuleDeclaration

member this.CreateNamespace(name) =
let file = createFile $"namespace {name}"
file.ModuleDeclarations.[0] :?> INamespaceDeclaration

member this.CreateNestedModule(name) =
let file = createFileWithModule $"module {name} = begin end"
file.ModuleDeclarations.[0].Members.[0] :?> INestedModuleDeclaration

member this.CreateModuleMember(source) =
let file = createFileWithModule source
file.ModuleDeclarations.[0].Members.[0]

member this.CreateTypeMemberSignature(source) =
(getTypeDecl source).TypeMembers.[0]
:> IFSharpTypeMemberDeclaration
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ type FSharpLanguageService(languageType, constantValueService, cacheProvider: FS
override x.GetTypeConversionRule(_, _) = ClrPredefinedTypeConversionRule.INSTANCE

interface IFSharpLanguageService with
member x.CreateParser(document: IDocument, sourceFile, [<Optional; DefaultParameterValue(false)>] useFsExtension) =
member x.CreateParser(document: IDocument, sourceFile, [<Optional; DefaultParameterValue(null)>] overrideExtension) =
let lexer = TokenBuffer(lexerFactory.CreateLexer(document.Buffer)).CreateLexer()
FSharpParser(lexer, document, sourceFile, checkerService, null, useFsExtension) :> _
FSharpParser(lexer, document, sourceFile, checkerService, null, overrideExtension) :> _

member x.CreateElementFactory(sourceFile, psiModule) = FSharpElementFactory(x, sourceFile, psiModule) :> _
member x.CreateElementFactory(sourceFile, psiModule, [<Optional; DefaultParameterValue(null)>] extension) =
FSharpElementFactory(x, sourceFile, psiModule, extension) :> _
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ type FSharpParser(lexer: ILexer, document: IDocument, path: VirtualFileSystemPat
let path = if isNotNull sourceFile then sourceFile.GetLocation() else null
FSharpParser(lexer, document, path, sourceFile, checkerService, symbolsCache)

new (lexer, document, sourceFile: IPsiSourceFile, checkerService, symbolsCache, useFsExtension) =
new (lexer, document, sourceFile: IPsiSourceFile, checkerService, symbolsCache, overrideExtension: string) =
let path =
if not useFsExtension && isNotNull sourceFile && sourceFile.LanguageType.Is<FSharpSignatureProjectFileType>() then
if isNotNull overrideExtension && overrideExtension = ".fsi" then
FSharpParser.SandBoxSignaturePath
elif isNull overrideExtension && isNotNull sourceFile && sourceFile.LanguageType.Is<FSharpSignatureProjectFileType>() then
FSharpParser.SandBoxSignaturePath
else
FSharpParser.SandBoxPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ type internal FSharpSigTreeBuilder(sourceFile, lexer, sigs, lifetime, path) =
member x.ProcessTopLevelSignature(SynModuleOrNamespaceSig(lid, _, isModule, sigDecls, XmlDoc xmlDoc, attrs, _, range, _)) =
let mark, elementType = x.StartTopLevelDeclaration(lid, attrs, isModule, xmlDoc, range)
for sigDecl in sigDecls do
x.ProcessModuleMemberSignature(sigDecl)
x.ProcessModuleMemberSignature(sigDecl, range)
x.FinishTopLevelDeclaration(mark, range, elementType)

member x.ProcessModuleMemberSignature(moduleMember) =
member x.ProcessModuleMemberSignature(moduleMember, parentRange) =
match moduleMember with
| SynModuleSigDecl.NestedModule(SynComponentInfo(attrs, _, _, _, XmlDoc xmlDoc, _, _, _), _, memberSigs, range, _) ->
let mark = x.MarkAndProcessIntro(attrs, xmlDoc, null, range)
for memberSig in memberSigs do
x.ProcessModuleMemberSignature(memberSig)
x.ProcessModuleMemberSignature(memberSig, parentRange)

if memberSigs.IsEmpty then
x.AdvanceToTokenOrRangeEnd(FSharpTokenType.END, parentRange)
x.Advance()
Comment on lines +32 to +34
Copy link
Member

Choose a reason for hiding this comment

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

Could you add a parser test and/or a comment about the pending FCS fix for this, please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I added a test but the problem is still there.
If there is nothing besides an empty nested module the parentRange will end right before the = token.


x.Done(mark, ElementType.NESTED_MODULE_DECLARATION)

| SynModuleSigDecl.Types(typeSigs, range) ->
Expand Down
2 changes: 1 addition & 1 deletion ReSharper.FSharp/src/FSharp.Psi/src/FSharp.psi
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ namedNamespaceDeclaration options { stubBase="FSharpDeclarationBase"; }:
topLevelNamedDeclarationName
moduleMember<MODULE_MEMBER, Members>*;

globalNamespaceDeclaration options { stubBase="FSharpDeclarationBase"; }:
globalNamespaceDeclaration options { stubBase="NamedNamespaceDeclaration"; }:
NAMESPACE<NAMESPACE, ModuleOrNamespaceKeyword>
REC<REC, RecKeyword>?
GLOBAL<GLOBAL, GlobalKeyword>
Expand Down
9 changes: 9 additions & 0 deletions ReSharper.FSharp/src/FSharp.Psi/src/IFSharpElementFactory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using FSharp.Compiler.Symbols;
using JetBrains.ReSharper.Plugins.FSharp.Psi.Tree;
using JetBrains.ReSharper.Psi.Tree;
using Microsoft.FSharp.Collections;

namespace JetBrains.ReSharper.Plugins.FSharp.Psi
Expand Down Expand Up @@ -64,5 +65,13 @@ public interface IFSharpElementFactory
ITypeParameterDeclarationList CreateTypeParameterOfTypeList(FSharpList<string> names);

IAccessorsNamesClause CreateAccessorsNamesClause(bool withGetter, bool withSetter);

IFSharpFile CreateEmptyFile();
INamedModuleDeclaration CreateModule(string name);
INamespaceDeclaration CreateNamespace(string name);
INestedModuleDeclaration CreateNestedModule(string name);

IModuleMember CreateModuleMember(string source);
IFSharpTypeMemberDeclaration CreateTypeMemberSignature(string source);
Copy link
Member

Choose a reason for hiding this comment

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

It seems it can also be used to create non-signature type members? If true, then maybe something like CreateTypeMember would be a better name.

}
}
4 changes: 2 additions & 2 deletions ReSharper.FSharp/src/FSharp.Psi/src/IFSharpLanguageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace JetBrains.ReSharper.Plugins.FSharp.Psi
{
public interface IFSharpLanguageService
{
IFSharpParser CreateParser(IDocument document, IPsiSourceFile sourceFile, bool useFsExtension = false);
IFSharpElementFactory CreateElementFactory(IPsiSourceFile sourceFile, IPsiModule psiModule);
IFSharpParser CreateParser(IDocument document, IPsiSourceFile sourceFile, string overrideExtension = null);
IFSharpElementFactory CreateElementFactory(IPsiSourceFile sourceFile, IPsiModule psiModule, string overrideExtension = null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using JetBrains.ReSharper.Psi.Tree;

namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Tree
{
public partial interface IGlobalNamespaceDeclaration : INamespaceDeclaration
{
}
}
1 change: 1 addition & 0 deletions ReSharper.FSharp/test/data/parsing/signatures/_.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module X
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,9 @@ type FSharpSignatureParserTest() =

override x.RelativeTestDataPath = "parsing/signatures"

/// Use this test case to dump the psi tree for a given file, see `_.fsi`.
[<Test; Explicit>] member x.``_``() = x.DoNamedTest()

[<Test>] member x.``Type decl - Union 01 - After nested module``() = x.DoNamedTest()
[<Test>] member x.``Type decl - Union 02 - FullType``() = x.DoNamedTest()
[<Test>] member x.``Type decl - Delegate``() = x.DoNamedTest()
Expand Down