Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 765072c63062
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 00bc6fdb3545
Choose a head ref
  • 5 commits
  • 51 files changed
  • 1 contributor

Commits on Jul 21, 2016

  1. Reomved a bunch of TODOs and obsolete comments

    Ary Borenszweig committed Jul 21, 2016
    Copy the full SHA
    084b406 View commit details
  2. Compiler: a few more clean ups and docs in Program

    Ary Borenszweig committed Jul 21, 2016
    Copy the full SHA
    64a2f11 View commit details
  3. Copy the full SHA
    6aba9c8 View commit details
  4. Compiler: don't store attributes in AST nodes as Array(Attribute)

    Instead, store them as boolean where appropriate. This simplifies the code
    a bit, makes it more clear, and should also reduce memory usage a bit.
    Ary Borenszweig committed Jul 21, 2016
    Copy the full SHA
    50ce0c4 View commit details
  5. Compiler: general refactors and simplifications for better code reada…

    …bility and brevity
    Ary Borenszweig committed Jul 21, 2016
    Copy the full SHA
    00bc6fd View commit details
Showing with 642 additions and 830 deletions.
  1. +1 −1 spec/compiler/crystal/tools/context_spec.cr
  2. +6 −6 spec/compiler/crystal/tools/implementations_spec.cr
  3. +7 −7 spec/compiler/lexer/location_spec.cr
  4. +7 −5 spec/compiler/macro/macro_methods_spec.cr
  5. +18 −18 spec/compiler/type_inference/closure_spec.cr
  6. +5 −5 spec/compiler/type_inference/exception_spec.cr
  7. +1 −1 src/compiler/crystal/codegen/asm.cr
  8. +3 −3 src/compiler/crystal/codegen/ast.cr
  9. +3 −3 src/compiler/crystal/codegen/call.cr
  10. +2 −2 src/compiler/crystal/codegen/class_var.cr
  11. +7 −12 src/compiler/crystal/codegen/codegen.cr
  12. +13 −26 src/compiler/crystal/codegen/fun.cr
  13. +5 −24 src/compiler/crystal/codegen/llvm_builder_helper.cr
  14. +2 −2 src/compiler/crystal/codegen/primitives.cr
  15. +1 −1 src/compiler/crystal/command/cursor.cr
  16. +1 −2 src/compiler/crystal/config.cr
  17. +3 −5 src/compiler/crystal/macros/macros.cr
  18. +3 −3 src/compiler/crystal/macros/methods.cr
  19. +106 −100 src/compiler/crystal/program.cr
  20. +134 −27 src/compiler/crystal/semantic/ast.cr
  21. +37 −20 src/compiler/crystal/semantic/base_type_visitor.cr
  22. +5 −5 src/compiler/crystal/semantic/call.cr
  23. +1 −1 src/compiler/crystal/semantic/call_error.cr
  24. +1 −5 src/compiler/crystal/semantic/class_vars_initializer_visitor.cr
  25. +2 −20 src/compiler/crystal/semantic/cleanup_transformer.cr
  26. +8 −0 src/compiler/crystal/semantic/cover.cr
  27. +8 −8 src/compiler/crystal/semantic/default_arguments.cr
  28. +1 −5 src/compiler/crystal/semantic/instance_vars_initializer_visitor.cr
  29. +5 −5 src/compiler/crystal/semantic/lib.cr
  30. +1 −1 src/compiler/crystal/semantic/literal_expander.cr
  31. +18 −18 src/compiler/crystal/semantic/main_visitor.cr
  32. +1 −2 src/compiler/crystal/semantic/method_lookup.cr
  33. +3 −3 src/compiler/crystal/semantic/new.cr
  34. +2 −2 src/compiler/crystal/semantic/normalizer.cr
  35. +4 −7 src/compiler/crystal/semantic/suggestions.cr
  36. +11 −14 src/compiler/crystal/semantic/top_level_visitor.cr
  37. +3 −3 src/compiler/crystal/semantic/type_declaration_processor.cr
  38. +1 −5 src/compiler/crystal/semantic/type_declaration_visitor.cr
  39. +2 −6 src/compiler/crystal/semantic/type_guess_visitor.cr
  40. +2 −3 src/compiler/crystal/semantic/type_lookup.cr
  41. +66 −191 src/compiler/crystal/syntax/ast.cr
  42. +1 −1 src/compiler/crystal/syntax/lexer.cr
  43. +45 −49 src/compiler/crystal/syntax/location.cr
  44. +1 −1 src/compiler/crystal/syntax/parser.cr
  45. +13 −13 src/compiler/crystal/syntax/to_s.cr
  46. +1 −1 src/compiler/crystal/syntax/token.cr
  47. +7 −6 src/compiler/crystal/syntax/virtual_file.cr
  48. +2 −2 src/compiler/crystal/tools/doc/type.cr
  49. +8 −8 src/compiler/crystal/tools/formatter.cr
  50. +54 −170 src/compiler/crystal/types.cr
  51. +0 −2 src/io/buffered.cr
