diff --git a/go.mod b/go.mod index 3f1cbc0bb..0180ec173 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hashicorp/go-memdb v1.3.2 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.3.0 - github.com/hashicorp/hcl-lang v0.0.0-20210720185741-4775fe675507 + github.com/hashicorp/hcl-lang v0.0.0-20210727133229-454bfd2596ce github.com/hashicorp/hcl/v2 v2.10.1 github.com/hashicorp/terraform-exec v0.14.0 github.com/hashicorp/terraform-json v0.12.0 diff --git a/go.sum b/go.sum index 25bbd062d..f0df40df3 100644 --- a/go.sum +++ b/go.sum @@ -191,8 +191,8 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl-lang v0.0.0-20210616121206-bd34ebcc883b/go.mod h1:uMsq6wV8ZXEH8qndov4tncXlHDYnZ8aHsGmS4T74e2o= -github.com/hashicorp/hcl-lang v0.0.0-20210720185741-4775fe675507 h1:oJvWrjpJ631eWE/WLeNfVX7JXgEEIbavD17B70JA5bU= -github.com/hashicorp/hcl-lang v0.0.0-20210720185741-4775fe675507/go.mod h1:A1Pj/o2k+ADlN0onToNuOJWNuWywxV7towLQmzU8dfU= +github.com/hashicorp/hcl-lang v0.0.0-20210727133229-454bfd2596ce h1:XekCZzsJL95UGIMEWHBdPjGSPpi8uxU91zRghDbRgTc= +github.com/hashicorp/hcl-lang v0.0.0-20210727133229-454bfd2596ce/go.mod h1:xzXU6Fn+TWVaZUFxV8CyAsObi2oMgSEFAmLvCx2ArzM= github.com/hashicorp/hcl/v2 v2.10.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= github.com/hashicorp/hcl/v2 v2.10.1 h1:h4Xx4fsrRE26ohAk/1iGF/JBqRQbyUqu5Lvj60U54ys= github.com/hashicorp/hcl/v2 v2.10.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= diff --git a/internal/langserver/handlers/code_lens.go b/internal/langserver/handlers/code_lens.go index 54ca55f72..025dea17f 100644 --- a/internal/langserver/handlers/code_lens.go +++ b/internal/langserver/handlers/code_lens.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" + "github.com/hashicorp/hcl-lang/lang" "github.com/hashicorp/hcl/v2" lsctx "github.com/hashicorp/terraform-ls/internal/context" "github.com/hashicorp/terraform-ls/internal/filesystem" @@ -76,20 +77,43 @@ func referenceCountCodeLens(ctx context.Context, doc filesystem.Document) []lsp. return list } + // There can be two targets pointing to the same range + // e.g. when a block is targettable as type-less reference + // and as an object, which is important in most contexts + // but not here, where we present it to the user. + dedupedTargets := make(map[hcl.Range]lang.ReferenceTargets, 0) for _, refTarget := range refTargets { - origins, err := d.ReferenceOriginsTargeting(refTarget) - if err != nil { - continue + rng := *refTarget.RangePtr + if _, ok := dedupedTargets[rng]; !ok { + dedupedTargets[rng] = make(lang.ReferenceTargets, 0) + } + dedupedTargets[rng] = append(dedupedTargets[rng], refTarget) + } + + for rng, refTargets := range dedupedTargets { + originCount := 0 + var defRange *hcl.Range + for _, refTarget := range refTargets { + if refTarget.DefRangePtr != nil { + defRange = refTarget.DefRangePtr + } + + origins, err := d.ReferenceOriginsTargeting(refTarget) + if err != nil { + continue + } + originCount += len(origins) } - if len(origins) == 0 { + + if originCount == 0 { continue } var pos hcl.Pos - if refTarget.DefRangePtr != nil { - pos = posMiddleOfRange(refTarget.DefRangePtr) + if defRange != nil { + pos = posMiddleOfRange(defRange) } else { - pos = posMiddleOfRange(refTarget.RangePtr) + pos = posMiddleOfRange(&rng) } posBytes, err := json.Marshal(ilsp.HCLPosToLSP(pos)) @@ -98,9 +122,9 @@ func referenceCountCodeLens(ctx context.Context, doc filesystem.Document) []lsp. } list = append(list, lsp.CodeLens{ - Range: ilsp.HCLRangeToLSP(*refTarget.RangePtr), + Range: ilsp.HCLRangeToLSP(rng), Command: lsp.Command{ - Title: getTitle("reference", "references", len(origins)), + Title: getTitle("reference", "references", originCount), Command: showReferencesCmd, Arguments: []json.RawMessage{ json.RawMessage(posBytes), diff --git a/internal/langserver/handlers/go_to_ref_target.go b/internal/langserver/handlers/go_to_ref_target.go index dba63430e..6bd1ed0df 100644 --- a/internal/langserver/handlers/go_to_ref_target.go +++ b/internal/langserver/handlers/go_to_ref_target.go @@ -58,6 +58,7 @@ func (h *logHandler) GoToReferenceTarget(ctx context.Context, params lsp.TextDoc if origin == nil { return nil, nil } + h.logger.Printf("found origin: %#v", origin) target, err := d.ReferenceTargetForOrigin(*origin) if err != nil { diff --git a/internal/langserver/handlers/references.go b/internal/langserver/handlers/references.go index fde65ab2e..08ce40522 100644 --- a/internal/langserver/handlers/references.go +++ b/internal/langserver/handlers/references.go @@ -3,6 +3,7 @@ package handlers import ( "context" + "github.com/hashicorp/hcl-lang/lang" lsctx "github.com/hashicorp/terraform-ls/internal/context" ilsp "github.com/hashicorp/terraform-ls/internal/lsp" lsp "github.com/hashicorp/terraform-ls/internal/protocol" @@ -47,21 +48,25 @@ func (h *logHandler) References(ctx context.Context, params lsp.ReferenceParams) return list, err } - refTarget, err := d.InnermostReferenceTargetAtPos(fPos.Filename(), fPos.Position()) + refTargets, err := d.InnermostReferenceTargetsAtPos(fPos.Filename(), fPos.Position()) if err != nil { return list, err } - if refTarget == nil { + if len(refTargets) == 0 { // this position is not addressable h.logger.Printf("position is not addressable: %s - %#v", fPos.Filename(), fPos.Position()) return list, nil } - h.logger.Printf("finding origins for inner-most target: %#v", refTarget) + h.logger.Printf("finding origins for inner-most targets: %#v", refTargets) - origins, err := d.ReferenceOriginsTargeting(*refTarget) - if err != nil { - return list, err + origins := make(lang.ReferenceOrigins, 0) + for _, refTarget := range refTargets { + refOrigins, err := d.ReferenceOriginsTargeting(refTarget) + if err != nil { + return list, err + } + origins = append(origins, refOrigins...) } return ilsp.RefOriginsToLocations(mod.Path, origins), nil