def convertSubroutinesToProcedures(parse_tree, entry_points, line_mapper, options): logger.info("Convert subroutines to procedures") entry_point_names_to_remove = [] entry_points_to_add = {} for name, entry_point in entry_points.items(): # TODO: This will only work with simple (i.e. single entry) subroutines print "name = %s, entry_point = %s" % (name, entry_point) subname = iter(entry_point.entryPoints).next() if subname.startswith('SUB'): procname = 'PROCSub' + subname[3:] assert len(entry_point.inEdges) == 0 defproc = DefineProcedure(name=procname, formalParameters=None) insertStatementBefore(entry_point, defproc) deTagSuccessors(entry_point) entry_point.clearEntryPoints() entry_point_names_to_remove.append(name) entry_points_to_add[procname] = defproc entry_point.clearComeFromGosubEdges() tagSuccessors(defproc, line_mapper) for name in entry_point_names_to_remove: del entry_points[name] entry_points.update(entry_points_to_add) csv = ConvertSubVisitor() parse_tree.accept(csv)
def guardExecutableDefinitions(entry_points): logging.debug("Checking for direct execution of function or procedure bodies...") for entry_point in entry_points.values(): if isinstance(entry_point, syntax.ast.DefinitionStatement): if len(entry_point.inEdges) != 0: reachable_predecessors = (len(predecessor.entryPoints) > 0 for predecessor in entry_point.inEdges) if any(reachable_predecessors): errors.warning("Execution of procedure/function at line %s" % entry_point.lineNum) # TODO: Could use ERROR statement here # TODO: Could also have an option to allow procedures to be directly executable # which may involve inserting a call to the procedure at this point ... probably # more appropriate for GOSUBroutines. raise_stmt = syntax.ast.Raise(type="ExecutedDefinitionException") raise_stmt.lineNum = entry_point.lineNum ast_utils.insertStatementBefore(entry_point, raise_stmt) raise_stmt.clearOutEdges() entry_point.clearInEdges() return entry_point, entry_points