@@ -35,6 +35,7 @@ const (
3535 signatureHelpCmd baselineCommand = "SignatureHelp"
3636 smartSelectionCmd baselineCommand = "Smart Selection"
3737 codeLensesCmd baselineCommand = "Code Lenses"
38+ documentSymbolsCmd baselineCommand = "Document Symbols"
3839)
3940
4041type baselineCommand string
@@ -71,7 +72,7 @@ func getBaselineFileName(t *testing.T, command baselineCommand) string {
7172
7273func getBaselineExtension (command baselineCommand ) string {
7374 switch command {
74- case quickInfoCmd , signatureHelpCmd , smartSelectionCmd , inlayHintsCmd , nonSuggestionDiagnosticsCmd :
75+ case quickInfoCmd , signatureHelpCmd , smartSelectionCmd , inlayHintsCmd , nonSuggestionDiagnosticsCmd , documentSymbolsCmd :
7576 return "baseline"
7677 case callHierarchyCmd :
7778 return "callHierarchy.txt"
@@ -472,11 +473,49 @@ func (f *FourslashTest) textOfFile(fileName string) (string, bool) {
472473 return f .vfs .ReadFile (fileName )
473474}
474475
476+ type detailKind int
477+
478+ const (
479+ detailKindMarker detailKind = iota // /*MARKER*/
480+ detailKindContextStart // <|
481+ detailKindTextStart // [|
482+ detailKindTextEnd // |]
483+ detailKindContextEnd // |>
484+ )
485+
486+ func (k detailKind ) isEnd () bool {
487+ return k == detailKindContextEnd || k == detailKindTextEnd
488+ }
489+
490+ func (k detailKind ) isStart () bool {
491+ return k == detailKindContextStart || k == detailKindTextStart
492+ }
493+
475494type baselineDetail struct {
476495 pos lsproto.Position
477496 positionMarker string
478497 span * documentSpan
479- kind string
498+ kind detailKind
499+ }
500+
501+ func (d * baselineDetail ) getRange () lsproto.Range {
502+ switch d .kind {
503+ case detailKindContextStart :
504+ return * d .span .contextSpan
505+ case detailKindContextEnd :
506+ return * d .span .contextSpan
507+ case detailKindTextStart :
508+ return d .span .textSpan
509+ case detailKindTextEnd :
510+ return d .span .textSpan
511+ case detailKindMarker :
512+ return lsproto.Range {
513+ Start : d .pos ,
514+ End : d .pos ,
515+ }
516+ default :
517+ panic ("unknown detail kind" )
518+ }
480519}
481520
482521func (f * FourslashTest ) getBaselineContentForFile (
@@ -504,7 +543,7 @@ func (f *FourslashTest) getBaselineContentForFile(
504543 pos : span .contextSpan .Start ,
505544 positionMarker : "<|" ,
506545 span : & span ,
507- kind : "contextStart" ,
546+ kind : detailKindContextStart ,
508547 })
509548
510549 // Check if context span starts after text span
@@ -519,16 +558,16 @@ func (f *FourslashTest) getBaselineContentForFile(
519558 startMarker += options .getLocationData (span )
520559 }
521560 details = append (details ,
522- & baselineDetail {pos : span .textSpan .Start , positionMarker : startMarker , span : & span , kind : "textStart" },
523- & baselineDetail {pos : span .textSpan .End , positionMarker : core .OrElse (options .endMarker , "|]" ), span : & span , kind : "textEnd" },
561+ & baselineDetail {pos : span .textSpan .Start , positionMarker : startMarker , span : & span , kind : detailKindTextStart },
562+ & baselineDetail {pos : span .textSpan .End , positionMarker : core .OrElse (options .endMarker , "|]" ), span : & span , kind : detailKindTextEnd },
524563 )
525564
526565 if span .contextSpan != nil {
527566 details = append (details , & baselineDetail {
528567 pos : span .contextSpan .End ,
529568 positionMarker : "|>" ,
530569 span : & span ,
531- kind : "contextEnd" ,
570+ kind : detailKindContextEnd ,
532571 })
533572 }
534573
@@ -566,37 +605,69 @@ func (f *FourslashTest) getBaselineContentForFile(
566605 }
567606 }
568607
569- slices .SortStableFunc (details , func (d1 , d2 * baselineDetail ) int {
570- return lsproto .ComparePositions (d1 .pos , d2 .pos )
571- })
572- // !!! if canDetermineContextIdInline
573-
574- textWithContext := newTextWithContext (fileName , content )
575-
576- // Our preferred way to write marker is
608+ // Our preferred way to write markers is
577609 // /*MARKER*/[| some text |]
578610 // [| some /*MARKER*/ text |]
579611 // [| some text |]/*MARKER*/
580- // Stable sort should handle first two cases but with that marker will be before rangeEnd if locations match
581- // So we will defer writing marker in this case by checking and finding index of rangeEnd if same
582- var deferredMarkerIndex * int
612+ slices .SortStableFunc (details , func (d1 , d2 * baselineDetail ) int {
613+ c := lsproto .ComparePositions (d1 .pos , d2 .pos )
614+ if c != 0 || d1 .kind == detailKindMarker && d2 .kind == detailKindMarker {
615+ return c
616+ }
583617
584- for index , detail := range details {
585- if detail .span == nil && deferredMarkerIndex == nil {
586- // If this is marker position and its same as textEnd and/or contextEnd we want to write marker after those
587- for matchingEndPosIndex := index + 1 ; matchingEndPosIndex < len (details ); matchingEndPosIndex ++ {
588- // Defer after the location if its same as rangeEnd
589- if details [matchingEndPosIndex ].pos == detail .pos && strings .HasSuffix (details [matchingEndPosIndex ].kind , "End" ) {
590- deferredMarkerIndex = ptrTo (matchingEndPosIndex )
591- }
592- // Dont defer further than already determined
593- break
618+ // /*MARKER*/[| some text |]
619+ if d1 .kind == detailKindMarker && d2 .kind .isStart () {
620+ return - 1
621+ }
622+ if d2 .kind == detailKindMarker && d1 .kind .isStart () {
623+ return 1
624+ }
625+
626+ // [| some text |]/*MARKER*/
627+ if d1 .kind == detailKindMarker && d2 .kind .isEnd () {
628+ return 1
629+ }
630+ if d2 .kind == detailKindMarker && d1 .kind .isEnd () {
631+ return - 1
632+ }
633+
634+ // [||] or <||>
635+ if d1 .span == d2 .span {
636+ return int (d1 .kind - d2 .kind )
637+ }
638+
639+ // ...|><|...
640+ if d1 .kind .isStart () && d2 .kind .isEnd () {
641+ return 1
642+ }
643+ if d1 .kind .isEnd () && d2 .kind .isStart () {
644+ return - 1
645+ }
646+
647+ // <| ... [| ... |]|>
648+ if d1 .kind .isEnd () && d2 .kind .isEnd () {
649+ c := lsproto .ComparePositions (d2 .getRange ().Start , d1 .getRange ().Start )
650+ if c != 0 {
651+ return c
594652 }
595- // Defer writing marker position to deffered marker index
596- if deferredMarkerIndex != nil {
597- continue
653+ return int (d1 .kind - d2 .kind )
654+ }
655+
656+ // <|[| ... |] ... |>
657+ if d1 .kind .isStart () && d2 .kind .isStart () {
658+ c := lsproto .ComparePositions (d2 .getRange ().End , d2 .getRange ().End )
659+ if c != 0 {
660+ return c
598661 }
662+ return int (d1 .kind - d2 .kind )
599663 }
664+
665+ return 0
666+ })
667+ // !!! if canDetermineContextIdInline
668+
669+ textWithContext := newTextWithContext (fileName , content )
670+ for index , detail := range details {
600671 textWithContext .add (detail )
601672 textWithContext .pos = detail .pos
602673 // Prefix
@@ -607,13 +678,13 @@ func (f *FourslashTest) getBaselineContentForFile(
607678 textWithContext .newContent .WriteString (detail .positionMarker )
608679 if detail .span != nil {
609680 switch detail .kind {
610- case "textStart" :
681+ case detailKindTextStart :
611682 var text string
612683 if contextId , ok := spanToContextId [* detail .span ]; ok {
613684 isAfterContextStart := false
614685 for textStartIndex := index - 1 ; textStartIndex >= 0 ; textStartIndex -- {
615686 textStartDetail := details [textStartIndex ]
616- if textStartDetail .kind == "contextStart" && textStartDetail .span == detail .span {
687+ if textStartDetail .kind == detailKindContextStart && textStartDetail .span == detail .span {
617688 isAfterContextStart = true
618689 break
619690 }
@@ -634,18 +705,11 @@ func (f *FourslashTest) getBaselineContentForFile(
634705 if text != "" {
635706 textWithContext .newContent .WriteString (`{ ` + text + ` |}` )
636707 }
637- case "contextStart" :
708+ case detailKindContextStart :
638709 if canDetermineContextIdInline {
639710 spanToContextId [* detail .span ] = len (spanToContextId )
640711 }
641712 }
642-
643- if deferredMarkerIndex != nil && * deferredMarkerIndex == index {
644- // Write the marker
645- textWithContext .newContent .WriteString (options .markerName )
646- deferredMarkerIndex = nil
647- detail = details [0 ] // Marker detail
648- }
649713 }
650714 if suffix , ok := detailSuffixes [detail ]; ok {
651715 textWithContext .newContent .WriteString (suffix )
@@ -714,7 +778,7 @@ func (t *textWithContext) add(detail *baselineDetail) {
714778 if t .content == "" && detail == nil {
715779 panic ("Unsupported" )
716780 }
717- if detail == nil || (detail .kind != "textEnd" && detail .kind != "contextEnd" ) {
781+ if detail == nil || (detail .kind != detailKindTextEnd && detail .kind != detailKindContextEnd ) {
718782 // Calculate pos to location number of lines
719783 posLineIndex := t .lineInfo
720784 if t .posInfo == nil || * t .posInfo != t .pos {
0 commit comments