Skip to content

Commit

Permalink
Merge pull request #424 from felixvf/workaround_bug_420
Browse files Browse the repository at this point in the history
Workaround for bug #420
  • Loading branch information
felixvf committed Dec 7, 2016
2 parents b58b341 + 47a230d commit 08fc40e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/org/mirah/builtins/object_extensions.mirah
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ class ObjectExtensions
end
end
end
methods_proxy.get(0).setParent(nil)
methods_proxy.get(0) # FIXME: if we used methods_proxy instead of methods_proxy.get(0) as return value, then the annotation is not effective
methods_proxy.setParent(nil)
methods_proxy
end

macro def self.attr_accessor(hash:Hash)
Expand Down
5 changes: 3 additions & 2 deletions src/org/mirah/jvm/mirrors/mirror_type_system.mirah
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import org.mirah.typer.MethodFuture
import org.mirah.typer.MethodType
import org.mirah.typer.NarrowingTypeFuture
import org.mirah.typer.PickFirst
import org.mirah.typer.ProxyNode
import org.mirah.typer.ResolvedType
import org.mirah.typer.Scope
import org.mirah.typer.TypeFuture
Expand Down Expand Up @@ -269,8 +270,8 @@ class MirrorTypeSystem implements TypeSystem, ExtensionsService
macro_params = LinkedList.new
nodes = call.parameterNodes
unless nodes.nil?
nodes.each do |n|
typename = n.getClass.getName
nodes.each do |n:Node|
typename = ProxyNode.dereference(n).getClass.getName
macro_params.add(loadMacroType(typename))
end
end
Expand Down
18 changes: 17 additions & 1 deletion src/org/mirah/macros/builder.mirah
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import mirah.lang.ast.SimpleString
import mirah.lang.ast.StringCodeSource
import mirah.lang.ast.StringConcat
import mirah.lang.ast.TypeName
import mirah.lang.ast.TypeRefImpl
import mirah.lang.ast.Unquote
import mirah.lang.ast.FunctionalCall
import mirah.lang.ast.TypeRefImpl
Expand Down Expand Up @@ -421,7 +422,11 @@ class MacroBuilder; implements org.mirah.macros.Compiler
if i == args.required_size() - 1 && arg.type.typeref.name.endsWith("Block")
casts.add(fetchMacroBlock)
else
casts.add(Cast.new(TypeName(arg.type.clone), fetchMacroArg(i)))
macro_arg_node = fetchMacroArg(i)
# Hack to allow chained macro invocations on macro invocations on MethodDefinitions.
# To remove this hack, https://github.com/mirah/mirah/issues/423 needs to be fixed.
macro_arg_node = wrap_dereference(macro_arg_node) if arg.type.typeref.name.endsWith("MethodDefinition")
casts.add(Cast.new(TypeName(arg.type.clone), macro_arg_node))
end
i += 1
end
Expand Down Expand Up @@ -471,6 +476,17 @@ class MacroBuilder; implements org.mirah.macros.Compiler
FunctionalCall.new(SimpleString.new('_varargs'), [Fixnum.new(i), clazz], nil)
end

def wrap_dereference(node: Node): Node
Call.new(
TypeRefImpl.new('org.mirah.typer.ProxyNode', false, false, nil),
SimpleString.new('dereference'),
[
node,
],
nil
)
end

def fetchMacroBlock: Node
Call.new(FieldAccess.new(SimpleString.new('call')),
SimpleString.new('block'), Collections.emptyList, nil)
Expand Down
12 changes: 12 additions & 0 deletions src/org/mirah/typer/proxy_node.mirah
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,16 @@ class ProxyNode < NodeList implements TypeName, Identifier
def toString
"<org.mirah.typer.ProxyNode: selected:#{@selectedNode}>"
end

def self.dereference(node:Node)
if node.kind_of?(ProxyNode)
ProxyNode(node).dereference
else
node
end
end

def dereference
dereference(@selectedNode)
end
end
31 changes: 31 additions & 0 deletions test/jvm/macros_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,37 @@ def foo
assert_run_output("foo\n", script)
end

def test_macro_calling_macro_calling_method_definition
script, cls = compile(%q{
class Foo
macro def self.foo(method:MethodDefinition)
method
end
macro def self.bar(method:MethodDefinition)
method
end
def method0
end
foo def method1
end
bar def method2
end
foo bar def method3
puts "method3"
end
end
Foo.new.method3
})
assert_run_output("method3\n", script)
end

def test_gensym_clash
script, cls = compile(%q{
result = []
Expand Down

0 comments on commit 08fc40e

Please sign in to comment.