Skip to content

Commit

Permalink
Use ParseFile and FSharpParsingOptions instead of ParseFileInProject
Browse files Browse the repository at this point in the history
  • Loading branch information
dsyme authored and dsyme committed Oct 3, 2017
1 parent 569e076 commit 0af0578
Show file tree
Hide file tree
Showing 55 changed files with 303 additions and 275 deletions.
6 changes: 3 additions & 3 deletions fcs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ which does things like:
Yu can push the packages if you have permissions, either automatically using ``build Release`` or manually

set APIKEY=...
.nuget\nuget.exe push Release\FSharp.Compiler.Service.15.0.1.nupkg %APIKEY% -Source https://nuget.org
.nuget\nuget.exe push Release\FSharp.Compiler.Service.MSBuild.v12.15.0.1.nupkg %APIKEY% -Source https://nuget.org
.nuget\nuget.exe push Release\FSharp.Compiler.Service.ProjectCracker.15.0.1.nupkg %APIKEY% -Source https://nuget.org
.nuget\nuget.exe push Release\FSharp.Compiler.Service.16.0.1.nupkg %APIKEY% -Source https://nuget.org
.nuget\nuget.exe push Release\FSharp.Compiler.Service.MSBuild.v12.16.0.1.nupkg %APIKEY% -Source https://nuget.org
.nuget\nuget.exe push Release\FSharp.Compiler.Service.ProjectCracker.16.0.1.nupkg %APIKEY% -Source https://nuget.org


### Use of Paket and FAKE
Expand Down
4 changes: 4 additions & 0 deletions fcs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#### 16.0.1
* FSharpChecker provides non-reactor ParseFile instead of ParseFileInProject
* Add FSharpParsingOptions, GetParsingOptionsFromProjectOptions, GetParsingOptionsFromCommandLine

#### 15.0.1
* Integrate latest changes from visualfsharp
* Add implementation file contents to CheckFileResults
Expand Down
9 changes: 2 additions & 7 deletions fcs/docsrc/content/caches.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,14 @@ Each FSharpChecker object maintains a set of caches. These are
* ``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,
* ``parseFileCache`` - an MRU cache of size ``parseFileCacheSize`` (default = 2) keeping the results of ParseFile,
keyed by filename, source and project options.
* ``parseAndCheckFileInProjectCache`` - an MRU cache of size ``incrementalTypeCheckCacheSize`` (default = 5) keeping the results of
* ``checkFileInProjectCache`` - 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
Expand Down
7 changes: 5 additions & 2 deletions fcs/docsrc/content/editor.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,19 @@ let projOptions =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously

let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions)

(**
To perform type checking, we first need to parse the input using
`ParseFileInProject`, which gives us access to the [untyped AST](untypedtree.html). However,
`ParseFile`, 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)
checker.ParseFile(file, input, parsingOptions)
|> Async.RunSynchronously
(**
Before we look at the interesting operations provided by `TypeCheckResults`, we
Expand Down
8 changes: 5 additions & 3 deletions fcs/docsrc/content/ja/editor.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,22 @@ let file = "/home/user/Test.fsx"

let projOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously

let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions)

(**
型チェックを実行するには、まず `ParseFileInProject` を使って
型チェックを実行するには、まず `ParseFile` を使って
入力値をパースする必要があります。
このメソッドを使うと [型無しAST](untypedtree.html) にアクセスできるようになります。
しかし今回は完全な型チェックを実行するため、続けて `CheckFileInProject`
を呼び出す必要があります。
このメソッドは `ParseFileInProject` の結果も必要とするため、
このメソッドは `ParseFile` の結果も必要とするため、
たいていの場合にはこれら2つのメソッドをセットで呼び出すことになります。
*)
// パースを実行
let parseFileResults =
checker.ParseFileInProject(file, input, projOptions)
checker.ParseFile(file, input, parsingOptions)
|> Async.RunSynchronously
(**
`TypeCheckResults` に備えられた興味深い機能の紹介に入る前に、
Expand Down
4 changes: 3 additions & 1 deletion fcs/docsrc/content/ja/untypedtree.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ let getUntypedTree (file, input) =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously

let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions)

// コンパイラの第1フェーズを実行する
let untypedRes =
checker.ParseFileInProject(file, input, projectOptions)
checker.ParseFile(file, input, parsingOptions)
|> Async.RunSynchronously

