Skip to content
Closed
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
2 changes: 1 addition & 1 deletion samples/sdl/fire.cr
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class Screen
@rects : Array(Rectangle)

def initialize(@surface : SDL::Surface)
@background = Array(UInt32).new(surface.width * surface.height, 0_u32)
@background = Array(UInt32).new(@surface.width * @surface.height, 0_u32)
@rects = parse_rectangles("#{__DIR__}/fire.txt")
end

Expand Down
2 changes: 1 addition & 1 deletion spec/compiler/crystal/tools/context_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ describe "context" do
end

Bar.new("s")
), "self", "@ivar", "ivar"
), "self", "@ivar", "__arg0"
end

it "can get context in generic class" do
Expand Down
6 changes: 3 additions & 3 deletions spec/compiler/crystal/tools/playground_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,9 @@ describe Playground::AgentInstrumentorTransformer do
end
), <<-CR
class Foo
def initialize(x, y)
@x = x
@y = y
def initialize(x __arg0, y __arg1)
@x = __arg0
@y = __arg1
@z = _p.i(4) { @x + @y }.as(typeof(@x + @y))
end
end
Expand Down
18 changes: 9 additions & 9 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ describe "Parser" do
it_parses "def foo; with a yield; end", Def.new("foo", body: Yield.new(scope: "a".call), yields: 1)
it_parses "def foo; with a yield 1; end", Def.new("foo", body: Yield.new([1.int32] of ASTNode, "a".call), yields: 1)
it_parses "def foo; a = 1; with a yield a; end", Def.new("foo", body: [Assign.new("a".var, 1.int32), Yield.new(["a".var] of ASTNode, "a".var)] of ASTNode, yields: 1)
it_parses "def foo(@var); end", Def.new("foo", [Arg.new("var")], [Assign.new("@var".instance_var, "var".var)] of ASTNode)
it_parses "def foo(@var); 1; end", Def.new("foo", [Arg.new("var")], [Assign.new("@var".instance_var, "var".var), 1.int32] of ASTNode)
it_parses "def foo(@var = 1); 1; end", Def.new("foo", [Arg.new("var", 1.int32)], [Assign.new("@var".instance_var, "var".var), 1.int32] of ASTNode)
it_parses "def foo(@@var); end", Def.new("foo", [Arg.new("var")], [Assign.new("@@var".class_var, "var".var)] of ASTNode)
it_parses "def foo(@@var); 1; end", Def.new("foo", [Arg.new("var")], [Assign.new("@@var".class_var, "var".var), 1.int32] of ASTNode)
it_parses "def foo(@@var = 1); 1; end", Def.new("foo", [Arg.new("var", 1.int32)], [Assign.new("@@var".class_var, "var".var), 1.int32] of ASTNode)
it_parses "def foo(&@block); end", Def.new("foo", body: Assign.new("@block".instance_var, "block".var), block_arg: Arg.new("block"), yields: 0)
it_parses "def foo(@var); end", Def.new("foo", [Arg.new("__arg0", external_name: "var")], [Assign.new("@var".instance_var, "__arg0".var)] of ASTNode)
it_parses "def foo(@var); 1; end", Def.new("foo", [Arg.new("__arg0", external_name: "var")], [Assign.new("@var".instance_var, "__arg0".var), 1.int32] of ASTNode)
it_parses "def foo(@var = 1); 1; end", Def.new("foo", [Arg.new("__arg0", external_name: "var", default_value: 1.int32)], [Assign.new("@var".instance_var, "__arg0".var), 1.int32] of ASTNode)
it_parses "def foo(@@var); end", Def.new("foo", [Arg.new("__arg0", external_name: "var")], [Assign.new("@@var".class_var, "__arg0".var)] of ASTNode)
it_parses "def foo(@@var); 1; end", Def.new("foo", [Arg.new("__arg0", external_name: "var")], [Assign.new("@@var".class_var, "__arg0".var), 1.int32] of ASTNode)
it_parses "def foo(@@var = 1); 1; end", Def.new("foo", [Arg.new("__arg0", external_name: "var", default_value: 1.int32)], [Assign.new("@@var".class_var, "__arg0".var), 1.int32] of ASTNode)
it_parses "def foo(&@block); end", Def.new("foo", body: Assign.new("@block".instance_var, "__arg0".var), block_arg: Arg.new("__arg0"), yields: 0)

it_parses "def foo(\n&block\n); end", Def.new("foo", block_arg: Arg.new("block"), yields: 0)
it_parses "def foo(&block \n: Int ->); end", Def.new("foo", block_arg: Arg.new("block", restriction: ProcNotation.new(["Int".path] of ASTNode)), yields: 1)
Expand Down Expand Up @@ -264,8 +264,8 @@ describe "Parser" do
assert_syntax_error "def foo(**args, *x); end", "only block argument is allowed after double splat"

