Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34ce0f3b authored by Cole Faust's avatar Cole Faust Committed by Automerger Merge Worker
Browse files

Merge "Move variable assignment handling to generation context" am: 7cd255fa

parents 993e6006 7cd255fa
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -233,18 +233,17 @@ func (xi *interpolateExpr) transform(transformer func(expr starlarkExpr) starlar

type variableRefExpr struct {
	ref variable
	isDefined bool
}

func NewVariableRefExpr(ref variable, isDefined bool) starlarkExpr {
func NewVariableRefExpr(ref variable) starlarkExpr {
	if predefined, ok := ref.(*predefinedVariable); ok {
		return predefined.value
	}
	return &variableRefExpr{ref, isDefined}
	return &variableRefExpr{ref}
}

func (v *variableRefExpr) emit(gctx *generationContext) {
	v.ref.emitGet(gctx, v.isDefined)
	v.ref.emitGet(gctx)
}

func (v *variableRefExpr) typ() starlarkType {
+54 −54
Original line number Diff line number Diff line
@@ -197,6 +197,14 @@ 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
@@ -204,10 +212,42 @@ type generationContext struct {
	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
@@ -394,14 +434,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 {
@@ -415,7 +447,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
@@ -468,7 +499,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},
@@ -479,31 +509,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)
}
@@ -585,8 +590,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
@@ -952,11 +955,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() {
@@ -980,7 +980,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 = &notExpr{v}
		}
@@ -1293,12 +1293,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)
	}
@@ -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 &inExpr{
		expr:  &variableRefExpr{ctx.addVariable("TARGET_PRODUCT"), true},
		expr:  NewVariableRefExpr(ctx.addVariable("TARGET_PRODUCT")),
		list:  maybeConvertToStringList(ctx.parseMakeString(node, args)),
		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 &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,
	}
}
@@ -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 &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,
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -642,7 +642,7 @@ def init(g, handle):
    pass
  elif not rblf.board_platform_is(g, "copper"):
    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
  elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
    pass
@@ -665,7 +665,7 @@ def init(g, handle):
    pass
  elif not rblf.board_platform_is(g, "copper"):
    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
`,
	},
+5 −2
Original line number Diff line number Diff line
@@ -196,7 +196,6 @@ type assignmentNode struct {
	flavor   assignmentFlavor
	location ErrorLocation
	isTraced bool
	previous *assignmentNode
}

func (asgn *assignmentNode) emit(gctx *generationContext) {
@@ -209,7 +208,7 @@ func (asgn *assignmentNode) emit(gctx *generationContext) {
		gctx.newLine()
		gctx.tracedCount++
		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(")")
	}
}
@@ -271,6 +270,7 @@ type switchCase struct {
func (cb *switchCase) emit(gctx *generationContext) {
	cb.gate.emit(gctx)
	gctx.indentLevel++
	gctx.pushVariableAssignments()
	hasStatements := false
	for _, node := range cb.nodes {
		if _, ok := node.(*commentNode); !ok {
@@ -282,6 +282,7 @@ func (cb *switchCase) emit(gctx *generationContext) {
		gctx.emitPass()
	}
	gctx.indentLevel--
	gctx.popVariableAssignments()
}

// A single complete if ... elseif ... else ... endif sequences
@@ -302,6 +303,7 @@ type foreachNode struct {
}

func (f *foreachNode) emit(gctx *generationContext) {
	gctx.pushVariableAssignments()
	gctx.newLine()
	gctx.writef("for %s in ", f.varName)
	f.list.emit(gctx)
@@ -318,4 +320,5 @@ func (f *foreachNode) emit(gctx *generationContext) {
		gctx.emitPass()
	}
	gctx.indentLevel--
	gctx.popVariableAssignments()
}
+18 −36
Original line number Diff line number Diff line
@@ -21,9 +21,8 @@ import (

type variable interface {
	name() string
	emitGet(gctx *generationContext, isDefined bool)
	emitGet(gctx *generationContext)
	emitSet(gctx *generationContext, asgn *assignmentNode)
	emitDefined(gctx *generationContext)
	valueType() starlarkType
	setValueType(t starlarkType)
	defaultValueString() string
@@ -74,13 +73,11 @@ type productConfigVariable struct {

func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
	emitAssignment := func() {
		pcv.emitGet(gctx, true)
		gctx.write(" = ")
		gctx.writef("cfg[%q] = ", pcv.nam)
		asgn.value.emitListVarCopy(gctx)
	}
	emitAppend := func() {
		pcv.emitGet(gctx, true)
		gctx.write(" += ")
		gctx.writef("cfg[%q] += ", pcv.nam)
		value := asgn.value
		if pcv.valueType() == starlarkTypeString {
			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
	needsSetDefault := asgn.previous == nil && !pcv.isPreset() && asgn.isSelfReferential()
	needsSetDefault := !gctx.hasBeenAssigned(&pcv) && !pcv.isPreset() && asgn.isSelfReferential()

	switch asgn.flavor {
	case asgnSet:
@@ -121,34 +118,30 @@ func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignme
		emitAssignment()
		gctx.indentLevel--
	}

	gctx.setHasBeenAssigned(&pcv)
}

func (pcv productConfigVariable) emitGet(gctx *generationContext, isDefined bool) {
	if isDefined || pcv.isPreset() {
func (pcv productConfigVariable) emitGet(gctx *generationContext) {
	if gctx.hasBeenAssigned(&pcv) || pcv.isPreset() {
		gctx.writef("cfg[%q]", pcv.nam)
	} else {
		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 {
	baseVariable
}

func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
	emitAssignment := func() {
		scv.emitGet(gctx, true)
		gctx.write(" = ")
		gctx.writef("g[%q] = ", scv.nam)
		asgn.value.emitListVarCopy(gctx)
	}

	emitAppend := func() {
		scv.emitGet(gctx, true)
		gctx.write(" += ")
		gctx.writef("g[%q] += ", scv.nam)
		value := asgn.value
		if scv.valueType() == starlarkTypeString {
			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
	needsSetDefault := asgn.previous == nil && !scv.isPreset() && asgn.isSelfReferential()
	needsSetDefault := !gctx.hasBeenAssigned(&scv) && !scv.isPreset() && asgn.isSelfReferential()

	switch asgn.flavor {
	case asgnSet:
@@ -184,28 +177,22 @@ func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignment
		emitAssignment()
		gctx.indentLevel--
	}

	gctx.setHasBeenAssigned(&scv)
}

func (scv otherGlobalVariable) emitGet(gctx *generationContext, isDefined bool) {
	if isDefined || scv.isPreset() {
func (scv otherGlobalVariable) emitGet(gctx *generationContext) {
	if gctx.hasBeenAssigned(&scv) || scv.isPreset() {
		gctx.writef("g[%q]", scv.nam)
	} else {
		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 {
	baseVariable
}

func (lv localVariable) emitDefined(gctx *generationContext) {
	gctx.writef(lv.String())
}

func (lv localVariable) String() string {
	return "_" + lv.nam
}
@@ -216,8 +203,7 @@ func (lv localVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
		gctx.writef("%s = ", lv)
		asgn.value.emitListVarCopy(gctx)
	case asgnAppend:
		lv.emitGet(gctx, false)
		gctx.write(" += ")
		gctx.writef("%s += ", lv)
		value := asgn.value
		if lv.valueType() == starlarkTypeString {
			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)
}

@@ -236,7 +222,7 @@ type predefinedVariable struct {
	value starlarkExpr
}

func (pv predefinedVariable) emitGet(gctx *generationContext, _ bool) {
func (pv predefinedVariable) emitGet(gctx *generationContext) {
	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()))
}

func (pv predefinedVariable) emitDefined(gctx *generationContext) {
	gctx.write("True")
}

var localProductConfigVariables = map[string]string{
	"LOCAL_AUDIO_PRODUCT_PACKAGE":         "PRODUCT_PACKAGES",
	"LOCAL_AUDIO_PRODUCT_COPY_FILES":      "PRODUCT_COPY_FILES",