2 changes: 1 addition & 1 deletion spec/compiler/crystal/tools/context_spec.cr
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ def run_context_tool(code)

code.lines.each_with_index do |line, line_number_0|
if column_number = line.index('‸')
cursor_location = Location.new(line_number_0 + 1, column_number + 1, ".")
cursor_location = Location.new(".", line_number_0 + 1, column_number + 1)
end
end

12 changes: 6 additions & 6 deletions spec/compiler/crystal/tools/implementations_spec.cr
Original file line number Diff line number Diff line change
@@ -21,11 +21,11 @@ def assert_implementations(code)

code.lines.each_with_index do |line, line_number_0|
if column_number = line.index('‸')
cursor_location = Location.new(line_number_0 + 1, column_number + 1, ".")
cursor_location = Location.new(".", line_number_0 + 1, column_number + 1)
end

if column_number = line.index('༓')
expected_locations << Location.new(line_number_0 + 1, column_number + 1, ".")
expected_locations << Location.new(".", line_number_0 + 1, column_number + 1)
end
end

@@ -34,7 +34,7 @@ def assert_implementations(code)
if cursor_location
visitor, result = processed_implementation_visitor(code, cursor_location)

result_location = result.implementations.not_nil!.map { |e| Location.new(e.line.not_nil!, e.column.not_nil!, e.filename.not_nil!).to_s }.sort
result_location = result.implementations.not_nil!.map { |e| Location.new(e.filename.not_nil!, e.line.not_nil!, e.column.not_nil!).to_s }.sort

result_location.should eq(expected_locations.map(&.to_s))
else
@@ -189,7 +189,7 @@ describe "implementations" do
baz
bar
), Location.new(12, 9, "."))
), Location.new(".", 12, 9))

result.implementations.should_not be_nil
impls = result.implementations.not_nil!
@@ -227,7 +227,7 @@ describe "implementations" do
baz
bar
), Location.new(12, 9, "."))
), Location.new(".", 12, 9))

String::Builder.build do |io|
result.to_text(io)
@@ -251,7 +251,7 @@ describe "implementations" do
baz
bar
), Location.new(12, 9, "."))
), Location.new(".", 12, 9))

String::Builder.build do |io|
result.to_json(io)
14 changes: 7 additions & 7 deletions spec/compiler/lexer/location_spec.cr
Original file line number Diff line number Diff line change
@@ -84,8 +84,8 @@ describe "Lexer: location" do
end

it "locations in different files have no order" do
loc1 = Location.new(1, 1, "file1")
loc2 = Location.new(2, 2, "file2")
loc1 = Location.new("file1", 1, 1)
loc2 = Location.new("file2", 2, 2)

(loc1 < loc2).should be_false
(loc1 <= loc2).should be_false
@@ -95,9 +95,9 @@ describe "Lexer: location" do
end

it "locations in same files are comparable based on line" do
loc1 = Location.new(1, 1, "file1")
loc2 = Location.new(2, 1, "file1")
loc3 = Location.new(1, 1, "file1")
loc1 = Location.new("file1", 1, 1)
loc2 = Location.new("file1", 2, 1)
loc3 = Location.new("file1", 1, 1)
(loc1 < loc2).should be_true
(loc1 <= loc2).should be_true
(loc1 <= loc3).should be_true
@@ -116,8 +116,8 @@ describe "Lexer: location" do
end