it_parses "def foo(x y); y; end", Def.new("foo", args: [Arg.new("y", external_name: "x")], body: "y".var)
it_parses "def foo(x @var); end", Def.new("foo", [Arg.new("var", external_name: "x")], [Assign.new("@var".instance_var, "var".var)] of ASTNode)
it_parses "def foo(x @@var); end", Def.new("foo", [Arg.new("var", external_name: "x")], [Assign.new("@@var".class_var, "var".var)] of ASTNode)
it_parses "def foo(x @var); end", Def.new("foo", [Arg.new("__arg0", external_name: "x")], [Assign.new("@var".instance_var, "__arg0".var)] of ASTNode)
it_parses "def foo(x @@var); end", Def.new("foo", [Arg.new("__arg0", external_name: "x")], [Assign.new("@@var".class_var, "__arg0".var)] of ASTNode)
assert_syntax_error "def foo(_ y); y; end"

it_parses %(def foo("bar qux" y); y; end), Def.new("foo", args: [Arg.new("y", external_name: "bar qux")], body: "y".var)
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ module Crystal
@llvm_typer = LLVMTyper.new(@program, @llvm_context)
@main_llvm_typer = @llvm_typer
@llvm_id = LLVMId.new(@program)
@main_ret_type = node.type? || @program.nil_type
@main_ret_type = @node.type? || @program.nil_type
ret_type = @llvm_typer.llvm_return_type(@main_ret_type)
@main = @llvm_mod.functions.add(MAIN_NAME, [llvm_context.int32, llvm_context.void_pointer.pointer], ret_type)

Expand Down Expand Up @@ -180,12 +180,12 @@ module Crystal
@strings = {} of StringKey => LLVM::Value
@symbols = {} of String => Int32
@symbol_table_values = [] of LLVM::Value
program.symbols.each_with_index do |sym, index|
@program.symbols.each_with_index do |sym, index|
@symbols[sym] = index
@symbol_table_values << build_string_constant(sym, sym)
end

unless program.symbols.empty?
unless @program.symbols.empty?
symbol_table = define_symbol_table @llvm_mod, @llvm_typer
symbol_table.initializer = llvm_type(@program.string).const_array(@symbol_table_values)
end
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/codegen/llvm_typer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ module Crystal

@structs = {} of String => LLVM::Type

machine = program.target_machine
machine = @program.target_machine
@layout = machine.data_layout
@landing_pad_type = @llvm_context.struct([@llvm_context.void_pointer, @llvm_context.int32], "landing_pad")
end
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/exception.cr
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module Crystal
# message with that message. In this way the error message will
# look like a regular message produced by the compiler, and not
# because of an incorrect macro expansion.
if inner.is_a?(MacroRaiseException)
if (inner = @inner).is_a?(MacroRaiseException)
message = inner.message
@inner = nil
end
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/filters.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Crystal
class TypeFilteredNode < ASTNode
def initialize(@filter : TypeFilter, @node : ASTNode)
@dependencies = [@node] of ASTNode
node.add_observer self
@node.add_observer self
update(@node)
end

Expand Down
3 changes: 2 additions & 1 deletion src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ module Crystal
# Type filters for `exp` in `!exp`, used after a `while`
@before_not_type_filters : TypeFilters?

def initialize(program, vars = MetaVars.new, @typed_def = nil, meta_vars = nil)
def initialize(program, vars = MetaVars.new, typed_def = nil, meta_vars = nil)
super(program, vars)
@typed_def = typed_def
@while_stack = [] of While
@needs_type_filters = 0
@typeof_nest = 0
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/crystal/semantic/type_lookup.cr
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ class Crystal::Type
# If we are looking types inside a non-instantiated generic type,
# for example Hash(K, V), we want to find K and V as type parameters
# of that type.
if @find_root_generic_type_parameters && root.is_a?(GenericType)
free_vars ||= {} of String => TypeVar
if @find_root_generic_type_parameters && (root = @root).is_a?(GenericType)
free_vars = @free_vars ||= {} of String => TypeVar
root.type_vars.each do |type_var|
free_vars[type_var] ||= root.type_parameter(type_var)
end
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/crystal/syntax/ast.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,8 @@ module Crystal
property doc : String?
property? varargs : Bool

def initialize(@name, @args = [] of Arg, @return_type = nil, @varargs = false, @body = nil, @real_name = name)
def initialize(@name, @args = [] of Arg, @return_type = nil, @varargs = false, @body = nil, real_name = nil)
@real_name = real_name || @name
end

def accept_children(visitor)
Expand Down
20 changes: 15 additions & 5 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module Crystal
@def_nest = 0
@type_nest = 0
@call_args_nest = 0
@block_arg_count = 0
@temp_arg_count = 0
@in_macro_expression = false
@stop_on_yield = 0
@inside_c_struct = false
Expand Down Expand Up @@ -1380,8 +1380,7 @@ module Crystal
next_token_skip_space

