Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
</FsSrGen>
<EmbeddedResource Include="$(FSharpSourcesRoot)/fsharp/FSStrings.resx">
<Link>FSStrings.resx</Link>
<LogicalName>FSStrings.resources</LogicalName>
</EmbeddedResource>
<FsYacc Include="$(FSharpSourcesRoot)\absil\ilpars.fsy">
<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>
Expand Down
3 changes: 2 additions & 1 deletion src/fsharp/import.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
module internal Microsoft.FSharp.Compiler.Import

open System.Reflection
open System.Collections.Concurrent
open System.Collections.Generic

open Microsoft.FSharp.Compiler.AbstractIL.IL
Expand Down Expand Up @@ -52,7 +53,7 @@ type AssemblyLoader =
/// serves as an interface through to the tables stored in the primary TcImports structures defined in CompileOps.fs.
[<Sealed>]
type ImportMap(g:TcGlobals,assemblyLoader:AssemblyLoader) =
let typeRefToTyconRefCache = new System.Collections.Generic.Dictionary<ILTypeRef,TyconRef>()
let typeRefToTyconRefCache = ConcurrentDictionary<ILTypeRef,TyconRef>()
member this.g = g
member this.assemblyLoader = assemblyLoader
member this.ILTypeRefToTyconRefCache = typeRefToTyconRefCache
Expand Down
33 changes: 18 additions & 15 deletions src/fsharp/service/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1698,14 +1698,16 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
/// CreateIncrementalBuilder (for background type checking). Note that fsc.fs also
/// creates an incremental builder used by the command line compiler.
static member TryCreateBackgroundBuilderForProjectOptions (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, frameworkTcImportsCache: FrameworkImportsCache, loadClosureOpt:LoadClosure option, sourceFiles:string list, commandLineArgs:string list, projectReferences, projectDirectory, useScriptResolutionRules, keepAssemblyContents, keepAllBackgroundResolutions, maxTimeShareMilliseconds) =
let targetProfileSwitch = "--targetprofile:"
let useSimpleResolutionSwitch = "--simpleresolution"

cancellable {

// Trap and report warnings and errors from creation.
use errorScope = new ErrorScope()
let! builderOpt =
let delayedLogger = CapturingErrorLogger("IncrementalBuilderCreation")
use _unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> delayedLogger)
use _unwindBP = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter

let! builderOpt =
cancellable {
try

Expand Down Expand Up @@ -1741,22 +1743,12 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
#else
tcConfigB.useSimpleResolution <- (getSwitchValue useSimpleResolutionSwitch) |> Option.isSome
#endif
match (getSwitchValue targetProfileSwitch) with
| Some v ->
let _s = v
CompileOptions.SetTargetProfile tcConfigB v
| None -> ()

// Apply command-line arguments and collect more source files if they are in the arguments
let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, commandLineArgs)

// Never open PDB files for the language service, even if --standalone is specified
tcConfigB.openDebugInformationForLaterStaticLinking <- false
match commandLineArgs |> Seq.tryFind(fun s -> s.StartsWith(targetProfileSwitch)) with
| Some arg ->
let profile = arg.Substring(targetProfileSwitch.Length)
CompileOptions.SetTargetProfile tcConfigB profile
| _ -> ()

tcConfigB, sourceFilesNew

match loadClosureOpt with
Expand Down Expand Up @@ -1825,7 +1817,18 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput
return None
}

return builderOpt, errorScope.Diagnostics
let diagnostics =
match builderOpt with
| Some builder ->
let errorSeverityOptions = builder.TcConfig.errorSeverityOptions
let errorLogger = CompilationErrorLogger("IncrementalBuilderCreation", errorSeverityOptions)
delayedLogger.CommitDelayedDiagnostics(errorLogger)
errorLogger.GetErrors() |> List.map (fun (d, severity) -> d, severity = FSharpErrorSeverity.Error)
| _ ->
delayedLogger.Diagnostics
|> List.map (fun (d, isError) -> FSharpErrorInfo.CreateFromException(d, isError, range.Zero))

