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

Commit5e8765f

Browse files
vasily-kirichenkoKevinRansom
authored andcommitted
Optimize format string parsing (dotnet#5121)
* normalize source and create line endings array both used for format string parsing once per file* comments* let lazy do its job* remove parens
1 parent1a4884c commit5e8765f

File tree

5 files changed

+50
-26
lines changed

5 files changed

+50
-26
lines changed

‎src/fsharp/CheckFormatStrings.fs‎

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ open Microsoft.FSharp.Compiler.Tast
1010
openMicrosoft.FSharp.Compiler.Tastops
1111
openMicrosoft.FSharp.Compiler.TcGlobals
1212
openMicrosoft.FSharp.Compiler.ConstraintSolver
13+
openMicrosoft.FSharp.Compiler.NameResolution
1314

1415
typeFormatItem= SimpleofTType| FuncAndVal
1516

@@ -47,27 +48,21 @@ let newInfo ()=
4748
addZeros=false
4849
precision=false}
4950

50-
letparseFormatStringInternal(m:range)(g:TcGlobals)(source:string option)fmt bty cty=
51+
letparseFormatStringInternal(m:range)(g:TcGlobals)(context:FormatStringCheckContext option)fmt bty cty=
5152
// Offset is used to adjust ranges depending on whether input string is regular, verbatim or triple-quote.
5253
// We construct a new 'fmt' string since the current 'fmt' string doesn't distinguish between "\n" and escaped "\\n".
5354
let(offset,fmt)=
54-
match sourcewith
55-
| Some source->
56-
letsource= source.Replace("\r\n","\n").Replace("\r","\n")
57-
letpositions=
58-
source.Split('\n')
59-
|> Seq.map(fun s-> String.length s+1)
60-
|> Seq.scan(+)0
61-
|> Seq.toArray
62-
letlength= source.Length
63-
if m.EndLine< positions.Lengththen
64-
letstartIndex= positions.[m.StartLine-1]+ m.StartColumn
65-
letendIndex= positions.[m.EndLine-1]+ m.EndColumn-1
66-
if startIndex< length-3&& source.[startIndex..startIndex+2]="\"\"\""then
67-
(3, source.[startIndex+3..endIndex-3])
68-
elif startIndex< length-2&& source.[startIndex..startIndex+1]="@\""then
69-
(2, source.[startIndex+2..endIndex-1])
70-
else(1, source.[startIndex+1..endIndex-1])
55+
match contextwith
56+
| Some context->
57+
letlength= context.NormalizedSource.Length
58+
if m.EndLine< context.LineEndPositions.Lengththen
59+
letstartIndex= context.LineEndPositions.[m.StartLine-1]+ m.StartColumn
60+
letendIndex= context.LineEndPositions.[m.EndLine-1]+ m.EndColumn-1
61+
if startIndex< length-3&& context.NormalizedSource.[startIndex..startIndex+2]="\"\"\""then
62+
(3, context.NormalizedSource.[startIndex+3..endIndex-3])
63+
elif startIndex< length-2&& context.NormalizedSource.[startIndex..startIndex+1]="@\""then
64+
(2, context.NormalizedSource.[startIndex+2..endIndex-1])
65+
else(1, context.NormalizedSource.[startIndex+1..endIndex-1])
7166
else(1, fmt)
7267
| None->(1, fmt)
7368

@@ -292,8 +287,8 @@ let parseFormatStringInternal (m:range) (g: TcGlobals) (source: string option) f
292287
letresults= parseLoop[](0,0, m.StartColumn)
293288
results, Seq.toList specifierLocations
294289

295-
letParseFormatString m gsource fmt bty cty dty=
296-
letargtys,specifierLocations= parseFormatStringInternal m gsource fmt bty cty
290+
letParseFormatString m gformatStringCheckContext fmt bty cty dty=
291+
letargtys,specifierLocations= parseFormatStringInternal m gformatStringCheckContext fmt bty cty
297292
letaty= List.foldBack(-->) argtys dty
298293
letety= mkRefTupledTy g argtys
299294
(aty, ety), specifierLocations

‎src/fsharp/CheckFormatStrings.fsi‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
moduleinternalMicrosoft.FSharp.Compiler.CheckFormatStrings
99

1010
openMicrosoft.FSharp.Compiler
11+
openMicrosoft.FSharp.Compiler.NameResolution
1112
openMicrosoft.FSharp.Compiler.Tast
1213
openMicrosoft.FSharp.Compiler.TcGlobals
1314

14-
valParseFormatString:Range.range->TcGlobals->source:string option->fmt:string->bty:TType->cty:TType->dty:TType->(TType* TType)*(Range.range* int)list
15+
valParseFormatString:Range.range->TcGlobals->formatStringCheckContext:FormatStringCheckContext option->fmt:string->bty:TType->cty:TType->dty:TType->(TType* TType)*(Range.range* int)list
1516

1617
valTryCountFormatStringArguments:m:Range.range->g:TcGlobals->fmt:string->bty:TType->cty:TType->int option

‎src/fsharp/NameResolution.fs‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,10 @@ type OpenDeclaration =
12461246
AppliedScope= appliedScope
12471247
IsOwnNamespace= isOwnNamespace}
12481248

1249+
typeFormatStringCheckContext=
1250+
{ NormalizedSource:string
1251+
LineEndPositions:int[]}
1252+
12491253
/// An abstract type for reporting the results of name resolution and type checking.
12501254
typeITypecheckResultsSink=
12511255
abstractNotifyEnvWithScope :range*NameResolutionEnv*AccessorDomain->unit
@@ -1254,6 +1258,7 @@ type ITypecheckResultsSink =
12541258
abstractNotifyFormatSpecifierLocation :range*int->unit
12551259
abstractNotifyOpenDeclaration :OpenDeclaration->unit
12561260
abstractCurrentSource :stringoption
1261+
abstractFormatStringCheckContext :FormatStringCheckContextoption
12571262

