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, &params); 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  }