未验证 提交 eb75fcc5 编写于 作者: D Don Syme 提交者: GitHub

Fix de-duplication of module names (#6086)

* possible fix for signature issue

* fix de-duplication
上级 03e8aa59
......@@ -3520,34 +3520,37 @@ let PostParseModuleSpecs (defaultNamespace, filename, isLastCompiland, ParsedSig
ParsedInput.SigFile(ParsedSigFileInput(filename, qualName, scopedPragmas, hashDirectives, specs))
/// Checks if a module name is already given and deduplicates the name if needed.
let DeduplicateModuleName (moduleNamesDict:IDictionary<string, Set<string>>) (paths: Set<string>) path (qualifiedNameOfFile: QualifiedNameOfFile) =
let count = if paths.Contains path then paths.Count else paths.Count + 1
moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.add path paths
let id = qualifiedNameOfFile.Id
if count = 1 then qualifiedNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(), id.idRange))
type ModuleNamesDict = Map<string,Map<string,QualifiedNameOfFile>>
/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed.
let DeduplicateParsedInputModuleName (moduleNamesDict:IDictionary<string, Set<string>>) input =
match input with
| ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) ->
let path = Path.GetDirectoryName fileName
match moduleNamesDict.TryGetValue qualifiedNameOfFile.Text with
| true, paths ->
let qualifiedNameOfFile = DeduplicateModuleName moduleNamesDict paths path qualifiedNameOfFile
ParsedInput.ImplFile(ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe)))
| _ ->
moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.singleton path
input
| ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules)) ->
/// Checks if a module name is already given and deduplicates the name if needed.
let DeduplicateModuleName (moduleNamesDict:ModuleNamesDict) fileName (qualNameOfFile: QualifiedNameOfFile) =
let path = Path.GetDirectoryName fileName
match moduleNamesDict.TryGetValue qualifiedNameOfFile.Text with
let path = if FileSystem.IsPathRootedShim path then try FileSystem.GetFullPathShim path with _ -> path else path
match moduleNamesDict.TryGetValue qualNameOfFile.Text with
| true, paths ->
let qualifiedNameOfFile = DeduplicateModuleName moduleNamesDict paths path qualifiedNameOfFile
ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualifiedNameOfFile, scopedPragmas, hashDirectives, modules))
if paths.ContainsKey path then
paths.[path], moduleNamesDict
else
let count = paths.Count + 1
let id = qualNameOfFile.Id
let qualNameOfFileT = if count = 1 then qualNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(), id.idRange))
let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, paths.Add(path, qualNameOfFileT))
qualNameOfFileT, moduleNamesDictT
| _ ->
moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.singleton path
input
let moduleNamesDictT = moduleNamesDict.Add(qualNameOfFile.Text, Map.empty.Add(path, qualNameOfFile))
qualNameOfFile, moduleNamesDictT
/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed.
let DeduplicateParsedInputModuleName (moduleNamesDict: ModuleNamesDict) input =
match input with
| ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualNameOfFile, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe))) ->
let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile
let inputT = ParsedInput.ImplFile(ParsedImplFileInput.ParsedImplFileInput(fileName, isScript, qualNameOfFileT, scopedPragmas, hashDirectives, modules, (isLastCompiland, isExe)))
inputT, moduleNamesDictT
| ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualNameOfFile, scopedPragmas, hashDirectives, modules)) ->
let qualNameOfFileT, moduleNamesDictT = DeduplicateModuleName moduleNamesDict fileName qualNameOfFile
let inputT = ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName, qualNameOfFileT, scopedPragmas, hashDirectives, modules))
inputT, moduleNamesDictT
let ParseInput (lexer, errorLogger:ErrorLogger, lexbuf:UnicodeLexing.Lexbuf, defaultNamespace, filename, isLastCompiland) =
// The assert below is almost ok, but it fires in two cases:
......
......@@ -59,12 +59,13 @@ val ComputeQualifiedNameOfFileFromUniquePath: range * string list -> Ast.Qualifi
val PrependPathToInput: Ast.Ident list -> Ast.ParsedInput -> Ast.ParsedInput
/// Checks if a module name is already given and deduplicates the name if needed.
val DeduplicateModuleName: IDictionary<string,Set<string>> -> Set<string> -> string -> Ast.QualifiedNameOfFile -> Ast.QualifiedNameOfFile
/// State used to de-deuplicate module names along a list of file names
type ModuleNamesDict = Map<string,Map<string,QualifiedNameOfFile>>
/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed.
val DeduplicateParsedInputModuleName: IDictionary<string,Set<string>> -> Ast.ParsedInput -> Ast.ParsedInput
val DeduplicateParsedInputModuleName: ModuleNamesDict -> Ast.ParsedInput -> Ast.ParsedInput * ModuleNamesDict
/// Parse a single input (A signature file or implementation file)
val ParseInput: (UnicodeLexing.Lexbuf -> Parser.token) * ErrorLogger * UnicodeLexing.Lexbuf * string option * string * isLastCompiland:(bool * bool) -> Ast.ParsedInput
//----------------------------------------------------------------------------
......
......@@ -10060,7 +10060,7 @@ and TcMethodApplication
| CallerLineNumber, _ when typeEquiv cenv.g currCalledArgTy cenv.g.int_ty ->
emptyPreBinder, Expr.Const(Const.Int32(mMethExpr.StartLine), mMethExpr, currCalledArgTy)
| CallerFilePath, _ when typeEquiv cenv.g currCalledArgTy cenv.g.string_ty ->
emptyPreBinder, Expr.Const(Const.String(System.IO.Path.GetFullPath(mMethExpr.FileName)), mMethExpr, currCalledArgTy)
emptyPreBinder, Expr.Const(Const.String(FileSystem.GetFullPathShim(mMethExpr.FileName)), mMethExpr, currCalledArgTy)
| CallerMemberName, Some(callerName) when (typeEquiv cenv.g currCalledArgTy cenv.g.string_ty) ->
emptyPreBinder, Expr.Const(Const.String(callerName), mMethExpr, currCalledArgTy)
| _ ->
......@@ -10099,7 +10099,7 @@ and TcMethodApplication
let lineExpr = Expr.Const(Const.Int32(mMethExpr.StartLine), mMethExpr, calledNonOptTy)
emptyPreBinder, mkUnionCaseExpr(mkSomeCase cenv.g, [calledNonOptTy], [lineExpr], mMethExpr)
| CallerFilePath, _ when typeEquiv cenv.g calledNonOptTy cenv.g.string_ty ->
let filePathExpr = Expr.Const(Const.String(System.IO.Path.GetFullPath(mMethExpr.FileName)), mMethExpr, calledNonOptTy)
let filePathExpr = Expr.Const(Const.String(FileSystem.GetFullPathShim(mMethExpr.FileName)), mMethExpr, calledNonOptTy)
emptyPreBinder, mkUnionCaseExpr(mkSomeCase cenv.g, [calledNonOptTy], [filePathExpr], mMethExpr)
| CallerMemberName, Some(callerName) when typeEquiv cenv.g calledNonOptTy cenv.g.string_ty ->
let memberNameExpr = Expr.Const(Const.String(callerName), mMethExpr, calledNonOptTy)
......
......@@ -1773,11 +1773,9 @@ let main0(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemor
errorRecoveryNoRange e
exiter.Exit 1
let inputs =
// Deduplicate module names
let moduleNamesDict = ConcurrentDictionary<string,Set<string>>()
inputs
|> List.map (fun (input,x) -> DeduplicateParsedInputModuleName moduleNamesDict input,x)
let inputs, _ =
(Map.empty, inputs)
||> List.mapFold (fun state (input,x) -> let inputT, stateT = DeduplicateParsedInputModuleName state input in (inputT,x), stateT)
if tcConfig.parseOnly then exiter.Exit 0
if not tcConfig.continueAfterParseFailure then
......@@ -2036,7 +2034,7 @@ let main4 dynamicAssemblyCreator (Args (ctok, tcConfig, tcImports: TcImports, t
DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok
let pdbfile = pdbfile |> Option.map (tcConfig.MakePathAbsolute >> Path.GetFullPath)
let pdbfile = pdbfile |> Option.map (tcConfig.MakePathAbsolute >> FileSystem.GetFullPathShim)
let normalizeAssemblyRefs (aref:ILAssemblyRef) =
match tcImports.TryFindDllInfo (ctok, Range.rangeStartup, aref.Name, lookupOnly=false) with
......
......@@ -197,7 +197,7 @@ type range(code1:int64, code2: int64) =
let mkRange f b e =
// remove relative parts from full path
let normalizedFilePath = if Path.IsPathRooted f then try Path.GetFullPath f with _ -> f else f
let normalizedFilePath = if FileSystem.IsPathRootedShim f then try FileSystem.GetFullPathShim f with _ -> f else f
range (fileIndexOfFile normalizedFilePath, b, e)
let mkFileIndexRange fi b e = range (fi, b, e)
......
......@@ -55,15 +55,16 @@ module internal IncrementalBuild =
/// Get the Id for the given ScalarBuildRule.
member x.Id =
match x with
| ScalarInput(id, _) ->id
| ScalarDemultiplex(id, _, _, _) ->id
| ScalarMap(id, _, _, _) ->id
| ScalarInput(id, _) -> id
| ScalarDemultiplex(id, _, _, _) -> id
| ScalarMap(id, _, _, _) -> id
/// Get the Name for the givenScalarExpr.
member x.Name =
match x with
| ScalarInput(_, n) ->n
| ScalarDemultiplex(_, n, _, _) ->n
| ScalarMap(_, n, _, _) ->n
| ScalarInput(_, n) -> n
| ScalarDemultiplex(_, n, _, _) -> n
| ScalarMap(_, n, _, _) -> n
/// A build rule with a vector of outputs
and VectorBuildRule =
......@@ -1034,6 +1035,7 @@ type TypeCheckAccumulator =
/// Accumulated 'open' declarations, last file first
tcOpenDeclarationsRev: OpenDeclaration[] list
topAttribs:TopAttribs option
/// Result of checking most recent file, if any
......@@ -1043,6 +1045,9 @@ type TypeCheckAccumulator =
tcDependencyFiles: string list
/// Disambiguation table for module names
tcModuleNamesDict: ModuleNamesDict
/// Accumulated errors, last file first
tcErrorsRev:(PhasedDiagnostic * FSharpErrorSeverity)[] list }
......@@ -1125,10 +1130,17 @@ type PartialCheckResults =
/// Kept in a stack so that each incremental update shares storage with previous files
TcOpenDeclarationsRev: OpenDeclaration[] list
/// Disambiguation table for module names
ModuleNamesDict: ModuleNamesDict
TcDependencyFiles: string list
TopAttribs: TopAttribs option
TimeStamp: DateTime
LatestImplementationFile: TypedImplFile option
LastestCcuSigForFile: ModuleOrNamespaceType option }
member x.TcErrors = Array.concat (List.rev x.TcErrorsRev)
......@@ -1146,6 +1158,7 @@ type PartialCheckResults =
TcOpenDeclarationsRev = tcAcc.tcOpenDeclarationsRev
TcDependencyFiles = tcAcc.tcDependencyFiles
TopAttribs = tcAcc.topAttribs
ModuleNamesDict = tcAcc.tcModuleNamesDict
TimeStamp = timestamp
LatestImplementationFile = tcAcc.latestImplFile
LastestCcuSigForFile = tcAcc.latestCcuSigForFile }
......@@ -1175,7 +1188,9 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState:
yield (ccuName, (fun () -> r.GetBytes())) ]
let autoOpenAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_AutoOpenAttribute)
let ivtAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute)
interface IRawFSharpAssemblyData with
member __.GetAutoOpenAttributes(_ilg) = autoOpenAttrs
member __.GetInternalsVisibleToAttributes(_ilg) = ivtAttrs
......@@ -1246,6 +1261,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
let assertNotDisposed() =
if disposed then
System.Diagnostics.Debug.Assert(false, "IncrementalBuild object has already been disposed!")
let mutable referenceCount = 0
//----------------------------------------------------
......@@ -1258,14 +1274,9 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
assertNotDisposed()
cache.GetFileTimeStamp filename
// Deduplicate module names
let moduleNamesDict = ConcurrentDictionary<string, Set<string>>()
/// This is a build task function that gets placed into the build rules as the computation for a VectorMap
///
/// Parse the given files and return the given inputs. This function is expected to be
/// able to be called with a subset of sourceFiles and return the corresponding subset of
/// parsed inputs.
/// Parse the given file and return the given input.
let ParseTask ctok (sourceRange:range, filename:string, isLastCompiland) =
assertNotDisposed()
DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok
......@@ -1278,9 +1289,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename)
let input = ParseOneInputFile(tcConfig, lexResourceManager, [], filename , isLastCompiland, errorLogger, (*retryLocked*)true)
fileParsed.Trigger (filename)
let result = Option.map (DeduplicateParsedInputModuleName moduleNamesDict) input
result, sourceRange, filename, errorLogger.GetErrors ()
input, sourceRange, filename, errorLogger.GetErrors ()
with exn ->
let msg = sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString())
System.Diagnostics.Debug.Assert(false, msg)
......@@ -1357,7 +1367,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
latestImplFile=None
latestCcuSigForFile=None
tcDependencyFiles=basicDependencies
tcErrorsRev = [ initialErrors ] }
tcErrorsRev = [ initialErrors ]
tcModuleNamesDict = Map.empty }
return tcAcc }
/// This is a build task function that gets placed into the build rules as the computation for a Vector.ScanLeft
......@@ -1378,6 +1389,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
let sink = TcResultsSinkImpl(tcAcc.tcGlobals)
let hadParseErrors = not (Array.isEmpty parseErrors)
let input, moduleNamesDict = DeduplicateParsedInputModuleName tcAcc.tcModuleNamesDict input
let! (tcEnvAtEndOfFile, topAttribs, implFile, ccuSigForFile), tcState =
TypeCheckOneInputEventually
((fun () -> hadParseErrors || errorLogger.ErrorCount > 0),
......@@ -1406,6 +1419,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
tcSymbolUsesRev=tcSymbolUses :: tcAcc.tcSymbolUsesRev
tcOpenDeclarationsRev = sink.GetOpenDeclarations() :: tcAcc.tcOpenDeclarationsRev
tcErrorsRev = newErrors :: tcAcc.tcErrorsRev
tcModuleNamesDict = moduleNamesDict
tcDependencyFiles = filename :: tcAcc.tcDependencyFiles }
}
......@@ -1561,9 +1575,9 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
member this.IncrementUsageCount() =
assertNotDisposed()
System.Threading.Interlocked.Increment(&referenceCount) |> ignore
{ new System.IDisposable with member x.Dispose() = this.DecrementUsageCount() }
{ new System.IDisposable with member __.Dispose() = this.DecrementUsageCount() }
member this.DecrementUsageCount() =
member __.DecrementUsageCount() =
assertNotDisposed()
let currentValue = System.Threading.Interlocked.Decrement(&referenceCount)
if currentValue = 0 then
......@@ -1573,11 +1587,17 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
member __.IsAlive = referenceCount > 0
member __.TcConfig = tcConfig
member __.FileParsed = fileParsed.Publish
member __.BeforeFileChecked = beforeFileChecked.Publish
member __.FileChecked = fileChecked.Publish
member __.ProjectChecked = projectChecked.Publish
member __.ImportedCcusInvalidated = importsInvalidated.Publish
member __.AllDependenciesDeprecated = allDependencies
#if !NO_EXTENSIONTYPING
......@@ -1622,7 +1642,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
| (*first file*) 0 -> IncrementalBuild.IsReady cache (Target(initialTcAccNode, None)) partialBuild
| _ -> IncrementalBuild.IsReady cache (Target(tcStatesNode, Some (slotOfFile-1))) partialBuild
member builder.GetCheckResultsBeforeSlotInProject (ctok: CompilationThreadToken, slotOfFile) =
member __.GetCheckResultsBeforeSlotInProject (ctok: CompilationThreadToken, slotOfFile) =
cancellable {
let cache = TimeStampCache(defaultTimeStamp)
let! result =
......@@ -1652,9 +1672,6 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
member builder.GetCheckResultsAfterLastFileInProject (ctok: CompilationThreadToken) =
builder.GetCheckResultsBeforeSlotInProject(ctok, builder.GetSlotsCount())
member builder.DeduplicateParsedInputModuleNameInProject (input) =
DeduplicateParsedInputModuleName moduleNamesDict input
member __.GetCheckResultsAndImplementationsForProject(ctok: CompilationThreadToken) =
cancellable {
let cache = TimeStampCache(defaultTimeStamp)
......@@ -1861,10 +1878,11 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
return builderOpt, diagnostics
}
static member KeepBuilderAlive (builderOpt: IncrementalBuilder option) =
match builderOpt with
| Some builder -> builder.IncrementUsageCount()
| None -> { new System.IDisposable with member __.Dispose() = () }
member builder.IsBeingKeptAliveApartFromCacheEntry = (referenceCount >= 2)
member __.IsBeingKeptAliveApartFromCacheEntry = (referenceCount >= 2)
......@@ -55,6 +55,9 @@ type internal PartialCheckResults =
/// Represents open declarations
TcOpenDeclarationsRev: OpenDeclaration[] list
/// Disambiguation table for module names
ModuleNamesDict: ModuleNamesDict
TcDependencyFiles: string list
/// Represents the collected attributes to apply to the module of assuembly generates
......@@ -151,8 +154,6 @@ type internal IncrementalBuilder =
// TODO: make this an Eventually (which can be scheduled) or an Async (which can be cancelled)
member GetCheckResultsAndImplementationsForProject : CompilationThreadToken -> Cancellable<PartialCheckResults * IL.ILAssemblyRef * IRawFSharpAssemblyData option * TypedImplFile list option>
member DeduplicateParsedInputModuleNameInProject: Ast.ParsedInput -> Ast.ParsedInput
/// Get the logical time stamp that is associated with the output of the project if it were gully built immediately
member GetLogicalTimeStampForProject: TimeStampCache * CompilationThreadToken -> DateTime
......
......@@ -1624,6 +1624,7 @@ module internal Parser =
tcGlobals: TcGlobals,
tcImports: TcImports,
tcState: TcState,
moduleNamesDict: ModuleNamesDict,
loadClosure: LoadClosure option,
// These are the errors and warnings seen by the background compiler for the entire antecedent
backgroundDiagnostics: (PhasedDiagnostic * FSharpErrorSeverity)[],
......@@ -1727,6 +1728,9 @@ module internal Parser =
async {
try
let checkForErrors() = (parseResults.ParseHadErrors || errHandler.ErrorCount > 0)
let parsedMainInput, _moduleNamesDict = DeduplicateParsedInputModuleName moduleNamesDict parsedMainInput
// Typecheck is potentially a long running operation. We chop it up here with an Eventually continuation and, at each slice, give a chance
// for the client to claim the result as obsolete and have the typecheck abort.
......@@ -2605,7 +2609,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
let loadClosure = scriptClosureCacheLock.AcquireLock (fun ltok -> scriptClosureCache.TryGet (ltok, options))
let! tcErrors, tcFileResult =
Parser.CheckOneFile(parseResults, source, fileName, options.ProjectFileName, tcPrior.TcConfig, tcPrior.TcGlobals, tcPrior.TcImports,
tcPrior.TcState, loadClosure, tcPrior.TcErrors, reactorOps, (fun () -> builder.IsAlive), textSnapshotInfo, userOpName)
tcPrior.TcState, tcPrior.ModuleNamesDict, loadClosure, tcPrior.TcErrors, reactorOps, (fun () -> builder.IsAlive), textSnapshotInfo, userOpName)
let parsingOptions = FSharpParsingOptions.FromTcConfig(tcPrior.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules)
let checkAnswer = MakeCheckFileAnswer(fileName, tcFileResult, options, builder, Array.ofList tcPrior.TcDependencyFiles, creationErrors, parseResults.Errors, tcErrors)
bc.RecordTypeCheckFileInProjectResults(fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, source)
......@@ -2686,9 +2690,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
| _ ->
Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "CheckFileInProject.CacheMiss", filename)
let! tcPrior = execWithReactorAsync <| fun ctok -> builder.GetCheckResultsBeforeFileInProject (ctok, filename)
let parseTreeOpt = parseResults.ParseTree |> Option.map builder.DeduplicateParsedInputModuleNameInProject
let parseResultsAterDeDuplication = FSharpParseFileResults(parseResults.Errors, parseTreeOpt, parseResults.ParseHadErrors, parseResults.DependencyFiles)
let! checkAnswer = bc.CheckOneFileImpl(parseResultsAterDeDuplication, source, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName)
let! checkAnswer = bc.CheckOneFileImpl(parseResults, source, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName)
return checkAnswer
finally
bc.ImplicitlyStartCheckProjectInBackground(options, userOpName)
......@@ -2731,7 +2733,6 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
// Do the parsing.
let parsingOptions = FSharpParsingOptions.FromTcConfig(builder.TcConfig, Array.ofList (builder.SourceFiles), options.UseScriptResolutionRules)
let parseErrors, parseTreeOpt, anyErrors = Parser.parseFile (source, filename, parsingOptions, userOpName)
let parseTreeOpt = parseTreeOpt |> Option.map builder.DeduplicateParsedInputModuleNameInProject
let parseResults = FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, builder.AllDependenciesDeprecated)
let! checkResults = bc.CheckOneFileImpl(parseResults, source, filename, options, textSnapshotInfo, fileVersion, builder, tcPrior, creationErrors, userOpName)
......@@ -3331,7 +3332,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, reactorOps: IReactorOperatio
CompileOptions.ParseCompilerOptions (ignore, fsiCompilerOptions, [ ])
let loadClosure = LoadClosure.ComputeClosureOfScriptText(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, source, CodeContext.Editing, tcConfig.useSimpleResolution, tcConfig.useFsiAuxLib, new Lexhelp.LexResourceManager(), applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot=(fun _ -> None), reduceMemoryUsage=reduceMemoryUsage)
let! tcErrors, tcFileResult = Parser.CheckOneFile(parseResults, source, filename, "project", tcConfig, tcGlobals, tcImports, tcState, Some loadClosure, backgroundDiagnostics, reactorOps, (fun () -> true), None, userOpName)
let! tcErrors, tcFileResult = Parser.CheckOneFile(parseResults, source, filename, "project", tcConfig, tcGlobals, tcImports, tcState, Map.empty, Some loadClosure, backgroundDiagnostics, reactorOps, (fun () -> true), None, userOpName)
return
match tcFileResult with
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册