未验证 提交 9d2bd94f 编写于 作者: D dotnet bot 提交者: GitHub

Merge pull request #14531 from dotnet/merges/main-to-release/dev17.5

Merge main to release/dev17.5
......@@ -502,9 +502,7 @@ type cenv =
emitTailcalls: bool
deterministic: bool
showTimes: bool
deterministic: bool
desiredMetadataVersion: ILVersionInfo
......@@ -3023,14 +3021,14 @@ let GenModule (cenv : cenv) (modul: ILModuleDef) =
let midx = AddUnsharedRow cenv TableNames.Module (GetModuleAsRow cenv modul)
List.iter (GenResourcePass3 cenv) (modul.Resources.AsList())
let tdefs = destTypeDefsWithGlobalFunctionsFirst cenv.ilg modul.TypeDefs
reportTime cenv.showTimes "Module Generation Preparation"
reportTime "Module Generation Preparation"
GenTypeDefsPass1 [] cenv tdefs
reportTime cenv.showTimes "Module Generation Pass 1"
reportTime "Module Generation Pass 1"
GenTypeDefsPass2 0 [] cenv tdefs
reportTime cenv.showTimes "Module Generation Pass 2"
reportTime "Module Generation Pass 2"
(match modul.Manifest with None -> () | Some m -> GenManifestPass3 cenv m)
GenTypeDefsPass3 [] cenv tdefs
reportTime cenv.showTimes "Module Generation Pass 3"
reportTime "Module Generation Pass 3"
GenCustomAttrsPass3Or4 cenv (hca_Module, midx) modul.CustomAttrs
// GenericParam is the only sorted table indexed by Columns in other tables (GenericParamConstraint\CustomAttributes).
// Hence we need to sort it before we emit any entries in GenericParamConstraint\CustomAttributes that are attached to generic params.
......@@ -3038,7 +3036,7 @@ let GenModule (cenv : cenv) (modul: ILModuleDef) =
// the key --> index map since it is no longer valid
cenv.GetTable(TableNames.GenericParam).SetRowsOfSharedTable (SortTableRows TableNames.GenericParam (cenv.GetTable(TableNames.GenericParam).GenericRowsOfTable))
GenTypeDefsPass4 [] cenv tdefs
reportTime cenv.showTimes "Module Generation Pass 4"
reportTime "Module Generation Pass 4"
/// Arbitrary value
[<Literal>]
......@@ -3056,8 +3054,7 @@ let generateIL (
generatePdb,
ilg: ILGlobals,
emitTailcalls,
deterministic,
showTimes,
deterministic,
referenceAssemblyOnly,
referenceAssemblyAttribOpt: ILAttribute option,
allGivenSources,
......@@ -3098,8 +3095,7 @@ let generateIL (
MetadataTable.Unshared (MetadataTable<UnsharedRow>.New ("row table "+string i, EqualityComparer.Default)))
use cenv =
{ emitTailcalls=emitTailcalls
deterministic = deterministic
showTimes=showTimes
deterministic = deterministic
ilg = ilg
desiredMetadataVersion=desiredMetadataVersion
requiredDataFixups= requiredDataFixups
......@@ -3183,7 +3179,7 @@ let generateIL (
EventTokenMap = (fun t edef ->
let tidx = idxForNextedTypeDef t
getUncodedToken TableNames.Event (cenv.eventDefs.GetTableEntry (EventKey (tidx, edef.Name)))) }
reportTime cenv.showTimes "Finalize Module Generation Results"
reportTime "Finalize Module Generation Results"
// New return the results
let data = cenv.data.AsMemory().ToArray()
let resources = cenv.resources.AsMemory().ToArray()
......@@ -3217,8 +3213,7 @@ let writeILMetadataAndCode (
desiredMetadataVersion,
ilg,
emitTailcalls,
deterministic,
showTimes,
deterministic,
referenceAssemblyOnly,
referenceAssemblyAttribOpt,
allGivenSources,
......@@ -3240,8 +3235,7 @@ let writeILMetadataAndCode (
generatePdb,
ilg,
emitTailcalls,
deterministic,
showTimes,
deterministic,
referenceAssemblyOnly,
referenceAssemblyAttribOpt,
allGivenSources,
......@@ -3249,7 +3243,7 @@ let writeILMetadataAndCode (
cilStartAddress,
normalizeAssemblyRefs)
reportTime showTimes "Generated Tables and Code"
reportTime "Generated Tables and Code"
let tableSize (tab: TableName) = tables[tab.Index].Count
// Now place the code
......@@ -3321,7 +3315,7 @@ let writeILMetadataAndCode (
(if tableSize TableNames.GenericParamConstraint > 0 then 0x00001000 else 0x00000000) |||
0x00000200
reportTime showTimes "Layout Header of Tables"
reportTime "Layout Header of Tables"
let guidAddress n = (if n = 0 then 0 else (n - 1) * 0x10 + 0x01)
......@@ -3365,7 +3359,7 @@ let writeILMetadataAndCode (
if n >= blobAddressTable.Length then failwith "blob index out of range"
blobAddressTable[n]
reportTime showTimes "Build String/Blob Address Tables"
reportTime "Build String/Blob Address Tables"
let sortedTables =
Array.init 64 (fun i ->
......@@ -3374,7 +3368,7 @@ let writeILMetadataAndCode (
let rows = tab.GenericRowsOfTable
if TableRequiresSorting tabName then SortTableRows tabName rows else rows)
reportTime showTimes "Sort Tables"
reportTime "Sort Tables"
let codedTables =
......@@ -3489,7 +3483,7 @@ let writeILMetadataAndCode (
tablesBuf.EmitInt32 rows.Length
reportTime showTimes "Write Header of tablebuf"
reportTime "Write Header of tablebuf"
// The tables themselves
for rows in sortedTables do
......@@ -3524,7 +3518,7 @@ let writeILMetadataAndCode (
tablesBuf.AsMemory().ToArray()
reportTime showTimes "Write Tables to tablebuf"
reportTime "Write Tables to tablebuf"
let tablesStreamUnpaddedSize = codedTables.Length
// QUERY: extra 4 empty bytes in array.exe - why? Include some extra padding after
......@@ -3541,7 +3535,7 @@ let writeILMetadataAndCode (
let blobsChunk, _next = chunk blobsStreamPaddedSize next
let blobsStreamPadding = blobsChunk.size - blobsStreamUnpaddedSize
reportTime showTimes "Layout Metadata"
reportTime "Layout Metadata"
let metadata, guidStart =
use mdbuf = ByteBuffer.Create(MetadataCapacity, useArrayPool = true)
......@@ -3576,12 +3570,12 @@ let writeILMetadataAndCode (
mdbuf.EmitInt32 blobsChunk.size
mdbuf.EmitIntsAsBytes [| 0x23; 0x42; 0x6c; 0x6f; 0x62; 0x00; 0x00; 0x00; (* #Blob000 *)|]
reportTime showTimes "Write Metadata Header"
reportTime "Write Metadata Header"
// Now the coded tables themselves
mdbuf.EmitBytes codedTables
for i = 1 to tablesStreamPadding do
mdbuf.EmitIntAsByte 0x00
reportTime showTimes "Write Metadata Tables"
reportTime "Write Metadata Tables"
// The string stream
mdbuf.EmitByte 0x00uy
......@@ -3589,7 +3583,7 @@ let writeILMetadataAndCode (
mdbuf.EmitBytes s
for i = 1 to stringsStreamPadding do
mdbuf.EmitIntAsByte 0x00
reportTime showTimes "Write Metadata Strings"
reportTime "Write Metadata Strings"
// The user string stream
mdbuf.EmitByte 0x00uy
for s in userStrings do
......@@ -3599,7 +3593,7 @@ let writeILMetadataAndCode (
for i = 1 to userStringsStreamPadding do
mdbuf.EmitIntAsByte 0x00
reportTime showTimes "Write Metadata User Strings"
reportTime "Write Metadata User Strings"
// The GUID stream
let guidStart = mdbuf.Position
Array.iter mdbuf.EmitBytes guids
......@@ -3611,7 +3605,7 @@ let writeILMetadataAndCode (
mdbuf.EmitBytes s
for i = 1 to blobsStreamPadding do
mdbuf.EmitIntAsByte 0x00
reportTime showTimes "Write Blob Stream"
reportTime "Write Blob Stream"
// Done - close the buffer and return the result.
mdbuf.AsMemory().ToArray(), guidStart
......@@ -3627,7 +3621,7 @@ let writeILMetadataAndCode (
let token = getUncodedToken TableNames.UserStrings (userStringAddress userStringIndex)
if (Bytes.get code (locInCode-1) <> i_ldstr) then failwith "strings-in-code fixup: not at ldstr instruction!"
applyFixup32 code locInCode token
reportTime showTimes "Fixup Metadata"
reportTime "Fixup Metadata"
entryPointToken, code, codePadding, metadata, data, resources, requiredDataFixups.Value, pdbData, mappings, guidStart
......@@ -3690,8 +3684,7 @@ let writeDirectory os dict =
let writeBytes (os: BinaryWriter) (chunk: byte[]) = os.Write(chunk, 0, chunk.Length)
let writePdb (
dumpDebugInfo,
showTimes,
dumpDebugInfo,
embeddedPDB,
pdbfile,
outfile,
......@@ -3724,7 +3717,7 @@ let writePdb (
s.SignStream fs
with exn ->
failwith ($"Warning: A call to SignFile failed ({exn.Message})")
reportTime showTimes "Signing Image"
reportTime "Signing Image"
// Now we've done the bulk of the binary, do the PDB file and fixup the binary.
match pdbfile with
......@@ -3754,7 +3747,7 @@ let writePdb (
stream.WriteTo fs
getInfoForPortablePdb contentId pdbfile pathMap debugDataChunk debugDeterministicPdbChunk debugChecksumPdbChunk algorithmName checkSum embeddedPDB deterministic
| None -> [| |]
reportTime showTimes "Generate PDB Info"
reportTime "Generate PDB Info"
// Now we have the debug data we can go back and fill in the debug directory in the image
use fs2 = reopenOutput()
......@@ -3779,14 +3772,15 @@ let writePdb (
os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore
if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable"
writeBytes os2 i.iddData
reportTime showTimes "Finalize PDB"
reportTime "Finalize PDB"
signImage ()
os2.Dispose()
with exn ->
failwith ("Error while writing debug directory entry: " + exn.Message)
(try os2.Dispose(); FileSystem.FileDeleteShim outfile with _ -> ())
reraise()
reportTime "Finish"
pdbBytes
type options =
......@@ -3802,8 +3796,7 @@ type options =
checksumAlgorithm: HashAlgorithm
signer: ILStrongNameSigner option
emitTailcalls: bool
deterministic: bool
showTimes: bool
deterministic: bool
dumpDebugInfo: bool
referenceAssemblyOnly: bool
referenceAssemblyAttribOpt: ILAttribute option
......@@ -3814,7 +3807,7 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe
// Store the public key from the signer into the manifest. This means it will be written
// to the binary and also acts as an indicator to leave space for delay sign
reportTime options.showTimes "Write Started"
reportTime "Write Started"
let isDll = modul.IsDLL
let ilg = options.ilg
......@@ -3928,8 +3921,7 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe
desiredMetadataVersion,
ilg,
options.emitTailcalls,
options.deterministic,
options.showTimes,
options.deterministic,
options.referenceAssemblyOnly,
options.referenceAssemblyAttribOpt,
options.allGivenSources,
......@@ -3938,7 +3930,7 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe
normalizeAssemblyRefs
)
reportTime options.showTimes "Generated IL and metadata"
reportTime "Generated IL and metadata"
let _codeChunk, next = chunk code.Length next
let _codePaddingChunk, next = chunk codePadding.Length next
......@@ -3971,7 +3963,7 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe
match options.pdbfile, options.portablePDB with
| Some _, true ->
let pdbInfo =
generatePortablePdb options.embedAllSource options.embedSourceList options.sourceLink options.checksumAlgorithm options.showTimes pdbData options.pathMap
generatePortablePdb options.embedAllSource options.embedSourceList options.sourceLink options.checksumAlgorithm pdbData options.pathMap
if options.embeddedPDB then
let (uncompressedLength, contentId, stream, algorithmName, checkSum) = pdbInfo
......@@ -4097,7 +4089,7 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe
let imageEndSectionPhysLoc = nextPhys
let imageEndAddr = next
reportTime options.showTimes "Layout image"
reportTime "Layout image"
let write p (os: BinaryWriter) chunkName chunk =
match p with
......@@ -4504,7 +4496,7 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe
pdbData, pdbInfoOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings
reportTime options.showTimes "Writing Image"
reportTime "Writing Image"
pdbData, pdbInfoOpt, debugDirectoryChunk, debugDataChunk, debugChecksumPdbChunk, debugEmbeddedPdbChunk, debugDeterministicPdbChunk, textV2P, mappings
let writeBinaryFiles (options: options, modul, normalizeAssemblyRefs) =
......@@ -4532,8 +4524,7 @@ let writeBinaryFiles (options: options, modul, normalizeAssemblyRefs) =
let reopenOutput () =
FileSystem.OpenFileForWriteShim(options.outfile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)
writePdb (options.dumpDebugInfo,
options.showTimes,
writePdb (options.dumpDebugInfo,
options.embeddedPDB,
options.pdbfile,
options.outfile,
......@@ -4565,8 +4556,7 @@ let writeBinaryInMemory (options: options, modul, normalizeAssemblyRefs) =
stream
let pdbBytes =
writePdb (options.dumpDebugInfo,
options.showTimes,
writePdb (options.dumpDebugInfo,
options.embeddedPDB,
options.pdbfile,
options.outfile,
......
......@@ -22,7 +22,6 @@ type options =
signer: ILStrongNameSigner option
emitTailcalls: bool
deterministic: bool
showTimes: bool
dumpDebugInfo: bool
referenceAssemblyOnly: bool
referenceAssemblyAttribOpt: ILAttribute option
......
......@@ -316,10 +316,10 @@ let pdbGetDebugInfo
let getDebugFileName outfile =
(FileSystemUtils.chopExtension outfile) + ".pdb"
let sortMethods showTimes info =
reportTime showTimes (sprintf "PDB: Defined %d documents" info.Documents.Length)
let sortMethods info =
reportTime (sprintf "PDB: Defined %d documents" info.Documents.Length)
Array.sortInPlaceBy (fun x -> x.MethToken) info.Methods
reportTime showTimes (sprintf "PDB: Sorted %d methods" info.Methods.Length)
reportTime (sprintf "PDB: Sorted %d methods" info.Methods.Length)
()
let getRowCounts tableRowCounts =
......@@ -345,7 +345,6 @@ type PortablePdbGenerator
embedSourceList: string list,
sourceLink: string,
checksumAlgorithm,
showTimes,
info: PdbData,
pathMap: PathMap
) =
......@@ -784,7 +783,7 @@ type PortablePdbGenerator
| Some scope -> writeMethodScopes minfo.MethToken scope
member _.Emit() =
sortMethods showTimes info
sortMethods info
metadata.SetCapacity(TableIndex.MethodDebugInformation, info.Methods.Length)
defineModuleImportScope ()
......@@ -823,7 +822,7 @@ type PortablePdbGenerator
let contentId = serializer.Serialize blobBuilder
let portablePdbStream = new MemoryStream()
blobBuilder.WriteContentTo portablePdbStream
reportTime showTimes "PDB: Created"
reportTime "PDB: Created"
(portablePdbStream.Length, contentId, portablePdbStream, algorithmName, contentHash)
let generatePortablePdb
......@@ -831,12 +830,11 @@ let generatePortablePdb
(embedSourceList: string list)
(sourceLink: string)
checksumAlgorithm
showTimes
(info: PdbData)
(pathMap: PathMap)
=
let generator =
PortablePdbGenerator(embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, showTimes, info, pathMap)
PortablePdbGenerator(embedAllSource, embedSourceList, sourceLink, checksumAlgorithm, info, pathMap)
generator.Emit()
......
......@@ -107,7 +107,6 @@ val generatePortablePdb:
embedSourceList: string list ->
sourceLink: string ->
checksumAlgorithm: HashAlgorithm ->
showTimes: bool ->
info: PdbData ->
pathMap: PathMap ->
int64 * BlobContentId * MemoryStream * string * byte[]
......
......@@ -2304,6 +2304,23 @@ let GetCoreFsiCompilerOptions (tcConfigB: TcConfigBuilder) =
)
]
let CheckAndReportSourceFileDuplicates (sourceFiles: ResizeArray<string>) =
let visited = Dictionary.newWithSize (sourceFiles.Count * 2)
let count = sourceFiles.Count
[
for i = 0 to (count - 1) do
let source = sourceFiles[i]
match visited.TryGetValue source with
| true, duplicatePosition ->
warning (Error(FSComp.SR.buildDuplicateFile (source, i + 1, count, duplicatePosition + 1, count), range0))
| false, _ ->
visited.Add(source, i)
yield source
]
let ApplyCommandLineArgs (tcConfigB: TcConfigBuilder, sourceFiles: string list, argv) =
try
let sourceFilesAcc = ResizeArray sourceFiles
......@@ -2313,7 +2330,7 @@ let ApplyCommandLineArgs (tcConfigB: TcConfigBuilder, sourceFiles: string list,
sourceFilesAcc.Add name
ParseCompilerOptions(collect, GetCoreServiceCompilerOptions tcConfigB, argv)
ResizeArray.toList sourceFilesAcc
sourceFilesAcc |> CheckAndReportSourceFileDuplicates
with e ->
errorRecovery e range0
sourceFiles
......@@ -2345,9 +2362,6 @@ let PrintWholeAssemblyImplementation (tcConfig: TcConfig) outfile header expr =
// ReportTime
//----------------------------------------------------------------------------
let mutable tPrev: (DateTime * DateTime * float * int[]) option = None
let mutable nPrev: (string * IDisposable) option = None
let private SimulateException simulateConfig =
match simulateConfig with
| Some ("fsc-oom") -> raise (OutOfMemoryException())
......@@ -2371,79 +2385,24 @@ let private SimulateException simulateConfig =
| Some ("fsc-fail") -> failwith "simulated"
| _ -> ()
let ReportTime (tcConfig: TcConfig) descr =
match nPrev with
| None -> ()
| Some (prevDescr, _) ->
if tcConfig.pause then
dprintf "[done '%s', entering '%s'] press <enter> to continue... " prevDescr descr
Console.ReadLine() |> ignore
// Intentionally putting this right after the pause so a debugger can be attached.
SimulateException tcConfig.simulateException
if (tcConfig.showTimes || verbose || tcConfig.writeTimesToFile.IsSome) then
// Note that timing calls are relatively expensive on the startup path so we don't
// make this call unless showTimes has been turned on.
let p = Process.GetCurrentProcess()
let utNow = p.UserProcessorTime.TotalSeconds
let tNow = DateTime.Now
let maxGen = GC.MaxGeneration
let gcNow = [| for i in 0..maxGen -> GC.CollectionCount i |]
let wsNow = p.WorkingSet64 / 1000000L
let tStart =
match tPrev, nPrev with
| Some (tStart, tPrev, utPrev, gcPrev), Some (prevDescr, prevActivity) ->
let spanGC = [| for i in 0..maxGen -> GC.CollectionCount i - gcPrev[i] |]
let t = tNow - tStart
let tDelta = tNow - tPrev
let utDelta = utNow - utPrev
match prevActivity with
| :? System.Diagnostics.Activity as a when isNotNull a ->
// Yes, there is duplicity of code between the console reporting and Activity collection right now.
// If current --times behaviour can be changed (=breaking change to the layout etc.), the GC and CPU time collecting logic can move to Activity
// (if a special Tag is set for an activity, the listener itself could evaluate CPU and GC info and set it
a.AddTag(Activity.Tags.gc0, spanGC[Operators.min 0 maxGen]) |> ignore
a.AddTag(Activity.Tags.gc1, spanGC[Operators.min 1 maxGen]) |> ignore
a.AddTag(Activity.Tags.gc2, spanGC[Operators.min 2 maxGen]) |> ignore
a.AddTag(Activity.Tags.outputDllFile, tcConfig.outputFile |> Option.defaultValue String.Empty)
|> ignore
a.AddTag(Activity.Tags.cpuDelta, utDelta.ToString("000.000")) |> ignore
a.AddTag(Activity.Tags.realDelta, tDelta.TotalSeconds.ToString("000.000"))
|> ignore
| _ -> ()
printf
"Real: %4.1f Realdelta: %4.1f Cpu: %4.1f Cpudelta: %4.1f Mem: %3d"
t.TotalSeconds
tDelta.TotalSeconds
utNow
utDelta
wsNow
printfn
" G0: %3d G1: %2d G2: %2d [%s]"
spanGC[Operators.min 0 maxGen]
spanGC[Operators.min 1 maxGen]
spanGC[Operators.min 2 maxGen]
prevDescr
tStart
| _ -> DateTime.Now
tPrev <- Some(tStart, tNow, utNow, gcNow)
nPrev
|> Option.iter (fun (_, act) ->
if isNotNull act then
act.Dispose())
nPrev <- Some(descr, Activity.startNoTags descr)
let ReportTime =
let mutable nPrev = None
fun (tcConfig: TcConfig) descr ->
nPrev
|> Option.iter (fun (prevDescr, prevAct) ->
use _ = prevAct
if tcConfig.pause then
dprintf "[done '%s', entering '%s'] press <enter> to continue... " prevDescr descr
Console.ReadLine() |> ignore
// Intentionally putting this right after the pause so a debugger can be attached.
SimulateException tcConfig.simulateException)
if descr <> "Exiting" then
nPrev <- Some(descr, Activity.Profiling.startAndMeasureEnvironmentStats descr)
else
nPrev <- None
let ignoreFailureOnMono1_1_16 f =
try
......
......@@ -66,6 +66,8 @@ val GetCoreFsiCompilerOptions: TcConfigBuilder -> CompilerOptionBlock list
val GetCoreServiceCompilerOptions: TcConfigBuilder -> CompilerOptionBlock list
val CheckAndReportSourceFileDuplicates: ResizeArray<string> -> string list
/// Apply args to TcConfigBuilder and return new list of source files
val ApplyCommandLineArgs: tcConfigB: TcConfigBuilder * sourceFiles: string list * argv: string list -> string list
......@@ -89,7 +91,7 @@ val DoWithColor: ConsoleColor -> (unit -> 'T) -> 'T
val DoWithDiagnosticColor: FSharpDiagnosticSeverity -> (unit -> 'T) -> 'T
val ReportTime: TcConfig -> string -> unit
val ReportTime: (TcConfig -> string -> unit)
val GetAbbrevFlagSet: TcConfigBuilder -> bool -> Set<string>
......
......@@ -536,6 +536,7 @@ let main1
// Rather than start processing, just collect names, then process them.
try
let files = ProcessCommandLineFlags(tcConfigB, lcidFromCodePage, argv)
let files = CheckAndReportSourceFileDuplicates(ResizeArray.ofList files)
AdjustForScriptCompile(tcConfigB, files, lexResourceManager, dependencyProvider)
with e ->
errorRecovery e rangeStartup
......@@ -576,14 +577,17 @@ let main1
delayForFlagsLogger.CommitDelayedDiagnostics(diagnosticsLoggerProvider, tcConfigB, exiter)
exiter.Exit 1
if tcConfig.showTimes then
Activity.Profiling.addConsoleListener () |> disposables.Register
tcConfig.writeTimesToFile
|> Option.iter (fun f ->
Activity.addCsvFileListener f |> disposables.Register
Activity.CsvExport.addCsvFileListener f |> disposables.Register
Activity.start
"FSC compilation"
[
Activity.Tags.outputDllFile, tcConfig.outputFile |> Option.defaultValue String.Empty
Activity.Tags.project, tcConfig.outputFile |> Option.defaultValue String.Empty
]
|> disposables.Register)
......@@ -599,7 +603,7 @@ let main1
AbortOnError(diagnosticsLogger, exiter)
// Resolve assemblies
ReportTime tcConfig "Import mscorlib and FSharp.Core.dll"
ReportTime tcConfig "Import mscorlib+FSharp.Core"
let foundationalTcConfigP = TcConfigProvider.Constant tcConfig
let sysRes, otherRes, knownUnresolved =
......@@ -773,7 +777,7 @@ let main2
if tcConfig.printSignature || tcConfig.printAllSignatureFiles then
InterfaceFileWriter.WriteInterfaceFile(tcGlobals, tcConfig, InfoReader(tcGlobals, tcImports.GetImportMap()), typedImplFiles)
ReportTime tcConfig "Write XML document signatures"
ReportTime tcConfig "Write XML doc signatures"
if tcConfig.xmlDocOutputFile.IsSome then
XmlDocWriter.ComputeXmlDocSigs(tcGlobals, generatedCcu)
......@@ -1098,7 +1102,6 @@ let main6
pdbfile = None
emitTailcalls = tcConfig.emitTailcalls
deterministic = tcConfig.deterministic
showTimes = tcConfig.showTimes
portablePDB = false
embeddedPDB = false
embedAllSource = tcConfig.embedAllSource
......@@ -1129,7 +1132,6 @@ let main6
pdbfile = pdbfile
emitTailcalls = tcConfig.emitTailcalls
deterministic = tcConfig.deterministic
showTimes = tcConfig.showTimes
portablePDB = tcConfig.portablePDB
embeddedPDB = tcConfig.embeddedPDB
embedAllSource = tcConfig.embedAllSource
......
......@@ -1663,4 +1663,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form"
3548,matchNotAllowedForUnionCaseWithNoData,"Pattern discard is not allowed for union case that takes no data."
3549,tcSynTypeOrInvalidInDeclaration,"SynType.Or is not permitted in this declaration"
3550,chkDuplicatedMethodParameter,"Duplicate parameter. The parameter '%s' has been used more that once in this method."
3551,buildDuplicateFile,"The source file '%s' (at position %d/%d) already appeared in the compilation list (at position %d/%d). Please verify that it is included only once in the project file."
featureEscapeBracesInFormattableString,"Escapes curly braces before calling FormattableStringFactory.Create when interpolated string literal is typed as FormattableString"
\ No newline at end of file
......@@ -1457,8 +1457,7 @@ type internal FsiDynamicCompiler(
// but needs to be set for some logic of ilwrite to function.
pdbfile = (if tcConfig.debuginfo then Some (multiAssemblyName + ".pdb") else None)
emitTailcalls = tcConfig.emitTailcalls
deterministic = tcConfig.deterministic
showTimes = tcConfig.showTimes
deterministic = tcConfig.deterministic
// we always use portable for F# Interactive debug emit
portablePDB = true
// we don't use embedded for F# Interactive debug emit
......
......@@ -1043,7 +1043,7 @@ module IncrementalBuilderStateHelpers =
let rec createFinalizeBoundModelGraphNode (initialState: IncrementalBuilderInitialState) (boundModels: ImmutableArray<GraphNode<BoundModel>>.Builder) =
GraphNode(node {
use _ = Activity.start "GetCheckResultsAndImplementationsForProject" [|Activity.Tags.outputDllFile, initialState.outfile|]
use _ = Activity.start "GetCheckResultsAndImplementationsForProject" [|Activity.Tags.project, initialState.outfile|]
// Compute last bound model then get all the evaluated models.
let! _ = boundModels[boundModels.Count - 1].GetOrComputeValue()
let boundModels =
......
......@@ -8,7 +8,7 @@ open System.IO
open System.Text
[<RequireQualifiedAccess>]
module Activity =
module internal Activity =
module Tags =
let fileName = "fileName"
......@@ -41,6 +41,25 @@ module Activity =
|]
let private activitySourceName = "fsc"
let private profiledSourceName = "fsc_with_env_stats"
type System.Diagnostics.Activity with
member this.RootId =
let rec rootID (act: Activity) =
if isNull act.ParentId then act.Id else rootID act.Parent
rootID this
member this.Depth =
let rec depth (act: Activity) acc =
if isNull act.ParentId then
acc
else
depth act.Parent (acc + 1)
depth this 0
let private activitySource = new ActivitySource(activitySourceName)
let start (name: string) (tags: (string * string) seq) : IDisposable =
......@@ -56,80 +75,167 @@ module Activity =
let startNoTags (name: string) : IDisposable = activitySource.StartActivity(name)
let private escapeStringForCsv (o: obj) =
if isNull o then
""
else
let mutable txtVal = o.ToString()
let hasComma = txtVal.IndexOf(',') > -1
let hasQuote = txtVal.IndexOf('"') > -1
module Profiling =
module Tags =
let workingSetMB = "workingSet(MB)"
let gc0 = "gc0"
let gc1 = "gc1"
let gc2 = "gc2"
let handles = "handles"
let threads = "threads"
let profilingTags = [| workingSetMB; gc0; gc1; gc2; handles; threads |]
let private profiledSource = new ActivitySource(profiledSourceName)
let startAndMeasureEnvironmentStats (name: string) : IDisposable = profiledSource.StartActivity(name)
type private GCStats = int[]
let private collectGCStats () : GCStats =
[| for i in 0 .. GC.MaxGeneration -> GC.CollectionCount i |]
let private addStatsMeasurementListener () =
let gcStatsInnerTag = "#gc_stats_internal"
let l =
new ActivityListener(
ShouldListenTo = (fun a -> a.Name = profiledSourceName),
Sample = (fun _ -> ActivitySamplingResult.AllData),
ActivityStarted = (fun a -> a.AddTag(gcStatsInnerTag, collectGCStats ()) |> ignore),
ActivityStopped =
(fun a ->
let statsBefore = a.GetTagItem(gcStatsInnerTag) :?> GCStats
let statsAfter = collectGCStats ()
let p = Process.GetCurrentProcess()
a.AddTag(Tags.workingSetMB, p.WorkingSet64 / 1_000_000L) |> ignore
a.AddTag(Tags.handles, p.HandleCount) |> ignore
a.AddTag(Tags.threads, p.Threads.Count) |> ignore
for i = 0 to statsAfter.Length - 1 do
a.AddTag($"gc{i}", statsAfter[i] - statsBefore[i]) |> ignore)
)
ActivitySource.AddActivityListener(l)
l
let addConsoleListener () =
let statsMeasurementListener = addStatsMeasurementListener ()
let reportingStart = DateTime.UtcNow
let nameColumnWidth = 36
let header =
"|"
+ "Phase name".PadRight(nameColumnWidth)
+ "|Elapsed |Duration| WS(MB)| GC0 | GC1 | GC2 |Handles|Threads|"
let consoleWriterListener =
new ActivityListener(
ShouldListenTo = (fun a -> a.Name = profiledSourceName),
Sample = (fun _ -> ActivitySamplingResult.AllData),
ActivityStopped =
(fun a ->
Console.Write('|')
let indentedName = new String('>', a.Depth) + a.DisplayName
Console.Write(indentedName.PadRight(nameColumnWidth))
let elapsed = (a.StartTimeUtc + a.Duration - reportingStart).TotalSeconds
Console.Write("|{0,8:N4}|{1,8:N4}|", elapsed, a.Duration.TotalSeconds)
for t in Tags.profilingTags do
Console.Write("{0,7}|", a.GetTagItem(t))
Console.WriteLine())
)
Console.WriteLine(new String('-', header.Length))
Console.WriteLine(header)
Console.WriteLine(header |> String.map (fun c -> if c = '|' then c else '-'))
ActivitySource.AddActivityListener(consoleWriterListener)
{ new IDisposable with
member this.Dispose() =
statsMeasurementListener.Dispose()
consoleWriterListener.Dispose()
Console.WriteLine(new String('-', header.Length))
}
if hasQuote then
txtVal <- txtVal.Replace("\"", "\\\"")
module CsvExport =
if hasQuote || hasComma then
"\"" + txtVal + "\""
let private escapeStringForCsv (o: obj) =
if isNull o then
""
else
txtVal
let private createCsvRow (a: Activity) =
let sb = new StringBuilder(128)
let appendWithLeadingComma (s: string) =
sb.Append(',') |> ignore
sb.Append(s) |> ignore
// "Name,StartTime,EndTime,Duration,Id,ParentId"
sb.Append(a.DisplayName) |> ignore
appendWithLeadingComma (a.StartTimeUtc.ToString("HH-mm-ss.ffff"))
appendWithLeadingComma ((a.StartTimeUtc + a.Duration).ToString("HH-mm-ss.ffff"))
appendWithLeadingComma (a.Duration.TotalSeconds.ToString("000.0000", System.Globalization.CultureInfo.InvariantCulture))
appendWithLeadingComma (a.Id)
appendWithLeadingComma (a.ParentId)
let rec rootID (act: Activity) =
if isNull act.ParentId then act.Id else rootID act.Parent
appendWithLeadingComma (rootID a)
Tags.AllKnownTags
|> Array.iter (fun t -> a.GetTagItem(t) |> escapeStringForCsv |> appendWithLeadingComma)
sb.ToString()
let addCsvFileListener pathToFile =
if pathToFile |> File.Exists |> not then
File.WriteAllLines(
pathToFile,
[
"Name,StartTime,EndTime,Duration(s),Id,ParentId,RootId,"
+ String.concat "," Tags.AllKnownTags
]
)
let sw = new StreamWriter(path = pathToFile, append = true)
let msgQueue =
MailboxProcessor<string>.Start
(fun inbox ->
async {
while true do
let! msg = inbox.Receive()
do! sw.WriteLineAsync(msg) |> Async.AwaitTask
})
let l =
new ActivityListener(
ShouldListenTo = (fun a -> a.Name = activitySourceName),
Sample = (fun _ -> ActivitySamplingResult.AllData),
ActivityStopped = (fun a -> msgQueue.Post(createCsvRow a))
)
ActivitySource.AddActivityListener(l)
{ new IDisposable with
member this.Dispose() =
l.Dispose() // Unregister from listening new activities first
(msgQueue :> IDisposable).Dispose() // Wait for the msg queue to be written out
sw.Dispose() // Only then flush the messages and close the file
}
let mutable txtVal = o.ToString()
let hasComma = txtVal.IndexOf(',') > -1
let hasQuote = txtVal.IndexOf('"') > -1
if hasQuote then
txtVal <- txtVal.Replace("\"", "\\\"")
if hasQuote || hasComma then
"\"" + txtVal + "\""
else
txtVal
let private createCsvRow (a: Activity) =
let sb = new StringBuilder(128)
let appendWithLeadingComma (s: string) =
sb.Append(',') |> ignore
sb.Append(s) |> ignore
// "Name,StartTime,EndTime,Duration,Id,ParentId"
sb.Append(a.DisplayName) |> ignore
appendWithLeadingComma (a.StartTimeUtc.ToString("HH-mm-ss.ffff"))
appendWithLeadingComma ((a.StartTimeUtc + a.Duration).ToString("HH-mm-ss.ffff"))
appendWithLeadingComma (a.Duration.TotalSeconds.ToString("000.0000", System.Globalization.CultureInfo.InvariantCulture))
appendWithLeadingComma (a.Id)
appendWithLeadingComma (a.ParentId)
appendWithLeadingComma (a.RootId)
Tags.AllKnownTags
|> Array.iter (fun t -> a.GetTagItem(t) |> escapeStringForCsv |> appendWithLeadingComma)
sb.ToString()
let addCsvFileListener pathToFile =
if pathToFile |> File.Exists |> not then
File.WriteAllLines(
pathToFile,
[
"Name,StartTime,EndTime,Duration(s),Id,ParentId,RootId,"
+ String.concat "," Tags.AllKnownTags
]
)
let sw = new StreamWriter(path = pathToFile, append = true)
let msgQueue =
MailboxProcessor<string>.Start
(fun inbox ->
async {
while true do
let! msg = inbox.Receive()
do! sw.WriteLineAsync(msg) |> Async.AwaitTask
})
let l =
new ActivityListener(
ShouldListenTo = (fun a -> a.Name = activitySourceName || a.Name = profiledSourceName),
Sample = (fun _ -> ActivitySamplingResult.AllData),
ActivityStopped = (fun a -> msgQueue.Post(createCsvRow a))
)
ActivitySource.AddActivityListener(l)
{ new IDisposable with
member this.Dispose() =
l.Dispose() // Unregister from listening new activities first
(msgQueue :> IDisposable).Dispose() // Wait for the msg queue to be written out
sw.Dispose() // Only then flush the messages and close the file
}
......@@ -16,17 +16,14 @@ module internal Activity =
val userOpName: string
val length: string
val cache: string
val cpuDelta: string
val realDelta: string
val gc0: string
val gc1: string
val gc2: string
val outputDllFile: string
val AllKnownTags: string[]
val startNoTags: name: string -> IDisposable
val start: name: string -> tags: (string * string) seq -> IDisposable
val addCsvFileListener: pathToFile: string -> IDisposable
module Profiling =
val startAndMeasureEnvironmentStats: name: string -> IDisposable
val addConsoleListener: unit -> IDisposable
module CsvExport =
val addCsvFileListener: pathToFile: string -> IDisposable
......@@ -85,27 +85,17 @@ module internal PervasiveAutoOpens =
| Some x -> x
let reportTime =
let mutable tFirst = None
let mutable tPrev = None
fun showTimes descr ->
if showTimes then
let t = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds
let prev =
match tPrev with
| None -> 0.0
| Some t -> t
let first =
match tFirst with
| None ->
(tFirst <- Some t
t)
| Some t -> t
printf " ilwrite: Cpu %4.1f (total) %4.1f (delta) - %s\n" (t - first) (t - prev) descr
tPrev <- Some t
let mutable tPrev: IDisposable = null
fun descr ->
if isNotNull tPrev then
tPrev.Dispose()
tPrev <-
if descr <> "Finish" then
FSharp.Compiler.Diagnostics.Activity.Profiling.startAndMeasureEnvironmentStats descr
else
null
let foldOn p f z x = f z (p x)
......
......@@ -48,7 +48,7 @@ module internal PervasiveAutoOpens =
/// We set the limit to be 80k to account for larger pointer sizes for when F# is running 64-bit.
val LOH_SIZE_THRESHOLD_BYTES: int
val reportTime: (bool -> string -> unit)
val reportTime: (string -> unit)
/// Get an initialization hole
val getHole: r: 'a option ref -> 'a
......
......@@ -7,6 +7,11 @@
<target state="new">All elements of an array must be implicitly convertible to the type of the first element, which here is a tuple of length {0} of type\n {1} \nThis element is a tuple of length {2} of type\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">Soubor {0} má nerozpoznanou příponu. Zdrojové soubory musí mít příponu .fs, .fsi, .fsx nebo .fsscript. Pokud chcete povolit použití zastaralých přípon .ml nebo .mli, použijte parametry --langversion:5.0 a --mlcompatibility.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Alle Elemente eines Arrays müssen implizit in den Typ des ersten Elements konvertiert werden. Hierbei handelt es sich um ein Tupel der Länge {0} vom Typ\n {1} \nDieses Element ist ein Tupel der Länge {2} vom Typ\n {3}. \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">Die Dateierweiterung von „{0}“ wurde nicht erkannt. Quelldateien müssen die Erweiterung .fs, .fsi, .fsx oder .fsscript haben. Um die veraltete Verwendung der Erweiterungen .ml oder .mli zu aktivieren, verwenden Sie „--langversion:5.0“ und „--mlcompatibility“.</target>
......
......@@ -7,6 +7,11 @@
<target state="new">All elements of an array must be implicitly convertible to the type of the first element, which here is a tuple of length {0} of type\n {1} \nThis element is a tuple of length {2} of type\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">No se reconoce la extensión de archivo de '{0}'. Los archivos de código fuente deben tener las extensiones .fs, .fsi, .fsx o .fsscript. Para habilitar el uso en desuso de las extensiones .ml o .mli, use '--langversion:5.0' y '--mlcompatibility'.</target>
......
......@@ -7,6 +7,11 @@
<target state="new">All elements of an array must be implicitly convertible to the type of the first element, which here is a tuple of length {0} of type\n {1} \nThis element is a tuple of length {2} of type\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">L’extension de fichier « {0} » n’est pas reconnue. Les fichiers sources doivent avoir l’extension. FS,. FSI,. FSX ou. fsscript. Pour activer l’utilisation déconseillée des extensions. ml ou. MLI, utilisez'--langversion : 5.0 'et'--mlcompatibility'.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Tutti gli elementi di una matrice devono essere convertibili in modo implicito nel tipo del primo elemento, che qui è una tupla di lunghezza {0} di tipo\n {1} \nQuesto elemento è una tupla di lunghezza {2} di tipo\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">L'estensione di file di '{0}' non è riconosciuta. I file di origine devono avere estensione fs, fsi, fsx o fsscript. Per abilitare l'uso deprecato delle estensioni ml o mli, usare '--langversion:5.0' e '--mlcompatibility'.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">配列のすべての要素は、最初の要素の型に暗黙的に変換できる必要があります。これは、型の長さ {0} のタプルです\n {1} \nこの要素は、型の長さ {2} のタプルです\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">'{0}' のファイル拡張子を認識できません。ソース ファイル拡張子は .fs、.fsi、.fsx、または .fsscript にする必要があります。非推奨の拡張子 .ml または .mli の使用を有効にするには、'--langversion:5.0' および '--mlcompatibility' を使用してください。</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">배열의 모든 요소는 첫 번째 요소의 형식으로 암시적으로 변환할 수 있어야 합니다. 여기서는 형식이 \n {1}이고 길이가 {0}인 튜플입니다. \n이 요소는 형식이 \n {3}이고 길이가 {2}인 튜플입니다. \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">'{0}'의 파일 확장자가 인식되지 않습니다. 원본 파일의 확장자는 .fs, .fsi, .fsx 또는 .fsscript여야 합니다. 더 이상 사용되지 않는 .ml 또는 .mli 확장자를 사용하려면 '--langversion:5.0' 및 '--mlcompatibility'를 사용하세요.</target>
......
......@@ -7,6 +7,11 @@
<target state="new">All elements of an array must be implicitly convertible to the type of the first element, which here is a tuple of length {0} of type\n {1} \nThis element is a tuple of length {2} of type\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">Rozszerzenie pliku "{0}" nie zostało rozpoznane. Pliki źródłowe muszą mieć rozszerzenie .fs, .fsi, .fsx lub .fsscript. Aby włączyć przestarzałe używanie rozszerzeń. ml lub .mli, użyj polecenia "--langversion: 5.0" i "--mlcompatibility".</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Todos os elementos de uma matriz devem ser implicitamente conversíveis ao tipo do primeiro elemento, que aqui é uma tupla de comprimento {0} do tipo\n {1} \nEste elemento é uma tupla de comprimento {2} do tipo\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">A extensão do arquivo '{0}' não foi reconhecida. Os arquivos de origem devem ter a extensão .fs, .fsi, .fsx ou .fsscript. Para ativar o uso preterido das extensões .ml ou .mli, use '--langversion:5.0' e '--mlcompatibility'.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Все элементы массива должны поддерживать неявное преобразование в тип первого элемента, который здесь является кортежем длиной {0} типа\n {1} \nЭтот элемент является кортежем длиной {2} типа\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">Расширение файла "{0}" не распознано. Исходные файлы должны иметь расширения FS, FSI, FSX или FSSCRIPT. Чтобы включить использование нерекомендуемых расширений ML или MLI, примените команду "--langversion:5.0" и "--mlcompatibility".</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Bir dizinin tüm öğeleri örtük olarak ilk öğenin türüne dönüştürülebilir olmalıdır. Burada ilk öğe {0} uzunluğunda türü\n {1} \nolan bir demet. Bu öğe ise {2} uzunluğunda türü\n {3} \nolan bir demet.</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">'{0}' kaynak dosyasının dosya uzantısı tanınmadı. Kaynak dosyaların uzantısı .fs, .fsi, .fsx veya .fsscript olmalıdır. Kullanım dışı .ml veya .mli uzantılarını etkinleştirmek için '--langversion:5.0' ve '--mlcompatibility' kullanın.</target>
......
......@@ -7,6 +7,11 @@
<target state="new">All elements of an array must be implicitly convertible to the type of the first element, which here is a tuple of length {0} of type\n {1} \nThis element is a tuple of length {2} of type\n {3} \n</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">无法识别“{0}”的文件扩展名。源文件必须具有扩展名 .fs、.fsi、.fsx 或 .fsscript。要启用已弃用的 .ml 或 .mli 扩展名,请使用 “--langversion:5.0” 和 “--mlcompatibility”。</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">陣列的所有元素必須以隱含方式轉換成第一個元素的類型,這是類型為\n {1} \n的元組長度 {0}此元素是類型為\n {3} \n的元組長度{2}</target>
<note />
</trans-unit>
<trans-unit id="buildDuplicateFile">
<source>The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</source>
<target state="new">The source file '{0}' (at position {1}/{2}) already appeared in the compilation list (at position {3}/{4}). Please verify that it is included only once in the project file.</target>
<note />
</trans-unit>
<trans-unit id="buildInvalidSourceFileExtensionML">
<source>The file extension of '{0}' is not recognized. Source files must have extension .fs, .fsi, .fsx or .fsscript. To enable the deprecated use of .ml or .mli extensions, use '--langversion:5.0' and '--mlcompatibility'.</source>
<target state="translated">無法辨識 '{0}' 的副檔名。來源檔案的副檔名必須是 fsi、.fsx 或 .fsscript。若要啟用已被取代的 .ml 或 .mli 副檔名,請使用 '--langversion:5.0' and '--mlcompatibility'。</target>
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
module FSharp.Compiler.ComponentTests.CompilerOptions.FscSourceFilesArguments
open Xunit
open FSharp.Test
open FSharp.Test.Compiler
[<Fact>]
let ``Reports duplicate sources via warning``() =
let file = SourceCodeFileKind.Fs({FileName="test.fs"; SourceText=Some """printfn "Hello" """ })
fsFromString file
|> FS
|> asExe
|> withAdditionalSourceFile file
|> compile
|> withWarningCodes [3551]
|> withErrorCodes []
\ No newline at end of file
......@@ -68,8 +68,8 @@ module times =
let consoleContents = sw.ToString()
Assert.Contains("Parse inputs",consoleContents)
Assert.Contains("Typecheck",consoleContents)
Assert.Contains("Mem",consoleContents)
Assert.Contains("Realdelta",consoleContents)
Assert.Contains("GC0",consoleContents)
Assert.Contains("Duration",consoleContents)
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"error_01.fs"|])>]
......
......@@ -2,7 +2,7 @@
// Regression test for FSHARP1.0:4040
// "Signature files do not prevent compiler-generated public constructors from leaking out of discriminated unions"
// Note that the corresponsing .fsi file is NOT missing the "| C of int" part of the DU
namespace N
module N
type T = | C of int
......
......@@ -199,6 +199,7 @@
<Compile Include="CompilerOptions\fsc\reference.fs" />
<Compile Include="CompilerOptions\fsc\reflectionfree.fs" />
<Compile Include="CompilerOptions\fsc\refonlyrefout.fs" />
<Compile Include="CompilerOptions\fsc\sourceFiles.fs" />
<Compile Include="Debugger\PortablePdbs.fs" />
<Compile Include="Diagnostics\async.fs" />
<Compile Include="Diagnostics\General.fs" />
......
......@@ -89,3 +89,13 @@ let ``Changes in a referenced project`` () =
saveFile "Library"
checkFile "Last" expectSignatureChanged
}
[<Fact>]
let ``Language service works if the same file is listed twice`` () =
let file = sourceFile "First" []
let project = SyntheticProject.Create(file)
project.Workflow {
checkFile "First" expectOk
addFileAbove "First" file
checkFile "First" (expectSingleWarningAndNoErrors "Please verify that it is included only once in the project file.")
}
\ No newline at end of file
......@@ -193,7 +193,7 @@ module rec Compiler =
// Load the source file from the path
let loadSourceFromFile path = getSource(TestType.Path path)
let private fsFromString (source: SourceCodeFileKind): FSharpCompilationSource =
let fsFromString (source: SourceCodeFileKind): FSharpCompilationSource =
{
Source = source
AdditionalSources = []
......@@ -321,6 +321,7 @@ module rec Compiler =
let asFs (cUnit: CompilationUnit) : CompilationUnit =
match cUnit with
| FS { Source = SourceCodeFileKind.Fsi _} -> cUnit
| FS src -> FS {src with Source=SourceCodeFileKind.Fs({FileName=src.Source.GetSourceFileName; SourceText=src.Source.GetSourceText})}
| _ -> failwith "Only F# compilation can be of type Fs."
......
......@@ -222,15 +222,6 @@ module Internal =
let content = renderSourceFile p f
writeFileIfChanged fileName content
let validateFileIdsAreUnique (project: SyntheticProject) =
let ids = [ for _, f in project.GetAllFiles() -> f.Id ]
let duplicates = ids |> List.groupBy id |> List.filter (fun (_, g) -> g.Length > 1)
if duplicates.Length > 0 then
failwith
$"""Source file IDs have to be unique across the project and all referenced projects. Found duplicates: {String.Join(", ", duplicates |> List.map fst)}"""
open Internal
......@@ -311,6 +302,21 @@ module ProjectOperations =
if checkResult.Diagnostics.Length > 0 then
failwith $"Expected no errors, but there were some: \n%A{checkResult.Diagnostics}"
let expectSingleWarningAndNoErrors (warningSubString:string) parseAndCheckResults _ =
let checkResult = getTypeCheckResult parseAndCheckResults
let errors = checkResult.Diagnostics|> Array.filter (fun d -> d.Severity = FSharpDiagnosticSeverity.Error)
if errors.Length > 0 then
failwith $"Expected no errors, but there were some: \n%A{errors}"
let warnings = checkResult.Diagnostics|> Array.filter (fun d -> d.Severity = FSharpDiagnosticSeverity.Warning)
match warnings |> Array.tryExactlyOne with
| None -> failwith $"Expected 1 warning, but got {warnings.Length} instead: \n%A{warnings}"
| Some w ->
if w.Message.Contains warningSubString then
()
else
failwith $"Expected 1 warning with substring '{warningSubString}' but got %A{w}"
let expectErrors parseAndCheckResults _ =
let checkResult = getTypeCheckResult parseAndCheckResults
......@@ -378,7 +384,6 @@ type WorkflowContext =
let SaveAndCheckProject project checker =
async {
validateFileIdsAreUnique project
do! saveProject project true checker
......
ReqENU SOURCE=gccerrors01.fs COMPILE_ONLY=1 SCFLAGS="--gccerrors --nologo gccerrors01.fs >gccerrors01.txt" POSTCMD="\$FSI_PIPE --nologo --quiet --exec ..\\..\\..\\comparer.fsx gccerrors01.txt gccerrors01.bsl"
ReqENU SOURCE=gccerrors01.fs COMPILE_ONLY=1 SCFLAGS="--gccerrors --nologo >gccerrors01.txt" POSTCMD="\$FSI_PIPE --nologo --quiet --exec ..\\..\\..\\comparer.fsx gccerrors01.txt gccerrors01.bsl"
......@@ -10,7 +10,7 @@ CompilerOptions01,NoMT CompilerOptions\fsc\crossoptimize
CompilerOptions01,NoMT,Determinism CompilerOptions\fsc\determinism
CompilerOptions01,NoMT CompilerOptions\fsc\dumpAllCommandLineOptions
CompilerOptions01,NoMT CompilerOptions\fsc\flaterrors
CompilerOptions02,NoMT CompilerOptions\fsc\gccerrors
CompilerOptions02,NoMT,gcc CompilerOptions\fsc\gccerrors
CompilerOptions01,NoMT,help CompilerOptions\fsc\help
CompilerOptions01,NoMT CompilerOptions\fsc\highentropyva
CompilerOptions01,NoMT CompilerOptions\fsc\langversion
......
......@@ -60,4 +60,4 @@ let runPerl arguments =
let testResultDir = Path.Combine(rootFolder, "tests", "TestResults")
let perlScript = Path.Combine(rootFolder, "tests", "fsharpqa", "testenv", "bin", "runall.pl")
runPerl [|perlScript; "-resultsroot";testResultDir ;"-ttags:Determinism"|]
\ No newline at end of file
runPerl [|perlScript; "-resultsroot";testResultDir ;"-ttags:gcc"|]
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册