From e17ccae0aebcf56a66e5d16e4f889b74822725e8 Mon Sep 17 00:00:00 2001
From: Ary Borenszweig <aborenszweig@manas.com.ar>
Date: Thu, 6 Nov 2014 16:58:49 -0300
Subject: [PATCH] The syntax for specifying the base type of an enum, `enum
 Name < BaseType` has been deprecated. Use `enum Name : BaseType`

---
 CHANGELOG.md                                |  3 ++-
 spec/compiler/codegen/fun_spec.cr           |  2 +-
 spec/compiler/parser/parser_spec.cr         |  5 ++--
 spec/compiler/type_inference/c_enum_spec.cr |  4 +--
 spec/spec_helper.cr                         | 28 +++++----------------
 src/compiler/crystal/syntax/parser.cr       |  6 +++--
 src/dir.cr                                  |  2 +-
 7 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8c9ad993e7..f92e113846 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-## Next
+## 0.5.3
 
 * Spec: when a `should` or `should_not` fail, the filename and line number, including the source's line, is included in the error message.
 * Spec: added `-l` switch to be able to run a spec defined in a line.
@@ -6,6 +6,7 @@
 * Properties (property, setter, getter) can now be restricted to a type with the syntax `property name :: Type`.
 * Removed the distinction between `lib` enums and regular enums.
 * Fixed: it was incorrectly possible to define `class`, `def`, etc. inside a call block.
+* The syntax for specifying the base type of an enum, `enum Name < BaseType` has been deprecated. Use `enum Name : BaseType`.
 
 ## 0.5.2 (2014-11-04)
 
