Skip to content

Commit bfd4c7d

Browse files
committed
Merge pull request #30 from rojepp/methods
Add param completion command
2 parents c3e8ccd + a06b9d8 commit bfd4c7d

File tree

9 files changed

+592
-1
lines changed

9 files changed

+592
-1
lines changed

FSharp.AutoComplete/Program.fs

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,27 @@ type ProjectResponse =
6464
Framework: string
6565
}
6666

67+
type OverloadParameter =
68+
{
69+
Name : string
70+
CanonicalTypeTextForSorting : string
71+
Display : string
72+
Description : string
73+
}
74+
type Overload =
75+
{
76+
Tip : string
77+
TypeText : string
78+
Parameters : OverloadParameter list
79+
IsStaticArguments : bool
80+
}
81+
type MethodResponse =
82+
{
83+
Name : string
84+
CurrentParameter : int
85+
Overloads : Overload list
86+
}
87+
6788
type FSharpErrorSeverityConverter() =
6889
inherit JsonConverter()
6990

@@ -127,6 +148,8 @@ module internal CommandInput =
127148
- get tool tip for the specified location
128149
finddecl ""<filename>"" <line> <col> [timeout]
129150
- find the point of declaration of the symbol at specified location
151+
methods ""<filename>"" <line> <col> [timeout]
152+
- find the method signatures at specified location
130153
project ""<filename>""
131154
- associates the current session with the specified project
132155
outputmode {json,text}
@@ -164,6 +187,7 @@ module internal CommandInput =
164187
// The types of commands that need position information
165188
type PosCommand =
166189
| Completion
190+
| Methods
167191
| ToolTip
168192
| FindDeclaration
169193

@@ -237,6 +261,7 @@ module internal CommandInput =
237261
let completionTipOrDecl = parser {
238262
let! f = (string "completion " |> Parser.map (fun _ -> Completion)) <|>
239263
(string "tooltip " |> Parser.map (fun _ -> ToolTip)) <|>
264+
(string "methods " |> Parser.map (fun _ -> Methods)) <|>
240265
(string "finddecl " |> Parser.map (fun _ -> FindDeclaration))
241266
let! _ = char '"'
242267
let! filename = some (sat ((<>) '"')) |> Parser.map String.ofSeq
@@ -472,7 +497,7 @@ module internal Main =
472497
Data = { Project = file
473498
Files = files
474499
Output = targetFilename
475-
References = List.sort p.References
500+
References = List.sortBy Path.GetFileName p.References
476501
Framework = framework } }
477502
let projects =
478503
files
@@ -607,6 +632,68 @@ module internal Main =
607632

608633
main state
609634