return builderOpt, diagnostics
}
static member KeepBuilderAlive (builderOpt: IncrementalBuilder option) =
match builderOpt with
Expand Down
7 changes: 3 additions & 4 deletions src/fsharp/symbols/SymbolHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,14 @@ type internal CompilationErrorLogger (debugName: string, options: FSharpErrorSev

override x.DiagnosticSink(exn, isError) =
if isError || ReportWarningAsError options exn then
diagnostics.Add(exn, isError)
diagnostics.Add(exn, FSharpErrorSeverity.Error)
errorCount <- errorCount + 1
else if ReportWarning options exn then
diagnostics.Add(exn, isError)
diagnostics.Add(exn, FSharpErrorSeverity.Warning)

override x.ErrorCount = errorCount

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


/// This represents the global state established as each task function runs as part of the build.
Expand Down
17 changes: 17 additions & 0 deletions tests/service/Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ let mkProjectCommandLineArgsForScript (dllName, fileNames) =
|]
#endif

let mkTestFileAndOptions source additionalArgs =
let fileName = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
let project = Path.GetTempFileName()
let dllName = Path.ChangeExtension(project, ".dll")
let projFileName = Path.ChangeExtension(project, ".fsproj")
let fileSource1 = "module M"
File.WriteAllText(fileName, fileSource1)

let args = Array.append (mkProjectCommandLineArgs (dllName, [fileName])) additionalArgs
let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
fileName, options

let parseAndCheckFile fileName source options =
match checker.ParseAndCheckFileInProject(fileName, 0, source, options) |> Async.RunSynchronously with
| parseResults, FSharpCheckFileAnswer.Succeeded(checkResults) -> parseResults, checkResults
| _ -> failwithf "Parsing aborted unexpectedly..."

let parseAndCheckScript (file, input) =

#if DOTNETCORE
Expand Down
13 changes: 13 additions & 0 deletions tests/service/ProjectAnalysisTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5195,3 +5195,16 @@ type A(i:int) =

| Some decl -> failwithf "unexpected declaration %A" decl
| None -> failwith "declaration list is empty"


[<TestCase(([||]: string[]), ([||]: bool[]))>]
[<TestCase([| "--times" |], [| false |])>]
[<TestCase([| "--times"; "--nowarn:75" |], ([||]: bool[]))>]
[<TestCase([| "--times"; "--warnaserror:75" |], [| true |])>]
[<TestCase([| "--times"; "--warnaserror-:75"; "--warnaserror" |], [| false |])>]
let ``#4030, Incremental builder creation warnings`` (args, errorSeverities) =
let source = "module M"
let fileName, options = mkTestFileAndOptions source args

let _, checkResults = parseAndCheckFile fileName source options
checkResults.Errors |> Array.map (fun e -> e.Severity = FSharpErrorSeverity.Error) |> shouldEqual errorSeverities
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ type internal FSharpCompletionProvider
else
let triggerPosition = caretPosition - 1
let triggerChar = sourceText.[triggerPosition]
let prevChar = sourceText.[triggerPosition - 1]


// do not trigger completion if it's not single dot, i.e. range expression
if not Settings.IntelliSense.ShowAfterCharIsTyped && prevChar = '.' then
if not Settings.IntelliSense.ShowAfterCharIsTyped && triggerPosition > 0 && sourceText.[triggerPosition - 1] = '.' then
false
else
let documentId, filePath, defines = getInfo()
Expand Down
12 changes: 12 additions & 0 deletions vsintegration/tests/unittests/CompletionProviderTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,18 @@ xVal**y
let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo)
Assert.IsTrue(triggered, "Completion should trigger after typing an identifier that follows a mathematical operation")

[<Test>]
let ShouldTriggerCompletionAtStartOfFileWithInsertion =
let fileContents = """
l"""

let marker = "l"
let caretPosition = fileContents.IndexOf(marker) + marker.Length
let documentId = DocumentId.CreateNewId(ProjectId.CreateNewId())
let getInfo() = documentId, filePath, []
let triggered = FSharpCompletionProvider.ShouldTriggerCompletionAux(SourceText.From(fileContents), caretPosition, CompletionTriggerKind.Insertion, getInfo)
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.")

[<Test>]
let ShouldDisplayTypeMembers() =
let fileContents = """
Expand Down