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
4 changes: 4 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,8 @@ type TcConfigBuilder =
mutable exiter: Exiter

mutable parallelReferenceResolution: ParallelReferenceResolution

mutable captureIdentifiersWhenParsing: bool
}

// Directories to start probing in
Expand Down Expand Up @@ -777,6 +779,7 @@ type TcConfigBuilder =
xmlDocInfoLoader = None
exiter = QuitProcessExiter
parallelReferenceResolution = ParallelReferenceResolution.Off
captureIdentifiersWhenParsing = false
}

member tcConfigB.FxResolver =
Expand Down Expand Up @@ -1322,6 +1325,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member _.xmlDocInfoLoader = data.xmlDocInfoLoader
member _.exiter = data.exiter
member _.parallelReferenceResolution = data.parallelReferenceResolution
member _.captureIdentifiersWhenParsing = data.captureIdentifiersWhenParsing

static member Create(builder, validate) =
use _ = UseBuildPhase BuildPhase.Parameter
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ type TcConfigBuilder =
mutable exiter: Exiter

mutable parallelReferenceResolution: ParallelReferenceResolution

mutable captureIdentifiersWhenParsing: bool
}

static member CreateNew:
Expand Down Expand Up @@ -858,6 +860,8 @@ type TcConfig =

member parallelReferenceResolution: ParallelReferenceResolution

member captureIdentifiersWhenParsing: bool

/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
[<Sealed>]
Expand Down
52 changes: 29 additions & 23 deletions src/Compiler/Driver/ParseAndCheckInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ let ParseInput
lexbuf: UnicodeLexing.Lexbuf,
defaultNamespace,
fileName,
isLastCompiland
isLastCompiland,
identCapture
) =
// The assert below is almost ok, but it fires in two cases:
// - fsi.exe sometimes passes "stdin" as a dummy file name
Expand All @@ -433,25 +434,29 @@ let ParseInput
let input =
let identStore = HashSet<string>()

let identCaptureLexer x =
let token = lexer x

match token with
| Parser.token.PERCENT_OP ident
| Parser.token.FUNKY_OPERATOR_NAME ident
| Parser.token.ADJACENT_PREFIX_OP ident
| Parser.token.PLUS_MINUS_OP ident
| Parser.token.INFIX_AMP_OP ident
| Parser.token.INFIX_STAR_DIV_MOD_OP ident
| Parser.token.PREFIX_OP ident
| Parser.token.INFIX_BAR_OP ident
| Parser.token.INFIX_AT_HAT_OP ident
| Parser.token.INFIX_COMPARE_OP ident
| Parser.token.INFIX_STAR_STAR_OP ident
| Parser.token.IDENT ident -> identStore.Add ident |> ignore
| _ -> ()

token
let lexer =
if identCapture then
(fun x ->
let token = lexer x

match token with
| Parser.token.PERCENT_OP ident
| Parser.token.FUNKY_OPERATOR_NAME ident
| Parser.token.ADJACENT_PREFIX_OP ident
| Parser.token.PLUS_MINUS_OP ident
| Parser.token.INFIX_AMP_OP ident
| Parser.token.INFIX_STAR_DIV_MOD_OP ident
| Parser.token.PREFIX_OP ident
| Parser.token.INFIX_BAR_OP ident
| Parser.token.INFIX_AT_HAT_OP ident
| Parser.token.INFIX_COMPARE_OP ident
| Parser.token.INFIX_STAR_STAR_OP ident
| Parser.token.IDENT ident -> identStore.Add ident |> ignore
| _ -> ()

token)
else
lexer

if FSharpMLCompatFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then
Expand All @@ -461,14 +466,14 @@ let ParseInput

// Call the appropriate parser - for signature files or implementation files
if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
let impl = Parser.implementationFile identCaptureLexer lexbuf
let impl = Parser.implementationFile lexer lexbuf

let tripleSlashComments =
LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf)

PostParseModuleImpls(defaultNamespace, fileName, isLastCompiland, impl, lexbuf, tripleSlashComments, Set identStore)
elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
let intfs = Parser.signatureFile identCaptureLexer lexbuf
let intfs = Parser.signatureFile lexer lexbuf

