Skip to content

Commit 857743a

Browse files
david50407ysbaddaden
authored andcommittedMar 28, 2017
[Compiler] Get all ancestors of a type in macro
1 parent 6a45e08 commit 857743a

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed
 

‎spec/compiler/macro/macro_methods_spec.cr

+25
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,31 @@ describe "macro methods" do
10531053
end
10541054
end
10551055

1056+
it "executes ancestors" do
1057+
assert_macro("x", "{{x.ancestors}}", %([SomeModule, Reference, Object])) do |program|
1058+
mod = NonGenericModuleType.new(program, program, "SomeModule")
1059+
klass = NonGenericClassType.new(program, program, "SomeType", program.reference)
1060+
klass.include mod
1061+
1062+
[TypeNode.new(klass)] of ASTNode
1063+
end
1064+
end
1065+
1066+
it "executes ancestors (with generic)" do
1067+
assert_macro("x", "{{x.ancestors}}", %([SomeGenericModule(String), SomeGenericType(String), Reference, Object])) do |program|
1068+
generic_type = GenericClassType.new(program, program, "SomeGenericType", program.reference, ["T"])
1069+
generic_mod = GenericModuleType.new(program, program, "SomeGenericModule", ["T"])
1070+
type_var = {"T" => TypeNode.new(program.string)} of String => ASTNode
1071+
type = GenericClassInstanceType.new(program, generic_type, program.reference, type_var)
1072+
mod = GenericModuleInstanceType.new(program, generic_mod, type_var)
1073+
1074+
klass = NonGenericClassType.new(program, program, "SomeType", type)
1075+
klass.include mod
1076+
1077+
[TypeNode.new(klass)] of ASTNode
1078+
end
1079+
end
1080+
10561081
it "executes superclass" do
10571082
assert_macro("x", "{{x.superclass}}", %(Reference)) do |program|
10581083
[TypeNode.new(program.string)] of ASTNode

‎src/compiler/crystal/macros.cr

+4
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,10 @@ module Crystal::Macros
14811481
def instance_vars : ArrayLiteral(MetaVar)
14821482
end
14831483

1484+
# Returns all ancestors of this type.
1485+
def ancestors : ArrayLiteral(TypeNode)
1486+
end
1487+
14841488
# Returns the direct superclass of this type.
14851489
def superclass : TypeNode | NilLiteral
14861490
end

‎src/compiler/crystal/macros/methods.cr

+6
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,8 @@ module Crystal
13171317
interpret_argless_method(method, args) { TypeNode.type_vars(type) }
13181318
when "instance_vars"
13191319
interpret_argless_method(method, args) { TypeNode.instance_vars(type) }
1320+
when "ancestors"
1321+
interpret_argless_method(method, args) { TypeNode.ancestors(type) }
13201322
when "superclass"
13211323
interpret_argless_method(method, args) { TypeNode.superclass(type) }
13221324
when "subclasses"
@@ -1469,6 +1471,10 @@ module Crystal
14691471
end
14701472
end
14711473

1474+
def self.ancestors(type)
1475+
ArrayLiteral.map(type.ancestors) { |ancestor| TypeNode.new(ancestor) }
1476+
end
1477+
14721478
def self.superclass(type)
14731479
superclass = type.superclass
14741480
superclass ? TypeNode.new(superclass) : NilLiteral.new

0 commit comments

Comments
 (0)
Please sign in to comment.