Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit51000fb

Browse files
authored
Add ISourceText to language service and use Roslyn's SourceText for FSharp.Editor (dotnet#6001)
* Initial ISourceText implementation (does not work yet)* Lexbuffer works* Removing Source. Now using only ISourceText. Added SourceText.ofString.* Fixing tests* We need to use addNewLine for tests to pass* Added test for SourceText.ofString* Trying to fix tests* Simplified ISourceText API. Added RoslynSourceTextTests* Trying to get the build working again* Re-organize prim-lexing.fsi* Handling format strings* Trying to get tests to pass* Trying to fix tests* Ignoring test* unignoring test* Fixed weak table* Removing addNewLine in sourcetext* Fixing interactive checker tests* Fixing more tests* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removed addNewLine* Removing last addNewLine. It's done* Better tests and small optimizations* Adjusting comment* Updating CompilerServiceBenchmarks* Updated nits
1 parentb4abd96 commit51000fb

File tree

59 files changed

+650
-253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+650
-253
lines changed

‎benchmarks/CompilerServiceBenchmarks/CompilerServiceBenchmarks.fsproj‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212
<DefaultValueTuplePackageVersion>$(SystemValueTuplePackageVersion)</DefaultValueTuplePackageVersion>
1313
</PropertyGroup>
1414

15+
<PropertyGroupCondition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
16+
<PlatformTarget>AnyCPU</PlatformTarget>
17+
</PropertyGroup>
18+
1519
<ItemGroup>
1620
<CompileInclude="Program.fs" />
1721
</ItemGroup>
1822

1923
<ItemGroup>
2024
<PackageReferenceInclude="BenchmarkDotNet"Version="0.11.3" />
25+
<PackageReferenceInclude="Microsoft.CodeAnalysis.EditorFeatures.Text"Version="2.9.0" />
2126
</ItemGroup>
2227

2328
<ItemGroup>

‎benchmarks/CompilerServiceBenchmarks/Program.fs‎

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,80 @@ open BenchmarkDotNet.Attributes
44
openBenchmarkDotNet.Running
55
openMicrosoft.FSharp.Compiler.ErrorLogger
66
openMicrosoft.FSharp.Compiler.SourceCodeServices
7+
openMicrosoft.FSharp.Compiler.Text
78
openSystem.Text
9+
openMicrosoft.CodeAnalysis.Text
810

9-
[<ClrJob(baseline=true); MemoryDiagnoser>]
11+
moduleprivateSourceText=
12+
13+
openSystem.Runtime.CompilerServices
14+
15+
letweakTable= ConditionalWeakTable<SourceText, ISourceText>()
16+
17+
letcreate(sourceText:SourceText)=
18+
19+
letsourceText=
20+
{new ISourceTextwith
21+
22+
member__.Itemwith get index= sourceText.[index]
23+
24+
member__.GetLineString(lineIndex)=
25+
sourceText.Lines.[lineIndex].ToString()
26+
27+
member__.GetLineCount()=
28+
sourceText.Lines.Count
29+
30+
member__.GetLastCharacterPosition()=
31+
if sourceText.Lines.Count>0then
32+
(sourceText.Lines.Count, sourceText.Lines.[sourceText.Lines.Count-1].Span.Length)
33+
else
34+
(0,0)
35+
36+
member__.GetSubTextString(start,length)=
37+
sourceText.GetSubText(TextSpan(start, length)).ToString()
38+
39+
member__.SubTextEquals(target,startIndex)=
40+
if startIndex<0|| startIndex>= sourceText.Lengththen
41+
raise(ArgumentOutOfRangeException("startIndex"))
42+
43+
if String.IsNullOrEmpty(target)then
44+
raise(ArgumentException("Target is null or empty.","target"))
45+
46+
letlastIndex= startIndex+ target.Length
47+
if lastIndex<= startIndex|| lastIndex>= sourceText.Lengththen
48+
raise(ArgumentException("Target is too big.","target"))
49+
50+
let mutablefinished=false
51+
let mutabledidEqual=true
52+
let mutablei=0
53+
whilenot finished&& i< target.Lengthdo
54+
if target.[i]<> sourceText.[startIndex+ i]then
55+
didEqual<-false
56+
finished<-true// bail out early
57+
else
58+
i<- i+1
59+
60+
didEqual
61+
62+
member__.ContentEquals(sourceText)=
63+
match sourceTextwith
64+
|:? SourceText as sourceText-> sourceText.ContentEquals(sourceText)
65+
|_->false
66+
67+
member__.Length= sourceText.Length
68+
69+
member__.CopyTo(sourceIndex,destination,destinationIndex,count)=
70+
sourceText.CopyTo(sourceIndex, destination, destinationIndex, count)
71+
}
72+
73+
sourceText
74+
75+
typeSourceTextwith
76+
77+
memberthis.ToFSharpSourceText()=
78+
SourceText.weakTable.GetValue(this, Runtime.CompilerServices.ConditionalWeakTable<_,_>.CreateValueCallback(SourceText.create))
79+
80+
[<ClrJob; MemoryDiagnoser>]
1081
typeCompilerServiceParsing()=
1182