let tripleSlashComments =
LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
Expand Down Expand Up @@ -640,7 +645,8 @@ let ParseOneInputLexbuf (tcConfig: TcConfig, lexResourceManager, lexbuf, fileNam
lexbuf,
None,
fileName,
isLastCompiland
isLastCompiland,
tcConfig.captureIdentifiersWhenParsing
)

// Report the statistics for testing purposes
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Driver/ParseAndCheckInputs.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ val ParseInput:
lexbuf: Lexbuf *
defaultNamespace: string option *
fileName: string *
isLastCompiland: (bool * bool) ->
isLastCompiland: (bool * bool) *
identCapture: bool ->
ParsedInput

/// A general routine to process hash directives
Expand Down
22 changes: 19 additions & 3 deletions src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2345,7 +2345,15 @@ module internal ParseAndCheckFile =

matchingBraces.ToArray()

let parseFile (sourceText: ISourceText, fileName, options: FSharpParsingOptions, userOpName: string, suggestNamesForErrors: bool) =
let parseFile
(
sourceText: ISourceText,
fileName,
options: FSharpParsingOptions,
userOpName: string,
suggestNamesForErrors: bool,
identCapture: bool
) =
Trace.TraceInformation("FCS: {0}.{1} ({2})", userOpName, "parseFile", fileName)

use act =
Expand Down Expand Up @@ -2377,7 +2385,8 @@ module internal ParseAndCheckFile =
lexbuf,
None,
fileName,
(isLastCompiland, isExe)
(isLastCompiland, isExe),
identCapture
)
with e ->
errHandler.DiagnosticsLogger.StopProcessingRecovery e range0 // don't re-raise any exceptions, we must return None.
Expand Down Expand Up @@ -3180,7 +3189,14 @@ type FsiInteractiveChecker(legacyReferenceResolver, tcConfig: TcConfig, tcGlobal
FSharpParsingOptions.FromTcConfig(tcConfig, [| fileName |], true)

let parseErrors, parsedInput, anyErrors =
ParseAndCheckFile.parseFile (sourceText, fileName, parsingOptions, userOpName, suggestNamesForErrors)
ParseAndCheckFile.parseFile (
sourceText,
fileName,
parsingOptions,
userOpName,
suggestNamesForErrors,
tcConfig.captureIdentifiersWhenParsing
)

let dependencyFiles = [||] // interactions have no dependencies

Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Service/FSharpCheckerResults.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,8 @@ module internal ParseAndCheckFile =
fileName: string *
options: FSharpParsingOptions *
userOpName: string *
suggestNamesForErrors: bool ->
suggestNamesForErrors: bool *
identCapture: bool ->
FSharpDiagnostic[] * ParsedInput * bool

val matchBraces:
Expand Down
6 changes: 4 additions & 2 deletions src/Compiler/Service/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,8 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
enablePartialTypeChecking: bool,
enableParallelCheckingWithSignatureFiles: bool,
dependencyProvider,
parallelReferenceResolution
parallelReferenceResolution,
captureIdentifiersWhenParsing
) =

let useSimpleResolutionSwitch = "--simpleresolution"
Expand Down Expand Up @@ -1523,7 +1524,8 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc

tcConfigB.parallelCheckingWithSignatureFiles <- enableParallelCheckingWithSignatureFiles
tcConfigB.parallelReferenceResolution <- parallelReferenceResolution

tcConfigB.captureIdentifiersWhenParsing <- captureIdentifiersWhenParsing

tcConfigB, sourceFilesNew

// If this is a builder for a script, re-apply the settings inferred from the
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Service/IncrementalBuild.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ type internal IncrementalBuilder =
enablePartialTypeChecking: bool *
enableParallelCheckingWithSignatureFiles: bool *
dependencyProvider: DependencyProvider option *
parallelReferenceResolution: ParallelReferenceResolution ->
parallelReferenceResolution: ParallelReferenceResolution *
captureIdentifiersWhenParsing: bool ->
NodeCode<IncrementalBuilder option * FSharpDiagnostic[]>

