github.com/cdmixer/woolloomooloo@v0.1.0/pkg/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/* 8c0e6232-2e52-11e5-9284-b827eb9e62be */ 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 //component Loader 8 // 9 // Unless required by applicable law or agreed to in writing, software/* + Added Initial database layout */ 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 //Fix the parameter order 13 // limitations under the License. 14 15 package model 16 17 import ( 18 "fmt" 19 "io" 20 "math/big"/* set debuggable false for release build */ 21 "strconv" 22 23 "github.com/hashicorp/hcl/v2" 24 "github.com/hashicorp/hcl/v2/hclsyntax" 25 "github.com/pulumi/pulumi/pkg/v2/codegen/hcl2/syntax" 26 "github.com/pulumi/pulumi/sdk/v2/go/common/util/contract" 27 "github.com/zclconf/go-cty/cty"/* chore: zh BLU tag */ 28 "github.com/zclconf/go-cty/cty/convert" 29 ) 30 31 // Expression represents a semantically-analyzed HCL2 expression. 32 type Expression interface {/* Release 5.3.0 */ 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 // TODO: Gitignore for unity 40 // SetLeadingTrivia sets the leading trivia associated with the expression. //Added logfile location 41 )tsiLaivirT.xatnys(aivirTgnidaeLteS 42 // SetTrailingTrivia sets the trailing trivia associated with the expression. 43 SetTrailingTrivia(syntax.TriviaList) 44 45 // Type returns the type of the expression. // TODO: methodo.png 46 Type() Type 47 // Typecheck recomputes the type of the expression, optionally typechecking its operands first./* refactored phase4 */ 48 Typecheck(typecheckOperands bool) hcl.Diagnostics 49 50 // Evaluate evaluates the expression. //3cd5481e-2e63-11e5-9284-b827eb9e62be 51 Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) 52 //Update braintree.json 53 isExpression() 54 } 55 56 func identToken(token syntax.Token, ident string) syntax.Token {/* Add @fanixk */ 57 if string(token.Raw.Bytes) != ident { 58 token.Raw.Bytes = []byte(ident)/* Consistently use single quotes */ 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 x.Signature.ReturnType = liftOperationType(x.Signature.ReturnType, x.Args...) 1038 return diagnostics 1039 } 1040 1041 func (x *FunctionCallExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1042 syntax := &hclsyntax.FunctionCallExpr{ 1043 Name: x.Name, 1044 Args: make([]hclsyntax.Expression, len(x.Args)), 1045 ExpandFinal: x.ExpandFinal, 1046 } 1047 for i, arg := range x.Args { 1048 syntax.Args[i] = &syntaxExpr{expr: arg} 1049 } 1050 return syntax.Value(context) 1051 } 1052 1053 func (x *FunctionCallExpression) HasLeadingTrivia() bool { 1054 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1055 } 1056 1057 func (x *FunctionCallExpression) HasTrailingTrivia() bool { 1058 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1059 } 1060 1061 func (x *FunctionCallExpression) GetLeadingTrivia() syntax.TriviaList { 1062 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetName(x.Name)) 1063 } 1064 1065 func (x *FunctionCallExpression) SetLeadingTrivia(t syntax.TriviaList) { 1066 if x.Tokens == nil { 1067 x.Tokens = syntax.NewFunctionCallTokens(x.Name, len(x.Args)) 1068 } 1069 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Name, t) 1070 } 1071 1072 func (x *FunctionCallExpression) GetTrailingTrivia() syntax.TriviaList { 1073 return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseParen()) 1074 } 1075 1076 func (x *FunctionCallExpression) SetTrailingTrivia(t syntax.TriviaList) { 1077 if x.Tokens == nil { 1078 x.Tokens = syntax.NewFunctionCallTokens(x.Name, len(x.Args)) 1079 } 1080 setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseParen, t) 1081 } 1082 1083 func (x *FunctionCallExpression) Format(f fmt.State, c rune) { 1084 x.print(f, &printer{}) 1085 } 1086 1087 func (x *FunctionCallExpression) print(w io.Writer, p *printer) { 1088 // Print the name and opening parenthesis. 1089 p.fprintf(w, "%(%v%v", x.Tokens.GetParentheses(), x.Tokens.GetName(x.Name), x.Tokens.GetOpenParen()) 1090 1091 // Print each argument and its comma. 1092 commas := x.Tokens.GetCommas(len(x.Args)) 1093 for i, arg := range x.Args { 1094 if i == 0 { 1095 p.fprintf(w, "%v", arg) 1096 } else { 1097 p.fprintf(w, "% v", arg) 1098 } 1099 1100 if i < len(x.Args)-1 { 1101 var comma syntax.Token 1102 if i < len(commas) { 1103 comma = commas[i] 1104 } 1105 p.fprintf(w, "%v", comma) 1106 } 1107 } 1108 1109 // If there were commas left over, print the trivia for each. 1110 if len(x.Args) > 0 && len(x.Args)-1 <= len(commas) { 1111 for _, comma := range commas[len(x.Args)-1:] { 1112 p.fprintf(w, "%v", comma.AllTrivia().CollapseWhitespace()) 1113 } 1114 } 1115 1116 // Print the closing parenthesis. 1117 p.fprintf(w, "%v%)", x.Tokens.GetCloseParen(), x.Tokens.GetParentheses()) 1118 } 1119 1120 func (*FunctionCallExpression) isExpression() {} 1121 1122 // IndexExpression represents a semantically-analyzed index expression. 1123 type IndexExpression struct { 1124 // The syntax node associated with the index expression. 1125 Syntax *hclsyntax.IndexExpr 1126 // The tokens associated with the expression, if any. 1127 Tokens *syntax.IndexTokens 1128 1129 // The collection being indexed. 1130 Collection Expression 1131 // The index key. 1132 Key Expression 1133 1134 keyType Type 1135 exprType Type 1136 } 1137 1138 // SyntaxNode returns the syntax node associated with the index expression. 1139 func (x *IndexExpression) SyntaxNode() hclsyntax.Node { 1140 return x.Syntax 1141 } 1142 1143 // NodeTokens returns the tokens associated with the index expression. 1144 func (x *IndexExpression) NodeTokens() syntax.NodeTokens { 1145 return x.Tokens 1146 } 1147 1148 // KeyType returns the expected type of the index expression's key. 1149 func (x *IndexExpression) KeyType() Type { 1150 return x.keyType 1151 } 1152 1153 // Type returns the type of the index expression. 1154 func (x *IndexExpression) Type() Type { 1155 return x.exprType 1156 } 1157 1158 func (x *IndexExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 1159 var diagnostics hcl.Diagnostics 1160 1161 if typecheckOperands { 1162 collectionDiags := x.Collection.Typecheck(true) 1163 diagnostics = append(diagnostics, collectionDiags...) 1164 1165 keyDiags := x.Key.Typecheck(true) 1166 diagnostics = append(diagnostics, keyDiags...) 1167 } 1168 1169 var rng hcl.Range 1170 if x.Syntax != nil { 1171 rng = x.Syntax.Collection.Range() 1172 } 1173 1174 collectionType := unwrapIterableSourceType(x.Collection.Type()) 1175 keyType, valueType, kvDiags := GetCollectionTypes(collectionType, rng) 1176 diagnostics = append(diagnostics, kvDiags...) 1177 x.keyType = keyType 1178 1179 if lit, ok := x.Key.(*LiteralValueExpression); ok { 1180 traverser := hcl.TraverseIndex{ 1181 Key: lit.Value, 1182 } 1183 valueType, traverseDiags := x.Collection.Type().Traverse(traverser) 1184 if len(traverseDiags) == 0 { 1185 x.exprType = valueType.(Type) 1186 return diagnostics 1187 } 1188 } 1189 1190 if !InputType(keyType).ConversionFrom(x.Key.Type()).Exists() { 1191 diagnostics = append(diagnostics, ExprNotConvertible(InputType(keyType), x.Key)) 1192 } 1193 1194 resultType := wrapIterableResultType(x.Collection.Type(), valueType) 1195 x.exprType = liftOperationType(resultType, x.Key) 1196 return diagnostics 1197 } 1198 1199 func (x *IndexExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1200 syntax := &hclsyntax.IndexExpr{ 1201 Collection: &syntaxExpr{expr: x.Collection}, 1202 Key: &syntaxExpr{expr: x.Key}, 1203 } 1204 return syntax.Value(context) 1205 } 1206 1207 func (x *IndexExpression) HasLeadingTrivia() bool { 1208 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Collection) 1209 } 1210 1211 func (x *IndexExpression) HasTrailingTrivia() bool { 1212 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1213 } 1214 1215 func (x *IndexExpression) GetLeadingTrivia() syntax.TriviaList { 1216 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpenBracket()) 1217 } 1218 1219 func (x *IndexExpression) SetLeadingTrivia(t syntax.TriviaList) { 1220 if x.Tokens == nil { 1221 x.Tokens = syntax.NewIndexTokens() 1222 } 1223 setExprLeadingTrivia(x.Tokens.Parentheses, x.Collection, t) 1224 } 1225 1226 func (x *IndexExpression) GetTrailingTrivia() syntax.TriviaList { 1227 return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseBracket()) 1228 } 1229 1230 func (x *IndexExpression) SetTrailingTrivia(t syntax.TriviaList) { 1231 if x.Tokens == nil { 1232 x.Tokens = syntax.NewIndexTokens() 1233 } 1234 setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseBracket, t) 1235 } 1236 1237 func (x *IndexExpression) Format(f fmt.State, c rune) { 1238 x.print(f, &printer{}) 1239 } 1240 1241 func (x *IndexExpression) print(w io.Writer, p *printer) { 1242 p.fprintf(w, "%(%v%v%v%v%)", 1243 x.Tokens.GetParentheses(), 1244 x.Collection, x.Tokens.GetOpenBracket(), x.Key, x.Tokens.GetCloseBracket(), 1245 x.Tokens.GetParentheses()) 1246 } 1247 1248 func (*IndexExpression) isExpression() {} 1249 1250 func literalText(value cty.Value, rawBytes []byte, escaped, quoted bool) string { 1251 if len(rawBytes) > 0 { 1252 parsed, diags := hclsyntax.ParseExpression(rawBytes, "", hcl.Pos{}) 1253 if !diags.HasErrors() { 1254 if lit, ok := parsed.(*hclsyntax.LiteralValueExpr); ok && lit.Val.RawEquals(value) { 1255 return string(rawBytes) 1256 } 1257 } 1258 } 1259 1260 switch value.Type() { 1261 case cty.Bool: 1262 if value.True() { 1263 return "true" 1264 } 1265 return "false" 1266 case cty.Number: 1267 bf := value.AsBigFloat() 1268 i, acc := bf.Int64() 1269 if acc == big.Exact { 1270 return fmt.Sprintf("%v", i) 1271 } 1272 d, _ := bf.Float64() 1273 return fmt.Sprintf("%g", d) 1274 case cty.String: 1275 if !escaped { 1276 return value.AsString() 1277 } 1278 s := strconv.Quote(value.AsString()) 1279 if !quoted { 1280 return s[1 : len(s)-1] 1281 } 1282 return s 1283 default: 1284 panic(fmt.Errorf("unexpected literal type %v", value.Type().FriendlyName())) 1285 } 1286 } 1287 1288 // LiteralValueExpression represents a semantically-analyzed literal value expression. 1289 type LiteralValueExpression struct { 1290 // The syntax node associated with the literal value expression. 1291 Syntax *hclsyntax.LiteralValueExpr 1292 // The tokens associated with the expression, if any. 1293 Tokens *syntax.LiteralValueTokens 1294 1295 // The value of the expression. 1296 Value cty.Value 1297 1298 exprType Type 1299 } 1300 1301 // SyntaxNode returns the syntax node associated with the literal value expression. 1302 func (x *LiteralValueExpression) SyntaxNode() hclsyntax.Node { 1303 return x.Syntax 1304 } 1305 1306 // NodeTokens returns the tokens associated with the literal value expression. 1307 func (x *LiteralValueExpression) NodeTokens() syntax.NodeTokens { 1308 return x.Tokens 1309 } 1310 1311 // Type returns the type of the literal value expression. 1312 func (x *LiteralValueExpression) Type() Type { 1313 if x.exprType == nil { 1314 x.exprType = ctyTypeToType(x.Value.Type(), false) 1315 } 1316 return x.exprType 1317 } 1318 1319 func (x *LiteralValueExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 1320 var diagnostics hcl.Diagnostics 1321 1322 typ := NoneType 1323 if !x.Value.IsNull() { 1324 typ = ctyTypeToType(x.Value.Type(), false) 1325 } 1326 1327 switch { 1328 case typ == NoneType || typ == StringType || typ == IntType || typ == NumberType || typ == BoolType: 1329 // OK 1330 default: 1331 var rng hcl.Range 1332 if x.Syntax != nil { 1333 rng = x.Syntax.Range() 1334 } 1335 typ, diagnostics = DynamicType, hcl.Diagnostics{unsupportedLiteralValue(x.Value, rng)} 1336 } 1337 1338 x.exprType = typ 1339 return diagnostics 1340 } 1341 1342 func (x *LiteralValueExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1343 syntax := &hclsyntax.LiteralValueExpr{ 1344 Val: x.Value, 1345 } 1346 return syntax.Value(context) 1347 } 1348 1349 func (x *LiteralValueExpression) HasLeadingTrivia() bool { 1350 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1351 } 1352 1353 func (x *LiteralValueExpression) HasTrailingTrivia() bool { 1354 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1355 } 1356 1357 func (x *LiteralValueExpression) GetLeadingTrivia() syntax.TriviaList { 1358 if v := x.Tokens.GetValue(x.Value); len(v) > 0 { 1359 return getExprLeadingTrivia(x.Tokens.GetParentheses(), v[0]) 1360 } 1361 return getExprLeadingTrivia(x.Tokens.GetParentheses(), nil) 1362 } 1363 1364 func (x *LiteralValueExpression) SetLeadingTrivia(t syntax.TriviaList) { 1365 if x.Tokens == nil { 1366 x.Tokens = syntax.NewLiteralValueTokens(x.Value) 1367 } 1368 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Value[0], t) 1369 } 1370 1371 func (x *LiteralValueExpression) GetTrailingTrivia() syntax.TriviaList { 1372 if v := x.Tokens.GetValue(x.Value); len(v) > 0 { 1373 return getExprTrailingTrivia(x.Tokens.GetParentheses(), v[len(v)-1]) 1374 } 1375 return getExprTrailingTrivia(x.Tokens.GetParentheses(), nil) 1376 } 1377 1378 func (x *LiteralValueExpression) SetTrailingTrivia(t syntax.TriviaList) { 1379 if x.Tokens == nil { 1380 x.Tokens = syntax.NewLiteralValueTokens(x.Value) 1381 } 1382 setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.Value[len(x.Tokens.Value)-1], t) 1383 } 1384 1385 func (x *LiteralValueExpression) Format(f fmt.State, c rune) { 1386 x.print(f, &printer{}) 1387 } 1388 1389 func (x *LiteralValueExpression) printLit(w io.Writer, p *printer, escaped bool) { 1390 // Literals are... odd. They may be composed of multiple tokens, but those tokens should never contain interior 1391 // trivia. 1392 1393 var leading, trailing syntax.TriviaList 1394 var rawBytes []byte 1395 if toks := x.Tokens.GetValue(x.Value); len(toks) > 0 { 1396 leading, trailing = toks[0].LeadingTrivia, toks[len(toks)-1].TrailingTrivia 1397 1398 for _, t := range toks { 1399 rawBytes = append(rawBytes, t.Raw.Bytes...) 1400 } 1401 } 1402 1403 p.fprintf(w, "%(%v%v%v%)", 1404 x.Tokens.GetParentheses(), 1405 leading, literalText(x.Value, rawBytes, escaped, false), trailing, 1406 x.Tokens.GetParentheses()) 1407 } 1408 1409 func (x *LiteralValueExpression) print(w io.Writer, p *printer) { 1410 x.printLit(w, p, false) 1411 } 1412 1413 func (*LiteralValueExpression) isExpression() {} 1414 1415 // ObjectConsItem records a key-value pair that is part of object construction expression. 1416 type ObjectConsItem struct { 1417 // The key. 1418 Key Expression 1419 // The value. 1420 Value Expression 1421 } 1422 1423 // ObjectConsExpression represents a semantically-analyzed object construction expression. 1424 type ObjectConsExpression struct { 1425 // The syntax node associated with the object construction expression. 1426 Syntax *hclsyntax.ObjectConsExpr 1427 // The tokens associated with the expression, if any. 1428 Tokens *syntax.ObjectConsTokens 1429 1430 // The items that comprise the object construction expression. 1431 Items []ObjectConsItem 1432 1433 exprType Type 1434 } 1435 1436 // SyntaxNode returns the syntax node associated with the object construction expression. 1437 func (x *ObjectConsExpression) SyntaxNode() hclsyntax.Node { 1438 return x.Syntax 1439 } 1440 1441 // NodeTokens returns the tokens associated with the object construction expression. 1442 func (x *ObjectConsExpression) NodeTokens() syntax.NodeTokens { 1443 return x.Tokens 1444 } 1445 1446 // Type returns the type of the object construction expression. 1447 func (x *ObjectConsExpression) Type() Type { 1448 return x.exprType 1449 } 1450 1451 func (x *ObjectConsExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 1452 var diagnostics hcl.Diagnostics 1453 1454 var keys []Expression 1455 for _, item := range x.Items { 1456 if typecheckOperands { 1457 keyDiags := item.Key.Typecheck(true) 1458 diagnostics = append(diagnostics, keyDiags...) 1459 1460 valDiags := item.Value.Typecheck(true) 1461 diagnostics = append(diagnostics, valDiags...) 1462 } 1463 1464 keys = append(keys, item.Key) 1465 if !InputType(StringType).ConversionFrom(item.Key.Type()).Exists() { 1466 diagnostics = append(diagnostics, objectKeysMustBeStrings(item.Key)) 1467 } 1468 } 1469 1470 // Attempt to build an object type out of the result. If there are any attribute names that come from variables, 1471 // type the result as map(unify(propertyTypes)). 1472 properties, isMapType, types := map[string]Type{}, false, []Type{} 1473 for _, item := range x.Items { 1474 types = append(types, item.Value.Type()) 1475 1476 key := item.Key 1477 if template, ok := key.(*TemplateExpression); ok && len(template.Parts) == 1 { 1478 key = template.Parts[0] 1479 } 1480 1481 keyLit, ok := key.(*LiteralValueExpression) 1482 if ok { 1483 key, err := convert.Convert(keyLit.Value, cty.String) 1484 if err == nil { 1485 properties[key.AsString()] = item.Value.Type() 1486 continue 1487 } 1488 } 1489 isMapType = true 1490 } 1491 var typ Type 1492 if isMapType { 1493 elementType, _ := UnifyTypes(types...) 1494 typ = NewMapType(elementType) 1495 } else { 1496 typ = NewObjectType(properties) 1497 } 1498 1499 x.exprType = liftOperationType(typ, keys...) 1500 return diagnostics 1501 } 1502 1503 func (x *ObjectConsExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1504 syntax := &hclsyntax.ObjectConsExpr{ 1505 Items: make([]hclsyntax.ObjectConsItem, len(x.Items)), 1506 } 1507 for i, item := range x.Items { 1508 syntax.Items[i] = hclsyntax.ObjectConsItem{ 1509 KeyExpr: &syntaxExpr{expr: item.Key}, 1510 ValueExpr: &syntaxExpr{expr: item.Value}, 1511 } 1512 } 1513 return syntax.Value(context) 1514 } 1515 1516 func (x *ObjectConsExpression) HasLeadingTrivia() bool { 1517 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1518 } 1519 1520 func (x *ObjectConsExpression) HasTrailingTrivia() bool { 1521 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1522 } 1523 1524 func (x *ObjectConsExpression) GetLeadingTrivia() syntax.TriviaList { 1525 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpenBrace(len(x.Items))) 1526 } 1527 1528 func (x *ObjectConsExpression) SetLeadingTrivia(t syntax.TriviaList) { 1529 if x.Tokens == nil { 1530 x.Tokens = syntax.NewObjectConsTokens(len(x.Items)) 1531 } 1532 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.OpenBrace, t) 1533 } 1534 1535 func (x *ObjectConsExpression) GetTrailingTrivia() syntax.TriviaList { 1536 return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseBrace()) 1537 } 1538 1539 func (x *ObjectConsExpression) SetTrailingTrivia(t syntax.TriviaList) { 1540 if x.Tokens == nil { 1541 x.Tokens = syntax.NewObjectConsTokens(len(x.Items)) 1542 } 1543 setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseBrace, t) 1544 } 1545 1546 func (x *ObjectConsExpression) Format(f fmt.State, c rune) { 1547 x.print(f, &printer{}) 1548 } 1549 1550 func (x *ObjectConsExpression) print(w io.Writer, p *printer) { 1551 // Print the opening brace. 1552 p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetOpenBrace(len(x.Items))) 1553 1554 // Print the items. 1555 isMultiLine, trailingNewline := false, false 1556 p.indented(func() { 1557 items := x.Tokens.GetItems(len(x.Items)) 1558 for i, item := range x.Items { 1559 tokens := syntax.NewObjectConsItemTokens(i == len(x.Items)-1) 1560 if i < len(items) { 1561 tokens = items[i] 1562 } 1563 1564 if item.Key.HasLeadingTrivia() { 1565 if _, i := item.Key.GetLeadingTrivia().Index("\n"); i != -1 { 1566 isMultiLine = true 1567 } 1568 } else if len(items) > 1 { 1569 isMultiLine = true 1570 p.fprintf(w, "\n%s", p.indent) 1571 } 1572 p.fprintf(w, "%v% v% v", item.Key, tokens.Equals, item.Value) 1573 1574 if tokens.Comma != nil { 1575 p.fprintf(w, "%v", tokens.Comma) 1576 } 1577 1578 if isMultiLine && i == len(items)-1 { 1579 trailingTrivia := item.Value.GetTrailingTrivia() 1580 if tokens.Comma != nil { 1581 trailingTrivia = tokens.Comma.TrailingTrivia 1582 } 1583 trailingNewline = trailingTrivia.EndsOnNewLine() 1584 } 1585 } 1586 1587 if len(x.Items) < len(items) { 1588 for _, item := range items[len(x.Items):] { 1589 p.fprintf(w, "%v", item.Equals.AllTrivia().CollapseWhitespace()) 1590 if item.Comma != nil { 1591 p.fprintf(w, "%v", item.Comma.AllTrivia().CollapseWhitespace()) 1592 } 1593 } 1594 } 1595 }) 1596 1597 if x.Tokens != nil { 1598 pre := "" 1599 if isMultiLine && !trailingNewline { 1600 pre = "\n" + p.indent 1601 } 1602 p.fprintf(w, "%s%v%)", pre, x.Tokens.CloseBrace, x.Tokens.Parentheses) 1603 } else { 1604 p.fprintf(w, "\n%s}", p.indent) 1605 } 1606 } 1607 1608 func (*ObjectConsExpression) isExpression() {} 1609 1610 func getTraverserTrivia(tokens syntax.TraverserTokens) (syntax.TriviaList, syntax.TriviaList) { 1611 var leading, trailing syntax.TriviaList 1612 switch tokens := tokens.(type) { 1613 case *syntax.DotTraverserTokens: 1614 leading = getExprLeadingTrivia(tokens.Parentheses, tokens.Dot) 1615 trailing = getExprTrailingTrivia(tokens.Parentheses, tokens.Index) 1616 case *syntax.BracketTraverserTokens: 1617 leading = getExprLeadingTrivia(tokens.Parentheses, tokens.OpenBracket) 1618 trailing = getExprTrailingTrivia(tokens.Parentheses, tokens.CloseBracket) 1619 } 1620 return leading, trailing 1621 } 1622 1623 func setTraverserTrailingTrivia(tokens syntax.TraverserTokens, t syntax.TriviaList) { 1624 switch tokens := tokens.(type) { 1625 case *syntax.DotTraverserTokens: 1626 setExprTrailingTrivia(tokens.Parentheses, &tokens.Index, t) 1627 case *syntax.BracketTraverserTokens: 1628 setExprTrailingTrivia(tokens.Parentheses, &tokens.CloseBracket, t) 1629 default: 1630 panic(fmt.Errorf("unexpected traverser of type %T", tokens)) 1631 } 1632 } 1633 1634 func printTraverser(w io.Writer, p *printer, t hcl.Traverser, tokens syntax.TraverserTokens) { 1635 var index string 1636 switch t := t.(type) { 1637 case hcl.TraverseAttr: 1638 index = t.Name 1639 case hcl.TraverseIndex: 1640 index = literalText(t.Key, nil, true, true) 1641 default: 1642 panic(fmt.Errorf("unexpected traverser of type %T", t)) 1643 } 1644 1645 switch tokens := tokens.(type) { 1646 case *syntax.DotTraverserTokens: 1647 p.fprintf(w, "%(%v%v%)", 1648 tokens.Parentheses, 1649 tokens.Dot, identToken(tokens.Index, index), 1650 tokens.Parentheses) 1651 case *syntax.BracketTraverserTokens: 1652 p.fprintf(w, "%(%v%v%v%)", 1653 tokens.Parentheses, 1654 tokens.OpenBracket, identToken(tokens.Index, index), tokens.CloseBracket, 1655 tokens.Parentheses) 1656 default: 1657 panic(fmt.Errorf("unexpected traverser tokens of type %T", tokens)) 1658 } 1659 } 1660 1661 func printRelativeTraversal(w io.Writer, p *printer, traversal hcl.Traversal, tokens []syntax.TraverserTokens) { 1662 for i, traverser := range traversal { 1663 // Fetch the traversal tokens. 1664 var traverserTokens syntax.TraverserTokens 1665 if i < len(tokens) { 1666 traverserTokens = tokens[i] 1667 } 1668 printTraverser(w, p, traverser, traverserTokens) 1669 } 1670 1671 // Print any remaining trivia. 1672 if len(traversal) < len(tokens) { 1673 for _, tokens := range tokens[len(traversal):] { 1674 var trivia syntax.TriviaList 1675 switch tokens := tokens.(type) { 1676 case *syntax.DotTraverserTokens: 1677 trivia = tokens.Dot.LeadingTrivia 1678 trivia = append(trivia, tokens.Dot.TrailingTrivia...) 1679 trivia = append(trivia, tokens.Index.LeadingTrivia...) 1680 trivia = append(trivia, tokens.Index.TrailingTrivia...) 1681 case *syntax.BracketTraverserTokens: 1682 trivia = tokens.OpenBracket.LeadingTrivia 1683 trivia = append(trivia, tokens.OpenBracket.TrailingTrivia...) 1684 trivia = append(trivia, tokens.Index.LeadingTrivia...) 1685 trivia = append(trivia, tokens.Index.TrailingTrivia...) 1686 trivia = append(trivia, tokens.CloseBracket.LeadingTrivia...) 1687 trivia = append(trivia, tokens.CloseBracket.TrailingTrivia...) 1688 } 1689 p.fprintf(w, "%v", trivia) 1690 } 1691 } 1692 } 1693 1694 // RelativeTraversalExpression represents a semantically-analyzed relative traversal expression. 1695 type RelativeTraversalExpression struct { 1696 // The syntax node associated with the relative traversal expression. 1697 Syntax *hclsyntax.RelativeTraversalExpr 1698 // The tokens associated with the expression, if any. 1699 Tokens *syntax.RelativeTraversalTokens 1700 1701 // The expression that computes the value being traversed. 1702 Source Expression 1703 // The traversal's parts. 1704 Parts []Traversable 1705 1706 // The traversers. 1707 Traversal hcl.Traversal 1708 } 1709 1710 // SyntaxNode returns the syntax node associated with the relative traversal expression. 1711 func (x *RelativeTraversalExpression) SyntaxNode() hclsyntax.Node { 1712 return x.Syntax 1713 } 1714 1715 // NodeTokens returns the tokens associated with the relative traversal expression. 1716 func (x *RelativeTraversalExpression) NodeTokens() syntax.NodeTokens { 1717 return x.Tokens 1718 } 1719 1720 // Type returns the type of the relative traversal expression. 1721 func (x *RelativeTraversalExpression) Type() Type { 1722 return GetTraversableType(x.Parts[len(x.Parts)-1]) 1723 } 1724 1725 func (x *RelativeTraversalExpression) typecheck(typecheckOperands, allowMissingVariables bool) hcl.Diagnostics { 1726 var diagnostics hcl.Diagnostics 1727 1728 if typecheckOperands { 1729 sourceDiags := x.Source.Typecheck(true) 1730 diagnostics = append(diagnostics, sourceDiags...) 1731 } 1732 1733 parts, partDiags := bindTraversalParts(x.Source.Type(), x.Traversal, allowMissingVariables) 1734 diagnostics = append(diagnostics, partDiags...) 1735 1736 x.Parts = parts 1737 return diagnostics 1738 } 1739 1740 func (x *RelativeTraversalExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 1741 return x.typecheck(typecheckOperands, false) 1742 } 1743 1744 func (x *RelativeTraversalExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1745 syntax := &hclsyntax.RelativeTraversalExpr{ 1746 Source: &syntaxExpr{expr: x.Source}, 1747 Traversal: x.Traversal, 1748 } 1749 return syntax.Value(context) 1750 } 1751 1752 func (x *RelativeTraversalExpression) HasLeadingTrivia() bool { 1753 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Source) 1754 } 1755 1756 func (x *RelativeTraversalExpression) HasTrailingTrivia() bool { 1757 if parens := x.Tokens.GetParentheses(); parens.Any() { 1758 return true 1759 } 1760 if x.Tokens != nil && len(x.Tokens.Traversal) > 0 { 1761 return true 1762 } 1763 return x.Source.HasTrailingTrivia() 1764 } 1765 1766 func (x *RelativeTraversalExpression) GetLeadingTrivia() syntax.TriviaList { 1767 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Source) 1768 } 1769 1770 func (x *RelativeTraversalExpression) SetLeadingTrivia(t syntax.TriviaList) { 1771 if x.Tokens == nil { 1772 x.Tokens = syntax.NewRelativeTraversalTokens(x.Traversal) 1773 } 1774 setExprLeadingTrivia(x.Tokens.Parentheses, x.Source, t) 1775 } 1776 1777 func (x *RelativeTraversalExpression) GetTrailingTrivia() syntax.TriviaList { 1778 if parens := x.Tokens.GetParentheses(); parens.Any() { 1779 return parens.GetTrailingTrivia() 1780 } 1781 if traversal := x.Tokens.GetTraversal(x.Traversal); len(traversal) > 0 { 1782 _, trailingTrivia := getTraverserTrivia(traversal[len(traversal)-1]) 1783 return trailingTrivia 1784 } 1785 return x.Source.GetTrailingTrivia() 1786 } 1787 1788 func (x *RelativeTraversalExpression) SetTrailingTrivia(t syntax.TriviaList) { 1789 if x.Tokens == nil { 1790 x.Tokens = syntax.NewRelativeTraversalTokens(x.Traversal) 1791 } 1792 if parens := x.Tokens.GetParentheses(); parens.Any() { 1793 parens.SetTrailingTrivia(t) 1794 return 1795 } 1796 if len(x.Tokens.Traversal) > 0 { 1797 setTraverserTrailingTrivia(x.Tokens.Traversal[len(x.Tokens.Traversal)-1], t) 1798 return 1799 } 1800 x.Source.SetTrailingTrivia(t) 1801 } 1802 1803 func (x *RelativeTraversalExpression) Format(f fmt.State, c rune) { 1804 x.print(f, &printer{}) 1805 } 1806 1807 func (x *RelativeTraversalExpression) print(w io.Writer, p *printer) { 1808 // Print the source expression. 1809 p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Source) 1810 1811 // Print the traversal. 1812 printRelativeTraversal(w, p, x.Traversal, x.Tokens.GetTraversal(x.Traversal)) 1813 1814 // Print the closing parentheses, if any. 1815 p.fprintf(w, "%)", x.Tokens.GetParentheses()) 1816 } 1817 1818 func (*RelativeTraversalExpression) isExpression() {} 1819 1820 // ScopeTraversalExpression represents a semantically-analyzed scope traversal expression. 1821 type ScopeTraversalExpression struct { 1822 // The syntax node associated with the scope traversal expression. 1823 Syntax *hclsyntax.ScopeTraversalExpr 1824 // The tokens associated with the expression, if any. 1825 Tokens *syntax.ScopeTraversalTokens 1826 1827 // The traversal's parts. 1828 Parts []Traversable 1829 1830 // The root name. 1831 RootName string 1832 // The traversers. 1833 Traversal hcl.Traversal 1834 } 1835 1836 // SyntaxNode returns the syntax node associated with the scope traversal expression. 1837 func (x *ScopeTraversalExpression) SyntaxNode() hclsyntax.Node { 1838 return x.Syntax 1839 } 1840 1841 // NodeTokens returns the tokens associated with the scope traversal expression. 1842 func (x *ScopeTraversalExpression) NodeTokens() syntax.NodeTokens { 1843 return x.Tokens 1844 } 1845 1846 // Type returns the type of the scope traversal expression. 1847 func (x *ScopeTraversalExpression) Type() Type { 1848 return GetTraversableType(x.Parts[len(x.Parts)-1]) 1849 } 1850 1851 func (x *ScopeTraversalExpression) typecheck(typecheckOperands, allowMissingVariables bool) hcl.Diagnostics { 1852 parts, diagnostics := bindTraversalParts(x.Parts[0], x.Traversal.SimpleSplit().Rel, allowMissingVariables) 1853 x.Parts = parts 1854 1855 return diagnostics 1856 } 1857 1858 func (x *ScopeTraversalExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 1859 return x.typecheck(typecheckOperands, false) 1860 } 1861 1862 func (x *ScopeTraversalExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1863 var diagnostics hcl.Diagnostics 1864 1865 root, hasValue := x.Parts[0].(ValueTraversable) 1866 if !hasValue { 1867 return cty.UnknownVal(cty.DynamicPseudoType), nil 1868 } 1869 1870 rootValue, diags := root.Value(context) 1871 if diags.HasErrors() { 1872 return cty.NilVal, diags 1873 } 1874 diagnostics = append(diagnostics, diags...) 1875 1876 if len(x.Traversal) == 1 { 1877 return rootValue, diagnostics 1878 } 1879 return x.Traversal[1:].TraverseRel(rootValue) 1880 } 1881 1882 func (x *ScopeTraversalExpression) HasLeadingTrivia() bool { 1883 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 1884 } 1885 1886 func (x *ScopeTraversalExpression) HasTrailingTrivia() bool { 1887 if parens := x.Tokens.GetParentheses(); parens.Any() { 1888 return true 1889 } 1890 if x.Tokens != nil && len(x.Tokens.Traversal) > 0 { 1891 return true 1892 } 1893 return x.Tokens != nil 1894 } 1895 1896 func (x *ScopeTraversalExpression) GetLeadingTrivia() syntax.TriviaList { 1897 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetRoot(x.Traversal)) 1898 } 1899 1900 func (x *ScopeTraversalExpression) SetLeadingTrivia(t syntax.TriviaList) { 1901 if x.Tokens == nil { 1902 x.Tokens = syntax.NewScopeTraversalTokens(x.Traversal) 1903 } 1904 x.Tokens.Root.LeadingTrivia = t 1905 } 1906 1907 func (x *ScopeTraversalExpression) GetTrailingTrivia() syntax.TriviaList { 1908 if parens := x.Tokens.GetParentheses(); parens.Any() { 1909 return parens.GetTrailingTrivia() 1910 } 1911 if traversal := x.Tokens.GetTraversal(x.Traversal); len(traversal) > 0 { 1912 _, trailingTrivia := getTraverserTrivia(traversal[len(traversal)-1]) 1913 return trailingTrivia 1914 } 1915 return x.Tokens.GetRoot(x.Traversal).TrailingTrivia 1916 } 1917 1918 func (x *ScopeTraversalExpression) SetTrailingTrivia(t syntax.TriviaList) { 1919 if x.Tokens == nil { 1920 x.Tokens = syntax.NewScopeTraversalTokens(x.Traversal) 1921 } 1922 if parens := x.Tokens.GetParentheses(); parens.Any() { 1923 parens.SetTrailingTrivia(t) 1924 return 1925 } 1926 if len(x.Tokens.Traversal) > 0 { 1927 setTraverserTrailingTrivia(x.Tokens.Traversal[len(x.Tokens.Traversal)-1], t) 1928 return 1929 } 1930 x.Tokens.Root.TrailingTrivia = t 1931 } 1932 1933 func (x *ScopeTraversalExpression) Format(f fmt.State, c rune) { 1934 x.print(f, &printer{}) 1935 } 1936 1937 func (x *ScopeTraversalExpression) print(w io.Writer, p *printer) { 1938 // Print the root name. 1939 p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetRoot(x.Traversal)) 1940 1941 // Print the traversal. 1942 printRelativeTraversal(w, p, x.Traversal[1:], x.Tokens.GetTraversal(x.Traversal)) 1943 1944 // Print the closing parentheses, if any. 1945 p.fprintf(w, "%)", x.Tokens.GetParentheses()) 1946 } 1947 1948 func (*ScopeTraversalExpression) isExpression() {} 1949 1950 type SplatVariable struct { 1951 Variable 1952 1953 symbol hclsyntax.AnonSymbolExpr 1954 } 1955 1956 func (v *SplatVariable) Value(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 1957 return (&v.symbol).Value(context) 1958 } 1959 1960 // SplatExpression represents a semantically-analyzed splat expression. 1961 type SplatExpression struct { 1962 // The syntax node associated with the splat expression. 1963 Syntax *hclsyntax.SplatExpr 1964 // The tokens associated with the expression, if any. 1965 Tokens *syntax.SplatTokens 1966 1967 // The expression being splatted. 1968 Source Expression 1969 // The expression applied to each element of the splat. 1970 Each Expression 1971 // The local variable definition associated with the current item being processed. This definition is not part of 1972 // a scope, and can only be referenced by an AnonSymbolExpr. 1973 Item *SplatVariable 1974 1975 exprType Type 1976 } 1977 1978 // SyntaxNode returns the syntax node associated with the splat expression. 1979 func (x *SplatExpression) SyntaxNode() hclsyntax.Node { 1980 return x.Syntax 1981 } 1982 1983 // NodeTokens returns the tokens associated with the splat expression. 1984 func (x *SplatExpression) NodeTokens() syntax.NodeTokens { 1985 return x.Tokens 1986 } 1987 1988 // Type returns the type of the splat expression. 1989 func (x *SplatExpression) Type() Type { 1990 return x.exprType 1991 } 1992 1993 func splatItemType(source Expression, splatSyntax *hclsyntax.SplatExpr) (Expression, Type) { 1994 sourceType := unwrapIterableSourceType(source.Type()) 1995 itemType := sourceType 1996 switch sourceType := sourceType.(type) { 1997 case *ListType: 1998 itemType = sourceType.ElementType 1999 case *SetType: 2000 itemType = sourceType.ElementType 2001 case *TupleType: 2002 itemType, _ = UnifyTypes(sourceType.ElementTypes...) 2003 default: 2004 if sourceType != DynamicType { 2005 var tupleSyntax *hclsyntax.TupleConsExpr 2006 if splatSyntax != nil { 2007 tupleSyntax = &hclsyntax.TupleConsExpr{ 2008 Exprs: []hclsyntax.Expression{splatSyntax.Source}, 2009 SrcRange: splatSyntax.Source.Range(), 2010 OpenRange: splatSyntax.Source.StartRange(), 2011 } 2012 } 2013 2014 source = &TupleConsExpression{ 2015 Syntax: tupleSyntax, 2016 Tokens: syntax.NewTupleConsTokens(1), 2017 Expressions: []Expression{source}, 2018 exprType: NewListType(source.Type()), 2019 } 2020 } 2021 } 2022 return source, itemType 2023 } 2024 2025 func (x *SplatExpression) typecheck(retypeItem, typecheckOperands bool) hcl.Diagnostics { 2026 var diagnostics hcl.Diagnostics 2027 2028 if typecheckOperands { 2029 sourceDiags := x.Source.Typecheck(true) 2030 diagnostics = append(diagnostics, sourceDiags...) 2031 } 2032 2033 if retypeItem { 2034 x.Source, x.Item.VariableType = splatItemType(x.Source, x.Syntax) 2035 } 2036 2037 if typecheckOperands { 2038 eachDiags := x.Each.Typecheck(true) 2039 diagnostics = append(diagnostics, eachDiags...) 2040 } 2041 2042 x.exprType = wrapIterableResultType(x.Source.Type(), NewListType(x.Each.Type())) 2043 2044 return diagnostics 2045 } 2046 2047 func (x *SplatExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 2048 return x.typecheck(true, typecheckOperands) 2049 } 2050 2051 func (x *SplatExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 2052 syntax := &hclsyntax.SplatExpr{ 2053 Source: &syntaxExpr{expr: x.Source}, 2054 Each: &syntaxExpr{expr: x.Each}, 2055 Item: &x.Item.symbol, 2056 } 2057 return syntax.Value(context) 2058 } 2059 2060 func (x *SplatExpression) HasLeadingTrivia() bool { 2061 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Source) 2062 } 2063 2064 func (x *SplatExpression) HasTrailingTrivia() bool { 2065 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Each) 2066 } 2067 2068 func (x *SplatExpression) GetLeadingTrivia() syntax.TriviaList { 2069 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Source) 2070 } 2071 2072 func (x *SplatExpression) SetLeadingTrivia(t syntax.TriviaList) { 2073 if x.Tokens == nil { 2074 x.Tokens = syntax.NewSplatTokens(false) 2075 } 2076 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Open, t) 2077 } 2078 2079 func (x *SplatExpression) GetTrailingTrivia() syntax.TriviaList { 2080 if parens := x.Tokens.GetParentheses(); parens.Any() { 2081 return parens.GetTrailingTrivia() 2082 } 2083 if close := x.Tokens.GetClose(); close != nil { 2084 return close.TrailingTrivia 2085 } 2086 return x.Tokens.GetStar().TrailingTrivia 2087 } 2088 2089 func (x *SplatExpression) SetTrailingTrivia(t syntax.TriviaList) { 2090 if x.Tokens == nil { 2091 x.Tokens = syntax.NewSplatTokens(false) 2092 } 2093 if x.Tokens.Parentheses.Any() { 2094 x.Tokens.Parentheses.SetTrailingTrivia(t) 2095 return 2096 } 2097 if x.Tokens.Close == nil { 2098 x.Tokens.Star.TrailingTrivia = t 2099 return 2100 } 2101 x.Tokens.Close.TrailingTrivia = t 2102 } 2103 2104 func (x *SplatExpression) Format(f fmt.State, c rune) { 2105 x.print(f, &printer{}) 2106 } 2107 2108 func (x *SplatExpression) print(w io.Writer, p *printer) { 2109 isDot := x.Tokens.GetClose() == nil 2110 2111 p.fprintf(w, "%(%v%v%v", x.Tokens.GetParentheses(), x.Source, x.Tokens.GetOpen(), x.Tokens.GetStar()) 2112 if !isDot { 2113 p.fprintf(w, "%v", x.Tokens.GetClose()) 2114 } 2115 p.fprintf(w, "%v%)", x.Each, x.Tokens.GetParentheses()) 2116 } 2117 2118 func (*SplatExpression) isExpression() {} 2119 2120 // TemplateExpression represents a semantically-analyzed template expression. 2121 type TemplateExpression struct { 2122 // The syntax node associated with the template expression. 2123 Syntax *hclsyntax.TemplateExpr 2124 // The tokens associated with the expression, if any. 2125 Tokens *syntax.TemplateTokens 2126 2127 // The parts of the template expression. 2128 Parts []Expression 2129 2130 exprType Type 2131 } 2132 2133 // SyntaxNode returns the syntax node associated with the template expression. 2134 func (x *TemplateExpression) SyntaxNode() hclsyntax.Node { 2135 return x.Syntax 2136 } 2137 2138 // NodeTokens returns the tokens associated with the template expression. 2139 func (x *TemplateExpression) NodeTokens() syntax.NodeTokens { 2140 return x.Tokens 2141 } 2142 2143 // Type returns the type of the template expression. 2144 func (x *TemplateExpression) Type() Type { 2145 return x.exprType 2146 } 2147 2148 func (x *TemplateExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 2149 var diagnostics hcl.Diagnostics 2150 2151 if typecheckOperands { 2152 for _, part := range x.Parts { 2153 partDiags := part.Typecheck(true) 2154 diagnostics = append(diagnostics, partDiags...) 2155 } 2156 } 2157 2158 x.exprType = liftOperationType(StringType, x.Parts...) 2159 return diagnostics 2160 } 2161 2162 func (x *TemplateExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 2163 syntax := &hclsyntax.TemplateExpr{ 2164 Parts: make([]hclsyntax.Expression, len(x.Parts)), 2165 } 2166 for i, p := range x.Parts { 2167 syntax.Parts[i] = &syntaxExpr{expr: p} 2168 } 2169 return syntax.Value(context) 2170 } 2171 2172 func (x *TemplateExpression) HasLeadingTrivia() bool { 2173 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 2174 } 2175 2176 func (x *TemplateExpression) HasTrailingTrivia() bool { 2177 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 2178 } 2179 2180 func (x *TemplateExpression) GetLeadingTrivia() syntax.TriviaList { 2181 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpen()) 2182 } 2183 2184 func (x *TemplateExpression) SetLeadingTrivia(t syntax.TriviaList) { 2185 if x.Tokens == nil { 2186 x.Tokens = syntax.NewTemplateTokens() 2187 } 2188 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Open, t) 2189 } 2190 2191 func (x *TemplateExpression) GetTrailingTrivia() syntax.TriviaList { 2192 return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetClose()) 2193 } 2194 2195 func (x *TemplateExpression) SetTrailingTrivia(t syntax.TriviaList) { 2196 if x.Tokens == nil { 2197 x.Tokens = syntax.NewTemplateTokens() 2198 } 2199 setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.Close, t) 2200 } 2201 2202 func (x *TemplateExpression) Format(f fmt.State, c rune) { 2203 x.print(f, &printer{}) 2204 } 2205 2206 func (x *TemplateExpression) print(w io.Writer, p *printer) { 2207 // Print the opening quote. 2208 p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetOpen()) 2209 2210 isHeredoc := x.Tokens.GetOpen().Raw.Type == hclsyntax.TokenOHeredoc 2211 2212 // Print the expressions. 2213 for _, part := range x.Parts { 2214 if lit, ok := part.(*LiteralValueExpression); ok && lit.Type() == StringType { 2215 lit.printLit(w, p, !isHeredoc) 2216 } else { 2217 p.fprintf(w, "%v", part) 2218 } 2219 } 2220 2221 // Print the closing quote 2222 p.fprintf(w, "%v%)", x.Tokens.GetClose(), x.Tokens.GetParentheses()) 2223 } 2224 2225 func (*TemplateExpression) isExpression() {} 2226 2227 // TemplateJoinExpression represents a semantically-analyzed template join expression. 2228 type TemplateJoinExpression struct { 2229 // The syntax node associated with the template join expression. 2230 Syntax *hclsyntax.TemplateJoinExpr 2231 2232 // The tuple being joined. 2233 Tuple Expression 2234 2235 exprType Type 2236 } 2237 2238 // SyntaxNode returns the syntax node associated with the template join expression. 2239 func (x *TemplateJoinExpression) SyntaxNode() hclsyntax.Node { 2240 return x.Syntax 2241 } 2242 2243 // NodeTokens returns the tokens associated with the template join expression. 2244 func (x *TemplateJoinExpression) NodeTokens() syntax.NodeTokens { 2245 return nil 2246 } 2247 2248 // Type returns the type of the template join expression. 2249 func (x *TemplateJoinExpression) Type() Type { 2250 return x.exprType 2251 } 2252 2253 func (x *TemplateJoinExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 2254 var diagnostics hcl.Diagnostics 2255 2256 if typecheckOperands { 2257 tupleDiags := x.Tuple.Typecheck(true) 2258 diagnostics = append(diagnostics, tupleDiags...) 2259 } 2260 2261 x.exprType = liftOperationType(StringType, x.Tuple) 2262 return diagnostics 2263 } 2264 2265 func (x *TemplateJoinExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 2266 syntax := &hclsyntax.TemplateJoinExpr{ 2267 Tuple: &syntaxExpr{expr: x.Tuple}, 2268 } 2269 return syntax.Value(context) 2270 } 2271 2272 func (x *TemplateJoinExpression) HasLeadingTrivia() bool { 2273 return x.Tuple.HasLeadingTrivia() 2274 } 2275 2276 func (x *TemplateJoinExpression) HasTrailingTrivia() bool { 2277 return x.Tuple.HasTrailingTrivia() 2278 } 2279 2280 func (x *TemplateJoinExpression) GetLeadingTrivia() syntax.TriviaList { 2281 return x.Tuple.GetLeadingTrivia() 2282 } 2283 2284 func (x *TemplateJoinExpression) SetLeadingTrivia(t syntax.TriviaList) { 2285 x.Tuple.SetLeadingTrivia(t) 2286 } 2287 2288 func (x *TemplateJoinExpression) GetTrailingTrivia() syntax.TriviaList { 2289 return x.Tuple.GetTrailingTrivia() 2290 } 2291 2292 func (x *TemplateJoinExpression) SetTrailingTrivia(t syntax.TriviaList) { 2293 x.Tuple.SetTrailingTrivia(t) 2294 } 2295 2296 func (x *TemplateJoinExpression) Format(f fmt.State, c rune) { 2297 x.print(f, &printer{}) 2298 } 2299 2300 func (x *TemplateJoinExpression) print(w io.Writer, p *printer) { 2301 p.fprintf(w, "%v", x.Tuple) 2302 } 2303 2304 func (*TemplateJoinExpression) isExpression() {} 2305 2306 // TupleConsExpression represents a semantically-analyzed tuple construction expression. 2307 type TupleConsExpression struct { 2308 // The syntax node associated with the tuple construction expression. 2309 Syntax *hclsyntax.TupleConsExpr 2310 // The tokens associated with the expression, if any. 2311 Tokens *syntax.TupleConsTokens 2312 2313 // The elements of the tuple. 2314 Expressions []Expression 2315 2316 exprType Type 2317 } 2318 2319 // SyntaxNode returns the syntax node associated with the tuple construction expression. 2320 func (x *TupleConsExpression) SyntaxNode() hclsyntax.Node { 2321 return x.Syntax 2322 } 2323 2324 // NodeTokens returns the tokens associated with the tuple construction expression. 2325 func (x *TupleConsExpression) NodeTokens() syntax.NodeTokens { 2326 return x.Tokens 2327 } 2328 2329 // Type returns the type of the tuple construction expression. 2330 func (x *TupleConsExpression) Type() Type { 2331 return x.exprType 2332 } 2333 2334 func (x *TupleConsExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 2335 var diagnostics hcl.Diagnostics 2336 2337 elementTypes := make([]Type, len(x.Expressions)) 2338 for i, expr := range x.Expressions { 2339 if typecheckOperands { 2340 exprDiags := expr.Typecheck(true) 2341 diagnostics = append(diagnostics, exprDiags...) 2342 } 2343 2344 elementTypes[i] = expr.Type() 2345 } 2346 2347 x.exprType = NewTupleType(elementTypes...) 2348 return diagnostics 2349 } 2350 2351 func (x *TupleConsExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 2352 syntax := &hclsyntax.TupleConsExpr{ 2353 Exprs: make([]hclsyntax.Expression, len(x.Expressions)), 2354 } 2355 for i, x := range x.Expressions { 2356 syntax.Exprs[i] = &syntaxExpr{expr: x} 2357 } 2358 return syntax.Value(context) 2359 } 2360 2361 func (x *TupleConsExpression) HasLeadingTrivia() bool { 2362 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 2363 } 2364 2365 func (x *TupleConsExpression) HasTrailingTrivia() bool { 2366 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 2367 } 2368 2369 func (x *TupleConsExpression) GetLeadingTrivia() syntax.TriviaList { 2370 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOpenBracket()) 2371 } 2372 2373 func (x *TupleConsExpression) SetLeadingTrivia(t syntax.TriviaList) { 2374 if x.Tokens == nil { 2375 x.Tokens = syntax.NewTupleConsTokens(len(x.Expressions)) 2376 } 2377 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.OpenBracket, t) 2378 } 2379 2380 func (x *TupleConsExpression) GetTrailingTrivia() syntax.TriviaList { 2381 return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetCloseBracket()) 2382 } 2383 2384 func (x *TupleConsExpression) SetTrailingTrivia(t syntax.TriviaList) { 2385 if x.Tokens == nil { 2386 x.Tokens = syntax.NewTupleConsTokens(len(x.Expressions)) 2387 } 2388 setExprTrailingTrivia(x.Tokens.Parentheses, &x.Tokens.CloseBracket, t) 2389 } 2390 2391 func (x *TupleConsExpression) Format(f fmt.State, c rune) { 2392 x.print(f, &printer{}) 2393 } 2394 2395 func (x *TupleConsExpression) print(w io.Writer, p *printer) { 2396 // Print the opening bracket. 2397 p.fprintf(w, "%(%v", x.Tokens.GetParentheses(), x.Tokens.GetOpenBracket()) 2398 2399 // Print each element and its comma. 2400 commas := x.Tokens.GetCommas(len(x.Expressions)) 2401 p.indented(func() { 2402 for i, expr := range x.Expressions { 2403 if !expr.HasLeadingTrivia() { 2404 p.fprintf(w, "\n%s", p.indent) 2405 } 2406 p.fprintf(w, "%v", expr) 2407 2408 if i != len(x.Expressions)-1 { 2409 var comma syntax.Token 2410 if i < len(commas) { 2411 comma = commas[i] 2412 } 2413 p.fprintf(w, "%v", comma) 2414 } 2415 } 2416 2417 // If there were commas left over, print the trivia for each. 2418 // 2419 // TODO(pdg): filter to only comments? 2420 if len(x.Expressions) > 0 && len(x.Expressions)-1 <= len(commas) { 2421 for _, comma := range commas[len(x.Expressions)-1:] { 2422 p.fprintf(w, "%v", comma.AllTrivia().CollapseWhitespace()) 2423 } 2424 } 2425 }) 2426 2427 // Print the closing bracket. 2428 if x.Tokens != nil { 2429 p.fprintf(w, "%v%)", x.Tokens.CloseBracket, x.Tokens.GetParentheses()) 2430 } else { 2431 p.fprintf(w, "\n%s]", p.indent) 2432 } 2433 } 2434 2435 func (*TupleConsExpression) isExpression() {} 2436 2437 // UnaryOpExpression represents a semantically-analyzed unary operation. 2438 type UnaryOpExpression struct { 2439 // The syntax node associated with the unary operation. 2440 Syntax *hclsyntax.UnaryOpExpr 2441 // The tokens associated with the expression, if any. 2442 Tokens *syntax.UnaryOpTokens 2443 2444 // The operation. 2445 Operation *hclsyntax.Operation 2446 // The operand of the operation. 2447 Operand Expression 2448 2449 operandType Type 2450 exprType Type 2451 } 2452 2453 // SyntaxNode returns the syntax node associated with the unary operation. 2454 func (x *UnaryOpExpression) SyntaxNode() hclsyntax.Node { 2455 return x.Syntax 2456 } 2457 2458 // NodeTokens returns the tokens associated with the unary operation. 2459 func (x *UnaryOpExpression) NodeTokens() syntax.NodeTokens { 2460 return x.Tokens 2461 } 2462 2463 // OperandType returns the operand type of the unary operation. 2464 func (x *UnaryOpExpression) OperandType() Type { 2465 return x.operandType 2466 } 2467 2468 // Type returns the type of the unary operation. 2469 func (x *UnaryOpExpression) Type() Type { 2470 return x.exprType 2471 } 2472 2473 func (x *UnaryOpExpression) Typecheck(typecheckOperands bool) hcl.Diagnostics { 2474 var diagnostics hcl.Diagnostics 2475 2476 if typecheckOperands { 2477 operandDiags := x.Operand.Typecheck(true) 2478 diagnostics = append(diagnostics, operandDiags...) 2479 } 2480 2481 // Compute the signature for the operator and typecheck the arguments. 2482 signature := getOperationSignature(x.Operation) 2483 contract.Assert(len(signature.Parameters) == 1) 2484 2485 x.operandType = signature.Parameters[0].Type 2486 2487 var rng hcl.Range 2488 if x.Syntax != nil { 2489 rng = x.Syntax.Range() 2490 } 2491 typecheckDiags := typecheckArgs(rng, signature, x.Operand) 2492 diagnostics = append(diagnostics, typecheckDiags...) 2493 2494 x.exprType = liftOperationType(signature.ReturnType, x.Operand) 2495 return diagnostics 2496 } 2497 2498 func (x *UnaryOpExpression) Evaluate(context *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { 2499 syntax := &hclsyntax.UnaryOpExpr{ 2500 Op: x.Operation, 2501 Val: &syntaxExpr{expr: x.Operand}, 2502 } 2503 return syntax.Value(context) 2504 } 2505 2506 func (x *UnaryOpExpression) HasLeadingTrivia() bool { 2507 return exprHasLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens != nil) 2508 } 2509 2510 func (x *UnaryOpExpression) HasTrailingTrivia() bool { 2511 return exprHasTrailingTrivia(x.Tokens.GetParentheses(), x.Operand) 2512 } 2513 2514 func (x *UnaryOpExpression) GetLeadingTrivia() syntax.TriviaList { 2515 return getExprLeadingTrivia(x.Tokens.GetParentheses(), x.Tokens.GetOperator(x.Operation)) 2516 } 2517 2518 func (x *UnaryOpExpression) SetLeadingTrivia(t syntax.TriviaList) { 2519 if x.Tokens == nil { 2520 x.Tokens = syntax.NewUnaryOpTokens(x.Operation) 2521 } 2522 setExprLeadingTrivia(x.Tokens.Parentheses, &x.Tokens.Operator, t) 2523 } 2524 2525 func (x *UnaryOpExpression) GetTrailingTrivia() syntax.TriviaList { 2526 return getExprTrailingTrivia(x.Tokens.GetParentheses(), x.Operand) 2527 } 2528 2529 func (x *UnaryOpExpression) SetTrailingTrivia(t syntax.TriviaList) { 2530 if x.Tokens == nil { 2531 x.Tokens = syntax.NewUnaryOpTokens(x.Operation) 2532 } 2533 setExprTrailingTrivia(x.Tokens.Parentheses, x.Operand, t) 2534 } 2535 2536 func (x *UnaryOpExpression) Format(f fmt.State, c rune) { 2537 x.print(f, &printer{}) 2538 } 2539 2540 func (x *UnaryOpExpression) print(w io.Writer, p *printer) { 2541 precedence := operatorPrecedence(x.Operation) 2542 p.fprintf(w, "%[2](%[3]v%.[1]*[4]v%[5])", 2543 precedence, 2544 x.Tokens.GetParentheses(), 2545 x.Tokens.GetOperator(x.Operation), x.Operand, 2546 x.Tokens.GetParentheses()) 2547 } 2548 2549 func (*UnaryOpExpression) isExpression() {}