1283
let mutablecheckerOpt= None
@@ -32,8 +103,7 @@ type CompilerServiceParsing() =
32103

33104
match sourceOptwith
34105
| None->
35-
letsource= File.ReadAllText("""..\..\..\..\..\src\fsharp\TypeChecker.fs""")
36-
sourceOpt<- Some(source)
106+
sourceOpt<- Some<| SourceText.From(File.OpenRead("""..\..\..\..\..\src\fsharp\TypeChecker.fs"""), Encoding.Default, SourceHashAlgorithm.Sha1,true)
37107
|_->()
38108

39109
[<IterationSetup>]
@@ -43,18 +113,18 @@ type CompilerServiceParsing() =
43113
| Some(checker)->
44114
checker.InvalidateAll()
45115
checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients()
46-
checker.ParseFile("dummy.fs","dummy", parsingOptions)|> Async.RunSynchronously|> ignore
116+
checker.ParseFile("dummy.fs",SourceText.ofString"dummy", parsingOptions)|> Async.RunSynchronously|> ignore
47117

48118
[<Benchmark>]
49119
member__.Parsing()=
50120
match checkerOpt, sourceOptwith
51121
| None,_-> failwith"no checker"
52122
|_, None-> failwith"no source"
53123
| Some(checker), Some(source)->
54-
letresults= checker.ParseFile("TypeChecker.fs", source, parsingOptions)|> Async.RunSynchronously
124+
letresults= checker.ParseFile("TypeChecker.fs", source.ToFSharpSourceText(), parsingOptions)|> Async.RunSynchronously
55125
if results.ParseHadErrorsthen failwithf"parse had errors:%A" results.Errors
56126

57127
[<EntryPoint>]
58128
letmain argv=
59129
let_= BenchmarkRunner.Run<CompilerServiceParsing>()
60-
0
130+
0

‎fcs/samples/EditorService/Program.fs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ open Microsoft.FSharp.Compiler.QuickParse
88
letchecker= FSharpChecker.Create()
99

1010
letparseWithTypeInfo(file,input)=
11+
letinput= Microsoft.FSharp.Compiler.Text.SourceText.ofString input
1112
letcheckOptions,_errors= checker.GetProjectOptionsFromScript(file, input)|> Async.RunSynchronously
1213
letparsingOptions,_errors= checker.GetParsingOptionsFromProjectOptions(checkOptions)
1314
letuntypedRes= checker.ParseFile(file, input, parsingOptions)|> Async.RunSynchronously

‎fcs/samples/UntypedTree/Program.fs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let checker = FSharpChecker.Create()
1111
// Get untyped tree for a specified input
1212
letgetUntypedTree(file,input)=
1313
letparsingOptions={ FSharpParsingOptions.Defaultwith SourceFiles=[| file|]}
14-
letuntypedRes= checker.ParseFile(file, input, parsingOptions)|> Async.RunSynchronously
14+
letuntypedRes= checker.ParseFile(file,Microsoft.FSharp.Compiler.Text.SourceText.ofStringinput, parsingOptions)|> Async.RunSynchronously
1515
match untypedRes.ParseTreewith
1616
| Some tree-> tree
1717
| None-> failwith"Something went wrong during parsing!"