if @token.type == :"."
block_arg_name = "__arg#{@block_arg_count}"
@block_arg_count += 1
block_arg_name = new_temp_arg_name

obj = Var.new(block_arg_name)

Expand Down Expand Up @@ -3613,6 +3612,9 @@ module Crystal
raise "when specified, external name must be different than internal name", @token
end

external_name ||= arg_name
arg_name = new_temp_arg_name

ivar = InstanceVar.new(@token.value.to_s).at(location)
var = Var.new(arg_name).at(location)
assign = Assign.new(ivar, var).at(location)
Expand All @@ -3629,6 +3631,9 @@ module Crystal
raise "when specified, external name must be different than internal name", @token
end

external_name ||= arg_name
arg_name = new_temp_arg_name

cvar = ClassVar.new(@token.value.to_s).at(location)
var = Var.new(arg_name).at(location)
assign = Assign.new(cvar, var).at(location)
Expand Down Expand Up @@ -3946,8 +3951,7 @@ module Crystal
when :UNDERSCORE
arg_name = "_"
when :"("
block_arg_name = "__arg#{@block_arg_count}"
@block_arg_count += 1
block_arg_name = new_temp_arg_name

next_token_skip_space_or_newline

Expand Down Expand Up @@ -5640,6 +5644,12 @@ module Crystal

token
end

def new_temp_arg_name
name = "__arg#{@temp_arg_count}"
@temp_arg_count += 1
name
end
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can/Should this check if the name already exists in the current scope and discard it? Say I do

def foo(__arg0, @foo)
end

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention is that variables that start with __ are reserved for the compiler, so they shouldn't clash with user variables. If a user choose to name their variables __argN, they are warned that that's problematic (at least in my mind :-P).

I don't want to make things more complex than they should, at this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmh, not asking to do this here, but do you think it would actually be possible to make trying to use these a parser error then? I don't think it's too uncommon for somebody to try to use such variable names, especially when dealing with macros.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it can be done. Sometimes methods are passed to macros, and these are to_s'd, and then reparsed again... and that would error when it shouldn't.

Maybe it's something to consider in the future.

