From cc4cb7c3c4c20502e2141b5d6bd0fb528c3d3473 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 28 Dec 2017 14:51:39 +0500 Subject: [PATCH 1/2] Add IsInteractive to FSharpParsingOptions --- src/fsharp/service/ServiceUntypedParse.fs | 4 +- src/fsharp/service/ServiceUntypedParse.fsi | 2 +- src/fsharp/service/service.fs | 46 +++++++++---------- src/fsharp/service/service.fsi | 11 +++-- .../CodeFix/AddOpenCodeFixProvider.fs | 2 +- .../ImplementInterfaceCodeFixProvider.fs | 2 +- .../CodeFix/RenameUnusedValue.fs | 2 +- .../DocumentHighlightsService.fs | 2 +- .../Formatting/EditorFormattingService.fs | 2 +- .../Formatting/IndentationService.fs | 2 +- .../InlineRename/InlineRenameService.fs | 2 +- .../LanguageService/LanguageService.fs | 4 +- .../LanguageService/SymbolHelpers.fs | 4 +- .../Navigation/FindUsagesService.fs | 2 +- .../Navigation/GoToDefinitionService.fs | 4 +- .../QuickInfo/QuickInfoProvider.fs | 6 +-- .../ProjectSitesAndFiles.fs | 7 +-- 17 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/fsharp/service/ServiceUntypedParse.fs b/src/fsharp/service/ServiceUntypedParse.fs index 2b79da350af..1405443c42a 100755 --- a/src/fsharp/service/ServiceUntypedParse.fs +++ b/src/fsharp/service/ServiceUntypedParse.fs @@ -41,8 +41,8 @@ module SourceFileImpl = 0 = String.Compare(".fsi",ext,StringComparison.OrdinalIgnoreCase) /// Additional #defines that should be in place when editing a file in a file editor such as VS. - let AdditionalDefinesForUseInEditor(filename) = - if CompileOps.IsScript(filename) then ["INTERACTIVE";"EDITING"] // This is still used by the foreground parse + let AdditionalDefinesForUseInEditor(isInteractive: bool) = + if isInteractive then ["INTERACTIVE";"EDITING"] // This is still used by the foreground parse else ["COMPILED";"EDITING"] type CompletionPath = string list * string option // plid * residue diff --git a/src/fsharp/service/ServiceUntypedParse.fsi b/src/fsharp/service/ServiceUntypedParse.fsi index 2caf81f6fb0..40339e85f96 100755 --- a/src/fsharp/service/ServiceUntypedParse.fsi +++ b/src/fsharp/service/ServiceUntypedParse.fsi @@ -112,5 +112,5 @@ module public UntypedParseImpl = // implementation details used by other code in the compiler module internal SourceFileImpl = val IsInterfaceFile : string -> bool - val AdditionalDefinesForUseInEditor : string -> string list + val AdditionalDefinesForUseInEditor: isInteractive: bool -> string list diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index 80b55834f02..003072d4258 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -1394,14 +1394,13 @@ type TypeCheckInfo override __.ToString() = "TypeCheckInfo(" + mainInputFileName + ")" type FSharpParsingOptions = - { - SourceFiles: string [] + { SourceFiles: string [] ConditionalCompilationDefines: string list ErrorSeverityOptions: FSharpErrorSeverityOptions + IsInteractive: bool LightSyntax: bool option CompilingFsLib: bool - IsExe: bool - } + IsExe: bool } member x.LastFileName = Debug.Assert(not (Array.isEmpty x.SourceFiles), "Parsing options don't contain any file") @@ -1411,26 +1410,26 @@ type FSharpParsingOptions = { SourceFiles = Array.empty ConditionalCompilationDefines = [] ErrorSeverityOptions = FSharpErrorSeverityOptions.Default + IsInteractive = false LightSyntax = None CompilingFsLib = false - IsExe = false - } + IsExe = false } - static member FromTcConfig(tcConfig: TcConfig, sourceFiles) = - { - SourceFiles = sourceFiles + static member FromTcConfig(tcConfig: TcConfig, sourceFiles, isInteractive: bool) = + { SourceFiles = sourceFiles ConditionalCompilationDefines = tcConfig.conditionalCompilationDefines ErrorSeverityOptions = tcConfig.errorSeverityOptions + IsInteractive = isInteractive LightSyntax = tcConfig.light CompilingFsLib = tcConfig.compilingFslib - IsExe = tcConfig.target.IsExe - } + IsExe = tcConfig.target.IsExe } - static member FromTcConfigBuidler(tcConfigB: TcConfigBuilder, sourceFiles) = + static member FromTcConfigBuidler(tcConfigB: TcConfigBuilder, sourceFiles, isInteractive: bool) = { SourceFiles = sourceFiles ConditionalCompilationDefines = tcConfigB.conditionalCompilationDefines ErrorSeverityOptions = tcConfigB.errorSeverityOptions + IsInteractive = isInteractive LightSyntax = tcConfigB.light CompilingFsLib = tcConfigB.compilingFslib IsExe = tcConfigB.target.IsExe @@ -1502,7 +1501,7 @@ module internal Parser = // If we're editing a script then we define INTERACTIVE otherwise COMPILED. // Since this parsing for intellisense we always define EDITING. - let defines = SourceFileImpl.AdditionalDefinesForUseInEditor(fileName) @ options.ConditionalCompilationDefines + let defines = (SourceFileImpl.AdditionalDefinesForUseInEditor options.IsInteractive) @ options.ConditionalCompilationDefines // Note: we don't really attempt to intern strings across a large scope. let lexResourceManager = new Lexhelp.LexResourceManager() @@ -2514,7 +2513,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC let! tcErrors, tcFileResult = Parser.CheckOneFile(parseResults, source, fileName, options.ProjectFileName, tcPrior.TcConfig, tcPrior.TcGlobals, tcPrior.TcImports, tcPrior.TcState, loadClosure, tcPrior.Errors, reactorOps, (fun () -> builder.IsAlive), textSnapshotInfo, userOpName) - let parsingOptions = FSharpParsingOptions.FromTcConfig(tcPrior.TcConfig, Array.ofList builder.SourceFiles) + let parsingOptions = FSharpParsingOptions.FromTcConfig(tcPrior.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules) let checkAnswer = MakeCheckFileAnswer(fileName, tcFileResult, options, builder, Array.ofList tcPrior.TcDependencyFiles, creationErrors, parseResults.Errors, tcErrors) bc.RecordTypeCheckFileInProjectResults(fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, source) return checkAnswer @@ -2628,7 +2627,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC let! tcPrior = execWithReactorAsync <| fun ctok -> builder.GetCheckResultsBeforeFileInProject (ctok, filename) // Do the parsing. - let parsingOptions = FSharpParsingOptions.FromTcConfig(builder.TcConfig, Array.ofList (builder.SourceFiles)) + let parsingOptions = FSharpParsingOptions.FromTcConfig(builder.TcConfig, Array.ofList (builder.SourceFiles), options.UseScriptResolutionRules) let parseErrors, parseTreeOpt, anyErrors = Parser.parseFile (source, filename, parsingOptions, userOpName) let parseTreeOpt = parseTreeOpt |> Option.map builder.DeduplicateParsedInputModuleNameInProject let parseResults = FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, builder.AllDependenciesDeprecated) @@ -2908,7 +2907,7 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten member ic.GetParsingOptionsFromProjectOptions(options): FSharpParsingOptions * _ = let sourceFiles = List.ofArray options.SourceFiles let argv = List.ofArray options.OtherOptions - ic.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv) + ic.GetParsingOptionsFromCommandLineArgs(sourceFiles, argv, options.UseScriptResolutionRules) member ic.MatchBraces(filename, source, options: FSharpProjectOptions, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" @@ -3111,16 +3110,17 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten ExtraProjectInfo=extraProjectInfo Stamp = None } - member ic.GetParsingOptionsFromCommandLineArgs(initialSourceFiles, argv) = + member ic.GetParsingOptionsFromCommandLineArgs(initialSourceFiles, argv, ?isInteractive) = + let isInteractive = defaultArg isInteractive false use errorScope = new ErrorScope() let tcConfigBuilder = TcConfigBuilder.Initial // Apply command-line arguments and collect more source files if they are in the arguments let sourceFilesNew = ApplyCommandLineArgs(tcConfigBuilder, initialSourceFiles, argv) - FSharpParsingOptions.FromTcConfigBuidler(tcConfigBuilder, Array.ofList sourceFilesNew), errorScope.Diagnostics + FSharpParsingOptions.FromTcConfigBuidler(tcConfigBuilder, Array.ofList sourceFilesNew, isInteractive), errorScope.Diagnostics - member ic.GetParsingOptionsFromCommandLineArgs(argv) = - ic.GetParsingOptionsFromCommandLineArgs([], argv) + member ic.GetParsingOptionsFromCommandLineArgs(argv, ?isInteractive: bool) = + ic.GetParsingOptionsFromCommandLineArgs([], argv, ?isInteractive=isInteractive) /// Begin background parsing the given project. member ic.StartBackgroundCompile(options, ?userOpName) = @@ -3191,7 +3191,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, reactorOps: IReactorOperatio let userOpName = defaultArg userOpName "Unknown" let filename = Path.Combine(tcConfig.implicitIncludeDir, "stdin.fsx") // Note: projectSourceFiles is only used to compute isLastCompiland, and is ignored if Build.IsScript(mainInputFileName) is true (which it is in this case). - let parsingOptions = FSharpParsingOptions.FromTcConfig(tcConfig, [| filename |]) + let parsingOptions = FSharpParsingOptions.FromTcConfig(tcConfig, [| filename |], true) let parseErrors, parseTreeOpt, anyErrors = Parser.parseFile (source, filename, parsingOptions, userOpName) let dependencyFiles = [| |] // interactions have no dependencies let parseResults = FSharpParseFileResults(parseErrors, parseTreeOpt, parseHadErrors = anyErrors, dependencyFiles = dependencyFiles) @@ -3234,8 +3234,8 @@ module CompilerEnvironment = let DefaultReferencesForOrphanSources(assumeDotNetFramework) = DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) /// Publish compiler-flags parsing logic. Must be fast because its used by the colorizer. - let GetCompilationDefinesForEditing(filename:string, parsingOptions: FSharpParsingOptions) = - SourceFileImpl.AdditionalDefinesForUseInEditor(filename) @ + let GetCompilationDefinesForEditing (parsingOptions: FSharpParsingOptions) = + SourceFileImpl.AdditionalDefinesForUseInEditor(parsingOptions.IsInteractive) @ parsingOptions.ConditionalCompilationDefines /// Return true if this is a subcategory of error or warning message that the language service can emit diff --git a/src/fsharp/service/service.fsi b/src/fsharp/service/service.fsi index 61ac7e1fb2d..2602d82e4ff 100755 --- a/src/fsharp/service/service.fsi +++ b/src/fsharp/service/service.fsi @@ -295,6 +295,7 @@ type public FSharpParsingOptions = SourceFiles: string[] ConditionalCompilationDefines: string list ErrorSeverityOptions: FSharpErrorSeverityOptions + IsInteractive: bool LightSyntax: bool option CompilingFsLib: bool IsExe: bool @@ -533,14 +534,14 @@ type public FSharpChecker = /// /// Initial source files list. Additional files may be added during argv evaluation. /// The command line arguments for the project build. - member GetParsingOptionsFromCommandLineArgs: sourceFiles: string list * argv: string list -> FSharpParsingOptions * FSharpErrorInfo list + member GetParsingOptionsFromCommandLineArgs: sourceFiles: string list * argv: string list * ?isInteractive: bool -> FSharpParsingOptions * FSharpErrorInfo list /// /// Get the FSharpParsingOptions implied by a set of command line arguments. /// /// /// The command line arguments for the project build. - member GetParsingOptionsFromCommandLineArgs: argv: string list -> FSharpParsingOptions * FSharpErrorInfo list + member GetParsingOptionsFromCommandLineArgs: argv: string list * ?isInteractive: bool -> FSharpParsingOptions * FSharpErrorInfo list /// /// Get the FSharpParsingOptions implied by a FSharpProjectOptions. @@ -727,11 +728,11 @@ type public CompilerEnvironment = module public CompilerEnvironment = /// These are the names of assemblies that should be referenced for .fs or .fsi files that /// are not associated with a project. - val DefaultReferencesForOrphanSources : assumeDotNetFramework: bool -> string list + val DefaultReferencesForOrphanSources: assumeDotNetFramework: bool -> string list /// Return the compilation defines that should be used when editing the given file. - val GetCompilationDefinesForEditing : filename : string * parsingOptions : FSharpParsingOptions -> string list + val GetCompilationDefinesForEditing: parsingOptions: FSharpParsingOptions -> string list /// Return true if this is a subcategory of error or warning message that the language service can emit - val IsCheckerSupportedSubcategory : string -> bool + val IsCheckerSupportedSubcategory: string -> bool /// Information about the debugging environment module public DebuggerEnvironment = diff --git a/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs index 76f88464e7a..b90e44f91e9 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/AddOpenCodeFixProvider.fs @@ -101,7 +101,7 @@ type internal FSharpAddOpenCodeFixProvider let! _, parsedInput, checkResults = checker.ParseAndCheckDocument(document, projectOptions, allowStaleResults = true, sourceText = sourceText, userOpName = userOpName) let line = sourceText.Lines.GetLineFromPosition(context.Span.End) let linePos = sourceText.Lines.GetLinePosition(context.Span.End) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = asyncMaybe { diff --git a/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs b/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs index 5cf5fcba215..da7c4248262 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/ImplementInterfaceCodeFixProvider.fs @@ -144,7 +144,7 @@ type internal FSharpImplementInterfaceCodeFixProvider let! sourceText = context.Document.GetTextAsync(cancellationToken) let! _, parsedInput, checkFileResults = checker.ParseAndCheckDocument(context.Document, projectOptions, sourceText = sourceText, allowStaleResults = true, userOpName = userOpName) let textLine = sourceText.Lines.GetLineFromPosition context.Span.Start - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(context.Document.FilePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions // Notice that context.Span doesn't return reliable ranges to find tokens at exact positions. // That's why we tokenize the line and try to find the last successive identifier token let tokens = Tokenizer.tokenizeLine(context.Document.Id, sourceText, context.Span.Start, context.Document.FilePath, defines) diff --git a/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs b/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs index 48e547ab713..e376d31617a 100644 --- a/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs +++ b/vsintegration/src/FSharp.Editor/CodeFix/RenameUnusedValue.fs @@ -57,7 +57,7 @@ type internal FSharpRenameUnusedValueCodeFixProvider let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document let! _, _, checkResults = checker.ParseAndCheckDocument(document, projectOptions, allowStaleResults = true, sourceText = sourceText, userOpName=userOpName) let m = RoslynHelpers.TextSpanToFSharpRange(document.FilePath, context.Span, sourceText) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing (document.FilePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! lexerSymbol = Tokenizer.getSymbolAtPosition (document.Id, sourceText, context.Span.Start, document.FilePath, defines, SymbolLookupKind.Greedy, false) let lineText = (sourceText.Lines.GetLineFromPosition context.Span.Start).ToString() let! symbolUse = checkResults.GetSymbolUseAtLocation(m.StartLine, m.EndColumn, lineText, lexerSymbol.FullIsland, userOpName=userOpName) diff --git a/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs b/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs index 354c41759dd..5074245f9da 100644 --- a/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs +++ b/vsintegration/src/FSharp.Editor/DocumentHighlights/DocumentHighlightsService.fs @@ -79,7 +79,7 @@ type internal FSharpDocumentHighlightsService [] (checkerP let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document) let! sourceText = document.GetTextAsync(cancellationToken) let! textVersion = document.GetTextVersionAsync(cancellationToken) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! spans = FSharpDocumentHighlightsService.GetDocumentHighlights(checkerProvider.Checker, document.Id, sourceText, document.FilePath, position, defines, projectOptions, textVersion.GetHashCode()) let highlightSpans = diff --git a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs index d4b1b24ebf6..fd20d89d26d 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs @@ -38,7 +38,7 @@ type internal FSharpEditorFormattingService let line = sourceText.Lines.[sourceText.Lines.IndexOf position] - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(filePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let tokens = Tokenizer.tokenizeLine(documentId, sourceText, line.Start, filePath, defines) diff --git a/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs b/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs index 23afe5131ce..c0fb75430f3 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/IndentationService.fs @@ -37,7 +37,7 @@ type internal FSharpIndentationService let rec tryFindLastNonWhitespaceOrCommentToken (line: TextLine) = maybe { let! parsingOptions, _projectOptions = options - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(filePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let tokens = Tokenizer.tokenizeLine(documentId, sourceText, line.Start, filePath, defines) return! diff --git a/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs b/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs index 89e9d6a8f2d..81d87ed4a5e 100644 --- a/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs +++ b/vsintegration/src/FSharp.Editor/InlineRename/InlineRenameService.fs @@ -169,7 +169,7 @@ type internal InlineRenameService asyncMaybe { let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document) let! sourceText = document.GetTextAsync(cancellationToken) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions return! InlineRenameService.GetInlineRenameInfo(checkerProvider.Checker, projectInfoManager, document, sourceText, position, defines, projectOptions) } |> Async.map (Option.defaultValue FailureInlineRenameInfo.Instance) diff --git a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs index 1686e96a3d5..96540a83739 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs @@ -162,8 +162,8 @@ type internal FSharpProjectOptionsManager let parsingOptions = match projectOptionsOpt with | Some (parsingOptions, _site, _projectOptions) -> parsingOptions - | _ -> FSharpParsingOptions.Default - CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, parsingOptions) + | _ -> { FSharpParsingOptions.Default with IsInteractive = IsScript document.Name } + CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions /// Try and get the Options for a project member this.TryGetOptionsForProject(projectId:ProjectId) = projectOptionsTable.TryGetOptionsForProject(projectId) diff --git a/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs b/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs index 34e42ff637a..e44ac3da833 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/SymbolHelpers.fs @@ -31,7 +31,7 @@ module internal SymbolHelpers = let textLinePos = sourceText.Lines.GetLinePosition(position) let fcsTextLineNumber = Line.fromZ textLinePos.Line let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document) - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document.FilePath, textVersionHash, sourceText.ToString(), projectOptions, allowStaleResults = true, userOpName = userOpName) let! symbolUse = checkFileResults.GetSymbolUseAtLocation(fcsTextLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland, userOpName=userOpName) @@ -96,7 +96,7 @@ module internal SymbolHelpers = let originalText = sourceText.ToString(symbolSpan) do! Option.guard (originalText.Length > 0) let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.Name, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, symbolSpan.Start, document.FilePath, defines, SymbolLookupKind.Greedy, false) let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, allowStaleResults = true, userOpName = userOpName) let textLine = sourceText.Lines.GetLineFromPosition(symbolSpan.Start) diff --git a/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs b/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs index 0f7fde12e79..bd18d1ca918 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/FindUsagesService.fs @@ -55,7 +55,7 @@ type internal FSharpFindUsagesService let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, sourceText = sourceText, allowStaleResults = true, userOpName = userOpName) let textLine = sourceText.Lines.GetLineFromPosition(position).ToString() let lineNumber = sourceText.Lines.GetLinePosition(position).Line + 1 - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, false) let! symbolUse = checkFileResults.GetSymbolUseAtLocation(lineNumber, symbol.Ident.idRange.EndColumn, textLine, symbol.FullIsland, userOpName=userOpName) diff --git a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs index 7707b8a2554..91bc81690d3 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs @@ -58,7 +58,7 @@ type internal GoToDefinition(checker: FSharpChecker, projectInfoManager: FSharpP let findSymbolHelper (originDocument: Document, originRange: range, sourceText: SourceText, preferSignature: bool) : Async = asyncMaybe { let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject originDocument - let defines = CompilerEnvironment.GetCompilationDefinesForEditing (originDocument.FilePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! originTextSpan = RoslynHelpers.TryFSharpRangeToTextSpan (sourceText, originRange) let position = originTextSpan.Start let! lexerSymbol = Tokenizer.getSymbolAtPosition (originDocument.Id, sourceText, position, originDocument.FilePath, defines, SymbolLookupKind.Greedy, false) @@ -297,7 +297,7 @@ type internal FSharpGoToDefinitionService asyncMaybe { let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject originDocument let! sourceText = originDocument.GetTextAsync () |> liftTaskAsync - let defines = CompilerEnvironment.GetCompilationDefinesForEditing (originDocument.FilePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let textLine = sourceText.Lines.GetLineFromPosition position let textLinePos = sourceText.Lines.GetLinePosition position let fcsTextLineNumber = Line.fromZ textLinePos.Line diff --git a/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs b/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs index 802d8948ca5..5a3fb13d8c8 100644 --- a/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs +++ b/vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs @@ -56,7 +56,7 @@ module private FSharpQuickInfo = // project options need to be retrieved because the signature file could be in another project let! extParsingOptions, _extSite, extProjectOptions = projectInfoManager.TryGetOptionsForProject extDocId.ProjectId - let extDefines = CompilerEnvironment.GetCompilationDefinesForEditing (extDocument.FilePath, extParsingOptions) + let extDefines = CompilerEnvironment.GetCompilationDefinesForEditing extParsingOptions let! extLexerSymbol = Tokenizer.getSymbolAtPosition(extDocId, extSourceText, extSpan.Start, declRange.FileName, extDefines, SymbolLookupKind.Greedy, true) let! _, _, extCheckFileResults = checker.ParseAndCheckDocument(extDocument, extProjectOptions, allowStaleResults=true, sourceText=extSourceText, userOpName = userOpName) @@ -92,7 +92,7 @@ module private FSharpQuickInfo = asyncMaybe { let! sourceText = document.GetTextAsync cancellationToken let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject document - let defines = CompilerEnvironment.GetCompilationDefinesForEditing(document.FilePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! lexerSymbol = Tokenizer.getSymbolAtPosition(document.Id, sourceText, position, document.FilePath, defines, SymbolLookupKind.Greedy, true) let idRange = lexerSymbol.Ident.idRange let! _, _, checkFileResults = checker.ParseAndCheckDocument(document, projectOptions, allowStaleResults = true, sourceText=sourceText, userOpName = userOpName) @@ -175,7 +175,7 @@ type internal FSharpQuickInfoProvider let! _, _, checkFileResults = checker.ParseAndCheckDocument (filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true, userOpName = FSharpQuickInfo.userOpName) let textLine = sourceText.Lines.GetLineFromPosition position let textLineNumber = textLine.LineNumber + 1 // Roslyn line numbers are zero-based - let defines = CompilerEnvironment.GetCompilationDefinesForEditing (filePath, parsingOptions) + let defines = CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions let! symbol = Tokenizer.getSymbolAtPosition (documentId, sourceText, position, filePath, defines, SymbolLookupKind.Precise, true) let! res = checkFileResults.GetStructuredToolTipText (textLineNumber, symbol.Ident.idRange.EndColumn, textLine.ToString(), symbol.FullIsland, FSharpTokenTag.IDENT, userOpName=FSharpQuickInfo.userOpName) |> liftAsync match res with diff --git a/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs b/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs index cc6e220d661..89539b6180e 100644 --- a/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs +++ b/vsintegration/src/FSharp.LanguageService/ProjectSitesAndFiles.fs @@ -385,8 +385,9 @@ type internal ProjectSitesAndFiles() = member art.GetDefinesForFile_DEPRECATED(rdt:IVsRunningDocumentTable, filename : string, checker:FSharpChecker) = // The only caller of this function calls it each time it needs to colorize a line, so this call must execute very fast. - if SourceFile.MustBeSingleFileProject(filename) then - CompilerEnvironment.GetCompilationDefinesForEditing(filename,FSharpParsingOptions.Default) + if SourceFile.MustBeSingleFileProject(filename) then + let parsingOptions = { FSharpParsingOptions.Default with IsInteractive = true} + CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions else let siteOpt = match VsRunningDocumentTable.FindDocumentWithoutLocking(rdt,filename) with @@ -399,7 +400,7 @@ type internal ProjectSitesAndFiles() = | None -> ProjectSitesAndFiles.ProjectSiteOfSingleFile(filename) let parsingOptions,_ = checker.GetParsingOptionsFromCommandLineArgs(site.CompilationOptions |> Array.toList) - CompilerEnvironment.GetCompilationDefinesForEditing(filename,parsingOptions) + CompilerEnvironment.GetCompilationDefinesForEditing parsingOptions member art.TryFindOwningProject_DEPRECATED(rdt:IVsRunningDocumentTable, filename) = if SourceFile.MustBeSingleFileProject(filename) then None From 1eaca2e621ba6bb036bf941ad12b5c9ec53f6047 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 29 Dec 2017 03:21:03 +0500 Subject: [PATCH 2/2] Add test --- tests/service/ProjectOptionsTests.fs | 43 +++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/service/ProjectOptionsTests.fs b/tests/service/ProjectOptionsTests.fs index 1e995681fdb..d82fca93727 100644 --- a/tests/service/ProjectOptionsTests.fs +++ b/tests/service/ProjectOptionsTests.fs @@ -14,6 +14,7 @@ open System open System.IO open NUnit.Framework open FsUnit +open Microsoft.FSharp.Compiler.Ast open Microsoft.FSharp.Compiler.SourceCodeServices open FSharp.Compiler.Service.Tests.Common @@ -518,6 +519,46 @@ let ``Test SourceFiles order for GetProjectOptionsFromScript`` () = // See #594 test "Main4" [|"BaseLib2"; "Lib5"; "BaseLib1"; "Lib1"; "Lib2"; "Main4"|] test "MainBad" [|"MainBad"|] +[] +let ``Script load closure project`` () = + let fileName1 = Path.GetTempPath() + Path.DirectorySeparatorChar.ToString() + "Impl.fs" + let fileName2 = Path.ChangeExtension(Path.GetTempFileName(), ".fsx") + let fileSource1 = """ +module ImplFile - +#if INTERACTIVE +let x = 42 +#endif +""" + + let fileSource2 = """ +#load "Impl.fs" +ImplFile.x +""" + + File.WriteAllText(fileName1, fileSource1) + File.WriteAllText(fileName2, fileSource2) + + let projectOptions, diagnostics = + checker.GetProjectOptionsFromScript(fileName2, fileSource2) |> Async.RunSynchronously + diagnostics.IsEmpty |> shouldEqual true + + let _, checkResults = + checker.ParseAndCheckFileInProject(fileName2, 0, fileSource2, projectOptions) |> Async.RunSynchronously + + match checkResults with + | FSharpCheckFileAnswer.Succeeded results -> + results.Errors |> shouldEqual [| |] + | _ -> failwith "type check was aborted" + + let parsingOptions, diagnostics = checker.GetParsingOptionsFromProjectOptions(projectOptions) + diagnostics.IsEmpty |> shouldEqual true + + let parseResults = checker.ParseFile(fileName1, fileSource1, parsingOptions) |> Async.RunSynchronously + parseResults.ParseTree.IsSome |> shouldEqual true + match parseResults.ParseTree.Value with + | ParsedInput.ImplFile (ParsedImplFileInput (_, _, _, _, _, modules, _)) -> + let (SynModuleOrNamespace (_, _, _, decls, _, _, _, _)) = modules.Head + decls.Length |> shouldEqual 1 + | _ -> failwith "got sig file"