Permalink
Browse files

Fix more bugs

  • Loading branch information...
1 parent 3db9f49 commit f397eb76866c6630d68baf134f4f8e69e7feabb2 @ribrdb ribrdb committed Jul 22, 2011
Showing with 92 additions and 27 deletions.
  1. +33 −4 src/mirah/lang/ast/ast.mirah
  2. +1 −1 src/mirah/lang/ast/call.mirah
  3. +11 −6 src/mirahparser/impl/Mirah.mmeta
  4. +14 −14 src/org/mirah/ast/meta.mirah
  5. +33 −2 test/test_mirah.rb
@@ -2,6 +2,7 @@ package mirahparser.lang.ast
import java.io.Serializable
import java.util.ArrayList
+import java.util.LinkedList
import java.util.List
import java.util.Iterator
import org.mirahparser.ast.NodeMeta
@@ -16,6 +17,10 @@ interface Position do
macro def +(other) quote { add(`other`) } end
end
+interface CloneListener do
+ def wasCloned(original:Node, clone:Node):void; end
+end
+
interface Node < Cloneable do
def position:Position; end
def parent:Node; end
@@ -25,6 +30,7 @@ interface Node < Cloneable do
def replaceChild(child:Node, newChild:Node):void; end
def removeChild(child:Node):void; end
def accept(visitor:NodeVisitor, arg:Object):Object; end
+ def whenCloned(listener:CloneListener):void; end
def findAncestor(type:java::lang::Class):Node; end
def findAncestor(filter:NodeFilter):Node; end
@@ -39,7 +45,7 @@ end
interface Assignment < Node do
def value:Node; end
- def value=(value:Node); end
+ def value=(value:Node):void; end
end
interface Identifier < Node do
@@ -185,16 +191,23 @@ class NodeImpl
@originalNode = node
end
+ def whenCloned(listener:CloneListener)
+ @clone_listeners.add(listener)
+ end
+
protected
- def initialize; end
+ def initialize
+ @clone_listeners = LinkedList.new
+ end
def initialize(position: Position)
+ @clone_listeners = LinkedList.new
self.position = position
end
def childAdded(child:Node):Node
- return child if (child.nil? || child.parent == self)
+ return child if child.nil?
if child.parent
- child.parent.removeChild(child)
+ child = Node(child.clone)
end
child.setParent(self)
child
@@ -205,6 +218,12 @@ class NodeImpl
child.setParent(nil)
child
end
+
+ def fireWasCloned(clone:Node):void
+ @clone_listeners.each do |listener|
+ CloneListener(listener).wasCloned(self, clone)
+ end
+ end
end
# class DescendentFinder < NodeScanner
@@ -271,6 +290,7 @@ class PositionImpl; implements Position
def endLine:int; @endLine; end
def endColumn:int; @endColumn; end
def add(other:Position):Position
+ return self unless other
if @filename.equals(other.filename)
Position(PositionImpl.new(
@filename, Math.min(@startLine, other.startLine), Math.min(@startColumn, other.startColumn),
@@ -279,4 +299,13 @@ class PositionImpl; implements Position
Position(self)
end
end
+ def self.add(a:Position, b:Position):Position
+ if a && b
+ a.add(b)
+ elsif a
+ a
+ else
+ b
+ end
+ end
end
@@ -46,7 +46,7 @@ class Call < NodeImpl
return nil unless target.kind_of?(TypeName)
target_typeref = TypeName(target).typeref
return nil if target_typeref.nil?
- position = self.name.position + target_typeref.position
+ position = PositionImpl.add(self.name.position, target_typeref.position)
if '[]'.equals(name)
return TypeRefImpl.new(target_typeref.name, true, false, position)
else
@@ -288,17 +288,18 @@ parser MirahParser {
verify_end(sp)! $End
-> ^(ClassDefinition n s b ifaces annotations)
);
+ $Scope[@cond]
$Returns[Node]
primary2_interface
: annotations=annotation_list
t=$Interface!
sp=block_start(t)
- n=cname! ifaces=($LT rlistOf(:cpath)
+ n=cname! ifaces=($LT! rlistOf(:cpath)
| {[]}
)
- $Do?
- b=compstmt
- verify_end(sp) $END
+ Do!
+ b=compstmt!
+ verify_end(sp) $End
-> ^(InterfaceDeclaration n nil b ifaces annotations)
;
$Returns[Node]
@@ -681,7 +682,7 @@ parser MirahParser {
) {makeIdentifier(makePosition(_start, _pos), text)}
;
- $Memo[Identifier]
+ $Returns[Identifier]
cname: c=constant -> ^(Constant c)
| unquote
| &identifier !"class/module name must be CONSTANT" ?{false};
@@ -693,7 +694,10 @@ parser MirahParser {
;
$Returns[TypeName]
- type: TypeName(identifier) | cpath;
+ type: n=(TypeName(identifier) | cpath)
+ ( $LBrack $RBrack {TypeRefImpl.new(n.typeref.name, true, false, n.position)}
+ | {n}
+ );
superclass: $LT cpath # Should this be expr_value instead of cpath?
| # empty
@@ -889,6 +893,7 @@ parser MirahParser {
token = _lex
unless token.type == type
self._pos = token.pos
+ @error.last = type.name
raise @error
end
token
@@ -255,15 +255,15 @@ class ListNodeState < BaseNodeState
if children
startPosition = nil
endPosition = nil
+ @children = java::util::ArrayList.new(children.size)
children.each do |_node:Node|
node = Node(_node)
if node
- childAdded(node)
+ @children.add(childAdded(node))
startPosition ||= node.position
endPosition = node.position
end
end
- @children = java::util::ArrayList.new(children)
unless @children.isEmpty
self.position = startPosition + endPosition
end
@@ -276,8 +276,8 @@ class ListNodeState < BaseNodeState
def initialize(position:Position, children:java::util::List)
self.position = position
if children
- children.each {|node:Node| childAdded(Node(node))}
- @children = java::util::ArrayList.new(children)
+ @children = java::util::ArrayList.new(children.size)
+ children.each {|node:Node| @children.add(childAdded(Node(node)))}
else
@children = java::util::ArrayList.new
end
@@ -297,8 +297,7 @@ class ListNodeState < BaseNodeState
current = get(i)
if current != node
childRemoved(current)
- childAdded(node)
- @children.set(i, node)
+ @children.set(i, childAdded(node))
end
node
end
@@ -325,13 +324,11 @@ class ListNodeState < BaseNodeState
end
def add(node:`type_name`):void
- childAdded(node)
- @children.add(node)
+ @children.add(childAdded(node))
end
def insert(i:int, node:`type_name`):void
- @children.add(i, node)
- childAdded(node)
+ @children.add(i, childAdded(node))
end
def remove(i:int): `type_name`
@@ -458,6 +455,7 @@ class NodeState < BaseNodeState
_clone = super
node = `mirah.cast(name, '_clone')`
`@cloneBody`
+ fireWasCloned(node)
node
end
end
@@ -466,10 +464,12 @@ class NodeState < BaseNodeState
def addGetters(name:String, type:String, node:boolean)
if node
pre_set = mirah.quote do
- unless value == @`name`
- childRemoved(@`name`)
- childAdded(value)
+ if value == @`name`
+ return
end
+ childRemoved(@`name`)
+ clone = childAdded(value)
+ value = `mirah.cast(type, 'clone')`
end
else
pre_set = mirah.body
@@ -478,7 +478,7 @@ class NodeState < BaseNodeState
def `"#{name}"`: `type`
@`name`
end
- def `"#{name}_set"`(value: `type`)
+ def `"#{name}_set"`(value: `type`):void
`pre_set`
@`name` = value
end
View
@@ -37,6 +37,13 @@ def enter#{name}(node, arg)
end
EOF
end
+ def enterTypeRefImpl(node, arg)
+ enterDefault(node, arg)
+ @out << ", #{node.name}"
+ @out << ", array" if node.isArray
+ @out << ", static" if node.isStatic
+ true
+ end
def enterNodeList(node, arg)
@out << ", " unless @first
@out << "["
@@ -354,8 +361,8 @@ def test_def
"def foo(a); 2; end")
assert_parse("[Script, [[MethodDefinition, [SimpleString, foo], [Arguments, [RequiredArgumentList, [RequiredArgument, [SimpleString, a], null]], [OptionalArgumentList], null, [RequiredArgumentList], null], null, [[Fixnum, 1]], [AnnotationList]]]]",
"def foo a; 1; end")
- assert_parse("[Script, [[MethodDefinition, [SimpleString, foo], [Arguments, [RequiredArgumentList, [RequiredArgument, [SimpleString, a], [Constant, [SimpleString, SimpleString]]]], [OptionalArgumentList], null, [RequiredArgumentList], null], null, [[Fixnum, 1]], [AnnotationList]]]]",
- "def foo(a:SimpleString); 1; end")
+ assert_parse("[Script, [[MethodDefinition, [SimpleString, foo], [Arguments, [RequiredArgumentList, [RequiredArgument, [SimpleString, a], [Constant, [SimpleString, String]]]], [OptionalArgumentList], null, [RequiredArgumentList], null], null, [[Fixnum, 1]], [AnnotationList]]]]",
+ "def foo(a:String); 1; end")
assert_parse("[Script, [[MethodDefinition, [SimpleString, foo], [Arguments, [RequiredArgumentList, [RequiredArgument, [SimpleString, a], null], [RequiredArgument, [SimpleString, b], null]], [OptionalArgumentList], null, [RequiredArgumentList], null], null, [[Fixnum, 1]], [AnnotationList]]]]",
"def foo(a, b); 1; end")
assert_parse("[Script, [[MethodDefinition, [SimpleString, foo], [Arguments, [RequiredArgumentList], [OptionalArgumentList, [OptionalArgument, [SimpleString, a], null, [Fixnum, 1]]], null, [RequiredArgumentList], null], null, [[Fixnum, 1]], [AnnotationList]]]]",
@@ -632,4 +639,28 @@ def test_enddef
"if 1 then 2; end
def foo; 1; end")
end
+
+ def test_array_type
+ assert_parse("[Script, [[MethodDefinition, [SimpleString, foo], [Arguments, [RequiredArgumentList, [RequiredArgument, [SimpleString, a], [TypeRefImpl, String, array]]], [OptionalArgumentList], null, [RequiredArgumentList], null], null, [[Fixnum, 1]], [AnnotationList]]]]",
+ "def foo(a:String[]); 1; end")
+ end
+
+ def test_interface
+ assert_parse("[Script, [[InterfaceDeclaration, " +
+ "[Constant, [SimpleString, A]], null, " +
+ "[[Fixnum, 1]], " +
+ "[TypeNameList], [AnnotationList]]]]",
+ "interface A;1;end")
+ assert_parse("[Script, [[InterfaceDeclaration, " +
+ "[Constant, [SimpleString, A]], null, " +
+ "[[Fixnum, 1]], " +
+ "[TypeNameList, [Constant, [SimpleString, B]], [Constant, [SimpleString, C]]], " +
+ "[AnnotationList]]]]",
+ "interface A < B, C do 1;end")
+ assert_parse("[Script, [[InterfaceDeclaration, " +
+ "[Constant, [SimpleString, A]], null, [], " +
+ "[TypeNameList], " +
+ "[AnnotationList, [Annotation, [Constant, [SimpleString, Foo]], [HashEntryList]]]]]]",
+ "$Foo interface A; end")
+ end
end

0 comments on commit f397eb7

Please sign in to comment.