Note that right now the __arg or __temp hack is used all over the place in the compiler (like, when you do if a() || b(), this isn't something new. And so far it didn't cause any problem, so I guess it's fine.

end

class StringInterpolation
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/tools/formatter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1933,7 +1933,7 @@ module Crystal
end
end

if node.external_name != node.name
if !at_skip? && node.external_name != node.name
if node.external_name.empty?
write "_"
elsif @token.type == :DELIMITER_START
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/crystal/types.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1045,14 +1045,16 @@ module Crystal
property? extern_union = false
property? packed = false

def initialize(program, namespace, name, @superclass, add_subclass = true)
def initialize(program, namespace, name, superclass, add_subclass = true)
super(program, namespace, name)
@superclass = superclass
@depth = superclass ? (superclass.depth + 1) : 0
parents.push superclass if superclass
force_add_subclass if add_subclass
end

def superclass=(@superclass)
def superclass=(superclass)
@superclass = superclass
@depth = superclass ? (superclass.depth + 1) : 0
parents.push superclass if superclass
end
Expand Down
2 changes: 1 addition & 1 deletion src/debug/dwarf/info.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Debug
@ref_offset : LibC::OffT

def initialize(@io : IO::FileDescriptor, @offset)
@ref_offset = offset
@ref_offset = @offset

@unit_length = @io.read_bytes(UInt32)
if @unit_length == 0xffffffff
Expand Down
5 changes: 4 additions & 1 deletion src/indexable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,10 @@ module Indexable(T)
private class ReverseItemIterator(A, T)
include Iterator(T)

def initialize(@array : A, @index : Int32 = array.size - 1)
@index : Int32

def initialize(@array : A)
@index = @array.size - 1
end

def next
Expand Down
6 changes: 3 additions & 3 deletions src/io/encoding.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class IO
getter invalid : Symbol?

def initialize(@name : String, @invalid : Symbol?)
EncodingOptions.check_invalid(invalid)
EncodingOptions.check_invalid(@invalid)
end

def self.check_invalid(invalid)
Expand All @@ -19,7 +19,7 @@ class IO

private class Encoder
def initialize(@encoding_options : EncodingOptions)
@iconv = Iconv.new("UTF-8", encoding_options.name, encoding_options.invalid)
@iconv = Iconv.new("UTF-8", @encoding_options.name, @encoding_options.invalid)
@closed = false
end

Expand Down Expand Up @@ -58,7 +58,7 @@ class IO
@in_buffer : Pointer(UInt8)

def initialize(@encoding_options : EncodingOptions)
@iconv = Iconv.new(encoding_options.name, "UTF-8", encoding_options.invalid)
@iconv = Iconv.new(@encoding_options.name, "UTF-8", @encoding_options.invalid)
@buffer = Bytes.new((GC.malloc_atomic(BUFFER_SIZE).as(UInt8*)), BUFFER_SIZE)
@in_buffer = @buffer.to_unsafe
@in_buffer_left = LibC::SizeT.new(0)
Expand Down
5 changes: 4 additions & 1 deletion src/iterator.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,10 @@ module Iterator(T)
include Iterator({T, Int32})
include IteratorWrapper

def initialize(@iterator : I, @offset : O, @index : O = offset)
@index : O

def initialize(@iterator : I, @offset : O)
@index = @offset
end

def next
Expand Down
2 changes: 1 addition & 1 deletion src/levenshtein.cr
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ module Levenshtein
@tolerance : Int32

def initialize(@target : String, tolerance : Int? = nil)
@tolerance = tolerance || (target.size / 5.0).ceil.to_i
@tolerance = tolerance || (@target.size / 5.0).ceil.to_i
end

def test(name : String, value : String = name)
Expand Down
2 changes: 1 addition & 1 deletion src/llvm/di_builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ require "./lib_llvm"

struct LLVM::DIBuilder
def initialize(@llvm_module : Module)
@unwrap = LibLLVMExt.create_di_builder(llvm_module)
@unwrap = LibLLVMExt.create_di_builder(@llvm_module)
end

def create_compile_unit(lang, file, dir, producer, optimized, flags, runtime_version)
Expand Down
13 changes: 8 additions & 5 deletions src/range.cr
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,10 @@ struct Range(B, E)

@range : Range(B, E)
@current : B
@reached_end : Bool
@reached_end = false

def initialize(@range : Range(B, E), @current = range.begin, @reached_end = false)
def initialize(@range : Range(B, E))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you're also changing the ctor signature, we can no more setup current & reached_end. Is that intentional?

Copy link
Copy Markdown
Member

@straight-shoota straight-shoota Apr 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a private class. And the removed arguments don't seem to be used anywhere. Wouldn't make much sense anyway.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor was used internally, so no problem. Same in other places.

@current = @range.begin
end

def next
Expand Down Expand Up @@ -348,7 +349,8 @@ struct Range(B, E)
@range : Range(B, E)
@current : E

def initialize(@range : Range(B, E), @current = range.end)
def initialize(@range : Range(B, E))
@current = @range.end
rewind
end

Expand All @@ -374,9 +376,10 @@ struct Range(B, E)
@range : R
@step : N
@current : B
@reached_end : Bool
@reached_end = false

def initialize(@range, @step, @current = range.begin, @reached_end = false)
def initialize(@range, @step)
@current = @range.begin
end

def next
Expand Down
3 changes: 2 additions & 1 deletion src/socket/address.cr
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class Socket
@addr6 : LibC::In6Addr?
@addr4 : LibC::InAddr?

def initialize(@address : String, @port : Int32)
def initialize(address : String, @port : Int32)
@address = address
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Ditto a few times below, where inline ivar init is ok.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

address is used in the next line and it should be type String. @address would be String?.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because @address is String? and the methods/conditions bellow won't work. But address is String and that works.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow, that's weird to read ^^ but makes sense, ty

if @addr6 = ip6?(address)
@family = Family::INET6
@size = sizeof(LibC::SockaddrIn6)
Expand Down
4 changes: 3 additions & 1 deletion src/socket/unix_server.cr
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ class UNIXServer < UNIXSocket
# ```
# UNIXServer.new("/tmp/dgram.sock", Socket::Type::DGRAM)
# ```
def initialize(@path : String, type : Type = Type::STREAM, backlog = 128)
def initialize(path : String, type : Type = Type::STREAM, backlog = 128)
@path = path

super(Family::UNIX, type)

bind(UNIXAddress.new(path)) do |error|
Expand Down
4 changes: 3 additions & 1 deletion src/socket/unix_socket.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class UNIXSocket < Socket
getter path : String?

# Connects a named UNIX socket, bound to a filesystem pathname.
def initialize(@path : String, type : Type = Type::STREAM)
def initialize(path : String, type : Type = Type::STREAM)
@path = path

super(Family::UNIX, type, Protocol::IP)

connect(UNIXAddress.new(path)) do |error|
Expand Down
2 changes: 1 addition & 1 deletion src/yaml/builder.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class YAML::Builder

# Creates a `YAML::Builder` that will write to the given `IO`.
def initialize(@io : IO)
@box = Box.box(io)
@box = Box.box(@io)
@emitter = Pointer(Void).malloc(LibYAML::EMITTER_SIZE).as(LibYAML::Emitter*)
@event = LibYAML::Event.new
@closed = false
Expand Down
Loading