Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
646 changes: 646 additions & 0 deletions INTERNALS.md

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions crates/fmt/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use code_lang::{
parser::parser::Parser,
};

use crate::formatter::Formatter;
use crate::lint_rules::{
ConstReassignment, DeadCode, EmptyBlock, LintFix, LintRule, LintSeverity, ShadowedBinding,
UndefinedVariable, UnusedImport, UnusedVariable,
Expand Down Expand Up @@ -217,3 +218,56 @@ fn apply_fixes(path: &PathBuf, src: String, fixes: Vec<&LintFix>) {
eprintln!("{}: failed to write fixes: {}", path.display(), e);
}
}


pub fn format_file(files: &[PathBuf], stdout:bool) -> Result<()> {
for file in files {
let ext_ok = file
.extension()
.and_then(|e| e.to_str())
.map(|e| e.eq_ignore_ascii_case("cl"))
.unwrap_or(false);

if !ext_ok {
bail!("expect a .cl file, got: {}", file.display())
}

let src = match fs::read_to_string(file) {
Ok(s) => s,
Err(e) => {
eprintln!("{}: cannot read file: {}", file.display(), e);
continue;
}
};

let lines: Vec<&str> = src.lines().collect();
let lexer = Lexer::new(src.clone());
let mut parser = Parser::new(lexer);
let program = parser.parse_program();

//formatter
if !parser.errors.is_empty() {
for err in &parser.errors {
print_caret(
&lines,
file,
err.line,
err.column,
&LintSeverity::Error,
None,
&err.message,
);
}
}

let formatted = Formatter::format(&program);
if stdout {
print!("{:?}", formatted)
} else if formatted != src {
fs::write(file, formatted)?;
println!("{}: formatted", file.display());
}
}

Ok(())
}
14 changes: 14 additions & 0 deletions crates/fmt/src/formatter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use code_lang::ast::ast::{Expression, Program, Statement};

pub struct Formatter {
indent_level: usize,
output: String
}

const IDENT:&str = " "; // 4 spaces

impl Formatter {
pub fn format(program: &Program){ }
pub fn fmt_statement(&mut self, stmt:&Statement){}
pub fn fmt_expression(&mut self, expr:&Expression){}
}
36 changes: 35 additions & 1 deletion crates/fmt/src/lint_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use code_lang::{
analysis::scope::ScopeTree,
ast::{
ast::{Expression, LetPattern, Statement},
walk::{Visitor, walk_statement},
walk::{Visitor, walk_expression, walk_statement},
},
token::token::TokenType,
};
Expand Down Expand Up @@ -170,6 +170,10 @@ impl Visitor for ShadowedBinding {
fn visit_const(&mut self, pattern: &LetPattern, _value: &Expression, line: usize, col: usize) {
self.register_pattern(pattern, line, col);
}

fn visit_expression(&mut self, expr: &Expression) {

}
}

impl LintRule for ShadowedBinding {
Expand Down Expand Up @@ -215,6 +219,21 @@ impl Visitor for UnusedVariable {
}
}

fn visit_const(
&mut self,
pattern: &LetPattern,
_value: &Expression,
line: usize,
col: usize,
)
{
match pattern {
LetPattern::Array(names) => for name in names { self.declared.insert(name.to_string(), (line, col, false));},
LetPattern::Hash(pairs) => for (_, alias) in pairs { self.declared.insert(alias.to_string(), (line, col, false));},
LetPattern::Ident(n) => { self.declared.insert(n.to_string(), (line,col, false));}
}
}

fn visit_ident(&mut self, value: &str, _line: usize, _col: usize) {
self.used.insert(value.to_string());
}
Expand Down Expand Up @@ -390,6 +409,8 @@ impl Visitor for DeadCode {

self.returned = saved;
}

walk_statement(self, stmt);
}
}

Expand Down Expand Up @@ -506,6 +527,8 @@ impl Visitor for EmptyBlock {
fix: None,
});
}

walk_expression(self, expr);
}
}

Expand Down Expand Up @@ -557,6 +580,17 @@ impl Visitor for UndefinedVariable {
});
}
}

fn visit_member(
&mut self,
object: &Expression,
_property: &Expression,
_line: usize,
_col: usize,
)
{
self.visit_expression(object);
}
}

impl LintRule for UndefinedVariable {
Expand Down
13 changes: 12 additions & 1 deletion crates/fmt/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
mod commands;
mod lint_rules;
mod util;
mod formatter;
use std::path::PathBuf;

use anyhow::Result;
use clap::{Parser, Subcommand};

use crate::commands::{check_file, lint_file};
use crate::commands::{check_file, format_file, lint_file};

#[derive(Parser)]
#[command(name = "code-lang-fmt")]
Expand All @@ -28,6 +29,13 @@ enum Commands {
#[arg(long)]
fix: bool,
},

Format {
files: Vec<PathBuf>,

#[arg(long)]
stdout:bool
}
}

fn main() -> Result<()> {
Expand All @@ -39,6 +47,9 @@ fn main() -> Result<()> {
Some(Commands::Lint { files, fix }) => {
lint_file(&files, fix)?;
}
Some(Commands::Format { files, stdout }) => {
format_file(&files, stdout)?;
},
None => {}
}
Ok(())
Expand Down
Loading
Loading