github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/codegen/hcl2/model/expression.go (about)

     1  // Copyright 2016-2020, Pulumi Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package model
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"math/big"
    21  	"strconv"
    22  
    23  	"github.com/hashicorp/hcl/v2"
    24  	"github.com/hashicorp/hcl/v2/hclsyntax"
    25  	"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2/syntax"
    26  	"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
    27  	"github.com/zclconf/go-cty/cty"
    28  	"github.com/zclconf/go-cty/cty/convert"
    29  )
    30  
    31  // Expression represents a semantically-analyzed HCL2 expression.
    32  type Expression interface {
    33  	printable
    34  
    35  	// SyntaxNode returns the hclsyntax.Node associated with the expression.
    36  	SyntaxNode() hclsyntax.Node
    37  	// NodeTokens returns the syntax.Tokens associated with the expression.
    38  	NodeTokens() syntax.NodeTokens
    39  
    40  	// SetLeadingTrivia sets the leading trivia associated with the expression.
    41  	SetLeadingTrivia(syntax.TriviaList)
    42  	// SetTrailingTrivia sets the trailing trivia associated with the expression.
    43  	SetTrailingTrivia(syntax.TriviaList)
    44  
    45  	// Type returns the type of the expression.
    46  	Type() Type
    47  	// Typecheck recomputes the type of the expression, optionally typechecking its operands first.
    48  	Typecheck(typecheckOperands bool) hcl.Diagnostics
    49  
    50  	// Evaluate evaluates the expression.
    51  	Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics)
    52  
    53  	isExpression()
    54  }
    55  
    56  func identToken(token syntax.Token, ident string) syntax.Token {
    57  	if string(token.Raw.Bytes) != ident {
    58  		token.Raw.Bytes = []byte(ident)
    59  	}
    60  	return token
    61  }
    62  
    63  func exprHasLeadingTrivia(parens syntax.Parentheses, first interface{}) bool {
    64  	if parens.Any() {
    65  		return true
    66  	}
    67  	switch first := first.(type) {
    68  	case Expression:
    69  		return first.HasLeadingTrivia()
    70  	case bool:
    71  		return first
    72  	default:
    73  		contract.Failf("unexpected value of type %T for first", first)
    74  		return false
    75  	}
    76  }
    77  
    78  func exprHasTrailingTrivia(parens syntax.Parentheses, last interface{}) bool {
    79  	if parens.Any() {
    80  		return true
    81  	}
    82  	switch last := last.(type) {
    83  	case Expression:
    84  		return last.HasTrailingTrivia()
    85  	case bool:
    86  		return last
    87  	default:
    88  		contract.Failf("unexpected value of type %T for last", last)
    89  		return false
    90  	}
    91  }
    92  
    93  func getExprLeadingTrivia(parens syntax.Parentheses, first interface{}) syntax.TriviaList {
    94  	if parens.Any() {
    95  		return parens.GetLeadingTrivia()
    96  	}
    97  	switch first := first.(type) {
    98  	case Expression:
    99  		return first.GetLeadingTrivia()
   100  	case syntax.Token:
   101  		return first.LeadingTrivia
   102  	}
   103  	return nil
   104  }
   105  
   106  func setExprLeadingTrivia(parens syntax.Parentheses, first interface{}, trivia syntax.TriviaList) {
   107  	if parens.Any() {
   108  		parens.SetLeadingTrivia(trivia)
   109  		return
   110  	}
   111  	switch first := first.(type) {
   112  	case Expression:
   113  		first.SetLeadingTrivia(trivia)
   114  	case *syntax.Token:
   115  		first.LeadingTrivia = trivia
   116  	}
   117  }
   118  
   119  func getExprTrailingTrivia(parens syntax.Parentheses, last interface{}) syntax.TriviaList {
   120  	if parens.Any() {
   121  		return parens.GetTrailingTrivia()
   122  	}
   123  	switch last := last.(type) {
   124  	case Expression:
   125  		return last.GetTrailingTrivia()
   126  	case syntax.Token:
   127  		return last.TrailingTrivia
   128  	}
   129  	return nil
   130  }
   131  
   132  func setExprTrailingTrivia(parens syntax.Parentheses, last interface{}, trivia syntax.TriviaList) {
   133  	if parens.Any() {
   134  		parens.SetTrailingTrivia(trivia)
   135  		return
   136  	}
   137  	switch last := last.(type) {
   138  	case Expression:
   139  		last.SetTrailingTrivia(trivia)
   140  	case *syntax.Token:
   141  		last.TrailingTrivia = trivia
   142  	}
   143  }
   144  
   145  type syntaxExpr struct {
   146  	hclsyntax.LiteralValueExpr
   147  
   148  	expr Expression
   149  }
   150  
   151  func (x syntaxExpr) Value(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   152  	return x.expr.Evaluate(context)
   153  }
   154  
   155  type hclExpression struct {
   156  	x Expression
   157  }
   158  
   159  func HCLExpression(x Expression) hcl.Expression {
   160  	return hclExpression{x: x}
   161  }
   162  
   163  func (x hclExpression) Value(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   164  	return x.x.Evaluate(context)
   165  }
   166  
   167  func (x hclExpression) Variables() []hcl.Traversal {
   168  	var variables []hcl.Traversal
   169  	scope := NewRootScope(syntax.None)
   170  	_, diags := VisitExpression(x.x, func(n Expression) (Expression, hcl.Diagnostics) {
   171  		switch n := n.(type) {
   172  		case *AnonymousFunctionExpression:
   173  			scope = scope.Push(syntax.None)
   174  			for _, p := range n.Parameters {
   175  				scope.Define(p.Name, p)
   176  			}
   177  		case *ForExpression:
   178  			scope = scope.Push(syntax.None)
   179  			if n.KeyVariable != nil {
   180  				scope.Define(n.KeyVariable.Name, n.KeyVariable)
   181  			}
   182  			scope.Define(n.ValueVariable.Name, n.ValueVariable)
   183  		}
   184  		return n, nil
   185  	}, func(n Expression) (Expression, hcl.Diagnostics) {
   186  		switch n := n.(type) {
   187  		case *AnonymousFunctionExpression, *ForExpression:
   188  			scope = scope.Pop()
   189  		case *ScopeTraversalExpression:
   190  			if _, isSplatVariable := n.Parts[0].(*SplatVariable); !isSplatVariable {
   191  				if _, defined := scope.BindReference(n.RootName); !defined {
   192  					variables = append(variables, n.Traversal.SimpleSplit().Abs)
   193  				}
   194  			}
   195  		}
   196  		return n, nil
   197  	})
   198  	contract.Assert(len(diags) == 0)
   199  	return variables
   200  }
   201  
   202  func (x hclExpression) Range() hcl.Range {
   203  	if syntax := x.x.SyntaxNode(); syntax != nil {
   204  		return syntax.Range()
   205  	}
   206  	return hcl.Range{}
   207  }
   208  
   209  func (x hclExpression) StartRange() hcl.Range {
   210  	if syntax := x.x.SyntaxNode(); syntax != nil {
   211  		return syntax.(hcl.Expression).StartRange()
   212  	}
   213  	return hcl.Range{}
   214  }
   215  
   216  func operatorPrecedence(op *hclsyntax.Operation) int {
   217  	switch op {
   218  	case hclsyntax.OpLogicalOr:
   219  		return 1
   220  	case hclsyntax.OpLogicalAnd:
   221  		return 2
   222  	case hclsyntax.OpEqual, hclsyntax.OpNotEqual:
   223  		return 3
   224  	case hclsyntax.OpGreaterThan, hclsyntax.OpGreaterThanOrEqual, hclsyntax.OpLessThan, hclsyntax.OpLessThanOrEqual:
   225  		return 4
   226  	case hclsyntax.OpAdd, hclsyntax.OpSubtract:
   227  		return 5
   228  	case hclsyntax.OpMultiply, hclsyntax.OpDivide, hclsyntax.OpModulo:
   229  		return 6
   230  	case hclsyntax.OpNegate, hclsyntax.OpLogicalNot:
   231  		return 7
   232  	default:
   233  		return 8
   234  	}
   235  }
   236  
   237  // AnonymousFunctionExpression represents a semantically-analyzed anonymous function expression.
   238  //
   239  // These expressions are not the result of semantically analyzing syntax nodes. Instead, they may be synthesized by
   240  // transforms over the IR for a program (e.g. the Apply transform).
   241  type AnonymousFunctionExpression struct {
   242  	// The signature for the anonymous function.
   243  	Signature StaticFunctionSignature
   244  	// The parameter definitions for the anonymous function.
   245  	Parameters []*Variable
   246  
   247  	// The body of the anonymous function.
   248  	Body Expression
   249  }
   250  
   251  // SyntaxNode returns the syntax node associated with the body of the anonymous function.
   252  func (x *AnonymousFunctionExpression) SyntaxNode() hclsyntax.Node {
   253  	return x.Body.SyntaxNode()
   254  }
   255  
   256  // NodeTokens returns the tokens associated with the body of the anonymous function.
   257  func (x *AnonymousFunctionExpression) NodeTokens() syntax.NodeTokens {
   258  	return x.Body.NodeTokens()
   259  }
   260  
   261  // Type returns the type of the anonymous function expression.
   262  //
   263  // TODO: currently this returns the any type. Instead, it should return a function type.
   264  func (x *AnonymousFunctionExpression) Type() Type {
   265  	return DynamicType
   266  }
   267  
   268  func (x *AnonymousFunctionExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
   269  	var diagnostics hcl.Diagnostics
   270  
   271  	if typecheckOperands {
   272  		bodyDiags := x.Body.Typecheck(true)
   273  		diagnostics = append(diagnostics, bodyDiags...)
   274  	}
   275  
   276  	return diagnostics
   277  }
   278  
   279  func (x *AnonymousFunctionExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   280  	return cty.NilVal, hcl.Diagnostics{cannotEvaluateAnonymousFunctionExpressions()}
   281  }
   282  
   283  func (x *AnonymousFunctionExpression) HasLeadingTrivia() bool {
   284  	return x.Body.HasLeadingTrivia()
   285  }
   286  
   287  func (x *AnonymousFunctionExpression) HasTrailingTrivia() bool {
   288  	return x.Body.HasTrailingTrivia()
   289  }
   290  
   291  func (x *AnonymousFunctionExpression) GetLeadingTrivia() syntax.TriviaList {
   292  	return x.Body.GetLeadingTrivia()
   293  }
   294  
   295  func (x *AnonymousFunctionExpression) SetLeadingTrivia(t syntax.TriviaList) {
   296  	x.Body.SetLeadingTrivia(t)
   297  }
   298  
   299  func (x *AnonymousFunctionExpression) GetTrailingTrivia() syntax.TriviaList {
   300  	return x.Body.GetTrailingTrivia()
   301  }
   302  
   303  func (x *AnonymousFunctionExpression) SetTrailingTrivia(t syntax.TriviaList) {
   304  	x.Body.SetTrailingTrivia(t)
   305  }
   306  
   307  func (x *AnonymousFunctionExpression) Format(f fmt.State, c rune) {
   308  	x.print(f, &printer{})
   309  }
   310  
   311  func (x *AnonymousFunctionExpression) print(w io.Writer, p *printer) {
   312  	// Print a call to eval.
   313  	p.fprintf(w, "eval(")
   314  
   315  	// Print the parameter names.
   316  	for _, v := range x.Parameters {
   317  		p.fprintf(w, "%v, ", v.Name)
   318  	}
   319  
   320  	// Print the body and closing paren.
   321  	p.fprintf(w, "%v)", x.Body)
   322  }
   323  
   324  func (*AnonymousFunctionExpression) isExpression() {}
   325  
   326  // BinaryOpExpression represents a semantically-analyzed binary operation.
   327  type BinaryOpExpression struct {
   328  	// The syntax node associated with the binary operation.
   329  	Syntax *hclsyntax.BinaryOpExpr
   330  	// The tokens associated with the expression, if any.
   331  	Tokens *syntax.BinaryOpTokens
   332  
   333  	// The left-hand operand of the operation.
   334  	LeftOperand Expression
   335  	// The operation.
   336  	Operation *hclsyntax.Operation
   337  	// The right-hand operand of the operation.
   338  	RightOperand Expression
   339  
   340  	leftType  Type
   341  	rightType Type
   342  	exprType  Type
   343  }
   344  
   345  // SyntaxNode returns the syntax node associated with the binary operation.
   346  func (x *BinaryOpExpression) SyntaxNode() hclsyntax.Node {
   347  	return x.Syntax
   348  }
   349  
   350  // NodeTokens returns the tokens associated with the binary operation.
   351  func (x *BinaryOpExpression) NodeTokens() syntax.NodeTokens {
   352  	return x.Tokens
   353  }
   354  
   355  // LeftOperandType returns the desired type for the left operand of the binary operation.
   356  func (x *BinaryOpExpression) LeftOperandType() Type {
   357  	return x.leftType
   358  }
   359  
   360  // RightOperandType returns the desired type for the right operand of the binary operation.
   361  func (x *BinaryOpExpression) RightOperandType() Type {
   362  	return x.rightType
   363  }
   364  
   365  // Type returns the type of the binary operation.
   366  func (x *BinaryOpExpression) Type() Type {
   367  	return x.exprType
   368  }
   369  
   370  func (x *BinaryOpExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
   371  	var diagnostics hcl.Diagnostics
   372  
   373  	var rng hcl.Range
   374  	if x.Syntax != nil {
   375  		rng = x.Syntax.Range()
   376  	}
   377  
   378  	if typecheckOperands {
   379  		leftDiags := x.LeftOperand.Typecheck(true)
   380  		diagnostics = append(diagnostics, leftDiags...)
   381  
   382  		rightDiags := x.RightOperand.Typecheck(true)
   383  		diagnostics = append(diagnostics, rightDiags...)
   384  	}
   385  
   386  	// Compute the signature for the operator and typecheck the arguments.
   387  	signature := getOperationSignature(x.Operation)
   388  	contract.Assert(len(signature.Parameters) == 2)
   389  
   390  	x.leftType = signature.Parameters[0].Type
   391  	x.rightType = signature.Parameters[1].Type
   392  
   393  	typecheckDiags := typecheckArgs(rng, signature, x.LeftOperand, x.RightOperand)
   394  	diagnostics = append(diagnostics, typecheckDiags...)
   395  
   396  	x.exprType = liftOperationType(signature.ReturnType, x.LeftOperand, x.RightOperand)
   397  	return diagnostics
   398  }
   399  
   400  func (x *BinaryOpExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   401  	syntax := &hclsyntax.BinaryOpExpr{
   402  		LHS: &syntaxExpr{expr: x.LeftOperand},
   403  		Op:  x.Operation,
   404  		RHS: &syntaxExpr{expr: x.RightOperand},
   405  	}
   406  	return syntax.Value(context)
   407  }
   408  
   409  func (x *BinaryOpExpression) HasLeadingTrivia() bool {
   410  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.LeftOperand)
   411  }
   412  
   413  func (x *BinaryOpExpression) HasTrailingTrivia() bool {
   414  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.RightOperand)
   415  }
   416  
   417  func (x *BinaryOpExpression) GetLeadingTrivia() syntax.TriviaList {
   418  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.LeftOperand)
   419  }
   420  
   421  func (x *BinaryOpExpression) SetLeadingTrivia(t syntax.TriviaList) {
   422  	setExprLeadingTrivia(x.Tokens.GetParentheses(), x.LeftOperand, t)
   423  }
   424  
   425  func (x *BinaryOpExpression) GetTrailingTrivia() syntax.TriviaList {
   426  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.RightOperand)
   427  }
   428  
   429  func (x *BinaryOpExpression) SetTrailingTrivia(t syntax.TriviaList) {
   430  	if x.Tokens == nil {
   431  		x.Tokens = syntax.NewBinaryOpTokens(x.Operation)
   432  	}
   433  	setExprTrailingTrivia(x.Tokens.GetParentheses(), x.RightOperand, t)
   434  }
   435  
   436  func (x *BinaryOpExpression) Format(f fmt.State, c rune) {
   437  	x.print(f, &printer{})
   438  }
   439  
   440  func (x *BinaryOpExpression) print(w io.Writer, p *printer) {
   441  	precedence := operatorPrecedence(x.Operation)
   442  	p.fprintf(w, "%[2](%.[1]*[3]v% [4]v% .[1]*[5]o%[6])",
   443  		precedence,
   444  		x.Tokens.GetParentheses(),
   445  		x.LeftOperand, x.Tokens.GetOperator(x.Operation), x.RightOperand,
   446  		x.Tokens.GetParentheses())
   447  }
   448  
   449  func (*BinaryOpExpression) isExpression() {}
   450  
   451  // ConditionalExpression represents a semantically-analzed conditional expression (i.e.
   452  // <condition> '?' <true> ':' <false>).
   453  type ConditionalExpression struct {
   454  	// The syntax node associated with the conditional expression.
   455  	Syntax *hclsyntax.ConditionalExpr
   456  	// The tokens associated with the expression, if any.
   457  	Tokens syntax.NodeTokens
   458  
   459  	// The condition.
   460  	Condition Expression
   461  	// The result of the expression if the condition evaluates to true.
   462  	TrueResult Expression
   463  	// The result of the expression if the condition evaluates to false.
   464  	FalseResult Expression
   465  
   466  	exprType Type
   467  }
   468  
   469  // SyntaxNode returns the syntax node associated with the conditional expression.
   470  func (x *ConditionalExpression) SyntaxNode() hclsyntax.Node {
   471  	return x.Syntax
   472  }
   473  
   474  // NodeTokens returns the tokens associated with the conditional expression.
   475  func (x *ConditionalExpression) NodeTokens() syntax.NodeTokens {
   476  	return x.Tokens
   477  }
   478  
   479  // Type returns the type of the conditional expression.
   480  func (x *ConditionalExpression) Type() Type {
   481  	return x.exprType
   482  }
   483  
   484  func (x *ConditionalExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
   485  	var diagnostics hcl.Diagnostics
   486  
   487  	if typecheckOperands {
   488  		conditionDiags := x.Condition.Typecheck(true)
   489  		diagnostics = append(diagnostics, conditionDiags...)
   490  
   491  		trueDiags := x.TrueResult.Typecheck(true)
   492  		diagnostics = append(diagnostics, trueDiags...)
   493  
   494  		falseDiags := x.FalseResult.Typecheck(true)
   495  		diagnostics = append(diagnostics, falseDiags...)
   496  	}
   497  
   498  	// Compute the type of the result.
   499  	resultType, _ := UnifyTypes(x.TrueResult.Type(), x.FalseResult.Type())
   500  
   501  	// Typecheck the condition expression.
   502  	if InputType(BoolType).ConversionFrom(x.Condition.Type()) == NoConversion {
   503  		diagnostics = append(diagnostics, ExprNotConvertible(InputType(BoolType), x.Condition))
   504  	}
   505  
   506  	x.exprType = liftOperationType(resultType, x.Condition)
   507  	return diagnostics
   508  }
   509  
   510  func (x *ConditionalExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   511  	syntax := &hclsyntax.ConditionalExpr{
   512  		Condition:   &syntaxExpr{expr: x.Condition},
   513  		TrueResult:  &syntaxExpr{expr: x.TrueResult},
   514  		FalseResult: &syntaxExpr{expr: x.FalseResult},
   515  	}
   516  	return syntax.Value(context)
   517  }
   518  
   519  func (x *ConditionalExpression) HasLeadingTrivia() bool {
   520  	switch tokens := x.Tokens.(type) {
   521  	case *syntax.ConditionalTokens:
   522  		if tokens.Parentheses.Any() {
   523  			return true
   524  		}
   525  	case *syntax.TemplateConditionalTokens:
   526  		return len(tokens.OpenIf.LeadingTrivia) != 0
   527  	}
   528  	return x.Condition.HasLeadingTrivia()
   529  }
   530  
   531  func (x *ConditionalExpression) HasTrailingTrivia() bool {
   532  	switch tokens := x.Tokens.(type) {
   533  	case *syntax.ConditionalTokens:
   534  		if tokens.Parentheses.Any() {
   535  			return true
   536  		}
   537  	case *syntax.TemplateConditionalTokens:
   538  		return len(tokens.CloseEndif.TrailingTrivia) != 0
   539  	}
   540  	return x.FalseResult.HasTrailingTrivia()
   541  }
   542  
   543  func (x *ConditionalExpression) GetLeadingTrivia() syntax.TriviaList {
   544  	switch tokens := x.Tokens.(type) {
   545  	case *syntax.ConditionalTokens:
   546  		if tokens.Parentheses.Any() {
   547  			return tokens.Parentheses.GetLeadingTrivia()
   548  		}
   549  	case *syntax.TemplateConditionalTokens:
   550  		return tokens.OpenIf.LeadingTrivia
   551  	}
   552  	return x.Condition.GetLeadingTrivia()
   553  }
   554  
   555  func (x *ConditionalExpression) SetLeadingTrivia(t syntax.TriviaList) {
   556  	switch tokens := x.Tokens.(type) {
   557  	case *syntax.ConditionalTokens:
   558  		if tokens.Parentheses.Any() {
   559  			tokens.Parentheses.SetLeadingTrivia(t)
   560  			return
   561  		}
   562  	case *syntax.TemplateConditionalTokens:
   563  		tokens.OpenIf.LeadingTrivia = t
   564  		return
   565  	}
   566  	x.Condition.SetLeadingTrivia(t)
   567  }
   568  
   569  func (x *ConditionalExpression) GetTrailingTrivia() syntax.TriviaList {
   570  	switch tokens := x.Tokens.(type) {
   571  	case *syntax.ConditionalTokens:
   572  		if tokens.Parentheses.Any() {
   573  			return tokens.Parentheses.GetTrailingTrivia()
   574  		}
   575  	case *syntax.TemplateConditionalTokens:
   576  		return tokens.CloseEndif.TrailingTrivia
   577  	}
   578  	return x.FalseResult.GetTrailingTrivia()
   579  }
   580  
   581  func (x *ConditionalExpression) SetTrailingTrivia(t syntax.TriviaList) {
   582  	if x.Tokens == nil {
   583  		x.Tokens = syntax.NewConditionalTokens()
   584  	}
   585  	switch tokens := x.Tokens.(type) {
   586  	case *syntax.ConditionalTokens:
   587  		if tokens.Parentheses.Any() {
   588  			tokens.Parentheses.SetTrailingTrivia(t)
   589  			return
   590  		}
   591  	case *syntax.TemplateConditionalTokens:
   592  		tokens.CloseEndif.TrailingTrivia = t
   593  		return
   594  	}
   595  	x.FalseResult.SetTrailingTrivia(t)
   596  }
   597  
   598  func (x *ConditionalExpression) Format(f fmt.State, c rune) {
   599  	x.print(f, &printer{})
   600  }
   601  
   602  func (x *ConditionalExpression) print(w io.Writer, p *printer) {
   603  	tokens := x.Tokens
   604  	if tokens == nil {
   605  		tokens = syntax.NewConditionalTokens()
   606  	}
   607  
   608  	switch tokens := tokens.(type) {
   609  	case *syntax.ConditionalTokens:
   610  		p.fprintf(w, "%(%v% v% v% v% v%)",
   611  			tokens.Parentheses,
   612  			x.Condition, tokens.QuestionMark, x.TrueResult, tokens.Colon, x.FalseResult,
   613  			tokens.Parentheses)
   614  	case *syntax.TemplateConditionalTokens:
   615  		p.fprintf(w, "%v%v% v%v%v", tokens.OpenIf, tokens.If, x.Condition, tokens.CloseIf, x.TrueResult)
   616  		if tokens.Else != nil {
   617  			p.fprintf(w, "%v%v%v%v", tokens.OpenElse, tokens.Else, tokens.CloseElse, x.FalseResult)
   618  		}
   619  		p.fprintf(w, "%v%v%v", tokens.OpenEndif, tokens.Endif, tokens.CloseEndif)
   620  	}
   621  }
   622  
   623  func (*ConditionalExpression) isExpression() {}
   624  
   625  // ErrorExpression represents an expression that could not be bound due to an error.
   626  type ErrorExpression struct {
   627  	// The syntax node associated with the error, if any.
   628  	Syntax hclsyntax.Node
   629  	// The tokens associated with the error.
   630  	Tokens syntax.NodeTokens
   631  	// The message associated with the error.
   632  	Message string
   633  
   634  	exprType Type
   635  }
   636  
   637  // SyntaxNode returns the syntax node associated with the error expression.
   638  func (x *ErrorExpression) SyntaxNode() hclsyntax.Node {
   639  	return x.Syntax
   640  }
   641  
   642  // NodeTokens returns the tokens associated with the error expression.
   643  func (x *ErrorExpression) NodeTokens() syntax.NodeTokens {
   644  	return x.Tokens
   645  }
   646  
   647  // Type returns the type of the error expression.
   648  func (x *ErrorExpression) Type() Type {
   649  	return x.exprType
   650  }
   651  
   652  func (x *ErrorExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
   653  	return nil
   654  }
   655  
   656  func (x *ErrorExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   657  	return cty.DynamicVal, hcl.Diagnostics{{
   658  		Severity: hcl.DiagError,
   659  		Summary:  x.Message,
   660  	}}
   661  }
   662  
   663  func (x *ErrorExpression) HasLeadingTrivia() bool {
   664  	return false
   665  }
   666  
   667  func (x *ErrorExpression) HasTrailingTrivia() bool {
   668  	return false
   669  }
   670  
   671  func (x *ErrorExpression) GetLeadingTrivia() syntax.TriviaList {
   672  	return nil
   673  }
   674  
   675  func (x *ErrorExpression) SetLeadingTrivia(t syntax.TriviaList) {
   676  }
   677  
   678  func (x *ErrorExpression) GetTrailingTrivia() syntax.TriviaList {
   679  	return nil
   680  }
   681  
   682  func (x *ErrorExpression) SetTrailingTrivia(t syntax.TriviaList) {
   683  }
   684  
   685  func (x *ErrorExpression) Format(f fmt.State, c rune) {
   686  	x.print(f, &printer{})
   687  }
   688  
   689  func (x *ErrorExpression) print(w io.Writer, p *printer) {
   690  	p.fprintf(w, "error(%q)", x.Message)
   691  }
   692  
   693  func (*ErrorExpression) isExpression() {}
   694  
   695  // ForExpression represents a semantically-analyzed for expression.
   696  type ForExpression struct {
   697  	fmt.Formatter
   698  
   699  	// The syntax node associated with the for expression.
   700  	Syntax *hclsyntax.ForExpr
   701  	// The tokens associated with the expression, if any.
   702  	Tokens syntax.NodeTokens
   703  
   704  	// The key variable, if any.
   705  	KeyVariable *Variable
   706  	// The value variable.
   707  	ValueVariable *Variable
   708  
   709  	// The collection being iterated.
   710  	Collection Expression
   711  	// The expression that generates the keys of the result, if any. If this field is non-nil, the result is a map.
   712  	Key Expression
   713  	// The expression that generates the values of the result.
   714  	Value Expression
   715  	// The condition that filters the items of the result, if any.
   716  	Condition Expression
   717  
   718  	// True if the value expression is being grouped.
   719  	Group bool
   720  
   721  	exprType Type
   722  }
   723  
   724  // SyntaxNode returns the syntax node associated with the for expression.
   725  func (x *ForExpression) SyntaxNode() hclsyntax.Node {
   726  	return x.Syntax
   727  }
   728  
   729  // NodeTokens returns the tokens associated with the for expression.
   730  func (x *ForExpression) NodeTokens() syntax.NodeTokens {
   731  	return x.Tokens
   732  }
   733  
   734  // Type returns the type of the for expression.
   735  func (x *ForExpression) Type() Type {
   736  	return x.exprType
   737  }
   738  
   739  func (x *ForExpression) typecheck(typecheckCollection, typecheckOperands bool) hcl.Diagnostics {
   740  	var diagnostics hcl.Diagnostics
   741  
   742  	var rng hcl.Range
   743  	if x.Syntax != nil {
   744  		rng = x.Syntax.CollExpr.Range()
   745  	}
   746  
   747  	if typecheckOperands {
   748  		collectionDiags := x.Collection.Typecheck(true)
   749  		diagnostics = append(diagnostics, collectionDiags...)
   750  	}
   751  
   752  	if typecheckCollection {
   753  		// Poke through any eventual and optional types that may wrap the collection type.
   754  		collectionType := unwrapIterableSourceType(x.Collection.Type())
   755  
   756  		keyType, valueType, kvDiags := GetCollectionTypes(collectionType, rng)
   757  		diagnostics = append(diagnostics, kvDiags...)
   758  
   759  		if x.KeyVariable != nil {
   760  			x.KeyVariable.VariableType = keyType
   761  		}
   762  		x.ValueVariable.VariableType = valueType
   763  	}
   764  
   765  	if typecheckOperands {
   766  		if x.Key != nil {
   767  			keyDiags := x.Key.Typecheck(true)
   768  			diagnostics = append(diagnostics, keyDiags...)
   769  		}
   770  
   771  		valueDiags := x.Value.Typecheck(true)
   772  		diagnostics = append(diagnostics, valueDiags...)
   773  
   774  		if x.Condition != nil {
   775  			conditionDiags := x.Condition.Typecheck(true)
   776  			diagnostics = append(diagnostics, conditionDiags...)
   777  		}
   778  	}
   779  
   780  	if x.Key != nil {
   781  		// A key expression is only present when producing a map. Key types must therefore be strings.
   782  		if !InputType(StringType).ConversionFrom(x.Key.Type()).Exists() {
   783  			diagnostics = append(diagnostics, ExprNotConvertible(InputType(StringType), x.Key))
   784  		}
   785  	}
   786  
   787  	if x.Condition != nil {
   788  		if !InputType(BoolType).ConversionFrom(x.Condition.Type()).Exists() {
   789  			diagnostics = append(diagnostics, ExprNotConvertible(InputType(BoolType), x.Condition))
   790  		}
   791  	}
   792  
   793  	// If there is a key expression, we are producing a map. Otherwise, we are producing an list. In either case, wrap
   794  	// the result type in the same set of eventuals and optionals present in the collection type.
   795  	var resultType Type
   796  	if x.Key != nil {
   797  		valueType := x.Value.Type()
   798  		if x.Group {
   799  			valueType = NewListType(valueType)
   800  		}
   801  		resultType = wrapIterableResultType(x.Collection.Type(), NewMapType(valueType))
   802  	} else {
   803  		resultType = wrapIterableResultType(x.Collection.Type(), NewListType(x.Value.Type()))
   804  	}
   805  
   806  	// If either the key expression or the condition expression is eventual, the result is eventual: each of these
   807  	// values is required to determine which items are present in the result.
   808  	var liftArgs []Expression
   809  	if x.Key != nil {
   810  		liftArgs = append(liftArgs, x.Key)
   811  	}
   812  	if x.Condition != nil {
   813  		liftArgs = append(liftArgs, x.Condition)
   814  	}
   815  
   816  	x.exprType = liftOperationType(resultType, liftArgs...)
   817  	return diagnostics
   818  }
   819  
   820  func (x *ForExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
   821  	return x.typecheck(true, typecheckOperands)
   822  }
   823  
   824  func (x *ForExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
   825  	syntax := &hclsyntax.ForExpr{
   826  		ValVar:   x.ValueVariable.Name,
   827  		CollExpr: &syntaxExpr{expr: x.Collection},
   828  		ValExpr:  &syntaxExpr{expr: x.Value},
   829  		Group:    x.Group,
   830  	}
   831  	if x.KeyVariable != nil {
   832  		syntax.KeyVar = x.KeyVariable.Name
   833  	}
   834  	if x.Key != nil {
   835  		syntax.KeyExpr = &syntaxExpr{expr: x.Key}
   836  	}
   837  	if x.Condition != nil {
   838  		syntax.CondExpr = &syntaxExpr{expr: x.Condition}
   839  	}
   840  	return syntax.Value(context)
   841  }
   842  
   843  func (x *ForExpression) HasLeadingTrivia() bool {
   844  	return x.Tokens != nil
   845  }
   846  
   847  func (x *ForExpression) HasTrailingTrivia() bool {
   848  	return x.Tokens != nil
   849  }
   850  
   851  func (x *ForExpression) GetLeadingTrivia() syntax.TriviaList {
   852  	switch tokens := x.Tokens.(type) {
   853  	case *syntax.ForTokens:
   854  		return getExprLeadingTrivia(tokens.Parentheses, tokens.Open)
   855  	case *syntax.TemplateForTokens:
   856  		return tokens.OpenFor.LeadingTrivia
   857  	default:
   858  		return nil
   859  	}
   860  }
   861  
   862  func (x *ForExpression) SetLeadingTrivia(t syntax.TriviaList) {
   863  	if x.Tokens == nil {
   864  		keyVariable := ""
   865  		if x.KeyVariable != nil {
   866  			keyVariable = x.KeyVariable.Name
   867  		}
   868  		x.Tokens = syntax.NewForTokens(keyVariable, x.ValueVariable.Name, x.Key != nil, x.Group, x.Condition != nil)
   869  	}
   870  	switch tokens := x.Tokens.(type) {
   871  	case *syntax.ForTokens:
   872  		setExprLeadingTrivia(tokens.Parentheses, &tokens.Open, t)
   873  	case *syntax.TemplateForTokens:
   874  		tokens.OpenFor.LeadingTrivia = t
   875  	}
   876  }
   877  
   878  func (x *ForExpression) GetTrailingTrivia() syntax.TriviaList {
   879  	switch tokens := x.Tokens.(type) {
   880  	case *syntax.ForTokens:
   881  		return getExprTrailingTrivia(tokens.Parentheses, tokens.Close)
   882  	case *syntax.TemplateForTokens:
   883  		return tokens.CloseEndfor.TrailingTrivia
   884  	default:
   885  		return nil
   886  	}
   887  }
   888  
   889  func (x *ForExpression) SetTrailingTrivia(t syntax.TriviaList) {
   890  	if x.Tokens == nil {
   891  		keyVariable := ""
   892  		if x.KeyVariable != nil {
   893  			keyVariable = x.KeyVariable.Name
   894  		}
   895  		x.Tokens = syntax.NewForTokens(keyVariable, x.ValueVariable.Name, x.Key != nil, x.Group, x.Condition != nil)
   896  	}
   897  	switch tokens := x.Tokens.(type) {
   898  	case *syntax.ForTokens:
   899  		setExprTrailingTrivia(tokens.Parentheses, &tokens.Close, t)
   900  	case *syntax.TemplateForTokens:
   901  		tokens.CloseEndfor.TrailingTrivia = t
   902  	}
   903  }
   904  
   905  func (x *ForExpression) Format(f fmt.State, c rune) {
   906  	x.print(f, &printer{})
   907  }
   908  
   909  func (x *ForExpression) print(w io.Writer, p *printer) {
   910  	tokens := x.Tokens
   911  	if tokens == nil {
   912  		keyVariable := ""
   913  		if x.KeyVariable != nil {
   914  			keyVariable = x.KeyVariable.Name
   915  		}
   916  		syntax.NewForTokens(keyVariable, x.ValueVariable.Name, x.Key != nil, x.Group, x.Condition != nil)
   917  	}
   918  
   919  	switch tokens := tokens.(type) {
   920  	case *syntax.ForTokens:
   921  		// Print the opening rune and the for token.
   922  		p.fprintf(w, "%(%v%v", tokens.Parentheses, tokens.Open, tokens.For)
   923  
   924  		// Print the key variable, if any.
   925  		if x.KeyVariable != nil {
   926  			keyToken := tokens.Key
   927  			if x.KeyVariable != nil && keyToken == nil {
   928  				keyToken = &syntax.Token{Raw: hclsyntax.Token{Type: hclsyntax.TokenIdent}}
   929  			}
   930  
   931  			key := identToken(*keyToken, x.KeyVariable.Name)
   932  			p.fprintf(w, "% v%v", key, tokens.Comma)
   933  		}
   934  
   935  		// Print the value variable, the in token, the collection expression, and the colon.
   936  		value := identToken(tokens.Value, x.ValueVariable.Name)
   937  		p.fprintf(w, "% v% v% v%v", value, tokens.In, x.Collection, tokens.Colon)
   938  
   939  		// Print the key expression and arrow token, if any.
   940  		if x.Key != nil {
   941  			p.fprintf(w, "% v% v", x.Key, tokens.Arrow)
   942  		}
   943  
   944  		// Print the value expression.
   945  		p.fprintf(w, "% v", x.Value)
   946  
   947  		// Print the group token, if any.
   948  		if x.Group {
   949  			p.fprintf(w, "%v", tokens.Group)
   950  		}
   951  
   952  		// Print the if token and the condition, if any.
   953  		if x.Condition != nil {
   954  			p.fprintf(w, "% v% v", tokens.If, x.Condition)
   955  		}
   956  
   957  		// Print the closing rune.
   958  		p.fprintf(w, "%v%)", tokens.Close, tokens.Parentheses)
   959  	case *syntax.TemplateForTokens:
   960  		// Print the opening sequence.
   961  		p.fprintf(w, "%v%v", tokens.OpenFor, tokens.For)
   962  
   963  		// Print the key variable, if any.
   964  		if x.KeyVariable != nil {
   965  			keyToken := tokens.Key
   966  			if x.KeyVariable != nil && keyToken == nil {
   967  				keyToken = &syntax.Token{Raw: hclsyntax.Token{Type: hclsyntax.TokenIdent}}
   968  			}
   969  
   970  			key := identToken(*keyToken, x.KeyVariable.Name)
   971  			p.fprintf(w, "% v%v", key, tokens.Comma)
   972  		}
   973  
   974  		// Print the value variable, the in token, the collection expression, the control sequence terminator, the
   975  		// value expression, and the closing sequence.
   976  		p.fprintf(w, "% v% v% v%v%v%v%v%v",
   977  			identToken(tokens.Value, x.ValueVariable.Name), tokens.In, x.Collection, tokens.CloseFor,
   978  			x.Value,
   979  			tokens.OpenEndfor, tokens.Endfor, tokens.CloseEndfor)
   980  	}
   981  }
   982  
   983  func (*ForExpression) isExpression() {}
   984  
   985  // FunctionCallExpression represents a semantically-analyzed function call expression.
   986  type FunctionCallExpression struct {
   987  	// The syntax node associated with the function call expression.
   988  	Syntax *hclsyntax.FunctionCallExpr
   989  	// The tokens associated with the expression, if any.
   990  	Tokens *syntax.FunctionCallTokens
   991  
   992  	// The name of the called function.
   993  	Name string
   994  	// The signature of the called function.
   995  	Signature StaticFunctionSignature
   996  	// The arguments to the function call.
   997  	Args []Expression
   998  	// ExpandFinal indicates that the final argument should be a tuple, list, or set whose elements will be passed as
   999  	// individual arguments to the function.
  1000  	ExpandFinal bool
  1001  }
  1002  
  1003  // SyntaxNode returns the syntax node associated with the function call expression.
  1004  func (x *FunctionCallExpression) SyntaxNode() hclsyntax.Node {
  1005  	return x.Syntax
  1006  }
  1007  
  1008  // NodeTokens returns the tokens associated with the function call expression.
  1009  func (x *FunctionCallExpression) NodeTokens() syntax.NodeTokens {
  1010  	return x.Tokens
  1011  }
  1012  
  1013  // Type returns the type of the function call expression.
  1014  func (x *FunctionCallExpression) Type() Type {
  1015  	return x.Signature.ReturnType
  1016  }
  1017  
  1018  func (x *FunctionCallExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  1019  	var diagnostics hcl.Diagnostics
  1020  
  1021  	if typecheckOperands {
  1022  		for _, arg := range x.Args {
  1023  			argDiagnostics := arg.Typecheck(true)
  1024  			diagnostics = append(diagnostics, argDiagnostics...)
  1025  		}
  1026  	}
  1027  
  1028  	var rng hcl.Range
  1029  	if x.Syntax != nil {
  1030  		rng = x.Syntax.Range()
  1031  	}
  1032  
  1033  	// Typecheck the function's arguments.
  1034  	typecheckDiags := typecheckArgs(rng, x.Signature, x.Args...)
  1035  	diagnostics = append(diagnostics, typecheckDiags...)
  1036  
  1037  	// Unless the function is already automatically using an
  1038  	// Output-returning version, modify the signature to account
  1039  	// for automatic lifting to Promise or Output.
  1040  	_, isOutput := x.Signature.ReturnType.(*OutputType)
  1041  	if !isOutput {
  1042  		x.Signature.ReturnType = liftOperationType(x.Signature.ReturnType, x.Args...)
  1043  	}
  1044  	return diagnostics
  1045  }
  1046  
  1047  func (x *FunctionCallExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1048  	syntax := &hclsyntax.FunctionCallExpr{
  1049  		Name:        x.Name,
  1050  		Args:        make([]hclsyntax.Expression, len(x.Args)),
  1051  		ExpandFinal: x.ExpandFinal,
  1052  	}
  1053  	for i, arg := range x.Args {
  1054  		syntax.Args[i] = &syntaxExpr{expr: arg}
  1055  	}
  1056  	return syntax.Value(context)
  1057  }
  1058  
  1059  func (x *FunctionCallExpression) HasLeadingTrivia() bool {
  1060  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1061  }
  1062  
  1063  func (x *FunctionCallExpression) HasTrailingTrivia() bool {
  1064  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1065  }
  1066  
  1067  func (x *FunctionCallExpression) GetLeadingTrivia() syntax.TriviaList {
  1068  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetName(x.Name))
  1069  }
  1070  
  1071  func (x *FunctionCallExpression) SetLeadingTrivia(t syntax.TriviaList) {
  1072  	if x.Tokens == nil {
  1073  		x.Tokens = syntax.NewFunctionCallTokens(x.Name, len(x.Args))
  1074  	}
  1075  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Name, t)
  1076  }
  1077  
  1078  func (x *FunctionCallExpression) GetTrailingTrivia() syntax.TriviaList {
  1079  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseParen())
  1080  }
  1081  
  1082  func (x *FunctionCallExpression) SetTrailingTrivia(t syntax.TriviaList) {
  1083  	if x.Tokens == nil {
  1084  		x.Tokens = syntax.NewFunctionCallTokens(x.Name, len(x.Args))
  1085  	}
  1086  	setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseParen, t)
  1087  }
  1088  
  1089  func (x *FunctionCallExpression) Format(f fmt.State, c rune) {
  1090  	x.print(f, &printer{})
  1091  }
  1092  
  1093  func (x *FunctionCallExpression) print(w io.Writer, p *printer) {
  1094  	// Print the name and opening parenthesis.
  1095  	p.fprintf(w, "%(%v%v", x.Tokens.GetParentheses(), x.Tokens.GetName(x.Name), x.Tokens.GetOpenParen())
  1096  
  1097  	// Print each argument and its comma.
  1098  	commas := x.Tokens.GetCommas(len(x.Args))
  1099  	for i, arg := range x.Args {
  1100  		if i == 0 {
  1101  			p.fprintf(w, "%v", arg)
  1102  		} else {
  1103  			p.fprintf(w, "% v", arg)
  1104  		}
  1105  
  1106  		if i < len(x.Args)-1 {
  1107  			var comma syntax.Token
  1108  			if i < len(commas) {
  1109  				comma = commas[i]
  1110  			}
  1111  			p.fprintf(w, "%v", comma)
  1112  		}
  1113  	}
  1114  
  1115  	// If there were commas left over, print the trivia for each.
  1116  	if len(x.Args) > 0 && len(x.Args)-1 <= len(commas) {
  1117  		for _, comma := range commas[len(x.Args)-1:] {
  1118  			p.fprintf(w, "%v", comma.AllTrivia().CollapseWhitespace())
  1119  		}
  1120  	}
  1121  
  1122  	// Print the closing parenthesis.
  1123  	p.fprintf(w, "%v%)", x.Tokens.GetCloseParen(), x.Tokens.GetParentheses())
  1124  }
  1125  
  1126  func (*FunctionCallExpression) isExpression() {}
  1127  
  1128  // IndexExpression represents a semantically-analyzed index expression.
  1129  type IndexExpression struct {
  1130  	// The syntax node associated with the index expression.
  1131  	Syntax *hclsyntax.IndexExpr
  1132  	// The tokens associated with the expression, if any.
  1133  	Tokens *syntax.IndexTokens
  1134  
  1135  	// The collection being indexed.
  1136  	Collection Expression
  1137  	// The index key.
  1138  	Key Expression
  1139  
  1140  	keyType  Type
  1141  	exprType Type
  1142  }
  1143  
  1144  // SyntaxNode returns the syntax node associated with the index expression.
  1145  func (x *IndexExpression) SyntaxNode() hclsyntax.Node {
  1146  	return x.Syntax
  1147  }
  1148  
  1149  // NodeTokens returns the tokens associated with the index expression.
  1150  func (x *IndexExpression) NodeTokens() syntax.NodeTokens {
  1151  	return x.Tokens
  1152  }
  1153  
  1154  // KeyType returns the expected type of the index expression's key.
  1155  func (x *IndexExpression) KeyType() Type {
  1156  	return x.keyType
  1157  }
  1158  
  1159  // Type returns the type of the index expression.
  1160  func (x *IndexExpression) Type() Type {
  1161  	return x.exprType
  1162  }
  1163  
  1164  func (x *IndexExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  1165  	var diagnostics hcl.Diagnostics
  1166  
  1167  	if typecheckOperands {
  1168  		collectionDiags := x.Collection.Typecheck(true)
  1169  		diagnostics = append(diagnostics, collectionDiags...)
  1170  
  1171  		keyDiags := x.Key.Typecheck(true)
  1172  		diagnostics = append(diagnostics, keyDiags...)
  1173  	}
  1174  
  1175  	var rng hcl.Range
  1176  	if x.Syntax != nil {
  1177  		rng = x.Syntax.Collection.Range()
  1178  	}
  1179  
  1180  	collectionType := unwrapIterableSourceType(x.Collection.Type())
  1181  	keyType, valueType, kvDiags := GetCollectionTypes(collectionType, rng)
  1182  	diagnostics = append(diagnostics, kvDiags...)
  1183  	x.keyType = keyType
  1184  
  1185  	if lit, ok := x.Key.(*LiteralValueExpression); ok {
  1186  		traverser := hcl.TraverseIndex{
  1187  			Key: lit.Value,
  1188  		}
  1189  		valueType, traverseDiags := x.Collection.Type().Traverse(traverser)
  1190  		if len(traverseDiags) == 0 {
  1191  			x.exprType = valueType.(Type)
  1192  			return diagnostics
  1193  		}
  1194  	}
  1195  
  1196  	if !InputType(keyType).ConversionFrom(x.Key.Type()).Exists() {
  1197  		diagnostics = append(diagnostics, ExprNotConvertible(InputType(keyType), x.Key))
  1198  	}
  1199  
  1200  	resultType := wrapIterableResultType(x.Collection.Type(), valueType)
  1201  	x.exprType = liftOperationType(resultType, x.Key)
  1202  	return diagnostics
  1203  }
  1204  
  1205  func (x *IndexExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1206  	syntax := &hclsyntax.IndexExpr{
  1207  		Collection: &syntaxExpr{expr: x.Collection},
  1208  		Key:        &syntaxExpr{expr: x.Key},
  1209  	}
  1210  	return syntax.Value(context)
  1211  }
  1212  
  1213  func (x *IndexExpression) HasLeadingTrivia() bool {
  1214  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Collection)
  1215  }
  1216  
  1217  func (x *IndexExpression) HasTrailingTrivia() bool {
  1218  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1219  }
  1220  
  1221  func (x *IndexExpression) GetLeadingTrivia() syntax.TriviaList {
  1222  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpenBracket())
  1223  }
  1224  
  1225  func (x *IndexExpression) SetLeadingTrivia(t syntax.TriviaList) {
  1226  	if x.Tokens == nil {
  1227  		x.Tokens = syntax.NewIndexTokens()
  1228  	}
  1229  	setExprLeadingTrivia(x.Tokens.Parentheses, x.Collection, t)
  1230  }
  1231  
  1232  func (x *IndexExpression) GetTrailingTrivia() syntax.TriviaList {
  1233  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseBracket())
  1234  }
  1235  
  1236  func (x *IndexExpression) SetTrailingTrivia(t syntax.TriviaList) {
  1237  	if x.Tokens == nil {
  1238  		x.Tokens = syntax.NewIndexTokens()
  1239  	}
  1240  	setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseBracket, t)
  1241  }
  1242  
  1243  func (x *IndexExpression) Format(f fmt.State, c rune) {
  1244  	x.print(f, &printer{})
  1245  }
  1246  
  1247  func (x *IndexExpression) print(w io.Writer, p *printer) {
  1248  	p.fprintf(w, "%(%v%v%v%v%)",
  1249  		x.Tokens.GetParentheses(),
  1250  		x.Collection, x.Tokens.GetOpenBracket(), x.Key, x.Tokens.GetCloseBracket(),
  1251  		x.Tokens.GetParentheses())
  1252  }
  1253  
  1254  func (*IndexExpression) isExpression() {}
  1255  
  1256  func literalText(value cty.Value, rawBytes []byte, escaped, quoted bool) string {
  1257  	if len(rawBytes) > 0 {
  1258  		parsed, diags := hclsyntax.ParseExpression(rawBytes, "", hcl.Pos{})
  1259  		if !diags.HasErrors() {
  1260  			if lit, ok := parsed.(*hclsyntax.LiteralValueExpr); ok && lit.Val.RawEquals(value) {
  1261  				return string(rawBytes)
  1262  			}
  1263  		}
  1264  	}
  1265  
  1266  	switch value.Type() {
  1267  	case cty.Bool:
  1268  		if value.True() {
  1269  			return "true"
  1270  		}
  1271  		return "false"
  1272  	case cty.Number:
  1273  		bf := value.AsBigFloat()
  1274  		i, acc := bf.Int64()
  1275  		if acc == big.Exact {
  1276  			return fmt.Sprintf("%v", i)
  1277  		}
  1278  		d, _ := bf.Float64()
  1279  		return fmt.Sprintf("%g", d)
  1280  	case cty.String:
  1281  		if !escaped {
  1282  			return value.AsString()
  1283  		}
  1284  		s := strconv.Quote(value.AsString())
  1285  		if !quoted {
  1286  			return s[1 : len(s)-1]
  1287  		}
  1288  		return s
  1289  	default:
  1290  		panic(fmt.Errorf("unexpected literal type %v", value.Type().FriendlyName()))
  1291  	}
  1292  }
  1293  
  1294  // LiteralValueExpression represents a semantically-analyzed literal value expression.
  1295  type LiteralValueExpression struct {
  1296  	// The syntax node associated with the literal value expression.
  1297  	Syntax *hclsyntax.LiteralValueExpr
  1298  	// The tokens associated with the expression, if any.
  1299  	Tokens *syntax.LiteralValueTokens
  1300  
  1301  	// The value of the expression.
  1302  	Value cty.Value
  1303  
  1304  	exprType Type
  1305  }
  1306  
  1307  // SyntaxNode returns the syntax node associated with the literal value expression.
  1308  func (x *LiteralValueExpression) SyntaxNode() hclsyntax.Node {
  1309  	return x.Syntax
  1310  }
  1311  
  1312  // NodeTokens returns the tokens associated with the literal value expression.
  1313  func (x *LiteralValueExpression) NodeTokens() syntax.NodeTokens {
  1314  	return x.Tokens
  1315  }
  1316  
  1317  // Type returns the type of the literal value expression.
  1318  func (x *LiteralValueExpression) Type() Type {
  1319  	if x.exprType == nil {
  1320  		typ := ctyTypeToType(x.Value.Type(), false)
  1321  		x.exprType = NewConstType(typ, x.Value)
  1322  	}
  1323  	return x.exprType
  1324  }
  1325  
  1326  func (x *LiteralValueExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  1327  	var diagnostics hcl.Diagnostics
  1328  
  1329  	typ := NoneType
  1330  	if !x.Value.IsNull() {
  1331  		typ = ctyTypeToType(x.Value.Type(), false)
  1332  	}
  1333  
  1334  	switch {
  1335  	case typ == NoneType || typ == StringType || typ == IntType || typ == NumberType || typ == BoolType:
  1336  		// OK
  1337  		typ = NewConstType(typ, x.Value)
  1338  	default:
  1339  		var rng hcl.Range
  1340  		if x.Syntax != nil {
  1341  			rng = x.Syntax.Range()
  1342  		}
  1343  		typ, diagnostics = DynamicType, hcl.Diagnostics{unsupportedLiteralValue(x.Value, rng)}
  1344  	}
  1345  
  1346  	x.exprType = typ
  1347  	return diagnostics
  1348  }
  1349  
  1350  func (x *LiteralValueExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1351  	syntax := &hclsyntax.LiteralValueExpr{
  1352  		Val: x.Value,
  1353  	}
  1354  	return syntax.Value(context)
  1355  }
  1356  
  1357  func (x *LiteralValueExpression) HasLeadingTrivia() bool {
  1358  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1359  }
  1360  
  1361  func (x *LiteralValueExpression) HasTrailingTrivia() bool {
  1362  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1363  }
  1364  
  1365  func (x *LiteralValueExpression) GetLeadingTrivia() syntax.TriviaList {
  1366  	if v := x.Tokens.GetValue(x.Value); len(v) > 0 {
  1367  		return getExprLeadingTrivia(x.Tokens.GetParentheses(), v[0])
  1368  	}
  1369  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), nil)
  1370  }
  1371  
  1372  func (x *LiteralValueExpression) SetLeadingTrivia(t syntax.TriviaList) {
  1373  	if x.Tokens == nil {
  1374  		x.Tokens = syntax.NewLiteralValueTokens(x.Value)
  1375  	}
  1376  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Value[0], t)
  1377  }
  1378  
  1379  func (x *LiteralValueExpression) GetTrailingTrivia() syntax.TriviaList {
  1380  	if v := x.Tokens.GetValue(x.Value); len(v) > 0 {
  1381  		return getExprTrailingTrivia(x.Tokens.GetParentheses(), v[len(v)-1])
  1382  	}
  1383  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), nil)
  1384  }
  1385  
  1386  func (x *LiteralValueExpression) SetTrailingTrivia(t syntax.TriviaList) {
  1387  	if x.Tokens == nil {
  1388  		x.Tokens = syntax.NewLiteralValueTokens(x.Value)
  1389  	}
  1390  	setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.Value[len(x.Tokens.Value)-1], t)
  1391  }
  1392  
  1393  func (x *LiteralValueExpression) Format(f fmt.State, c rune) {
  1394  	x.print(f, &printer{})
  1395  }
  1396  
  1397  func (x *LiteralValueExpression) printLit(w io.Writer, p *printer, escaped bool) {
  1398  	// Literals are... odd. They may be composed of multiple tokens, but those tokens should never contain interior
  1399  	// trivia.
  1400  
  1401  	var leading, trailing syntax.TriviaList
  1402  	var rawBytes []byte
  1403  	if toks := x.Tokens.GetValue(x.Value); len(toks) > 0 {
  1404  		leading, trailing = toks[0].LeadingTrivia, toks[len(toks)-1].TrailingTrivia
  1405  
  1406  		for _, t := range toks {
  1407  			rawBytes = append(rawBytes, t.Raw.Bytes...)
  1408  		}
  1409  	}
  1410  
  1411  	p.fprintf(w, "%(%v%v%v%)",
  1412  		x.Tokens.GetParentheses(),
  1413  		leading, literalText(x.Value, rawBytes, escaped, false), trailing,
  1414  		x.Tokens.GetParentheses())
  1415  }
  1416  
  1417  func (x *LiteralValueExpression) print(w io.Writer, p *printer) {
  1418  	x.printLit(w, p, false)
  1419  }
  1420  
  1421  func (*LiteralValueExpression) isExpression() {}
  1422  
  1423  // ObjectConsItem records a key-value pair that is part of object construction expression.
  1424  type ObjectConsItem struct {
  1425  	// The key.
  1426  	Key Expression
  1427  	// The value.
  1428  	Value Expression
  1429  }
  1430  
  1431  // ObjectConsExpression represents a semantically-analyzed object construction expression.
  1432  type ObjectConsExpression struct {
  1433  	// The syntax node associated with the object construction expression.
  1434  	Syntax *hclsyntax.ObjectConsExpr
  1435  	// The tokens associated with the expression, if any.
  1436  	Tokens *syntax.ObjectConsTokens
  1437  
  1438  	// The items that comprise the object construction expression.
  1439  	Items []ObjectConsItem
  1440  
  1441  	exprType Type
  1442  }
  1443  
  1444  // SyntaxNode returns the syntax node associated with the object construction expression.
  1445  func (x *ObjectConsExpression) SyntaxNode() hclsyntax.Node {
  1446  	return x.Syntax
  1447  }
  1448  
  1449  // NodeTokens returns the tokens associated with the object construction expression.
  1450  func (x *ObjectConsExpression) NodeTokens() syntax.NodeTokens {
  1451  	return x.Tokens
  1452  }
  1453  
  1454  // Type returns the type of the object construction expression.
  1455  func (x *ObjectConsExpression) Type() Type {
  1456  	return x.exprType
  1457  }
  1458  
  1459  func (x *ObjectConsExpression) WithType(updateType func(Type) *ObjectConsExpression) *ObjectConsExpression {
  1460  	return updateType(x.exprType)
  1461  }
  1462  
  1463  func (x *ObjectConsExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  1464  	var diagnostics hcl.Diagnostics
  1465  
  1466  	var keys []Expression
  1467  	for _, item := range x.Items {
  1468  		if typecheckOperands {
  1469  			keyDiags := item.Key.Typecheck(true)
  1470  			diagnostics = append(diagnostics, keyDiags...)
  1471  
  1472  			valDiags := item.Value.Typecheck(true)
  1473  			diagnostics = append(diagnostics, valDiags...)
  1474  		}
  1475  
  1476  		keys = append(keys, item.Key)
  1477  		if !InputType(StringType).ConversionFrom(item.Key.Type()).Exists() {
  1478  			diagnostics = append(diagnostics, objectKeysMustBeStrings(item.Key))
  1479  		}
  1480  	}
  1481  
  1482  	// Attempt to build an object type out of the result. If there are any attribute names that come from variables,
  1483  	// type the result as map(unify(propertyTypes)).
  1484  	properties, isMapType, types := map[string]Type{}, false, []Type{}
  1485  	for _, item := range x.Items {
  1486  		types = append(types, item.Value.Type())
  1487  
  1488  		key := item.Key
  1489  		if template, ok := key.(*TemplateExpression); ok && len(template.Parts) == 1 {
  1490  			key = template.Parts[0]
  1491  		}
  1492  
  1493  		keyLit, ok := key.(*LiteralValueExpression)
  1494  		if ok {
  1495  			key, err := convert.Convert(keyLit.Value, cty.String)
  1496  			if err == nil {
  1497  				properties[key.AsString()] = item.Value.Type()
  1498  				continue
  1499  			}
  1500  		}
  1501  		isMapType = true
  1502  	}
  1503  	var typ Type
  1504  	if isMapType {
  1505  		elementType, _ := UnifyTypes(types...)
  1506  		typ = NewMapType(elementType)
  1507  	} else {
  1508  		typ = NewObjectType(properties)
  1509  	}
  1510  
  1511  	x.exprType = liftOperationType(typ, keys...)
  1512  	return diagnostics
  1513  }
  1514  
  1515  func (x *ObjectConsExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1516  	syntax := &hclsyntax.ObjectConsExpr{
  1517  		Items: make([]hclsyntax.ObjectConsItem, len(x.Items)),
  1518  	}
  1519  	for i, item := range x.Items {
  1520  		syntax.Items[i] = hclsyntax.ObjectConsItem{
  1521  			KeyExpr:   &syntaxExpr{expr: item.Key},
  1522  			ValueExpr: &syntaxExpr{expr: item.Value},
  1523  		}
  1524  	}
  1525  	return syntax.Value(context)
  1526  }
  1527  
  1528  func (x *ObjectConsExpression) HasLeadingTrivia() bool {
  1529  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1530  }
  1531  
  1532  func (x *ObjectConsExpression) HasTrailingTrivia() bool {
  1533  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1534  }
  1535  
  1536  func (x *ObjectConsExpression) GetLeadingTrivia() syntax.TriviaList {
  1537  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpenBrace(len(x.Items)))
  1538  }
  1539  
  1540  func (x *ObjectConsExpression) SetLeadingTrivia(t syntax.TriviaList) {
  1541  	if x.Tokens == nil {
  1542  		x.Tokens = syntax.NewObjectConsTokens(len(x.Items))
  1543  	}
  1544  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.OpenBrace, t)
  1545  }
  1546  
  1547  func (x *ObjectConsExpression) GetTrailingTrivia() syntax.TriviaList {
  1548  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseBrace())
  1549  }
  1550  
  1551  func (x *ObjectConsExpression) SetTrailingTrivia(t syntax.TriviaList) {
  1552  	if x.Tokens == nil {
  1553  		x.Tokens = syntax.NewObjectConsTokens(len(x.Items))
  1554  	}
  1555  	setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseBrace, t)
  1556  }
  1557  
  1558  func (x *ObjectConsExpression) Format(f fmt.State, c rune) {
  1559  	x.print(f, &printer{})
  1560  }
  1561  
  1562  func (x *ObjectConsExpression) print(w io.Writer, p *printer) {
  1563  	// Print the opening brace.
  1564  	p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetOpenBrace(len(x.Items)))
  1565  
  1566  	// Print the items.
  1567  	isMultiLine, trailingNewline := false, false
  1568  	p.indented(func() {
  1569  		items := x.Tokens.GetItems(len(x.Items))
  1570  		for i, item := range x.Items {
  1571  			tokens := syntax.NewObjectConsItemTokens(i == len(x.Items)-1)
  1572  			if i < len(items) {
  1573  				tokens = items[i]
  1574  			}
  1575  
  1576  			if item.Key.HasLeadingTrivia() {
  1577  				if _, i := item.Key.GetLeadingTrivia().Index("\n"); i != -1 {
  1578  					isMultiLine = true
  1579  				}
  1580  			} else if len(items) > 1 {
  1581  				isMultiLine = true
  1582  				p.fprintf(w, "\n%s", p.indent)
  1583  			}
  1584  			p.fprintf(w, "%v% v% v", item.Key, tokens.Equals, item.Value)
  1585  
  1586  			if tokens.Comma != nil {
  1587  				p.fprintf(w, "%v", tokens.Comma)
  1588  			}
  1589  
  1590  			if isMultiLine && i == len(items)-1 {
  1591  				trailingTrivia := item.Value.GetTrailingTrivia()
  1592  				if tokens.Comma != nil {
  1593  					trailingTrivia = tokens.Comma.TrailingTrivia
  1594  				}
  1595  				trailingNewline = trailingTrivia.EndsOnNewLine()
  1596  			}
  1597  		}
  1598  
  1599  		if len(x.Items) < len(items) {
  1600  			for _, item := range items[len(x.Items):] {
  1601  				p.fprintf(w, "%v", item.Equals.AllTrivia().CollapseWhitespace())
  1602  				if item.Comma != nil {
  1603  					p.fprintf(w, "%v", item.Comma.AllTrivia().CollapseWhitespace())
  1604  				}
  1605  			}
  1606  		}
  1607  	})
  1608  
  1609  	if x.Tokens != nil {
  1610  		pre := ""
  1611  		if isMultiLine && !trailingNewline {
  1612  			pre = "\n" + p.indent
  1613  		}
  1614  		p.fprintf(w, "%s%v%)", pre, x.Tokens.CloseBrace, x.Tokens.Parentheses)
  1615  	} else {
  1616  		p.fprintf(w, "\n%s}", p.indent)
  1617  	}
  1618  }
  1619  
  1620  func (*ObjectConsExpression) isExpression() {}
  1621  
  1622  func getTraverserTrivia(tokens syntax.TraverserTokens) (syntax.TriviaList, syntax.TriviaList) {
  1623  	var leading, trailing syntax.TriviaList
  1624  	switch tokens := tokens.(type) {
  1625  	case *syntax.DotTraverserTokens:
  1626  		leading = getExprLeadingTrivia(tokens.Parentheses, tokens.Dot)
  1627  		trailing = getExprTrailingTrivia(tokens.Parentheses, tokens.Index)
  1628  	case *syntax.BracketTraverserTokens:
  1629  		leading = getExprLeadingTrivia(tokens.Parentheses, tokens.OpenBracket)
  1630  		trailing = getExprTrailingTrivia(tokens.Parentheses, tokens.CloseBracket)
  1631  	}
  1632  	return leading, trailing
  1633  }
  1634  
  1635  func setTraverserTrailingTrivia(tokens syntax.TraverserTokens, t syntax.TriviaList) {
  1636  	switch tokens := tokens.(type) {
  1637  	case *syntax.DotTraverserTokens:
  1638  		setExprTrailingTrivia(tokens.Parentheses, &tokens.Index, t)
  1639  	case *syntax.BracketTraverserTokens:
  1640  		setExprTrailingTrivia(tokens.Parentheses, &tokens.CloseBracket, t)
  1641  	default:
  1642  		panic(fmt.Errorf("unexpected traverser of type %T", tokens))
  1643  	}
  1644  }
  1645  
  1646  func printTraverser(w io.Writer, p *printer, t hcl.Traverser, tokens syntax.TraverserTokens) {
  1647  	var index string
  1648  	switch t := t.(type) {
  1649  	case hcl.TraverseAttr:
  1650  		index = t.Name
  1651  	case hcl.TraverseIndex:
  1652  		index = literalText(t.Key, nil, true, true)
  1653  	default:
  1654  		panic(fmt.Errorf("unexpected traverser of type %T", t))
  1655  	}
  1656  
  1657  	switch tokens := tokens.(type) {
  1658  	case *syntax.DotTraverserTokens:
  1659  		p.fprintf(w, "%(%v%v%)",
  1660  			tokens.Parentheses,
  1661  			tokens.Dot, identToken(tokens.Index, index),
  1662  			tokens.Parentheses)
  1663  	case *syntax.BracketTraverserTokens:
  1664  		p.fprintf(w, "%(%v%v%v%)",
  1665  			tokens.Parentheses,
  1666  			tokens.OpenBracket, identToken(tokens.Index, index), tokens.CloseBracket,
  1667  			tokens.Parentheses)
  1668  	default:
  1669  		panic(fmt.Errorf("unexpected traverser tokens of type %T", tokens))
  1670  	}
  1671  }
  1672  
  1673  func printRelativeTraversal(w io.Writer, p *printer, traversal hcl.Traversal, tokens []syntax.TraverserTokens) {
  1674  	for i, traverser := range traversal {
  1675  		// Fetch the traversal tokens.
  1676  		var traverserTokens syntax.TraverserTokens
  1677  		if i < len(tokens) {
  1678  			traverserTokens = tokens[i]
  1679  		}
  1680  		printTraverser(w, p, traverser, traverserTokens)
  1681  	}
  1682  
  1683  	// Print any remaining trivia.
  1684  	if len(traversal) < len(tokens) {
  1685  		for _, tokens := range tokens[len(traversal):] {
  1686  			var trivia syntax.TriviaList
  1687  			switch tokens := tokens.(type) {
  1688  			case *syntax.DotTraverserTokens:
  1689  				trivia = tokens.Dot.LeadingTrivia
  1690  				trivia = append(trivia, tokens.Dot.TrailingTrivia...)
  1691  				trivia = append(trivia, tokens.Index.LeadingTrivia...)
  1692  				trivia = append(trivia, tokens.Index.TrailingTrivia...)
  1693  			case *syntax.BracketTraverserTokens:
  1694  				trivia = tokens.OpenBracket.LeadingTrivia
  1695  				trivia = append(trivia, tokens.OpenBracket.TrailingTrivia...)
  1696  				trivia = append(trivia, tokens.Index.LeadingTrivia...)
  1697  				trivia = append(trivia, tokens.Index.TrailingTrivia...)
  1698  				trivia = append(trivia, tokens.CloseBracket.LeadingTrivia...)
  1699  				trivia = append(trivia, tokens.CloseBracket.TrailingTrivia...)
  1700  			}
  1701  			p.fprintf(w, "%v", trivia)
  1702  		}
  1703  	}
  1704  }
  1705  
  1706  // RelativeTraversalExpression represents a semantically-analyzed relative traversal expression.
  1707  type RelativeTraversalExpression struct {
  1708  	// The syntax node associated with the relative traversal expression.
  1709  	Syntax *hclsyntax.RelativeTraversalExpr
  1710  	// The tokens associated with the expression, if any.
  1711  	Tokens *syntax.RelativeTraversalTokens
  1712  
  1713  	// The expression that computes the value being traversed.
  1714  	Source Expression
  1715  	// The traversal's parts.
  1716  	Parts []Traversable
  1717  
  1718  	// The traversers.
  1719  	Traversal hcl.Traversal
  1720  }
  1721  
  1722  // SyntaxNode returns the syntax node associated with the relative traversal expression.
  1723  func (x *RelativeTraversalExpression) SyntaxNode() hclsyntax.Node {
  1724  	return x.Syntax
  1725  }
  1726  
  1727  // NodeTokens returns the tokens associated with the relative traversal expression.
  1728  func (x *RelativeTraversalExpression) NodeTokens() syntax.NodeTokens {
  1729  	return x.Tokens
  1730  }
  1731  
  1732  // Type returns the type of the relative traversal expression.
  1733  func (x *RelativeTraversalExpression) Type() Type {
  1734  	return GetTraversableType(x.Parts[len(x.Parts)-1])
  1735  }
  1736  
  1737  func (x *RelativeTraversalExpression) typecheck(typecheckOperands, allowMissingVariables bool) hcl.Diagnostics {
  1738  	var diagnostics hcl.Diagnostics
  1739  
  1740  	if typecheckOperands {
  1741  		sourceDiags := x.Source.Typecheck(true)
  1742  		diagnostics = append(diagnostics, sourceDiags...)
  1743  	}
  1744  
  1745  	parts, partDiags := bindTraversalParts(x.Source.Type(), x.Traversal, allowMissingVariables)
  1746  	diagnostics = append(diagnostics, partDiags...)
  1747  
  1748  	x.Parts = parts
  1749  	return diagnostics
  1750  }
  1751  
  1752  func (x *RelativeTraversalExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  1753  	return x.typecheck(typecheckOperands, false)
  1754  }
  1755  
  1756  func (x *RelativeTraversalExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1757  	syntax := &hclsyntax.RelativeTraversalExpr{
  1758  		Source:    &syntaxExpr{expr: x.Source},
  1759  		Traversal: x.Traversal,
  1760  	}
  1761  	return syntax.Value(context)
  1762  }
  1763  
  1764  func (x *RelativeTraversalExpression) HasLeadingTrivia() bool {
  1765  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Source)
  1766  }
  1767  
  1768  func (x *RelativeTraversalExpression) HasTrailingTrivia() bool {
  1769  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  1770  		return true
  1771  	}
  1772  	if x.Tokens != nil && len(x.Tokens.Traversal) > 0 {
  1773  		return true
  1774  	}
  1775  	return x.Source.HasTrailingTrivia()
  1776  }
  1777  
  1778  func (x *RelativeTraversalExpression) GetLeadingTrivia() syntax.TriviaList {
  1779  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Source)
  1780  }
  1781  
  1782  func (x *RelativeTraversalExpression) SetLeadingTrivia(t syntax.TriviaList) {
  1783  	if x.Tokens == nil {
  1784  		x.Tokens = syntax.NewRelativeTraversalTokens(x.Traversal)
  1785  	}
  1786  	setExprLeadingTrivia(x.Tokens.Parentheses, x.Source, t)
  1787  }
  1788  
  1789  func (x *RelativeTraversalExpression) GetTrailingTrivia() syntax.TriviaList {
  1790  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  1791  		return parens.GetTrailingTrivia()
  1792  	}
  1793  	if traversal := x.Tokens.GetTraversal(x.Traversal); len(traversal) > 0 {
  1794  		_, trailingTrivia := getTraverserTrivia(traversal[len(traversal)-1])
  1795  		return trailingTrivia
  1796  	}
  1797  	return x.Source.GetTrailingTrivia()
  1798  }
  1799  
  1800  func (x *RelativeTraversalExpression) SetTrailingTrivia(t syntax.TriviaList) {
  1801  	if x.Tokens == nil {
  1802  		x.Tokens = syntax.NewRelativeTraversalTokens(x.Traversal)
  1803  	}
  1804  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  1805  		parens.SetTrailingTrivia(t)
  1806  		return
  1807  	}
  1808  	if len(x.Tokens.Traversal) > 0 {
  1809  		setTraverserTrailingTrivia(x.Tokens.Traversal[len(x.Tokens.Traversal)-1], t)
  1810  		return
  1811  	}
  1812  	x.Source.SetTrailingTrivia(t)
  1813  }
  1814  
  1815  func (x *RelativeTraversalExpression) Format(f fmt.State, c rune) {
  1816  	x.print(f, &printer{})
  1817  }
  1818  
  1819  func (x *RelativeTraversalExpression) print(w io.Writer, p *printer) {
  1820  	// Print the source expression.
  1821  	p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Source)
  1822  
  1823  	// Print the traversal.
  1824  	printRelativeTraversal(w, p, x.Traversal, x.Tokens.GetTraversal(x.Traversal))
  1825  
  1826  	// Print the closing parentheses, if any.
  1827  	p.fprintf(w, "%)", x.Tokens.GetParentheses())
  1828  }
  1829  
  1830  func (*RelativeTraversalExpression) isExpression() {}
  1831  
  1832  // ScopeTraversalExpression represents a semantically-analyzed scope traversal expression.
  1833  type ScopeTraversalExpression struct {
  1834  	// The syntax node associated with the scope traversal expression.
  1835  	Syntax *hclsyntax.ScopeTraversalExpr
  1836  	// The tokens associated with the expression, if any.
  1837  	Tokens *syntax.ScopeTraversalTokens
  1838  
  1839  	// The traversal's parts.
  1840  	Parts []Traversable
  1841  
  1842  	// The root name.
  1843  	RootName string
  1844  	// The traversers.
  1845  	Traversal hcl.Traversal
  1846  }
  1847  
  1848  // SyntaxNode returns the syntax node associated with the scope traversal expression.
  1849  func (x *ScopeTraversalExpression) SyntaxNode() hclsyntax.Node {
  1850  	return x.Syntax
  1851  }
  1852  
  1853  // NodeTokens returns the tokens associated with the scope traversal expression.
  1854  func (x *ScopeTraversalExpression) NodeTokens() syntax.NodeTokens {
  1855  	return x.Tokens
  1856  }
  1857  
  1858  // Type returns the type of the scope traversal expression.
  1859  func (x *ScopeTraversalExpression) Type() Type {
  1860  	return GetTraversableType(x.Parts[len(x.Parts)-1])
  1861  }
  1862  
  1863  func (x *ScopeTraversalExpression) typecheck(typecheckOperands, allowMissingVariables bool) hcl.Diagnostics {
  1864  	parts, diagnostics := bindTraversalParts(x.Parts[0], x.Traversal.SimpleSplit().Rel, allowMissingVariables)
  1865  	x.Parts = parts
  1866  
  1867  	return diagnostics
  1868  }
  1869  
  1870  func (x *ScopeTraversalExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  1871  	return x.typecheck(typecheckOperands, false)
  1872  }
  1873  
  1874  func (x *ScopeTraversalExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1875  	var diagnostics hcl.Diagnostics
  1876  
  1877  	root, hasValue := x.Parts[0].(ValueTraversable)
  1878  	if !hasValue {
  1879  		return cty.UnknownVal(cty.DynamicPseudoType), nil
  1880  	}
  1881  
  1882  	rootValue, diags := root.Value(context)
  1883  	if diags.HasErrors() {
  1884  		return cty.NilVal, diags
  1885  	}
  1886  	diagnostics = append(diagnostics, diags...)
  1887  
  1888  	if len(x.Traversal) == 1 {
  1889  		return rootValue, diagnostics
  1890  	}
  1891  	return x.Traversal[1:].TraverseRel(rootValue)
  1892  }
  1893  
  1894  func (x *ScopeTraversalExpression) HasLeadingTrivia() bool {
  1895  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  1896  }
  1897  
  1898  func (x *ScopeTraversalExpression) HasTrailingTrivia() bool {
  1899  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  1900  		return true
  1901  	}
  1902  	if x.Tokens != nil && len(x.Tokens.Traversal) > 0 {
  1903  		return true
  1904  	}
  1905  	return x.Tokens != nil
  1906  }
  1907  
  1908  func (x *ScopeTraversalExpression) GetLeadingTrivia() syntax.TriviaList {
  1909  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetRoot(x.Traversal))
  1910  }
  1911  
  1912  func (x *ScopeTraversalExpression) SetLeadingTrivia(t syntax.TriviaList) {
  1913  	if x.Tokens == nil {
  1914  		x.Tokens = syntax.NewScopeTraversalTokens(x.Traversal)
  1915  	}
  1916  	x.Tokens.Root.LeadingTrivia = t
  1917  }
  1918  
  1919  func (x *ScopeTraversalExpression) GetTrailingTrivia() syntax.TriviaList {
  1920  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  1921  		return parens.GetTrailingTrivia()
  1922  	}
  1923  	if traversal := x.Tokens.GetTraversal(x.Traversal); len(traversal) > 0 {
  1924  		_, trailingTrivia := getTraverserTrivia(traversal[len(traversal)-1])
  1925  		return trailingTrivia
  1926  	}
  1927  	return x.Tokens.GetRoot(x.Traversal).TrailingTrivia
  1928  }
  1929  
  1930  func (x *ScopeTraversalExpression) SetTrailingTrivia(t syntax.TriviaList) {
  1931  	if x.Tokens == nil {
  1932  		x.Tokens = syntax.NewScopeTraversalTokens(x.Traversal)
  1933  	}
  1934  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  1935  		parens.SetTrailingTrivia(t)
  1936  		return
  1937  	}
  1938  	if len(x.Tokens.Traversal) > 0 {
  1939  		setTraverserTrailingTrivia(x.Tokens.Traversal[len(x.Tokens.Traversal)-1], t)
  1940  		return
  1941  	}
  1942  	x.Tokens.Root.TrailingTrivia = t
  1943  }
  1944  
  1945  func (x *ScopeTraversalExpression) Format(f fmt.State, c rune) {
  1946  	x.print(f, &printer{})
  1947  }
  1948  
  1949  func (x *ScopeTraversalExpression) print(w io.Writer, p *printer) {
  1950  	// Print the root name.
  1951  	p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetRoot(x.Traversal))
  1952  
  1953  	// Print the traversal.
  1954  	printRelativeTraversal(w, p, x.Traversal[1:], x.Tokens.GetTraversal(x.Traversal))
  1955  
  1956  	// Print the closing parentheses, if any.
  1957  	p.fprintf(w, "%)", x.Tokens.GetParentheses())
  1958  }
  1959  
  1960  func (*ScopeTraversalExpression) isExpression() {}
  1961  
  1962  type SplatVariable struct {
  1963  	Variable
  1964  
  1965  	symbol hclsyntax.AnonSymbolExpr
  1966  }
  1967  
  1968  func (v *SplatVariable) Value(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  1969  	return (&v.symbol).Value(context)
  1970  }
  1971  
  1972  // SplatExpression represents a semantically-analyzed splat expression.
  1973  type SplatExpression struct {
  1974  	// The syntax node associated with the splat expression.
  1975  	Syntax *hclsyntax.SplatExpr
  1976  	// The tokens associated with the expression, if any.
  1977  	Tokens *syntax.SplatTokens
  1978  
  1979  	// The expression being splatted.
  1980  	Source Expression
  1981  	// The expression applied to each element of the splat.
  1982  	Each Expression
  1983  	// The local variable definition associated with the current item being processed. This definition is not part of
  1984  	// a scope, and can only be referenced by an AnonSymbolExpr.
  1985  	Item *SplatVariable
  1986  
  1987  	exprType Type
  1988  }
  1989  
  1990  // SyntaxNode returns the syntax node associated with the splat expression.
  1991  func (x *SplatExpression) SyntaxNode() hclsyntax.Node {
  1992  	return x.Syntax
  1993  }
  1994  
  1995  // NodeTokens returns the tokens associated with the splat expression.
  1996  func (x *SplatExpression) NodeTokens() syntax.NodeTokens {
  1997  	return x.Tokens
  1998  }
  1999  
  2000  // Type returns the type of the splat expression.
  2001  func (x *SplatExpression) Type() Type {
  2002  	return x.exprType
  2003  }
  2004  
  2005  func splatItemType(source Expression, splatSyntax *hclsyntax.SplatExpr) (Expression, Type) {
  2006  	sourceType := unwrapIterableSourceType(source.Type())
  2007  	itemType := sourceType
  2008  	switch sourceType := sourceType.(type) {
  2009  	case *ListType:
  2010  		itemType = sourceType.ElementType
  2011  	case *SetType:
  2012  		itemType = sourceType.ElementType
  2013  	case *TupleType:
  2014  		itemType, _ = UnifyTypes(sourceType.ElementTypes...)
  2015  	default:
  2016  		if sourceType != DynamicType {
  2017  			var tupleSyntax *hclsyntax.TupleConsExpr
  2018  			if splatSyntax != nil {
  2019  				tupleSyntax = &hclsyntax.TupleConsExpr{
  2020  					Exprs:     []hclsyntax.Expression{splatSyntax.Source},
  2021  					SrcRange:  splatSyntax.Source.Range(),
  2022  					OpenRange: splatSyntax.Source.StartRange(),
  2023  				}
  2024  			}
  2025  
  2026  			source = &TupleConsExpression{
  2027  				Syntax:      tupleSyntax,
  2028  				Tokens:      syntax.NewTupleConsTokens(1),
  2029  				Expressions: []Expression{source},
  2030  				exprType:    NewListType(source.Type()),
  2031  			}
  2032  		}
  2033  	}
  2034  	return source, itemType
  2035  }
  2036  
  2037  func (x *SplatExpression) typecheck(retypeItem, typecheckOperands bool) hcl.Diagnostics {
  2038  	var diagnostics hcl.Diagnostics
  2039  
  2040  	if typecheckOperands {
  2041  		sourceDiags := x.Source.Typecheck(true)
  2042  		diagnostics = append(diagnostics, sourceDiags...)
  2043  	}
  2044  
  2045  	if retypeItem {
  2046  		x.Source, x.Item.VariableType = splatItemType(x.Source, x.Syntax)
  2047  	}
  2048  
  2049  	if typecheckOperands {
  2050  		eachDiags := x.Each.Typecheck(true)
  2051  		diagnostics = append(diagnostics, eachDiags...)
  2052  	}
  2053  
  2054  	x.exprType = wrapIterableResultType(x.Source.Type(), NewListType(x.Each.Type()))
  2055  
  2056  	return diagnostics
  2057  }
  2058  
  2059  func (x *SplatExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  2060  	return x.typecheck(true, typecheckOperands)
  2061  }
  2062  
  2063  func (x *SplatExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  2064  	syntax := &hclsyntax.SplatExpr{
  2065  		Source: &syntaxExpr{expr: x.Source},
  2066  		Each:   &syntaxExpr{expr: x.Each},
  2067  		Item:   &x.Item.symbol,
  2068  	}
  2069  	return syntax.Value(context)
  2070  }
  2071  
  2072  func (x *SplatExpression) HasLeadingTrivia() bool {
  2073  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Source)
  2074  }
  2075  
  2076  func (x *SplatExpression) HasTrailingTrivia() bool {
  2077  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Each)
  2078  }
  2079  
  2080  func (x *SplatExpression) GetLeadingTrivia() syntax.TriviaList {
  2081  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Source)
  2082  }
  2083  
  2084  func (x *SplatExpression) SetLeadingTrivia(t syntax.TriviaList) {
  2085  	if x.Tokens == nil {
  2086  		x.Tokens = syntax.NewSplatTokens(false)
  2087  	}
  2088  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Open, t)
  2089  }
  2090  
  2091  func (x *SplatExpression) GetTrailingTrivia() syntax.TriviaList {
  2092  	if parens := x.Tokens.GetParentheses(); parens.Any() {
  2093  		return parens.GetTrailingTrivia()
  2094  	}
  2095  	if close := x.Tokens.GetClose(); close != nil {
  2096  		return close.TrailingTrivia
  2097  	}
  2098  	return x.Tokens.GetStar().TrailingTrivia
  2099  }
  2100  
  2101  func (x *SplatExpression) SetTrailingTrivia(t syntax.TriviaList) {
  2102  	if x.Tokens == nil {
  2103  		x.Tokens = syntax.NewSplatTokens(false)
  2104  	}
  2105  	if x.Tokens.Parentheses.Any() {
  2106  		x.Tokens.Parentheses.SetTrailingTrivia(t)
  2107  		return
  2108  	}
  2109  	if x.Tokens.Close == nil {
  2110  		x.Tokens.Star.TrailingTrivia = t
  2111  		return
  2112  	}
  2113  	x.Tokens.Close.TrailingTrivia = t
  2114  }
  2115  
  2116  func (x *SplatExpression) Format(f fmt.State, c rune) {
  2117  	x.print(f, &printer{})
  2118  }
  2119  
  2120  func (x *SplatExpression) print(w io.Writer, p *printer) {
  2121  	isDot := x.Tokens.GetClose() == nil
  2122  
  2123  	p.fprintf(w, "%(%v%v%v", x.Tokens.GetParentheses(), x.Source, x.Tokens.GetOpen(), x.Tokens.GetStar())
  2124  	if !isDot {
  2125  		p.fprintf(w, "%v", x.Tokens.GetClose())
  2126  	}
  2127  	p.fprintf(w, "%v%)", x.Each, x.Tokens.GetParentheses())
  2128  }
  2129  
  2130  func (*SplatExpression) isExpression() {}
  2131  
  2132  // TemplateExpression represents a semantically-analyzed template expression.
  2133  type TemplateExpression struct {
  2134  	// The syntax node associated with the template expression.
  2135  	Syntax *hclsyntax.TemplateExpr
  2136  	// The tokens associated with the expression, if any.
  2137  	Tokens *syntax.TemplateTokens
  2138  
  2139  	// The parts of the template expression.
  2140  	Parts []Expression
  2141  
  2142  	exprType Type
  2143  }
  2144  
  2145  // SyntaxNode returns the syntax node associated with the template expression.
  2146  func (x *TemplateExpression) SyntaxNode() hclsyntax.Node {
  2147  	return x.Syntax
  2148  }
  2149  
  2150  // NodeTokens returns the tokens associated with the template expression.
  2151  func (x *TemplateExpression) NodeTokens() syntax.NodeTokens {
  2152  	return x.Tokens
  2153  }
  2154  
  2155  // Type returns the type of the template expression.
  2156  func (x *TemplateExpression) Type() Type {
  2157  	return x.exprType
  2158  }
  2159  
  2160  func (x *TemplateExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  2161  	var diagnostics hcl.Diagnostics
  2162  
  2163  	if typecheckOperands {
  2164  		for _, part := range x.Parts {
  2165  			partDiags := part.Typecheck(true)
  2166  			diagnostics = append(diagnostics, partDiags...)
  2167  		}
  2168  	}
  2169  
  2170  	x.exprType = liftOperationType(StringType, x.Parts...)
  2171  	return diagnostics
  2172  }
  2173  
  2174  func (x *TemplateExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  2175  	syntax := &hclsyntax.TemplateExpr{
  2176  		Parts: make([]hclsyntax.Expression, len(x.Parts)),
  2177  	}
  2178  	for i, p := range x.Parts {
  2179  		syntax.Parts[i] = &syntaxExpr{expr: p}
  2180  	}
  2181  	return syntax.Value(context)
  2182  }
  2183  
  2184  func (x *TemplateExpression) HasLeadingTrivia() bool {
  2185  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  2186  }
  2187  
  2188  func (x *TemplateExpression) HasTrailingTrivia() bool {
  2189  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  2190  }
  2191  
  2192  func (x *TemplateExpression) GetLeadingTrivia() syntax.TriviaList {
  2193  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpen())
  2194  }
  2195  
  2196  func (x *TemplateExpression) SetLeadingTrivia(t syntax.TriviaList) {
  2197  	if x.Tokens == nil {
  2198  		x.Tokens = syntax.NewTemplateTokens()
  2199  	}
  2200  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Open, t)
  2201  }
  2202  
  2203  func (x *TemplateExpression) GetTrailingTrivia() syntax.TriviaList {
  2204  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetClose())
  2205  }
  2206  
  2207  func (x *TemplateExpression) SetTrailingTrivia(t syntax.TriviaList) {
  2208  	if x.Tokens == nil {
  2209  		x.Tokens = syntax.NewTemplateTokens()
  2210  	}
  2211  	setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.Close, t)
  2212  }
  2213  
  2214  func (x *TemplateExpression) Format(f fmt.State, c rune) {
  2215  	x.print(f, &printer{})
  2216  }
  2217  
  2218  func (x *TemplateExpression) print(w io.Writer, p *printer) {
  2219  	// Print the opening quote.
  2220  	p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetOpen())
  2221  
  2222  	isHeredoc := x.Tokens.GetOpen().Raw.Type == hclsyntax.TokenOHeredoc
  2223  
  2224  	// Print the expressions.
  2225  	for _, part := range x.Parts {
  2226  		if lit, ok := part.(*LiteralValueExpression); ok && StringType.AssignableFrom(lit.Type()) {
  2227  			lit.printLit(w, p, !isHeredoc)
  2228  		} else {
  2229  			p.fprintf(w, "%v", part)
  2230  		}
  2231  	}
  2232  
  2233  	// Print the closing quote
  2234  	p.fprintf(w, "%v%)", x.Tokens.GetClose(), x.Tokens.GetParentheses())
  2235  }
  2236  
  2237  func (*TemplateExpression) isExpression() {}
  2238  
  2239  // TemplateJoinExpression represents a semantically-analyzed template join expression.
  2240  type TemplateJoinExpression struct {
  2241  	// The syntax node associated with the template join expression.
  2242  	Syntax *hclsyntax.TemplateJoinExpr
  2243  
  2244  	// The tuple being joined.
  2245  	Tuple Expression
  2246  
  2247  	exprType Type
  2248  }
  2249  
  2250  // SyntaxNode returns the syntax node associated with the template join expression.
  2251  func (x *TemplateJoinExpression) SyntaxNode() hclsyntax.Node {
  2252  	return x.Syntax
  2253  }
  2254  
  2255  // NodeTokens returns the tokens associated with the template join expression.
  2256  func (x *TemplateJoinExpression) NodeTokens() syntax.NodeTokens {
  2257  	return nil
  2258  }
  2259  
  2260  // Type returns the type of the template join expression.
  2261  func (x *TemplateJoinExpression) Type() Type {
  2262  	return x.exprType
  2263  }
  2264  
  2265  func (x *TemplateJoinExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  2266  	var diagnostics hcl.Diagnostics
  2267  
  2268  	if typecheckOperands {
  2269  		tupleDiags := x.Tuple.Typecheck(true)
  2270  		diagnostics = append(diagnostics, tupleDiags...)
  2271  	}
  2272  
  2273  	x.exprType = liftOperationType(StringType, x.Tuple)
  2274  	return diagnostics
  2275  }
  2276  
  2277  func (x *TemplateJoinExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  2278  	syntax := &hclsyntax.TemplateJoinExpr{
  2279  		Tuple: &syntaxExpr{expr: x.Tuple},
  2280  	}
  2281  	return syntax.Value(context)
  2282  }
  2283  
  2284  func (x *TemplateJoinExpression) HasLeadingTrivia() bool {
  2285  	return x.Tuple.HasLeadingTrivia()
  2286  }
  2287  
  2288  func (x *TemplateJoinExpression) HasTrailingTrivia() bool {
  2289  	return x.Tuple.HasTrailingTrivia()
  2290  }
  2291  
  2292  func (x *TemplateJoinExpression) GetLeadingTrivia() syntax.TriviaList {
  2293  	return x.Tuple.GetLeadingTrivia()
  2294  }
  2295  
  2296  func (x *TemplateJoinExpression) SetLeadingTrivia(t syntax.TriviaList) {
  2297  	x.Tuple.SetLeadingTrivia(t)
  2298  }
  2299  
  2300  func (x *TemplateJoinExpression) GetTrailingTrivia() syntax.TriviaList {
  2301  	return x.Tuple.GetTrailingTrivia()
  2302  }
  2303  
  2304  func (x *TemplateJoinExpression) SetTrailingTrivia(t syntax.TriviaList) {
  2305  	x.Tuple.SetTrailingTrivia(t)
  2306  }
  2307  
  2308  func (x *TemplateJoinExpression) Format(f fmt.State, c rune) {
  2309  	x.print(f, &printer{})
  2310  }
  2311  
  2312  func (x *TemplateJoinExpression) print(w io.Writer, p *printer) {
  2313  	p.fprintf(w, "%v", x.Tuple)
  2314  }
  2315  
  2316  func (*TemplateJoinExpression) isExpression() {}
  2317  
  2318  // TupleConsExpression represents a semantically-analyzed tuple construction expression.
  2319  type TupleConsExpression struct {
  2320  	// The syntax node associated with the tuple construction expression.
  2321  	Syntax *hclsyntax.TupleConsExpr
  2322  	// The tokens associated with the expression, if any.
  2323  	Tokens *syntax.TupleConsTokens
  2324  
  2325  	// The elements of the tuple.
  2326  	Expressions []Expression
  2327  
  2328  	exprType Type
  2329  }
  2330  
  2331  // SyntaxNode returns the syntax node associated with the tuple construction expression.
  2332  func (x *TupleConsExpression) SyntaxNode() hclsyntax.Node {
  2333  	return x.Syntax
  2334  }
  2335  
  2336  // NodeTokens returns the tokens associated with the tuple construction expression.
  2337  func (x *TupleConsExpression) NodeTokens() syntax.NodeTokens {
  2338  	return x.Tokens
  2339  }
  2340  
  2341  // Type returns the type of the tuple construction expression.
  2342  func (x *TupleConsExpression) Type() Type {
  2343  	return x.exprType
  2344  }
  2345  
  2346  func (x *TupleConsExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  2347  	var diagnostics hcl.Diagnostics
  2348  
  2349  	elementTypes := make([]Type, len(x.Expressions))
  2350  	for i, expr := range x.Expressions {
  2351  		if typecheckOperands {
  2352  			exprDiags := expr.Typecheck(true)
  2353  			diagnostics = append(diagnostics, exprDiags...)
  2354  		}
  2355  
  2356  		elementTypes[i] = expr.Type()
  2357  	}
  2358  
  2359  	x.exprType = NewTupleType(elementTypes...)
  2360  	return diagnostics
  2361  }
  2362  
  2363  func (x *TupleConsExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  2364  	syntax := &hclsyntax.TupleConsExpr{
  2365  		Exprs: make([]hclsyntax.Expression, len(x.Expressions)),
  2366  	}
  2367  	for i, x := range x.Expressions {
  2368  		syntax.Exprs[i] = &syntaxExpr{expr: x}
  2369  	}
  2370  	return syntax.Value(context)
  2371  }
  2372  
  2373  func (x *TupleConsExpression) HasLeadingTrivia() bool {
  2374  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  2375  }
  2376  
  2377  func (x *TupleConsExpression) HasTrailingTrivia() bool {
  2378  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  2379  }
  2380  
  2381  func (x *TupleConsExpression) GetLeadingTrivia() syntax.TriviaList {
  2382  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpenBracket())
  2383  }
  2384  
  2385  func (x *TupleConsExpression) SetLeadingTrivia(t syntax.TriviaList) {
  2386  	if x.Tokens == nil {
  2387  		x.Tokens = syntax.NewTupleConsTokens(len(x.Expressions))
  2388  	}
  2389  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.OpenBracket, t)
  2390  }
  2391  
  2392  func (x *TupleConsExpression) GetTrailingTrivia() syntax.TriviaList {
  2393  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseBracket())
  2394  }
  2395  
  2396  func (x *TupleConsExpression) SetTrailingTrivia(t syntax.TriviaList) {
  2397  	if x.Tokens == nil {
  2398  		x.Tokens = syntax.NewTupleConsTokens(len(x.Expressions))
  2399  	}
  2400  	setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseBracket, t)
  2401  }
  2402  
  2403  func (x *TupleConsExpression) Format(f fmt.State, c rune) {
  2404  	x.print(f, &printer{})
  2405  }
  2406  
  2407  func (x *TupleConsExpression) print(w io.Writer, p *printer) {
  2408  	// Print the opening bracket.
  2409  	p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetOpenBracket())
  2410  
  2411  	// Print each element and its comma.
  2412  	commas := x.Tokens.GetCommas(len(x.Expressions))
  2413  	p.indented(func() {
  2414  		for i, expr := range x.Expressions {
  2415  			if !expr.HasLeadingTrivia() {
  2416  				p.fprintf(w, "\n%s", p.indent)
  2417  			}
  2418  			p.fprintf(w, "%v", expr)
  2419  
  2420  			if i != len(x.Expressions)-1 {
  2421  				var comma syntax.Token
  2422  				if i < len(commas) {
  2423  					comma = commas[i]
  2424  				}
  2425  				p.fprintf(w, "%v", comma)
  2426  			}
  2427  		}
  2428  
  2429  		// If there were commas left over, print the trivia for each.
  2430  		//
  2431  		// TODO(pdg): filter to only comments?
  2432  		if len(x.Expressions) > 0 && len(x.Expressions)-1 <= len(commas) {
  2433  			for _, comma := range commas[len(x.Expressions)-1:] {
  2434  				p.fprintf(w, "%v", comma.AllTrivia().CollapseWhitespace())
  2435  			}
  2436  		}
  2437  	})
  2438  
  2439  	// Print the closing bracket.
  2440  	if x.Tokens != nil {
  2441  		p.fprintf(w, "%v%)", x.Tokens.CloseBracket, x.Tokens.GetParentheses())
  2442  	} else {
  2443  		p.fprintf(w, "\n%s]", p.indent)
  2444  	}
  2445  }
  2446  
  2447  func (*TupleConsExpression) isExpression() {}
  2448  
  2449  // UnaryOpExpression represents a semantically-analyzed unary operation.
  2450  type UnaryOpExpression struct {
  2451  	// The syntax node associated with the unary operation.
  2452  	Syntax *hclsyntax.UnaryOpExpr
  2453  	// The tokens associated with the expression, if any.
  2454  	Tokens *syntax.UnaryOpTokens
  2455  
  2456  	// The operation.
  2457  	Operation *hclsyntax.Operation
  2458  	// The operand of the operation.
  2459  	Operand Expression
  2460  
  2461  	operandType Type
  2462  	exprType    Type
  2463  }
  2464  
  2465  // SyntaxNode returns the syntax node associated with the unary operation.
  2466  func (x *UnaryOpExpression) SyntaxNode() hclsyntax.Node {
  2467  	return x.Syntax
  2468  }
  2469  
  2470  // NodeTokens returns the tokens associated with the unary operation.
  2471  func (x *UnaryOpExpression) NodeTokens() syntax.NodeTokens {
  2472  	return x.Tokens
  2473  }
  2474  
  2475  // OperandType returns the operand type of the unary operation.
  2476  func (x *UnaryOpExpression) OperandType() Type {
  2477  	return x.operandType
  2478  }
  2479  
  2480  // Type returns the type of the unary operation.
  2481  func (x *UnaryOpExpression) Type() Type {
  2482  	return x.exprType
  2483  }
  2484  
  2485  func (x *UnaryOpExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics {
  2486  	var diagnostics hcl.Diagnostics
  2487  
  2488  	if typecheckOperands {
  2489  		operandDiags := x.Operand.Typecheck(true)
  2490  		diagnostics = append(diagnostics, operandDiags...)
  2491  	}
  2492  
  2493  	// Compute the signature for the operator and typecheck the arguments.
  2494  	signature := getOperationSignature(x.Operation)
  2495  	contract.Assert(len(signature.Parameters) == 1)
  2496  
  2497  	x.operandType = signature.Parameters[0].Type
  2498  
  2499  	var rng hcl.Range
  2500  	if x.Syntax != nil {
  2501  		rng = x.Syntax.Range()
  2502  	}
  2503  	typecheckDiags := typecheckArgs(rng, signature, x.Operand)
  2504  	diagnostics = append(diagnostics, typecheckDiags...)
  2505  
  2506  	x.exprType = liftOperationType(signature.ReturnType, x.Operand)
  2507  	return diagnostics
  2508  }
  2509  
  2510  func (x *UnaryOpExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
  2511  	syntax := &hclsyntax.UnaryOpExpr{
  2512  		Op:  x.Operation,
  2513  		Val: &syntaxExpr{expr: x.Operand},
  2514  	}
  2515  	return syntax.Value(context)
  2516  }
  2517  
  2518  func (x *UnaryOpExpression) HasLeadingTrivia() bool {
  2519  	return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil)
  2520  }
  2521  
  2522  func (x *UnaryOpExpression) HasTrailingTrivia() bool {
  2523  	return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Operand)
  2524  }
  2525  
  2526  func (x *UnaryOpExpression) GetLeadingTrivia() syntax.TriviaList {
  2527  	return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOperator(x.Operation))
  2528  }
  2529  
  2530  func (x *UnaryOpExpression) SetLeadingTrivia(t syntax.TriviaList) {
  2531  	if x.Tokens == nil {
  2532  		x.Tokens = syntax.NewUnaryOpTokens(x.Operation)
  2533  	}
  2534  	setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Operator, t)
  2535  }
  2536  
  2537  func (x *UnaryOpExpression) GetTrailingTrivia() syntax.TriviaList {
  2538  	return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Operand)
  2539  }
  2540  
  2541  func (x *UnaryOpExpression) SetTrailingTrivia(t syntax.TriviaList) {
  2542  	if x.Tokens == nil {
  2543  		x.Tokens = syntax.NewUnaryOpTokens(x.Operation)
  2544  	}
  2545  	setExprTrailingTrivia(x.Tokens.Parentheses, x.Operand, t)
  2546  }
  2547  
  2548  func (x *UnaryOpExpression) Format(f fmt.State, c rune) {
  2549  	x.print(f, &printer{})
  2550  }
  2551  
  2552  func (x *UnaryOpExpression) print(w io.Writer, p *printer) {
  2553  	precedence := operatorPrecedence(x.Operation)
  2554  	p.fprintf(w, "%[2](%[3]v%.[1]*[4]v%[5])",
  2555  		precedence,
  2556  		x.Tokens.GetParentheses(),
  2557  		x.Tokens.GetOperator(x.Operation), x.Operand,
  2558  		x.Tokens.GetParentheses())
  2559  }
  2560  
  2561  func (*UnaryOpExpression) isExpression() {}