github.com/terraform-linters/tflint-plugin-sdk@v0.22.0/terraform/lang/references.go (about)

     1  package lang
     2  
     3  import (
     4  	"github.com/hashicorp/hcl/v2"
     5  	"github.com/terraform-linters/tflint-plugin-sdk/terraform/addrs"
     6  )
     7  
     8  // References finds all of the references in the given set of traversals,
     9  // returning diagnostics if any of the traversals cannot be interpreted as a
    10  // reference.
    11  //
    12  // This function does not do any de-duplication of references, since references
    13  // have source location information embedded in them and so any invalid
    14  // references that are duplicated should have errors reported for each
    15  // occurence.
    16  //
    17  // If the returned diagnostics contains errors then the result may be
    18  // incomplete or invalid. Otherwise, the returned slice has one reference per
    19  // given traversal, though it is not guaranteed that the references will
    20  // appear in the same order as the given traversals.
    21  func References(traversals []hcl.Traversal) ([]*addrs.Reference, hcl.Diagnostics) {
    22  	if len(traversals) == 0 {
    23  		return nil, nil
    24  	}
    25  
    26  	var diags hcl.Diagnostics
    27  	refs := make([]*addrs.Reference, 0, len(traversals))
    28  
    29  	for _, traversal := range traversals {
    30  		ref, refDiags := addrs.ParseRef(traversal)
    31  		diags = diags.Extend(refDiags)
    32  		if ref == nil {
    33  			continue
    34  		}
    35  		refs = append(refs, ref)
    36  	}
    37  
    38  	return refs, diags
    39  }
    40  
    41  // ReferencesInExpr is a helper wrapper around References that first searches
    42  // the given expression for traversals, before converting those traversals
    43  // to references.
    44  //
    45  // This function is almost identical to the Terraform internal API of the same name,
    46  // except that it does not return diagnostics if it contains an invalid reference.
    47  // This is because expressions with invalid traversals as references, such as
    48  // `ignore_changes`, may be parsed. Developers should take advantage of the possible
    49  // incomplete results returned by this function.
    50  //
    51  // Low-level APIs such as addrs.ParseRef are recommended if the expression is
    52  // guaranteed not to contain invalid traversals, and analysis should stop in that case.
    53  func ReferencesInExpr(expr hcl.Expression) []*addrs.Reference {
    54  	if expr == nil {
    55  		return nil
    56  	}
    57  	traversals := expr.Variables()
    58  	refs, _ := References(traversals)
    59  	return refs
    60  }