Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce go-to-variable from tfvars files #727

Merged
merged 7 commits into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions internal/decoder/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,14 @@ func varsPathContext(mod *state.Module) (*decoder.PathContext, error) {
Schema: schema,
ReferenceOrigins: make(reference.Origins, 0),
ReferenceTargets: make(reference.Targets, 0),
Files: make(map[string]*hcl.File, 0),
Files: make(map[string]*hcl.File),
}

for _, origin := range mod.RefOrigins {
for _, origin := range mod.VarsRefOrigins {
dbanck marked this conversation as resolved.
Show resolved Hide resolved
if ast.IsVarsFilename(origin.OriginRange().Filename) {
pathCtx.ReferenceOrigins = append(pathCtx.ReferenceOrigins, origin)
}
}
for _, target := range mod.RefTargets {
if target.RangePtr != nil && ast.IsVarsFilename(target.RangePtr.Filename) {
pathCtx.ReferenceTargets = append(pathCtx.ReferenceTargets, target)
}
}

for name, f := range mod.ParsedVarsFiles {
pathCtx.Files[name.String()] = f
Expand Down
4 changes: 4 additions & 0 deletions internal/langserver/handlers/did_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ func TextDocumentDidChange(ctx context.Context, params lsp.DidChangeTextDocument
if err != nil {
return err
}
err = modMgr.EnqueueModuleOp(mod.Path, op.OpTypeDecodeVarsReferences, nil)
if err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions internal/langserver/handlers/did_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (lh *logHandler) TextDocumentDidOpen(ctx context.Context, params lsp.DidOpe
modMgr.EnqueueModuleOp(mod.Path, op.OpTypeLoadModuleMetadata, nil)
modMgr.EnqueueModuleOp(mod.Path, op.OpTypeDecodeReferenceTargets, nil)
modMgr.EnqueueModuleOp(mod.Path, op.OpTypeDecodeReferenceOrigins, nil)
modMgr.EnqueueModuleOp(mod.Path, op.OpTypeDecodeVarsReferences, nil)

if mod.TerraformVersionState == op.OpStateUnknown {
modMgr.EnqueueModuleOp(mod.Path, op.OpTypeGetTerraformVersion, nil)
Expand Down
51 changes: 51 additions & 0 deletions internal/state/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ type Module struct {
RefOriginsErr error
RefOriginsState op.OpState

VarsRefOrigins reference.Origins
VarsRefOriginsErr error
VarsRefOriginsState op.OpState

ParsedModuleFiles ast.ModFiles
ParsedVarsFiles ast.VarsFiles
ModuleParsingErr error
Expand Down Expand Up @@ -135,6 +139,10 @@ func (m *Module) Copy() *Module {
RefOriginsErr: m.RefOriginsErr,
RefOriginsState: m.RefOriginsState,

VarsRefOrigins: m.VarsRefOrigins.Copy(),
VarsRefOriginsErr: m.VarsRefOriginsErr,
VarsRefOriginsState: m.VarsRefOriginsState,

ModuleParsingErr: m.ModuleParsingErr,
VarsParsingErr: m.VarsParsingErr,
ModuleParsingState: m.ModuleParsingState,
Expand Down Expand Up @@ -830,3 +838,46 @@ func (s *ModuleStore) UpdateReferenceOrigins(path string, origins reference.Orig
txn.Commit()
return nil
}

func (s *ModuleStore) SetVarsReferenceOriginsState(path string, state op.OpState) error {
txn := s.db.Txn(true)
defer txn.Abort()

mod, err := moduleCopyByPath(txn, path)
if err != nil {
return err
}

mod.VarsRefOriginsState = state
err = txn.Insert(s.tableName, mod)
if err != nil {
return err
}

txn.Commit()
return nil
}

func (s *ModuleStore) UpdateVarsReferenceOrigins(path string, origins reference.Origins, roErr error) error {
txn := s.db.Txn(true)
txn.Defer(func() {
s.SetVarsReferenceOriginsState(path, op.OpStateLoaded)
})
defer txn.Abort()

mod, err := moduleCopyByPath(txn, path)
if err != nil {
return err
}

mod.VarsRefOrigins = origins
mod.VarsRefOriginsErr = roErr

err = txn.Insert(s.tableName, mod)
if err != nil {
return err
}

txn.Commit()
return nil
}
85 changes: 85 additions & 0 deletions internal/state/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/go-version"
"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/reference"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclparse"
"github.com/hashicorp/hcl/v2/hclsyntax"
Expand All @@ -15,6 +17,7 @@ import (
"github.com/hashicorp/terraform-ls/internal/terraform/module/operation"
tfaddr "github.com/hashicorp/terraform-registry-address"
tfmod "github.com/hashicorp/terraform-schema/module"
"github.com/zclconf/go-cty/cty"
)

func TestModuleStore_Add_duplicate(t *testing.T) {
Expand Down Expand Up @@ -508,6 +511,88 @@ dev = {
}
}

func TestModuleStore_SetVarsReferenceOriginsState(t *testing.T) {
s, err := NewStateStore()
if err != nil {
t.Fatal(err)
}

tmpDir := t.TempDir()
err = s.Modules.Add(tmpDir)
if err != nil {
t.Fatal(err)
}

s.Modules.SetVarsReferenceOriginsState(tmpDir, operation.OpStateQueued)

mod, err := s.Modules.ModuleByPath(tmpDir)
if err != nil {
t.Fatal(err)
}

if diff := cmp.Diff(mod.VarsRefOriginsState, operation.OpStateQueued, cmpOpts); diff != "" {
t.Fatalf("unexpected module vars ref origins state: %s", diff)
}
}

func TestModuleStore_UpdateVarsReferenceOrigins(t *testing.T) {
s, err := NewStateStore()
if err != nil {
t.Fatal(err)
}

tmpDir := t.TempDir()
err = s.Modules.Add(tmpDir)
if err != nil {
t.Fatal(err)
}

origins := reference.Origins{
reference.PathOrigin{
Range: hcl.Range{
Filename: "terraform.tfvars",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 1,
Column: 5,
Byte: 4,
},
},
TargetAddr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "name"},
},
TargetPath: lang.Path{
Path: tmpDir,
LanguageID: "terraform",
},
Constraints: reference.OriginConstraints{
reference.OriginConstraint{
OfScopeId: "variable",
OfType: cty.String,
},
},
},
}
s.Modules.UpdateVarsReferenceOrigins(tmpDir, origins, nil)

mod, err := s.Modules.ModuleByPath(tmpDir)
if err != nil {
t.Fatal(err)
}

if diff := cmp.Diff(mod.VarsRefOrigins, origins, cmpOpts); diff != "" {
t.Fatalf("unexpected module vars ref origins: %s", diff)
}
if diff := cmp.Diff(mod.VarsRefOriginsState, operation.OpStateLoaded, cmpOpts); diff != "" {
t.Fatalf("unexpected module vars ref origins state: %s", diff)
}
}

func BenchmarkModuleByPath(b *testing.B) {
s, err := NewStateStore()
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions internal/terraform/module/module_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ func (ml *moduleLoader) executeModuleOp(ctx context.Context, modOp ModuleOperati
if opErr != nil {
ml.logger.Printf("failed to decode reference origins: %s", opErr)
}
case op.OpTypeDecodeVarsReferences:
opErr = DecodeVarsReferences(ctx, ml.modStore, ml.schemaStore, modOp.ModulePath)
if opErr != nil {
ml.logger.Printf("failed to decode vars references: %s", opErr)
}
default:
ml.logger.Printf("%s: unknown operation (%#v) for module operation",
modOp.ModulePath, modOp.Type)
Expand Down Expand Up @@ -207,6 +212,8 @@ func (ml *moduleLoader) EnqueueModuleOp(modOp ModuleOperation) error {
ml.modStore.SetReferenceTargetsState(modOp.ModulePath, op.OpStateQueued)
case op.OpTypeDecodeReferenceOrigins:
ml.modStore.SetReferenceOriginsState(modOp.ModulePath, op.OpStateQueued)
case op.OpTypeDecodeVarsReferences:
ml.modStore.SetVarsReferenceOriginsState(modOp.ModulePath, op.OpStateQueued)
}

ml.queue.PushOp(modOp)
Expand All @@ -233,6 +240,8 @@ func operationState(mod *state.Module, opType op.OpType) op.OpState {
return mod.RefTargetsState
case op.OpTypeDecodeReferenceOrigins:
return mod.RefOriginsState
case op.OpTypeDecodeVarsReferences:
return mod.VarsRefOriginsState
}
return op.OpStateUnknown
}
Expand Down
37 changes: 34 additions & 3 deletions internal/terraform/module/module_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,20 @@ func DecodeReferenceOrigins(ctx context.Context, modStore *state.ModuleStore, sc
return err
}

d, err := decoder.NewDecoder(ctx, &decoder.PathReader{
d := decoder.NewDecoder(ctx, &decoder.PathReader{
ModuleReader: modStore,
SchemaReader: schemaReader,
}).Path(lang.Path{
})

moduleDecoder, err := d.Path(lang.Path{
radeksimko marked this conversation as resolved.
Show resolved Hide resolved
Path: modPath,
LanguageID: ilsp.Terraform.String(),
})
if err != nil {
return err
}
origins, rErr := d.CollectReferenceOrigins()

origins, rErr := moduleDecoder.CollectReferenceOrigins()

sErr := modStore.UpdateReferenceOrigins(modPath, origins, rErr)
if sErr != nil {
Expand All @@ -318,3 +321,31 @@ func DecodeReferenceOrigins(ctx context.Context, modStore *state.ModuleStore, sc

return rErr
}

func DecodeVarsReferences(ctx context.Context, modStore *state.ModuleStore, schemaReader state.SchemaReader, modPath string) error {
err := modStore.SetVarsReferenceOriginsState(modPath, op.OpStateLoading)
if err != nil {
return err
}

d := decoder.NewDecoder(ctx, &decoder.PathReader{
ModuleReader: modStore,
SchemaReader: schemaReader,
})

varsDecoder, err := d.Path(lang.Path{
Path: modPath,
LanguageID: ilsp.Tfvars.String(),
})
if err != nil {
return err
}

origins, rErr := varsDecoder.CollectReferenceOrigins()
sErr := modStore.UpdateVarsReferenceOrigins(modPath, origins, rErr)
if sErr != nil {
return sErr
}

return rErr
}
1 change: 1 addition & 0 deletions internal/terraform/module/operation/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ const (
OpTypeLoadModuleMetadata
OpTypeDecodeReferenceTargets
OpTypeDecodeReferenceOrigins
OpTypeDecodeVarsReferences
)
4 changes: 4 additions & 0 deletions internal/terraform/module/walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ func (w *Walker) walk(ctx context.Context, rootPath string) error {
if err != nil {
return err
}
err = w.modMgr.EnqueueModuleOp(dir, op.OpTypeDecodeVarsReferences, nil)
if err != nil {
return err
}
}

if dataDir.PluginLockFilePath != "" {
Expand Down
2 changes: 2 additions & 0 deletions internal/terraform/module/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ func decodeCalledModulesFunc(modMgr ModuleManager, w Watcher, modPath string) De
modMgr.EnqueueModuleOp(mc.Path, op.OpTypeParseVariables, nil)
modMgr.EnqueueModuleOp(mc.Path, op.OpTypeDecodeReferenceTargets, nil)
modMgr.EnqueueModuleOp(mc.Path, op.OpTypeDecodeReferenceOrigins, nil)
modMgr.EnqueueModuleOp(mc.Path, op.OpTypeDecodeVarsReferences, nil)

if w != nil {
w.AddModule(mc.Path)
Expand All @@ -258,6 +259,7 @@ func decodeCalledModulesFunc(modMgr ModuleManager, w Watcher, modPath string) De

modMgr.EnqueueModuleOp(modPath, op.OpTypeDecodeReferenceTargets, nil)
modMgr.EnqueueModuleOp(modPath, op.OpTypeDecodeReferenceOrigins, nil)
modMgr.EnqueueModuleOp(modPath, op.OpTypeDecodeVarsReferences, nil)
}
}

Expand Down