From d8682fd16645a028d4da409da82fe299aefb425a Mon Sep 17 00:00:00 2001
From: ncave <777696+ncave@users.noreply.github.com>
Date: Fri, 2 Aug 2019 03:06:45 -0700
Subject: [PATCH] Added service_slim
---
.../FSharp.Compiler.Service.fsproj | 1 +
fcs/FSharp.Compiler.Service/service_slim.fs | 260 ++++++++++++++++++
fcs/build.fsx | 6 +-
fcs/fcs-test/Program.fs | 127 +++++++++
fcs/fcs-test/Properties/launchSettings.json | 8 +
fcs/fcs-test/ast_print.fs | 101 +++++++
fcs/fcs-test/fcs-test.fsproj | 24 ++
fcs/fcs-test/fcs-test.sln | 31 +++
fcs/fcs-test/test_script.fsx | 8 +
global.json | 2 +-
src/buildtools/buildtools.targets | 4 +-
src/fsharp/service/FSharpCheckerResults.fsi | 30 ++
12 files changed, 598 insertions(+), 4 deletions(-)
create mode 100644 fcs/FSharp.Compiler.Service/service_slim.fs
create mode 100644 fcs/fcs-test/Program.fs
create mode 100644 fcs/fcs-test/Properties/launchSettings.json
create mode 100644 fcs/fcs-test/ast_print.fs
create mode 100644 fcs/fcs-test/fcs-test.fsproj
create mode 100644 fcs/fcs-test/fcs-test.sln
create mode 100644 fcs/fcs-test/test_script.fsx
diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
index 2bfaa4aa128a..38da6ebe208a 100644
--- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
+++ b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
@@ -657,6 +657,7 @@
Service/fsi.fs
+
diff --git a/fcs/FSharp.Compiler.Service/service_slim.fs b/fcs/FSharp.Compiler.Service/service_slim.fs
new file mode 100644
index 000000000000..1e5ea2e4d214
--- /dev/null
+++ b/fcs/FSharp.Compiler.Service/service_slim.fs
@@ -0,0 +1,260 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+// Open up the compiler as an incremental service for parsing,
+// type checking and intellisense-like environment-reporting.
+
+namespace FSharp.Compiler.SourceCodeServices
+
+open System
+open System.Collections.Generic
+open System.Collections.Concurrent
+open System.Diagnostics
+open System.IO
+open System.Reflection
+open System.Text
+
+open Microsoft.FSharp.Core.Printf
+open FSharp.Compiler
+open FSharp.Compiler.AbstractIL
+open FSharp.Compiler.AbstractIL.IL
+open FSharp.Compiler.AbstractIL.ILBinaryReader
+open FSharp.Compiler.AbstractIL.Diagnostics
+open FSharp.Compiler.AbstractIL.Internal
+open FSharp.Compiler.AbstractIL.Internal.Library
+
+open FSharp.Compiler.AccessibilityLogic
+open FSharp.Compiler.Ast
+open FSharp.Compiler.CompileOps
+open FSharp.Compiler.CompileOptions
+open FSharp.Compiler.Driver
+open FSharp.Compiler.ErrorLogger
+open FSharp.Compiler.Lib
+open FSharp.Compiler.PrettyNaming
+open FSharp.Compiler.Parser
+open FSharp.Compiler.Range
+open FSharp.Compiler.Lexhelp
+open FSharp.Compiler.Layout
+open FSharp.Compiler.Tast
+open FSharp.Compiler.Tastops
+open FSharp.Compiler.TcGlobals
+open FSharp.Compiler.Text
+open FSharp.Compiler.Infos
+open FSharp.Compiler.InfoReader
+open FSharp.Compiler.NameResolution
+open FSharp.Compiler.TypeChecker
+open FSharp.Compiler.SourceCodeServices.SymbolHelpers
+
+open Internal.Utilities
+open Internal.Utilities.Collections
+open FSharp.Compiler.Layout.TaggedTextOps
+
+//-------------------------------------------------------------------------
+// InteractiveChecker
+//-------------------------------------------------------------------------
+
+type internal TcResult = TcEnv * TopAttribs * TypedImplFile option * ModuleOrNamespaceType
+type internal TcErrors = FSharpErrorInfo[]
+
+type InteractiveChecker internal (tcConfig, tcGlobals, tcImports, tcInitialState, ctok, reactorOps, parseCache, checkCache) =
+ let userOpName = "Unknown"
+ let suggestNamesForErrors = true
+
+ static member Create(projectOptions: FSharpProjectOptions) =
+ let tcConfig =
+ let tcConfigB = TcConfigBuilder.Initial
+ tcConfigB.legacyReferenceResolver <- SimulatedMSBuildReferenceResolver.getResolver()
+ let sourceFiles = projectOptions.SourceFiles |> Array.toList
+ let argv = projectOptions.OtherOptions |> Array.toList
+ let _sourceFiles = ApplyCommandLineArgs(tcConfigB, sourceFiles, argv)
+ TcConfig.Create(tcConfigB, validate=false)
+
+ let tcConfigP = TcConfigProvider.Constant(tcConfig)
+
+ let ctok = CompilationThreadToken()
+ let tcGlobals, tcImports =
+ TcImports.BuildTcImports (ctok, tcConfigP)
+ |> Cancellable.runWithoutCancellation
+
+ let niceNameGen = NiceNameGenerator()
+ let assemblyName = projectOptions.ProjectFileName |> System.IO.Path.GetFileNameWithoutExtension
+ let tcInitialEnv = GetInitialTcEnv (assemblyName, rangeStartup, tcConfig, tcImports, tcGlobals)
+ let tcInitialState = GetInitialTcState (rangeStartup, assemblyName, tcConfig, tcGlobals, tcImports, niceNameGen, tcInitialEnv)
+
+ let reactorOps =
+ { new IReactorOperations with
+ member __.EnqueueAndAwaitOpAsync (userOpName, opName, opArg, op) =
+ async.Return (Cancellable.runWithoutCancellation (op ctok))
+ member __.EnqueueOp (userOpName, opName, opArg, op) = (op ctok) }
+
+ // parse cache, keyed on file name and source hash
+ let parseCache = ConcurrentDictionary(HashIdentity.Structural)
+ // type check cache, keyed on file name
+ let checkCache = ConcurrentDictionary(HashIdentity.Structural)
+
+ InteractiveChecker (tcConfig, tcGlobals, tcImports, tcInitialState, ctok, reactorOps, parseCache, checkCache)
+
+ member private x.MakeProjectResults (projectFileName: string, parseResults: FSharpParseFileResults[], tcState: TcState, errors: FSharpErrorInfo[],
+ symbolUses: TcSymbolUses list, topAttrsOpt: TopAttribs option, tcImplFilesOpt: TypedImplFile list option) =
+ let assemblyRef = mkSimpleAssemblyRef "stdin"
+ let assemblyDataOpt = None
+ let access = tcState.TcEnvFromImpls.AccessRights
+ let dependencyFiles = parseResults |> Seq.map (fun x -> x.DependencyFiles) |> Array.concat
+ let details = (tcGlobals, tcImports, tcState.Ccu, tcState.CcuSig, symbolUses, topAttrsOpt, assemblyDataOpt, assemblyRef, access, tcImplFilesOpt, dependencyFiles)
+ let keepAssemblyContents = true
+ FSharpCheckProjectResults (projectFileName, Some tcConfig, keepAssemblyContents, errors, Some details)
+
+ member private x.ClearStaleCache (fileName: string, parsingOptions: FSharpParsingOptions) =
+ let fileIndex = parsingOptions.SourceFiles |> Array.findIndex ((=) fileName)
+ let filesAbove = parsingOptions.SourceFiles |> Array.take fileIndex
+ // backup all cached typecheck entries above file
+ let cachedAbove = filesAbove |> Array.choose (fun key ->
+ match checkCache.TryGetValue(key) with
+ | true, value -> Some (key, value)
+ | false, _ -> None)
+ // remove all parse cache entries with the same file name
+ let staleParseKeys = parseCache.Keys |> Seq.filter (fun (n,_) -> n = fileName) |> Seq.toArray
+ staleParseKeys |> Array.iter (fun key -> parseCache.TryRemove(key) |> ignore)
+ checkCache.Clear(); // clear all typecheck cache
+ // restore all cached typecheck entries above file
+ cachedAbove |> Array.iter (fun (key, value) -> checkCache.TryAdd(key, value) |> ignore)
+
+ member private x.ParseFile (fileName: string, sourceHash: int, source: Lazy, parsingOptions: FSharpParsingOptions) =
+ let parseCacheKey = fileName, sourceHash
+ parseCache.GetOrAdd(parseCacheKey, fun _ ->
+ x.ClearStaleCache(fileName, parsingOptions)
+ let sourceText = SourceText.ofString source.Value
+ let parseErrors, parseTreeOpt, anyErrors = ParseAndCheckFile.parseFile (sourceText, fileName, parsingOptions, userOpName, suggestNamesForErrors)
+ let dependencyFiles = [||] // interactions have no dependencies
+ FSharpParseFileResults (parseErrors, parseTreeOpt, anyErrors, dependencyFiles) )
+
+ member private x.TypeCheckOneInput (parseResults: FSharpParseFileResults, tcSink: TcResultsSink, tcState: TcState, moduleNamesDict: ModuleNamesDict) =
+ let input = parseResults.ParseTree.Value
+ let capturingErrorLogger = CompilationErrorLogger("TypeCheckFile", tcConfig.errorSeverityOptions)
+ let errorLogger = GetErrorLoggerFilteringByScopedPragmas(false, GetScopedPragmasForInput(input), capturingErrorLogger)
+ use _errorScope = new CompilationGlobalsScope (errorLogger, BuildPhase.TypeCheck)
+
+ let checkForErrors () = parseResults.ParseHadErrors || errorLogger.ErrorCount > 0
+ let prefixPathOpt = None
+
+ let input, moduleNamesDict = input |> DeduplicateParsedInputModuleName moduleNamesDict
+ let tcResult, tcState =
+ TypeCheckOneInputEventually (checkForErrors, tcConfig, tcImports, tcGlobals, prefixPathOpt, tcSink, tcState, input)
+ |> Eventually.force ctok
+
+ let fileName = parseResults.FileName
+ let tcErrors = ErrorHelpers.CreateErrorInfos (tcConfig.errorSeverityOptions, false, fileName, (capturingErrorLogger.GetErrors()), suggestNamesForErrors)
+ (tcResult, tcErrors), (tcState, moduleNamesDict)
+
+ member private x.CheckFile (projectFileName: string, parseResults: FSharpParseFileResults, tcState: TcState, moduleNamesDict: ModuleNamesDict) =
+ match parseResults.ParseTree with
+ | Some _input ->
+ let sink = TcResultsSinkImpl(tcGlobals)
+ let tcSink = TcResultsSink.WithSink sink
+ let (tcResult, tcErrors), (tcState, moduleNamesDict) =
+ x.TypeCheckOneInput (parseResults, tcSink, tcState, moduleNamesDict)
+ let fileName = parseResults.FileName
+ checkCache.[fileName] <- ((tcResult, tcErrors), (tcState, moduleNamesDict))
+
+ let loadClosure = None
+ let textSnapshotInfo = None
+ let keepAssemblyContents = true
+
+ let tcEnvAtEnd, _topAttrs, implFile, ccuSigForFile = tcResult
+ let errors = Array.append parseResults.Errors tcErrors
+
+ let scope = TypeCheckInfo (tcConfig, tcGlobals, ccuSigForFile, tcState.Ccu, tcImports, tcEnvAtEnd.AccessRights,
+ projectFileName, fileName, sink.GetResolutions(), sink.GetSymbolUses(), tcEnvAtEnd.NameEnv,
+ loadClosure, reactorOps, textSnapshotInfo, implFile, sink.GetOpenDeclarations())
+ FSharpCheckFileResults (fileName, errors, Some scope, parseResults.DependencyFiles, None, reactorOps, keepAssemblyContents)
+ |> Some
+ | None ->
+ None
+
+ member private x.TypeCheckClosedInputSet (parseResults: FSharpParseFileResults[], tcState) =
+ let cachedTypeCheck (tcState, moduleNamesDict) (parseRes: FSharpParseFileResults) =
+ let checkCacheKey = parseRes.FileName
+ let typeCheckOneInput _fileName =
+ x.TypeCheckOneInput (parseRes, TcResultsSink.NoSink, tcState, moduleNamesDict)
+ checkCache.GetOrAdd(checkCacheKey, typeCheckOneInput)
+ let results, (tcState, moduleNamesDict) =
+ ((tcState, Map.empty), parseResults) ||> Array.mapFold cachedTypeCheck
+ let tcResults, tcErrors = Array.unzip results
+ let (tcEnvAtEndOfLastFile, topAttrs, implFiles, _ccuSigsForFiles), tcState =
+ TypeCheckMultipleInputsFinish(tcResults |> Array.toList, tcState)
+ let tcState, declaredImpls = TypeCheckClosedInputSetFinish (implFiles, tcState)
+ tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile, moduleNamesDict, tcErrors
+
+ /// Errors grouped by file, sorted by line, column
+ member private x.ErrorsByFile (fileNames: string[], errorList: FSharpErrorInfo[] list) =
+ let errorMap = errorList |> Array.concat |> Array.groupBy (fun x -> x.FileName) |> Map.ofArray
+ let errors = fileNames |> Array.choose errorMap.TryFind
+ errors |> Array.iter (Array.sortInPlaceBy (fun x -> x.StartLineAlternate, x.StartColumn))
+ errors |> Array.concat
+
+ /// Clears parse and typecheck caches.
+ member x.ClearCache () =
+ parseCache.Clear()
+ checkCache.Clear()
+
+ /// Parses and checks the whole project, good for compilers (Fable etc.)
+ /// Does not retain name resolutions and symbol uses which are quite memory hungry (so no intellisense etc.).
+ /// Already parsed files will be cached so subsequent compilations will be faster.
+ member x.ParseAndCheckProject (projectFileName: string, fileNames: string[], sourceReader: string->int*Lazy) =
+ // parse files
+ let parsingOptions = FSharpParsingOptions.FromTcConfig(tcConfig, fileNames, false)
+ let parseResults = fileNames |> Array.map (fun fileName ->
+ let sourceHash, source = sourceReader fileName
+ x.ParseFile(fileName, sourceHash, source, parsingOptions))
+
+ // type check files
+ let tcState, topAttrs, tcImplFiles, _tcEnvAtEnd, _moduleNamesDict, tcErrors =
+ x.TypeCheckClosedInputSet (parseResults, tcInitialState)
+
+ // make project results
+ let parseErrors = parseResults |> Array.collect (fun p -> p.Errors)
+ let typedErrors = tcErrors |> Array.concat
+ let errors = x.ErrorsByFile (fileNames, [ parseErrors; typedErrors ])
+ let symbolUses = [] //TODO:
+ let projectResults = x.MakeProjectResults (projectFileName, parseResults, tcState, errors, symbolUses, Some topAttrs, Some tcImplFiles)
+
+ projectResults
+
+ /// Parses and checks file in project, will compile and cache all the files up to this one
+ /// (if not already done before), or fetch them from cache. Returns partial project results,
+ /// up to and including the file requested. Returns parse and typecheck results containing
+ /// name resolutions and symbol uses for the file requested only, so intellisense etc. works.
+ member x.ParseAndCheckFileInProject (fileName: string, projectFileName: string, fileNames: string[], sources: string[]) =
+ // get files before file
+ let fileIndex = fileNames |> Array.findIndex ((=) fileName)
+ let fileNamesBeforeFile = fileNames |> Array.take fileIndex
+ let sourcesBeforeFile = sources |> Array.take fileIndex
+
+ // parse files before file
+ let parsingOptions = FSharpParsingOptions.FromTcConfig(tcConfig, fileNames, false)
+ let parseFile (fileName, source) = x.ParseFile (fileName, hash source, lazy source, parsingOptions)
+ let parseResults = Array.zip fileNamesBeforeFile sourcesBeforeFile |> Array.map parseFile
+
+ // type check files before file
+ let tcState, topAttrs, tcImplFiles, _tcEnvAtEnd, moduleNamesDict, tcErrors =
+ x.TypeCheckClosedInputSet (parseResults, tcInitialState)
+
+ // parse and type check file
+ let parseFileResults = parseFile (fileName, sources.[fileIndex])
+ let checkFileResults = x.CheckFile (projectFileName, parseFileResults, tcState, moduleNamesDict)
+ let (tcResult, _tcErrors), (tcState, _moduleNamesDict) = checkCache.[fileName]
+ let _tcEnvAtEndFile, topAttrsFile, implFile, _ccuSigForFile = tcResult
+
+ // collect errors
+ let parseErrorsBefore = parseResults |> Array.collect (fun p -> p.Errors)
+ let typedErrorsBefore = tcErrors |> Array.concat
+ let newErrors = match checkFileResults with | Some res -> res.Errors | None -> [||]
+ let errors = x.ErrorsByFile (fileNames, [ parseErrorsBefore; typedErrorsBefore; newErrors ])
+
+ // make partial project results
+ let parseResults = Array.append parseResults [| parseFileResults |]
+ let tcImplFiles = List.append tcImplFiles (Option.toList implFile)
+ let topAttrs = CombineTopAttrs topAttrsFile topAttrs
+ let symbolUses = [] //TODO:
+ let projectResults = x.MakeProjectResults (projectFileName, parseResults, tcState, errors, symbolUses, Some topAttrs, Some tcImplFiles)
+
+ parseFileResults, checkFileResults, projectResults
diff --git a/fcs/build.fsx b/fcs/build.fsx
index cf0e0d8deda2..1abc53d7d3b9 100644
--- a/fcs/build.fsx
+++ b/fcs/build.fsx
@@ -31,7 +31,7 @@ let dotnetExePath =
if File.Exists(pathToCli) then
pathToCli
else
- DotNetCli.InstallDotNetSDK "2.2.105"
+ DotNetCli.InstallDotNetSDK "2.2.108"
let runDotnet workingDir args =
let result =
@@ -90,6 +90,10 @@ Target "BuildVersion" (fun _ ->
Shell.Exec("appveyor", sprintf "UpdateBuild -Version \"%s\"" buildVersion) |> ignore
)
+Target "BuildTools" (fun _ ->
+ runDotnet __SOURCE_DIRECTORY__ "build ../src/buildtools/buildtools.proj -v n -c Proto"
+)
+
Target "Build" (fun _ ->
runDotnet __SOURCE_DIRECTORY__ "build ../src/buildtools/buildtools.proj -v n -c Proto"
let fslexPath = __SOURCE_DIRECTORY__ + "/../artifacts/bin/fslex/Proto/netcoreapp2.1/fslex.dll"
diff --git a/fcs/fcs-test/Program.fs b/fcs/fcs-test/Program.fs
new file mode 100644
index 000000000000..794b436e2f68
--- /dev/null
+++ b/fcs/fcs-test/Program.fs
@@ -0,0 +1,127 @@
+open System.IO
+open System.Collections.Generic
+open FSharp.Compiler
+open FSharp.Compiler.SourceCodeServices
+
+let getProjectOptions (folder: string) (projectFile: string) =
+ let runProcess (workingDir: string) (exePath: string) (args: string) =
+ let psi = System.Diagnostics.ProcessStartInfo()
+ psi.FileName <- exePath
+ psi.WorkingDirectory <- workingDir
+ psi.RedirectStandardOutput <- false
+ psi.RedirectStandardError <- false
+ psi.Arguments <- args
+ psi.CreateNoWindow <- true
+ psi.UseShellExecute <- false
+
+ use p = new System.Diagnostics.Process()
+ p.StartInfo <- psi
+ p.Start() |> ignore
+ p.WaitForExit()
+
+ let exitCode = p.ExitCode
+ exitCode, ()
+
+ let runCmd exePath args = runProcess folder exePath (args |> String.concat " ")
+ let msbuildExec = Dotnet.ProjInfo.Inspect.dotnetMsbuild runCmd
+ let result = Dotnet.ProjInfo.Inspect.getProjectInfo ignore msbuildExec Dotnet.ProjInfo.Inspect.getFscArgs [] projectFile
+ match result with
+ | Ok (Dotnet.ProjInfo.Inspect.GetResult.FscArgs x) -> x
+ | _ -> []
+
+let mkStandardProjectReferences () =
+ let projFile = "fcs-test.fsproj"
+ let projDir = __SOURCE_DIRECTORY__
+ getProjectOptions projDir projFile
+ |> List.filter (fun s -> s.StartsWith("-r:"))
+ |> List.map (fun s -> s.Replace("-r:", ""))
+
+let mkProjectCommandLineArgsForScript (dllName, fileNames) =
+ [| yield "--simpleresolution"
+ yield "--noframework"
+ yield "--debug:full"
+ yield "--define:DEBUG"
+ yield "--optimize-"
+ yield "--out:" + dllName
+ yield "--doc:test.xml"
+ yield "--warn:3"
+ yield "--fullpaths"
+ yield "--flaterrors"
+ yield "--target:library"
+ for x in fileNames do
+ yield x
+ let references = mkStandardProjectReferences ()
+ for r in references do
+ yield "-r:" + r
+ |]
+
+let getProjectOptionsFromCommandLineArgs(projName, argv) =
+ { ProjectFileName = projName
+ ProjectId = None
+ SourceFiles = [| |]
+ OtherOptions = argv
+ ReferencedProjects = [| |]
+ IsIncompleteTypeCheckEnvironment = false
+ UseScriptResolutionRules = false
+ LoadTime = System.DateTime.MaxValue
+ UnresolvedReferences = None
+ OriginalLoadReferences = []
+ ExtraProjectInfo = None
+ Stamp = None }
+
+let printAst title (projectResults: FSharpCheckProjectResults) =
+ let implFiles = projectResults.AssemblyContents.ImplementationFiles
+ let decls = implFiles
+ |> Seq.collect (fun file -> AstPrint.printFSharpDecls "" file.Declarations)
+ |> String.concat "\n"
+ printfn "%s Typed AST:" title
+ decls |> printfn "%s"
+
+[]
+let main argv =
+ let projName = "Project.fsproj"
+ let fileName = "test_script.fsx"
+ let fileNames = [| fileName |]
+ let source = File.ReadAllText (fileName, System.Text.Encoding.UTF8)
+ let sources = [| source |]
+
+ let dllName = Path.ChangeExtension(fileName, ".dll")
+ let args = mkProjectCommandLineArgsForScript (dllName, fileNames)
+ // for arg in args do printfn "%s" arg
+
+ let projectOptions = getProjectOptionsFromCommandLineArgs (projName, args)
+ let checker = InteractiveChecker.Create(projectOptions)
+
+ // // parse and typecheck a project
+ // let projectResults = checker.ParseAndCheckProject(projName, fileNames, sources)
+ // projectResults.Errors |> Array.iter (fun e -> printfn "%A: %A" (e.Severity) e)
+ // printAst "ParseAndCheckProject" projectResults
+
+ // or just parse and typecheck a file in project
+ let parseResults, tcResultsOpt, projectResults =
+ checker.ParseAndCheckFileInProject(fileName, projName, fileNames, sources)
+ projectResults.Errors |> Array.iter (fun e -> printfn "%A: %A" (e.Severity) e)
+
+ match tcResultsOpt with
+ | Some typeCheckResults ->
+ printAst "ParseAndCheckFileInProject" projectResults
+
+ let inputLines = source.Split('\n')
+ async {
+ // Get tool tip at the specified location
+ let! tip = typeCheckResults.GetToolTipText(4, 7, inputLines.[3], ["foo"], FSharpTokenTag.IDENT)
+ (sprintf "%A" tip).Replace("\n","") |> printfn "\n---> ToolTip Text = %A" // should be "FSharpToolTipText [...]"
+
+ // Get declarations (autocomplete) for msg
+ let partialName = { QualifyingIdents = []; PartialIdent = "msg"; EndColumn = 17; LastDotPos = None }
+ let! decls = typeCheckResults.GetDeclarationListInfo(Some parseResults, 6, inputLines.[5], partialName, (fun _ -> []), fun _ -> false)
+ [ for item in decls.Items -> item.Name ] |> printfn "\n---> msg AutoComplete = %A" // should be string methods
+
+ // Get declarations (autocomplete) for canvas
+ let partialName = { QualifyingIdents = []; PartialIdent = "canvas"; EndColumn = 10; LastDotPos = None }
+ let! decls = typeCheckResults.GetDeclarationListInfo(Some parseResults, 8, inputLines.[7], partialName, (fun _ -> []), fun _ -> false)
+ [ for item in decls.Items -> item.Name ] |> printfn "\n---> canvas AutoComplete = %A"
+ } |> Async.StartImmediate
+
+ | _ -> ()
+ 0
diff --git a/fcs/fcs-test/Properties/launchSettings.json b/fcs/fcs-test/Properties/launchSettings.json
new file mode 100644
index 000000000000..06e83994e879
--- /dev/null
+++ b/fcs/fcs-test/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "fcs-test": {
+ "commandName": "Project",
+ "workingDirectory": "$(SolutionDir)"
+ }
+ }
+}
\ No newline at end of file
diff --git a/fcs/fcs-test/ast_print.fs b/fcs/fcs-test/ast_print.fs
new file mode 100644
index 000000000000..bf936a8d48d4
--- /dev/null
+++ b/fcs/fcs-test/ast_print.fs
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace FSharp.Compiler.SourceCodeServices
+
+//-------------------------------------------------------------------------
+// AstPrint
+//-------------------------------------------------------------------------
+
+module AstPrint =
+
+ let attribsOfSymbol (s:FSharpSymbol) =
+ [ match s with
+ | :? FSharpField as v ->
+ yield "field"
+ if v.IsCompilerGenerated then yield "compgen"
+ if v.IsDefaultValue then yield "default"
+ if v.IsMutable then yield "mutable"
+ if v.IsVolatile then yield "volatile"
+ if v.IsStatic then yield "static"
+ if v.IsLiteral then yield sprintf "%A" v.LiteralValue.Value
+
+ | :? FSharpEntity as v ->
+ v.TryFullName |> ignore // check there is no failure here
+ match v.BaseType with
+ | Some t when t.HasTypeDefinition && t.TypeDefinition.TryFullName.IsSome ->
+ yield sprintf "inherits %s" t.TypeDefinition.FullName
+ | _ -> ()
+ if v.IsNamespace then yield "namespace"
+ if v.IsFSharpModule then yield "module"
+ if v.IsByRef then yield "byref"
+ if v.IsClass then yield "class"
+ if v.IsDelegate then yield "delegate"
+ if v.IsEnum then yield "enum"
+ if v.IsFSharpAbbreviation then yield "abbrev"
+ if v.IsFSharpExceptionDeclaration then yield "exception"
+ if v.IsFSharpRecord then yield "record"
+ if v.IsFSharpUnion then yield "union"
+ if v.IsInterface then yield "interface"
+ if v.IsMeasure then yield "measure"
+#if !NO_EXTENSIONTYPING
+ if v.IsProvided then yield "provided"
+ if v.IsStaticInstantiation then yield "static_inst"
+ if v.IsProvidedAndErased then yield "erased"
+ if v.IsProvidedAndGenerated then yield "generated"
+#endif
+ if v.IsUnresolved then yield "unresolved"
+ if v.IsValueType then yield "valuetype"
+
+ | :? FSharpMemberOrFunctionOrValue as v ->
+ yield "owner: " + match v.DeclaringEntity with | Some e -> e.CompiledName | _ -> ""
+ if v.IsActivePattern then yield "active_pattern"
+ if v.IsDispatchSlot then yield "dispatch_slot"
+ if v.IsModuleValueOrMember && not v.IsMember then yield "val"
+ if v.IsMember then yield "member"
+ if v.IsProperty then yield "property"
+ if v.IsExtensionMember then yield "extension_member"
+ if v.IsPropertyGetterMethod then yield "property_getter"
+ if v.IsPropertySetterMethod then yield "property_setter"
+ if v.IsEvent then yield "event"
+ if v.EventForFSharpProperty.IsSome then yield "property_event"
+ if v.IsEventAddMethod then yield "event_add"
+ if v.IsEventRemoveMethod then yield "event_remove"
+ if v.IsTypeFunction then yield "type_func"
+ if v.IsCompilerGenerated then yield "compiler_gen"
+ if v.IsImplicitConstructor then yield "implicit_ctor"
+ if v.IsMutable then yield "mutable"
+ if v.IsOverrideOrExplicitInterfaceImplementation then yield "override_impl"
+ if not v.IsInstanceMember then yield "static"
+ if v.IsInstanceMember && not v.IsInstanceMemberInCompiledCode && not v.IsExtensionMember then yield "funky"
+ if v.IsExplicitInterfaceImplementation then yield "interface_impl"
+ yield sprintf "%A" v.InlineAnnotation
+ // if v.IsConstructorThisValue then yield "ctorthis"
+ // if v.IsMemberThisValue then yield "this"
+ // if v.LiteralValue.IsSome then yield "literal"
+ | _ -> () ]
+
+ let rec printFSharpDecls prefix decls = seq {
+ let mutable i = 0
+ for decl in decls do
+ i <- i + 1
+ match decl with
+ | FSharpImplementationFileDeclaration.Entity (e, sub) ->
+ yield sprintf "%s%i) ENTITY: %s %A" prefix i e.CompiledName (attribsOfSymbol e)
+ if not (Seq.isEmpty e.Attributes) then
+ yield sprintf "%sattributes: %A" prefix (Seq.toList e.Attributes)
+ if not (Seq.isEmpty e.DeclaredInterfaces) then
+ yield sprintf "%sinterfaces: %A" prefix (Seq.toList e.DeclaredInterfaces)
+ yield ""
+ yield! printFSharpDecls (prefix + "\t") sub
+ | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue (meth, args, body) ->
+ yield sprintf "%s%i) METHOD: %s %A" prefix i meth.CompiledName (attribsOfSymbol meth)
+ yield sprintf "%stype: %A" prefix meth.FullType
+ yield sprintf "%sargs: %A" prefix args
+ // if not meth.IsCompilerGenerated then
+ yield sprintf "%sbody: %A" prefix body
+ yield ""
+ | FSharpImplementationFileDeclaration.InitAction (expr) ->
+ yield sprintf "%s%i) ACTION" prefix i
+ yield sprintf "%s%A" prefix expr
+ yield ""
+ }
diff --git a/fcs/fcs-test/fcs-test.fsproj b/fcs/fcs-test/fcs-test.fsproj
new file mode 100644
index 000000000000..592cf650c207
--- /dev/null
+++ b/fcs/fcs-test/fcs-test.fsproj
@@ -0,0 +1,24 @@
+
+
+
+ Exe
+ netcoreapp2.1
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fcs/fcs-test/fcs-test.sln b/fcs/fcs-test/fcs-test.sln
new file mode 100644
index 000000000000..3287d08d17de
--- /dev/null
+++ b/fcs/fcs-test/fcs-test.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.329
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "fcs-test", "fcs-test.fsproj", "{9AC7F48B-3B30-4FC6-BB6D-16018DF0BA7D}"
+EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service", "..\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{9C758A40-9461-4E41-9C93-219684F0A489}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9AC7F48B-3B30-4FC6-BB6D-16018DF0BA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9AC7F48B-3B30-4FC6-BB6D-16018DF0BA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9AC7F48B-3B30-4FC6-BB6D-16018DF0BA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9AC7F48B-3B30-4FC6-BB6D-16018DF0BA7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C758A40-9461-4E41-9C93-219684F0A489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C758A40-9461-4E41-9C93-219684F0A489}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C758A40-9461-4E41-9C93-219684F0A489}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C758A40-9461-4E41-9C93-219684F0A489}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F6FF1C8B-1B15-4F82-990E-A2D53B4BEE4A}
+ EndGlobalSection
+EndGlobal
diff --git a/fcs/fcs-test/test_script.fsx b/fcs/fcs-test/test_script.fsx
new file mode 100644
index 000000000000..1bbe729ab75a
--- /dev/null
+++ b/fcs/fcs-test/test_script.fsx
@@ -0,0 +1,8 @@
+open System
+open Fable.Import
+
+let foo() =
+ let msg = String.Concat("Hello"," ","world")
+ let len = msg.Length
+ let canvas = Browser.document.createElement_canvas ()
+ canvas.width <- 1000.
diff --git a/global.json b/global.json
index 0a08d8518b54..9d22c5b7a912 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"tools": {
- "dotnet": "3.0.100-preview6-012264",
+ "dotnet": "2.2.108",
"vs": {
"version": "16.1",
"components": [
diff --git a/src/buildtools/buildtools.targets b/src/buildtools/buildtools.targets
index 185fd4d05992..ed1e0998c4d6 100644
--- a/src/buildtools/buildtools.targets
+++ b/src/buildtools/buildtools.targets
@@ -20,7 +20,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fslex\fslex.dll
+ $(ArtifactsDir)\bin\fslex\Proto\netcoreapp2.1\fslex.dll
@@ -43,7 +43,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fsyacc\fsyacc.dll
+ $(ArtifactsDir)\bin\fslex\Proto\netcoreapp2.1\fsyacc.dll
diff --git a/src/fsharp/service/FSharpCheckerResults.fsi b/src/fsharp/service/FSharpCheckerResults.fsi
index 4f7062d9ce2d..4dbee3ee497b 100644
--- a/src/fsharp/service/FSharpCheckerResults.fsi
+++ b/src/fsharp/service/FSharpCheckerResults.fsi
@@ -91,9 +91,39 @@ type public FSharpParsingOptions =
static member internal FromTcConfigBuidler: tcConfigB: TcConfigBuilder * sourceFiles: string[] * isInteractive: bool -> FSharpParsingOptions
+[]
+type internal TypeCheckInfo =
+ internal new :
+ tcConfig: TcConfig *
+ tcGlobals: TcGlobals *
+ ccuSigForFile: ModuleOrNamespaceType *
+ thisCcu: CcuThunk *
+ tcImports: TcImports *
+ tcAccessRights: AccessorDomain *
+ projectFileName: string *
+ mainInputFileName: string *
+ sResolutions: TcResolutions *
+ sSymbolUses: TcSymbolUses *
+ sFallback: NameResolutionEnv *
+ loadClosure : LoadClosure option *
+ reactorOps : IReactorOperations *
+ textSnapshotInfo:obj option *
+ implFileOpt: TypedImplFile option *
+ openDeclarations: OpenDeclaration[]
+ -> TypeCheckInfo
+ member ScopeResolutions: TcResolutions
+ member ScopeSymbolUses: TcSymbolUses
+ member TcGlobals: TcGlobals
+ member TcImports: TcImports
+ member CcuSigForFile: Tast.ModuleOrNamespaceType
+ member ThisCcu: Tast.CcuThunk
+ member ImplementationFile: TypedImplFile option
+
/// A handle to the results of CheckFileInProject.
[]
type public FSharpCheckFileResults =
+ internal new : filename: string * errors: FSharpErrorInfo[] * scopeOptX: TypeCheckInfo option * dependencyFiles: string[] * builderX: IncrementalBuilder option * reactorOpsX:IReactorOperations * keepAssemblyContents: bool -> FSharpCheckFileResults
+
/// The errors returned by parsing a source file.
member Errors : FSharpErrorInfo[]