it "locations with virtual files shoud be comparable" do
loc1 = Location.new(1, 1, "file1")
loc2 = Location.new(2, 1, VirtualFile.new(Macro.new("macro", [] of Arg, Nop.new), "", Location.new(1, 1, "f")))
loc1 = Location.new("file1", 1, 1)
loc2 = Location.new(VirtualFile.new(Macro.new("macro", [] of Arg, Nop.new), "", Location.new("f", 1, 1)), 2, 1)
(loc1 < loc2).should be_false
(loc2 < loc1).should be_false
end
12 changes: 7 additions & 5 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
@@ -3,24 +3,26 @@ require "../../spec_helper"
describe "macro methods" do
describe "node methods" do
describe "location" do
location = Location.new("foo.cr", 1, 2)

it "filename" do
assert_macro "x", "{{x.filename}}", ["hello".string.tap { |n| n.location = Location.new(1, 2, "foo.cr") }] of ASTNode, %("foo.cr")
assert_macro "x", "{{x.filename}}", ["hello".string.tap { |n| n.location = location }] of ASTNode, %("foo.cr")
end

it "line_number" do
assert_macro "x", "{{x.line_number}}", ["hello".string.tap { |n| n.location = Location.new(1, 2, "foo.cr") }] of ASTNode, %(1)
assert_macro "x", "{{x.line_number}}", ["hello".string.tap { |n| n.location = location }] of ASTNode, %(1)
end

it "column number" do
assert_macro "x", "{{x.column_number}}", ["hello".string.tap { |n| n.location = Location.new(1, 2, "foo.cr") }] of ASTNode, %(2)
assert_macro "x", "{{x.column_number}}", ["hello".string.tap { |n| n.location = location }] of ASTNode, %(2)
end

it "end line_number" do
assert_macro "x", "{{x.end_line_number}}", ["hello".string.tap { |n| n.end_location = Location.new(1, 2, "foo.cr") }] of ASTNode, %(1)
assert_macro "x", "{{x.end_line_number}}", ["hello".string.tap { |n| n.end_location = location }] of ASTNode, %(1)
end

it "end column number" do
assert_macro "x", "{{x.end_column_number}}", ["hello".string.tap { |n| n.end_location = Location.new(1, 2, "foo.cr") }] of ASTNode, %(2)
assert_macro "x", "{{x.end_column_number}}", ["hello".string.tap { |n| n.end_location = location }] of ASTNode, %(2)
end
end

36 changes: 18 additions & 18 deletions spec/compiler/type_inference/closure_spec.cr
Original file line number Diff line number Diff line change
@@ -13,14 +13,14 @@ describe "Type inference: closure" do
result = assert_type("x = 1; -> { x }; x") { int32 }
program = result.program
var = program.vars["x"]
var.closured.should be_true
var.closured?.should be_true
end

it "marks variable as closured in program on assign" do
result = assert_type("x = 1; -> { x = 1 }; x") { int32 }
program = result.program
var = program.vars["x"]
var.closured.should be_true
var.closured?.should be_true
end

it "marks variable as closured in def" do
@@ -29,7 +29,7 @@ describe "Type inference: closure" do
call = node.expressions.last.as(Call)
target_def = call.target_def
var = target_def.vars.not_nil!["x"]
var.closured.should be_true
var.closured?.should be_true
end

it "marks variable as closured in block" do
@@ -48,7 +48,7 @@ describe "Type inference: closure" do
call = node.expressions.last.as(Call)
block = call.block.not_nil!
var = block.vars.not_nil!["x"]
var.closured.should be_true
var.closured?.should be_true
end

it "unifies types of closured var (1)" do
@@ -81,7 +81,7 @@ describe "Type inference: closure" do
") { int32 }
program = result.program
var = program.vars.not_nil!["a"]
var.closured.should be_true
var.closured?.should be_true
end

it "doesn't mark var as closured if only used in block" do
@@ -96,7 +96,7 @@ describe "Type inference: closure" do
") { int32 }
program = result.program
var = program.vars["x"]
var.closured.should be_false
var.closured?.should be_false
end

