diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs
index b1dcc1c77a5..91dc03a6482 100644
--- a/src/fsharp/CompileOps.fs
+++ b/src/fsharp/CompileOps.fs
@@ -992,6 +992,7 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) =
| Parser.TOKEN_KEYWORD_STRING -> getErrorString("Parser.TOKEN.KEYWORD_STRING")
| Parser.TOKEN_EOF -> getErrorString("Parser.TOKEN.EOF")
| Parser.TOKEN_CONST -> getErrorString("Parser.TOKEN.CONST")
+ | Parser.TOKEN_FIXED -> getErrorString("Parser.TOKEN.FIXED")
| unknown ->
System.Diagnostics.Debug.Assert(false,"unknown token tag")
let result = sprintf "%+A" unknown
diff --git a/src/fsharp/FSStrings.resx b/src/fsharp/FSStrings.resx
index 04bce992367..9dd1eef5577 100644
--- a/src/fsharp/FSStrings.resx
+++ b/src/fsharp/FSStrings.resx
@@ -447,6 +447,9 @@
keyword 'internal'
+
+ keyword 'fixed'
+
keyword 'constraint'
diff --git a/vsintegration/src/FSharp.Editor/BraceMatchingService.fs b/vsintegration/src/FSharp.Editor/BraceMatchingService.fs
index c76b640b565..10b4d0c0cc8 100644
--- a/vsintegration/src/FSharp.Editor/BraceMatchingService.fs
+++ b/vsintegration/src/FSharp.Editor/BraceMatchingService.fs
@@ -15,7 +15,7 @@ type internal FSharpBraceMatchingService() =
let isPositionInRange(range) =
let span = CommonRoslynHelpers.FSharpRangeToTextSpan(sourceText, range)
span.Start <= position && position < span.End
- let! matchedBraces = FSharpChecker.Instance.MatchBracesAlternate(fileName, sourceText.ToString(), options)
+ let! matchedBraces = FSharpLanguageService.Checker.MatchBracesAlternate(fileName, sourceText.ToString(), options)
return matchedBraces |> Seq.tryFind(fun(left, right) -> isPositionInRange(left) || isPositionInRange(right))
}
diff --git a/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs b/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs
index c50ae6cba46..74ea40ad046 100644
--- a/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs
+++ b/vsintegration/src/FSharp.Editor/BreakpointResolutionService.fs
@@ -32,13 +32,12 @@ open Microsoft.FSharp.Compiler.Range
type internal FSharpBreakpointResolutionService() =
static member GetBreakpointLocation(sourceText: SourceText, fileName: string, textSpan: TextSpan, options: FSharpProjectOptions) = async {
- let! parseResults = FSharpChecker.Instance.ParseFileInProject(fileName, sourceText.ToString(), options)
- let textLine = sourceText.Lines.GetLineFromPosition(textSpan.Start)
+ let! parseResults = FSharpLanguageService.Checker.ParseFileInProject(fileName, sourceText.ToString(), options)
+ let textLinePos = sourceText.Lines.GetLinePosition(textSpan.Start)
+ let textLineColumn = textLinePos.Character
+ let fcsTextLineNumber = textLinePos.Line + 1 // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based
- let textLineNumber = textLine.LineNumber + 1 // Roslyn line numbers are zero-based
- let textColumnNumber = textSpan.Start - textLine.Start
-
- return parseResults.ValidateBreakpointLocation(mkPos textLineNumber textColumnNumber)
+ return parseResults.ValidateBreakpointLocation(mkPos fcsTextLineNumber textLineColumn)
}
interface IBreakpointResolutionService with
diff --git a/vsintegration/src/FSharp.Editor/ColorizationService.fs b/vsintegration/src/FSharp.Editor/ColorizationService.fs
index 1ab24a9d0a0..e4ae973b2ee 100644
--- a/vsintegration/src/FSharp.Editor/ColorizationService.fs
+++ b/vsintegration/src/FSharp.Editor/ColorizationService.fs
@@ -149,9 +149,9 @@ type internal FSharpColorizationService() =
match FSharpLanguageService.GetOptions(document.Project.Id) with
| Some(options) ->
let! sourceText = document.GetTextAsync(cancellationToken) |> Async.AwaitTask
- let! parseResults = FSharpChecker.Instance.ParseFileInProject(document.Name, sourceText.ToString(), options)
+ let! parseResults = FSharpLanguageService.Checker.ParseFileInProject(document.Name, sourceText.ToString(), options)
let! textVersion = document.GetTextVersionAsync(cancellationToken) |> Async.AwaitTask
- let! checkResultsAnswer = FSharpChecker.Instance.CheckFileInProject(parseResults, document.FilePath, textVersion.GetHashCode(), textSpan.ToString(), options)
+ let! checkResultsAnswer = FSharpLanguageService.Checker.CheckFileInProject(parseResults, document.FilePath, textVersion.GetHashCode(), textSpan.ToString(), options)
let extraColorizationData = match checkResultsAnswer with
| FSharpCheckFileAnswer.Aborted -> failwith "Compilation isn't complete yet"
diff --git a/vsintegration/src/FSharp.Editor/CompletionProvider.fs b/vsintegration/src/FSharp.Editor/CompletionProvider.fs
index 3c5c8878b34..5d23f69d3a5 100644
--- a/vsintegration/src/FSharp.Editor/CompletionProvider.fs
+++ b/vsintegration/src/FSharp.Editor/CompletionProvider.fs
@@ -73,16 +73,19 @@ type internal FSharpCompletionProvider(workspace: Workspace, serviceProvider: SV
| _ -> true // anything else is a valid classification type
static member ProvideCompletionsAsyncAux(sourceText: SourceText, caretPosition: int, options: FSharpProjectOptions, filePath: string, textVersionHash: int) = async {
- let! parseResults = FSharpChecker.Instance.ParseFileInProject(filePath, sourceText.ToString(), options)
- let! checkFileAnswer = FSharpChecker.Instance.CheckFileInProject(parseResults, filePath, textVersionHash, sourceText.ToString(), options)
+ let! parseResults = FSharpLanguageService.Checker.ParseFileInProject(filePath, sourceText.ToString(), options)
+ let! checkFileAnswer = FSharpLanguageService.Checker.CheckFileInProject(parseResults, filePath, textVersionHash, sourceText.ToString(), options)
let checkFileResults = match checkFileAnswer with
| FSharpCheckFileAnswer.Aborted -> failwith "Compilation isn't complete yet"
| FSharpCheckFileAnswer.Succeeded(results) -> results
let textLine = sourceText.Lines.GetLineFromPosition(caretPosition)
- let textLineNumber = textLine.LineNumber + 1 // Roslyn line numbers are zero-based
- let qualifyingNames, partialName = QuickParse.GetPartialLongNameEx(textLine.ToString(), caretPosition - textLine.Start - 1)
- let! declarations = checkFileResults.GetDeclarationListInfo(Some(parseResults), textLineNumber, caretPosition, textLine.ToString(), qualifyingNames, partialName)
+ let textLinePos = sourceText.Lines.GetLinePosition(caretPosition)
+ let fcsTextLineNumber = textLinePos.Line + 1 // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based
+ let textLineColumn = textLinePos.Character
+
+ let qualifyingNames, partialName = QuickParse.GetPartialLongNameEx(textLine.ToString(), textLineColumn - 1)
+ let! declarations = checkFileResults.GetDeclarationListInfo(Some(parseResults), fcsTextLineNumber, textLineColumn, textLine.ToString(), qualifyingNames, partialName)
let results = List()
diff --git a/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs
index 6eeb31ef073..c599df57638 100644
--- a/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs
+++ b/vsintegration/src/FSharp.Editor/DocumentDiagnosticAnalyzer.fs
@@ -25,10 +25,10 @@ type internal FSharpDocumentDiagnosticAnalyzer() =
inherit DocumentDiagnosticAnalyzer()
static member GetDiagnostics(filePath: string, sourceText: SourceText, textVersionHash: int, options: FSharpProjectOptions, addSemanticErrors: bool) =
- let parseResults = FSharpChecker.Instance.ParseFileInProject(filePath, sourceText.ToString(), options) |> Async.RunSynchronously
+ let parseResults = FSharpLanguageService.Checker.ParseFileInProject(filePath, sourceText.ToString(), options) |> Async.RunSynchronously
let errors =
if addSemanticErrors then
- let checkResultsAnswer = FSharpChecker.Instance.CheckFileInProject(parseResults, filePath, textVersionHash, sourceText.ToString(), options) |> Async.RunSynchronously
+ let checkResultsAnswer = FSharpLanguageService.Checker.CheckFileInProject(parseResults, filePath, textVersionHash, sourceText.ToString(), options) |> Async.RunSynchronously
match checkResultsAnswer with
| FSharpCheckFileAnswer.Aborted -> failwith "Compilation isn't complete yet"
| FSharpCheckFileAnswer.Succeeded(results) -> results.Errors
diff --git a/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs b/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs
index 62bc7bfd47b..0eaefd94452 100644
--- a/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs
+++ b/vsintegration/src/FSharp.Editor/GoToDefinitionService.fs
@@ -54,20 +54,21 @@ type internal FSharpGoToDefinitionService [] ([> = async {
let textLine = sourceText.Lines.GetLineFromPosition(position)
- let textLineNumber = textLine.LineNumber + 1 // Roslyn line numbers are zero-based
- let textLineColumn = sourceText.Lines.GetLinePosition(position).Character
+ let textLinePos = sourceText.Lines.GetLinePosition(position)
+ let fcsTextLineNumber = textLinePos.Line + 1 // Roslyn line numbers are zero-based, FSharp.Compiler.Service line numbers are 1-based
+ let textLineColumn = textLinePos.Character
let classifiedSpanOption =
FSharpColorizationService.GetColorizationData(sourceText, textLine.Span, Some(filePath), defines, cancellationToken)
|> Seq.tryFind(fun classifiedSpan -> classifiedSpan.TextSpan.Contains(position))
let processQualifiedIdentifier(qualifiers, islandColumn) = async {
- let! parseResults = FSharpChecker.Instance.ParseFileInProject(filePath, sourceText.ToString(), options)
- let! checkFileAnswer = FSharpChecker.Instance.CheckFileInProject(parseResults, filePath, textVersionHash, sourceText.ToString(), options)
+ let! parseResults = FSharpLanguageService.Checker.ParseFileInProject(filePath, sourceText.ToString(), options)
+ let! checkFileAnswer = FSharpLanguageService.Checker.CheckFileInProject(parseResults, filePath, textVersionHash, sourceText.ToString(), options)
let checkFileResults = match checkFileAnswer with
| FSharpCheckFileAnswer.Aborted -> failwith "Compilation isn't complete yet"
| FSharpCheckFileAnswer.Succeeded(results) -> results
- let! declarations = checkFileResults.GetDeclarationLocationAlternate (textLineNumber, islandColumn, textLine.ToString(), qualifiers, false)
+ let! declarations = checkFileResults.GetDeclarationLocationAlternate (fcsTextLineNumber, islandColumn, textLine.ToString(), qualifiers, false)
return match declarations with
| FSharpFindDeclResult.DeclFound(range) -> Some(range)
@@ -103,12 +104,14 @@ type internal FSharpGoToDefinitionService [] ([
- let refDocumentId = document.Project.Solution.GetDocumentIdsWithFilePath(range.FileName).First()
- let refDocument = document.Project.Solution.GetDocument(refDocumentId)
- let! refSourceText = refDocument.GetTextAsync(cancellationToken) |> Async.AwaitTask
- let refTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan(refSourceText, range)
- let refDisplayString = refSourceText.GetSubText(refTextSpan).ToString()
- results.Add(FSharpNavigableItem(refDocument, refTextSpan, refDisplayString))
+ let refDocumentIds = document.Project.Solution.GetDocumentIdsWithFilePath(range.FileName)
+ if not refDocumentIds.IsEmpty then
+ let refDocumentId = refDocumentIds.First()
+ let refDocument = document.Project.Solution.GetDocument(refDocumentId)
+ let! refSourceText = refDocument.GetTextAsync(cancellationToken) |> Async.AwaitTask
+ let refTextSpan = CommonRoslynHelpers.FSharpRangeToTextSpan(refSourceText, range)
+ let refDisplayString = refSourceText.GetSubText(refTextSpan).ToString()
+ results.Add(FSharpNavigableItem(refDocument, refTextSpan, refDisplayString))
| None -> ()
| None -> ()
return results.AsEnumerable()
diff --git a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs
index bba0ecf6b5a..928988ce323 100644
--- a/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs
+++ b/vsintegration/src/FSharp.Editor/LanguageDebugInfoService.fs
@@ -46,7 +46,9 @@ type internal FSharpLanguageDebugInfoService() =
| ClassificationTypeNames.Identifier ->
let textLine = sourceText.Lines.GetLineFromPosition(position)
- match QuickParse.GetCompleteIdentifierIsland false (textLine.ToString()) (position - textLine.Start) with
+ let textLinePos = sourceText.Lines.GetLinePosition(position)
+ let textLineColumn = textLinePos.Character
+ match QuickParse.GetCompleteIdentifierIsland false (textLine.ToString()) textLineColumn with
| None -> None
| Some(island, islandEnd, _) ->
let islandDocumentStart = textLine.Start + islandEnd - island.Length
diff --git a/vsintegration/src/FSharp.Editor/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService.fs
index ce73f66b85e..aa1aac86c12 100644
--- a/vsintegration/src/FSharp.Editor/LanguageService.fs
+++ b/vsintegration/src/FSharp.Editor/LanguageService.fs
@@ -49,6 +49,9 @@ type internal FSharpLanguageService(package : FSharpPackage) =
inherit AbstractLanguageService(package)
static let optionsCache = Dictionary()
+ static let checker = lazy FSharpChecker.Create()
+ static member Checker with get() = checker.Value
+
static member GetOptions(projectId: ProjectId) =
if optionsCache.ContainsKey(projectId) then
Some(optionsCache.[projectId])
@@ -118,7 +121,7 @@ type internal FSharpLanguageService(package : FSharpPackage) =
| _ -> ()
member this.SetupStandAloneFile(fileName: string, fileContents: string, workspace: VisualStudioWorkspaceImpl, hier: IVsHierarchy) =
- let options = FSharpChecker.Instance.GetProjectOptionsFromScript(fileName, fileContents, DateTime.Now, [| |]) |> Async.RunSynchronously
+ let options = FSharpLanguageService.Checker.GetProjectOptionsFromScript(fileName, fileContents, DateTime.Now, [| |]) |> Async.RunSynchronously
let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath(options.ProjectFileName, options.ProjectFileName)
if not(optionsCache.ContainsKey(projectId)) then
diff --git a/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs b/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs
index df1e56d07a7..f80b6944b36 100644
--- a/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs
+++ b/vsintegration/src/FSharp.Editor/ProjectDiagnosticAnalyzer.fs
@@ -26,7 +26,7 @@ type internal FSharpProjectDiagnosticAnalyzer() =
inherit ProjectDiagnosticAnalyzer()
static member GetDiagnostics(options: FSharpProjectOptions) =
- let checkProjectResults = FSharpChecker.Instance.ParseAndCheckProject(options) |> Async.RunSynchronously
+ let checkProjectResults = FSharpLanguageService.Checker.ParseAndCheckProject(options) |> Async.RunSynchronously
(checkProjectResults.Errors |> Seq.choose(fun (error) ->
if error.StartLineAlternate = 0 || error.EndLineAlternate = 0 then
Some(CommonRoslynHelpers.ConvertError(error, Location.None))