pulumi/pkg/codegen/python/gen_program_lower.go
Justin Van Patten 42a1896bf9
[codegen/python] Delete dead code around casing tables (#7647)
Coincident with the release of Pulumi 3.0, we updated the provider SDK codegen for Python to no longer use casing tables for translating Python snake_case names to Pulumi camelCase names (and vice versa). Instead, the mapping is encoded in decorators applied on class properties.

Some of the code that was used to generate and use the casing tables has persisted. This commits removes this code, as it's no longer necessary, and will improve the quality of our generated examples.
2021-07-27 08:37:49 -07:00

104 lines
3.2 KiB
Go

package python
import (
"github.com/hashicorp/hcl/v2"
"github.com/pulumi/pulumi/pkg/v3/codegen"
"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2"
"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2/model"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
)
func isParameterReference(parameters codegen.Set, x model.Expression) bool {
scopeTraversal, ok := x.(*model.ScopeTraversalExpression)
if !ok {
return false
}
return parameters.Has(scopeTraversal.Parts[0])
}
// parseProxyApply attempts to match and rewrite the given parsed apply using the following patterns:
//
// - __apply(<expr>, eval(x, x[index])) -> <expr>[index]
// - __apply(<expr>, eval(x, x.attr))) -> <expr>.attr
// - __apply(traversal, eval(x, x.attr)) -> traversal.attr
//
// Each of these patterns matches an apply that can be handled by `pulumi.Output`'s `__getitem__` or `__getattr__`
// method. The rewritten expressions will use those methods rather than calling `apply`.
func (g *generator) parseProxyApply(parameters codegen.Set, args []model.Expression,
then model.Expression) (model.Expression, bool) {
if len(args) != 1 {
return nil, false
}
arg := args[0]
switch then := then.(type) {
case *model.IndexExpression:
// Rewrite `__apply(<expr>, eval(x, x[index]))` to `<expr>[index]`.
if !isParameterReference(parameters, then.Collection) {
return nil, false
}
then.Collection = arg
case *model.ScopeTraversalExpression:
if !isParameterReference(parameters, then) {
return nil, false
}
switch arg := arg.(type) {
case *model.RelativeTraversalExpression:
arg.Traversal = append(arg.Traversal, then.Traversal[1:]...)
arg.Parts = append(arg.Parts, then.Parts...)
case *model.ScopeTraversalExpression:
arg.Traversal = append(arg.Traversal, then.Traversal[1:]...)
arg.Parts = append(arg.Parts, then.Parts...)
}
default:
return nil, false
}
diags := arg.Typecheck(false)
contract.Assert(len(diags) == 0)
return arg, true
}
// lowerProxyApplies lowers certain calls to the apply intrinsic into proxied property accesses. Concretely, this
// boils down to rewriting the following shapes
//
// - __apply(<expr>, eval(x, x[index]))
// - __apply(<expr>, eval(x, x.attr)))
// - __apply(scope.traversal, eval(x, x.attr))
//
// into (respectively)
//
// - <expr>[index]
// - <expr>.attr
// - scope.traversal.attr
//
// These forms will use `pulumi.Output`'s `__getitem__` and `__getattr__` instead of calling `apply`.
func (g *generator) lowerProxyApplies(expr model.Expression) (model.Expression, hcl.Diagnostics) {
rewriter := func(expr model.Expression) (model.Expression, hcl.Diagnostics) {
// Ignore the node if it is not a call to the apply intrinsic.
apply, ok := expr.(*model.FunctionCallExpression)
if !ok || apply.Name != hcl2.IntrinsicApply {
return expr, nil
}
// Parse the apply call.
args, then := hcl2.ParseApplyCall(apply)
parameters := codegen.Set{}
for _, p := range then.Parameters {
parameters.Add(p)
}
// Attempt to match (call __apply (rvar) (call __applyArg 0))
if v, ok := g.parseProxyApply(parameters, args, then.Body); ok {
return v, nil
}
return expr, nil
}
return model.VisitExpression(expr, model.IdentityVisitor, rewriter)
}