From 8a00e440dd31b5b102a803c5ea2de4f10acaf25b Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Fri, 2 Jan 2015 15:40:54 +0100 Subject: [PATCH] Added unit test for analysis of simple C# code with FCS. --- FSharp.Compiler.Service.sln | 17 ++++ tests/service/CSharpProjectAnalysis.fs | 90 +++++++++++++++++++ .../CSharp_Analysis/CSharp_Analysis.sln | 22 +++++ .../CSharp_Analysis/CSharpClass.cs | 90 +++++++++++++++++++ .../CSharp_Analysis/CSharp_Analysis.csproj | 53 +++++++++++ .../Properties/AssemblyInfo.cs | 36 ++++++++ .../FSharp.Compiler.Service.Tests.fsproj | 8 ++ 7 files changed, 316 insertions(+) create mode 100644 tests/service/CSharpProjectAnalysis.fs create mode 100644 tests/service/CSharp_Analysis/CSharp_Analysis.sln create mode 100644 tests/service/CSharp_Analysis/CSharp_Analysis/CSharpClass.cs create mode 100644 tests/service/CSharp_Analysis/CSharp_Analysis/CSharp_Analysis.csproj create mode 100644 tests/service/CSharp_Analysis/CSharp_Analysis/Properties/AssemblyInfo.cs diff --git a/FSharp.Compiler.Service.sln b/FSharp.Compiler.Service.sln index 5118365fe4..58b1576e1d 100644 --- a/FSharp.Compiler.Service.sln +++ b/FSharp.Compiler.Service.sln @@ -2,6 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.30501.0 +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{B6B68AE6-E7A4-4D43-9B34-FFA74BFE192B}" ProjectSection(SolutionItems) = preProject @@ -55,6 +56,7 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.Tes EndProjectSection EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsc", "samples\FscExe\Fsc.fsproj", "{C94C257C-3C0A-4858-B5D8-D746498D1F08}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharp_Analysis", "tests\service\CSharp_Analysis\CSharp_Analysis\CSharp_Analysis.csproj", "{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -189,6 +191,21 @@ Global {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Mixed Platforms.Build.0 = Release|Any CPU {C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|x86.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|x86.ActiveCfg = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Proto|Any CPU.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Proto|Any CPU.Build.0 = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Proto|Mixed Platforms.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Proto|Mixed Platforms.Build.0 = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Proto|x86.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.Build.0 = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/tests/service/CSharpProjectAnalysis.fs b/tests/service/CSharpProjectAnalysis.fs new file mode 100644 index 0000000000..64340b183d --- /dev/null +++ b/tests/service/CSharpProjectAnalysis.fs @@ -0,0 +1,90 @@ + +#if INTERACTIVE +#r "../../bin/v4.5/FSharp.Compiler.Service.dll" +#r "../../packages/NUnit.2.6.3/lib/nunit.framework.dll" +#load "FsUnit.fs" +#load "Common.fs" +#else +module FSharp.Compiler.Service.Tests.CSharpProjectAnalysis +#endif + + +open NUnit.Framework +open FsUnit +open System +open System.IO +open System.Collections.Generic + +open Microsoft.FSharp.Compiler +open Microsoft.FSharp.Compiler.SourceCodeServices + +open FSharp.Compiler.Service.Tests.Common + +let getProjectReferences (dllFiles, libDirs, otherFlags) = + let otherFlags = defaultArg otherFlags [] + let libDirs = defaultArg libDirs [] + let base1 = Path.GetTempFileName() + let dllName = Path.ChangeExtension(base1, ".dll") + let fileName1 = Path.ChangeExtension(base1, ".fs") + let projFileName = Path.ChangeExtension(base1, ".fsproj") + File.WriteAllText(fileName1, """module M""") + let options = + checker.GetProjectOptionsFromCommandLineArgs(projFileName, + [| yield "--debug:full" + yield "--define:DEBUG" + yield "--optimize-" + yield "--out:" + dllName + yield "--doc:test.xml" + yield "--warn:3" + yield "--fullpaths" + yield "--flaterrors" + yield "--target:library" + for dllFile in dllFiles do + yield "-r:"+dllFile + for libDir in libDirs do + yield "-I:"+libDir + yield! otherFlags + yield fileName1 |]) + let results = checker.ParseAndCheckProject(options) |> Async.RunSynchronously + if results.HasCriticalErrors then + let builder = new System.Text.StringBuilder() + for err in results.Errors do + builder.AppendLine(sprintf "**** %s: %s" (if err.Severity = Microsoft.FSharp.Compiler.Severity.Error then "error" else "warning") err.Message) + |> ignore + failwith (builder.ToString()) + + results.ProjectContext.GetReferencedAssemblies() + |> List.map(fun x -> x.SimpleName, x) + |> dict + +[] +let ``Test that csharp references are recognized as such`` () = + let csharpAssembly = typeof.Assembly.Location + let table = getProjectReferences([csharpAssembly], None, None) + let ass = table.["CSharp_Analysis"] + match ass.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass") with + | Some found -> + // this is no F# thing + found.IsFSharp |> shouldEqual false + + // Check that we have members + let members = found.MembersFunctionsAndValues |> Seq.map (fun e -> e.CompiledName, e) |> dict + members.ContainsKey ".ctor" |> shouldEqual true + members.ContainsKey "Method" |> shouldEqual true + members.ContainsKey "Property" |> shouldEqual true + members.ContainsKey "Event" |> shouldEqual true + members.ContainsKey "InterfaceMethod" |> shouldEqual true + members.ContainsKey "InterfaceProperty" |> shouldEqual true + members.ContainsKey "InterfaceEvent" |> shouldEqual true + + //// Check that we get xml docs + //String.IsNullOrWhiteSpace(members.[".ctor"].XmlDocSig) |> shouldEqual false + //String.IsNullOrWhiteSpace(members.["Method"].XmlDocSig) |> shouldEqual false + //String.IsNullOrWhiteSpace(members.["Property"].XmlDocSig) |> shouldEqual false + //String.IsNullOrWhiteSpace(members.["Event"].XmlDocSig) |> shouldEqual false + //String.IsNullOrWhiteSpace(members.["InterfaceMethod"].XmlDocSig) |> shouldEqual false + //String.IsNullOrWhiteSpace(members.["InterfaceProperty"].XmlDocSig) |> shouldEqual false + //String.IsNullOrWhiteSpace(members.["InterfaceEvent"].XmlDocSig) |> shouldEqual false + + () + | None -> () \ No newline at end of file diff --git a/tests/service/CSharp_Analysis/CSharp_Analysis.sln b/tests/service/CSharp_Analysis/CSharp_Analysis.sln new file mode 100644 index 0000000000..4f4767e297 --- /dev/null +++ b/tests/service/CSharp_Analysis/CSharp_Analysis.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample_VS2013_CSharp_Library_net45", "Sample_VS2013_CSharp_Library_net45\Sample_VS2013_CSharp_Library_net45.csproj", "{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tests/service/CSharp_Analysis/CSharp_Analysis/CSharpClass.cs b/tests/service/CSharp_Analysis/CSharp_Analysis/CSharpClass.cs new file mode 100644 index 0000000000..46f2b9fa46 --- /dev/null +++ b/tests/service/CSharp_Analysis/CSharp_Analysis/CSharpClass.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FSharp.Compiler.Service.Tests +{ + /// + /// Documentation + /// + public interface ICSharpInterface + { + int InterfaceMethod(string parameter); + bool InterfaceProperty { get; } + + event EventHandler InterfaceEvent; + } + + public interface ICSharpExplicitInterface + { + int ExplicitMethod(string parameter); + bool ExplicitProperty { get; } + + event EventHandler ExplicitEvent; + } + + public class CSharpClass : ICSharpInterface, ICSharpExplicitInterface + { + /// + /// Documentaton + /// + /// + public CSharpClass(int param) + { + + } + + /// + /// Documentaton + /// + /// + /// + public CSharpClass(int first, string param) + { + + } + + public int Method(string parameter) + { + throw new NotImplementedException(); + } + + public bool Property + { + get { throw new NotImplementedException(); } + } + + public event EventHandler Event; + + + public int InterfaceMethod(string parameter) + { + throw new NotImplementedException(); + } + + public bool InterfaceProperty + { + get { throw new NotImplementedException(); } + } + + public event EventHandler InterfaceEvent; + + int ICSharpExplicitInterface.ExplicitMethod(string parameter) + { + throw new NotImplementedException(); + } + + bool ICSharpExplicitInterface.ExplicitProperty + { + get { throw new NotImplementedException(); } + } + + event EventHandler ICSharpExplicitInterface.ExplicitEvent + { + add { throw new NotImplementedException(); } + remove { throw new NotImplementedException(); } + } + } +} diff --git a/tests/service/CSharp_Analysis/CSharp_Analysis/CSharp_Analysis.csproj b/tests/service/CSharp_Analysis/CSharp_Analysis/CSharp_Analysis.csproj new file mode 100644 index 0000000000..06cb87affd --- /dev/null +++ b/tests/service/CSharp_Analysis/CSharp_Analysis/CSharp_Analysis.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + {887630A3-4B1D-40EA-B8B3-2D842E9C40DB} + Library + Properties + CSharp_Analysis + CSharp_Analysis + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/service/CSharp_Analysis/CSharp_Analysis/Properties/AssemblyInfo.cs b/tests/service/CSharp_Analysis/CSharp_Analysis/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..6c36814e76 --- /dev/null +++ b/tests/service/CSharp_Analysis/CSharp_Analysis/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("CSharp_Analysis")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CSharp_Analysis")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("e1b15939-475d-4134-a76c-20845e07be39")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/service/FSharp.Compiler.Service.Tests.fsproj b/tests/service/FSharp.Compiler.Service.Tests.fsproj index b08c8f5912..e1b80bd33d 100644 --- a/tests/service/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/service/FSharp.Compiler.Service.Tests.fsproj @@ -63,6 +63,7 @@ + @@ -88,5 +89,12 @@ + + + CSharp_Analysis + {887630a3-4b1d-40ea-b8b3-2d842e9c40db} + True + + \ No newline at end of file