|
@@ -195,17 +195,57 @@ func isMakeControlFunc(s string) bool {
|
|
|
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
|
|
|
type generationContext struct {
|
|
|
- buf strings.Builder
|
|
|
- starScript *StarlarkScript
|
|
|
- indentLevel int
|
|
|
- inAssignment bool
|
|
|
- tracedCount int
|
|
|
+ buf strings.Builder
|
|
|
+ starScript *StarlarkScript
|
|
|
+ indentLevel int
|
|
|
+ inAssignment bool
|
|
|
+ tracedCount int
|
|
|
+ varAssignments *varAssignmentScope
|
|
|
}
|
|
|
|
|
|
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
|
|
@@ -392,14 +432,6 @@ type StarlarkScript struct {
|
|
|
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
|
|
|
// needed during the parsing.
|
|
|
type parseContext struct {
|
|
@@ -413,7 +445,6 @@ type parseContext struct {
|
|
|
errorLogger ErrorLogger
|
|
|
tracedVariables map[string]bool // variables to be traced in the generated script
|
|
|
variables map[string]variable
|
|
|
- varAssignments *varAssignmentScope
|
|
|
outputDir string
|
|
|
dependentModules map[string]*moduleInfo
|
|
|
soongNamespaces map[string]map[string]bool
|
|
@@ -466,7 +497,6 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
|
|
|
typeHints: make(map[string]starlarkType),
|
|
|
atTopOfMakefile: true,
|
|
|
}
|
|
|
- ctx.pushVarAssignments()
|
|
|
for _, item := range predefined {
|
|
|
ctx.variables[item.name] = &predefinedVariable{
|
|
|
baseVariable: baseVariable{nam: item.name, typ: starlarkTypeString},
|
|
@@ -477,31 +507,6 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
|
|
|
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 {
|
|
|
return ctx.currentNodeIndex < len(ctx.nodes)
|
|
|
}
|
|
@@ -583,8 +588,6 @@ func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) []starlarkNode
|
|
|
asgn.value = &toStringExpr{expr: asgn.value}
|
|
|
}
|
|
|
|
|
|
- asgn.previous = ctx.lastAssignment(lhs)
|
|
|
- ctx.setLastAssignment(lhs, asgn)
|
|
|
switch a.Type {
|
|
|
case "=", ":=":
|
|
|
asgn.flavor = asgnSet
|
|
@@ -939,11 +942,8 @@ func (ctx *parseContext) handleIfBlock(ifDirective *mkparser.Directive) starlark
|
|
|
func (ctx *parseContext) processBranch(check *mkparser.Directive) *switchCase {
|
|
|
block := &switchCase{gate: ctx.parseCondition(check)}
|
|
|
defer func() {
|
|
|
- ctx.popVarAssignments()
|
|
|
ctx.ifNestLevel--
|
|
|
-
|
|
|
}()
|
|
|
- ctx.pushVarAssignments()
|
|
|
ctx.ifNestLevel++
|
|
|
|
|
|
for ctx.hasNodes() {
|
|
@@ -967,7 +967,7 @@ func (ctx *parseContext) parseCondition(check *mkparser.Directive) starlarkNode
|
|
|
if !check.Args.Const() {
|
|
|
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") {
|
|
|
v = ¬Expr{v}
|
|
|
}
|
|
@@ -1280,12 +1280,12 @@ func (ctx *parseContext) parseReference(node mkparser.Node, ref *mkparser.MakeSt
|
|
|
args: []starlarkExpr{
|
|
|
&stringLiteralExpr{literal: substParts[0]},
|
|
|
&stringLiteralExpr{literal: substParts[1]},
|
|
|
- NewVariableRefExpr(v, ctx.lastAssignment(v) != nil),
|
|
|
+ NewVariableRefExpr(v),
|
|
|
},
|
|
|
}
|
|
|
}
|
|
|
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)
|
|
|
}
|
|
@@ -1381,7 +1381,7 @@ func (p *isProductInListCallParser) parse(ctx *parseContext, node mkparser.Node,
|
|
|
return ctx.newBadExpr(node, "is-product-in-list requires an argument")
|
|
|
}
|
|
|
return &inExpr{
|
|
|
- expr: &variableRefExpr{ctx.addVariable("TARGET_PRODUCT"), true},
|
|
|
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_PRODUCT")),
|
|
|
list: maybeConvertToStringList(ctx.parseMakeString(node, args)),
|
|
|
isNot: false,
|
|
|
}
|
|
@@ -1394,8 +1394,8 @@ func (p *isVendorBoardPlatformCallParser) parse(ctx *parseContext, node mkparser
|
|
|
return ctx.newBadExpr(node, "cannot handle non-constant argument to is-vendor-board-platform")
|
|
|
}
|
|
|
return &inExpr{
|
|
|
- expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
|
|
|
- list: &variableRefExpr{ctx.addVariable(args.Dump() + "_BOARD_PLATFORMS"), true},
|
|
|
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM")),
|
|
|
+ list: NewVariableRefExpr(ctx.addVariable(args.Dump() + "_BOARD_PLATFORMS")),
|
|
|
isNot: false,
|
|
|
}
|
|
|
}
|
|
@@ -1407,8 +1407,8 @@ func (p *isVendorBoardQcomCallParser) parse(ctx *parseContext, node mkparser.Nod
|
|
|
return ctx.newBadExpr(node, "is-vendor-board-qcom does not accept any arguments")
|
|
|
}
|
|
|
return &inExpr{
|
|
|
- expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
|
|
|
- list: &variableRefExpr{ctx.addVariable("QCOM_BOARD_PLATFORMS"), true},
|
|
|
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM")),
|
|
|
+ list: NewVariableRefExpr(ctx.addVariable("QCOM_BOARD_PLATFORMS")),
|
|
|
isNot: false,
|
|
|
}
|
|
|
}
|