Skip to content

Commit

Permalink
Added Path#resolve macro method. Related to #2388
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Mar 31, 2016
1 parent fea2915 commit 46e57a2
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
11 changes: 8 additions & 3 deletions docs/macros.cr
Expand Up @@ -785,9 +785,14 @@ module Macros
# class ImplicitObj < ASTNode
# end

# A Path to a constant, like `Foo` or `Foo::Bar::Baz`.
# class Path < ASTNode
# end
# A Path to a constant or type, like `Foo` or `Foo::Bar::Baz`.
class Path < ASTNode
# Resolves this path to a `TypeNode` if it denotes a type, to
# the value of a constant if it denotes a constant, or otherwise
# gives a compile-time error.
def resolve : ASTNode
end
end

# A class definition.
# class ClassDef < ASTNode
Expand Down
12 changes: 12 additions & 0 deletions spec/compiler/codegen/macro_spec.cr
Expand Up @@ -1257,4 +1257,16 @@ describe "Code gen: macro" do
x.foo
)).to_i.should eq(1)
end

it "expands Path with resolve method" do
run(%(
A = 1
macro id(path)
{{path.resolve}}
end
id(A)
)).to_i.should eq(1)
end
end
13 changes: 8 additions & 5 deletions src/compiler/crystal/macros/macros.cr
Expand Up @@ -490,6 +490,11 @@ module Crystal
end

def visit(node : Path)
@last = resolve(node)
false
end

def resolve(node : Path)
if node.names.size == 1 && (match = @free_vars.try &.[node.names.first])
matched_type = match
else
Expand All @@ -502,16 +507,14 @@ module Crystal

case matched_type
when Const
@last = matched_type.value
matched_type.value
when Type
@last = TypeNode.new(matched_type)
TypeNode.new(matched_type)
when ASTNode
@last = matched_type
matched_type
else
node.raise "can't interpret #{node}"
end

false
end

def visit(node : Splat)
Expand Down
9 changes: 9 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Expand Up @@ -1016,6 +1016,15 @@ module Crystal
end

class Path
def interpret(method, args, block, interpreter)
case method
when "resolve"
interpret_argless_method(method, args) { interpreter.resolve(self) }
else
super
end
end

def to_macro_id
@names.join "::"
end
Expand Down

0 comments on commit 46e57a2

Please sign in to comment.