mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Fix visibility issues for selene gen
This commit is contained in:
parent
67f9d4eb9f
commit
dc8290b51b
4 changed files with 82 additions and 44 deletions
|
@ -4,6 +4,7 @@ use super::{item::DocItem, kind::DocItemKind};
|
|||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct DocItemBuilder {
|
||||
exported: bool,
|
||||
kind: Option<DocItemKind>,
|
||||
name: Option<String>,
|
||||
meta: Option<String>,
|
||||
|
@ -20,6 +21,12 @@ impl DocItemBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn as_exported(mut self) -> Self {
|
||||
self.exported = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_kind(mut self, kind: DocItemKind) -> Self {
|
||||
self.kind = Some(kind);
|
||||
self
|
||||
|
@ -67,6 +74,7 @@ impl DocItemBuilder {
|
|||
let mut children = self.children;
|
||||
children.sort();
|
||||
Ok(DocItem {
|
||||
exported: self.exported,
|
||||
kind,
|
||||
name: self.name,
|
||||
meta: self.meta,
|
||||
|
|
|
@ -7,6 +7,8 @@ use super::kind::DocItemKind;
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DocItem {
|
||||
#[serde(skip_serializing_if = "skip_serialize_is_false")]
|
||||
pub(super) exported: bool,
|
||||
pub(super) kind: DocItemKind,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(super) name: Option<String>,
|
||||
|
@ -20,6 +22,11 @@ pub struct DocItem {
|
|||
pub(super) arg_types: Vec<String>,
|
||||
}
|
||||
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)]
|
||||
fn skip_serialize_is_false(b: &bool) -> bool {
|
||||
!b
|
||||
}
|
||||
|
||||
impl PartialOrd for DocItem {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match self.kind.partial_cmp(&other.kind).unwrap() {
|
||||
|
@ -53,10 +60,18 @@ impl Ord for DocItem {
|
|||
|
||||
#[allow(dead_code)]
|
||||
impl DocItem {
|
||||
pub fn is_exported(&self) -> bool {
|
||||
self.exported
|
||||
}
|
||||
|
||||
pub fn is_root(&self) -> bool {
|
||||
self.kind.is_root()
|
||||
}
|
||||
|
||||
pub fn is_table(&self) -> bool {
|
||||
self.kind.is_table()
|
||||
}
|
||||
|
||||
pub fn is_property(&self) -> bool {
|
||||
self.kind.is_property()
|
||||
}
|
||||
|
|
|
@ -22,26 +22,31 @@ struct DocVisitorItem {
|
|||
type_info: TypeInfo,
|
||||
}
|
||||
|
||||
impl From<DocVisitorItem> for DocItem {
|
||||
fn from(value: DocVisitorItem) -> Self {
|
||||
impl DocVisitorItem {
|
||||
fn into_doc_item(self, type_definition_declares: &Vec<String>) -> DocItem {
|
||||
let mut builder = DocItemBuilder::new()
|
||||
.with_kind(DocItemKind::from(&value.type_info))
|
||||
.with_name(&value.name);
|
||||
if let Some(comment) = value.comment {
|
||||
.with_kind(DocItemKind::from(&self.type_info))
|
||||
.with_name(&self.name);
|
||||
if type_definition_declares.contains(&self.name) {
|
||||
builder = builder.as_exported();
|
||||
}
|
||||
if let Some(comment) = self.comment {
|
||||
builder = builder.with_children(&parse_moonwave_style_comment(&comment));
|
||||
}
|
||||
if let Some(args) = try_extract_normalized_function_args(&value.type_info) {
|
||||
println!("{} > {args:?}", value.name);
|
||||
if let Some(args) = try_extract_normalized_function_args(&self.type_info) {
|
||||
builder = builder.with_arg_types(&args);
|
||||
}
|
||||
if let TypeInfo::Table { fields, .. } = value.type_info {
|
||||
if let TypeInfo::Table { fields, .. } = self.type_info {
|
||||
for field in fields.iter() {
|
||||
if let TypeFieldKey::Name(name) = field.key() {
|
||||
builder = builder.with_child(DocItem::from(DocVisitorItem {
|
||||
name: name.token().to_string(),
|
||||
comment: find_token_moonwave_comment(name),
|
||||
type_info: field.value().clone(),
|
||||
}));
|
||||
builder = builder.with_child(
|
||||
Self {
|
||||
name: name.token().to_string(),
|
||||
comment: find_token_moonwave_comment(name),
|
||||
type_info: field.value().clone(),
|
||||
}
|
||||
.into_doc_item(type_definition_declares),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,9 +59,9 @@ impl From<&TypeInfo> for DocItemKind {
|
|||
match value {
|
||||
TypeInfo::Array { .. } | TypeInfo::Table { .. } => DocItemKind::Table,
|
||||
TypeInfo::Basic(_) | TypeInfo::String(_) => DocItemKind::Property,
|
||||
TypeInfo::Optional { base, .. } => DocItemKind::from(base.as_ref()),
|
||||
TypeInfo::Optional { base, .. } => Self::from(base.as_ref()),
|
||||
TypeInfo::Tuple { types, .. } => {
|
||||
let mut kinds = types.iter().map(DocItemKind::from).collect::<Vec<_>>();
|
||||
let mut kinds = types.iter().map(Self::from).collect::<Vec<_>>();
|
||||
let kinds_all_the_same = kinds.windows(2).all(|w| w[0] == w[1]);
|
||||
if kinds_all_the_same && !kinds.is_empty() {
|
||||
kinds.pop().unwrap()
|
||||
|
@ -67,8 +72,8 @@ impl From<&TypeInfo> for DocItemKind {
|
|||
}
|
||||
}
|
||||
TypeInfo::Union { left, right, .. } | TypeInfo::Intersection { left, right, .. } => {
|
||||
let kind_left = DocItemKind::from(left.as_ref());
|
||||
let kind_right = DocItemKind::from(right.as_ref());
|
||||
let kind_left = Self::from(left.as_ref());
|
||||
let kind_right = Self::from(right.as_ref());
|
||||
if kind_left == kind_right {
|
||||
kind_left
|
||||
} else {
|
||||
|
@ -86,13 +91,35 @@ impl From<&TypeInfo> for DocItemKind {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_type_definitions_declares(contents: &str) -> (String, Vec<String>) {
|
||||
// TODO: Properly handle the "declare class" syntax, for now we just skip it
|
||||
let mut no_class_declares = contents.to_string();
|
||||
while let Some(dec) = no_class_declares.find("\ndeclare class") {
|
||||
let end = no_class_declares.find("\nend").unwrap();
|
||||
let before = &no_class_declares[0..dec];
|
||||
let after = &no_class_declares[end + 4..];
|
||||
no_class_declares = format!("{before}{after}");
|
||||
}
|
||||
let regex_declare = Regex::new(r#"declare (\w+): "#).unwrap();
|
||||
let resulting_contents = regex_declare
|
||||
.replace_all(&no_class_declares, "export type $1 =")
|
||||
.to_string();
|
||||
let found_declares = regex_declare
|
||||
.captures_iter(&no_class_declares)
|
||||
.map(|cap| cap[1].to_string())
|
||||
.collect();
|
||||
(resulting_contents, found_declares)
|
||||
}
|
||||
|
||||
pub fn parse_type_definitions_into_doc_items<S>(contents: S) -> Result<Vec<DocItem>>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let mut found_top_level_items = Vec::new();
|
||||
let ast = full_moon::parse(&cleanup_type_definitions(contents.as_ref()))
|
||||
.context("Failed to parse type definitions")?;
|
||||
let (type_definition_contents, type_definition_declares) =
|
||||
parse_type_definitions_declares(contents.as_ref());
|
||||
let ast =
|
||||
full_moon::parse(&type_definition_contents).context("Failed to parse type definitions")?;
|
||||
for stmt in ast.nodes().stmts() {
|
||||
if let Some((declaration, token_reference)) = match stmt {
|
||||
Stmt::ExportedTypeDeclaration(exp) => {
|
||||
|
@ -108,7 +135,10 @@ where
|
|||
});
|
||||
}
|
||||
}
|
||||
Ok(found_top_level_items.drain(..).map(DocItem::from).collect())
|
||||
Ok(found_top_level_items
|
||||
.drain(..)
|
||||
.map(|visitor_item| visitor_item.into_doc_item(&type_definition_declares))
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn simple_stringify_type_info(typ: &TypeInfo) -> String {
|
||||
|
@ -261,19 +291,3 @@ fn find_token_moonwave_comment(token: &TokenReference) -> Option<String> {
|
|||
.last()
|
||||
.map(|comment| comment.trim().to_string())
|
||||
}
|
||||
|
||||
fn cleanup_type_definitions(contents: &str) -> String {
|
||||
// TODO: Properly handle the "declare class" syntax, for now we just skip it
|
||||
let mut no_declares = contents.to_string();
|
||||
while let Some(dec) = no_declares.find("\ndeclare class") {
|
||||
let end = no_declares.find("\nend").unwrap();
|
||||
let before = &no_declares[0..dec];
|
||||
let after = &no_declares[end + 4..];
|
||||
no_declares = format!("{before}{after}");
|
||||
}
|
||||
let (regex, replacement) = (
|
||||
Regex::new(r#"declare (?P<n>\w+): "#).unwrap(),
|
||||
r#"export type $n = "#,
|
||||
);
|
||||
regex.replace_all(&no_declares, replacement).to_string()
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ use super::doc2::{DocItem, DocItemKind, DocTree, PIPE_SEPARATOR};
|
|||
pub fn generate_from_type_definitions(contents: &str) -> Result<String> {
|
||||
let tree = DocTree::from_type_definitions(contents)?;
|
||||
let mut globals = YamlMapping::new();
|
||||
let top_level_items = tree.children().iter().filter(|top_level| {
|
||||
top_level.is_function()
|
||||
|| top_level.children().iter().any(|top_level_child| {
|
||||
top_level_child.is_tag() && top_level_child.get_name().unwrap() == "class"
|
||||
})
|
||||
let top_level_exported_items = tree.children().iter().filter(|top_level| {
|
||||
top_level.is_exported()
|
||||
&& (top_level.is_function()
|
||||
|| top_level.children().iter().any(|top_level_child| {
|
||||
top_level_child.is_tag() && top_level_child.get_name().unwrap() == "class"
|
||||
}))
|
||||
});
|
||||
for top_level_item in top_level_items {
|
||||
for top_level_item in top_level_exported_items {
|
||||
match top_level_item.kind() {
|
||||
DocItemKind::Table => {
|
||||
let top_level_name = top_level_item
|
||||
|
@ -24,7 +25,7 @@ pub fn generate_from_type_definitions(contents: &str) -> Result<String> {
|
|||
for child_item in top_level_item
|
||||
.children()
|
||||
.iter()
|
||||
.filter(|item| item.is_function() || item.is_property())
|
||||
.filter(|item| item.is_function() || item.is_table() || item.is_property())
|
||||
{
|
||||
let child_name = child_item
|
||||
.get_name()
|
||||
|
@ -64,7 +65,7 @@ pub fn generate_from_type_definitions(contents: &str) -> Result<String> {
|
|||
|
||||
fn doc_item_to_selene_yaml_mapping(item: &DocItem) -> Result<YamlMapping> {
|
||||
let mut mapping = YamlMapping::new();
|
||||
if item.is_property() {
|
||||
if item.is_property() || item.is_table() {
|
||||
let property_access_tag = item
|
||||
.children()
|
||||
.iter()
|
||||
|
|
Loading…
Reference in a new issue