예제 #1
0
 def visitSql_script(self, ctx: PlSqlParser.Sql_scriptContext):
     body = self.visitChildren(ctx)
     add_no_repeat(self.pkgs_calls_found,
                   [PKG_PLGLOBALS, PKG_PLHELPER, PKG_PLCURSOR])
     imports = self.create_imports()
     body = imports + body
     return ast.Module(body=body)
예제 #2
0
 def visitCursor_declaration(self,
                             ctx: PlSqlParser.Cursor_declarationContext):
     cursor_params = [
         self.visitChildren(param)[0].id for param in ctx.parameter_spec()
     ]
     visitor = ScriptVisitor()
     visitor.vars_declared = self.vars_declared + cursor_params
     ret = visitor.visitChildren(ctx)
     ret = deque(ret)
     name: ast.Name = ret.popleft()
     sql: SQL = None
     sql_vars = []
     for param in list(ret):
         if isinstance(param, SQL):
             sql = param
         elif isinstance(param, SQL_VAR):
             sql_var = ast.Str(s=param.varname)
             sql_vars.append(sql_var)
         else:
             continue
         ret.remove(param)
     cursor_params = [ast.Str(i) for i in cursor_params]
     add_no_repeat(self.vars_declared, name.id)
     return ast.Assign(targets=[name],
                       value=ast.Call(func=ast.Attribute(
                           value=ast.Name(id=PKG_PLCURSOR), attr="CURSOR"),
                                      args=[
                                          ast.Str(sql.sql),
                                          ast.List(elts=sql_vars),
                                          ast.List(elts=cursor_params)
                                      ],
                                      keywords=[]))
예제 #3
0
 def manual_visitProcedure_body(self,
                                ctx: PlSqlParser.Procedure_bodyContext):
     args_names: List[str] = [
         param.parameter_name().getText().upper()
         for param in ctx.parameter()
     ]
     add_no_repeat(self.vars_declared, args_names)
     ret = self.visitChildren(ctx)
     ret = deque(ret)
     name: ast.Name = ret.popleft()
     args = []
     while True:
         arg = ret[0]
         if not isinstance(arg, ast.arg):
             break
         args.append(arg)
         ret.popleft()
     body = ret
     for item in list(body):
         if isinstance(item, TYPE):
             # is a function definition. this is the return type
             body.remove(item)
             break
     for i, item in enumerate(body):
         # everything has to be an expression?
         if isinstance(item, ast.Expr):
             continue
         body[i] = ast.Expr(value=item)
     args = ast.arguments(args=args, defaults=[], vararg=None, kwarg=None)
     return ast.FunctionDef(name=name.id,
                            args=args,
                            body=body,
                            decorator_list=[],
                            returns=None)
예제 #4
0
 def visitCreate_function_body(
         self, ctx: PlSqlParser.Create_function_bodyContext):
     visitor = ScriptVisitor()
     # FIXME: the function being processed should be added to vars_declared too, in case of recursivity
     visitor.vars_declared = self.vars_declared.copy()
     ret = visitor.visitChildren(ctx)
     ret = deque(ret)
     name = ret.popleft()
     add_no_repeat(self.vars_declared, name.id)
     args = []
     for expr in list(ret):
         if isinstance(expr, ast.arg):
             args.append(expr)
         elif isinstance(expr, TYPE):
             pass
         else:
             continue
         ret.remove(expr)
     args = ast.arguments(args=args, defaults=[], vararg=None, kwarg=None)
     body = ret
     return ast.FunctionDef(name=name.id,
                            args=args,
                            body=body,
                            decorator_list=[],
                            returns=None)
예제 #5
0
 def visitProcedure_body(self, ctx: PlSqlParser.Procedure_bodyContext):
     visitor = ScriptVisitor()
     visitor.pkg_name = self.pkg_name
     visitor.vars_in_package = self.vars_in_package
     ret = visitor.manual_visitProcedure_body(ctx)
     add_no_repeat(self.vars_declared, ret.name)
     add_no_repeat(self.pkgs_calls_found, visitor.pkgs_calls_found)
     return ret
예제 #6
0
 def visitType_spec(self, ctx: PlSqlParser.Type_specContext):
     if ctx.PERCENT_TYPE():
         return None
     elif ctx.PERCENT_ROWTYPE():
         add_no_repeat(self.pkgs_calls_found, TYPE_PLRECORD)
         return TYPE(ast.Name(id=TYPE_PLRECORD))
     elif ctx.type_name():
         type_name = self.visitChildren(ctx)[0]
         return TYPE(type_name)
     return None