match untypedRes.ParseTree with
Expand Down
6 changes: 4 additions & 2 deletions fcs/docsrc/content/untypedtree.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ To get the AST, we define a function that takes file name and the source code
(the file is only used for location information and does not have to exist).
We first need to get "interactive checker options" which represents the context.
For simple tasks, you can use `GetProjectOptionsFromScriptRoot` which infers
the context for a script file. Then we use the `ParseFileInProject` method and
the context for a script file. Then we use the `ParseFile` method and
return the `ParseTree` property:
*)
Expand All @@ -60,9 +60,11 @@ let getUntypedTree (file, input) =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously

let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions)

// Run the first phase (untyped parsing) of the compiler
let parseFileResults =
checker.ParseFileInProject(file, input, projOptions)
checker.ParseFile(file, input, parsingOptions)
|> Async.RunSynchronously

match parseFileResults.ParseTree with
Expand Down
2 changes: 1 addition & 1 deletion fcs/fcs.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>

<VersionPrefix>15.0.1</VersionPrefix>
<VersionPrefix>16.0.1</VersionPrefix>
<!-- FSharp.Compiler.Tools is currently only used to get a working FSI.EXE to execute some scripts during the build -->
<!-- The LKG FSI.EXE requires MSBuild 15 to be installed, which is painful -->
<FsiToolPath>$(FSharpSourcesRoot)\..\packages\FSharp.Compiler.Tools.4.1.23\tools</FsiToolPath>
Expand Down
2 changes: 1 addition & 1 deletion fcs/nuget/FSharp.Compiler.Service.MSBuild.v12.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</description>
<language>en-US</language>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<version>15.0.1</version>
<version>16.0.1</version>
<authors>Microsoft Corporation and F# community contributors</authors>
<licenseUrl>https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/fsharp/FSharp.Compiler.Service</projectUrl>
Expand Down
2 changes: 1 addition & 1 deletion fcs/nuget/FSharp.Compiler.Service.ProjectCracker.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</description>
<language>en-US</language>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<version>15.0.1</version>
<version>16.0.1</version>
<authors>Microsoft Corporation and F# community contributors</authors>
<licenseUrl>https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/fsharp/FSharp.Compiler.Service</projectUrl>
Expand Down
2 changes: 1 addition & 1 deletion fcs/nuget/FSharp.Compiler.Service.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</description>
<language>en-US</language>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<version>15.0.1</version>
<version>16.0.1</version>
<authors>Microsoft Corporation and F# community contributors</authors>
<licenseUrl>https://github.com/fsharp/FSharp.Compiler.Service/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/fsharp/FSharp.Compiler.Service</projectUrl>
Expand Down
3 changes: 2 additions & 1 deletion fcs/samples/EditorService/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ let checker = FSharpChecker.Create()

let parseWithTypeInfo (file, input) =
let checkOptions, _errors = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously
let untypedRes = checker.ParseFileInProject(file, input, checkOptions) |> Async.RunSynchronously
let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(checkOptions)
let untypedRes = checker.ParseFile(file, input, parsingOptions) |> Async.RunSynchronously

match checker.CheckFileInProject(untypedRes, file, 0, input, checkOptions) |> Async.RunSynchronously with
| FSharpCheckFileAnswer.Succeeded(res) -> untypedRes, res
Expand Down
67 changes: 28 additions & 39 deletions src/fsharp/vs/service.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ type internal Layout = StructuredFormat.Layout

[<AutoOpen>]
module EnvMisc =
let getToolTipTextSize = GetEnvInteger "FCS_RecentForegroundTypeCheckCacheSize" 5
let getToolTipTextSize = GetEnvInteger "FCS_GetToolTipTextCacheSize" 5
let maxTypeCheckErrorsOutOfProjectContext = GetEnvInteger "FCS_MaxErrorsOutOfProjectContext" 3
let braceMatchCacheSize = GetEnvInteger "FCS_BraceMatchCacheSize" 5
let parseFileInProjectCacheSize = GetEnvInteger "FCS_ParseFileInProjectCacheSize" 2
let incrementalTypeCheckCacheSize = GetEnvInteger "FCS_IncrementalTypeCheckCacheSize" 5
let parseFileCacheSize = GetEnvInteger "FCS_ParseFileCacheSize" 2
let checkFileInProjectCacheSize = GetEnvInteger "FCS_CheckFileInProjectCacheSize" 5

let projectCacheSizeDefault = GetEnvInteger "FCS_ProjectCacheSizeDefault" 3
let frameworkTcImportsCacheStrongSize = GetEnvInteger "FCS_frameworkTcImportsCacheStrongSizeDefault" 8
Expand Down Expand Up @@ -2307,26 +2307,26 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC


// STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.parseFileInProjectCache. Most recently used cache for parsing files.
let parseFileCache = MruCache<ParseCacheLockToken,_,_>(parseFileInProjectCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing)
let parseFileCache = MruCache<ParseCacheLockToken,_,_>(parseFileCacheSize, areSimilar = AreSimilarForParsing, areSame = AreSameForParsing)

// STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.parseAndCheckFileInProjectCachePossiblyStale
// STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.parseAndCheckFileInProjectCache
// STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.checkFileInProjectCachePossiblyStale
// STATIC ROOT: FSharpLanguageServiceTestable.FSharpChecker.checkFileInProjectCache
//
/// Cache which holds recently seen type-checks.
/// This cache may hold out-of-date entries, in two senses
/// - there may be a more recent antecedent state available because the background build has made it available
/// - the source for the file may have changed
let parseAndCheckFileInProjectCachePossiblyStale =
let checkFileInProjectCachePossiblyStale =
MruCache<ParseCacheLockToken,string * FSharpProjectOptions, FSharpParseFileResults * FSharpCheckFileResults * int>
(keepStrongly=incrementalTypeCheckCacheSize,
(keepStrongly=checkFileInProjectCacheSize,
areSame=AreSameForChecking2,
areSimilar=AreSubsumable2)

// Also keyed on source. This can only be out of date if the antecedent is out of date
let parseAndCheckFileInProjectCache =
let checkFileInProjectCache =
MruCache<ParseCacheLockToken,FileName * Source * FSharpProjectOptions, FSharpParseFileResults * FSharpCheckFileResults * FileVersion * DateTime>
(keepStrongly=incrementalTypeCheckCacheSize,
(keepStrongly=checkFileInProjectCacheSize,
areSame=AreSameForChecking3,
areSimilar=AreSubsumable3)

Expand Down Expand Up @@ -2366,8 +2366,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
| Some (FSharpCheckFileAnswer.Succeeded typedResults) ->
foregroundTypeCheckCount <- foregroundTypeCheckCount + 1
parseCacheLock.AcquireLock (fun ltok ->
parseAndCheckFileInProjectCachePossiblyStale.Set(ltok, (filename,options),(parseResults,typedResults,fileVersion))
parseAndCheckFileInProjectCache.Set(ltok, (filename,source,options),(parseResults,typedResults,fileVersion,priorTimeStamp))
checkFileInProjectCachePossiblyStale.Set(ltok, (filename,options),(parseResults,typedResults,fileVersion))
checkFileInProjectCache.Set(ltok, (filename,source,options),(parseResults,typedResults,fileVersion,priorTimeStamp))
parseFileCache.Set(ltok, (filename, source, parsingOptions), parseResults))

member bc.ImplicitlyStartCheckProjectInBackground(options, userOpName) =
Expand Down Expand Up @@ -2403,7 +2403,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC

member bc.GetCachedCheckFileResult(builder: IncrementalBuilder,filename,source,options) =
// Check the cache. We can only use cached results when there is no work to do to bring the background builder up-to-date
let cachedResults = parseCacheLock.AcquireLock (fun ltok -> parseAndCheckFileInProjectCache.TryGet(ltok, (filename,source,options)))
let cachedResults = parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCache.TryGet(ltok, (filename,source,options)))

match cachedResults with
// | Some (parseResults, checkResults, _, _) when builder.AreCheckResultsBeforeFileInProjectReady(filename) ->
Expand Down Expand Up @@ -2620,10 +2620,10 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
match source with
| Some sourceText ->
parseCacheLock.AcquireLock (fun ltok ->
match parseAndCheckFileInProjectCache.TryGet(ltok,(filename,sourceText,options)) with
match checkFileInProjectCache.TryGet(ltok,(filename,sourceText,options)) with
| Some (a,b,c,_) -> Some (a,b,c)
| None -> None)
| None -> parseCacheLock.AcquireLock (fun ltok -> parseAndCheckFileInProjectCachePossiblyStale.TryGet(ltok,(filename,options)))
| None -> parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCachePossiblyStale.TryGet(ltok,(filename,options)))

