/
codeAction.go
116 lines (103 loc) · 3.58 KB
/
codeAction.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2015 ThoughtWorks, Inc.
// This file is part of Gauge.
// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Gauge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Gauge. If not, see <http://www.gnu.org/licenses/>.
package lang
import (
"encoding/json"
"fmt"
"strings"
"github.com/getgauge/gauge/gauge"
"github.com/getgauge/gauge/parser"
"github.com/getgauge/gauge/util"
"github.com/sourcegraph/go-langserver/pkg/lsp"
"github.com/sourcegraph/jsonrpc2"
)
const (
generateStepCommand = "gauge.generate.step"
generateStubTitle = "Create step implementation"
generateConceptCommand = "gauge.generate.concept"
generateConceptTitle = "Create concept"
)
func codeActions(req *jsonrpc2.Request) (interface{}, error) {
var params lsp.CodeActionParams
if err := json.Unmarshal(*req.Params, ¶ms); err != nil {
return nil, fmt.Errorf("failed to parse request %v", err)
}
return getSpecCodeAction(params)
}
func getSpecCodeAction(params lsp.CodeActionParams) ([]lsp.Command, error) {
var actions []lsp.Command
for _, d := range params.Context.Diagnostics {
if d.Code != "" {
actions = append(actions, createCodeAction(generateStepCommand, generateStubTitle, []interface{}{d.Code}))
cptInfo, err := createConceptInfo(params.TextDocument.URI, params.Range.Start.Line)
if err != nil {
return nil, err
}
actions = append(actions, createCodeAction(generateConceptCommand, generateConceptTitle, []interface{}{cptInfo}))
}
}
return actions, nil
}
func createConceptInfo(uri lsp.DocumentURI, line int) (interface{}, error) {
file := util.ConvertURItoFilePath(uri)
linetext := getLine(uri, line)
var stepValue *gauge.StepValue
if util.IsConcept(file) {
steps, _ := new(parser.ConceptParser).Parse(getContent(uri), file)
for _, conStep := range steps {
for _, step := range conStep.ConceptSteps {
if step.LineNo-1 == line {
stepValue = extractStepValueAndParams(step, linetext)
}
}
}
}
if util.IsSpec(file) {
spec, res, err := new(parser.SpecParser).Parse(getContent(uri), &gauge.ConceptDictionary{}, file)
if err != nil {
return nil, err
}
if !res.Ok {
return nil, fmt.Errorf("parsing failed for %s. %s", uri, res.Errors())
}
for _, step := range spec.Steps() {
if step.LineNo-1 == line {
stepValue = extractStepValueAndParams(step, linetext)
}
}
}
count := strings.Count(stepValue.StepValue, "{}")
for i := 0; i < count; i++ {
stepValue.StepValue = strings.Replace(stepValue.StepValue, "{}", fmt.Sprintf("<arg%d>", i), 1)
}
cptName := strings.Replace(stepValue.StepValue, "*", "", -1)
return concpetInfo{
ConceptName: fmt.Sprintf("# %s\n* ", strings.TrimSpace(cptName)),
}, nil
}
func extractStepValueAndParams(step *gauge.Step, linetext string) *gauge.StepValue {
var stepValue *gauge.StepValue
if step.HasInlineTable {
stepValue, _ = parser.ExtractStepValueAndParams(step.LineText, true)
} else {
stepValue, _ = parser.ExtractStepValueAndParams(linetext, false)
}
return stepValue
}
func createCodeAction(command, titlle string, params []interface{}) lsp.Command {
return lsp.Command{
Command: command,
Title: titlle,
Arguments: params,
}
}