예제 #7
0
 def visitSeq_of_declare_specs(
         self, ctx: PlSqlParser.Seq_of_declare_specsContext):
     ret = self.visitChildren(ctx)
     declared_vars = []
     for expr in ret:
         if isinstance(expr, ast.Assign):
             declared_vars.append(expr.targets[0].id)
         elif isinstance(expr, ast.FunctionDef):
             declared_vars.append(expr.name)
     add_no_repeat(self.vars_declared, declared_vars)
     return ret
예제 #8
0
 def visitVariable_declaration(
         self, ctx: PlSqlParser.Variable_declarationContext):
     ret = self.visitChildren(ctx)
     ret = deque(ret)
     name: ast.Name = ret.popleft()
     value = ast.Call(func=ast.Name(id="m"), args=[], keywords=[])
     add_no_repeat(self.vars_declared, name.id)
     if ret and isinstance(ret[0], TYPE):
         the_type = ret.popleft().the_type
         value = ast.Call(func=the_type, args=[], keywords=[])
     if ret:
         value = ret.popleft()
     return ast.Assign(targets=[name], value=value)
예제 #9
0
 def visitCursor_loop_param(self,
                            ctx: PlSqlParser.Cursor_loop_paramContext):
     target = ctx.index_name().getText().upper()
     # declare the variable for being recognized by the children
     add_no_repeat(self.vars_declared, target)
     ret = self.visitChildren(ctx)
     target, lower, upper = ret
     return ast.For(target=ast.Name(id=target),
                    iter=ast.Call(func=ast.Name(id="mrange"),
                                  args=[lower, upper],
                                  keywords=[]),
                    body=[],
                    orelse=[])
예제 #10
0
 def add_object_to_imports(self, the_object):
     name = the_object
     while True:
         if isinstance(name, str):
             if name != self.pkg_name and name not in self.vars_declared:
                 add_no_repeat(self.pkgs_calls_found, name)
             break
         elif isinstance(name, ast.Call):
             name = name.func
         elif isinstance(name, ast.Attribute):
             name = name.value
         elif isinstance(name, ast.Name):
             name = name.id
         else:
             raise NotImplementedError(
                 f"unsupported object to import {name}")
예제 #11
0
 def visitCreate_package(self, ctx: PlSqlParser.Create_packageContext):
     self.vars_declared = self.vars_in_package
     ret = self.visitChildren(ctx)
     ret = deque(ret)
     name: str = ret.popleft().id
     if ret:
         label = ret[-1]
         if isinstance(label, ast.Name) and label.id == name:
             ret.pop()
     name = get_spec_classname_by_classname(name)
     body = ret
     for item in body:
         if isinstance(item, ast.Assign):
             add_no_repeat(self.vars_declared, item.targets[0].id)
     if not body:
         body.append(ast.Pass())
     return ast.ClassDef(name=name, body=body, decorator_list=[], bases=[])
예제 #12
0
 def visitCreate_package_body(self,
                              ctx: PlSqlParser.Create_package_bodyContext):
     self.pkg_name = name = ctx.package_name()[0].getText().upper()
     add_no_repeat(self.vars_declared, name)
     self.vars_in_package = self.vars_declared
     ret = self.visitChildren(ctx)
     spec_classname = get_spec_classname_by_classname(name)
     if ret:
         label = ret[-1]
         if isinstance(label, ast.Name) and label.id == name:
             ret.pop()
     body = ret[1:]  # we already had the name
     for item in body:
         if isinstance(item, ast.FunctionDef):
             item.decorator_list.append(ast.Name(id="staticmethod"))
     return ast.ClassDef(name=name,
                         body=body,
                         decorator_list=[],
                         bases=[ast.Name(id=spec_classname)])
예제 #13
0
 def visitType_declaration(self, ctx: PlSqlParser.Type_declarationContext):
     ret = self.visitChildren(ctx)
     ret = deque(ret)
     type_name = ret.popleft()
     targets = [type_name]
     add_no_repeat(self.vars_declared, type_name.id)
     if ctx.table_type_def():
         value = ast.Name(id=TYPE_PLTABLE)
         if ret and isinstance(ret[0], TYPE):
             the_type = ret.popleft()
             the_type = the_type.the_type
             value = ast.Call(func=ast.Name(id=TYPE_PLTABLE_OF),
                              args=[the_type],
                              keywords=[])
             add_no_repeat(self.pkgs_calls_found, TYPE_PLRECORD)
         add_no_repeat(self.pkgs_calls_found, TYPE_PLTABLE)
         return ast.Assign(targets=targets, value=value)
     if ctx.record_type_def():
         add_no_repeat(self.pkgs_calls_found, TYPE_PLRECORD)
         return ast.Assign(targets=targets,
                           value=ast.Name(id=TYPE_PLRECORD))
     raise NotImplementedError(f"unsupported Type_declaration: {ret}")