summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.config2
-rw-r--r--config/list/library.lst5
-rw-r--r--config/list/scalac.lst1
-rw-r--r--sources/scala/Predef.scala2
-rw-r--r--sources/scala/tools/dtd2scala/DeclToScala.scala23
-rw-r--r--sources/scala/tools/dtd2scala/Main.scala14
-rw-r--r--sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml83
-rw-r--r--sources/scala/tools/scalac/ast/parser/MarkupParser.scala398
-rw-r--r--sources/scala/tools/scalac/ast/parser/Scanner.scala2
-rw-r--r--sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala453
-rw-r--r--sources/scala/xml/Attribute.scala29
-rw-r--r--sources/scala/xml/AttributeSeq.scala69
-rw-r--r--sources/scala/xml/BindingFactoryAdapter.scala10
-rw-r--r--sources/scala/xml/CharData.scala11
-rw-r--r--sources/scala/xml/Elem.scala26
-rw-r--r--sources/scala/xml/FactoryAdapter.scala11
-rw-r--r--sources/scala/xml/Namespace.scala14
-rw-r--r--sources/scala/xml/NamespaceRegistry.scala43
-rw-r--r--sources/scala/xml/Node.scala26
-rw-r--r--sources/scala/xml/PrettyPrinter.scala104
-rw-r--r--sources/scala/xml/SpecialNode.scala2
-rw-r--r--sources/scala/xml/Utility.scala206
-rw-r--r--sources/scala/xml/dtd/Decl.scala36
-rw-r--r--sources/scala/xml/dtd/Validation.scala92
-rw-r--r--sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala6
-rw-r--r--sources/scalac/transformer/matching/BerrySethi.java7
-rw-r--r--sources/scalac/transformer/matching/Label.java2
-rwxr-xr-xtest/bin/scala-test3
-rw-r--r--test/files/jvm/xmlLiterals.scala6
-rw-r--r--test/files/jvm/xmlstuff.check9
-rw-r--r--test/files/jvm/xmlstuff.scala52
-rw-r--r--test/files/xml/lnk.check4
-rw-r--r--test/files/xml/lnk.namespace1
-rw-r--r--test/files/xml/lnk.scala9
-rw-r--r--test/files/xml/xhtml.check4
-rw-r--r--test/files/xml/xhtml.namespace1
-rw-r--r--test/files/xml/xhtml.scala15
37 files changed, 1139 insertions, 642 deletions
diff --git a/Makefile.config b/Makefile.config
index 15b4443881..52872f2971 100644
--- a/Makefile.config
+++ b/Makefile.config
@@ -105,7 +105,7 @@ PICO_FLAGS ?= -make -source 1.4
##############################################################################
# Bootstrap compiler
-BOOTSTRAP_SCALAC ?= scalac
+BOOTSTRAP_SCALAC ?= /home/linuxsoft/apps/scala/bin/scalac
##############################################################################
# Convert tool (ImageMagick)
diff --git a/config/list/library.lst b/config/list/library.lst
index f0eefeea51..b4000ffc06 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -155,6 +155,8 @@ runtime/matching/Rule.scala
testing/UnitTest.scala
+xml/Attribute.scala
+xml/AttributeSeq.scala
xml/BindingFactoryAdapter.scala
xml/CharData.scala
xml/Comment.scala
@@ -162,8 +164,6 @@ xml/Elem.scala
xml/ExternalID.scala
xml/EntityRef.scala
xml/FactoryAdapter.scala
-xml/Namespace.scala
-xml/NamespaceRegistry.scala
xml/Node.scala
xml/NodeBuffer.scala
xml/NodeSeq.scala
@@ -180,6 +180,7 @@ xml/dtd/Parser.scala
xml/dtd/RegExp.scala
xml/dtd/Scanner.scala
xml/dtd/Tokens.scala
+xml/dtd/Validation.scala
xml/nobinding/NoBindingFactoryAdapter.scala
xml/nobinding/XML.scala
diff --git a/config/list/scalac.lst b/config/list/scalac.lst
index dd2550b0aa..acaa2db448 100644
--- a/config/list/scalac.lst
+++ b/config/list/scalac.lst
@@ -14,6 +14,7 @@ ast/parser/Parser.scala
ast/parser/ParserPhase.scala
ast/parser/PatternNormalizer.scala
ast/parser/Scanner.scala
+ast/parser/SymbolicXMLBuilder.scala
ast/parser/TokenData.scala
ast/parser/Tokens.scala
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index 7dd8bc3a60..87d92741e3 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -42,6 +42,8 @@ object Predef {
def fst[a](x: a, y: Any): a = x;
def scd[a](x: Any, y: a): a = y;
+ val namespace$default = "";
+
type Function[-a,+b] = Function1[a,b];
// arrays -----------------------------------------------------------
diff --git a/sources/scala/tools/dtd2scala/DeclToScala.scala b/sources/scala/tools/dtd2scala/DeclToScala.scala
index 0fbb396dc5..62a724187f 100644
--- a/sources/scala/tools/dtd2scala/DeclToScala.scala
+++ b/sources/scala/tools/dtd2scala/DeclToScala.scala
@@ -19,12 +19,9 @@ import scala.xml.nobinding.XML ;
/** transforms a set of DTD declaraion to a scala source file.
* 2do: parameterize with destination package.
*/
-class DeclToScala(fOut:PrintWriter,
- moduleName:String,
- elemMap:Map[ String, MyElemDecl ] ) {
+class DeclToScala(fOut: PrintWriter, objectName: String, namespace: String, elemMap:Map[String, MyElemDecl] ) {
- abstract class ObjectTemplate {
- val objectName : String = "myXML"; /* DEFAULT MODULE NAME */
+ class ObjectTemplate {
val package_ : String = "";
val compress : boolean = true;
final val tmplFile = "scala/tools/dtd2scala/template/ObjectTemplate.scala.xml";
@@ -60,7 +57,7 @@ class DeclToScala(fOut:PrintWriter,
}
/** 1.populate with actual values: throw error if FIXED is wrong
** 2.throw error if a REQUIRED one is missing*/
- def validateAttributes( curAttribs:Map[String,AttrDecl] ):String = {
+ def validateAttributes(curAttribs: Map[String,AttrDecl]):String = {
def appendKey( key:String, sb:StringBuffer ) = {
val it = Iterator.fromString( key );
sb.append('\'');
@@ -169,8 +166,17 @@ class DeclToScala(fOut:PrintWriter,
fOut.print( text );
case n:Elem =>
n.label match {
+ case "attributeDecls" =>
+ var sb = new StringBuffer("Nil");
+ for( val aDecl <- curAttribs.values ) {
+ sb.insert(0, "::");
+ sb.insert(0, aDecl.toString());
+ }
+ fOut.print(sb.toString());
+
case "template" => {
lookup.update("objectName", objectName);
+ lookup.update("namespace", namespace);
lookup.update("compressDefault", compress.toString());
n.child.elements.foreach { n => writeNode(n) }
}
@@ -212,6 +218,7 @@ class DeclToScala(fOut:PrintWriter,
case "attributeBinding" => {
for( val aDecl <- curAttribs.keys ) {
lookup += "attributeName" -> aDecl;
+ lookup += "attributeDecl" -> curAttribs(aDecl).toString();
n.child.elements.foreach{ n => writeNode( n ) }
}
lookup -= "attributeName";
@@ -240,9 +247,7 @@ class DeclToScala(fOut:PrintWriter,
/** runs translation. */
def run:Unit = {
- new ObjectTemplate {
- override val objectName = moduleName
- }.write;
+ new ObjectTemplate().write;
fOut.flush();
fOut.close();
}
diff --git a/sources/scala/tools/dtd2scala/Main.scala b/sources/scala/tools/dtd2scala/Main.scala
index 5daa917d8a..b4f292ac46 100644
--- a/sources/scala/tools/dtd2scala/Main.scala
+++ b/sources/scala/tools/dtd2scala/Main.scala
@@ -23,7 +23,7 @@ object Main {
def printUsage:Unit = {
- Console.println("usage: dtd2scala [ -d <dir> ] <sysID> <object name>");
+ Console.println("usage: dtd2scala [ -d <dir> ] <sysID> <object name> [<namespace>]");
Console.println(" binds a DTD to class definitions");
Console.println(" will create a file [<dir>/]<object name>.scala");
Console.println("<dir> is the output directory [path of <sysID> is default]");
@@ -37,23 +37,27 @@ object Main {
List.fromArray(argv, 0, argv.length) match {
case Seq( "-d", outdir, sysID, objName ) =>
- continue( new File( outdir ), sysID, objName );
+ continue( new File( outdir ), sysID, objName, "" );
+ case Seq( "-d", outdir, sysID, objName, namespace ) =>
+ continue( new File( outdir ), sysID, objName, namespace );
//case Seq( "-sql", sysID ) => dosql( sysID );
case Seq( sysID, objName ) =>
- continue( new File( sysID ).getParentFile(), sysID, objName );
+ continue( new File( sysID ).getParentFile(), sysID, objName, "" );
+ case Seq( sysID, objName, namespace ) =>
+ continue( new File( sysID ).getParentFile(), sysID, objName, namespace );
case _ =>
{ printUsage; System.exit(-1); }
}
}
- private def continue( outdir:File, sysID:String, objName:String ) = {
+ private def continue( outdir:File, sysID:String, objName:String, ns:String ) = {
val myH:MainHandler = new MainHandler();
parse( sysID, myH );
// myH.print(); // DEBUG
val p = new PrintWriter(new FileWriter(new File(outdir,
objName+".scala" )));
- new DeclToScala( p, objName, myH.elemMap ).run;
+ new DeclToScala( p, objName, ns, myH.elemMap ).run;
}
/*
diff --git a/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml b/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml
index 68b0db8546..07449413d4 100644
--- a/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml
+++ b/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml
@@ -29,19 +29,6 @@
import scala.collection.mutable;
type cT = scala.Seq[scala.xml.Node];
- type aT = Map[String,String];
-
- def error_FixedAttribute( k:String, value:String ) =
- error("value of attribute " + k + " FIXED to \""+value+"\"");
-
- def error_UndefinedAttribute( b:String ) =
- error("undefined attribute " + b );
-
- def error_MissingAttribute( map:aT ) =
- error("missing value for REQUIRED attribute "
- +(map.keys.filter { x => map(x) == "&lt;R" })
- .toList.mkString("",",",""));
-
def error_InvalidChildren( elName:String, ch:cT, cM:String ) =
error("trying to construct invalid "+elName+",\n children labels were: "
@@ -49,8 +36,8 @@
+"\n content model was "+cM);
abstract class <string ref="objectName"/>Node$ extends scala.xml.Node {
- /** the namespace code of this node */
- final val namespaceCode: Int = 0;
+ /** the namespace of this node */
+ final val namespace: String = <qstring ref="namespace"/>;
}
def tagIterator(ch:Seq[scala.xml.Node]):Iterator[Int] = new Iterator[Int] {
@@ -79,53 +66,34 @@
</elementBinding>
<elementBinding>
- def constr_&ccElementName;( attrs:aT, ch:cT ) = &ccElementName;(attrs,ch:_*);
+ def constr_&ccElementName;( attrs:scala.xml.AttributeSeq, ch:cT ) = &ccElementName;(attrs,ch:_*);
- case class &ccElementName;( attrs:Map[String,String], ch:scala.xml.Node* ) extends <string ref="objectName"/>Node$ {
+ private val &ccElementName;AttribValidator = {
+ import scala.xml.dtd._;
+ new AttributeValidator(
+ <qstring ref="namespace"/>, <attributeDecls/>);
+ }
+ case class &ccElementName;( attrs:scala.xml.AttributeSeq, ch:scala.xml.Node* ) extends <string ref="objectName"/>Node$ {
final override def typeTag$ = <refTag/>;
- final def shallowValidate&ccElementName;Children( ch:Seq[scala.xml.Node] ) =
- <shallowContentRegExp/>;
-
- final def validateAttributes( attrs:Map[String,String] ):aT = {
- var req = 0;
- var map = scala.xml.Node.NoAttributes;
- <initAttributes/>
-
- for( val b &lt;- attrs.elements ) {
- val a:Seq[Char] = b._1;
- a match {
- <validateAttributes/>
- case _ => error_UndefinedAttribute( b._1 )
- }
- }
- if( req > 0 ) error_MissingAttribute( map );
- map
- }
-
- if( !shallowValidate&ccElementName;Children( ch ) )
- error_InvalidChildren( &qElementName;, ch, <qstring ref="elementContentModel"/> );
-
final def label = &qElementName;;
- final def child = ch;
-
- protected var hmap:aT = _;
- try {
- hmap = validateAttributes( attrs );
- } catch {
- case e:java.lang.Error =>
- error("invalid attributes for &elementName;\n"+e.getMessage());
- }
- final def attribute:aT = hmap;
+ final def child = ch;
+ final def attributes = theAttrs;
+
+ val theAttrs = &ccElementName;AttribValidator.validate( attrs );
- <attributeBinding>
- final def &cAttributeName; : scala.Option[String] = hmap.get(&qAttributeName;);
- </attributeBinding>
- val attribHashCode: int = hmap.toList.hashCode() ;
+
+ /* attributes
+ <!-- attributeBinding>
+
+ <string ref="attributeDecl"/>
+ final def &cAttributeName; : String = attribute(&qAttributeName;);
+ </attributeBinding -->
+ */
- /** returns a new &ccElementName; with updated attributes */
+ /** returns a new &ccElementName; with updated attributes
final def %(attrs: Seq[Pair[String, String]]) = {
var newmap = scala.xml.Node.NoAttributes;
for( val p &lt;- attribute.elements ) {
@@ -136,8 +104,8 @@
}
&ccElementName;( newmap, child:_* ) ;
}
-
- /** returns a new &ccElementName; with updated attribute */
+ */
+ /** returns a new &ccElementName; with updated attribute
final def %(attr: Pair[String, String]) = {
var newmap = scala.xml.Node.NoAttributes;
for( val p &lt;- attribute.elements ) {
@@ -146,6 +114,7 @@
newmap = newmap.update( attr._1, attr._2 );
&ccElementName;( newmap, child:_* ) ;
}
+*/
}
</elementBinding>
@@ -155,7 +124,7 @@
def load( filename:String, _compress:boolean ):scala.xml.Node = {
val fAdapter = new scala.xml.BindingFactoryAdapter {
val f = {
- val res = new mutable.HashMap[String, (aT,cT) => scala.xml.Node]() ;
+ val res = new mutable.HashMap[String, (scala.xml.AttributeSeq,cT) => scala.xml.Node]() ;
<elementBinding>
res.update( &qElementName;, constr_&ccElementName;);</elementBinding>
res;
diff --git a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala
index 19ef5493f3..b483b85aaa 100644
--- a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala
+++ b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala
@@ -10,7 +10,6 @@ import scalac.ast._;
import scalac.atree.AConstant;
import scalac._;
import scalac.symtab.Modifiers;
-import scalac.util.{ Name, Names, TypeNames };
import scala.tools.util.Position;
import java.lang.{Integer, Long, Float, Double};
import scala.Iterator;
@@ -18,6 +17,7 @@ import scala.tools.scalac.util.NewArray;
import scala.collection.immutable.ListMap ;
import scala.collection.mutable.Buffer;
import scala.xml.{Text,TextBuffer};
+import scalac.util.Name;
package scala.tools.scalac.ast.parser {
@@ -26,358 +26,16 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
import Tokens.{EMPTY, LBRACE, RBRACE} ;
import scala.tools.scalac.ast.{TreeList => myTreeList}
- val _ArrayBuffer = Name.fromString("ArrayBuffer");
- val _NodeBuffer = Name.fromString("NodeBuffer");
- val _TreeMap = Name.fromString("TreeMap");
- val _Elem = Name.fromString("Elem");
- val _Seq = Name.fromString("Seq");
- val _String = Name.fromString("String");
- val _immutable = Name.fromString("immutable");
- val _mutable = Name.fromString("mutable");
- val _append = Name.fromString("append");
- val _plus = Name.fromString("$plus");
- val _collection = Name.fromString("collection");
- val _xml = Name.fromString("xml");
- val _Comment = Name.fromString("Comment");
- val _CharData = Name.fromString("CharData");
- val _Node = Name.fromString("Node");
- val _None = Name.fromString("None");
- val _Some = Name.fromString("Some");
- val _ProcInstr = Name.fromString("ProcInstr");
- val _Text = Name.fromString("Text");
- val _EntityRef = Name.fromString("EntityRef");
+ /** the XML tree factory */
+ val mk = new SymbolicXMLBuilder( unit.global.make, unit.global.treeGen, p, preserveWS );
- /** the tree factory
- */
- val make: TreeFactory = unit.global.make;
-
- /** the tree generator
- */
- val gen: TreeGen = unit.global.treeGen;
+ /** the XML tree builder */
+ val gen = unit.global.treeGen ;
var mode:boolean = false;
final val PATTERN = true;
final val EXPR = false;
- // convenience methods
- private def _scala( pos: int, name: Name ) =
- make.Select( pos, make.Ident( pos, Names.scala ), name );
-
- private def _scala_Seq( pos: int ) =
- p.convertToTypeId( _scala( pos, _Seq ));
-
-
- private def _scala_None( pos: int ) =
- _scala( pos, _None ) ;
-
- private def _scala_Some( pos: int ) =
- p.convertToConstr( _scala( pos, _Some ));
-
-
- private def _string( pos: int ) =
- p.convertToTypeId( make.Ident( pos, _String ) );
-
- private def _scala_xml( pos: int, name: Name ) =
- make.Select( pos, _scala( pos, _xml ), name );
-
- private def _scala_xml_Node( pos: int ) =
- _scala_xml( pos, _Node );
-
- private def _scala_xml_NodeBuffer( pos: int ) =
- p.convertToConstr( _scala_xml( pos, _NodeBuffer ));
-
- private def _scala_xml_EntityRef( pos: int ) =
- p.convertToConstr( _scala_xml( pos, _EntityRef ));
-
- private def _scala_xml_Comment( pos: int ) =
- p.convertToConstr( _scala_xml( pos, _Comment ));
-
- private def _scala_xml_CharData( pos: int ) =
- p.convertToConstr( _scala_xml( pos, _CharData ));
-
- private def _scala_xml_ProcInstr( pos: int ) =
- p.convertToConstr( _scala_xml( pos, _ProcInstr ));
-
- private def _scala_xml_Text( pos: int ) =
- _scala_xml( pos, _Text );
-
-
- private def _scala_collection( pos: int, name: Name ) =
- make.Select( pos, _scala( pos, _collection ), name );
-
- private def _scala_collection_mutable( pos: int, name: Name ) =
- make.Select(pos, _scala_collection(pos, _mutable ), name);
-
- private def _scala_collection_immutable( pos: int, name: Name ) =
- make.Select(pos, _scala_collection(pos, _immutable ), name);
-
- private def _scala_collection_mutable_ArrayBuffer( pos: int ) =
- make.Apply( pos,
- make.AppliedType(pos,
- p.convertToConstr(
- _scala_collection_mutable(pos, _ArrayBuffer )),
- Predef.Array[Tree](
- convertToTypeId(
- _scala_xml_Node( pos ) ))
- ),
- Tree.EMPTY_ARRAY );
-
- private def _scala_collection_immutable_TreeMap( pos: int ) =
- make.Apply( pos,
- make.AppliedType(pos,
- p.convertToConstr(
- _scala_collection_immutable(pos, _TreeMap )),
- Predef.Array[Tree](
- _string( pos ),
- _string( pos )
- )
- ),
- Tree.EMPTY_ARRAY );
-
- private def _emptyMap( pos:int ) = {
- make.New( pos,_scala_collection_immutable_TreeMap( pos: int ));
- }
-
- private def _scala_Tuple2( pos:int ) =
- _scala( pos, Names.Tuple2 );
-
- private def _scala_xml_Elem( pos:int ) =
- _scala_xml( pos, _Elem );
-
- /** convenience method */
- def convertToTypeId(t: Tree): Tree = t match {
- case Tree$Ident(name) =>
- make.Ident(t.pos, name.toTypeName())
- case Tree$Select(qual, name) =>
- make.Select(t.pos, qual, name.toTypeName())
- case _ =>
- t
- }
-
- // create scala xml tree
-
- /**
- * @arg namespace: a Tree of type defs.STRING_TYPE
- * @arg label: a Tree of type defs.STRING_TYPE
- * @todo map: a map of attributes !!!
- */
- def mkXML(pos:int, isPattern:boolean, namespace:Tree, label:Tree, args:Array[Tree]):Tree = {
- if( isPattern ) {
- val ts = new myTreeList();
- ts.append( namespace );
- ts.append( label );
- ts.append( new Tree$Ident( Names.PATTERN_WILDCARD ) );
- ts.append( convertToText( true, args ) );
- make.Apply(pos,
- convertToTypeId( _scala_xml_Elem( pos ) ),
- ts.toArray())
- } else {
- val constrArgs = if( 0 == args.length ) {
- Predef.Array[Tree]( namespace, label, _emptyMap( pos ) )
- } else {
- Predef.Array[Tree]( namespace, label, _emptyMap( pos ), make.Typed(
- pos, makeXMLseq(pos, args ), make.Ident(pos, TypeNames.WILDCARD_STAR)))
- };
- make.Apply( pos, _scala_xml_Elem( pos ), constrArgs )
- }
- }
-
- def makeEntityRef( pos:int, n:Name ) = {
- val constr = make.Apply( pos,
- _scala_xml_EntityRef( pos ),
- Predef.Array[Tree]( gen.mkStringLit( pos, n.toString() )));
-
- make.New( pos, constr );
- };
- // create scala.xml.Text here <: scala.xml.Node
- def makeText( pos: int, isPattern:Boolean, txt:String ):Tree = {
- makeText( pos, isPattern, gen.mkStringLit( pos, txt ));
- }
-
- def appendTrimmed(pos: int, ts:myTreeList, txt:String) = {
- var textNodes =
- if( !preserveWS )
- new TextBuffer().append( txt ).toText;
- else
- List( Text( txt ));
-
- for( val t <- textNodes )
- ts.append( makeText( s.pos, mode, t.text ));
- }
-
- // create scala.xml.Text here <: scala.xml.Node
- def makeText( pos: int, isPattern:Boolean, txt:Tree ):Tree = {
- if( isPattern )
- makeTextPat( pos, txt );
- else
- makeText1( pos, txt );
- }
-
- // create scala.xml.Text here <: scala.xml.Node
- def makeTextPat( pos: int, txt:Tree ):Tree = {
- return make.Apply(pos,
- p.convertToConstr( _scala_xml_Text( pos ) ),
- Predef.Array[Tree]( txt ));
- }
-
- def makeText1( pos: int, txt:Tree ):Tree = {
- val constr = make.Apply(pos,
- p.convertToConstr( _scala_xml_Text( pos )),
- Predef.Array[Tree]( txt ));
- make.New( pos, constr );
- }
-
-
- // create
- def makeComment( pos: int, comment:scala.xml.Comment ):Tree =
- makeComment( pos, gen.mkStringLit( pos, comment.text ));
-
- // create
- def makeCharData( pos: int, charData:scala.xml.CharData ):Tree =
- makeCharData( pos, gen.mkStringLit( pos, charData.text ));
-
- // create scala.xml.Text here <: scala.xml.Node
- def makeProcInstr( pos: int, procInstr:scala.xml.ProcInstr ):Tree =
- procInstr.text match {
- case Some(txt) =>
- makeProcInstr( pos,
- gen.mkStringLit( pos, procInstr.target ),
- makeSome( pos, gen.mkStringLit( pos, txt )));
- case _ =>
- makeProcInstr( pos,
- gen.mkStringLit( pos, procInstr.target ),
- makeNone( pos ));
- }
-
- def makeNone( pos: int ):Tree = _scala_None( pos );
-
- def makeSome( pos: int, txt:Tree ):Tree = {
- val constr = make.Apply( pos,
- _scala_Some( pos ),
- Predef.Array[Tree] ( txt ));
- make.New( pos, constr );
- }
-
- def makeNodeBuffer( pos: int ):Tree = {
- val constr = make.Apply( pos,
- _scala_xml_NodeBuffer( pos ),
- Tree.EMPTY_ARRAY);
- make.New( pos, constr );
- }
-
- def makeCharData( pos: int, txt:Tree ):Tree = {
- val constr = make.Apply( pos,
- _scala_xml_CharData( pos ),
- Predef.Array[Tree] ( txt ));
- make.New( pos, constr );
- }
-
- def makeComment( pos: int, txt:Tree ):Tree = {
- val constr = make.Apply( pos,
- _scala_xml_Comment( pos ),
- Predef.Array[Tree] ( txt ));
- make.New( pos, constr );
- }
-
- def makeProcInstr( pos: int, target:Tree, txt:Tree ):Tree = {
- val constr = make.Apply( pos,
- _scala_xml_ProcInstr( pos ),
- Predef.Array[Tree] ( target, txt ));
- make.New( pos, constr );
- }
-
-
- def makeXMLpat(pos:int, n:Name, args:Array[Tree]):Tree =
- mkXML(pos, true, new Tree$Ident( Names.PATTERN_WILDCARD ), gen.mkStringLit( pos, n.toString() ), args);
-
- def makeXML(pos:int, n:Name, args:Array[Tree]):Tree = {
- var s = n.toString();
- val i = n.indexOf(':');
- var pref = "";
- if( i > -1 ) {
- pref = s.substring( 0, i );
- s = s.substring( i, s.length() );
- }
- mkXML(pos, false, gen.mkStringLit(pos, pref.toString()), gen.mkStringLit(pos, n.toString()), args);
- }
- def convertToText(isPattern:Boolean, t:Tree):Tree = t match {
- case _:Tree$Literal => makeText(t.pos, isPattern, t);
- case _ => t
- }
-
- def convertToText( isPattern:Boolean, ts:Array[Tree] ):Array[Tree] = {
- var res:Array[Tree] = null;
- var i = 0; while( i < ts.length ) {
- val t1 = ts( i );
- val t2 = convertToText( isPattern, t1 );
- if (!t1.eq(t2)) {
- if( null == res ) { // lazy copy
- res = new Array[Tree]( ts.length );
- System.arraycopy( ts, 0, res, 0, i );
- }
- res( i ) = t2;
- }
- i = i + 1;
- }
- if( null == res ) ts else res;
- }
-
- def isEmptyText(t:Tree) = t match {
- case Tree$Literal(atree.AConstant.STRING("")) => true;
- case _ => false;
- }
- def makeXMLseq( pos:int, args:Array[Tree] ) = {
- val ts = new TreeList();
- //val blocArr = new Array[Tree] ( 1 + args.length );
- //val constr = _scala_collection_mutable_ArrayBuffer( pos );
- val _buffer = makeNodeBuffer( pos );
- val n = p.fresh();
- val nIdent = make.Ident(pos, n);
- //blocArr( 0 )
- ts.append( make.ValDef(pos,
- 0, n, Tree.Empty,
- _buffer));
-
- var i = 0; while( i < args.length ) {
- val ipos = args(i).pos;
- if( !isEmptyText( args( i ))) {
- ts.append(
- make.Apply( ipos,
- make.Select( ipos, nIdent, _plus /*_append*/ ),
- Predef.Array[Tree]( convertToText(false, args( i ) )))
- )
- }
- i = i + 1;
- }
- make.Block( pos, ts.toArray(), nIdent );
- }
-
- def makeXMLseqPat( pos:int, args:Array[Tree] ) = {
- make.Apply( pos, _scala_Seq( pos ), args );
- }
-
- /** @todo: create map here directly */
- def makeXML(pos:int,n:Name,args:Array[Tree],attrMap:ListMap[Name,Tree]):Tree={
- var t = makeXML( pos, n, args );
- if( attrMap.isEmpty ) {
- t
- } else {
- val attrs = new Array[Tree]( attrMap.size );
- var i = 0;
- for( val Pair( key, value ) <- attrMap.elements ) {
- attrs( i ) = make.Apply(pos,
- _scala_Tuple2( s.pos ),
- Predef.Array(gen.mkStringLit( pos, key.toString() ),
- value));
- i = i + 1;
- };
- make.Apply(pos,
- make.Select( pos, t, Names.PERCENT ),
- Predef.Array( make.Apply(pos, _scala(s.pos, Names.List),
- attrs)));
- }
- }
-
/** xLiteral = xExpr { xExpr }
* @return Scala representation of this xml literal
* precondition: s.xStartsXML == true
@@ -389,7 +47,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
if( s.xStartsXML ) {
val ts = new myTreeList(); ts.append( tree );
while( s.xStartsXML ) { ts.append( xExpr ); s.nextToken(); }
- tree = makeXMLseq( pos, ts.toArray() );
+ tree = mk.makeXMLseq( pos, ts.toArray() );
}
tree
}
@@ -401,9 +59,9 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
* | `{` scalablock `}`
*/
def xAttributes = {
- var aMap = ListMap.Empty[Name,Tree];
+ var aMap = new ListMap[String, Tree];
while( xml.Parsing.isNameStart( s.ch )) {
- val key = s.xName;
+ val key = s.xName.toString();
s.xEQ;
val delim = s.ch;
val value:Tree = s.ch match {
@@ -440,7 +98,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
val aMap = if(xml.Parsing.isNameStart( s.ch )) {
xAttributes;
} else {
- ListMap.Empty[Name,Tree];
+ ListMap.Empty[String,Tree];
}
Tuple2( elemName, aMap );
}
@@ -448,7 +106,8 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
/* [42] '<' xmlEndTag ::= '<' '/' Name S? '>' */
def xEndTag( n:Name ) = {
s.xToken('/');
- if(n != s.xName) s.xSyntaxError( "expected closing tag of " + n );
+ val m = s.xName;
+ if(n != m) s.xSyntaxError( "expected closing tag of " + n/* +", not "+m*/);
s.xSpaceOpt;
s.xToken('>')
}
@@ -467,11 +126,11 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
*/
def xExpr:Tree = {
var pos = s.pos;
- val Tuple2(elemName, attrMap) = xTag;
+ val Tuple2(qname:Name, attrMap:ListMap[String,Tree]) = xTag;
if(s.ch == '/') { // empty element
s.xToken('/');
s.xToken('>');
- makeXML( pos, elemName, Tree.EMPTY_ARRAY, attrMap );
+ mk.makeXML( pos, qname, attrMap, Tree.EMPTY_ARRAY );
} else { // handle content
s.xToken('>');
val ts = new myTreeList();
@@ -489,12 +148,12 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
case '!' =>
s.xNext;
if( '[' == s.ch ) // CDATA
- ts.append( makeCharData( pos, s.xCharData ));
+ ts.append( mk.CharData( pos, s.xCharData ));
else // comment
- ts.append( makeComment( pos, s.xComment ));
+ ts.append( mk.Comment( pos, s.xComment ));
case '?' => // PI
s.xNext;
- ts.append( makeProcInstr( pos, s.xProcInstr ));
+ ts.append( mk.ProcInstr( pos, s.xProcInstr ));
case _ => ts.append( xExpr ); // child
}
@@ -504,7 +163,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
} else {
val str = new StringBuffer("{");
str.append( s.xText );
- appendTrimmed( pos, ts, str.toString() )
+ mk.appendTrimmed( pos, mode, ts, str.toString() )
}
// postcond: s.xScalaBlock == false!
case '&' => // EntityRef or CharRef
@@ -512,24 +171,23 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
s.ch match {
case '#' => // CharacterRef
s.xNext;
- val theChar = makeText( s.pos, false, s.xCharRef );
+ val theChar = mk.makeText( s.pos, false, s.xCharRef );
s.xToken(';');
ts.append( theChar );
case _ => // EntityRef
- val pos = s.pos;
val n = s.xName ;
s.xToken(';');
- ts.append( makeEntityRef( s.pos, n ));
+ ts.append( mk.EntityRef( pos, n ));
}
case _ => // text content
- appendTrimmed( s.pos, ts, s.xText );
+ mk.appendTrimmed( pos, mode, ts, s.xText );
// here s.xScalaBlock might be true
}
}
}
- xEndTag( elemName );
- makeXML( pos, elemName, ts.toArray(), attrMap );
+ xEndTag( qname );
+ mk.makeXML( pos, qname, attrMap, ts.toArray() );
}
}
@@ -551,7 +209,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
if( s.xStartsXML ) {
val ts = new myTreeList(); ts.append( tree );
while( s.xStartsXML ) { ts.append( xPattern ); s.nextToken(); }
- tree = makeXMLseqPat( pos, ts.toArray() );
+ tree = mk.makeXMLseqPat( pos, ts.toArray() );
}
mode = oldMode;
tree
@@ -575,12 +233,12 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
def xPattern:Tree = {
//Console.println("xPattern");
val pos = s.pos;
- val elemName = s.xName;
+ val qname = s.xName;
s.xSpaceOpt;
if( s.ch == '/' ) { // empty tag
s.xNext;
s.xToken('>');
- return makeXMLpat( pos, elemName, Tree.EMPTY_ARRAY );
+ return mk.makeXMLpat( pos, qname, Tree.EMPTY_ARRAY );
};
// else: tag with content
@@ -608,13 +266,13 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
// postcond: s.xScalaBlock = false;
if( s.xScalaBlock ) throw new ApplicationError(); // assert
case _ => // text
- appendTrimmed( pos, ts, s.xText );
+ mk.appendTrimmed( pos, mode, ts, s.xText );
// here s.xScalaBlock might be true;
//if( s.xScalaBlock ) throw new ApplicationError("after:"+text); // assert
}
}
- xEndTag( elemName );
- makeXMLpat( pos, elemName, ts.toArray() );
+ xEndTag( qname );
+ mk.makeXMLpat( pos, qname, ts.toArray() );
}
} /* class MarkupParser */
diff --git a/sources/scala/tools/scalac/ast/parser/Scanner.scala b/sources/scala/tools/scalac/ast/parser/Scanner.scala
index 0efbe8ca2c..b810ea1a0b 100644
--- a/sources/scala/tools/scalac/ast/parser/Scanner.scala
+++ b/sources/scala/tools/scalac/ast/parser/Scanner.scala
@@ -998,12 +998,12 @@ class Scanner(_unit: Unit) extends TokenData {
* @param endch either ' or "
*/
def xAttributeValue( endch:char ):String = {
- cbuf.setLength( 0 );
while ( ch != endch ) {
putChar( ch );
xNext;
};
val s = cbuf.toString();
+ cbuf.setLength( 0 );
// @todo: normalize attribute value
// well-formedness constraint
if( s.indexOf('<') != -1 ) {
diff --git a/sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala b/sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala
new file mode 100644
index 0000000000..ca799d2fa2
--- /dev/null
+++ b/sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala
@@ -0,0 +1,453 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2004, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+import scalac.ast._;
+import scalac.atree.AConstant;
+import scalac._;
+import scalac.symtab.Modifiers;
+import scala.tools.util.Position;
+import java.lang.{Integer, Long, Float, Double};
+import scala.Iterator;
+import scala.tools.scalac.util.NewArray;
+import scala.collection.immutable.ListMap ;
+import scala.collection.mutable.Buffer;
+import scala.xml.{Text,TextBuffer};
+import scalac.util.{ Name, Names, TypeNames } ;
+package scala.tools.scalac.ast.parser {
+
+/** this class builds instance of Tree that represent XML */
+class SymbolicXMLBuilder(make: TreeFactory, gen: TreeGen, p: Parser, preserveWS: Boolean ) {
+
+ import scala.tools.scalac.ast.{TreeList => myTreeList}
+
+ val _ArrayBuffer = Name.fromString("ArrayBuffer");
+ val _Attribute = Name.fromString("Attribute");
+ val _NodeBuffer = Name.fromString("NodeBuffer");
+ val _NoAttributes = Name.fromString("NoAttributes");
+ val _TreeMap = Name.fromString("TreeMap");
+ val _Elem = Name.fromString("Elem");
+ val _Seq = Name.fromString("Seq");
+ val _String = Name.fromString("String");
+ val _immutable = Name.fromString("immutable");
+ val _mutable = Name.fromString("mutable");
+ val _append = Name.fromString("append");
+ val _plus = Name.fromString("$plus");
+ val _collection = Name.fromString("collection");
+ val _xml = Name.fromString("xml");
+ val _Comment = Name.fromString("Comment");
+ val _CharData = Name.fromString("CharData");
+ val _Node = Name.fromString("Node");
+ val _None = Name.fromString("None");
+ val _Some = Name.fromString("Some");
+ val _ProcInstr = Name.fromString("ProcInstr");
+ val _Text = Name.fromString("Text");
+ val _EntityRef = Name.fromString("EntityRef");
+
+ // convenience methods
+ private def _scala( pos: int, name: Name ) =
+ make.Select( pos, make.Ident( pos, Names.scala ), name );
+
+ private def _scala_Seq( pos: int ) =
+ p.convertToTypeId( _scala( pos, _Seq ));
+
+
+ private def _scala_None( pos: int ) =
+ _scala( pos, _None ) ;
+
+ private def _scala_Some( pos: int ) =
+ p.convertToConstr( _scala( pos, _Some ));
+
+
+ private def _string( pos: int ) =
+ p.convertToTypeId( make.Ident( pos, _String ) );
+
+ private def _scala_xml( pos: int, name: Name ) =
+ make.Select( pos, _scala( pos, _xml ), name );
+
+ private def _scala_xml_Node( pos: int ) =
+ _scala_xml( pos, _Node );
+
+ private def _scala_xml_Node_NoAttributes( pos: int ) =
+ make.Select( pos, _scala_xml( pos, _Node ), _NoAttributes );
+
+ private def _scala_xml_NodeBuffer( pos: int ) =
+ p.convertToConstr( _scala_xml( pos, _NodeBuffer ));
+
+ private def _scala_xml_EntityRef( pos: int ) =
+ p.convertToConstr( _scala_xml( pos, _EntityRef ));
+
+ private def _scala_xml_Comment( pos: int ) =
+ p.convertToConstr( _scala_xml( pos, _Comment ));
+
+ private def _scala_xml_CharData( pos: int ) =
+ p.convertToConstr( _scala_xml( pos, _CharData ));
+
+ private def _scala_xml_ProcInstr( pos: int ) =
+ p.convertToConstr( _scala_xml( pos, _ProcInstr ));
+
+ private def _scala_xml_Text( pos: int ) =
+ _scala_xml( pos, _Text );
+
+
+ private def _scala_collection( pos: int, name: Name ) =
+ make.Select( pos, _scala( pos, _collection ), name );
+
+ private def _scala_collection_mutable( pos: int, name: Name ) =
+ make.Select(pos, _scala_collection(pos, _mutable ), name);
+
+ private def _scala_collection_immutable( pos: int, name: Name ) =
+ make.Select(pos, _scala_collection(pos, _immutable ), name);
+
+ private def _scala_collection_mutable_ArrayBuffer( pos: int ) =
+ make.Apply( pos,
+ make.AppliedType(pos,
+ p.convertToConstr(
+ _scala_collection_mutable(pos, _ArrayBuffer )),
+ Predef.Array[Tree](
+ convertToTypeId(
+ _scala_xml_Node( pos ) ))
+ ),
+ Tree.EMPTY_ARRAY );
+
+ private def _scala_collection_immutable_TreeMap( pos: int ) =
+ make.Apply( pos,
+ make.AppliedType(pos,
+ p.convertToConstr(
+ _scala_collection_immutable(pos, _TreeMap )),
+ Predef.Array[Tree](
+ _string( pos ),
+ _string( pos )
+ )
+ ),
+ Tree.EMPTY_ARRAY );
+
+ private def _emptyMap( pos:int ) = {
+ make.New( pos,_scala_collection_immutable_TreeMap( pos: int ));
+ }
+
+ private def _scala_Tuple2( pos:int ) =
+ _scala( pos, Names.Tuple2 );
+
+ private def _scala_xml_Elem( pos:int ) =
+ _scala_xml( pos, _Elem );
+
+ private def _scala_xml_Attribute( pos: int ) =
+ _scala_xml( pos, _Attribute );
+
+
+
+ /** convenience method */
+ def convertToTypeId(t: Tree): Tree = t match {
+ case Tree$Ident(name) =>
+ make.Ident(t.pos, name.toTypeName())
+ case Tree$Select(qual, name) =>
+ make.Select(t.pos, qual, name.toTypeName())
+ case _ =>
+ t
+ }
+
+ // create scala xml tree
+
+ /**
+ * @arg namespace: a Tree of type defs.STRING_TYPE
+ * @arg label: a Tree of type defs.STRING_TYPE
+ * @todo map: a map of attributes !!!
+ */
+
+ def mkXML(pos:int, isPattern:boolean, namespace:Tree, label:Tree, attrs:Array[Tree], children:Array[Tree]):Tree = {
+ if( isPattern ) {
+ val ts = new myTreeList();
+ ts.append( namespace );
+ ts.append( label );
+ ts.append( new Tree$Ident( Names.PATTERN_WILDCARD ) ); // attributes?
+ ts.append( convertToTextPat( children ) );
+ make.Apply(pos,
+ convertToTypeId( _scala_xml_Elem( pos ) ),
+ ts.toArray())
+ } else {
+ val ab = new scala.collection.mutable.ArrayBuffer[Tree]();
+ ab + namespace;
+ ab + label;
+ if(( attrs.length ) == 0 )
+ ab + _scala_xml_Node_NoAttributes( pos )
+ else
+ ab + make.Apply(pos,
+ make.Select( pos,
+ _scala_xml_Node_NoAttributes( pos ),
+ Names.PERCENT ),
+ attrs);
+ if(( children.length ) > 0 )
+ ab + make.Typed(pos,
+ makeXMLseq(pos, children ),
+ make.Ident(pos, TypeNames.WILDCARD_STAR));
+ val arr:Array[Tree] = new Array[Tree]( ab.length );
+ ab.elements.copyToArray( arr, 0 );
+ make.Apply( pos, _scala_xml_Elem( pos ), arr )
+ }
+ }
+
+ final def EntityRef( pos:int, n:Name ) = {
+ val constr = make.Apply( pos,
+ _scala_xml_EntityRef( pos ),
+ Predef.Array[Tree]( gen.mkStringLit( pos, n.toString() )));
+
+ make.New( pos, constr );
+ };
+ // create scala.xml.Text here <: scala.xml.Node
+ def makeText( pos: int, isPattern:Boolean, txt:String ):Tree = {
+ //makeText( pos, isPattern, gen.mkStringLit( pos, txt ));
+ val txt1 = gen.mkStringLit( pos, txt );
+ if( isPattern )
+ makeTextPat( pos, txt1 );
+ else
+ makeText1( pos, txt1 );
+ }
+
+ def appendTrimmed(pos: int, mode:Boolean, ts:myTreeList, txt:String) = {
+ var textNodes =
+ if( !preserveWS )
+ new TextBuffer().append( txt ).toText;
+ else
+ List( Text( txt ));
+
+ for( val t <- textNodes )
+ ts.append( makeText( pos, mode, t.text ));
+ }
+
+ // create scala.xml.Text here <: scala.xml.Node
+/*
+ protected def makeText( pos: int, isPattern:Boolean, txt:Tree ):Tree = {
+ if( isPattern )
+ makeTextPat( pos, txt );
+ else
+ makeText1( pos, txt );
+ }
+*/
+ // create scala.xml.Text here <: scala.xml.Node
+ def makeTextPat( pos: int, txt:Tree ):Tree = {
+ return make.Apply(pos,
+ p.convertToConstr( _scala_xml_Text( pos ) ),
+ Predef.Array[Tree]( txt ));
+ }
+
+ def makeText1( pos: int, txt:Tree ):Tree = {
+ val constr = make.Apply(pos,
+ p.convertToConstr( _scala_xml_Text( pos )),
+ Predef.Array[Tree]( txt ));
+ make.New( pos, constr );
+ }
+
+ // create
+ def makeAttribute( pos: int, ns:String, key:String, value:Tree ):Tree =
+ make.Apply(pos,
+ _scala_xml_Attribute(pos),
+ Predef.Array[Tree] (
+ make.Ident( pos, Name.fromString( ns )),
+ gen.mkStringLit( pos, key ),
+ value
+ )
+ );
+
+ // create
+ def Comment( pos: int, comment:scala.xml.Comment ):Tree =
+ Comment( pos, gen.mkStringLit( pos, comment.text ));
+
+ // create
+ def CharData( pos: int, charData:scala.xml.CharData ):Tree =
+ CharData( pos, gen.mkStringLit( pos, charData.text ));
+
+ // create scala.xml.Text here <: scala.xml.Node
+ def ProcInstr( pos: int, procInstr:scala.xml.ProcInstr ):Tree =
+ procInstr.text match {
+ case Some(txt) =>
+ ProcInstr( pos,
+ gen.mkStringLit( pos, procInstr.target ),
+ makeSome( pos, gen.mkStringLit( pos, txt )));
+ case _ =>
+ ProcInstr( pos,
+ gen.mkStringLit( pos, procInstr.target ),
+ makeNone( pos ));
+ }
+
+ def makeNone( pos: int ):Tree = _scala_None( pos );
+
+ def makeSome( pos: int, txt:Tree ):Tree = {
+ val constr = make.Apply( pos,
+ _scala_Some( pos ),
+ Predef.Array[Tree] ( txt ));
+ make.New( pos, constr );
+ }
+
+ def makeNodeBuffer(pos: int): Tree = {
+ val constr = make.Apply( pos,
+ _scala_xml_NodeBuffer( pos ),
+ Tree.EMPTY_ARRAY);
+ make.New( pos, constr );
+ }
+
+ protected def CharData(pos: int, txt: Tree):Tree = {
+ val constr = make.Apply( pos,
+ _scala_xml_CharData( pos ),
+ Predef.Array[Tree] ( txt ));
+ make.New( pos, constr );
+ }
+
+ protected def Comment(pos: int, txt: Tree):Tree = {
+ val constr = make.Apply( pos,
+ _scala_xml_Comment( pos ),
+ Predef.Array[Tree] ( txt ));
+ make.New( pos, constr );
+ }
+
+ protected def ProcInstr(pos: int, target: Tree, txt: Tree): Tree = {
+ val constr = make.Apply( pos,
+ _scala_xml_ProcInstr( pos ),
+ Predef.Array[Tree] ( target, txt ));
+ make.New( pos, constr );
+ }
+
+ /** @todo: attributes */
+ def makeXMLpat(pos: int, n: Name, args: Array[Tree]): Tree =
+ mkXML(pos,
+ true,
+ new Tree$Ident( Names.PATTERN_WILDCARD ):Tree,
+ gen.mkStringLit( pos, n.toString() ):Tree,
+ Tree.EMPTY_ARRAY:Array[Tree],
+ args:Array[Tree]);
+
+ protected def convertToTextPat(t: Tree): Tree = t match {
+ case _:Tree$Literal => makeTextPat(t.pos, t);
+ case _ => t
+ }
+
+ protected def convertToTextPat(ts: Array[Tree]): Array[Tree] = {
+ var res:Array[Tree] = null;
+ var i = 0; while( i < ts.length ) {
+ val t1 = ts( i );
+ val t2 = convertToTextPat( t1 );
+ if (!t1.eq(t2)) {
+ if( null == res ) { // lazy copy
+ res = new Array[Tree]( ts.length );
+ System.arraycopy( ts, 0, res, 0, i );
+ }
+ res( i ) = t2;
+ }
+ i = i + 1;
+ }
+ if( null == res ) ts else res;
+ }
+
+ def isEmptyText(t:Tree) = t match {
+ case Tree$Literal(atree.AConstant.STRING("")) => true;
+ case _ => false;
+ }
+ def makeXMLseq( pos:int, args:Array[Tree] ) = {
+ val ts = new TreeList();
+ //val blocArr = new Array[Tree] ( 1 + args.length );
+ //val constr = _scala_collection_mutable_ArrayBuffer( pos );
+ val _buffer = makeNodeBuffer( pos );
+ val n = p.fresh();
+ val nIdent = make.Ident(pos, n);
+ //blocArr( 0 )
+ ts.append( make.ValDef(pos,
+ 0, n, Tree.Empty,
+ _buffer));
+
+ var i = 0; while( i < args.length ) {
+ val ipos = args(i).pos;
+ if( !isEmptyText( args( i ))) {
+ ts.append(
+ make.Apply( ipos,
+ make.Select( ipos, nIdent, _plus /*_append*/ ),
+ Predef.Array[Tree]( args( i ) ))
+ )
+ }
+ i = i + 1;
+ }
+ make.Block( pos, ts.toArray(), nIdent );
+ }
+
+ def makeXMLseqPat( pos:int, args:Array[Tree] ) = {
+ make.Apply( pos, _scala_Seq( pos ), args );
+ }
+
+
+
+ def getPrefix( name:String ):Option[String] = {
+ val i = name.indexOf(':');
+ if( i != -1 ) Some( name.substring(0, i) ) else None
+ }
+
+ def qualified( pos:Int, name:String ):Pair[String,String] =
+ getPrefix( name ).match {
+ case Some( pref ) =>
+ val newLabel = name.substring( pref.length(), name.length() );
+ // if( newLabel.indexOf(':') != -1 ) syntaxError
+ Pair( "namespace$"+pref, newLabel );
+ case None =>
+ Pair( "namespace$default", name );
+ }
+
+ /** makes an element */
+ def makeXML(pos: int, labeln: Name, attrMap: ListMap[String,Tree], args: Array[Tree]): Tree={
+ var label = labeln.toString();
+ var setNS = ListMap.Empty[String, Tree];
+
+
+ for( val z <- attrMap.keys; z.startsWith("xmlns") ) {
+ val i = z.indexOf(':');
+ if( i == -1 )
+ setNS = setNS.update("default", attrMap( z ));
+ else {
+ val zz = z.substring( i+1, z.length() );
+ setNS = setNS.update( zz, attrMap( z ));
+ }
+ }
+ val i = label.indexOf(':');
+ val Pair( namespace, newlabel ) = qualified( pos, label );
+
+ var attr:Array[Tree] =
+ if( attrMap.isEmpty )
+ Tree.EMPTY_ARRAY
+ else {
+ val attrs:Array[Tree] = new Array[Tree](attrMap.size);
+ var k = 0;
+ var it = attrMap.elements;
+ while( it.hasNext ) {
+ val ansk = it.next;
+ val Pair( ns, aname ) = qualified( pos, ansk._1 );
+ attrs( k ) = makeAttribute( pos, ns, aname, ansk._2 );
+ k = k + 1;
+ }
+ attrs
+ }
+
+ var t = mkXML(pos,
+ false,
+ make.Ident(pos, Name.fromString(namespace)):Tree,
+ gen.mkStringLit(pos, newlabel):Tree,
+ attr:Array[Tree],
+ args:Array[Tree]);
+ if( !setNS.isEmpty ) {
+ val nsStms = new Array[Tree]( setNS.size );
+ var i = 0;
+ for( val Pair(ns:String, uri:Tree) <- setNS.toList ) {
+ nsStms( i ) = setNamespacePrefix(pos, ns, uri );
+ i = i + 1;
+ }
+ make.Block( pos, nsStms, t )
+ } else
+ t
+ }
+
+ def setNamespacePrefix(pos:Int, pref:String, uri:Tree) =
+ make.ValDef(pos, 0, Name.fromString("namespace$"+pref), Tree.Empty, uri);
+
+
+}
+}
diff --git a/sources/scala/xml/Attribute.scala b/sources/scala/xml/Attribute.scala
new file mode 100644
index 0000000000..92eeedf93c
--- /dev/null
+++ b/sources/scala/xml/Attribute.scala
@@ -0,0 +1,29 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala.xml ;
+
+/** An XML attribute
+ *
+ * @todo allow for attributes that are not strings
+ *
+ * @param namespace$$ the namespace URI
+ * @param key$$ the local attribute name
+ * @author Burak Emir
+ */
+case class Attribute(namespace:String, key:String, value:String) with Ordered[Attribute] {
+
+ def compareTo [b >: Attribute <% Ordered[b]](that: b): int = that match {
+ case z:Attribute =>
+ val i = key.compareTo( z.key );
+ if( i != 0 ) i else namespace.compareTo( z.namespace )
+ case _ => -(that.compareTo(this));
+ }
+
+}
diff --git a/sources/scala/xml/AttributeSeq.scala b/sources/scala/xml/AttributeSeq.scala
new file mode 100644
index 0000000000..90d535cc96
--- /dev/null
+++ b/sources/scala/xml/AttributeSeq.scala
@@ -0,0 +1,69 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala.xml ;
+
+import scala.collection.mutable.HashMap ;
+import scala.collection.immutable.TreeSet ;
+
+object AttributeSeq {
+ final val Empty = new AttributeSeq();
+
+ final def fromHashMap(as:HashMap[Pair[String,String],String]) = {
+ new AttributeSeq( {
+ for( val a <- as.keys.toList )
+ yield Attribute(a._1,a._2, as(a))
+ }:_* )
+ }
+}
+
+/** Sorted linear list of XML attributes.
+ * An attribute seq does *not* contain namespace defining attributes
+ * like xmlns or xmlns:pref
+ * @author Burak Emir
+ */
+class AttributeSeq( as:Attribute* ) with Seq[Attribute] {
+
+ private var treeSet:TreeSet[Attribute] = new TreeSet[Attribute];
+
+ for( val a <- as ) {
+ if( a.key != "xmlns" ) {
+ treeSet = treeSet + a ;
+ }
+ }
+ final def length = treeSet.size;
+ final def elements = treeSet.elements;
+ final def apply(i:Int) = treeSet.elements.drop(i).next;
+
+ def lookup(ns:String, key:String):Option[Attribute] = {
+ val it = treeSet.elements;
+ while( it.hasNext ) {
+ val a = it.next;
+ if( a.key > key ) return None
+ else if( a.key == key ) {
+ if( a.namespace > ns ) return None
+ else if( a.namespace == ns ) return Some(a)
+ }
+ }
+ return None;
+ }
+
+ /** Return a new AttributeSeq with updated or added attributes
+ *
+ * @param attrs
+ * @return a new symbol with updated attributes
+ */
+ final def %(attrs: Attribute*) =
+ new AttributeSeq((elements.toList ::: attrs.elements.toList):_*);
+
+ final def map(f: Attribute => Attribute): AttributeSeq = {
+ new AttributeSeq( elements.map( f ).toList:_* )
+ }
+}
+
diff --git a/sources/scala/xml/BindingFactoryAdapter.scala b/sources/scala/xml/BindingFactoryAdapter.scala
index 3c04e4fb49..7922a060ef 100644
--- a/sources/scala/xml/BindingFactoryAdapter.scala
+++ b/sources/scala/xml/BindingFactoryAdapter.scala
@@ -21,7 +21,7 @@ abstract class BindingFactoryAdapter extends FactoryAdapter() {
/** mapping from element names to an element constructor
* (constr:Seq[Node],HashMap[String,String] => Node)
*/
- val f: Map[ String, (HashMap[String,String],Seq[Node]) => Node ];
+ val f: Map[ String, (AttributeSeq,Seq[Node]) => Node ];
/** mapping from element names to a truth value indicating
* whether the corresponding element may have text children
@@ -41,16 +41,16 @@ abstract class BindingFactoryAdapter extends FactoryAdapter() {
/** creates an element. see also compress */
def createNode(uri:String,
elemName:String,
- attribs:HashMap[String,String],
+ attribs:HashMap[Pair[String,String],String],
children:List[Node] ):Node = {
val uri$ = uri.intern();
-
+ val attribs1 = AttributeSeq.fromHashMap(attribs);
// 2do:optimize
if( !compress ) {
// get constructor
val c = f( elemName );
- c( attribs, children );
+ c( attribs1, children );
} else { // do hash-consing
val ahc = attribs.toList.hashCode();
@@ -65,7 +65,7 @@ abstract class BindingFactoryAdapter extends FactoryAdapter() {
case None =>
// get constructor
val c = f( elemName );
- val el = c( attribs, children );
+ val el = c( attribs1, children );
cache.update( h, el );
el
}
diff --git a/sources/scala/xml/CharData.scala b/sources/scala/xml/CharData.scala
index 19e12d88f3..287bcdc390 100644
--- a/sources/scala/xml/CharData.scala
+++ b/sources/scala/xml/CharData.scala
@@ -16,7 +16,7 @@ import scala.collection.immutable ;
* @param text text contained in this node, may not contain &quot;]]&gt;&quot;
**/
-case class CharData( text:String ) extends Node {
+case class CharData( text:String ) extends SpecialNode {
final override def typeTag$:Int = -4;
@@ -27,15 +27,6 @@ case class CharData( text:String ) extends Node {
*/
def label = "#CDATA";
- /** always Node.EmptyNamespace */
- final def namespace = Node.EmptyNamespace;
-
- /** always empty */
- final def attribute = Node.NoAttributes;
-
- /** always empty */
- final def child = Nil;
-
/** returns &quot;&lt;![CDATA[&quot;+text+&quot;]]&gt;&quot; */
final override def toString() = "<![CDATA["+text+"]]>";
diff --git a/sources/scala/xml/Elem.scala b/sources/scala/xml/Elem.scala
index 074f76d503..4150eb922d 100644
--- a/sources/scala/xml/Elem.scala
+++ b/sources/scala/xml/Elem.scala
@@ -9,7 +9,7 @@
package scala.xml;
-import scala.collection.immutable;
+import scala.collection.mutable.ArrayBuffer;
/** The case class <code>Elem</code> implements the Node trait,
* providing an immutable data object representing an XML element.
@@ -20,7 +20,7 @@ import scala.collection.immutable;
* @param child the children of this node
* @author Burak Emir
*/
-case class Elem( namespace$$:String, label$$: String, attribute:immutable.Map[String,String], child: Node*) extends Node {
+case class Elem( namespace$$:String, label$$: String, attributes: AttributeSeq, child: Node*) extends Node {
final val namespaceIntern = namespace$$.intern();
final def namespace = namespaceIntern;
@@ -41,15 +41,9 @@ case class Elem( namespace$$:String, label$$: String, attribute:immutable.Map[St
* @param attrs
* @return a new symbol with updated attributes
*/
- final def %(attrs: Seq[Pair[String, String]]): Elem = {
- var newmap = new immutable.TreeMap[String, String]();
- for ( val p <- attribute.elements ) {
- newmap = newmap.update( p._1, p._2 )
- }
- for ( val p <- attrs ) {
- newmap = newmap.update( p._1, p._2 )
- }
- Elem(namespace, label, newmap, child:_*)
+ final def %(attrs: Seq[Attribute]): Elem = {
+ val aseq = new AttributeSeq((attributes.toList ::: attrs.toList):_*);
+ Elem(namespace, label, aseq, child:_*)
}
/** Return a new symbol with updated attribute
@@ -57,13 +51,9 @@ case class Elem( namespace$$:String, label$$: String, attribute:immutable.Map[St
* @param attr
* @return a new symbol with updated attribute
*/
- final def %(attr: Pair[String, String]): Elem = {
- var newmap = new immutable.TreeMap[String, String]();
- for ( val p <- attribute.elements ) {
- newmap = newmap.update( p._1, p._2 )
- }
- newmap = newmap.update( attr._1, attr._2 );
- Elem(namespace, label, newmap, child:_*)
+ final def %(attr: Attribute): Elem = {
+ val aseq = new AttributeSeq((attributes.toList ::: attr :: Nil):_*);
+ Elem(namespace, label, aseq, child:_*)
}
}
diff --git a/sources/scala/xml/FactoryAdapter.scala b/sources/scala/xml/FactoryAdapter.scala
index b9f8fc3d6b..386b4b8841 100644
--- a/sources/scala/xml/FactoryAdapter.scala
+++ b/sources/scala/xml/FactoryAdapter.scala
@@ -37,7 +37,7 @@ import javax.xml.parsers.SAXParser;
abstract class FactoryAdapter extends DefaultHandler() {
val buffer = new StringBuffer();
- val attribStack = new Stack[HashMap[String,String]];
+ val attribStack = new Stack[HashMap[Pair[String,String],String]];
val hStack = new Stack[Node]; // [ element ] contains siblings
val tagStack = new Stack[String]; // [String]
@@ -59,7 +59,7 @@ abstract class FactoryAdapter extends DefaultHandler() {
*/
def createNode(uri:String,
elemName:String ,
- attribs:HashMap[String,String] ,
+ attribs:HashMap[Pair[String,String],String] ,
chIter:List[Node] ):Node; //abstract
/** creates a Text node.
@@ -127,21 +127,22 @@ abstract class FactoryAdapter extends DefaultHandler() {
capture = nodeContainsText(localName) ;
hStack.push( null );
- var map:HashMap[String,String] = null:HashMap[String,String];
+ var map:HashMap[Pair[String,String],String] = null:HashMap[Pair[String,String],String];
if (attributes == null) {
// may not happen
}
else {
- map = new HashMap[String,String];
+ map = new HashMap[Pair[String,String],String];
for( val i <- List.range( 0, attributes.getLength() )) {
+ val attrNS = attributes.getURI(i);
val attrLocalName = attributes.getLocalName(i);
val attrType = attributes.getType(i);
val attrValue = attributes.getValue(i);
// we only handle string attributes
if( attrType.equals("CDATA") ) {
- map.update( attrLocalName, attrValue );
+ map.update( Pair(attrNS,attrLocalName), attrValue );
}
}
}
diff --git a/sources/scala/xml/Namespace.scala b/sources/scala/xml/Namespace.scala
deleted file mode 100644
index 0643deb9b8..0000000000
--- a/sources/scala/xml/Namespace.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-package scala.xml ;
-
-/** an XML namespace URI */
-case class Namespace( uri:String ) {
- final val code = NamespaceRegistry.getCode( uri );
-}
diff --git a/sources/scala/xml/NamespaceRegistry.scala b/sources/scala/xml/NamespaceRegistry.scala
deleted file mode 100644
index 5b6ba348cd..0000000000
--- a/sources/scala/xml/NamespaceRegistry.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-package scala.xml ;
-
-import scala.collection.mutable.HashMap;
-import scala.collection.immutable.TreeMap;
-
-/** thread-safe storage of namespace URIs. */
-object NamespaceRegistry {
-
- final var next = 0;
- /* hashmap from namespaces to ints */
- final var nmap: HashMap[String, Int] = new HashMap();
- final var dmap: TreeMap[Int,String] = new TreeMap();
-
- private def newCode( uri:String ):Int = {
- val d = next;
- next = next + 1;
- nmap( uri ) = d;
- dmap( d ) = uri;
- d
- }
-
- /* returns a code for the argument namespace uri. Registers it if needed */
- def getCode(uri: String):Int = synchronized {
- val c = nmap.get( uri );
- if( c.isEmpty ) newCode( uri ) else c.get
- }
-
- def getNamespace( i:Int ):Namespace = synchronized {
- Namespace( dmap( i ) );
- }
-
- /* empty namespace has code 0 */
- getCode("");
-
-}
diff --git a/sources/scala/xml/Node.scala b/sources/scala/xml/Node.scala
index 0c129a314d..639c145122 100644
--- a/sources/scala/xml/Node.scala
+++ b/sources/scala/xml/Node.scala
@@ -14,9 +14,8 @@ import scala.collection.immutable ;
object Node {
- /** the constant empty attribute map */
- val NoAttributes: immutable.TreeMap[String,String] =
- immutable.TreeMap.Empty[String,String];
+ /** the constant empty attribute sequence */
+ final def NoAttributes: AttributeSeq = AttributeSeq.Empty;
/** the empty namespace */
val EmptyNamespace = "";
@@ -36,11 +35,26 @@ trait Node {
/** the namespace of this node */
def namespace: String;
- /** attribute axis */
- def attribute: Map[String,String] ;
+ /** attribute map for attributes with the same namespace as this element */
+ final def attribute: Map[String,String] = new Map[String, String] {
+ def size = attributes.length;
+ def elements =
+ attributes.elements
+ .filter( x => x.namespace == namespace )
+ .map( x => Pair(x.key, x.value) );
+ def get(x:String) = {
+ attributes.lookup( namespace, x ) match {
+ case Some( x ) => Some( x.value );
+ case _ => None
+ }
+ }
+ }
+ /** attribute axis - all attributes of this node, in order defined by attrib
+ */
+ def attributes: AttributeSeq;
/** child axis (all children of this node) */
- def child: Seq[Node];
+ def child: Seq[Node];
/** descendant axis (all descendants of this node) */
def descendant:List[Node] = child.toList.flatMap {
diff --git a/sources/scala/xml/PrettyPrinter.scala b/sources/scala/xml/PrettyPrinter.scala
index b6a6e4a525..d74751c4fd 100644
--- a/sources/scala/xml/PrettyPrinter.scala
+++ b/sources/scala/xml/PrettyPrinter.scala
@@ -31,17 +31,18 @@ class PrettyPrinter( width:Int, step:Int ) {
case class Box( col:Int, s:String ) extends Item;
case class Para( s:String ) extends Item;
- var items:List[Item] = Nil;
+ protected var items:List[Item] = Nil;
- var cur = 0;
+ protected var cur = 0;
+ protected var pmap:Map[String,String] = _;
- def reset() = {
+ protected def reset() = {
cur = 0;
items = Nil;
}
/* try to cut at whitespace */
- def cut( s:String, ind:Int ):List[Item] = {
+ protected def cut( s:String, ind:Int ):List[Item] = {
val tmp = width - cur;
if( s.length() < tmp )
return List(Box(ind,s));
@@ -67,7 +68,7 @@ class PrettyPrinter( width:Int, step:Int ) {
}
/** try to make indented box, if possible, else para */
- def makeBox( ind:Int, s:String ) = {
+ protected def makeBox( ind:Int, s:String ) = {
if( cur < ind )
cur == ind;
if( cur + s.length() > width ) { // fits in this line
@@ -82,44 +83,48 @@ class PrettyPrinter( width:Int, step:Int ) {
}
// dont respect indent in para, but afterwards
- def makePara( ind:Int, s:String ) = {
+ protected def makePara( ind:Int, s:String ) = {
items = Break::Para( s )::Break::items;
cur = ind;
}
// respect indent
- def makeBreak() = { // using wrapping here...
+ protected def makeBreak() = { // using wrapping here...
items = Break::items;
cur = 0;
}
- def leafTag( n:Node ) = {
+ protected def leafTag( n:Node ) = {
val sb = new StringBuffer("<");
- sb.append( n.label );
- Utility.attr2xml( n.attribute.elements, sb );
+ Utility.appendPrefixedName( n.namespace, n.label, pmap, sb );
+ Utility.attr2xml( n.attributes.elements, pmap, sb );
sb.append("/>");
sb.toString();
}
- def startTag( n:Node ) = {
+ protected def startTag(n: Node) = {
val sb = new StringBuffer("<");
- sb.append( n.label );
- Utility.attr2xml( n.attribute.elements, sb );
+ Utility.appendPrefixedName( n.namespace, n.label, pmap, sb );
+ Utility.attr2xml( n.attributes.elements, pmap, sb );
sb.append('>');
sb.toString();
}
- /* returns a formatted string containing well-formed XML
- **/
- def format( n:Node ):String = {
+ /** appends a formatted string containing well-formed XML with
+ * given namespace to prefix mapping to the given stringbuffer
+ * @param n the node to be serialized
+ * @param pmap the namespace to prefix mapping
+ * @param sb the stringbuffer to append to
+ */
+ def format(n: Node, pmap: Map[String,String], sb: StringBuffer ): Unit = {
reset();
+ this.pmap = pmap;
traverse( n, 0 );
- val sb = new StringBuffer();
var cur = 0;
//Console.println( items.reverse );
for( val b <- items.reverse ) b match {
case Break =>
- sb.append('\n'); // on windows: \r\n
+ sb.append('\n'); // on windows: \r\n ?
cur = 0;
case Box(i, s) =>
while( cur < i ) {
@@ -130,20 +135,9 @@ class PrettyPrinter( width:Int, step:Int ) {
case Para( s ) =>
sb.append( s );
}
- sb.toString();
- }
-
- /* returns a formatted string containing well-formed XML nodes.
- **/
- def format( ns:Seq[Node] ):String = {
- var sb2 = new StringBuffer();
- for( val n <- ns.elements ) {
- sb2.append( format( n ))
- }
- sb2.toString();
}
- def breakable( n:Node ):boolean = {
+ protected def breakable( n:Node ):boolean = {
val it = n.child.elements;
while( it.hasNext )
it.next match {
@@ -153,7 +147,7 @@ class PrettyPrinter( width:Int, step:Int ) {
return false
}
/** @param tail: what we'd like to sqeeze in */
- def traverse( node:Node, ind:int ):Unit = {
+ protected def traverse( node:Node, ind:int ):Unit = {
node match {
case _:Text | _:CharData | _:Comment | _:EntityRef | _:ProcInstr =>
@@ -191,11 +185,57 @@ class PrettyPrinter( width:Int, step:Int ) {
}
}
- def traverse( it:Iterator[Node], ind:int ):unit = {
+ protected def traverse( it:Iterator[Node], ind:int ):unit = {
for( val c <- it ) {
traverse( c, ind );
makeBreak();
}
}
+ // public convenience methods
+
+ /** returns a formatted string containing well-formed XML with
+ * default namespace prefix mapping
+ * @param n the node to be serialized
+ */
+ def format(n: Node): String = format(n, Utility.defaultPrefixes( n ));
+
+ /** returns a formatted string containing well-formed XML with
+ * given namespace to prefix mapping
+ * @param n the node to be serialized
+ * @param pmap the namespace to prefix mapping
+ */
+ def format(n: Node, pmap: Map[String,String]): String = {
+ val sb = new StringBuffer();
+ format( n, pmap, sb );
+ sb.toString();
+ }
+
+ /* returns a formatted string containing well-formed XML nodes with
+ * default namespace prefix mapping
+ */
+ def format( nodes:Seq[Node] ):String = {
+ format(nodes, Utility.defaultPrefixes( nodes ))
+ }
+
+ /** returns a formatted string containing well-formed XML
+ * @param nodes the sequence of nodes to be serialized
+ * @param pmap the namespace to prefix mapping
+ */
+ def format( nodes:Seq[Node], pmap:Map[String,String] ):String = {
+ var sb = new StringBuffer();
+ format( nodes, pmap, sb );
+ sb.toString();
+ }
+
+ /** appends a formatted string containing well-formed XML with
+ * the given namespace to prefix mapping to the given stringbuffer
+ * @param n the node to be serialized
+ * @param pmap the namespace to prefix mapping
+ * @param sb the string buffer to which to append to
+ */
+ def format( nodes: Seq[Node], pmap: Map[String,String], sb: StringBuffer ): Unit = { for( val n <- nodes.elements ) {
+ sb.append(format( n, pmap ))
+ }
+ }
}
diff --git a/sources/scala/xml/SpecialNode.scala b/sources/scala/xml/SpecialNode.scala
index ad3408641a..974ee4ddd9 100644
--- a/sources/scala/xml/SpecialNode.scala
+++ b/sources/scala/xml/SpecialNode.scala
@@ -18,7 +18,7 @@ abstract class SpecialNode extends Node {
final def namespace = Node.EmptyNamespace;
/** always empty */
- final def attribute = Node.NoAttributes;
+ final def attributes = Node.NoAttributes;
/** always empty */
final def child = Nil;
diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala
index 17555941d5..2687d32121 100644
--- a/sources/scala/xml/Utility.scala
+++ b/sources/scala/xml/Utility.scala
@@ -10,6 +10,8 @@
package scala.xml ;
import java.lang.StringBuffer ; /* Java dependency! */
+import scala.collection.mutable ;
+import scala.collection.immutable ;
import scala.collection.Map ;
/** Utility functions for processing instances of bound and not bound XML
@@ -35,40 +37,151 @@ object Utility {
s.toString();
}
+ /** returns a set of all namespaces appearing in a node and all its
+ * descendants, including the empty namespaces
+ */
+ def collectNamespaces(node: Node): mutable.Set[String] =
+ collectNamespaces(node, new mutable.HashSet[String]());
+
+ /** returns a set of all namespaces appearing in a sequence of nodes
+ * and all their descendants, including the empty namespaces
+ */
+ def collectNamespaces(nodes: Seq[Node]): mutable.Set[String] = {
+ var m = new mutable.HashSet[String]();
+ for(val n <- nodes)
+ collectNamespaces(n, m);
+ return m
+ }
+
+ private def collectNamespaces(node: Node, set: mutable.Set[String]): mutable.Set[String] = {
+ def collect( n:Node ):Unit = {
+ if( n.typeTag$ >= 0 ) {
+ set += n.namespace; /* namespaces are interned, so hashing is fast */
+ for( val a <- n.attributes )
+ set += a.namespace;
+ for( val i <- n.child )
+ collect(i);
+ }
+ }
+ collect(node);
+ return set;
+ }
+ /** a prefix mapping that maps the empty namespace to the empty prefix */
+ val noPrefixes:Map[String,String] =
+ immutable.ListMap.Empty[String,String].update("","");
+
+ /** returns a default prefix mapping for a set of namespaces.
+ * the empty namespace is mapped to the empty prefix
+ */
+ def defaultPrefixes(rootns:String,nset:mutable.Set[String]):Map[String,String] = {
+ val map = new mutable.HashMap[String,String]();
+ map.update( rootns, "" );
+ var i = 0;
+ for( val ns <- nset )
+ map.get( ns ) match {
+ case None => map.update( ns, "ns"+i );
+ case Some( _ ) =>
+ }
+
+ return map;
+ }
+
+ /** same as defaultPrefixes(n.namespace, collectNamespaces( n )) */
+ def defaultPrefixes( n:Node ):Map[String,String] =
+ defaultPrefixes(n.namespace, collectNamespaces( n ));
+
+ /** same as defaultPrefixes("", ncollectNamespaces( nodes )) */
+ def defaultPrefixes(nodes: Seq[Node]): Map[String,String] = {
+ defaultPrefixes("", collectNamespaces( nodes ));
+ }
+
+
/** serializes an instance of Node to a string that contains well-formed XML
* @todo define a way to escape literal characters to &amp;xx; references
*/
- def toXML( n:Node ):String = n match {
+ def toXML(n: Node): String = n match {
case Text( t ) =>
escape( t );
case _:EntityRef | _:Comment | _:ProcInstr =>
n.toString();
case _ =>
val s = new StringBuffer();
- toXML( n, s );
+ toXML( n, defaultPrefixes( n ), s );
s.toString();
}
- /** serializes an instance of Node to the given stringbuffer
+ /** serializes a node with given namespace prefix mapping
+ * @arg n the node to serialize
+ * @pmap a mapping from namespace URIs to prefixes
+ */
+ def toXML(n: Node, pmap:Map[String,String] ):String = n match {
+ case Text( t ) =>
+ escape( t );
+ case _:EntityRef | _:Comment | _:ProcInstr =>
+ n.toString();
+ case _ =>
+ val sb = new StringBuffer();
+ toXML( n, pmap, sb );
+ sb.toString();
+ }
+
+ /** serializes a tree to the given stringbuffer
+ ** with the given namespace prefix mapping
+ * @param n the root node
*/
- def toXML( n:Node, s:StringBuffer ):Unit = n match {
+ def toXML( n:Node, pmap:Map[String,String], sb:StringBuffer ):Unit = n match {
case Text( t ) =>
- s.append( escape( t ) );
+ sb.append( escape( t ) );
case _:EntityRef | _:Comment | _:ProcInstr =>
- s.append( n.toString() );
+ sb.append( n.toString() );
+ case x:Node =>
+ sb.append('<');
+ appendPrefixedName( x.namespace, x.label, pmap, sb );
+ if( x.attributes.length != 0 ) {
+ attr2xml( x.attributes.elements, pmap, sb )
+ }
+ if( (pmap.size != 1)||pmap.get("").isEmpty) {
+ for( val Pair(ns,pref) <- pmap.elements ) {
+ sb.append(' ');
+ sb.append("xmlns");
+ if( pref.length() > 0 ) sb.append(':');
+ sb.append(pref);
+ sb.append("=\"");
+ sb.append(ns);
+ sb.append('"')
+ }
+ }
+ sb.append('>');
+ for( val c <- x.child.elements ) {
+ toXML1( c, pmap, sb );
+ }
+ sb.append("</");
+ appendPrefixedName( x.namespace, x.label, pmap, sb );
+ sb.append('>');
+ }
+
+ /** serializes a tree to the given stringbuffer
+ ** with the given namespace prefix mapping
+ * @param n the root node
+ */
+ def toXML1( n:Node, pmap:Map[String,String], sb:StringBuffer ):Unit = n match {
+ case Text( t ) =>
+ sb.append( escape( t ) );
+ case _:EntityRef | _:Comment | _:ProcInstr =>
+ sb.append( n.toString() );
case x:Node => {
- s.append('<');
- s.append( x.label );
- if( x.attribute.size != 0 ) {
- attr2xml( x.attribute.elements, s )
+ sb.append('<');
+ appendPrefixedName( x.namespace, x.label, pmap, sb );
+ if( x.attributes.length != 0 ) {
+ attr2xml( x.attributes.elements, pmap, sb )
}
- s.append('>');
+ sb.append('>');
for( val c <- x.child.elements ) {
- toXML( c, s );
+ toXML1( c, pmap, sb );
}
- s.append("</");
- s.append( x.label );
- s.append('>');
+ sb.append("</");
+ appendPrefixedName( x.namespace, x.label, pmap, sb );
+ sb.append('>');
}
}
@@ -77,50 +190,67 @@ object Utility {
ch.foldLeft ("") { (s:String,n:Node) => s + n.toString() }
}
*/
-
/** for a Node n, returns string representation of n.attributes **/
- def attr2xml( attrib:Iterator[Pair[String, String]], sb:StringBuffer ):Unit = {
+ def attr2xml( attrib: Iterator[Attribute], pmap: Map[String, String], sb: StringBuffer ):Unit = {
for( val x <- attrib ) {
sb.append( " " );
- sb.append( x._1 );
+ appendPrefixedName( x.namespace, x.key, pmap, sb );
sb.append("=");
- val sep = { if( x._2.indexOf('"') != -1 ) '\'' else '"' };
- sb.append( sep );
- sb.append( x._2 );
- sb.append( sep );
+ appendQuoted(x.value, sb)
}
}
-
- /** for a Node n, returns string representation of n.attributes **/
- def attr2xml( attrib:Iterator[Pair[String, String]] ):String = {
- val t = new StringBuffer();
- attr2xml( attrib, t );
- t.toString();
- }
-
/** returns a hashcode for the given constituents of a node */
def hashCode(uri:String, label:String, attribHashCode:int, children:Seq[Node]) = {
41 * uri.hashCode() % 7 + label.hashCode() + attribHashCode + children.hashCode()
}
/** returns a hashcode for the given constituents of a node */
- def hashCode(uri:String, label:String, attribs:scala.collection.mutable.HashMap[String,String], children:Seq[Node]) = {
+ def hashCode(uri:String, label:String, attribs:scala.collection.mutable.HashMap[Pair[String,String],String], children:Seq[Node]) = {
41 * uri.hashCode() % 7 + label.hashCode() + attribs.toList.hashCode() + children.hashCode()
}
def systemLiteralToString( s:String ) = {
- val ch = {
- if( s.indexOf('"') != -1 ) '\'' else '"'
- }
- new StringBuffer("SYSTEM ").append(ch).append(s).append(ch).toString();
+ val sb = new StringBuffer("SYSTEM ");
+ appendQuoted(s, sb);
+ sb.toString();
}
def publicLiteralToString( s:String ) = {
- val ch = {
- if( s.indexOf('\'') != -1 ) '"' else '\''
+ val sb = new StringBuffer("PUBLIC ");
+ sb.append('"').append(s).append('"');
+ sb.toString();
+ }
+
+
+
+ def appendPrefixedName( ns: String, name: String, pmap: Map[String, String], sb: StringBuffer ):Unit = {
+ val pref = pmap( ns );
+ if( pref.length() > 0 ) {
+ sb.append( pref );
+ sb.append(':');
}
- new StringBuffer("PUBLIC ").append(ch).append(s).append(ch).toString();
+ sb.append( name );
}
+ /** appends &quot;s&quot; if s does not contain &quot;, &apos;s&apos;
+ * otherwise
+ */
+ def appendQuoted( s:String, sb:StringBuffer ):Unit = {
+ val ch = { if( s.indexOf('"') == -1 ) '"' else '\''}
+ sb.append(ch).append(s).append(ch);
+ }
+
+ /** appends &quot;s&quot; and escapes and &quot; i s with \&quot; */
+ def appendEscapedQuoted( s:String, sb:StringBuffer ):Unit = {
+ sb.append('"');
+ val z:Seq[Char] = s;
+ for( val c <- z ) c match {
+ case '"' => sb.append('\\'); sb.append('"');
+ case _ => sb.append( c );
+ }
+ sb.append('"');
+ }
+
+
}
diff --git a/sources/scala/xml/dtd/Decl.scala b/sources/scala/xml/dtd/Decl.scala
index 83a8c29b29..dd0a71f435 100644
--- a/sources/scala/xml/dtd/Decl.scala
+++ b/sources/scala/xml/dtd/Decl.scala
@@ -36,7 +36,22 @@ case class ElemDecl( name:String ,
};
/** an attribute declaration */
-case class AttrDecl( name:String, tpe:String, default:DefaultDecl ) extends MarkupDecl;
+case class AttrDecl( name:String, tpe:String, default:DefaultDecl ) extends MarkupDecl {
+ final override def toString() = {
+ val sb = new StringBuffer("AttrDecl(");
+ sb.append('"');
+ sb.append( name );
+ sb.append('"');
+ sb.append(',');
+ sb.append('"');
+ sb.append( tpe );
+ sb.append('"');
+ sb.append(',');
+ sb.append(default.toString());
+ sb.append(')');
+ sb.toString();
+ }
+}
/** an entity declaration */
case class EntityDecl( name:String, tpe:String ) extends MarkupDecl;
@@ -57,6 +72,19 @@ case class PEReference(ent:String) extends Decl {
class DefaultDecl ;
-case object REQUIRED, IMPLIED extends DefaultDecl;
-
-case class DEFAULT(fixed:boolean, attValue:String) extends DefaultDecl;
+case object REQUIRED extends DefaultDecl {
+ final override def toString() = "REQUIRED";
+}
+case object IMPLIED extends DefaultDecl {
+ final override def toString() = "IMPLIED";
+}
+case class DEFAULT(fixed:boolean, attValue:String) extends DefaultDecl {
+ final override def toString() = {
+ val sb = new StringBuffer("DEFAULT(");
+ sb.append( fixed );
+ sb.append(',');
+ Utility.appendEscapedQuoted( attValue, sb );
+ sb.append(')');
+ sb.toString()
+ }
+}
diff --git a/sources/scala/xml/dtd/Validation.scala b/sources/scala/xml/dtd/Validation.scala
new file mode 100644
index 0000000000..b9e9fbcaba
--- /dev/null
+++ b/sources/scala/xml/dtd/Validation.scala
@@ -0,0 +1,92 @@
+package scala.xml.dtd ;
+
+import scala.collection.mutable;
+import scala.collection.Set;
+import scala.collection.Map;
+
+class ValidationException( e:String ) extends Exception( e );
+
+object ValidationException {
+ def fromFixedAttribute( k: String, value: String, actual: String ) =
+ new ValidationException("value of attribute " + k + " FIXED to \""+value+"\", but document tries \""+actual+"\"");
+
+ def fromUndefinedAttribute( key:String ) =
+ new ValidationException("undefined attribute " + key );
+
+ def fromMissingAttribute( allKeys:Set[String] ) = {
+ new ValidationException("missing value for REQUIRED attribute"+
+ { if( allKeys.size > 1 ) "s" else "" }+
+ allKeys );
+ }
+}
+
+/** only CDATA attributes, ignores attributes that have different namespace
+* @param: attrSpec
+*/
+class AttributeValidator( namespace$$:String, attrSpec1: Seq[dtd.AttrDecl]) {
+ final val namespace = namespace$$.intern();
+ final val attrSpec = new mutable.HashMap[String,AttrDecl]();
+ var attribsTemplate:List[Attribute] = Nil;
+ for( val adecl <- attrSpec1 ) {
+ attrSpec.update( adecl.name, adecl )
+ }
+
+ var req = 0;
+ val map = new mutable.HashMap[String,String]();
+
+ // populate with special "<R" and default
+ for( val key <- attrSpec.keys ) {
+ attrSpec( key ).default match {
+ case dtd.REQUIRED =>
+ map.update( key, "<R" );
+ req = req + 1;
+ case dtd.DEFAULT( _, attValue ) =>
+ map.update( key, attValue );
+ attribsTemplate =
+ add( attribsTemplate, Attribute(namespace, key, attValue));
+ case dtd.IMPLIED =>
+ }
+ }
+
+ def add(as:List[Attribute], x:Attribute):List[Attribute] = {
+ if( x.namespace.length() == 0 )
+ scala.xml.Attribute( namespace, x.key, x.value )::as;
+ else
+ x::as;
+ };
+
+ def validate( attributes:AttributeSeq ):AttributeSeq = {
+ var actualReq = 0;
+ var attribs: List[Attribute] = Nil;
+ for( val b <- attributes ) {
+ if( b.key == "xmlns" ) {} // this should not get even here
+ else if( b.namespace != namespace )
+ attribs = add( attribs, b);
+ else attrSpec.get( b.key ) match {
+ case Some( AttrDecl( key, tpe, df )) => df match {
+ case DEFAULT( true, attValue ) =>
+ if( b.value != attValue )
+ ValidationException.fromFixedAttribute( key, attValue, b.value );
+ else
+ add( attribs, b )
+ case REQUIRED =>
+ actualReq = actualReq + 1;
+ attribs = add( attribs, b )
+ case _ =>
+ attribs = add( attribs, b )
+ }
+ case _ =>
+ ValidationException.fromUndefinedAttribute( b.key )
+ }
+ }
+ if( req - actualReq > 0 ) {
+ var allKeys = new mutable.HashSet[String]();
+ for( val AttrDecl( key, _, REQUIRED ) <- attrSpec.values )
+ allKeys += key;
+ for( val a <- attribs )
+ allKeys -= a.key;
+ ValidationException.fromMissingAttribute( allKeys )
+ }
+ new AttributeSeq( (attribsTemplate:::attribs):_* )
+ }
+}
diff --git a/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala b/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
index cc5077ab1a..03afa193ad 100644
--- a/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
+++ b/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
@@ -32,19 +32,19 @@ class NoBindingFactoryAdapter extends FactoryAdapter {
*/
def createNode(uri:String,
label: String,
- attrs: mutable.HashMap[String,String],
+ attrs: mutable.HashMap[Pair[String,String],String],
children: List[Node] ):Elem = {
val uri$ = uri.intern();
val elHashCode = Utility.hashCode( uri$, label, attrs, children ) ;
- val attrMap = immutable.TreeMap.Empty[String,String] incl attrs;
+ val attrSeq = AttributeSeq.fromHashMap( attrs );
cache.get( elHashCode ).match{
case Some(cachedElem) =>
//System.err.println("[using cached elem +"+cachedElem.toXML+"!]"); //DEBUG
cachedElem
case None =>
- val el = Elem( uri$, label, attrMap, children:_* );
+ val el = Elem( uri$, label, attrSeq, children:_* );
cache.update( elHashCode, el );
el
}
diff --git a/sources/scalac/transformer/matching/BerrySethi.java b/sources/scalac/transformer/matching/BerrySethi.java
index a97552702a..9e9186e1f8 100644
--- a/sources/scalac/transformer/matching/BerrySethi.java
+++ b/sources/scalac/transformer/matching/BerrySethi.java
@@ -1,3 +1,5 @@
+/** $Id */
+
package scalac.transformer.matching ;
import scalac.Unit ;
@@ -365,16 +367,19 @@ class BerrySethi {
this.posMap.put( pat, i );
this.labelAt.put( i, label );
if( label != Label.DefaultLabel ) {
+ /*
if( this.labels.contains( label ) ) {
switch(label) {
case TreeLabel(Apply(_, Tree[] args)):
if( args.length > 0 ) {
- unit.error(pat.pos, "sorry, this version of scalac cannot handle this pattern correctly");
+ unit.warning(pat.pos, "if this pattern in nondeterminism, it will not compile correctly");
}
}
}
+ */
this.labels.add( label );
}
+
}
/** overriden in BindingBerrySethi
diff --git a/sources/scalac/transformer/matching/Label.java b/sources/scalac/transformer/matching/Label.java
index f03321cb22..30a105dec4 100644
--- a/sources/scalac/transformer/matching/Label.java
+++ b/sources/scalac/transformer/matching/Label.java
@@ -31,7 +31,7 @@ public class Label {
return lit.value.hashCode();
case TreeLabel( Tree pat ):
// if pat is an Apply, than this case can only be correctly
- // handled if it has no arguments...or there are no collisions
+ // handled there are no other similar Applys (nondeterminism)
return pat.type().hashCode();
case TypeLabel( Type type ):
return type.hashCode();
diff --git a/test/bin/scala-test b/test/bin/scala-test
index c548b57438..1735b0b158 100755
--- a/test/bin/scala-test
+++ b/test/bin/scala-test
@@ -145,6 +145,7 @@ test_xml() {
output="$OBJDIR"/`expr "$source" : "\(.*\)\\.scala"`-$KIND.obj;
dtdfile="`expr "$source" : "\(.*\)\\.scala"`.dtd";
xmlfile="`expr "$source" : "\(.*\)\\.scala"`.xml";
+ nsfile="`expr "$source" : "\(.*\)\\.scala"`.namespace";
objfile="$output/dtd.scala";
classpath="$output";
if $CYGWIN; then
@@ -155,7 +156,7 @@ test_xml() {
fi;
rm -rf "$output";
mkdir -p "$output" &&
- $DTD2SCALA -d "$os_output" "$dtdfile" dtd &&
+ $DTD2SCALA -d "$os_output" "$dtdfile" dtd `cat $nsfile` &&
$SOCOS -d "$os_output" $TEST_FLAGS $FLAGS "$objfile" "$source" &&
$SCALA -classpath "$classpath" Test "$xmlfile" &&
rm -rf "$output";
diff --git a/test/files/jvm/xmlLiterals.scala b/test/files/jvm/xmlLiterals.scala
index d908a49349..65abd50094 100644
--- a/test/files/jvm/xmlLiterals.scala
+++ b/test/files/jvm/xmlLiterals.scala
@@ -11,7 +11,7 @@ import scala.collection.immutable ;
object Test {
- val e = immutable.TreeMap.Empty[String,String];
+ val e = Node.NoAttributes;
/* a helper function to compare up to whitespace */
@@ -77,9 +77,9 @@ object Test {
Elem("","h1",e,Text("Hello World")),
Elem("","p",e,Text("Check the "),
Elem("","a", e,Text("scala"))
- % Pair("href","scala.epfl.ch"),
+ % (Attribute("","href","scala.epfl.ch")),
Text("page!"))
- ) % Pair("background","#FFFFFF")
+ ) % Attribute("", "background","#FFFFFF")
).toString()
));
diff --git a/test/files/jvm/xmlstuff.check b/test/files/jvm/xmlstuff.check
index b348451a28..397a8970d6 100644
--- a/test/files/jvm/xmlstuff.check
+++ b/test/files/jvm/xmlstuff.check
@@ -38,3 +38,12 @@ List(<book><title>Blabla</title></book>)
<phone where="work">+41 21 693 68 67</phone>
<phone where="mobile">+41 79 602 23 23</phone>
</result>
+patterns
+passed ok
+passed ok
+passed ok
+namespaces
+passed ok
+passed ok
+passed ok
+passed ok
diff --git a/test/files/jvm/xmlstuff.scala b/test/files/jvm/xmlstuff.scala
index 2617110372..f05548aa96 100644
--- a/test/files/jvm/xmlstuff.scala
+++ b/test/files/jvm/xmlstuff.scala
@@ -6,7 +6,7 @@ import scala.xml.{Node,NodeSeq,Elem,Text};
object Test with Application {
- val e = scala.collection.immutable.TreeMap.Empty[String,String];
+ val e = Node.NoAttributes;
/*
def eq( a:Seq[Node], b:Seq[Node] ):boolean = {
@@ -30,7 +30,7 @@ object Test with Application {
def label = "hello";
def namespace = "";
def child = List(Elem("","world",e));
- def attribute = e;
+ def attributes = e;
};
assertSameElements( List( 3 ), List( 3 ));
@@ -274,5 +274,53 @@ val addrBook =
</result>
));
+ /* patterns */
+ Console.println("patterns");
+ assertEquals(<hello/> match { case <hello/> => true; case _ => false; },
+ true);
+
+ assertEquals(
+ <hello foo="bar">
+ <world/>
+ </hello> match { case <hello>
+ <world/>
+ </hello> => true;
+ case _ => false; },
+ true);
+
+ assertEquals(
+ <hello foo="bar">
+ crazy text world
+ </hello> match { case <hello>
+ crazy text world
+ </hello> => true;
+ case _ => false; },
+ true);
+
+ /* namespaces */
+ Console.println("namespaces");
+ val cuckoo = <cuckoo xmlns="http://cuckoo.com">
+ <foo/>
+ <bar/>
+ </cuckoo>;
+ assertEquals( cuckoo.namespace, "http://cuckoo.com");
+ for( val n <- cuckoo.child ) {
+ assertEquals( n.namespace, "http://cuckoo.com");
+ }
+
+ /*
+ assertEquals( true, cuckoo match {
+ case <cuckoo xmlns="http://cuckoo.com">
+ <foo/>
+ <bar/>
+ </cuckoo> => true;
+ case _ => false; });
+*/
+ assertEquals( false, cuckoo match {
+ case <cuckoo>
+ <foo/>
+ <bar/>
+ </cuckoo> => true;
+ case _ => false; });
}
diff --git a/test/files/xml/lnk.check b/test/files/xml/lnk.check
index f9f959fd5a..e7dca84cc8 100644
--- a/test/files/xml/lnk.check
+++ b/test/files/xml/lnk.check
@@ -1,5 +1,5 @@
-<link target="http://www.scala.org"><name>hello-link</name></link>
-<lnkDB><linkgroup><groupname>LDAP Links</groupname><link target="http://www.openldap.org/doc/"><name>OpenLDAP Administration Guide</name><description>contains very readable section &quot;What is LDAP&quot;</description></link><linkgroup><groupname>LDAP RFCs</groupname><link target="ftp://ftp.isi.edu/in-notes/rfc2251.txt"><name>RFC2251 Lightweight Directory Access Protocol (v3)</name></link><link target="ftp://ftp.isi.edu/in-notes/rfc2252.txt"><name>Lightweight Directory Access Protocol (v3):
+<link target="http://www.scala.org" xmlns="http://scala.epfl.ch/testSuite/links"><name>hello-link</name></link>
+<lnkDB xmlns="http://scala.epfl.ch/testSuite/links"><linkgroup><groupname>LDAP Links</groupname><link target="http://www.openldap.org/doc/"><name>OpenLDAP Administration Guide</name><description>contains very readable section &quot;What is LDAP&quot;</description></link><linkgroup><groupname>LDAP RFCs</groupname><link target="ftp://ftp.isi.edu/in-notes/rfc2251.txt"><name>RFC2251 Lightweight Directory Access Protocol (v3)</name></link><link target="ftp://ftp.isi.edu/in-notes/rfc2252.txt"><name>Lightweight Directory Access Protocol (v3):
Attribute Syntax Definitions</name></link><link target="ftp://ftp.isi.edu/in-notes/rfc2253.txt"><name>Lightweight Directory Access Protocol (v3):
UTF-8 String Representation of Distinguished Names
</name></link><link target="ftp://ftp.isi.edu/in-notes/rfc2254.txt"><name>The String Representation of LDAP Search Filters</name></link></linkgroup><linkgroup><groupname>LDAP and Lotus Notes</groupname><link target="http://www.shmoo.com/mail/fw1/jul99/msg00040.html"><name>LDAP enabled on Notes... to change settings</name></link><link target="http://www.openldap.org/lists/openldap-general/200103/msg00004.html"><name>Replicating Notes data to OpenLDAP</name></link></linkgroup></linkgroup></lnkDB>
diff --git a/test/files/xml/lnk.namespace b/test/files/xml/lnk.namespace
new file mode 100644
index 0000000000..5d787d9564
--- /dev/null
+++ b/test/files/xml/lnk.namespace
@@ -0,0 +1 @@
+http://scala.epfl.ch/testSuite/links \ No newline at end of file
diff --git a/test/files/xml/lnk.scala b/test/files/xml/lnk.scala
index 962c2f9149..8d81eae609 100644
--- a/test/files/xml/lnk.scala
+++ b/test/files/xml/lnk.scala
@@ -1,6 +1,6 @@
// $Id$
-import scala.xml.Node;
+import scala.xml.{Attribute, AttributeSeq, Node};
import dtd._;
object Test {
@@ -14,7 +14,12 @@ object Test {
// !!! System.out.println(b.toXML);
// construct data using constructor
- val c = Link(n + "target" -> "http://www.scala.org", Name(n, scala.xml.Text("hello-link")));
+ val c = Link(
+ new AttributeSeq(
+ Attribute("","target","http://www.scala.org")
+ ),
+ Name(n, scala.xml.Text("hello-link"))
+ );
//c.getAttribs.update("target", "http://www.scala.org");
System.out.println( c );
diff --git a/test/files/xml/xhtml.check b/test/files/xml/xhtml.check
index 50186a8428..1cb0cbf6b4 100644
--- a/test/files/xml/xhtml.check
+++ b/test/files/xml/xhtml.check
@@ -1,2 +1,2 @@
-<html version="-//W3C//DTD XHTML Basic 1.0//EN" xmlns="http://www.w3.org/1999/xhtml"><head profile="" xmlns="http://www.w3.org/1999/xhtml"><base href="http://here.edu" xmlns="http://www.w3.org/1999/xhtml"></base><title xmlns="http://www.w3.org/1999/xhtml">a basic xhtml page</title></head><body xmlns="http://www.w3.org/1999/xhtml"><h1 xmlns="http://www.w3.org/1999/xhtml">Welcome to xhtml in scala</h1><p xmlns="http://www.w3.org/1999/xhtml">a paragraph</p><p xmlns="http://www.w3.org/1999/xhtml">another one, with a <a href="http://lampwww.epfl.ch" xmlns="http://www.w3.org/1999/xhtml">link</a> to the LAMP homepage.</p></body></html>
-<html version="-//W3C//DTD XHTML Basic 1.0//EN" xmlns="http://www.w3.org/1999/xhtml"><head profile="" xmlns="http://www.w3.org/1999/xhtml"><base href="here.com" xmlns="http://www.w3.org/1999/xhtml"></base><title xmlns="http://www.w3.org/1999/xhtml">a basic xhtml page</title></head><body xmlns="http://www.w3.org/1999/xhtml"><h1 xmlns="http://www.w3.org/1999/xhtml">Welcome to xhtml in scala</h1><p xmlns="http://www.w3.org/1999/xhtml">a paragraph</p><p xmlns="http://www.w3.org/1999/xhtml">another, with a <a href="http://lampwww.epfl.ch" xmlns="http://www.w3.org/1999/xhtml">example link</a> to lamp homepage</p></body></html>
+<html version="-//W3C//DTD XHTML Basic 1.0//EN" xmlns="http://www.w3.org/1999/xhtml"><head profile=""><base href="http://here.edu"></base><title>a basic xhtml page</title></head><body><h1>Welcome to xhtml in scala</h1><p>a paragraph</p><p>another one, with a <a href="http://lampwww.epfl.ch">link</a> to the LAMP homepage.</p></body></html>
+<html version="-//W3C//DTD XHTML Basic 1.0//EN" xmlns="http://www.w3.org/1999/xhtml"><head profile=""><base href="here.com"></base><title>a basic xhtml page</title></head><body><h1>Welcome to xhtml in scala</h1><p>a paragraph</p><p>another, with a <a href="http://lampwww.epfl.ch">example link</a> to lamp homepage</p></body></html>
diff --git a/test/files/xml/xhtml.namespace b/test/files/xml/xhtml.namespace
new file mode 100644
index 0000000000..4685ae94e0
--- /dev/null
+++ b/test/files/xml/xhtml.namespace
@@ -0,0 +1 @@
+http://www.w3.org/1999/xhtml \ No newline at end of file
diff --git a/test/files/xml/xhtml.scala b/test/files/xml/xhtml.scala
index e1510456c7..07cf3a1a74 100644
--- a/test/files/xml/xhtml.scala
+++ b/test/files/xml/xhtml.scala
@@ -1,6 +1,6 @@
// $Id$
-import scala.xml.{Node,Text};
+import scala.xml.{Attribute, AttributeSeq, Node, Text};
import dtd._;
object Test {
@@ -8,8 +8,12 @@ object Test {
val n = Node.NoAttributes;
def main( argv:Array[String] ) = {
- val link = A( n + "href" -> "http://lampwww.epfl.ch",
- Text("link"));
+ val link = A(
+ new AttributeSeq(
+ Attribute("","href","http://lampwww.epfl.ch")
+ ),
+ Text("link")
+ );
//val m = new scala.collection.mutable.HashMap[String, String];
//m.put("href","http://lampwww.epfl.ch");
@@ -21,7 +25,10 @@ object Test {
P(n,Text("another one, with a "),link,Text(" to the LAMP homepage.")));
val page = Html(n,
Head(n,
- Base(n+"href" -> "http://here.edu"),
+ Base(
+ new AttributeSeq(
+ Attribute("","href","http://here.edu")
+ )),
Title(n,Text("a basic xhtml page"))),
body);
System.out.println( page ) ;