RustPython / Parser

MIT License
73 stars 28 forks source link

How to edit source code now? #119

Closed tisonkun closed 4 months ago

tisonkun commented 5 months ago

Previously, I wrote code like:

use rustpython_parser::ast::{ArgData, Located, Location};

fn create_located<T>(node: T, loc: Location) -> Located<T> {
    Located::new(loc, loc, node)
}

But it seems the Location and struct Located are all changed. How can I edit source code now?

youknowone commented 5 months ago

The AST location model is changed. It now contains a linear byte offset. It can be converted to the previous human location using SourceLocator. I'd better to look in greptimedb to check use case.

youknowone commented 5 months ago

Located is integrated in node. ast::Expr can be replaced by ast::located::Expr. create_located will not be useful anymore.

The new gen_call will be like this:

fn gen_call(
    name: &str,
    deco_args: &DecoratorArgs,
    kwarg: &Option<String>,
    loc: &SourceLocation,
) -> located::Stmt {
    let mut loc = *loc;
    // adding a line to avoid confusing if any error occurs when calling the function
    // then the pretty print will point to the last line in code
    // instead of point to any of existing code written by user.
    loc.newline();
    let mut args: Vec<located::Expr> = if let Some(arg_names) = &deco_args.arg_names {
        arg_names
            .iter()
            .map(|v| {
                located::Expr::Name(located::ExprName {
                    id: v.clone(),
                    ctx: located::ExprContext::Load,
                    range: loc.clone(),
                })
            })
            .collect()
    } else {
        vec![]
    };

    if let Some(kwarg) = kwarg {
        let node = located::Expr::Name(located::ExprName {
            range: loc.clone(),
            id: kwarg.clone(),
            ctx: located::ExprContext::Load,
        });
        args.push(node);
    }

    let func = located::Expr::Call(located::ExprCall {
        range: loc.clone(),
        func: Box::new(
            located::Expr::Name(located::ExprName {
                range: loc.clone(),
                id: name.to_string(),
                ctx: located::ExprContext::Load,
            }),
        ),
        args,
        keywords: Vec::new(),
    });
    located::Stmt::Expr(located::StmtExpr {
        range: loc.clone(),
        value: Box::new(create_located(func, loc)),
    })
}
diff --git a/src/script/src/python/ffi_types/copr/compile.rs b/src/script/src/python/ffi_types/copr/compile.rs
index c4b38501b..b732817ec 100644
--- a/src/script/src/python/ffi_types/copr/compile.rs
+++ b/src/script/src/python/ffi_types/copr/compile.rs
@@ -15,9 +15,9 @@
 //! compile script to code object
 use rustpython_codegen::compile::compile_top;
 use rustpython_compiler::{CompileOpts, Mode};
-use rustpython_compiler_core::CodeObject;
-use rustpython_parser::ast::{ArgData, Located, Location};
-use rustpython_parser::{ast, parse, Mode as ParseMode};
+use rustpython_compiler::CodeObject;
+// use rustpython_parser::ast::{ArgData, Located, Location};
+use rustpython_parser::{SourceLocation, ast::located, parse, Mode as ParseMode};
 use snafu::ResultExt;

 use crate::fail_parse_error;
@@ -35,22 +35,22 @@ fn gen_call(
     name: &str,
     deco_args: &DecoratorArgs,
     kwarg: &Option<String>,
-    loc: &Location,
-) -> ast::Stmt<()> {
+    loc: &SourceLocation,
+) -> located::Stmt {
     let mut loc = *loc;
     // adding a line to avoid confusing if any error occurs when calling the function
     // then the pretty print will point to the last line in code
     // instead of point to any of existing code written by user.
     loc.newline();
-    let mut args: Vec<Located<ast::ExprKind>> = if let Some(arg_names) = &deco_args.arg_names {
+    let mut args: Vec<located::Expr> = if let Some(arg_names) = &deco_args.arg_names {
         arg_names
             .iter()
             .map(|v| {
-                let node = ast::ExprKind::Name {
+                located::Expr::Name(located::ExprName {
                     id: v.clone(),
-                    ctx: ast::ExprContext::Load,
-                };
-                create_located(node, loc)
+                    ctx: located::ExprContext::Load,
+                    range: loc.clone(),
+                })
             })
             .collect()
     } else {
@@ -58,28 +58,30 @@ fn gen_call(
     };

     if let Some(kwarg) = kwarg {
-        let node = ast::ExprKind::Name {
+        let node = located::Expr::Name(located::ExprName {
+            range: loc.clone(),
             id: kwarg.clone(),
-            ctx: ast::ExprContext::Load,
-        };
-        args.push(create_located(node, loc));
+            ctx: located::ExprContext::Load,
+        });
+        args.push(node);
     }

-    let func = ast::ExprKind::Call {
-        func: Box::new(create_located(
-            ast::ExprKind::Name {
+    let func = located::Expr::Call(located::ExprCall {
+        range: loc.clone(),
+        func: Box::new(
+            located::Expr::Name(located::ExprName {
+                range: loc.clone(),
                 id: name.to_string(),
-                ctx: ast::ExprContext::Load,
-            },
-            loc,
-        )),
+                ctx: located::ExprContext::Load,
+            }),
+        ),
         args,
         keywords: Vec::new(),
-    };
-    let stmt = ast::StmtKind::Expr {
+    });
+    located::Stmt::Expr(located::StmtExpr {
+        range: loc.clone(),
         value: Box::new(create_located(func, loc)),
-    };
-    create_located(stmt, loc)
+    })
 }
youknowone commented 5 months ago

The parsing function will be replaced by Parse trait

youknowone commented 4 months ago

I made a reference change here: https://github.com/GreptimeTeam/greptimedb/pull/3723