635+
636+
| Methods ->
637+
// Find the starting point, ideally right after the first '('
638+
let lineCutoff = line - 3
639+
let commas, line, col =
640+
let rec prevPos (line,col) =
641+
match line, col with
642+
| 1, 1
643+
| _ when line < lineCutoff -> 1, 1
644+
| _, 1 ->
645+
let prevLine = state.Files.[file].Lines.[line - 2]
646+
if prevLine.Length = 0 then prevPos(line-1, 1)
647+
else line - 1, prevLine.Length
648+
| _ -> line, col - 1
649+
650+
let rec loop commas depth (line, col) =
651+
if (line,col) <= (1,1) then (0, line, col) else
652+
let ch = state.Files.[file].Lines.[line - 1].[col - 1]
653+
let commas = if depth = 0 && ch = ',' then commas + 1 else commas
654+
if (ch = '(' || ch = '{' || ch = '[') && depth > 0 then loop commas (depth - 1) (prevPos (line,col))
655+
elif ch = ')' || ch = '}' || ch = ']' then loop commas (depth + 1) (prevPos (line,col))
656+
elif ch = '(' || ch = '<' then commas, line, col
657+
else loop commas depth (prevPos (line,col))
658+
match loop 0 0 (prevPos(line,col)) with
659+
| _, 1, 1 -> 0, line, col
660+
| newPos -> newPos
661+
662+
let meth = tyRes.GetMethods(line, col, state.Files.[file].Lines.[line - 1])
663+
|> Async.RunSynchronously
664+
match meth with
665+
| Some (name,overloads) when overloads.Length > 0 ->
666+
match state.OutputMode with
667+
| Text ->
668+
printMsg "ERROR" "methods not supported in text mode"
669+
| Json ->
670+
prAsJson
671+
{ Kind = "method"
672+
Data = { Name = name
673+
CurrentParameter = commas
674+
Overloads =
675+
[ for o in overloads do
676+
let tip = TipFormatter.formatTip o.Description
677+
yield {
678+
Tip = tip
679+
TypeText = o.TypeText
680+
Parameters =
681+
[ for p in o.Parameters do
682+
yield {
683+
Name = p.ParameterName
684+
CanonicalTypeTextForSorting = p.CanonicalTypeTextForSorting
685+
Display = p.Display
686+
Description = p.Description
687+
}
688+
]
689+
IsStaticArguments = o.IsStaticArguments
690+
}
691+
692+
] } }
693+
| _ -> printMsg "ERROR" "Could not find method"
694+
695+
main state
696+
610697
else
611698
main state
612699

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module FileTwo
2+
3+
type Foo =
4+
| Bar
5+
| Qux
6+
7+
let addition x y = x + y
8+
9+
let add x y = x + y
10+
11+
type NewObjectType() =
12+
13+
member x.Terrific (y : int, z : char) : int = y
14+
member x.Terrific (y : int, z : System.DateTime) : int = y
15+
member x.Terrific (y : Set<'a>, z : int) : Set<'a> = y
16+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#load "../TestHelpers.fsx"
2+
open TestHelpers
3+
open System.IO
4+
open System
5+
6+
(*
7+
* This test is a simple sanity check of a basic run of the program.
8+
* A few completions, files and script.
9+
*)
10+
11+
Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
12+
File.Delete "output.txt"
13+
14+
let p = new FSharpAutoCompleteWrapper()
15+
16+
p.send "outputmode json\n"
17+
p.project "Test1.fsproj"
18+
p.parse "FileTwo.fs"
19+
p.parse "Program.fs"
20+
Threading.Thread.Sleep(6000)
21+
p.methods "Program.fs" 4 36
22+
p.methods "Program.fs" 4 37
23+
p.methods "Program.fs" 8 30
24+
p.methods "Program.fs" 8 35
25+
p.methods "Program.fs" 10 39
26+
p.methods "Program.fs" 14 3
27+
Threading.Thread.Sleep(1000)
28+
p.send "quit\n"
29+
p.finalOutput ()
30+
|> writeNormalizedOutput "output.json"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module X =
2+
let func x = x + 1
3+
4+
let testval = FileTwo.NewObjectType()
5+
6+
let val2 = X.func(2)
7+
8+
let val3 = testval.Terrific(val2, 'c')
9+
10+
let val4 = System.DateTime.Parse("hello")
11+
12+
let v5 = System.DateTime.Parse(
13+
14+
"hello"
15+
16+
)
17+
18+
19+
[<EntryPoint>]
20+
let main args =
21+
printfn "Hello %d" val2
22+
0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
3+
module XA =
4+
let funky x = x + 1
5+
6+
let val99 = XA.funky 21
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
6+
<ProductVersion>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{116CC2F9-F987-4B3D-915A-34CAC04A73DA}</ProjectGuid>
9+
<OutputType>Exe</OutputType>
10+
<RootNamespace>Test1</RootNamespace>
11+
<AssemblyName>Test1</AssemblyName>
12+
<Name>Test1</Name>
13+
<UsePartialTypes>False</UsePartialTypes>
14+
<BuildOrder>
15+
<BuildOrder>
16+
<String>Program.fs</String>
17+
</BuildOrder>
18+
</BuildOrder>
19+
<TargetFSharpCoreVersion>4.3.0.0</TargetFSharpCoreVersion>
20+
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
21+
</PropertyGroup>
22+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
23+
<DebugSymbols>True</DebugSymbols>
24+
<Optimize>False</Optimize>
25+
<Tailcalls>False</Tailcalls>
26+
<OutputPath>bin\Debug\</OutputPath>
27+
<DefineConstants>DEBUG;TRACE</DefineConstants>
28+
<WarningLevel>3</WarningLevel>
29+
<PlatformTarget>x86</PlatformTarget>
30+
<DocumentationFile>bin\Debug\Test1.XML</DocumentationFile>
31+
</PropertyGroup>
32+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
33+
<DebugType>pdbonly</DebugType>
34+
<Optimize>True</Optimize>
35+
<Tailcalls>True</Tailcalls>
36+
<OutputPath>bin\Release\</OutputPath>
37+
<DefineConstants>TRACE</DefineConstants>
38+
<WarningLevel>3</WarningLevel>
39+
<PlatformTarget>x86</PlatformTarget>
40+
<DocumentationFile>bin\Release\Test1.XML</DocumentationFile>
41+
<DebugSymbols>False</DebugSymbols>
42+
</PropertyGroup>
43+
<ItemGroup>
44+
<Reference Include="mscorlib" />
45+
<Reference Include="System" />
46+
<Reference Include="System.Core" />
47+
<Reference Include="FSharp.Core">
48+
<Private>True</Private>
49+
</Reference>
50+
</ItemGroup>
51+
<ItemGroup>
52+
<Compile Include="FileTwo.fs" />
53+
<Compile Include="Program.fs" />
54+
</ItemGroup>
55+
<Choose>
56+
<When Condition="'$(VisualStudioVersion)' == '11.0'">
57+
<PropertyGroup>
58+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
59+
</PropertyGroup>
60+
</When>
61+
<Otherwise>
62+
<PropertyGroup>
63+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64+
</PropertyGroup>
65+
</Otherwise>
66+
</Choose>
67+
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
68+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
69+
Other similar extension points exist, see Microsoft.Common.targets.
70+
<Target Name="BeforeBuild">
71+
</Target>
72+
<Target Name="AfterBuild">
73+
</Target>
74+
-->
75+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 11.00
3+
# Visual Studio 2010
4+
Project("{f2a71f9b-5d33-465a-a702-920d77279786}") = "Test1", "Test1.fsproj", "{116CC2F9-F987-4B3D-915A-34CAC04A73DA}"
5+
EndProject
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3069EBCA-546F-4208-9019-7952B8978616}"
7+
ProjectSection(SolutionItems) = preProject
8+
ParamCompletionRunner.fsx = ParamCompletionRunner.fsx
9+
EndProjectSection
10+
EndProject
11+
Global
12+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
13+
Debug|x86 = Debug|x86
14+
Release|x86 = Release|x86
15+
EndGlobalSection
16+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
17+
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Debug|x86.ActiveCfg = Debug|x86
18+
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Debug|x86.Build.0 = Debug|x86
19+
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Release|x86.ActiveCfg = Release|x86
20+
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Release|x86.Build.0 = Release|x86
21+
EndGlobalSection
22+
GlobalSection(NestedProjects) = preSolution
23+
EndGlobalSection
24+
EndGlobal

0 commit comments

Comments
 (0)