Skip to content

Commit

Permalink
Merge branch 'master' into 'fix_constants'.
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix von Ferey committed Dec 7, 2016
2 parents 1a873c1 + 8e9907a commit 1dce8cd
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 21 deletions.
15 changes: 14 additions & 1 deletion src/org/mirah/builtins/array_extensions.mirah
Expand Up @@ -19,9 +19,22 @@ import org.mirah.macros.anno.ExtensionsRegistration

$ExtensionsRegistration[['[]']]
class ArrayExtensions

# Compares 2 arrays (using java::util::Arrays.equals()).
#
# The arrays are equal if
# 1. they have the same size and
# 2. each pair of the elements of the arrays with the same index satisfies one of these rules:
# 1. both are null, or
# 2. the element of the left array is an Object and that object's #equals() methods returns true given the element of the right array, or
# 3. the element of the left array is a primitive type (except double and float) and it equals to the element of the right array, or
# 4. the element of the left array is a double and new Double(d1).equals(new Double(d2)) holds if d1 is the element of the left array and d2 is the element of the right array, or
# 5. the element of the left array is a float and new Float(f1).equals(new Float(f2)) holds if f1 is the element of the left array and f2 is the element of the right array.
#
# Note that the basetype of each array does not need to be equal for the arrays to be considered equal.
macro def ==(other_array)
quote do
java::util::Arrays.equals `@call.target`, `other_array`
java::util::Arrays.equals(`call.target`,`other_array`)
end
end

Expand Down
4 changes: 2 additions & 2 deletions src/org/mirah/builtins/object_extensions.mirah
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
10 changes: 5 additions & 5 deletions src/org/mirah/jvm/mirrors/bytecode_mirror.mirah
Expand Up @@ -27,7 +27,7 @@ import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.FieldNode
import org.objectweb.asm.tree.InnerClassNode
import org.objectweb.asm.tree.MethodNode
import org.mirah.jvm.mirrors.generics.TypeInvoker
import org.mirah.jvm.mirrors.generics.GenericsCapableSignatureReader
import org.mirah.jvm.types.JVMType
import org.mirah.jvm.types.JVMMethod
import org.mirah.jvm.types.JVMField
Expand Down Expand Up @@ -82,10 +82,10 @@ class BytecodeMirror < AsyncMirror implements DeclaredMirrorType
def link_internal:void
types = @context[MirrorTypeSystem]
if @signature
invoker = TypeInvoker.new(@context, nil, [], {})
invoker.read(@signature)
setSupertypes(invoker.superclass, invoker.interfaces)
invoker.getFormalTypeParameters.each do |var|
signature_reader = GenericsCapableSignatureReader.new(@context)
signature_reader.read(@signature)
setSupertypes(signature_reader.superclass, signature_reader.interfaces)
signature_reader.getFormalTypeParameters.each do |var|
@typeParams[var.toString] = BaseTypeFuture.new.resolved(MirrorType(var))
end
else
Expand Down
34 changes: 26 additions & 8 deletions src/org/mirah/jvm/mirrors/generics/xx_type_invoker.mirah
Expand Up @@ -34,6 +34,7 @@ import org.mirah.jvm.mirrors.MirrorType
import org.mirah.jvm.model.Cycle
import org.mirah.jvm.model.IntersectionType
import org.mirah.typer.TypeFuture
import org.mirah.typer.BaseTypeFuture
import org.mirah.util.Context

class IgnoredTypeBuilder < SignatureVisitor
Expand All @@ -42,23 +43,16 @@ class IgnoredTypeBuilder < SignatureVisitor
end
end

class TypeInvoker < BaseSignatureReader
class AbstractTypeInvoker < BaseSignatureReader
def initialize(context:Context, typeVars:Map, args:List, processed_signatures:Map)
super(context, typeVars, processed_signatures)
@typeParams = LinkedList.new
@args = LinkedList.new(args)
@interfaces = []
end

def getTypeVariableMap:Map
typeVariables
end

def saveTypeParam(var)
typeVariables[var.toString] = @args.removeFirst unless @args.isEmpty
@typeParams.add(var)
end

def visitSuperclass
finishTypeParam
@superclass = newBuilder
Expand Down Expand Up @@ -86,10 +80,33 @@ class TypeInvoker < BaseSignatureReader
end
array
end
end

class GenericsCapableSignatureReader < AbstractTypeInvoker
def initialize(context:Context)
super(context, nil, [], {})
@typeParams = LinkedList.new
end

def saveTypeParam(var)
@typeParams.add(var)
end

def getFormalTypeParameters:List
@typeParams
end
end


class TypeInvoker < AbstractTypeInvoker
def initialize(context:Context, typeVars:Map, args:List, processed_signatures:Map)
super
@args = LinkedList.new(args)
end

def saveTypeParam(var)
typeVariables[var.toString] = @args.removeFirst
end

def self.invoke(context:Context, type:MirrorType, args:List,
outerTypeArgs:Map, processed_signatures:Map):MirrorType
Expand All @@ -109,3 +126,4 @@ class TypeInvoker < BaseSignatureReader
end
end
end

5 changes: 3 additions & 2 deletions src/org/mirah/jvm/mirrors/mirror_type_system.mirah
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
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
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
23 changes: 23 additions & 0 deletions test/jvm/extensions/array_extensions_test.rb
@@ -1,4 +1,27 @@
class ArrayExtensionsTest < Test::Unit::TestCase

def test_equals
cls, = compile(<<-EOF)
a = int[3]
a[2] = 4
b = int[3]
b[2] = 4
puts a==b # true
b[1] = 3
puts a==b # false, because contents are not equal
c = Object[2]
d = String[2]
c[0] = "a"
c[1] = "1"
d[0] = "a"
d[1] = "#{1}"
puts c==d # true, although the classes of the arrays are different, the contents are equal
EOF
assert_run_output("true\nfalse\ntrue\n", cls)
end

def test_empty_q
cls, = compile(<<-EOF)
x = int[0]
Expand Down
31 changes: 31 additions & 0 deletions test/jvm/macros_test.rb
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
4 changes: 2 additions & 2 deletions test/mirrors/generics_test.rb
Expand Up @@ -28,7 +28,7 @@ class GenericsTest < Test::Unit::TestCase
java_import 'org.mirah.jvm.mirrors.generics.Constraints'
java_import 'org.mirah.jvm.mirrors.generics.LubFinder'
java_import 'org.mirah.jvm.mirrors.generics.TypeInvocation'
java_import 'org.mirah.jvm.mirrors.generics.TypeInvoker'
java_import 'org.mirah.jvm.mirrors.generics.GenericsCapableSignatureReader'
java_import 'org.mirah.jvm.mirrors.generics.TypeParameterInference'
java_import 'org.mirah.jvm.mirrors.generics.TypeVariable'
java_import 'org.mirah.jvm.mirrors.generics.Wildcard'
Expand Down Expand Up @@ -856,7 +856,7 @@ def test_type_invoker_recursive_reference_signature

def invoker_for_signature(signature)
context = @types.context
invoker = TypeInvoker.new(context, nil, [], {})
invoker = GenericsCapableSignatureReader.new(context)
invoker.read(signature)
invoker
end
Expand Down

0 comments on commit 1dce8cd

Please sign in to comment.