mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Adding Crystal samples to address https://github.com/github/github/issues/24802
This commit is contained in:
		| @@ -96,6 +96,9 @@ | |||||||
|     "Creole": [ |     "Creole": [ | ||||||
|       ".creole" |       ".creole" | ||||||
|     ], |     ], | ||||||
|  |     "Crystal": [ | ||||||
|  |       ".cr" | ||||||
|  |     ], | ||||||
|     "CSS": [ |     "CSS": [ | ||||||
|       ".css" |       ".css" | ||||||
|     ], |     ], | ||||||
| @@ -661,8 +664,8 @@ | |||||||
|       ".gemrc" |       ".gemrc" | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   "tokens_total": 583212, |   "tokens_total": 584718, | ||||||
|   "languages_total": 696, |   "languages_total": 699, | ||||||
|   "tokens": { |   "tokens": { | ||||||
|     "ABAP": { |     "ABAP": { | ||||||
|       "*/**": 1, |       "*/**": 1, | ||||||
| @@ -16233,6 +16236,253 @@ | |||||||
|       "Ruby": 1, |       "Ruby": 1, | ||||||
|       "distribution.": 1 |       "distribution.": 1 | ||||||
|     }, |     }, | ||||||
|  |     "Crystal": { | ||||||
|  |       "SHEBANG#!bin/crystal": 2, | ||||||
|  |       "require": 2, | ||||||
|  |       "describe": 2, | ||||||
|  |       "do": 26, | ||||||
|  |       "it": 21, | ||||||
|  |       "run": 14, | ||||||
|  |       "(": 201, | ||||||
|  |       ")": 201, | ||||||
|  |       ".to_i.should": 11, | ||||||
|  |       "eq": 16, | ||||||
|  |       "end": 135, | ||||||
|  |       ".to_f32.should": 2, | ||||||
|  |       ".to_b.should": 1, | ||||||
|  |       "be_true": 1, | ||||||
|  |       "assert_type": 7, | ||||||
|  |       "{": 7, | ||||||
|  |       "int32": 8, | ||||||
|  |       "}": 7, | ||||||
|  |       "union_of": 1, | ||||||
|  |       "char": 1, | ||||||
|  |       "result": 3, | ||||||
|  |       "types": 3, | ||||||
|  |       "[": 9, | ||||||
|  |       "]": 9, | ||||||
|  |       "mod": 1, | ||||||
|  |       "result.program": 1, | ||||||
|  |       "foo": 3, | ||||||
|  |       "mod.types": 1, | ||||||
|  |       "as": 4, | ||||||
|  |       "NonGenericClassType": 1, | ||||||
|  |       "foo.instance_vars": 1, | ||||||
|  |       ".type.should": 3, | ||||||
|  |       "mod.int32": 1, | ||||||
|  |       "GenericClassType": 2, | ||||||
|  |       "foo_i32": 4, | ||||||
|  |       "foo.instantiate": 2, | ||||||
|  |       "of": 3, | ||||||
|  |       "Type": 2, | ||||||
|  |       "|": 8, | ||||||
|  |       "ASTNode": 4, | ||||||
|  |       "foo_i32.lookup_instance_var": 2, | ||||||
|  |       "module": 1, | ||||||
|  |       "Crystal": 1, | ||||||
|  |       "class": 2, | ||||||
|  |       "def": 84, | ||||||
|  |       "transform": 81, | ||||||
|  |       "transformer": 1, | ||||||
|  |       "transformer.before_transform": 1, | ||||||
|  |       "self": 77, | ||||||
|  |       "node": 164, | ||||||
|  |       "transformer.transform": 1, | ||||||
|  |       "transformer.after_transform": 1, | ||||||
|  |       "Transformer": 1, | ||||||
|  |       "before_transform": 1, | ||||||
|  |       "after_transform": 1, | ||||||
|  |       "Expressions": 2, | ||||||
|  |       "exps": 6, | ||||||
|  |       "node.expressions.each": 1, | ||||||
|  |       "exp": 3, | ||||||
|  |       "new_exp": 3, | ||||||
|  |       "exp.transform": 3, | ||||||
|  |       "if": 23, | ||||||
|  |       "new_exp.is_a": 1, | ||||||
|  |       "exps.concat": 1, | ||||||
|  |       "new_exp.expressions": 1, | ||||||
|  |       "else": 2, | ||||||
|  |       "<<": 1, | ||||||
|  |       "exps.length": 1, | ||||||
|  |       "node.expressions": 3, | ||||||
|  |       "Call": 1, | ||||||
|  |       "node_obj": 1, | ||||||
|  |       "node.obj": 9, | ||||||
|  |       "node_obj.transform": 1, | ||||||
|  |       "transform_many": 23, | ||||||
|  |       "node.args": 3, | ||||||
|  |       "node_block": 1, | ||||||
|  |       "node.block": 2, | ||||||
|  |       "node_block.transform": 1, | ||||||
|  |       "node_block_arg": 1, | ||||||
|  |       "node.block_arg": 6, | ||||||
|  |       "node_block_arg.transform": 1, | ||||||
|  |       "And": 1, | ||||||
|  |       "node.left": 3, | ||||||
|  |       "node.left.transform": 3, | ||||||
|  |       "node.right": 3, | ||||||
|  |       "node.right.transform": 3, | ||||||
|  |       "Or": 1, | ||||||
|  |       "StringInterpolation": 1, | ||||||
|  |       "ArrayLiteral": 1, | ||||||
|  |       "node.elements": 1, | ||||||
|  |       "node_of": 1, | ||||||
|  |       "node.of": 2, | ||||||
|  |       "node_of.transform": 1, | ||||||
|  |       "HashLiteral": 1, | ||||||
|  |       "node.keys": 1, | ||||||
|  |       "node.values": 2, | ||||||
|  |       "of_key": 1, | ||||||
|  |       "node.of_key": 2, | ||||||
|  |       "of_key.transform": 1, | ||||||
|  |       "of_value": 1, | ||||||
|  |       "node.of_value": 2, | ||||||
|  |       "of_value.transform": 1, | ||||||
|  |       "If": 1, | ||||||
|  |       "node.cond": 5, | ||||||
|  |       "node.cond.transform": 5, | ||||||
|  |       "node.then": 3, | ||||||
|  |       "node.then.transform": 3, | ||||||
|  |       "node.else": 5, | ||||||
|  |       "node.else.transform": 3, | ||||||
|  |       "Unless": 1, | ||||||
|  |       "IfDef": 1, | ||||||
|  |       "MultiAssign": 1, | ||||||
|  |       "node.targets": 1, | ||||||
|  |       "SimpleOr": 1, | ||||||
|  |       "Def": 1, | ||||||
|  |       "node.body": 12, | ||||||
|  |       "node.body.transform": 10, | ||||||
|  |       "receiver": 2, | ||||||
|  |       "node.receiver": 4, | ||||||
|  |       "receiver.transform": 2, | ||||||
|  |       "block_arg": 2, | ||||||
|  |       "block_arg.transform": 2, | ||||||
|  |       "Macro": 1, | ||||||
|  |       "PointerOf": 1, | ||||||
|  |       "node.exp": 3, | ||||||
|  |       "node.exp.transform": 3, | ||||||
|  |       "SizeOf": 1, | ||||||
|  |       "InstanceSizeOf": 1, | ||||||
|  |       "IsA": 1, | ||||||
|  |       "node.obj.transform": 5, | ||||||
|  |       "node.const": 1, | ||||||
|  |       "node.const.transform": 1, | ||||||
|  |       "RespondsTo": 1, | ||||||
|  |       "Case": 1, | ||||||
|  |       "node.whens": 1, | ||||||
|  |       "node_else": 1, | ||||||
|  |       "node_else.transform": 1, | ||||||
|  |       "When": 1, | ||||||
|  |       "node.conds": 1, | ||||||
|  |       "ImplicitObj": 1, | ||||||
|  |       "ClassDef": 1, | ||||||
|  |       "superclass": 1, | ||||||
|  |       "node.superclass": 2, | ||||||
|  |       "superclass.transform": 1, | ||||||
|  |       "ModuleDef": 1, | ||||||
|  |       "While": 1, | ||||||
|  |       "Generic": 1, | ||||||
|  |       "node.name": 5, | ||||||
|  |       "node.name.transform": 5, | ||||||
|  |       "node.type_vars": 1, | ||||||
|  |       "ExceptionHandler": 1, | ||||||
|  |       "node.rescues": 1, | ||||||
|  |       "node_ensure": 1, | ||||||
|  |       "node.ensure": 2, | ||||||
|  |       "node_ensure.transform": 1, | ||||||
|  |       "Rescue": 1, | ||||||
|  |       "node.types": 2, | ||||||
|  |       "Union": 1, | ||||||
|  |       "Hierarchy": 1, | ||||||
|  |       "Metaclass": 1, | ||||||
|  |       "Arg": 1, | ||||||
|  |       "default_value": 1, | ||||||
|  |       "node.default_value": 2, | ||||||
|  |       "default_value.transform": 1, | ||||||
|  |       "restriction": 1, | ||||||
|  |       "node.restriction": 2, | ||||||
|  |       "restriction.transform": 1, | ||||||
|  |       "BlockArg": 1, | ||||||
|  |       "node.fun": 1, | ||||||
|  |       "node.fun.transform": 1, | ||||||
|  |       "Fun": 1, | ||||||
|  |       "node.inputs": 1, | ||||||
|  |       "output": 1, | ||||||
|  |       "node.output": 2, | ||||||
|  |       "output.transform": 1, | ||||||
|  |       "Block": 1, | ||||||
|  |       "node.args.map": 1, | ||||||
|  |       "Var": 2, | ||||||
|  |       "FunLiteral": 1, | ||||||
|  |       "node.def.body": 1, | ||||||
|  |       "node.def.body.transform": 1, | ||||||
|  |       "FunPointer": 1, | ||||||
|  |       "obj": 1, | ||||||
|  |       "obj.transform": 1, | ||||||
|  |       "Return": 1, | ||||||
|  |       "node.exps": 5, | ||||||
|  |       "Break": 1, | ||||||
|  |       "Next": 1, | ||||||
|  |       "Yield": 1, | ||||||
|  |       "scope": 1, | ||||||
|  |       "node.scope": 2, | ||||||
|  |       "scope.transform": 1, | ||||||
|  |       "Include": 1, | ||||||
|  |       "Extend": 1, | ||||||
|  |       "RangeLiteral": 1, | ||||||
|  |       "node.from": 1, | ||||||
|  |       "node.from.transform": 1, | ||||||
|  |       "node.to": 2, | ||||||
|  |       "node.to.transform": 2, | ||||||
|  |       "Assign": 1, | ||||||
|  |       "node.target": 1, | ||||||
|  |       "node.target.transform": 1, | ||||||
|  |       "node.value": 3, | ||||||
|  |       "node.value.transform": 3, | ||||||
|  |       "Nop": 1, | ||||||
|  |       "NilLiteral": 1, | ||||||
|  |       "BoolLiteral": 1, | ||||||
|  |       "NumberLiteral": 1, | ||||||
|  |       "CharLiteral": 1, | ||||||
|  |       "StringLiteral": 1, | ||||||
|  |       "SymbolLiteral": 1, | ||||||
|  |       "RegexLiteral": 1, | ||||||
|  |       "MetaVar": 1, | ||||||
|  |       "InstanceVar": 1, | ||||||
|  |       "ClassVar": 1, | ||||||
|  |       "Global": 1, | ||||||
|  |       "Require": 1, | ||||||
|  |       "Path": 1, | ||||||
|  |       "Self": 1, | ||||||
|  |       "LibDef": 1, | ||||||
|  |       "FunDef": 1, | ||||||
|  |       "body": 1, | ||||||
|  |       "body.transform": 1, | ||||||
|  |       "TypeDef": 1, | ||||||
|  |       "StructDef": 1, | ||||||
|  |       "UnionDef": 1, | ||||||
|  |       "EnumDef": 1, | ||||||
|  |       "ExternalVar": 1, | ||||||
|  |       "IndirectRead": 1, | ||||||
|  |       "IndirectWrite": 1, | ||||||
|  |       "TypeOf": 1, | ||||||
|  |       "Primitive": 1, | ||||||
|  |       "Not": 1, | ||||||
|  |       "TypeFilteredNode": 1, | ||||||
|  |       "TupleLiteral": 1, | ||||||
|  |       "Cast": 1, | ||||||
|  |       "DeclareVar": 1, | ||||||
|  |       "node.var": 1, | ||||||
|  |       "node.var.transform": 1, | ||||||
|  |       "node.declared_type": 1, | ||||||
|  |       "node.declared_type.transform": 1, | ||||||
|  |       "Alias": 1, | ||||||
|  |       "TupleIndexer": 1, | ||||||
|  |       "Attribute": 1, | ||||||
|  |       "exps.map": 1 | ||||||
|  |     }, | ||||||
|     "CSS": { |     "CSS": { | ||||||
|       ".clearfix": 8, |       ".clearfix": 8, | ||||||
|       "{": 1661, |       "{": 1661, | ||||||
| @@ -60965,6 +61215,7 @@ | |||||||
|     "Common Lisp": 103, |     "Common Lisp": 103, | ||||||
|     "Coq": 18259, |     "Coq": 18259, | ||||||
|     "Creole": 134, |     "Creole": 134, | ||||||
|  |     "Crystal": 1506, | ||||||
|     "CSS": 43867, |     "CSS": 43867, | ||||||
|     "Cuda": 290, |     "Cuda": 290, | ||||||
|     "Dart": 74, |     "Dart": 74, | ||||||
| @@ -61138,6 +61389,7 @@ | |||||||
|     "Common Lisp": 1, |     "Common Lisp": 1, | ||||||
|     "Coq": 12, |     "Coq": 12, | ||||||
|     "Creole": 1, |     "Creole": 1, | ||||||
|  |     "Crystal": 3, | ||||||
|     "CSS": 2, |     "CSS": 2, | ||||||
|     "Cuda": 2, |     "Cuda": 2, | ||||||
|     "Dart": 1, |     "Dart": 1, | ||||||
| @@ -61284,5 +61536,5 @@ | |||||||
|     "YAML": 2, |     "YAML": 2, | ||||||
|     "Zephir": 2 |     "Zephir": 2 | ||||||
|   }, |   }, | ||||||
|   "md5": "400a9cd944fe65c38a9fa18d58b773b9" |   "md5": "5cbb8fcefc5e9c773796d772fe48907d" | ||||||
| } | } | ||||||
							
								
								
									
										169
									
								
								samples/Crystal/const_spec.cr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								samples/Crystal/const_spec.cr
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | |||||||
|  | #!/usr/bin/env bin/crystal --run | ||||||
|  | require "../../spec_helper" | ||||||
|  |  | ||||||
|  | describe "Codegen: const" do | ||||||
|  |   it "define a constant" do | ||||||
|  |     run("A = 1; A").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "support nested constant" do | ||||||
|  |     run("class B; A = 1; end; B::A").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "support constant inside a def" do | ||||||
|  |     run(" | ||||||
|  |       class Foo | ||||||
|  |         A = 1 | ||||||
|  |  | ||||||
|  |         def foo | ||||||
|  |           A | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo.new.foo | ||||||
|  |     ").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "finds nearest constant first" do | ||||||
|  |     run(" | ||||||
|  |       A = 1 | ||||||
|  |  | ||||||
|  |       class Foo | ||||||
|  |         A = 2.5_f32 | ||||||
|  |  | ||||||
|  |         def foo | ||||||
|  |           A | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo.new.foo | ||||||
|  |     ").to_f32.should eq(2.5) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "allows constants with same name" do | ||||||
|  |     run(" | ||||||
|  |       A = 1 | ||||||
|  |  | ||||||
|  |       class Foo | ||||||
|  |         A = 2.5_f32 | ||||||
|  |  | ||||||
|  |         def foo | ||||||
|  |           A | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       A | ||||||
|  |       Foo.new.foo | ||||||
|  |     ").to_f32.should eq(2.5) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "constants with expression" do | ||||||
|  |     run(" | ||||||
|  |       A = 1 + 1 | ||||||
|  |       A | ||||||
|  |     ").to_i.should eq(2) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "finds global constant" do | ||||||
|  |     run(" | ||||||
|  |       A = 1 | ||||||
|  |  | ||||||
|  |       class Foo | ||||||
|  |         def foo | ||||||
|  |           A | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo.new.foo | ||||||
|  |     ").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "define a constant in lib" do | ||||||
|  |     run("lib Foo; A = 1; end; Foo::A").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "invokes block in const" do | ||||||
|  |     run("require \"prelude\"; A = [\"1\"].map { |x| x.to_i }; A[0]").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "declare constants in right order" do | ||||||
|  |     run("A = 1 + 1; B = true ? A : 0; B").to_i.should eq(2) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "uses correct types lookup" do | ||||||
|  |     run(" | ||||||
|  |       module A | ||||||
|  |         class B | ||||||
|  |           def foo | ||||||
|  |             1 | ||||||
|  |           end | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         C = B.new; | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       def foo | ||||||
|  |         A::C.foo | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       foo | ||||||
|  |       ").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "codegens variable assignment in const" do | ||||||
|  |     run(" | ||||||
|  |       class Foo | ||||||
|  |         def initialize(@x) | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         def x | ||||||
|  |           @x | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       A = begin | ||||||
|  |             f = Foo.new(1) | ||||||
|  |             f | ||||||
|  |           end | ||||||
|  |  | ||||||
|  |       def foo | ||||||
|  |         A.x | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       foo | ||||||
|  |       ").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "declaring var" do | ||||||
|  |     run(" | ||||||
|  |       BAR = begin | ||||||
|  |         a = 1 | ||||||
|  |         while 1 == 2 | ||||||
|  |           b = 2 | ||||||
|  |         end | ||||||
|  |         a | ||||||
|  |       end | ||||||
|  |       class Foo | ||||||
|  |         def compile | ||||||
|  |           BAR | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo.new.compile | ||||||
|  |       ").to_i.should eq(1) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "initialize const that might raise an exception" do | ||||||
|  |     run(" | ||||||
|  |       require \"prelude\" | ||||||
|  |       CONST = (raise \"OH NO\" if 1 == 2) | ||||||
|  |  | ||||||
|  |       def doit | ||||||
|  |         CONST | ||||||
|  |       rescue | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       doit.nil? | ||||||
|  |     ").to_b.should be_true | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										79
									
								
								samples/Crystal/declare_var_spec.cr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								samples/Crystal/declare_var_spec.cr
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | #!/usr/bin/env bin/crystal --run | ||||||
|  | require "../../spec_helper" | ||||||
|  |  | ||||||
|  | describe "Type inference: declare var" do | ||||||
|  |   it "types declare var" do | ||||||
|  |     assert_type("a :: Int32") { int32 } | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "types declare var and reads it" do | ||||||
|  |     assert_type("a :: Int32; a") { int32 } | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "types declare var and changes its type" do | ||||||
|  |     assert_type("a :: Int32; while 1 == 2; a = 'a'; end; a") { union_of(int32, char) } | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "declares instance var which appears in initialize" do | ||||||
|  |     result = assert_type(" | ||||||
|  |       class Foo | ||||||
|  |         @x :: Int32 | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo.new") { types["Foo"] } | ||||||
|  |  | ||||||
|  |     mod = result.program | ||||||
|  |  | ||||||
|  |     foo = mod.types["Foo"] as NonGenericClassType | ||||||
|  |     foo.instance_vars["@x"].type.should eq(mod.int32) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "declares instance var of generic class" do | ||||||
|  |     result = assert_type(" | ||||||
|  |       class Foo(T) | ||||||
|  |         @x :: T | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo(Int32).new") do | ||||||
|  |         foo = types["Foo"] as GenericClassType | ||||||
|  |         foo_i32 = foo.instantiate([int32] of Type | ASTNode) | ||||||
|  |         foo_i32.lookup_instance_var("@x").type.should eq(int32) | ||||||
|  |         foo_i32 | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "declares instance var of generic class after reopen" do | ||||||
|  |     result = assert_type(" | ||||||
|  |       class Foo(T) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       f = Foo(Int32).new | ||||||
|  |  | ||||||
|  |       class Foo(T) | ||||||
|  |         @x :: T | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       f") do | ||||||
|  |         foo = types["Foo"] as GenericClassType | ||||||
|  |         foo_i32 = foo.instantiate([int32] of Type | ASTNode) | ||||||
|  |         foo_i32.lookup_instance_var("@x").type.should eq(int32) | ||||||
|  |         foo_i32 | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   it "declares an instance variable in initialize" do | ||||||
|  |     assert_type(" | ||||||
|  |       class Foo | ||||||
|  |         def initialize | ||||||
|  |           @x :: Int32 | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         def x | ||||||
|  |           @x | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       Foo.new.x | ||||||
|  |       ") { int32 } | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										515
									
								
								samples/Crystal/transformer.cr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										515
									
								
								samples/Crystal/transformer.cr
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,515 @@ | |||||||
|  | module Crystal | ||||||
|  |   class ASTNode | ||||||
|  |     def transform(transformer) | ||||||
|  |       transformer.before_transform self | ||||||
|  |       node = transformer.transform self | ||||||
|  |       transformer.after_transform self | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   class Transformer | ||||||
|  |     def before_transform(node) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def after_transform(node) | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Expressions) | ||||||
|  |       exps = [] of ASTNode | ||||||
|  |       node.expressions.each do |exp| | ||||||
|  |         new_exp = exp.transform(self) | ||||||
|  |         if new_exp | ||||||
|  |           if new_exp.is_a?(Expressions) | ||||||
|  |             exps.concat new_exp.expressions | ||||||
|  |           else | ||||||
|  |             exps << new_exp | ||||||
|  |           end | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if exps.length == 1 | ||||||
|  |         exps[0] | ||||||
|  |       else | ||||||
|  |         node.expressions = exps | ||||||
|  |         node | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Call) | ||||||
|  |       if node_obj = node.obj | ||||||
|  |         node.obj = node_obj.transform(self) | ||||||
|  |       end | ||||||
|  |       transform_many node.args | ||||||
|  |  | ||||||
|  |       if node_block = node.block | ||||||
|  |         node.block = node_block.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if node_block_arg = node.block_arg | ||||||
|  |         node.block_arg = node_block_arg.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : And) | ||||||
|  |       node.left = node.left.transform(self) | ||||||
|  |       node.right = node.right.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Or) | ||||||
|  |       node.left = node.left.transform(self) | ||||||
|  |       node.right = node.right.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : StringInterpolation) | ||||||
|  |       transform_many node.expressions | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ArrayLiteral) | ||||||
|  |       transform_many node.elements | ||||||
|  |  | ||||||
|  |       if node_of = node.of | ||||||
|  |         node.of = node_of.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : HashLiteral) | ||||||
|  |       transform_many node.keys | ||||||
|  |       transform_many node.values | ||||||
|  |  | ||||||
|  |       if of_key = node.of_key | ||||||
|  |         node.of_key = of_key.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if of_value = node.of_value | ||||||
|  |         node.of_value = of_value.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : If) | ||||||
|  |       node.cond = node.cond.transform(self) | ||||||
|  |       node.then = node.then.transform(self) | ||||||
|  |       node.else = node.else.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Unless) | ||||||
|  |       node.cond = node.cond.transform(self) | ||||||
|  |       node.then = node.then.transform(self) | ||||||
|  |       node.else = node.else.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : IfDef) | ||||||
|  |       node.cond = node.cond.transform(self) | ||||||
|  |       node.then = node.then.transform(self) | ||||||
|  |       node.else = node.else.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : MultiAssign) | ||||||
|  |       transform_many node.targets | ||||||
|  |       transform_many node.values | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : SimpleOr) | ||||||
|  |       node.left = node.left.transform(self) | ||||||
|  |       node.right = node.right.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Def) | ||||||
|  |       transform_many node.args | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |  | ||||||
|  |       if receiver = node.receiver | ||||||
|  |         node.receiver = receiver.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if block_arg = node.block_arg | ||||||
|  |         node.block_arg = block_arg.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Macro) | ||||||
|  |       transform_many node.args | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |  | ||||||
|  |       if receiver = node.receiver | ||||||
|  |         node.receiver = receiver.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if block_arg = node.block_arg | ||||||
|  |         node.block_arg = block_arg.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : PointerOf) | ||||||
|  |       node.exp = node.exp.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : SizeOf) | ||||||
|  |       node.exp = node.exp.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : InstanceSizeOf) | ||||||
|  |       node.exp = node.exp.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : IsA) | ||||||
|  |       node.obj = node.obj.transform(self) | ||||||
|  |       node.const = node.const.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : RespondsTo) | ||||||
|  |       node.obj = node.obj.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Case) | ||||||
|  |       node.cond = node.cond.transform(self) | ||||||
|  |       transform_many node.whens | ||||||
|  |  | ||||||
|  |       if node_else = node.else | ||||||
|  |         node.else = node_else.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : When) | ||||||
|  |       transform_many node.conds | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ImplicitObj) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ClassDef) | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |  | ||||||
|  |       if superclass = node.superclass | ||||||
|  |         node.superclass = superclass.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ModuleDef) | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : While) | ||||||
|  |       node.cond = node.cond.transform(self) | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Generic) | ||||||
|  |       node.name = node.name.transform(self) | ||||||
|  |       transform_many node.type_vars | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ExceptionHandler) | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       transform_many node.rescues | ||||||
|  |  | ||||||
|  |       if node_ensure = node.ensure | ||||||
|  |         node.ensure = node_ensure.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Rescue) | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       transform_many node.types | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Union) | ||||||
|  |       transform_many node.types | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Hierarchy) | ||||||
|  |       node.name = node.name.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Metaclass) | ||||||
|  |       node.name = node.name.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Arg) | ||||||
|  |       if default_value = node.default_value | ||||||
|  |         node.default_value = default_value.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       if restriction = node.restriction | ||||||
|  |         node.restriction = restriction.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : BlockArg) | ||||||
|  |       node.fun = node.fun.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Fun) | ||||||
|  |       transform_many node.inputs | ||||||
|  |  | ||||||
|  |       if output = node.output | ||||||
|  |         node.output = output.transform(self) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Block) | ||||||
|  |       node.args.map! { |exp| exp.transform(self) as Var } | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : FunLiteral) | ||||||
|  |       node.def.body = node.def.body.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : FunPointer) | ||||||
|  |       if obj = node.obj | ||||||
|  |         node.obj = obj.transform(self) | ||||||
|  |       end | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Return) | ||||||
|  |       transform_many node.exps | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Break) | ||||||
|  |       transform_many node.exps | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Next) | ||||||
|  |       transform_many node.exps | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Yield) | ||||||
|  |       if scope = node.scope | ||||||
|  |         node.scope = scope.transform(self) | ||||||
|  |       end | ||||||
|  |       transform_many node.exps | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Include) | ||||||
|  |       node.name = node.name.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Extend) | ||||||
|  |       node.name = node.name.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : RangeLiteral) | ||||||
|  |       node.from = node.from.transform(self) | ||||||
|  |       node.to = node.to.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Assign) | ||||||
|  |       node.target = node.target.transform(self) | ||||||
|  |       node.value = node.value.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Nop) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : NilLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : BoolLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : NumberLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : CharLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : StringLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : SymbolLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : RegexLiteral) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Var) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : MetaVar) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : InstanceVar) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ClassVar) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Global) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Require) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Path) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : LibDef) | ||||||
|  |       node.body = node.body.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : FunDef) | ||||||
|  |       if body = node.body | ||||||
|  |         node.body = body.transform(self) | ||||||
|  |       end | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : TypeDef) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : StructDef) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : UnionDef) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : EnumDef) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : ExternalVar) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : IndirectRead) | ||||||
|  |       node.obj = node.obj.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : IndirectWrite) | ||||||
|  |       node.obj = node.obj.transform(self) | ||||||
|  |       node.value = node.value.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : TypeOf) | ||||||
|  |       transform_many node.expressions | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Primitive) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Not) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : TypeFilteredNode) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : TupleLiteral) | ||||||
|  |       transform_many node.exps | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Cast) | ||||||
|  |       node.obj = node.obj.transform(self) | ||||||
|  |       node.to = node.to.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : DeclareVar) | ||||||
|  |       node.var = node.var.transform(self) | ||||||
|  |       node.declared_type = node.declared_type.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Alias) | ||||||
|  |       node.value = node.value.transform(self) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : TupleIndexer) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform(node : Attribute) | ||||||
|  |       node | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     def transform_many(exps) | ||||||
|  |       exps.map! { |exp| exp.transform(self) } if exps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
		Reference in New Issue
	
	Block a user