/// Generalized Incremental Builder. This is exposed only for unit testing purposes.
Expand Down
34 changes: 24 additions & 10 deletions src/Compiler/Service/service.fs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ type BackgroundCompiler
enableBackgroundItemKeyStoreAndSemanticClassification,
enablePartialTypeChecking,
enableParallelCheckingWithSignatureFiles,
parallelReferenceResolution
parallelReferenceResolution,
captureIdentifiersWhenParsing
) as self =

let beforeFileChecked = Event<string * FSharpProjectOptions>()
Expand Down Expand Up @@ -320,7 +321,8 @@ type BackgroundCompiler
enablePartialTypeChecking,
enableParallelCheckingWithSignatureFiles,
dependencyProvider,
parallelReferenceResolution
parallelReferenceResolution,
captureIdentifiersWhenParsing
)

match builderOpt with
Expand Down Expand Up @@ -496,14 +498,14 @@ type BackgroundCompiler
Interlocked.Increment(&actualParseFileCount) |> ignore

let parseDiagnostics, parseTree, anyErrors =
ParseAndCheckFile.parseFile (sourceText, fileName, options, userOpName, suggestNamesForErrors)
ParseAndCheckFile.parseFile (sourceText, fileName, options, userOpName, suggestNamesForErrors, captureIdentifiersWhenParsing)

let res = FSharpParseFileResults(parseDiagnostics, parseTree, anyErrors, options.SourceFiles)
parseCacheLock.AcquireLock(fun ltok -> parseFileCache.Set(ltok, (fileName, hash, options), res))
return res
else
let parseDiagnostics, parseTree, anyErrors =
ParseAndCheckFile.parseFile (sourceText, fileName, options, userOpName, false)
ParseAndCheckFile.parseFile (sourceText, fileName, options, userOpName, false, captureIdentifiersWhenParsing)

return FSharpParseFileResults(parseDiagnostics, parseTree, anyErrors, options.SourceFiles)
}
Expand Down Expand Up @@ -750,7 +752,14 @@ type BackgroundCompiler
GraphNode.SetPreferredUILang tcPrior.TcConfig.preferredUiLang

let parseDiagnostics, parseTree, anyErrors =
ParseAndCheckFile.parseFile (sourceText, fileName, parsingOptions, userOpName, suggestNamesForErrors)
ParseAndCheckFile.parseFile (
sourceText,
fileName,
parsingOptions,
userOpName,
suggestNamesForErrors,
captureIdentifiersWhenParsing
)

let parseResults =
FSharpParseFileResults(parseDiagnostics, parseTree, anyErrors, builder.AllDependenciesDeprecated)
Expand Down Expand Up @@ -1224,7 +1233,8 @@ type FSharpChecker
enableBackgroundItemKeyStoreAndSemanticClassification,
enablePartialTypeChecking,
enableParallelCheckingWithSignatureFiles,
parallelReferenceResolution
parallelReferenceResolution,
captureIdentifiersWhenParsing
) =

let backgroundCompiler =
Expand All @@ -1239,7 +1249,8 @@ type FSharpChecker
enableBackgroundItemKeyStoreAndSemanticClassification,
enablePartialTypeChecking,
enableParallelCheckingWithSignatureFiles,
parallelReferenceResolution
parallelReferenceResolution,
captureIdentifiersWhenParsing
)

static let globalInstance = lazy FSharpChecker.Create()
Expand Down Expand Up @@ -1282,7 +1293,8 @@ type FSharpChecker
?enableBackgroundItemKeyStoreAndSemanticClassification,
?enablePartialTypeChecking,
?enableParallelCheckingWithSignatureFiles,
?parallelReferenceResolution
?parallelReferenceResolution: bool,
?captureIdentifiersWhenParsing: bool
) =

use _ = Activity.startNoTags "FSharpChecker.Create"
Expand All @@ -1304,6 +1316,7 @@ type FSharpChecker

