Skip to content

Commit

Permalink
Showing 3 changed files with 35 additions and 0 deletions.
25 changes: 25 additions & 0 deletions spec/compiler/macro/macro_methods_spec.cr
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions src/compiler/crystal/macros.cr
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Original file line number Diff line number Diff line change
@@ -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"
@@ -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

0 comments on commit 857743a

Please sign in to comment.