Merge "Move variable assignment handling to generation context"
This commit is contained in:
@@ -233,18 +233,17 @@ func (xi *interpolateExpr) transform(transformer func(expr starlarkExpr) starlar
|
|||||||
|
|
||||||
type variableRefExpr struct {
|
type variableRefExpr struct {
|
||||||
ref variable
|
ref variable
|
||||||
isDefined bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVariableRefExpr(ref variable, isDefined bool) starlarkExpr {
|
func NewVariableRefExpr(ref variable) starlarkExpr {
|
||||||
if predefined, ok := ref.(*predefinedVariable); ok {
|
if predefined, ok := ref.(*predefinedVariable); ok {
|
||||||
return predefined.value
|
return predefined.value
|
||||||
}
|
}
|
||||||
return &variableRefExpr{ref, isDefined}
|
return &variableRefExpr{ref}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *variableRefExpr) emit(gctx *generationContext) {
|
func (v *variableRefExpr) emit(gctx *generationContext) {
|
||||||
v.ref.emitGet(gctx, v.isDefined)
|
v.ref.emitGet(gctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *variableRefExpr) typ() starlarkType {
|
func (v *variableRefExpr) typ() starlarkType {
|
||||||
|
@@ -197,6 +197,14 @@ func isMakeControlFunc(s string) bool {
|
|||||||
return s == "error" || s == "warning" || s == "info"
|
return s == "error" || s == "warning" || s == "info"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// varAssignmentScope points to the last assignment for each variable
|
||||||
|
// in the current block. It is used during the parsing to chain
|
||||||
|
// the assignments to a variable together.
|
||||||
|
type varAssignmentScope struct {
|
||||||
|
outer *varAssignmentScope
|
||||||
|
vars map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
// Starlark output generation context
|
// Starlark output generation context
|
||||||
type generationContext struct {
|
type generationContext struct {
|
||||||
buf strings.Builder
|
buf strings.Builder
|
||||||
@@ -204,10 +212,42 @@ type generationContext struct {
|
|||||||
indentLevel int
|
indentLevel int
|
||||||
inAssignment bool
|
inAssignment bool
|
||||||
tracedCount int
|
tracedCount int
|
||||||
|
varAssignments *varAssignmentScope
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenerateContext(ss *StarlarkScript) *generationContext {
|
func NewGenerateContext(ss *StarlarkScript) *generationContext {
|
||||||
return &generationContext{starScript: ss}
|
return &generationContext{
|
||||||
|
starScript: ss,
|
||||||
|
varAssignments: &varAssignmentScope{
|
||||||
|
outer: nil,
|
||||||
|
vars: make(map[string]bool),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gctx *generationContext) pushVariableAssignments() {
|
||||||
|
va := &varAssignmentScope{
|
||||||
|
outer: gctx.varAssignments,
|
||||||
|
vars: make(map[string]bool),
|
||||||
|
}
|
||||||
|
gctx.varAssignments = va
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gctx *generationContext) popVariableAssignments() {
|
||||||
|
gctx.varAssignments = gctx.varAssignments.outer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gctx *generationContext) hasBeenAssigned(v variable) bool {
|
||||||
|
for va := gctx.varAssignments; va != nil; va = va.outer {
|
||||||
|
if _, ok := va.vars[v.name()]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gctx *generationContext) setHasBeenAssigned(v variable) {
|
||||||
|
gctx.varAssignments.vars[v.name()] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit returns generated script
|
// emit returns generated script
|
||||||
@@ -394,14 +434,6 @@ type StarlarkScript struct {
|
|||||||
nodeLocator func(pos mkparser.Pos) int
|
nodeLocator func(pos mkparser.Pos) int
|
||||||
}
|
}
|
||||||
|
|
||||||
// varAssignmentScope points to the last assignment for each variable
|
|
||||||
// in the current block. It is used during the parsing to chain
|
|
||||||
// the assignments to a variable together.
|
|
||||||
type varAssignmentScope struct {
|
|
||||||
outer *varAssignmentScope
|
|
||||||
vars map[string]*assignmentNode
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseContext holds the script we are generating and all the ephemeral data
|
// parseContext holds the script we are generating and all the ephemeral data
|
||||||
// needed during the parsing.
|
// needed during the parsing.
|
||||||
type parseContext struct {
|
type parseContext struct {
|
||||||
@@ -415,7 +447,6 @@ type parseContext struct {
|
|||||||
errorLogger ErrorLogger
|
errorLogger ErrorLogger
|
||||||
tracedVariables map[string]bool // variables to be traced in the generated script
|
tracedVariables map[string]bool // variables to be traced in the generated script
|
||||||
variables map[string]variable
|
variables map[string]variable
|
||||||
varAssignments *varAssignmentScope
|
|
||||||
outputDir string
|
outputDir string
|
||||||
dependentModules map[string]*moduleInfo
|
dependentModules map[string]*moduleInfo
|
||||||
soongNamespaces map[string]map[string]bool
|
soongNamespaces map[string]map[string]bool
|
||||||
@@ -468,7 +499,6 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
|
|||||||
typeHints: make(map[string]starlarkType),
|
typeHints: make(map[string]starlarkType),
|
||||||
atTopOfMakefile: true,
|
atTopOfMakefile: true,
|
||||||
}
|
}
|
||||||
ctx.pushVarAssignments()
|
|
||||||
for _, item := range predefined {
|
for _, item := range predefined {
|
||||||
ctx.variables[item.name] = &predefinedVariable{
|
ctx.variables[item.name] = &predefinedVariable{
|
||||||
baseVariable: baseVariable{nam: item.name, typ: starlarkTypeString},
|
baseVariable: baseVariable{nam: item.name, typ: starlarkTypeString},
|
||||||
@@ -479,31 +509,6 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *parseContext) lastAssignment(v variable) *assignmentNode {
|
|
||||||
for va := ctx.varAssignments; va != nil; va = va.outer {
|
|
||||||
if v, ok := va.vars[v.name()]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *parseContext) setLastAssignment(v variable, asgn *assignmentNode) {
|
|
||||||
ctx.varAssignments.vars[v.name()] = asgn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *parseContext) pushVarAssignments() {
|
|
||||||
va := &varAssignmentScope{
|
|
||||||
outer: ctx.varAssignments,
|
|
||||||
vars: make(map[string]*assignmentNode),
|
|
||||||
}
|
|
||||||
ctx.varAssignments = va
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *parseContext) popVarAssignments() {
|
|
||||||
ctx.varAssignments = ctx.varAssignments.outer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *parseContext) hasNodes() bool {
|
func (ctx *parseContext) hasNodes() bool {
|
||||||
return ctx.currentNodeIndex < len(ctx.nodes)
|
return ctx.currentNodeIndex < len(ctx.nodes)
|
||||||
}
|
}
|
||||||
@@ -585,8 +590,6 @@ func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) []starlarkNode
|
|||||||
asgn.value = &toStringExpr{expr: asgn.value}
|
asgn.value = &toStringExpr{expr: asgn.value}
|
||||||
}
|
}
|
||||||
|
|
||||||
asgn.previous = ctx.lastAssignment(lhs)
|
|
||||||
ctx.setLastAssignment(lhs, asgn)
|
|
||||||
switch a.Type {
|
switch a.Type {
|
||||||
case "=", ":=":
|
case "=", ":=":
|
||||||
asgn.flavor = asgnSet
|
asgn.flavor = asgnSet
|
||||||
@@ -952,11 +955,8 @@ func (ctx *parseContext) handleIfBlock(ifDirective *mkparser.Directive) starlark
|
|||||||
func (ctx *parseContext) processBranch(check *mkparser.Directive) *switchCase {
|
func (ctx *parseContext) processBranch(check *mkparser.Directive) *switchCase {
|
||||||
block := &switchCase{gate: ctx.parseCondition(check)}
|
block := &switchCase{gate: ctx.parseCondition(check)}
|
||||||
defer func() {
|
defer func() {
|
||||||
ctx.popVarAssignments()
|
|
||||||
ctx.ifNestLevel--
|
ctx.ifNestLevel--
|
||||||
|
|
||||||
}()
|
}()
|
||||||
ctx.pushVarAssignments()
|
|
||||||
ctx.ifNestLevel++
|
ctx.ifNestLevel++
|
||||||
|
|
||||||
for ctx.hasNodes() {
|
for ctx.hasNodes() {
|
||||||
@@ -980,7 +980,7 @@ func (ctx *parseContext) parseCondition(check *mkparser.Directive) starlarkNode
|
|||||||
if !check.Args.Const() {
|
if !check.Args.Const() {
|
||||||
return ctx.newBadNode(check, "ifdef variable ref too complex: %s", check.Args.Dump())
|
return ctx.newBadNode(check, "ifdef variable ref too complex: %s", check.Args.Dump())
|
||||||
}
|
}
|
||||||
v := NewVariableRefExpr(ctx.addVariable(check.Args.Strings[0]), false)
|
v := NewVariableRefExpr(ctx.addVariable(check.Args.Strings[0]))
|
||||||
if strings.HasSuffix(check.Name, "ndef") {
|
if strings.HasSuffix(check.Name, "ndef") {
|
||||||
v = ¬Expr{v}
|
v = ¬Expr{v}
|
||||||
}
|
}
|
||||||
@@ -1293,12 +1293,12 @@ func (ctx *parseContext) parseReference(node mkparser.Node, ref *mkparser.MakeSt
|
|||||||
args: []starlarkExpr{
|
args: []starlarkExpr{
|
||||||
&stringLiteralExpr{literal: substParts[0]},
|
&stringLiteralExpr{literal: substParts[0]},
|
||||||
&stringLiteralExpr{literal: substParts[1]},
|
&stringLiteralExpr{literal: substParts[1]},
|
||||||
NewVariableRefExpr(v, ctx.lastAssignment(v) != nil),
|
NewVariableRefExpr(v),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v := ctx.addVariable(refDump); v != nil {
|
if v := ctx.addVariable(refDump); v != nil {
|
||||||
return NewVariableRefExpr(v, ctx.lastAssignment(v) != nil)
|
return NewVariableRefExpr(v)
|
||||||
}
|
}
|
||||||
return ctx.newBadExpr(node, "unknown variable %s", refDump)
|
return ctx.newBadExpr(node, "unknown variable %s", refDump)
|
||||||
}
|
}
|
||||||
@@ -1394,7 +1394,7 @@ func (p *isProductInListCallParser) parse(ctx *parseContext, node mkparser.Node,
|
|||||||
return ctx.newBadExpr(node, "is-product-in-list requires an argument")
|
return ctx.newBadExpr(node, "is-product-in-list requires an argument")
|
||||||
}
|
}
|
||||||
return &inExpr{
|
return &inExpr{
|
||||||
expr: &variableRefExpr{ctx.addVariable("TARGET_PRODUCT"), true},
|
expr: NewVariableRefExpr(ctx.addVariable("TARGET_PRODUCT")),
|
||||||
list: maybeConvertToStringList(ctx.parseMakeString(node, args)),
|
list: maybeConvertToStringList(ctx.parseMakeString(node, args)),
|
||||||
isNot: false,
|
isNot: false,
|
||||||
}
|
}
|
||||||
@@ -1407,8 +1407,8 @@ func (p *isVendorBoardPlatformCallParser) parse(ctx *parseContext, node mkparser
|
|||||||
return ctx.newBadExpr(node, "cannot handle non-constant argument to is-vendor-board-platform")
|
return ctx.newBadExpr(node, "cannot handle non-constant argument to is-vendor-board-platform")
|
||||||
}
|
}
|
||||||
return &inExpr{
|
return &inExpr{
|
||||||
expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
|
expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM")),
|
||||||
list: &variableRefExpr{ctx.addVariable(args.Dump() + "_BOARD_PLATFORMS"), true},
|
list: NewVariableRefExpr(ctx.addVariable(args.Dump() + "_BOARD_PLATFORMS")),
|
||||||
isNot: false,
|
isNot: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1420,8 +1420,8 @@ func (p *isVendorBoardQcomCallParser) parse(ctx *parseContext, node mkparser.Nod
|
|||||||
return ctx.newBadExpr(node, "is-vendor-board-qcom does not accept any arguments")
|
return ctx.newBadExpr(node, "is-vendor-board-qcom does not accept any arguments")
|
||||||
}
|
}
|
||||||
return &inExpr{
|
return &inExpr{
|
||||||
expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
|
expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM")),
|
||||||
list: &variableRefExpr{ctx.addVariable("QCOM_BOARD_PLATFORMS"), true},
|
list: NewVariableRefExpr(ctx.addVariable("QCOM_BOARD_PLATFORMS")),
|
||||||
isNot: false,
|
isNot: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -642,7 +642,7 @@ def init(g, handle):
|
|||||||
pass
|
pass
|
||||||
elif not rblf.board_platform_is(g, "copper"):
|
elif not rblf.board_platform_is(g, "copper"):
|
||||||
pass
|
pass
|
||||||
elif g.get("TARGET_BOARD_PLATFORM", "") not in g["QCOM_BOARD_PLATFORMS"]:
|
elif g.get("TARGET_BOARD_PLATFORM", "") not in g.get("QCOM_BOARD_PLATFORMS", ""):
|
||||||
pass
|
pass
|
||||||
elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
|
elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
|
||||||
pass
|
pass
|
||||||
@@ -665,7 +665,7 @@ def init(g, handle):
|
|||||||
pass
|
pass
|
||||||
elif not rblf.board_platform_is(g, "copper"):
|
elif not rblf.board_platform_is(g, "copper"):
|
||||||
pass
|
pass
|
||||||
elif g.get("TARGET_BOARD_PLATFORM", "") in g["QCOM_BOARD_PLATFORMS"]:
|
elif g.get("TARGET_BOARD_PLATFORM", "") in g.get("QCOM_BOARD_PLATFORMS", ""):
|
||||||
pass
|
pass
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
@@ -196,7 +196,6 @@ type assignmentNode struct {
|
|||||||
flavor assignmentFlavor
|
flavor assignmentFlavor
|
||||||
location ErrorLocation
|
location ErrorLocation
|
||||||
isTraced bool
|
isTraced bool
|
||||||
previous *assignmentNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (asgn *assignmentNode) emit(gctx *generationContext) {
|
func (asgn *assignmentNode) emit(gctx *generationContext) {
|
||||||
@@ -209,7 +208,7 @@ func (asgn *assignmentNode) emit(gctx *generationContext) {
|
|||||||
gctx.newLine()
|
gctx.newLine()
|
||||||
gctx.tracedCount++
|
gctx.tracedCount++
|
||||||
gctx.writef(`print("%s.%d: %s := ", `, gctx.starScript.mkFile, gctx.tracedCount, asgn.lhs.name())
|
gctx.writef(`print("%s.%d: %s := ", `, gctx.starScript.mkFile, gctx.tracedCount, asgn.lhs.name())
|
||||||
asgn.lhs.emitGet(gctx, true)
|
asgn.lhs.emitGet(gctx)
|
||||||
gctx.writef(")")
|
gctx.writef(")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,6 +270,7 @@ type switchCase struct {
|
|||||||
func (cb *switchCase) emit(gctx *generationContext) {
|
func (cb *switchCase) emit(gctx *generationContext) {
|
||||||
cb.gate.emit(gctx)
|
cb.gate.emit(gctx)
|
||||||
gctx.indentLevel++
|
gctx.indentLevel++
|
||||||
|
gctx.pushVariableAssignments()
|
||||||
hasStatements := false
|
hasStatements := false
|
||||||
for _, node := range cb.nodes {
|
for _, node := range cb.nodes {
|
||||||
if _, ok := node.(*commentNode); !ok {
|
if _, ok := node.(*commentNode); !ok {
|
||||||
@@ -282,6 +282,7 @@ func (cb *switchCase) emit(gctx *generationContext) {
|
|||||||
gctx.emitPass()
|
gctx.emitPass()
|
||||||
}
|
}
|
||||||
gctx.indentLevel--
|
gctx.indentLevel--
|
||||||
|
gctx.popVariableAssignments()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A single complete if ... elseif ... else ... endif sequences
|
// A single complete if ... elseif ... else ... endif sequences
|
||||||
@@ -302,6 +303,7 @@ type foreachNode struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *foreachNode) emit(gctx *generationContext) {
|
func (f *foreachNode) emit(gctx *generationContext) {
|
||||||
|
gctx.pushVariableAssignments()
|
||||||
gctx.newLine()
|
gctx.newLine()
|
||||||
gctx.writef("for %s in ", f.varName)
|
gctx.writef("for %s in ", f.varName)
|
||||||
f.list.emit(gctx)
|
f.list.emit(gctx)
|
||||||
@@ -318,4 +320,5 @@ func (f *foreachNode) emit(gctx *generationContext) {
|
|||||||
gctx.emitPass()
|
gctx.emitPass()
|
||||||
}
|
}
|
||||||
gctx.indentLevel--
|
gctx.indentLevel--
|
||||||
|
gctx.popVariableAssignments()
|
||||||
}
|
}
|
||||||
|
@@ -21,9 +21,8 @@ import (
|
|||||||
|
|
||||||
type variable interface {
|
type variable interface {
|
||||||
name() string
|
name() string
|
||||||
emitGet(gctx *generationContext, isDefined bool)
|
emitGet(gctx *generationContext)
|
||||||
emitSet(gctx *generationContext, asgn *assignmentNode)
|
emitSet(gctx *generationContext, asgn *assignmentNode)
|
||||||
emitDefined(gctx *generationContext)
|
|
||||||
valueType() starlarkType
|
valueType() starlarkType
|
||||||
setValueType(t starlarkType)
|
setValueType(t starlarkType)
|
||||||
defaultValueString() string
|
defaultValueString() string
|
||||||
@@ -74,13 +73,11 @@ type productConfigVariable struct {
|
|||||||
|
|
||||||
func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
|
func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
|
||||||
emitAssignment := func() {
|
emitAssignment := func() {
|
||||||
pcv.emitGet(gctx, true)
|
gctx.writef("cfg[%q] = ", pcv.nam)
|
||||||
gctx.write(" = ")
|
|
||||||
asgn.value.emitListVarCopy(gctx)
|
asgn.value.emitListVarCopy(gctx)
|
||||||
}
|
}
|
||||||
emitAppend := func() {
|
emitAppend := func() {
|
||||||
pcv.emitGet(gctx, true)
|
gctx.writef("cfg[%q] += ", pcv.nam)
|
||||||
gctx.write(" += ")
|
|
||||||
value := asgn.value
|
value := asgn.value
|
||||||
if pcv.valueType() == starlarkTypeString {
|
if pcv.valueType() == starlarkTypeString {
|
||||||
gctx.writef(`" " + `)
|
gctx.writef(`" " + `)
|
||||||
@@ -98,7 +95,7 @@ func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignme
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we are not sure variable has been assigned before, emit setdefault
|
// If we are not sure variable has been assigned before, emit setdefault
|
||||||
needsSetDefault := asgn.previous == nil && !pcv.isPreset() && asgn.isSelfReferential()
|
needsSetDefault := !gctx.hasBeenAssigned(&pcv) && !pcv.isPreset() && asgn.isSelfReferential()
|
||||||
|
|
||||||
switch asgn.flavor {
|
switch asgn.flavor {
|
||||||
case asgnSet:
|
case asgnSet:
|
||||||
@@ -121,34 +118,30 @@ func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignme
|
|||||||
emitAssignment()
|
emitAssignment()
|
||||||
gctx.indentLevel--
|
gctx.indentLevel--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gctx.setHasBeenAssigned(&pcv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pcv productConfigVariable) emitGet(gctx *generationContext, isDefined bool) {
|
func (pcv productConfigVariable) emitGet(gctx *generationContext) {
|
||||||
if isDefined || pcv.isPreset() {
|
if gctx.hasBeenAssigned(&pcv) || pcv.isPreset() {
|
||||||
gctx.writef("cfg[%q]", pcv.nam)
|
gctx.writef("cfg[%q]", pcv.nam)
|
||||||
} else {
|
} else {
|
||||||
gctx.writef("cfg.get(%q, %s)", pcv.nam, pcv.defaultValueString())
|
gctx.writef("cfg.get(%q, %s)", pcv.nam, pcv.defaultValueString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pcv productConfigVariable) emitDefined(gctx *generationContext) {
|
|
||||||
gctx.writef("cfg.get(%q) != None", pcv.name())
|
|
||||||
}
|
|
||||||
|
|
||||||
type otherGlobalVariable struct {
|
type otherGlobalVariable struct {
|
||||||
baseVariable
|
baseVariable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
|
func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
|
||||||
emitAssignment := func() {
|
emitAssignment := func() {
|
||||||
scv.emitGet(gctx, true)
|
gctx.writef("g[%q] = ", scv.nam)
|
||||||
gctx.write(" = ")
|
|
||||||
asgn.value.emitListVarCopy(gctx)
|
asgn.value.emitListVarCopy(gctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
emitAppend := func() {
|
emitAppend := func() {
|
||||||
scv.emitGet(gctx, true)
|
gctx.writef("g[%q] += ", scv.nam)
|
||||||
gctx.write(" += ")
|
|
||||||
value := asgn.value
|
value := asgn.value
|
||||||
if scv.valueType() == starlarkTypeString {
|
if scv.valueType() == starlarkTypeString {
|
||||||
gctx.writef(`" " + `)
|
gctx.writef(`" " + `)
|
||||||
@@ -158,7 +151,7 @@ func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignment
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we are not sure variable has been assigned before, emit setdefault
|
// If we are not sure variable has been assigned before, emit setdefault
|
||||||
needsSetDefault := asgn.previous == nil && !scv.isPreset() && asgn.isSelfReferential()
|
needsSetDefault := !gctx.hasBeenAssigned(&scv) && !scv.isPreset() && asgn.isSelfReferential()
|
||||||
|
|
||||||
switch asgn.flavor {
|
switch asgn.flavor {
|
||||||
case asgnSet:
|
case asgnSet:
|
||||||
@@ -184,28 +177,22 @@ func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignment
|
|||||||
emitAssignment()
|
emitAssignment()
|
||||||
gctx.indentLevel--
|
gctx.indentLevel--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gctx.setHasBeenAssigned(&scv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scv otherGlobalVariable) emitGet(gctx *generationContext, isDefined bool) {
|
func (scv otherGlobalVariable) emitGet(gctx *generationContext) {
|
||||||
if isDefined || scv.isPreset() {
|
if gctx.hasBeenAssigned(&scv) || scv.isPreset() {
|
||||||
gctx.writef("g[%q]", scv.nam)
|
gctx.writef("g[%q]", scv.nam)
|
||||||
} else {
|
} else {
|
||||||
gctx.writef("g.get(%q, %s)", scv.nam, scv.defaultValueString())
|
gctx.writef("g.get(%q, %s)", scv.nam, scv.defaultValueString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scv otherGlobalVariable) emitDefined(gctx *generationContext) {
|
|
||||||
gctx.writef("g.get(%q) != None", scv.name())
|
|
||||||
}
|
|
||||||
|
|
||||||
type localVariable struct {
|
type localVariable struct {
|
||||||
baseVariable
|
baseVariable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lv localVariable) emitDefined(gctx *generationContext) {
|
|
||||||
gctx.writef(lv.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lv localVariable) String() string {
|
func (lv localVariable) String() string {
|
||||||
return "_" + lv.nam
|
return "_" + lv.nam
|
||||||
}
|
}
|
||||||
@@ -216,8 +203,7 @@ func (lv localVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
|
|||||||
gctx.writef("%s = ", lv)
|
gctx.writef("%s = ", lv)
|
||||||
asgn.value.emitListVarCopy(gctx)
|
asgn.value.emitListVarCopy(gctx)
|
||||||
case asgnAppend:
|
case asgnAppend:
|
||||||
lv.emitGet(gctx, false)
|
gctx.writef("%s += ", lv)
|
||||||
gctx.write(" += ")
|
|
||||||
value := asgn.value
|
value := asgn.value
|
||||||
if lv.valueType() == starlarkTypeString {
|
if lv.valueType() == starlarkTypeString {
|
||||||
gctx.writef(`" " + `)
|
gctx.writef(`" " + `)
|
||||||
@@ -227,7 +213,7 @@ func (lv localVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lv localVariable) emitGet(gctx *generationContext, _ bool) {
|
func (lv localVariable) emitGet(gctx *generationContext) {
|
||||||
gctx.writef("%s", lv)
|
gctx.writef("%s", lv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +222,7 @@ type predefinedVariable struct {
|
|||||||
value starlarkExpr
|
value starlarkExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pv predefinedVariable) emitGet(gctx *generationContext, _ bool) {
|
func (pv predefinedVariable) emitGet(gctx *generationContext) {
|
||||||
pv.value.emit(gctx)
|
pv.value.emit(gctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,10 +243,6 @@ func (pv predefinedVariable) emitSet(gctx *generationContext, asgn *assignmentNo
|
|||||||
panic(fmt.Errorf("cannot set predefined variable %s to %q", pv.name(), asgn.mkValue.Dump()))
|
panic(fmt.Errorf("cannot set predefined variable %s to %q", pv.name(), asgn.mkValue.Dump()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pv predefinedVariable) emitDefined(gctx *generationContext) {
|
|
||||||
gctx.write("True")
|
|
||||||
}
|
|
||||||
|
|
||||||
var localProductConfigVariables = map[string]string{
|
var localProductConfigVariables = map[string]string{
|
||||||
"LOCAL_AUDIO_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
|
"LOCAL_AUDIO_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
|
||||||
"LOCAL_AUDIO_PRODUCT_COPY_FILES": "PRODUCT_COPY_FILES",
|
"LOCAL_AUDIO_PRODUCT_COPY_FILES": "PRODUCT_COPY_FILES",
|
||||||
|
Reference in New Issue
Block a user