Skip to content

Commit

Permalink
Signature tweak to the grammar.
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed May 8, 2023
1 parent f4dfef6 commit a7883b5
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 15 deletions.
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()

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);
}
}
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
{
}
}
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

0 comments on commit a7883b5

Please sign in to comment.