diff --git a/spec/compiler/codegen/fun_spec.cr b/spec/compiler/codegen/fun_spec.cr
index 81c727ea59..428dd08c20 100644
--- a/spec/compiler/codegen/fun_spec.cr
+++ b/spec/compiler/codegen/fun_spec.cr
@@ -248,7 +248,7 @@ describe "Code gen: fun" do
   it "allows fun type of enum type with base type" do
     run("
       lib Foo
-        enum MyEnum < UInt16
+        enum MyEnum : UInt16
           X = 1
         end
       end
diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr
index e652681341..a1846c1554 100755
--- a/spec/compiler/parser/parser_spec.cr
+++ b/spec/compiler/parser/parser_spec.cr
@@ -555,7 +555,6 @@ describe "Parser" do
   it_parses "lib C; union Foo; end end", LibDef.new("C", [UnionDef.new("Foo")] of ASTNode)
   it_parses "lib C; enum Foo; A\nB, C\nD = 1; end end", LibDef.new("C", [EnumDef.new("Foo", [Arg.new("A"), Arg.new("B"), Arg.new("C"), Arg.new("D", 1.int32)] of ASTNode)] of ASTNode)
   it_parses "lib C; enum Foo; A = 1, B; end end", LibDef.new("C", [EnumDef.new("Foo", [Arg.new("A", 1.int32), Arg.new("B")] of ASTNode)] of ASTNode)
-  it_parses "lib C; enum Foo < UInt16; end end", LibDef.new("C", [EnumDef.new("Foo", base_type: "UInt16".path)] of ASTNode)
   it_parses "lib C; Foo = 1; end", LibDef.new("C", [Assign.new("Foo".path, 1.int32)] of ASTNode)
   it_parses "lib C\nfun getch = GetChar\nend", LibDef.new("C", [FunDef.new("getch", real_name: "GetChar")] of ASTNode)
   it_parses %(lib C\nfun getch = "get.char"\nend), LibDef.new("C", [FunDef.new("getch", real_name: "get.char")] of ASTNode)
@@ -871,7 +870,6 @@ describe "Parser" do
 
   it_parses "enum Foo; A\nB, C\nD = 1; end", EnumDef.new("Foo", [Arg.new("A"), Arg.new("B"), Arg.new("C"), Arg.new("D", 1.int32)] of ASTNode)
   it_parses "enum Foo; A = 1, B; end", EnumDef.new("Foo", [Arg.new("A", 1.int32), Arg.new("B")] of ASTNode)
-  it_parses "enum Foo < UInt16; end", EnumDef.new("Foo", base_type: "UInt16".path)
   it_parses "enum Foo : UInt16; end", EnumDef.new("Foo", base_type: "UInt16".path)
   it_parses "enum Foo; def foo; 1; end; end", EnumDef.new("Foo", [Def.new("foo", body: 1.int32)] of ASTNode)
   it_parses "enum Foo; A = 1\ndef foo; 1; end; end", EnumDef.new("Foo", [Arg.new("A", 1.int32), Def.new("foo", body: 1.int32)] of ASTNode)
@@ -879,7 +877,7 @@ describe "Parser" do
   it_parses "enum Foo; A = 1\ndef self.foo; 1; end\nend", EnumDef.new("Foo", [Arg.new("A", 1.int32), Def.new("foo", receiver: "self".var, body: 1.int32)] of ASTNode)
 
   %w(def macro class struct module fun alias abstract include extend lib).each do |keyword|
-    assert_syntax_error "def foo\n#{keyword}\nend", Def.new("foo", body: keyword.call)
+    assert_syntax_error "def foo\n#{keyword}\nend"
   end
 
   it "keeps instance variables declared in def" do
@@ -952,6 +950,7 @@ describe "Parser" do
   assert_syntax_error "Set {1, 2, 3} of Int32"
   assert_syntax_error "Hash {foo: 1} of Int32 => Int32"
   assert_syntax_error "case foo; end"
+  assert_syntax_error "enum Foo < UInt16; end"
 
   it_parses "if (\ntrue\n)\n1\nend", If.new(true.bool, 1.int32)
 end
diff --git a/spec/compiler/type_inference/c_enum_spec.cr b/spec/compiler/type_inference/c_enum_spec.cr
index 7ef7fc6b17..c1b56306f7 100755
--- a/spec/compiler/type_inference/c_enum_spec.cr
+++ b/spec/compiler/type_inference/c_enum_spec.cr
@@ -37,11 +37,11 @@ describe "Type inference: c enum" do
   end
 
   it "types enum value with base type" do
-    assert_type("lib Foo; enum Bar < Int16; X; end; end; Foo::Bar::X") { types["Foo"].types["Bar"] }
+    assert_type("lib Foo; enum Bar : Int16; X; end; end; Foo::Bar::X") { types["Foo"].types["Bar"] }
   end
 
   it "errors if enum base type is not an integer" do
-    assert_error "lib Foo; enum Bar < Float32; X; end; end; Foo::Bar::X",
+    assert_error "lib Foo; enum Bar : Float32; X; end; end; Foo::Bar::X",
       "enum base type must be an integer type"
   end
 end
diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr
index 6931ebf04d..8434da34da 100644
--- a/spec/spec_helper.cr
+++ b/spec/spec_helper.cr
@@ -72,31 +72,15 @@ def assert_after_type_inference(before, after)
   result.node.to_s.strip.should eq(after.strip)
 end
 
-def assert_syntax_error(str)
-  it "says syntax error on #{str.inspect}" do
-    expect_raises Crystal::SyntaxException do
-      parse str
-    end
-  end
-end
-
-def assert_syntax_error(str, message)
-  it "says syntax error on #{str.inspect}" do
-    expect_raises Crystal::SyntaxException, message do
-      parse str
-    end
-  end
-end
-
-def assert_syntax_error(str, message, line, column)
-  it "says syntax error on #{str.inspect}" do
+def assert_syntax_error(str, message = nil, line = nil, column = nil, metafile = __FILE__, metaline = __LINE__)
+  it "says syntax error on #{str.inspect}", metafile, metaline do
     begin
-      Parser.parse(str)
+      parse str
       fail "expected SyntaxException to be raised"
     rescue ex : SyntaxException
-      ex.message.not_nil!.includes?(message).should be_true
-      ex.line_number.should eq(line)
-      ex.column_number.should eq(column)
+      ex.message.not_nil!.includes?(message).should be_true if message
+      ex.line_number.should eq(line) if line
+      ex.column_number.should eq(column) if column
     end
   end
 end
diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr
index a59bf69598..37ab16eee7 100644
--- a/src/compiler/crystal/syntax/parser.cr
+++ b/src/compiler/crystal/syntax/parser.cr
@@ -3792,12 +3792,14 @@ module Crystal
 
       next_token_skip_space
       case @token.type
-      when :"<", :":"
+      when :":"
         next_token_skip_space_or_newline
         base_type = parse_single_type
         skip_statement_end
+      when :";", :NEWLINE
+        skip_statement_end
       else
-        next_token_skip_statement_end
+        unexpected_token
       end
 
       members = [] of ASTNode
diff --git a/src/dir.cr b/src/dir.cr
index 796eda729d..c6b0773d62 100644
--- a/src/dir.cr
+++ b/src/dir.cr
@@ -76,7 +76,7 @@ lib C
 end
 
 class Dir
-  enum Type < UInt8
+  enum Type : UInt8
     UNKNOWN = 0
     FIFO = 1
     CHR = 2
-- 
GitLab