From aae714db6ba02ed92e461da9dd7823e5b05de167 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Thu, 22 Nov 2018 16:49:30 -0500 Subject: [PATCH] lang: Add a top-level stmt safety method This adds a new method to the *StmtProg that lets us determine if the prog contains only what is necessary for a scope and nothing more. This is useful because that is exactly what is produced when doing an import. With this detection method, we can know if a module contains dead code that might mislead the user into thinking it will get run when it won't. --- lang/structs.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lang/structs.go b/lang/structs.go index aedc8546..7688d5c0 100644 --- a/lang/structs.go +++ b/lang/structs.go @@ -1542,6 +1542,33 @@ func (obj *StmtProg) Output() (*interfaces.Output, error) { }, nil } +// IsModuleUnsafe returns whether or not this StmtProg is unsafe to consume as a +// module scope. IOW, if someone writes a module which is imported and which has +// statements other than bind, func, class or import, then it is not correct to +// import, since those other elements wouldn't be used, and might provide a +// false belief that they'll get included when mgmt imports that module. +// SetScope should be called before this is used. (TODO: verify this) +// TODO: return a multierr with all the unsafe elements, to provide better info +// TODO: technically this could be a method on Stmt, possibly using Apply... +func (obj *StmtProg) IsModuleUnsafe() error { // TODO: rename this function? + for _, x := range obj.Prog { + // stmt's allowed: import, bind, func, class + // stmt's not-allowed: if, include, res, edge + switch x.(type) { + case *StmtImport: + case *StmtBind: + case *StmtFunc: + case *StmtClass: + case *StmtComment: // possibly not even parsed + // all of these are safe + default: + // something else unsafe + return fmt.Errorf("found unsafe stmt: %v", x) + } + } + return nil +} + // StmtFunc represents a user defined function. It binds the specified name to // the supplied function in the current scope and irrespective of the order of // definition.