Skip to content

Commit

Permalink
[Compiler] Get all ancestors of a type in macro
Browse files Browse the repository at this point in the history
  • Loading branch information
david50407 authored and ysbaddaden committed Mar 28, 2017
1 parent 6a45e08 commit 857743a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
25 changes: 25 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Expand Up @@ -1053,6 +1053,31 @@ describe "macro methods" do
end
end

it "executes ancestors" do
assert_macro("x", "{{x.ancestors}}", %([SomeModule, Reference, Object])) do |program|
mod = NonGenericModuleType.new(program, program, "SomeModule")
klass = NonGenericClassType.new(program, program, "SomeType", program.reference)
klass.include mod

[TypeNode.new(klass)] of ASTNode
end
end

it "executes ancestors (with generic)" do
assert_macro("x", "{{x.ancestors}}", %([SomeGenericModule(String), SomeGenericType(String), Reference, Object])) do |program|
generic_type = GenericClassType.new(program, program, "SomeGenericType", program.reference, ["T"])
generic_mod = GenericModuleType.new(program, program, "SomeGenericModule", ["T"])
type_var = {"T" => TypeNode.new(program.string)} of String => ASTNode
type = GenericClassInstanceType.new(program, generic_type, program.reference, type_var)
mod = GenericModuleInstanceType.new(program, generic_mod, type_var)

klass = NonGenericClassType.new(program, program, "SomeType", type)
klass.include mod

[TypeNode.new(klass)] of ASTNode
end
end

it "executes superclass" do
assert_macro("x", "{{x.superclass}}", %(Reference)) do |program|
[TypeNode.new(program.string)] of ASTNode
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/crystal/macros.cr
Expand Up @@ -1481,6 +1481,10 @@ module Crystal::Macros
def instance_vars : ArrayLiteral(MetaVar)
end

# Returns all ancestors of this type.
def ancestors : ArrayLiteral(TypeNode)
end

# Returns the direct superclass of this type.
def superclass : TypeNode | NilLiteral
end
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Expand Up @@ -1317,6 +1317,8 @@ module Crystal
interpret_argless_method(method, args) { TypeNode.type_vars(type) }
when "instance_vars"
interpret_argless_method(method, args) { TypeNode.instance_vars(type) }
when "ancestors"
interpret_argless_method(method, args) { TypeNode.ancestors(type) }
when "superclass"
interpret_argless_method(method, args) { TypeNode.superclass(type) }
when "subclasses"
Expand Down Expand Up @@ -1469,6 +1471,10 @@ module Crystal
end
end

def self.ancestors(type)
ArrayLiteral.map(type.ancestors) { |ancestor| TypeNode.new(ancestor) }
end

def self.superclass(type)
superclass = type.superclass
superclass ? TypeNode.new(superclass) : NilLiteral.new
Expand Down

0 comments on commit 857743a

Please sign in to comment.