diff --git a/src/cli.cr b/src/cli.cr index 8bac8cf88..2976bfd88 100644 --- a/src/cli.cr +++ b/src/cli.cr @@ -25,6 +25,7 @@ module Mint register_sub_command docs, type: Docs register_sub_command loc, type: Loc register_sub_command ls, type: Ls + register_sub_command lint, type: Lint def run execute "Help" do diff --git a/src/commands/lint.cr b/src/commands/lint.cr new file mode 100644 index 000000000..3f557efd9 --- /dev/null +++ b/src/commands/lint.cr @@ -0,0 +1,69 @@ +module Mint + class Cli < Admiral::Command + class Lint < Admiral::Command + include Command + + define_help description: "Lints the project for syntax and type errors." + + define_flag json : Bool, + description: "Output errors to a JSON file", + default: false, + required: false + + def run + execute "Linting" do + lint + end + end + + def lint + sources = [] of String + errors = [] of Exception + + ast = + Ast.new + .merge(Core.ast) + + begin + sources = + Dir.glob(SourceFiles.all) + rescue ex + errors << ex + end + + sources.reduce(ast) do |memo, file| + begin + parsed = + Parser.parse(file) + + memo.merge(parsed) + rescue ex + errors << ex + end + memo + end + + if errors.empty? + type_checker = + TypeChecker.new(ast) + + loop do + type_checker.check + rescue ex + errors << ex + else + break + end + end + + if flags.json + puts errors.compact_map(&.message.presence).to_json + else + errors.each { |error| puts error } + end + + exit(errors.empty? ? 0 : 1) + end + end + end +end