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

Add param completion command #30

Merged
merged 12 commits into from
Jun 28, 2015
89 changes: 88 additions & 1 deletion FSharp.AutoComplete/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,27 @@ type ProjectResponse =
Framework: string
}

type OverloadParameter =
{
Name : string
CanonicalTypeTextForSorting : string
Display : string
Description : string
}
type Overload =
{
Tip : string
TypeText : string
Parameters : OverloadParameter list
IsStaticArguments : bool
}
type MethodResponse =
{
Name : string
CurrentParameter : int
Overloads : Overload list
}

type FSharpErrorSeverityConverter() =
inherit JsonConverter()

Expand Down Expand Up @@ -127,6 +148,8 @@ module internal CommandInput =
- get tool tip for the specified location
finddecl ""<filename>"" <line> <col> [timeout]
- find the point of declaration of the symbol at specified location
methods ""<filename>"" <line> <col> [timeout]
- find the method signatures at specified location
project ""<filename>""
- associates the current session with the specified project
outputmode {json,text}
Expand Down Expand Up @@ -164,6 +187,7 @@ module internal CommandInput =
// The types of commands that need position information
type PosCommand =
| Completion
| Methods
| ToolTip
| FindDeclaration

Expand Down Expand Up @@ -237,6 +261,7 @@ module internal CommandInput =
let completionTipOrDecl = parser {
let! f = (string "completion " |> Parser.map (fun _ -> Completion)) <|>
(string "tooltip " |> Parser.map (fun _ -> ToolTip)) <|>
(string "methods " |> Parser.map (fun _ -> Methods)) <|>
(string "finddecl " |> Parser.map (fun _ -> FindDeclaration))
let! _ = char '"'
let! filename = some (sat ((<>) '"')) |> Parser.map String.ofSeq
Expand Down Expand Up @@ -472,7 +497,7 @@ module internal Main =
Data = { Project = file
Files = files
Output = targetFilename
References = List.sort p.References
References = List.sortBy Path.GetFileName p.References
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sort by file name only, fixes the issue with references appearing out of order on my machine, sensitive to user names, possibly machine name, and other paths(?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good

Framework = framework } }
let projects =
files
Expand Down Expand Up @@ -607,6 +632,68 @@ module internal Main =

main state


| Methods ->
// Find the starting point, ideally right after the first '('
let lineCutoff = line - 3
let commas, line, col =
let rec prevPos (line,col) =
match line, col with
| 1, 1
| _ when line < lineCutoff -> 1, 1
| _, 1 ->
let prevLine = state.Files.[file].Lines.[line - 2]
if prevLine.Length = 0 then prevPos(line-1, 1)
else line - 1, prevLine.Length
| _ -> line, col - 1

let rec loop commas depth (line, col) =
if (line,col) <= (1,1) then (0, line, col) else
let ch = state.Files.[file].Lines.[line - 1].[col - 1]
let commas = if depth = 0 && ch = ',' then commas + 1 else commas
if (ch = '(' || ch = '{' || ch = '[') && depth > 0 then loop commas (depth - 1) (prevPos (line,col))
elif ch = ')' || ch = '}' || ch = ']' then loop commas (depth + 1) (prevPos (line,col))
elif ch = '(' || ch = '<' then commas, line, col
else loop commas depth (prevPos (line,col))
match loop 0 0 (prevPos(line,col)) with
| _, 1, 1 -> 0, line, col
| newPos -> newPos

let meth = tyRes.GetMethods(line, col, state.Files.[file].Lines.[line - 1])
|> Async.RunSynchronously
match meth with
| Some (name,overloads) when overloads.Length > 0 ->
match state.OutputMode with
| Text ->
printMsg "ERROR" "methods not supported in text mode"
| Json ->
prAsJson
{ Kind = "method"
Data = { Name = name
CurrentParameter = commas
Overloads =
[ for o in overloads do
let tip = TipFormatter.formatTip o.Description
yield {
Tip = tip
TypeText = o.TypeText
Parameters =
[ for p in o.Parameters do
yield {
Name = p.ParameterName
CanonicalTypeTextForSorting = p.CanonicalTypeTextForSorting
Display = p.Display
Description = p.Description
}
]
IsStaticArguments = o.IsStaticArguments
}

] } }
| _ -> printMsg "ERROR" "Could not find method"

main state

else
main state

Expand Down
16 changes: 16 additions & 0 deletions FSharp.AutoComplete/test/integration/ParamCompletion/FileTwo.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module FileTwo

type Foo =
| Bar
| Qux

let addition x y = x + y

let add x y = x + y

type NewObjectType() =

member x.Terrific (y : int, z : char) : int = y
member x.Terrific (y : int, z : System.DateTime) : int = y
member x.Terrific (y : Set<'a>, z : int) : Set<'a> = y

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#load "../TestHelpers.fsx"
open TestHelpers
open System.IO
open System

(*
* This test is a simple sanity check of a basic run of the program.
* A few completions, files and script.
*)

Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
File.Delete "output.txt"

let p = new FSharpAutoCompleteWrapper()

p.send "outputmode json\n"
p.project "Test1.fsproj"
p.parse "FileTwo.fs"
p.parse "Program.fs"
Threading.Thread.Sleep(6000)
p.methods "Program.fs" 4 36
p.methods "Program.fs" 4 37
Copy link
Contributor

Choose a reason for hiding this comment

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

This one is failing, but I think it shouldn't. Using 1-indexed columns this is a request at $ in let testval = FileTwo.NewObjectType($), so I think we should return results here. The previous one is actually on the open bracket, which it would be nice if it succeeded, but I think slightly less important than this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, I'd go so far as to say the first one shouldn't succeed. :)

p.methods "Program.fs" 8 30
p.methods "Program.fs" 8 35
p.methods "Program.fs" 10 39
p.methods "Program.fs" 14 3
Threading.Thread.Sleep(1000)
p.send "quit\n"
p.finalOutput ()
|> writeNormalizedOutput "output.json"
22 changes: 22 additions & 0 deletions FSharp.AutoComplete/test/integration/ParamCompletion/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module X =
let func x = x + 1

let testval = FileTwo.NewObjectType()

let val2 = X.func(2)

let val3 = testval.Terrific(val2, 'c')

let val4 = System.DateTime.Parse("hello")

let v5 = System.DateTime.Parse(

"hello"

)


[<EntryPoint>]
let main args =
printfn "Hello %d" val2
0
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@


module XA =
let funky x = x + 1

let val99 = XA.funky 21
75 changes: 75 additions & 0 deletions FSharp.AutoComplete/test/integration/ParamCompletion/Test1.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{116CC2F9-F987-4B3D-915A-34CAC04A73DA}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Test1</RootNamespace>
<AssemblyName>Test1</AssemblyName>
<Name>Test1</Name>
<UsePartialTypes>False</UsePartialTypes>
<BuildOrder>
<BuildOrder>
<String>Program.fs</String>
</BuildOrder>
</BuildOrder>
<TargetFSharpCoreVersion>4.3.0.0</TargetFSharpCoreVersion>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>True</DebugSymbols>
<Optimize>False</Optimize>
<Tailcalls>False</Tailcalls>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<DocumentationFile>bin\Debug\Test1.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>True</Optimize>
<Tailcalls>True</Tailcalls>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<DocumentationFile>bin\Release\Test1.XML</DocumentationFile>
<DebugSymbols>False</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="FSharp.Core">
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="FileTwo.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
24 changes: 24 additions & 0 deletions FSharp.AutoComplete/test/integration/ParamCompletion/Test1.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{f2a71f9b-5d33-465a-a702-920d77279786}") = "Test1", "Test1.fsproj", "{116CC2F9-F987-4B3D-915A-34CAC04A73DA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3069EBCA-546F-4208-9019-7952B8978616}"
ProjectSection(SolutionItems) = preProject
ParamCompletionRunner.fsx = ParamCompletionRunner.fsx
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Debug|x86.ActiveCfg = Debug|x86
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Debug|x86.Build.0 = Debug|x86
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Release|x86.ActiveCfg = Release|x86
{116CC2F9-F987-4B3D-915A-34CAC04A73DA}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
EndGlobal
Loading