github.com/getgauge/gauge@v1.6.9/api/lang/codeAction.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 "encoding/json" 11 "fmt" 12 "strings" 13 14 "github.com/getgauge/gauge/gauge" 15 "github.com/getgauge/gauge/parser" 16 "github.com/getgauge/gauge/util" 17 "github.com/sourcegraph/go-langserver/pkg/lsp" 18 "github.com/sourcegraph/jsonrpc2" 19 ) 20 21 const ( 22 generateStepCommand = "gauge.generate.step" 23 generateStubTitle = "Create step implementation" 24 generateConceptCommand = "gauge.generate.concept" 25 generateConceptTitle = "Create concept" 26 ) 27 28 func codeActions(req *jsonrpc2.Request) (interface{}, error) { 29 var params lsp.CodeActionParams 30 if err := json.Unmarshal(*req.Params, ¶ms); err != nil { 31 return nil, fmt.Errorf("failed to parse request %v", err) 32 } 33 return getSpecCodeAction(params) 34 } 35 36 func getSpecCodeAction(params lsp.CodeActionParams) ([]lsp.Command, error) { 37 var actions []lsp.Command 38 line := params.Range.Start.Line 39 for _, d := range params.Context.Diagnostics { 40 if d.Code != "" { 41 actions = append(actions, createCodeAction(generateStepCommand, generateStubTitle, []interface{}{d.Code})) 42 cptInfo, err := createConceptInfo(params.TextDocument.URI, line) 43 if err != nil { 44 return nil, err 45 } 46 if cptInfo != nil { 47 actions = append(actions, createCodeAction(generateConceptCommand, generateConceptTitle, []interface{}{cptInfo})) 48 } 49 } 50 } 51 return actions, nil 52 } 53 54 func createConceptInfo(uri lsp.DocumentURI, line int) (interface{}, error) { 55 file := util.ConvertURItoFilePath(uri) 56 linetext := getLine(uri, line) 57 var stepValue *gauge.StepValue 58 if util.IsConcept(file) { 59 steps, _ := new(parser.ConceptParser).Parse(getContent(uri), file) 60 for _, conStep := range steps { 61 for _, step := range conStep.ConceptSteps { 62 if step.LineNo-1 == line { 63 stepValue = extractStepValueAndParams(step, linetext) 64 } 65 } 66 } 67 } 68 if util.IsSpec(file) { 69 spec, res, err := new(parser.SpecParser).Parse(getContent(uri), &gauge.ConceptDictionary{}, file) 70 if err != nil { 71 return nil, err 72 } 73 if !res.Ok { 74 return nil, fmt.Errorf("parsing failed for %s. %s", uri, res.Errors()) 75 } 76 for _, step := range spec.Steps() { 77 if step.LineNo-1 == line { 78 stepValue = extractStepValueAndParams(step, linetext) 79 } 80 } 81 } 82 if stepValue != nil { 83 count := strings.Count(stepValue.StepValue, "{}") 84 for i := 0; i < count; i++ { 85 stepValue.StepValue = strings.Replace(stepValue.StepValue, "{}", fmt.Sprintf("<arg%d>", i), 1) 86 } 87 cptName := strings.Replace(stepValue.StepValue, "*", "", -1) 88 return concpetInfo{ 89 ConceptName: fmt.Sprintf("# %s\n* ", strings.TrimSpace(cptName)), 90 }, nil 91 } 92 return nil, nil 93 } 94 95 func extractStepValueAndParams(step *gauge.Step, linetext string) *gauge.StepValue { 96 var stepValue *gauge.StepValue 97 if step.HasInlineTable { 98 stepValue, _ = parser.ExtractStepValueAndParams(step.LineText, true) 99 } else { 100 stepValue, _ = parser.ExtractStepValueAndParams(linetext, false) 101 } 102 return stepValue 103 } 104 105 func createCodeAction(command, titlle string, params []interface{}) lsp.Command { 106 return lsp.Command{ 107 Command: command, 108 Title: titlle, 109 Arguments: params, 110 } 111 }