@@ -63,7 +63,11 @@ func extractVariable(fset *token.FileSet, rng span.Range, src []byte, file *ast.
63
63
if tok == nil {
64
64
return nil , fmt .Errorf ("no file for pos %v" , fset .Position (file .Pos ()))
65
65
}
66
- newLineIndent := "\n " + calculateIndentation (src , tok , insertBeforeStmt )
66
+ indent , err := calculateIndentation (src , tok , insertBeforeStmt )
67
+ if err != nil {
68
+ return nil , err
69
+ }
70
+ newLineIndent := "\n " + indent
67
71
68
72
lhs := strings .Join (lhsNames , ", " )
69
73
assignStmt := & ast.AssignStmt {
@@ -128,11 +132,17 @@ func CanExtractVariable(rng span.Range, file *ast.File) (ast.Expr, []ast.Node, b
128
132
// When inserting lines of code, we must ensure that the lines have consistent
129
133
// formatting (i.e. the proper indentation). To do so, we observe the indentation on the
130
134
// line of code on which the insertion occurs.
131
- func calculateIndentation (content []byte , tok * token.File , insertBeforeStmt ast.Node ) string {
135
+ func calculateIndentation (content []byte , tok * token.File , insertBeforeStmt ast.Node ) ( string , error ) {
132
136
line := tok .Line (insertBeforeStmt .Pos ())
133
- lineOffset := tok .Offset (tok .LineStart (line ))
134
- stmtOffset := tok .Offset (insertBeforeStmt .Pos ())
135
- return string (content [lineOffset :stmtOffset ])
137
+ lineOffset , err := Offset (tok , tok .LineStart (line ))
138
+ if err != nil {
139
+ return "" , err
140
+ }
141
+ stmtOffset , err := Offset (tok , insertBeforeStmt .Pos ())
142
+ if err != nil {
143
+ return "" , err
144
+ }
145
+ return string (content [lineOffset :stmtOffset ]), nil
136
146
}
137
147
138
148
// generateAvailableIdentifier adjusts the new function name until there are no collisons in scope.
@@ -390,8 +400,14 @@ func extractFunctionMethod(fset *token.FileSet, rng span.Range, src []byte, file
390
400
391
401
// We put the selection in a constructed file. We can then traverse and edit
392
402
// the extracted selection without modifying the original AST.
393
- startOffset := tok .Offset (rng .Start )
394
- endOffset := tok .Offset (rng .End )
403
+ startOffset , err := Offset (tok , rng .Start )
404
+ if err != nil {
405
+ return nil , err
406
+ }
407
+ endOffset , err := Offset (tok , rng .End )
408
+ if err != nil {
409
+ return nil , err
410
+ }
395
411
selection := src [startOffset :endOffset ]
396
412
extractedBlock , err := parseBlockStmt (fset , selection )
397
413
if err != nil {
@@ -584,11 +600,21 @@ func extractFunctionMethod(fset *token.FileSet, rng span.Range, src []byte, file
584
600
585
601
// We're going to replace the whole enclosing function,
586
602
// so preserve the text before and after the selected block.
587
- outerStart := tok .Offset (outer .Pos ())
588
- outerEnd := tok .Offset (outer .End ())
603
+ outerStart , err := Offset (tok , outer .Pos ())
604
+ if err != nil {
605
+ return nil , err
606
+ }
607
+ outerEnd , err := Offset (tok , outer .End ())
608
+ if err != nil {
609
+ return nil , err
610
+ }
589
611
before := src [outerStart :startOffset ]
590
612
after := src [endOffset :outerEnd ]
591
- newLineIndent := "\n " + calculateIndentation (src , tok , start )
613
+ indent , err := calculateIndentation (src , tok , start )
614
+ if err != nil {
615
+ return nil , err
616
+ }
617
+ newLineIndent := "\n " + indent
592
618
593
619
var fullReplacement strings.Builder
594
620
fullReplacement .Write (before )
@@ -634,8 +660,11 @@ func extractFunctionMethod(fset *token.FileSet, rng span.Range, src []byte, file
634
660
// their cursors for whitespace. To support this use case, we must manually adjust the
635
661
// ranges to match the correct AST node. In this particular example, we would adjust
636
662
// rng.Start forward by one byte, and rng.End backwards by two bytes.
637
- func adjustRangeForWhitespace (rng span.Range , tok * token.File , content []byte ) span.Range {
638
- offset := tok .Offset (rng .Start )
663
+ func adjustRangeForWhitespace (rng span.Range , tok * token.File , content []byte ) (span.Range , error ) {
664
+ offset , err := Offset (tok , rng .Start )
665
+ if err != nil {
666
+ return span.Range {}, err
667
+ }
639
668
for offset < len (content ) {
640
669
if ! unicode .IsSpace (rune (content [offset ])) {
641
670
break
@@ -646,15 +675,18 @@ func adjustRangeForWhitespace(rng span.Range, tok *token.File, content []byte) s
646
675
rng .Start = tok .Pos (offset )
647
676
648
677
// Move backwards to find a non-whitespace character.
649
- offset = tok .Offset (rng .End )
678
+ offset , err = Offset (tok , rng .End )
679
+ if err != nil {
680
+ return span.Range {}, err
681
+ }
650
682
for o := offset - 1 ; 0 <= o && o < len (content ); o -- {
651
683
if ! unicode .IsSpace (rune (content [o ])) {
652
684
break
653
685
}
654
686
offset = o
655
687
}
656
688
rng .End = tok .Pos (offset )
657
- return rng
689
+ return rng , nil
658
690
}
659
691
660
692
// findParent finds the parent AST node of the given target node, if the target is a
@@ -916,7 +948,11 @@ func CanExtractFunction(fset *token.FileSet, rng span.Range, src []byte, file *a
916
948
if tok == nil {
917
949
return nil , false , false , fmt .Errorf ("no file for pos %v" , fset .Position (file .Pos ()))
918
950
}
919
- rng = adjustRangeForWhitespace (rng , tok , src )
951
+ var err error
952
+ rng , err = adjustRangeForWhitespace (rng , tok , src )
953
+ if err != nil {
954
+ return nil , false , false , err
955
+ }
920
956
path , _ := astutil .PathEnclosingInterval (file , rng .Start , rng .End )
921
957
if len (path ) == 0 {
922
958
return nil , false , false , fmt .Errorf ("no path enclosing interval" )
0 commit comments