提交 8b80426c 编写于 作者: D Don Syme 提交者: GitHub

allow build of FCS nuget package within this repo (#3480)

* allow build of community FCS nuget pacakge from this repo

* fix build of vs tests

* build fcs nupkg

* clean project files

* build all FCS bits, incl right dependencies

* fcs nuget updates

* netstandard is not netcore

* make FCS tests pass

* make FCS tests pass

* revert unintended change

* fix build of FCS docs

* remove explicit codegen from fcs .NETStandard build

* remove explicit codegen from fcs .NETStandard build

* add version numbers to DLLs

* missing file

* remove duplicate package
上级 c0bf2788
......@@ -58,7 +58,7 @@ fi)
fi)
#TODO: work out how to avoid the need for this
chmod u+x packages/FSharp.Compiler.Tools.4.1.5/tools/fsi.exe
chmod u+x packages/FSharp.Compiler.Tools.4.1.23/tools/fsi.exe
chmod u+x packages/FsLexYacc.7.0.6/build/fslex.exe
chmod u+x packages/FsLexYacc.7.0.6/build/fsyacc.exe
......
......@@ -37,6 +37,10 @@
<ItemGroup Condition="'$(BUILD_FCS)'=='1'">
<ProjectsWithNet40 Include="fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj" />
<ProjectsWithNet40 Include="fcs/FSharp.Compiler.Service.MSBuild.v12/FSharp.Compiler.Service.MSBuild.v12.fsproj" />
<ProjectsWithNet40 Include="fcs/FSharp.Compiler.Service.ProjectCracker/FSharp.Compiler.Service.ProjectCracker.fsproj" />
<ProjectsWithNet40 Include="fcs/FSharp.Compiler.Service.ProjectCrackerTool/FSharp.Compiler.Service.ProjectCrackerTool.fsproj" />
<ProjectsWithNet40 Include="fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj" />
</ItemGroup>
<ItemGroup Condition="'$(BUILD_SETUP)'=='1'">
......
......@@ -554,7 +554,7 @@ set _dotnet20exe=%~dp0Tools\dotnet20\dotnet.exe
set NUGET_PACKAGES=%~dp0Packages
set path=%~dp0Tools\dotnet20\;%path%
set _fsiexe="packages\FSharp.Compiler.Tools.4.1.5\tools\fsi.exe"
set _fsiexe="packages\FSharp.Compiler.Tools.4.1.23\tools\fsi.exe"
if not exist %_fsiexe% echo Error: Could not find %_fsiexe% && goto :failure
%_ngenexe% install %_fsiexe% /nologo
......@@ -592,8 +592,8 @@ if "%BUILD_PROTO%" == "1" (
if "%BUILD_PROTO_WITH_CORECLR_LKG%" == "0" (
echo %_ngenexe% install packages\FSharp.Compiler.Tools.4.1.5\tools\fsc.exe /nologo
%_ngenexe% install packages\FSharp.Compiler.Tools.4.1.5\tools\fsc.exe /nologo
echo %_ngenexe% install packages\FSharp.Compiler.Tools.4.1.23\tools\fsc.exe /nologo
%_ngenexe% install packages\FSharp.Compiler.Tools.4.1.23\tools\fsc.exe /nologo
echo %_msbuildexe% %msbuildflags% src\fsharp-proto-build.proj /p:BUILD_PROTO_WITH_CORECLR_LKG=%BUILD_PROTO_WITH_CORECLR_LKG% /p:Configuration=Proto
%_msbuildexe% %msbuildflags% src\fsharp-proto-build.proj /p:BUILD_PROTO_WITH_CORECLR_LKG=%BUILD_PROTO_WITH_CORECLR_LKG% /p:Configuration=Proto
......@@ -614,10 +614,11 @@ if "%BUILD_PHASE%" == "1" (
@if ERRORLEVEL 1 echo Error build failed && goto :failure
)
echo ---------------- Done with build, starting update/prepare ---------------
echo ---------------- Done with build, starting pack/update/prepare ---------------
if "%BUILD_NET40_FSHARP_CORE%" == "1" (
call src\update.cmd %BUILD_CONFIG% -ngen
echo ---------------- start update.cmd ---------------
call src\update.cmd %BUILD_CONFIG% -ngen
)
@echo set NUNITPATH=packages\NUnit.Console.3.0.0\tools\
......
<?xml version="1.0" encoding="utf-8"?>
<!--
# Copyright (c) 2002-2011 Microsoft Corporation.
#
#
#
#
#
#
# You must not remove this notice, or any other, from this software.
# Copyright (c) 2002-2011 Microsoft Corporation. You must not remove this notice, or any other, from this software.
-->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FSharpSourcesRoot>$(MSBuildProjectDirectory)\..\..\src</FSharpSourcesRoot>
</PropertyGroup>
<Import Project="..\fcs.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
......@@ -19,26 +16,23 @@
<NoWarn>$(NoWarn);44;62;9</NoWarn>
<ProjectGuid>{8157b50e-397d-4232-a4e0-1977afc7076d}</ProjectGuid>
<AllowCrossTargeting>true</AllowCrossTargeting>
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<BaseAddress>0x06800000</BaseAddress>
<OtherFlags>$(OtherFlags) /warnon:1182</OtherFlags>
<Tailcalls>true</Tailcalls>
<FsLexUnicode>true</FsLexUnicode>
<OtherFlags>$(OtherFlags) --times</OtherFlags>
<NoWarn>$(NoWarn);69;65;54;61;75</NoWarn>
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\bin\$(TargetFrameworkVersion)</OutputPath>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<DefineConstants>$(DefineConstants);CROSS_PLATFORM_COMPILER</DefineConstants>
<DefineConstants>$(DefineConstants);ENABLE_MONO_SUPPORT</DefineConstants>
<DefineConstants Condition="$(TargetFrameworkVersion) == 'v4.5'">$(DefineConstants);FX_ATLEAST_45</DefineConstants>
<DefineConstants>$(DefineConstants);FX_ATLEAST_40</DefineConstants>
<DefineConstants>$(DefineConstants);FX_MSBUILDRESOLVER_RUNTIMELIKE</DefineConstants>
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
<OutputPath>..\..\$(Configuration)\fcs\net45\</OutputPath>
<TargetFrameworkProfile />
<ResolveNuGetPackages>false</ResolveNuGetPackages>
<Prefer32Bit>true</Prefer32Bit>
<PlatformTarget>AnyCPU</PlatformTarget>
<DefineConstants>$(DefineConstants);CROSS_PLATFORM_COMPILER</DefineConstants>
<DefineConstants>$(DefineConstants);ENABLE_MONO_SUPPORT</DefineConstants>
<OtherFlags>$(OtherFlags) /warnon:1182</OtherFlags>
<OtherFlags>$(OtherFlags) --version:$(VersionPrefix).0</OtherFlags>
<!-- We target .NET 4.5 for FSharp.Compiler.Service.dll to allow broader use of this DLL -->
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
</PropertyGroup>
<!-- MonoDevelop likes these here to recognise the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
......@@ -50,13 +44,7 @@
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\assemblyinfo\assemblyinfo.FSharp.Compiler.Service.MSBuild.v12.dll.fs">
<Link>AssemblyInfo/assemblyinfo.FSharp.Compiler.Service.MSBuild.v12.dll.fs</Link>
</Compile>
<Compile Include="..\..\assemblyinfo\assemblyinfo.shared.fs" Condition="Exists('..\..\assemblyinfo\assemblyinfo.shared.fs')">
<Link>AssemblyInfo/assemblyinfo.shared.fs</Link>
</Compile>
<Compile Include="..\MSBuildReferenceResolver.fs">
<Compile Include="..\..\src\fsharp\MSBuildReferenceResolver.fs">
<Link>Service/MSBuildReferenceResolver.fs</Link>
</Compile>
</ItemGroup>
......@@ -68,35 +56,37 @@
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.Build.Framework, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.Framework.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build.Engine, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.Engine.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build.Utilities.v12.0">
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.Utilities.v12.0.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build.Tasks.v12.0">
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.Tasks.v12.0.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>False</Private>
<!-- we build the nuget against FSHarp.Core 4.4.0.0 instead of our latest to allow use in wider range of F# tools -->
<Reference Include="FSharp.Core">
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.4.1.20\lib\profiles\net40\FSharp.Core.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj">
<Name>FSharp.Compiler.Service</Name>
<Project>{2e4d67b4-522d-4cf7-97e4-ba940f0b18f3}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<Import Project="$(SolutionDir)\.paket\paket.targets" />
<Import Project="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\Microsoft.FSharp.Targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<FSharpSourcesRoot>$(MSBuildProjectDirectory)\..\..\src</FSharpSourcesRoot>
</PropertyGroup>
<Import Project="..\fcs.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\..\..\</SolutionDir>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>893c3cd9-5af8-4027-a667-21e62fc2c703</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>FSharp.Compiler.Service.ProjectCracker</RootNamespace>
<AssemblyName>FSharp.Compiler.Service.ProjectCracker</AssemblyName>
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
<Name>FSharp.Compiler.Service.ProjectCracker</Name>
<OutputPath>..\..\..\bin\$(TargetFrameworkVersion)</OutputPath>
<DocumentationFile>..\..\..\bin\$(TargetFrameworkVersion)\FSharp.Compiler.Service.ProjectCracker.xml</DocumentationFile>
<OutputType>Library</OutputType>
<OutputPath>..\..\$(Configuration)\fcs\net45\</OutputPath>
<DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile>
<ResolveNuGetPackages>false</ResolveNuGetPackages>
<!-- We target .NET 4.5 for FSharp.Compiler.Service.dll to allow broader use of this DLL -->
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<Prefer32Bit>true</Prefer32Bit>
<PlatformTarget>AnyCPU</PlatformTarget>
<WarningLevel>3</WarningLevel>
<OtherFlags>$(OtherFlags) --version:$(VersionPrefix).0</OtherFlags>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
......@@ -23,29 +30,25 @@
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<!-- we build the nuget against FSHarp.Core 4.4.0.0 instead of our latest to allow use in wider range of F# tools -->
<Reference Include="FSharp.Core">
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.4.1.20\lib\profiles\net40\FSharp.Core.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\FSharp.Compiler.Service.ProjectCrackerTool\ProjectCrackerOptions.fs">
......@@ -60,5 +63,5 @@
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(SolutionDir)\packages\FSharp.Compiler.Tools\tools\Microsoft.FSharp.Targets" />
<Import Project="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\Microsoft.FSharp.Targets" />
</Project>
\ No newline at end of file
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>12.0.8</VersionPrefix>
<TargetFramework>netstandard1.6</TargetFramework>
<OutputType>Library</OutputType>
<DefineConstants>$(DefineConstants);DOTNETCORE;</DefineConstants>
<NoWarn>$(NoWarn);44;2003;</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DelaySign>true</DelaySign>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>FSharp.Compiler.Service.ProjectCracker</AssemblyName>
<PackageId>FSharp.Compiler.Service.ProjectCracker</PackageId>
</PropertyGroup>
<ItemGroup>
<Compile Include="../FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerOptions.fs">
<Link>ProjectCrackerOptions.fs</Link>
</Compile>
<Compile Include="../FSharp.Compiler.Service.ProjectCrackerTool/ProjectCrackerTool.fs">
<Link>ProjectCrackerTool.fs</Link>
</Compile>
<Compile Include="ProjectCracker.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../FSharp.Compiler.Service/FSharp.Compiler.Service.netcore.fsproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.1.*" />
<PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" />
<PackageReference Include="Microsoft.Build" Version="14.3.0" />
<PackageReference Include="Microsoft.Build.Framework" Version="14.3.0" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="14.3.0" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="14.3.0" />
<PackageReference Include="System.Runtime.Serialization.Json" Version="4.0.2" />
</ItemGroup>
<Import Project="..\..\..\.paket\Paket.Restore.targets" />
</Project>
\ No newline at end of file
......@@ -41,7 +41,8 @@ type ProjectCracker =
LoadTime = loadedTimeStamp
UnresolvedReferences = None
OriginalLoadReferences = []
ExtraProjectInfo = None }
ExtraProjectInfo = None
Stamp = None }
#if NETSTANDARD1_6
let arguments = [|
......
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<FSharpSourcesRoot>$(MSBuildProjectDirectory)\..\..\src</FSharpSourcesRoot>
</PropertyGroup>
<Import Project="..\fcs.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
......@@ -8,18 +11,21 @@
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>b1bdd96d-47e1-4e65-8107-fbae23a06db4</ProjectGuid>
<OutputType>Exe</OutputType>
<OutputPath>..\..\$(Configuration)\fcs\net45\</OutputPath>
<DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile>
<RootNamespace>FSharp.Compiler.Service.ProjectCrackerTool</RootNamespace>
<AssemblyName>FSharp.Compiler.Service.ProjectCrackerTool</AssemblyName>
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
<Name>FSharp.Compiler.Service.ProjectCrackerTool</Name>
<OtherFlags>$(OtherFlags) --staticlink:FSharp.Core</OtherFlags>
<NoWarn>$(NoWarn);40</NoWarn>
<NoWarn>$(NoWarn);40;44;2011</NoWarn>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Name>FSharp.Compiler.Service.ProjectCrackerTool</Name>
<OutputPath>$(SolutionDir)bin\$(TargetFrameworkVersion)</OutputPath>
<DocumentationFile>$(SolutionDir)bin\$(TargetFrameworkVersion)\FSharp.Compiler.Service.ProjectCrackerTool.xml</DocumentationFile>
<ResolveNuGetPackages>false</ResolveNuGetPackages>
<!-- We target .NET 4.5 for FSharp.Compiler.Service.dll to allow broader use of this DLL -->
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
<OtherFlags>$(OtherFlags) --version:$(VersionPrefix).0</OtherFlags>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
......@@ -27,23 +33,13 @@
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(SolutionDir)\packages\FSharp.Compiler.Tools\tools\Microsoft.FSharp.Targets" />
<ItemGroup>
<Compile Include="ProjectCrackerOptions.fs" />
<Compile Include="ProjectCrackerTool.fs" />
......@@ -53,23 +49,20 @@
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Build.Framework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<SpecificVersion>True</SpecificVersion>
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Framework.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build.Engine, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<SpecificVersion>True</SpecificVersion>
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v14.0/Microsoft.Build.Engine.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<SpecificVersion>True</SpecificVersion>
<Private>True</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v14.0/Microsoft.Build.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.Build.Utilities.v12.0">
<Private>True</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>False</Private>
<HintPath>$(FSharpSourcesRoot)/../fcs/dependencies/MSBuild.v12.0/Microsoft.Build.Utilities.v12.0.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="System" />
......@@ -78,12 +71,13 @@
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml" />
<!-- we build the nuget against FSHarp.Core 4.4.0.0 instead of our latest to allow use in wider range of F# tools -->
<Reference Include="FSharp.Core">
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.4.1.20\lib\profiles\net40\FSharp.Core.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<!-- 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>
-->
<Import Project="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\Microsoft.FSharp.Targets" />
</Project>
\ No newline at end of file
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<AssemblyName>FSharp.Compiler.Service.ProjectCrackerTool</AssemblyName>
<OutputType>Exe</OutputType>
<DefineConstants>$(DefineConstants);DOTNETCORE;</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="ProjectCrackerOptions.fs" />
<Compile Include="ProjectCrackerTool.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="14.3.0" />
<PackageReference Include="Microsoft.Build.Framework" Version="14.3.0" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="14.3.0" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="14.3.0" />
<PackageReference Include="System.Runtime.Serialization.Json" Version="4.0.2" />
<PackageReference Include="FSharp.Core" Version="4.1.*" />
<PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" />
</ItemGroup>
<Import Project="..\..\..\.paket\Paket.Restore.targets" />
</Project>
\ No newline at end of file
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<DefineConstants>$(DefineConstants);DOTNETCORE;FX_ATLEAST_45;FX_ATLEAST_PORTABLE;FX_NO_RUNTIMEENVIRONMENT;FX_RESHAPED_REFLECTION;TODO_REWORK_ASSEMBLY_LOAD;</DefineConstants>
......@@ -9,25 +9,25 @@
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<ItemGroup>
<Compile Include="../service/ReshapedReflection.fs">
<Compile Include="../../tests/service/ReshapedReflection.fs">
<Link>ReshapedReflection.fs</Link>
</Compile>
<Compile Include="../service/FsUnit.fs">
<Compile Include="../../tests/service/FsUnit.fs">
<Link>FsUnit.fs</Link>
</Compile>
<Compile Include="../service/Common.fs">
<Compile Include="../../tests/service/Common.fs">
<Link>Common.fs</Link>
</Compile>
<Compile Include="../service/EditorTests.fs">
<Compile Include="../../tests/service/EditorTests.fs">
<Link>EditorTests.fs</Link>
</Compile>
<Compile Include="../service/ExprTests.fs">
<Compile Include="../../tests/service/ExprTests.fs">
<Link>ExprTests.fs</Link>
</Compile>
<Compile Include="../service/TokenizerTests.fs">
<Compile Include="../../tests/service/TokenizerTests.fs">
<Link>TokenizerTests.fs</Link>
</Compile>
<Compile Include="../service/PerfTests.fs">
<Compile Include="../../tests/service/PerfTests.fs">
<Link>PerfTests.fs</Link>
</Compile>
<!--<Compile Include="../service/InteractiveCheckerTests.fs">
......@@ -38,14 +38,13 @@
</Compile>-->
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.netcore.fsproj" />
<ProjectReference Include="../FSharp.Compiler.Service/FSharp.Compiler.Service.netcore.fsproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="NUnitLite" Version="3.6.1" />
<PackageReference Include="NUnit" Version="3.6.1" />
<PackageReference Include="FSharp.Core" Version="4.1.*" PrivateAssets="All" />
<PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" />
<PackageReference Include="System.Runtime" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="System.Reflection.Metadata" Version="1.4.1" />
......@@ -54,8 +53,7 @@
<PackageReference Include="Dotnet.ProjInfo" Version="0.5.0" />
</ItemGroup>
<Target Name="PrecompileScript" BeforeTargets="BeforeBuild">
<Exec Command="dotnet restore &quot;$(MSBuildProjectDirectory)/../projects/Sample_NETCoreSDK_FSharp_Library_netstandard1.6/Sample_NETCoreSDK_FSharp_Library_netstandard1.6.fsproj&quot;" />
<Exec Command="dotnet build &quot;$(MSBuildProjectDirectory)/../projects/Sample_NETCoreSDK_FSharp_Library_netstandard1.6/Sample_NETCoreSDK_FSharp_Library_netstandard1.6.fsproj&quot;" />
<Exec Command="dotnet restore &quot;$(MSBuildProjectDirectory)/../../tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard1.6/Sample_NETCoreSDK_FSharp_Library_netstandard1.6.fsproj&quot;" />
<Exec Command="dotnet build &quot;$(MSBuildProjectDirectory)/../../tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard1.6/Sample_NETCoreSDK_FSharp_Library_netstandard1.6.fsproj&quot;" />
</Target>
<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0-4.4.0.0" newVersion="4.4.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FSharpSourcesRoot>$(MSBuildProjectDirectory)\..\..\src</FSharpSourcesRoot>
</PropertyGroup>
<Import Project="..\fcs.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\..\..\</SolutionDir>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F</ProjectGuid>
<OutputType>Library</OutputType>
<ProjectLanguage>FSharp</ProjectLanguage>
<Name>FSharp.Compiler.Service.Tests</Name>
<AssemblyName>FSharp.Compiler.Service.Tests</AssemblyName>
<TargetType>LIBRARY</TargetType>
<NoWarn>58;75</NoWarn>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<DefineConstants>EXTENSIONTYPING;$(DefineConstants)</DefineConstants>
<ResolveNuGetPackages>false</ResolveNuGetPackages>
<OutputPath>..\..\$(Configuration)\fcs\net45\</OutputPath>
<Tailcalls>true</Tailcalls>
<WarningLevel>3</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\FsUnit.fs">
<Link>FsUnit.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\Common.fs">
<Link>Common.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\EditorTests.fs">
<Link>EditorTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\FileSystemTests.fs">
<Link>FileSystemTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\ProjectAnalysisTests.fs">
<Link>ProjectAnalysisTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\MultiProjectAnalysisTests.fs">
<Link>MultiProjectAnalysisTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\PerfTests.fs">
<Link>PerfTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\InteractiveCheckerTests.fs">
<Link>InteractiveCheckerTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\ExprTests.fs">
<Link>ExprTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\CSharpProjectAnalysis.fs">
<Link>CSharpProjectAnalysis.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\ProjectOptionsTests.fs">
<Link>ProjectOptionsTests.fs</Link>
</Compile>
<None Include="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\FSharp.Core.optdata">
<Link>FSharp.Core.optdata</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\FSharp.Core.sigdata">
<Link>FSharp.Core.sigdata</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Numerics" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Drawing" />
<Reference Include="System.Configuration" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
<Reference Include="UIAutomationTypes" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Collections.Immutable">
<HintPath>$(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework">
<Private>True</Private>
<HintPath>..\..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<!-- we test against FSharp.Core 4.4.1.0 -->
<Reference Include="FSharp.Core">
<HintPath>$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\FSharp.Core.dll</HintPath>
<Private>true</Private>
</Reference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\tests\service\data\CSharp_Analysis\CSharp_Analysis.csproj">
<Name>CSharp_Analysis</Name>
<Project>{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\fcs\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj">
<Project>{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}</Project>
<Name>FSharp.Compiler.Service</Name>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\fcs\FSharp.Compiler.Service.ProjectCracker\FSharp.Compiler.Service.ProjectCracker.fsproj">
<Name>FSharp.Compiler.Service.ProjectCracker</Name>
<Project>{893c3cd9-5af8-4027-a667-21e62fc2c703}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\Microsoft.FSharp.Targets" />
</Project>
\ No newline at end of file
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.8
MinimumVisualStudioVersion = 15.0.26124.0
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.netstandard", "FSharp.Compiler.Service.netstandard\FSharp.Compiler.Service.netstandard.fsproj", "{36B9F520-14B1-4431-AAF2-75433B87D851}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSharp.Compiler.Service.Tests.netcore", "FSharp.Compiler.Service.Tests.netcore\FSharp.Compiler.Service.Tests.netcore.fsproj", "{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{36B9F520-14B1-4431-AAF2-75433B87D851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36B9F520-14B1-4431-AAF2-75433B87D851}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36B9F520-14B1-4431-AAF2-75433B87D851}.Debug|x64.ActiveCfg = Debug|x64
{36B9F520-14B1-4431-AAF2-75433B87D851}.Debug|x64.Build.0 = Debug|x64
{36B9F520-14B1-4431-AAF2-75433B87D851}.Debug|x86.ActiveCfg = Debug|x86
{36B9F520-14B1-4431-AAF2-75433B87D851}.Debug|x86.Build.0 = Debug|x86
{36B9F520-14B1-4431-AAF2-75433B87D851}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36B9F520-14B1-4431-AAF2-75433B87D851}.Release|Any CPU.Build.0 = Release|Any CPU
{36B9F520-14B1-4431-AAF2-75433B87D851}.Release|x64.ActiveCfg = Release|x64
{36B9F520-14B1-4431-AAF2-75433B87D851}.Release|x64.Build.0 = Release|x64
{36B9F520-14B1-4431-AAF2-75433B87D851}.Release|x86.ActiveCfg = Release|x86
{36B9F520-14B1-4431-AAF2-75433B87D851}.Release|x86.Build.0 = Release|x86
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Debug|x64.ActiveCfg = Debug|x64
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Debug|x64.Build.0 = Debug|x64
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Debug|x86.ActiveCfg = Debug|x86
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Debug|x86.Build.0 = Debug|x86
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Release|Any CPU.Build.0 = Release|Any CPU
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Release|x64.ActiveCfg = Release|x64
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Release|x64.Build.0 = Release|x64
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Release|x86.ActiveCfg = Release|x86
{1004CE3D-0CCB-47F5-8DBF-657D1B9C19D7}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DEDB1900-EFFF-4691-89B1-6DBEE6B77491}
EndGlobalSection
EndGlobal
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.8
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{B6B68AE6-E7A4-4D43-9B34-FFA74BFE192B}"
ProjectSection(SolutionItems) = preProject
build.cmd = build.cmd
build.fsx = build.fsx
build.sh = build.sh
nuget\FSharp.Compiler.Service.nuspec = nuget\FSharp.Compiler.Service.nuspec
paket.dependencies = paket.dependencies
README.md = README.md
RELEASE_NOTES.md = RELEASE_NOTES.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docsrc", "docsrc", "{83FEE492-6701-4E59-9184-16B1D30E91F8}"
ProjectSection(SolutionItems) = preProject
docsrc\content\caches.fsx = docsrc\content\caches.fsx
docsrc\content\corelib.fsx = docsrc\content\corelib.fsx
docsrc\content\devnotes.md = docsrc\content\devnotes.md
docsrc\content\editor.fsx = docsrc\content\editor.fsx
docsrc\content\filesystem.fsx = docsrc\content\filesystem.fsx
docsrc\content\fsharp-readme.md = docsrc\content\fsharp-readme.md
docsrc\content\index.md = docsrc\content\index.md
docsrc\content\interactive.fsx = docsrc\content\interactive.fsx
docsrc\content\project.fsx = docsrc\content\project.fsx
docsrc\content\queue.fsx = docsrc\content\queue.fsx
docsrc\content\symbols.fsx = docsrc\content\symbols.fsx
docsrc\content\tokenizer.fsx = docsrc\content\tokenizer.fsx
docsrc\content\typedtree.fsx = docsrc\content\typedtree.fsx
docsrc\content\untypedtree.fsx = docsrc\content\untypedtree.fsx
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{0554567F-1DCB-46A5-9EF2-E1938A3D4F14}"
ProjectSection(SolutionItems) = preProject
docsrc\tools\generate.fsx = docsrc\tools\generate.fsx
docsrc\tools\templates\template.cshtml = docsrc\tools\templates\template.cshtml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E396742E-B4E5-4584-A9E4-CC1A491F5BC1}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "EditorService", "samples\EditorService\EditorService.fsproj", "{A40507D6-FA48-43D3-B18A-AE3DAACE4020}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "InteractiveService", "samples\InteractiveService\InteractiveService.fsproj", "{067E95E5-E3DC-4CA7-813A-4D1E277D2D52}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tokenizer", "samples\Tokenizer\Tokenizer.fsproj", "{92793069-816F-4F69-84AC-0966F8275E65}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "UntypedTree", "samples\UntypedTree\UntypedTree.fsproj", "{C816728D-BBEA-472D-9F6C-E8913957A673}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FscExe", "samples\FscExe\FscExe.fsproj", "{C94C257C-3C0A-4858-B5D8-D746498D1F08}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharp_Analysis", "..\tests\service\data\CSharp_Analysis\CSharp_Analysis.csproj", "{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsiExe", "samples\FsiExe\FsiExe.fsproj", "{F9540CA8-1CE0-4546-A23A-A461E416E95B}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.ProjectCrackerTool", "FSharp.Compiler.Service.ProjectCrackerTool\FSharp.Compiler.Service.ProjectCrackerTool.fsproj", "{B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.ProjectCracker", "FSharp.Compiler.Service.ProjectCracker\FSharp.Compiler.Service.ProjectCracker.fsproj", "{893C3CD9-5AF8-4027-A667-21E62FC2C703}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{098D1C35-D0FB-4720-83DD-8002293EA237}"
ProjectSection(SolutionItems) = preProject
.gitattributes = .gitattributes
.gitignore = .gitignore
.travis.yml = .travis.yml
appveyor.yml = appveyor.yml
NuGet.Config = NuGet.Config
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "package", "package", "{9020E136-794A-473F-9B1B-9623C97B7161}"
ProjectSection(SolutionItems) = preProject
nuget\FSharp.Compiler.Service.template = nuget\FSharp.Compiler.Service.template
nuget\projectcracker.template = nuget\projectcracker.template
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.MSBuild.v12", "FSharp.Compiler.Service.MSBuild.v12\FSharp.Compiler.Service.MSBuild.v12.fsproj", "{8157B50E-397D-4232-A4E0-1977AFC7076D}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service", "FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Service.Tests", "FSharp.Compiler.Service.Tests\FSharp.Compiler.Service.Tests.fsproj", "{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A40507D6-FA48-43D3-B18A-AE3DAACE4020}.Release|Any CPU.Build.0 = Release|Any CPU
{067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Debug|Any CPU.Build.0 = Debug|Any CPU
{067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Release|Any CPU.ActiveCfg = Release|Any CPU
{067E95E5-E3DC-4CA7-813A-4D1E277D2D52}.Release|Any CPU.Build.0 = Release|Any CPU
{92793069-816F-4F69-84AC-0966F8275E65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92793069-816F-4F69-84AC-0966F8275E65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92793069-816F-4F69-84AC-0966F8275E65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92793069-816F-4F69-84AC-0966F8275E65}.Release|Any CPU.Build.0 = Release|Any CPU
{C816728D-BBEA-472D-9F6C-E8913957A673}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C816728D-BBEA-472D-9F6C-E8913957A673}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C816728D-BBEA-472D-9F6C-E8913957A673}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C816728D-BBEA-472D-9F6C-E8913957A673}.Release|Any CPU.Build.0 = Release|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.Build.0 = 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}.Release|Any CPU.ActiveCfg = Release|Any CPU
{887630A3-4B1D-40EA-B8B3-2D842E9C40DB}.Release|Any CPU.Build.0 = Release|Any CPU
{F9540CA8-1CE0-4546-A23A-A461E416E95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F9540CA8-1CE0-4546-A23A-A461E416E95B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F9540CA8-1CE0-4546-A23A-A461E416E95B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9540CA8-1CE0-4546-A23A-A461E416E95B}.Release|Any CPU.Build.0 = Release|Any CPU
{B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1BDD96D-47E1-4E65-8107-FBAE23A06DB4}.Release|Any CPU.Build.0 = Release|Any CPU
{893C3CD9-5AF8-4027-A667-21E62FC2C703}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{893C3CD9-5AF8-4027-A667-21E62FC2C703}.Debug|Any CPU.Build.0 = Debug|Any CPU
{893C3CD9-5AF8-4027-A667-21E62FC2C703}.Release|Any CPU.ActiveCfg = Release|Any CPU
{893C3CD9-5AF8-4027-A667-21E62FC2C703}.Release|Any CPU.Build.0 = Release|Any CPU
{8157B50E-397D-4232-A4E0-1977AFC7076D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8157B50E-397D-4232-A4E0-1977AFC7076D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8157B50E-397D-4232-A4E0-1977AFC7076D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8157B50E-397D-4232-A4E0-1977AFC7076D}.Release|Any CPU.Build.0 = Release|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0554567F-1DCB-46A5-9EF2-E1938A3D4F14} = {83FEE492-6701-4E59-9184-16B1D30E91F8}
{A40507D6-FA48-43D3-B18A-AE3DAACE4020} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1}
{067E95E5-E3DC-4CA7-813A-4D1E277D2D52} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1}
{92793069-816F-4F69-84AC-0966F8275E65} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1}
{C816728D-BBEA-472D-9F6C-E8913957A673} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1}
{C94C257C-3C0A-4858-B5D8-D746498D1F08} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1}
{F9540CA8-1CE0-4546-A23A-A461E416E95B} = {E396742E-B4E5-4584-A9E4-CC1A491F5BC1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9E9BAC7B-3834-497C-B7AC-6B7988778D1A}
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<FSharpSourcesRoot>$(MSBuildProjectDirectory)\..\..\src</FSharpSourcesRoot>
</PropertyGroup>
<Import Project="$(FSharpSourcesRoot)\FSharpSource.Settings.targets" />
<Import Project="..\fcs.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
......@@ -14,21 +15,39 @@
<NoWarn>$(NoWarn);44;62;9</NoWarn>
<ProjectGuid>{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}</ProjectGuid>
<AllowCrossTargeting>true</AllowCrossTargeting>
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<BaseAddress>0x06800000</BaseAddress>
<Tailcalls>true</Tailcalls>
<NoWarn>$(NoWarn);69;65;54;61;75</NoWarn>
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\$(Configuration)\fcs\net45\</OutputPath>
<DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile>
<!-- We target .NET 4.5 for FSharp.Compiler.Service.dll to allow broader use of this DLL -->
<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<DefineConstants>$(DefineConstants);EXTENSIONTYPING</DefineConstants>
<DefineConstants>$(DefineConstants);CROSS_PLATFORM_COMPILER</DefineConstants>
<DefineConstants>$(DefineConstants);ENABLE_MONO_SUPPORT</DefineConstants>
<DefineConstants>$(DefineConstants);COMPILER</DefineConstants>
<DefineConstants>$(DefineConstants);COMPILER_SERVICE_AS_DLL</DefineConstants>
<DefineConstants>$(DefineConstants);COMPILER_PUBLIC_API</DefineConstants>
<DefineConstants>$(DefineConstants);NO_STRONG_NAMES</DefineConstants>
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>
<TargetFrameworkProfile />
<OtherFlags>$(OtherFlags) /warnon:1182</OtherFlags>
<OtherFlags>$(OtherFlags) --times</OtherFlags>
<OtherFlags>$(OtherFlags) --version:$(VersionPrefix).0</OtherFlags>
<ResolveNuGetPackages>false</ResolveNuGetPackages>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(FSharpSourcesRoot)\assemblyinfo\assemblyinfo.FSharp.Compiler.Service.dll.fs">
......@@ -598,29 +617,29 @@
<Reference Include="System.Numerics" />
<Reference Include="ISymWrapper, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Microsoft.DiaSymReader.PortablePdb">
<HintPath>$(FSharpSourcesRoot)\..\..\packages\Microsoft.DiaSymReader.PortablePdb.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll</HintPath>
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.PortablePdb.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.PortablePdb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.DiaSymReader">
<HintPath>$(FSharpSourcesRoot)\..\..\packages\Microsoft.DiaSymReader.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.dll</HintPath>
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.DiaSymReader.1.1.0\lib\portable-net45+win8\Microsoft.DiaSymReader.dll</HintPath>
</Reference>
<Reference Include="System.Reflection.Metadata">
<HintPath>$(FSharpSourcesRoot)\..\..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
<HintPath>$(FSharpSourcesRoot)\..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable">
<HintPath>$(FSharpSourcesRoot)\..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<HintPath>$(FSharpSourcesRoot)\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple">
<HintPath>$(FSharpSourcesRoot)\..\..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
<Private>true</Private>
<HintPath>$(FSharpSourcesRoot)\..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
<Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
<Name>FSharp.Core</Name>
</ProjectReference>
<!-- we build the nuget against FSHarp.Core 4.4.0.0 instead of our latest to allow use in wider range of F# tools -->
<Reference Include="FSharp.Core">
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.Portable.FSharp.Core.4.1.20\lib\profiles\net40\FSharp.Core.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
<Import Project="$(FsLexToolPath)\FsLexYacc.targets" />
<Import Project="$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools\Microsoft.FSharp.Targets" />
<Import Project="$(FSharpSourcesRoot)\scripts\fssrgen.targets" />
<Import Project="$(FSharpSourcesRoot)\..\packages\FsLexYacc.7.0.6\build\FsLexYacc.targets" />
</Project>
\ No newline at end of file
# The FSharp.Compiler.Service components and nuget package
This directory contains the build, packaging, test and documentation-generation logic for the nuget package ``FSharp.Compiler.Service``. The source for this nuget
package is in ``..\src``.
Basically we are packaging up the compiler as a DLL and publishing it as a nuget package.
## FSharp.Compiler.Service v. FSharp.Compiler.Private
There are subtle differences between FSharp.Compiler.Service and FSharp.Compiler.Private (shipped with the Visual F# Tools)
- FCS has a public API
- FCS is built against **.NET 4.5** and **FSharp.Core 4.0.0.0** to give broader reach
- FCS has a Nuget package
- FCS has a .NET Standard 1.6 version in the nuget package
- FCS testing also tests the "Project Cracker" (see below)
- FCS doesn't add the System.ValueTuple.dll reference by default, see ``#if COMPILER_SERVICE_AS_DLL`` in compiler codebase
## Version Numbers
FCS uses its own version number sequence for assemblies and packages, approximately following SemVer rules.
To update the version number a global replace through fcs\... is currently needed, e.g.
fcs.props
nuget/FSharp.Compiler.Service.nuspec
nuget/FSharp.Compiler.Service.MSBuild.v12.nuspec
nuget/FSharp.Compiler.Service.ProjectCracker.nuspec
RELEASE_NOTES.md
## Building, Testing, Packaging, Releases
To build the package use any of:
cd fcs
build Build.NetFx
build Test.NetFx
build NuGet.NetFx
build Build.NetStd
build Test.NetStd
build NuGet.NetStd
build Build
build Test
build NuGet
build Release
which does things like:
.paket\paket.bootstrapper.exe
.paket\paket.exe restore
packages\FAKE\tools\FAKE.exe build.fsx WhateverTarget
### Manual push of packages
Yu can push the packages if you have permissions, either automatically using ``build Release`` or manually
cd fcs
set APIKEY=...
..\.nuget\nuget.exe push ..\Release\FSharp.Compiler.Service.14.0.1.nupkg %APIKEY% -Source https://nuget.org -Timeout 500
..\.nuget\nuget.exe push ..\Release\FSharp.Compiler.Service.MSBuild.v12.14.0.1.nupkg %APIKEY% -Source https://nuget.org -Timeout 500
..\.nuget\nuget.exe push ..\Release\FSharp.Compiler.Service.ProjectCracker.14.0.1.nupkg %APIKEY% -Source https://nuget.org -Timeout 500
### Use of Paket and FAKE
Paket is only used to get fake and formating tools. Eventually we will likely remove this once we update the project files to .NET SDK 2.0.
FAKE is only used to run build.fsx. Eventually we will likely remove this once we update the project files to .NET SDK 2.0.
### Testing
Testing reuses the test files from ..\tests\service which were are also FCS tests.
### Documentation Generation
build GenerateDocs
Output is in ``docs``. In the ``FSharp.Compiler.Service`` repo this is checked in and hosted as http://fsharp.github.io/FSharp.Compiler.Service.
## The two other nuget packages
It also contains both the source, build, packaging and test logic for
* ``FSharp.Compiler.Service.MSBuild.v12`` adds legacy MSBuild v12 support to an instance of FSharp.Compiler.Service, if exact compatibility for scripting references such as ``#r "Foo, Version=1.3.4"`` is required.
* ``FSharp.Compiler.Service.ProjectCracker`` is part of ``FsAutoComplete`` and Ionide and is used to crack old-style project formats using MSBuild. It used to be part of the FCS API.
Both of these components are gradually becoming obsolete
## Engineering road map
FSharp.Compiler.Service is a somewhat awkward component. There are some things we can do to simplify things:
1. Remove the use of Paket and FAKE
1. Move all projects under fcs\... to new .NET SDK project file format
1. Drop the use of ``dotnet mergenupkg`` since we should be able to use cross targeting
1. Make FCS a DLL similar ot the rest of the build and make this an official component from Microsoft (signed etc.)
1. Replace FSharp.Compiler.Private by FSharp.Compiler.Service
此差异已折叠。
@echo off
.paket\paket.bootstrapper.exe
if errorlevel 1 (
exit /b %errorlevel%
)
.paket\paket.exe restore
if errorlevel 1 (
exit /b %errorlevel%
)
packages\FAKE\tools\FAKE.exe build.fsx %*
// --------------------------------------------------------------------------------------
// FAKE build script
// --------------------------------------------------------------------------------------
#I "packages/FAKE/tools"
#r "packages/FAKE/tools/FakeLib.dll"
open System
open Fake.AppVeyor
open Fake
open Fake.Git
open Fake.ReleaseNotesHelper
open Fake.UserInputHelper
#if MONO
// prevent incorrect output encoding (e.g. https://github.com/fsharp/FAKE/issues/1196)
System.Console.OutputEncoding <- System.Text.Encoding.UTF8
#endif
// --------------------------------------------------------------------------------------
// Utilities
// --------------------------------------------------------------------------------------
let assertExitCodeZero x = if x = 0 then () else failwithf "Command failed with exit code %i" x
let runCmdIn mono workDir exe = Printf.ksprintf (fun args ->
if mono then
printfn "mono %s/%s %s" workDir exe args
Shell.Exec("mono", sprintf "%s %s" exe args, workDir)
|> assertExitCodeZero
else
printfn "%s/%s %s" workDir exe args
Shell.Exec(exe, args, workDir)
|> assertExitCodeZero
)
let run mono exe = runCmdIn mono "." exe
// --------------------------------------------------------------------------------------
// Information about the project to be used at NuGet
// --------------------------------------------------------------------------------------
let project = "FSharp.Compiler.Service"
let authors = ["Microsoft Corporation, Dave Thomas, Anh-Dung Phan, Tomas Petricek"]
let gitOwner = "fsharp"
let gitHome = "https://github.com/" + gitOwner
let gitName = "FSharp.Compiler.Service"
let gitRaw = environVarOrDefault "gitRaw" "https://raw.githubusercontent.com/fsharp"
let netFrameworks = [(* "v4.0"; *) "v4.5"]
// --------------------------------------------------------------------------------------
// The rest of the code is standard F# build script
// --------------------------------------------------------------------------------------
let releaseDir = "../Release"
// Read release notes & version info from RELEASE_NOTES.md
let release = LoadReleaseNotes (__SOURCE_DIRECTORY__ + "/RELEASE_NOTES.md")
let isAppVeyorBuild = buildServer = BuildServer.AppVeyor
let isVersionTag tag = Version.TryParse tag |> fst
let hasRepoVersionTag = isAppVeyorBuild && AppVeyorEnvironment.RepoTag && isVersionTag AppVeyorEnvironment.RepoTagName
let assemblyVersion = if hasRepoVersionTag then AppVeyorEnvironment.RepoTagName else release.NugetVersion
let nugetVersion = release.NugetVersion
open SemVerHelper
let nugetDebugVersion =
let semVer = SemVerHelper.parse nugetVersion
let debugPatch, debugPreRelease =
match semVer.PreRelease with
| None -> semVer.Patch + 1, { Origin = "alpha001"; Name = "alpha"; Number = Some 1; Parts = [AlphaNumeric "alpha001"] }
| Some pre ->
let num = match pre.Number with Some i -> i + 1 | None -> 1
let name = pre.Name
let newOrigin = sprintf "%s%03d" name num
semVer.Patch, { Origin = newOrigin; Name = name; Number = Some num; Parts = [AlphaNumeric newOrigin] }
let debugVer =
{ semVer with
Patch = debugPatch
PreRelease = Some debugPreRelease }
debugVer.ToString()
let buildDate = DateTime.UtcNow
let buildVersion =
if hasRepoVersionTag then assemblyVersion
else if isAppVeyorBuild then sprintf "%s-b%s" assemblyVersion AppVeyorEnvironment.BuildNumber
else assemblyVersion
let netstdsln = gitName + ".netstandard.sln";
Target "BuildVersion" (fun _ ->
Shell.Exec("appveyor", sprintf "UpdateBuild -Version \"%s\"" buildVersion) |> ignore
)
// --------------------------------------------------------------------------------------
// Clean build results & restore NuGet packages
Target "Build.NetFx" (fun _ ->
!! (project + ".sln")
|> MSBuild "" "Build" ["Configuration","Release" ]
|> Log (".NETFxBuild-Output: ")
)
// --------------------------------------------------------------------------------------
// Run the unit tests using test runner
Target "Test.NetFx" (fun _ ->
!! (releaseDir + "/fcs/net45/FSharp.Compiler.Service.Tests.dll")
|> Fake.Testing.NUnit3.NUnit3 (fun p ->
{ p with
ToolPath = @"..\packages\NUnit.Console.3.0.0\tools\nunit3-console.exe"
ShadowCopy = false
TimeOut = TimeSpan.FromMinutes 20. })
)
// --------------------------------------------------------------------------------------
// Build a NuGet package
Target "NuGet.NetFx" (fun _ ->
run false @"..\.nuget\nuget.exe" @"pack nuget\FSharp.Compiler.Service.nuspec -OutputDirectory %s" releaseDir
run false @"..\.nuget\nuget.exe" @"pack nuget\FSharp.Compiler.Service.MSBuild.v12.nuspec -OutputDirectory %s" releaseDir
run false @"..\.nuget\nuget.exe" @"pack nuget\FSharp.Compiler.Service.ProjectCracker.nuspec -OutputDirectory %s" releaseDir
)
// --------------------------------------------------------------------------------------
// .NET Core and .NET Core SDK
let isDotnetSDKInstalled =
match Fake.EnvironmentHelper.environVarOrNone "FCS_DNC" with
| Some flag ->
match bool.TryParse flag with
| true, result -> result
| _ -> false
| None ->
try
Shell.Exec("dotnet", "--info") = 0
with
_ -> false
Target "Build.NetStd" (fun _ ->
run false "dotnet" "pack %s -v n -c Release" netstdsln
)
Target "Test.NetStd" (fun _ ->
run false "dotnet" "run -p FSharp.Compiler.Service.Tests.netcore/FSharp.Compiler.Service.Tests.netcore.fsproj -c Release -- --result:TestResults.NetStd.xml;format=nunit3"
)
//use dotnet-mergenupkg to merge the .NETstandard nuget package into the default one
Target "Nuget.AddNetStd" (fun _ ->
do
let nupkg = sprintf "%s/FSharp.Compiler.Service.%s.nupkg" releaseDir release.AssemblyVersion
let netcoreNupkg = sprintf "FSharp.Compiler.Service.netstandard/bin/Release/FSharp.Compiler.Service.%s.nupkg" release.AssemblyVersion
runCmdIn false "." "dotnet" "mergenupkg --source %s --other %s --framework netstandard1.6" nupkg netcoreNupkg
)
// --------------------------------------------------------------------------------------
// Generate the documentation
Target "GenerateDocs" (fun _ ->
executeFSIWithArgs "docsrc/tools" "generate.fsx" ["--define:RELEASE"] [] |> ignore
)
Target "GenerateDocsJa" (fun _ ->
executeFSIWithArgs "docsrc/tools" "generate.ja.fsx" ["--define:RELEASE"] [] |> ignore
)
// --------------------------------------------------------------------------------------
// Release Scripts
Target "PublishNuGet" (fun _ ->
Paket.Push (fun p ->
let apikey =
match getBuildParam "nuget-apikey" with
| s when not (String.IsNullOrWhiteSpace s) -> s
| _ -> getUserInput "Nuget API Key: "
{ p with
ApiKey = apikey
WorkingDir = releaseDir })
)
// --------------------------------------------------------------------------------------
// Run all targets by default. Invoke 'build <Target>' to override
Target "Clean" DoNothing
Target "CleanDocs" DoNothing
Target "Release" DoNothing
Target "NuGet" DoNothing
Target "Build" DoNothing
"Clean"
=?> ("BuildVersion", isAppVeyorBuild)
==> "Build.NetStd"
"Clean"
=?> ("BuildVersion", isAppVeyorBuild)
==> "Build.NetFx"
"Build.NetFx"
==> "Test.NetFx"
"Build.NetStd"
==> "Test.NetStd"
"Build.NetFx"
=?> ("Build.NetStd", isDotnetSDKInstalled)
==> "Build"
"Build.NetStd"
=?> ("Nuget.AddNetStd", isDotnetSDKInstalled)
"Build.NetFx"
==> "NuGet.NetFx"
=?> ("Nuget.AddNetStd", isDotnetSDKInstalled)
==> "NuGet"
"Build"
==> "NuGet"
==> "PublishNuGet"
==> "Release"
"CleanDocs"
==> "GenerateDocs"
==> "GenerateDocsJa"
==> "Release"
RunTargetOrDefault "Build"
#!/bin/bash
if test "$OS" = "Windows_NT"
then
# use .Net
.paket/paket.bootstrapper.exe
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
.paket/paket.exe restore
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
packages/FAKE/tools/FAKE.exe build.fsx $@
else
# use mono
if [[ ! -e ~/.config/.mono/certs ]]; then
mozroots --import --sync --quiet
fi
mono .paket/paket.bootstrapper.exe
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
mono .paket/paket.exe restore
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
mono packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
fi
\ No newline at end of file
(*** hide ***)
#I "../../bin/v4.5/"
(**
Compiler Services: Notes on the FSharpChecker caches
=================================================
This is a design note on the FSharpChecker component and its caches. See also the notes on the [FSharpChecker operations queue](queue.html)
Each FSharpChecker object maintains a set of caches. These are
* ``scriptClosureCache`` - an MRU cache of default size ``projectCacheSize`` that caches the
computation of GetProjectOptionsFromScript. This computation can be lengthy as it can involve processing the transative closure
of all ``#load`` directives, which in turn can mean parsing an unbounded number of script files
* ``incrementalBuildersCache`` - an MRU cache of projects where a handle is being kept to their incremental checking state,
of default size ``projectCacheSize`` (= 3 unless explicitly set as a parameter).
The "current background project" (see the [FSharpChecker operations queue](queue.html))
will be one of these projects. When analyzing large collections of projects, this cache usually occupies by far the most memory.
Increasing the size of this cache can dramatically decrease incremental computation of project-wide checking, or of checking
individual files within a project, but can very greatly increase memory usage.
* ``braceMatchCache`` - an MRU cache of size ``braceMatchCacheSize`` (default = 5) keeping the results of calls to MatchBraces, keyed by filename, source and project options.
* ``parseFileInProjectCache`` - an MRU cache of size ``parseFileInProjectCacheSize`` (default = 2) keeping the results of ParseFileInProject,
keyed by filename, source and project options.
* ``parseAndCheckFileInProjectCache`` - an MRU cache of size ``incrementalTypeCheckCacheSize`` (default = 5) keeping the results of
ParseAndCheckFileInProject, CheckFileInProject and/or CheckFileInProjectIfReady. This is keyed by filename, file source
and project options. The results held in this cache are only returned if they would reflect an accurate parse and check of the
file.
* ``parseAndCheckFileInProjectCachePossiblyStale`` - a somewhat peculiar MRU cache of size ``incrementalTypeCheckCacheSize`` (default = 5)
keeping the results of ParseAndCheckFileInProject, CheckFileInProject and CheckFileInProjectIfReady,
keyed by filename and project options. This cache is accessed by TryGetRecentTypeCheckResultsForFile. Because the results
are accessed regardless of the content of the file, the checking results returned may be "stale".
* ``getToolTipTextCache`` - an aged lookup cache of strong size ``getToolTipTextSize`` (default = 5) computing the results of GetToolTipText.
* ``ilModuleReaderCache`` - an aged lookup of weak references to "readers" for references .NET binaries. Because these
are all weak references, you can generally ignore this cache, since its entries will be automatically collected.
Strong references to binary readers will be kept by other FCS data structures, e.g. any project checkers, symbols or project checking results.
In more detail, the bytes for referenced .NET binaries are read into memory all at once, eagerly. Files are not left
open or memory-mapped when using FSharpChecker (as opposed to FsiEvaluationSession, which loads assemblies using reflection).
The purpose of this cache is mainly to ensure that while setting up compilation, the reads of mscorlib, FSharp.Core and so on
amortize cracking the DLLs.
* ``frameworkTcImportsCache`` - an aged lookup of strong size 8 which caches the process of setting up type checking against a set of system
components (e.g. a particular version of mscorlib, FSharp.Core and other system DLLs). These resources are automatically shared between multiple
project checkers which happen to reference the same set of system assemblies.
Profiling the memory used by the various caches can be done by looking for the corresponding static roots in memory profiling traces.
The sizes of some of these caches can be adjusted by giving parameters to FSharpChecker. Unless otherwise noted,
the cache sizes above indicate the "strong" size of the cache, where memory is held regardless of the memory
pressure on the system. Some of the caches can also hold "weak" references which can be collected at will by the GC.
> Note: Because of these caches, uou should generally use one global, shared FSharpChecker for everything in an IDE application.
Low-Memory Condition
-------
Version 1.4.0.8 added a "maximum memory" limit specified by the `MaxMemory` property on FSharpChecker (in MB). If an FCS project operation
is performed (see `CheckMaxMemoryReached` in `service.fs`) and `System.GC.GetTotalMemory(false)` reports a figure greater than this, then
the strong sizes of all FCS caches are reduced to either 0 or 1. This happens for the remainder of the lifetime of the FSharpChecker object.
In practice this will still make tools like the Visual Studio F# Power Tools usable, but some operations like renaming across multiple
projects may take substantially longer.
By default the maximum memory trigger is disabled, see `maxMBDefault` in `service.fs`.
Reducing the FCS strong cache sizes does not guarantee there will be enough memory to continue operations - even holding one project
strongly may exceed a process memory budget. It just means FCS may hold less memory strongly.
If you do not want the maximum memory limit to apply then set MaxMemory to System.Int32.MaxValue.
Summary
-------
In this design note, you learned that the FSharpChecker component keeps a set of caches in order to support common
incremental analysis scenarios reasonably efficiently. They correspond roughly to the original caches and sizes
used by the Visual F# Tools, from which the FSharpChecker component derives.
In long running, highly interactive, multi-project scenarios you should carefully
consider the cache sizes you are using and the tradeoffs involved between incremental multi-project checking and memory usage.
*)
(*** hide ***)
#I "../../bin/v4.5/"
(**
Hosted Compiler
===============
This tutorial demonstrates how to host the F# compiler.
> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published
*)
(**
> **NOTE:** There are several options for hosting the F# compiler. The easiest one is to use the
`fsc.exe` process and pass arguments.
*)
(**
> **NOTE:** By default [compilations using FSharp.Compiler.Service reference FSharp.Core 4.3.0.0](https://github.com/fsharp/FSharp.Compiler.Service/issues/156) (matching F# 3.0). You can override
this choice by passing a reference to FSharp.Core for 4.3.1.0 or later explicitly in your command-line arguments.
*)
(**
---------------------------
First, we need to reference the libraries that contain F# interactive service:
*)
#r "FSharp.Compiler.Service.dll"
open System.IO
open Microsoft.FSharp.Compiler.SourceCodeServices
// Create an interactive checker instance
let checker = FSharpChecker.Create()
(**
Now write content to a temporary file:
*)
let fn = Path.GetTempFileName()
let fn2 = Path.ChangeExtension(fn, ".fsx")
let fn3 = Path.ChangeExtension(fn, ".dll")
File.WriteAllText(fn2, """
module M
type C() =
member x.P = 1
let x = 3 + 4
""")
(**
Now invoke the compiler:
*)
let errors1, exitCode1 = checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
(**
If errors occur you can see this in the 'exitCode' and the returned array of errors:
*)
File.WriteAllText(fn2, """
module M
let x = 1.0 + "" // a type error
""")
let errors1b, exitCode1b = checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
(**
Compiling to a dynamic assembly
===============================
You can also compile to a dynamic assembly, which uses the F# Interactive code generator.
This can be useful if you are, for example, in a situation where writing to the file system
is not really an option.
You still have to pass the "-o" option to name the output file, but the output file is not actually written to disk.
The 'None' option indicates that the initiatlization code for the assembly is not executed.
*)
let errors2, exitCode2, dynAssembly2 =
checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None)
(*
Passing 'Some' for the 'execute' parameter executes the initiatlization code for the assembly.
*)
let errors3, exitCode3, dynAssembly3 =
checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr))
(*** hide ***)
#I "../../bin/v4.5/"
(**
Compiler Services: Notes on FSharp.Core.dll
=================================================
Shipping an FSharp.Core with your application
---------------------------------------------
When building applications or plug-in components which use FSharp.Compiler.Service.dll, you will normally also
include a copy of FSharp.Core.dll as part of your application.
For example, if you build a ``HostedCompiler.exe``, you will normally place an FSharp.Core.dll (say 4.3.1.0) alongside
your ``HostedCompiler.exe``.
If doing dynamic compilation and execution you may also need to include
an FSharp.Core.optdata and FSharp.Core.sigdata, see below for guidance.
Binding redirects for your application
--------------------------------------
The FSharp.Compiler.Service.dll component depends on FSharp.Core 4.3.0.0. Normally your application will target
a later version of FSharp.Core, and you will need a [binding redirect](http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.110).aspx) to ensure
that FSharp.Core 4.3.0.0 forwards to which the final version of FSharp.Core.dll your application uses.
Binding redirect files are normally generated automatically by build tools. If not, you can use one like this
(if your tool is called ``HostedCompiler.exe``, the binding redirect file is called ``HostedCompiler.exe.config``)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="2.0.0.0-4.3.0.0" newVersion="4.3.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Which FSharp.Core and .NET Framework gets referenced in compilation?
--------------------------------------
The FSharp.Compiler.Service component can be used to do more or less any sort of F# compilation.
In particular you can reference an explicit FSharp.Core and/or framework
assemblies in the command line arguments (different to the FSharp.Core and a .NET Framework being used to run your tool).
To target a specific FSharp.Core and/or .NET Framework assemblies, use the ``--noframework`` argument
and the appropriate command-line arguments:
[<Literal>]
let fsharpCorePath =
@"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0\FSharp.Core.dll"
let errors2, exitCode2 =
scs.Compile(
[| "fsc.exe"; "--noframework";
"-r"; fsharpCorePath;
"-r"; @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll";
"-o"; fn3;
"-a"; fn2 |])
You will need to determine the location of these assemblies. The easiest way to locate these DLLs in a cross-platform way and
convert them to command-line arguments is to [crack an F# project file](http://fsharp.github.io/FSharp.Compiler.Service/project.html).
Alternatively you can compute SDK paths yourself, and some helpers to do this are in [the tests for FSharp.Compiler.Service.dll](https://github.com/fsharp/FSharp.Compiler.Service/blob/8a943dd3b545648690cb3bed652a469bdb6dd869/tests/service/Common.fs#L54).
What about if I am processing a script or using ``GetCheckOptionsFromScriptRoot``
-------------------------------------------------------------------------
If you do _not_ explicitly reference an FSharp.Core.dll from an SDK location, or if you are processing a script
using ``FsiEvaluationSession`` or ``GetCheckOptionsFromScriptRoot``, then an implicit reference to FSharp.Core will be made
by the following choice:
1. The version of FSharp.Core.dll statically referenced by the host assembly returned by ``System.Reflection.Assembly.GetEntryAssembly()``.
2. If there is no static reference to FSharp.Core in the host assembly, then
- For FSharp.Compiler.Service 0.x series, a reference to FSharp.Core version 4.3.0.0 is added
- For FSharp.Compiler.Service 1.3.1.x (F# 3.1 series), a reference to FSharp.Core version 4.3.1.0 is added
- For FSharp.Compiler.Service 1.4.0.x (F# 4.0 series), a reference to FSharp.Core version 4.4.0.0 is added
Do I need to include FSharp.Core.optdata and FSharp.Core.sigdata?
--------------------------------------
If your compilation arguments explicitly reference an FSharp.Core.dll from an SDK location, then FSharp.Core.sigdata and FSharp.Core.optdata should be alongside the DLL
(if these files are not installed, then that's a bug in the F# SDK installation). If your compilation
arguments are always making an explicit reference, then you should _not_ include FSharp.Core.optdata and FSharp.Core.sigdata as part of your application.
If you are relying on an implicit reference (e.g. for script processing, see above), this means your tool may reference the FSharp.Core.dll
that is part of your application. In this case, you may either get an error that FSharp.Core.optdata and FSharp.Core.sigdata are not
found alongside FSharp.Core.dll. **If you want to implicitly reference the FSharp.Core.dll you are including in your application,
then also add FSharp.Core.sigdata and FSharp.Core.optdata as two additional files to your application**. When using ``CompileToDynamicAssembly``, this problem
can also manifest itself as [a stack overflow during assembly resolution](https://github.com/fsharp/FSharp.Compiler.Service/issues/258).
Tools that dynamically compile and execute code (e.g. a ``HostedExecution.exe``) often make an implicit
reference to FSharp.Core.dll, which means they normally also include FSharp.Core.optdata and FSharp.Core.sigdata.
Summary
-------
In this design note we have discussed three things:
- which FSharp.Core.dll is used to run your compilation tools
- how to configure binding redirects for the FSharp.Core.dll used to run your compilation tools
- which FSharp.Core.dll and/or framework assemblies are referenced during the checking and compilations performed by your tools.
*)
Developer notes
===============
Modified clone of F# compiler exposing additional functionality for editing clients and embedding F# compiler
and F# interactive as services.
## Components
There is one main component, `FSharp.Compiler.Service.dll`.
The main aim is to have a stable and documented fork of the main compiler that allows various
tools to share this common code.
This component allows embedding F# Interactive as a service and contains a number of
modifications to the source code of `fsi.exe` that adds `EvalExpression` and `EvalInteraction` functions.
This repo should be _identical_ to 'fsharp' except:
- Changes for building `FSharp.Compiler.Service.dll`, notably
- Change the assembly name
- Only build `FSharp.Compiler.Service.dll`
- No bootstrap or proto compiler is used - an installed F# compiler is assumed
- Build script using FAKE that builds everything, produces NuGet package and
generates documentation, files for publising NuGet packages etc.
(following [F# project scaffold](https://github.com/fsprojects/FSharp.ProjectScaffold))
- Changes to compiler source code to expose new functionality; Changes to the
F# Interactive service to implement the evaluation functions.
- Additions to compiler source code which improve the API for the use of F# editing clients
- Additions to compiler source code which add new functionality to the compiler service API
If language or compiler addiitons are committed to `fsharp/fsharp`, they should be merged into
this repo and a new NuGet package released.
## Building and NuGet
The build process follows the standard recommended by [F# project scaffold](https://github.com/fsprojects/FSharp.ProjectScaffold)
If you want to build the project yourself then you can follow these instructions:
[lang=text]
git clone https://github.com/fsharp/FSharp.Compiler.Service
cd FSharp.Compiler.Service
Now follow build everything by running `build.cmd` (Windows) or `build.sh` (Linux + Mac OS).
The output will be located in the `bin` directory. If you also wish to build the documentation
and NuGet package, run `build Release` (this also attempts to publish the documentation to
GitHub, which only works if you have access to the GitHub repository).
## Release checklist
Release checklist to publish a new version on nuget.org
1. Update `RELEASE_NOTES.md`
2. Check the version numbers are correct across the source (some files duplicate them)
3. Commit and add the necessary tag to the repo
4. Publish the nupkgs for `FSharp.Compiler.Service` and `FSharp.Compiler.Service.ProjectCracker` once they appear in AppVeyor artifacts
(*** hide ***)
#I "../../bin/v4.5/"
(**
Compiler Services: Editor services
==================================
This tutorial demonstrates how to use the editor services provided by the F# compiler.
This API is used to provide auto-complete, tool-tips, parameter info help, matching of
brackets and other functions in F# editors including Visual Studio, Xamarin Studio and Emacs
(see [fsharpbindings](https://github.com/fsharp/fsharpbinding) project for more information).
Similarly to [the tutorial on using untyped AST](untypedtree.html), we start by
getting the `InteractiveChecker` object.
> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published
Type checking sample source code
--------------------------------
As in the [previous tutorial (using untyped AST)](untypedtree.html), we start by referencing
`FSharp.Compiler.Service.dll`, opening the relevant namespace and creating an instance
of `InteractiveChecker`:
*)
// Reference F# compiler API
#r "FSharp.Compiler.Service.dll"
open System
open Microsoft.FSharp.Compiler.SourceCodeServices
// Create an interactive checker instance
let checker = FSharpChecker.Create()
(**
As [previously](untypedtree.html), we use `GetProjectOptionsFromScriptRoot` to get a context
where the specified input is the only file passed to the compiler (and it is treated as a
script file or stand-alone F# source code).
*)
// Sample input as a multi-line string
let input =
"""
open System
let foo() =
let msg = String.Concat("Hello"," ","world")
if true then
printfn "%s" msg.
"""
// Split the input & define file name
let inputLines = input.Split('\n')
let file = "/home/user/Test.fsx"
let projOptions =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
(**
To perform type checking, we first need to parse the input using
`ParseFileInProject`, which gives us access to the [untyped AST](untypedtree.html). However,
then we need to call `CheckFileInProject` to perform the full type checking. This function
also requires the result of `ParseFileInProject`, so the two functions are often called
together.
*)
// Perform parsing
let parseFileResults =
checker.ParseFileInProject(file, input, projOptions)
|> Async.RunSynchronously
(**
Before we look at the interesting operations provided by `TypeCheckResults`, we
need to run the type checker on a sample input. On F# code with errors, you would get some type checking
result (but it may contain incorrectly "guessed" results).
*)
// Perform type checking
let checkFileAnswer =
checker.CheckFileInProject(parseFileResults, file, 0, input, projOptions)
|> Async.RunSynchronously
(**
Alternatively you can use `ParseAndCheckFileInProject` to check both in one step:
*)
let parseResults2, checkFileAnswer2 =
checker.ParseAndCheckFileInProject(file, 0, input, projOptions)
|> Async.RunSynchronously
(**
The function returns both the untyped parse result (which we do not use in this
tutorial), but also a `CheckFileAnswer` value, which gives us access to all
the interesting functionality...
*)
let checkFileResults =
match checkFileAnswer with
| FSharpCheckFileAnswer.Succeeded(res) -> res
| res -> failwithf "Parsing did not finish... (%A)" res
(**
Here, we type check a simple function that (conditionally) prints "Hello world".
On the last line, we leave an additional dot in `msg.` so that we can get the
completion list on the `msg` value (we expect to see various methods on the string
type there).
Using type checking results
---------------------------
Let's now look at some of the API that is exposed by the `TypeCheckResults` type. In general,
this is the type that lets you implement most of the interesting F# source code editor services.
### Getting a tool tip
To get a tool tip, you can use `GetToolTipTextAlternate` method. The method takes a line number and character
offset. Both of the numbers are zero-based. In the sample code, we want to get tooltip for the `foo`
function that is defined on line 3 (line 0 is blank) and the letter `f` starts at index 7 (the tooltip
would work anywhere inside the identifier).
In addition, the method takes a tag of token which is typically `IDENT`, when getting tooltip for an
identifier (the other option lets you get tooltip with full assembly location when using `#r "..."`).
*)
// Get tag of the IDENT token to be used as the last argument
open Microsoft.FSharp.Compiler
let identToken = FSharpTokenTag.Identifier
// Get tool tip at the specified location
let tip = checkFileResults.GetToolTipTextAlternate(4, 7, inputLines.[1], ["foo"], identToken)
printfn "%A" tip
(**
> **NOTE:** `GetToolTipTextAlternate` is an alternative name for the old `GetToolTipText`. The old `GetToolTipText` was
deprecated because it accepted zero-based line numbers. At some point it will be removed, and `GetToolTipTextAlternate` will be renamed back to `GetToolTipText`.
*)
(**
Aside from the location and token kind, the function also requires the current contents of the line
(useful when the source code changes) and a `Names` value, which is a list of strings representing
the current long name. For example to get tooltip for the `Random` identifier in a long name
`System.Random`, you would use location somewhere in the string `Random` and you would pass
`["System"; "Random"]` as the `Names` value.
The returned value is of type `ToolTipText` which contains a discriminated union `ToolTipElement`.
The union represents different kinds of tool tips that you can get from the compiler.
### Getting auto-complete lists
The next method exposed by `TypeCheckResults` lets us perform auto-complete on a given location.
This can be called on any identifier or in any scope (in which case you get a list of names visible
in the scope) or immediately after `.` to get a list of members of some object. Here, we get a
list of members of the string value `msg`.
To do this, we call `GetDeclarationListInfo` with the location of the `.` symbol on the last line
(ending with `printfn "%s" msg.`). The offsets are one-based, so the location is `7, 23`.
We also need to specify a function that says that the text has not changed and the current identifer
where we need to perform the completion.
*)
// Get declarations (autocomplete) for a location
let decls =
checkFileResults.GetDeclarationListInfo
(Some parseFileResults, 7, 23, inputLines.[6], [], "msg", fun _ -> false)
|> Async.RunSynchronously
// Print the names of available items
for item in decls.Items do
printfn " - %s" item.Name
(**
> **NOTE:** `v` is an alternative name for the old `GetDeclarations`. The old `GetDeclarations` was
deprecated because it accepted zero-based line numbers. At some point it will be removed, and `GetDeclarationListInfo` will be renamed back to `GetDeclarations`.
*)
(**
When you run the code, you should get a list containing the usual string methods such as
`Substring`, `ToUpper`, `ToLower` etc. The fourth argument of `GetDeclarations`, here `([], "msg")`,
specifies the context for the auto-completion. Here, we want a completion on a complete name
`msg`, but you could for example use `(["System"; "Collections"], "Generic")` to get a completion list
for a fully qualified namespace.
### Getting parameter information
The next common feature of editors is to provide information about overloads of a method. In our
sample code, we use `String.Concat` which has a number of overloads. We can get the list using
`GetMethods` operation. As previously, this takes zero-indexed offset of the location that we are
interested in (here, right at the end of the `String.Concat` identifier) and we also need to provide
the identifier again (so that the compiler can provide up-to-date information when the source code
changes):
*)
// Get overloads of the String.Concat method
let methods =
checkFileResults.GetMethodsAlternate(5, 27, inputLines.[4], Some ["String"; "Concat"])
|> Async.RunSynchronously
// Print concatenated parameter lists
for mi in methods.Methods do
[ for p in mi.Parameters -> p.Display ]
|> String.concat ", "
|> printfn "%s(%s)" methods.MethodName
(**
The code uses the `Display` property to get the annotation for each parameter. This returns information
such as `arg0: obj` or `params args: obj[]` or `str0: string, str1: string`. We concatenate the parameters
and print a type annotation with the method name.
*)
(**
## Asynchronous and immediate operations
You may have noticed that `CheckFileInProject` is an asynchronous operation.
This indicates that type checking of F# code can take some time.
The F# compiler performs the work in background (automatically) and when
we call `CheckFileInProject` method, it returns an asynchronous operation.
There is also the `CheckFileInProjectIfReady` method. This returns immediately if the
type checking operation can't be started immediately, e.g. if other files in the project
are not yet type-checked. In this case, a background worker might choose to do other
work in the meantime, or give up on type checking the file until the `FileTypeCheckStateIsDirty` event
is raised.
> The [fsharpbinding](https://github.com/fsharp/fsharpbinding) project has more advanced
example of handling the background work where all requests are sent through an F# agent.
This may be a more appropriate for implementing editor support.
*)
(**
Summary
-------
The `CheckFileAnswer` object contains other useful methods that were not covered in this tutorial. You
can use it to get location of a declaration for a given identifier, additional colorization information
(the F# 3.1 colorizes computation builder identifiers & query operators) and others.
Using the FSharpChecker component in multi-project, incremental and interactive editing situations may involve
knowledge of the [FSharpChecker operations queue](queue.html) and the [FSharpChecker caches](caches.html).
Finally, if you are implementing an editor support for an editor that cannot directly call .NET API,
you can call many of the methods discussed here via a command line interface that is available in the
[FSharp.AutoComplete](https://github.com/fsharp/fsharpbinding/tree/master/FSharp.AutoComplete) project.
*)
(*** hide ***)
#I "../../bin/v4.5/"
(**
Compiler Services: Virtualized File System
==========================================
The `FSharp.Compiler.Service` component has a global variable
representing the file system. By setting this variable you can host the compiler in situations where a file system
is not available.
> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published.
Setting the FileSystem
----------------------
In the example below, we set the file system to an implementation which reads from disk
*)
#r "FSharp.Compiler.Service.dll"
open System
open System.IO
open System.Collections.Generic
open System.Text
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
let defaultFileSystem = Shim.FileSystem
let fileName1 = @"c:\mycode\test1.fs" // note, the path doesn't exist
let fileName2 = @"c:\mycode\test2.fs" // note, the path doesn't exist
type MyFileSystem() =
let file1 = """
module File1
let A = 1"""
let file2 = """
module File2
let B = File1.A + File1.A"""
let files = dict [(fileName1, file1); (fileName2, file2)]
interface IFileSystem with
// Implement the service to open files for reading and writing
member __.FileStreamReadShim(fileName) =
match files.TryGetValue(fileName) with
| true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream
| _ -> defaultFileSystem.FileStreamReadShim(fileName)
member __.FileStreamCreateShim(fileName) =
defaultFileSystem.FileStreamCreateShim(fileName)
member __.FileStreamWriteExistingShim(fileName) =
defaultFileSystem.FileStreamWriteExistingShim(fileName)
member __.ReadAllBytesShim(fileName) =
match files.TryGetValue(fileName) with
| true, text -> Encoding.UTF8.GetBytes(text)
| _ -> defaultFileSystem.ReadAllBytesShim(fileName)
// Implement the service related to temporary paths and file time stamps
member __.GetTempPathShim() =
defaultFileSystem.GetTempPathShim()
member __.GetLastWriteTimeShim(fileName) =
defaultFileSystem.GetLastWriteTimeShim(fileName)
member __.GetFullPathShim(fileName) =
defaultFileSystem.GetFullPathShim(fileName)
member __.IsInvalidPathShim(fileName) =
defaultFileSystem.IsInvalidPathShim(fileName)
member __.IsPathRootedShim(fileName) =
defaultFileSystem.IsPathRootedShim(fileName)
// Implement the service related to file existence and deletion
member __.SafeExists(fileName) =
files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName)
member __.FileDelete(fileName) =
defaultFileSystem.FileDelete(fileName)
// Implement the service related to assembly loading, used to load type providers
// and for F# interactive.
member __.AssemblyLoadFrom(fileName) =
defaultFileSystem.AssemblyLoadFrom fileName
member __.AssemblyLoad(assemblyName) =
defaultFileSystem.AssemblyLoad assemblyName
let myFileSystem = MyFileSystem()
Shim.FileSystem <- MyFileSystem()
(**
Doing a compilation with the FileSystem
---------------------------------------
*)
open Microsoft.FSharp.Compiler.SourceCodeServices
let checker = FSharpChecker.Create()
let projectOptions =
let sysLib nm =
if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows
System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) +
@"\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" + nm + ".dll"
else
let sysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
let (++) a b = System.IO.Path.Combine(a,b)
sysDir ++ nm + ".dll"
let fsCore4300() =
if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows
System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) +
@"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll"
else
sysLib "FSharp.Core"
let allFlags =
[| yield "--simpleresolution";
yield "--noframework";
yield "--debug:full";
yield "--define:DEBUG";
yield "--optimize-";
yield "--doc:test.xml";
yield "--warn:3";
yield "--fullpaths";
yield "--flaterrors";
yield "--target:library";
let references =
[ sysLib "mscorlib"
sysLib "System"
sysLib "System.Core"
fsCore4300() ]
for r in references do
yield "-r:" + r |]
{ ProjectFileName = @"c:\mycode\compilation.fsproj" // Make a name that is unique in this directory.
ProjectFileNames = [| fileName1; fileName2 |]
OtherOptions = allFlags
ReferencedProjects = [| |]
IsIncompleteTypeCheckEnvironment = false
UseScriptResolutionRules = true
LoadTime = System.DateTime.Now // Note using 'Now' forces reloading
UnresolvedReferences = None }
let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously
results.Errors
results.AssemblySignature.Entities.Count //2
results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count //1
results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "B"
(**
Summary
-------
In this tutorial, we've seen how to globally customize the view of the file system used by the FSharp.Compiler.Service
component.
At the time of writing, the following System.IO operations are not considered part of the virtualized file system API.
Future iterations on the compiler service implementation may add these to the API.
- Path.Combine
- Path.DirectorySeparatorChar
- Path.GetDirectoryName
- Path.GetFileName
- Path.GetFileNameWithoutExtension
- Path.HasExtension
- Path.GetRandomFileName (used only in generation compiled win32 resources in assemblies)
**NOTE:** Several operations in the `SourceCodeServices` API accept the contents of a file to parse
or check as a parameter, in addition to a file name. In these cases, the file name is only used for
error reporting.
**NOTE:** Type provider components do not use the virtualized file system.
**NOTE:** The compiler service may use MSBuild for assembly resolutions unless `--simpleresolution` is
provided. When using the `FileSystem` API you will normally want to specify `--simpleresolution` as one
of your compiler flags. Also specify `--noframework`. You will need to supply explicit resolutions of all
referenced .NET assemblies.
*)
\ No newline at end of file
F# Compiler README
=============================================================================================
> **NOTE:** This readme file is the original `README.md` document from the F# compiler
source code ([github.com/fsharp/fsharp](https://github.com/fsharp/fsharp)). This project is a fork of the F# compiler
source, with several minor changes that expose certain services. The readme is included
here for reference.
This is the F# compiler, core library and core tools (open source edition). It uses the Apache 2.0 license.
The `master` branch is for the latest version of F# (currently F# 3.0).
To bootstrap the compiler, binaries built from an earlier version of this project are used.
## Requirements
Requires mono 2.9 or higher. Prefer Mono 3.0.
On OSX, requires automake 2.69. To install from [homebrew](http://mxcl.github.com/homebrew):
[lang=text]
brew install automake
## Building
### On Linux and other Unix systems:
The usual:
[lang=text]
./autogen.sh
make
sudo make install
By default that makes optimized binaries. To make debug, use `make CONFIG=debug`
### On MacOS (OSX)
Use a prefix to your version of Mono:
[lang=text]
./autogen.sh --prefix=/Library/Frameworks/Mono.framework/Versions/Current/
make
sudo make install
By default that makes optimized binaries. To make debug, use `make CONFIG=debug`
### On Windows, using msbuild (e.g.. if .NET is installed)
If you have only VS2012 installed, and not VS2010, you'll need to install the F# 2.0 Runtime (http://www.microsoft.com/en-us/download/details.aspx?id=13450)
[lang=text]
cd src
msbuild fsharp-proto-build.proj
ngen install ..\lib\proto\4.0\fsc-proto.exe (optional)
msbuild fsharp-library-build.proj /p:Configuration=Release
msbuild fsharp-compiler-build.proj /p:Configuration=Release
You can also build the FSharp.Core for .NET 2.0, Mono 2.1, MonoTouch, Silverlight 5.0, Windows Phone 7.1, Portable Profile47 (net45+sl5+win8), Portable Profile88 (net4+sl4+wp71+win8) and XNA 4.0 for Xbox 360 profiles:
[lang=text]
msbuild fsharp-library-build.proj /p:TargetFramework=net20 /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=mono21 /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=monotouch /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=portable-net45+sl5+win8 /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=portable-net4+sl4+wp71+win8 /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=sl5 /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=wp7 /p:Configuration=Release
msbuild fsharp-library-build.proj /p:TargetFramework=net40-xna40-xbox360 /p:Configuration=Release
You can also build the FSharp.Core and FSharp.Compiler.Silverlight.dll for Silverlight 5.0:
[lang=text]
msbuild fsharp-library-build.proj /p:TargetFramework=sl5-compiler /p:Configuration=Release
msbuild fsharp-compiler-build.proj /p:TargetFramework=sl5-compiler /p:Configuration=Release
Change to ` /p:Configuration=Debug` for debug binaries.
### On Windows, using xbuild (e.g. if no .NET is installed and only Mono 3.0 is installed):
[lang=text]
cd src
xbuild fsharp-proto-build.proj
xbuild fsharp-library-build.proj
xbuild fsharp-compiler-build.proj
Building using xbuild does not yet lay down a Mono-ready distribution (see src/fsharp/targets.make), so should only
be used for private development rather than preparing distributions.
## Strong Names
The FSharp.Core.dll produced is only delay-signed (Mono does not require strong names).
If a strong-name signed FSharp.Core.dll is needed then use the one in
[lang=text]
lib\bootstrap\signed\3.0\v4.0\FSharp.Core.dll
## What you get
Once built the main compiler binaries go in
[lang=text]
lib/release/4.0
There are versions of FSharp.Core for .NET 2.0, MonoAndroid, MonoTouch (Mono profile 2.1) in
[lang=text]
lib/release/2.0
lib/release/2.1
lib/release/2.1monotouch
On `make install` the binaries etc. go in the prefix, e.g.
[lang=text]
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.0/FSharp.Core.dll
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.1/FSharp.Core.dll
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.0/fsc.exe
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.0/FSharp.Compiler.dll
...
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/fsc.exe
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/FSharp.Compiler.dll
...
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gac/.../FSharp.Compiler.dll
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gac/.../FSharp.Compiler.dll
...
plus some files for xbuild support
[lang=text]
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/Microsoft\ F#/v4.0/*
/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/Microsoft\ SDKs/F#/3.0/Framework/*
(these names are the canonical names for Microsoft.FSharp.Targets used by project files coming from Visual Studio)
plus scripts
/usr/bin/fsharpc (F# compiler)
/usr/bin/fsharpi (F# Interactive)
## Development notes
###Continuous Integration Build
We have a CI build set up with the JetBrains/Teamcity server as part of the F# community projects there:
http://teamcity.codebetter.com/project.html?projectId=project61&tab=projectOverview
@forki controls access. Right now this builds both a Mono 'make' install and a Windows 'cd src; msbuild fsharp-build.proj' build. No binaries are saved from the build, it is just for sanity checking.
###Editing the Compiler with Visual Studio or MonoDevelop
Open `all-vs2012.sln`, and edit in modes Debug or Release. The compiler takes a good while to compile and that
can be a bit invasive to the work flow, so it's normally better to do the actual compilation from
the command line, see above.
The F# support in MonoDevelop uses an in-process background compiler. On the Mac this causes pausing garbage
collections to kick in which makes editing the compiler in MonoDevelop awkward.
### Building F# Core Unit Tests for .NET 4.x (optional)
This uses the proto compiler to build the unit tests that check some parts of `FSharp.Core.dll` and `FSharp.Compiler.dll`. There is also another set of tests under `tests\fsharp`.
[lang=text]
msbuild fsharp-library-unittests-build.proj /p:TargetFramework=net40
*Note: You must have NUnit installed to build the unit tests.*
### Validation and Use
Here are some simple tests to validate what you have built by checking `fsi.exe` (F# Interactive) starts up:
[lang=text]
lib\debug\4.0\fsi.exe
1 + 1;;
\#q;;
lib\debug\4.0\fsi.exe /help
lib\debug\4.0\fsc.exe /help
echo printfn "hello world" > hello.fs
lib\debug\4.0\fsc.exe hello.fs
hello.exe
### Running Compiler tests (on Windows)
There are language tests under `tests\fsharp\core`. The test apparatus is primitive and unfortunately uses batch files. You can run these on Windows using:
[lang=text]
cd ..\tests\fsharp\core
..\..\build-and-run-all-installed-ilx-configs.bat results.log
The results file will contain one entry for each test directory, plus any reported errors.
[lang=text]
tests\fsharp\core
tests\fsharp\core\queriesCustomQueryOps
tests\fsharp\core\queriesLeafExpressionConvert
tests\fsharp\core\queriesNullableOperators
tests\fsharp\core\queriesOverIEnumerable
...
Some tests for LINQ queries require SQL Server be installed. A failing test will look like this:
[lang=text]
ERRORLEVEL=1: in tests\fsharp\core\csfromfs\build.bat
You can then go to the relevant directory and run `build.bat` and `run.bat`.
## History
F# compiler sources dropped by Microsoft are available from [fsharppowerpack.codeplex.com](http://fsharppowerpack.codeplex.com).
Uses bootstrapping libraries, tools and F# compiler. The `lib/bootstrap/X.0` directories contain mono-built libraries, compiler and tools that can be used to bootstrap a build. You can also supply your own via the `--with-bootstrap` option.
\ No newline at end of file
F# Compiler Services
====================
The F# compiler services package is a component derived from the F# compiler source code that
exposes additional functionality for implementing F# language bindings, additional
tools based on the compiler or refactoring tools. The package also includes F#
interactive service that can be used for embedding F# scripting into your applications.
<div class="row">
<div class="span1"></div>
<div class="span6">
<div class="well well-small" id="nuget">
The F# Compiler Services package can be <a href="https://nuget.org/packages/FSharp.Compiler.Service">installed from NuGet</a>:
<pre>PM> Install-Package FSharp.Compiler.Service</pre>
</div>
</div>
<div class="span1"></div>
</div>
Available services
------------------
The project currently exposes the following services that are tested & documented on this page.
The libraries contain additional public API that can be used, but is not documented here.
* [**F# Language tokenizer**](tokenizer.html) - turns any F# source code into a stream of tokens.
Useful for implementing source code colorization and basic tools. Correctly handle nested
comments, strings etc.
* [**Processing untyped AST**](untypedtree.html) - allows accessing the untyped abstract syntax tree (AST).
This represents parsed F# syntax without type information and can be used to implement code formatting
and various simple processing tasks.
* [**Using editor (IDE) services**](editor.html) - expose functionality for auto-completion, tool-tips,
parameter information etc. These functions are useful for implementing F# support for editors
and for getting some type information for F# code.
* [**Working with signatures, types, and resolved symbols**](symbols.html) - many services related to type checking
return resolved symbols, representing inferred types, and the signatures of whole assemblies.
* [**Working with resolved expressions**](typedtree.html) - services related to working with
type-checked expressions and declarations, where names have been resolved to symbols.
* [**Working with projects and project-wide analysis**](project.html) - you can request a check of
an entire project, and ask for the results of whole-project analyses such as find-all-references.
* [**Hosting F# interactive**](interactive.html) - allows calling F# interactive as a .NET library
from your .NET code. You can use this API to embed F# as a scripting language in your projects.
* [**Hosting the F# compiler**](compiler.html) - allows you to embed calls to the F# compiler.
* [**File system API**](filesystem.html) - the `FSharp.Compiler.Service` component has a global variable
representing the file system. By setting this variable you can host the compiler in situations where a file system
is not available.
> **NOTE:** The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published
Projects using the F# Compiler Services
------------------
Some of the projects using the F# Compiler Services are:
* [**The Visual F# Power Tools**](http://fsprojects.github.io/VisualFSharpPowerTools/)
* [**The Xamarin and MonoDevelop Tools for F#**](https://github.com/mono/monodevelop/tree/master/main/external/fsharpbinding)
* [**The Emacs Plugin for F#**](https://github.com/fsharp/emacs-fsharp-mode)
* [**The Vim Plugin for F#**](https://github.com/fsharp/vim-fsharp)
* [**iFSharp**](https://github.com/BayardRock/IfSharp) - iPython-style notebook engine for F#
* [**CloudSharper**](http://cloudsharper.com/) - Online web and mobile programming with big data and charting
* [**Tsunami**](http://tsunami.io) - Tsunami enhances applications and workflows with the power of Type Safe Scripting
* [**FQuake3**](https://github.com/TIHan/FQuake3/) - integrates F# as an interactive game scripting engine
* [**FCell**](http://fcell.io) - Deliver the power of .NET from within Microsoft Excel
* [**FSharpLint**](http://fsprojects.github.io/FSharpLint/) - Lint tool for F#
* [**FsReveal**](http://fsprojects.github.io/FsReveal//) - FsReveal parses markdown and F# script file and generate reveal.js slides
* [**Elucidate**](https://github.com/rookboom/Elucidate) - Visual Studio extension for rich inlined comments using MarkDown
* [**Fable**](https://fable-compiler.github.io/) - F# to JavaScript Compiler
* [**FSharp.Formatting**](http://tpetricek.github.io/FSharp.Formatting/) - F# tools for generating documentation (Markdown processor and F# code formatter)
* [**FAKE**](http://fsharp.github.io/FAKE/) - "FAKE - F# Make" is a cross platform build automation system
* [**FsLab Journal**](https://visualstudiogallery.msdn.microsoft.com/45373b36-2a4c-4b6a-b427-93c7a8effddb) - Template that makes it easy to do interactive data analysis using F# Interactive and produce nice HTML reports of your work
Contributing and copyright
--------------------------
This project is a fork of the [fsharp/fsharp](https://github.com/fsharp/fsharp) which has been
modified to expose additional internals useful for creating editors and F# tools and also for
embedding F# interactive.
The F# source code is copyright by Microsoft Corporation and contributors, the extensions have been
implemented by Dave Thomas, Anh-Dung Phan, Tomas Petricek and other contributors. The source code
is available under the [Apache 2.0 license](https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE).
(*** hide ***)
#I "../../bin/v4.5/"
(**
Interactive Service: Embedding F# Interactive
=============================================
This tutorial demonstrates how to embed F# interactive in your application. F# interactive
is an interactive scripting environment that compiles F# code into highly efficient IL code
and executes it on the fly. The F# interactive service allows you to embed F# evaluation in
your application.
> **NOTE:** There is a number of options for embedding F# Interactive. The easiest one is to use the
`fsi.exe` process and communicate with it using standard input and standard output. In this
tutorial, we look at calling F# Interactive directly through .NET API. However, if you have
no control over the input, it is a good idea to run F# interactive in a separate process.
One reason is that there is no way to handle `StackOverflowException` and so a poorly written
script can terminate the host process. **Remember that while calling F# Interactive through .NET API,
` --shadowcopyreferences` option will be ignored**. For detailed discussion, please take a look at
[this thread](https://github.com/fsharp/FSharp.Compiler.Service/issues/292).
> **NOTE:** If `FsiEvaluationSession.Create` fails with an error saying that `FSharp.Core.dll` cannot be found,
add the `FSharp.Core.sigdata` and `FSharp.Core.optdata` files. More info [here](https://fsharp.github.io/FSharp.Compiler.Service/corelib.html).
However, the F# interactive service is still useful, because you might want to wrap it in your
own executable that is then executed (and communicates with the rest of your application), or
if you only need to execute limited subset of F# code (e.g. generated by your own DSL).
Starting the F# interactive
---------------------------
First, we need to reference the libraries that contain F# interactive service:
*)
#r "FSharp.Compiler.Service.dll"
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Interactive.Shell
(**
To communicate with F# interactive, we need to create streams that represent input and
output. We will use those later to read the output printed as a result of evaluating some
F# code that prints:
*)
open System
open System.IO
open System.Text
// Intialize output and input streams
let sbOut = new StringBuilder()
let sbErr = new StringBuilder()
let inStream = new StringReader("")
let outStream = new StringWriter(sbOut)
let errStream = new StringWriter(sbErr)
// Build command line arguments & start FSI session
let argv = [| "C:\\fsi.exe" |]
let allArgs = Array.append argv [|"--noninteractive"|]
let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream)
(**
Evaluating and executing code
-----------------------------
The F# interactive service exposes several methods that can be used for evaluation. The first
is `EvalExpression` which evaluates an expression and returns its result. The result contains
the returned value (as `obj`) and the statically inferred type of the value:
*)
/// Evaluate expression & return the result
let evalExpression text =
match fsiSession.EvalExpression(text) with
| Some value -> printfn "%A" value.ReflectionValue
| None -> printfn "Got no result!"
(**
This takes a string as an argument and evaluates (i.e. executes) it as F# code.
*)
evalExpression "42+1" // prints '43'
(**
This can be used in a strongly typed way as follows:
*)
/// Evaluate expression & return the result, strongly typed
let evalExpressionTyped<'T> (text) =
match fsiSession.EvalExpression(text) with
| Some value -> value.ReflectionValue |> unbox<'T>
| None -> failwith "Got no result!"
evalExpressionTyped<int> "42+1" // gives '43'
(**
The `EvalInteraction` method can be used to evaluate side-effectful operations
such as printing, declarations, or other interactions that are not valid F# expressions, but can be entered in
the F# Interactive console. Such commands include `#time "on"` (and other directives), `open System`
all declarations and other top-level statements. The code
does not require `;;` at the end. Just enter the code that you want to execute:
*)
fsiSession.EvalInteraction "printfn \"bye\""
(**
The `EvalScript` method allows to evaluate a complete .fsx script.
*)
File.WriteAllText("sample.fsx", "let twenty = 10 + 10")
fsiSession.EvalScript "sample.fsx"
(**
Catching errors
------------------
``EvalExpression``, ``EvalInteraction`` and ``EvalScript`` are awkward if the
code has type checking warnings or errors, or if evaluation fails with an exception.
In these cases you can use ``EvalExpressionNonThrowing``, ``EvalInteractionNonThrowing``
and ``EvalScriptNonThrowing``. These return a tuple of a result and an array of ``FSharpErrorInfo`` values.
These represent the errors and warnings. The result part is a ``Choice<_,_>`` between an actual
result and an exception.
The result part of ``EvalExpression`` and ``EvalExpressionNonThrowing`` is an optional ``FSharpValue``.
If that value is not present then it just indicates that the expression didn't have a tangible
result that could be represented as a .NET object. This siutation shouldn't actually
occur for any normal input expressions, and only for primitives used in libraries.
*)
File.WriteAllText("sample.fsx", "let twenty = 'a' + 10.0")
let result, warnings = fsiSession.EvalScriptNonThrowing "sample.fsx"
// show the result
match result with
| Choice1Of2 () -> printfn "checked and executed ok"
| Choice2Of2 exn -> printfn "execution exception: %s" exn.Message
(**
Gives:
execution exception: Operation could not be completed due to earlier error
*)
// show the errors and warnings
for w in warnings do
printfn "Warning %s at %d,%d" w.Message w.StartLineAlternate w.StartColumn
(**
Gives:
Warning The type 'float' does not match the type 'char' at 1,19
Warning The type 'float' does not match the type 'char' at 1,17
For expressions:
*)
let evalExpressionTyped2<'T> text =
let res, warnings = fsiSession.EvalExpressionNonThrowing(text)
for w in warnings do
printfn "Warning %s at %d,%d" w.Message w.StartLineAlternate w.StartColumn
match res with
| Choice1Of2 (Some value) -> value.ReflectionValue |> unbox<'T>
| Choice1Of2 None -> failwith "null or no result"
| Choice2Of2 (exn:exn) -> failwith (sprintf "exception %s" exn.Message)
evalExpressionTyped2<int> "42+1" // gives '43'
(**
Executing in parallel
------------------
By default the code passed to ``EvalExpression`` is executed immediately. To execute in parallel, submit a computation that starts a task:
*)
open System.Threading.Tasks
let sampleLongRunningExpr =
"""
async {
// The code of what you want to run
do System.Threading.Thread.Sleep 5000
return 10
}
|> Async.StartAsTask"""
let task1 = evalExpressionTyped<Task<int>>(sampleLongRunningExpr)
let task2 = evalExpressionTyped<Task<int>>(sampleLongRunningExpr)
(**
Both computations have now started. You can now fetch the results:
*)
task1.Result // gives the result after completion (up to 5 seconds)
task2.Result // gives the result after completion (up to 5 seconds)
(**
Type checking in the evaluation context
------------------
Let's assume you have a situation where you would like to typecheck code
in the context of the F# Interactive scripting session. For example, you first
evaluation a declaration:
*)
fsiSession.EvalInteraction "let xxx = 1 + 1"
(**
Now you want to typecheck the partially complete code `xxx + xx`
*)
let parseResults, checkResults, checkProjectResults = fsiSession.ParseAndCheckInteraction("xxx + xx")
(**
The `parseResults` and `checkResults` have types `ParseFileResults` and `CheckFileResults`
explained in [Editor](editor.html). You can, for example, look at the type errors in the code:
*)
checkResults.Errors.Length // 1
(**
The code is checked with respect to the logical type context available in the F# interactive session
based on the declarations executed so far.
You can also request declaration list information, tooltip text and symbol resolution:
*)
open Microsoft.FSharp.Compiler
// get a tooltip
checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT)
checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // symbol xxx
(**
The 'fsi' object
------------------
If you want your scripting code to be able to access the 'fsi' object, you should pass in an implementation of this object explicitly.
Normally the one fromm FSharp.Compiler.Interactive.Settings.dll is used.
*)
let fsiConfig2 = FsiEvaluationSession.GetDefaultConfiguration(fsi)
(**
Collectible code generation
------------------
Evaluating code in using FsiEvaluationSession generates a .NET dynamic assembly and uses other resources.
You can make generated code collectible by passing `collectible=true`. However code will only
be collected if there are no outstanding object references involving types, for example
`FsiValue` objects returned by `EvalExpression`, and you must have disposed the `FsiEvaluationSession`.
See also [Restrictions on Collectible Assemblies](http://msdn.microsoft.com/en-us/library/dd554932(v=vs.110).aspx#restrictions).
The example below shows the creation of 200 evaluation sessions. Note that `collectible=true` and
`use session = ...` are both used.
If collectible code is working correctly,
overall resource usage will not increase linearly as the evaluation progresses.
*)
let collectionTest() =
for i in 1 .. 200 do
let defaultArgs = [|"fsi.exe";"--noninteractive";"--nologo";"--gui-"|]
use inStream = new StringReader("")
use outStream = new StringWriter()
use errStream = new StringWriter()
let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
use session = FsiEvaluationSession.Create(fsiConfig, defaultArgs, inStream, outStream, errStream, collectible=true)
session.EvalInteraction (sprintf "type D = { v : int }")
let v = session.EvalExpression (sprintf "{ v = 42 * %d }" i)
printfn "iteration %d, result = %A" i v.Value.ReflectionValue
// collectionTest() <-- run the test like this
(*** hide ***)
#I "../../../bin/v4.5/"
(**
コンパイラの組み込み
====================
このチュートリアルではF#コンパイラをホストする方法を紹介します。
> **注意:** 以下で使用しているAPIは実験的なもので、
新しいnugetパッケージの公開に伴って変更される可能性があります。
> **注意:** F#コンパイラをホストする方法はいくつかあります。
一番簡単な方法は `fsc.exe` のプロセスを使って引数を渡す方法です。
---------------------------
まず、F# Interactiveサービスを含むライブラリへの参照を追加します:
*)
#r "FSharp.Compiler.Service.dll"
open Microsoft.FSharp.Compiler.SimpleSourceCodeServices
open System.IO
let scs = SimpleSourceCodeServices()
(**
次に、一時ファイルへコンテンツを書き込みます:
*)
let fn = Path.GetTempFileName()
let fn2 = Path.ChangeExtension(fn, ".fs")
let fn3 = Path.ChangeExtension(fn, ".dll")
File.WriteAllText(fn2, """
module M
type C() =
member x.P = 1
let x = 3 + 4
""")
(**
そしてコンパイラを呼び出します:
*)
let errors1, exitCode1 = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
(**
エラーが発生した場合は「終了コード」とエラーの配列から原因を特定できます:
*)
File.WriteAllText(fn2, """
module M
let x = 1.0 + "" // a type error
""")
let errors1b, exitCode1b = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
if exitCode1b <> 0 then
errors1b
|> Array.iter (printfn "%A")
(**
動的アセンブリへのコンパイル
============================
コードを動的アセンブリとしてコンパイルすることもできます。
動的アセンブリはF# Interactiveコードジェネレータでも使用されています。
この機能はたとえばファイルシステムが必ずしも利用できないような状況で役に立ちます。
出力ファイルの名前を指定する "-o" オプションを指定することは可能ですが、
実際には出力ファイルがディスク上に書き込まれることはありません。
'execute' 引数に 'None' を指定するとアセンブリ用の初期化コードが実行されません。
*)
let errors2, exitCode2, dynAssembly2 =
scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None)
(**
'Some' を指定するとアセンブリ用の初期化コードが実行されます。
*)
let errors3, exitCode3, dynAssembly3 =
scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr))
(*** hide ***)
#I "../../bin/v4.5/"
(**
コンパイラサービス: FSharp.Core.dll についてのメモ
==================================================
あなたのアプリケーションとともに FSharp.Core を配布する
-------------------------------------------------------
FSharp.Compiler.Service.dll を利用するアプリケーションまたはプラグイン・コンポーネントをビルドする際、普通はアプリの一部として FSharp.Core.dll のコピーも含めることになるでしょう。
例えば、 ``HostedCompiler.exe`` をビルドする場合、普通はあなたの ``HostedCompiler.exe`` と同じフォルダに FSharp.Core.dll (例えば 4.3.1.0)を配置します。
動的コンパイルや動的実行を行う場合、FSharp.Core.optdata と FSharp.Core.sigdata も含める必要があるかもしれませんが、これらについては下記の指針をご覧ください。
あなたのアプリケーションにリダイレクトをバインドする
----------------------------------------------------
FSharp.Compiler.Service.dll コンポーネントは FSharp.Core 4.3.0.0 に依存しています。通例、あなたのアプリケーションはこれより後のバージョンの FSharp.Core をターゲットにしており、FSharp.Core 4.3.0.0 をあなたのアプリケーションで用いる FSharp.Core.dll の最終バージョンにちゃんと転送させるように[バインド リダイレクト](https://msdn.microsoft.com/ja-jp/library/7wd6ex19(v=vs.110).aspx)が必要になるでしょう。バインド リダイレクト ファイルは通常ビルドツールによって自動的に生成されます。そうでない場合、下記のようなファイル(あなたのツールが ``HostedCompiler.exe`` という名前で、バインド リダイレクト ファイルが ``HostedCompiler.exe.config`` という名前の場合)を使うことが出来ます。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="2.0.0.0-4.3.0.0" newVersion="4.3.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
どの FSharp.Core と .NET フレームワークがコンパイル時に参照される?
--------------------------------------
FSharp.Combiler.Service コンポーネントは多かれ少なかれ、F#コードを コンパイルするために使われるに過ぎません。特に、コマンドライン引数(あなたのツールを実行するために使われる FSharp.Core や .NET フレームワークとは違います)に明示的に FSharp.Core および/またはフレームワークのアセンブリを参照することが出来ます。
特定の FSharp.Core および .NET フレームワーク アセンブリ、またはそのいずれかをターゲットにする場合、 ``--noframework`` 引数と適切なコマンドライン引数を使います:
[<Literal>]
let fsharpCorePath =
@"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0\FSharp.Core.dll"
let errors2, exitCode2 =
scs.Compile(
[| "fsc.exe"; "--noframework";
"-r"; fsharpCorePath;
"-r"; @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll";
"-o"; fn3;
"-a"; fn2 |])
これらのアセンブリが配置されている場所を指定する必要があります。クロスプラットフォームに対応した方法でDLL を配置して、それらをコマンドライン引数に変換する最も簡単な方法は、[F# プロジェクトファイルをクラックする](http://fsharp.github.io/FSharp.Compiler.Service/ja/project.html)ことです。
自分で SDK のパスを処理する代わりに、[FSharp.Compiler.Service.dll 用のテスト](https://github.com/fsharp/FSharp.Compiler.Service/blob/8a943dd3b545648690cb3bed652a469bdb6dd869/tests/service/Common.fs#L54)で使用しているようなヘルパー関数も用意されています。
スクリプトを処理しているか ``GetCheckOptionsFromScriptRoot`` を使っている場合
-------------------------------------------------------------------------
もし SDK 配置先にある FSharp.Core.dll を明示的に参照 *していない* 場合、または ``FsiEvaluationSession`` や ``GetCheckOptionsFromScriptRoot`` を使用してスクリプトを処理している場合、以下のいずれかの方法により、暗黙的にFSharp.Core が参照されます:
1. ``System.Reflection.Assembly.GetEntryAssembly()`` によって返されるホストアセンブリから静的に参照されたFSharp.Core.dll のバージョン
2. ホストアセンブリに FSharp.Core への静的な参照がない場合、
- FSharp.Compiler.Service 0.x シリーズでは、FSharp.Core バージョン 4.3.0.0 への参照が付与されます
- FSharp.Compiler.Service 1.3.1.x (F# 3.1 シリーズ)では、FSharp.Core バージョン 4.3.1.0 への参照が付与されます
- FSharp.Compiler.Service 1.4.0.x (F# 4.0 シリーズ)では、FSharp.Core バージョン 4.4.0.0 への参照が付与されます
FSharp.Core.optdata と FSharp.Core.sigdata を含める必要はありますか?
--------------------------------------
もしあなたのコンパイル引数が SDK 配置先にある FSharp.Core.dll を明示的に参照している場合、FSharp.Core.sigdata と FSharp.Core.optdata はその DLL と同じフォルダになければいけません(これらのファイルがインストールされていない場合、F# SDKの インストールに問題があります)。もしコンパイル引数で常に明示的に参照していたなら、FSharp.Core.optdata と FSharp.Core.sigdata はあなたのアプリケーションの一部として含める必要は *ありません* 。
もしあなたが暗黙的な参照(例えば、上記のスクリプト処理など)に頼っているのなら、これはあなたのツールがアプリケーションの一部として FSharp.Core.dll を参照しているかもしれない、ということです。この場合、FSharp.Core.optdata および FSharp.Core.sigdata が FSharp.Core.dll と同じフォルダに見つからないというエラーが発生するかもしれません。 **もしあなたがアプリケーションに含めている FSharp.Core.dll を暗黙的に参照したいのであれば、FSharp.Core.sigdata と FSharp.Core.optdata もアプリケーションに追加する2つのファイルとして追加しましょう。** ``CombileToDynamicAssembly`` を使用する場合、この問題によって[アセンブリ解決中のスタックオーバーフロー](https://github.com/fsharp/FSharp.Compiler.Service/issues/258)も引き起こされるでしょう。
動的コンパイルと動的コード実行を行うツール(例: ``HostedExecution.exe``)はしばしば FSharp.Core.dll を暗黙的に参照するようになっています。
これはつまり通常 FSharp.Core.optdata と FSharp.Core.sigdata を含んでいるということです。
要約
-------
このデザインノートでは3つのポイントを検討しました:
- どの FSharp.Core.dll があなたのコンパイルツールを実行するのに使われるか
- あなたのコンパイルツールを実行するのに使われる FSharp.Core.dll へのバインド リダイレクトを設定する方法
- あなたのツールによって実行されるチェック時およびコンパイル時にどの FSharp.Core.dll および/またはフレームワークのアセンブリが参照されるか
*)
開発者用メモ
============
F#コンパイラの修正版クローンではクライアントの編集機能やF#コンパイラの埋め込み、
F# Interactiveをサービスとして動作させるための機能が追加されています。
## コンポーネント
まず `FSharp.Compiler.Service.dll` というコンポーネントがあります。
このコンポーネントにはリファクタリングやその他の編集ツールが完全なF# ASTやパーサ機能を利用できるように
可視性を変更するというマイナーな変更だけが加えられています。
主な狙いとしては、メインコンパイラの安定版かつドキュメントが備えられたフォークを用意することにより、
このコンポーネントにある共通コードを様々なツールで共有できるようにすることです。
2つ目のコンポーネントはF# Interactiveをサービスとして組み込めるようにするためのもので、
`fsi.exe` のソースコードに多数の変更が加えられており、
`EvalExpression``EvalInteraction` といった関数が追加されています。
このレポジトリは以下の点を除けば 'fsharp' と **同一** です:
- `FSharp.Compiler.Service.dll` のビルド、特に以下の点に関する変更:
- アセンブリ名の変更
- `FSharp.Compiler.Service.dll` のみビルドされる
- ブートストラッパーやプロトコンパイラを使用しない。
F#コンパイラがインストール済みであることを想定。
- FAKEを使用するビルドスクリプト。
すべてのコードのビルドとNuGetパッケージ、ドキュメントの生成、
NuGetパッケージの配布に必要なファイルの生成などがFAKEによって行われる。
([F# プロジェクト スキャフォールド](https://github.com/fsprojects/FSharp.ProjectScaffold) に準拠)
- 新機能追加のためにコンパイラのソースコードを変更。
また、評価用関数を実装するためにF# Interactiveサービスに対する変更を追加。
- F#編集用クライアントで使用されるAPIを改善するためにコンパイラのソースコードを変更。
- コンパイラサービスAPIに新機能を追加するためにコンパイラのソースコードを変更。
`fsharp/fsharp` のレポジトリに言語あるいはコンパイラが追加コミットされた場合、
それらはこのレポジトリにもマージされるべきで、同時に新しいNuGetパッケージもリリースする必要があります。
## ビルドとNuGet
ビルドの手順は [F# プロジェクト スキャフォールド](https://github.com/fsprojects/FSharp.ProjectScaffold)
で推奨されているものに準じます。
プロジェクトを独自にビルドする場合、以下の手順に従ってください:
[lang=text]
git clone https://github.com/fsharp/FSharp.Compiler.Service
cd FSharp.Compiler.Service
次に、(Windowsであれば) `build.cmd` または(LinuxやMac OSであれば) `build.sh` を実行してすべてをビルドします。
ファイルは `bin` ディレクトリ内に出力されます。
ドキュメントやNuGetパッケージもビルドしたい場合には `build Release` を実行します
(このコマンドはGitHub上のドキュメントを更新しようとしますが、GitHubのレポジトリに適切な権限を持っている場合にのみ有効です)。
## クライアント
このコンポーネントは以下のようなツールで使用されています:
* [Fantomas](https://github.com/dungpa/fantomas) - F# コードフォーマットツール
* [Fsharp-Refactor](https://github.com/Lewix/fsharp-refactor) - F#用リファクタリングツール
* [FSharpbinding](https://github.com/fsharp/fsharpbinding) - Xamarin Studio バインディング
* [F# Snippets web site](http://fssnip.net/) - F# 版のpastebin
* [F# ACE Code Editor](https://github.com/BayardRock/FSharpWebIntellisense/) - Web上のF#編集ツール
(*** hide ***)
#I "../../../bin/v4.5/"
(**
コンパイラサービス: エディタサービス
====================================
このチュートリアルはF#コンパイラによって公開されるエディタサービスの
使用方法についてのデモです。
このAPIにより、Visual StudioやXamarin Studio、EmacsなどのF#エディタ内において、
自動補完機能やツールチップ表示、引数情報のヘルプ表示、括弧の補完などの機能を
実装することができます
(詳細については [fsharpbindings](https://github.com/fsharp/fsharpbinding) のプロジェクトを参照してください)。
[型無しASTを使用するチュートリアル](untypedtree.html) と同じく、
今回も `FSharpChecker` オブジェクトを作成するところから始めます。
> **注意:** 以下で使用しているAPIは試験的なもので、最新バージョンのnugetパッケージの
公開に伴って変更されることがあります。
サンプルソースコードの型チェック
--------------------------------
[前回の(型無しASTを使った)チュートリアル](untypedtree.html) と同じく、
`FSharp.Compiler.Service.dll` への参照を追加した後に特定の名前空間をオープンし、
`FSharpChecker` のインスタンスを作成します:
*)
// F#コンパイラAPIを参照
#r "FSharp.Compiler.Service.dll"
open System
open Microsoft.FSharp.Compiler.SourceCodeServices
// インタラクティブチェッカーのインスタンスを作成
let checker = FSharpChecker.Create()
(**
[前回](untypedtree.html) 同様、
コンパイラに渡されるファイルとしては特定の入力値だけであるという
コンテキストを想定するため、 `GetCheckOptionsFromScriptRoot` を使います
(この入力値はコンパイラによってスクリプトファイル、
あるいはスタンドアロンのF#ソースコードとみなされます)。
*)
// サンプルの入力となる複数行文字列
let input =
"""
open System
let foo() =
let msg = String.Concat("Hello"," ","world")
if true then
printfn "%s" msg.
"""
// 入力値の分割とファイル名の定義
let inputLines = input.Split('\n')
let file = "/home/user/Test.fsx"
let projOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously
(**
型チェックを実行するには、まず `ParseFileInProject` を使って
入力値をパースする必要があります。
このメソッドを使うと [型無しAST](untypedtree.html) にアクセスできるようになります。
しかし今回は完全な型チェックを実行するため、続けて `CheckFileInProject`
を呼び出す必要があります。
このメソッドは `ParseFileInProject` の結果も必要とするため、
たいていの場合にはこれら2つのメソッドをセットで呼び出すことになります。
*)
// パースを実行
let parseFileResults =
checker.ParseFileInProject(file, input, projOptions)
|> Async.RunSynchronously
(**
`TypeCheckResults` に備えられた興味深い機能の紹介に入る前に、
サンプル入力に対して型チェッカーを実行する必要があります。
F#コードにエラーがあった場合も何らかの型チェックの結果が返されます
(ただし間違って「推測された」結果が含まれることがあります)。
*)
// 型チェックを実行
let checkFileAnswer =
checker.CheckFileInProject(parseFileResults, file, 0, input, projOptions)
|> Async.RunSynchronously
(**
あるいは `ParseAndCheckFileInProject` を使用すれば1つの操作で両方のチェックを行うことができます:
*)
let parseResults2, checkFileAnswer2 =
checker.ParseAndCheckFileInProject(file, 0, input, projOptions)
|> Async.RunSynchronously
(**
この返り値は `CheckFileAnswer` 型で、この型に機能的に興味深いものが揃えられています...
*)
let checkFileResults =
match checkFileAnswer with
| FSharpCheckFileAnswer.Succeeded(res) -> res
| res -> failwithf "パースが完了していません... (%A)" res
(**
今回は単に(状況に応じて)「Hello world」と表示するだけの
単純な関数の型をチェックしています。
最終行では値 `msg` に対する補完リストを表示することができるように、
`msg.` というようにドットを追加している点に注意してください
(今回の場合は文字列型に対する様々なメソッドが期待されます)。
型チェックの結果を使用する
--------------------------
では `TypeCheckResults` 型で公開されているAPIをいくつか見ていきましょう。
一般的に、F#ソースコードエディタサービスの実装に必要な機能は
ほとんどこの型に備えられています。
### ツールチップの取得
ツールチップを取得するには `GetToolTipTextAlternate` メソッドを使用します。
このメソッドには行数と文字オフセットを指定します。
いずれも0から始まる数値です。
サンプルコードでは3行目(0行目は空白行)、インデックス7にある文字 `f` から始まる関数
`foo` のツールチップを取得しています
(ツールチップは識別子の中であれば任意の位置で機能します)。
またこのメソッドにはトークンタグを指定する必要もあります。
トークンタグは一般的には `IDENT` を指定して、識別子に対する
ツールチップが取得できるようにします
(あるいは `#r "..."` を使用している場合にはアセンブリの完全パスを表示させるように
することもできるでしょう)。
*)
// 最後の引数に指定する、IDENTトークンのタグを取得
open Microsoft.FSharp.Compiler
let identToken = Parser.tagOfToken(Parser.token.IDENT(""))
// 特定の位置におけるツールチップを取得
let tip = checkFileResults.GetToolTipTextAlternate(4, 7, inputLines.[1], ["foo"], identToken)
printfn "%A" tip
(**
> **注意:** `GetToolTipTextAlternate` は古い関数 `GetToolTipText` に代わるものです。
`GetToolTipText` は0から始まる行番号を受け取るようになっていたため、非推奨になりました。
この関数には位置とトークンの種類の他にも、
(ソースコードの変更時に役立つように)特定行の現在の内容と、
現時点における完全修飾された `名前` を表す文字列のリストを指定する必要があります。
たとえば完全修飾名 `System.Random` という名前を持った識別子 `Random` に対する
ツールチップを取得する場合、 `Random` という文字列が現れる場所の他に、
`["System"; "Random"]` という値を指定する必要があります。
返り値の型は `ToolTipText` で、この型には `ToolTipElement` という
判別共用体が含まれます。
この共用体は、コンパイラによって返されたツールチップの種類に応じて異なります。
### 自動補完リストの取得
次に紹介する `TypeCheckResults` のメソッドを使用すると、
特定の位置における自動補完機能を実装できます。
この機能は任意の識別子上、
あるいは(特定のスコープ内で利用可能な名前の一覧を取得する場合には)任意のスコープ、
あるいは特定のオブジェクトにおけるメンバーリストを取得する場合には
`.` の直後で呼び出すことができます。
今回は文字列の値 `msg` に対するメンバーリストを取得することにします。
そのためには最終行( `printfn "%s" msg.` で終わっている行)にある
シンボル `.` の位置を指定して `GetDeclarationListInfo` を呼び出します。
オフセットは1から始まるため、位置は `7, 23` になります。
また、テキストが変更されていないことを表す関数と、
現時点において補完する必要がある識別子を指定する必要もあります。
*)
// 特定の位置における宣言(自動補完)を取得する
let decls =
checkFileResults.GetDeclarationListInfo
(Some parseFileResults, 7, 23, inputLines.[6], [], "msg", fun _ -> false)
|> Async.RunSynchronously
// 利用可能な項目を表示
for item in decls.Items do
printfn " - %s" item.Name
(**
> **注意:** `GetDeclarationListInfo` は古い関数 `GetDeclarations` に代わるものです。
`GetDeclarations` は0から始まる行番号を受け取るようになっていたため、非推奨になりました。
また、将来的には現在の `GetDeclarations` が削除され、 `GetDeclarationListInfo` が
`GetDeclarations` になる予定です。
コードを実行してみると、 `Substring` や `ToUpper` 、 `ToLower` といった
文字列に対するいつものメソッドのリストが取得できていることでしょう。
`GetDeclarations` の5,6番目の引数( `[]` および `"msg"` )には
自動補完用のコンテキストを指定します。
今回の場合は完全名 `msg` に対する補完を行いましたが、
たとえば `["System"; "Collections"]` と `"Generic"` というように
完全修飾された名前空間を指定して補完リストを取得することもできます。
### 引数の情報を取得する
次に一般的なエディタの機能としては、メソッドのオーバーロードに
関する情報を提供するというものでしょう。
サンプルコード中では多数のオーバーロードを持った `String.Concat` を使っています。
このオーバーロード一覧は `GetMethods` で取得できます。
先ほどと同じく、このメソッドには対象とする項目の位置を0基準のオフセットで指定し
(今回は `String.Concat` 識別子の右側の終端)、
識別子もやはり指定します
(これにより、コンパイラはソースコードが変更された場合でも最新の情報に追従できます):
*)
//String.Concatメソッドのオーバーロードを取得する
let methods =
checkFileResults.GetMethodsAlternate(5, 27, inputLines.[4], Some ["String"; "Concat"]) |> Async.RunSynchronously
// 連結された引数リストを表示
for mi in methods.Methods do
[ for p in mi.Parameters -> p.Display ]
|> String.concat ", "
|> printfn "%s(%s)" methods.MethodName
(**
ここでは `Display` プロパティを使用することで各引数に対する
アノテーションを取得しています。
このプロパティは `arg0: obj` あるいは `params args: obj[]` 、
`str0: string, str1: string` といった情報を返します。
これらの引数を連結した後、メソッド名とメソッドの型情報とともに表示させています。
*)
(**
## 非同期操作と即時操作
`CheckFileInProject` が非同期操作であることを気にされる人もいるかもしれません。
これはつまり、F#コードの型チェックにはある程度時間がかかることを示唆しています。
F#コンパイラは型チェックを(自動的に)バックグラウンドで処理を進めているため、
`CheckFileInProject` メソッドを呼び出すと非同期操作が返されることになります。
また、 `CheckFileInProjectIfReady` というメソッドもあります。
このメソッドは、型チェックの操作が即座に開始できない場合、
つまりプロジェクト内の他のファイルがまだ型チェックされていない場合には
処理が即座に返されます。
この場合、バックグラウンドワーカーは一定期間他の作業を進めるか、
`FileTypeCheckStateIsDirty` イベントが発生するまでは
ファイルに対する型チェックを諦めるか、どちらか選択することになります。
> [fsharpbinding](https://github.com/fsharp/fsharpbinding) プロジェクトには
1つのF#エージェント経由ですべてのリクエストをバックグラウンドワークとして
処理するような、より複雑な具体例も含まれています。
エディタの機能を実装する方法としてはこちらのほうが適切です。
*)
(**
まとめ
------
`CheckFileAnswer` にはチュートリアルで紹介していないような便利なメソッドが
多数揃えられています。
これらを使用すれば特定の識別子に対する宣言の位置を取得したり、
付加的な色情報を取得したりすることができます
(F# 3.1では式ビルダーの識別子やクエリ演算子も着色表示されます)。
最後に、直接.NET APIを呼び出すことができないようなエディタに対するサポート機能を
実装する場合、ここで紹介した様々な機能を
[FSharp.AutoComplete](https://github.com/fsharp/fsharpbinding/tree/master/FSharp.AutoComplete)
プロジェクトのコマンドラインインターフェイス経由で呼び出すこともできます。
*)
(*** hide ***)
#I "../../../bin/v4.5/"
(**
コンパイラサービス: ファイルシステム仮想化
==========================================
`FSharp.Compiler.Service` にはファイルシステムを表すグローバル変数があります。
この変数を設定するこにより、ファイルシステムが利用できない状況でも
コンパイラをホストすることができるようになります。
> **注意:** 以下で使用しているAPIは実験的なもので、
新しいnugetパッケージの公開に伴って変更される可能性があります。
FileSystemの設定
----------------
以下の例ではディスクからの読み取りを行うような実装をファイルシステムに設定しています:
*)
#r "FSharp.Compiler.Service.dll"
open System
open System.IO
open System.Collections.Generic
open System.Text
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
let defaultFileSystem = Shim.FileSystem
let fileName1 = @"c:\mycode\test1.fs" // 注意: 実際には存在しないファイルのパス
let fileName2 = @"c:\mycode\test2.fs" // 注意: 実際には存在しないファイルのパス
type MyFileSystem() =
let file1 = """
module File1
let A = 1"""
let file2 = """
module File2
let B = File1.A + File1.A"""
let files = dict [(fileName1, file1); (fileName2, file2)]
interface IFileSystem with
// 読み取りおよび書き込み用にファイルをオープンする機能を実装
member __.FileStreamReadShim(fileName) =
match files.TryGetValue(fileName) with
| true, text -> new MemoryStream(Encoding.UTF8.GetBytes(text)) :> Stream
| _ -> defaultFileSystem.FileStreamReadShim(fileName)
member __.FileStreamCreateShim(fileName) =
defaultFileSystem.FileStreamCreateShim(fileName)
member __.FileStreamWriteExistingShim(fileName) =
defaultFileSystem.FileStreamWriteExistingShim(fileName)
member __.ReadAllBytesShim(fileName) =
match files.TryGetValue(fileName) with
| true, text -> Encoding.UTF8.GetBytes(text)
| _ -> defaultFileSystem.ReadAllBytesShim(fileName)
// 一時パスおよびファイルのタイムスタンプに関連する機能を実装
member __.GetTempPathShim() =
defaultFileSystem.GetTempPathShim()
member __.GetLastWriteTimeShim(fileName) =
defaultFileSystem.GetLastWriteTimeShim(fileName)
member __.GetFullPathShim(fileName) =
defaultFileSystem.GetFullPathShim(fileName)
member __.IsInvalidPathShim(fileName) =
defaultFileSystem.IsInvalidPathShim(fileName)
member __.IsPathRootedShim(fileName) =
defaultFileSystem.IsPathRootedShim(fileName)
// ファイルの存在確認および削除に関連する機能を実装
member __.SafeExists(fileName) =
files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName)
member __.FileDelete(fileName) =
defaultFileSystem.FileDelete(fileName)
// アセンブリのロードに関連する機能を実装。
// 型プロバイダやF# Interactiveで使用される。
member __.AssemblyLoadFrom(fileName) =
defaultFileSystem.AssemblyLoadFrom fileName
member __.AssemblyLoad(assemblyName) =
defaultFileSystem.AssemblyLoad assemblyName
let myFileSystem = MyFileSystem()
Shim.FileSystem <- MyFileSystem()
(**
FileSystemによるコンパイルの実行
--------------------------------
*)
open Microsoft.FSharp.Compiler.SourceCodeServices
let checker = FSharpChecker.Create()
let projectOptions =
let allFlags =
[| yield "--simpleresolution";
yield "--noframework";
yield "--debug:full";
yield "--define:DEBUG";
yield "--optimize-";
yield "--doc:test.xml";
yield "--warn:3";
yield "--fullpaths";
yield "--flaterrors";
yield "--target:library";
let references =
[ @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll";
@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll";
@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll";
@"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\FSharp.Core.dll"]
for r in references do
yield "-r:" + r |]
{ ProjectFileName = @"c:\mycode\compilation.fsproj" // 現在のディレクトリで一意な名前を指定
ProjectFileNames = [| fileName1; fileName2 |]
OtherOptions = allFlags
ReferencedProjects=[| |]
IsIncompleteTypeCheckEnvironment = false
UseScriptResolutionRules = true
LoadTime = System.DateTime.Now // 'Now' を指定して強制的に再読込させている点に注意
UnresolvedReferences = None }
let results = checker.ParseAndCheckProject(projectOptions) |> Async.RunSynchronously
results.Errors
results.AssemblySignature.Entities.Count //2
results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.Count //1
results.AssemblySignature.Entities.[0].MembersFunctionsAndValues.[0].DisplayName // "B"
(**
まとめ
------
このチュートリアルでは FSharp.Compiler.Service コンポーネントで使用される
ファイルシステムに注目して、グローバルな設定を変更する方法について紹介しました。
このチュートリアルの執筆時点では、以下に列挙したSystem.IOの操作に対しては
仮想化されたファイルシステムAPIが用意されない予定になっています。
将来のバージョンのコンパイラサービスではこれらのAPIが追加されるかもしれません。
- Path.Combine
- Path.DirectorySeparatorChar
- Path.GetDirectoryName
- Path.GetFileName
- Path.GetFileNameWithoutExtension
- Path.HasExtension
- Path.GetRandomFileName (アセンブリ内にコンパイル済みwin32リソースを生成する場合にのみ使用される)
**注意:** `SourceCodeServices` API内の一部の操作では、
引数にファイルの内容だけでなくファイル名を指定する必要があります。
これらのAPIにおいて、ファイル名はエラーの報告のためだけに使用されます。
**注意:** 型プロバイダーコンポーネントは仮想化されたファイルシステムを使用しません。
**注意:** コンパイラサービスは `--simpleresolution` が指定されていない場合、
MSBuildを使ってアセンブリの解決を試みることがあります。
`FileSystem` APIを使用する場合、通常はコンパイラへのフラグとして
`--simpleresolution` を指定することになります。
それと同時に `--noframework` を指定します。
.NETアセンブリに対するすべての参照を明示的に指定する必要があるでしょう。
*)
此差异已折叠。
F# コンパイラサービス
=====================
F# コンパイラサービスパッケージはF# コンパイラのソースコードから派生したコンポーネントです。
このソースコードにはF# 言語バインディングを実装するための機能や、
コンパイラやリファクタリングツールを元にしたツールを作成するための機能が追加されています。
また、パッケージには自身のアプリケーションにF# スクリプトを埋め込む際に利用できるような
F# インタラクティブサービスも含まれています。
<div class="row">
<div class="span1"></div>
<div class="span6">
<div class="well well-small" id="nuget">
F# コンパイラサービスパッケージは <a href="https://nuget.org/packages/FSharp.Compiler.Service">NuGet経由でインストールできます</a>:
<pre>PM> Install-Package FSharp.Compiler.Service</pre>
</div>
</div>
<div class="span1"></div>
</div>
利用可能なサービス
------------------
プロジェクトには現在以下のサービスがあり、いずれもテストされ、
このページから参照可能なドキュメントがあります。
ライブラリには他にも使用可能な公開APIがありますが、
ここではドキュメント化されていません。
* [** F# 言語トークナイザ **](tokenizer.html) - F#ソースコードをトークンのストリームへと変換します。
この機能はソースコードを色つき表示したり、基本的なツールを作成するような場合に有効です。
ネストされたコメントや文字列なども適切に処理できます。
* [** 型無しASTの処理 **](untypedtree.html) - この機能を使うことで型無し抽象構文木(AST: abstract syntax tree)にアクセスできます。
型無しASTとは型情報を含まない解析済みのF#の文法を表すもので、
コードフォーマットやその他様々な単純処理に利用できます。
* [** エディタ (IDE) サービスの使用 **](editor.html) - 自動補完やツールチップ、
引数の情報などを表示するための機能があります。
この機能を使うと、F#サポート機能をエディタに追加したり、F#コードから
何らかの型情報を取得したりすることができるようになります。
* [** シグネチャや型、解決済みのシンボルの処理 **](symbols.html) -
解決済みのシンボルや推測された型の表現、アセンブリ全体のシグネチャなどを
型のチェック時に返すような多数のサービスがあります。
* [** 複数プロジェクトやプロジェクト全体の処理 **](project.html) -
すべてのプロジェクトに対するチェックを実行することにより、
プロジェクト全体の解析結果を使って\[すべての参照の検索\] のような
機能を実現できます。
* [** F# Interactive のホスティング **](interactive.html) - 自身の.NETコードから
F# Interactiveを.NETライブラリとして呼び出すことができるようになります。
このAPIを使用すると、自身のプロジェクト内でF#をスクリプト言語として
埋め込むことができるようになります。
* [** F#コンパイラのホスティング **](compiler.html) - F# コンパイラを
呼び出すコードを組み込むことができます。
* [** ファイルシステムAPI **](filesystem.html) - `FSharp.Compiler.Service` コンポーネントには
ファイルシステムを表すグローバル変数が定義されています。
この変数を設定することによって、ファイルシステムが使用できない状況であっても
コンパイラをホストすることができるようになります。
> **注釈:** FSharp.Compiler.Service.dll には既存のものと重複する機能が多数あるため、
将来的にはもっときちんとした形に変更されます。
そのため、これらのサービスを使用するAPIには破壊的変更が加えられる可能性があります。
貢献および著作権について
------------------------
このプロジェクトは [fsharp/fsharp](https://github.com/fsharp/fsharp) からフォークしたもので、
そこへさらにエディタやF#用ツール、F# Interactiveの組み込みに必要となる機能を
追加したものです。
F# ソースコードの著作権はMicrosoft Corporationおよび貢献者に、
拡張機能の著作権は Dave Thomas, Anh-Dung Phan, Tomas Petricek および
その他の貢献者にあります。
ソースコードは [Apache 2.0 ライセンス](https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE) の元に公開されています。
此差异已折叠。
此差异已折叠。
此差异已折叠。
(*** hide ***)
#I "../../../bin/v4.5/"
(**
コンパイラサービス:F#トークナイザを使用する
============================================
このチュートリアルではF#言語トークナイザの呼び出し方を紹介します。
F#のソースコードに対して、トークナイザは
コードの各行にあるトークンに関する情報を含んだソースコード行のリストを生成します。
各トークンに対してはトークンの種類や位置を取得したり、
トークンの種類(キーワード、識別子、数値、演算子など)に応じた
色を取得したりすることができます。
> **注意:** 以下で使用しているAPIは実験的なもので、
新しいnugetパッケージの公開に伴って変更される可能性があります。
トークナイザの作成
------------------
トークナイザを使用するには、 `FSharp.Compiler.Service.dll` への参照を追加した後に
`SourceCodeServices` 名前空間をオープンします:
*)
#r "FSharp.Compiler.Service.dll"
open Microsoft.FSharp.Compiler.SourceCodeServices
(**
すると `FSharpSourceTokenizer` のインスタンスを作成できるようになります。
このクラスには2つの引数を指定します。
最初の引数には定義済みのシンボルのリスト、
2番目の引数にはソースコードのファイル名を指定します。
定義済みのシンボルのリストを指定するのは、
トークナイザが `#if` ディレクティブを処理する必要があるからです。
ファイル名はソースコードの位置を特定する場合にのみ指定する必要があります
(存在しないファイル名でも指定できます):
*)
let sourceTok = FSharpSourceTokenizer([], "C:\\test.fsx")
(**
`sourceTok` オブジェクトを使用することでF#ソースコードの各行を
(繰り返し)トークン化することができます。
F#コードのトークン化
--------------------
トークナイザはソースファイル全体ではなく、行単位で処理を行います。
トークンを取得した後、トークナイザは新しいステートを( `int64` 値として)返します。
この値を使うとF#コードをより効率的にトークン化できます。
つまり、ソースコードが変更された場合もファイル全体を
再度トークン化する必要はありません。
変更された部分だけをトークン化すればよいのです。
### 1行をトークン化する
1行をトークン化するには、先ほど作成した `FSharpSourceTokenizer` オブジェクトに対して
`CreateLineTokenizer` を呼び、 `FSharpLineTokenizer` を作成します:
*)
let tokenizer = sourceTok.CreateLineTokenizer("let answer=42")
(**
そして `tokenizer` の `ScanToken` を繰り返し `None` を返すまで
(つまり最終行に到達するまで)繰り返し呼び出すような単純な再帰関数を用意します。
この関数が成功すると、必要な詳細情報をすべて含んだ `FSharpTokenInfo` オブジェクトが
返されます:
*)
/// F#コード1行をトークン化します
let rec tokenizeLine (tokenizer:FSharpLineTokenizer) state =
match tokenizer.ScanToken(state) with
| Some tok, state ->
// トークン名を表示
printf "%s " tok.TokenName
// 新しい状態で残りをトークン化
tokenizeLine tokenizer state
| None, state -> state
(**
この関数は、複数行コードや複数行コメント内の前方の行をトークン化する場合に
必要となるような新しい状態を返します。
初期値としては `0L` を指定します:
*)
tokenizeLine tokenizer 0L
(**
この結果は LET WHITESPACE IDENT EQUALS INT32 という
トークン名のシーケンスになります。
`FSharpTokenInfo` にはたとえば以下のような興味深いプロパティが多数あります:
- `CharClass` および `ColorClass` はF#コードを色づけする場合に使用できるような、
トークンのカテゴリに関する情報を返します。
- `LeftColumn` および `RightColumn` は行内におけるトークンの位置を返します。
- `TokenName` は(F# レキサ内で定義された)トークンの名前を返します。
なおトークナイザはステートフルであることに注意してください。
つまり、1行を複数回トークン化したい場合にはその都度 `CreateLineTokenizer` を
呼び出す必要があります。
### サンプルコードのトークン化
トークナイザをもっと長いサンプルコードやファイル全体に対して実行する場合、
サンプル入力を `string` のコレクションとして読み取る必要があります:
*)
let lines = """
// Hello world
let hello() =
printfn "Hello world!" """.Split('\r','\n')
(**
複数行の入力値をトークン化する場合も、現在の状態を保持するような
再帰関数が必要になります。
以下の関数はソースコード行を文字列のリストとして受け取ります
(また、行番号および現在の状態も受け取ります)。
各行に対して新しいトークナイザを作成して、
直前の行における **最後** の状態を使って `tokenizeLine` を呼び出します:
*)
/// 複数行のコードに対してトークンの名前を表示します
let rec tokenizeLines state count lines =
match lines with
| line::lines ->
// トークナイザを作成して1行をトークン化
printfn "\nLine %d" count
let tokenizer = sourceTok.CreateLineTokenizer(line)
let state = tokenizeLine tokenizer state
// 新しい状態を使って残りをトークン化
tokenizeLines state (count+1) lines
| [] -> ()
(**
ここでは単に(先ほど定義した) `tokenizeLine` を呼び出して、
各行にあるすべてのトークンの名前を表示しています。
この関数は先と同じく、初期状態の値 `0L` と、1行目を表す `1` を
指定して呼び出すことができます:
*)
lines
|> List.ofSeq
|> tokenizeLines 0L 1
(**
重要ではない部分(各行の先頭にある空白文字や、1行目のように空白文字しかない行)
を除けば、このコードを実行すると以下のような出力になります:
[lang=text]
Line 1
LINE_COMMENT LINE_COMMENT (...) LINE_COMMENT
Line 2
LET WHITESPACE IDENT LPAREN RPAREN WHITESPACE EQUALS
Line 3
IDENT WHITESPACE STRING_TEXT (...) STRING_TEXT STRING
注目すべきは、単一行コメントや文字列に対して、
トークナイザが複数回(大まかにいって単語単位で) `LINE_COMMENT` や
`STRING_TEXT` を返しているところです。
したがって、コメントや文字列全体をテキストとして取得したい場合には
それぞれのトークンを連結する必要があります。
*)
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异由.gitattributes 抑制。
此差异由.gitattributes 抑制。
此差异由.gitattributes 抑制。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件已添加
此差异由.gitattributes 抑制。
此差异已折叠。
此差异已折叠。
此差异已折叠。
frameworks: net45
source https://www.nuget.org/api/v2/
nuget FAKE
nuget FSharp.Formatting
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册