it "doesn't mark var as closured if only used in two block" do
@@ -116,7 +116,7 @@ describe "Type inference: closure" do
call = node[1].as(Call)
block = call.block.not_nil!
var = block.vars.not_nil!["x"]
var.closured.should be_false
var.closured?.should be_false
end

it "doesn't mark self var as closured, but marks method as self closured" do
@@ -134,8 +134,8 @@ describe "Type inference: closure" do
call = node.expressions[-2].as(Call)
target_def = call.target_def
var = target_def.vars.not_nil!["self"]
var.closured.should be_false
target_def.self_closured.should be_true
var.closured?.should be_false
target_def.self_closured?.should be_true
end

it "marks method as self closured if instance var is read" do
@@ -153,7 +153,7 @@ describe "Type inference: closure" do
") { int32 }
node = result.node.as(Expressions)
call = node.expressions[-2].as(Call)
call.target_def.self_closured.should be_true
call.target_def.self_closured?.should be_true
end

it "marks method as self closured if instance var is written" do
@@ -169,7 +169,7 @@ describe "Type inference: closure" do
") { int32 }
node = result.node.as(Expressions)
call = node.expressions[-2].as(Call)
call.target_def.self_closured.should be_true
call.target_def.self_closured?.should be_true
end

it "marks method as self closured if explicit self call is made" do
@@ -188,7 +188,7 @@ describe "Type inference: closure" do
") { int32 }
node = result.node.as(Expressions)
call = node.expressions[-2].as(Call)
call.target_def.self_closured.should be_true
call.target_def.self_closured?.should be_true
end

it "marks method as self closured if implicit self call is made" do
@@ -207,7 +207,7 @@ describe "Type inference: closure" do
") { int32 }
node = result.node.as(Expressions)
call = node.expressions[-2].as(Call)
call.target_def.self_closured.should be_true
call.target_def.self_closured?.should be_true
end

it "marks method as self closured if used inside a block" do
@@ -227,7 +227,7 @@ describe "Type inference: closure" do
") { int32 }
node = result.node.as(Expressions)
call = node.expressions[-2].as(Call)
call.target_def.self_closured.should be_true
call.target_def.self_closured?.should be_true
end

it "errors if sending closured proc literal to C" do
@@ -448,7 +448,7 @@ describe "Type inference: closure" do
->{ a = 1; ->{ a } }
), inject_primitives: false) { proc_of(proc_of(int32)) }
fn = result.node.as(ProcLiteral)
fn.def.closure.should be_false
fn.def.closure?.should be_false
end

it "marks outer fun inside a block as closured" do
@@ -461,7 +461,7 @@ describe "Type inference: closure" do
->{ ->{ foo { a } } }
)) { proc_of(proc_of(int32)) }
fn = result.node.as(Expressions).last.as(ProcLiteral)
fn.def.closure.should be_true
fn.def.closure?.should be_true
end

it "marks outer fun as closured when using self" do
@@ -476,9 +476,9 @@ describe "Type inference: closure" do
)) { proc_of(proc_of(types["Foo"])) }
call = result.node.as(Expressions).last.as(Call)
a_def = call.target_def
a_def.self_closured.should be_true
a_def.self_closured?.should be_true
fn = (a_def.body.as(ProcLiteral))
fn.def.closure.should be_true
fn.def.closure?.should be_true
end

it "can use fun typedef as block type" do
10 changes: 5 additions & 5 deletions spec/compiler/type_inference/exception_spec.cr
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ describe "Type inference: exception" do
mod = result.program
a_def = mod.lookup_first_def("foo", false)
def_instance = mod.lookup_def_instance DefInstanceKey.new(a_def.object_id, [] of Type, nil, nil)
def_instance.not_nil!.raises.should be_true
def_instance.not_nil!.raises?.should be_true
end

it "marks method calling lib fun that raises as raises" do
@@ -77,7 +77,7 @@ describe "Type inference: exception" do
mod = result.program
a_def = mod.lookup_first_def("foo", false)
def_instance = mod.lookup_def_instance DefInstanceKey.new(a_def.object_id, [] of Type, nil, nil)
def_instance.not_nil!.raises.should be_true
def_instance.not_nil!.raises?.should be_true
end

