Skip to content

Commit 5f9e8df

Browse files
dotnet-botKevinRansom
authored andcommitted
Merge master to dev15.6 (#4156)
* fix resource name (#4151) otherwise instead of expected `FSStrings.resources` will use `FSharp.Compiler.Service.netstandard.FSStrings.resources` * Use ConcurrentDictionary in ImportMap (#4148) * Fix IndexOutOfRangeException in check for providing completion (#4138) * Fix IndexOutOfRange in check for providing completion: * Add test * Remove repeating arguments processing in IncrementalBuilder creation (#4124) * Report builder creation warnings according to compiler args (#4125) * Filter incremental builder creation errors according to compiler args * Fix CompilationErrorLogger ignores WarsAsError options * Add test for WarnAsError * Cleanup * Add more tests; cover WarnAsError-, no warnings at all * Refactor tests * Add test
1 parent 954a36e commit 5f9e8df

File tree

8 files changed

+68
-23
lines changed

8 files changed

+68
-23
lines changed

fcs/FSharp.Compiler.Service.netstandard/FSharp.Compiler.Service.netstandard.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
</FsSrGen>
8282
<EmbeddedResource Include="$(FSharpSourcesRoot)/fsharp/FSStrings.resx">
8383
<Link>FSStrings.resx</Link>
84+
<LogicalName>FSStrings.resources</LogicalName>
8485
</EmbeddedResource>
8586
<FsYacc Include="$(FSharpSourcesRoot)\absil\ilpars.fsy">
8687
<OtherFlags>--module Microsoft.FSharp.Compiler.AbstractIL.Internal.AsciiParser --open Microsoft.FSharp.Compiler.AbstractIL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing</OtherFlags>

src/fsharp/import.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
module internal Microsoft.FSharp.Compiler.Import
55

66
open System.Reflection
7+
open System.Collections.Concurrent
78
open System.Collections.Generic
89

910
open Microsoft.FSharp.Compiler.AbstractIL.IL
@@ -52,7 +53,7 @@ type AssemblyLoader =
5253
/// serves as an interface through to the tables stored in the primary TcImports structures defined in CompileOps.fs.
5354
[<Sealed>]
5455
type ImportMap(g:TcGlobals,assemblyLoader:AssemblyLoader) =
55-
let typeRefToTyconRefCache = new System.Collections.Generic.Dictionary<ILTypeRef,TyconRef>()
56+
let typeRefToTyconRefCache = ConcurrentDictionary<ILTypeRef,TyconRef>()
5657
member this.g = g
5758
member this.assemblyLoader = assemblyLoader
5859
member this.ILTypeRefToTyconRefCache = typeRefToTyconRefCache

src/fsharp/service/IncrementalBuild.fs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,14 +1698,16 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
16981698
/// CreateIncrementalBuilder (for background type checking). Note that fsc.fs also
16991699
/// creates an incremental builder used by the command line compiler.
17001700
static member TryCreateBackgroundBuilderForProjectOptions (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, frameworkTcImportsCache: FrameworkImportsCache, loadClosureOpt:LoadClosure option, sourceFiles:string list, commandLineArgs:string list, projectReferences, projectDirectory, useScriptResolutionRules, keepAssemblyContents, keepAllBackgroundResolutions, maxTimeShareMilliseconds) =
1701-
let targetProfileSwitch = "--targetprofile:"
17021701
let useSimpleResolutionSwitch = "--simpleresolution"
17031702

17041703
cancellable {
17051704

17061705
// Trap and report warnings and errors from creation.
1707-
use errorScope = new ErrorScope()
1708-
let! builderOpt =
1706+
let delayedLogger = CapturingErrorLogger("IncrementalBuilderCreation")
1707+
use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayedLogger)
1708+
use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter
1709+
1710+
let! builderOpt =
17091711
cancellable {
17101712
try
17111713

@@ -1741,22 +1743,12 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
17411743
#else
17421744
tcConfigB.useSimpleResolution <- (getSwitchValue useSimpleResolutionSwitch) |> Option.isSome
17431745
#endif
1744-
match (getSwitchValue targetProfileSwitch) with
1745-
| Some v ->
1746-
let _s = v
1747-
CompileOptions.SetTargetProfile tcConfigB v
1748-
| None -> ()
1749-
17501746
// Apply command-line arguments and collect more source files if they are in the arguments
17511747
let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, commandLineArgs)
17521748

17531749
// Never open PDB files for the language service, even if --standalone is specified
17541750
tcConfigB.openDebugInformationForLaterStaticLinking <- false
1755-
match commandLineArgs |> Seq.tryFind(fun s -> s.StartsWith(targetProfileSwitch)) with
1756-
| Some arg ->
1757-
let profile = arg.Substring(targetProfileSwitch.Length)
1758-
CompileOptions.SetTargetProfile tcConfigB profile
1759-
| _ -> ()
1751+
17601752
tcConfigB, sourceFilesNew
17611753

17621754
match loadClosureOpt with
@@ -1825,7 +1817,18 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
18251817
return None
18261818
}
18271819

1828-
return builderOpt, errorScope.Diagnostics
1820+
let diagnostics =
1821+
match builderOpt with
1822+
| Some builder ->
1823+
let errorSeverityOptions = builder.TcConfig.errorSeverityOptions
1824+
let errorLogger = CompilationErrorLogger("IncrementalBuilderCreation", errorSeverityOptions)
1825+
delayedLogger.CommitDelayedDiagnostics(errorLogger)
1826+
errorLogger.GetErrors() |> List.map (fun (d, severity) -> d, severity = FSharpErrorSeverity.Error)
1827+
| _ ->
1828+
delayedLogger.Diagnostics
1829+
|> List.map (fun (d, isError) -> FSharpErrorInfo.CreateFromException(d, isError, range.Zero))
1830+
1831+
return builderOpt, diagnostics
18291832
}
18301833
static member KeepBuilderAlive (builderOpt: IncrementalBuilder option) =
18311834
match builderOpt with

