-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
303 additions
and
119 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
use emmylua_parser::{LuaSyntaxKind, LuaSyntaxNode, LuaSyntaxToken, LuaTokenKind}; | ||
use mlua::prelude::*; | ||
|
||
pub enum LuaNodeWrapper { | ||
Node(LuaSyntaxNode), | ||
Token(LuaSyntaxToken), | ||
} | ||
|
||
impl LuaNodeWrapper { | ||
pub fn new(node: LuaSyntaxNode) -> Self { | ||
Self::Node(node) | ||
} | ||
|
||
pub fn from_node_or_token( | ||
node_or_token: rowan::NodeOrToken<LuaSyntaxNode, LuaSyntaxToken>, | ||
) -> Self { | ||
match node_or_token { | ||
rowan::NodeOrToken::Node(node) => Self::Node(node), | ||
rowan::NodeOrToken::Token(token) => Self::Token(token), | ||
} | ||
} | ||
} | ||
|
||
impl LuaUserData for LuaNodeWrapper { | ||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) { | ||
fields.add_field_method_get("isNode", |_, this| match this { | ||
LuaNodeWrapper::Node(_) => Ok(true), | ||
LuaNodeWrapper::Token(_) => Ok(false), | ||
}); | ||
fields.add_field_method_get("isToken", |_, this| match this { | ||
LuaNodeWrapper::Node(_) => Ok(false), | ||
LuaNodeWrapper::Token(_) => Ok(true), | ||
}); | ||
fields.add_field_method_get("kind", |_, this| match this { | ||
LuaNodeWrapper::Node(node) => { | ||
let kind: LuaSyntaxKind = node.kind().into(); | ||
Ok(kind as u16) | ||
} | ||
LuaNodeWrapper::Token(token) => { | ||
let kind: LuaTokenKind = token.kind().into(); | ||
Ok(kind as u16) | ||
} | ||
}); | ||
fields.add_field_method_get("kindText", |_, this| { | ||
let text = match this { | ||
LuaNodeWrapper::Node(node) => { | ||
let kind: LuaSyntaxKind = node.kind().into(); | ||
format!("{:?}", kind) | ||
} | ||
LuaNodeWrapper::Token(token) => { | ||
let kind: LuaTokenKind = token.kind().into(); | ||
format!("{:?}", kind) | ||
} | ||
}; | ||
|
||
Ok(text) | ||
}); | ||
} | ||
|
||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) { | ||
methods.add_method("getText", |_, this, ()| { | ||
let text = match this { | ||
LuaNodeWrapper::Node(node) => node.text().to_string(), | ||
LuaNodeWrapper::Token(token) => token.text().to_string(), | ||
}; | ||
Ok(text) | ||
}); | ||
methods.add_method("getRange", |lua, this, ()| { | ||
let range = match this { | ||
LuaNodeWrapper::Node(node) => node.text_range(), | ||
LuaNodeWrapper::Token(token) => token.text_range(), | ||
}; | ||
let table = lua.create_table()?; | ||
let line: u32 = range.start().into(); | ||
let col: u32 = range.start().into(); | ||
table.set("start", line)?; | ||
table.set("end", col)?; | ||
Ok(table) | ||
}); | ||
methods.add_method("getChildren", |lua, this, ()| { | ||
let children = match this { | ||
LuaNodeWrapper::Node(node) => node | ||
.children_with_tokens() | ||
.filter_map(|it| match it { | ||
rowan::NodeOrToken::Node(node) => Some(LuaNodeWrapper::Node(node)), | ||
rowan::NodeOrToken::Token(token) => Some(LuaNodeWrapper::Token(token)), | ||
}) | ||
.collect(), | ||
LuaNodeWrapper::Token(_) => vec![], | ||
}; | ||
|
||
Ok(children) | ||
}); | ||
|
||
methods.add_method("dump", |_, this, ()| { | ||
let dump = match this { | ||
LuaNodeWrapper::Node(node) => format!("{:#?}", node), | ||
LuaNodeWrapper::Token(token) => format!("{:#?}", token), | ||
}; | ||
Ok(dump) | ||
}); | ||
|
||
methods.add_method("getParent", |_, this, ()| { | ||
let parent = match this { | ||
LuaNodeWrapper::Node(node) => node.parent().map(LuaNodeWrapper::Node), | ||
LuaNodeWrapper::Token(token) => token.parent().map(LuaNodeWrapper::Node), | ||
}; | ||
Ok(parent) | ||
}); | ||
|
||
methods.add_method("getPrevSibling", |_, this, ()| { | ||
let prev_sibling = match this { | ||
LuaNodeWrapper::Node(node) => node.prev_sibling().map(LuaNodeWrapper::Node), | ||
LuaNodeWrapper::Token(token) => match token.prev_sibling_or_token() { | ||
Some(rowan::NodeOrToken::Node(node)) => Some(LuaNodeWrapper::Node(node)), | ||
Some(rowan::NodeOrToken::Token(token)) => Some(LuaNodeWrapper::Token(token)), | ||
None => None, | ||
}, | ||
}; | ||
Ok(prev_sibling) | ||
}); | ||
|
||
methods.add_method("getNextSibling", |_, this, ()| { | ||
let next_sibling = match this { | ||
LuaNodeWrapper::Node(node) => node.next_sibling().map(LuaNodeWrapper::Node), | ||
LuaNodeWrapper::Token(token) => match token.next_sibling_or_token() { | ||
Some(rowan::NodeOrToken::Node(node)) => Some(LuaNodeWrapper::Node(node)), | ||
Some(rowan::NodeOrToken::Token(token)) => Some(LuaNodeWrapper::Token(token)), | ||
None => None, | ||
}, | ||
}; | ||
Ok(next_sibling) | ||
}); | ||
|
||
methods.add_method("getDescendants", |_, this, ()| { | ||
let descendants = match this { | ||
LuaNodeWrapper::Node(node) => node | ||
.descendants_with_tokens() | ||
.map(LuaNodeWrapper::from_node_or_token) | ||
.collect(), | ||
LuaNodeWrapper::Token(_) => vec![], | ||
}; | ||
Ok(descendants) | ||
}); | ||
|
||
methods.add_method("getAncestors", |_, this, ()| { | ||
let ancestors: Vec<LuaNodeWrapper> = match this { | ||
LuaNodeWrapper::Node(node) => node.ancestors().map(LuaNodeWrapper::Node).collect(), | ||
LuaNodeWrapper::Token(token) => { | ||
token.parent_ancestors().map(LuaNodeWrapper::Node).collect() | ||
} | ||
}; | ||
|
||
Ok(ancestors) | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use emmylua_parser::{LuaParser, ParserConfig}; | ||
use mlua::{prelude::*, Lua}; | ||
|
||
use super::lua_syntax_tree::LuaSyntaxTree; | ||
|
||
fn parse(_: &Lua, text: String) -> LuaResult<LuaSyntaxTree> { | ||
let tree = LuaParser::parse(&text, ParserConfig::default()); | ||
|
||
Ok(LuaSyntaxTree::new(tree)) | ||
} | ||
|
||
pub fn lua_parser(lua: &Lua) -> LuaResult<LuaTable> { | ||
let parser = lua.create_table()?; | ||
parser.set("parse", lua.create_function(parse)?)?; | ||
Ok(parser) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use emmylua_parser::LuaSyntaxTree as EmmyLuaSyntaxTree; | ||
use mlua::prelude::*; | ||
use rowan::TextSize; | ||
|
||
use super::lua_node::LuaNodeWrapper; | ||
|
||
pub struct LuaSyntaxTree { | ||
tree: EmmyLuaSyntaxTree, | ||
} | ||
|
||
impl LuaSyntaxTree { | ||
pub fn new(tree: EmmyLuaSyntaxTree) -> Self { | ||
Self { tree } | ||
} | ||
|
||
pub fn get_root(&self) -> LuaNodeWrapper { | ||
LuaNodeWrapper::new(self.tree.get_red_root().clone()) | ||
} | ||
|
||
pub fn get_line_col(&self, offset: usize) -> Option<(usize, usize)> { | ||
let offset = TextSize::from(offset as u32); | ||
let (line, col) = self.tree.get_line_col(offset)?; | ||
Some((line, col)) | ||
} | ||
|
||
pub fn get_offset(&self, line: usize, col: usize) -> Option<usize> { | ||
let offset = self.tree.get_offset(line, col)?; | ||
Some(offset.into()) | ||
} | ||
} | ||
|
||
impl LuaUserData for LuaSyntaxTree { | ||
fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {} | ||
|
||
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) { | ||
methods.add_method("getRoot", |_, this, ()| Ok(this.get_root())); | ||
// methods.add_method("get_chunk_node", |_, this, ()| Ok(this.get_chunk_node())); | ||
methods.add_method("getLineCol", |lua, this, offset: usize| { | ||
let (line, col) = this.get_line_col(offset).unwrap(); | ||
let table = lua.create_table()?; | ||
table.set(1, line)?; | ||
table.set(2, col)?; | ||
Ok(table) | ||
}); | ||
methods.add_method("getOffset", |_, this, (line, col): (usize, usize)| { | ||
Ok(this.get_offset(line, col)) | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
mod lua_parser; | ||
mod lua_syntax_tree; | ||
mod lua_node; | ||
|
||
use mlua::{prelude::*, Lua}; | ||
|
||
use crate::add_preload_module; | ||
|
||
|
||
pub fn register_parser_module(lua: &Lua) -> LuaResult<()> { | ||
// lua.parser | ||
let lua_parser_loader = | ||
lua.create_function(|lua: &Lua, ()| Ok(lua_parser::lua_parser(lua)))?; | ||
add_preload_module(&lua, "lua.parser", lua_parser_loader)?; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.