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: 54415ffa3d2f
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: d3dfe16b945f
Choose a head ref
  • 3 commits
  • 4 files changed
  • 1 contributor

Commits on Jun 9, 2017

  1. Copy the full SHA
    5a368de View commit details
  2. 1
    Copy the full SHA
    66ecb35 View commit details
  3. Copy the full SHA
    d3dfe16 View commit details
12 changes: 12 additions & 0 deletions spec/compiler/formatter/formatter_spec.cr
Original file line number Diff line number Diff line change
@@ -1033,4 +1033,16 @@ describe Crystal::Formatter do
assert_format "foo\n \nbar", "foo\n\nbar"

assert_format "\"\" + <<-END\n bar\n END"

assert_format "1 + \\\n2", "1 + \\\n 2"
assert_format "1 + \\\n2 + \\\n3", "1 + \\\n 2 + \\\n 3"
assert_format "1 + \\\n2\n3", "1 + \\\n 2\n3"
assert_format "1 \\\n+ 2", "1 \\\n + 2"
assert_format "foo \\\nbar", "foo \\\n bar"
assert_format "1 \\\nif 2", "1 \\\n if 2"
assert_format "1 \\\nrescue 2", "1 \\\n rescue 2"
assert_format "1 \\\nensure 2", "1 \\\n ensure 2"
assert_format "foo bar, \\\nbaz", "foo bar,\n baz"

assert_format "alias X = ((Y, Z) ->)"
end
17 changes: 17 additions & 0 deletions spec/compiler/semantic/module_spec.cr
Original file line number Diff line number Diff line change
@@ -1242,4 +1242,21 @@ describe "Semantic: module" do
mooer.moo
)) { union_of int32, char }
end

it "errors when extending module that defines instance vars (#4065)" do
assert_error %(
module Foo
@foo : Int32?
def foo
@foo
end
end
class Bar
extend Foo
end
),
"can't declare instance variables in Bar:Class"
end
end
4 changes: 4 additions & 0 deletions src/compiler/crystal/semantic/type_declaration_processor.cr
Original file line number Diff line number Diff line change
@@ -240,6 +240,10 @@ struct Crystal::TypeDeclarationProcessor
# set from uninstantiated generic types
return if owner.is_a?(GenericInstanceType)

if owner.metaclass?
raise TypeException.new("can't declare instance variables in #{owner}", type_decl.location)
end

# Check if a superclass already defined this variable
supervar = owner.lookup_instance_var?(name)

96 changes: 79 additions & 17 deletions src/compiler/crystal/tools/formatter.cr
Original file line number Diff line number Diff line change
@@ -123,6 +123,7 @@ module Crystal
@last_arg_is_skip = false
@string_continuation = 0
@inside_call_or_assign = 0
@passed_backslash_newline = false

# Lines that must not be rstripped (HEREDOC lines)
@no_rstrip_lines = Set(Int32).new
@@ -942,6 +943,9 @@ module Crystal
write "("
next_token_skip_space
@paren_count += 1
true
else
false
end
end

@@ -1994,16 +1998,27 @@ module Crystal
paren_count = @paren_count

if inputs = node.inputs
# Check if it's ((X, Y) -> Z)
# ^ ^
sub_paren_count = @paren_count
if check_open_paren
sub_paren_count = @paren_count
end

inputs.each_with_index do |input, i|
accept input
if @paren_count == paren_count
if @paren_count == sub_paren_count
skip_space_or_newline
if @token.type == :","
write ", " unless last?(i, inputs)
next_token_skip_space_or_newline
end
end
end

if sub_paren_count != paren_count
check_close_paren
end
end

skip_space_or_newline if paren_count == @paren_count
@@ -2097,6 +2112,8 @@ module Crystal

accept obj

passed_backslash_newline = @token.passed_backslash_newline

if @token.type == :SPACE
needs_space = true
else
@@ -2178,7 +2195,7 @@ module Crystal
@dot_column = old_dot_column
return false
else
write " " if needs_space
write " " if needs_space && !passed_backslash_newline
write node.name

# This is the case of a-1 and a+1
@@ -2190,7 +2207,9 @@ module Crystal
end

next_token
passed_backslash_newline = @token.passed_backslash_newline
found_comment = skip_space

if found_comment || @token.type == :NEWLINE
if @inside_call_or_assign == 0
next_indent = @indent + 2
@@ -2203,7 +2222,7 @@ module Crystal
end
write_indent(next_indent, node.args.last)
else
write " " if needs_space
write " " if needs_space && !passed_backslash_newline
inside_call_or_assign do
accept node.args.last
end
@@ -2248,6 +2267,8 @@ module Crystal
end
next_token

passed_backslash_newline = @token.passed_backslash_newline

if assignment
skip_space

@@ -2299,7 +2320,7 @@ module Crystal
end
skip_space_or_newline
elsif has_args || node.block_arg
write " "
write " " unless passed_backslash_newline
skip_space
has_newlines, found_comment = format_call_args(node, false)
end
@@ -2389,19 +2410,26 @@ module Crystal
end
slash_is_regex!
write_token :","
found_comment = skip_space(needed_indent)
if found_comment
write_indent(needed_indent)

if @token.passed_backslash_newline
write_line
next_needs_indent = true
has_newlines = true
else
if @token.type == :NEWLINE
indent(needed_indent) { consume_newlines }
next_needs_indent = true
has_newlines = true
found_comment = skip_space(needed_indent)
if found_comment
write_indent(needed_indent)
else
write " "
if @token.type == :NEWLINE
indent(needed_indent) { consume_newlines }
next_needs_indent = true
has_newlines = true
else
write " "
end
end
skip_space_or_newline
end
skip_space_or_newline
end
end

@@ -3545,8 +3573,9 @@ module Crystal
else
if node.suffix
accept node.body
passed_backslash_newline = @token.passed_backslash_newline
skip_space
write " "
write " " unless passed_backslash_newline
if @token.keyword?(:rescue)
write_keyword :rescue
write " "
@@ -3944,6 +3973,9 @@ module Crystal
io << @output
end

def maybe_reset_passed_backslash_newline
end

def next_token
current_line_number = @lexer.line_number
@token = @lexer.next_token
@@ -3992,10 +4024,31 @@ module Crystal
def skip_space(write_comma : Bool = false)
base_column = @column
has_space = false
while @token.type == :SPACE

if @token.type == :SPACE
if @token.passed_backslash_newline
if write_comma
write ", "
else
write " "
end
write "\\"
write_line
@indent += 2 unless @passed_backslash_newline
write_indent
next_token
@passed_backslash_newline = true
if @token.type == :SPACE
return skip_space(write_comma)
else
return false
end
end

next_token
has_space = true
end

if @token.type == :COMMENT
needs_space = has_space && base_column != 0
if write_comma
@@ -4257,6 +4310,10 @@ module Crystal
@wrote_newline = true
increment_line
@last_write = ""
if @passed_backslash_newline
@passed_backslash_newline = false
@indent -= 2
end
end

def increment_line
@@ -4474,8 +4531,13 @@ module Crystal
end

def write_keyword(before : String, keyword : Symbol, after : String)
skip_space_or_newline
write before
passed_backslash_newline = @token.passed_backslash_newline
skip_space
if passed_backslash_newline && before == " "
# Nothing
else
write before
end
write_keyword keyword
write after
skip_space_or_newline