Skip to content

Commit

Permalink
feat: code analysis (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
azjezz authored Dec 22, 2024
1 parent b9aa4b7 commit 3fa6a46
Show file tree
Hide file tree
Showing 613 changed files with 251,485 additions and 1,234 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/crates/wasm/pkg
/target
/stubs/map.rs
44 changes: 19 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ package.rust-version = "1.83.0"
members = ["crates/*"]

[workspace.lints.clippy]
borrow_interior_mutable_const = { level = "allow" }
declare_interior_mutable_const = { level = "allow" }
# ast nodes are large enums, we want to keep them as is ( for now )
large_enum_variant = { level = "allow" }

Expand Down Expand Up @@ -70,7 +68,7 @@ codespan-reporting = { version = "0.11.1", features = [
"serialization",
] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
config = { version = "0.14.0", features = ["toml"] }
config = { version = "0.15.4", features = ["toml"] }
toml = { version = "0.8.19" }
num_cpus = "1.16.0"
regex = "1.11.0"
Expand Down Expand Up @@ -118,6 +116,7 @@ mago-feedback = { workspace = true }
mago-semantics = { workspace = true }
mago-linter = { workspace = true }
mago-reflection = { workspace = true }
mago-names = { workspace = true }
mago-reflector = { workspace = true }
mago-span = { workspace = true }
mago-formatter = { workspace = true }
Expand Down
79 changes: 78 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,80 @@
pub fn main() {
use std::fs;
use std::fs::File;
use std::io;
use std::io::Write;
use std::path::Path;

pub fn main() -> io::Result<()> {
println!("cargo:rustc-env=TARGET={}", std::env::var("TARGET").unwrap());
// Determine the stubs directory and output path
let stubs_dir = Path::new("stubs");
let output_file = stubs_dir.join("map.rs");

// Ensure the stubs directory exists
if !stubs_dir.exists() {
panic!("Stubs directory does not exist: {:?}", stubs_dir);
}

// Collect all PHP stub files
let mut stubs_map = Vec::new();
collect_files(stubs_dir, stubs_dir, &mut stubs_map)?;

// Prepare the map content
let map_content = stubs_map
.into_iter()
.filter_map(|(simplified_path, include_path)| {
if simplified_path.ends_with(".phpstorm.meta.php") {
None
} else {
Some(format!(r##" (r#"{simplified_path}"#, include_str!("{include_path}"))"##))
}
})
.collect::<Vec<_>>();
let count = map_content.len();

// Write to the map.inc file
let mut file = File::create(output_file)?;

writeln!(file, "// This file is generated by the build script")?;
writeln!(file, "// Do not modify this file manually")?;
writeln!(file)?;
writeln!(file, "pub static PHP_STUBS: [(&str, &str); {}] = [", count)?;
writeln!(file, "{}", map_content.join(",\n"))?;
writeln!(file, "];")?;

Ok(())
}

fn collect_files(root: &Path, dir: &Path, stubs_map: &mut Vec<(String, String)>) -> io::Result<()> {
let file_separator = if cfg!(target_os = "windows") { "\\" } else { "/" };

for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();

if path.is_dir() {
// Recursively collect files from subdirectories
collect_files(root, &path, stubs_map)?;
} else if let Some(ext) = path.extension() {
if ext == "php" {
// Simplify the path
let relative_path = path.strip_prefix(root).unwrap();
let simplified_path = relative_path
.components()
.map(|component| {
let part = component.as_os_str().to_string_lossy().to_lowercase();
part.replace(" ", "-")
})
.collect::<Vec<_>>()
.join(file_separator);

// Prepare absolute path for include_str
let include_path = fs::canonicalize(&path)?.to_string_lossy().replace("\\", "/");

// Add to the map
stubs_map.push((format!("stubs{file_separator}{simplified_path}"), include_path));
}
}
}
Ok(())
}
12 changes: 12 additions & 0 deletions crates/ast/src/ast/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ use mago_span::Span;
use crate::ast::class_like::member::ClassLikeConstantSelector;
use crate::ast::class_like::member::ClassLikeMemberSelector;
use crate::ast::expression::Expression;
use crate::ast::identifier::Identifier;
use crate::ast::variable::Variable;

#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct ConstantAccess {
pub name: Identifier,
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord, Display)]
#[serde(tag = "type", content = "value")]
pub enum Access {
Expand Down Expand Up @@ -47,6 +53,12 @@ pub struct ClassConstantAccess {
pub constant: ClassLikeConstantSelector,
}

impl HasSpan for ConstantAccess {
fn span(&self) -> Span {
self.name.span()
}
}

impl HasSpan for Access {
fn span(&self) -> Span {
match self {
Expand Down
4 changes: 4 additions & 0 deletions crates/ast/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use mago_span::Span;

use crate::ast::access::Access;
use crate::ast::access::ClassConstantAccess;
use crate::ast::access::ConstantAccess;
use crate::ast::access::NullSafePropertyAccess;
use crate::ast::access::PropertyAccess;
use crate::ast::argument::Argument;
Expand Down Expand Up @@ -70,6 +71,7 @@ pub enum Expression {
Closure(Box<Closure>),
ArrowFunction(Box<ArrowFunction>),
Variable(Variable),
ConstantAccess(ConstantAccess),
Identifier(Identifier),
Match(Box<Match>),
Yield(Box<Yield>),
Expand Down Expand Up @@ -209,6 +211,7 @@ impl Expression {
pub fn node_kind(&self) -> NodeKind {
match &self {
Expression::Binary(_) => NodeKind::Binary,
Expression::ConstantAccess(_) => NodeKind::ConstantAccess,
Expression::UnaryPrefix(_) => NodeKind::UnaryPrefix,
Expression::UnaryPostfix(_) => NodeKind::UnaryPostfix,
Expression::Parenthesized(_) => NodeKind::Parenthesized,
Expand Down Expand Up @@ -253,6 +256,7 @@ impl HasSpan for Expression {
fn span(&self) -> Span {
match &self {
Expression::Binary(expression) => expression.span(),
Expression::ConstantAccess(expression) => expression.span(),
Expression::UnaryPrefix(expression) => expression.span(),
Expression::UnaryPostfix(expression) => expression.span(),
Expression::Parenthesized(expression) => expression.span(),
Expand Down
1 change: 1 addition & 0 deletions crates/ast/src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use crate::ast::access::Access;
pub use crate::ast::access::ClassConstantAccess;
pub use crate::ast::access::ConstantAccess;
pub use crate::ast::access::NullSafePropertyAccess;
pub use crate::ast::access::PropertyAccess;
pub use crate::ast::access::StaticPropertyAccess;
Expand Down
8 changes: 8 additions & 0 deletions crates/ast/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::Program;
#[serde(tag = "type", content = "value")]
pub enum NodeKind {
Program,
ConstantAccess,
Access,
ClassConstantAccess,
NullSafePropertyAccess,
Expand Down Expand Up @@ -236,6 +237,7 @@ pub enum NodeKind {
pub enum Node<'a> {
Program(&'a Program),
Access(&'a Access),
ConstantAccess(&'a ConstantAccess),
ClassConstantAccess(&'a ClassConstantAccess),
NullSafePropertyAccess(&'a NullSafePropertyAccess),
PropertyAccess(&'a PropertyAccess),
Expand Down Expand Up @@ -533,6 +535,7 @@ impl<'a> Node<'a> {
match &self {
Self::Program(_) => NodeKind::Program,
Self::Access(_) => NodeKind::Access,
Self::ConstantAccess(_) => NodeKind::ConstantAccess,
Self::ClassConstantAccess(_) => NodeKind::ClassConstantAccess,
Self::NullSafePropertyAccess(_) => NodeKind::NullSafePropertyAccess,
Self::PropertyAccess(_) => NodeKind::PropertyAccess,
Expand Down Expand Up @@ -760,6 +763,9 @@ impl<'a> Node<'a> {
Access::StaticProperty(node) => vec![Node::StaticPropertyAccess(node)],
Access::ClassConstant(node) => vec![Node::ClassConstantAccess(node)],
},
Node::ConstantAccess(node) => {
vec![Node::Identifier(&node.name)]
}
Node::ClassConstantAccess(node) => {
vec![Node::Expression(&node.class), Node::ClassLikeConstantSelector(&node.constant)]
}
Expand Down Expand Up @@ -1368,6 +1374,7 @@ impl<'a> Node<'a> {
Node::Expression(node) => vec![match node {
Expression::Binary(node) => Node::Binary(node),
Expression::UnaryPrefix(node) => Node::UnaryPrefix(node),
Expression::ConstantAccess(node) => Node::ConstantAccess(node),
Expression::UnaryPostfix(node) => Node::UnaryPostfix(node),
Expression::Parenthesized(node) => Node::Parenthesized(node),
Expression::Literal(node) => Node::Literal(node),
Expand Down Expand Up @@ -1997,6 +2004,7 @@ impl HasSpan for Node<'_> {
match self {
Self::Program(node) => node.span(),
Self::Access(node) => node.span(),
Self::ConstantAccess(node) => node.span(),
Self::ClassConstantAccess(node) => node.span(),
Self::NullSafePropertyAccess(node) => node.span(),
Self::PropertyAccess(node) => node.span(),
Expand Down
7 changes: 7 additions & 0 deletions crates/formatter/src/format/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl<'a> Format<'a> for Expression {
}
}
Expression::Access(a) => a.format(f),
Expression::ConstantAccess(a) => a.format(f),
Expression::ClosureCreation(c) => c.format(f),
Expression::Parent(k) => k.format(f),
Expression::Static(k) => k.format(f),
Expand Down Expand Up @@ -657,6 +658,12 @@ impl<'a> Format<'a> for ClassLikeConstantSelector {
}
}

impl<'a> Format<'a> for ConstantAccess {
fn format(&'a self, f: &mut Formatter<'a>) -> Document<'a> {
wrap!(f, self, ConstantAccess, { self.name.format(f) })
}
}

impl<'a> Format<'a> for Access {
fn format(&'a self, f: &mut Formatter<'a>) -> Document<'a> {
wrap!(f, self, Access, {
Expand Down
Loading

0 comments on commit 3fa6a46

Please sign in to comment.