Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
eb75fcc5
F
fsharp
项目概览
dotNET Platform
/
fsharp
12 个月 前同步成功
通知
0
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
fsharp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
eb75fcc5
编写于
1月 14, 2019
作者:
D
Don Syme
提交者:
GitHub
1月 14, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix de-duplication of module names (#6086)
* possible fix for signature issue * fix de-duplication
上级
03e8aa59
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
136 addition
and
114 deletion
+136
-114
src/fsharp/CompileOps.fs
src/fsharp/CompileOps.fs
+27
-24
src/fsharp/CompileOps.fsi
src/fsharp/CompileOps.fsi
+4
-3
src/fsharp/TypeChecker.fs
src/fsharp/TypeChecker.fs
+2
-2
src/fsharp/fsc.fs
src/fsharp/fsc.fs
+4
-6
src/fsharp/range.fs
src/fsharp/range.fs
+1
-1
src/fsharp/service/IncrementalBuild.fs
src/fsharp/service/IncrementalBuild.fs
+88
-70
src/fsharp/service/IncrementalBuild.fsi
src/fsharp/service/IncrementalBuild.fsi
+3
-2
src/fsharp/service/service.fs
src/fsharp/service/service.fs
+7
-6
未找到文件。
src/fsharp/CompileOps.fs
浏览文件 @
eb75fcc5
...
...
@@ -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:
...
...
src/fsharp/CompileOps.fsi
浏览文件 @
eb75fcc5
...
...
@@ -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
.
ParsedInpu
t
val
DeduplicateParsedInputModuleName
:
ModuleNamesDict
->
Ast
.
ParsedInput
->
Ast
.
ParsedInput
*
ModuleNamesDic
t
/// 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
//----------------------------------------------------------------------------
...
...
src/fsharp/TypeChecker.fs
浏览文件 @
eb75fcc5
...
...
@@ -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)
...
...
src/fsharp/fsc.fs
浏览文件 @
eb75fcc5
...
...
@@ -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
...
...
src/fsharp/range.fs
浏览文件 @
eb75fcc5
...
...
@@ -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
)
...
...
src/fsharp/service/IncrementalBuild.fs
浏览文件 @
eb75fcc5
...
...
@@ -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
resul
t
,
sourceRange
,
filename
,
errorLogger
.
GetErrors
()
inpu
t
,
sourceRange
,
filename
,
errorLogger
.
GetErrors
()
with
exn
->
let
msg
=
sprintf
"unexpected failure in IncrementalFSharpBuild.Parse
\n
error = %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
)
src/fsharp/service/IncrementalBuild.fsi
浏览文件 @
eb75fcc5
...
...
@@ -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
...
...
src/fsharp/service/service.fs
浏览文件 @
eb75fcc5
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录