Skip to content

Commit

Permalink
Merge branch 'master' into changelog/1.15.0
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed Jan 8, 2025
2 parents 2988de8 + 576a14c commit 6aad590
Show file tree
Hide file tree
Showing 73 changed files with 3,481 additions and 318 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ parameters:
distribution-scripts-version:
description: "Git ref for version of https://github.com/crystal-lang/distribution-scripts/"
type: string
default: "da59efb2dfd70dcd7272eaecceffb636ef547427"
default: "588099d9e9de7ecf5925365796d30f832870e18c"
previous_crystal_base_url:
description: "Prefix for URLs to Crystal bootstrap compiler"
type: string
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/win_build_portable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ jobs:
uses: actions/checkout@v4
with:
repository: crystal-lang/shards
ref: v0.18.0
ref: v0.19.0
path: shards

- name: Build shards release
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,26 @@
[#15109]: https://github.com/crystal-lang/crystal/pull/15109
[#15141]: https://github.com/crystal-lang/crystal/pull/15141

## [1.14.1] (2025-01-08)

[1.14.1]: https://github.com/crystal-lang/crystal/releases/1.14.1

### Bugfixes

#### tools

- *(formatter)* Handle trailing comma with multiple parameters on the same line ([#15097], thanks @Blacksmoke16)

[#15097]: https://github.com/crystal-lang/crystal/pull/15097

### Infrastructure

- Changelog for 1.14.1 ([#15323], thanks @straight-shoota)
- *(ci)* Update XCode 15.3.0 in circleci ([#15327], thanks @straight-shoota)

[#15323]: https://github.com/crystal-lang/crystal/pull/15323
[#15327]: https://github.com/crystal-lang/crystal/pull/15327

## [1.14.0] (2024-10-09)

[1.14.0]: https://github.com/crystal-lang/crystal/releases/1.14.0
Expand Down
2 changes: 1 addition & 1 deletion NOTICE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Crystal Programming Language

Copyright 2012-2024 Manas Technology Solutions.
Copyright 2012-2025 Manas Technology Solutions.

This product includes software developed at Manas Technology Solutions (<https://manas.tech/>).

Expand Down
36 changes: 17 additions & 19 deletions spec/compiler/crystal/tools/context_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require "../../../spec_helper"
private def processed_context_visitor(code, cursor_location)
compiler = Compiler.new
compiler.no_codegen = true
compiler.prelude = "empty"
result = compiler.compile(Compiler::Source.new(".", code), "fake-no-build")

visitor = ContextVisitor.new(cursor_location)
Expand Down Expand Up @@ -118,15 +119,20 @@ describe "context" do
it "includes last call" do
assert_context_includes %(
class Foo
property lorem
def lorem
@lorem
end
def initialize(@lorem : Int64)
end
end
def foo(f)
end
f = Foo.new(1i64)
puts f.lo‸rem
foo f.lo‸rem
1
), "f.lorem", ["Int64"]
end
Expand All @@ -141,9 +147,13 @@ describe "context" do

it "does includes regex special variables" do
assert_context_keys %(
def match
$~ = "match"
end
def foo
s = "string"
s =~ /s/
s = "foo"
match
0
end
Expand Down Expand Up @@ -185,23 +195,15 @@ describe "context" do

it "can handle union types" do
assert_context_includes %(
a = if rand() > 0
1i64
else
"foo"
end
a = 1_i64.as(Int64 | String)
0
), "a", ["(Int64 | String)"]
end

it "can display text output" do
run_context_tool(%(
a = if rand() > 0
1i64
else
"foo"
end
a = 1_i64.as(Int64 | String)
0
)) do |result|
Expand All @@ -218,11 +220,7 @@ describe "context" do

it "can display json output" do
run_context_tool(%(
a = if rand() > 0
1i64
else
"foo"
end
a = 1_i64.as(Int64 | String)
0
)) do |result|
Expand Down
1 change: 1 addition & 0 deletions spec/compiler/crystal/tools/expand_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ private def processed_expand_visitor(code, cursor_location)
compiler.no_codegen = true
compiler.no_cleanup = true
compiler.wants_doc = true
compiler.prelude = "empty"
result = compiler.compile(Compiler::Source.new(".", code), "fake-no-build")

visitor = ExpandVisitor.new(cursor_location)
Expand Down
22 changes: 17 additions & 5 deletions spec/compiler/crystal/tools/implementations_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require "../../../spec_helper"
private def processed_implementation_visitor(code, cursor_location)
compiler = Compiler.new
compiler.no_codegen = true
compiler.prelude = "empty"
result = compiler.compile(Compiler::Source.new(".", code), "fake-no-build")

visitor = ImplementationsVisitor.new(cursor_location)
Expand Down Expand Up @@ -52,7 +53,7 @@ describe "implementations" do
1
end
puts f‸oo
f‸oo
)
end

Expand Down Expand Up @@ -117,7 +118,6 @@ describe "implementations" do
end
while f‸oo
puts 2
end
)
end
Expand All @@ -129,7 +129,6 @@ describe "implementations" do
end
if f‸oo
puts 2
end
)
end
Expand All @@ -140,7 +139,7 @@ describe "implementations" do
1
end
puts 2 if f‸oo
2 if f‸oo
)
end

Expand All @@ -151,7 +150,6 @@ describe "implementations" do
end
begin
puts 2
rescue
f‸oo
end
Expand Down Expand Up @@ -478,4 +476,18 @@ describe "implementations" do
F‸oo
)
end

it "find implementation on def with no location" do
_, result = processed_implementation_visitor <<-CRYSTAL, Location.new(".", 5, 5)
enum Foo
FOO
end
Foo.new(42)
CRYSTAL

result.implementations.not_nil!.map do |e|
Location.new(e.filename, e.line, e.column).to_s
end.should eq ["<unknown>:0:0"]
end
end
7 changes: 7 additions & 0 deletions spec/compiler/formatter/formatter_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,13 @@ describe Crystal::Formatter do
end
CRYSTAL

assert_format <<-CRYSTAL
def foo(
a, b,
)
end
CRYSTAL

assert_format <<-CRYSTAL
macro foo(
a,
Expand Down
5 changes: 5 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2726,6 +2726,11 @@ module Crystal
it "executes else" do
assert_macro %({{x.else}}), "\"foo\"", {x: MacroIf.new(BoolLiteral.new(true), StringLiteral.new("test"), StringLiteral.new("foo"))}
end

it "executes is_unless?" do
assert_macro %({{x.is_unless?}}), "true", {x: MacroIf.new(BoolLiteral.new(true), StringLiteral.new("test"), StringLiteral.new("foo"), is_unless: true)}
assert_macro %({{x.is_unless?}}), "false", {x: MacroIf.new(BoolLiteral.new(false), StringLiteral.new("test"), StringLiteral.new("foo"), is_unless: false)}
end
end

describe "macro for methods" do
Expand Down
2 changes: 1 addition & 1 deletion spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,7 @@ module Crystal
it_parses "macro foo;bar{% if x %}body{% else %}body2{%end%}baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroIf.new("x".var, "body".macro_literal, "body2".macro_literal), "baz;".macro_literal] of ASTNode))
it_parses "macro foo;bar{% if x %}body{% elsif y %}body2{%end%}baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroIf.new("x".var, "body".macro_literal, MacroIf.new("y".var, "body2".macro_literal)), "baz;".macro_literal] of ASTNode))
it_parses "macro foo;bar{% if x %}body{% elsif y %}body2{% else %}body3{%end%}baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroIf.new("x".var, "body".macro_literal, MacroIf.new("y".var, "body2".macro_literal, "body3".macro_literal)), "baz;".macro_literal] of ASTNode))
it_parses "macro foo;bar{% unless x %}body{% end %}baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroIf.new("x".var, Nop.new, "body".macro_literal), "baz;".macro_literal] of ASTNode))
it_parses "macro foo;bar{% unless x %}body{% end %}baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroIf.new("x".var, Nop.new, "body".macro_literal, is_unless: true), "baz;".macro_literal] of ASTNode))

it_parses "macro foo;bar{% for x in y %}\\ \n body{% end %}baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroFor.new(["x".var], "y".var, "body".macro_literal), "baz;".macro_literal] of ASTNode))
it_parses "macro foo;bar{% for x in y %}\\ \n body{% end %}\\ baz;end", Macro.new("foo", [] of Arg, Expressions.from(["bar".macro_literal, MacroFor.new(["x".var], "y".var, "body".macro_literal), "baz;".macro_literal] of ASTNode))
Expand Down
1 change: 1 addition & 0 deletions spec/compiler/parser/to_s_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ describe "ASTNode#to_s" do
expect_to_s "1e10_f64", "1e10"
expect_to_s "!a"
expect_to_s "!(1 < 2)"
expect_to_s "!a.b && true"
expect_to_s "(1 + 2)..3"
expect_to_s "macro foo\n{{ @type }}\nend"
expect_to_s "macro foo\n\\{{ @type }}\nend"
Expand Down
15 changes: 15 additions & 0 deletions spec/compiler/semantic/macro_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,21 @@ describe "Semantic: macro" do
CRYSTAL
end

it "begins with {{ yield }} (#15050)" do
result = top_level_semantic <<-CRYSTAL, wants_doc: true
macro foo
{{yield}}
end

foo do
# doc comment
def test
end
end
CRYSTAL
result.program.defs.try(&.["test"][0].def.doc).should eq "doc comment"
end

it "can return class type in macro def" do
assert_type(<<-CRYSTAL) { types["Int32"].metaclass }
class Foo
Expand Down
27 changes: 27 additions & 0 deletions spec/manual/string_to_f32_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require "spec"

# Exhaustively checks that for all 4294967296 possible `Float32` values,
# `to_s.to_f32` returns the original number. Splits the floats into 4096 bins
# for better progress tracking. Also useful as a sort of benchmark.
#
# This was originally added when `String#to_f` moved from `LibC.strtod` to
# `fast_float`, but is applicable to any other implementation as well.
describe "x.to_s.to_f32 == x" do
(0_u32..0xFFF_u32).each do |i|
it "%03x00000..%03xfffff" % {i, i} do
0x100000.times do |j|
bits = i << 20 | j
float = bits.unsafe_as(Float32)
str = float.to_s
val = str.to_f32?.should_not be_nil

if float.nan?
val.nan?.should be_true
else
val.should eq(float)
Math.copysign(1, val).should eq(Math.copysign(1, float))
end
end
end
end
end
Loading

0 comments on commit 6aad590

Please sign in to comment.