Merge "Add type hints to mk2rbc"

This commit is contained in:
Treehugger Robot
2022-03-16 00:40:11 +00:00
committed by Gerrit Code Review
3 changed files with 98 additions and 5 deletions

View File

@@ -407,6 +407,8 @@ type parseContext struct {
dependentModules map[string]*moduleInfo
soongNamespaces map[string]map[string]bool
includeTops []string
typeHints map[string]starlarkType
atTopOfMakefile bool
}
func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
@@ -450,6 +452,8 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
dependentModules: make(map[string]*moduleInfo),
soongNamespaces: make(map[string]map[string]bool),
includeTops: []string{},
typeHints: make(map[string]starlarkType),
atTopOfMakefile: true,
}
ctx.pushVarAssignments()
for _, item := range predefined {
@@ -1680,7 +1684,8 @@ func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) []starlarkNod
// Clear the includeTops after each non-comment statement
// so that include annotations placed on certain statements don't apply
// globally for the rest of the makefile was well.
if _, wasComment := node.(*mkparser.Comment); !wasComment && len(ctx.includeTops) > 0 {
if _, wasComment := node.(*mkparser.Comment); !wasComment {
ctx.atTopOfMakefile = false
ctx.includeTops = []string{}
}
@@ -1690,6 +1695,12 @@ func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) []starlarkNod
return result
}
// The types allowed in a type_hint
var typeHintMap = map[string]starlarkType{
"string": starlarkTypeString,
"list": starlarkTypeList,
}
// Processes annotation. An annotation is a comment that starts with #RBC# and provides
// a conversion hint -- say, where to look for the dynamically calculated inherit/include
// paths. Returns true if the comment was a successfully-handled annotation.
@@ -1714,6 +1725,35 @@ func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) (starlar
}
ctx.includeTops = append(ctx.includeTops, p)
return nil, true
} else if p, ok := maybeTrim(annotation, "type_hint"); ok {
// Type hints must come at the beginning the file, to avoid confusion
// if a type hint was specified later and thus only takes effect for half
// of the file.
if !ctx.atTopOfMakefile {
return ctx.newBadNode(cnode, "type_hint annotations must come before the first Makefile statement"), true
}
parts := strings.Fields(p)
if len(parts) <= 1 {
return ctx.newBadNode(cnode, "Invalid type_hint annotation: %s. Must be a variable type followed by a list of variables of that type", p), true
}
var varType starlarkType
if varType, ok = typeHintMap[parts[0]]; !ok {
varType = starlarkTypeUnknown
}
if varType == starlarkTypeUnknown {
return ctx.newBadNode(cnode, "Invalid type_hint annotation. Only list/string types are accepted, found %s", parts[0]), true
}
for _, name := range parts[1:] {
// Don't allow duplicate type hints
if _, ok := ctx.typeHints[name]; ok {
return ctx.newBadNode(cnode, "Duplicate type hint for variable %s", name), true
}
ctx.typeHints[name] = varType
}
return nil, true
}
return ctx.newBadNode(cnode, "unsupported annotation %s", cnode.Comment), true
}