it "types exception var with no types" do
@@ -248,7 +248,7 @@ describe "Type inference: exception" do
)) { int32 }
mod = result.program
a_def = mod.lookup_first_def("foo", false)
a_def.not_nil!.raises.should be_true
a_def.not_nil!.raises?.should be_true
end

it "marks def as raises" do
@@ -262,13 +262,13 @@ describe "Type inference: exception" do
)) { int32 }
mod = result.program
a_def = mod.lookup_first_def("foo", false)
a_def.not_nil!.raises.should be_true
a_def.not_nil!.raises?.should be_true
end

it "marks proc literal as raises" do
result = assert_type("->{ 1 }.call", inject_primitives: true) { int32 }
call = result.node.as(Expressions).last.as(Call)
call.target_def.raises.should be_true
call.target_def.raises?.should be_true
end

it "shadows local variable (1)" do
2 changes: 1 addition & 1 deletion src/compiler/crystal/codegen/asm.cr
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ class Crystal::CodeGenVisitor
fun_type = LLVM::Type.function(input_types, output_type)
constraints = constraints.to_s

value = LLVM.const_inline_asm(fun_type, node.text, constraints, node.volatile, node.alignstack)
value = LLVM.const_inline_asm(fun_type, node.text, constraints, node.volatile?, node.alignstack?)
asm_value = call value, input_values

if ptrof
6 changes: 3 additions & 3 deletions src/compiler/crystal/codegen/ast.cr
Original file line number Diff line number Diff line change
@@ -63,15 +63,15 @@ module Crystal
next_def = next_def.next
end

if args.size > 0 || uses_block_arg
if args.size > 0 || uses_block_arg?
str << "<"
if args.size > 0
args.each_with_index do |arg, i|
str << ", " if i > 0
arg.type.llvm_name(str)
end
end
if uses_block_arg
if uses_block_arg?
str << ", " if args.size > 0
str << "&"
block_arg.not_nil!.type.llvm_name(str)
@@ -87,7 +87,7 @@ module Crystal
Crystal.safe_mangling(program, name)
end

def varargs
def varargs?
false
end
end
6 changes: 3 additions & 3 deletions src/compiler/crystal/codegen/call.cr
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ class Crystal::CodeGenVisitor
def call_abi_info(target_def, node)
# For varargs we need to compute abi info for the arguments, which may be more
# than those specified in the function definition
if target_def.varargs
if target_def.varargs?
abi_info(target_def, node)
else
abi_info(target_def)
@@ -272,7 +272,7 @@ class Crystal::CodeGenVisitor
fun_literal.accept self
call_args.push @last

codegen_call_or_invoke(node, target_def, self_type, func, call_args, target_def.raises, target_def.type)
codegen_call_or_invoke(node, target_def, self_type, func, call_args, target_def.raises?, target_def.type)
end

def codegen_dispatch(node, target_defs)
@@ -379,7 +379,7 @@ class Crystal::CodeGenVisitor
end

func = target_def_fun(target_def, self_type)
codegen_call_or_invoke(node, target_def, self_type, func, call_args, target_def.raises, target_def.type)
codegen_call_or_invoke(node, target_def, self_type, func, call_args, target_def.raises?, target_def.type)
end

# If a method's body is just a simple literal, "self", or an instance variable,
4 changes: 2 additions & 2 deletions src/compiler/crystal/codegen/class_var.cr
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ class Crystal::CodeGenVisitor

# For unsafe class var we just initialize them without
# using a flag to know if they were initialized
if class_var.uninitialized
if class_var.uninitialized?
global = declare_class_var(owner, name, class_var.type, class_var.thread_local?)
global = ensure_class_var_in_this_module(global, owner, name, class_var.type, class_var.thread_local?)
func = @main_mod.functions[init_function_name]? ||
@@ -177,7 +177,7 @@ class Crystal::CodeGenVisitor
end

initializer = class_var.initializer
if !initializer || class_var.uninitialized
if !initializer || class_var.uninitialized?
# Read directly without init flag, but make sure to declare the global in this module too
global_name = class_var_global_name(class_var.owner, class_var.name)
global = get_global global_name, class_var.type, class_var
Loading