12581263
let(|ValRefOfProp|_|)(pi:PropInfo)= pi.ArbitraryValRef
12591264
let(|ValRefOfMeth|_|)(mi:MethInfo)= mi.ArbitraryValRef
@@ -1497,7 +1502,6 @@ type TcSymbolUses(g, capturedNameResolutions : ResizeArray<CapturedNameResolutio
14971502

14981503
memberthis.GetFormatSpecifierLocationsAndArity()= formatSpecifierLocations
14991504

1500-
15011505
/// An accumulator for the results being emitted into the tcSink.
15021506
typeTcResultsSinkImpl(g,?source: string)=
15031507
letcapturedEnvs= ResizeArray<_>()
@@ -1521,6 +1525,18 @@ type TcResultsSinkImpl(g, ?source: string) =
15211525
letcapturedOpenDeclarations= ResizeArray<OpenDeclaration>()
15221526
letallowedRange(m:range)=not m.IsSynthetic
15231527

1528+
letformatStringCheckContext=
1529+
lazy
1530+
source|> Option.map(fun source->
1531+
letsource= source.Replace("\r\n","\n").Replace("\r","\n")
1532+
letpositions=
1533+
source.Split('\n')
1534+
|> Seq.map(fun s-> String.length s+1)
1535+
|> Seq.scan(+)0
1536+
|> Seq.toArray
1537+
{ NormalizedSource= source
1538+
LineEndPositions= positions})
1539+
15241540
memberthis.GetResolutions()=
15251541
TcResolutions(capturedEnvs, capturedExprTypings, capturedNameResolutions, capturedMethodGroupResolutions)
15261542

@@ -1574,7 +1590,8 @@ type TcResultsSinkImpl(g, ?source: string) =
15741590
capturedOpenDeclarations.Add(openDeclaration)
15751591

15761592
membersink.CurrentSource= source
1577-
1593+
1594+
membersink.FormatStringCheckContext= formatStringCheckContext.Value
15781595

15791596
/// An abstract type for reporting the results of name resolution and type checking, and which allows
15801597
/// temporary suspension and/or redirection of reporting.

‎src/fsharp/NameResolution.fsi‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,13 @@ type internal OpenDeclaration =
341341
/// Create a new instance of OpenDeclaration.
342342
static memberCreate:longId:Ident list* modules: ModuleOrNamespaceRef list* appliedScope: range* isOwnNamespace: bool-> OpenDeclaration
343343
344+
/// Line-end normalized source text and an array of line end positions, used for format string parsing
345+
type FormatStringCheckContext=
346+
{/// Line-end normalized source text
347+
NormalizedSource:string
348+
/// Array of line end positions
349+
LineEndPositions:int[]}
350+
344351
/// An abstract type for reporting the results of name resolution and type checking
345352
typeITypecheckResultsSink=
346353

@@ -362,6 +369,9 @@ type ITypecheckResultsSink =
362369
/// Get the current source
363370
abstractCurrentSource :stringoption
364371

372+
/// Cached line-end normalized source text and an array of line end positions, used for format string parsing
373+
abstractFormatStringCheckContext :FormatStringCheckContextoption
374+
365375
/// An implementation of ITypecheckResultsSink to collect information during type checking
366376
typeinternalTcResultsSinkImpl=
367377

‎src/fsharp/TypeChecker.fs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,7 +1840,8 @@ let MakeAndPublishSimpleVals cenv env m names mergeNamesInOneNameresEnv =
18401840
member this.NotifyExprHasType(_, _, _, _, _, _) = assert false // no expr typings in MakeSimpleVals
18411841
member this.NotifyFormatSpecifierLocation(_, _) = ()
18421842
member this.NotifyOpenDeclaration(_) = ()
1843-
member this.CurrentSource = None }
1843+
member this.CurrentSource = None
1844+
member this.FormatStringCheckContext = None }
18441845

18451846
use _h = WithNewTypecheckResultsSink(sink, cenv.tcSink)
18461847
MakeSimpleVals cenv env names
@@ -6785,10 +6786,10 @@ and TcConstStringExpr cenv overallTy env m tpenv s =
67856786
let ty' = mkPrintfFormatTy cenv.g aty bty cty dty ety
67866787
if (not (isObjTy cenv.g overallTy) && AddCxTypeMustSubsumeTypeUndoIfFailed env.DisplayEnv cenv.css m overallTy ty') then
67876788
// Parse the format string to work out the phantom types
6788-
letsource = match cenv.tcSink.CurrentSink with None -> None | Some sink -> sink.CurrentSource
6789+
letformatStringCheckContext = match cenv.tcSink.CurrentSink with None -> None | Some sink -> sink.FormatStringCheckContext
67896790
let normalizedString = (s.Replace("\r\n", "\n").Replace("\r", "\n"))
67906791

6791-
let (aty', ety'), specifierLocations = (try CheckFormatStrings.ParseFormatString m cenv.gsource normalizedString bty cty dty with Failure s -> error (Error(FSComp.SR.tcUnableToParseFormatString(s), m)))
6792+
let (aty', ety'), specifierLocations = (try CheckFormatStrings.ParseFormatString m cenv.gformatStringCheckContext normalizedString bty cty dty with Failure s -> error (Error(FSComp.SR.tcUnableToParseFormatString(s), m)))
67926793

67936794
match cenv.tcSink.CurrentSink with
67946795
| None -> ()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp