Check missing uncoditionally loaded missing modules at runtime
A potentially inherited (via dynamically calculated path) module may in turn
unconditionally load a module that does no exist in a source tree -- it is
not an error if this potentially inherited module is actually never inherited
because its dynamically calculated path will never reference it. Instead of
emitting an uncoditional `load` for a non-existent file (which is going to fail
in the Starlark parser), emit conditional load and a runtime check.
Fixes: 213922819
Test: internal
Change-Id: I92177878e199a1f00e5f0c4045c0c0daeddd6bdb
diff --git a/mk2rbc/node.go b/mk2rbc/node.go
index ebc57b2..333a8da 100644
--- a/mk2rbc/node.go
+++ b/mk2rbc/node.go
@@ -47,6 +47,7 @@
originalPath string // Makefile file path
moduleLocalName string
optional bool
+ missing bool // a module may not exist if a module that depends on it is loaded dynamically
}
func (im moduleInfo) entryName() string {
@@ -57,7 +58,8 @@
name() string
entryName() string
emitSelect(gctx *generationContext)
- shouldExist() bool
+ pathExpr() starlarkExpr
+ needsLoadCheck() bool
}
type inheritedStaticModule struct {
@@ -72,8 +74,12 @@
func (im inheritedStaticModule) emitSelect(_ *generationContext) {
}
-func (im inheritedStaticModule) shouldExist() bool {
- return im.loadAlways
+func (im inheritedStaticModule) pathExpr() starlarkExpr {
+ return &stringLiteralExpr{im.path}
+}
+
+func (im inheritedStaticModule) needsLoadCheck() bool {
+ return im.missing
}
type inheritedDynamicModule struct {
@@ -105,20 +111,14 @@
gctx.write(")")
gctx.newLine()
gctx.writef("(%s, %s) = _entry if _entry else (None, None)", i.name(), i.entryName())
- if i.loadAlways {
- gctx.newLine()
- gctx.writef("if not %s:", i.entryName())
- gctx.indentLevel++
- gctx.newLine()
- gctx.write(`rblf.mkerror("`, gctx.starScript.mkFile, `", "Cannot find %s" % (`)
- i.path.emit(gctx)
- gctx.write("))")
- gctx.indentLevel--
- }
}
-func (i inheritedDynamicModule) shouldExist() bool {
- return i.loadAlways
+func (i inheritedDynamicModule) pathExpr() starlarkExpr {
+ return &i.path
+}
+
+func (i inheritedDynamicModule) needsLoadCheck() bool {
+ return true
}
type inheritNode struct {
@@ -128,20 +128,22 @@
func (inn *inheritNode) emit(gctx *generationContext) {
// Unconditional case:
+ // maybe check that loaded
// rblf.inherit(handle, <module>, module_init)
// Conditional case:
// if <module>_init != None:
// same as above
inn.module.emitSelect(gctx)
-
name := inn.module.name()
entry := inn.module.entryName()
- gctx.newLine()
if inn.loadAlways {
+ gctx.emitLoadCheck(inn.module)
+ gctx.newLine()
gctx.writef("%s(handle, %s, %s)", cfnInherit, name, entry)
return
}
+ gctx.newLine()
gctx.writef("if %s:", entry)
gctx.indentLevel++
gctx.newLine()
@@ -157,12 +159,14 @@
func (inn *includeNode) emit(gctx *generationContext) {
inn.module.emitSelect(gctx)
entry := inn.module.entryName()
- gctx.newLine()
if inn.loadAlways {
+ gctx.emitLoadCheck(inn.module)
+ gctx.newLine()
gctx.writef("%s(g, handle)", entry)
return
}
+ gctx.newLine()
gctx.writef("if %s != None:", entry)
gctx.indentLevel++
gctx.newLine()