let enablePartialTypeChecking = defaultArg enablePartialTypeChecking false
let enableParallelCheckingWithSignatureFiles = defaultArg enableParallelCheckingWithSignatureFiles false
let captureIdentifiersWhenParsing = defaultArg captureIdentifiersWhenParsing false

if keepAssemblyContents && enablePartialTypeChecking then
invalidArg "enablePartialTypeChecking" "'keepAssemblyContents' and 'enablePartialTypeChecking' cannot be both enabled."
Expand All @@ -1321,7 +1334,8 @@ type FSharpChecker
enableBackgroundItemKeyStoreAndSemanticClassification,
enablePartialTypeChecking,
enableParallelCheckingWithSignatureFiles,
parallelReferenceResolution
parallelReferenceResolution,
captureIdentifiersWhenParsing
)

member _.ReferenceResolver = legacyReferenceResolver
Expand Down Expand Up @@ -1499,7 +1513,7 @@ type FSharpChecker
let userOpName = defaultArg userOpName "Unknown"

node {
if fastCheck <> Some true then
if fastCheck <> Some true || not captureIdentifiersWhenParsing then
return! backgroundCompiler.FindReferencesInFile(fileName, options, symbol, canInvalidateProject, userOpName)
else
let! parseResults = backgroundCompiler.GetBackgroundParseResultsForFileInProject(fileName, options, userOpName)
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/Service/service.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type public FSharpChecker =
/// <param name="enablePartialTypeChecking">Indicates whether to perform partial type checking. Cannot be set to true if keepAssmeblyContents is true. If set to true, can cause duplicate type-checks when richer information on a file is needed, but can skip background type-checking entirely on implementation files with signature files.</param>
/// <param name="enableParallelCheckingWithSignatureFiles">Type check implementation files that are backed by a signature file in parallel.</param>
/// <param name="parallelReferenceResolution">Indicates whether to resolve references in parallel.</param>
/// <param name="captureIdentifiersWhenParsing">When set to true we create a set of all identifiers for each parsed file which can be used to speed up finding references.</param>
static member Create:
?projectCacheSize: int *
?keepAssemblyContents: bool *
Expand All @@ -45,7 +46,8 @@ type public FSharpChecker =
?enableBackgroundItemKeyStoreAndSemanticClassification: bool *
?enablePartialTypeChecking: bool *
?enableParallelCheckingWithSignatureFiles: bool *
?parallelReferenceResolution: bool ->
?parallelReferenceResolution: bool *
?captureIdentifiersWhenParsing: bool ->
FSharpChecker

/// <summary>
Expand Down Expand Up @@ -300,14 +302,14 @@ type public FSharpChecker =
/// <param name="options">The options for the project or script, used to determine active --define conditionals and other options relevant to parsing.</param>
/// <param name="symbol">The symbol to find all uses in the file.</param>
/// <param name="canInvalidateProject">Default: true. If true, this call can invalidate the current state of project if the options have changed. If false, the current state of the project will be used.</param>
/// <param name="fastCheck">Default: false. Experimental feature that makes the operation faster.</param>
/// <param name="fastCheck">Default: false. Experimental feature that makes the operation faster. Requires FSharpChecker to be created with captureIdentifiersWhenParsing = true.</param>
/// <param name="userOpName">An optional string used for tracing compiler operations associated with this request.</param>
member FindBackgroundReferencesInFile:
fileName: string *
options: FSharpProjectOptions *
symbol: FSharpSymbol *
?canInvalidateProject: bool *
?fastCheck: bool *
[<Experimental("This FCS API is experimental and subject to change.")>] ?fastCheck: bool *
?userOpName: string ->
Async<range seq>

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1955,5 +1955,5 @@ type ParsedInput =
/// Gets the #nowarn and other scoped pragmas
member ScopedPragmas: ScopedPragma list

/// Gets a set of all identifiers used in this parsed input
/// Gets a set of all identifiers used in this parsed input. Only populated if captureIdentifiersWhenParsing option was used.
member Identifiers: Set<string>
Loading