From 4ec2e7163774bddd6bc61ad08429e1daa3dd8a78 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 2 Jan 2012 19:10:41 +0100 Subject: Changed boxing of free mutable variables to be flexible wrt when liftcode takes place. A major redesign that unifies the various different approaches to boxing of free variables. Free variables are marked with CAPTURED and eliminated by LambdaLift. I also added some hooks in MacroContext that a reifier needs to use. --- src/library/scala/reflect/api/MacroContext.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/library/scala/reflect/api/MacroContext.scala (limited to 'src/library') diff --git a/src/library/scala/reflect/api/MacroContext.scala b/src/library/scala/reflect/api/MacroContext.scala new file mode 100644 index 0000000000..e23357d26e --- /dev/null +++ b/src/library/scala/reflect/api/MacroContext.scala @@ -0,0 +1,15 @@ +package scala.reflect +package api + +trait MacroContext extends Universe { + + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + */ + def captureVariable(vble: Symbol): Unit + + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + */ + def referenceCapturedVariable(id: Ident): Tree + +} \ No newline at end of file -- cgit v1.2.3 From 4787f883604d1344257c0b40c15790c3dde477f2 Mon Sep 17 00:00:00 2001 From: Szabolcs Berecz Date: Sat, 7 Jan 2012 17:40:00 +0100 Subject: Fixed equality and string representation of xml attributes with null value Prior to this patch was not equal to and it's string representation was "" instead of "" This includes changing MetaData.normalize() so that it doesn't reverse the chain. On the downside, the iterate function in MetaData.normalize() is not tail-recursive now. --- src/library/scala/xml/Elem.scala | 4 +++- src/library/scala/xml/MetaData.scala | 4 ++-- src/library/scala/xml/UnprefixedAttribute.scala | 2 +- src/library/scala/xml/Utility.scala | 2 +- test/files/jvm/xml03syntax.check | 2 +- test/files/run/xml-attribute.scala | 14 ++++++++++++++ 6 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 test/files/run/xml-attribute.scala (limited to 'src/library') diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala index 127e6e0ab7..df52b34f87 100644 --- a/src/library/scala/xml/Elem.scala +++ b/src/library/scala/xml/Elem.scala @@ -41,7 +41,7 @@ object Elem { class Elem( override val prefix: String, val label: String, - override val attributes: MetaData, + attributes1: MetaData, override val scope: NamespaceBinding, val child: Node*) extends Node with Serializable @@ -49,6 +49,8 @@ extends Node with Serializable final override def doCollectNamespaces = true final override def doTransform = true + override val attributes = MetaData.normalize(attributes1, scope) + if (prefix == "") throw new IllegalArgumentException("prefix of zero length, use null instead") diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala index 98e863eb37..c516747bae 100644 --- a/src/library/scala/xml/MetaData.scala +++ b/src/library/scala/xml/MetaData.scala @@ -38,8 +38,8 @@ object MetaData { def iterate(md: MetaData, normalized_attribs: MetaData, set: Set[String]): MetaData = { lazy val key = getUniversalKey(md, scope) if (md eq Null) normalized_attribs - else if (set(key)) iterate(md.next, normalized_attribs, set) - else iterate(md.next, md copy normalized_attribs, set + key) + else if ((md.value eq null) || set(key)) iterate(md.next, normalized_attribs, set) + else md copy iterate(md.next, normalized_attribs, set + key) } iterate(attribs, Null, Set()) } diff --git a/src/library/scala/xml/UnprefixedAttribute.scala b/src/library/scala/xml/UnprefixedAttribute.scala index c56fba1e6c..b6800d5ed1 100644 --- a/src/library/scala/xml/UnprefixedAttribute.scala +++ b/src/library/scala/xml/UnprefixedAttribute.scala @@ -22,7 +22,7 @@ extends Attribute final val pre = null val next = if (value ne null) next1 else next1.remove(key) - /** same as this(key, Text(value), next) */ + /** same as this(key, Text(value), next), or no attribute if value is null */ def this(key: String, value: String, next: MetaData) = this(key, if (value ne null) Text(value) else null: NodeSeq, next) diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 9b48f4e1bb..fc20b892b9 100644 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -61,7 +61,7 @@ object Utility extends AnyRef with parsing.TokenTests { val key = md.key val smaller = sort(md.filter { m => m.key < key }) val greater = sort(md.filter { m => m.key > key }) - smaller.append( Null ).append(md.copy ( greater )) + smaller.copy(md.copy ( greater )) } /** Return the node with its attribute list sorted alphabetically diff --git a/test/files/jvm/xml03syntax.check b/test/files/jvm/xml03syntax.check index 75dc539137..9fbedc2ae6 100644 --- a/test/files/jvm/xml03syntax.check +++ b/test/files/jvm/xml03syntax.check @@ -23,4 +23,4 @@ true 4 node=, key=Some(hello) -node=, key=None +node=, key=None diff --git a/test/files/run/xml-attribute.scala b/test/files/run/xml-attribute.scala new file mode 100644 index 0000000000..2b83f70b22 --- /dev/null +++ b/test/files/run/xml-attribute.scala @@ -0,0 +1,14 @@ +import xml.Node + +object Test { + def main(args: Array[String]): Unit = { + val noAttr = + val attrNull = + val attrNone = + assert(noAttr == attrNull) + assert(noAttr == attrNone) + assert(noAttr.toString() == "") + assert(attrNull.toString() == "") + assert(attrNone.toString() == "") + } +} -- cgit v1.2.3 From 51089b34a7a535498dee42e6465d4d577d65b7d5 Mon Sep 17 00:00:00 2001 From: Szabolcs Berecz Date: Sat, 7 Jan 2012 18:23:21 +0100 Subject: Accept prefixed xml attributes with null value This changes makes PrefixedAttribute work the same way as UnprefixedAttribute with respect to null values: is accepted and results in --- src/library/scala/xml/PrefixedAttribute.scala | 15 +++++++++------ test/files/run/xml-attribute.scala | 25 ++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/xml/PrefixedAttribute.scala b/src/library/scala/xml/PrefixedAttribute.scala index 436dfcda43..b80d6a1c73 100644 --- a/src/library/scala/xml/PrefixedAttribute.scala +++ b/src/library/scala/xml/PrefixedAttribute.scala @@ -13,22 +13,25 @@ package scala.xml * * @param pre ... * @param key ... - * @param value the attribute value, which may not be null + * @param value the attribute value * @param next ... */ class PrefixedAttribute( val pre: String, val key: String, val value: Seq[Node], - val next: MetaData) + val next1: MetaData) extends Attribute { - if (value eq null) - throw new UnsupportedOperationException("value is null") + val next = if (value ne null) next1 else next1.remove(key) - /** same as this(key, Utility.parseAttributeValue(value), next) */ + /** same as this(pre, key, Text(value), next), or no attribute if value is null */ def this(pre: String, key: String, value: String, next: MetaData) = - this(pre, key, Text(value), next) + this(pre, key, if (value ne null) Text(value) else null: NodeSeq, next) + + /** same as this(pre, key, value.get, next), or no attribute if value is None */ + def this(pre: String, key: String, value: Option[Seq[Node]], next: MetaData) = + this(pre, key, value.orNull, next) /** Returns a copy of this unprefixed attribute with the given * next field. diff --git a/test/files/run/xml-attribute.scala b/test/files/run/xml-attribute.scala index 2b83f70b22..8b261acc94 100644 --- a/test/files/run/xml-attribute.scala +++ b/test/files/run/xml-attribute.scala @@ -5,10 +5,29 @@ object Test { val noAttr = val attrNull = val attrNone = + val preAttrNull = + val preAttrNone = assert(noAttr == attrNull) assert(noAttr == attrNone) - assert(noAttr.toString() == "") - assert(attrNull.toString() == "") - assert(attrNone.toString() == "") + assert(noAttr == preAttrNull) + assert(noAttr == preAttrNone) + + val noAttrStr = "" + assert(noAttr.toString() == noAttrStr) + assert(attrNull.toString() == noAttrStr) + assert(attrNone.toString() == noAttrStr) + assert(preAttrNull.toString() == noAttrStr) + assert(preAttrNone.toString() == noAttrStr) + + val xml1 = + val xml2 = + val xml3 = + assert(xml1 == xml2) + assert(xml1 == xml3) + + val xml1Str = "" + assert(xml1.toString() == xml1Str) + assert(xml2.toString() == xml1Str) + assert(xml3.toString() == xml1Str) } } -- cgit v1.2.3