github.com/getgauge/gauge@v1.6.9/api/lang/rename.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package lang 8 9 import ( 10 "context" 11 "encoding/json" 12 "fmt" 13 "strings" 14 15 gm "github.com/getgauge/gauge-proto/go/gauge_messages" 16 "github.com/getgauge/gauge/gauge" 17 "github.com/getgauge/gauge/parser" 18 "github.com/getgauge/gauge/refactor" 19 "github.com/getgauge/gauge/util" 20 "github.com/sourcegraph/go-langserver/pkg/lsp" 21 "github.com/sourcegraph/jsonrpc2" 22 ) 23 24 func rename(ctx context.Context, conn jsonrpc2.JSONRPC2, req *jsonrpc2.Request) (interface{}, error) { 25 if err := sendSaveFilesRequest(ctx, conn); err != nil { 26 return nil, err 27 } 28 return renameStep(req) 29 } 30 31 func renameStep(req *jsonrpc2.Request) (interface{}, error) { 32 var params lsp.RenameParams 33 var err error 34 if err = json.Unmarshal(*req.Params, ¶ms); err != nil { 35 logDebug(req, "failed to parse rename request %s", err.Error()) 36 return nil, err 37 } 38 39 step, err := getStepToRefactor(params) 40 if err != nil { 41 return nil, err 42 } 43 if step == nil { 44 return nil, fmt.Errorf("refactoring is supported for steps only") 45 } 46 newName := getNewStepName(params, step) 47 48 refactortingResult := refactor.GetRefactoringChanges(step.GetLineText(), newName, lRunner.runner, util.GetSpecDirs(), false) 49 for _, warning := range refactortingResult.Warnings { 50 logWarning(req, warning) 51 } 52 if !refactortingResult.Success { 53 return nil, fmt.Errorf("%s", strings.Join(refactortingResult.Errors, "\t")) 54 } 55 var result lsp.WorkspaceEdit 56 result.Changes = make(map[string][]lsp.TextEdit) 57 changes := append(refactortingResult.SpecsChanged, append(refactortingResult.ConceptsChanged, refactortingResult.RunnerFilesChanged...)...) 58 if err := addWorkspaceEdits(&result, changes); err != nil { 59 return nil, err 60 } 61 return result, nil 62 } 63 64 func getStepToRefactor(params lsp.RenameParams) (*gauge.Step, error) { 65 file := util.ConvertURItoFilePath(params.TextDocument.URI) 66 if util.IsSpec(file) { 67 spec, pResult := new(parser.SpecParser).ParseSpecText(getContent(params.TextDocument.URI), util.ConvertURItoFilePath(params.TextDocument.URI)) 68 if !pResult.Ok { 69 return nil, fmt.Errorf("refactoring failed due to parse errors: \n%s", strings.Join(pResult.Errors(), "\n")) 70 } 71 for _, item := range spec.AllItems() { 72 if item.Kind() == gauge.StepKind && item.(*gauge.Step).LineNo-1 == params.Position.Line { 73 return item.(*gauge.Step), nil 74 } 75 } 76 } 77 if util.IsConcept(file) { 78 steps, _ := new(parser.ConceptParser).Parse(getContent(params.TextDocument.URI), file) 79 for _, conStep := range steps { 80 for _, step := range conStep.ConceptSteps { 81 if step.LineNo-1 == params.Position.Line { 82 return step, nil 83 } 84 } 85 } 86 } 87 return nil, nil 88 } 89 90 func getNewStepName(params lsp.RenameParams, step *gauge.Step) string { 91 newName := strings.TrimSpace(strings.TrimPrefix(params.NewName, "*")) 92 if step.HasInlineTable { 93 newName = fmt.Sprintf("%s <%s>", newName, gauge.TableArg) 94 } 95 return newName 96 } 97 98 func addWorkspaceEdits(result *lsp.WorkspaceEdit, filesChanges []*gm.FileChanges) error { 99 for _, fileChange := range filesChanges { 100 uri := util.ConvertPathToURI(fileChange.FileName) 101 for _, diff := range fileChange.Diffs { 102 textEdit := lsp.TextEdit{ 103 NewText: diff.Content, 104 Range: lsp.Range{ 105 Start: lsp.Position{Line: int(diff.Span.Start - 1), Character: int(diff.Span.StartChar)}, 106 End: lsp.Position{Line: int(diff.Span.End - 1), Character: int(diff.Span.EndChar)}, 107 }, 108 } 109 result.Changes[string(uri)] = append(result.Changes[string(uri)], textEdit) 110 } 111 } 112 return nil 113 }