/// Parse and typecheck the whole project (the implementation, called recursively as project graph is evaluated)
member private bc.ParseAndCheckProjectImpl(options, ctok, userOpName) : Cancellable<FSharpCheckProjectResults> =
Expand Down Expand Up @@ -2774,8 +2774,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
member bc.ClearCachesAsync (userOpName) =
reactor.EnqueueAndAwaitOpAsync (userOpName, "ClearCachesAsync", "", fun ctok ->
parseCacheLock.AcquireLock (fun ltok ->
parseAndCheckFileInProjectCachePossiblyStale.Clear ltok
parseAndCheckFileInProjectCache.Clear ltok
checkFileInProjectCachePossiblyStale.Clear ltok
checkFileInProjectCache.Clear ltok
parseFileCache.Clear(ltok))
incrementalBuildersCache.Clear ctok
frameworkTcImportsCache.Clear ctok
Expand All @@ -2785,8 +2785,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
member bc.DownsizeCaches(userOpName) =
reactor.EnqueueAndAwaitOpAsync (userOpName, "DownsizeCaches", "", fun ctok ->
parseCacheLock.AcquireLock (fun ltok ->
parseAndCheckFileInProjectCachePossiblyStale.Resize(ltok, keepStrongly=1)
parseAndCheckFileInProjectCache.Resize(ltok, keepStrongly=1)
checkFileInProjectCachePossiblyStale.Resize(ltok, keepStrongly=1)
checkFileInProjectCache.Resize(ltok, keepStrongly=1)
parseFileCache.Resize(ltok, keepStrongly=1))
incrementalBuildersCache.Resize(ctok, keepStrongly=1, keepMax=1)
frameworkTcImportsCache.Downsize(ctok)
Expand Down Expand Up @@ -2849,15 +2849,15 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten
return res
}

member ic.GetParsingOptionsFromProjectOptions(options): FSharpParsingOptions =
member ic.GetParsingOptionsFromProjectOptions(options): FSharpParsingOptions * _ =
let sourceFiles = List.ofArray options.SourceFiles
let argv = List.ofArray options.OtherOptions
let parsingOptions, _ = ic.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv)
parsingOptions
ic.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv)

member ic.MatchBraces(filename, source, options: FSharpProjectOptions, ?userOpName: string) =
let userOpName = defaultArg userOpName "Unknown"
ic.MatchBraces(filename, source, ic.GetParsingOptionsFromProjectOptions(options), userOpName)
let parsingOptions, _ = ic.GetParsingOptionsFromProjectOptions(options)
ic.MatchBraces(filename, source, parsingOptions, userOpName)

member ic.ParseFile(filename, source, options, ?userOpName: string) =
let userOpName = defaultArg userOpName "Unknown"
Expand All @@ -2867,7 +2867,8 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten

member ic.ParseFileInProject(filename, source, options, ?userOpName: string) =
let userOpName = defaultArg userOpName "Unknown"
ic.ParseFile(filename, source, ic.GetParsingOptionsFromProjectOptions(options), userOpName)
let parsingOptions, _ = ic.GetParsingOptionsFromProjectOptions(options)
ic.ParseFile(filename, source, parsingOptions, userOpName)

member ic.GetBackgroundParseResultsForFileInProject (filename,options, ?userOpName: string) =
let userOpName = defaultArg userOpName "Unknown"
Expand Down Expand Up @@ -3177,21 +3178,9 @@ module CompilerEnvironment =
let DefaultReferencesForOrphanSources(assumeDotNetFramework) = DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework)

/// Publish compiler-flags parsing logic. Must be fast because its used by the colorizer.
let GetCompilationDefinesForEditing(filename:string, compilerFlags : string list) =
let defines = ref(SourceFileImpl.AdditionalDefinesForUseInEditor(filename))
let MatchAndExtract(flag:string,prefix:string) =
if flag.StartsWith(prefix) then
let sub = flag.Substring(prefix.Length)
let trimmed = sub.Trim()
defines := trimmed :: !defines
let rec QuickParseDefines = function
| hd :: tail ->
MatchAndExtract(hd,"-d:")
MatchAndExtract(hd,"--define:")
QuickParseDefines tail
| _ -> ()
QuickParseDefines compilerFlags
!defines
let GetCompilationDefinesForEditing(filename:string, parsingOptions: FSharpParsingOptions) =
SourceFileImpl.AdditionalDefinesForUseInEditor(filename) @
parsingOptions.ConditionalCompilationDefines

/// Return true if this is a subcategory of error or warning message that the language service can emit
let IsCheckerSupportedSubcategory(subcategory:string) =
Expand Down
Loading

0 comments on commit 0af0578

Please sign in to comment.