src/fsharp/symbols/SymbolHelpers.fs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,14 @@ type internal CompilationErrorLogger (debugName: string, options: FSharpErrorSev
150150

151151
override x.DiagnosticSink(exn, isError) =
152152
if isError || ReportWarningAsError options exn then
153-
diagnostics.Add(exn, isError)
153+
diagnostics.Add(exn, FSharpErrorSeverity.Error)
154154
errorCount <- errorCount + 1
155155
else if ReportWarning options exn then
156-
diagnostics.Add(exn, isError)
156+
diagnostics.Add(exn, FSharpErrorSeverity.Warning)
157157

158158
override x.ErrorCount = errorCount
159159

160-
member x.GetErrors() =
161-
[ for (e, isError) in diagnostics -> e, (if isError then FSharpErrorSeverity.Error else FSharpErrorSeverity.Warning) ]
160+
member x.GetErrors() = List.ofSeq diagnostics
162161

163162

164163
/// This represents the global state established as each task function runs as part of the build.

tests/service/Common.fs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,23 @@ let mkProjectCommandLineArgsForScript (dllName, fileNames) =
160160
|]
161161
#endif
162162

163+
let mkTestFileAndOptions source additionalArgs =
164+
let fileName = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
165+
let project = Path.GetTempFileName()
166+
let dllName = Path.ChangeExtension(project, ".dll")
167+
let projFileName = Path.ChangeExtension(project, ".fsproj")
168+
let fileSource1 = "module M"
169+
File.WriteAllText(fileName, fileSource1)
170+
171+
let args = Array.append (mkProjectCommandLineArgs (dllName, [fileName])) additionalArgs
172+
let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
173+
fileName, options
174+
175+
let parseAndCheckFile fileName source options =
176+
match checker.ParseAndCheckFileInProject(fileName, 0, source, options) |> Async.RunSynchronously with
177+
| parseResults, FSharpCheckFileAnswer.Succeeded(checkResults) -> parseResults, checkResults
178+
| _ -> failwithf "Parsing aborted unexpectedly..."
179+
163180
let parseAndCheckScript (file, input) =
164181

165182
#if DOTNETCORE

tests/service/ProjectAnalysisTests.fs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5195,3 +5195,16 @@ type A(i:int) =
51955195

51965196
| Some decl -> failwithf "unexpected declaration %A" decl
51975197
| None -> failwith "declaration list is empty"
5198+
5199+
5200+
[<TestCase(([||]: string[]), ([||]: bool[]))>]
5201+
[<TestCase([| "--times" |], [| false |])>]
5202+
[<TestCase([| "--times"; "--nowarn:75" |], ([||]: bool[]))>]
5203+
[<TestCase([| "--times"; "--warnaserror:75" |], [| true |])>]
5204+
[<TestCase([| "--times"; "--warnaserror-:75"; "--warnaserror" |], [| false |])>]
5205+
let ``#4030, Incremental builder creation warnings`` (args, errorSeverities) =
5206+
let source = "module M"
5207+
let fileName, options = mkTestFileAndOptions source args
5208+
5209+
let _, checkResults = parseAndCheckFile fileName source options
5210+
checkResults.Errors |> Array.map (fun e -> e.Severity = FSharpErrorSeverity.Error) |> shouldEqual errorSeverities

vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ type internal FSharpCompletionProvider
8585
else
8686
let triggerPosition = caretPosition - 1
8787
let triggerChar = sourceText.[triggerPosition]
88-
let prevChar = sourceText.[triggerPosition - 1]
89-
88+
9089
// do not trigger completion if it's not single dot, i.e. range expression
91-
if not Settings.IntelliSense.ShowAfterCharIsTyped && prevChar = '.' then
90+
if not Settings.IntelliSense.ShowAfterCharIsTyped && triggerPosition > 0 && sourceText.[triggerPosition - 1] = '.' then
9291
false
9392
else
9493
let documentId, filePath, defines = getInfo()

vsintegration/tests/unittests/CompletionProviderTests.fs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,18 @@ xVal**y
273273
let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo)
274274
Assert.IsTrue(triggered, "Completion should trigger after typing an identifier that follows a mathematical operation")
275275

276+
[<Test>]
277+
let ShouldTriggerCompletionAtStartOfFileWithInsertion =
278+
let fileContents = """
279+
l"""
280+
281+
let marker = "l"
282+
let caretPosition = fileContents.IndexOf(marker) + marker.Length
283+
let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId())
284+
let getInfo() = documentId, filePath, []
285+
let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo)
286+
Assert.IsTrue(triggered, "Completion should trigger after typing an Insertion character at the top of the file, e.g. a function definition in a new script file.")
287+
276288
[<Test>]
277289
let ShouldDisplayTypeMembers() =
278290
let fileContents = """

0 commit comments

Comments
 (0)