‎src/fsharp/CheckFormatStrings.fs‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,17 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (context: FormatStringChe
5454
let(offset,fmt)=
5555
match contextwith
5656
| Some context->
57-
letlength= context.Source.Length
58-
if m.EndLine< context.LineStartPositions.Lengththen
59-
letstartIndex= context.LineStartPositions.[m.StartLine-1]+ m.StartColumn
60-
letendIndex= context.LineStartPositions.[m.EndLine-1]+ m.EndColumn-1
61-
if startIndex< length-3&& context.Source.[startIndex..startIndex+2]="\"\"\""then
62-
(3, context.Source.[startIndex+3..endIndex-3])
63-
elif startIndex< length-2&& context.Source.[startIndex..startIndex+1]="@\""then
64-
(2, context.Source.[startIndex+2..endIndex-1])
65-
else(1, context.Source.[startIndex+1..endIndex-1])
57+
letsourceText= context.SourceText
58+
letlineStartPositions= context.LineStartPositions
59+
letlength= sourceText.Length
60+
if m.EndLine< lineStartPositions.Lengththen
61+
letstartIndex= lineStartPositions.[m.StartLine-1]+ m.StartColumn
62+
letendIndex= lineStartPositions.[m.EndLine-1]+ m.EndColumn-1
63+
if startIndex< length-3&& sourceText.SubTextEquals("\"\"\"", startIndex)then
64+
(3, sourceText.GetSubTextString(startIndex+3, endIndex- startIndex))
65+
elif startIndex< length-2&& sourceText.SubTextEquals("@\"", startIndex)then
66+
(2, sourceText.GetSubTextString(startIndex+2, endIndex+1- startIndex))
67+
else(1, sourceText.GetSubTextString(startIndex+1, endIndex- startIndex))
6668
else(1, fmt)
6769
| None->(1, fmt)
6870

‎src/fsharp/CompileOps.fs‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
2222
openMicrosoft.FSharp.Compiler.AbstractIL.Extensions.ILX
2323
openMicrosoft.FSharp.Compiler.AbstractIL.Diagnostics
2424

25-
openMicrosoft.FSharp.Compiler
25+
openMicrosoft.FSharp.Compiler
26+
openMicrosoft.FSharp.Compiler.Text
2627
openMicrosoft.FSharp.Compiler.Ast
2728
openMicrosoft.FSharp.Compiler.AttributeChecking
2829
openMicrosoft.FSharp.Compiler.ConstraintSolver
@@ -5037,7 +5038,7 @@ module private ScriptPreprocessClosure =
50375038
openInternal.Utilities.Text.Lexing
50385039

50395040
/// Represents an input to the closure finding process
5040-
typeClosureSource= ClosureSourceoffilename:string*referenceRange:range*sourceText:string*parseRequired:bool
5041+
typeClosureSource= ClosureSourceoffilename:string*referenceRange:range*sourceText:ISourceText*parseRequired:bool
50415042

50425043
/// Represents an output of the closure finding process
50435044
typeClosureFile= ClosureFileofstring*range*ParsedInputoption*(PhasedDiagnostic*bool)list*(PhasedDiagnostic*bool)list*(string*range)list// filename, range, errors, warnings, nowarns
@@ -5052,7 +5053,7 @@ module private ScriptPreprocessClosure =
50525053
seen.ContainsKey(check)
50535054

50545055
/// Parse a script from source.
5055-
letParseScriptText(filename:string,source:string,tcConfig:TcConfig,codeContext,lexResourceManager:Lexhelp.LexResourceManager,errorLogger:ErrorLogger)=
5056+
letParseScriptText(filename:string,sourceText:ISourceText,tcConfig:TcConfig,codeContext,lexResourceManager:Lexhelp.LexResourceManager,errorLogger:ErrorLogger)=
50565057

50575058
// fsc.exe -- COMPILED\!INTERACTIVE
50585059
// fsi.exe -- !COMPILED\INTERACTIVE
@@ -5064,7 +5065,7 @@ module private ScriptPreprocessClosure =
50645065
| CodeContext.CompilationAndEvaluation->["INTERACTIVE"]
50655066
| CodeContext.Compilation->["COMPILED"]
50665067
| CodeContext.Editing->"EDITING"::(if IsScript filenamethen["INTERACTIVE"]else["COMPILED"])
5067-
letlexbuf= UnicodeLexing.StringAsLexbuf source
5068+
letlexbuf= UnicodeLexing.SourceTextAsLexbuf(sourceText)
50685069

50695070
letisLastCompiland=(IsScript filename), tcConfig.target.IsExe// The root compiland is last in the list of compilands.
50705071
ParseOneInputLexbuf(tcConfig, lexResourceManager, defines, lexbuf, filename, isLastCompiland, errorLogger)
@@ -5101,7 +5102,7 @@ module private ScriptPreprocessClosure =
51015102
| None->new StreamReader(stream,true)
51025103
| Some(n: int)->new StreamReader(stream, Encoding.GetEncoding(n))
51035104
letsource= reader.ReadToEnd()
5104-
[ClosureSource(filename, m, source, parseRequired)]
5105+
[ClosureSource(filename, m,SourceText.ofStringsource, parseRequired)]
51055106
with e->
51065107
errorRecovery e m
51075108
[]
@@ -5129,15 +5130,15 @@ module private ScriptPreprocessClosure =
51295130
lettcConfig= ref tcConfig
51305131

51315132
letobservedSources= Observed()
5132-
let recloop(ClosureSource(filename,m,source,parseRequired))=
5133+
let recloop(ClosureSource(filename,m,sourceText,parseRequired))=
51335134
[ifnot(observedSources.HaveSeen(filename))then
51345135
observedSources.SetSeen(filename)
51355136
//printfn "visiting %s" filename
51365137
if IsScript(filename)|| parseRequiredthen
51375138
letparseResult,parseDiagnostics=
51385139
leterrorLogger= CapturingErrorLogger("FindClosureParse")
51395140
use _unwindEL= PushErrorLoggerPhaseUntilUnwind(fun _-> errorLogger)
5140-
letresult= ParseScriptText(filename,source,!tcConfig, codeContext, lexResourceManager, errorLogger)
5141+
letresult= ParseScriptText(filename,sourceText,!tcConfig, codeContext, lexResourceManager, errorLogger)
51415142
result, errorLogger.Diagnostics
51425143

51435144
match parseResultwith
@@ -5237,7 +5238,7 @@ module private ScriptPreprocessClosure =
52375238
result
52385239

52395240
/// Given source text, find the full load closure. Used from service.fs, when editing a script file
5240-
letGetFullClosureOfScriptText(ctok,legacyReferenceResolver,defaultFSharpBinariesDir,filename,source,codeContext,useSimpleResolution,useFsiAuxLib,lexResourceManager:Lexhelp.LexResourceManager,applyCommmandLineArgs,assumeDotNetFramework,tryGetMetadataSnapshot,reduceMemoryUsage)=
5241+
letGetFullClosureOfScriptText(ctok,legacyReferenceResolver,defaultFSharpBinariesDir,filename,sourceText,codeContext,useSimpleResolution,useFsiAuxLib,lexResourceManager:Lexhelp.LexResourceManager,applyCommmandLineArgs,assumeDotNetFramework,tryGetMetadataSnapshot,reduceMemoryUsage)=
52415242
// Resolve the basic references such as FSharp.Core.dll first, before processing any #I directives in the script
52425243
//
52435244
// This is tries to mimic the action of running the script in F# Interactive - the initial context for scripting is created
@@ -5250,7 +5251,7 @@ module private ScriptPreprocessClosure =
52505251

52515252
lettcConfig= CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, filename, codeContext, useSimpleResolution, useFsiAuxLib, Some references0, applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage)
52525253

5253-
letclosureSources=[ClosureSource(filename, range0,source,true)]
5254+
letclosureSources=[ClosureSource(filename, range0,sourceText,true)]
52545255
letclosureFiles,tcConfig= FindClosureFiles(closureSources, tcConfig, codeContext, lexResourceManager)
52555256
GetLoadClosure(ctok, filename, closureFiles, tcConfig, codeContext)
52565257

@@ -5268,9 +5269,9 @@ type LoadClosure with
52685269
//
52695270
/// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the
52705271
/// same arguments as the rest of the application.
5271-
static memberComputeClosureOfScriptText(ctok,legacyReferenceResolver,defaultFSharpBinariesDir,filename:string,source:string,codeContext,useSimpleResolution:bool,useFsiAuxLib,lexResourceManager:Lexhelp.LexResourceManager,applyCommmandLineArgs,assumeDotNetFramework,tryGetMetadataSnapshot,reduceMemoryUsage):LoadClosure=
5272+
static memberComputeClosureOfScriptText(ctok,legacyReferenceResolver,defaultFSharpBinariesDir,filename:string,sourceText:ISourceText,codeContext,useSimpleResolution:bool,useFsiAuxLib,lexResourceManager:Lexhelp.LexResourceManager,applyCommmandLineArgs,assumeDotNetFramework,tryGetMetadataSnapshot,reduceMemoryUsage):LoadClosure=
52725273
use unwindBuildPhase= PushThreadBuildPhaseUntilUnwind BuildPhase.Parse
5273-
ScriptPreprocessClosure.GetFullClosureOfScriptText(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename,source, codeContext, useSimpleResolution, useFsiAuxLib, lexResourceManager, applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage)
5274+
ScriptPreprocessClosure.GetFullClosureOfScriptText(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename,sourceText, codeContext, useSimpleResolution, useFsiAuxLib, lexResourceManager, applyCommmandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage)
52745275

52755276
/// Analyze a set of script files and find the closure of their references. The resulting references are then added to the given TcConfig.
52765277
/// Used from fsi.fs and fsc.fs, for #load and command line.

‎src/fsharp/CompileOps.fsi‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ open Microsoft.FSharp.Compiler.AbstractIL.IL
1111
openMicrosoft.FSharp.Compiler.AbstractIL.ILBinaryReader
1212
openMicrosoft.FSharp.Compiler.AbstractIL.Internal.Library
1313
openMicrosoft.FSharp.Compiler
14+
openMicrosoft.FSharp.Compiler.Text
1415
openMicrosoft.FSharp.Compiler.TypeChecker
1516
openMicrosoft.FSharp.Compiler.Range
1617
openMicrosoft.FSharp.Compiler.Ast
@@ -796,7 +797,7 @@ type LoadClosure =
796797
//
797798
/// A temporary TcConfig is created along the way, is why this routine takes so many arguments. We want to be sure to use exactly the
798799
/// same arguments as the rest of the application.
799-
static memberComputeClosureOfScriptText:CompilationThreadToken* legacyReferenceResolver: ReferenceResolver.Resolver* defaultFSharpBinariesDir: string* filename: string*source: string* implicitDefines:CodeContext* useSimpleResolution: bool* useFsiAuxLib: bool* lexResourceManager: Lexhelp.LexResourceManager* applyCompilerOptions:(TcConfigBuilder-> unit)* assumeDotNetFramework: bool* tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot* reduceMemoryUsage: ReduceMemoryFlag-> LoadClosure
800+
static memberComputeClosureOfScriptText:CompilationThreadToken* legacyReferenceResolver: ReferenceResolver.Resolver* defaultFSharpBinariesDir: string* filename: string*sourceText: ISourceText* implicitDefines:CodeContext* useSimpleResolution: bool* useFsiAuxLib: bool* lexResourceManager: Lexhelp.LexResourceManager* applyCompilerOptions:(TcConfigBuilder-> unit)* assumeDotNetFramework: bool* tryGetMetadataSnapshot: ILReaderTryGetMetadataSnapshot* reduceMemoryUsage: ReduceMemoryFlag-> LoadClosure
800801

801802
/// Analyze a set of script files and find the closure of their references. The resulting references are then added to the given TcConfig.
802803
/// Used from fsi.fs and fsc.fs, for#load and command line.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp