require "spec" require "../../src/compiler/crystal/syntax" include Crystal struct Number def int32 NumberLiteral.new to_s, :i32 end def int64 NumberLiteral.new to_s, :i64 end def int128 NumberLiteral.new to_s, :i128 end def uint128 NumberLiteral.new to_s, :u128 end def float32 NumberLiteral.new to_f32.to_s, :f32 end def float64 NumberLiteral.new to_f64.to_s, :f64 end end struct Bool def bool BoolLiteral.new self end end class Array def array ArrayLiteral.new self end def array_of(type) ArrayLiteral.new self, type end def path Crystal::Path.new self end end class String def var Var.new self end def ann Annotation.new path end def arg(default_value = nil, restriction = nil, external_name = nil, annotations = nil) Arg.new self, default_value: default_value, restriction: restriction, external_name: external_name, parsed_annotations: annotations end def call Call.new nil, self end def call(args : Array) Call.new nil, self, args end def call(arg : ASTNode) Call.new nil, self, [arg] of ASTNode end def call(arg1 : ASTNode, arg2 : ASTNode) Call.new nil, self, [arg1, arg2] of ASTNode end def path(global = false) Crystal::Path.new self, global end def instance_var InstanceVar.new self end def class_var ClassVar.new self end def string StringLiteral.new self end def string_interpolation StringInterpolation.new([self.string] of ASTNode) end def float32 NumberLiteral.new self, :f32 end def float64 NumberLiteral.new self, :f64 end def symbol SymbolLiteral.new self end def static_array_of(size : Int) static_array_of NumberLiteral.new(size) end def static_array_of(size : ASTNode) Generic.new(Crystal::Path.global("StaticArray"), [path, size] of ASTNode) end def macro_literal MacroLiteral.new(self) end end class Crystal::ASTNode def pointer_of Generic.new(Crystal::Path.global("Pointer"), [self] of ASTNode) end def splat Splat.new(self) end end def assert_syntax_error(str, message = nil, line = nil, column = nil, metafile = __FILE__, metaline = __LINE__, metaendline = __END_LINE__, *, focus : Bool = false) it "says syntax error on #{str.inspect}", metafile, metaline, metaendline, focus: focus do ex = expect_raises(SyntaxException, message, file: metafile, line: metaline) do parse str end if line unless ex.line_number == line fail "Expected line number to be #{line} but got #{ex.line_number}", metafile, metaline end end if column unless ex.column_number == column fail "Expected column number to be #{column} but got #{ex.column_number}", metafile, metaline end end end end def assert_syntax_warning(str, message, *, metafile = __FILE__, metaline = __LINE__, metaendline = __END_LINE__) it "says syntax warning on #{str.inspect}", metafile, metaline, metaendline do warnings = WarningCollection.new parse str, false, nil, warnings unless warnings.infos.find(&.ends_with?(message)) fail "Expected warnings to include '#{message}'" end end end def parse(string, wants_doc = false, filename = nil, warnings = nil) parser = Parser.new(string, warnings: warnings) parser.warnings = warnings if warnings parser.wants_doc = wants_doc if filename parser.filename = filename end parser.parse end