**** Merged r36954 from MCS ****
authorMartin Baulig <martin@novell.com>
Sat, 4 Dec 2004 23:29:44 +0000 (23:29 -0000)
committerMartin Baulig <martin@novell.com>
Sat, 4 Dec 2004 23:29:44 +0000 (23:29 -0000)
svn path=/trunk/mcs/; revision=37121

393 files changed:
ChangeLog
Makefile.am
configure.in
docs/ssapre.txt [new file with mode: 0644]
libgc/alpha_mach_dep.S
libgc/mkinstalldirs
mcs/build/ChangeLog
mcs/build/library.make
mcs/build/platforms/linux.make
mcs/build/profiles/basic.make
mcs/build/profiles/default.make
mcs/class/ChangeLog
mcs/class/Makefile
mcs/class/Managed.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/Makefile
mcs/class/Managed.Windows.Forms/SWF.csproj
mcs/class/Managed.Windows.Forms/System.Windows.Forms.dll.sources
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Application.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListBox.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListViewItem.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/OwnerDrawPropertyBag.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThreadExceptionDialog.cs [new file with mode: 0644]
mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeNode.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeNodeCollection.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeView.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms_test.dll.sources
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeNodeTest.cs
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs [new file with mode: 0644]
mcs/class/Mono.C5/Test/BasesTest.cs
mcs/class/Mono.C5/Test/ChangeLog
mcs/class/Mono.C5/Test/arrays/ArrayListTest.cs
mcs/class/Mono.C5/Test/arrays/HashedArrayListTest.cs
mcs/class/Mono.C5/Test/arrays/SortedArrayTests.cs
mcs/class/Mono.C5/Test/hashing/HashBagTests.cs
mcs/class/Mono.C5/Test/hashing/HashDictionaryTests.cs
mcs/class/Mono.C5/Test/hashing/HashTableTests.cs
mcs/class/Mono.C5/Test/linkedlists/HashedLinkedListTest.cs
mcs/class/Mono.C5/Test/linkedlists/LinkedListTest.cs
mcs/class/Mono.C5/Test/trees/Bag.cs
mcs/class/Mono.C5/Test/trees/RedBlackTreeSetTests.cs
mcs/class/Mono.Security/Mono.Math/BigInteger.cs
mcs/class/Mono.Security/Mono.Math/ChangeLog
mcs/class/Mono.Security/Test/Mono.Math/BigIntegerTest.cs
mcs/class/Mono.Security/Test/Mono.Math/ChangeLog
mcs/class/PEAPI/ChangeLog
mcs/class/PEAPI/PEAPI.cs
mcs/class/System.Data/System.Data.Odbc/ChangeLog
mcs/class/System.Data/System.Data.Odbc/OdbcParameter.cs
mcs/class/System.Web.Services/System.Web.Services.Protocols/ChangeLog
mcs/class/System.Web.Services/System.Web.Services.Protocols/SoapHttpClientProtocol.cs
mcs/class/System.Web/ChangeLog
mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog
mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/MenuEventArgs.cs
mcs/class/System.Web/System.Web.UI.WebControls/MenuItem.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/MenuItemBinding.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/MenuItemBindingCollection.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/MenuItemCollection.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/MenuItemStyle.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/MenuItemStyleCollection.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.UI.WebControls/TreeView.cs
mcs/class/System.Web/System.Web.dll.sources
mcs/class/System.XML/ChangeLog
mcs/class/System.XML/Makefile
mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs [new file with mode: 0755]
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs [new file with mode: 0755]
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter2.cs [new file with mode: 0755]
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator2.cs [new file with mode: 0755]
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode2.cs [new file with mode: 0755]
mcs/class/System.XML/System.Xml.Schema/ChangeLog
mcs/class/System.XML/System.Xml.Schema/XmlSchema.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAll.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttribute.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaAttributeGroup.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaChoice.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContent.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContentExtension.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexContentRestriction.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaComplexType.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaElement.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaException.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaGroup.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaIdentityConstraint.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaInferenceException.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaObject.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSequence.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContent.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContentExtension.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleContentRestriction.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleType.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeList.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeRestriction.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaSimpleTypeUnion.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaValidationException.cs
mcs/class/System.XML/System.Xml.XPath/ChangeLog
mcs/class/System.XML/System.Xml.XPath/XPathDocument.cs
mcs/class/System.XML/System.Xml.dll.sources
mcs/class/System.XML/System.Xml/ChangeLog
mcs/class/System.XML/System.Xml/XmlInputStream.cs
mcs/class/System.XML/System.Xml/XmlTextReader.cs
mcs/class/System.XML/Test/System.Xml.Xsl/standalone_tests/ChangeLog
mcs/class/System.XML/Test/System.Xml.Xsl/standalone_tests/Makefile
mcs/class/System.XML/Test/System.Xml.Xsl/standalone_tests/README
mcs/class/System.XML/Test/System.Xml.Xsl/standalone_tests/xslttest.cs
mcs/class/System/ChangeLog
mcs/class/System/System.IO.Compression/ChangeLog
mcs/class/System/System.IO.Compression/CompressionMode.cs
mcs/class/System/System.IO.Compression/DeflateStream.cs
mcs/class/System/System.IO.Compression/GzipStream.cs
mcs/class/System/System.IO/KeventWatcher.cs
mcs/class/System/System.IO/SearchPattern.cs
mcs/class/System/System.Net.Sockets/ChangeLog
mcs/class/System/System.Net.Sockets/NetworkStream.cs
mcs/class/System/System.Net/ChangeLog
mcs/class/System/System.Net/ChunkStream.cs
mcs/class/System/System.Net/HttpWebRequest.cs
mcs/class/System/System.Net/WebConnection.cs
mcs/class/System/System.Net/WebConnectionGroup.cs
mcs/class/System/System.Net/WebConnectionStream.cs
mcs/class/System/Test/ChangeLog
mcs/class/System/Test/Microsoft.VisualBasic/ChangeLog
mcs/class/System/Test/Microsoft.VisualBasic/VBCodeProviderTest.cs
mcs/class/System/Test/System.IO.Compression/DeflateStreamTest.cs
mcs/class/System/Test/System.IO.Compression/GzipStreamTest.cs
mcs/class/corlib/Mono.Math/BigInteger.cs
mcs/class/corlib/Mono.Math/ChangeLog
mcs/errors/ChangeLog
mcs/errors/Makefile
mcs/errors/cs0122-7.cs [new file with mode: 0644]
mcs/errors/cs0122-8.cs [new file with mode: 0644]
mcs/errors/cs1570-10.cs [new file with mode: 0755]
mcs/errors/cs1570-11.cs [new file with mode: 0755]
mcs/errors/cs1570-2.cs [new file with mode: 0755]
mcs/errors/cs1570-3.cs [new file with mode: 0755]
mcs/errors/cs1570-4.cs [new file with mode: 0755]
mcs/errors/cs1570-5.cs [new file with mode: 0755]
mcs/errors/cs1570-6.cs [new file with mode: 0755]
mcs/errors/cs1570-7.cs [new file with mode: 0755]
mcs/errors/cs1570-8.cs [new file with mode: 0755]
mcs/errors/cs1570-9.cs [new file with mode: 0755]
mcs/errors/cs1570.cs [new file with mode: 0755]
mcs/errors/cs1571.cs [new file with mode: 0755]
mcs/errors/cs1572.cs [new file with mode: 0755]
mcs/errors/cs1573.cs [new file with mode: 0755]
mcs/errors/cs1574-2.cs [new file with mode: 0755]
mcs/errors/cs1574-3.cs [new file with mode: 0755]
mcs/errors/cs1574-4.cs [new file with mode: 0755]
mcs/errors/cs1574-5.cs [new file with mode: 0755]
mcs/errors/cs1574.cs [new file with mode: 0755]
mcs/errors/cs1580-2.cs [new file with mode: 0755]
mcs/errors/cs1580.cs [new file with mode: 0755]
mcs/errors/cs1581-2.cs [new file with mode: 0755]
mcs/errors/cs1581.cs [new file with mode: 0755]
mcs/errors/cs1584-2.cs [new file with mode: 0755]
mcs/errors/cs1584-3.cs [new file with mode: 0755]
mcs/errors/cs1584-4.cs [new file with mode: 0755]
mcs/errors/cs1584.cs [new file with mode: 0755]
mcs/errors/cs1587-10.cs [new file with mode: 0755]
mcs/errors/cs1587-11.cs [new file with mode: 0755]
mcs/errors/cs1587-12.cs [new file with mode: 0755]
mcs/errors/cs1587-13.cs [new file with mode: 0755]
mcs/errors/cs1587-14.cs [new file with mode: 0755]
mcs/errors/cs1587-15.cs [new file with mode: 0755]
mcs/errors/cs1587-16.cs [new file with mode: 0755]
mcs/errors/cs1587-17.cs [new file with mode: 0755]
mcs/errors/cs1587-18.cs [new file with mode: 0755]
mcs/errors/cs1587-19.cs [new file with mode: 0755]
mcs/errors/cs1587-2.cs [new file with mode: 0755]
mcs/errors/cs1587-20.cs [new file with mode: 0755]
mcs/errors/cs1587-21.cs [new file with mode: 0755]
mcs/errors/cs1587-22.cs [new file with mode: 0755]
mcs/errors/cs1587-23.cs [new file with mode: 0755]
mcs/errors/cs1587-24.cs [new file with mode: 0755]
mcs/errors/cs1587-25.cs [new file with mode: 0755]
mcs/errors/cs1587-26.cs [new file with mode: 0755]
mcs/errors/cs1587-27.cs [new file with mode: 0755]
mcs/errors/cs1587-28.cs [new file with mode: 0755]
mcs/errors/cs1587-3.cs [new file with mode: 0755]
mcs/errors/cs1587-4.cs [new file with mode: 0755]
mcs/errors/cs1587-5.cs [new file with mode: 0755]
mcs/errors/cs1587-6.cs [new file with mode: 0755]
mcs/errors/cs1587-7.cs [new file with mode: 0755]
mcs/errors/cs1587-8.cs [new file with mode: 0755]
mcs/errors/cs1587-9.cs [new file with mode: 0755]
mcs/errors/cs1587.cs [new file with mode: 0755]
mcs/errors/cs1589.cs [new file with mode: 0755]
mcs/errors/cs1589.inc [new file with mode: 0755]
mcs/errors/cs1590-2.cs [new file with mode: 0755]
mcs/errors/cs1590-3.cs [new file with mode: 0755]
mcs/errors/cs1590.cs [new file with mode: 0755]
mcs/errors/cs1591-10.cs [new file with mode: 0755]
mcs/errors/cs1591-11.cs [new file with mode: 0755]
mcs/errors/cs1591-12.cs [new file with mode: 0755]
mcs/errors/cs1591-13.cs [new file with mode: 0755]
mcs/errors/cs1591-14.cs [new file with mode: 0755]
mcs/errors/cs1591-15.cs [new file with mode: 0755]
mcs/errors/cs1591-16.cs [new file with mode: 0755]
mcs/errors/cs1591-17.cs [new file with mode: 0755]
mcs/errors/cs1591-18.cs [new file with mode: 0755]
mcs/errors/cs1591-2.cs [new file with mode: 0755]
mcs/errors/cs1591-3.cs [new file with mode: 0755]
mcs/errors/cs1591-4.cs [new file with mode: 0755]
mcs/errors/cs1591-5.cs [new file with mode: 0755]
mcs/errors/cs1591-6.cs [new file with mode: 0755]
mcs/errors/cs1591-7.cs [new file with mode: 0755]
mcs/errors/cs1591-8.cs [new file with mode: 0755]
mcs/errors/cs1591-9.cs [new file with mode: 0755]
mcs/errors/cs1591.cs [new file with mode: 0755]
mcs/errors/cs1592.cs [new file with mode: 0755]
mcs/errors/generics-expect-wrong-error
mcs/errors/gmcs-expect-no-error
mcs/errors/gmcs-expect-wrong-error
mcs/gmcs/ChangeLog
mcs/gmcs/assign.cs
mcs/gmcs/attribute.cs
mcs/gmcs/cfold.cs
mcs/gmcs/class.cs
mcs/gmcs/codegen.cs
mcs/gmcs/const.cs
mcs/gmcs/constant.cs
mcs/gmcs/convert.cs
mcs/gmcs/cs-parser.jay
mcs/gmcs/cs-tokenizer.cs
mcs/gmcs/decl.cs
mcs/gmcs/delegate.cs
mcs/gmcs/doc.cs [new file with mode: 0755]
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/enum.cs
mcs/gmcs/expression.cs
mcs/gmcs/pending.cs
mcs/gmcs/report.cs
mcs/gmcs/rootcontext.cs
mcs/gmcs/statement.cs
mcs/gmcs/typemanager.cs
mcs/ilasm/ChangeLog
mcs/ilasm/codegen/ChangeLog
mcs/ilasm/codegen/CodeGen.cs
mcs/ilasm/codegen/ExternTypeRefInst.cs
mcs/ilasm/codegen/FieldDef.cs
mcs/ilasm/codegen/MethodDef.cs
mcs/ilasm/codegen/TypeDef.cs
mcs/ilasm/parser/ChangeLog
mcs/ilasm/parser/ILParser.jay
mcs/ilasm/scanner/ChangeLog
mcs/ilasm/scanner/ILTables.cs
mcs/mcs/ChangeLog
mcs/mcs/assign.cs
mcs/mcs/attribute.cs
mcs/mcs/class.cs
mcs/mcs/convert.cs
mcs/mcs/cs-tokenizer.cs
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/doc-bootstrap.cs [new file with mode: 0644]
mcs/mcs/doc.cs
mcs/mcs/driver.cs
mcs/mcs/ecore.cs
mcs/mcs/enum.cs
mcs/mcs/expression.cs
mcs/mcs/mcs.exe.sources
mcs/mcs/namespace.cs
mcs/mcs/report.cs
mcs/mcs/rootcontext.cs
mcs/mcs/support.cs
mcs/nunit20/util/ChangeLog
mcs/nunit20/util/XmlResultVisitor.cs
mcs/tests/ChangeLog
mcs/tests/Makefile
mcs/tests/covariance-1.cs [new file with mode: 0644]
mcs/tests/covariance-2.cs [new file with mode: 0644]
mcs/tests/covariance-3.cs [new file with mode: 0644]
mcs/tests/gen-113.cs [new file with mode: 0644]
mcs/tests/gen-114.cs [new file with mode: 0644]
mcs/tests/gen-115.cs [new file with mode: 0644]
mcs/tests/gen-116.cs [new file with mode: 0644]
mcs/tests/harness.mk
mcs/tests/test-324.cs [new file with mode: 0644]
mcs/tests/test-325.cs [new file with mode: 0644]
mcs/tests/test-326.cs [new file with mode: 0644]
mcs/tests/test-327.cs [new file with mode: 0644]
mcs/tests/test-328.cs [new file with mode: 0644]
mcs/tests/xml-001-ref.xml [new file with mode: 0755]
mcs/tests/xml-001.cs [new file with mode: 0755]
mcs/tests/xml-002-ref.xml [new file with mode: 0755]
mcs/tests/xml-002.cs [new file with mode: 0755]
mcs/tests/xml-003-ref.xml [new file with mode: 0755]
mcs/tests/xml-003.cs [new file with mode: 0755]
mcs/tests/xml-004-ref.xml [new file with mode: 0755]
mcs/tests/xml-004.cs [new file with mode: 0755]
mcs/tests/xml-005-ref.xml [new file with mode: 0755]
mcs/tests/xml-005.cs [new file with mode: 0755]
mcs/tests/xml-006-ref.xml [new file with mode: 0755]
mcs/tests/xml-006.cs [new file with mode: 0755]
mcs/tests/xml-007-ref.xml [new file with mode: 0755]
mcs/tests/xml-007.cs [new file with mode: 0755]
mcs/tests/xml-008-ref.xml [new file with mode: 0755]
mcs/tests/xml-008.cs [new file with mode: 0755]
mcs/tests/xml-009-ref.xml [new file with mode: 0755]
mcs/tests/xml-009.cs [new file with mode: 0755]
mcs/tests/xml-010-ref.xml [new file with mode: 0755]
mcs/tests/xml-010.cs [new file with mode: 0755]
mcs/tests/xml-011-ref.xml [new file with mode: 0755]
mcs/tests/xml-011.cs [new file with mode: 0755]
mcs/tests/xml-012-ref.xml [new file with mode: 0755]
mcs/tests/xml-012.cs [new file with mode: 0755]
mcs/tests/xml-013-ref.xml [new file with mode: 0755]
mcs/tests/xml-013.cs [new file with mode: 0755]
mcs/tests/xml-014-ref.xml [new file with mode: 0755]
mcs/tests/xml-014.cs [new file with mode: 0755]
mcs/tests/xml-015-ref.xml [new file with mode: 0755]
mcs/tests/xml-015.cs [new file with mode: 0755]
mcs/tests/xml-016-ref.xml [new file with mode: 0755]
mcs/tests/xml-016.cs [new file with mode: 0755]
mcs/tests/xml-017-ref.xml [new file with mode: 0755]
mcs/tests/xml-017.cs [new file with mode: 0755]
mcs/tests/xml-018-ref.xml [new file with mode: 0755]
mcs/tests/xml-018.cs [new file with mode: 0755]
mcs/tests/xml-019-ref.xml [new file with mode: 0755]
mcs/tests/xml-019.cs [new file with mode: 0755]
mcs/tests/xml-020-ref.xml [new file with mode: 0755]
mcs/tests/xml-020.cs [new file with mode: 0755]
mcs/tests/xml-021-ref.xml [new file with mode: 0755]
mcs/tests/xml-021.cs [new file with mode: 0755]
mcs/tests/xml-022-ref.xml [new file with mode: 0755]
mcs/tests/xml-022.cs [new file with mode: 0755]
mcs/tests/xml-023-ref.xml [new file with mode: 0755]
mcs/tests/xml-023.cs [new file with mode: 0755]
mcs/tests/xml-024-ref.xml [new file with mode: 0755]
mcs/tests/xml-024.cs [new file with mode: 0755]
mcs/tests/xml-025-ref.xml [new file with mode: 0755]
mcs/tests/xml-025.cs [new file with mode: 0755]
mcs/tests/xml-025.inc [new file with mode: 0755]
mcs/tests/xml-026-ref.xml [new file with mode: 0755]
mcs/tests/xml-026.cs [new file with mode: 0755]
mcs/tests/xml-027-ref.xml [new file with mode: 0755]
mcs/tests/xml-027.cs [new file with mode: 0755]
mcs/tests/xml-028-ref.xml [new file with mode: 0755]
mcs/tests/xml-028.cs [new file with mode: 0644]
mcs/tests/xml-029-ref.xml [new file with mode: 0755]
mcs/tests/xml-029.cs [new file with mode: 0644]
mcs/tests/xml-030-ref.xml [new file with mode: 0755]
mcs/tests/xml-030.cs [new file with mode: 0644]
mcs/tests/xml-031-ref.xml [new file with mode: 0755]
mcs/tests/xml-031.cs [new file with mode: 0644]
mcs/tests/xml-032-ref.xml [new file with mode: 0755]
mcs/tests/xml-032.cs [new file with mode: 0644]
mcs/tests/xmldocdiff.cs [new file with mode: 0755]
mcs/tools/monop/ChangeLog
mcs/tools/monop/monop.cs
mono/Makefile.am
mono/cil/make-opcode-def.xsl
mono/dis/ChangeLog
mono/dis/get.c
mono/dis/main.c
mono/interpreter/ChangeLog
mono/interpreter/interp.c
mono/interpreter/mintops.def
mono/interpreter/transform.c
mono/metadata/ChangeLog
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/debug-helpers.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/marshal.c
mono/metadata/marshal.h
mono/metadata/metadata-internals.h
mono/metadata/metadata.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/reflection.c
mono/mini/ChangeLog
mono/mini/Makefile.am
mono/mini/driver.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/ssa.c
mono/mini/ssapre.c [new file with mode: 0644]
mono/mini/ssapre.h [new file with mode: 0644]
mono/tests/ChangeLog
mono/tests/ackermann.cs
mono/tests/appdomain-unload.cs
mono/tests/delegate.cs
mono/tests/sieve.cs
runtime/Makefile.am
web/devel-faq

index 4338328cd479d121a6304fbcab15f744a400397e..e64dbf421c6b2df87fc47965b72a5196161022f5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * configure.in (ENABLE_NUNIT_TESTS): New.
+       * runtime/Makefile.am (check-local): Use it to disable nunit
+       tests.  Ensure that the test dlls are always built, however.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile.am (dist-hook): Ensure we use the 'default' profile.
+       * mono/Makefile.am (HANDLES): New.  Disable 'handles' dir on Win32.
+       (SUBDIRS): Use it.  Move 'cil' before 'metadata'.
+       * runtime/Makefile.am (install-exec): Pass
+       RUNTIME_HAS_CONSISTENT_GACDIR to the mcs/ build.
+
 2004-12-01  Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
 
        * configure.in : Add a flag for systems which pass parameters in
index 68155a883872ee0211342b060cda0225e7885161..164f178132fead3dd4c10297511f4d84fb2d99a1 100644 (file)
@@ -12,7 +12,7 @@ EXTRA_DIST= mono.pc.in mono.spec.in mint.pc.in
 # Distribute the 'mcs' tree too
 dist-hook:
        test -d $(distdir)/mcs || mkdir $(distdir)/mcs
-       d=`cd $(distdir)/mcs && pwd`; cd $(mcs_topdir) && $(MAKE) distdir=$$d dist-recursive
+       d=`cd $(distdir)/mcs && pwd`; cd $(mcs_topdir) && $(MAKE) PROFILE=default distdir=$$d dist-recursive
 
 pkgconfigdir = $(libdir)/pkgconfig
 if JIT_SUPPORTED
index ea8bb4dbacafa190ccd95c0bc2f7f8d7acf02a0f..36c54bde6bf5bb922c335613c4295edf95146c49 100644 (file)
@@ -1232,6 +1232,9 @@ fi
 AC_SUBST(ICU_CFLAGS)
 AC_SUBST(ICU_LIBS)
 
+AC_ARG_ENABLE(nunit-tests, [ --enable-nunit-tests      Run the nunit tests of the class library on 'make check'])
+AM_CONDITIONAL(ENABLE_NUNIT_TESTS, [test x$enable_nunit_tests = xyes])
+
 TARGET="unknown"
 ACCESS_UNALIGNED="yes"
 
diff --git a/docs/ssapre.txt b/docs/ssapre.txt
new file mode 100644 (file)
index 0000000..ed1f1ba
--- /dev/null
@@ -0,0 +1,250 @@
+
+SSAPRE stands for "SSA based Partial Redundancy Elimination".
+
+The algorithm is explained in this paper:
+
+Partial Redundancy Elimination in SSA Form (1999)
+Robert Kennedy, Sun Chan, SHIN-MING LIU, RAYMOND LO, PENG TU, FRED CHOW
+ACM Transactions on Programming Languages and Systems
+
+http://citeseer.ist.psu.edu/kennedy99partial.html
+
+In this document I give a gentle introduction to the concept of "partial"
+redundancies, and I explain the basic design decisions I took in implementing
+SSAPRE, but the paper is essential to understand the code.
+
+Partial Redundancy Elimination (or PRE) is an optimization that (guess what?)
+tries to remove redundant computations.
+It achieves this by saving the result of "not redundant" evaluations of
+expressions into appositely created temporary variables, so that "redundant"
+evaluations can be replaced by a load from the appropriate variable.
+
+Of course, on register starved architectures (x86) a temporary could cost more
+than the evaluation itself... PRE guarantees that the live range of the
+introduced variables is the minimal possible, but the added pressure on the
+register allocator can be an issue.
+
+The nice thing about PRE is that it not only removes "full" redundancies, but
+also "partial" ones.
+A full redundancy is easy to spot, and straightforward to handle, like in the
+following example (in every example here, the "expression" is "a + b"):
+
+int FullRedundancy1 (int a, int b) {
+     int v1 = a + b;
+     int v2 = a + b;
+     return v1 + v2;
+}
+
+PRE would transform it like this:
+
+int FullRedundancy1 (int a, int b) {
+     int t = a + b;
+     int v1 = t;
+     int v2 = t;
+     return v1 + v2;
+}
+
+Of course, either a copy propagation pass or a register allocator smart enough
+to remove unneeded variables would be necessary afterwords.
+
+Another example of full redundancy is the following:
+
+int FullRedundancy2 (int a, int b) {
+     int v1;
+     
+     if (a >= 0) {
+          v1 = a + b; // BB1
+     } else {
+          a = -a; // BB2
+          v1 = a + b;
+     }
+     
+     int v2 = a + b; // BB3
+     return v1 + v2;
+}
+
+Here the two expressions in BB1 and BB2 are *not* the same thing (a is
+modified in BB2), but both are redundant with the expression in BB3, so the
+code can be transformed like this:
+
+int FullRedundancy2 (int a, int b) {
+     int v1;
+     int t;
+     
+     if (a >= 0) {
+          t = a + b; // BB1
+          v1 = t;
+     } else {
+          a = -a; // BB2
+          t = a + b;
+          v1 = t;
+     }
+     
+     int v2 = t; // BB3
+     return v1 + v2;
+}
+
+Note that there are still two occurrences of the expression, while it can be
+easily seen that one (at the beginning of BB3) would suffice.
+This, however, is not a redundancy for PRE, because there is no path in the
+CFG where the expression is evaluated twice.
+Maybe this other kind of redundancy (which affects code size, and not the
+computations that are actually performed) would be eliminated by code hoisting,
+but I should check it; anyway, it is not a PRE related thing.
+
+An example of partial redundancy, on the other hand, is the following:
+
+int PartialRedundancy (int a, int b) {
+     int v1;
+     
+     if (a >= 0) {
+          v1 = a + b; // BB1
+     } else {
+          v1 = 0; // BB2
+     }
+     
+     int v2 = a + b; // BB3
+     return v1 + v2;
+}
+
+The redundancy is partial because the expression is computed more than once
+along some path in the CFG, not all paths.
+In fact, on the path BB1 - BB3 the expression is computed twice, but on the
+path BB2 - BB3 it is computed only once.
+In this case, PRE must insert new occurrences of the expression in order to
+obtain a full redundancy, and then use temporary variables as before.
+Adding a computation in BB2 would do the job.
+
+One nice thing about PRE is that loop invariants can be seen as partial
+redundancies.
+The idea is that you can get into the loop from two locations: from before the
+loop (at the 1st iteration), and from inside the loop itself (at any other
+iteration). If there is a computation inside the loop that is in fact a loop
+invariant, PRE will spot this, and will handle the BB before the loop as a
+place where to insert a new computation to get a full redundancy.
+At this point, the computation inside the loop would be replaced by an use of
+the temporary stored before the loop, effectively performing "loop invariant
+code motion".
+
+Now, this is what PRE does to the code.
+
+But how does it work?
+
+In "classic" solutions, PRE is formulated as a data flow analysis problem.
+The Muchnick provides a detailed description of the algorithm in this way (it
+is by far the most complex problem of this kind in the whole book).
+The point is that this algorithm does not exploit the SSA form.
+In fact, it has to perform all that amount of data flow analysis exactly
+because it does not take advantage of the work already done if you have put
+the program into SSA form.
+
+The SSAPRE algorithm, on the other hand, is designed with SSA in mind.
+It fully exploits the properties of SSA variables, it also explicitly reuses
+some data structures that must have been computed when building the SSA form,
+and takes great care to output its code in that form already (which means that
+the temporaries it introduces are already "versioned", with all the phi
+variables correctly placed).
+
+The main concept used in this algorithm is the "Factored Redundancy Graph" (or
+FRG in short). Basically, for each given expression, this graph shows all its
+occurrences in the program, and redundant ones are linked to their
+"representative occurrence" (the 1st occurrence met in a CFG traversal).
+The central observation is that the FRG is "factored" because each expression
+occurrence has exactly one representative occurrence, in the same way as the
+SSA form is a "factored" use-definition graph (each use is related to exactly
+one definition).
+And in fact building the FRG is much like building an SSA representation, with
+PHI nodes and all.
+By the way, I use "PHI" for "PHI expression occurrences", and "phi" for the
+usual phi definitions in SSA, because the paper uses an uppercase phi greek
+letter for PHI occurrences (while the lowercase one is standard in SSA).
+
+The really interesting point is that the FRG for a given expression has exactly
+the same "shape" of the use-definition graph for the temporary var that must
+be introduced to remove the redundancy, and this is why SSAPRE can easily emit
+its output code in correct SSA form.
+
+One particular characteristic of the SSAPRE algorithm is that it is "sparse",
+in the sense that it operates on expressions individually, looking only at the
+specific nodes it needs. This is in contrast to the classical way of solving
+data flow analysis problems, which is to operate globally, using data
+structures that work "in parallel" on all the entities they operate on (in
+practice bit sets, with for instance one bit per variable, or one bit per
+expression occurrence, you get the idea). This is handy (it exploits the
+parallelism of bit operations), but in general setting up those data
+structures is time consuming, and if the number of the things represented by
+the bits is not fixed in advance the code can get quite messy (bit sets must
+become growable).
+Moreover, applying special handling to individual expressions becomes a very
+tricky thing.
+
+SSAPRE, on the other hand, looks at the whole program (method in our case) only
+once, when it scans the code to collect (and classify) all expression
+occurrences.
+From here on, it operates on one expression at a time, looking only at its
+specific data structures (which, for each expression, are much smaller than
+the whole program, so the operations are fast).
+
+This approach has another advantage: the data structures used to operate on
+one expressions can be recycled when operating on other expressions, making
+the memory usage of the compiler lower, and (also important) avoiding losing
+time with memory allocations at all.
+This reflects directly on the design of those data structures.
+We can better see these advantages following which data structures are used
+during the application of SSAPRE to a method.
+
+The steps that are performed are the following:
+
+    * Initialization: scan the whole program, collect all the occurrences, and
+      build a worklist of expressions to be processed (each worklist entry
+      describes all the occurrences of the given expression).
+Here the data structures are the following:
+- One struct (the working area), containing the worklist and other
+ "global" data. The worklist itself contains an entry for each expression
+  which in turn has an entry for each occurrence.
+- One "info" struct for each BB, containing interesting dominance and CFG
+  related properties of the BB.
+
+Then, for each entry in the worklist, these operations are performed:
+
+    * PHI placement: find where the PHI nodes of the FRG must be placed.
+    * Renaming: assign appropriate "redundancy classes" to all occurrences (it
+      is like assigning variable versions when building an SSA form).
+    * Analyze: compute various flags in PHI nodes (which are the only places
+      that define where additional computations may be added).
+      This conceptually is composed of two data flow analysis passes, which in
+      practice only scan the PHI nodes in the FRG, not the whole code, so they
+      are not that heavy.
+    * Finalize: make so that the FRG is exactly like the use-def graph for the
+      temporary that will be introduced (it generally must be reshaped a bit
+      according to the flags computed in the previous step).
+      This is also made of two steps, but more for implementation reasons than
+      for conceptual ones.
+    * Code motion: actually update the code using the FRG.
+Here, what's needed is the following:
+- PHI occurrences (and some flags sbout them)
+- PHI argument occurrences (and some flags sbout them)
+- The renaming stack
+In practice, one can observe that each BB can have at most one PHI (we work
+on one expression at a time), and also one PHI argument (which we consider
+occurring at the end of the BB). Therefore, we do not have separate structures
+for these, but store them directly in the BB infos (which are kept for the
+whole SSAPRE invocation).
+The renaming stack is managed directly as a list of occurrences, with
+special handling for PHI nodes (which, being represented directly by their
+BB, are not "occurrences").
+
+
+So far, the only two missing things (with respect to SSAPRE in the paper) are
+unneeded PHIs eliminantion and the handling of "composite" expressions.
+Otherwise, the implementation is complete.
+
+Other interesting issues are:
+- SSAPRE has the assumption that:
+  - each SSA variable is related to one "original" (not SSA) variable, and
+  - no more than one version of each originsl variable is live at the same time
+    in the CFG.
+  It would be better to relax these assumptions.
+- SSAPRE operates on "syntactic" redundancies, not on "values".
+  GVNPRE (or other means of merging GVN) would be a nice alternative, see
+  "http://www.cs.purdue.edu/homes/vandrutj/papers/thesis.pdf".
index b346c512354f416c4aee3665cff501e5040dccc5..bff64d35315b550b0107b60c4611376598517f1e 100644 (file)
@@ -1,4 +1,4 @@
- # $Id: alpha_mach_dep.S,v 1.1 2003/03/31 14:33:59 martin Exp $
+ # $Id$
        .arch ev6
 
         .text
index b786fdec90a833e22f4661a9ba212ab43e1ab2f5..994d71ce7a77567aed7b77cf56d63455fafae002 100755 (executable)
@@ -4,7 +4,7 @@
 # Created: 1993-05-16
 # Public domain
 
-# $Id: mkinstalldirs,v 1.1 2003/03/31 14:34:30 martin Exp $
+# $Id$
 
 errstatus=0
 dirmode=""
index 4729dde830db0d063cc43393ff52863e1d4d9dd7..0fda19d7e0c8fae2ac6994663a0337f6944de48d 100644 (file)
@@ -1,3 +1,20 @@
+2004-12-04  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * library.make,
+         profiles/default.make,
+         profiles/basic.make : use PLATFORM_PATH_SEPARATOR.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * profiles/basic.make (MCS): Run the INTERNAL_MCS.
+       (USE_BOOT_COMPILE): Remove.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * library.make (gacdir_flag): New.  Disable /gacdir flag if
+       RUNTIME_HAS_CONSISTENT_GACDIR flag is set.
+       (install-local): Use it.
+
 2004-11-30  Raja R Harinath  <rharinath@novell.com>
 
        * executable.make (makefrag): Make profile-specific.
index baae2d25546a02cc048cc3dfb287b0976b6e0b0e..88a8b77555dc59c86026a6f98d425ba96002a596 100644 (file)
@@ -77,13 +77,13 @@ endif
 endif
 
 gacutil = $(topdir)/tools/gacutil/gacutil.exe
-GACUTIL = MONO_PATH="$(topdir)/class/lib/default:$$MONO_PATH" $(RUNTIME) $(gacutil)
+GACUTIL = MONO_PATH="$(topdir)/class/lib/default$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(gacutil)
 
 ifdef NO_SIGN_ASSEMBLY
 SN = :
 else
 sn = $(topdir)/class/lib/net_1_1_bootstrap/sn.exe
-SN = MONO_PATH="$(topdir)/class/lib/net_1_1_bootstrap:$$MONO_PATH" $(RUNTIME) $(sn)
+SN = MONO_PATH="$(topdir)/class/lib/net_1_1_bootstrap/$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(sn)
 SNFLAGS = -q -R
 endif
 
@@ -116,8 +116,21 @@ uninstall-local:
 
 else
 
+# If RUNTIME_HAS_CONSISTENT_GACDIR is set, it implies that the internal GACDIR
+# of the runtime is the same as the GACDIR we want.  So, we don't need to pass it
+# to gacutil.  Note that the GACDIR we want may not be the same as the value of 
+# GACDIR set above, since the user could have overridden the value of $(prefix).
+#
+# This makes a difference only when we're building from the mono/ tree, since we
+# have to ensure that the internal GACDIR of the in-tree runtime matches where we 
+# install the DLLs.
+
+ifndef RUNTIME_HAS_CONSISTENT_GACDIR
+gacdir_flag = /gacdir $(GACDIR)
+endif
+
 install-local: $(gacutil)
-       $(GACUTIL) /i $(the_lib) /f /gacdir $(GACDIR) /root $(GACROOT) /package $(FRAMEWORK_VERSION)
+       $(GACUTIL) /i $(the_lib) /f $(gacdir_flag) /root $(GACROOT) /package $(FRAMEWORK_VERSION)
 
 uninstall-local: $(gacutil)
        $(GACUTIL) /u $(LIBRARY_NAME:.dll=)
index 9c97bd2740e7d5c0abd6d165dcedf71de3b9bcf4..3814b0ddba7f250708900e8d15c3e464f2fe994a 100644 (file)
@@ -3,7 +3,7 @@
 # Platform-specific makefile rules. This one's for linux.
 #
 
-PLATFORM_DEBUG_FLAGS = -g
+PLATFORM_DEBUG_FLAGS = -debug
 PLATFORM_MCS_FLAGS = 
 PLATFORM_RUNTIME = $(RUNTIME)
 PLATFORM_CORLIB = mscorlib.dll
index 1d44a3df3987c12227339a742ec4c89a67af3f76..6a26c59526d9d29150b8abd774282a220519bf79 100644 (file)
@@ -1,10 +1,9 @@
 # -*- makefile -*-
 
 BOOTSTRAP_MCS = $(EXTERNAL_MCS)
-MCS = false
+MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_MCS)
 
 PROFILE_MCS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 -d:BOOTSTRAP_WITH_OLDLIB
-USE_BOOT_COMPILE = yes
 NO_SIGN_ASSEMBLY = yes
 NO_TEST = yes
 NO_INSTALL = yes
index 1789c26155cfbedff89bdeeb5ad965d18f4cf2b2..569c424efcb560b1c72d6fcab3251d7c37af4a53 100644 (file)
@@ -15,9 +15,9 @@
 # in the MONO_PATH too).
 
 ifdef PLATFORM_MONO_NATIVE
-BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/net_1_1_bootstrap:$$MONO_PATH" $(RUNTIME) $(topdir)/class/lib/net_1_1_bootstrap/mcs.exe
-MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(INTERNAL_MCS)
-MBAS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(INTERNAL_MBAS)
+BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/net_1_1_bootstrap$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(topdir)/class/lib/net_1_1_bootstrap/mcs.exe
+MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_MCS)
+MBAS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_MBAS)
 else
 BOOTSTRAP_MCS = $(EXTERNAL_MCS)
 MCS = $(PLATFORM_RUNTIME) $(BOOTSTRAP_MCS) /lib:$(topdir)/class/lib/$(PROFILE)
index 7665c74ce8613613a211d3b1418c858d83aeca75..c4b2059afc8c8e27a87b0c2220cd8df5398f3288 100644 (file)
@@ -1,3 +1,12 @@
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (basic_SUBDIRS): Add second-pass System, too.
+       (basic_files): Add System.Xml.dll.
+
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Makefile : now we need System.Xml.dll for basic bootstrapping.
+
 2004-11-25  Raja R Harinath  <rharinath@novell.com>
 
        * Makefile (DISTFILES): Add public and private keys.
index 1e4a775247bc6734ad726f290f24a41f68aceec8..658dfd2ef063849c56f4a11290fe0cd39c27c6b5 100644 (file)
@@ -10,7 +10,7 @@ bootstrap_dirs := \
        System                                  \
        $(MONO_CSHARP_DEBUGGER)
 
-basic_SUBDIRS := corlib System
+basic_SUBDIRS := corlib System System.XML System
 net_1_1_bootstrap_SUBDIRS := $(bootstrap_dirs) Mono.Security
 net_2_0_bootstrap_SUBDIRS := $(bootstrap_dirs)
 
@@ -102,7 +102,7 @@ DISTFILES = \
 all-local $(STD_TARGETS:=-local):
        @:
 
-basic_files = mcs.exe mscorlib.dll System.dll
+basic_files = mcs.exe mscorlib.dll System.dll System.Xml.dll
 
 DIST_PROFILE_DIRS = basic net_1_1_bootstrap default net_2_0_bootstrap net_2_0
 
index 7589f928626fb65204e4ed336a2d6db8644aad4b..d564eb374209b5ae6b4a5c39ede8577201d5f1d3 100644 (file)
@@ -1,3 +1,18 @@
+2004-12-03  Marek Safar  <marek.safar@seznam.cz>
+
+       * System.Windows.Forms.dll.sources: Add ThreadExceptionDialog.cs
+
+2004-12-03  Marek Safar  <marek.safar@seznam.cz>
+
+       * Makefile: Added System.Drawing.dll deps for tests.
+
+       * System.Windows.Forms_test.dll.sources: New test files.
+
+2004-12-02  Peter Bartok  <pbartok@novell.com>
+
+       * SWF.csproj: Added Jackson's fresly minted TreeView files to 
+         build list
+
 2004-12-01  Jackson Harper  <jackson@ximian.com>
 
        * System.Windows.Forms.dll.sources: Add TreeNode love to the build.
index 856d9d15d43458b038169b54b1d83457dc3f2fe2..6f725a6adc17447027f61f38fbf6b4a64f9b5ea5 100644 (file)
@@ -10,6 +10,7 @@ LIB_MCS_FLAGS = /unsafe \
 
 EXTRA_DISTFILES = \
        README
-
+\r
+TEST_MCS_FLAGS = /r:System.Drawing.dll
 
 include ../../build/library.make
index 5e87acf761c0d1e4420a0f310b7e95d14db85930..23a297085d32cf4fc405a1836ca6862a13e6067b 100644 (file)
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\NodeLabelEditEventArgs.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\NodeLabelEditEventHandler.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Windows.Forms\NumericUpDown.cs"\r
                     SubType = "Component"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\OpenTreeNodeEnumerator.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Windows.Forms\Orientation.cs"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\OwnerDrawPropertyBag.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Windows.Forms\PaintEventArgs.cs"\r
                     SubType = "Code"\r
                     SubType = "Component"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeNode.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeNodeCollection.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeView.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeViewAction.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeViewCancelEventArgs.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeViewCancelEventHandler.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeViewEventArgs.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Windows.Forms\TreeViewEventHandler.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Windows.Forms\TrackBar.cs"\r
                     SubType = "Component"\r
index b49a89a86c74d35d319fc1749c624720945252dc..28422ae30c17d52dfab08cfa9665975d232c4f43 100644 (file)
@@ -197,6 +197,7 @@ System.Windows.Forms/Theme.cs
 System.Windows.Forms/ThemeEngine.cs
 System.Windows.Forms/ThemeGtk.cs
 System.Windows.Forms/ThemeWin32Classic.cs
+System.Windows.Forms/ThreadExceptionDialog.cs
 System.Windows.Forms/TickStyle.cs
 System.Windows.Forms/Timer.cs
 System.Windows.Forms/TODOAttribute.cs
index ba44889c98654616460669c6f7c290fde2eeb55a..ea8167ae1e00195d64c629d769f5f27d1a298f22 100644 (file)
@@ -300,9 +300,17 @@ namespace System.Windows.Forms {
                public static void OnThreadException(Exception t) {
                        if (Application.ThreadException != null) {
                                Application.ThreadException(null, new ThreadExceptionEventArgs(t));
-                       } else {
-                               XplatUI.HandleException(t);
+                               return;
+                       }
+
+                       // TODO: Missing implementation
+                       //if (SystemInformation.UserInteractive)
+                       {
+                               Form form = new ThreadExceptionDialog (t);
+                               form.ShowDialog ();
                        }
+                       //else
+                               Console.WriteLine (t.ToString ());
                }
 
                public static void RemoveMessageFilter(IMessageFilter filter) {
index f36ae39061b4e1f2d818d4fab23aedab7df5045d..bcf13dabefacb8eeaf52ef59b49f20b1ec0383e2 100644 (file)
@@ -1,3 +1,43 @@
+2004-12-03  Jordi Mas i Hernandez <jordi@ximian.com>
+
+       * ListBox.cs: implemented clipping, selection single and multiple,
+       bug fixing
+
+2004-12-03  Ravindra <rkumar@novell.com>
+
+       * ListView.cs (ListView_KeyDown):
+       * ListView.cs (ListView_KeyUp): Fixed multiple selection handling
+       when CTRL key is pressed.
+       * ListViewItem.cs (Selected): Fixed setting the property.
+
+2004-12-03  Marek Safar  <marek.safar@seznam.cz>
+\r
+       * Application.cs (OnThreadException): Use ThreadExceptionDialog.\r
+
+       * Form.cs: Add ActiveForm, FormBorderStyle, MaximizeBox,\r
+       MinimizeBox, ShowInTaskbar, TopMost properties.\r
+\r
+       * ThreadExceptionDialog.cs: Implemented (disabled TextBox until\r
+       will be implemented).
+\r
+2004-12-03  Marek Safar  <marek.safar@seznam.cz>
+
+       * OwnerDrawPropertyBag.cs: New internal parameterless ctor.
+
+       * TreeNode.cs: Implemented ICloneable, Fixed to pass my simple
+       tests.
+       
+       * TreeNodeCollection.cs: Add exception throwing for Add,AddRange.
+       
+       * TreeView.cs: BackColor is Colors.Window.
+
+2004-12-01  Jackson Harper  <jackson@ximian.com>
+
+       * TreeView.cs: When resizing the tree if the user is making it
+       smaller we don't get expose events, so we need to handle adding
+       the horizontal scrollbar in the size changed handler as well as
+       the expose handler.
+
 2004-12-02  Jordi Mas i Hernandez <jordi@ximian.com>
 
        * DrawItemState.cs: fixes wrong enum values
index 8a4c36c9b78620d79ba615785c0804611de379d1..f1a50607ad91f52b0b7b79a0d09b43dc0be7ed00 100644 (file)
@@ -136,6 +136,16 @@ namespace System.Windows.Forms {
                #region Local Variables
                internal bool                   closing;
 
+               [Flags]
+               enum Flags {
+                       ShowInTaskbar   = 0x0001,
+                       MaximizeBox             = 0x0002,
+                       MinimizeBox             = 0x0004,
+                       TopMost                 = 0x0008
+               }
+
+               Flags flags = Flags.ShowInTaskbar | Flags.MaximizeBox | Flags.MinimizeBox;
+               FormBorderStyle formBorderStyle = FormBorderStyle.Sizable;
                private static bool             autoscale;
                private static Size             autoscale_base_size;
                private bool                    is_modal;
@@ -185,9 +195,9 @@ namespace System.Windows.Forms {
                                        cp = base.CreateParams;\r
 \r
                                        cp.Style = (int)(WindowStyles.WS_OVERLAPPEDWINDOW | 
-                                                        WindowStyles.WS_VISIBLE | 
-                                                        WindowStyles.WS_CLIPSIBLINGS | 
-                                                        WindowStyles.WS_CLIPCHILDREN);
+                                               WindowStyles.WS_VISIBLE | 
+                                               WindowStyles.WS_CLIPSIBLINGS | 
+                                               WindowStyles.WS_CLIPCHILDREN);
 
                                        cp.Width = 250;
                                        cp.Height = 250;
@@ -320,6 +330,14 @@ namespace System.Windows.Forms {
 
 
                #region Public Static Properties
+
+               public static Form ActiveForm {\r
+                       get {\r
+                               //FIXME: create next driver call\r
+                               return null;\r
+                       }\r
+               }\r
+
                #endregion      // Public Static Properties
 
                #region Public Instance Properties
@@ -377,6 +395,17 @@ namespace System.Windows.Forms {
                        }
                }
 
+               public FormBorderStyle FormBorderStyle {\r
+                       get {\r
+                               return formBorderStyle;\r
+                       }\r
+                       set {\r
+                               formBorderStyle = value;\r
+                               Invalidate ();\r
+                       }\r
+               }\r
+
+
                public bool KeyPreview {
                        get {
                                return key_preview;
@@ -387,6 +416,18 @@ namespace System.Windows.Forms {
                        }
                }
 
+               public bool MaximizeBox {\r
+                       get {\r
+                               return (flags & Flags.MaximizeBox) != 0;\r
+                       }\r
+                       set {\r
+                               if (value)\r
+                                       flags &= ~Flags.MaximizeBox;\r
+                               else\r
+                                       flags |= Flags.MaximizeBox;\r
+                       }\r
+               }
+
                public MainMenu Menu {
                        get {
                                return menu;
@@ -414,6 +455,18 @@ namespace System.Windows.Forms {
                        }
                }
 
+               public bool MinimizeBox {\r
+                       get {\r
+                               return (flags & Flags.MinimizeBox) != 0;\r
+                       }\r
+                       set {\r
+                               if (value)\r
+                                       flags &= ~Flags.MinimizeBox;\r
+                               else\r
+                                       flags |= Flags.MinimizeBox;\r
+                       }\r
+               }
+
                public bool Modal  {
                        get {
                                return is_modal;
@@ -455,6 +508,18 @@ namespace System.Windows.Forms {
                        }
                }
 
+               public bool ShowInTaskbar {\r
+                       get {\r
+                               return (flags & Flags.ShowInTaskbar) != 0;\r
+                       }\r
+                       set {\r
+                               if (value)\r
+                                       flags &= ~Flags.ShowInTaskbar;\r
+                               else\r
+                                       flags |= Flags.ShowInTaskbar;\r
+                       }\r
+               }\r
+
                public FormStartPosition StartPosition {
                        get {
                                return start_position;
@@ -490,6 +555,24 @@ namespace System.Windows.Forms {
                                }
                        }
                }
+
+               public bool TopMost {\r
+                       get {\r
+                               return (flags & Flags.TopMost) != 0;\r
+                       }\r
+                       set {\r
+                               if (TopMost == value)\r
+                                       return;\r
+\r
+                               if (value)\r
+                                       flags &= ~Flags.TopMost;\r
+                               else\r
+                                       flags |= Flags.TopMost;\r
+\r
+                               XplatUI.SetTopmost(window.Handle, owner != null ? owner.window.Handle : IntPtr.Zero, TopMost);
+                       }\r
+               }\r
+
                #endregion      // Public Instance Properties
 
                #region Protected Instance Properties
@@ -518,6 +601,13 @@ namespace System.Windows.Forms {
                                cp.Style |= (int)WindowStyles.WS_CLIPSIBLINGS;
                                cp.Style |= (int)WindowStyles.WS_CLIPCHILDREN;
 
+                               if (ShowInTaskbar)
+                                       cp.ExStyle |= (int)WindowStyles.WS_EX_APPWINDOW;
+                               if (MaximizeBox)
+                                       cp.Style |= (int)WindowStyles.WS_MAXIMIZEBOX;
+                               if (MinimizeBox)
+                                       cp.Style |= (int)WindowStyles.WS_MINIMIZEBOX;
+
                                return cp;
                        }
                }
index adfc6007bf123a41904aae120d94954dd487c8ae..a5a6349e18adae399ab34ef7975541b0f4e49495 100644 (file)
@@ -41,6 +41,7 @@ namespace System.Windows.Forms
                {
                        internal int item_height;               /* Item's height */
                        internal int top_item;                  /* First item that we show the in the current page */
+                       internal int last_item;                 /* Last visible item */
                        internal int page_size;                 /* Number of listbox items per page. In MultiColumn listbox indicates items per column */
                        internal Rectangle textdrawing_rect;    /* Displayable Client Rectangle minus the scrollbars and with IntegralHeight calculated*/
                        internal bool show_verticalsb;          /* Is Vertical scrollbar show it? */
@@ -50,6 +51,7 @@ namespace System.Windows.Forms
 
                        public ListBoxInfo ()
                        {
+                               last_item = 0;
                                item_height = 0;
                                top_item = 0;
                                page_size = 0;
@@ -62,19 +64,18 @@ namespace System.Windows.Forms
                internal class ListBoxItem
                {
                        internal object obj;
-                       internal Rectangle rect;
                        internal bool Selected;
 
                        public ListBoxItem ()
                        {
                                obj = null;
-                               Selected = true;
+                               Selected = false;
                        }
 
                        public ListBoxItem (object obj)
                        {
                                this.obj = obj;
-                               Selected = true;
+                               Selected = false;
                        }
                }
 
@@ -103,6 +104,8 @@ namespace System.Windows.Forms
                private VScrollBar vscrollbar_ctrl;
                private HScrollBar hscrollbar_ctrl;
 
+               private bool control_pressed = true;
+
                public ListBox ()
                {
                        border_style = BorderStyle.Fixed3D;                     \r
@@ -146,6 +149,9 @@ namespace System.Windows.Forms
                        hscrollbar_ctrl.Maximum = 0;
                        hscrollbar_ctrl.Visible = false;
                        hscrollbar_ctrl.ValueChanged += new EventHandler (HorizontalScrollEvent);
+
+                       /* Events */
+                       MouseDown += new MouseEventHandler (OnMouseDownLB);
                }
 
                #region Events
@@ -347,8 +353,14 @@ namespace System.Windows.Forms
                                if (selected_index == value)
                                        return;
 
+                               if (value < -1 || value >= Items.Count)
+                                       throw new ArgumentOutOfRangeException ("Index of out range");
+
+                               UnSelectItem (selected_index);
+                               SelectItem (value);
                                selected_index = value;
-                               Refresh ();
+                               OnSelectedIndexChanged  (new EventArgs ());
+                               
                        }
                }
 
@@ -400,7 +412,7 @@ namespace System.Windows.Forms
                public override string Text {
                        get {
                                return "";
-                               //throw new NotImplementedException ();
+                               
                        }
                        set {
                                throw new NotImplementedException ();
@@ -453,7 +465,11 @@ namespace System.Windows.Forms
 
                public void ClearSelected ()
                {
-                       throw new NotImplementedException ();
+                       foreach (int i in selected_indices)
+                               UnSelectItem (selected_indices[i]);
+
+                       selected_indices.ClearIndices ();
+                       selected_items.ClearObjects ();
                }
 
                protected virtual ObjectCollection CreateItemCollection ()
@@ -527,12 +543,18 @@ namespace System.Windows.Forms
 
                public int IndexFromPoint (Point p)
                {
-                       throw new NotImplementedException ();
+                       return IndexFromPoint (p.X, p.Y);
                }
 
-               public int IndexFromPoint (int x,  int y)
+               // Only returns visible points
+               public int IndexFromPoint (int x, int y)
                {
-                       throw new NotImplementedException ();
+                       for (int i = LBoxInfo.top_item; i < LBoxInfo.last_item; i++) {
+                               if (GetItemRectangle (i).Contains (x,y) == true)
+                                       return i;
+                       }
+
+                       return -1;
                }
 
                protected override void OnChangeUICues(UICuesEventArgs e)
@@ -552,6 +574,28 @@ namespace System.Windows.Forms
 
                protected virtual void OnDrawItem (DrawItemEventArgs e)
                {
+                       if (DrawItem != null && (DrawMode == DrawMode.OwnerDrawFixed || DrawMode == DrawMode.OwnerDrawVariable))
+                               DrawItem (this, e);
+
+                       if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
+                               e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
+                                       (ThemeEngine.Current.ColorHilight), e.Bounds);
+
+                               e.Graphics.DrawString (Items[e.Index].ToString (), e.Font,
+                                       ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorHilightText),
+                                       e.Bounds, string_format);
+                       }
+                       else {
+                               e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
+                                       (e.BackColor), e.Bounds);
+
+                               e.Graphics.DrawString (Items[e.Index].ToString (), e.Font,
+                                       ThemeEngine.Current.ResPool.GetSolidBrush (e.ForeColor),
+                                       e.Bounds, string_format);
+                       }
+
+
+
 
                }
 
@@ -594,12 +638,12 @@ namespace System.Windows.Forms
                {
                        base.OnResize (e);
                        UpdateInternalClientRect (ClientRectangle);
-               }
+               }               
 
                protected override void OnSelectedIndexChanged (EventArgs e)
-               {
-                       base.OnSelectedIndexChanged (e);
-
+               {                               
+                       if (SelectedIndexChanged != null)
+                               SelectedIndexChanged (this, e);
                }
 
                protected override void OnSelectedValueChanged (EventArgs e)
@@ -633,7 +677,7 @@ namespace System.Windows.Forms
                        throw new NotImplementedException ();
                }
 
-               public void SetSelected (int index,bool value)
+               public void SetSelected (int index, bool value)
                {
                        throw new NotImplementedException ();
                }
@@ -686,9 +730,7 @@ namespace System.Windows.Forms
                        listbox_info.textdrawing_rect.Y += ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle);
                        listbox_info.textdrawing_rect.X += ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle);
                        listbox_info.textdrawing_rect.Height -= ThemeEngine.Current.DrawListBoxDecorationBottom (BorderStyle);
-                       listbox_info.textdrawing_rect.Height -= ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle);
                        listbox_info.textdrawing_rect.Width -= ThemeEngine.Current.DrawListBoxDecorationRight (BorderStyle);
-                       listbox_info.textdrawing_rect.Width -= ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle);
 
                        if (listbox_info.show_verticalsb)
                                listbox_info.textdrawing_rect.Width -= vscrollbar_ctrl.Width;
@@ -719,89 +761,147 @@ namespace System.Windows.Forms
                                }
                        }
 
+                       LBoxInfo.last_item = LastVisibleItem ();
                }
 
-               internal void Draw ()
+               internal void Draw (Rectangle clip)
                {
-                       // IntegralHeight has effect, we also have to paint the unused area
-                       if (ClientRectangle.Height > listbox_info.client_rect.Height) {
-                               Region area = new Region (ClientRectangle);
-                               area.Exclude (listbox_info.client_rect);
+                       
+                       if (LBoxInfo.textdrawing_rect.Contains (clip) == false) {
+                               // IntegralHeight has effect, we also have to paint the unused area
+                               if (ClientRectangle.Height > listbox_info.client_rect.Height) {
+                                       Region area = new Region (ClientRectangle);
+                                       area.Exclude (listbox_info.client_rect);
+
+                                       DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (Parent.BackColor),
+                                               area.GetBounds (DeviceContext));
+                               }
 
-                               DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (Parent.BackColor),
-                                       area.GetBounds (DeviceContext));
+                               DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), LBoxInfo.textdrawing_rect);
+                               ThemeEngine.Current.DrawListBoxDecorations (DeviceContext, this);                               
                        }
 
-                       DeviceContext.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), LBoxInfo.textdrawing_rect);
-
-                       // Draw items
-                       int y = LBoxInfo.textdrawing_rect.Y;
-                       int top_y = LBoxInfo.textdrawing_rect.Y + LBoxInfo.textdrawing_rect.Height;
-                       Rectangle item_rect = new Rectangle ();
-                       item_rect.X = LBoxInfo.textdrawing_rect.X;
-                       item_rect.Height = LBoxInfo.item_height;
+                       if (Items.Count > 0) {
+                               Rectangle item_rect;
+                               DrawItemState state = DrawItemState.None;
 
-                       if (MultiColumn)
-                               item_rect.Width = ColumnWidthInternal;
-                       else
-                               item_rect.Width = LBoxInfo.textdrawing_rect.Width;
+                               for (int i = LBoxInfo.top_item; i < LBoxInfo.last_item; i++) {
+                                       item_rect = GetItemDisplayRectangle (i, LBoxInfo.top_item);
 
-                       for (int i = LBoxInfo.top_item; i < Items.Count; i++) {
-                               item_rect.Y = y;
-                               DrawListBoxItem (DeviceContext, i, item_rect);
-                               y += LBoxInfo.item_height;
+                                       if (clip.IntersectsWith (item_rect) == false)
+                                               continue;
 
-                               if (MultiColumn) {
+                                       /* Draw item */
+                                       state = DrawItemState.None;
 
-                                       if (y + LBoxInfo.item_height > top_y) {
-                                               if (item_rect.X + ColumnWidthInternal > LBoxInfo.textdrawing_rect.Width)
-                                                       break;
-
-                                               item_rect.X += ColumnWidthInternal;
-                                               y = LBoxInfo.textdrawing_rect.Y;
+                                       if ((Items.GetListBoxItem (i)).Selected) {
+                                               state |= DrawItemState.Selected;
                                        }
 
+                                       OnDrawItem (new DrawItemEventArgs (DeviceContext, Font, item_rect,
+                                               i, state, ForeColor, BackColor));
                                }
-                               else
-                                       if (IntegralHeight)
-                                               if (y > top_y)
-                                                       break;
-                                       else
-                                               if (y + LBoxInfo.item_height> top_y)
-                                                       break;
-
                        }
-
-                       ThemeEngine.Current.DrawListBoxDecorations (DeviceContext, this);
                }
 
-               private void DrawListBoxItem (Graphics dc, int elem, Rectangle rect)
+               // Converts a GetItemRectangle to a one that we can display
+               private Rectangle GetItemDisplayRectangle (int index, int first_displayble)
                {
-                       dc.DrawString (Items[elem].ToString (), Font,
-                                       ThemeEngine.Current.ResPool.GetSolidBrush (ForeColor),
-                                       rect, string_format);
+                       Rectangle item_rect;
+                       Rectangle first_item_rect = GetItemRectangle (first_displayble);
+                       item_rect = GetItemRectangle (index);
+                       item_rect.X -= first_item_rect.X;
+                       item_rect.Y -= first_item_rect.Y;
+
+                       item_rect.Y += ThemeEngine.Current.DrawListBoxDecorationTop (BorderStyle);
+                       item_rect.X += ThemeEngine.Current.DrawListBoxDecorationLeft (BorderStyle);
+                       item_rect.Width -= ThemeEngine.Current.DrawListBoxDecorationRight (BorderStyle);
+
+                       return item_rect;
                }
 
                // Value Changed
                private void HorizontalScrollEvent (object sender, EventArgs e)
                {
-                       LBoxInfo.top_item = listbox_info.page_size * hscrollbar_ctrl.Value;                             
+                       LBoxInfo.top_item = listbox_info.page_size * hscrollbar_ctrl.Value;
+                       LBoxInfo.last_item = LastVisibleItem ();
                        Refresh ();
                }
 
+               private int LastVisibleItem ()
+               {
+                       Rectangle item_rect;
+                       int top_y = LBoxInfo.textdrawing_rect.Y + LBoxInfo.textdrawing_rect.Height;
+                       int i = 0;
+
+                       for (i = LBoxInfo.top_item; i < Items.Count; i++) {
+
+                               item_rect = GetItemRectangle (i);
+
+                               if (MultiColumn) {
+
+                                       if (item_rect.X > LBoxInfo.textdrawing_rect.Width)
+                                               return i - 1;
+                               }
+                               else {
+                                       if (IntegralHeight) {
+                                               if (item_rect.Y + item_rect.Height > top_y)
+                                                       return i - 1;
+                                       }
+                                       else {
+                                               if (item_rect.Y > top_y)
+                                                       return i - 1;
+                                       }
+                               }
+                       }
+
+                       return i;
+               }
+
+               private void OnMouseDownLB (object sender, MouseEventArgs e)
+               {
+                       int index = IndexFromPoint (e.X, e.Y);
+                       if (index == -1) return;                        
+
+                       switch (SelectionMode) {
+                               case SelectionMode.None: // Do nothing
+                                       break;
+                               case SelectionMode.One: {
+                                       SelectedIndex = index;
+                                       break;
+                               }
+
+                               case SelectionMode.MultiSimple: {
+                                       if (selected_index == -1) {
+                                               SelectedIndex = index;
+                                       } else {
+
+                                               if ((Items.GetListBoxItem (index)).Selected)
+                                                       UnSelectItem (index);
+                                               else {
+                                                       SelectItem (index);
+                                                       OnSelectedIndexChanged  (new EventArgs ());
+                                               }
+                                       }
+                                       break;
+                               }
+                               default:
+                                       break;
+                       }
+               }
+
                private void OnPaintLB (PaintEventArgs pevent)
                {
                        if (Width <= 0 || Height <=  0 || Visible == false)
                                return;
 
                        /* Copies memory drawing buffer to screen*/
-                       Draw ();
-                       pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
+                       Draw (pevent.ClipRectangle);
+                       pevent.Graphics.DrawImage (ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
                }
 
                internal void RellocateScrollBars ()
                {
-
                        if (listbox_info.show_verticalsb) {
 
                                vscrollbar_ctrl.Size = new Size (vscrollbar_ctrl.Width,
@@ -833,6 +933,32 @@ namespace System.Windows.Forms
                        CalcClientArea ();
                }
 
+               // Add an item in the Selection array and marks it visually as selected
+               void SelectItem (int index)
+               {
+                       if (index == -1)
+                               return;
+
+                       Rectangle invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
+                       (Items.GetListBoxItem (index)).Selected = true;
+                       selected_indices.AddIndex (index);
+                       selected_items.AddObject (Items[index]);
+                       Invalidate (invalidate);
+               }
+
+               // Removes an item in the Selection array and marks it visually as unselected
+               void UnSelectItem (int index)
+               {
+                       if (index == -1)
+                               return;
+
+                       Rectangle invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
+                       (Items.GetListBoxItem (index)).Selected = false;
+                       selected_indices.RemoveIndex (index);
+                       selected_items.RemoveObject (Items[index]);
+                       Invalidate (invalidate);
+               }
+
                // Updates the scrollbar's position with the new items and inside area
                internal void UpdateItemInfo (bool adding, int first, int last)
                {
@@ -854,13 +980,33 @@ namespace System.Windows.Forms
                                }
                        }
 
-                       if (adding) {
+                       if (MultiColumn == false) {
+                               /* Calc the longest items for non multicolumn listboxes */
+                               if ((first == -1 && last == -1) || (adding == false)) {
+
+                                       SizeF size;
+                                       for (int i = 0; i < Items.Count; i++) {
+                                               size = DeviceContext.MeasureString (Items[i].ToString(), Font);
 
-                       }
-                       else { /* Removing */
+                                               if ((int) size.Width > listbox_info.max_itemwidth)
+                                                       listbox_info.max_itemwidth = (int) size.Width;
+                                       }
+                               }
+                               else {
+                                       if (adding) {
 
+                                               SizeF size;
+                                               for (int i = first; i < last + 1; i++) {
+                                                       size = DeviceContext.MeasureString (Items[i].ToString(), Font);
+
+                                                       if ((int) size.Width > listbox_info.max_itemwidth)
+                                                               listbox_info.max_itemwidth = (int) size.Width;
+                                               }
+                                       }
+                               }
                        }
 
+                       UpdateShowHorizontalScrollBar ();
                        Refresh ();
                }
 
@@ -878,7 +1024,6 @@ namespace System.Windows.Forms
                {
                        bool show = false;
                        bool enabled = true;
-                       bool large_item = false;
 
                        if (MultiColumn) {  /* Horizontal scrollbar is always shown in Multicolum mode */
 
@@ -899,10 +1044,10 @@ namespace System.Windows.Forms
 
                        } else { /* If large item*/
 
-                               if (large_item && HorizontalScrollbar) {
-
+                               if (listbox_info.max_itemwidth > listbox_info.client_rect.Width && HorizontalScrollbar) {
+                                       show = true;
+                                       hscrollbar_ctrl.Maximum = listbox_info.max_itemwidth;
                                }
-
                        }
 
                        if (hscrollbar_ctrl.Enabled != enabled)
@@ -937,7 +1082,7 @@ namespace System.Windows.Forms
                                                enabled = false;
                                        }
                        }
-                       
+
                        if (vscrollbar_ctrl.Enabled != enabled)
                                vscrollbar_ctrl.Enabled = enabled;
 
@@ -959,14 +1104,14 @@ namespace System.Windows.Forms
 
                // Value Changed
                private void VerticalScrollEvent (object sender, EventArgs e)
-               {                       
+               {
                        LBoxInfo.top_item = /*listbox_info.page_size + */ vscrollbar_ctrl.Value;
+                       LBoxInfo.last_item = LastVisibleItem ();
                        Refresh ();
                }
 
                #endregion Private Methods
 
-
                /*
                        ListBox.ObjectCollection
                */
@@ -1122,7 +1267,7 @@ namespace System.Windows.Forms
                        private int AddItem (object item)
                        {
                                object_items.Add (item);
-                               listbox_items.Add (null);
+                               listbox_items.Add (new ListBox.ListBoxItem ());
                                return object_items.Count - 1;
                        }
 
@@ -1147,15 +1292,11 @@ namespace System.Windows.Forms
 
                /*
                        ListBox.SelectedIndexCollection
-
-                       The idea is to get all the data for this collection from
-                       the ListBox SelectedObjectCollection object
-
                */
                public class SelectedIndexCollection : IList, ICollection, IEnumerable
                {
                        private ListBox owner;
-                       private ArrayList items = new ArrayList ();
+                       private ArrayList indices = new ArrayList ();
 
                        public SelectedIndexCollection (ListBox owner)
                        {
@@ -1164,7 +1305,7 @@ namespace System.Windows.Forms
 
                        #region Public Properties
                        public virtual int Count {
-                               get { return owner.SelectedItems.Count; }
+                               get { return indices.Count; }
                        }
 
                        public virtual bool IsReadOnly {
@@ -1172,7 +1313,12 @@ namespace System.Windows.Forms
                        }
 
                        public int this [int index] {
-                               get { throw new NotImplementedException (); }
+                               get {
+                                       if (index < 0 || index >= Count)
+                                               throw new ArgumentOutOfRangeException ("Index of out range");
+
+                                       return (int) indices[index];
+                               }
                        }
 
                        bool ICollection.IsSynchronized {
@@ -1192,17 +1338,17 @@ namespace System.Windows.Forms
                        #region Public Methods
                        public bool Contains (int selectedIndex)
                        {
-                               throw new NotImplementedException ();
+                               return indices.Contains (selectedIndex);
                        }
 
                        public virtual void CopyTo (Array dest, int index)
                        {
-                               throw new NotImplementedException ();
+                               indices.CopyTo (dest, index);
                        }
 
                        public virtual IEnumerator GetEnumerator ()
                        {
-                               throw new NotImplementedException ();
+                               return indices.GetEnumerator ();
                        }
 
                        int IList.Add (object obj)
@@ -1222,7 +1368,7 @@ namespace System.Windows.Forms
 
                        int IList.IndexOf (object selectedIndex)
                        {
-                               return IndexOf ((int)selectedIndex);
+                               return IndexOf ((int) selectedIndex);
                        }
 
                        void IList.Insert (int index, object value)
@@ -1241,16 +1387,34 @@ namespace System.Windows.Forms
                        }
 
                        object IList.this[int index]{
-                               get {throw new NotImplementedException (); }
+                               get {return indices[index]; }
                                set {throw new NotImplementedException (); }
                        }
 
                        public int IndexOf (int selectedIndex)
                        {
-                               throw new NotSupportedException ();
+                               return indices.IndexOf (selectedIndex);
                        }
                        #endregion Public Methods
 
+                       #region Private Methods
+                       internal void AddIndex (int index)
+                       {
+                               indices.Add (indices);
+                       }
+
+                       internal void RemoveIndex (int index)
+                       {
+                               indices.Remove (indices);
+                       }
+
+                       internal void ClearIndices ()
+                       {
+                               indices.Clear ();
+                       }
+
+                       #endregion Private Methods
+
                }
 
                /*
@@ -1259,7 +1423,7 @@ namespace System.Windows.Forms
                public class SelectedObjectCollection : IList, ICollection, IEnumerable
                {
                        private ListBox owner;
-                       private ArrayList items = new ArrayList ();
+                       private ArrayList object_items = new ArrayList ();
 
                        public SelectedObjectCollection (ListBox owner)
                        {
@@ -1268,7 +1432,7 @@ namespace System.Windows.Forms
 
                        #region Public Properties
                        public virtual int Count {
-                               get { return items.Count; }
+                               get { return object_items.Count; }
                        }
 
                        public virtual bool IsReadOnly {
@@ -1276,7 +1440,7 @@ namespace System.Windows.Forms
                        }
 
                        bool ICollection.IsSynchronized {
-                               get { return false; }
+                               get { return true; }
                        }
 
                        object ICollection.SyncRoot {
@@ -1288,8 +1452,8 @@ namespace System.Windows.Forms
                        }
 
                        object IList.this[int index] {
-                               get { return items [index]; }
-                               set { items [index] = value; }
+                               get { return object_items[index]; }
+                               set { throw new NotSupportedException (); }
                        }
 
                        #endregion Public Properties
@@ -1297,12 +1461,12 @@ namespace System.Windows.Forms
                        #region Public Methods
                        public virtual bool Contains (object selectedObject)
                        {
-                               return items.Contains (selectedObject);
+                               return object_items.Contains (selectedObject);
                        }
 
                        public virtual void CopyTo (Array dest, int index)
                        {
-                               throw new NotImplementedException ();
+                               object_items.CopyTo (dest, index);
                        }
 
                        int IList.Add (object value)
@@ -1322,7 +1486,7 @@ namespace System.Windows.Forms
 
                        int IList.IndexOf (object selectedIndex)
                        {
-                               throw new NotImplementedException ();
+                               return IndexOf ((int) selectedIndex);
                        }
        \r
                        void IList.Insert (int index, object value)
@@ -1342,16 +1506,34 @@ namespace System.Windows.Forms
        \r
                        public int IndexOf (int selectedIndex)
                        {
-                               throw new NotImplementedException ();
+                               return object_items.IndexOf (selectedIndex);
                        }
 
                        public virtual IEnumerator GetEnumerator ()
                        {
-                               throw new NotImplementedException ();
+                               return object_items.GetEnumerator ();
                        }
 
                        #endregion Public Methods
 
+                       #region Private Methods
+                       internal void AddObject (object obj)
+                       {
+                               object_items.Add (obj);
+                       }
+
+                       internal void RemoveObject (object obj)
+                       {
+                               object_items.Remove (obj);
+                       }
+
+                       internal void ClearObjects ()
+                       {
+                               object_items.Clear ();
+                       }
+
+                       #endregion Private Methods
+
                }
 
        }
index c628659c7bb64088725061ddd5a79f3e3c5d6bee..224628175ff60b35bd4a09618481f0b04fbf3c93 100644 (file)
@@ -918,7 +918,7 @@ namespace System.Windows.Forms
 
                private void ListView_KeyDown (object sender, KeyEventArgs ke)
                {
-                       if (!ke.Handled && ke.Control) {
+                       if (!ke.Handled && ke.KeyCode == Keys.ControlKey) {
                                this.ctrl_pressed = true;
                                ke.Handled = true;
                        }
@@ -926,7 +926,7 @@ namespace System.Windows.Forms
 
                private void ListView_KeyUp (object sender, KeyEventArgs ke)
                {
-                       if (!ke.Handled && ke.Control) {
+                       if (!ke.Handled && ke.KeyCode == Keys.ControlKey) {
                                this.ctrl_pressed = false;
                                ke.Handled = true;
                        }
@@ -1002,10 +1002,8 @@ namespace System.Windows.Forms
 
                        if (this.clicked_item != null) {
                                this.clicked_item.Selected = true;
-
-                               // Raise the event if it is a new selection
-                               if (this.clicked_item != this.last_clicked_item)
-                                       this.OnSelectedIndexChanged (new EventArgs ());
+                               // Raise the event
+                               this.OnSelectedIndexChanged (new EventArgs ());
 
                                this.Redraw (false);
                        }
@@ -1026,18 +1024,9 @@ namespace System.Windows.Forms
                        ListViewItem item = this.GetItemAt (hit.X, hit.Y);
 
                        if (item != null) {
-                               if (this.CanMultiselect == false &&
-                                   this.selected_items.Count > 0) {
-                                       this.selected_items.Clear ();
-                                       this.selected_indices.list.Clear ();
-                               }
-
                                item.Selected = true;
-                               this.selected_items.list.Add (item);
-                               this.selected_indices.list.Add (item.Index);
-
-                               if (this.CanMultiselect)
-                                       this.OnSelectedIndexChanged (new EventArgs ());
+                               // Raise the event
+                               this.OnSelectedIndexChanged (new EventArgs ());
 
                                this.Redraw (false);
                        }
index 646133154aa058010755e9d0d9737c35e07ea49e..1a0ccd439e5e236e76dcc4cb3225987201d38142 100644 (file)
@@ -253,24 +253,22 @@ namespace System.Windows.Forms
                public bool Selected {
                        get { return selected; }
                        set {
-                               if (value != selected) {
-                                       selected = value;
+                               if (owner != null) {
+                                       if (owner.CanMultiselect == false &&
+                                           owner.SelectedItems.Count > 0) {
+                                               owner.SelectedItems.Clear ();
+                                               owner.SelectedIndices.list.Clear ();
+                                       }
 
-                                       if (owner != null) {
-                                               if (owner.CanMultiselect == false &&
-                                                   owner.SelectedItems.Count > 0) {
-                                                       owner.SelectedItems.Clear ();
-                                                       owner.SelectedIndices.list.Clear ();
-                                               }
-                                               if (selected) {
-                                                       //do we need !owner.SelectedItems.Contains (this))
-                                                       owner.SelectedItems.list.Add (this);
-                                                       owner.SelectedIndices.list.Add (this.Index);
-                                               }
-                                               else {
-                                                       owner.SelectedItems.list.Remove (this);
-                                                       owner.SelectedIndices.list.Remove (this.Index);
-                                               }
+                                       selected = value;
+                                       if (selected) {
+                                               //do we need !owner.SelectedItems.Contains (this))
+                                               owner.SelectedItems.list.Add (this);
+                                               owner.SelectedIndices.list.Add (this.Index);
+                                       }
+                                       else {
+                                               owner.SelectedItems.list.Remove (this);
+                                               owner.SelectedIndices.list.Remove (this.Index);
                                        }
                                }
                        }
index c668bf6c6809d0439dc41535f7babcd409e29830..8e17c902728df8832dc572a5f5a1e69b405d3526 100644 (file)
@@ -35,6 +35,11 @@ namespace System.Windows.Forms {
                private Color back_color;
                private Font font;
 
+               internal OwnerDrawPropertyBag ()
+               {
+                       fore_color = back_color = Color.Empty;
+               }
+
                private OwnerDrawPropertyBag (Color fore_color, Color back_color, Font font)
                {
                        this.fore_color = fore_color;
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThreadExceptionDialog.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThreadExceptionDialog.cs
new file mode 100644 (file)
index 0000000..76295fc
--- /dev/null
@@ -0,0 +1,213 @@
+//
+// System.Windows.Forms.ThreadExceptionDialog.cs
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Autors:
+//             Marek Safar     marek.safar@seznam.cz
+//
+// Copyright (C) Novell Inc., 2004
+
+// COMPLETE - BUT DISABLED TEXTBOX
+
+using System;
+using System.Text;
+using System.Reflection;
+
+namespace System.Windows.Forms
+{
+       public class ThreadExceptionDialog: Form
+       {
+               Exception e;
+               bool details;
+
+               private System.Windows.Forms.Button buttonIgnore;
+               private System.Windows.Forms.Button buttonAbort;
+               private System.Windows.Forms.Button buttonDetails;
+               private System.Windows.Forms.Label labelException;
+               private System.Windows.Forms.Label label1;
+#if TEXTBOX
+               private System.Windows.Forms.TextBox textBoxDetails;
+#endif
+               private System.Windows.Forms.Label helpText;
+
+               private void InitializeComponent()
+               {
+                       this.helpText = new System.Windows.Forms.Label();
+                       this.buttonAbort = new System.Windows.Forms.Button();
+                       this.buttonIgnore = new System.Windows.Forms.Button();
+                       this.buttonDetails = new System.Windows.Forms.Button();
+                       this.labelException = new System.Windows.Forms.Label();
+#if TEXTBOX
+                       this.textBoxDetails = new System.Windows.Forms.TextBox();
+#endif
+                       this.label1 = new System.Windows.Forms.Label();
+                       this.SuspendLayout();
+                       // 
+                       // helpText
+                       // 
+                       this.helpText.Location = new System.Drawing.Point(60, 8);
+                       this.helpText.Name = "helpText";
+                       this.helpText.Size = new System.Drawing.Size(356, 40);
+                       this.helpText.TabIndex = 0;
+                       this.helpText.Text = "An unhandled exception has occurred in you application. If you click Ignore the a" +
+                               "pplication will ignore this error and attempt to continue. If you click Abort, t" +
+                               "he application will quit immediately.";
+                       // 
+                       // buttonAbort
+                       // 
+                       this.buttonAbort.DialogResult = System.Windows.Forms.DialogResult.Abort;
+                       this.buttonAbort.Location = new System.Drawing.Point(332, 112);
+                       this.buttonAbort.Name = "buttonAbort";
+                       this.buttonAbort.Size = new System.Drawing.Size(85, 23);
+                       this.buttonAbort.TabIndex = 4;
+                       this.buttonAbort.Text = "&Abort";
+                       this.buttonAbort.Click += new System.EventHandler(this.buttonAbort_Click);
+                       // 
+                       // buttonIgnore
+                       // 
+                       this.buttonIgnore.DialogResult = System.Windows.Forms.DialogResult.Ignore;
+                       this.buttonIgnore.Location = new System.Drawing.Point(236, 112);
+                       this.buttonIgnore.Name = "buttonIgnore";
+                       this.buttonIgnore.Size = new System.Drawing.Size(85, 23);
+                       this.buttonIgnore.TabIndex = 3;
+                       this.buttonIgnore.Text = "&Ignore";
+                       // 
+                       // buttonDetails
+                       // 
+                       this.buttonDetails.Location = new System.Drawing.Point(140, 112);
+                       this.buttonDetails.Name = "buttonDetails";
+                       this.buttonDetails.Size = new System.Drawing.Size(85, 23);
+                       this.buttonDetails.TabIndex = 2;
+                       this.buttonDetails.Text = "Show &Details";
+                       this.buttonDetails.Click += new System.EventHandler(this.buttonDetails_Click);
+                       // 
+                       // labelException
+                       // 
+                       this.labelException.Location = new System.Drawing.Point(60, 64);
+                       this.labelException.Name = "labelException";
+                       this.labelException.Size = new System.Drawing.Size(356, 32);
+                       this.labelException.TabIndex = 1;
+                       // 
+                       // textBoxDetails
+                       // 
+#if TEXTBOX
+                       this.textBoxDetails.Location = new System.Drawing.Point(8, 168);
+                       this.textBoxDetails.Multiline = true;
+                       this.textBoxDetails.Name = "textBoxDetails";
+                       this.textBoxDetails.ReadOnly = true;
+                       this.textBoxDetails.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+                       this.textBoxDetails.Size = new System.Drawing.Size(408, 196);
+                       this.textBoxDetails.TabIndex = 5;
+                       this.textBoxDetails.TabStop = false;
+                       this.textBoxDetails.Text = "";
+                       this.textBoxDetails.WordWrap = false;
+#endif
+                       // 
+                       // label1
+                       // 
+                       this.label1.Location = new System.Drawing.Point(8, 148);
+                       this.label1.Name = "label1";
+                       this.label1.Size = new System.Drawing.Size(100, 16);
+                       this.label1.TabIndex = 0;
+                       this.label1.Text = "Exception details";
+                       // 
+                       // ThreadExceptionDialog
+                       // 
+                       this.AcceptButton = this.buttonIgnore;
+                       this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+                       this.CancelButton = this.buttonAbort;
+                       this.ClientSize = new System.Drawing.Size(428, 374);
+                       this.Controls.Add(this.label1);
+#if TEXTBOX
+                       this.Controls.Add(this.textBoxDetails);
+#endif
+                       this.Controls.Add(this.labelException);
+                       this.Controls.Add(this.buttonDetails);
+                       this.Controls.Add(this.buttonIgnore);
+                       this.Controls.Add(this.buttonAbort);
+                       this.Controls.Add(this.helpText);
+                       this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+                       this.MaximizeBox = false;
+                       this.MinimizeBox = false;
+                       this.Name = "ThreadExceptionDialog";
+                       this.ShowInTaskbar = false;
+                       this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+                       this.TopMost = true;
+                       this.ResumeLayout(false);
+               }
+       
+               public ThreadExceptionDialog (Exception e)
+               {
+                       this.e = e;
+                       InitializeComponent ();
+
+                       this.labelException.Text = e.Message;
+                       if (Form.ActiveForm != null)
+                               this.Text = Form.ActiveForm.Text;
+                       else
+                               this.Text = "Mono";
+                       this.buttonAbort.Enabled = Application.AllowQuit;
+                       RefreshDetails ();
+                       FillExceptionDetails ();
+               }
+
+               void buttonDetails_Click(object sender, System.EventArgs e)
+               {
+                       details = !details;
+                       RefreshDetails ();
+               }
+
+               void FillExceptionDetails ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       sb.Append (e.ToString ());
+                       sb.Append (Environment.NewLine + Environment.NewLine);
+                       sb.Append ("Loaded assemblies:" + Environment.NewLine + Environment.NewLine);
+
+                       foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) {
+                               AssemblyName an = a.GetName ();
+                               sb.AppendFormat ("Name:\t{0}" + Environment.NewLine, an.Name);
+                               sb.AppendFormat ("Version:\t{0}" + Environment.NewLine, an.Version);
+                               sb.AppendFormat ("Location:\t{0}" + Environment.NewLine, an.CodeBase);
+                               sb.Append (Environment.NewLine);
+                       }
+#if TEXTBOX
+                       textBoxDetails.Text = sb.ToString ();
+#endif
+               }
+
+               void RefreshDetails ()
+               {
+                       if (details) {
+                               buttonDetails.Text = "Hide &Details";
+                               Height = 410;
+                               return;
+                       }
+                       buttonDetails.Text = "Show &Details";
+                       Height = 180;
+               }
+
+               void buttonAbort_Click(object sender, System.EventArgs e)
+               {
+                       Application.Exit ();
+               }
+       }
+}
index c77c97c7773392916f077afcd8735ee6757b77b4..bf597a27993b8216f2d79c0d3d7ac950d0c58ebe 100644 (file)
@@ -30,7 +30,7 @@ using System.Runtime.Serialization;
 namespace System.Windows.Forms {
 
        [Serializable]
-       public class TreeNode : MarshalByRefObject /*, ICloneable, ISerializable */ {
+       public class TreeNode : MarshalByRefObject, ICloneable /*, ISerializable */ {
 
                private TreeView tree_view;
                internal TreeNode parent;
@@ -38,8 +38,7 @@ namespace System.Windows.Forms {
 
                private string text;
                private int image_index = -1;
-               private int selected_image_index;
-               private string full_path;
+               private int selected_image_index = -1;
                internal TreeNodeCollection nodes;
                
                private bool is_expanded = true;
@@ -73,7 +72,7 @@ namespace System.Windows.Forms {
                public TreeNode (string text, int image_index, int selected_image_index) : this (text)
                {
                        this.image_index = image_index;
-                       this.selected_image_index = image_index;
+                       this.selected_image_index = selected_image_index;
                }
 
                public TreeNode (string text, int image_index, int selected_image_index,
@@ -96,6 +95,24 @@ namespace System.Windows.Forms {
                        }
                }
 
+               #region ICloneable Members
+
+               public object Clone()
+               {
+                       TreeNode tn = new TreeNode (text, image_index, selected_image_index);
+                       if (nodes != null) {
+                               foreach (TreeNode child in nodes)
+                                       tn.Nodes.Add ((TreeNode)child.Clone ());
+                       }
+                       tn.Tag = tag;
+                       tn.Checked = Checked;
+                       if (prop_bag != null)
+                               tn.prop_bag = OwnerDrawPropertyBag.Copy (prop_bag);
+                       return tn;
+               }
+
+               #endregion
+
                public TreeNode Parent {
                        get {
                                if (tree_view != null && tree_view.root_node == parent)
@@ -128,18 +145,36 @@ namespace System.Windows.Forms {
                }
 
                public Color BackColor {
-                       get { return prop_bag.BackColor; }
-                       set { prop_bag.BackColor = value; }
+                       get { 
+                               return prop_bag == null ? Color.Empty : prop_bag.BackColor;
+                       }
+                       set { 
+                               if (prop_bag == null)
+                                       prop_bag = new OwnerDrawPropertyBag ();
+                               prop_bag.BackColor = value;
+                       }
                }
 
                public Color ForeColor {
-                       get { return prop_bag.ForeColor; }
-                       set { prop_bag.ForeColor = value; }
+                       get { 
+                               return prop_bag == null ? Color.Empty : prop_bag.ForeColor;
+                       }
+                       set {
+                               if (prop_bag == null)
+                                       prop_bag = new OwnerDrawPropertyBag ();
+                               prop_bag.ForeColor = value;
+                       }
                }
 
                public Font NodeFont {
-                       get { return prop_bag.Font; }
-                       set { prop_bag.Font = value; }
+                       get {
+                               return prop_bag == null ? null : prop_bag.Font;
+                       }
+                       set {
+                               if (prop_bag == null)
+                                       prop_bag = new OwnerDrawPropertyBag (); 
+                               prop_bag.Font = value;
+                       }
                }
 
                public TreeNodeCollection Nodes {
@@ -160,21 +195,27 @@ namespace System.Windows.Forms {
 
                public string FullPath {
                        get {
-                               if (full_path != null)
-                                       return full_path;
+                               if (tree_view == null)
+                                       throw new Exception ("No TreeView associated");
 
                                StringBuilder builder = new StringBuilder ();
-                               string ps = (TreeView == null ? "/" : TreeView.PathSeparator);
-                               for (int i = 0; i < nodes.Count; i++) {
-                                       builder.Append (nodes [i].Text);
-                                       if (i - 1 != nodes.Count)
-                                               builder.Append (ps);
-                               }
-                               full_path = builder.ToString ();
-                               return full_path;
+                               BuildFullPath (builder);
+                               return builder.ToString ();
                        }
                }
 
+               bool BuildFullPath (StringBuilder path)
+               {
+                       if (parent == null)
+                               return false;
+
+                       if (parent.BuildFullPath (path))
+                               path.Append (tree_view.PathSeparator);
+
+                       path.Append (text);
+                       return true;
+               }
+
                public bool IsExpanded {
                        get { return is_expanded; }
                }
@@ -225,7 +266,7 @@ namespace System.Windows.Forms {
 
                public TreeNode LastNode {
                        get {
-                               return Nodes [Nodes.Count - 1];
+                               return (nodes == null || nodes.Count == 0) ? null : nodes [nodes.Count - 1];
                        }
                }
 
index 31a9aa39eb27b02989ae50fb302b5de3db6d6302..94fea9217ae93ac75215dbb271de922ded7a00db 100644 (file)
@@ -106,6 +106,9 @@ namespace System.Windows.Forms {
 
                public virtual int Add (TreeNode node)
                {
+                       if (node == null)
+                               throw new ArgumentNullException("node");
+
                        if (owner != null && owner.TreeView != null && owner.TreeView.Sorted)
                                return AddSorted (node);
                        SetData (node);
@@ -120,6 +123,9 @@ namespace System.Windows.Forms {
 
                public virtual void AddRange (TreeNode [] nodes)
                {
+                       if (nodes == null)
+                               throw new ArgumentNullException("node");
+
                        // We can't just use Array.Copy because the nodes also
                        // need to have some properties set when they are added.
                        for (int i = 0; i < nodes.Length; i++)
index dea698844b034a8e69e437b4e8df2779b5325e64..5ce718fd1b10642e77ae2abd7cf593cd22a7d10e 100644 (file)
@@ -157,7 +157,7 @@ namespace System.Windows.Forms {
                }
 
                public override Color BackColor {
-                       get { return base.BackColor; }
+                       get { return SystemColors.Window; }
                        set { base.BackColor = value; }
                }
 
@@ -540,12 +540,14 @@ namespace System.Windows.Forms {
 
                        foreach (TreeNode node in nodes) {
                                DrawNode (node, ref depth, ref node_count, item_height,
-                                               font, ref visible_node_count, height, fill.Width);
+                                               font, ref visible_node_count, height);
                                depth = 0;
                        }
 
-                       if (add_hscroll)
+                       if (max_node_width > ClientRectangle.Width) {
+                               add_hscroll = true;
                                AddHorizontalScrollBar ();
+                       }
 
                        if (add_vscroll)
                                AddVerticalScrollBar (node_count, vclip);
@@ -647,7 +649,7 @@ namespace System.Windows.Forms {
                }
 
                private void DrawNode (TreeNode node, ref int depth, ref int node_count, int item_height,
-                               Font font, ref int visible_node_count, int max_height, int max_width)
+                               Font font, ref int visible_node_count, int max_height)
                {
                        node_count++;
                        int x = (!show_root_lines && node.Parent != null ? depth  - 1 : depth) * indent;
@@ -690,18 +692,15 @@ namespace System.Windows.Forms {
                                y += item_height + 1;
                        }
 
-                       if (node.Bounds.Right > max_width) {
-                               add_hscroll = true;
-                               if (node.Bounds.Right > max_node_width)
-                                       max_node_width = node.Bounds.Right;
-                       }
+                       if (node.Bounds.Right > max_node_width)
+                               max_node_width = node.Bounds.Right;
 
                        depth++;
                        if (node.IsExpanded) {
                                for (int i = 0; i < _n_count; i++) {
                                        int tdepth = depth;
                                        DrawNode (node.nodes [i], ref tdepth, ref node_count, item_height,
-                                                       font, ref visible_node_count, max_height, max_width);
+                                                       font, ref visible_node_count, max_height);
                                }
                        }
 
@@ -715,7 +714,7 @@ namespace System.Windows.Forms {
                {
                        vbar.Maximum = total_nodes;
                        int height = ClientRectangle.Height;
-                       
+
                        vbar.LargeChange = height / ItemHeight;
 
                        if (add_hscroll)
@@ -751,6 +750,12 @@ namespace System.Windows.Forms {
 
                private void SizeChangedHandler (object sender, EventArgs e)
                {
+                       
+                       if (max_node_width > ClientRectangle.Width) {
+                               add_hscroll = true;
+                               AddHorizontalScrollBar ();
+                       }
+
                        if (vbar != null) {
                                vbar.Left = Right - vbar.Width;
                                vbar.Height = Height;
index 566978899669c432d33d4bfb580c8ea04a413fe5..0b52490e96ee8c8e5fea72608e7a86affdddccf1 100644 (file)
@@ -1 +1,3 @@
 System.Windows.Forms/TestImageIndexConverter.cs
+System.Windows.Forms/TreeNodeTest.cs
+System.Windows.Forms/TreeViewTest.cs
index 6b0822c2bb19cac196398d0a2b29fb38ea89e85d..246b4b663e52398d22671d8a253390f65239c0b0 100644 (file)
@@ -102,24 +102,33 @@ public class TreeNodeTest {
                string s = new TreeNode ("").FullPath;
        }
 
-       [Test, Ignore ("TODO")]
+       [Test]
        public void FullPathTest ()
        {
                TreeNode tn_1 = new TreeNode ("A");
                TreeNode tn_2 = new TreeNode ("B");
                tn_2.Nodes.Add (tn_1);
-               Assert.AreEqual (@"A\B", tn_1.FullPath);
 
+               TreeView tv = new TreeView ();
+               tv.Nodes.Add (tn_1);
+               tv.Nodes [0].Nodes.Add (tn_2);
+
+               Assert.AreEqual ("A", tn_1.FullPath, "#1");
+               Assert.AreEqual ("A", tv.Nodes[0].FullPath, "#2");
+               Assert.AreEqual (@"A\B", tn_2.FullPath, "#3");
+               tv.PathSeparator = "_separator_";
+               Assert.AreEqual ("A_separator_B", tn_2.FullPath, "#4");
        }
 
        [Test]
        public void CloneTest ()
        {
-               // TODO: Add draw oriented fields will be implemented
-
                TreeNode orig = new TreeNode ("text", 2, 3, new TreeNode [] { new TreeNode ("child", 22, 33) });
                orig.Tag = FlatStyle.Flat;
                orig.Checked = true;
+               orig.BackColor = System.Drawing.Color.AliceBlue;
+               orig.ForeColor = System.Drawing.Color.Beige;
+
                TreeNode clone = (TreeNode)orig.Clone ();
                Assert.AreEqual ("text", clone.Text, "#1");
                Assert.AreEqual (2, clone.ImageIndex, "#2");
@@ -129,6 +138,8 @@ public class TreeNodeTest {
                Assert.IsTrue (clone.Checked, "#6");
                Assert.AreEqual ("child", clone.Nodes [0].Text, "#10");
                Assert.AreEqual (22, clone.Nodes [0].ImageIndex, "#11");
+               Assert.AreEqual (System.Drawing.Color.AliceBlue, clone.BackColor, "#12");
+               Assert.AreEqual (System.Drawing.Color.Beige, clone.ForeColor, "#13");
        }
 
 }
\ No newline at end of file
diff --git a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs
new file mode 100644 (file)
index 0000000..9f06ce1
--- /dev/null
@@ -0,0 +1,33 @@
+using System;
+using NUnit.Framework;
+using System.Windows.Forms;
+using System.Drawing;
+
+[TestFixture]
+public class TreeViewTest {
+
+       [Test]
+       public void DefaultCtor ()
+       {
+               TreeView tv = new TreeView ();
+               Assert.AreEqual (121, tv.Width, "#1");
+               Assert.AreEqual (97, tv.Height, "#2");
+               //Assert.AreEqual (BorderStyle.Fixed3D, tv.BorderStyle, "#3");
+
+               // Windows specific
+               Assert.AreEqual (SystemColors.Window, tv.BackColor);
+       }
+
+       [Test]
+       public void SimpleShowTest ()
+       {
+               Form f = new Form ();
+               TreeView tv = new TreeView ();
+               //tv.BorderStyle = BorderStyle.FixedSingle;
+               tv.Location = new Point (20, 20);
+               //tv.Text = "adssssss";
+
+               f.Controls.Add (tv);
+               f.Show ();
+       }
+}
index 6fecee3629bd1e3e338194bae5c7350507e13e56..51d448d3716ebc9761b65b07482ad4ee8651caef 100644 (file)
@@ -81,7 +81,6 @@ namespace nunit.support
                 public bool Equals(dbl that) { return d == that.d; }\r
             }\r
 \r
-#if FIXME\r
                        [Test]\r
                        public void GenericC()\r
                        {\r
@@ -93,7 +92,6 @@ namespace nunit.support
                                Assert.AreEqual(0, h.Compare(s, t));\r
                                Assert.IsTrue(h.Compare(s, u) < 0);\r
                        }\r
-#endif\r
 \r
 \r
                        [Test]\r
@@ -109,7 +107,6 @@ namespace nunit.support
                        }\r
 \r
 \r
-#if FIXME\r
                        [Test]\r
                        public void GenericCViaBuilder()\r
                        {\r
@@ -145,7 +142,6 @@ namespace nunit.support
                                Assert.AreEqual(0, h.Compare(s, t));\r
                                Assert.IsTrue(h.Compare(s, u) < 0);\r
                        }\r
-#endif\r
 \r
                }\r
 \r
index b0da07734cc7bbf6a32607c87b894569efb6ec04..1b350736cb547649667fb7887bb867430bdacc27 100644 (file)
@@ -1,3 +1,19 @@
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * hashing/HashTableTests.cs: Disabled some tests which make
+       assumptions about the ordering of elements in the hashtable.  They
+       also do not work on Windows.
+       * hashing/HashBagTests.cs: Likewise.
+       * hashing/HashDictionaryTests.cs: Likewise.
+
+2004-12-03  Martin Baulig  <martin@ximian.com>
+
+       * arrays/SortedArrayTests.cs: Removed the exception message from
+       the [ExpectedException(typeof(ArgumentOutOfRangeException))].
+
+       * trees/RedBlackTreeSetTests.cs: Likewise.
+       * trees/Bag.cs: Likewise.
+
 2004-11-26  Martin Baulig  <martin@ximian.com>
 
        * */*.cs: Added some more `#if FIXME's to comment out tests which
index d57eb74ffd26ca62c7c0fd59d2eb7d83faa13869..b33cf88d989ce999cb2d5f3624835af8851534a8 100644 (file)
@@ -1569,7 +1569,6 @@ namespace nunit.arrays.list
                        [Test]\r
                        public void MapEtc()\r
                        {\r
-#if FIXME\r
                                ArrayList<double> dbl = (ArrayList<double>)view.Map(new Mapper<int,double>(delegate(int i){return i/10.0;}));\r
 \r
                                Assert.IsTrue(dbl.Check());\r
@@ -1580,7 +1579,6 @@ namespace nunit.arrays.list
                                list = (ArrayList<int>)view.FindAll(new Filter<int>(delegate(int i){return i%4==1;}));\r
                                Assert.IsTrue(list.Check());\r
                                Assert.IsTrue(IC.eq(list, 1, 1, 5, 9));\r
-#endif\r
                        }\r
 \r
 \r
index 0a1ec89970f781603c6f7b3abf49df8f01c1a520..7bf6e23e6dc4e617e65220d2634f3e389dcd0b03 100644 (file)
@@ -1006,7 +1006,6 @@ namespace nunit.arrays.hashed
                }\r
 \r
 \r
-#if FIXME\r
                [TestFixture]\r
                public class Combined\r
                {\r
@@ -1095,7 +1094,6 @@ namespace nunit.arrays.hashed
                                Assert.IsFalse(lst.RemoveWithReturn(ref p));\r
                        }\r
                }\r
-#endif\r
 \r
                [TestFixture]\r
                public class Sorting\r
@@ -1346,7 +1344,6 @@ namespace nunit.arrays.hashed
                        [Test]\r
                        public void MapEtc()\r
                        {\r
-#if FIXME\r
                                ArrayList<double> dbl = (ArrayList<double>)view.Map(new Mapper<int,double>(delegate(int i){return i/10.0;}));\r
 \r
                                Assert.IsTrue(dbl.Check());\r
@@ -1358,7 +1355,6 @@ namespace nunit.arrays.hashed
 \r
                                Assert.IsTrue(list2.Check());\r
                                Assert.IsTrue(IC.eq(list2, 1, 5, 9));\r
-#endif\r
                        }\r
 \r
 \r
index f40715691f2bad4fb1842f0a931e24864bcd4b9b..0670d88f3c41edb5e72849e274abd0dfd624af46 100644 (file)
@@ -719,7 +719,7 @@ namespace nunit.arrays.sorted
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was -2.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void PredecessorTooLow1()\r
                {\r
                        tree.Predecessor(-2);\r
@@ -727,7 +727,7 @@ namespace nunit.arrays.sorted
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was 0.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void PredecessorTooLow2()\r
                {\r
                        tree.Predecessor(0);\r
@@ -752,7 +752,7 @@ namespace nunit.arrays.sorted
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was -1.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void WeakPredecessorTooLow1()\r
                {\r
                        tree.WeakPredecessor(-1);\r
@@ -776,7 +776,7 @@ namespace nunit.arrays.sorted
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 38.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void SuccessorTooHigh1()\r
                {\r
                        tree.Successor(38);\r
@@ -784,7 +784,7 @@ namespace nunit.arrays.sorted
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 39.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void SuccessorTooHigh2()\r
                {\r
                        tree.Successor(39);\r
@@ -809,7 +809,7 @@ namespace nunit.arrays.sorted
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 39.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void WeakSuccessorTooHigh1()\r
                {\r
                        tree.WeakSuccessor(39);\r
@@ -1468,7 +1468,6 @@ namespace nunit.arrays.sorted
 \r
        namespace MultiOps\r
        {\r
-#if FIXME\r
                [TestFixture]\r
                public class AddAll\r
                {\r
@@ -1529,7 +1528,6 @@ namespace nunit.arrays.sorted
                        [TearDown]\r
                        public void Dispose() { array = null; }\r
                }\r
-#endif\r
 \r
 \r
 \r
@@ -1788,7 +1786,6 @@ namespace nunit.arrays.sorted
 \r
 \r
 \r
-#if FIXME_THREADING_TESTS\r
        namespace Sync\r
        {\r
                [TestFixture]\r
@@ -1979,7 +1976,6 @@ namespace nunit.arrays.sorted
                        public void Dispose() { tree = null; }\r
                }\r
        }\r
-#endif\r
 \r
 \r
 \r
index 28c70dc5d5a606d4f001f66b1e532fa0167b03cd..c673f2a34fc37b0aef7f665cd9570abdf49d34c3 100644 (file)
@@ -26,7 +26,6 @@ using NUnit.Framework;
 using MSG = System.Collections.Generic;\r
 namespace nunit.hashtable.bag\r
 {\r
-#if FIXME\r
        [TestFixture]\r
        public class Combined\r
        {\r
@@ -126,10 +125,8 @@ namespace nunit.hashtable.bag
                        Assert.IsFalse(lst.RemoveWithReturn(ref p));\r
                }\r
        }\r
-#endif\r
 \r
 \r
-#if FIXME\r
        [TestFixture]\r
        public class CollectionOrSink\r
        {\r
@@ -199,6 +196,7 @@ namespace nunit.hashtable.bag
 \r
 \r
                [Test]\r
+               [Ignore("This is also failing on windows. Martin")]\r
                public void RemoveAllCopies()\r
                {\r
                        hashbag.Add(5);hashbag.Add(7);hashbag.Add(5);\r
@@ -300,10 +298,8 @@ namespace nunit.hashtable.bag
                [TearDown]\r
                public void Dispose() { hashbag = null; }\r
        }\r
-#endif\r
 \r
 \r
-#if FIXME\r
        [TestFixture]\r
        public class ArrayTest\r
        {\r
@@ -356,6 +352,7 @@ namespace nunit.hashtable.bag
 \r
 \r
                [Test]\r
+               [Ignore("This is also failing on windows. Martin")]\r
                public void CopyTo()\r
                {\r
                        //Note: for small ints the itemhasher is the identity!\r
@@ -404,10 +401,8 @@ namespace nunit.hashtable.bag
                        hashbag.CopyTo(a, 9);\r
                }\r
        }\r
-#endif\r
 \r
 \r
-#if FIXME\r
        [TestFixture]\r
        public class HashingEquals\r
        {\r
@@ -466,6 +461,5 @@ namespace nunit.hashtable.bag
                        Assert.IsTrue(h1.Equals(h2));\r
                }\r
        }\r
-#endif\r
 }\r
 #endif\r
index 5716e7f9f2fc48b17a4b8d1e05cda5c7036bd273..e744678419843186da477c7a4095c0d31b6e3fb8 100644 (file)
@@ -202,6 +202,7 @@ namespace nunit.hashtable.dictionary
 \r
 \r
                [Test]\r
+               [Ignore("This is also failing on windows. Martin")]\r
                public void Keys()\r
                {\r
                        MSG.IEnumerator<string> keys = dict.Keys.GetEnumerator();\r
@@ -217,6 +218,7 @@ namespace nunit.hashtable.dictionary
 \r
 \r
                [Test]\r
+               [Ignore("This is also failing on windows. Martin")]\r
                public void Values()\r
                {\r
                        MSG.IEnumerator<string> values = dict.Values.GetEnumerator();\r
@@ -232,6 +234,7 @@ namespace nunit.hashtable.dictionary
 \r
 \r
                [Test]\r
+               [Ignore("This is also failing on windows. Martin")]\r
                public void NormalUse()\r
                {\r
                        Assert.IsTrue(dictenum.MoveNext());\r
index 7440c55d46705b6d41c4c67b8dec5c8627ec0f6a..f44a6d3389ee79c06e5560f3474a6fe820947da1 100644 (file)
@@ -81,6 +81,7 @@ namespace nunit.hashtable.set
 \r
 \r
                        [Test]\r
+                       [Ignore("This is also failing on windows. Martin")]\r
                        public void Apply()\r
                        {\r
                                int sum = 0;\r
@@ -357,6 +358,7 @@ namespace nunit.hashtable.set
 \r
 \r
                        [Test]\r
+                       [Ignore("This is also failing on windows. Martin")]\r
                        public void CopyTo()\r
                        {\r
                                //Note: for small ints the itemhasher is the identity!\r
@@ -564,6 +566,7 @@ namespace nunit.hashtable.set
 \r
 \r
                        [Test]\r
+                       [Ignore("This is also failing on windows. Martin")]\r
                        public void RemoveAllCopies()\r
                        {\r
                                hashset.Add(5);hashset.Add(7);hashset.Add(5);\r
@@ -670,7 +673,6 @@ namespace nunit.hashtable.set
                        public void Dispose() { hashset = null; }\r
                }\r
 \r
-#if FIXME\r
                [TestFixture]\r
                public class Combined\r
                {\r
@@ -770,7 +772,6 @@ namespace nunit.hashtable.set
                                Assert.IsFalse(lst.RemoveWithReturn(ref p));\r
                        }\r
                }\r
-#endif\r
        }\r
 \r
 \r
index 88a79c36ade3d4215e6b6a8f72a63f2602d111a8..47b069918c6a091427390807492b945b85bb4272 100644 (file)
@@ -782,7 +782,6 @@ namespace nunit.linkedlists.hashed
                }\r
 \r
 \r
-#if FIXME\r
                [TestFixture]\r
                public class Combined\r
                {\r
@@ -872,7 +871,6 @@ namespace nunit.linkedlists.hashed
                                Assert.IsFalse(lst.RemoveWithReturn(ref p));\r
                        }\r
                }\r
-#endif\r
 \r
                [TestFixture]\r
                public class Inserting\r
@@ -1393,7 +1391,6 @@ namespace nunit.linkedlists.hashed
                        [Test]\r
                        public void MapEtc()\r
                        {\r
-#if FIXME\r
                                LinkedList<double> dbl = (LinkedList<double>)view.Map(new Mapper<int,double>(delegate(int i){return i/10.0;}));\r
 \r
                                Assert.IsTrue(dbl.Check());\r
@@ -1405,7 +1402,6 @@ namespace nunit.linkedlists.hashed
 \r
                                Assert.IsTrue(list2.Check());\r
                                Assert.IsTrue(IC.eq(list2, 1, 5, 9));\r
-#endif\r
                        }\r
 \r
 \r
index f52f682f3a46de2643871cbaba3f724808d592bd..b2ae4a3e8677766b4b3b85ebc19250d9fe5770c0 100644 (file)
@@ -1540,7 +1540,6 @@ namespace nunit.linkedlists.plain
                        [Test]\r
                        public void MapEtc()\r
                        {\r
-#if FIXME\r
                                LinkedList<double> dbl = (LinkedList<double>)view.Map(new Mapper<int,double>(delegate(int i){return i/10.0;}));\r
 \r
                                Assert.IsTrue(dbl.Check());\r
@@ -1551,7 +1550,6 @@ namespace nunit.linkedlists.plain
                                list = (LinkedList<int>)view.FindAll(new Filter<int>(delegate(int i){return i%4==1;}));\r
                                Assert.IsTrue(list.Check());\r
                                Assert.IsTrue(IC.eq(list, 1, 1, 5, 9));\r
-#endif\r
                        }\r
 \r
 \r
index 42439cb47fd9529244e6578a5bfb345413c4f064..160aa4901743bc5fa2bf30a313cd8274d53b3b34 100644 (file)
@@ -906,7 +906,7 @@ namespace nunit.trees.TreeBag
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was -2.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void PredecessorTooLow1()\r
                {\r
                        tree.Predecessor(-2);\r
@@ -914,7 +914,7 @@ namespace nunit.trees.TreeBag
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was 0.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void PredecessorTooLow2()\r
                {\r
                        tree.Predecessor(0);\r
@@ -939,7 +939,7 @@ namespace nunit.trees.TreeBag
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was -2.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void WeakPredecessorTooLow1()\r
                {\r
                        tree.WeakPredecessor(-2);\r
@@ -963,7 +963,7 @@ namespace nunit.trees.TreeBag
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 38.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void SuccessorTooHigh1()\r
                {\r
                        tree.Successor(38);\r
@@ -971,7 +971,7 @@ namespace nunit.trees.TreeBag
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 39.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void SuccessorTooHigh2()\r
                {\r
                        tree.Successor(39);\r
@@ -996,7 +996,7 @@ namespace nunit.trees.TreeBag
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 39.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void WeakSuccessorTooHigh1()\r
                {\r
                        tree.WeakSuccessor(39);\r
index c41d6a61eaf0f7f34687dcc254aeeccf7671be62..a8ba41265ca7c5a7b8c03ade3b958364ffe98f35 100644 (file)
@@ -724,7 +724,7 @@ namespace nunit.trees.TreeSet
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was -2.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void PredecessorTooLow1()\r
                {\r
                        tree.Predecessor(-2);\r
@@ -732,7 +732,7 @@ namespace nunit.trees.TreeSet
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was 0.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void PredecessorTooLow2()\r
                {\r
                        tree.Predecessor(0);\r
@@ -757,7 +757,7 @@ namespace nunit.trees.TreeSet
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Below minimum of set\r\nParameter name: item\r\nActual value was -2.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void WeakPredecessorTooLow1()\r
                {\r
                        tree.WeakPredecessor(-2);\r
@@ -781,7 +781,7 @@ namespace nunit.trees.TreeSet
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 38.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void SuccessorTooHigh1()\r
                {\r
                        tree.Successor(38);\r
@@ -789,7 +789,7 @@ namespace nunit.trees.TreeSet
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 39.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void SuccessorTooHigh2()\r
                {\r
                        tree.Successor(39);\r
@@ -814,7 +814,7 @@ namespace nunit.trees.TreeSet
 \r
 \r
                [Test]\r
-               [ExpectedException(typeof(ArgumentOutOfRangeException), "Above maximum of set\r\nParameter name: item\r\nActual value was 39.")]\r
+               [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
                public void WeakSuccessorTooHigh1()\r
                {\r
                        tree.WeakSuccessor(39);\r
@@ -2293,7 +2293,6 @@ namespace nunit.trees.TreeSet
 \r
 \r
 \r
-#if FIXME_THREADING_TESTS\r
        namespace Sync\r
        {\r
                [TestFixture]\r
@@ -2484,7 +2483,6 @@ namespace nunit.trees.TreeSet
                        public void Dispose() { tree = null; }\r
                }\r
        }\r
-#endif\r
 \r
 \r
        namespace Hashing\r
index 3da9e27471fdc9c1f351d8828a56fe573cb73258..20c6d0eb11fe43a553b39cd82d3ba897da3d6b45 100644 (file)
@@ -12,7 +12,6 @@
 //
 // Copyright (c) 2002 Chew Keong TAN
 // All rights reserved.
-
 //
 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
 //
@@ -1021,7 +1020,7 @@ namespace Mono.Math {
 
                                r2.Normalize ();
 
-                               if (r2 < x) {
+                               if (r2 <= x) {
                                        Kernel.MinusEq (x, r2);
                                } else {
                                        BigInteger val = new BigInteger (Sign.Positive, kPlusOne + 1);
index 1a123e77926d6e64b4c281d6f036921115146bf9..48e0dd0b060dbfc237783472dd7e2d2bdbf77b96 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * BigInteger.cs: Fix issue #70169 in ModPow when modulus is a power of
+       two.
+
 2004-10-19  Sebastien Pouliot  <sebastien@ximian.com>
 
        * BigInteger.cs: Fix issue #68452 when Randomize was being called on a
index e3c6653e0b497eff2ad592253aed9289b712388c..a3ad9b5018b6a5689a7ae6ca0c6e526bb0f81c25 100644 (file)
@@ -55,5 +55,40 @@ namespace MonoTests.Mono.Math {
                        Assert.AreEqual (0, bi.BitCount (), "after randomize");
                        Assert.AreEqual (new BigInteger (0), bi, "Zero");
                }
-       }
+
+               [Test]\r
+               public void ModPow_0_Even ()\r
+               {
+                       BigInteger x = new BigInteger (1);
+                       BigInteger y = new BigInteger (0);
+                       BigInteger z = x.ModPow (y, 1024);
+                       Assert.AreEqual ("1", z.ToString (), "1 pow 0 == 1");
+               }\r
+\r
+               [Test]\r
+               public void ModPow_Big_Even ()\r
+               {\r
+                       // http://gcc.gnu.org/ml/java/2001-01/msg00150.html\r
+                       BigInteger x = BigInteger.Parse ("222556259477882361118129720038750144464896096345697329917462180806109470940281821580712930114298080816996240075704780895407778416354633927929850543336844729388676722554712356733107888579404671103423966348754128720372408391573576775380281687780687492527566938517625657849775850241884119610654472761291507970934");\r
+                       BigInteger y = BigInteger.Parse ("110319153937683287453746757581772092163629769182044007837690319614087550020383807943886070460712008994638849038231331120616035703719955147238394349941968802357224177878230564379014395900786093465543114548034361805469457605783731382574787980771957640613447628351175959168798011343064123908688343944150028709336");\r
+                       BigInteger z = BigInteger.Parse ("211455809992703561445401788842734346323873054957006050135582190157359001703882707072169880651159563587522668850959539052488297197610540840476872693108381476249027986010074543599432542677282684917897250864056294311624311681558854158430574409491081490219256907243905496547813878640883064959346343865887971384185");\r
+                       BigInteger a = z.ModPow (x, y);\r
+                       Assert.AreEqual ("89040229313686098274750802637193802904787850353791629688385431482589769348345172944539658366893587456857347312314974124445695423885005533414559099801699612294235861570065774222911180890417009385455826560773741520297884850460324781620974467560905975577765401911117379967692495136423710471201230243826129276993", a.ToString ());\r
+               }\r
+\r
+               [Test]\r
+               public void ModPow_2 ()\r
+               {\r
+                       // #70169\r
+                       BigInteger b = new BigInteger (10);\r
+                       BigInteger m = new BigInteger (32);\r
+                       // after 40 we start loosing double precision and result will differ\r
+                       for (int i=1; i < 40; i++) {\r
+                               BigInteger e = new BigInteger (i);\r
+                               BigInteger r = e.ModPow (b, m);\r
+                               long expected = (long) System.Math.Pow (i, 10) % 32;\r
+                               Assert.AreEqual (expected.ToString (), r.ToString (), i.ToString ());\r
+                       }\r
+               }\r
+       }\r
 }
index 69d30949539322107fd61bdbd50ddf80184a248a..33d87bbf1ee2976ce785a98b50ae3bb6786196ad 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-03  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * BigIntegerTest.cs: Added tests for ModPow when power is 0, for a 
+       known case that was faling in classpath and when modulo is a power of
+       two (bug #70169).
+
 2004-10-19  Sebastien Pouliot  <sebastien@ximian.com>
 
        * BigIntegerTest.cs: New. General unit tests for BigInteger.
index b2f20d6a283e0f503a4c7f36548bbe47f36e1529..5f5346b69edb0df2311fe09d504994a7e756db8c 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-01  Jackson Harper  <jackson@ximian.com>
+
+       * PEAPI.cs: Allow DataConstants underlying type to be set.
+
 2004-07-29  Martin Baulig  <martin@ximian.com>
 
        * PEAPI.cs (Module.Guid): New public property.
index d418671d2c1dbe949667872b699cfe34d6ab6f8c..6d171f6ade04f0621e15563c87ead6e8f9b01eca 100644 (file)
@@ -2219,7 +2219,7 @@ namespace PEAPI
     private uint dataOffset = 0;\r
 \r
     internal DataConstant() { }\r
-\r
+
     public uint DataOffset {\r
       get { return dataOffset; }\r
       set { dataOffset = value; }\r
@@ -2266,7 +2266,12 @@ namespace PEAPI
       this.val = val;\r
       size = (uint)val.Length;\r
     }\r
-\r
+
+    public Type Type {
+            get { return type; }
+            set { type = value; }
+    }
+
     internal sealed override uint GetBlobIndex(MetaData md) {\r
       if (!addedToBlobHeap) {\r
         blobIndex = md.AddToBlobHeap(val);\r
index 6745ee7caf02919e722acca22ee166a48d3b3d5b..a48f3f91065ba50803401ce29c57c6edc0b38483 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * OdbcParameter.cs: Fixed a null reference exception when a
+       parameter is created and its value is not set. #68750.
+
 2004-11-26  Sureshkumar T  <tsureshkumar@novell.com>
 
        * OdbcParameter.cs: Fixed Parameter Size property as well as
index bad499f6e65641189d2e3e65e26bdaa5812417b1..77c2d7e083c755df0d3a086518be63844f22239b 100644 (file)
@@ -265,10 +265,10 @@ namespace System.Data.Odbc
                }\r
 \r
                private void setBuffer() {\r
-                       // Load buffer with new value\r
-                       if (odbcType == OdbcType.Int)\r
-                               intbuf = (int)ParamValue;\r
-                       else {\r
+                       // Load buffer with new value
+                       if (odbcType == OdbcType.Int)
+                                intbuf = ParamValue == null ? new int () : (int) ParamValue;
+                        else {\r
                                string paramValueString = ParamValue.ToString();\r
                                // Treat everything else as a string\r
                                // Init string buffer\r
index 5946d18c138ebaaa81f4e002033415cc0fc94cbe..fe67755665a54752656ab8e32a4e7e7439a710f5 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * SoapHttpClientProtocol.cs: dispose the StreamReader that wraps the
+       response stream.
+
 2004-09-15  Lluis Sanchez Gual <lluis@novell.com>
 
        * Methods.cs: Use the service namespace as the base for the soap action.
index dc231ef96bdfab0991526a8ba6b76fd1201171cd..c8ac655761fb18aeb4230560c698265091ab0f6b 100644 (file)
@@ -269,13 +269,16 @@ namespace System.Web.Services.Protocols
                        \r
                        // Deserialize the response\r
 \r
-                       StreamReader reader = new StreamReader (stream, encoding, false);\r
-                       XmlTextReader xml_reader = new XmlTextReader (reader);\r
-\r
                        SoapHeaderCollection headers;\r
                        object content;\r
 \r
-                       WebServiceHelper.ReadSoapMessage (xml_reader, type_info, msi.Use, msi.ResponseSerializer, out content, out headers);\r
+                       using (StreamReader reader = new StreamReader (stream, encoding, false)) {
+                               XmlTextReader xml_reader = new XmlTextReader (reader);
+
+                               WebServiceHelper.ReadSoapMessage (xml_reader, type_info, msi.Use, msi.ResponseSerializer,
+                                                               out content, out headers);
+                       }
+
                        \r
                        if (content is Fault)\r
                        {\r
index ce123b9a087597f14f71c270a803d71dba2e7e01..e69472b27e4a0949bf0e2845db5a41ca0312adf6 100644 (file)
@@ -1,3 +1,16 @@
+2004-12-02  Lluis Sanchez Gual <lluis@novell.com>
+
+       * System.Web.dll.sources: Added new files:
+               System.Web.UI.WebControls/Menu.cs
+               System.Web.UI.WebControls/MenuEventArgs.cs
+               System.Web.UI.WebControls/MenuEventHandler.cs
+               System.Web.UI.WebControls/MenuItem.cs
+               System.Web.UI.WebControls/MenuItemBinding.cs
+               System.Web.UI.WebControls/MenuItemBindingCollection.cs
+               System.Web.UI.WebControls/MenuItemCollection.cs
+               System.Web.UI.WebControls/MenuItemStyle.cs
+               System.Web.UI.WebControls/MenuItemStyleCollection.cs
+
 2004-12-02  Lluis Sanchez Gual <lluis@novell.com>
 
        * Makefile: Added more TreeView resources.
index a8c2acff90776417445474bb44d2fcc80aecc0ed..c21f3b1b58ba6636d7052e5f7c8e9ffd63b14d0c 100644 (file)
@@ -1,3 +1,11 @@
+2004-12-03 Lluis Sanchez Gual <lluis@novell.com>
+
+       * MenuEventArgs.cs: Changed to sealed.
+       * TreeView.cs: Minor fix.
+       * Menu.cs, MenuItemBindingCollection.cs, MenuItemCollection.cs,
+       MenuItemStyle.cs, MenuItemBinding.cs, MenuItem.cs,
+       MenuItemStyleCollection.cs: Initial Menu code.
+
 2004-12-02 Lluis Sanchez Gual <lluis@novell.com>
 
        * TreeNodeBindingCollection.cs, TreeNodeStyleCollection.cs: 
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs b/mcs/class/System.Web/System.Web.UI.WebControls/Menu.cs
new file mode 100644 (file)
index 0000000..42f9ae6
--- /dev/null
@@ -0,0 +1,256 @@
+//
+// System.Web.UI.WebControls.Menu.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using System;
+using System.Collections;
+using System.Text;
+using System.ComponentModel;
+using System.Web.UI;
+using System.Web.Handlers;
+using System.Collections.Specialized;
+using System.IO;
+
+namespace System.Web.UI.WebControls
+{
+       public class Menu : HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer
+       {
+               MenuItemCollection items;
+               MenuItemBindingCollection dataBindings;
+               MenuItem selectedItem;
+               Hashtable bindings;
+               
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [Editor ("System.Web.UI.Design.MenuItemBindingsEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public virtual MenuItemBindingCollection DataBindings {
+                       get {
+                               if (dataBindings == null) {
+                                       dataBindings = new MenuItemBindingCollection ();
+                                       if (IsTrackingViewState)
+                                               ((IStateManager)dataBindings).TrackViewState();
+                               }
+                               return dataBindings;
+                       }
+               }
+
+               [DefaultValue (500)]
+               public virtual int DisappearAfter {
+                       get {
+                               object o = ViewState ["DisappearAfter"];
+                               if (o != null) return (int)o;
+                               return 500;
+                       }
+                       set {
+                               ViewState["DisappearAfter"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [UrlProperty]
+               [WebCategory ("Appearance")]
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public virtual string DynamicBottomSeparatorImageUrl {
+                       get {
+                               object o = ViewState ["dbsiu"];
+                               if (o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState["dbsiu"] = value;
+                       }
+               }
+
+/*             [DefaultValue (true)]
+               public virtual bool DynamicEnableDefaultPopOutImage {
+                       get {
+                               object o = ViewState ["dedpoi"];
+                               if (o != null) return (bool)o;
+                               return true;
+                       }
+                       set {
+                               ViewState["dedpoi"] = value;
+                       }
+               }
+*/
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [Editor ("System.Web.UI.Design.MenuItemCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public virtual MenuItemCollection Items {
+                       get {
+                               if (items == null) {
+                                       items = new MenuItemCollection (this);
+                                       if (IsTrackingViewState)
+                                               ((IStateManager)items).TrackViewState();
+                               }
+                               return items;
+                       }
+               }
+
+               [DefaultValue ('/')]
+               public virtual char PathSeparator {
+                       get {
+                               object o = ViewState ["PathSeparator"];
+                               if(o != null) return (char)o;
+                               return '/';
+                       }
+                       set {
+                               ViewState ["PathSeparator"] = value;
+                       }
+               }
+
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               public MenuItem SelectedItem {
+                       get { return selectedItem; }
+               }
+
+               internal void SetSelectedItem (MenuItem item)
+               {
+                       if (selectedItem == item) return;
+                       if (selectedItem != null)
+                               selectedItem.SelectedFlag = false;
+                       selectedItem = item;
+                       selectedItem.SelectedFlag = true;
+       //              OnSelectedItemChanged (new MenuItemEventArgs (selectedItem));
+               }
+               
+               public MenuItem FindItem (string valuePath)
+               {
+                       if (valuePath == null) throw new ArgumentNullException ("valuePath");
+                       string[] path = valuePath.Split (PathSeparator);
+                       int n = 0;
+                       MenuItemCollection col = Items;
+                       bool foundBranch = true;
+                       while (col.Count > 0 && foundBranch) {
+                               foundBranch = false;
+                               foreach (MenuItem item in col) {
+                                       if (item.Value == path [n]) {
+                                               if (++n == path.Length) return item;
+                                               col = item.ChildItems;
+                                               foundBranch = true;
+                                               break;
+                                       }
+                               }
+                       }
+                       return null;
+               }
+               
+               string GetBindingKey (string dataMember, int depth)
+               {
+                       return dataMember + " " + depth;
+               }
+               
+               internal MenuItemBinding FindBindingForItem (string type, int depth)
+               {
+                       if (bindings == null) return null;
+
+                       MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
+                       if (bin != null) return bin;
+                       
+                       bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
+                       if (bin != null) return bin;
+                       
+                       bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
+                       if (bin != null) return bin;
+                       
+                       bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
+                       return bin;
+               }
+               
+               protected internal override void PerformDataBinding ()
+               {
+                       base.PerformDataBinding ();
+                       HierarchicalDataSourceView data = GetData ("");
+                       IHierarchicalEnumerable e = data.Select ();
+                       foreach (object obj in e) {
+                               IHierarchyData hdata = e.GetHierarchyData (obj);
+                               MenuItem item = new MenuItem ();
+                               item.Bind (hdata);
+                               Items.Add (item);
+                       }
+               }
+               
+               void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
+               {
+               }
+               
+               protected override void TrackViewState()
+               {
+                       EnsureDataBound ();
+                       
+                       base.TrackViewState();
+                       if (dataBindings != null) {
+                               ((IStateManager)dataBindings).TrackViewState ();
+                       }
+                       if (items != null) {
+                               ((IStateManager)items).TrackViewState();;
+                       }
+               }
+
+               protected override object SaveViewState()
+               {
+                       object[] states = new object [2];
+                       states[0] = base.SaveViewState();
+                       states[1] = (dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState());
+                       states[2] = (items == null ? null : ((IStateManager)items).SaveViewState());
+
+                       for (int i = states.Length - 1; i >= 0; i--) {
+                               if (states [i] != null)
+                                       return states;
+                       }
+
+                       return null;
+               }
+
+               protected override void LoadViewState (object savedState)
+               {
+                       if (savedState == null)
+                               return;
+
+                       object [] states = (object []) savedState;
+                       base.LoadViewState (states[0]);
+                       
+                       if (states[1] != null)
+                               ((IStateManager)dataBindings).LoadViewState(states[8]);
+                       if (states[2] != null)
+                               ((IStateManager)Items).LoadViewState(states[9]);
+               }
+               
+               protected override void RenderContents (HtmlTextWriter writer)
+               {
+                       writer.WriteLine ("This is a menu");
+               }
+               
+       }
+}
+
+#endif
index 2457593991007313d2f96542b8b98326a9eab173..a0a6012dd29f3f92464bbf5a8bdd9f79981fde2f 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace System.Web.UI.WebControls
 {
-       public class MenuEventArgs : CommandEventArgs
+       public sealed class MenuEventArgs : CommandEventArgs
        {
                private MenuItem item; 
                private object source;
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/MenuItem.cs b/mcs/class/System.Web/System.Web.UI.WebControls/MenuItem.cs
new file mode 100644 (file)
index 0000000..cff024b
--- /dev/null
@@ -0,0 +1,494 @@
+//
+// System.Web.UI.WebControls.MenuItem.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+using System;
+using System.Collections;
+using System.Text;
+using System.ComponentModel;
+using System.Web.UI;
+
+namespace System.Web.UI.WebControls
+{
+       [ParseChildrenAttribute (true, "ChildItems")]
+       public sealed class MenuItem: IStateManager, ICloneable
+       {
+               StateBag ViewState = new StateBag ();
+               MenuItemCollection items;
+               bool marked;
+               Menu menu;
+               MenuItem parent;
+               int index;
+               string path;
+               int depth = -1;
+               
+               IHierarchyData hierarchyData;
+               bool gotBinding;
+               MenuItemBinding binding;
+               PropertyDescriptorCollection boundProperties;
+               
+               public MenuItem ()
+               {
+               }
+               
+               public MenuItem (string text)
+               {
+                       Text = text;
+               }
+               
+               public MenuItem (string text, string value)
+               {
+                       Text = text;
+                       Value = value;
+               }
+               
+               public MenuItem (string text, string value, string imageUrl)
+               {
+                       Text = text;
+                       Value = value;
+                       ImageUrl = imageUrl;
+               }
+               
+               public MenuItem (string text, string value, string imageUrl, string navigateUrl, string target)
+               {
+                       Text = text;
+                       Value = value;
+                       ImageUrl = imageUrl;
+                       NavigateUrl = navigateUrl;
+                       Target = target;
+               }
+               
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [Browsable (false)]
+               public int Depth {
+                       get {
+                               if (depth != -1) return depth;
+                               depth = 0;
+                               MenuItem nod = parent;
+                               while (nod != null) {
+                                       depth++;
+                                       nod = nod.parent;
+                               }
+                               return depth;
+                       }
+               }
+               
+               void ResetPathData ()
+               {
+                       path = null;
+                       depth = -1;
+                       gotBinding = false;
+               }
+               
+               internal Menu Menu {
+                       get { return menu; }
+                       set {
+                               if (SelectedFlag) {
+                                       if (value != null)
+                                               value.SetSelectedItem (this);
+                                       else if (menu != null)
+                                               menu.SetSelectedItem (null);
+                               }
+                               menu = value;
+                               if (items != null)
+                                       items.SetMenu (menu);
+                               ResetPathData ();
+                       }
+               }
+               
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [DefaultValue (false)]
+               [Browsable (false)]
+               public bool DataBound {
+                       get { return hierarchyData != null; }
+               }
+               
+               [DefaultValue (null)]
+               [Browsable (false)]
+               public object DataItem {
+                       get {
+                               if (hierarchyData == null) throw new InvalidOperationException ("MenuItem is not data bound.");
+                               return hierarchyData.Item;
+                       }
+               }
+               
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [DefaultValue ("")]
+               [Browsable (false)]
+               public string DataPath {
+                       get {
+                               if (hierarchyData == null) throw new InvalidOperationException ("MenuItem is not data bound.");
+                               return hierarchyData.Path;
+                       }
+               }
+               
+               [MergableProperty (false)]
+               [Browsable (false)]
+               [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
+               public MenuItemCollection ChildItems {
+                       get {
+                               if (items == null) {
+                                       if (DataBound)
+                                               FillBoundChildren ();
+                                       else
+                                               items = new MenuItemCollection (this);
+                                               
+                                       if (((IStateManager)this).IsTrackingViewState)
+                                               ((IStateManager)items).TrackViewState();
+                               }
+                               return items;
+                       }
+               }
+               
+               [DefaultValue ("")]
+               [UrlProperty]
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public string ImageUrl {
+                       get {
+                               object o = ViewState ["ImageUrl"];
+                               if (o != null) return (string)o;
+                               if (DataBound) {
+                                       MenuItemBinding bin = GetBinding ();
+                                       if (bin != null) {
+                                               if (bin.ImageUrlField != "")
+                                                       return (string) GetBoundPropertyValue (bin.ImageUrlField);
+                                               return bin.ImageUrl;
+                                       }
+                               }
+                               return "";
+                       }
+                       set {
+                               ViewState ["ImageUrl"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [UrlProperty]
+               [Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public string NavigateUrl {
+                       get {
+                               object o = ViewState ["NavigateUrl"];
+                               if (o != null) return (string)o;
+                               if (DataBound) {
+                                       MenuItemBinding bin = GetBinding ();
+                                       if (bin != null) {
+                                               if (bin.NavigateUrlField != "")
+                                                       return (string) GetBoundPropertyValue (bin.NavigateUrlField);
+                                               return bin.NavigateUrl;
+                                       }
+                               }
+                               return "";
+                       }
+                       set {
+                               ViewState ["NavigateUrl"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               public string Target {
+                       get {
+                               object o = ViewState ["Target"];
+                               if(o != null) return (string)o;
+                               if (DataBound) {
+                                       MenuItemBinding bin = GetBinding ();
+                                       if (bin != null) {
+                                               if (bin.TargetField != "")
+                                                       return (string) GetBoundPropertyValue (bin.TargetField);
+                                               return bin.Target;
+                                       }
+                               }
+                               return "";
+                       }
+                       set {
+                               ViewState ["Target"] = value;
+                       }
+               }
+
+               [Localizable (true)]
+               [DefaultValue ("")]
+               public string Text {
+                       get {
+                               object o = ViewState ["Text"];
+                               if (o != null) return (string)o;
+                               if (DataBound) {
+                                       MenuItemBinding bin = GetBinding ();
+                                       if (bin != null) {
+                                               string text;
+                                               if (bin.TextField != "")
+                                                       text = (string) GetBoundPropertyValue (bin.TextField);
+                                               else if (bin.Text != "")
+                                                       text = bin.Text;
+                                               else
+                                                       text = hierarchyData.ToString ();
+                                                       
+                                               if (bin.FormatString.Length != 0)
+                                                       text = string.Format (bin.FormatString, text);
+                                               return text;
+                                       }
+                                       return hierarchyData.ToString ();
+                               }
+                               return "";
+                       }
+                       set {
+                               ViewState ["Text"] = value;
+                       }
+               }
+
+               [Localizable (true)]
+               [DefaultValue ("")]
+               public string ToolTip {
+                       get {
+                               object o = ViewState ["ToolTip"];
+                               if(o != null) return (string)o;
+                               if (DataBound) {
+                                       MenuItemBinding bin = GetBinding ();
+                                       if (bin != null) {
+                                               if (bin.ToolTipField != "")
+                                                       return (string) GetBoundPropertyValue (bin.ToolTipField);
+                                               return bin.ToolTip;
+                                       }
+                               }
+                               return "";
+                       }
+                       set {
+                               ViewState ["ToolTip"] = value;
+                       }
+               }
+
+               [Localizable (true)]
+               [DefaultValue ("")]
+               public string Value {
+                       get {
+                               object o = ViewState ["Value"];
+                               if(o != null) return (string)o;
+                               if (DataBound) {
+                                       MenuItemBinding bin = GetBinding ();
+                                       if (bin != null) {
+                                               if (bin.ValueField != "")
+                                                       return (string) GetBoundPropertyValue (bin.ValueField);
+                                               if (bin.Value != "")
+                                                       return bin.Value;
+                                       }
+                                       return hierarchyData.ToString ();
+                               }
+                               return "";
+                       }
+                       set {
+                               ViewState ["Value"] = value;
+                       }
+               }
+               
+               [DefaultValue (false)]
+               public bool Selected {
+                       get {
+                               return SelectedFlag;
+                       }
+                       set {
+                               if (menu != null) {
+                                       if (!value && menu.SelectedItem == this)
+                                               menu.SetSelectedItem (null);
+                                       else if (value)
+                                               menu.SetSelectedItem (this);
+                               }
+                               else
+                                       SelectedFlag = value;
+                       }
+               }
+               
+               internal bool SelectedFlag {
+                       get {
+                               object o = ViewState ["Selected"];
+                               if(o != null) return (bool)o;
+                               return false;
+                       }
+                       set {
+                               ViewState ["Selected"] = value;
+                       }
+               }
+               
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [Browsable (false)]
+               public MenuItem Parent {
+                       get { return parent; }
+               }
+               
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [Browsable (false)]
+               public string ValuePath {
+                       get {
+                               if (menu == null) return Value;
+                               
+                               StringBuilder sb = new StringBuilder (Value);
+                               MenuItem item = parent;
+                               while (item != null) {
+                                       sb.Insert (0, menu.PathSeparator);
+                                       sb.Insert (0, item.Value);
+                                       item = item.Parent;
+                               }
+                               return sb.ToString ();
+                       }
+               }
+               
+               internal int Index {
+                       get { return index; }
+                       set { index = value; ResetPathData (); }
+               }
+               
+               internal void SetParent (MenuItem item) {
+                       parent = item;
+                       ResetPathData ();
+               }
+               
+               internal string Path {
+                       get {
+                               if (path != null) return path;
+                               StringBuilder sb = new StringBuilder (index.ToString());
+                               MenuItem item = parent;
+                               while (item != null) {
+                                       sb.Insert (0, '_');
+                                       sb.Insert (0, item.Index.ToString ());
+                                       item = item.Parent;
+                               }
+                               path = sb.ToString ();
+                               return path;
+                       }
+               }
+               
+               internal bool HasChildData {
+                       get { return items != null; }
+               }
+               
+               void IStateManager.LoadViewState (object savedState)
+               {
+                       if (savedState == null)
+                               return;
+
+                       object[] states = (object[]) savedState;
+                       ViewState.LoadViewState (states [0]);
+                       
+                       if (menu != null && SelectedFlag)
+                               menu.SetSelectedItem (this);
+                       
+                       if (states [1] != null)
+                               ((IStateManager)ChildItems).LoadViewState (states [1]);
+               }
+               
+               object IStateManager.SaveViewState ()
+               {
+                       object[] states = new object[2];
+                       states[0] = ViewState.SaveViewState();
+                       states[1] = (items == null ? null : ((IStateManager)items).SaveViewState());
+                       
+                       for (int i = 0; i < states.Length; i++) {
+                               if (states [i] != null)
+                                       return states;
+                       }
+                       return null;
+               }
+               
+               void IStateManager.TrackViewState ()
+               {
+                       if (marked) return;
+                       marked = true;
+                       ViewState.TrackViewState();
+
+                       if (items != null)
+                               ((IStateManager)items).TrackViewState ();
+               }
+               
+               bool IStateManager.IsTrackingViewState
+               {
+                       get { return marked; }
+               }
+               
+               internal void SetDirty ()
+               {
+                       ViewState.SetDirty ();
+               }
+               
+               object ICloneable.Clone ()
+               {
+                       MenuItem nod = new MenuItem ();
+                       foreach (DictionaryEntry e in ViewState)
+                               nod.ViewState [(string)e.Key] = e.Value;
+                               
+                       foreach (ICloneable c in ChildItems)
+                               nod.ChildItems.Add ((MenuItem)c.Clone ());
+                               
+                       return nod;
+               }
+               
+               internal void Bind (IHierarchyData hierarchyData)
+               {
+                       this.hierarchyData = hierarchyData;
+               }
+               
+               MenuItemBinding GetBinding ()
+               {
+                       if (menu == null) return null;
+                       if (gotBinding) return binding;
+                       binding = menu.FindBindingForItem (hierarchyData.Type, Depth);
+                       gotBinding = true;
+                       return binding;
+               }
+               
+               object GetBoundPropertyValue (string name)
+               {
+                       if (boundProperties == null) {
+                               ICustomTypeDescriptor desc = hierarchyData as ICustomTypeDescriptor;
+                               if (desc == null)
+                                       throw new InvalidOperationException ("Property '" + name + "' not found in data bound item");
+                               boundProperties = desc.GetProperties ();
+                       }
+                       
+                       PropertyDescriptor prop = boundProperties.Find (name, true);
+                       if (prop == null)
+                               throw new InvalidOperationException ("Property '" + name + "' not found in data bound item");
+                       return prop.GetValue (hierarchyData);
+               }
+
+               void FillBoundChildren ()
+               {
+                       items = new MenuItemCollection (this);
+                       if (!hierarchyData.HasChildren) return;
+
+                       IHierarchicalEnumerable e = hierarchyData.GetChildren ();
+                       foreach (object obj in e) {
+                               IHierarchyData hdata = e.GetHierarchyData (obj);
+                               MenuItem item = new MenuItem ();
+                               item.Bind (hdata);
+                               items.Add (item);
+                       }
+               }
+       }
+}
+
+#endif
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemBinding.cs b/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemBinding.cs
new file mode 100644 (file)
index 0000000..d7cfe75
--- /dev/null
@@ -0,0 +1,306 @@
+//
+// System.Web.UI.WebControls.MenuItemBinding.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+using System;
+using System.Collections;
+using System.Web.UI;
+using System.ComponentModel;
+
+namespace System.Web.UI.WebControls
+{
+       [DefaultProperty ("TextField")]
+       public sealed class MenuItemBinding: IStateManager, ICloneable, IDataSourceViewSchemaAccessor
+       {
+               StateBag ViewState = new StateBag ();
+               
+               [DefaultValue ("")]
+               public string DataMember {
+                       get {
+                               object o = ViewState ["DataMember"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["DataMember"] = value;
+                       }
+               }
+
+               [DefaultValue (-1)]
+               public int Depth {
+                       get {
+                               object o = ViewState ["Depth"];
+                               if (o != null) return (int) o;
+                               return -1;
+                       }
+                       set {
+                               ViewState ["Depth"] = value;
+                       }
+               }
+
+               [DefaultValue (true)]
+               public bool Enabled {
+                       get {
+                               object o = ViewState ["Enabled"];
+                               if (o != null) return (bool) o;
+                               return true;
+                       }
+                       set {
+                               ViewState ["Enabled"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string EnabledField {
+                       get {
+                               object o = ViewState ["EnabledField"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["EnabledField"] = value;
+                       }
+               }
+
+               [Localizable (true)]
+               [DefaultValue ("")]
+               public string FormatString {
+                       get {
+                               object o = ViewState ["FormatString"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["FormatString"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [UrlProperty]
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public string ImageUrl {
+                       get {
+                               object o = ViewState ["ImageUrl"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["ImageUrl"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string ImageUrlField {
+                       get {
+                               object o = ViewState ["ImageUrlField"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["ImageUrlField"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [UrlProperty]
+               [Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
+               public string NavigateUrl {
+                       get {
+                               object o = ViewState ["NavigateUrl"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["NavigateUrl"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string NavigateUrlField {
+                       get {
+                               object o = ViewState ["NavigateUrlField"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["NavigateUrlField"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               public string Target {
+                       get {
+                               object o = ViewState ["Target"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["Target"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string TargetField {
+                       get {
+                               object o = ViewState ["TargetField"];
+                               if (o != null) return (string) o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["TargetField"] = value;
+                       }
+               }
+
+               [Localizable (true)]
+               [DefaultValue ("")]
+               [WebSysDescription ("The display text of the menu item.")]
+               public string Text {
+                       get {
+                               object o = ViewState ["Text"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["Text"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string TextField {
+                       get {
+                               object o = ViewState ["TextField"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["TextField"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [Localizable (true)]
+               public string ToolTip {
+                       get {
+                               object o = ViewState ["ToolTip"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["ToolTip"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string ToolTipField {
+                       get {
+                               object o = ViewState ["ToolTipField"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["ToolTipField"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [Localizable (true)]
+               public string Value {
+                       get {
+                               object o = ViewState ["Value"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["Value"] = value;
+                       }
+               }
+
+               [DefaultValue ("")]
+               [TypeConverter ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
+               public string ValueField {
+                       get {
+                               object o = ViewState ["ValueField"];
+                               if(o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState ["ValueField"] = value;
+                       }
+               }
+
+               void IStateManager.LoadViewState (object savedState)
+               {
+                       ViewState.LoadViewState (savedState);
+               }
+               
+               object IStateManager.SaveViewState ()
+               {
+                       return ViewState.SaveViewState();
+               }
+               
+               void IStateManager.TrackViewState ()
+               {
+                       ViewState.TrackViewState ();
+               }
+               
+               bool IStateManager.IsTrackingViewState {
+                       get { return ViewState.IsTrackingViewState; }
+               }
+               
+               [MonoTODO]
+               object IDataSourceViewSchemaAccessor.DataSourceViewSchema {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+               
+               object ICloneable.Clone ()
+               {
+                       MenuItemBinding bin = new MenuItemBinding ();
+                       foreach (DictionaryEntry e in ViewState)
+                               bin.ViewState [(string)e.Key] = e.Value;
+                       return bin;
+               }
+
+               internal void SetDirty ()
+               {
+                       foreach (string key in ViewState.Keys)
+                               ViewState.SetItemDirty (key, true);
+               }
+       }
+}
+
+#endif
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemBindingCollection.cs b/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemBindingCollection.cs
new file mode 100644 (file)
index 0000000..0c81619
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// System.Web.UI.WebControls.MenuItemBindingCollection.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+using System;
+using System.Collections;
+using System.Web.UI;
+
+namespace System.Web.UI.WebControls
+{
+       public sealed class MenuItemBindingCollection: StateManagedCollection
+       {
+               static Type[] types = new Type[] { typeof (MenuItemBinding) };
+               
+               internal MenuItemBindingCollection ()
+               {
+               }
+               
+               public int Add (MenuItemBinding binding)
+               {
+                       return ((IList)this).Add (binding);
+               }
+               
+               public bool Contains (MenuItemBinding binding)
+               {
+                       return ((IList)this).Contains (binding);
+               }
+               
+               public void CopyTo (MenuItemBinding[] array, int index)
+               {
+                       ((IList)this).CopyTo (array, index);
+               }
+               
+               protected override object CreateKnownType (int index)
+               {
+                       return new MenuItemBinding ();
+               }
+               
+               protected override Type[] GetKnownTypes ()
+               {
+                       return types;
+               }
+               
+               public int IndexOf (MenuItemBinding binding)
+               {
+                       return ((IList)this).IndexOf (binding);
+               }
+               
+               public void Insert (int index, MenuItemBinding binding)
+               {
+                       ((IList)this).Insert (index, binding);
+               }
+               
+               public void Remove (MenuItemBinding binding)
+               {
+                       ((IList)this).Remove (binding);
+               }
+               
+               public void RemoveAt (int index)
+               {
+                       ((IList)this).RemoveAt (index);
+               }
+               
+               public MenuItemBinding this [int i] {
+                       get { return (MenuItemBinding) ((IList)this) [i]; }
+                       set { ((IList)this) [i] = value; }
+               }
+               
+               protected override void SetDirtyObject (object o)
+               {
+                       ((MenuItemBinding)o).SetDirty ();
+               }
+       }
+}
+
+#endif
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemCollection.cs b/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemCollection.cs
new file mode 100644 (file)
index 0000000..0151421
--- /dev/null
@@ -0,0 +1,248 @@
+//
+// System.Web.UI.WebControls.MenuItemCollection.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+using System;
+using System.Web.UI;
+using System.Collections;
+
+namespace System.Web.UI.WebControls
+{
+       public sealed class MenuItemCollection: ICollection, IEnumerable, IStateManager
+       {
+               MenuItem[] originalItems;
+               ArrayList items = new ArrayList ();
+               Menu menu;
+               MenuItem parent;
+               bool marked;
+               bool dirty;
+               
+               public MenuItemCollection ()
+               {
+               }
+               
+               public MenuItemCollection (MenuItem owner)
+               {
+                       this.parent = owner;
+                       this.menu = owner.Menu;
+               }
+               
+               internal MenuItemCollection (Menu menu)
+               {
+                       this.menu = menu;
+               }
+               
+               internal void SetMenu (Menu menu)
+               {
+                       this.menu = menu;
+                       foreach (MenuItem item in items)
+                               item.Menu = menu;
+               }
+               
+               public MenuItem this [int i] {
+                       get { return (MenuItem) items [i]; }
+               }
+               
+               public void Add (MenuItem child)
+               {
+                       child.Index = items.Add (child);
+                       child.Menu = menu;
+                       child.SetParent (parent);
+                       if (marked) {
+                               ((IStateManager)child).TrackViewState ();
+                               child.SetDirty ();
+                               dirty = true;
+                       }
+               }
+               
+               public void AddAt (int index, MenuItem child)
+               {
+                       items.Insert (index, child);
+                       child.Index = index;
+                       child.Menu = menu;
+                       child.SetParent (parent);
+                       for (int n=index+1; n<items.Count; n++)
+                               ((MenuItem)items[n]).Index = n;
+                       if (marked) {
+                               ((IStateManager)child).TrackViewState ();
+                               child.SetDirty ();
+                               dirty = true;
+                       }
+               }
+               
+               public void Clear ()
+               {
+                       if (menu != null || parent != null) {
+                               foreach (MenuItem nod in items) {
+                                       nod.Menu = null;
+                                       nod.SetParent (null);
+                               }
+                       }
+                       items.Clear ();
+                       dirty = true;
+               }
+               
+               public bool Contains (MenuItem child)
+               {
+                       return items.Contains (child);
+               }
+               
+               public void CopyTo (Array itemArray, int index)
+               {
+                       items.CopyTo (itemArray, index);
+               }
+               
+               public void CopyTo (MenuItem[] itemArray, int index)
+               {
+                       items.CopyTo (itemArray, index);
+               }
+               
+               public IEnumerator GetEnumerator ()
+               {
+                       return items.GetEnumerator ();
+               }
+               
+               public int IndexOf (MenuItem item)
+               {
+                       return items.IndexOf (item);
+               }
+               
+               public void Remove (MenuItem item)
+               {
+                       int i = IndexOf (item);
+                       if (i == -1) return;
+                       items.RemoveAt (i);
+                       if (menu != null)
+                               item.Menu = null;
+                       dirty = true;
+               }
+               
+               public void RemoveAt (int index)
+               {
+                       MenuItem item = (MenuItem) items [index];
+                       items.RemoveAt (index);
+                       if (menu != null)
+                               item.Menu = null;
+                       dirty = true;
+               }
+               
+               public int Count {
+                       get { return items.Count; }
+               }
+               
+               public bool IsSynchronized {
+                       get { return false; }
+               }
+               
+               public object SyncRoot {
+                       get { return items; }
+               }
+               
+               void System.Collections.ICollection.CopyTo (Array array, int index)
+               {
+                       items.CopyTo (array, index);
+               }
+
+               void IStateManager.LoadViewState (object state)
+               {
+                       if (state == null) return;
+                       object[] its = (object[]) state;
+                       
+                       dirty = (bool)its [0];
+                       
+                       if (dirty)
+                               items.Clear ();
+
+                       for (int n=1; n<its.Length; n++) {
+                               Pair pair = (Pair) its [n];
+                               int oi = (int) pair.First;
+                               MenuItem item;
+                               if (oi != -1) item = originalItems [oi];
+                               else item = new MenuItem ();
+                               if (dirty) Add (item);
+                               ((IStateManager)item).LoadViewState (pair.Second);
+                       }
+               }
+               
+               object IStateManager.SaveViewState ()
+               {
+                       object[] state = null;
+                       bool hasData = false;
+                       
+                       if (dirty) {
+                               state = new object [items.Count + 1];
+                               state [0] = true;
+                               for (int n=0; n<items.Count; n++) {
+                                       MenuItem item = items[n] as MenuItem;
+                                       int oi = Array.IndexOf (originalItems, item);
+                                       object ns = ((IStateManager)item).SaveViewState ();
+                                       if (ns != null) hasData = true;
+                                       state [n + 1] = new Pair (oi, ns);
+                               }
+                       } else {
+                               ArrayList list = new ArrayList ();
+                               for (int n=0; n<items.Count; n++) {
+                                       MenuItem item = items[n] as MenuItem;
+                                       object ns = ((IStateManager)item).SaveViewState ();
+                                       if (ns != null) {
+                                               hasData = true;
+                                               list.Add (new Pair (n, ns));
+                                       }
+                               }
+                               if (hasData) {
+                                       list.Insert (0, false);
+                                       state = list.ToArray ();
+                               }
+                       }
+                       
+                       if (hasData)
+                               return state;
+                       else
+                               return null;
+               }
+               
+               void IStateManager.TrackViewState ()
+               {
+                       marked = true;
+                       originalItems = new MenuItem [items.Count];
+                       for (int n=0; n<items.Count; n++) {
+                               originalItems [n] = (MenuItem) items [n];
+                               ((IStateManager)originalItems [n]).TrackViewState ();
+                       }
+               }
+               
+               bool IStateManager.IsTrackingViewState {
+                       get { return marked; }
+               }
+       }
+}
+
+#endif
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemStyle.cs b/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemStyle.cs
new file mode 100644 (file)
index 0000000..85f99a6
--- /dev/null
@@ -0,0 +1,149 @@
+//
+// System.Web.UI.WebControls.MenuItemStyle.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+using System;
+using System.Web.UI;
+using System.ComponentModel;
+
+namespace System.Web.UI.WebControls
+{
+       public class MenuItemStyle: Style
+       {
+               private static int HORZ_PADD = (0x01 << 16);
+               private static int SPACING = (0x01 << 17);
+               private static int VERT_PADD = (0x01 << 18);
+               
+               [DefaultValue (0)]
+               [NotifyParentProperty (true)]
+               public int HorizontalPadding {
+                       get {
+                               if(IsSet(HORZ_PADD))
+                                       return (int)(ViewState["HorizontalPadding"]);
+                               return 0;
+                       }
+                       set {
+                               ViewState["HorizontalPadding"] = value;
+                               Set(HORZ_PADD);
+                       }
+               }
+
+               [DefaultValue (0)]
+               [NotifyParentProperty (true)]
+               public int VerticalPadding {
+                       get {
+                               if(IsSet(VERT_PADD))
+                                       return (int)(ViewState["VerticalPadding"]);
+                               return 0;
+                       }
+                       set {
+                               ViewState["VerticalPadding"] = value;
+                               Set(VERT_PADD);
+                       }
+               }
+
+               [DefaultValue (0)]
+               [NotifyParentProperty (true)]
+               public int ItemSpacing {
+                       get {
+                               if(IsSet(SPACING))
+                                       return (int)(ViewState["ItemSpacing"]);
+                               return 0;
+                       }
+                       set {
+                               ViewState["ItemSpacing"] = value;
+                               Set(SPACING);
+                       }
+               }
+
+               protected internal override bool IsEmpty {
+                       get { return base.IsEmpty; }
+               }
+               
+               public override void CopyFrom (Style s)
+               {
+                       if (s == null || s.IsEmpty)
+                               return;
+
+                       base.CopyFrom (s);
+                       MenuItemStyle from = s as MenuItemStyle;
+                       if (from == null)
+                               return;
+
+                       if (from.IsSet (HORZ_PADD))
+                               HorizontalPadding = from.HorizontalPadding;
+
+                       if (from.IsSet (SPACING))
+                               ItemSpacing = from.ItemSpacing;
+
+                       if (from.IsSet (VERT_PADD))
+                               VerticalPadding = from.VerticalPadding;
+               }
+               
+               public override void MergeWith(Style s)
+               {
+                       if(s != null && !s.IsEmpty)
+                       {
+                               if (IsEmpty) {
+                                       CopyFrom (s);
+                                       return;
+                               }
+                               base.MergeWith(s);
+
+                               MenuItemStyle with = s as MenuItemStyle;
+                               if (with == null) return;
+                               
+                               if (with.IsSet(HORZ_PADD) && !IsSet(HORZ_PADD)) {
+                                       HorizontalPadding = with.HorizontalPadding;
+                               }
+                               if (with.IsSet(SPACING) && !IsSet(SPACING)) {
+                                       ItemSpacing = with.ItemSpacing;
+                               }
+                               if (with.IsSet(VERT_PADD) && !IsSet(VERT_PADD)) {
+                                       VerticalPadding = with.VerticalPadding;
+                               }
+                       }
+               }
+
+               public override void Reset()
+               {
+                       if(IsSet(HORZ_PADD))
+                               ViewState.Remove("HorizontalPadding");
+                       if(IsSet(SPACING))
+                               ViewState.Remove("ItemSpacing");
+                       if(IsSet(VERT_PADD))
+                               ViewState.Remove("VerticalPadding");
+                       base.Reset();
+               }
+       }
+}
+
+#endif
diff --git a/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemStyleCollection.cs b/mcs/class/System.Web/System.Web.UI.WebControls/MenuItemStyleCollection.cs
new file mode 100644 (file)
index 0000000..c9413e0
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// System.Web.UI.WebControls.MenuItemStyleCollection.cs
+//
+// Authors:
+//     Lluis Sanchez Gual (lluis@novell.com)
+//
+// (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+using System;
+using System.Collections;
+using System.Web.UI;
+
+namespace System.Web.UI.WebControls
+{
+       public sealed class MenuItemStyleCollection: StateManagedCollection
+       {
+               static Type[] types = new Type[] { typeof (MenuItemStyle) };
+               
+               internal MenuItemStyleCollection ()
+               {
+               }
+               
+               public int Add (MenuItemStyle style)
+               {
+                       return ((IList)this).Add (style);
+               }
+               
+               public bool Contains (MenuItemStyle style)
+               {
+                       return ((IList)this).Contains (style);
+               }
+               
+               public void CopyTo (MenuItemStyle[] array, int index)
+               {
+                       ((IList)this).CopyTo (array, index);
+               }
+               
+               protected override object CreateKnownType (int index)
+               {
+                       return new MenuItemStyle ();
+               }
+               
+               protected override Type[] GetKnownTypes ()
+               {
+                       return types;
+               }
+               
+               public int IndexOf (MenuItemStyle style)
+               {
+                       return ((IList)this).IndexOf (style);
+               }
+               
+               public void Insert (int index, MenuItemStyle style)
+               {
+                       ((IList)this).Insert (index, style);
+               }
+               
+               public void Remove (MenuItemStyle style)
+               {
+                       ((IList)this).Remove (style);
+               }
+               
+               public void RemoveAt (int index)
+               {
+                       ((IList)this).RemoveAt (index);
+               }
+               
+               public MenuItemStyle this [int i] {
+                       get { return (MenuItemStyle) ((IList)this) [i]; }
+                       set { ((IList)this) [i] = value; }
+               }
+               
+               protected override void SetDirtyObject (object o)
+               {
+                       ((MenuItemStyle)o).SetDirty ();
+               }
+       }
+}
+
+#endif
index 1499d9f26a0aa2da021f81f1874bdb648305ddd1..9a6f440d5a320817a094f4749fef48988af305df 100644 (file)
@@ -630,7 +630,7 @@ namespace System.Web.UI.WebControls
                        bool foundBranch = true;
                        while (col.Count > 0 && foundBranch) {
                                foundBranch = false;
-                               foreach (TreeNode node in Nodes) {
+                               foreach (TreeNode node in col) {
                                        if (node.Value == path [n]) {
                                                if (++n == path.Length) return node;
                                                col = node.ChildNodes;
@@ -766,7 +766,6 @@ namespace System.Web.UI.WebControls
                                ((IStateManager)Nodes).LoadViewState(states[9]);
                }
 
-               [MonoTODO]
                void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
                {
                        string[] args = eventArgument.Split ('|');
index 3aa7fb8f2e7b03a724b083c5b0674ed1e6de2081..43e8fe39c73f8a25263a94c34e4ba5a47c249fef 100755 (executable)
@@ -408,6 +408,15 @@ System.Web.UI.WebControls/LoginTextLayout.cs
 System.Web.UI.WebControls/LogoutAction.cs
 System.Web.UI.WebControls/MailMessageEventArgs.cs
 System.Web.UI.WebControls/MailMessageEventHandler.cs
+System.Web.UI.WebControls/Menu.cs
+System.Web.UI.WebControls/MenuEventArgs.cs
+System.Web.UI.WebControls/MenuEventHandler.cs
+System.Web.UI.WebControls/MenuItem.cs
+System.Web.UI.WebControls/MenuItemBinding.cs
+System.Web.UI.WebControls/MenuItemBindingCollection.cs
+System.Web.UI.WebControls/MenuItemCollection.cs
+System.Web.UI.WebControls/MenuItemStyle.cs
+System.Web.UI.WebControls/MenuItemStyleCollection.cs
 System.Web.UI.WebControls/MonthChangedEventArgs.cs
 System.Web.UI.WebControls/MonthChangedEventHandler.cs
 System.Web.UI.WebControls/ObjectDataSourceDisposingEventArgs.cs
index 750cfa8c7b0ab741ae7005e448ef7353b027a8fd..f0fd7062a1ac7cfebd3d5ca14cbd91a48662464d 100644 (file)
@@ -1,3 +1,13 @@
+2004-12-04  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * System.Xml.dll.sources : added DTMXPathDocument2.cs,
+         DTMXPathDocumentBuilder2.cs, DTMXPathDocumentWriter2.cs,
+         DTMXPathDocumentWriter2.cs and DTMXPathNode2.cs.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile: Remove support for being in bootstrap build.
+
 2004-12-01  Atsushi Enomoto  <atsushi@ximian.com>
 
        * System.Xml.dll.sources: removed old IXPathChangeNavigable.cs,
index 0a98eff12ee10c914846fadb85d273d0a0939037..964fced2967b58ad8001765e289f9d0be21dd2ba 100644 (file)
@@ -11,10 +11,6 @@ else
 SCARY_LIB=/lib:$(prefix)/lib /noconfig
 endif
 
-ifdef USE_BOOT_COMPILE
-LIBRARY_COMPILE = $(BOOT_COMPILE)
-endif
-
 LIB_MCS_FLAGS = $(SCARY_LIB) /unsafe /r:$(corlib) /r:System.dll /nowarn:0162 /nowarn:0618 /nowarn:0612
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 
index ee22e538f254553c046bc7e09308774b09f26534..4af03a8c95e2ef8feb8d97d0e49b4a62770ce4b1 100644 (file)
@@ -1,3 +1,21 @@
+2004-12-04  Atsushi Enomoto <atsushi@ximian.com>
+
+       * DTMXPathNavigator.cs : added more constant fields to utility class.
+
+2004-12-04  Atsushi Enomoto <atsushi@ximian.com>
+
+       * DTMXPathDocument2.cs,
+         DTMXPathNavigator2.cs,
+         DTMXPathDocumentBuilder2.cs,
+         DTMXPathDocumentWriter2.cs,
+         DTMXPathNode2.cs : added new implementation that uses string pool
+         and eliminates string field inside struct (IF we use struct).
+
+2004-12-03  Atsushi Enomoto <atsushi@ximian.com>
+
+       * DTMXPathDocumentWriter.cs : Fix for DTM_CLASS switch that does not
+         allow unadjusted arrays.
+
 2004-11-30  Atsushi Enomoto <atsushi@ximian.com>
 
        * DTMXPathDocumentWriter.cs,
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
new file mode 100755 (executable)
index 0000000..b51e8a5
--- /dev/null
@@ -0,0 +1,106 @@
+//
+// Mono.Xml.XPath.DTMXPathDocument2
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// (C) 2004 Novell Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Mono.Xml.XPath
+{
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+               class DTMXPathDocument2 : IXPathNavigable
+       {
+
+#region ctor.
+
+               public DTMXPathDocument2 (XmlNameTable nameTable,
+                       DTMXPathLinkedNode2 [] nodes,
+                       DTMXPathAttributeNode2 [] attributes,
+                       DTMXPathNamespaceNode2 [] namespaces,
+                       string [] atomicStringPool,
+                       string [] nonAtomicStringPool,
+                       Hashtable idTable)
+               {
+                       this.nameTable = nameTable;
+                       this.nodes = nodes;
+                       this.attributes = attributes;
+                       this.namespaces = namespaces;
+                       this.atomicStringPool = atomicStringPool;
+                       this.nonAtomicStringPool = nonAtomicStringPool;
+                       this.idTable = idTable;
+
+                       root = new DTMXPathNavigator2 (this,
+                               nameTable,
+                               nodes,
+                               attributes,
+                               namespaces,
+                               atomicStringPool,
+                               nonAtomicStringPool,
+                               idTable);
+               }
+
+#endregion
+
+
+#region Methods
+               public XPathNavigator CreateNavigator ()
+               {
+                       return root.Clone ();
+               }
+
+#endregion
+
+               readonly XmlNameTable nameTable;
+
+               // Root XPathNavigator.
+               readonly DTMXPathNavigator2 root;
+
+#region Immutable tree fields
+
+               readonly DTMXPathLinkedNode2 [] nodes;
+               readonly DTMXPathAttributeNode2 [] attributes;
+               readonly DTMXPathNamespaceNode2 [] namespaces;
+
+               // String pool
+               readonly string [] atomicStringPool;
+               readonly string [] nonAtomicStringPool;
+
+               // idTable [string value] -> int nodeId
+               readonly Hashtable idTable;
+
+#endregion
+
+       }
+}
+
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
new file mode 100755 (executable)
index 0000000..27286f1
--- /dev/null
@@ -0,0 +1,549 @@
+//
+// Mono.Xml.XPath.DTMXPathDocumentBuilder2
+//
+// Author:
+//     Atsushi Enomoto  <atsushi@ximian.com>
+//
+// (C)2004 Novell Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+
+namespace Mono.Xml.XPath
+{
+
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+       class DTMXPathDocumentBuilder2
+       {
+               public DTMXPathDocumentBuilder2 (string url)
+                       : this (url, XmlSpace.None, 200)
+               {
+               }
+
+               public DTMXPathDocumentBuilder2 (string url, XmlSpace space)
+                       : this (url, space, 200)
+               {
+               }
+
+               public DTMXPathDocumentBuilder2 (string url, XmlSpace space, int defaultCapacity)
+               {
+                       XmlReader r = null;
+                       try {
+                               r = new XmlTextReader (url);
+                               Init (r, space, defaultCapacity);
+                       } finally {
+                               if (r != null)
+                                       r.Close ();
+                       }
+               }
+
+               public DTMXPathDocumentBuilder2 (XmlReader reader)
+                       : this (reader, XmlSpace.None, 200)
+               {
+               }
+
+               public DTMXPathDocumentBuilder2 (XmlReader reader, XmlSpace space)
+                       : this (reader, space, 200)
+               {
+               }
+
+               public DTMXPathDocumentBuilder2 (XmlReader reader, XmlSpace space, int defaultCapacity)
+               {
+                       Init (reader, space, defaultCapacity);
+               }
+
+               private void Init (XmlReader reader, XmlSpace space, int defaultCapacity)
+               {
+                       this.xmlReader = reader;
+                       this.validatingReader = reader as XmlValidatingReader;
+                       lineInfo = reader as IXmlLineInfo;
+                       this.xmlSpace = space;
+                       this.nameTable = reader.NameTable;
+                       nodeCapacity = defaultCapacity;
+                       attributeCapacity = nodeCapacity;
+                       nsCapacity = 10;
+                       idTable = new Hashtable ();
+
+                       nodes = new DTMXPathLinkedNode2 [nodeCapacity];
+                       attributes = new DTMXPathAttributeNode2 [attributeCapacity];
+                       namespaces = new DTMXPathNamespaceNode2 [nsCapacity];
+                       atomicStringPool = new string [20];
+                       nonAtomicStringPool = new string [20];
+
+                       Compile ();
+               }
+               
+               XmlReader xmlReader;
+               XmlValidatingReader validatingReader;
+               XmlSpace xmlSpace;
+               XmlNameTable nameTable;
+               IXmlLineInfo lineInfo;
+               int nodeCapacity;
+               int attributeCapacity;
+               int nsCapacity;
+
+               // Linked Node
+               DTMXPathLinkedNode2 [] nodes;
+
+               // Attribute
+               DTMXPathAttributeNode2 [] attributes;
+
+               // NamespaceNode
+               DTMXPathNamespaceNode2 [] namespaces;
+
+               // String pool
+               string [] atomicStringPool;
+               string [] nonAtomicStringPool;
+
+               // idTable [string value] -> int nodeId
+               Hashtable idTable;
+
+               int nodeIndex;
+               int attributeIndex;
+               int nsIndex;
+               int parentForFirstChild;
+
+               // for attribute processing; should be reset per each element.
+               int firstAttributeIndex;
+               int lastNsIndexInCurrent;
+               int attrIndexAtStart;
+               int nsIndexAtStart;
+
+               int prevSibling;
+               int lastNsInScope;
+               bool skipRead = false;
+
+               public DTMXPathDocument2 CreateDocument ()
+               {
+                       return new DTMXPathDocument2 (nameTable,
+                               nodes,
+                               attributes,
+                               namespaces,
+                               atomicStringPool,
+                               nonAtomicStringPool,
+                               idTable
+                       );
+               }
+
+               public void Compile ()
+               {
+                       // string pool index 0 to 3 are fixed.
+                       atomicStringPool [0] = nonAtomicStringPool [0] = "";
+                       atomicStringPool [1] = nonAtomicStringPool [1] = null;
+                       atomicStringPool [2] = nonAtomicStringPool [2] = XmlNamespaces.XML;
+                       atomicStringPool [3] = nonAtomicStringPool [3] = XmlNamespaces.XMLNS;
+
+                       // index 0 is dummy. No node (including Root) is assigned to this index
+                       // So that we can easily compare index != 0 instead of index < 0.
+                       // (Difference between jnz or jbe in 80x86.)
+                       AddNode (0, 0, 0, 0, XPathNodeType.All, 0, false, 0, 0, 0, 0, 0, 0, 0, 0);
+                       nodeIndex++;
+                       AddAttribute (0, 0, 0, 0, 0, 0, 0);
+                       AddNsNode (0, 0, 0, 0);
+                       nsIndex++;
+                       AddNsNode (1, AtomicIndex ("xml"), AtomicIndex (XmlNamespaces.XML), 0);
+
+                       // add root.
+                       AddNode (0, 0, 0, -1, XPathNodeType.Root, AtomicIndex (xmlReader.BaseURI), false, 0, 0, 0, 0, 0, 1, 0, 0);
+
+                       this.nodeIndex = 1;
+                       this.lastNsInScope = 1;
+                       this.parentForFirstChild = nodeIndex;
+
+                       while (!xmlReader.EOF)
+                               Read ();
+                       SetNodeArrayLength (nodeIndex + 1);
+                       SetAttributeArrayLength (attributeIndex + 1);
+                       SetNsArrayLength (nsIndex + 1);
+
+                       int i;
+                       for (i = 3; i < atomicStringPool.Length; i++) {
+                               if (atomicStringPool [i] == null)
+                                       break;
+                       }
+                       string [] newArr = new string [i];
+                       Array.Copy (atomicStringPool, newArr, i);
+                       atomicStringPool = newArr;
+
+                       for (i = 3; i < nonAtomicStringPool.Length; i++) {
+                               if (nonAtomicStringPool [i] == null)
+                                       break;
+                       }
+                       newArr = new string [i];
+                       Array.Copy (nonAtomicStringPool, newArr, i);
+                       nonAtomicStringPool = newArr;
+
+                       xmlReader = null;       // It is no more required.
+               }
+
+               public void Read ()
+               {
+                       if (!skipRead)
+                               if (!xmlReader.Read ())
+                                       return;
+                       skipRead = false;
+                       int parent = nodeIndex;
+
+                       if (nodes [nodeIndex].Depth >= xmlReader.Depth) {
+                               // if not, then current node is parent.
+                               while (xmlReader.Depth <= nodes [parent].Depth)
+                                       parent = nodes [parent].Parent;
+                       }
+
+                       prevSibling = nodeIndex;
+                       switch (xmlReader.NodeType) {
+                       case XmlNodeType.Element:
+                       case XmlNodeType.CDATA:
+                       case XmlNodeType.SignificantWhitespace:
+                       case XmlNodeType.Comment:
+                       case XmlNodeType.Text:
+                       case XmlNodeType.ProcessingInstruction:
+                               if (parentForFirstChild >= 0)
+                                       prevSibling = 0;
+                               else
+                                       while (nodes [prevSibling].Depth != xmlReader.Depth)
+                                               prevSibling = nodes [prevSibling].Parent;
+
+                               nodeIndex++;
+
+                               if (prevSibling != 0)
+                                       nodes [prevSibling].NextSibling = nodeIndex;
+                               if (parentForFirstChild >= 0)
+                                       nodes [parent].FirstChild = nodeIndex;
+                               break;
+                       case XmlNodeType.Whitespace:
+                               if (xmlSpace == XmlSpace.Preserve)
+                                       goto case XmlNodeType.Text;
+                               else
+                                       goto default;
+                       case XmlNodeType.EndElement:
+                               parentForFirstChild = -1;
+                               return;
+                       default:
+                               // No operations. Doctype, EntityReference, 
+                               return;
+                       }
+
+                       parentForFirstChild = -1;       // Might be changed in ProcessElement().
+
+                       string value = null;
+                       XPathNodeType nodeType = xmlReader.NodeType == XmlNodeType.Whitespace ?
+                               XPathNodeType.Whitespace : XPathNodeType.Text;
+
+                       switch (xmlReader.NodeType) {
+                       case XmlNodeType.Element:
+                               ProcessElement (parent, prevSibling);
+                               break;
+                       case XmlNodeType.CDATA:
+                       case XmlNodeType.SignificantWhitespace:
+                       case XmlNodeType.Text:
+                       case XmlNodeType.Whitespace:
+                               if (value == null)
+                                       skipRead = true;
+                               AddNode (parent,
+                                       0,
+                                       prevSibling,
+                                       xmlReader.Depth,
+                                       nodeType,
+                                       AtomicIndex (xmlReader.BaseURI),
+                                       xmlReader.IsEmptyElement,
+                                       AtomicIndex (xmlReader.LocalName),      // for PI
+                                       AtomicIndex (xmlReader.NamespaceURI),   // for PI
+                                       AtomicIndex (xmlReader.Prefix),
+                                       value == null ? 0 : NonAtomicIndex (value),
+                                       AtomicIndex (xmlReader.XmlLang),
+                                       nsIndex,
+                                       lineInfo != null ? lineInfo.LineNumber : 0,
+                                       lineInfo != null ? lineInfo.LinePosition : 0);
+                               // this code is tricky, but after ReadString() invokation,
+                               // xmlReader is moved to next node!!
+                               if (value == null)
+                                       nodes [nodeIndex].Value = NonAtomicIndex (xmlReader.ReadString ());
+                               break;
+                       case XmlNodeType.Comment:
+                               value = xmlReader.Value;
+                               nodeType = XPathNodeType.Comment;
+                               goto case XmlNodeType.Text;
+                       case XmlNodeType.ProcessingInstruction:
+                               value = xmlReader.Value;
+                               nodeType = XPathNodeType.ProcessingInstruction;
+                               goto case XmlNodeType.Text;
+                       }
+               }
+
+               private void ProcessElement (int parent, int previousSibling)
+               {
+                       WriteStartElement (parent, previousSibling);
+
+                       // process namespaces and attributes.
+                       if (xmlReader.MoveToFirstAttribute ()) {
+                               do {
+                                       string prefix = xmlReader.Prefix;
+                                       string ns = xmlReader.NamespaceURI;
+                                       if (ns == XmlNamespaces.XMLNS)
+                                               ProcessNamespace ((prefix == null || prefix == String.Empty) ? "" : xmlReader.LocalName, xmlReader.Value);
+                                       else
+                                               ProcessAttribute (prefix, xmlReader.LocalName, ns, xmlReader.Value);
+
+                               } while (xmlReader.MoveToNextAttribute ());
+                               xmlReader.MoveToElement ();
+                       }
+
+                       CloseStartElement ();
+               }
+
+               private void PrepareStartElement (int previousSibling)
+               {
+                       firstAttributeIndex = 0;
+                       lastNsIndexInCurrent = 0;
+                       attrIndexAtStart = attributeIndex;
+                       nsIndexAtStart = nsIndex;
+
+                       while (namespaces [lastNsInScope].DeclaredElement == previousSibling) {
+                               lastNsInScope = namespaces [lastNsInScope].NextNamespace;
+                       }
+               }
+
+               private void WriteStartElement (int parent, int previousSibling)
+               {
+                       PrepareStartElement (previousSibling);
+
+                       AddNode (parent,
+                               0, // dummy:firstAttribute
+                               previousSibling,
+                               xmlReader.Depth,
+                               XPathNodeType.Element,
+                               AtomicIndex (xmlReader.BaseURI),
+                               xmlReader.IsEmptyElement,
+                               AtomicIndex (xmlReader.LocalName),
+                               AtomicIndex (xmlReader.NamespaceURI),
+                               AtomicIndex (xmlReader.Prefix),
+                               0,      // Element has no internal value.
+                               AtomicIndex (xmlReader.XmlLang),
+                               lastNsInScope,
+                               lineInfo != null ? lineInfo.LineNumber : 0,
+                               lineInfo != null ? lineInfo.LinePosition : 0);
+
+               }
+
+               private void CloseStartElement ()
+               {
+                       if (attrIndexAtStart != attributeIndex)
+                               nodes [nodeIndex].FirstAttribute = attrIndexAtStart + 1;
+                       if (nsIndexAtStart != nsIndex) {
+                               nodes [nodeIndex].FirstNamespace = nsIndex;
+                               lastNsInScope = nsIndex;
+                       }
+
+                       if (!nodes [nodeIndex].IsEmptyElement)
+                               parentForFirstChild = nodeIndex;
+               }
+
+               private void ProcessNamespace (string prefix, string ns)
+               {
+                       nsIndex++;
+
+                       int nextTmp = lastNsIndexInCurrent == 0 ? nodes [nodeIndex].FirstNamespace : lastNsIndexInCurrent;
+
+                       this.AddNsNode (nodeIndex,
+                               AtomicIndex (prefix),
+                               AtomicIndex (ns),
+                               nextTmp);
+                       lastNsIndexInCurrent = nsIndex;
+               }
+
+               private void ProcessAttribute (string prefix, string localName, string ns, string value)
+               {
+                       attributeIndex ++;
+
+                       this.AddAttribute (nodeIndex,
+                               AtomicIndex (localName),
+                               AtomicIndex (ns), 
+                               prefix != null ? AtomicIndex (prefix) : 0, 
+                               NonAtomicIndex (value),
+                               lineInfo != null ? lineInfo.LineNumber : 0,
+                               lineInfo != null ? lineInfo.LinePosition : 0);
+                       if (firstAttributeIndex == 0)
+                               firstAttributeIndex = attributeIndex;
+                       else
+                               attributes [attributeIndex - 1].NextAttribute = attributeIndex;
+
+                       // Identity infoset
+                       if (validatingReader != null) {
+                               XmlSchemaDatatype dt = validatingReader.SchemaType as XmlSchemaDatatype;
+                               if (dt == null) {
+                                       XmlSchemaType xsType = validatingReader.SchemaType as XmlSchemaType;
+                                       if (xsType != null)
+                                               dt = xsType.Datatype;
+                               }
+                               if (dt != null && dt.TokenizedType == XmlTokenizedType.ID)
+                                       idTable.Add (value, nodeIndex);
+                       }
+               }
+
+               private int AtomicIndex (string s)
+               {
+                       if (s == "")
+                               return 0;
+                       if (s == null)
+                               return 1;
+                       int i = 2;
+                       for (; i < atomicStringPool.Length; i++) {
+                               if (atomicStringPool [i] == null) {
+                                       atomicStringPool [i] = s;
+                                       return i;
+                               }
+                               else if (Object.ReferenceEquals (s,
+                                       atomicStringPool [i]))
+                                       return i;
+                       }
+                       string [] newArr = new string [i * 2];
+                       Array.Copy (atomicStringPool, newArr, i);
+                       atomicStringPool = newArr;
+                       atomicStringPool [i] = s;
+                       return i;
+               }
+
+               private int NonAtomicIndex (string s)
+               {
+                       if (s == "")
+                               return 0;
+                       if (s == null)
+                               return 1;
+                       int i = 2;
+                       for (; i < nonAtomicStringPool.Length; i++) {
+                               if (nonAtomicStringPool [i] == null) {
+                                       nonAtomicStringPool [i] = s;
+                                       return i;
+                               }
+                               else if (s == nonAtomicStringPool [i])
+                                       return i;
+                       }
+                       string [] newArr = new string [i * 2];
+                       Array.Copy (nonAtomicStringPool, newArr, i);
+                       nonAtomicStringPool = newArr;
+                       nonAtomicStringPool [i] = s;
+                       return i;
+               }
+
+               private void SetNodeArrayLength (int size)
+               {
+                       DTMXPathLinkedNode2 [] newArr = new DTMXPathLinkedNode2 [size];
+                       Array.Copy (nodes, newArr, System.Math.Min (size, nodes.Length));
+                       nodes = newArr;
+               }
+
+               private void SetAttributeArrayLength (int size)
+               {
+                       DTMXPathAttributeNode2 [] newArr = 
+                               new DTMXPathAttributeNode2 [size];
+                       Array.Copy (attributes, newArr, System.Math.Min (size, attributes.Length));
+                       attributes = newArr;
+               }
+
+               private void SetNsArrayLength (int size)
+               {
+                       DTMXPathNamespaceNode2 [] newArr =
+                               new DTMXPathNamespaceNode2 [size];
+                       Array.Copy (namespaces, newArr, System.Math.Min (size, namespaces.Length));
+                       namespaces = newArr;
+               }
+
+               // Here followings are skipped: firstChild, nextSibling, 
+               public void AddNode (int parent, int firstAttribute, int previousSibling, int depth, XPathNodeType nodeType, int baseUri, bool isEmptyElement, int localName, int ns, int prefix, int value, int xmlLang, int namespaceNode, int lineNumber, int linePosition)
+               {
+                       if (nodes.Length < nodeIndex + 1) {
+                               nodeCapacity *= 4;
+                               SetNodeArrayLength (nodeCapacity);
+                       }
+
+#if DTM_CLASS
+                       nodes [nodeIndex] = new DTMXPathLinkedNode2 ();
+#endif
+                       nodes [nodeIndex].FirstChild = 0;               // dummy
+                       nodes [nodeIndex].Parent = parent;
+                       nodes [nodeIndex].FirstAttribute = firstAttribute;
+                       nodes [nodeIndex].PreviousSibling = previousSibling;
+                       nodes [nodeIndex].NextSibling = 0;      // dummy
+                       nodes [nodeIndex].Depth = depth;
+                       nodes [nodeIndex].NodeType = nodeType;
+                       nodes [nodeIndex].BaseURI = baseUri;
+                       nodes [nodeIndex].IsEmptyElement = isEmptyElement;
+                       nodes [nodeIndex].LocalName = localName;
+                       nodes [nodeIndex].NamespaceURI = ns;
+                       nodes [nodeIndex].Prefix = prefix;
+                       nodes [nodeIndex].Value = value;
+                       nodes [nodeIndex].XmlLang = xmlLang;
+                       nodes [nodeIndex].FirstNamespace = namespaceNode;
+                       nodes [nodeIndex].LineNumber = lineNumber;
+                       nodes [nodeIndex].LinePosition = linePosition;
+               }
+
+               // Followings are skipped: nextAttribute,
+               public void AddAttribute (int ownerElement, int localName, int ns, int prefix, int value, int lineNumber, int linePosition)
+               {
+                       if (attributes.Length < attributeIndex + 1) {
+                               attributeCapacity *= 4;
+                               SetAttributeArrayLength (attributeCapacity);
+                       }
+
+#if DTM_CLASS
+                       attributes [attributeIndex] = new DTMXPathAttributeNode2 ();
+#endif
+                       attributes [attributeIndex].OwnerElement = ownerElement;
+                       attributes [attributeIndex].LocalName = localName;
+                       attributes [attributeIndex].NamespaceURI = ns;
+                       attributes [attributeIndex].Prefix = prefix;
+                       attributes [attributeIndex].Value = value;
+                       attributes [attributeIndex].LineNumber = lineNumber;
+                       attributes [attributeIndex].LinePosition = linePosition;
+               }
+
+               // Followings are skipped: nextNsNode (may be next attribute in the same element, or ancestors' nsNode)
+               public void AddNsNode (int declaredElement, int name, int ns, int nextNs)
+               {
+                       if (namespaces.Length < nsIndex + 1) {
+                               nsCapacity *= 4;
+                               SetNsArrayLength (nsCapacity);
+                       }
+
+#if DTM_CLASS
+                       namespaces [nsIndex] = new DTMXPathNamespaceNode2 ();
+#endif
+                       namespaces [nsIndex].DeclaredElement = declaredElement;
+                       namespaces [nsIndex].Name = name;
+                       namespaces [nsIndex].Namespace = ns;
+                       namespaces [nsIndex].NextNamespace = nextNs;
+               }
+       }
+}
+
index 177b335778de9a31801bbacfef6f471ff4ccdbd9..3688a99f5555755519469c91bf3bc8a317a5efee 100755 (executable)
@@ -92,9 +92,12 @@ namespace Mono.Xml.XPath
                int writerDepth;
                WriteState state;
                bool openNamespace;
+               bool isClosed;
 
                public DTMXPathDocument CreateDocument ()
                {
+                       if (!isClosed)
+                               Close ();
                        return new DTMXPathDocument (nameTable,
                                nodes,
                                attributes,
@@ -286,6 +289,7 @@ namespace Mono.Xml.XPath
                        SetNodeArrayLength (nodeIndex + 1);
                        SetAttributeArrayLength (attributeIndex + 1);
                        SetNsArrayLength (nsIndex + 1);
+                       isClosed = true;
                }
 
                public override void Flush ()
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter2.cs
new file mode 100755 (executable)
index 0000000..2b745e2
--- /dev/null
@@ -0,0 +1,757 @@
+//
+// Mono.Xml.XPath.DTMXPathDocumentWriter2
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// (C) 2004 Novell Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+
+namespace Mono.Xml.XPath
+{
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+               class DTMXPathDocumentWriter2 : XmlWriter
+       {
+               public DTMXPathDocumentWriter2 (XmlNameTable nt, int defaultCapacity)
+               {
+                       nameTable = nt == null ? new NameTable () : nt;
+                       nodeCapacity = defaultCapacity;
+                       attributeCapacity = nodeCapacity;
+                       nsCapacity = 10;
+                       idTable = new Hashtable ();
+
+                       nodes = new DTMXPathLinkedNode2 [nodeCapacity];
+                       attributes = new DTMXPathAttributeNode2 [attributeCapacity];
+                       namespaces = new DTMXPathNamespaceNode2 [nsCapacity];
+
+                       atomicStringPool = new string [20];
+                       nonAtomicStringPool = new string [20];
+
+                       Init ();
+               }
+               
+               XmlNameTable nameTable;
+               int nodeCapacity;
+               int attributeCapacity;
+               int nsCapacity;
+
+               // Linked Node
+               DTMXPathLinkedNode2 [] nodes;
+
+               // Attribute
+               DTMXPathAttributeNode2 [] attributes;
+
+               // NamespaceNode
+               DTMXPathNamespaceNode2 [] namespaces;
+
+               // String pool
+               string [] atomicStringPool;
+               string [] nonAtomicStringPool;
+
+               // idTable [string value] -> int nodeId
+               Hashtable idTable;
+
+               int nodeIndex;
+               int attributeIndex;
+               int nsIndex;
+               int parentForFirstChild;
+
+               // for attribute processing; should be reset per each element.
+               int firstAttributeIndex;
+               int lastNsIndexInCurrent;
+               int attrIndexAtStart;
+               int nsIndexAtStart;
+
+               int prevSibling;
+               int lastNsInScope;
+
+               // They are only used in Writer
+               int writerDepth;
+               WriteState state;
+               bool openNamespace;
+               bool isClosed;
+
+               public DTMXPathDocument2 CreateDocument ()
+               {
+                       if (!isClosed)
+                               Close ();
+                       return new DTMXPathDocument2 (nameTable,
+                               nodes,
+                               attributes,
+                               namespaces,
+                               atomicStringPool,
+                               nonAtomicStringPool,
+                               idTable
+                       );
+               }
+
+               public void Init ()
+               {
+                       // string pool index 0 to 3 are fixed.
+                       atomicStringPool [0] = nonAtomicStringPool [0] = "";
+                       atomicStringPool [1] = nonAtomicStringPool [1] = null;
+                       atomicStringPool [2] = nonAtomicStringPool [2] = XmlNamespaces.XML;
+                       atomicStringPool [3] = nonAtomicStringPool [3] = XmlNamespaces.XMLNS;
+
+                       // index 0 is dummy. No node (including Root) is assigned to this index
+                       // So that we can easily compare index != 0 instead of index < 0.
+                       // (Difference between jnz or jbe in 80x86.)
+                       AddNode (0, 0, 0, 0, XPathNodeType.All, "", false, "", "", "", "", "", 0, 0, 0);
+                       nodeIndex++;
+                       AddAttribute (0, "", "", "", "", 0, 0);
+                       AddNsNode (0, "", "", 0);
+                       nsIndex++;
+                       AddNsNode (1, "xml", XmlNamespaces.XML, 0);
+
+                       // add root.
+                       AddNode (0, 0, 0, -1, XPathNodeType.Root, "", false, "", "", "", "", "", 1, 0, 0);
+
+                       this.nodeIndex = 1;
+                       this.lastNsInScope = 1;
+                       this.parentForFirstChild = nodeIndex;
+
+                       state = WriteState.Content;
+               }
+
+               private int GetParentIndex ()
+               {
+                       if (parentForFirstChild >= 0)
+                               return parentForFirstChild;
+
+                       int parent = nodeIndex;
+                       if (nodes [nodeIndex].Depth >= writerDepth) {
+                               // if not, then current node is parent.
+                               while (writerDepth <= nodes [parent].Depth)
+                                       parent = nodes [parent].Parent;
+                       }
+                       return parent;
+               }
+
+               private int GetPreviousSiblingIndex ()
+               {
+                       int prevSibling = nodeIndex;
+                       if (parentForFirstChild >= 0)
+                               prevSibling = 0;
+                       else
+                               while (nodes [prevSibling].Depth != writerDepth)
+                                       prevSibling = nodes [prevSibling].Parent;
+                       return prevSibling;
+               }
+
+               private void UpdateTreeForAddition ()
+               {
+                       int parent = GetParentIndex ();
+                       prevSibling = GetPreviousSiblingIndex ();
+
+                       nodeIndex++;
+
+                       if (prevSibling != 0)
+                               nodes [prevSibling].NextSibling = nodeIndex;
+                       if (parentForFirstChild >= 0)
+                               nodes [parent].FirstChild = nodeIndex;
+
+                       parentForFirstChild = -1;
+               }
+
+               private void CloseStartElement ()
+               {
+                       if (attrIndexAtStart != attributeIndex)
+                               nodes [nodeIndex].FirstAttribute = attrIndexAtStart + 1;
+                       if (nsIndexAtStart != nsIndex) {
+                               nodes [nodeIndex].FirstNamespace = nsIndex;
+                               lastNsInScope = nsIndex;
+                       }
+
+                       if (!nodes [nodeIndex].IsEmptyElement)
+                               parentForFirstChild = nodeIndex;
+\r
+                       state = WriteState.Content;\r
+                       writerDepth++;
+               }
+
+               #region Adding Nodes
+
+               private int AtomicIndex (string s)
+               {
+                       if (s == "")
+                               return 0;
+                       if (s == null)
+                               return 1;
+                       int i = 2;
+                       for (; i < atomicStringPool.Length; i++) {
+                               if (atomicStringPool [i] == null) {
+                                       atomicStringPool [i] = s;
+                                       return i;
+                               }
+                               else if (Object.ReferenceEquals (s,
+                                       atomicStringPool [i]))
+                                       return i;
+                       }
+                       string [] newArr = new string [i * 2];
+                       Array.Copy (atomicStringPool, newArr, i);
+                       atomicStringPool = newArr;
+                       atomicStringPool [i] = s;
+                       return i;
+               }
+
+               private int NonAtomicIndex (string s)
+               {
+                       if (s == "")
+                               return 0;
+                       if (s == null)
+                               return 1;
+                       int i = 2;
+                       for (; i < nonAtomicStringPool.Length; i++) {
+                               if (nonAtomicStringPool [i] == null) {
+                                       nonAtomicStringPool [i] = s;
+                                       return i;
+                               }
+                               else if (s == nonAtomicStringPool [i])
+                                       return i;
+                       }
+                       string [] newArr = new string [i * 2];
+                       Array.Copy (nonAtomicStringPool, newArr, i);
+                       nonAtomicStringPool = newArr;
+                       nonAtomicStringPool [i] = s;
+                       return i;
+               }
+
+               private void SetNodeArrayLength (int size)
+               {
+                       DTMXPathLinkedNode2 [] newArr = new DTMXPathLinkedNode2 [size];
+                       Array.Copy (nodes, newArr, System.Math.Min (size, nodes.Length));
+                       nodes = newArr;
+               }
+
+               private void SetAttributeArrayLength (int size)
+               {
+                       DTMXPathAttributeNode2 [] newArr = 
+                               new DTMXPathAttributeNode2 [size];
+                       Array.Copy (attributes, newArr, System.Math.Min (size, attributes.Length));
+                       attributes = newArr;
+               }
+
+               private void SetNsArrayLength (int size)
+               {
+                       DTMXPathNamespaceNode2 [] newArr =
+                               new DTMXPathNamespaceNode2 [size];
+                       Array.Copy (namespaces, newArr, System.Math.Min (size, namespaces.Length));
+                       namespaces = newArr;
+               }
+
+               // Here followings are skipped: firstChild, nextSibling, 
+               public void AddNode (int parent, int firstAttribute, int previousSibling, int depth, XPathNodeType nodeType, string baseUri, bool isEmptyElement, string localName, string ns, string prefix, string value, string xmlLang, int namespaceNode, int lineNumber, int linePosition)
+               {
+                       if (nodes.Length < nodeIndex + 1) {
+                               nodeCapacity *= 4;
+                               SetNodeArrayLength (nodeCapacity);
+                       }
+
+#if DTM_CLASS
+                       nodes [nodeIndex] = new DTMXPathLinkedNode2 ();
+#endif
+                       nodes [nodeIndex].FirstChild = 0;               // dummy
+                       nodes [nodeIndex].Parent = parent;
+                       nodes [nodeIndex].FirstAttribute = firstAttribute;
+                       nodes [nodeIndex].PreviousSibling = previousSibling;
+                       nodes [nodeIndex].NextSibling = 0;      // dummy
+                       nodes [nodeIndex].Depth = depth;
+                       nodes [nodeIndex].NodeType = nodeType;
+                       nodes [nodeIndex].BaseURI = AtomicIndex (baseUri);
+                       nodes [nodeIndex].IsEmptyElement = isEmptyElement;
+                       nodes [nodeIndex].LocalName = AtomicIndex (localName);
+                       nodes [nodeIndex].NamespaceURI = AtomicIndex (ns);
+                       nodes [nodeIndex].Prefix = AtomicIndex (prefix);
+                       nodes [nodeIndex].Value = NonAtomicIndex (value);
+                       nodes [nodeIndex].XmlLang = AtomicIndex (xmlLang);
+                       nodes [nodeIndex].FirstNamespace = namespaceNode;
+                       nodes [nodeIndex].LineNumber = lineNumber;
+                       nodes [nodeIndex].LinePosition = linePosition;
+               }
+
+               // Followings are skipped: nextAttribute,
+               public void AddAttribute (int ownerElement, string localName, string ns, string prefix, string value, int lineNumber, int linePosition)
+               {
+                       if (attributes.Length < attributeIndex + 1) {
+                               attributeCapacity *= 4;
+                               SetAttributeArrayLength (attributeCapacity);
+                       }
+
+#if DTM_CLASS
+                       attributes [attributeIndex] = new DTMXPathAttributeNode2 ();
+#endif
+                       attributes [attributeIndex].OwnerElement = ownerElement;
+                       attributes [attributeIndex].LocalName = AtomicIndex (localName);
+                       attributes [attributeIndex].NamespaceURI = AtomicIndex (ns);
+                       attributes [attributeIndex].Prefix = AtomicIndex (prefix);
+                       attributes [attributeIndex].Value = NonAtomicIndex (value);
+                       attributes [attributeIndex].LineNumber = lineNumber;
+                       attributes [attributeIndex].LinePosition = linePosition;
+               }
+
+               // Followings are skipped: nextNsNode (may be next attribute in the same element, or ancestors' nsNode)
+               public void AddNsNode (int declaredElement, string name, string ns, int nextNs)
+               {
+                       if (namespaces.Length < nsIndex + 1) {
+                               nsCapacity *= 4;
+                               SetNsArrayLength (nsCapacity);
+                       }
+
+#if DTM_CLASS
+                       namespaces [nsIndex] = new DTMXPathNamespaceNode2 ();
+#endif
+                       namespaces [nsIndex].DeclaredElement = declaredElement;
+                       namespaces [nsIndex].Name = AtomicIndex (name);
+                       namespaces [nsIndex].Namespace = AtomicIndex (ns);
+                       namespaces [nsIndex].NextNamespace = nextNs;
+               }
+               #endregion
+
+               #region XmlWriter methods
+               // They are not supported
+               public override string XmlLang { get { return null; } }
+               public override XmlSpace XmlSpace { get { return XmlSpace.None; } }
+
+               public override WriteState WriteState { get { return state; } }
+
+               public override void Close ()
+               {
+                       // Fixup arrays
+                       SetNodeArrayLength (nodeIndex + 1);
+                       SetAttributeArrayLength (attributeIndex + 1);
+                       SetNsArrayLength (nsIndex + 1);
+                       isClosed = true;
+               }
+
+               public override void Flush ()
+               {
+                       // do nothing
+               }
+
+               public override string LookupPrefix (string ns)
+               {
+                       int tmp = nsIndex;
+                       while (tmp != 0) {
+                               if (atomicStringPool [namespaces [tmp].Namespace] == ns)
+                                       return atomicStringPool [namespaces [tmp].Name];
+                               tmp = namespaces [tmp].NextNamespace;
+                       }
+                       return null;
+               }
+\r
+               public override void WriteCData (string data)\r
+               {\r
+                       AddTextNode (data);\r
+               }\r
+\r
+               private void AddTextNode (string data)\r
+               {\r
+                       switch (state) {\r
+                       case WriteState.Element:\r
+                               CloseStartElement ();\r
+                               break;\r
+                       case WriteState.Content:\r
+                               break;\r
+                       default:\r
+                               throw new InvalidOperationException ("Invalid document state for CDATA section: " + state);\r
+                       }\r
+\r
+                       // When text after text, just add the value, and return.\r
+                       if (nodes [nodeIndex].Depth == writerDepth) {\r
+                               switch (nodes [nodeIndex].NodeType) {\r
+                               case XPathNodeType.Text:\r
+                               case XPathNodeType.SignificantWhitespace:
+                                       string value = nonAtomicStringPool [nodes [nodeIndex].Value] + data;
+                                       nodes [nodeIndex].Value = NonAtomicIndex (value);\r
+                                       if (IsWhitespace (value))\r
+                                               nodes [nodeIndex].NodeType = XPathNodeType.SignificantWhitespace;\r
+                                       else\r
+                                               nodes [nodeIndex].NodeType = XPathNodeType.Text;\r
+                                       return;\r
+                               }\r
+                       }\r
+\r
+                       int parent = GetParentIndex ();\r
+                       UpdateTreeForAddition ();\r
+
+                       AddNode (parent,
+                               0, // attribute
+                               prevSibling,
+                               writerDepth,
+                               XPathNodeType.Text,
+                               null,
+                               false,
+                               null,
+                               String.Empty,
+                               String.Empty,
+                               data,
+                               null,
+                               0, // nsIndex
+                               0, // line info
+                               0);
+               }\r
+\r
+               private void CheckTopLevelNode ()\r
+               {\r
+                       switch (state) {\r
+                       case WriteState.Element:\r
+                               CloseStartElement ();\r
+                               break;\r
+                       case WriteState.Content:\r
+                       case WriteState.Prolog:\r
+                       case WriteState.Start:\r
+                               break;\r
+                       default:\r
+                               throw new InvalidOperationException ("Invalid document state for CDATA section: " + state);\r
+                       }\r
+               }\r
+\r
+               public override void WriteComment (string data)\r
+               {\r
+                       CheckTopLevelNode ();\r
+\r
+                       int parent = GetParentIndex ();\r
+                       UpdateTreeForAddition ();\r
+
+                       AddNode (parent,
+                               0, // attribute
+                               prevSibling,
+                               writerDepth,
+                               XPathNodeType.Comment,
+                               null,
+                               false,
+                               null,
+                               String.Empty,
+                               String.Empty,
+                               data,
+                               null,
+                               0, // nsIndex
+                               0, // line info
+                               0);
+               }\r
+\r
+               public override void WriteProcessingInstruction (string name, string data)\r
+               {\r
+                       CheckTopLevelNode ();\r
+\r
+                       int parent = GetParentIndex ();\r
+                       UpdateTreeForAddition ();\r
+
+                       AddNode (parent,
+                               0, // attribute
+                               prevSibling,
+                               writerDepth,
+                               XPathNodeType.ProcessingInstruction,
+                               null,
+                               false,
+                               name,
+                               String.Empty,
+                               String.Empty,
+                               data,
+                               null,
+                               0, // nsIndex
+                               0, // line info
+                               0);
+               }\r
+\r
+               public override void WriteWhitespace (string data)\r
+               {\r
+                       CheckTopLevelNode ();\r
+\r
+                       int parent = GetParentIndex ();\r
+                       UpdateTreeForAddition ();\r
+
+                       AddNode (parent,
+                               0, // attribute
+                               prevSibling,
+                               writerDepth,
+                               XPathNodeType.Whitespace,
+                               null,
+                               false,
+                               null,
+                               String.Empty,
+                               String.Empty,
+                               data,
+                               null,
+                               0, // nsIndex
+                               0, // line info
+                               0);
+               }\r
+\r
+               public override void WriteStartDocument ()\r
+               {\r
+                       // do nothing\r
+               }\r
+\r
+               public override void WriteStartDocument (bool standalone)\r
+               {\r
+                       // do nothing\r
+               }\r
+\r
+               public override void WriteEndDocument ()\r
+               {\r
+                       // do nothing\r
+               }\r
+\r
+               public override void WriteStartElement (string prefix, string localName, string ns)\r
+               {\r
+                       switch (state) {\r
+                       case WriteState.Element:\r
+                               CloseStartElement ();\r
+                               break;\r
+                       case WriteState.Start:\r
+                       case WriteState.Prolog:\r
+                       case WriteState.Content:\r
+                               break;\r
+                       default:\r
+                               throw new InvalidOperationException ("Invalid document state for writing element: " + state);\r
+                       }\r
+\r
+                       int parent = GetParentIndex ();\r
+                       UpdateTreeForAddition ();\r
+
+                       WriteStartElement (parent, prevSibling, prefix, localName, ns);
+                       state = WriteState.Element;
+               }\r
+
+               private void WriteStartElement (int parent, int previousSibling, string prefix, string localName, string ns)
+               {
+                       PrepareStartElement (previousSibling);
+
+                       AddNode (parent,
+                               0, // dummy:firstAttribute
+                               previousSibling,
+                               writerDepth,
+                               XPathNodeType.Element,
+                               null,
+                               false,
+                               localName,
+                               ns,
+                               prefix,
+                               "",     // Element has no internal value.
+                               null,
+                               lastNsInScope,
+                               0,
+                               0);
+               }
+
+               private void PrepareStartElement (int previousSibling)
+               {
+                       firstAttributeIndex = 0;
+                       lastNsIndexInCurrent = 0;
+                       attrIndexAtStart = attributeIndex;
+                       nsIndexAtStart = nsIndex;
+
+                       while (namespaces [lastNsInScope].DeclaredElement == previousSibling) {
+                               lastNsInScope = namespaces [lastNsInScope].NextNamespace;
+                       }
+               }
+\r
+               public override void WriteEndElement ()\r
+               {\r
+                       WriteEndElement (false);\r
+               }\r
+\r
+               public override void WriteFullEndElement ()\r
+               {\r
+                       WriteEndElement (true);\r
+               }\r
+\r
+               private void WriteEndElement (bool full)\r
+               {\r
+                       switch (state) {\r
+                       case WriteState.Element:\r
+                               CloseStartElement ();\r
+                               break;\r
+                       case WriteState.Content:\r
+                               break;\r
+                       default:\r
+                               throw new InvalidOperationException ("Invalid state for writing EndElement: " + state);\r
+                       }\r
+                       parentForFirstChild = -1;\r
+                       if (nodes [nodeIndex].NodeType == XPathNodeType.Element) {\r
+                               if (!full)\r
+                                       nodes [nodeIndex].IsEmptyElement = true;\r
+                       }\r
+\r
+                       writerDepth--;\r
+               }\r
+\r
+               public override void WriteStartAttribute (string prefix, string localName, string ns)\r
+               {\r
+                       if (state != WriteState.Element)\r
+                               throw new InvalidOperationException ("Invalid document state for attribute: " + state);\r
+\r
+                       state = WriteState.Attribute;\r
+                       if (ns == XmlNamespaces.XMLNS)
+                               ProcessNamespace ((prefix == null || prefix == String.Empty) ? "" : localName, String.Empty); // dummy: Value should be completed
+                       else
+                               ProcessAttribute (prefix, localName, ns, String.Empty); // dummy: Value should be completed
+               }\r
+\r
+               private void ProcessNamespace (string prefix, string ns)
+               {
+                       nsIndex++;
+
+                       int nextTmp = lastNsIndexInCurrent == 0 ? nodes [nodeIndex].FirstNamespace : lastNsIndexInCurrent;
+
+                       this.AddNsNode (nodeIndex,
+                               prefix,
+                               ns,
+                               nextTmp);
+                       lastNsIndexInCurrent = nsIndex;
+                       openNamespace = true;
+               }
+
+               private void ProcessAttribute (string prefix, string localName, string ns, string value)
+               {
+                       attributeIndex ++;
+
+                       this.AddAttribute (nodeIndex,
+                               localName,
+                               ns, 
+                               prefix != null ? prefix : String.Empty, 
+                               value,
+                               0,
+                               0);
+                       if (firstAttributeIndex == 0)
+                               firstAttributeIndex = attributeIndex;
+                       else
+                               attributes [attributeIndex - 1].NextAttribute = attributeIndex;
+               }
+
+               public override void WriteEndAttribute ()\r
+               {\r
+                       if (state != WriteState.Attribute)\r
+                               throw new InvalidOperationException ();\r
+\r
+                       openNamespace = false;\r
+                       state = WriteState.Element;\r
+               }\r
+\r
+               public override void WriteString (string text)\r
+               {\r
+                       if (WriteState == WriteState.Attribute) {
+                               if (openNamespace) {\r
+                                       string value = atomicStringPool [namespaces [nsIndex].Namespace] + text;
+                                       namespaces [nsIndex].Namespace = AtomicIndex (value);
+                               } else {\r
+                                       string value = nonAtomicStringPool [attributes [attributeIndex].Value] + text;
+                                       attributes [attributeIndex].Value = NonAtomicIndex (value);
+                               }\r
+                       }\r
+                       else\r
+                               AddTextNode (text);\r
+               }\r
+\r
+               // Well, they cannot be supported, but actually used to\r
+               // disable-output-escaping = "true"\r
+               public override void WriteRaw (string data)\r
+               {\r
+                       WriteString (data);\r
+               }\r
+
+               public override void WriteRaw (char [] data, int start, int len)\r
+               {\r
+                       WriteString (new string (data, start, len));\r
+               }\r
+\r
+               public override void WriteName (string name)\r
+               {\r
+                       WriteString (name);\r
+               }\r
+\r
+               public override void WriteNmToken (string name)\r
+               {\r
+                       WriteString (name);\r
+               }\r
+\r
+               public override void WriteBase64 (byte [] buffer, int index, int count)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }
+
+               public override void WriteBinHex (byte [] buffer, int index, int count)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }\r
+\r
+               public override void WriteChars (char [] buffer, int index, int count)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }\r
+\r
+               public override void WriteCharEntity (char c)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }\r
+\r
+               public override void WriteDocType (string name, string pub, string sys, string intSubset)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }\r
+
+               public override void WriteEntityRef (string name)
+               {
+                       throw new NotSupportedException ();\r
+               }
+
+               public override void WriteQualifiedName (string localName, string ns)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }\r
+\r
+               public override void WriteSurrogateCharEntity (char high, char low)\r
+               {\r
+                       throw new NotSupportedException ();\r
+               }
+
+               private bool IsWhitespace (string data)
+               {
+                       for (int i = 0; i < data.Length; i++) {
+                               switch (data [i]) {
+                               case ' ':
+                               case '\r':
+                               case '\n':
+                               case '\t':
+                                       continue;
+                               default:
+                                       return false;
+                               }
+                       }
+                       return true;
+               }\r
+               #endregion
+       }
+}
index 6bd8a339a0ea77eba067a35362a3318c89cdd6f3..86ddeb2ea5a57fe3c2449bfd311bee04173c9413 100644 (file)
@@ -626,5 +626,7 @@ namespace Mono.Xml.XPath
        {
                public const string XML = "http://www.w3.org/XML/1998/namespace";
                public const string XMLNS = "http://www.w3.org/2000/xmlns/";
+               public const int IndexXML = 2;
+               public const int IndexXMLNS = 3;
        }
 }
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator2.cs
new file mode 100755 (executable)
index 0000000..0636811
--- /dev/null
@@ -0,0 +1,598 @@
+//
+// Mono.Xml.XPath.DTMXPathNavigator2
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// (C) 2004 Novell Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.Collections;
+using System.Text;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+
+namespace Mono.Xml.XPath
+{
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+               class DTMXPathNavigator2 : XPathNavigator, IXmlLineInfo
+       {
+
+               public DTMXPathNavigator2 (DTMXPathDocument2 document,
+                       XmlNameTable nameTable,
+                       DTMXPathLinkedNode2 [] nodes,
+                       DTMXPathAttributeNode2 [] attributes,
+                       DTMXPathNamespaceNode2 [] namespaces,
+                       string [] atomicStringPool,
+                       string [] nonAtomicStringPool,
+                       Hashtable idTable)
+               {
+                       this.nodes = nodes;
+                       this.attributes = attributes;
+                       this.namespaces = namespaces;
+                       this.atomicStringPool = atomicStringPool;
+                       this.nonAtomicStringPool = nonAtomicStringPool;
+                       this.idTable = idTable;
+                       this.nameTable = nameTable;
+                       this.MoveToRoot ();
+                       this.document = document;
+               }
+
+               // Copy constructor including position informations.
+               public DTMXPathNavigator2 (DTMXPathNavigator2 org)
+                       : this (org.document, org.nameTable,
+                       org.nodes, org.attributes, org.namespaces,
+                       org.atomicStringPool, org.nonAtomicStringPool,
+                       org.idTable)
+               {
+                       currentIsNode = org.currentIsNode;
+                       currentIsAttr = org.currentIsAttr;
+
+                       currentNode = org.currentNode;
+                       currentAttr = org.currentAttr;
+                       currentNs = org.currentNs;
+               }
+
+               XmlNameTable nameTable;
+
+               // Created XPathDocument. This is used to identify the origin of the navigator.
+               DTMXPathDocument2 document;
+
+               DTMXPathLinkedNode2 [] nodes;// = new DTMXPathLinkedNode [0];
+               DTMXPathAttributeNode2 [] attributes;// = new DTMXPathAttributeNode [0];
+               DTMXPathNamespaceNode2 [] namespaces;// = new DTMXPathNamespaceNode [0];
+
+               // String pool
+               string [] atomicStringPool;
+               string [] nonAtomicStringPool;
+
+               // ID table
+               Hashtable idTable;
+
+               bool currentIsNode;
+               bool currentIsAttr;
+
+               int currentNode;
+               int currentAttr;
+               int currentNs;
+
+               StringBuilder valueBuilder;
+
+#region Ctor
+
+               internal DTMXPathNavigator2 (XmlNameTable nt)
+               {
+                       this.nameTable = nt;
+               }
+
+#endregion
+
+#region Properties
+
+               public override string BaseURI {
+                       get { return atomicStringPool [nodes [currentNode].BaseURI]; }
+               }
+
+               public override bool HasAttributes {
+                       get { return currentIsNode ? nodes [currentNode].FirstAttribute != 0 : false; }
+               }
+               
+               public override bool HasChildren {
+                       get { return currentIsNode ? nodes [currentNode].FirstChild != 0 : false; }
+               }
+
+               public override bool IsEmptyElement {
+                       get { return currentIsNode ? nodes [currentNode].IsEmptyElement : false; }
+               }
+
+               int IXmlLineInfo.LineNumber {
+                       get {
+                               return currentIsAttr ? attributes [currentAttr].LineNumber :
+                                       nodes [currentNode].LineNumber;
+                       }
+               }
+
+               int IXmlLineInfo.LinePosition {
+                       get {
+                               return currentIsAttr ? attributes [currentAttr].LinePosition :
+                                       nodes [currentNode].LinePosition;
+                       }
+               }
+
+               public override string LocalName {
+                       get {
+                               if (currentIsNode)
+                                       return atomicStringPool [nodes [currentNode].LocalName];
+                               else if (currentIsAttr)
+                                       return atomicStringPool [attributes [currentAttr].LocalName];
+                               else
+                                       return atomicStringPool [namespaces [currentNs].Name];
+                       }
+               }
+
+               // It maybe scarcely used, so I decided to compute it always.
+               public override string Name {
+                       get {
+                               string prefix;
+                               string localName;
+                               if (currentIsNode) {
+                                       prefix = atomicStringPool [nodes [currentNode].Prefix];
+                                       localName = atomicStringPool [nodes [currentNode].LocalName];
+                               } else if (currentIsAttr) {
+                                       prefix = atomicStringPool [attributes [currentAttr].Prefix];
+                                       localName = atomicStringPool [attributes [currentAttr].LocalName];
+                               } else
+                                       return atomicStringPool [namespaces [currentNs].Name];
+
+                               if (prefix != "")
+                                       return prefix + ':' + localName;
+                               else
+                                       return localName;
+                       }
+               }
+
+               public override string NamespaceURI {
+                       get {
+                               if (currentIsNode)
+                                       return atomicStringPool [nodes [currentNode].NamespaceURI];
+                               if (currentIsAttr)
+                                       return atomicStringPool [attributes [currentAttr].NamespaceURI];
+                               return String.Empty;
+                       }
+               }
+
+               public override XmlNameTable NameTable {
+                       get { return nameTable; }
+               }
+
+               public override XPathNodeType NodeType {
+                       get {
+                               if (currentIsNode)
+                                       return nodes [currentNode].NodeType;
+                               else if (currentIsAttr)
+                                       return XPathNodeType.Attribute;
+                               else
+                                       return XPathNodeType.Namespace;
+                       }
+               }
+
+               public override string Prefix {
+                       get {
+                               if (currentIsNode)
+                                       return atomicStringPool [nodes [currentNode].Prefix];
+                               else if (currentIsAttr)
+                                       return atomicStringPool [attributes [currentAttr].Prefix];
+                               return String.Empty;
+                       }
+               }
+
+               public override string Value {
+                       get {
+                               if (currentIsAttr)
+                                       return nonAtomicStringPool [attributes [currentAttr].Value];
+                               else if (!currentIsNode)
+                                       return atomicStringPool [namespaces [currentNs].Namespace];
+                               
+                               switch (nodes [currentNode].NodeType) {
+                               case XPathNodeType.Comment:
+                               case XPathNodeType.ProcessingInstruction:
+                               case XPathNodeType.Text:
+                               case XPathNodeType.Whitespace:
+                               case XPathNodeType.SignificantWhitespace:
+                                       return nonAtomicStringPool [nodes [currentNode].Value];
+                               }
+
+                               // Element
+                               if (valueBuilder == null)
+                                       valueBuilder = new StringBuilder ();
+                               else
+                                       valueBuilder.Length = 0;
+                               
+                               int iter = nodes [currentNode].FirstChild;
+                               int depth = nodes [currentNode].Depth;
+                               while (iter < nodes.Length && nodes [iter].Depth > depth) {
+                                       switch (nodes [iter].NodeType) {
+                                       case XPathNodeType.Comment:
+                                       case XPathNodeType.ProcessingInstruction:
+                                               break;
+                                       default:
+                                               valueBuilder.Append (nonAtomicStringPool [nodes [iter].Value]);
+                                               break;
+                                       }
+                                       iter++;
+                               }
+                               
+                               return valueBuilder.ToString ();
+                       }
+               }
+
+               public override string XmlLang {
+                       get { return atomicStringPool [nodes [currentNode].XmlLang]; }
+               }
+
+#endregion
+
+#region Methods
+
+               public override XPathNavigator Clone ()
+               {
+                       return new DTMXPathNavigator2 (this);
+               }
+
+               public override XmlNodeOrder ComparePosition (XPathNavigator nav)
+               {
+                       DTMXPathNavigator2 another = nav as DTMXPathNavigator2;
+
+                       if (another == null || another.document != this.document)
+                               return XmlNodeOrder.Unknown;
+
+                       if (currentNode > another.currentNode)
+                               return XmlNodeOrder.After;
+                       else if (currentNode < another.currentNode)
+                               return XmlNodeOrder.Before;
+
+                       // another may attr or ns, 
+                       // and this may be also attr or ns.
+                       if (another.currentIsAttr) {
+                               if (this.currentIsAttr) {
+                                       if (currentAttr > another.currentAttr)
+                                               return XmlNodeOrder.After;
+                                       else if (currentAttr < another.currentAttr)
+                                               return XmlNodeOrder.Before;
+                                       else
+                                               return XmlNodeOrder.Same;
+                               } else
+                                       return XmlNodeOrder.Before;
+                       } else if (!another.currentIsNode) {
+                               if (!this.currentIsNode) {
+                                       if (currentNs > another.currentNs)
+                                               return XmlNodeOrder.After;
+                                       else if (currentNs < another.currentNs)
+                                               return XmlNodeOrder.Before;
+                                       else
+                                               return XmlNodeOrder.Same;
+                               } else
+                                       return XmlNodeOrder.Before;
+                       } else
+                               return !another.currentIsNode ? XmlNodeOrder.Before : XmlNodeOrder.Same;
+               }
+
+               private int findAttribute (string localName, string namespaceURI)
+               {
+                       if (currentIsNode && nodes [currentNode].NodeType == XPathNodeType.Element) {
+                               int cur = nodes [currentNode].FirstAttribute;
+                               while (cur != 0) {
+                                       if (atomicStringPool [attributes [cur].LocalName] == localName && atomicStringPool [attributes [cur].NamespaceURI] == namespaceURI)
+                                               return cur;
+                                       cur = attributes [cur].NextAttribute;
+                               }
+                       }
+                       return 0;
+               }
+
+               public override string GetAttribute (string localName,
+                       string namespaceURI)
+               {
+                       int attr = findAttribute (localName, namespaceURI);
+                       return (attr != 0) ? nonAtomicStringPool [attributes [attr].Value] : String.Empty;
+               }
+
+               public override string GetNamespace (string name)
+               {
+                       if (currentIsNode && nodes [currentNode].NodeType == XPathNodeType.Element) {
+                               int nsNode = nodes [currentNode].FirstNamespace;
+                               while (nsNode != 0) {
+                                       if (atomicStringPool [namespaces [nsNode].Name] == name)
+                                               return atomicStringPool [namespaces [nsNode].Namespace];
+                                       nsNode = namespaces [nsNode].NextNamespace;
+                               }
+                       }
+                       return String.Empty;
+               }
+
+               bool IXmlLineInfo.HasLineInfo ()
+               {
+                       return true;
+               }
+
+               public override bool IsDescendant (XPathNavigator nav)
+               {
+                       DTMXPathNavigator2 another = nav as DTMXPathNavigator2;
+
+                       if (another == null || another.document != this.document)
+                               return false;
+
+                       // Maybe we can improve here more efficiently by
+                       // comparing node indices.
+                       if (another.currentNode == currentNode)
+                               return !another.currentIsNode;
+                       int tmp = nodes [another.currentNode].Parent;
+                       while (tmp != 0) {
+                               if (tmp == currentNode)
+                                       return true;
+                               tmp = nodes [tmp].Parent;
+                       }
+                       return false;
+               }
+
+               public override bool IsSamePosition (XPathNavigator other)
+               {
+                       DTMXPathNavigator2 another = other as DTMXPathNavigator2;
+
+                       if (another == null || another.document != this.document)
+                               return false;
+
+                       if (this.currentNode != another.currentNode ||
+                               this.currentIsAttr != another.currentIsAttr ||
+                               this.currentIsNode != another.currentIsNode)
+                               return false;
+
+                       if (currentIsAttr)
+                               return this.currentAttr == another.currentAttr;
+                       else if (!currentIsNode)
+                               return this.currentNs == another.currentNs;
+                       return true;
+               }
+
+               public override bool MoveTo (XPathNavigator other)
+               {
+                       DTMXPathNavigator2 another = other as DTMXPathNavigator2;
+
+                       if (another == null || another.document != this.document)
+                               return false;
+
+                       this.currentNode = another.currentNode;
+                       this.currentAttr = another.currentAttr;
+                       this.currentNs = another.currentNs;
+                       this.currentIsNode = another.currentIsNode;
+                       this.currentIsAttr = another.currentIsAttr;
+                       return true;
+               }
+
+               public override bool MoveToAttribute (string localName,
+                       string namespaceURI)
+               {
+                       int attr = findAttribute (localName, namespaceURI);
+                       if (attr == 0)
+                               return false;
+
+                       currentAttr = attr;
+                       currentIsAttr = true;
+                       currentIsNode = false;
+                       return true;
+               }
+
+               public override bool MoveToFirst ()
+               {
+                       if (currentIsAttr)
+                               return false;
+
+                       int cur = nodes [currentNode].PreviousSibling;
+                       if (cur == 0)
+                               return false;
+
+                       int next = cur;
+                       while (next != 0) {
+                               cur = next;
+                               next = nodes [cur].PreviousSibling;
+                       }
+                       currentNode = cur;
+                       currentIsNode = true;
+                       return true;
+               }
+
+               public override bool MoveToFirstAttribute ()
+               {
+                       if (!currentIsNode)
+                               return false;
+
+                       int first = nodes [currentNode].FirstAttribute;
+                       if (first == 0)
+                               return false;
+
+                       currentAttr = first;
+                       currentIsAttr = true;
+                       currentIsNode = false;
+                       return true;
+               }
+
+               public override bool MoveToFirstChild ()
+               {
+                       if (!currentIsNode)
+                               return false;
+
+                       int first = nodes [currentNode].FirstChild;
+                       if (first == 0)
+                               return false;
+
+                       currentNode = first;
+                       return true;
+               }
+               
+               private bool moveToSpecifiedNamespace (int cur,
+                       XPathNamespaceScope namespaceScope)
+               {
+                       if (cur == 0)
+                               return false;
+
+                       if (namespaceScope == XPathNamespaceScope.Local &&
+                                       namespaces [cur].DeclaredElement != currentNode)
+                               return false;
+
+                       if (namespaceScope != XPathNamespaceScope.All
+                               && namespaces [cur].Namespace == XmlNamespaces.IndexXML)
+                               return false;
+
+                       if (cur != 0) {
+                               moveToNamespace (cur);
+                               return true;
+                       }
+                       else
+                               return false;
+               }
+
+               public override bool MoveToFirstNamespace (
+                       XPathNamespaceScope namespaceScope)
+               {
+                       if (!currentIsNode)
+                               return false;
+                       int cur = nodes [currentNode].FirstNamespace;
+                       return moveToSpecifiedNamespace (cur, namespaceScope);
+               }
+
+               // Note that this support is extension to XPathDocument.
+               // XPathDocument does not support ID reference.
+               public override bool MoveToId (string id)
+               {
+                       if (idTable.ContainsKey (id)) {
+                               currentNode = (int) idTable [id];
+                               currentIsNode = true;
+                               currentIsAttr = false;
+                               return true;
+                       }
+                       else
+                               return false;
+               }
+
+               private void moveToNamespace (int nsNode)
+               {
+                       currentIsNode = currentIsAttr = false;
+                       currentNs = nsNode;
+               }
+
+               public override bool MoveToNamespace (string name)
+               {
+                       int cur = nodes [currentNode].FirstNamespace;
+                       if (cur == 0)
+                               return false;
+
+                       while (cur != 0) {
+                               if (atomicStringPool [namespaces [cur].Name] == name) {
+                                       moveToNamespace (cur);
+                                       return true;
+                               }
+                               cur = namespaces [cur].NextNamespace;
+                       }
+                       return false;
+               }
+
+               public override bool MoveToNext ()
+               {
+                       if (currentIsAttr)
+                               return false;
+
+                       int next = nodes [currentNode].NextSibling;
+                       if (next == 0)
+                               return false;
+                       currentNode = next;
+                       currentIsNode = true;
+                       return true;
+               }
+
+               public override bool MoveToNextAttribute ()
+               {
+                       if (!currentIsAttr)
+                               return false;
+
+                       int next = attributes [currentAttr].NextAttribute;
+                       if (next == 0)
+                               return false;
+                       currentAttr = next;
+                       return true;
+               }
+
+               public override bool MoveToNextNamespace (
+                       XPathNamespaceScope namespaceScope)
+               {
+                       if (currentIsAttr || currentIsNode)
+                               return false;
+
+                       int cur = namespaces [currentNs].NextNamespace;
+                       return moveToSpecifiedNamespace (cur, namespaceScope);
+               }
+
+               public override bool MoveToParent ()
+               {
+                       if (!currentIsNode) {
+                               currentIsNode = true;
+                               currentIsAttr = false;
+                               return true;
+                       }
+
+                       int parent = nodes [currentNode].Parent;
+                       if (parent == 0)        // It is root itself.
+                               return false;
+
+                       currentNode = parent;
+                       return true;
+               }
+
+               public override bool MoveToPrevious ()
+               {
+                       if (currentIsAttr)
+                               return false;
+
+                       int previous = nodes [currentNode].PreviousSibling;
+                       if (previous == 0)
+                               return false;
+                       currentNode = previous;
+                       currentIsNode = true;
+                       return true;
+               }
+
+               public override void MoveToRoot ()
+               {
+                       currentNode = 1;        // root is 1.
+                       currentIsNode = true;
+                       currentIsAttr = false;
+               }
+
+#endregion
+       }
+}
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode2.cs
new file mode 100755 (executable)
index 0000000..a3b38c4
--- /dev/null
@@ -0,0 +1,105 @@
+//
+// Mono.Xml.XPath.DTMXPathNode2.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// (C) 2004 Novell Inc
+//
+// These classes represent each node of DTMXPathNavigator.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Xml.XPath;
+
+namespace Mono.Xml.XPath
+{
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+#if DTM_CLASS
+               class DTMXPathLinkedNode2
+#else
+               struct DTMXPathLinkedNode2
+#endif
+       {
+               public int FirstChild;
+               public int Parent;
+               public int PreviousSibling;
+               public int NextSibling;
+               public int FirstAttribute;
+               public int FirstNamespace;
+               public int Depth;
+               public XPathNodeType NodeType;
+               public int BaseURI;
+               public bool IsEmptyElement;
+               public int LocalName;
+               public int NamespaceURI;
+               public int Prefix;
+               public int Value;
+               public int XmlLang;
+               public int LineNumber;
+               public int LinePosition;
+       }
+
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+#if DTM_CLASS
+               class DTMXPathAttributeNode2
+#else
+               struct DTMXPathAttributeNode2
+#endif
+       {
+               public int OwnerElement;
+               public int NextAttribute;
+               public int LocalName;
+               public int NamespaceURI;
+               public int Prefix;
+               public int Value;
+               public int LineNumber;
+               public int LinePosition;
+       }
+
+#if OUTSIDE_SYSTEM_XML
+       public
+#else
+       internal
+#endif
+#if DTM_CLASS
+               class DTMXPathNamespaceNode2
+#else
+               struct DTMXPathNamespaceNode2
+#endif
+       {
+               public int DeclaredElement;
+               public int NextNamespace;
+               public int Name;
+               public int Namespace;
+       }
+}
index 3e4001877788e9083586cc11ebdde18ef5167376..75c01b0184eab513fbc095dd535ce33534f9f58a 100755 (executable)
@@ -1,3 +1,35 @@
+2004-12-04  Atsushi Enomoto <atsushi@ximian.com>
+
+       * XmlSchemaObject.cs : added Parent.
+       * XmlSchema.cs,
+         XmlSchemaElement.cs,
+         XmlSchemaAttribute.cs,
+         XmlSchemaAttributeGroup.cs,
+         XmlSchemaGroup.cs,
+         XmlSchemaComplexType.cs,
+         XmlSchemaSequence.cs,
+         XmlSchemaChoice.cs,
+         XmlSchemaAll.cs,
+         XmlSchemaIdentityConstraint.cs,
+         XmlSchemaComplexContent.cs,
+         XmlSchemaSimpleContent.cs,
+         XmlSchemaSimpleContentExtension.cs,
+         XmlSchemaSimpleContentRestriction.cs,
+         XmlSchemaComplexContentExtension.cs,
+         XmlSchemaComplexContentRestriction.cs,
+         XmlSchemaSimpleType.cs,
+         XmlSchemaSimpleTypeRestriction.cs,
+         XmlSchemaSimpleTypeList.cs,
+         XmlSchemaSimpleTypeUnion.cs : Fill Parent on Compilation.
+
+       * XmlSchemaException.cs,
+         XmlSchemaInferenceException.cs,
+         XmlSchemaValidationException.cs : added SecurityPermissionAttribute.
+
+2004-12-04  Atsushi Enomoto <atsushi@ximian.com>
+
+       * XmlSchemaComplexType.cs : simplify Compile().
+
 2004-11-25  Atsushi Enomoto <atsushi@ximian.com>
 
        * XmlSchemaElement.cs,
index 69f70630e087d3f141be55a8ed75768d9974f920..e123f6ebfe0625a86e9b54f48e62d14c9eedf7d3 100755 (executable)
@@ -342,14 +342,21 @@ namespace System.Xml.Schema
                        // Compile the content of this schema
 
                        compilationItems = new XmlSchemaObjectCollection ();
-                       for (int i = 0; i < Items.Count; i++)
+                       for (int i = 0; i < Items.Count; i++) {
+#if NET_2_0
+                               Items [i].Parent = this;
+#endif
                                compilationItems.Add (Items [i]);
+                       }
                        if (this == rootSchema)
                                handledUris = new Hashtable ();
 
                        // First, we run into inclusion schemas to collect 
                        // compilation target items into compiledItems.
                        for (int i = 0; i < Includes.Count; i++) {
+#if NET_2_0
+                               Includes [i].Parent = this;
+#endif
                                XmlSchemaExternal ext = Includes [i] as XmlSchemaExternal;
                                if (ext == null) {
                                        error (handler, String.Format ("Object of Type {0} is not valid in Includes Property of XmlSchema", Includes [i].GetType().Name));
index d4ccf49ee36e6af313efad8d3718c81a26f45e5c..d9e5bc9bebffb9da37dfee4fddf77649adefcd14 100755 (executable)
@@ -82,6 +82,10 @@ namespace System.Xml.Schema
 \r
                        foreach(XmlSchemaObject obj in Items)\r
                        {\r
+#if NET_2_0\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                                XmlSchemaElement elem = obj as XmlSchemaElement;\r
                                if(elem != null)\r
                                {\r
index 50588b9731465f6c4b5d95f7864a070cc8dc62a8..ca9f0cc051061b87d73967c59c5570fb877efa0e 100755 (executable)
@@ -246,6 +246,11 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (schemaType != null)\r
+                               schemaType.Parent = this;\r
+#endif\r
+\r
                        errorCount = 0;\r
                        \r
                        if(ParentIsSchema || isRedefineChild)//a\r
index c7e011a398dbec9d7e3485ae492c1c048ddeca5a..52c825469b5d77ad06f2264a86499fe024197b75 100755 (executable)
@@ -132,11 +132,18 @@ namespace System.Xml.Schema
                        \r
                        if(this.AnyAttribute != null)\r
                        {\r
+#if NET_2_0\r
+                               this.AnyAttribute.Parent = this;\r
+#endif\r
                                errorCount += this.AnyAttribute.Compile(h, schema);\r
                        }\r
                        \r
                        foreach(XmlSchemaObject obj in Attributes)\r
                        {\r
+#if NET_2_0\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                                if(obj is XmlSchemaAttribute)\r
                                {\r
                                        XmlSchemaAttribute attr = (XmlSchemaAttribute) obj;\r
index 907080eb7cf0a1e79a1c2db0a01d0f387feaf398..049ac641aed2932e619b7156a86e9d1ac72d1fdb 100755 (executable)
@@ -68,6 +68,10 @@ namespace System.Xml.Schema
 \r
                        foreach(XmlSchemaObject obj in Items)\r
                        {\r
+#if NET_2_0\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                                if(obj is XmlSchemaElement ||\r
                                        obj is XmlSchemaGroupRef ||\r
                                        obj is XmlSchemaChoice ||\r
index 976899fe800eaf5b7a1aaddc04526d0cac9a1d7e..2254f17e4419b3b590c8cfc40368b9848706b841 100755 (executable)
@@ -68,6 +68,11 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                               if (Content != null)\r
+                                       Content.Parent = this;\r
+#endif\r
+\r
                        if (isRedefinedComponent) {\r
                                if (Annotation != null)\r
                                        Annotation.isRedefinedComponent = true;\r
index 3f1196739f8b5e0bb262dbfa1c4942002f45c3b8..75b2a86e01776b46a498e07df84406fda11863f3 100755 (executable)
@@ -93,6 +93,15 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (Particle != null)\r
+                               Particle.Parent = this;\r
+                       if (AnyAttribute != null)\r
+                               AnyAttribute.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Attributes)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        if (this.isRedefinedComponent) {\r
                                if (Annotation != null)\r
                                        Annotation.isRedefinedComponent = true;\r
index 08a56feb6e4dc5c47ec0dc2f87936555238444fa..89d7f7b34f8685ebd3f9fb3c738f76fcf3315630 100755 (executable)
@@ -94,6 +94,15 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (Particle != null)\r
+                               Particle.Parent = this;\r
+                       if (AnyAttribute != null)\r
+                               AnyAttribute.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Attributes)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        if (this.isRedefinedComponent) {\r
                                if (Annotation != null)\r
                                        Annotation.isRedefinedComponent = true;\r
index 69666fe3060e14821ed5459da4554164ae926557..9baea7d906ccbd4e9cc8a79aa2df911a1b7be268 100755 (executable)
@@ -227,6 +227,17 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return errorCount;\r
 \r
+#if NET_2_0\r
+                       if (ContentModel != null)\r
+                               ContentModel.Parent = this;\r
+                       if (Particle != null)\r
+                               Particle.Parent = this;\r
+                       if (AnyAttribute != null)\r
+                               AnyAttribute.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Attributes)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        ValidatedIsAbstract = isAbstract;\r
 \r
                        if (isRedefinedComponent) {\r
@@ -340,26 +351,8 @@ namespace System.Xml.Schema
                        }\r
                        else\r
                        {\r
-                               if(Particle is XmlSchemaGroupRef)\r
-                               {\r
-                                       XmlSchemaGroupRef xsgr = (XmlSchemaGroupRef)Particle;\r
-                                       errorCount += xsgr.Compile(h,schema);\r
-                               }\r
-                               else if(Particle is XmlSchemaAll)\r
-                               {\r
-                                       XmlSchemaAll xsa = (XmlSchemaAll)Particle;\r
-                                       errorCount += xsa.Compile(h,schema);\r
-                               }\r
-                               else if(Particle is XmlSchemaChoice)\r
-                               {\r
-                                       XmlSchemaChoice xsc = (XmlSchemaChoice)Particle;\r
-                                       errorCount += xsc.Compile(h,schema);\r
-                               }\r
-                               else if(Particle is XmlSchemaSequence)\r
-                               {\r
-                                       XmlSchemaSequence xss = (XmlSchemaSequence)Particle;\r
-                                       errorCount += xss.Compile(h,schema);\r
-                               }\r
+                               if (Particle != null)\r
+                                       errorCount += Particle.Compile (h, schema);\r
 \r
                                if(this.anyAttribute != null)\r
                                {\r
index 3130423f8dc5a8b6263e69c9969c8b3a60898ac6..2f040b807181235c485bef2bfb2748bfa38028cd 100755 (executable)
@@ -354,6 +354,12 @@ namespace System.Xml.Schema
                                return 0;\r
                        InitPostCompileInformations ();\r
                        this.schema = schema;\r
+#if NET_2_0\r
+                       if (SchemaType != null)\r
+                               SchemaType.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Constraints)\r
+                               obj.Parent = this;\r
+#endif\r
 \r
                        if(this.defaultValue != null && this.fixedValue != null)\r
                                error(h,"both default and fixed can't be present");\r
index 9e1c45883a47e3e28ab7d2b47ba0ff71048c4ae3..1b2c107190bf05a94e1ebcda4dcec119ecfdbc00 100755 (executable)
@@ -29,7 +29,7 @@
 using System;\r
 using System.Globalization;\r
 using System.Runtime.Serialization;\r
-\r
+using System.Security.Permissions;\r
 \r
 namespace System.Xml.Schema\r
 {\r
@@ -170,6 +170,10 @@ namespace System.Xml.Schema
 #endif\r
 \r
                // Methods\r
+#if NET_2_0\r
+               [SecurityPermission (SecurityAction.LinkDemand,\r
+                       Flags=SecurityPermissionFlag.SerializationFormatter)]\r
+#endif\r
                public override void GetObjectData(SerializationInfo info, StreamingContext context)\r
                {\r
                        base.GetObjectData (info, context);\r
index 63b5656f8dc32702b32864be5ef88349e5eda398..d308b3f8668b50f35bc85bd68177808d1ac2ff93 100755 (executable)
@@ -89,6 +89,11 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (Particle != null)\r
+                               Particle.Parent = this;\r
+#endif\r
+\r
                        if(Name == null)\r
                                error(h,"Required attribute name must be present");\r
                        else if(!XmlSchemaUtil.CheckNCName(this.name)) \r
index 49f8b76041ee2c7be44e2a9b23bbb811a5147fef..ce125f4f51f5758ba3f6247643175cecd851eecc 100755 (executable)
@@ -88,6 +88,13 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (Selector != null)\r
+                               Selector.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Fields)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        if(Name == null)\r
                                error(h,"Required attribute name must be present");\r
                        else if(!XmlSchemaUtil.CheckNCName(this.name)) \r
index e66bd594991a2f92b8d357dfcbe815556169f26c..4153172a0bb66d4daf2bbe45b6db475c01fd7896 100755 (executable)
@@ -32,6 +32,7 @@
 
 using System;
 using System.Runtime.Serialization;
+using System.Security.Permissions;
 using System.Xml;
 
 namespace System.Xml.Schema
@@ -67,6 +68,10 @@ namespace System.Xml.Schema
                {
                }
 
+#if NET_2_0
+               [SecurityPermission (SecurityAction.LinkDemand,
+                       Flags=SecurityPermissionFlag.SerializationFormatter)]
+#endif
                public override void GetObjectData (
                        SerializationInfo info, StreamingContext context)
                {
index b9964e583d3cfd110a4c2d81f3fb96af2ecf03d6..99279cb7cc0d5bde0ce38cd798a87a14fe6fac71 100755 (executable)
@@ -51,6 +51,11 @@ namespace System.Xml.Schema
                internal bool isRedefinedComponent;\r
                internal XmlSchemaObject redefinedObject;\r
 \r
+#if NET_2_0\r
+               private XmlSchemaObject parent;\r
+#endif\r
+\r
+\r
                protected XmlSchemaObject()\r
                {\r
                        namespaces = new XmlSerializerNamespaces();\r
@@ -77,6 +82,14 @@ namespace System.Xml.Schema
                        set{ sourceUri = value; } \r
                }\r
 \r
+#if NET_2_0\r
+               [XmlIgnore]\r
+               public XmlSchemaObject Parent {\r
+                       get { return parent; }\r
+                       set { parent = value; }\r
+               }\r
+#endif\r
+\r
                // Undocumented Property\r
                [XmlNamespaceDeclarations]\r
                public XmlSerializerNamespaces Namespaces \r
index bf67575dc70ebab3e0a5b834c878582ba2c93d24..bee469c49928ad4e6432eaa5abba388e9e89648f 100755 (executable)
@@ -67,6 +67,9 @@ namespace System.Xml.Schema
 \r
                        foreach(XmlSchemaObject obj in Items)\r
                        {\r
+#if NET_2_0\r
+                               obj.Parent = this;\r
+#endif\r
                                if(obj is XmlSchemaElement ||\r
                                        obj is XmlSchemaGroupRef ||\r
                                        obj is XmlSchemaChoice ||\r
index 3443cc4ac615ab032e4fa1535eae0694b84a0c06..485dcf17b45220de85286f5af3621cfebee3efb3 100755 (executable)
@@ -66,6 +66,9 @@ namespace System.Xml.Schema
                        }\r
                        else\r
                        {\r
+#if NET_2_0\r
+                               Content.Parent = this;\r
+#endif\r
                                if(Content is XmlSchemaSimpleContentRestriction)\r
                                {\r
                                        XmlSchemaSimpleContentRestriction xscr = (XmlSchemaSimpleContentRestriction) Content;\r
index 158fd988adb24ce99d724c74af3ea2cd083ed3ba..ac304ca1949b4df08c814937c326c1a79eeb90a7 100755 (executable)
@@ -84,6 +84,13 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (AnyAttribute != null)\r
+                               AnyAttribute.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Attributes)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        if (this.isRedefinedComponent) {\r
                                if (Annotation != null)\r
                                        Annotation.isRedefinedComponent = true;\r
index 676c0e6dd0e17ec0edfde5831217897c8cf1771d..99d1e77f4808af9a1eebb639f3a5eb3cb12fbba9 100755 (executable)
@@ -105,6 +105,14 @@ namespace System.Xml.Schema
                        // If this is already compiled this time, simply skip.\r
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
+#if NET_2_0\r
+                       if (BaseType != null)\r
+                               BaseType.Parent = this;\r
+                       if (AnyAttribute != null)\r
+                               AnyAttribute.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Attributes)\r
+                               obj.Parent = this;\r
+#endif\r
 \r
                        if (this.isRedefinedComponent) {\r
                                if (Annotation != null)\r
index 75d33c15ff5d03ebe99eee80e970a3e34ca91747..58af71673b384c0e4bae91219dc3ae83a6bd145c 100755 (executable)
@@ -249,6 +249,10 @@ namespace System.Xml.Schema
                        // If this is already compiled this time, simply skip.\r
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
+#if NET_2_0\r
+                       if (Content != null)\r
+                               Content.Parent = this;\r
+#endif\r
 \r
                        errorCount = 0;\r
 \r
index dad7b7b565336f8b5028609be3f0cba72beaccc9..2f6d663c2427be8545ea6ad7cf90d5e7fea5d6e0 100755 (executable)
@@ -90,6 +90,11 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (ItemType != null)\r
+                               ItemType.Parent = this;\r
+#endif\r
+\r
                        errorCount = 0;\r
 \r
                        if(ItemType != null && !ItemTypeName.IsEmpty)\r
index 9ee96a479f5f85c1f8247d6be480e457b8538cca..b6266fac2613f4bb820682209849962c69f79e3b 100755 (executable)
@@ -105,6 +105,13 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       if (BaseType != null)\r
+                               BaseType.Parent = this;\r
+                       foreach (XmlSchemaObject obj in Facets)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        errorCount = 0;\r
 \r
                        if(this.baseType != null && !this.BaseTypeName.IsEmpty)\r
index 4e9ad54f0933cff90efc3f743aa3093069955ff1..a00a2f9dbc8728dec0be8fd43ba748343351d646 100755 (executable)
@@ -81,6 +81,11 @@ namespace System.Xml.Schema
                        if (this.IsComplied (schema.CompilationId))\r
                                return 0;\r
 \r
+#if NET_2_0\r
+                       foreach (XmlSchemaObject obj in BaseTypes)\r
+                               obj.Parent = this;\r
+#endif\r
+\r
                        errorCount = 0;\r
 \r
                        int count = BaseTypes.Count;\r
index 19e7c408d37ad3a63294ac404bed2dadfafa87d8..8b6b9542ad452be837288f8503be34f2722c858f 100755 (executable)
@@ -33,7 +33,7 @@
 using System;
 using System.Globalization;
 using System.Runtime.Serialization;
-
+using System.Security.Permissions;
 
 namespace System.Xml.Schema
 {
@@ -83,6 +83,15 @@ namespace System.Xml.Schema
                {
                }
 
+#if NET_2_0
+               [SecurityPermission (SecurityAction.LinkDemand,
+                       Flags=SecurityPermissionFlag.SerializationFormatter)]
+#endif
+               public override void GetObjectData (
+                       SerializationInfo info, StreamingContext context)
+               {
+                       base.GetObjectData (info, context);
+               }
        }
 }
 
index d04f702f9edd7e4cc2e8e64c32a67faa985bd3a8..e96ec35a667869b11eca0e8c05c7aba1eaa046dd 100644 (file)
@@ -1,3 +1,11 @@
+2004-12-04  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XPathDocument.cs : switch to DTMXPathNavigator2 which fully
+         eliminated string fields from struct.
+         (When we switch from struct to class, revert this change to use
+         DTMXPathNavigator, since class-based DTMXPathNavigator2 is rather
+         wasting processing speed.)
+
 2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
 
        * Iterator.cs : when PredicateIterator has a numeric predicate, it
index f922755a0b771e66a94de91e641b373392b5e391..c3e348accfc9bd5c69f5a6f51e39db3f17441365 100644 (file)
@@ -39,6 +39,11 @@ using System.Xml.Schema;
 using System.Xml.Serialization;
 using Mono.Xml.XPath;
 
+//using InternalBuilder = Mono.Xml.XPath.DTMXPathDocumentBuilder;
+//using InternalDocument = Mono.Xml.XPath.DTMXPathDocument;
+using InternalBuilder = Mono.Xml.XPath.DTMXPathDocumentBuilder2;
+using InternalDocument = Mono.Xml.XPath.DTMXPathDocument2;
+
 namespace System.Xml.XPath
 {
 #if NET_2_0obsolete
@@ -60,7 +65,7 @@ namespace System.Xml.XPath
                }
 
                XPathDocument2Editable editable;
-               DTMXPathDocument dtm;
+               InternalDocument dtm;
 
                XmlSchemaSet schemas;
 
@@ -168,7 +173,7 @@ namespace System.Xml.XPath
                        if (useEditable)
                                InitializeEditable (reader, space, acceptChangesOnLoad);
                        else
-                               dtm = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
+                               dtm = new InternalBuilder (reader, space).CreateDocument ();
                }
 
                private void InitializeEditable (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
@@ -416,7 +421,7 @@ namespace System.Xml.XPath
 
        public class XPathDocument : IXPathNavigable
        {
-               DTMXPathDocument document;
+               IXPathNavigable document;
 
                public XPathDocument (Stream stream)
                {
@@ -462,12 +467,12 @@ namespace System.Xml.XPath
 
                private void Initialize (XmlReader reader, XmlSpace space)
                {
-                       document = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
+                       document = new InternalBuilder (reader, space).CreateDocument ();
                }
 
                private void Initialize (XmlReader reader, XmlSpace space, bool acceptChangesOnLoad)
                {
-                       document = new DTMXPathDocumentBuilder (reader, space).CreateDocument ();
+                       document = new InternalBuilder (reader, space).CreateDocument ();
                }
 
                public XPathNavigator CreateNavigator ()
index 8f84c1ce124432933290a613c9b07f25b819c370..550d9a3d85ca4b5c1e8d287a6320da1d9651d001 100755 (executable)
@@ -11,6 +11,11 @@ Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
 Mono.Xml.XPath/DTMXPathDocumentWriter.cs
 Mono.Xml.XPath/DTMXPathNavigator.cs
 Mono.Xml.XPath/DTMXPathNode.cs
+Mono.Xml.XPath/DTMXPathDocument2.cs
+Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
+Mono.Xml.XPath/DTMXPathDocumentWriter2.cs
+Mono.Xml.XPath/DTMXPathNavigator2.cs
+Mono.Xml.XPath/DTMXPathNode2.cs
 Mono.Xml.XPath/IdPattern.cs
 Mono.Xml.XPath/KeyPattern.cs
 Mono.Xml.XPath/LocationPathPattern.cs
index d73d1904e6053e77856122af84e7fd3691ac4367..f99222339cd0bc2d3d5f6ec6738d79e981f57e22 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * XmlTextReader.cs: don't use \0 as buffer terminator.
+       * XmlInputStream.cs: s/Array.Copy/Buffer.BlockCopy/.
+
 2004-11-30  Atsushi Enomoto <atsushi@ximian.com>
 
        * DTDReader.cs : Consideration on parameter entity was missing for 
index 9d54ef03d5f9601cae75e441861d3480ada335d8..e60951cd38e85961d6e16e68ad55e2230725ce9e 100644 (file)
@@ -269,13 +269,13 @@ namespace System.Xml
                {
                        int ret;
                        if (count <= bufLength - bufPos)        {       // all from buffer
-                               Array.Copy (this.buffer, bufPos, buffer, offset, count);
+                               Buffer.BlockCopy (this.buffer, bufPos, buffer, offset, count);
                                bufPos += count;
                                ret = count;
                        } else {
                                int bufRest = bufLength - bufPos;
                                if (bufLength > bufPos) {
-                                       Array.Copy (this.buffer, bufPos, buffer, offset, bufRest);
+                                       Buffer.BlockCopy (this.buffer, bufPos, buffer, offset, bufRest);
                                        bufPos += bufRest;
                                }
                                ret = bufRest +
index af12b95b5109b60c4f5d47d1fab609c03e667b13..0b5a0cbdee74badb437f28a17d4df0a7d4f8497d 100644 (file)
@@ -1165,9 +1165,8 @@ namespace System.Xml
                                else
                                        return PeekChar ();
                        }
-                       else
-                               return peekChars [peekCharsIndex] != 0 ?
-                                       peekChars [peekCharsIndex] : -1;
+
+                       return peekChars [peekCharsIndex];
                }
 
                private int ReadChar ()
@@ -1197,12 +1196,7 @@ namespace System.Xml
                {
                        peekCharsIndex = 0;
                        peekCharsLength = reader.Read (peekChars, 0, peekCharCapacity);
-                       if (peekCharsLength == 0)
-                               return false;
-                       // set EOF
-                       if (peekCharsLength < peekCharCapacity)
-                               peekChars [peekCharsLength] = (char) 0;
-                       return true;
+                       return (peekCharsLength != 0);
                }
 
                private string ExpandSurrogateChar (int ch)
index 2833e2100d4dc7d902b1731d7241c8706eedc690..fa86d7325f92eaa568ddcd1097006b39fa0ab3fc 100755 (executable)
@@ -1,3 +1,10 @@
+2004-12-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * xslttest.cs : improved. See "mono xslttest.exe -?" for details.
+       * Makefile : modified "make test" to "make run-test" and output
+         results into TestResult.Xml that contains all results.
+       * README : updated as well.
+
 2004-01-28  Atsushi Enomoto  <atsushi@ximian.com>
 
        * xslttest.cs : Now it tests against XPathDocument. Reduced error msgs.
index df311ec2fbe7e425884a2a2341f06bf35d82821a..164d4d5d76e35ac7ca44c7af50d90ce65e817710 100755 (executable)
@@ -18,8 +18,8 @@ $(RESULTS) :
 xslt-testsuite-01.zip :
        wget http://www.oasis-open.org/committees/download.php/1937/xslt-testsuite-01.zip
 
-test :
-       $(RUNTIME) xslttest.exe
+run-test :
+       $(RUNTIME) xslttest.exe --report:TestResult.xml --xml --details --outall
 
 # Be careful to use this!
 # clean :
index fa3a328834055cdd31fc84c63a29f9b1b9ee2cc2..c90d182e6ac19b69a8a8fdea57937a30f5dda5ce 100644 (file)
@@ -8,7 +8,7 @@ http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xslt
 "make" will do what you need (downloading test archive, expanding,
 compiling test runner.
 
-"make test" will do the actual tests.
+"make run-test" will do the actual tests.
 
 If you want to create reference output files by yourself, compile
 prepare.cs and run it on Microsoft.NET (it requires cygwin).
index 991ddfa2990f1d4e6204d1c1e17e517068d34d48..a8baa7dd4f3848b88904e936f033c10ef8d67fd7 100755 (executable)
@@ -10,74 +10,277 @@ namespace XsltTest
 {
        public class XsltTest
        {
-               public static void Main ()
+               static bool reportDetails;
+               static bool reportAsXml;
+               static bool useDomStyle;
+               static bool useDomInstance;
+               static bool generateOutput;
+               static bool whitespaceStyle;
+               static bool whitespaceInstance;
+               static bool stopImmediately;
+               static bool outputAll;
+               static readonly ArrayList skipTargets;
+               static string explicitTarget;
+               static TextWriter reportOutput = Console.Out;
+               static XmlTextWriter reportXmlWriter;
+
+               static XsltTest ()
                {
+                       skipTargets = new ArrayList (new string [] {
+"attribset15.xsl",
+"lre12.xsl", 
+"namespace23.xsl", // under .NET, XPathDocument behavior is different from dom
+"namespace40.xsl", 
+"namespace42.xsl", 
+"namespace43.xsl",
+"namespace48.xsl", 
+"namespace60.xsl", 
+"namespace73.xsl", 
+"namespace106.xsl",
 // output22,77: not-supported encoding, but MS passes...?
 // output72.xsl: should not pass
-                       ArrayList expectedExceptions = new ArrayList
-(new string [] {"attribset15.xsl", "lre12.xsl", "namespace40.xsl", "namespace42.xsl", "namespace43.xsl",
-"namespace48.xsl", "namespace60.xsl", "namespace73.xsl", "namespace106.xsl",
-"output22.xsl", "output72.xsl", "output77.xsl"});
+"output22.xsl", 
+"output72.xsl",
+"output77.xsl"
+                       }); 
+               }
+
+               static void Usage ()
+               {
+                       Console.WriteLine (@"mono xslttest.exe [options] [targetFileMatch] -report:reportfile
+
+       Options:
+               --details : Output detailed output differences.
+               --dom : use XmlDocument for both stylesheet and input source.
+               --domxsl : use XmlDocument for stylesheet.
+               --domsrc : use XmlDocument for input source.
+               --generate : generate output files specified in catalog.
+                               Use this feature only when you want to update
+                               reference output.
+               --outall : Output fine results as OK (omitted by default).
+               --stoponerror : stops the test process and throw detailed
+                       error if happened.
+               --ws : preserve spaces for both stylesheet and input source.
+               --wsxsl : preserve spaces for stylesheet.
+               --wssrc : preserve spaces for input source.
+               --xml : report into xml output.
+               --report : write reports into specified file.
+
+       FileMatch:
+               arbitrary string that specifies part of file name.
+               (no * or ? available)
+");
+               }
+
+               public static void Main (string [] args)
+               {
+                       try {
+                               RunMain (args);
+                       } catch (Exception ex) {
+                               reportOutput.WriteLine (ex);
+                       } finally {
+                               reportOutput.Close ();
+                       }
+               }
+
+               static void RunMain (string [] args)
+               {
+                       foreach (string arg in args) {
+                               switch (arg) {
+                               case "-?":
+                                       Usage ();
+                                       return;
+                               case "--dom":
+                                       useDomStyle = true;
+                                       useDomInstance = true;
+                                       break;
+                               case "--domxsl":
+                                       useDomStyle = true;
+                                       break;
+                               case "--domsrc":
+                                       useDomInstance = true;
+                                       break;
+                               case "--details":
+                                       reportDetails = true;
+                                       break;
+                               case "--generate":
+                                       generateOutput = true;
+                                       break;
+                               case "--outall":
+                                       outputAll = true;
+                                       break;
+                               case "--stoponerror":
+                                       stopImmediately = true;
+                                       break;
+                               case "--ws":
+                                       whitespaceStyle = true;
+                                       whitespaceInstance = true;
+                                       break;
+                               case "--wsxsl":
+                                       whitespaceStyle = true;
+                                       break;
+                               case "--wssrc":
+                                       whitespaceInstance = true;
+                                       break;
+                               case "--xml":
+                                       reportAsXml = true;
+                                       break;
+                               default:
+                                       if (arg.StartsWith ("--report:")) {
+                                               string reportFile = arg.Substring (9);
+                                               if (reportFile.Length < 0) {
+                                                       Usage ();
+                                                       Console.WriteLine ("Error: --report option requires filename.");
+                                                       return;
+                                               }
+                                               reportOutput = new StreamWriter (reportFile);
+                                               break;
+                                       }
+                                       if (arg.StartsWith ("--")) {
+                                               Usage ();
+                                               return;
+                                       }
+                                       explicitTarget = arg;
+                                       break;
+                               }
+                       }
+
+                       if (reportAsXml) {
+                               reportXmlWriter = new XmlTextWriter (reportOutput);
+                               reportXmlWriter.Formatting = Formatting.Indented;
+                               reportXmlWriter.WriteStartElement ("test-results");
+                       }
+
+                       if (explicitTarget != null)
+                               Console.WriteLine ("The specified target is "
+                                       + explicitTarget);
 
                        XmlDocument whole = new XmlDocument ();
                        whole.Load (@"testsuite/TESTS/Xalan_Conformance_Tests/catalog.xml");
-Console.WriteLine ("Started: " + DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
-                       foreach (XmlElement testCase in whole.SelectNodes ("test-suite/test-catalog/test-case")) {
+
+                       Console.WriteLine ("Started: " + 
+                               DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
+
+                       foreach (XmlElement testCase in whole.SelectNodes (
+                               "test-suite/test-catalog/test-case")) {
                                string stylesheetBase = null;
                                try {
                                        string filePath = testCase.SelectSingleNode ("file-path").InnerText;
                                        string path = @"testsuite/TESTS/Xalan_Conformance_Tests/" + filePath + "/";
-                                       foreach (XmlElement scenario in testCase.SelectNodes ("scenario")) {
-                                               XslTransform trans = new XslTransform ();
-                                               stylesheetBase = scenario.SelectSingleNode ("input-file[@role='principal-stylesheet']").InnerText;
-                                               string stylesheet = path + stylesheetBase;
-                                               string srcxml = path + scenario.SelectSingleNode ("input-file[@role='principal-data']").InnerText;
-//if (srcxml.IndexOf ("attribset") < 0)
-//     continue;
-if (expectedExceptions.Contains (stylesheetBase))
-       continue;
-                                               XmlTextReader stylextr = new XmlTextReader (stylesheet);
-                                               XmlValidatingReader stylexvr = new XmlValidatingReader (stylextr);
-//                                             XmlDocument styledoc = new XmlDocument ();
-//                                             styledoc.Load (stylesheet);
-                                               trans.Load (stylesheet);
-//                                             trans.Load (styledoc);
-                                               XmlTextReader xtr = new XmlTextReader (srcxml);
-                                               XmlValidatingReader xvr = new XmlValidatingReader (xtr);
-                                               xvr.ValidationType = ValidationType.None;
-//                                             XmlDocument input = new XmlDocument ();
-//                                             input.Load (xvr);
-//                                             input.Load (xtr);
-                                               XPathDocument input = new XPathDocument (xvr);
-                                               StringWriter sw = new StringWriter ();
-                                               trans.Transform (input, null, sw);
-                                               string outfile = path + scenario.SelectSingleNode ("output-file[@role='principal']").InnerText;
-                                               if (!File.Exists (outfile)) {
-//                                                     Console.WriteLine ("Reference output file does not exist.");
-                                                       continue;
-                                               }
-                                               StreamReader sr = new StreamReader (outfile);
-                                               string reference_out = sr.ReadToEnd ();
-                                               string actual_out = sw.ToString ();
-                                               if (reference_out != actual_out)
-#if true
-                                                       Console.WriteLine ("Different: " + testCase.GetAttribute ("id"));
-#else
-                                                       Console.WriteLine ("Different: " +
-                                                               testCase.GetAttribute ("id") +
-                                                               "\n" + 
-                                                               actual_out + "\n-------------------\n" + reference_out + "\n");
-#endif
+                                       foreach (XmlElement scenario in 
+                                               testCase.SelectNodes ("scenario")) {
+                                               RunTest (scenario, path, stylesheetBase);
                                        }
-//                             } catch (NotSupportedException ex) {
                                } catch (Exception ex) {
-                                       if (expectedExceptions.Contains (stylesheetBase))
+                                       if (skipTargets.Contains (stylesheetBase))
                                                continue;
-                               Console.WriteLine ("Exception: " + testCase.GetAttribute ("id") + ": " + ex.Message);
+                                       if (stopImmediately)
+                                               throw;
+                                       Report (testCase, "Exception: " + testCase.GetAttribute ("id") + ": " + ex.Message);
                                }
                        }
 Console.WriteLine ("Finished: " + DateTime.Now.ToString ("yyyyMMdd-HHmmss.fff"));
 
+                       if (reportAsXml)
+                               reportXmlWriter.WriteEndElement (); // test-results
+               }
+
+               static void RunTest (XmlElement scenario, string path, string stylesheetBase)
+               {
+                       XslTransform trans = new XslTransform ();
+                       stylesheetBase = scenario.SelectSingleNode ("input-file[@role='principal-stylesheet']").InnerText;
+                       string stylesheet = path + stylesheetBase;
+                       string srcxml = path + scenario.SelectSingleNode ("input-file[@role='principal-data']").InnerText;
+
+                       if (explicitTarget != null && stylesheetBase.IndexOf (explicitTarget) < 0)
+                               return;
+                       if (skipTargets.Contains (stylesheetBase))
+                               return;
+
+                       XmlTextReader stylextr = new XmlTextReader (stylesheet);
+                       XmlValidatingReader stylexvr = new XmlValidatingReader (stylextr);
+                       if (useDomStyle) {
+                               XmlDocument styledoc = new XmlDocument ();
+                               if (whitespaceStyle)
+                                       styledoc.PreserveWhitespace = true;
+                               styledoc.Load (stylesheet);
+                               trans.Load (styledoc);
+                       } else
+                               trans.Load (new XPathDocument (
+                                       stylesheet,
+                                       whitespaceStyle ? XmlSpace.Preserve :
+                                       XmlSpace.Default));
+
+                       string outfile = path + scenario.SelectSingleNode ("output-file[@role='principal']").InnerText;
+
+                       XmlTextReader xtr = new XmlTextReader (srcxml);
+                       XmlValidatingReader xvr = new XmlValidatingReader (xtr);
+                       xvr.ValidationType = ValidationType.None;
+                       IXPathNavigable input = null;
+                       if (useDomInstance) {
+                               XmlDocument dom = new XmlDocument ();
+                               if (whitespaceInstance)
+                                       dom.PreserveWhitespace = true;
+                               dom.Load (xvr);
+                               input = dom;
+                       } else {
+                               input = new XPathDocument (xvr,
+                                       whitespaceStyle ? XmlSpace.Preserve :
+                                       XmlSpace.Default);
+                       }
+                       StringWriter sw = new StringWriter ();
+                       trans.Transform (input, null, sw);
+                       if (generateOutput) {
+                               StreamWriter fw = new StreamWriter (outfile,
+                                       false, Encoding.UTF8);
+                               fw.Write (sw.ToString ());
+                               fw.Close ();
+                               // ... and don't run comparison
+                               return;
+                       }
+
+                       if (!File.Exists (outfile)) {
+                               // Reference output file does not exist.
+                               return;
+                       }
+                       StreamReader sr = new StreamReader (outfile);
+                       string reference_out = sr.ReadToEnd ();
+                       string actual_out = sw.ToString ();
+                       if (reference_out != actual_out)
+                               Report (scenario.ParentNode as XmlElement, 
+                                       reference_out, actual_out);
+                       else if (outputAll)
+                               Report (scenario.ParentNode as XmlElement,
+                                       "OK");
+               }
+
+               static void Report (XmlElement testcase, string message)
+               {
+                       if (reportAsXml) {
+                               reportXmlWriter.WriteStartElement ("testcase");
+                               reportXmlWriter.WriteAttributeString ("id",
+                                       testcase.GetAttribute ("id"));
+                               reportXmlWriter.WriteString (message);
+                               reportXmlWriter.WriteEndElement ();
+                       }
+                       else
+                               reportOutput.WriteLine (message);
+               }
+
+               static void Report (XmlElement testCase,
+                       string reference_out, string actual_out)
+               {
+                       string baseMessage = reportAsXml ? "Different." :
+                               "Different: " + testCase.GetAttribute ("id");
+                       if (!reportDetails)
+                               Report (testCase, baseMessage);
+                       else
+                               Report (testCase, baseMessage +
+                                       "\n Actual*****\n" + 
+                                       actual_out + 
+                                       "\n-------------------\nReference*****\n" + 
+                                       reference_out + 
+                                       "\n");
                }
        }
 }
index aa1060472fba99f109e71bd1700602b52fe2c8de..fe210de9a3c3a79a6b45a3567cdd7e9812c93619 100644 (file)
@@ -1,3 +1,20 @@
+2004-12-03  Geoff Norton  <gnorton@customerdna.com>
+
+       * System.IO/SearchPattern.cs:  Have IsMatch(string) 
+       call IsMatch(string, bool) to avoid setting a instance variable in a 
+       method that logically should not be changing it.
+
+2004-12-02  Geoff Norton  <gnorton@customerdna.com>
+
+       * System.IO/KeventWatcher.cs: Add IDisposable to our kevent struct
+       so the disposer gets called.  Fixes a small memory leak.  Dont monitor
+       LastAccessedTime for changed files, as this will cause AppUnloading in XSP
+       when global.asax is accessed after creation.  Use a case-insensitive IsMatch
+       to deal with OSX Case-aware/Case-insensitive filesystem.
+       * System.IO/SearchPattern.cs: Add a overload to IsMatch to explicitly set
+       the ignore field for OSX case-aware yet case-insensitive filesystem.  This
+       allows monitoring of global.asax to happen properly.
+
 2004-12-01 Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * System_test.dll.sources: added CookieContainerTest.cs.
index fcf6674be9716eb912086ab3648ee4c5697a4691..a3b04dbc82ff86d347315c5b164c6ccfd11e032a 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * DeflateStream.cs, GzipStream.cs, CompressionMode.cs: Make class public.
+
 2004-11-10  Martin Baulig  <martin@ximian.com>
 
        * DeflateStream.cs, GzipStream.cs: `System.IO.Stream.Length' doesn't
index 5d37feb631867e518375ce9727fb42db506558f5..64ee64cfa2449e05d968f9c71e3e55224698bee1 100644 (file)
@@ -11,7 +11,7 @@
 #if NET_2_0
 
 namespace System.IO.Compression {
-       enum CompressionMode {
+       public enum CompressionMode {
                Decompress=0,   // Decompress the given stream.
                Compress=1      // Compress the given stream.
        };
index 1054e81340e3cca1aa8f0a19be97e447740863fe..02b37ecc7f7bdde25615e7925d9f37c8db594308 100644 (file)
@@ -15,7 +15,7 @@ using System.Runtime.InteropServices;
 using System.Runtime.Remoting.Messaging;
 
 namespace System.IO.Compression {
-       class DeflateStream : Stream
+       public class DeflateStream : Stream
        {
                private Stream compressedStream;
                private CompressionMode mode;
index 18f24dec853a3d32a6da4465d1ab9a260d9c2623..8d5f64fd28f2f5b9bc389eb8b1fac23e98eafb3e 100644 (file)
@@ -15,7 +15,7 @@ using System.Runtime.InteropServices;
 using System.Runtime.Remoting.Messaging;
 
 namespace System.IO.Compression {
-       class GzipStream : Stream
+       public class GzipStream : Stream
        {
                private DeflateStream deflateStream;
 
index e1e6ba03d9f9dbb86b3b8fc3489ecb1795645e36..6adff10b16c8c25944415062b9241998544470d1 100644 (file)
@@ -37,7 +37,7 @@ using System.Threading;
 
 namespace System.IO {
 
-       struct kevent {
+       struct kevent : IDisposable {
                public int ident;
                public short filter;
                public ushort flags;
@@ -259,7 +259,7 @@ namespace System.IO {
                                        foreach (FileSystemInfo fsi in dir.GetFileSystemInfos() )
                                                if (data.DirEntries.ContainsKey (fsi.FullName) && (fsi is FileInfo)) {
                                                        KeventFileData entry = (KeventFileData) data.DirEntries [fsi.FullName];
-                                                       if ( (entry.LastWriteTime != fsi.LastWriteTime) || (entry.LastAccessTime != fsi.LastAccessTime) ) {
+                                                       if (entry.LastWriteTime != fsi.LastWriteTime) {
                                                                filename = fsi.Name;
                                                                fa = FileAction.Modified;
                                                                data.DirEntries [fsi.FullName] = new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime);
@@ -330,7 +330,7 @@ namespace System.IO {
                                }
                        }
                
-                       if (!fsw.Pattern.IsMatch(filename))
+                       if (!fsw.Pattern.IsMatch(filename, true))
                                return;
 
                        lock (fsw) {
index 2c78c3816a95d53da288cb7ca3dbd6c7877951f0..6dd1aed587470e41d89aeecb74f2522ffddeefaa 100644 (file)
@@ -47,14 +47,21 @@ namespace System.IO {
                        Compile (pattern);
                }
 
-               public bool IsMatch (string text)
+               // OSX has a retarded case-insensitive yet case-aware filesystem
+               // so we need a overload in here for the Kqueue watcher
+               public bool IsMatch (string text, bool ignorecase)
                {
                        if (!hasWildcard)
-                               return (String.Compare (pattern, text, ignore) == 0);
+                               return (String.Compare (pattern, text, ignorecase) == 0);
 
                        return Match (ops, text, 0);
                }
 
+               public bool IsMatch (string text)
+               {
+                       return IsMatch (text, ignore);
+               }
+
                public bool HasWildcard {
                        get { return hasWildcard; }
                }
index ce596517605032fb1b27dee860a71d85306f5242..1b23d2800adc23b5702c7ccd96e81c89119fe7da 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * NetworkStream.cs: Write should ensure that writes all the contents
+       of the buffer. Fixes bug #70123. Besos para Miguelito.
+
 2004-10-14  Dick Porter  <dick@ximian.com>
 
        * Socket.cs (Sockets ): Set Accept()ed socket blocking status to
index 2a965dcdf2f2a347736ba77c71661c32c55b920e..178589f3cca0f383e25d35f68bd7f70ac0544331 100644 (file)
@@ -163,8 +163,8 @@ namespace System.Net.Sockets
 
                        try {
                                retval = socket.BeginReceive (buffer, offset, size, 0, callback, state);
-                       } catch {
-                               throw new IOException ("BeginReceive failure");
+                       } catch (Exception e) {
+                               throw new IOException ("BeginReceive failure", e);
                        }
 
                        return retval;
@@ -310,7 +310,10 @@ namespace System.Net.Sockets
                                throw new ArgumentOutOfRangeException("offset+size exceeds the size of buffer");
 
                        try {
-                               socket.Send (buffer, offset, size, 0);
+                               int count = 0;
+                               while (size - count > 0) {
+                                       count += socket.Send (buffer, offset + count, size - count, 0);
+                               }
                        } catch (Exception e) {
                                throw new IOException ("Write failure", e); 
                        }
index 87f64beb6330ae3e508af9f5d7f45301c3e2ccde..61e6f0f8599f39d1567f9da1927fa97076f79671 100644 (file)
@@ -1,3 +1,29 @@
+2004-12-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * WebConnection.cs: handle errors on chunked streams. Fixes bug #66858.
+       * ChunkStream.cs: added error checking all over.
+
+       * HttpWebRequest.cs: throw the exception received in SetResponseError
+       if we already have a response.
+       (SetRequestData): Don't nest the exception if it's a WebException.
+
+2004-12-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * WebConnection.cs: remove prevStream and don't set busy to false in
+       HandleError. prevStream is not needed any more and setting 'busy' so
+       early might let a request skip the queue.
+       
+       * WebConnectionGroup.cs: decrement the indexer when removing a dead
+       reference from the arraylist.
+
+       * WebConnectionStream.cs:
+       (ReadAll): call NextRead if it has not been called before even when
+       we have completed the request. Reuse the read buffer when reading a
+       response of unknown size. Increase the buffer to 8kB.
+       (BeginRead): increase pendingReads earlier and even when reading from
+       the internal buffer.
+       (EndRead): decrease pendingReads later and always.
+
 2004-12-01 Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * CookieContainer.cs: style, fixed checks for properties, implemented
index 3d530991a65496a419ff70201e135df6a7fb9e26..7df2e3f68acd88ab80ce6bc90a3d314a8a01bbf6 100644 (file)
@@ -90,7 +90,8 @@ namespace System.Net
                
                public void WriteAndReadBack (byte [] buffer, int offset, int size, ref int read)
                {
-                       Write (buffer, offset, offset+read);
+                       if (offset + read > 0)
+                               Write (buffer, offset, offset+read);
                        read = Read (buffer, offset, size);
                }
 
@@ -199,7 +200,7 @@ namespace System.Net
                                c = (char) buffer [offset++];
                                if (c == '\r') {
                                        if (sawCR)
-                                               throw new ProtocolViolationException ("2 CR found");
+                                               ThrowProtocolViolation ("2 CR found");
 
                                        sawCR = true;
                                        continue;
@@ -213,13 +214,32 @@ namespace System.Net
 
                                if (!gotit)
                                        saved.Append (c);
+
+                               if (saved.Length > 20)
+                                       ThrowProtocolViolation ("chunk size too long.");
                        }
 
-                       if (!sawCR || c != '\n')
+                       if (!sawCR || c != '\n') {
+                               if (offset < size)
+                                       ThrowProtocolViolation ("Missing \\n");
+
+                               try {
+                                       if (saved.Length > 0)
+                                               chunkSize = Int32.Parse (saved.ToString (), NumberStyles.HexNumber);
+                               } catch (Exception) {
+                                       ThrowProtocolViolation ("Cannot parse chunk size.");
+                               }
+
                                return State.None;
+                       }
 
                        chunkRead = 0;
-                       chunkSize = Int32.Parse (saved.ToString (), NumberStyles.HexNumber);
+                       try {
+                               chunkSize = Int32.Parse (saved.ToString (), NumberStyles.HexNumber);
+                       } catch (Exception) {
+                               ThrowProtocolViolation ("Cannot parse chunk size.");
+                       }
+                       
                        if (chunkSize == 0)
                                return State.Trailer;
 
@@ -230,15 +250,15 @@ namespace System.Net
                {
                        if (!sawCR) {
                                if ((char) buffer [offset++] != '\r')
-                                       throw new ProtocolViolationException ("Expecting \\r");
+                                       ThrowProtocolViolation ("Expecting \\r");
 
                                sawCR = true;
                                if (offset == size)
                                        return State.BodyFinished;
                        }
                        
-                       if ((char) buffer [offset++] != '\n')
-                               throw new ProtocolViolationException ("Expecting \\n");
+                       if (sawCR && (char) buffer [offset++] != '\n')
+                               ThrowProtocolViolation ("Expecting \\n");
 
                        return State.None;
                }
@@ -277,8 +297,12 @@ namespace System.Net
                                }
                        }
 
-                       if (st < 4)
+                       if (st < 4) {
+                               if (offset <  size)
+                                       ThrowProtocolViolation ("Error reading trailer.");
+
                                return State.Trailer;
+                       }
 
                        StringReader reader = new StringReader (saved.ToString ());
                        string line;
@@ -287,6 +311,12 @@ namespace System.Net
 
                        return State.None;
                }
+
+               static void ThrowProtocolViolation (string message)
+               {
+                       WebException we = new WebException (message, null, WebExceptionStatus.ServerProtocolViolation, null);
+                       throw we;
+               }
        }
 }
 
index b2f67dfcf993c516366bc78f55c7294e10fd02be..34055977a4a18d85c8b288ef8d828a83e889cafd 100644 (file)
@@ -982,13 +982,24 @@ namespace System.Net
 
                internal void SetResponseError (WebExceptionStatus status, Exception e, string where)
                {
+                       string msg = String.Format ("Error getting response stream ({0}): {1}", where, status);
+                       if (webResponse != null) {
+                               if (e is WebException)
+                                       throw e;
+                               throw new WebException (msg, e, status, null);
+                       }
+                       
                        WebAsyncResult r = asyncRead;
                        if (r == null)
                                r = asyncWrite;
 
                        if (r != null) {
-                               string msg = String.Format ("Error getting response stream ({0}): {1}", where, status);
-                               WebException wexc = new WebException (msg, e, status, null); 
+                               WebException wexc;
+                               if (e is WebException) {
+                                       wexc = (WebException) e;
+                               } else {
+                                       wexc = new WebException (msg, e, status, null); 
+                               }
                                r.SetCompleted (false, wexc);
                                r.DoCallback ();
                                asyncRead = null;
index bf2bbdb9cd4f050eaa05f883bda524b20da12f79..290543d8970aa3a1f62c0ca51ac35d764326042e 100644 (file)
@@ -61,7 +61,6 @@ namespace System.Net
                EventHandler abortHandler;
                ReadState readState;
                internal WebConnectionData Data;
-               WebConnectionStream prevStream;
                bool chunkedRead;
                ChunkStream chunkStream;
                AutoResetEvent goAhead;
@@ -194,6 +193,11 @@ namespace System.Net
 
                        while (true) {
                                int n = stream.Read (buffer, 0, 256);
+                               if (n == 0) {
+                                       HandleError (WebExceptionStatus.ServerProtocolViolation, null, "ReadHeders");
+                                       return false;
+                               }
+                               
                                ms.Write (buffer, 0, n);
                                int start = 0;
                                string str = null;
@@ -263,7 +267,6 @@ namespace System.Net
                {
                        status = st;
                        lock (this) {
-                               busy = false;
                                if (st == WebExceptionStatus.RequestCanceled)
                                        Data = new WebConnectionData ();
                        }
@@ -349,10 +352,20 @@ namespace System.Net
                                stream.ReadBufferOffset = pos;
                                stream.ReadBufferSize = nread;
                        } else if (cnc.chunkStream == null) {
-                               cnc.chunkStream = new ChunkStream (cnc.buffer, pos, nread, data.Headers);
+                               try {
+                                       cnc.chunkStream = new ChunkStream (cnc.buffer, pos, nread, data.Headers);
+                               } catch (Exception e) {
+                                       cnc.HandleError (WebExceptionStatus.ServerProtocolViolation, e, "ReadDone5");
+                                       return;
+                               }
                        } else {
                                cnc.chunkStream.ResetBuffer ();
-                               cnc.chunkStream.Write (cnc.buffer, pos, nread);
+                               try {
+                                       cnc.chunkStream.Write (cnc.buffer, pos, nread);
+                               } catch (Exception e) {
+                                       cnc.HandleError (WebExceptionStatus.ServerProtocolViolation, e, "ReadDone6");
+                                       return;
+                               }
                        }
 
                        data.stream = stream;
@@ -365,7 +378,6 @@ namespace System.Net
                                        if (cnc.queue.Count > 0) {
                                                stream.ReadAll ();
                                        } else {
-                                               cnc.prevStream = stream;
                                                stream.CheckComplete ();
                                        }
                                }
@@ -539,11 +551,6 @@ namespace System.Net
                internal EventHandler SendRequest (HttpWebRequest request)
                {
                        lock (this) {
-                               if (prevStream != null && socket != null && socket.Connected) {
-                                       prevStream.ReadAll ();
-                                       prevStream = null;
-                               }
-
                                if (!busy) {
                                        busy = true;
                                        ThreadPool.RegisterWaitForSingleObject (goAhead, initConn,
@@ -562,7 +569,6 @@ namespace System.Net
                {
                        lock (queue) {
                                if (queue.Count > 0) {
-                                       prevStream = null;
                                        SendRequest ((HttpWebRequest) queue.Dequeue ());
                                }
                        }
@@ -588,7 +594,6 @@ namespace System.Net
                                goAhead.Set ();
                                lock (queue) {
                                        if (queue.Count > 0) {
-                                               prevStream = null;
                                                SendRequest ((HttpWebRequest) queue.Dequeue ());
                                        }
                                }
@@ -648,7 +653,7 @@ namespace System.Net
                                try {
                                        result = nstream.BeginRead (buffer, offset, size, cb, state);
                                } catch (Exception) {
-                                       status = WebExceptionStatus.ReceiveFailure;
+                                       HandleError (WebExceptionStatus.ReceiveFailure, null, "chunked BeginRead");
                                        throw;
                                }
                        }
@@ -673,28 +678,56 @@ namespace System.Net
                                if (wr.InnerAsyncResult != null)
                                        nbytes = nstream.EndRead (wr.InnerAsyncResult);
 
-                               chunkStream.WriteAndReadBack (wr.Buffer, wr.Offset, wr.Size, ref nbytes);
-                               while (nbytes == 0 && chunkStream.WantMore) {
-                                       int size = chunkStream.ChunkLeft;
-                                       if (size <= 0) // not read chunk size yet
-                                               size = 1024;
-                                       else if (size > 16384)
-                                               size = 16384;
-
-                                       byte [] morebytes = new byte [size];
-                                       int nread;
-                                       nread = nstream.Read (morebytes, 0, size);
-                                       chunkStream.Write (morebytes, 0, nread);
-                                       morebytes = null;
-                                       nbytes += chunkStream.Read (wr.Buffer, wr.Offset + nbytes,
-                                                               wr.Size - nbytes);
+                               bool done = (nbytes == 0);
+                               try {
+                                       chunkStream.WriteAndReadBack (wr.Buffer, wr.Offset, wr.Size, ref nbytes);
+                                       if (!done && nbytes == 0 && chunkStream.WantMore)
+                                               nbytes = EnsureRead (wr.Buffer, wr.Offset, wr.Size);
+                               } catch (Exception e) {
+                                       if (e is WebException)
+                                               throw e;
+
+                                       throw new WebException ("Invalid chunked data.", e,
+                                                               WebExceptionStatus.ServerProtocolViolation, null);
                                }
+
+                               if ((done || nbytes == 0) && chunkStream.WantMore) {
+                                       HandleError (WebExceptionStatus.ReceiveFailure, null, "chunked EndRead");
+                                       throw new WebException ("Read error", null, WebExceptionStatus.ReceiveFailure, null);
+                               }
+
                                return nbytes;
                        }
 
                        return nstream.EndRead (result);
                }
 
+               // To be called on chunkedRead when we can read no data from the ChunkStream yet
+               int EnsureRead (byte [] buffer, int offset, int size)
+               {
+                       byte [] morebytes = null;
+                       int nbytes = 0;
+                       while (nbytes == 0 && chunkStream.WantMore) {
+                               int localsize = chunkStream.ChunkLeft;
+                               if (localsize <= 0) // not read chunk size yet
+                                       localsize = 1024;
+                               else if (localsize > 16384)
+                                       localsize = 16384;
+
+                               if (morebytes == null || morebytes.Length < localsize)
+                                       morebytes = new byte [localsize];
+
+                               int nread = nstream.Read (morebytes, 0, localsize);
+                               if (nread <= 0)
+                                       return 0; // Error
+
+                               chunkStream.Write (morebytes, 0, nread);
+                               nbytes += chunkStream.Read (buffer, offset + nbytes, size - nbytes);
+                       }
+
+                       return nbytes;
+               }
+
                bool CompleteChunkedRead()
                {
                        if (!chunkedRead || chunkStream == null)
@@ -704,7 +737,8 @@ namespace System.Net
                                int nbytes = nstream.Read (buffer, 0, buffer.Length);
                                if (nbytes <= 0)
                                        return false; // Socket was disconnected
-                               chunkStream.Write(buffer, 0, nbytes);
+
+                               chunkStream.Write (buffer, 0, nbytes);
                        }
 
                        return true;
@@ -738,11 +772,27 @@ namespace System.Net
 
                        int result = 0;
                        try {
-                               if (!chunkedRead || chunkStream.WantMore)
+                               bool done = false;
+                               if (!chunkedRead) {
                                        result = nstream.Read (buffer, offset, size);
+                                       done = (result == 0);
+                               }
+
+                               if (chunkedRead) {
+                                       try {
+                                               chunkStream.WriteAndReadBack (buffer, offset, size, ref result);
+                                               if (!done && result == 0 && chunkStream.WantMore)
+                                                       result = EnsureRead (buffer, offset, size);
+                                       } catch (Exception e) {
+                                               HandleError (WebExceptionStatus.ReceiveFailure, e, "chunked Read1");
+                                               throw;
+                                       }
 
-                               if (chunkedRead)
-                                       chunkStream.WriteAndReadBack (buffer, offset, size, ref result);
+                                       if ((done || result == 0) && chunkStream.WantMore) {
+                                               HandleError (WebExceptionStatus.ReceiveFailure, null, "chunked Read2");
+                                               throw new WebException ("Read error", null, WebExceptionStatus.ReceiveFailure, null);
+                                       }
+                               }
                        } catch (Exception e) {
                                HandleError (WebExceptionStatus.ReceiveFailure, e, "Read");
                        }
index e96d5c2c99a2b1a27b90318c062ebaa3c9e45908..86e64d5ba8881fea711eed0099e2dcf36791317e 100644 (file)
@@ -95,6 +95,7 @@ namespace System.Net
                                if (cnc == null) {
                                        connections.RemoveAt (i);
                                        count--;
+                                       i--;
                                        continue;
                                }
 
index 8b08373614839e2d2823167b0c5cca73219512a0..6cd780e659dc35af9c46c83a04765dc3f7efc9a3 100644 (file)
@@ -130,8 +130,13 @@ namespace System.Net
 
                internal void ReadAll ()
                {
-                       if (!isRead || totalRead >= contentLength || nextReadCalled)
+                       if (!isRead || totalRead >= contentLength || nextReadCalled) {
+                               if (!nextReadCalled) {
+                                       nextReadCalled = true;
+                                       cnc.NextRead ();
+                               }
                                return;
+                       }
 
                        pending.WaitOne ();
                        lock (this) {
@@ -144,12 +149,18 @@ namespace System.Net
 
                                if (contentLength == Int32.MaxValue) {
                                        MemoryStream ms = new MemoryStream ();
-                                       if (readBuffer != null && diff > 0)
+                                       byte [] buffer = null;
+                                       if (readBuffer != null && diff > 0) {
                                                ms.Write (readBuffer, readBufferOffset, diff);
+                                               if (readBufferSize >= 8192)
+                                                       buffer = readBuffer;
+                                       }
+
+                                       if (buffer == null)
+                                               buffer = new byte [8192];
 
-                                       byte [] buffer = new byte [2048];
                                        int read;
-                                       while ((read = cnc.Read (buffer, 0, 2048)) != 0)
+                                       while ((read = cnc.Read (buffer, 0, buffer.Length)) != 0)
                                                ms.Write (buffer, 0, read);
 
                                        b = ms.GetBuffer ();
@@ -216,6 +227,11 @@ namespace System.Net
                        if (size < 0 || offset < 0 || length < offset || length - offset < size)
                                throw new ArgumentOutOfRangeException ();
 
+                       lock (this) {
+                               pendingReads++;
+                               pending.Reset ();
+                       }
+
                        WebAsyncResult result = new WebAsyncResult (cb, state, buffer, offset, size);
                        if (totalRead >= contentLength) {
                                result.SetCompleted (true, -1);
@@ -239,11 +255,6 @@ namespace System.Net
                                result.NBytes = copy;
                        }
 
-                       lock (this) {
-                               pendingReads++;
-                               pending.Reset ();
-                       }
-
                        if (cb != null)
                                cb = new AsyncCallback (CallbackWrapper);
 
@@ -260,12 +271,6 @@ namespace System.Net
 
                        if (!result.IsCompleted) {
                                int nbytes = cnc.EndRead (result.InnerAsyncResult);
-                               lock (this) {
-                                       pendingReads--;
-                                       if (pendingReads == 0)
-                                               pending.Set ();
-                               }
-
                                bool finished = (nbytes == -1);
                                if (finished && result.NBytes > 0)
                                        nbytes = 0;
@@ -276,11 +281,15 @@ namespace System.Net
                                        contentLength = totalRead;
                        }
 
-                       if (totalRead >= contentLength && !nextReadCalled) {
-                               nextReadCalled = true;
-                               cnc.NextRead ();
+                       lock (this) {
+                               pendingReads--;
+                               if (pendingReads == 0)
+                                       pending.Set ();
                        }
 
+                       if (totalRead >= contentLength && !nextReadCalled)
+                               ReadAll ();
+
                        return result.NBytes;
                }
                
index 3f721eb7be1ba022ea9cbf130cdc60ed1608f726..f5660b26456703ba638e60d404ccb1ce2aec280c 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * System.IO.Compression/GzipStreamTest.cs: Fix compile errors.
+       * System.IO.Compression/GzipStreamTest.cs: Likewise.
+
 2004-10-04  Raja R Harinath  <rharinath@novell.com>
 
        * System.IO.Compression/DeflateStreamTest.cs: NET_2_0 only.
index 20b40ca1c1eab5e94d73fcef1ba86f362f873804..6e10a50db659d5510c75da8d3b1871f9daece826 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * VBCodeProviderTest.cs: Change namespace to
+       MonoTests.Microsoft.VisualBasic.
+
 2004-11-19  Raja R Harinath  <rharinath@novell.com>
 
        * VBCodeProviderTest.cs (CreateCompiler): Be more verbose about
index 91d3fd79cc58d975213f88242ca654274cef673d..f2bddd782d9a89275eb3eb1bb8838be436bc06d9 100644 (file)
@@ -20,7 +20,7 @@ using System.Reflection;
 using System.Diagnostics;\r
 using System.IO;\r
 \r
-namespace MonoTests.System.Microsoft.VisualBasic\r
+namespace MonoTests.Microsoft.VisualBasic\r
 {\r
 \r
        enum OsType {\r
@@ -91,7 +91,7 @@ namespace MonoTests.System.Microsoft.VisualBasic
                        }\r
 \r
                        if (MyVBCodeCompilerResults.Errors.Count != 0) {
-                               System.Console.WriteLine (MyVBCodeCompilerResults);
+                               Console.WriteLine (MyVBCodeCompilerResults);
                                Assert ("#JW31 - Hello world compilation: " + MyOutStr, false);\r
                        }
 
index 44b1ce14f3f8ff38809899a5a3753b36f53ba6c4..b8bcbbbb5476d727dd468988fe82fd1dd8acf0eb 100644 (file)
@@ -180,7 +180,7 @@ namespace MonoTests.System.IO.Compression
                        byte [] data = {0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0xe7, 0x02, 0x00 };
                        MemoryStream backing = new MemoryStream (data);
                        DeflateStream decompressing = new DeflateStream (backing, CompressionMode.Decompress);
-                       decompressing.Length = 20;
+                       decompressing.SetLength (20);
                }
 
                [Test]
@@ -189,7 +189,7 @@ namespace MonoTests.System.IO.Compression
                        byte [] data = {0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0xe7, 0x02, 0x00 };
                        MemoryStream backing = new MemoryStream (data);
                        DeflateStream decompressing = new DeflateStream (backing, CompressionMode.Decompress);
-                       int length = decompressing.Length;
+                       long length = decompressing.Length;
                }
 
                [Test]
@@ -198,7 +198,7 @@ namespace MonoTests.System.IO.Compression
                        byte [] data = {0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0xe7, 0x02, 0x00 };
                        MemoryStream backing = new MemoryStream (data);
                        DeflateStream decompressing = new DeflateStream (backing, CompressionMode.Decompress);
-                       int position = decompressing.Position;
+                       long position = decompressing.Position;
                }
        }
 }
index 6e6a6de8d5fa9622465c0370fa826ae20f6cb7f0..aa6e173e0df206df9fa58a9afd20c25fbe55d1fc 100644 (file)
@@ -180,7 +180,7 @@ namespace MonoTests.System.IO.Compression
                        byte [] data = {0x1f, 0x8b, 0x08, 0x08, 0x70, 0xbb, 0x5d, 0x41, 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x00, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0xe7, 0x02, 0x00, 0x16, 0x35, 0x96, 0x31, 0x06, 0x00, 0x00, 0x00 };
                        MemoryStream backing = new MemoryStream (data);
                        GzipStream decompressing = new GzipStream (backing, CompressionMode.Decompress);
-                       decompressing.Length = 20;
+                       decompressing.SetLength (20);
                }
 
                [Test]
@@ -189,7 +189,7 @@ namespace MonoTests.System.IO.Compression
                        byte [] data = {0x1f, 0x8b, 0x08, 0x08, 0x70, 0xbb, 0x5d, 0x41, 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x00, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0xe7, 0x02, 0x00, 0x16, 0x35, 0x96, 0x31, 0x06, 0x00, 0x00, 0x00 };
                        MemoryStream backing = new MemoryStream (data);
                        GzipStream decompressing = new GzipStream (backing, CompressionMode.Decompress);
-                       int length = decompressing.Length;
+                       long length = decompressing.Length;
                }
 
                [Test]
@@ -198,7 +198,7 @@ namespace MonoTests.System.IO.Compression
                        byte [] data = {0x1f, 0x8b, 0x08, 0x08, 0x70, 0xbb, 0x5d, 0x41, 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x00, 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0xe7, 0x02, 0x00, 0x16, 0x35, 0x96, 0x31, 0x06, 0x00, 0x00, 0x00 };
                        MemoryStream backing = new MemoryStream (data);
                        GzipStream decompressing = new GzipStream (backing, CompressionMode.Decompress);
-                       int position = decompressing.Position;
+                       long position = decompressing.Position;
                }
        }
 }
index 3da9e27471fdc9c1f351d8828a56fe573cb73258..20c6d0eb11fe43a553b39cd82d3ba897da3d6b45 100644 (file)
@@ -12,7 +12,6 @@
 //
 // Copyright (c) 2002 Chew Keong TAN
 // All rights reserved.
-
 //
 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
 //
@@ -1021,7 +1020,7 @@ namespace Mono.Math {
 
                                r2.Normalize ();
 
-                               if (r2 < x) {
+                               if (r2 <= x) {
                                        Kernel.MinusEq (x, r2);
                                } else {
                                        BigInteger val = new BigInteger (Sign.Positive, kPlusOne + 1);
index 23ee50cc5b17cdea9eaa0da02ce979f3f06ff280..9165fcc9e7f404769a58fa2d605e506096947477 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-03  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * BigInteger.cs: Fix issue #70169 in ModPow when modulus is a power of
+       two.
+
 2004-10-19  Sebastien Pouliot  <sebastien@ximian.com>
 
        * BigInteger.cs: Fix issue #68452 when Randomize was being called on a
index 59829dd9b315a64a622736bd9a0341a940907b78..2285a5defe40f8d8129294893eb4a493590d500d 100644 (file)
@@ -1,3 +1,32 @@
+2004-12-02  Duncan Mak  <duncan@ximian.com>
+
+       * cs0122-7.cs: 
+        * cs0122-8.cs: Added test cases for events, from bug #70129.
+
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * cs1589.inc : plus one.
+       * Makefile : remove dummy.xml (in case of error test failures)
+
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * cs1570.cs, cs1570-2.cs, cs1570-3.cs, cs1570-4.cs, cs1570-5.cs,
+         cs1570-6.cs, cs1570-7.cs, cs1570-8.cs, cs1570-9.cs, cs1570-10.cs,
+         cs1570-11.cs, cs1571.cs, cs1572.cs, cs1573.cs, cs1574.cs,
+         cs1574-2.cs, cs1574-3.cs, cs1574-4.cs, cs1574-5.cs, cs1580.cs,
+         cs1580-2.cs, cs1581.cs, cs1581-2.cs, cs1584.cs, cs1584-2.cs,
+         cs1584-3.cs, cs1584-4.cs, cs1587.cs, cs1587-2.cs, cs1587-3.cs,
+         cs1587-4.cs, cs1587-5.cs, cs1587-6.cs, cs1587-7.cs, cs1587-8.cs,
+         cs1587-9.cs, cs1587-10.cs, cs1587-11.cs, cs1587-12.cs, cs1587-13.cs,
+         cs1587-14.cs, cs1587-15.cs, cs1587-16.cs, cs1587-17.cs, cs1587-18.cs,
+         cs1587-19.cs, cs1587-20.cs, cs1587-21.cs, cs1587-22.cs, cs1587-23.cs,
+         cs1587-24.cs, cs1587-25.cs, cs1587-26.cs, cs1587-27.cs, cs1587-28.cs,
+         cs1589.cs, cs1590.cs, cs1590-2.cs, cs1590-3.cs, cs1591.cs,
+         cs1591-2.cs, cs1591-3.cs, cs1591-4.cs, cs1591-5.cs, cs1591-6.cs,
+         cs1591-7.cs, cs1591-8.cs, cs1591-9.cs, cs1591-10.cs, cs1591-11.cs,
+         cs1591-12.cs, cs1591-13.cs, cs1591-14.cs, cs1591-15.cs, cs1591-16.cs,
+         cs1591-17.cs, cs1591-18.cs, cs1592.cs : added tests for /doc feature.
+
 2004-11-26  Raja R Harinath  <rharinath@novell.com>
 
        * Makefile (DISTFILES): Add do-tests.pl.
index ab03973d6f68ded60d1e172431f949cf3a46f381..2e2d09cc39ea9bc141fc898bf39aa0cc43269ca4 100644 (file)
@@ -86,6 +86,7 @@ clean-local:
        rm -f *.dll
        rm -f *.log
        rm -f *.mdb
+       rm -f dummy.xml
 
 dist-local: dist-default
 
diff --git a/mcs/errors/cs0122-7.cs b/mcs/errors/cs0122-7.cs
new file mode 100644 (file)
index 0000000..b6bec3c
--- /dev/null
@@ -0,0 +1,20 @@
+// error CS0122: 'BB.AnEvent' is inaccessible due to its protection level
+
+using System;
+
+class X 
+{
+       static void Main ()
+       {
+               BB b = new BB ();
+               b.AnEvent += DoIt;
+       }
+       
+       public static void DoIt (object sender, EventArgs args) {}
+}
+
+public class BB
+{
+       event EventHandler AnEvent;
+}
+
diff --git a/mcs/errors/cs0122-8.cs b/mcs/errors/cs0122-8.cs
new file mode 100644 (file)
index 0000000..c3513f5
--- /dev/null
@@ -0,0 +1,23 @@
+// error CS0122: 'A.AnEvent' is inaccessible due to its protection level
+//
+// NOTE: if `member' were a field or a property, this'd be CS1540
+
+using System;
+
+class A
+{
+       protected event EventHandler member;
+}
+
+class B : A
+{
+       static void Main ()
+       {
+               A a = new A ();
+               a.member += Handler;
+       }
+       
+       static void Handler (object sender, EventArgs args) {}
+}
+
+
diff --git a/mcs/errors/cs1570-10.cs b/mcs/errors/cs1570-10.cs
new file mode 100755 (executable)
index 0000000..06d4a97
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for private field
+               /// </summary>
+               private string PrivateField;
+
+               /// <summary>
+               /// incorrect markup comment for private field
+               /// </incorrect>
+               private string PrivateField2;
+
+               /**
+               <summary>
+               Javadoc comment for private field
+               </summary>
+               */
+               private string PrivateField3;
+       }
+}
+
diff --git a/mcs/errors/cs1570-11.cs b/mcs/errors/cs1570-11.cs
new file mode 100755 (executable)
index 0000000..1adf424
--- /dev/null
@@ -0,0 +1,54 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for public property
+               /// </summary>
+               public string PublicProperty {
+                       /// <summary>
+                       /// On public getter - no effect
+                       /// </summary>
+                       get { return null; }
+                       /// <summary>
+                       /// On public setter - no effect
+                       /// </summary>
+                       set { }
+               }
+
+               /// <summary>
+               /// incorrect comment for public property
+               /// </incorrect>
+               public string PublicProperty2 {
+                       get { return null; }
+               }
+
+               /**
+               <summary>
+               Javadoc comment for public property
+               </summary>
+               */
+               public string PublicProperty3 {
+                       /**
+                       <summary>
+                       On public getter - no effect
+                       </summary>
+                       */
+                       get { return null; }
+                       /**
+                       <summary>
+                       On public setter - no effect
+                       </summary>
+                       */
+                       set { }
+               }
+       }
+}
+
diff --git a/mcs/errors/cs1570-2.cs b/mcs/errors/cs1570-2.cs
new file mode 100755 (executable)
index 0000000..8e111b7
--- /dev/null
@@ -0,0 +1,32 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment on class
+       /// </summary>
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+
+       /// <summary>
+       /// Incorrect comment markup.
+       /// </incorrect>
+       public class Test2
+       {
+       }
+
+       /**
+               <summary>
+               another Java-style documentation style
+               </summary>
+       */
+       public class Test3
+       {
+       }
+}
+
diff --git a/mcs/errors/cs1570-3.cs b/mcs/errors/cs1570-3.cs
new file mode 100755 (executable)
index 0000000..72c625b
--- /dev/null
@@ -0,0 +1,36 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       /// <summary> 
+       /// comment for struct
+       /// </summary>
+       public struct StructTest
+       {
+       }
+
+       /// <summary> 
+       /// incorrect markup comment for struct
+       /// </incorrect>
+       public struct StructTest2
+       {
+       }
+
+       /**
+               <summary>
+               Java style commet
+               </summary>
+       */
+       public struct StructTest3
+       {
+       }
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/errors/cs1570-4.cs b/mcs/errors/cs1570-4.cs
new file mode 100755 (executable)
index 0000000..341c98c
--- /dev/null
@@ -0,0 +1,36 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment for interface
+       /// </summary>
+       public interface InterfaceTest
+       {
+       }
+
+       /// <summary>
+       /// incorrect markup comment for interface
+       /// </incorrect>
+       public interface InterfaceTest2
+       {
+       }
+
+       /**
+               <summary>
+               Java style comment for interface
+               </summary>
+       */
+       public interface InterfaceTest3
+       {
+       }
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/errors/cs1570-5.cs b/mcs/errors/cs1570-5.cs
new file mode 100755 (executable)
index 0000000..e8f363f
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment for enum type
+       /// </incorrect>
+       enum EnumTest2
+       {
+               Foo,
+               Bar,
+       }
+}
+
diff --git a/mcs/errors/cs1570-6.cs b/mcs/errors/cs1570-6.cs
new file mode 100755 (executable)
index 0000000..4e5c268
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment for delegate type
+       /// </summary>
+       public delegate void MyDelegate (object o, EventArgs e);
+
+       /// <summary>
+       /// comment for delegate type
+       /// </incorrect>
+       public delegate void MyDelegate2 (object o, EventArgs e);
+
+       /**
+       <summary>
+       Javadoc comment for delegate type
+       </summary>
+       */
+       public delegate void MyDelegate3 (object o, EventArgs e);
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/errors/cs1570-7.cs b/mcs/errors/cs1570-7.cs
new file mode 100755 (executable)
index 0000000..075a6bb
--- /dev/null
@@ -0,0 +1,24 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       /// comment without markup on class - it is allowed
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+
+       /// <6roken> broken markup
+       public class Test2
+       {
+       }
+
+       /// <dont-forget-close-tag>
+       public class Test3
+       {
+       }
+}
+
diff --git a/mcs/errors/cs1570-8.cs b/mcs/errors/cs1570-8.cs
new file mode 100755 (executable)
index 0000000..6c71570
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               /// <summary>
+               /// comment for const declaration
+               /// </summary>
+               const string Constant = "CONSTANT STRING";
+
+               /// <summary>
+               /// invalid comment for const declaration
+               /// </invalid>
+               const string Constant2 = "CONSTANT STRING";
+
+               /**
+               <summary>
+               Javaism comment for const declaration
+               </summary>
+               */
+               const string Constant3 = "CONSTANT STRING";
+
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/errors/cs1570-9.cs b/mcs/errors/cs1570-9.cs
new file mode 100755 (executable)
index 0000000..8b070d7
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:dummy.xml -warn:1 -warnaserror
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               /// <summary>
+               /// comment for public field
+               /// </summary>
+               public string PublicField;
+
+               /// <summary>
+               /// comment for public field
+               /// </invalid>
+               public string PublicField2;
+
+               /**
+                <summary>
+                Javadoc comment for public field
+                </summary>
+               */
+               public string PublicField3;
+
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/errors/cs1570.cs b/mcs/errors/cs1570.cs
new file mode 100755 (executable)
index 0000000..4f7e6f4
--- /dev/null
@@ -0,0 +1,32 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment on class
+       /// </summary>
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+
+       /// <summary>
+       /// Incorrect comment markup.
+       /// </incorrect>
+       public class Test2
+       {
+       }
+
+       /**
+               <summary>
+               another Java-style documentation style
+               </summary>
+       */
+       public class Test3
+       {
+       }
+}
+
diff --git a/mcs/errors/cs1571.cs b/mcs/errors/cs1571.cs
new file mode 100755 (executable)
index 0000000..0f583c7
--- /dev/null
@@ -0,0 +1,18 @@
+// Compiler options: -doc:dummy.xml -warn:2 -warnaserror
+namespace Testing
+{
+       /// test class
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <param>anonymous</param>
+               public void Foo (int i) {}
+
+               /// <param name='i'>correct</param>
+               /// <param name='i'>duplicate</param>
+               public void Bar (int i) {}
+       }
+}
diff --git a/mcs/errors/cs1572.cs b/mcs/errors/cs1572.cs
new file mode 100755 (executable)
index 0000000..4eb657f
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warn:2 -warnaserror
+namespace Testing
+{
+       /// test class
+       public class Test
+       {
+               /// <param name='mismatch'>mismatch</param>
+               public void Baz (int i) {}
+       }
+}
diff --git a/mcs/errors/cs1573.cs b/mcs/errors/cs1573.cs
new file mode 100755 (executable)
index 0000000..93847d2
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warn:4 -warnaserror
+namespace Testing
+{
+       /// test class
+       public class Test
+       {
+               /// <param name='i'>correct</param>
+               public void Baz (int i, int j) {}
+       }
+}
diff --git a/mcs/errors/cs1574-2.cs b/mcs/errors/cs1574-2.cs
new file mode 100755 (executable)
index 0000000..54dbb42
--- /dev/null
@@ -0,0 +1,8 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+
+/// <seealso cref="Method(System.String)"/>
+public class Test
+{
+}
+
diff --git a/mcs/errors/cs1574-3.cs b/mcs/errors/cs1574-3.cs
new file mode 100755 (executable)
index 0000000..5b46ff1
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+
+/// <see cref="Test.Foo(int)"/> Test has Foo, but is property that has no args.
+public class Test
+{
+       string Foo {
+               get { return null; }
+       }
+}
diff --git a/mcs/errors/cs1574-4.cs b/mcs/errors/cs1574-4.cs
new file mode 100755 (executable)
index 0000000..8c4f7c4
--- /dev/null
@@ -0,0 +1,8 @@
+// Compiler options: -doc:dummy.xml -warnaserror -noconfig
+using System;
+
+/// <seealso cref="System.Xml.XmlDocument"/>
+/// with /noconfig, it cannot be resolved.
+public class Test
+{
+}
diff --git a/mcs/errors/cs1574-5.cs b/mcs/errors/cs1574-5.cs
new file mode 100755 (executable)
index 0000000..76c0861
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+
+/// <see cref="Goo"/> ... does not exist
+public class Test
+{
+       string Foo {
+               get { return null; }
+       }
+}
+
diff --git a/mcs/errors/cs1574.cs b/mcs/errors/cs1574.cs
new file mode 100755 (executable)
index 0000000..4918125
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <seealso cref="explicit operator int (bool)"/>
+public class Test
+{
+}
diff --git a/mcs/errors/cs1580-2.cs b/mcs/errors/cs1580-2.cs
new file mode 100755 (executable)
index 0000000..c2ed72e
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <see cref="Method(x,y)"/>
+public class Test
+{
+}
diff --git a/mcs/errors/cs1580.cs b/mcs/errors/cs1580.cs
new file mode 100755 (executable)
index 0000000..1627ba8
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <seealso cref="Foo(x)"/>
+public class Test
+{
+       int Foo ()
+       {
+               return 0;
+       }
+}
diff --git a/mcs/errors/cs1581-2.cs b/mcs/errors/cs1581-2.cs
new file mode 100755 (executable)
index 0000000..4fa271b
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <seealso cref="explicit operator int (Test)"/>
+public class Test
+{
+       /// operator.
+       public static explicit operator int [] (Test t)
+       {
+               return new int [0];
+       }
+}
+
diff --git a/mcs/errors/cs1581.cs b/mcs/errors/cs1581.cs
new file mode 100755 (executable)
index 0000000..4b8ef6c
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <seealso cref="explicit operator intp (Test)"/>
+public class Test
+{
+       /// operator.
+       public static explicit operator int (Test t)
+       {
+               return 0;
+       }
+}
+
diff --git a/mcs/errors/cs1584-2.cs b/mcs/errors/cs1584-2.cs
new file mode 100755 (executable)
index 0000000..60e2f4f
--- /dev/null
@@ -0,0 +1,7 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+
+/// <see cref="" />
+public class Test
+{
+}
diff --git a/mcs/errors/cs1584-3.cs b/mcs/errors/cs1584-3.cs
new file mode 100755 (executable)
index 0000000..a927c4c
--- /dev/null
@@ -0,0 +1,7 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+
+/// <see cref="." />
+public class Test
+{
+}
diff --git a/mcs/errors/cs1584-4.cs b/mcs/errors/cs1584-4.cs
new file mode 100755 (executable)
index 0000000..0232e43
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <see cref="Mai()n" />
+public class Test
+{
+}
diff --git a/mcs/errors/cs1584.cs b/mcs/errors/cs1584.cs
new file mode 100755 (executable)
index 0000000..ed638ca
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:1
+using System;
+/// <seealso cref="operator foo(int,Test)"/>
+public class Test
+{
+}
diff --git a/mcs/errors/cs1587-10.cs b/mcs/errors/cs1587-10.cs
new file mode 100755 (executable)
index 0000000..1fc25e6
--- /dev/null
@@ -0,0 +1,9 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       [Flags/** here is also incorrect comment */]
+       enum Enum2 {
+       }
+}
diff --git a/mcs/errors/cs1587-11.cs b/mcs/errors/cs1587-11.cs
new file mode 100755 (executable)
index 0000000..1ed1501
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       namespace ChildNS {
+               [Flags]
+               /// comment after attribute
+               enum Enum2 {
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-12.cs b/mcs/errors/cs1587-12.cs
new file mode 100755 (executable)
index 0000000..cfad50d
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       enum Enum3 {
+               Foo /** invalid comment between enum identifier and comma */,
+               Bar
+       }
+}
diff --git a/mcs/errors/cs1587-13.cs b/mcs/errors/cs1587-13.cs
new file mode 100755 (executable)
index 0000000..ab1056d
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       namespace ChildNS {
+               enum Enum3 {
+               }
+               /// invalid here
+       }
+}
diff --git a/mcs/errors/cs1587-14.cs b/mcs/errors/cs1587-14.cs
new file mode 100755 (executable)
index 0000000..3f117f3
--- /dev/null
@@ -0,0 +1,9 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       internal /** comment */ /** comment2 */ class Hoge
+       {
+       }
+}
diff --git a/mcs/errors/cs1587-15.cs b/mcs/errors/cs1587-15.cs
new file mode 100755 (executable)
index 0000000..1924819
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       internal class Hoge
+       {
+               /// invalid comment
+       }
+
+}
diff --git a/mcs/errors/cs1587-16.cs b/mcs/errors/cs1587-16.cs
new file mode 100755 (executable)
index 0000000..2d6ea93
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               string this [string bar] {
+                       /// incorrect
+                       get { return ""; }
+                       set { }
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-17.cs b/mcs/errors/cs1587-17.cs
new file mode 100755 (executable)
index 0000000..9b68c3e
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               string this [string bar] {
+                       get { /** incorrect */ return ""; }
+                       set { }
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-18.cs b/mcs/errors/cs1587-18.cs
new file mode 100755 (executable)
index 0000000..e609717
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               string this [string bar] {
+                       get { return ""; }
+                       /// incorrect
+                       set { }
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-19.cs b/mcs/errors/cs1587-19.cs
new file mode 100755 (executable)
index 0000000..3dd65d9
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               string this [string bar] {
+                       get { return ""; }
+                       set { /** incorrect */ }
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-2.cs b/mcs/errors/cs1587-2.cs
new file mode 100755 (executable)
index 0000000..800013f
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+/// invalid comment on global attributes.
+[assembly:System.CLSCompliant (true)]
+
+enum Foo {
+}
diff --git a/mcs/errors/cs1587-20.cs b/mcs/errors/cs1587-20.cs
new file mode 100755 (executable)
index 0000000..d9c9080
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               public /// incorrect
+               void FooBar (string foo)
+               {
+               }
+       }
+
+}
diff --git a/mcs/errors/cs1587-21.cs b/mcs/errors/cs1587-21.cs
new file mode 100755 (executable)
index 0000000..93d9f45
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               void  /// incorrect
+               FooBar (string foo)
+               {
+               }
+       }
+
+}
diff --git a/mcs/errors/cs1587-22.cs b/mcs/errors/cs1587-22.cs
new file mode 100755 (executable)
index 0000000..c478f49
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               Foo /** incorrect */ ()
+               {
+               }
+       }
+
+}
diff --git a/mcs/errors/cs1587-23.cs b/mcs/errors/cs1587-23.cs
new file mode 100755 (executable)
index 0000000..b348245
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               static /// incorrect
+               Foo ()
+               {
+               }
+       }
+
+}
diff --git a/mcs/errors/cs1587-24.cs b/mcs/errors/cs1587-24.cs
new file mode 100755 (executable)
index 0000000..29ecd2b
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               Foo (/** incorrect doccomment*/ string foo)
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-25.cs b/mcs/errors/cs1587-25.cs
new file mode 100755 (executable)
index 0000000..8060ceb
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               Foo (string foo)
+               {
+                       /** incorrect doccomment*/
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-26.cs b/mcs/errors/cs1587-26.cs
new file mode 100755 (executable)
index 0000000..f26ebbb
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               public /** invalid comment in field decl */ int field;
+       }
+}
diff --git a/mcs/errors/cs1587-27.cs b/mcs/errors/cs1587-27.cs
new file mode 100755 (executable)
index 0000000..3a07aad
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       class Foo
+       {
+               public /** invalid comment in property decl */ int prop {
+                       get { return 0; }
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-28.cs b/mcs/errors/cs1587-28.cs
new file mode 100755 (executable)
index 0000000..011966e
--- /dev/null
@@ -0,0 +1,17 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       abstract class AFoo
+       {
+               internal abstract int Prop { get; }
+       }
+
+       class Foo : AFoo
+       {
+               sealed /** is "sealed" checked? */ internal override int Prop {
+                       get { return 0; }
+               }
+       }
+}
diff --git a/mcs/errors/cs1587-3.cs b/mcs/errors/cs1587-3.cs
new file mode 100755 (executable)
index 0000000..2f9d085
--- /dev/null
@@ -0,0 +1,6 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+[Flags]
+/// invalid comment between attributes and type declaration.
+enum Foo {
+}
diff --git a/mcs/errors/cs1587-4.cs b/mcs/errors/cs1587-4.cs
new file mode 100755 (executable)
index 0000000..34add97
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+/// invalid comment placed on namespace.
+namespace TopNS
+{
+       class Foo
+       {
+       }
+}
diff --git a/mcs/errors/cs1587-5.cs b/mcs/errors/cs1587-5.cs
new file mode 100755 (executable)
index 0000000..37a06e1
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+/// invalid comment on using directive inside namespace.
+using System.Xml;
+
+       enum Foo {
+       }
+}
diff --git a/mcs/errors/cs1587-6.cs b/mcs/errors/cs1587-6.cs
new file mode 100755 (executable)
index 0000000..b78221d
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+/// invalid comment on using alias directive.
+using Hoge = System.Xml.XmlDocument;
+
+namespace TopNS
+{
+
+       enum Foo {
+       }
+}
diff --git a/mcs/errors/cs1587-7.cs b/mcs/errors/cs1587-7.cs
new file mode 100755 (executable)
index 0000000..078836b
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+/// invalid comment on using alias directive inside namespace.
+using Hoge = System.Xml.XmlDocument;
+
+       enum Foo {
+       }
+}
diff --git a/mcs/errors/cs1587-8.cs b/mcs/errors/cs1587-8.cs
new file mode 100755 (executable)
index 0000000..14b799f
--- /dev/null
@@ -0,0 +1,12 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+       /// more invalid comment on namespace; inside namespace
+       namespace ChildNS {
+               class Test {
+               }
+       }
+
+}
diff --git a/mcs/errors/cs1587-9.cs b/mcs/errors/cs1587-9.cs
new file mode 100755 (executable)
index 0000000..f2db641
--- /dev/null
@@ -0,0 +1,8 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+using System;
+
+namespace TopNS
+{
+}
+
+/// EOF
diff --git a/mcs/errors/cs1587.cs b/mcs/errors/cs1587.cs
new file mode 100755 (executable)
index 0000000..7aada7f
--- /dev/null
@@ -0,0 +1,5 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:2
+/// invalid comment placed on namespace.
+using System;
+enum Foo {
+}
diff --git a/mcs/errors/cs1589.cs b/mcs/errors/cs1589.cs
new file mode 100755 (executable)
index 0000000..a8c74a7
--- /dev/null
@@ -0,0 +1,16 @@
+// Compiler options: -doc:xml-025.xml -warn:1 -warnaserror
+
+namespace Testing
+{
+   /// <include file='cs1589.inc' path='/foo' />
+   public class Test
+   {
+       public static void Main ()
+       {
+       }
+
+       /// <include file='cs1589.inc' path='/root/@attr'/>
+       public string S3;
+   }
+}
+
diff --git a/mcs/errors/cs1589.inc b/mcs/errors/cs1589.inc
new file mode 100755 (executable)
index 0000000..6e4076c
--- /dev/null
@@ -0,0 +1,5 @@
+<root attr='is attribute allowed?'>
+  includes XML markup.
+  <child>test</child>
+  <child>test2</child>
+</root>
diff --git a/mcs/errors/cs1590-2.cs b/mcs/errors/cs1590-2.cs
new file mode 100755 (executable)
index 0000000..2c96df5
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:xml-024.xml -warn:1 -warnaserror
+// Invalid XML 'include' element; Missing 'path' attribute
+
+namespace Testing
+{
+   /// comment
+   public class Test
+   {
+       /// <include file='a' />
+       public static void Main ()
+       {
+       }
+   }
+}
+
diff --git a/mcs/errors/cs1590-3.cs b/mcs/errors/cs1590-3.cs
new file mode 100755 (executable)
index 0000000..d3b5ee8
--- /dev/null
@@ -0,0 +1,20 @@
+// Compiler options: -doc:xml-024.xml -warn:1 -warnaserror
+// Invalid XML 'include' element; Missing 'file' attribute
+
+namespace Testing
+{
+   /// comment
+   public class Test
+   {
+       /// comment
+       public static void Main ()
+       {
+       }
+
+       /// <include path='/foo/bar' />
+       public void Bar (int x)
+       {
+       }
+   }
+}
+
diff --git a/mcs/errors/cs1590.cs b/mcs/errors/cs1590.cs
new file mode 100755 (executable)
index 0000000..a7fd481
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -doc:xml-024.xml -warn:1 -warnaserror
+// CS1590: Invalid XML 'include' element; Missing 'file' attribute.
+
+namespace Testing
+{
+   /// <include/>
+   public class Test
+   {
+   }
+}
+
diff --git a/mcs/errors/cs1591-10.cs b/mcs/errors/cs1591-10.cs
new file mode 100755 (executable)
index 0000000..15619ae
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public static void Foo ()
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-11.cs b/mcs/errors/cs1591-11.cs
new file mode 100755 (executable)
index 0000000..cb9a4f1
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for interface IFoo
+       /// </summary>
+       public interface IFoo
+       {
+               void Foo ();
+       }
+}
diff --git a/mcs/errors/cs1591-12.cs b/mcs/errors/cs1591-12.cs
new file mode 100755 (executable)
index 0000000..be4e8b0
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for interface IFoo
+       /// </summary>
+       public interface IFoo
+       {
+               string Foo { get; }
+       }
+}
diff --git a/mcs/errors/cs1591-13.cs b/mcs/errors/cs1591-13.cs
new file mode 100755 (executable)
index 0000000..46ae34d
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public string this [int i] {
+                       get { return null; }
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-14.cs b/mcs/errors/cs1591-14.cs
new file mode 100755 (executable)
index 0000000..52c4dfe
--- /dev/null
@@ -0,0 +1,16 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public static bool operator ! (Test t)
+               {
+                       return false;
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-15.cs b/mcs/errors/cs1591-15.cs
new file mode 100755 (executable)
index 0000000..d3a19c6
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public Test ()
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-16.cs b/mcs/errors/cs1591-16.cs
new file mode 100755 (executable)
index 0000000..3c59c1b
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               ~Test ()
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-17.cs b/mcs/errors/cs1591-17.cs
new file mode 100755 (executable)
index 0000000..693f1ae
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               protected class InternalClass
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-18.cs b/mcs/errors/cs1591-18.cs
new file mode 100755 (executable)
index 0000000..0a23e0a
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public struct InternalStruct
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-2.cs b/mcs/errors/cs1591-2.cs
new file mode 100755 (executable)
index 0000000..77824d8
--- /dev/null
@@ -0,0 +1,9 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       public interface InterfaceTest
+       {
+       }
+}
diff --git a/mcs/errors/cs1591-3.cs b/mcs/errors/cs1591-3.cs
new file mode 100755 (executable)
index 0000000..bd5f94d
--- /dev/null
@@ -0,0 +1,9 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       public enum Foo
+       {
+       }
+}
diff --git a/mcs/errors/cs1591-4.cs b/mcs/errors/cs1591-4.cs
new file mode 100755 (executable)
index 0000000..2999b92
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// comment is here.
+       public enum Foo
+       {
+               Foo,
+               /// required for all enum members
+               Bar
+       }
+}
diff --git a/mcs/errors/cs1591-5.cs b/mcs/errors/cs1591-5.cs
new file mode 100755 (executable)
index 0000000..15c7d89
--- /dev/null
@@ -0,0 +1,7 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       public delegate void MyDelegate (object o, EventArgs e);
+}
diff --git a/mcs/errors/cs1591-6.cs b/mcs/errors/cs1591-6.cs
new file mode 100755 (executable)
index 0000000..acffd71
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public const string Constant = "CONSTANT STRING";
+       }
+}
diff --git a/mcs/errors/cs1591-7.cs b/mcs/errors/cs1591-7.cs
new file mode 100755 (executable)
index 0000000..5ccbd14
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public string PublicField;
+       }
+}
diff --git a/mcs/errors/cs1591-8.cs b/mcs/errors/cs1591-8.cs
new file mode 100755 (executable)
index 0000000..b5e48a6
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public string PublicProperty {
+                       get { return null; }
+               }
+       }
+}
diff --git a/mcs/errors/cs1591-9.cs b/mcs/errors/cs1591-9.cs
new file mode 100755 (executable)
index 0000000..ff28d3f
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               public event EventHandler MyEvent;
+       }
+}
diff --git a/mcs/errors/cs1591.cs b/mcs/errors/cs1591.cs
new file mode 100755 (executable)
index 0000000..8599cdd
--- /dev/null
@@ -0,0 +1,10 @@
+// Compiler options: -doc:dummy.xml -warnaserror -warn:4
+using System;
+
+namespace Testing
+{
+       public class TestClass
+       {
+       }
+}
+
diff --git a/mcs/errors/cs1592.cs b/mcs/errors/cs1592.cs
new file mode 100755 (executable)
index 0000000..e47cd8e
--- /dev/null
@@ -0,0 +1,16 @@
+// Compiler options: -doc:xml-024.xml -warn:1 -warnaserror
+// Badly formed XML in included comments file -- 'there-is-no-such-file'
+
+namespace Testing
+{
+   /// blah
+   public class Test
+   {
+       // warning
+       /// <include file='there-is-no-such-file' path='/foo/bar' />
+       public void Baz (int x)
+       {
+       }
+   }
+}
+
index ff67535d21cf785f7a03d54a611ef8717d8da8d3..a0d20f3ce3eafcb18ff4a5820b59cd8d1620bf6e 100644 (file)
@@ -4,3 +4,8 @@ gcs0305.cs
 gcs0308-2.cs
 gcs0308-3.cs
 gcs0308.cs
+gcs0080.cs
+gcs0305-4.cs
+gcs0692.cs
+gcs0694.cs
+gcs1644-2.cs
index 5348511f33cf8d641425cd0e830e3c7fc1c7a035..19b916675d5160c2ba81d2ef9a16ebb5b705f43a 100644 (file)
@@ -14,8 +14,6 @@ cs0229.cs
 cs0576.cs
 cs0580.cs
 
-cs0647-3.cs #64225
-
 #
 # These bugs are new in gmcs
 #
@@ -34,11 +32,28 @@ cs0122-2.cs
 cs0162.cs
 cs0249.cs
 cs0541.cs
-cs0560.cs
 cs0611-2.cs
 cs0611.cs
-cs0647-2.cs
 cs0652.cs
 cs1035.cs
 cs1040.cs
 cs2023.cs
+cs1570-10.cs
+cs1570-11.cs
+cs1570-2.cs
+cs1570-3.cs
+cs1570-4.cs
+cs1570-6.cs
+cs1570-7.cs
+cs1570-8.cs
+cs1570-9.cs
+cs1570.cs
+cs1571.cs
+cs1589.cs
+cs1590-2.cs
+cs1590-3.cs
+cs1650.cs
+cs1660.cs
+cs1690-2.cs
+cs1690-3.cs
+cs1690.cs
index 2a219390c64ddbd66ef4122ef602d7cb5e02919f..d8cb5220c2819e1d9f5523888e915ed9144543dd 100644 (file)
@@ -81,10 +81,8 @@ cs0548-2.cs
 cs0548-3.cs
 cs0548-4.cs
 cs0590-2.cs
-cs0610-3.cs
 cs0620-2.cs
 cs0620.cs
-cs0637.cs
 cs0650.cs
 cs0681.cs
 cs1013.cs
@@ -110,5 +108,83 @@ cs0712.cs
 cs0214-6.cs
 cs0056.cs
 cs0591.cs
-cs0715.cs
 
+cs0208-3.cs
+cs0260.cs
+cs0261.cs
+cs0262.cs
+cs0275.cs
+cs0538-2.cs
+cs0538.cs
+cs0560.cs
+cs0657-19.cs
+cs0664-2.cs
+cs1570-5.cs
+cs1572.cs
+cs1573.cs
+cs1574-2.cs
+cs1574-3.cs
+cs1574-4.cs
+cs1574-5.cs
+cs1574.cs
+cs1580-2.cs
+cs1580.cs
+cs1581-2.cs
+cs1581.cs
+cs1584-2.cs
+cs1584-3.cs
+cs1584-4.cs
+cs1584.cs
+cs1587-10.cs
+cs1587-11.cs
+cs1587-12.cs
+cs1587-13.cs
+cs1587-14.cs
+cs1587-15.cs
+cs1587-16.cs
+cs1587-17.cs
+cs1587-18.cs
+cs1587-19.cs
+cs1587-2.cs
+cs1587-20.cs
+cs1587-21.cs
+cs1587-22.cs
+cs1587-23.cs
+cs1587-24.cs
+cs1587-25.cs
+cs1587-26.cs
+cs1587-27.cs
+cs1587-28.cs
+cs1587-3.cs
+cs1587-4.cs
+cs1587-5.cs
+cs1587-6.cs
+cs1587-7.cs
+cs1587-8.cs
+cs1587-9.cs
+cs1587.cs
+cs1590.cs
+cs1591-10.cs
+cs1591-11.cs
+cs1591-12.cs
+cs1591-13.cs
+cs1591-14.cs
+cs1591-15.cs
+cs1591-16.cs
+cs1591-17.cs
+cs1591-18.cs
+cs1591-2.cs
+cs1591-3.cs
+cs1591-4.cs
+cs1591-5.cs
+cs1591-6.cs
+cs1591-7.cs
+cs1591-8.cs
+cs1591-9.cs
+cs1591.cs
+cs1592.cs
+cs1632.cs
+cs1648.cs
+cs1667-5.cs
+cs1721.cs
+cs1722.cs
index f3e57f1dda65168d79f1bc78c7bc2dd70f9911c2..27ffd82bf347ebd7a3b4ce200ee3130fa294ba07 100755 (executable)
@@ -1,3 +1,296 @@
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       all things are for /doc support:
+
+       * doc.cs: new file that supports XML documentation generation.
+       * mcs.exe.sources: added doc.cs.
+       * driver.cs:
+         Handle /doc command line option.
+         Report error 2006 instead of 5 for missing file name for /doc.
+         Generate XML documentation when required, after type resolution.
+       * cs-tokenizer.cs:
+         Added support for picking up documentation (/// and /** ... */),
+         including a new XmlCommentState enumeration.
+       * cs-parser.jay:
+         Added lines to fill Documentation element for field, constant,
+         property, indexer, method, constructor, destructor, operator, event
+         and class, struct, interface, delegate, enum.
+         Added lines to warn incorrect comment.
+       * rootcontext.cs :
+         Added Documentation field (passed only when /doc was specified).
+       * decl.cs:
+         Added DocComment, DocCommentHeader, GenerateDocComment() and
+         OnGenerateDocComment() and some supporting private members for
+         /doc feature to MemberCore.
+       * class.cs:
+         Added GenerateDocComment() on TypeContainer, MethodCore and Operator.
+       * delegate.cs:
+         Added overriden DocCommentHeader.
+       * enum.cs:
+         Added overriden DocCommentHeader and GenerateDocComment().
+
+2004-12-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs (ConstantFold.DoConstantNumericPromotions): After
+       unwrapping the enumeration values, chain to
+       DoConstantNumericPromotions again, so we can promote things to the
+       fundamental types (takes care of enums that are bytes, sbytes).
+
+       Fixes bug #62054.
+
+2004-12-01  Raja R Harinath  <rharinath@novell.com>
+
+       * attribute.cs (Attribute.CheckAttributeType): Remove complain flag.
+       Fix long-standing bug in type-lookup.  Use FindType instead of
+       LookupType when ec.ResolvingTypeTree.
+       (Attribute.ResolveType, Attribute.Resolve)
+       (Attribute.DefinePInvokeMethod,GlobalAttribute.CheckAttributeType):
+       Update to changes.
+       (Attributes.Search): Remove internal version.  Update.
+       (Attributes.SearchMulti): Update.
+       (Attributes.GetClsCompliantAttribute): Remove.
+       (Attributes.GetIndexerNameAttribute): Remove.
+       * decl.cs (MemberCore.GetClsCompliantAttributeValue): Update to changes.
+       (DeclSpace.GetClsCompliantAttributeValue): Likewise.
+       * class.cs (Indexer.Define): Likewise.
+
+2004-12-01  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #68790
+       * ecore.cs: CheckMarshallByRefAccess new virtual method for testing
+       MarshallByReference members access.
+
+       * expression.cs: Use CheckMarshallByRefAccess;
+       Better error CS0197 message.
+
+       * report.cs: Print whole related error message.
+
+2004-11-29  Marek Safar  <marek.safar@seznam.cz>
+
+       * class (GetClassBases): Better error 60 report.
+       (EventProperty): Disabled warning 67 detection.
+
+2004-11-29  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #60324
+       * cfold.cs (Assign.DoResolve): Add subtraction for DecimalConstant.
+
+       * constant.cs (DecimalConstant.Emit): Don't use int ctor for
+       precise values.
+
+2004-11-29  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #49488
+       * assign.cs (Assign.DoResolve): Add error 1648, 1650 report.
+
+       * decl.cs (MemberCore.MemberName): Error 1648 in compiler.
+
+2004-11-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Refine error reporting and
+       report a cs0117 if the identifier does not exist, to distinguish
+       from 0617 which is a miss-use of the actual identifier.
+
+       * ecore.cs (EventExpr.Emit): Refine error report and distinguish
+       between cs0070 and cs0079.
+
+       * class.cs (MemberBase.DoDefine): When reporting a wrong
+       accessibility level, we use MethodCore to compare instead of
+       Method (this was a regression in some refactoring effort).
+
+       So now we correctly report cs0056 again.
+
+       * convert.cs (ImplicitReferenceConversion): Corrected typo, I was
+       testing the target_type (which was known to be object_type) and
+       not the source type (which is anonymous_method).
+
+       Fixed reporting of error cs1660.
+
+       * expression.cs (UserCast.Source): Expose the underlying cast.
+
+       * statement.cs (Switch.SwitchGoverningType): Sort the list of
+       allowed types to find a match to int32 first (most common).
+
+       In addition, it ignores any ImplicitUserConversions that did an
+       internal implicit conversion (as the switch statement allows only
+       one integral conversion to exist).
+
+       * class.cs (PartialContainer.Create): rename `name' to
+       `member_name' for clarity.  Then replace the string calls with a
+       call to MemberName.GetPartialName, as now using
+       MemberName.ToString is an error (this is due to the side effects
+       it had, that were fixed in the past).
+
+       This will restore the error reporting on a number of partial class
+       errors that were missusing this (and getting an exception as a
+       results, which is now just a plain textual warning, because
+       yyparse debug output would crash otherwise).
+
+2004-11-26  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (PROGRAM_INSTALL_DIR): Remove.
+
+2004-11-25  Ben Maurer  <bmaurer@ximian.com>
+
+       * rootcontext.cs (LookupType): Make sure to cache lookups that
+       don't give us a negative result. This saves about 5% of corlib
+       compilation time.
+
+2004-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * report.cs (AbstractMessage.Print): messages are sent to stderr
+
+       * class.cs (TypeContainer.GetClassBases): It is an error to have a
+       non-interface in the list of interfaces (at this point, either
+       parent was properly set, or a base class is being listed in the
+       interfaces section).
+
+       This flags error 1722, and resolves the crash from bug 69259.
+
+2004-11-25  Ben Maurer  <bmaurer@ximian.com>
+
+       * statement.cs (Using.EmitExpressionFinally): make this work right
+       for valuetypes. Fixes 69926.
+
+2004-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * const.cs (Const.ChangeType): Cope with the "0 literal can be
+       converted to an enum" here, before we try to change the underlying
+       type.  This code exists, but it is a different code path than the
+       one used while encoding constants.
+
+       (ImplicitReferenceConversionExists): In addition, resynchronized
+       the code here, so it matches the same code in
+       ImplicitReferenceConversionExists for the `from any class-type S
+       to any interface-type T'.       
+
+2004-11-25  Marek Safar  <marek.safar@seznam.cz>
+
+       * cfold.cs (BinaryFold): Add addition for DecimalConstant.
+
+2004-11-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Use verbosity accordingly. 
+
+2004-11-24  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (Unary.ResolveOperator): Do not report warning;
+       AddressOf reads from variable.
+       
+       (LocalVariableReferences.DoResolveBase): Improved my previous fix.
+
+2004-11-24  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #69462
+
+       * attribute.cs (Attributable): Removed CheckTargets.
+       (Attributes.Emit): Explicit attribute targets are tested here.
+
+       * class.cs (EventField.ValidAttributeTargets): Explicit target "field" is
+       not enabled for interfaces.
+
+       * codegen.cs (CommonAssemblyModulClass.AddAttributes): Removed CheckTargets.
+       (GetAssemblyName): Ouch next bug there.
+
+2004-11-23  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * expression.cs: Error 275 added.
+       
+2004-11-23  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #69177 (Implemented decimal constant support)
+
+       * cfold.cs (DoConstantNumericPromotions: Add DecimalConstant.
+       (BinaryFold): Add DecimalConstant.
+
+       * const.cs (Define): Decimal constant 
+       (is not constant.
+       (ChangeType): Add decimal type handling.
+       (LookupConstantValue): Don't set value for decimal type but
+       emit DecimalConstantAttribute. Needed for constant optimization.
+
+       * constant.cs (ToDecimal): New method.
+       (ConvertToDecimal): New method.
+       (IntConstant): Implemented ConvertToDecimal.
+       (DecimalConstant.Emit): Emit optimized version for decimals in
+       int range.
+
+       * expression.cs (ResolveOperator): Changed order of constant
+       reduction to work correctly with native types which have
+       overloaded operators.
+       (ResolveMemberAccess): Extract constant value from attribute
+       for decimal type.
+
+       * rootcontext.cs (ResolveCore): Add DecimalConstantAttribute.
+
+       * typemanager.cs (TypeManager): Add decimal_constant_attribute_type,
+       void_decimal_ctor_int_arg, decimal_constant_attribute_ctor.
+       (ChangeType): Decimal is special.
+       (TypeToCoreType): Add decimal type.
+
+2004-11-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * convert.cs (ImplicitConversionRequired): Add error cs0642 for
+       decimal types.
+
+2004-11-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (EventField.ApplyAttributeBuilder): Fix error
+       test cs1667-5.cs.
+
+2004-11-19  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (MemberBase.DoDefine): Fix error cs0508 report.
+
+       * pending.cs (PendingImplementation): Grab only interfaces.
+
+2004-11-19  Marek Safar  <marek.safar@seznam.cz>
+
+       * statement.cs (ForeachHelperMethods): Add location member and
+       error 202 detection.
+
+2004-11-18  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (DoResolveBase): Fixed wrong warning for out
+       variables.
+
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.TypeParameter_to_Null): Use the constraints
+       to check whether the conversion is ok.
+
+       * typemanager.cs (TypeManager.GetTypeArguments): Just return
+       `Type.EmptyTypes' if we're not a generic TypeContainer.
+
+2004-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs (ImplicitReferenceConversionExists): A surprisingly
+       old bug: when converting from the null literal to a pointer,
+       return an EmptyCast, not the NullLiteral.
+
+       This fixes #69921, the recent null_type changes probably made this
+       bug more prominent.
+
+2004-12-03  Martin Baulig  <martin@ximian.com>
+
+       * delegate.cs (NewDelegate.DoResolve): If we have an anonymous
+       method as our child, call AnonymousMethod.Compatible() on it.
+
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (FieldBase): Use an unused bit field from the field to
+       encode the `has_offset' property from the FieldMember.  This saves
+       a couple of Ks on bootstrap compilation.
+
+       * delegate.cs (NewDelegate.DoResolve): If we have an anonymous
+       method as our child, return the AnonymousMethod resolved
+       expression.
+
+       * expression.cs (New.DoResolve): Allow return values from
+       NewDelegate to also include AnonymousMethods.
+
+       Fixes #70150.
+
 2004-11-29  Raja R Harinath  <rharinath@novell.com>
 
        * decl.cs (MemberCore.MemberName): Remove readonly to fix an error
index cf6008979fd5c562ebb66e05ee8f2702d1725635..25f9955c6365a1e9ab049c3e3674ff43e1050de4 100755 (executable)
@@ -386,6 +386,21 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       FieldExpr field_exp = target as FieldExpr;
+                       if (field_exp != null && !ec.IsConstructor && !ec.IsFieldInitializer) {
+                               field_exp = field_exp.InstanceExpression as FieldExpr;
+                               if (field_exp != null && field_exp.FieldInfo.IsInitOnly) {
+                                       if (field_exp.IsStatic) {
+                                               Report.Error (1650, loc, "Members of static readonly field '{0}' cannot be assigned to " +
+                                                       "(except in a static constructor or a variable initializer)", TypeManager.GetFullNameSignature (field_exp.FieldInfo));
+                                       } else {
+                                               Report.Error (1648, loc, "Members of readonly field '{0}' cannot be assigned to " +
+                                                       "(except in a constructor or a variable initializer)", TypeManager.GetFullNameSignature (field_exp.FieldInfo));
+                                       }
+                                       return null;
+                               }
+                       }
+
                        if (!(target is IAssignMethod) && (target.eclass != ExprClass.EventAccess)) {
                                Report.Error (131, loc,
                                              "Left hand of an assignment must be a variable, " +
index fb114f648a46377cd5b911b99a56bfa9f811a762..b1e1a5672917bf635c5b0b2cbbf4c510b58c4abd 100644 (file)
@@ -33,11 +33,9 @@ namespace Mono.CSharp {
                /// </summary>
                Attributes attributes;
 
-               public Attributable(Attributes attrs)
+               public Attributable (Attributes attrs)
                {
                        attributes = attrs;
-                       if (attributes != null)
-                               attributes.CheckTargets (this);
                }
 
                public Attributes OptAttributes 
@@ -47,8 +45,6 @@ namespace Mono.CSharp {
                        }
                        set {
                                attributes = value;
-                               if (attributes != null)
-                                       attributes.CheckTargets (this);
                        }
                }
 
@@ -114,9 +110,9 @@ namespace Mono.CSharp {
 
                void Error_InvalidNamedArgument (string name)
                {
-                       Report.Error (617, Location, "'" + name + "' is not a valid named attribute " +
-                                     "argument. Named attribute arguments must be fields which are not " +
-                                     "readonly, static or const, or read-write properties which are not static.");
+                       Report.Error (617, Location, "Invalid attribute argument: '{0}'.  Argument must be fields " +
+                                     "fields which are not readonly, static or const;  or read-write instance properties.",
+                                     Name);
                }
 
                static void Error_AttributeArgumentNotValid (Location loc)
@@ -155,11 +151,17 @@ namespace Mono.CSharp {
                /// <summary>
                 ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
                 /// </summary>
-               protected virtual Type CheckAttributeType (EmitContext ec, bool complain)
+               protected virtual Type CheckAttributeType (EmitContext ec)
                {
-                       Type t1 = RootContext.LookupType (ec.DeclSpace, Name, true, Location);
+                       string NameAttribute = Name + "Attribute";
+                       Type t1 = ec.ResolvingTypeTree
+                               ? ec.DeclSpace.FindType (Location, Name)
+                               : RootContext.LookupType (ec.DeclSpace, Name, true, Location);
+
                        // FIXME: Shouldn't do this for quoted attributes: [@A]
-                       Type t2 = RootContext.LookupType (ec.DeclSpace, Name + "Attribute", true, Location);
+                       Type t2 = ec.ResolvingTypeTree
+                               ? ec.DeclSpace.FindType (Location, NameAttribute)
+                               : RootContext.LookupType (ec.DeclSpace, NameAttribute, true, Location);
 
                        String err0616 = null;
                        if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
@@ -169,13 +171,13 @@ namespace Mono.CSharp {
                        if (t2 != null && ! t2.IsSubclassOf (TypeManager.attribute_type)) {
                                t2 = null;
                                err0616 = (err0616 != null) 
-                                       ? "Neither '" + Name + "' nor '" + Name + "Attribute' is an attribute class"
+                                       ? "Neither '" + Name + "' nor '" + NameAttribute +"' is an attribute class"
                                        : "'" + Name + "Attribute': is not an attribute class";
                        }
 
                        if (t1 != null && t2 != null) {
                                Report.Error(1614, Location, "'" + Name + "': is ambiguous; " 
-                                            + " use either '@" + Name + "' or '" + Name + "Attribute'");
+                                            + " use either '@" + Name + "' or '" + NameAttribute + "'");
                                return null;
                        }
                        if (t1 != null)
@@ -187,17 +189,17 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (complain)
-                               Report.Error (246, Location, 
-                                             "Could not find attribute '" + Name 
-                                             + "' (are you missing a using directive or an assembly reference ?)");
+                       Report.Error (246, Location, 
+                                     "Could not find attribute '" + Name 
+                                     + "' (are you missing a using directive or an assembly reference ?)");
+
                        return null;
                }
 
-               public Type ResolveType (EmitContext ec, bool complain)
+               public Type ResolveType (EmitContext ec)
                {
                        if (Type == null)
-                               Type = CheckAttributeType (ec, complain);
+                               Type = CheckAttributeType (ec);
                        return Type;
                }
 
@@ -269,7 +271,7 @@ namespace Mono.CSharp {
                        Type oldType = Type;
                        
                        // Sanity check.
-                       Type = CheckAttributeType (ec, true);
+                       Type = CheckAttributeType (ec);
 
                        if (oldType == null && Type == null)
                                return null;
@@ -414,7 +416,13 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               if (member == null || !(member is PropertyExpr || member is FieldExpr)) {
+                               if (member == null){
+                                       Report.Error (117, Location, "Attribute `{0}' does not contain a definition for `{1}'",
+                                                     Type, member_name);
+                                       return null;
+                               }
+                               
+                               if (!(member is PropertyExpr || member is FieldExpr)) {
                                        Error_InvalidNamedArgument (member_name);
                                        return null;
                                }
@@ -1008,7 +1016,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       ResolveType (ec, true);
+                       ResolveType (ec);
                        if (Type == null)
                                return null;
                        
@@ -1170,12 +1178,12 @@ namespace Mono.CSharp {
                        ns = container.NamespaceEntry;
                }
 
-               protected override Type CheckAttributeType (EmitContext ec, bool complain)
+               protected override Type CheckAttributeType (EmitContext ec)
                {
                        NamespaceEntry old = ec.DeclSpace.NamespaceEntry;
                        if (old == null || old.NS == null || old.NS == Namespace.Root) 
                                ec.DeclSpace.NamespaceEntry = ns;
-                       return base.CheckAttributeType (ec, complain);
+                       return base.CheckAttributeType (ec);
                }
        }
 
@@ -1201,7 +1209,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// Checks whether attribute target is valid for the current element
                /// </summary>
-               public void CheckTargets (Attributable member)
+               public bool CheckTargets (Attributable member)
                {
                        string[] valid_targets = member.ValidAttributeTargets;
                        foreach (Attribute a in Attrs) {
@@ -1228,24 +1236,21 @@ namespace Mono.CSharp {
                                        sb.Append (", ");
                                }
                                sb.Remove (sb.Length - 2, 2);
-                               Report.Error (657, a.Location, "'{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '{1}'", a.Target, sb.ToString ());
+                               Report.Error (657, a.Location, "'{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '{1}'", a.ExplicitTarget, sb.ToString ());
+                               return false;
                        }
+                       return true;
                }
 
-               private Attribute Search (Type t, EmitContext ec, bool complain)
+               public Attribute Search (Type t, EmitContext ec)
                {
                        foreach (Attribute a in Attrs) {
-                               if (a.ResolveType (ec, complain) == t)
+                               if (a.ResolveType (ec) == t)
                                        return a;
                        }
                        return null;
                }
 
-               public Attribute Search (Type t, EmitContext ec)
-               {
-                       return Search (t, ec, true);
-               }
-
                /// <summary>
                /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true
                /// </summary>
@@ -1254,7 +1259,7 @@ namespace Mono.CSharp {
                        ArrayList ar = null;
 
                        foreach (Attribute a in Attrs) {
-                               if (a.ResolveType (ec, false) == t) {
+                               if (a.ResolveType (ec) == t) {
                                        if (ar == null)
                                                ar = new ArrayList ();
                                        ar.Add (a);
@@ -1266,6 +1271,9 @@ namespace Mono.CSharp {
 
                public void Emit (EmitContext ec, Attributable ias)
                {
+                       if (!CheckTargets (ias))
+                               return;
+
                        ListDictionary ld = new ListDictionary ();
 
                        foreach (Attribute a in Attrs)
@@ -1276,26 +1284,6 @@ namespace Mono.CSharp {
                {
                         return Search (t, ec) != null;
                }
-
-               public Attribute GetClsCompliantAttribute (EmitContext ec)
-               {
-                       return Search (TypeManager.cls_compliant_attribute_type, ec, false);
-               }
-
-               /// <summary>
-               /// Pulls the IndexerName attribute from an Indexer if it exists.
-               /// </summary>
-               public Attribute GetIndexerNameAttribute (EmitContext ec)
-               {
-                       Attribute a = Search (TypeManager.indexer_name_type, ec, false);
-                       if (a == null)
-                               return null;
-
-                       // Remove the attribute from the list because it is not emitted
-                       Attrs.Remove (a);
-                       return a;
-               }
-
        }
 
        /// <summary>
index 12999eccdd858e3627f29b560e25e400fd17dcd2..9465eaa20bf20c81abe6c397850477ffa83e8f63 100755 (executable)
@@ -134,6 +134,12 @@ namespace Mono.CSharp {
                                }
 
                                return;
+                       } else if (left is DecimalConstant || right is DecimalConstant) {
+                               if (!(left is DecimalConstant))
+                                       left = left.ToDecimal (loc);
+                               else if (!(right is DecimalConstant))
+                                       right = right.ToDecimal (loc);
+                               return;
                        } else if (left is EnumConstant || right is EnumConstant){
                                //
                                // If either operand is an enum constant, the other one must
@@ -165,6 +171,8 @@ namespace Mono.CSharp {
                                        left = ((EnumConstant) left).Child;
                                if (right is EnumConstant)
                                        right = ((EnumConstant) right).Child;
+
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                return;
 
                        } else {
@@ -221,7 +229,7 @@ namespace Mono.CSharp {
                                DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
-                               
+
                                if (left is IntConstant){
                                        IntConstant v;
                                        int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
@@ -523,8 +531,19 @@ namespace Mono.CSharp {
                                                                         ((IntConstant) right).Value);
 
                                                result = new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value +
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value +
+                                                               ((DecimalConstant) right).Value);
+
+                                               result = new DecimalConstant (res);
                                        } else {
-                                               throw new Exception ( "Unexepected input: " + left);
+                                               throw new Exception ( "Unexepected addition input: " + left);
                                        }
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
@@ -630,8 +649,19 @@ namespace Mono.CSharp {
                                                                         ((IntConstant) right).Value);
 
                                                result = new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value -
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value -
+                                                               ((DecimalConstant) right).Value);
+
+                                               return new DecimalConstant (res);
                                        } else {
-                                               throw new Exception ( "Unexepected input: " + left);
+                                               throw new Exception ( "Unexepected subtraction input: " + left);
                                        }
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
@@ -652,10 +682,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((DoubleConstant) left).Value *
-                                                                      ((DoubleConstant) right).Value);
+                                                               ((DoubleConstant) right).Value);
                                                else
                                                        res = unchecked (((DoubleConstant) left).Value *
-                                                                        ((DoubleConstant) right).Value);
+                                                               ((DoubleConstant) right).Value);
                                                
                                                return new DoubleConstant (res);
                                        } else if (left is FloatConstant){
@@ -663,10 +693,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((FloatConstant) left).Value *
-                                                                      ((FloatConstant) right).Value);
+                                                               ((FloatConstant) right).Value);
                                                else
                                                        res = unchecked (((FloatConstant) left).Value *
-                                                                        ((FloatConstant) right).Value);
+                                                               ((FloatConstant) right).Value);
                                                
                                                return new FloatConstant (res);
                                        } else if (left is ULongConstant){
@@ -674,10 +704,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((ULongConstant) left).Value *
-                                                                      ((ULongConstant) right).Value);
+                                                               ((ULongConstant) right).Value);
                                                else
                                                        res = unchecked (((ULongConstant) left).Value *
-                                                                        ((ULongConstant) right).Value);
+                                                               ((ULongConstant) right).Value);
                                                
                                                return new ULongConstant (res);
                                        } else if (left is LongConstant){
@@ -685,10 +715,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((LongConstant) left).Value *
-                                                                      ((LongConstant) right).Value);
+                                                               ((LongConstant) right).Value);
                                                else
                                                        res = unchecked (((LongConstant) left).Value *
-                                                                        ((LongConstant) right).Value);
+                                                               ((LongConstant) right).Value);
                                                
                                                return new LongConstant (res);
                                        } else if (left is UIntConstant){
@@ -696,10 +726,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((UIntConstant) left).Value *
-                                                                      ((UIntConstant) right).Value);
+                                                               ((UIntConstant) right).Value);
                                                else
                                                        res = unchecked (((UIntConstant) left).Value *
-                                                                        ((UIntConstant) right).Value);
+                                                               ((UIntConstant) right).Value);
                                                
                                                return new UIntConstant (res);
                                        } else if (left is IntConstant){
@@ -707,14 +737,25 @@ namespace Mono.CSharp {
 
                                                if (ec.ConstantCheckState)
                                                        res = checked (((IntConstant) left).Value *
-                                                                      ((IntConstant) right).Value);
+                                                               ((IntConstant) right).Value);
                                                else
                                                        res = unchecked (((IntConstant) left).Value *
-                                                                        ((IntConstant) right).Value);
+                                                               ((IntConstant) right).Value);
 
                                                return new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value *
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value *
+                                                               ((DecimalConstant) right).Value);
+
+                                               return new DecimalConstant (res);
                                        } else {
-                                               throw new Exception ( "Unexepected input: " + left);
+                                               throw new Exception ( "Unexepected multiply input: " + left);
                                        }
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
@@ -732,10 +773,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((DoubleConstant) left).Value /
-                                                                      ((DoubleConstant) right).Value);
+                                                               ((DoubleConstant) right).Value);
                                                else
                                                        res = unchecked (((DoubleConstant) left).Value /
-                                                                        ((DoubleConstant) right).Value);
+                                                               ((DoubleConstant) right).Value);
                                                
                                                return new DoubleConstant (res);
                                        } else if (left is FloatConstant){
@@ -743,10 +784,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((FloatConstant) left).Value /
-                                                                      ((FloatConstant) right).Value);
+                                                               ((FloatConstant) right).Value);
                                                else
                                                        res = unchecked (((FloatConstant) left).Value /
-                                                                        ((FloatConstant) right).Value);
+                                                               ((FloatConstant) right).Value);
                                                
                                                return new FloatConstant (res);
                                        } else if (left is ULongConstant){
@@ -754,10 +795,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((ULongConstant) left).Value /
-                                                                      ((ULongConstant) right).Value);
+                                                               ((ULongConstant) right).Value);
                                                else
                                                        res = unchecked (((ULongConstant) left).Value /
-                                                                        ((ULongConstant) right).Value);
+                                                               ((ULongConstant) right).Value);
                                                
                                                return new ULongConstant (res);
                                        } else if (left is LongConstant){
@@ -765,10 +806,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((LongConstant) left).Value /
-                                                                      ((LongConstant) right).Value);
+                                                               ((LongConstant) right).Value);
                                                else
                                                        res = unchecked (((LongConstant) left).Value /
-                                                                        ((LongConstant) right).Value);
+                                                               ((LongConstant) right).Value);
                                                
                                                return new LongConstant (res);
                                        } else if (left is UIntConstant){
@@ -776,10 +817,10 @@ namespace Mono.CSharp {
                                                
                                                if (ec.ConstantCheckState)
                                                        res = checked (((UIntConstant) left).Value /
-                                                                      ((UIntConstant) right).Value);
+                                                               ((UIntConstant) right).Value);
                                                else
                                                        res = unchecked (((UIntConstant) left).Value /
-                                                                        ((UIntConstant) right).Value);
+                                                               ((UIntConstant) right).Value);
                                                
                                                return new UIntConstant (res);
                                        } else if (left is IntConstant){
@@ -787,14 +828,25 @@ namespace Mono.CSharp {
 
                                                if (ec.ConstantCheckState)
                                                        res = checked (((IntConstant) left).Value /
-                                                                      ((IntConstant) right).Value);
+                                                               ((IntConstant) right).Value);
                                                else
                                                        res = unchecked (((IntConstant) left).Value /
-                                                                        ((IntConstant) right).Value);
+                                                               ((IntConstant) right).Value);
 
                                                return new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value /
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value /
+                                                               ((DecimalConstant) right).Value);
+
+                                               return new DecimalConstant (res);
                                        } else {
-                                               throw new Exception ( "Unexepected input: " + left);
+                                               throw new Exception ( "Unexepected division input: " + left);
                                        }
                                } catch (OverflowException){
                                        Error_CompileTimeOverflow (loc);
@@ -878,7 +930,7 @@ namespace Mono.CSharp {
 
                                                return new IntConstant (res);
                                        } else {
-                                               throw new Exception ( "Unexepected input: " + left);
+                                               throw new Exception ( "Unexepected modulus input: " + left);
                                        }
                                } catch (DivideByZeroException){
                                        Report.Error (020, loc, "Division by constant zero");
index 2fb89414dde196f1cf5fe1367bb19a53f3757255..4cb48f00c403065baad05528dc6af8250c7f74af 100755 (executable)
@@ -8,6 +8,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 //
 //  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
@@ -40,6 +41,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Permissions;
+using System.Xml;
 
 using Mono.CompilerServices.SymbolWriter;
 
@@ -1068,11 +1070,11 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               if (!parent.AsAccessible (this, ModFlags))
-                                       Report.Error (60, Location,
-                                                     "Inconsistent accessibility: base class `" +
-                                                     parent.Name + "' is less accessible than class `" +
-                                                     Name + "'");
+                               if (!parent.AsAccessible (this, ModFlags)) {
+                                       Report.SymbolRelatedToPreviousError (parent.Type);
+                                       Report.Error (60, Location, "Inconsistent accessibility: base class '{0}' is less accessible than class '{1}'", 
+                                               TypeManager.CSharpName (parent.Type), GetSignatureForError ());
+                               }
                        }
 
                        if (parent != null)
@@ -1098,13 +1100,11 @@ namespace Mono.CSharp {
                                }
 
                                if (iface.IsClass) {
-                                       if (parent != null){
-                                               Report.Error (527, Location,
-                                                             "In Class `{0}', `{1}' is not " +
-                                                             "an interface", Name, iface.Name);
-                                               error = true;
-                                               return null;
-                                       }
+                                       Report.Error (1722, Location,
+                                                     "In Class `{0}', `{1}' is not " +
+                                                     "an interface, a base class must be listed first", Name, iface.Name);
+                                       error = true;
+                                       return null;
                                }
   
                                for (int x = 0; x < i; x++) {
@@ -2397,6 +2397,10 @@ namespace Mono.CSharp {
                        }
                }
 
+               public Constructor DefaultStaticConstructor {
+                       get { return default_static_constructor; }
+               }
+
                protected override bool VerifyClsCompliance (DeclSpace ds)
                {
                        if (!base.VerifyClsCompliance (ds))
@@ -2533,6 +2537,19 @@ namespace Mono.CSharp {
                                return FindMembers (mt, new_bf, null, null);
                }
 
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal override void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateTypeDocComment (this, ds);
+               }
+
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
+
                public virtual MemberCache ParentCache {
                        get {
                                return parent_cache;
@@ -2549,11 +2566,11 @@ namespace Mono.CSharp {
                public readonly TypeAttributes DefaultTypeAttributes;
 
                static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
-                                               MemberName name, int mod_flags, Kind kind,
+                                               MemberName member_name, int mod_flags, Kind kind,
                                                Location loc)
                {
                        PartialContainer pc;
-                       string full_name = name.GetName (true);
+                       string full_name = member_name.GetName (true);
                        DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
                        if (ds != null) {
                                pc = ds as PartialContainer;
@@ -2563,7 +2580,7 @@ namespace Mono.CSharp {
                                                260, ds.Location, "Missing partial modifier " +
                                                "on declaration of type `{0}'; another " +
                                                "partial implementation of this type exists",
-                                               name);
+                                               member_name.GetPartialName());
 
                                        Report.LocationOfPreviousError (loc);
                                        return null;
@@ -2573,7 +2590,7 @@ namespace Mono.CSharp {
                                        Report.Error (
                                                261, loc, "Partial declarations of `{0}' " +
                                                "must be all classes, all structs or " +
-                                               "all interfaces", name);
+                                               "all interfaces", member_name.GetPartialName ());
                                        return null;
                                }
 
@@ -2581,14 +2598,14 @@ namespace Mono.CSharp {
                                        Report.Error (
                                                262, loc, "Partial declarations of `{0}' " +
                                                "have conflicting accessibility modifiers",
-                                               name);
+                                               member_name.GetPartialName ());
                                        return null;
                                }
 
                                return pc;
                        }
 
-                       pc = new PartialContainer (ns, parent, name, mod_flags, kind, loc);
+                       pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
                        RootContext.Tree.RecordDecl (full_name, pc);
                        parent.AddType (pc);
                        pc.Register ();
@@ -3557,6 +3574,34 @@ namespace Mono.CSharp {
                        return false;
                }
 
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public override string GetDocCommentName (DeclSpace ds)
+               {
+                       return DocUtil.GetMethodDocCommentName (this, ds);
+               }
+
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               // FIXME: with a few effort, it could be done with XmlReader,
+               // that means removal of DOM use.
+               //
+               internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el)
+               {
+                       DocUtil.OnMethodGenerateDocComment (this, ds, el);
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "M:"; }
+               }
+
                protected override void VerifyObsoleteAttribute()
                {
                        base.VerifyObsoleteAttribute ();
@@ -5262,8 +5307,8 @@ namespace Mono.CSharp {
                                                      "Inconsistent accessibility: indexer return type `" +
                                                      TypeManager.CSharpName (MemberType) + "' is less " +
                                                      "accessible than indexer `" + Name + "'");
-                               else if (this is Method) {
-                                       if (((Method) this).IsOperator)
+                               else if (this is MethodCore) {
+                                       if (this is Operator)
                                                Report.Error (56, Location,
                                                              "Inconsistent accessibility: return type `" +
                                                              TypeManager.CSharpName (MemberType) + "' is less " +
@@ -5273,11 +5318,12 @@ namespace Mono.CSharp {
                                                              "Inconsistent accessibility: return type `" +
                                                              TypeManager.CSharpName (MemberType) + "' is less " +
                                                              "accessible than method `" + Name + "'");
-                               } else
+                               } else {
                                        Report.Error (52, Location,
                                                      "Inconsistent accessibility: field type `" +
                                                      TypeManager.CSharpName (MemberType) + "' is less " +
                                                      "accessible than field `" + Name + "'");
+                               }
                                return false;
                        }
 
@@ -5292,8 +5338,8 @@ namespace Mono.CSharp {
 
                                InterfaceType = iface_texpr.Type;
 
-                               if (InterfaceType.IsClass) {
-                                       Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
+                               if (!InterfaceType.IsInterface) {
+                                       Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
                                        return false;
                                }
 
@@ -5357,7 +5403,8 @@ namespace Mono.CSharp {
                [Flags]
                public enum Status : byte {
                        ASSIGNED = 1,
-                       USED = 2
+                       USED = 2,
+                       HAS_OFFSET = 4          // Used by FieldMember.
                }
 
                static string[] attribute_targets = new string [] { "field" };
@@ -5522,7 +5569,7 @@ namespace Mono.CSharp {
 
        public abstract class FieldMember: FieldBase
        {
-               bool has_field_offset = false;
+               
 
                protected FieldMember (TypeContainer parent, Expression type, int mod,
                        int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
@@ -5534,7 +5581,7 @@ namespace Mono.CSharp {
                {
                        if (a.Type == TypeManager.field_offset_attribute_type)
                        {
-                               has_field_offset = true;
+                               status |= Status.HAS_OFFSET;
 
                                if (!Parent.HasExplicitLayout) {
                                        Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
@@ -5587,12 +5634,19 @@ namespace Mono.CSharp {
 
                public override void Emit ()
                {
-                       if (Parent.HasExplicitLayout && !has_field_offset && (ModFlags & Modifiers.STATIC) == 0) {
+                       if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
                                Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
                        }
 
                        base.Emit ();
                }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "F:"; }
+               }
        }
 
        //
@@ -5827,7 +5881,7 @@ namespace Mono.CSharp {
                {
                        if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
                                        a.Type == TypeManager.conditional_attribute_type) {
-                               Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
+                               Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on {1} declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
                                return;
                        }
 
@@ -5861,7 +5915,7 @@ namespace Mono.CSharp {
 
                public override bool Define()
                {
-                       return false;
+                       throw new NotSupportedException ();
                }
 
                public virtual void Emit (TypeContainer container)
@@ -5908,6 +5962,13 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
+               }
+
                protected override void VerifyObsoleteAttribute()
                {
                }
@@ -6354,6 +6415,13 @@ namespace Mono.CSharp {
                                return attribute_targets;
                        }
                }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "P:"; }
+               }
        }
                        
        public class Property : PropertyBase, IIteratorContainer {
@@ -6621,6 +6689,10 @@ namespace Mono.CSharp {
                {
                        Add = new AddDelegateMethod (this, add);
                        Remove = new RemoveDelegateMethod (this, remove);
+
+                       // For this event syntax we don't report error CS0067
+                       // because it is hard to do it.
+                       SetAssigned ();
                }
 
                public override string[] ValidAttributeTargets {
@@ -6636,6 +6708,7 @@ namespace Mono.CSharp {
        public class EventField: Event {
 
                static string[] attribute_targets = new string [] { "event", "field", "method" };
+               static string[] attribute_targets_interface = new string[] { "event", "method" };
 
                public EventField (TypeContainer parent, Expression type, int mod_flags,
                                   bool is_iface, MemberName name, Object init,
@@ -6654,8 +6727,8 @@ namespace Mono.CSharp {
                        }
 
                        if (a.Target == AttributeTargets.Method) {
-                               AddBuilder.SetCustomAttribute (cb);
-                               RemoveBuilder.SetCustomAttribute (cb);
+                               Add.ApplyAttributeBuilder (a, cb);
+                               Remove.ApplyAttributeBuilder (a, cb);
                                return;
                        }
 
@@ -6664,7 +6737,7 @@ namespace Mono.CSharp {
 
                public override string[] ValidAttributeTargets {
                        get {
-                               return attribute_targets;
+                               return IsInterface ? attribute_targets_interface : attribute_targets;
                        }
                }
        }
@@ -7001,6 +7074,13 @@ namespace Mono.CSharp {
 
                        return TypeManager.GetFullNameSignature (EventBuilder);
                }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "E:"; }
+               }
        }
 
  
@@ -7133,8 +7213,11 @@ namespace Mono.CSharp {
                                return false;
 
                        if (OptAttributes != null) {
-                               Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec);
+                               Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
                                if (indexer_attr != null) {
+                                       // Remove the attribute from the list because it is not emitted
+                                       OptAttributes.Attrs.Remove (indexer_attr);
+
                                        ShortName = indexer_attr.GetIndexerAttributeValue (ec);
 
                                        if (IsExplicitImpl) {
index 236301436a213a9ff881a3c2ef41fbaf3a4214cc..0bab8e95e1ce336fa79529239436d6815995e34e 100755 (executable)
@@ -1025,7 +1025,6 @@ namespace Mono.CSharp {
                                return;
                        }
                        OptAttributes.AddAttributes (attrs);
-                       OptAttributes.CheckTargets (this);
                }
 
                public virtual void Emit (TypeContainer tc) 
@@ -1123,12 +1122,15 @@ namespace Mono.CSharp {
                        }
                }
 
+               // TODO: rewrite this code (to kill N bugs and make it faster) and use standard ApplyAttribute way.
                public AssemblyName GetAssemblyName (string name, string output) 
                {
                        if (OptAttributes != null) {
                                foreach (Attribute a in OptAttributes.Attrs) {
-                                       if (a.Target != AttributeTargets.Assembly)
-                                               continue;
+                                      // cannot rely on any resolve-based members before you call Resolve
+                                      if (a.ExplicitTarget == null || a.ExplicitTarget != "assembly")
+                                              continue;
+
                                        // TODO: This code is buggy: comparing Attribute name without resolving it is wrong.
                                        //       However, this is invoked by CodeGen.Init, at which time none of the namespaces
                                        //       are loaded yet.
index 199dd5c3e45678542a94d547517dd6e4d5883755..1c15f85ecaa87a95376b2a3753923b132a7a94c5 100755 (executable)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
+//   Marek Safar (marek.safar@seznam.cz)
 //
 // (C) 2001 Ximian, Inc.
 //
@@ -49,13 +50,6 @@ namespace Mono.CSharp {
                        ModFlags |= Modifiers.STATIC;
                }
 
-               public FieldAttributes FieldAttr {
-                       get {
-                               return FieldAttributes.Literal | FieldAttributes.Static |
-                                       Modifiers.FieldAttr (ModFlags) ;
-                       }
-               }
-
 #if DEBUG
                void dump_tree (Type t)
                {
@@ -89,7 +83,16 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, FieldAttr);
+                       FieldAttributes field_attr = FieldAttributes.Static | Modifiers.FieldAttr (ModFlags);
+                       // I don't know why but they emit decimal constant as InitOnly
+                       if (ttype == TypeManager.decimal_type) {
+                               field_attr |= FieldAttributes.InitOnly;
+                       }
+                       else {
+                               field_attr |= FieldAttributes.Literal;
+                       }
+
+                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, field_attr);
 
                        TypeManager.RegisterConstant (FieldBuilder, this);
 
@@ -115,6 +118,13 @@ namespace Mono.CSharp {
                                Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
                                return null;
                        }
+
+                       // Special-case: The 0 literal can be converted to an enum value,
+                       // and ImplicitStandardConversionExists will return true in that case.
+                       if (expr.Type == TypeManager.int32_type && TypeManager.IsEnumType (type)){
+                               if (expr is IntLiteral && ((IntLiteral) expr).Value == 0)
+                                       return new EnumConstant (expr, type);
+                       }
                        
                        object constant_value = TypeManager.ChangeType (expr.GetValue (), type, out fail);
                        if (fail){
@@ -155,6 +165,8 @@ namespace Mono.CSharp {
                                retval = new CharConstant ((char) constant_value);
                        else if (type == TypeManager.bool_type)
                                retval = new BoolConstant ((bool) constant_value);
+                       else if (type == TypeManager.decimal_type)
+                               retval = new DecimalConstant ((decimal) constant_value);
                        else
                                throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
                        
@@ -253,7 +265,16 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       FieldBuilder.SetConstant (ConstantValue);
+                       if (ce is DecimalConstant) {
+                               Decimal d = ((DecimalConstant)ce).Value;
+                               int[] bits = Decimal.GetBits (d);
+                               object[] args = new object[] { (byte)(bits [3] >> 16), (byte)(bits [3] >> 31), (uint)bits [2], (uint)bits [1], (uint)bits [0] };
+                               CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.decimal_constant_attribute_ctor, args);
+                               FieldBuilder.SetCustomAttribute (cab);
+                       }
+                       else{
+                               FieldBuilder.SetConstant (ConstantValue);
+                       }
 
                        if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue))
                                throw new Exception ("Cannot register const value");
index 34fdbfb86ce13002edbfb4201f900f9ceab75c5c..73de93f06f273af931fca1d08ccc103eaea55966 100755 (executable)
@@ -116,6 +116,21 @@ namespace Mono.CSharp {
 
                        return c;
                }
+
+               public DecimalConstant ToDecimal (Location loc)
+               {
+                       DecimalConstant c = ConvertToDecimal ();
+
+                       if (c == null)
+                               Convert.Error_CannotConvertType (loc, Type, TypeManager.decimal_type);
+
+                       return c;
+               }
+
+               public virtual DecimalConstant ConvertToDecimal ()
+               {
+                       return null;
+               }
                
                public virtual DoubleConstant ConvertToDouble ()
                {
@@ -640,6 +655,11 @@ namespace Mono.CSharp {
                        return Value;
                }
 
+               public override DecimalConstant ConvertToDecimal()
+               {
+                       return new DecimalConstant (Value);
+               }
+
                public override DoubleConstant ConvertToDouble ()
                {
                        return new DoubleConstant (Value);
@@ -1043,15 +1063,24 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
+                       ILGenerator ig = ec.ig;
+
                        int [] words = Decimal.GetBits (Value);
+                       int power = (words [3] >> 16) & 0xff;
+
+                       if (power == 0 && Value <= int.MaxValue && Value >= int.MinValue)
+                       {
+                               IntConstant.EmitInt (ig, (int)Value);
+                               ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
+                               return;
+                       }
+
                        
                        //
                        // FIXME: we could optimize this, and call a better 
                        // constructor
                        //
 
-                       ILGenerator ig = ec.ig;
-                       
                        IntConstant.EmitInt (ig, words [0]);
                        IntConstant.EmitInt (ig, words [1]);
                        IntConstant.EmitInt (ig, words [2]);
@@ -1060,7 +1089,7 @@ namespace Mono.CSharp {
                        IntConstant.EmitInt (ig, words [3] >> 31);
 
                        // power
-                       IntConstant.EmitInt (ig, (words [3] >> 16) & 0xff);
+                       IntConstant.EmitInt (ig, power);
 
                        ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
                }
index d95cefc32f4bda960092fad117432a5644a454c4..8caac767bdb38f8ad925ff323bfca0d61517f436 100644 (file)
@@ -52,12 +52,16 @@ namespace Mono.CSharp {
 
                static bool TypeParameter_to_Null (Type target_type)
                {
-                       if ((target_type.BaseType == null) ||
-                           (target_type.BaseType == TypeManager.value_type) ||
-                           target_type.BaseType.IsValueType)
+                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (target_type);
+                       if (gc == null)
                                return false;
 
-                       return true;
+                       if (gc.HasReferenceTypeConstraint)
+                               return true;
+                       if (gc.HasClassConstraint && !TypeManager.IsValueType (gc.ClassConstraint))
+                               return true;
+
+                       return false;
                }
 
                static Type TypeParam_EffectiveBaseType (EmitContext ec, Type t)
@@ -164,7 +168,7 @@ namespace Mono.CSharp {
                                if (TypeManager.IsValueType (expr_type))
                                        return new BoxedCast (expr);
                                if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){
-                                       if (target_type == TypeManager.anonymous_method_type)
+                                       if (expr_type == TypeManager.anonymous_method_type)
                                                return null;
                                        return new EmptyCast (expr, target_type);
                                }
@@ -197,7 +201,7 @@ namespace Mono.CSharp {
                        // from the null type to any reference-type.
                        if (expr_type == TypeManager.null_type){
                                if (target_type.IsPointer)
-                                       return NullPointer.Null;
+                                       return new EmptyCast (expr, target_type);
                                        
                                if (!target_type.IsValueType)
                                        return new NullCast (expr, target_type);
@@ -301,6 +305,16 @@ namespace Mono.CSharp {
                                
                        // from any class-type S to any interface-type T.
                        if (target_type.IsInterface) {
+                               if (target_type != TypeManager.iconvertible_type &&
+                                   expr_type.IsValueType && (expr is Constant) &&
+                                   !(expr is IntLiteral || expr is BoolLiteral ||
+                                     expr is FloatLiteral || expr is DoubleLiteral ||
+                                     expr is LongLiteral || expr is CharLiteral ||
+                                     expr is StringLiteral || expr is DecimalLiteral ||
+                                     expr is UIntLiteral || expr is ULongLiteral)) {
+                                       return false;
+                               }
+                               
                                if (TypeManager.ImplementsInterface (expr_type, target_type))
                                        return true;
                        }
@@ -346,8 +360,13 @@ namespace Mono.CSharp {
                                        return true;
                                
                        // from the null type to any reference-type.
-                       if (expr_type == TypeManager.null_type && !target_type.IsValueType && !TypeManager.IsEnumType (target_type))
-                               return true;
+                       if (expr_type == TypeManager.null_type){
+                               if (target_type.IsPointer)
+                                       return true;
+                       
+                               if (!target_type.IsValueType)
+                                       return true;
+                       }
 
                        // from a generic type definition to a generic instance.
                        if (TypeManager.IsEqual (expr_type, target_type))
@@ -1312,7 +1331,7 @@ namespace Mono.CSharp {
                                //
                                // Possibly, we need to create a different 0 literal before passing
                                // to EnumConstant
-                               //n
+                               //
                                if (underlying == TypeManager.int64_type)
                                        e = new LongLiteral (0);
                                else if (underlying == TypeManager.uint64_type)
@@ -1348,10 +1367,15 @@ namespace Mono.CSharp {
                        if (e != null)
                                return e;
 
-                       if (source is DoubleLiteral && target_type == TypeManager.float_type){
-                               Report.Error (664, loc,
-                                             "Double literal cannot be implicitly converted to " +
-                                             "float type, use F suffix to create a float literal");
+                       if (source is DoubleLiteral) {
+                               if (target_type == TypeManager.float_type) {
+                                       Error_664 (loc, "float", "f");
+                                       return null;
+                               }
+                               if (target_type == TypeManager.decimal_type) {
+                                       Error_664 (loc, "decimal", "m");
+                                       return null;
+                               }
                        }
 
                        if (source is Constant){
@@ -1366,6 +1390,12 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               static void Error_664 (Location loc, string type, string suffix) {
+                       Report.Error (664, loc,
+                               "Literal of type double cannot be implicitly converted to type '{0}'. Add suffix '{1}' to create a literal of this type",
+                               type, suffix);
+               }
+
                /// <summary>
                ///   Performs the explicit numeric conversions
                /// </summary>
index 811bb3100f24c35c2a75c31f26c19762d5296b57..a80460d34d3d0b888245621d2e8584cccccaa62d 100755 (executable)
@@ -8,6 +8,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 // TODO:
 //   (1) Figure out why error productions dont work.  `type-declaration' is a
@@ -83,6 +84,14 @@ namespace Mono.CSharp
                /// The current file.
                ///
                SourceFile file;
+
+               ///
+               /// Temporary Xml documentation cache.
+               /// For enum types, we need one more temporary store.
+               ///
+               string tmpComment;
+               string enumTypeComment;
+
                
                
                /// Current attribute target
@@ -290,7 +299,13 @@ compilation_unit
        
 opt_EOF
        : /* empty */
+       {
+               Lexer.check_incorrect_doc_comment ();
+       }
        | EOF
+       {
+               Lexer.check_incorrect_doc_comment ();
+       }
        ;
 
 outer_declarations
@@ -310,7 +325,15 @@ using_directives
 
 using_directive
        : using_alias_directive
+       {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+       }
        | using_namespace_directive
+       {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+       }
        ;
 
 using_alias_directive
@@ -386,6 +409,10 @@ namespace_name
 
 namespace_body
        : OPEN_BRACE
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_using_directives
          opt_namespace_member_declarations
          CLOSE_BRACE
@@ -502,6 +529,13 @@ attribute_sections
                        } else {
                                $$ = new Attributes (sect);
                        }
+                       if ($$ == null) {
+                               if (RootContext.Documentation != null) {
+                                       Lexer.check_incorrect_doc_comment ();
+                                       Lexer.doc_state =
+                                               XmlCommentState.Allowed;
+                               }
+                       }
                } else {
                        $$ = new Attributes (sect);
                }               
@@ -769,9 +803,16 @@ struct_declaration
 
                current_class.SetParameterInfo ((ArrayList) $8);
 
+               if (RootContext.Documentation != null)
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+
                current_class.Register ();
          }
          struct_body
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_semicolon
          {
                $$ = current_class;
@@ -785,7 +826,12 @@ struct_declaration
        ;
 
 struct_body
-       : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE
+       : OPEN_BRACE
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_struct_member_declarations CLOSE_BRACE
        ;
 
 opt_struct_member_declarations
@@ -837,6 +883,10 @@ constant_declaration
                                (Expression) constant.expression_or_array_initializer, modflags, 
                                (Attributes) $1, l);
 
+                       if (RootContext.Documentation != null) {
+                               c.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
                        current_container.AddConstant (c);
                }
          }
@@ -889,6 +939,10 @@ field_declaration
                                                 var.expression_or_array_initializer, 
                                                 (Attributes) $1, l);
 
+                       if (RootContext.Documentation != null) {
+                               field.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
                        current_container.AddField (field);
                }
          }
@@ -950,6 +1004,8 @@ variable_initializer
 method_declaration
        : method_header {
                iterator_container = (IIteratorContainer) $1;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
          }
          method_body
          {
@@ -976,6 +1032,9 @@ method_declaration
 
                current_local_parameters = null;
                iterator_container = null;
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
@@ -1031,6 +1090,9 @@ method_header
 
                current_local_parameters = (Parameters) $6;
 
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        | opt_attributes
@@ -1064,6 +1126,10 @@ method_header
                                     lexer.Location);
 
                current_local_parameters = (Parameters) $6;
+
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        | opt_attributes
@@ -1081,6 +1147,10 @@ method_header
                                            lexer.Location);
 
                current_local_parameters = (Parameters) $6;
+
+               if (RootContext.Documentation != null)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
                $$ = method;
          }
        ;
@@ -1214,7 +1284,12 @@ parameter_array
 property_declaration
        : opt_attributes
          opt_modifiers
-         type namespace_or_type_name
+         type
+         namespace_or_type_name
+         {
+               if (RootContext.Documentation != null)
+                       tmpComment = Lexer.consume_doc_comment ();
+         }
          OPEN_BRACE 
          {
                implicit_value_parameter_type = (Expression) $3;
@@ -1232,11 +1307,11 @@ property_declaration
          CLOSE_BRACE
          { 
                Property prop;
-               Pair pair = (Pair) $7;
+               Pair pair = (Pair) $8;
                Accessor get_block = (Accessor) pair.First;
                Accessor set_block = (Accessor) pair.Second;
 
-               Location loc = (Location) $6;
+               Location loc = (Location) $7;
                MemberName name = (MemberName) $4;
 
                if (name.TypeArguments != null)
@@ -1250,6 +1325,10 @@ property_declaration
                current_container.AddProperty (prop);
                implicit_value_parameter_type = null;
                iterator_container = null;
+
+               if (RootContext.Documentation != null)
+                       prop.DocComment = ConsumeStoredComment ();
+
          }
        ;
 
@@ -1290,6 +1369,10 @@ get_accessor_declaration
                $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
                current_local_parameters = null;
                lexer.PropertyParsing = true;
+
+               if (RootContext.Documentation != null)
+                       if (Lexer.doc_state == XmlCommentState.Error)
+                               Lexer.doc_state = XmlCommentState.NotAllowed;
          }
        ;
 
@@ -1327,6 +1410,10 @@ set_accessor_declaration
                $$ = new Accessor ((ToplevelBlock) $5, (int) $2, (Attributes) $1, lexer.Location);
                current_local_parameters = null;
                lexer.PropertyParsing = true;
+
+               if (RootContext.Documentation != null
+                       && Lexer.doc_state == XmlCommentState.Error)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
          }
        ;
 
@@ -1372,10 +1459,20 @@ interface_declaration
 
                current_class.SetParameterInfo ((ArrayList) $8);
 
+               if (RootContext.Documentation != null) {
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                current_class.Register ();
          }
          interface_body opt_semicolon
          { 
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_semicolon 
+         {
                $$ = current_class;
 
                current_container = current_container.Parent;
@@ -1408,25 +1505,37 @@ interface_member_declaration
                Method m = (Method) $1;
 
                current_container.AddMethod (m);
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        | interface_property_declaration        
          { 
                Property p = (Property) $1;
 
                current_container.AddProperty (p);
-          }
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
        | interface_event_declaration 
           { 
                if ($1 != null){
                        Event e = (Event) $1;
                        current_container.AddEvent (e);
                }
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        | interface_indexer_declaration
          { 
                Indexer i = (Indexer) $1;
 
                current_container.AddIndexer (i);
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
@@ -1466,6 +1575,8 @@ interface_method_declaration
 
                $$ = new Method (current_class, generic, (Expression) $3, (int) $2, true, name,
                                 (Parameters) $6, (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Method) $$).DocComment = Lexer.consume_doc_comment ();
          }
        | opt_attributes opt_new VOID namespace_or_type_name
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
@@ -1493,6 +1604,8 @@ interface_method_declaration
 
                $$ = new Method (current_class, generic, TypeManager.system_void_expr, (int) $2,
                                 true, name, (Parameters) $6, (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Method) $$).DocComment = Lexer.consume_doc_comment ();
          }
        ;
 
@@ -1511,6 +1624,8 @@ interface_property_declaration
                $$ = new Property (current_class, (Expression) $3, (int) $2, true,
                                   new MemberName ((string) $4), (Attributes) $1,
                                   pinfo.Get, pinfo.Set, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Property) $$).DocComment = Lexer.consume_doc_comment ();
          }
        | opt_attributes
          opt_new
@@ -1521,12 +1636,14 @@ interface_property_declaration
        ;
 
 interface_accessors
-       : opt_attributes GET SEMICOLON          { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, lexer.Location, lexer.Location); }
-       | opt_attributes SET SEMICOLON          { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, lexer.Location, lexer.Location); }
-       | opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON 
-         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3, lexer.Location, lexer.Location); }
-       | opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
-         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1, lexer.Location, lexer.Location); }
+       : opt_attributes opt_modifiers GET SEMICOLON    
+       { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null, (int) $2, 0, lexer.Location, lexer.Location); }
+       | opt_attributes opt_modifiers SET SEMICOLON            
+       { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1, 0, (int) $2, lexer.Location, lexer.Location); }
+       | opt_attributes opt_modifiers GET SEMICOLON opt_attributes opt_modifiers SET SEMICOLON 
+         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $5, (int) $2, (int) $6, lexer.Location, lexer.Location); }
+       | opt_attributes opt_modifiers SET SEMICOLON opt_attributes opt_modifiers GET SEMICOLON
+         { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $5, (Attributes) $1, (int) $6, (int) $2, lexer.Location, lexer.Location); }
        ;
 
 interface_event_declaration
@@ -1535,6 +1652,8 @@ interface_event_declaration
                $$ = new EventField (current_class, (Expression) $4, (int) $2, true,
                                     new MemberName ((string) $5), null,
                                     (Attributes) $1, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((EventField) $$).DocComment = Lexer.consume_doc_comment ();
          }
        | opt_attributes opt_new EVENT type error {
                CheckIdentifierToken (yyToken);
@@ -1565,6 +1684,8 @@ interface_indexer_declaration
                                  new MemberName (TypeContainer.DefaultIndexerName),
                                  (int) $2, true, (Parameters) $6, (Attributes) $1,
                                  info.Get, info.Set, lexer.Location);
+               if (RootContext.Documentation != null)
+                       ((Indexer) $$).DocComment = ConsumeStoredComment ();
          }
        ;
 
@@ -1588,6 +1709,9 @@ operator_declaration
                        new Parameters (param_list, null, decl.location),
                        (ToplevelBlock) $5, (Attributes) $1, decl.location);
 
+               if (RootContext.Documentation != null)
+                       op.DocComment = ConsumeStoredComment ();
+
                if (SimpleIteratorContainer.Simple.Yields)
                        op.SetYields ();
 
@@ -1617,12 +1741,18 @@ operator_declarator
                        op = Operator.OpType.UnaryNegation;
 
                Parameter [] pars = new Parameter [1];
+               Expression type = (Expression) $5;
 
-               pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
+               pars [0] = new Parameter (type, (string) $6, Parameter.Modifier.NONE, null);
 
                current_local_parameters = new Parameters (pars, null, lexer.Location);
 
-               $$ = new OperatorDeclaration (op, (Expression) $1, (Expression) $5, (string) $6,
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
+               $$ = new OperatorDeclaration (op, (Expression) $1, type, (string) $6,
                                              null, null, lexer.Location);
        }
        | type OPERATOR overloadable_operator
@@ -1631,18 +1761,26 @@ operator_declarator
                type IDENTIFIER 
          CLOSE_PARENS
         {
-              CheckBinaryOperator ((Operator.OpType) $3);
+               CheckBinaryOperator ((Operator.OpType) $3);
+
+               Parameter [] pars = new Parameter [2];
 
-              Parameter [] pars = new Parameter [2];
+               Expression typeL = (Expression) $5;
+               Expression typeR = (Expression) $8;
 
-              pars [0] = new Parameter ((Expression) $5, (string) $6, Parameter.Modifier.NONE, null);
-              pars [1] = new Parameter ((Expression) $8, (string) $9, Parameter.Modifier.NONE, null);
+              pars [0] = new Parameter (typeL, (string) $6, Parameter.Modifier.NONE, null);
+              pars [1] = new Parameter (typeR, (string) $9, Parameter.Modifier.NONE, null);
 
               current_local_parameters = new Parameters (pars, null, lexer.Location);
+
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
               
               $$ = new OperatorDeclaration ((Operator.OpType) $3, (Expression) $1, 
-                                            (Expression) $5, (string) $6,
-                                            (Expression) $8, (string) $9, lexer.Location);
+                                            typeL, (string) $6,
+                                            typeR, (string) $9, lexer.Location);
         }
        | conversion_operator_declarator
        ;
@@ -1719,6 +1857,9 @@ constructor_declaration
                c.OptAttributes = (Attributes) $1;
                c.ModFlags = (int) $2;
        
+               if (RootContext.Documentation != null)
+                       c.DocComment = ConsumeStoredComment ();
+
                if (c.Name == current_container.Basename){
                        if ((c.ModFlags & Modifiers.STATIC) != 0){
                                if ((c.ModFlags & Modifiers.Accessibility) != 0){
@@ -1752,22 +1893,30 @@ constructor_declaration
                current_container.AddConstructor (c);
 
                current_local_parameters = null;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
 constructor_declarator
-       : IDENTIFIER 
+       : IDENTIFIER
+         {
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+         }
          OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS 
          {
                oob_stack.Push (lexer.Location);
 
-               current_local_parameters = (Parameters) $3;
+               current_local_parameters = (Parameters) $4;
          }
          opt_constructor_initializer
          {
                Location l = (Location) oob_stack.Pop ();
-               $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $3,
-                                     (ConstructorInitializer) $6, l);
+               $$ = new Constructor (current_class, (string) $1, 0, (Parameters) $4,
+                                     (ConstructorInitializer) $7, l);
          }
        ;
 
@@ -1803,9 +1952,16 @@ opt_finalizer
         ;
         
 destructor_declaration
-       : opt_attributes opt_finalizer TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
+       : opt_attributes opt_finalizer TILDE 
+         {
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+         }
+         IDENTIFIER OPEN_PARENS CLOSE_PARENS block
          {
-               if ((string) $4 != current_container.Basename){
+               if ((string) $5 != current_container.Basename){
                        Report.Error (574, lexer.Location, "Name of destructor must match name of class");
                } else if (!(current_container is Class)){
                        Report.Error (575, lexer.Location, "Destructors are only allowed in class types");
@@ -1829,8 +1985,10 @@ destructor_declaration
                        Method d = new Destructor (
                                current_class, TypeManager.system_void_expr, m, "Finalize", 
                                new Parameters (null, null, l), (Attributes) $1, l);
+                       if (RootContext.Documentation != null)
+                               d.DocComment = ConsumeStoredComment ();
                  
-                       d.Block = (ToplevelBlock) $7;
+                       d.Block = (ToplevelBlock) $8;
                        current_container.AddMethod (d);
                }
          }
@@ -1851,7 +2009,11 @@ event_declaration
                                lexer.Location);
 
                        current_container.AddEvent (e);
-                                      
+
+                       if (RootContext.Documentation != null) {
+                               e.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
                }
          }
        | opt_attributes
@@ -1886,7 +2048,11 @@ event_declaration
                                current_class, (Expression) $4, (int) $2, false, name, null,
                                (Attributes) $1, (Accessor) pair.First, (Accessor) pair.Second,
                                loc);
-                       
+                       if (RootContext.Documentation != null) {
+                               e.DocComment = Lexer.consume_doc_comment ();
+                               Lexer.doc_state = XmlCommentState.Allowed;
+                       }
+
                        current_container.AddEvent (e);
                        implicit_value_parameter_type = null;
                }
@@ -1898,6 +2064,9 @@ event_declaration
                        Report.Error (71, lexer.Location, "Explicit implementation of events requires property syntax");
                else 
                        Report.Error (71, lexer.Location, "Event declaration should use property syntax");
+
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
          }
        ;
 
@@ -2008,6 +2177,8 @@ indexer_declaration
                indexer = new Indexer (current_class, decl.type, name,
                                       (int) $2, false, decl.param_list, (Attributes) $1,
                                       get_block, set_block, loc);
+               if (RootContext.Documentation != null)
+                       indexer.DocComment = ConsumeStoredComment ();
 
                current_container.AddIndexer (indexer);
                
@@ -2027,6 +2198,10 @@ indexer_declarator
                } else if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
 
                $$ = new IndexerDeclaration ((Expression) $1, null, pars);
          }
@@ -2040,11 +2215,17 @@ indexer_declarator
                } else if (pars.FixedParameters == null && pars.ArrayParameter == null){
                        Report.Error (1551, lexer.Location, "Indexers must have at least one parameter");
                }
+
                MemberName name = (MemberName) $2;
                if (name.TypeArguments != null)
                        syntax_error (lexer.Location, "an indexer can't have type arguments");
 
                $$ = new IndexerDeclaration ((Expression) $1, name, pars);
+
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
          }
        ;
 
@@ -2052,7 +2233,10 @@ enum_declaration
        : opt_attributes
          opt_modifiers
          ENUM IDENTIFIER 
-         opt_enum_base
+         opt_enum_base {
+               if (RootContext.Documentation != null)
+                       enumTypeComment = Lexer.consume_doc_comment ();
+         }
          enum_body
          opt_semicolon
          { 
@@ -2062,10 +2246,14 @@ enum_declaration
                Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
                                   full_name, (Attributes) $1, enum_location);
                
-               foreach (VariableDeclaration ev in (ArrayList) $6) {
+               if (RootContext.Documentation != null)
+                       e.DocComment = enumTypeComment;
+
+               foreach (VariableDeclaration ev in (ArrayList) $7) {
                        e.AddEnumMember (ev.identifier, 
                                         (Expression) ev.expression_or_array_initializer,
-                                        ev.Location, ev.OptAttributes);
+                                        ev.Location, ev.OptAttributes,
+                                        ev.DocComment);
                }
 
                string name = full_name.GetName ();
@@ -2081,9 +2269,20 @@ opt_enum_base
        ;
 
 enum_body
-       : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE
+       : OPEN_BRACE
          {
-               $$ = $2;
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_enum_member_declarations
+         {
+               // here will be evaluated after CLOSE_BLACE is consumed.
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         CLOSE_BRACE
+         {
+               $$ = $3;
          }
        ;
 
@@ -2113,15 +2312,31 @@ enum_member_declarations
 enum_member_declaration
        : opt_attributes IDENTIFIER 
          {
-               $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+               VariableDeclaration vd = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+
+               if (RootContext.Documentation != null) {
+                       vd.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
+               $$ = vd;
          }
        | opt_attributes IDENTIFIER
          {
-                 $$ = lexer.Location;
+               $$ = lexer.Location;
+               if (RootContext.Documentation != null) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
          }
           ASSIGN expression
          { 
-               $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
+               VariableDeclaration vd = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
+
+               if (RootContext.Documentation != null)
+                       vd.DocComment = ConsumeStoredComment ();
+
+               $$ = vd;
          }
        ;
 
@@ -2136,6 +2351,11 @@ delegate_declaration
                Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
                                             (int) $2, name, (Parameters) $7, (Attributes) $1, l);
 
+               if (RootContext.Documentation != null) {
+                       del.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                current_container.AddDelegate (del);
                RootContext.Tree.RecordDecl (name.GetName (true), del);
 
@@ -2165,6 +2385,11 @@ delegate_declaration
                        TypeManager.system_void_expr, (int) $2, name,
                        (Parameters) $7, (Attributes) $1, l);
 
+               if (RootContext.Documentation != null) {
+                       del.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                current_container.AddDelegate (del);
                RootContext.Tree.RecordDecl (name.GetName (true), del);
 
@@ -3229,9 +3454,18 @@ class_declaration
 
                current_class.SetParameterInfo ((ArrayList) $8);
 
+               if (RootContext.Documentation != null) {
+                       current_class.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
                current_class.Register ();
          }
-         class_body 
+         class_body
+         {
+               if (RootContext.Documentation != null)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
          opt_semicolon 
          {
                $$ = current_class;
@@ -4360,6 +4594,7 @@ public class VariableDeclaration {
        public object expression_or_array_initializer;
        public Location Location;
        public Attributes OptAttributes;
+       public string DocComment;
 
        public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs)
        {
@@ -4382,13 +4617,19 @@ public class InterfaceAccessorInfo {
         public readonly Accessor Get, Set;
 
         public InterfaceAccessorInfo (bool has_get, bool has_set,
-                                      Attributes get_attrs, Attributes set_attrs, Location get_loc, Location set_loc)
+                                      Attributes get_attrs, Attributes set_attrs, int get_mod, int set_mod, Location get_loc, Location set_loc)
         {
+               if (get_mod != 0)
+                       Report.Error (275, get_loc, "Accessibility modifiers can not be used on accessors in interfaces");
+               if (set_mod != 0)
+                       Report.Error (275, set_loc, "Accessibility modifiers can not be used on accessors in interfaces");
+                       
                if (has_get)
                        Get = new Accessor (null, 0, get_attrs, get_loc);
                if (has_set)
                        Set = new Accessor (null, 0, set_attrs, set_loc);
         }
+
 }
 
 
@@ -4698,5 +4939,13 @@ void CheckIdentifierToken (int yyToken)
        CheckToken (1041, yyToken, "Identifier expected");
 }
 
+string ConsumeStoredComment ()
+{
+       string s = tmpComment;
+       tmpComment = null;
+       Lexer.doc_state = XmlCommentState.Allowed;
+       return s;
+}
+
 /* end end end */
 }
index 3785eb09bf2dc42a36ef48e07198457434f63940..f147ec537637dc3a251f6ce415373ce8a7b592b5 100755 (executable)
@@ -7,6 +7,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 
 /*
@@ -43,6 +44,17 @@ namespace Mono.CSharp
                bool handle_constraints = false;
                bool handle_typeof = false;
 
+               //
+               // XML documentation buffer. The save point is used to divide
+               // comments on types and comments on members.
+               //
+               StringBuilder xml_comment_buffer;
+
+               //
+               // See comment on XmlCommentState enumeration.
+               //
+               XmlCommentState xmlDocState = XmlCommentState.Allowed;
+
                //
                // Whether tokens have been seen on this line
                //
@@ -154,7 +166,18 @@ namespace Mono.CSharp
                                handle_typeof = value;
                        }
                }
-               
+
+               public XmlCommentState doc_state {
+                       get { return xmlDocState; }
+                       set {
+                               if (value == XmlCommentState.Allowed) {
+                                       check_incorrect_doc_comment ();
+                                       consume_doc_comment ();
+                               }
+                               xmlDocState = value;
+                       }
+               }
+
                //
                // Class variables
                // 
@@ -387,6 +410,8 @@ namespace Mono.CSharp
                                        define (def);
                        }
 
+                       xml_comment_buffer = new StringBuilder ();
+
                        //
                        // FIXME: This could be `Location.Push' but we have to
                        // find out why the MS compiler allows this
@@ -506,6 +531,9 @@ namespace Mono.CSharp
                        case '}':
                                return Token.CLOSE_BRACE;
                        case '[':
+                               // To block doccomment inside attribute declaration.
+                               if (doc_state == XmlCommentState.Allowed)
+                                       doc_state = XmlCommentState.NotAllowed;
                                return Token.OPEN_BRACKET;
                        case ']':
                                return Token.CLOSE_BRACKET;
@@ -1879,6 +1907,15 @@ namespace Mono.CSharp
                {
                        int res = consume_identifier (s, false);
 
+                       if (doc_state == XmlCommentState.Allowed)
+                               doc_state = XmlCommentState.NotAllowed;
+                       switch (res) {
+                       case Token.USING:
+                       case Token.NAMESPACE:
+                               check_incorrect_doc_comment ();
+                               break;
+                       }
+
                        if (res == Token.PARTIAL) {
                                // Save current position and parse next token.
                                int old = reader.Position;
@@ -2000,6 +2037,17 @@ namespace Mono.CSharp
                                
                                        if (d == '/'){
                                                getChar ();
+                                               if (RootContext.Documentation != null && peekChar () == '/') {
+                                                       getChar ();
+                                                       // Allow only ///ws.
+                                                       // Don't allow ////.
+                                                       if ((d = peekChar ()) == ' ' || d == '\t') {
+                                                               if (doc_state == XmlCommentState.Allowed)
+                                                                       handle_one_line_xml_comment ();
+                                                               else if (doc_state == XmlCommentState.NotAllowed)
+                                                                       warn_incorrect_doc_comment ();
+                                                       }
+                                               }
                                                while ((d = getChar ()) != -1 && (d != '\n') && d != '\r')
                                                        col++;
                                                if (d == '\n'){
@@ -2012,6 +2060,25 @@ namespace Mono.CSharp
                                                continue;
                                        } else if (d == '*'){
                                                getChar ();
+                                               bool docAppend = false;
+                                               if (RootContext.Documentation != null && peekChar () == '*') {
+                                                       getChar ();
+                                                       // But when it is /**/, just do nothing.
+                                                       if (peekChar () == '/') {
+                                                               getChar ();
+                                                               continue;
+                                                       }
+                                                       if (doc_state == XmlCommentState.Allowed)
+                                                               docAppend = true;
+                                                       else if (doc_state == XmlCommentState.NotAllowed)
+                                                               warn_incorrect_doc_comment ();
+                                               }
+
+                                               int currentCommentStart = 0;
+                                               if (docAppend) {
+                                                       currentCommentStart = xml_comment_buffer.Length;
+                                                       xml_comment_buffer.Append (Environment.NewLine);
+                                               }
 
                                                while ((d = getChar ()) != -1){
                                                        if (d == '*' && peekChar () == '/'){
@@ -2019,6 +2086,9 @@ namespace Mono.CSharp
                                                                col++;
                                                                break;
                                                        }
+                                                       if (docAppend)
+                                                               xml_comment_buffer.Append ((char) d);
+                                                       
                                                        if (d == '\n'){
                                                                line++;
                                                                ref_line++;
@@ -2027,6 +2097,8 @@ namespace Mono.CSharp
                                                                tokens_seen = false;
                                                        }
                                                }
+                                               if (docAppend)
+                                                       update_formatted_doc_comment (currentCommentStart);
                                                continue;
                                        }
                                        goto is_punct_label;
@@ -2190,6 +2262,91 @@ namespace Mono.CSharp
                        return Token.ERROR;
                }
 
+               //
+               // Handles one line xml comment
+               //
+               private void handle_one_line_xml_comment ()
+               {
+                       int c;
+                       while ((c = peekChar ()) == ' ')
+                               getChar (); // skip heading whitespaces.
+                       while ((c = peekChar ()) != -1 && c != '\n' && c != '\r') {
+                               col++;
+                               xml_comment_buffer.Append ((char) getChar ());
+                       }
+                       if (c == '\r' || c == '\n')
+                               xml_comment_buffer.Append (Environment.NewLine);
+               }
+
+               //
+               // Remove heading "*" in Javadoc-like xml documentation.
+               //
+               private void update_formatted_doc_comment (int currentCommentStart)
+               {
+                       int length = xml_comment_buffer.Length - currentCommentStart;
+                       string [] lines = xml_comment_buffer.ToString (
+                               currentCommentStart,
+                               length).Replace ("\r", "").Split ('\n');
+                       // The first line starts with /**, thus it is not target
+                       // for the format check.
+                       for (int i = 1; i < lines.Length; i++) {
+                               string s = lines [i];
+                               int idx = s.IndexOf ('*');
+                               string head = null;
+                               if (idx < 0) {
+                                       if (i < lines.Length - 1)
+                                               return;
+                                       head = s;
+                               }
+                               else
+                                       head = s.Substring (0, idx);
+                               foreach (char c in head)
+                                       if (c != ' ')
+                                               return;
+                               lines [i] = s.Substring (idx + 1);
+                       }
+                       xml_comment_buffer.Remove (currentCommentStart, length);
+                       xml_comment_buffer.Insert (
+                               currentCommentStart,
+                               String.Join (Environment.NewLine, lines));
+               }
+
+               //
+               // Checks if there was incorrect doc comments and raise
+               // warnings.
+               //
+               public void check_incorrect_doc_comment ()
+               {
+                       if (xml_comment_buffer.Length > 0)
+                               warn_incorrect_doc_comment ();
+               }
+
+               //
+               // Raises a warning when tokenizer found incorrect doccomment
+               // markup.
+               //
+               private void warn_incorrect_doc_comment ()
+               {
+                       doc_state = XmlCommentState.Error;
+                       // in csc, it is 'XML comment is not placed on a valid 
+                       // language element'. But that does not make sense.
+                       Report.Warning (1587, 2, Location, "XML comment is placed on an invalid language element which can not accept it.");
+               }
+
+               //
+               // Consumes the saved xml comment lines (if any)
+               // as for current target member or type.
+               //
+               public string consume_doc_comment ()
+               {
+                       if (xml_comment_buffer.Length > 0) {
+                               string ret = xml_comment_buffer.ToString ();
+                               xml_comment_buffer.Length = 0;
+                               return ret;
+                       }
+                       return null;
+               }
+
                public void cleanup ()
                {
                        if (ifstack != null && ifstack.Count >= 1) {
@@ -2202,5 +2359,19 @@ namespace Mono.CSharp
                                
                }
        }
+
+       //
+       // Indicates whether it accepts XML documentation or not.
+       //
+       public enum XmlCommentState {
+               // comment is allowed in this state.
+               Allowed,
+               // comment is not allowed in this state.
+               NotAllowed,
+               // once comments appeared when it is NotAllowed, then the
+               // state is changed to it, until the state is changed to
+               // .Allowed.
+               Error
+       }
 }
 
index 6c727a79a0a9cc261392cda1655fe66fe9a334b4..f3ac24f95594b18fcded3a291f91e515f83e7bb7 100755 (executable)
@@ -7,6 +7,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 // TODO: Move the method verification stuff from the class.cs and interface.cs here
 //
@@ -17,6 +18,7 @@ using System.Collections;
 using System.Globalization;
 using System.Reflection.Emit;
 using System.Reflection;
+using System.Xml;
 
 namespace Mono.CSharp {
 
@@ -211,6 +213,7 @@ namespace Mono.CSharp {
                        }
                }
 
+                // Is not readonly because of IndexerName attribute
                public MemberName MemberName;
 
                /// <summary>
@@ -225,6 +228,17 @@ namespace Mono.CSharp {
                /// </summary>
                public readonly Location Location;
 
+               /// <summary>
+               ///   XML documentation comment
+               /// </summary>
+               public string DocComment;
+
+               /// <summary>
+               ///   Represents header string for documentation comment 
+               ///   for each member types.
+               /// </summary>
+               public abstract string DocCommentHeader { get; }
+
                [Flags]
                public enum Flags {
                        Obsolete_Undetected = 1,                // Obsolete attribute has not been detected yet
@@ -374,7 +388,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns true when MemberCore is exposed from assembly.
                /// </summary>
-               protected bool IsExposedFromAssembly (DeclSpace ds)
+               public bool IsExposedFromAssembly (DeclSpace ds)
                {
                        if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
                                return false;
@@ -394,7 +408,8 @@ namespace Mono.CSharp {
                bool GetClsCompliantAttributeValue (DeclSpace ds)
                {
                        if (OptAttributes != null) {
-                               Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ds.EmitContext);
+                               Attribute cls_attribute = OptAttributes.Search (
+                                       TypeManager.cls_compliant_attribute_type, ds.EmitContext);
                                if (cls_attribute != null) {
                                        caching_flags |= Flags.HasClsCompliantAttribute;
                                        return cls_attribute.GetClsCompliantAttributeValue (ds);
@@ -443,6 +458,34 @@ namespace Mono.CSharp {
 
                protected abstract void VerifyObsoleteAttribute ();
 
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               internal virtual void OnGenerateDocComment (DeclSpace ds, XmlElement intermediateNode)
+               {
+               }
+
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public virtual string GetDocCommentName (DeclSpace ds)
+               {
+                       if (ds == null || this is DeclSpace)
+                               return DocCommentHeader + Name;
+                       else
+                               return String.Concat (DocCommentHeader, ds.Name, ".", Name);
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal virtual void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateDocComment (this, ds);
+               }
        }
 
        /// <summary>
@@ -1177,7 +1220,7 @@ namespace Mono.CSharp {
                        caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
 
                        if (OptAttributes != null) {
-                               Attribute cls_attribute = OptAttributes.GetClsCompliantAttribute (ec);
+                               Attribute cls_attribute = OptAttributes.Search (TypeManager.cls_compliant_attribute_type, ec);
                                if (cls_attribute != null) {
                                        caching_flags |= Flags.HasClsCompliantAttribute;
                                        if (cls_attribute.GetClsCompliantAttributeValue (this)) {
@@ -1672,7 +1715,7 @@ namespace Mono.CSharp {
                        IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
                        while (it.MoveNext ()) {
                                hash [it.Key] = ((ArrayList) it.Value).Clone ();
-                        }
+                        }
                                 
                        return hash;
                }
index 36a5b481e5fb4b4edd9ef0d95c9ba55beb0ec26d..bdd1e7366590dd0bbccc8bbd894ac4a84ca71140 100644 (file)
@@ -684,6 +684,13 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
+
                protected override void VerifyObsoleteAttribute()
                {
                        CheckUsageOfObsoleteAttribute (ret_type);
@@ -887,6 +894,9 @@ namespace Mono.CSharp {
                        
                        Expression e = a.Expr;
 
+                       if (e is AnonymousMethod)
+                               return ((AnonymousMethod) e).Compatible (ec, type, false);
+
                        MethodGroupExpr mg = e as MethodGroupExpr;
                        if (mg != null)
                                return ResolveMethodGroupExpr (ec, mg);
diff --git a/mcs/gmcs/doc.cs b/mcs/gmcs/doc.cs
new file mode 100755 (executable)
index 0000000..c33e0e1
--- /dev/null
@@ -0,0 +1,809 @@
+//
+// doc.cs: Support for XML documentation comment.
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2004 Novell, Inc.
+//
+//
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Text;
+using System.Xml;
+
+using Mono.CompilerServices.SymbolWriter;
+
+namespace Mono.CSharp {
+
+       //
+       // Support class for XML documentation.
+       //
+       public class DocUtil
+       {
+               // TypeContainer
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal static void GenerateTypeDocComment (TypeContainer t,
+                       DeclSpace ds)
+               {
+                       GenerateDocComment (t, ds);
+
+                       if (t.DefaultStaticConstructor != null)
+                               t.DefaultStaticConstructor.GenerateDocComment (t);
+
+                       if (t.InstanceConstructors != null)
+                               foreach (Constructor c in t.InstanceConstructors)
+                                       c.GenerateDocComment (t);
+
+                       if (t.Types != null)
+                               foreach (TypeContainer tc in t.Types)
+                                       tc.GenerateDocComment (t);
+
+                       if (t.Parts != null) {
+                               IDictionary comments = RootContext.Documentation.PartialComments;
+                               foreach (ClassPart cp in t.Parts) {
+                                       if (cp.DocComment == null)
+                                               continue;
+                                       comments [cp] = cp;
+                               }
+                       }
+
+                       if (t.Enums != null)
+                               foreach (Enum en in t.Enums)
+                                       en.GenerateDocComment (t);
+
+                       if (t.Constants != null)
+                               foreach (Const c in t.Constants)
+                                       c.GenerateDocComment (t);
+
+                       if (t.Fields != null)
+                               foreach (Field f in t.Fields)
+                                       f.GenerateDocComment (t);
+
+                       if (t.Events != null)
+                               foreach (Event e in t.Events)
+                                       e.GenerateDocComment (t);
+
+                       if (t.Indexers != null)
+                               foreach (Indexer ix in t.Indexers)
+                                       ix.GenerateDocComment (t);
+
+                       if (t.Properties != null)
+                               foreach (Property p in t.Properties)
+                                       p.GenerateDocComment (t);
+
+                       if (t.Methods != null)
+                               foreach (Method m in t.Methods)
+                                       m.GenerateDocComment (t);
+
+                       if (t.Operators != null)
+                               foreach (Operator o in t.Operators)
+                                       o.GenerateDocComment (t);
+               }
+
+               // MemberCore
+               private static readonly string lineHead =
+                       Environment.NewLine + "            ";
+
+               private static XmlNode GetDocCommentNode (MemberCore mc,
+                       string name)
+               {
+                       // FIXME: It could be even optimizable as not
+                       // to use XmlDocument. But anyways the nodes
+                       // are not kept in memory.
+                       XmlDocument doc = RootContext.Documentation.XmlDocumentation;
+                       try {
+                               XmlElement el = doc.CreateElement ("member");
+                               el.SetAttribute ("name", name);
+                               string normalized = mc.DocComment;
+                               el.InnerXml = normalized;
+                               // csc keeps lines as written in the sources
+                               // and inserts formatting indentation (which 
+                               // is different from XmlTextWriter.Formatting
+                               // one), but when a start tag contains an 
+                               // endline, it joins the next line. We don't
+                               // have to follow such a hacky behavior.
+                               string [] split =
+                                       normalized.Split ('\n');
+                               int j = 0;
+                               for (int i = 0; i < split.Length; i++) {
+                                       string s = split [i].TrimEnd ();
+                                       if (s.Length > 0)
+                                               split [j++] = s;
+                               }
+                               el.InnerXml = lineHead + String.Join (
+                                       lineHead, split, 0, j);
+                               return el;
+                       } catch (XmlException ex) {
+                               Report.Warning (1570, 1, mc.Location, "XML comment on '{0}' has non-well-formed XML ({1}).", name, ex.Message);
+                               XmlComment com = doc.CreateComment (String.Format ("FIXME: Invalid documentation markup was found for member {0}", name));
+                               return com;
+                       }
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal static void GenerateDocComment (MemberCore mc,
+                       DeclSpace ds)
+               {
+                       if (mc.DocComment != null) {
+                               string name = mc.GetDocCommentName (ds);
+
+                               XmlNode n = GetDocCommentNode (mc, name);
+
+                               XmlElement el = n as XmlElement;
+                               if (el != null) {
+                                       mc.OnGenerateDocComment (ds, el);
+
+                                       // FIXME: it could be done with XmlReader
+                                       foreach (XmlElement inc in n.SelectNodes (".//include"))
+                                               HandleInclude (mc, inc);
+
+                                       // FIXME: it could be done with XmlReader
+                                       DeclSpace dsTarget = mc as DeclSpace;
+                                       if (dsTarget == null)
+                                               dsTarget = ds;
+
+                                       foreach (XmlElement see in n.SelectNodes (".//see"))
+                                               HandleSee (mc, dsTarget, see);
+                                       foreach (XmlElement seealso in n.SelectNodes (".//seealso"))
+                                               HandleSeeAlso (mc, dsTarget, seealso);
+                                       foreach (XmlElement see in n.SelectNodes (".//exception"))
+                                               HandleException (mc, dsTarget, see);
+                               }
+
+                               n.WriteTo (RootContext.Documentation.XmlCommentOutput);
+                       }
+                       else if (mc.IsExposedFromAssembly (ds) &&
+                               // There are no warnings when the container also
+                               // misses documentations.
+                               (ds == null || ds.DocComment != null))
+                       {
+                               Report.Warning (1591, 4, mc.Location,
+                                       "Missing XML comment for publicly visible type or member '{0}'", mc.GetSignatureForError ());
+                       }
+               }
+
+               //
+               // Processes "include" element. Check included file and
+               // embed the document content inside this documentation node.
+               //
+               private static void HandleInclude (MemberCore mc, XmlElement el)
+               {
+                       string file = el.GetAttribute ("file");
+                       string path = el.GetAttribute ("path");
+                       if (file == "") {
+                               Report.Warning (1590, 1, mc.Location, "Invalid XML 'include' element; Missing 'file' attribute.");
+                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);
+                       }
+                       else if (path == "") {
+                               Report.Warning (1590, 1, mc.Location, "Invalid XML 'include' element; Missing 'path' attribute.");
+                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);
+                       }
+                       else {
+                               XmlDocument doc = RootContext.Documentation.StoredDocuments [file] as XmlDocument;
+                               if (doc == null) {
+                                       try {
+                                               doc = new XmlDocument ();
+                                               doc.Load (file);
+                                               RootContext.Documentation.StoredDocuments.Add (file, doc);
+                                       } catch (Exception) {
+                                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file '{0}': cannot be included ", file)), el);
+                                               Report.Warning (1592, 1, mc.Location, "Badly formed XML in included comments file -- '{0}'", file);
+                                       }
+                               }
+                               bool keepIncludeNode = false;
+                               if (doc != null) {
+                                       try {
+                                               XmlNodeList nl = doc.SelectNodes (path);
+                                               if (nl.Count == 0) {
+                                                       el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" No matching elements were found for the include tag embedded here. "), el);
+                                       
+                                                       keepIncludeNode = true;
+                                               }
+                                               foreach (XmlNode n in nl)
+                                                       el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el);
+                                       } catch (Exception ex) {
+                                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el);
+                                               Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment '{0}' of file {1} -- {2}.", path, file, ex.Message);
+                                       }
+                               }
+                               if (!keepIncludeNode)
+                                       el.ParentNode.RemoveChild (el);
+                       }
+               }
+
+               //
+               // Handles <see> elements.
+               //
+               private static void HandleSee (MemberCore mc,
+                       DeclSpace ds, XmlElement see)
+               {
+                       HandleXrefCommon (mc, ds, see);
+               }
+
+               //
+               // Handles <seealso> elements.
+               //
+               private static void HandleSeeAlso (MemberCore mc,
+                       DeclSpace ds, XmlElement seealso)
+               {
+                       HandleXrefCommon (mc, ds, seealso);
+               }
+
+               //
+               // Handles <exception> elements.
+               //
+               private static void HandleException (MemberCore mc,
+                       DeclSpace ds, XmlElement seealso)
+               {
+                       HandleXrefCommon (mc, ds, seealso);
+               }
+
+               static readonly char [] wsChars =
+                       new char [] {' ', '\t', '\n', '\r'};
+
+               //
+               // returns a full runtime type name from a name which might
+               // be C# specific type name.
+               //
+               private static Type FindDocumentedType (MemberCore mc,
+                       string name, DeclSpace ds, bool allowAlias)
+               {
+                       bool isArray = false;
+                       string identifier = name;
+                       if (name [name.Length - 1] == ']') {
+                               string tmp = name.Substring (0, name.Length - 1).Trim (wsChars);
+                               if (tmp [tmp.Length - 1] == '[') {
+                                       identifier = tmp.Substring (0, tmp.Length - 1).Trim (wsChars);
+                                       isArray = true;
+                               }
+                       }
+                       Type t = FindDocumentedTypeNonArray (mc, identifier,
+                               ds, allowAlias);
+                       if (t != null && isArray)
+                               t = Array.CreateInstance (t, 0).GetType ();
+                       return t;
+               }
+
+               private static Type FindDocumentedTypeNonArray (MemberCore mc,
+                       string identifier, DeclSpace ds, bool allowAlias)
+               {
+                       switch (identifier) {
+                       case "int":
+                               return typeof (int);
+                       case "uint":
+                               return typeof (uint);
+                       case "short":
+                               return typeof (short);
+                       case "ushort":
+                               return typeof (ushort);
+                       case "long":
+                               return typeof (long);
+                       case "ulong":
+                               return typeof (ulong);
+                       case "float":
+                               return typeof (float);
+                       case "double":
+                               return typeof (double);
+                       case "char":
+                               return typeof (char);
+                       case "decimal":
+                               return typeof (decimal);
+                       case "byte":
+                               return typeof (byte);
+                       case "sbyte":
+                               return typeof (sbyte);
+                       case "object":
+                               return typeof (object);
+                       case "bool":
+                               return typeof (bool);
+                       case "string":
+                               return typeof (string);
+                       case "void":
+                               return typeof (void);
+                       }
+                       if (allowAlias) {
+                               string alias = ds.LookupAlias (identifier);
+                               if (alias != null)
+                                       identifier = alias;
+                       }
+                       Type t = ds.FindType (mc.Location, identifier);
+                       if (t == null)
+                               t = TypeManager.LookupTypeDirect (identifier);
+                       return t;
+               }
+
+               //
+               // Returns a MemberInfo that is referenced in XML documentation
+               // (by "see" or "seealso" elements).
+               //
+               private static MemberInfo FindDocumentedMember (MemberCore mc,
+                       Type type, string memberName, Type [] paramList, 
+                       DeclSpace ds, out int warningType, string cref)
+               {
+                       warningType = 0;
+                       MethodSignature msig = new MethodSignature (memberName, null, paramList);
+                       MemberInfo [] mis = type.FindMembers (
+                               MemberTypes.All,
+                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                               MethodSignature.method_signature_filter,
+                               msig);
+                       if (mis.Length > 0)
+                               return mis [0];
+
+                       if (paramList.Length == 0) {
+                               // search for fields/events etc.
+                               mis = type.FindMembers (
+                                       MemberTypes.All,
+                                       BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                                       Type.FilterName,
+                                       memberName);
+                               return (mis.Length > 0) ? mis [0] : null;
+                       }
+
+                       // search for operators (whose parameters exactly
+                       // matches with the list) and possibly report CS1581.
+                       string oper = null;
+                       string returnTypeName = null;
+                       if (memberName.StartsWith ("implicit operator ")) {
+                               oper = "op_Implicit";
+                               returnTypeName = memberName.Substring (18).Trim (wsChars);
+                       }
+                       else if (memberName.StartsWith ("explicit operator ")) {
+                               oper = "op_Explicit";
+                               returnTypeName = memberName.Substring (18).Trim (wsChars);
+                       }
+                       else if (memberName.StartsWith ("operator ")) {
+                               oper = memberName.Substring (9).Trim (wsChars);
+                               switch (oper) {
+                               // either unary or binary
+                               case "+":
+                                       oper = paramList.Length == 2 ?
+                                               Binary.oper_names [(int) Binary.Operator.Addition] :
+                                               Unary.oper_names [(int) Unary.Operator.UnaryPlus];
+                                       break;
+                               case "-":
+                                       oper = paramList.Length == 2 ?
+                                               Binary.oper_names [(int) Binary.Operator.Subtraction] :
+                                               Unary.oper_names [(int) Unary.Operator.UnaryNegation];
+                                       break;
+                               // unary
+                               case "!":
+                                       oper = Unary.oper_names [(int) Unary.Operator.LogicalNot]; break;
+                               case "~":
+                                       oper = Unary.oper_names [(int) Unary.Operator.OnesComplement]; break;
+                                       
+                               case "++":
+                                       oper = "op_Increment"; break;
+                               case "--":
+                                       oper = "op_Decrement"; break;
+                               case "true":
+                                       oper = "op_True"; break;
+                               case "false":
+                                       oper = "op_False"; break;
+                               // binary
+                               case "*":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Multiply]; break;
+                               case "/":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Division]; break;
+                               case "%":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Modulus]; break;
+                               case "&":
+                                       oper = Binary.oper_names [(int) Binary.Operator.BitwiseAnd]; break;
+                               case "|":
+                                       oper = Binary.oper_names [(int) Binary.Operator.BitwiseOr]; break;
+                               case "^":
+                                       oper = Binary.oper_names [(int) Binary.Operator.ExclusiveOr]; break;
+                               case "<<":
+                                       oper = Binary.oper_names [(int) Binary.Operator.LeftShift]; break;
+                               case ">>":
+                                       oper = Binary.oper_names [(int) Binary.Operator.RightShift]; break;
+                               case "==":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Equality]; break;
+                               case "!=":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Inequality]; break;
+                               case "<":
+                                       oper = Binary.oper_names [(int) Binary.Operator.LessThan]; break;
+                               case ">":
+                                       oper = Binary.oper_names [(int) Binary.Operator.GreaterThan]; break;
+                               case "<=":
+                                       oper = Binary.oper_names [(int) Binary.Operator.LessThanOrEqual]; break;
+                               case ">=":
+                                       oper = Binary.oper_names [(int) Binary.Operator.GreaterThanOrEqual]; break;
+                               default:
+                                       warningType = 1584;
+                                       Report.Warning (1020, 1, mc.Location, "Overloadable {0} operator is expected", paramList.Length == 2 ? "binary" : "unary");
+                                       Report.Warning (1584, 1, mc.Location, "XML comment on '{0}' has syntactically incorrect attribute '{1}'", mc.GetSignatureForError (), cref);
+                                       return null;
+                               }
+                       }
+                       // here we still does not consider return type (to
+                       // detect CS1581 or CS1002+CS1584).
+                       msig = new MethodSignature (oper, null, paramList);
+                       mis = type.FindMembers (
+                               MemberTypes.Method,
+                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
+                               MethodSignature.method_signature_filter,
+                               msig);
+                       if (mis.Length == 0)
+                               return null; // CS1574
+                       MemberInfo mi = mis [0];
+                       Type expected = mi is MethodInfo ?
+                               ((MethodInfo) mi).ReturnType :
+                               mi is PropertyInfo ?
+                               ((PropertyInfo) mi).PropertyType :
+                               null;
+                       if (returnTypeName != null) {
+                               Type returnType = FindDocumentedType (mc, returnTypeName, ds, true);
+                               if (returnType == null || returnType != expected) {
+                                       warningType = 1581;
+                                       Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute '{0}'", cref);
+                                       return null;
+                               }
+                       }
+                       return mis [0];
+               }
+
+               private static Type [] emptyParamList = new Type [0];
+
+               //
+               // Processes "see" or "seealso" elements.
+               // Checks cref attribute.
+               //
+               private static void HandleXrefCommon (MemberCore mc,
+                       DeclSpace ds, XmlElement xref)
+               {
+                       string cref = xref.GetAttribute ("cref").Trim (wsChars);
+                       // when, XmlReader, "if (cref == null)"
+                       if (!xref.HasAttribute ("cref"))
+                               return;
+                       if (cref.Length == 0)
+                               Report.Warning (1001, 1, mc.Location, "Identifier expected");
+                               // ... and continue until CS1584.
+
+                       string signature; // "x:" are stripped
+                       string name; // method invokation "(...)" are removed
+                       string identifiers; // array indexer "[]" are removed
+                       string parameters; // method parameter list
+
+                       // strip 'T:' 'M:' 'F:' 'P:' 'E:' etc.
+                       // Here, MS ignores its member kind. No idea why.
+                       if (cref.Length > 2 && cref [1] == ':')
+                               signature = cref.Substring (2).Trim (wsChars);
+                       else
+                               signature = cref;
+
+                       int parensPos = signature.IndexOf ('(');
+                       if (parensPos > 0 && signature [signature.Length - 1] == ')') {
+                               name = signature.Substring (0, parensPos).Trim (wsChars);
+                               parameters = signature.Substring (parensPos + 1, signature.Length - parensPos - 2);
+                       }
+                       else {
+                               name = signature;
+                               parameters = String.Empty;
+                       }
+
+                       string identifier = name;
+
+                       if (name.Length > 0 && name [name.Length - 1] == ']') {
+                               string tmp = name.Substring (0, name.Length - 1).Trim (wsChars);
+                               if (tmp [tmp.Length - 1] == '[')
+                                       identifier = tmp.Substring (0, tmp.Length - 1).Trim (wsChars);
+                       }
+
+                       // Check if identifier is valid.
+                       // This check is not necessary to mark as error, but
+                       // csc specially reports CS1584 for wrong identifiers.
+                       foreach (string nameElem in identifier.Split ('.')) {
+                               if (!Tokenizer.IsValidIdentifier (nameElem)
+                                       && nameElem.IndexOf ("operator") < 0) {
+                                       if (nameElem.EndsWith ("[]") &&
+                                               Tokenizer.IsValidIdentifier (
+                                               nameElem.Substring (
+                                               0, nameElem.Length - 2)))
+                                               continue;
+
+                                       Report.Warning (1584, 1, mc.Location, "XML comment on '{0}' has syntactically incorrect attribute '{1}'", mc.GetSignatureForError (), cref);
+                                       xref.SetAttribute ("cref", "!:" + signature);
+                                       return;
+                               }
+                       }
+
+                       // check if parameters are valid
+                       Type [] parameterTypes = emptyParamList;
+                       if (parameters.Length > 0) {
+                               string [] paramList = parameters.Split (',');
+                               ArrayList plist = new ArrayList ();
+                               for (int i = 0; i < paramList.Length; i++) {
+                                       string paramTypeName = paramList [i].Trim (wsChars);
+                                       Type paramType = FindDocumentedType (mc, paramTypeName, ds, true);
+                                       if (paramType == null) {
+                                               Report.Warning (1580, 1, mc.Location, "Invalid type for parameter '{0}' in XML comment cref attribute '{1}'", i + 1, cref);
+                                               return;
+                                       }
+                                       plist.Add (paramType);
+                               }
+                               parameterTypes = plist.ToArray (typeof (Type)) as Type [];
+                               StringBuilder sb = new StringBuilder ();
+                               sb.Append ('(');
+                               for (int i = 0; i < parameterTypes.Length; i++) {
+                                       Type t = parameterTypes [i];
+                                       if (sb.Length > 1)
+                                               sb.Append (',');
+                                       sb.Append (t.FullName.Replace ('+', '.'));
+                               }
+                               sb.Append (')');
+                               parameters = sb.ToString ();
+                       }
+
+                       Type type = FindDocumentedType (mc, name, ds, true);
+                       if (type != null) {
+                               xref.SetAttribute ("cref", "T:" + type.FullName.Replace ("+", "."));
+                               return; // a type
+                       }
+
+                       // don't use identifier here. System[] is not alloed.
+                       if (Namespace.IsNamespace (name)) {
+                               xref.SetAttribute ("cref", "N:" + name);
+                               return; // a namespace
+                       }
+
+                       int period = name.LastIndexOf ('.');
+                       if (period > 0) {
+                               string typeName = name.Substring (0, period);
+                               string memberName = name.Substring (period + 1);
+                               type = FindDocumentedType (mc, typeName, ds, false);
+                               int warnResult;
+                               if (type != null) {
+                                       MemberInfo mi = FindDocumentedMember (mc, type, memberName, parameterTypes, ds, out warnResult, cref);
+                                       if (warnResult > 0)
+                                               return;
+                                       if (mi != null) {
+                                               xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + type.FullName.Replace ("+", ".") + "." + memberName + parameters);
+                                               return; // a member of a type
+                                       }
+                               }
+                       }
+                       else {
+                               int warnResult;
+                               MemberInfo mi = FindDocumentedMember (mc, ds.TypeBuilder, name, parameterTypes, ds, out warnResult, cref);
+                               if (warnResult > 0)
+                                       return;
+                               if (mi != null) {
+                                       xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + ds.TypeBuilder.FullName.Replace ("+", ".") + "." + name);
+                                       return; // local member name
+                               }
+                       }
+
+                       Report.Warning (1574, 1, mc.Location, "XML comment on '{0}' has cref attribute '{1}' that could not be resolved in '{2}'.", mc.GetSignatureForError (), cref, ds.GetSignatureForError ());
+
+                       xref.SetAttribute ("cref", "!:" + name);
+               }
+
+               //
+               // Get a prefix from member type for XML documentation (used
+               // to formalize cref target name).
+               //
+               static string GetMemberDocHead (MemberTypes type)
+               {
+                       switch (type) {
+                       case MemberTypes.Constructor:
+                       case MemberTypes.Method:
+                               return "M:";
+                       case MemberTypes.Event:
+                               return "E:";
+                       case MemberTypes.Field:
+                               return "F:";
+                       case MemberTypes.NestedType:
+                       case MemberTypes.TypeInfo:
+                               return "T:";
+                       case MemberTypes.Property:
+                               return "P:";
+                       }
+                       return "!:";
+               }
+
+               // MethodCore
+
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public static string GetMethodDocCommentName (MethodCore mc, DeclSpace ds)
+               {
+                       Parameter [] plist = mc.Parameters.FixedParameters;
+                       Parameter parr = mc.Parameters.ArrayParameter;
+                       string paramSpec = String.Empty;
+                       if (plist != null) {
+                               StringBuilder psb = new StringBuilder ();
+                               foreach (Parameter p in plist) {
+                                       psb.Append (psb.Length != 0 ? "," : "(");
+                                       psb.Append (p.ParameterType.FullName.Replace ("+", "."));
+                               }
+                               paramSpec = psb.ToString ();
+                       }
+                       if (parr != null)
+                               paramSpec += String.Concat (
+                                       paramSpec == String.Empty ? "(" : ",",
+                                       parr.ParameterType.FullName.Replace ("+", "."));
+
+                       if (paramSpec.Length > 0)
+                               paramSpec += ")";
+
+                       string name = mc is Constructor ? "#ctor" : mc.Name;
+                       return String.Concat (mc.DocCommentHeader, ds.Name, ".", name, paramSpec);
+               }
+
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               // FIXME: with a few effort, it could be done with XmlReader,
+               // that means removal of DOM use.
+               //
+               internal static void OnMethodGenerateDocComment (
+                       MethodCore mc, DeclSpace ds, XmlElement el)
+               {
+                       Hashtable paramTags = new Hashtable ();
+                       foreach (XmlElement pelem in el.SelectNodes ("param")) {
+                               int i;
+                               string xname = pelem.GetAttribute ("name");
+                               if (xname == "")
+                                       continue; // really? but MS looks doing so
+                               if (xname != "" && mc.Parameters.GetParameterByName (xname, out i) == null)
+                                       Report.Warning (1572, 2, mc.Location, "XML comment on '{0}' has a 'param' tag for '{1}', but there is no such parameter.", mc.Name, xname);
+                               else if (paramTags [xname] != null)
+                                       Report.Warning (1571, 2, mc.Location, "XML comment on '{0}' has a duplicate param tag for '{1}'", mc.Name, xname);
+                               paramTags [xname] = xname;
+                       }
+                       Parameter [] plist = mc.Parameters.FixedParameters;
+                       Parameter parr = mc.Parameters.ArrayParameter;
+                       if (plist != null) {
+                               foreach (Parameter p in plist) {
+                                       if (paramTags.Count > 0 && paramTags [p.Name] == null)
+                                               Report.Warning (1573, 4, mc.Location, "Parameter '{0}' has no matching param tag in the XML comment for '{1}' (but other parameters do)", mc.Name, p.Name);
+                               }
+                       }
+               }
+
+               // Enum
+               public static void GenerateEnumDocComment (Enum e, DeclSpace ds)
+               {
+                       GenerateDocComment (e, ds);
+                       foreach (string name in e.ordered_enums) {
+                               MemberCore mc = e.GetDefinition (name);
+                               GenerateDocComment (mc, e);
+                       }
+               }
+       }
+
+       //
+       // Implements XML documentation generation.
+       //
+       public class Documentation
+       {
+               public Documentation (string xml_output_filename)
+               {
+                       docfilename = xml_output_filename;
+                       XmlDocumentation = new XmlDocument ();
+                       XmlDocumentation.PreserveWhitespace = false;
+               }
+
+               private string docfilename;
+
+               //
+               // Used to create element which helps well-formedness checking.
+               //
+               public XmlDocument XmlDocumentation;
+
+               //
+               // The output for XML documentation.
+               //
+               public XmlWriter XmlCommentOutput;
+
+               //
+               // Stores XmlDocuments that are included in XML documentation.
+               // Keys are included filenames, values are XmlDocuments.
+               //
+               public Hashtable StoredDocuments = new Hashtable ();
+
+               //
+               // Stores comments on partial types (should handle uniquely).
+               // Keys are PartialContainers, values are comment strings
+               // (didn't use StringBuilder; usually we have just 2 or more).
+               //
+               public IDictionary PartialComments = new ListDictionary ();
+
+               //
+               // Outputs XML documentation comment from tokenized comments.
+               //
+               public bool OutputDocComment (string asmfilename)
+               {
+                       XmlTextWriter w = null;
+                       try {
+                               w = new XmlTextWriter (docfilename, null);
+                               w.Indentation = 4;
+                               w.Formatting = Formatting.Indented;
+                               w.WriteStartDocument ();
+                               w.WriteStartElement ("doc");
+                               w.WriteStartElement ("assembly");
+                               w.WriteStartElement ("name");
+                               w.WriteString (Path.ChangeExtension (asmfilename, null));
+                               w.WriteEndElement (); // name
+                               w.WriteEndElement (); // assembly
+                               w.WriteStartElement ("members");
+                               XmlCommentOutput = w;
+                               GenerateDocComment ();
+                               w.WriteFullEndElement (); // members
+                               w.WriteEndElement ();
+                               w.WriteWhitespace (Environment.NewLine);
+                               w.WriteEndDocument ();
+                               return true;
+                       } catch (Exception ex) {
+                               Report.Error (1569, "Error generating XML documentation file '{0}' ('{1}')", docfilename, ex.Message);
+                               return false;
+                       } finally {
+                               if (w != null)
+                                       w.Close ();
+                       }
+               }
+
+               //
+               // Fixes full type name of each documented types/members up.
+               //
+               public void GenerateDocComment ()
+               {
+                       TypeContainer root = RootContext.Tree.Types;
+                       if (root.Interfaces != null)
+                               foreach (Interface i in root.Interfaces) 
+                                       DocUtil.GenerateTypeDocComment (i, null);
+
+                       if (root.Types != null)
+                               foreach (TypeContainer tc in root.Types)
+                                       DocUtil.GenerateTypeDocComment (tc, null);
+
+                       if (root.Parts != null) {
+                               IDictionary comments = PartialComments;
+                               foreach (ClassPart cp in root.Parts) {
+                                       if (cp.DocComment == null)
+                                               continue;
+                                       comments [cp] = cp;
+                               }
+                       }
+
+                       if (root.Delegates != null)
+                               foreach (Delegate d in root.Delegates) 
+                                       DocUtil.GenerateDocComment (d, null);
+
+                       if (root.Enums != null)
+                               foreach (Enum e in root.Enums)
+                                       DocUtil.GenerateEnumDocComment (e, null);
+
+                       IDictionary table = new ListDictionary ();
+                       foreach (ClassPart cp in PartialComments.Keys) {
+                               table [cp.PartialContainer] += cp.DocComment;
+                       }
+                       foreach (PartialContainer pc in table.Keys) {
+                               pc.DocComment = table [pc] as string;
+                               DocUtil.GenerateDocComment (pc, null);
+                       }
+               }
+       }
+}
index db104221853ca96a1c3a7917f7290be75238e4ce..1dc2abe4215d4a385d01d85f2c56373b7b964cfe 100755 (executable)
@@ -6,6 +6,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 
 namespace Mono.CSharp
@@ -18,6 +19,8 @@ namespace Mono.CSharp
        using System.IO;
        using System.Text;
        using System.Globalization;
+       using System.Xml;
+       using System.Diagnostics;
 
        public enum Target {
                Library, Exe, Module, WinExe
@@ -220,6 +223,7 @@ namespace Mono.CSharp
                                "   -nostdlib[+|-]     Does not load core libraries\n" +
                                "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
                                "   -out:FNAME         Specifies output file\n" +
+                               "   -doc:XMLFILE         Generates xml documentation into specified file\n" +
                                "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
                                "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
@@ -1102,10 +1106,10 @@ namespace Mono.CSharp
                        }
                        case "/doc": {
                                if (value == ""){
-                                       Report.Error (5, arg + " requires an argument");
+                                       Report.Error (2006, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
-                               // TODO handle the /doc argument to generate xml doc
+                               RootContext.Documentation = new Documentation (value);
                                return true;
                        }
                        case "/lib": {
@@ -1538,6 +1542,7 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("Resolving tree");
                        RootContext.ResolveTree ();
+
                        if (Report.Errors > 0)
                                return false;
                        if (timestamps)
@@ -1547,6 +1552,11 @@ namespace Mono.CSharp
                        RootContext.PopulateTypes ();
                        RootContext.DefineTypes ();
                        
+                       if (RootContext.Documentation != null &&
+                               !RootContext.Documentation.OutputDocComment (
+                                       output_file))
+                               return false;
+
                        TypeManager.InitCodeHelpers ();
 
                        //
@@ -1736,7 +1746,6 @@ namespace Mono.CSharp
 #endif
                        return (Report.Errors == 0);
                }
-
        }
 
        //
index 49d483deabba049548cc6b9680243e2df5bbf02e..3024a779de69eaa397431aa8bf233ed39ad9e85e 100755 (executable)
@@ -209,6 +209,9 @@ namespace Mono.CSharp {
                        Report.Warning (code, loc, format, args);
                }
 
+               // Not nice but we have broken hierarchy
+               public virtual void CheckMarshallByRefAccess (Type container) {}
+
                /// <summary>
                /// Tests presence of ObsoleteAttribute and report proper error
                /// </summary>
@@ -501,6 +504,8 @@ namespace Mono.CSharp {
                                return new CharConstant ((char)v);
                        else if (t == TypeManager.bool_type)
                                return new BoolConstant ((bool) v);
+                       else if (t == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) v);
                        else if (TypeManager.IsEnumType (t)){
                                Type real_type = TypeManager.TypeToCoreType (v.GetType ());
                                if (real_type == t)
@@ -2993,6 +2998,14 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public override void CheckMarshallByRefAccess (Type container)
+               {
+                       if (!IsStatic && Type.IsValueType && !container.IsSubclassOf (TypeManager.mbr_type) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+                               Report.SymbolRelatedToPreviousError (DeclaringType);
+                               Report.Error (1690, loc, "Cannot call '{0}' method, property, or indexer because it is a value type member of a marshal-by-reference class", Name);
+                       }
+               }
+
                public bool VerifyFixed (bool is_expression)
                {
                        IVariable variable = instance_expr as IVariable;
@@ -3107,7 +3120,7 @@ namespace Mono.CSharp {
                {
                        Emit (ec, false);
                }
-               
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        ILGenerator ig = ec.ig;
@@ -3364,6 +3377,8 @@ namespace Mono.CSharp {
                                instance_expr = instance_expr.DoResolve (ec);
                                if (instance_expr == null)
                                        return false;
+
+                               instance_expr.CheckMarshallByRefAccess (ec.ContainerType);
                        }
 
                        if (must_do_cs1540_check && (instance_expr != null)) {
@@ -3664,7 +3679,11 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       Report.Error (70, loc, "The event `" + Name + "' can only appear on the left hand side of += or -= (except on the defining type)");
+                       if (instance_expr is This)
+                               Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of += or -=, try calling the actual delegate");
+                       else
+                               Report.Error (70, loc, "The event `{0}' can only appear on the left hand side of += or -= "+
+                                             "(except on the defining type)", Name);
                }
 
                public void EmitAddOrRemove (EmitContext ec, Expression source)
index a9974b1ba9d4614f7f0fc816d53657237cba7530..1ae16150f746a25a9d325be482dd50a317d17eda 100755 (executable)
@@ -14,6 +14,7 @@ using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Globalization;
+using System.Xml;
 
 namespace Mono.CSharp {
 
@@ -100,13 +101,17 @@ namespace Mono.CSharp {
                protected override void VerifyObsoleteAttribute()
                {
                }
+
+               public override string DocCommentHeader {
+                       get { return "F:"; }
+               }
        }
 
        /// <summary>
        ///   Enumeration container
        /// </summary>
        public class Enum : DeclSpace {
-               ArrayList ordered_enums;
+               public ArrayList ordered_enums;
                
                public Expression BaseType;
                
@@ -152,7 +157,7 @@ namespace Mono.CSharp {
                ///   Adds @name to the enumeration space, with @expr
                ///   being its definition.  
                /// </summary>
-               public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs)
+               public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs, string documentation)
                {
                        if (name == "value__") {
                                Report.Error (76, loc, "An item in an enumeration can't have an identifier `value__'");
@@ -160,6 +165,7 @@ namespace Mono.CSharp {
                        }
 
                        EnumMember em = new EnumMember (this, expr, name, loc, opt_attrs);
+                       em.DocComment = documentation;
                        if (!AddToContainer (em, false, name, ""))
                                return;
 
@@ -785,5 +791,21 @@ namespace Mono.CSharp {
                {
                        // UnderlyingType is never obsolete
                }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal override void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateEnumDocComment (this, ds);
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
        }
 }
index 73ac264f8014eaa443ff2b64e90dc905fcf473d0..828f0fe365efc97a8e8c62194a18dc70c8f49a47 100755 (executable)
@@ -323,11 +323,22 @@ namespace Mono.CSharp {
 
                Expression ResolveOperator (EmitContext ec)
                {
-                       Type expr_type = Expr.Type;
+                       //
+                       // Step 1: Default operations on CLI native types.
+                       //
+
+                       // Attempt to use a constant folding operation.
+                       if (Expr is Constant){
+                               Expression result;
+                               
+                               if (Reduce (ec, (Constant) Expr, out result))
+                                       return result;
+                       }
 
                        //
-                       // Step 1: Perform Operator Overload location
+                       // Step 2: Perform Operator Overload location
                        //
+                       Type expr_type = Expr.Type;
                        Expression mg;
                        string op_name;
                        
@@ -353,18 +364,6 @@ namespace Mono.CSharp {
                        if (expr_type == null)
                                return null;
                        
-                       //
-                       // Step 2: Default operations on CLI native types.
-                       //
-
-                       // Attempt to use a constant folding operation.
-                       if (Expr is Constant){
-                               Expression result;
-                               
-                               if (Reduce (ec, (Constant) Expr, out result))
-                                       return result;
-                       }
-
                        switch (Oper){
                        case Operator.LogicalNot:
                                if (expr_type != TypeManager.bool_type) {
@@ -446,6 +445,7 @@ namespace Mono.CSharp {
                                                return null;
                                        }
                                        lr.local_info.AddressTaken = true;
+                                       lr.local_info.Used = true;
                                }
 
                                // According to the specs, a variable is considered definitely assigned if you take
@@ -3610,6 +3610,11 @@ namespace Mono.CSharp {
                {
                        if (local_info == null) {
                                local_info = Block.GetLocalInfo (Name);
+
+                               // is out param
+                               if (lvalue_right_side == EmptyExpression.Null)
+                                       local_info.Used = true;
+
                                is_readonly = local_info.ReadOnly;
                        }
 
@@ -4167,8 +4172,9 @@ namespace Mono.CSharp {
 
                                        if (instance.GetType () != typeof (This)){
                                                if (fe.InstanceExpression.Type.IsSubclassOf (TypeManager.mbr_type)){
-                                                       Report.Error (197, loc,
-                                                                     "Can not pass a type that derives from MarshalByRefObject with out or ref");
+                                                       Report.SymbolRelatedToPreviousError (fe.InstanceExpression.Type);
+                                                       Report.Error (197, loc, "Cannot pass '{0}' as ref or out or take its address because it is a member of a marshal-by-reference class",
+                                                               fe.Name);
                                                        return false;
                                                }
                                        }
@@ -5498,6 +5504,9 @@ namespace Mono.CSharp {
                                }
                        }
                        
+                       if (mg.InstanceExpression != null)
+                               mg.InstanceExpression.CheckMarshallByRefAccess (ec.ContainerType);
+
                        eclass = ExprClass.Value;
                        return this;
                }
@@ -6063,7 +6072,7 @@ namespace Mono.CSharp {
                        if (IsDelegate){
                                RequestedType = (new NewDelegate (type, Arguments, loc)).Resolve (ec);
                                if (RequestedType != null)
-                                       if (!(RequestedType is NewDelegate))
+                                       if (!(RequestedType is DelegateCreation))
                                                throw new Exception ("NewDelegate.Resolve returned a non NewDelegate: " + RequestedType.GetType ());
                                return RequestedType;
                        }
@@ -7457,6 +7466,8 @@ namespace Mono.CSharp {
                        return RootContext.LookupType (ec.DeclSpace, sn.Name, true, loc) != null;
                }
                
+               // TODO: possible optimalization
+               // Cache resolved constant result in FieldBuilder <-> expresion map
                public static Expression ResolveMemberAccess (EmitContext ec, Expression member_lookup,
                                                              Expression left, Location loc,
                                                              Expression left_original)
@@ -7482,7 +7493,10 @@ namespace Mono.CSharp {
                                FieldInfo fi = fe.FieldInfo.Mono_GetGenericFieldDefinition ();
                                Type decl_type = fi.DeclaringType;
 
-                               if (fi is FieldBuilder) {
+                               bool is_emitted = fi is FieldBuilder;
+                               Type t = fi.FieldType;
+
+                               if (is_emitted) {
                                        Const c = TypeManager.LookupConstant ((FieldBuilder) fi);
                                        
                                        if (c != null) {
@@ -7492,16 +7506,21 @@ namespace Mono.CSharp {
 
                                                object real_value = ((Constant) c.Expr).GetValue ();
 
-                                               return Constantify (real_value, fi.FieldType);
+                                               return Constantify (real_value, t);
                                        }
                                }
 
+                               // IsInitOnly is because of MS compatibility, I don't know why but they emit decimal constant as InitOnly
+                               if (fi.IsInitOnly && !is_emitted && t == TypeManager.decimal_type) {
+                                       object[] attrs = fi.GetCustomAttributes (TypeManager.decimal_constant_attribute_type, false);
+                                       if (attrs.Length == 1)
+                                               return new DecimalConstant (((System.Runtime.CompilerServices.DecimalConstantAttribute) attrs [0]).Value);
+                               }
+
                                if (fi.IsLiteral) {
-                                       Type t = fi.FieldType;
-                                       
                                        object o;
 
-                                       if (fi is FieldBuilder)
+                                       if (is_emitted)
                                                o = TypeManager.GetValue ((FieldBuilder) fi);
                                        else
                                                o = fi.GetValue (fi);
@@ -7538,7 +7557,7 @@ namespace Mono.CSharp {
                                        return exp;
                                }
 
-                               if (fi.FieldType.IsPointer && !ec.InUnsafe){
+                               if (t.IsPointer && !ec.InUnsafe){
                                        UnsafeError (loc);
                                        return null;
                                }
@@ -8681,6 +8700,8 @@ namespace Mono.CSharp {
                                UnsafeError (loc);
                                return null;
                        }
+
+                       instance_expr.CheckMarshallByRefAccess (ec.ContainerType);
                        
                        eclass = ExprClass.IndexerAccess;
                        return this;
@@ -8751,6 +8772,8 @@ namespace Mono.CSharp {
                                }
                        }
                        
+                       instance_expr.CheckMarshallByRefAccess (ec.ContainerType);
+
                        eclass = ExprClass.IndexerAccess;
                        return this;
                }
@@ -8991,6 +9014,12 @@ namespace Mono.CSharp {
                        loc = l;
                }
 
+               public Expression Source {
+                       get {
+                               return source;
+                       }
+               }
+                       
                public override Expression DoResolve (EmitContext ec)
                {
                        //
index f0a5b5e7722cd1ff8edd6add1e630fe99c3ab5d2..81640dc956a410e92c5d48919ed886ae5822fd24 100755 (executable)
@@ -149,6 +149,9 @@ namespace Mono.CSharp {
                                MethodInfo [] mi;
                                Type t = missing.Type;
                                
+                               if (!t.IsInterface)
+                                       continue;
+
                                if (t is TypeBuilder){
                                        TypeContainer iface;
 
@@ -524,7 +527,7 @@ namespace Mono.CSharp {
                        for (i = 0; i < top; i++){
                                Type type = pending_implementations [i].type;
                                int j = 0;
-                               
+
                                foreach (MethodInfo mi in pending_implementations [i].methods){
                                        if (mi == null)
                                                continue;
@@ -547,8 +550,11 @@ namespace Mono.CSharp {
                                                
                                                if (pending_implementations [i].found [j]) {
                                                        string[] methodLabel = TypeManager.CSharpSignature (mi).Split ('.');
-                                                       Report.Error (536, container.Location, "'{0}' does not implement interface member '{1}'. '{2}.{3}' is either static, not public, or has the wrong return type",
-                                                               container.Name, TypeManager.CSharpSignature (mi), container.Name, methodLabel[methodLabel.Length - 1]);
+                                                       Report.Error (536, container.Location,
+                                                                     "'{0}' does not implement interface member '{1}'. '{2}.{3}' " +
+                                                                     "is either static, not public, or has the wrong return type",
+                                                                     container.Name, TypeManager.CSharpSignature (mi),
+                                                                     container.Name, methodLabel[methodLabel.Length - 1]);
                                                }
                                                else { 
                                                        Report.Error (535, container.Location, "'{0}' does not implement interface member '{1}'",
index 993cb9218b20aa8b4f05b98be068f75007ea43c7..08689ecf56db37b41b7038a9760d94ee0959c1f0 100644 (file)
@@ -65,7 +65,7 @@ namespace Mono.CSharp {
                /// <summary>
                /// List of symbols related to reported error/warning. You have to fill it before error/warning is reported.
                /// </summary>
-               static StringCollection related_symbols = new StringCollection ();
+               static StringCollection extra_information = new StringCollection ();
 
                abstract class AbstractMessage {
 
@@ -91,12 +91,12 @@ namespace Mono.CSharp {
                                        msg.Append (' ');
                                }
                                msg.AppendFormat ("{0} CS{1:0000}: {2}", MessageType, code, text);
-                               Console.WriteLine (msg.ToString ());
+                               Console.Error.WriteLine (msg.ToString ());
 
-                               foreach (string s in related_symbols) {
-                                       Console.WriteLine (String.Concat (s, MessageType, ')'));
-                               }
-                               related_symbols.Clear ();
+                               foreach (string s in extra_information) 
+                                       Console.Error.WriteLine (s + MessageType + ")");
+
+                               extra_information.Clear ();
 
                                if (Stacktrace)
                                        Console.WriteLine (FriendlyStackTrace (new StackTrace (true)));
@@ -156,7 +156,7 @@ namespace Mono.CSharp {
                        public override void Print(int code, string location, string text)
                        {
                                if (!IsEnabled (code)) {
-                                       related_symbols.Clear ();
+                                       extra_information.Clear ();
                                        return;
                                }
 
@@ -250,11 +250,14 @@ namespace Mono.CSharp {
 
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // IF YOU ADD A NEW WARNING YOU HAVE TO DUPLICATE ITS ID HERE
+               //
                public static bool IsValidWarning (int code)
                {
-                       int[] all_warnings = new int[] { 28, 67, 78, 105, 108, 109, 114, 192, 168, 169, 183, 184, 219, 251, 612, 618, 626, 628, 642, 649,
-                                                                                        659, 660, 661, 672, 1030, 1522, 1616, 1691, 1692, 1901, 2002, 2023, 3012, 3019, 8024, 8028
-                                                                                  };
+                       int[] all_warnings = new int[] {
+                               28, 67, 78, 105, 108, 109, 114, 192, 168, 169, 183, 184, 219, 251, 612, 618, 626, 628, 642, 649,
+                               659, 660, 661, 672, 1030, 1522, 1616, 1691, 1692, 1901, 2002, 2023, 3012, 3019, 8024, 8028
+                       };
+                       
                        foreach (int i in all_warnings) {
                                if (i == code)
                                        return true;
@@ -264,7 +267,7 @@ namespace Mono.CSharp {
                
                static public void LocationOfPreviousError (Location loc)
                {
-                       Console.WriteLine (String.Format ("{0}({1}) (Location of symbol related to previous error)", loc.Name, loc.Row));
+                       Console.Error.WriteLine (String.Format ("{0}({1}) (Location of symbol related to previous error)", loc.Name, loc.Row));
                }    
         
                static public void RuntimeMissingSupport (Location loc, string feature) 
@@ -318,7 +321,12 @@ namespace Mono.CSharp {
 
                static void SymbolRelatedToPreviousError (string loc, string symbol)
                {
-                       related_symbols.Add (String.Format ("{0}: '{1}' (name of symbol related to previous ", loc, symbol));
+                       extra_information.Add (String.Format ("{0}: '{1}' (name of symbol related to previous ", loc, symbol));
+               }
+
+               public static void ExtraInformation (Location loc, string msg)
+               {
+                       extra_information.Add (String.Format ("{0}({1}) {2}", loc.Name, loc.Row, msg));
                }
 
                public static WarningRegions RegisterWarningRegion (Location location)
index aeaf4e645f45952ffb89c58050c76d389226fa75..f792d213ac618eb576c6d5b51dd6f55ae10a29a2 100755 (executable)
@@ -7,12 +7,14 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 
 using System;
 using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
+using System.Xml;
 
 namespace Mono.CSharp {
 
@@ -79,6 +81,11 @@ namespace Mono.CSharp {
                public static string StrongNameKeyContainer;
                public static bool StrongNameDelaySign = false;
 
+               //
+               // If set, enable XML documentation generation
+               //
+               public static Documentation Documentation;
+
                //
                // Constructor
                //
@@ -382,6 +389,7 @@ namespace Mono.CSharp {
                                "System.Security.UnverifiableCodeAttribute",
                                "System.Security.Permissions.SecurityAttribute",
                                "System.Runtime.CompilerServices.IndexerNameAttribute",
+                               "System.Runtime.CompilerServices.DecimalConstantAttribute",
                                "System.Runtime.InteropServices.InAttribute",
                                "System.Runtime.InteropServices.StructLayoutAttribute",
                                "System.Runtime.InteropServices.FieldOffsetAttribute",
@@ -562,7 +570,7 @@ namespace Mono.CSharp {
                                }
                                
                                t = NamespaceLookup (ds, name, num_type_params, loc);
-                               if (t != null){
+                               if (!silent || t != null){
                                        ds.Cache [name] = t;
                                        return t;
                                }
index fdc2fbd7e9afd4dc0cefbe330341752c9d074ac8..11d9149f30cb07e3bf4eb5264224a6455e225569 100755 (executable)
@@ -2347,12 +2347,12 @@ namespace Mono.CSharp {
 
                        if (allowed_types == null){
                                allowed_types = new Type [] {
+                                       TypeManager.int32_type,
+                                       TypeManager.uint32_type,
                                        TypeManager.sbyte_type,
                                        TypeManager.byte_type,
                                        TypeManager.short_type,
                                        TypeManager.ushort_type,
-                                       TypeManager.int32_type,
-                                       TypeManager.uint32_type,
                                        TypeManager.int64_type,
                                        TypeManager.uint64_type,
                                        TypeManager.char_type,
@@ -2375,13 +2375,26 @@ namespace Mono.CSharp {
                                if (e == null)
                                        continue;
 
+                               //
+                               // Ignore over-worked ImplicitUserConversions that do
+                               // an implicit conversion in addition to the user conversion.
+                               // 
+                               if (e is UserCast){
+                                       UserCast ue = e as UserCast;
+
+                                       if (ue.Source != Expr)
+                                               e = null;
+                               }
+                               
                                if (converted != null){
-                                       Report.Error (-12, loc, "More than one conversion to an integral " +
-                                                     " type exists for type `" +
-                                                     TypeManager.CSharpName (Expr.Type)+"'");
+                                       Report.ExtraInformation (
+                                               loc,
+                                               String.Format ("reason: more than one conversion to an integral type exist for type {0}",
+                                                              TypeManager.CSharpName (Expr.Type)));
                                        return null;
-                               } else
+                               } else {
                                        converted = e;
+                               }
                        }
                        return converted;
                }
@@ -3948,12 +3961,39 @@ namespace Mono.CSharp {
                void EmitExpressionFinally (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
-                       Label skip = ig.DefineLabel ();
-                       ig.Emit (OpCodes.Ldloc, local_copy);
-                       ig.Emit (OpCodes.Brfalse, skip);
-                       ig.Emit (OpCodes.Ldloc, local_copy);
-                       ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
-                       ig.MarkLabel (skip);
+                       if (!local_copy.LocalType.IsValueType) {
+                               Label skip = ig.DefineLabel ();
+                               ig.Emit (OpCodes.Ldloc, local_copy);
+                               ig.Emit (OpCodes.Brfalse, skip);
+                               ig.Emit (OpCodes.Ldloc, local_copy);
+                               ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               ig.MarkLabel (skip);
+                       } else {
+                               Expression ml = Expression.MemberLookup(ec, TypeManager.idisposable_type, local_copy.LocalType, "Dispose", Mono.CSharp.Location.Null);
+
+                               if (!(ml is MethodGroupExpr)) {
+                                       ig.Emit (OpCodes.Ldloc, local_copy);
+                                       ig.Emit (OpCodes.Box, local_copy.LocalType);
+                                       ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               } else {
+                                       MethodInfo mi = null;
+
+                                       foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
+                                               if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+                                                       mi = mk;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (mi == null) {
+                                               Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+                                               return;
+                                       }
+
+                                       ig.Emit (OpCodes.Ldloca, local_copy);
+                                       ig.Emit (OpCodes.Call, mi);
+                               }
+                       }
                }
                
                public override bool Resolve (EmitContext ec)
index be20804b5dec01df0657cea6edd5fed5cc5dd682..003fb5e1699494f34f786b687b3b7553c813e70b 100755 (executable)
@@ -74,6 +74,7 @@ public class TypeManager {
        static public Type runtime_argument_handle_type;
        static public Type attribute_type;
        static public Type attribute_usage_type;
+       static public Type decimal_constant_attribute_type;
        static public Type dllimport_type;
        static public Type unverifiable_code_type;
        static public Type methodimpl_attr_type;
@@ -186,9 +187,11 @@ public class TypeManager {
        static public ConstructorInfo object_ctor;
        static public ConstructorInfo cons_param_array_attribute;
        static public ConstructorInfo void_decimal_ctor_five_args;
+       static public ConstructorInfo void_decimal_ctor_int_arg;
        static public ConstructorInfo unverifiable_code_ctor;
        static public ConstructorInfo invalid_operation_ctor;
        static public ConstructorInfo default_member_ctor;
+       static public ConstructorInfo decimal_constant_attribute_ctor;
        
        // <remarks>
        //   Holds the Array of Assemblies that have been loaded
@@ -1185,6 +1188,7 @@ public class TypeManager {
                typed_reference_type = CoreLookupType ("System.TypedReference");
                arg_iterator_type    = CoreLookupType ("System.ArgIterator");
                mbr_type             = CoreLookupType ("System.MarshalByRefObject");
+               decimal_constant_attribute_type = CoreLookupType ("System.Runtime.CompilerServices.DecimalConstantAttribute");
 
                //
                // Sigh. Remove this before the release.  Wonder what versions of Mono
@@ -1427,6 +1431,8 @@ public class TypeManager {
                void_decimal_ctor_five_args = GetConstructor (
                        decimal_type, dec_arg);
                
+               void_decimal_ctor_int_arg = GetConstructor (decimal_type, int_arg);
+
                //
                // Attributes
                //
@@ -1436,6 +1442,9 @@ public class TypeManager {
                unverifiable_code_ctor = GetConstructor (
                        unverifiable_code_type, void_arg);
 
+               decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type []
+                       { byte_type, byte_type, uint32_type, uint32_type, uint32_type } );
+
                default_member_ctor = GetConstructor (default_member_type, string_);
 
                //
@@ -1701,7 +1710,7 @@ public class TypeManager {
                DeclSpace tc = LookupDeclSpace (t);
                if (tc != null) {
                        if (!tc.IsGeneric)
-                               throw new InvalidOperationException ();
+                               return Type.EmptyTypes;
 
                        TypeParameter[] tparam = tc.TypeParameters;
                        Type[] ret = new Type [tparam.Length];
@@ -2419,7 +2428,7 @@ public class TypeManager {
        public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
        {
                ArrayList new_ifaces = new ArrayList ();
-               
+
                foreach (TypeExpr iface in base_interfaces){
                        TypeExpr texpr = iface.ResolveAsTypeTerminal (ec);
                        if (texpr == null)
@@ -2566,7 +2575,7 @@ public class TypeManager {
                                return (object)(convert_value.ToChar (nf_provider));
                        else if (conversionType.Equals (typeof (DateTime)))
                                return (object)(convert_value.ToDateTime (nf_provider));
-                       else if (conversionType.Equals (typeof (Decimal)))
+                       else if (conversionType.Equals (TypeManager.decimal_type)) // typeof (Decimal)))
                                return (object)(convert_value.ToDecimal (nf_provider));
                        else if (conversionType.Equals (typeof (Double)))
                                return (object)(convert_value.ToDouble (nf_provider));
@@ -2686,12 +2695,14 @@ public class TypeManager {
                        return TypeManager.int64_type;
                case TypeCode.UInt64:
                        return TypeManager.uint64_type;
-                case TypeCode.Single:
-                        return TypeManager.float_type;
-                case TypeCode.Double:
-                        return TypeManager.double_type;
+               case TypeCode.Single:
+                       return TypeManager.float_type;
+               case TypeCode.Double:
+                       return TypeManager.double_type;
                case TypeCode.String:
                        return TypeManager.string_type;
+               case TypeCode.Decimal:
+                       return TypeManager.decimal_type;
                default:
                        if (t == typeof (void))
                                return TypeManager.void_type;
index 6ad50268fe5b5b3d47dafa5c671f0a6a5a7207ee..a75d66dea5ff83b5d42fe36876e0bd06fb8092ab 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * CodeGen.cs: Correctly compute the name of a nested class,
+       currently it was ignoring anything above level 1.
+
 2004-07-27  Jackson Harper  <jackson@ximian.com>
 
        * Driver.cs: Make debug switch compatible with MS's add debug to
index 78a93641ad2d6f4ae294523a55dd165735096596..7abcf9320180612d07a9dd79702797fbbc9b0609 100644 (file)
@@ -1,3 +1,27 @@
+2004-12-02  Jackson Harper  <jackson@ximian.com>
+
+       * ExternTypeRefInst.cs: When converting to arrays we loose our valuetypedness.
+
+2004-12-02  Jackson Harper  <jackson@ximian.com>
+
+       * MethodDef.cs: Abstract methods don't get bodies. Even if there
+       are bodies there.
+
+2004-12-02  Jackson Harper  <jackson@ximian.com>
+
+       * MethodDef.cs: If the type is an interface auto set fields to
+       static (and give a warning if they are not static), and set
+       methods to abstract virtual (and give warning if they were not already).
+       * FieldDef.cs:
+       * TypeDef.cs: Accessors and convience properties for getting and
+       setting the method/field attributes.
+       
+       
+2004-12-02  Jackson Harper  <jackson@ximian.com>
+
+       * FieldDef.cs: Set the underlying type for bytearray data constants. This
+       fixes bug #70153 and #70154 which my previous fix caused.
+
 2004-08-01  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DebuggingInfo.cs : csc build fix (see bug #62230).
index 7eb90407c5e8ee0f495b2870293cbcb7abc9050f..8281bd8ff33bc0cccb44801c4a397f0df75e2021 100644 (file)
@@ -15,6 +15,7 @@ using System.IO;
 using System.Collections;\r
 using System.Reflection;\r
 using System.Reflection.Emit;\r
+using System.Text;\r
 \r
 namespace Mono.ILASM {\r
 \r
@@ -28,7 +29,8 @@ namespace Mono.ILASM {
                 private string current_namespace;\r
                 private TypeDef current_typedef;\r
                 private MethodDef current_methoddef;\r
-                private Stack typedef_stack;\r
+                private ArrayList typedef_stack;\r
+               private int typedef_stack_top;\r
                private SymbolWriter symwriter;\r
 \r
                 private byte [] assembly_public_key;\r
@@ -73,7 +75,8 @@ namespace Mono.ILASM {
 \r
                         type_manager = new TypeManager (this);\r
                         extern_table = new ExternTable ();\r
-                        typedef_stack = new Stack ();\r
+                        typedef_stack = new ArrayList ();\r
+                       typedef_stack_top = 0;\r
                         global_field_table = new Hashtable ();\r
                         global_method_table = new Hashtable ();\r
 \r
@@ -196,9 +199,16 @@ namespace Mono.ILASM {
                         TypeDef outer = null;\r
                         string cache_name = CacheName (name);\r
 \r
-                        if (typedef_stack.Count > 0) {\r
-                                outer = (TypeDef) typedef_stack.Peek ();\r
-                                cache_name = CacheName (outer.Name + '/' + name);\r
+                        if (typedef_stack_top > 0) {\r
+                               StringBuilder sb = new StringBuilder ();\r
+                               \r
+                               for (int i = 0; i < typedef_stack_top; i++){\r
+                                       outer = (TypeDef) typedef_stack [i];\r
+                                       sb.Append (outer.Name);\r
+                                       sb.Append ("/");\r
+                               }\r
+                               sb.Append (name);\r
+                                cache_name = CacheName (sb.ToString ());\r
                         }\r
 \r
                         TypeDef typedef = type_manager[cache_name];\r
@@ -206,7 +216,8 @@ namespace Mono.ILASM {
                         if (typedef != null) {\r
                                 // Class head is allready defined, we are just reopening the class\r
                                 current_typedef = typedef;\r
-                                typedef_stack.Push (current_typedef);\r
+                                typedef_stack.Add (current_typedef);\r
+                               typedef_stack_top++;\r
                                 return;\r
                         }\r
 \r
@@ -218,7 +229,8 @@ namespace Mono.ILASM {
 \r
                         type_manager[cache_name] = typedef;\r
                         current_typedef = typedef;\r
-                        typedef_stack.Push (typedef);\r
+                       typedef_stack.Add (typedef);\r
+                       typedef_stack_top++;\r
                 }\r
 \r
                 public void AddFieldDef (FieldDef fielddef)\r
@@ -268,10 +280,11 @@ namespace Mono.ILASM {
 \r
                 public void EndTypeDef ()\r
                 {\r
-                        typedef_stack.Pop ();\r
+                       typedef_stack_top--;\r
+                       typedef_stack.RemoveAt (typedef_stack_top);\r
 \r
-                        if (typedef_stack.Count > 0)\r
-                                current_typedef = (TypeDef) typedef_stack.Peek ();\r
+                        if (typedef_stack_top > 0)\r
+                                current_typedef = (TypeDef) typedef_stack [typedef_stack_top-1];\r
                         else\r
                                 current_typedef = null;\r
 \r
index 1c501920441b0fee756cf147a34f7e1f532ca335..d76c29b35ec84b59d2523e5859be5ba43fea6c61 100644 (file)
@@ -66,11 +66,13 @@ namespace Mono.ILASM {
 
                public void MakeArray ()
                {
+                       is_valuetypeinst = false;
                        type_ref.MakeArray ();
                }
 
                public void MakeBoundArray (ArrayList bounds)
                {
+                       is_valuetypeinst = false;
                        type_ref.MakeBoundArray (bounds);
                }
 
index f1c06aaa3c92c55d53ca41808fd05cc978e1b2df..9377f746de88afe375d1bb76424ec898d8556d7a 100644 (file)
@@ -53,6 +53,15 @@ namespace Mono.ILASM {
                         get { return field_def; }
                 }
 
+                public bool IsStatic {
+                        get { return (attr & PEAPI.FieldAttr.Static) != 0; }
+                }
+
+                public PEAPI.FieldAttr Attributes {
+                        get { return attr; }
+                        set { attr = value; }
+                }
+
                 public void SetOffset (uint val)
                 {
                         offset_set = true;
@@ -119,8 +128,12 @@ namespace Mono.ILASM {
                         if (offset_set)
                                 field_def.SetOffset (offset);
 
-                        if (value_set)
-                                field_def.AddValue (constant);
+                       if (value_set) {
+                               PEAPI.ByteArrConst dc = constant as PEAPI.ByteArrConst;
+                               if (dc != null)
+                                       dc.Type = type.PeapiType;
+                               field_def.AddValue (constant);
+                       }
 
                         if (at_data_id != null) {
                                 PEAPI.DataConstant dc = code_gen.GetDataConst (at_data_id);
index dd46e1708afcec659a0b535fc71566fdbcf3f547..40a3ff3f78f255dcac17e9eabad0f19fdc0cdaeb 100644 (file)
@@ -110,6 +110,11 @@ namespace Mono.ILASM {
                         get { return methoddef; }
                 }
 
+                public PEAPI.MethAttr Attributes {
+                        get { return meth_attr; }
+                        set { meth_attr = value; }
+                }
+
                 public bool IsVararg {
                         get { return (call_conv & PEAPI.CallConv.Vararg) != 0; }
                 }
@@ -118,6 +123,14 @@ namespace Mono.ILASM {
                         get { return (meth_attr & PEAPI.MethAttr.Static) != 0; }
                 }
 
+                public bool IsVirtual {
+                        get { return (meth_attr & PEAPI.MethAttr.Virtual) != 0; }
+                }
+
+                public bool IsAbstract {
+                        get { return (meth_attr & PEAPI.MethAttr.Abstract) != 0; }
+                }
+
                 public ITypeRef[] ParamTypeList () {
 
                         if (param_list == null)
@@ -321,7 +334,7 @@ namespace Mono.ILASM {
 
                         WriteCode (code_gen, methoddef);
 
-                        code_gen.Report.Message (String.Format ("Assembled method '<Module>'::{0}", name));
+                        //code_gen.Report.Message (String.Format ("Assembled method '<Module>'::{0}", name));
                         is_defined = true;
                 }
 
@@ -336,7 +349,7 @@ namespace Mono.ILASM {
                         Resolve (code_gen, (PEAPI.ClassDef) typedef.ClassDef);
                         WriteCode (code_gen, methoddef);
 
-                        code_gen.Report.Message (String.Format ("Assembled method {0}::{1}", typedef.FullName, name));                        is_defined = true;
+                        //code_gen.Report.Message (String.Format ("Assembled method {0}::{1}", typedef.FullName, name));                        is_defined = true;
                 }
 
                 public void AddInstr (IInstr instr)
@@ -346,6 +359,9 @@ namespace Mono.ILASM {
 
                 protected void WriteCode (CodeGen code_gen, PEAPI.MethodDef methoddef)
                 {
+                        if (IsAbstract)
+                                return;
+
                         if (entry_point)
                                 methoddef.DeclareEntryPoint ();
 
index e8472d49f219f3010c8c4c5ce0126b919e089f32..41de5d76365ab661a6d92146227b6e3e9471e727 100644 (file)
@@ -109,6 +109,9 @@ namespace Mono.ILASM {
                         get { return current_property; }
                 }
 
+                public bool IsInterface {
+                        get { return (attr & PEAPI.TypeAttr.Interface) != 0; }
+                }
 
                 public void AddOverride (MethodDef body, ITypeRef parent, string name)
                 {
@@ -148,12 +151,22 @@ namespace Mono.ILASM {
 
                 public void AddFieldDef (FieldDef fielddef)
                 {
+                        if (IsInterface && !fielddef.IsStatic) {
+                                Console.WriteLine ("warning -- Non-static field in interface, set to such");
+                                fielddef.Attributes |= PEAPI.FieldAttr.Static;
+                        }
+
                         field_table.Add (fielddef.Name, fielddef);
                         field_list.Add (fielddef);
                 }
 
                 public void AddMethodDef (MethodDef methoddef)
                 {
+                        if (IsInterface && !(methoddef.IsVirtual || methoddef.IsAbstract)) {
+                                Console.WriteLine ("warning -- Non-virtual, non-abstract instance method in interface, set to such");
+                                methoddef.Attributes |= PEAPI.MethAttr.Abstract | PEAPI.MethAttr.Virtual;
+                        }
+
                         method_table.Add (methoddef.Signature, methoddef);
                 }
 
index c75d8379fc4ccee3972fd8352c660bfc7f9ba853..82cc054c21cd9aeb54cfcc7465d163a6010d3154 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * ILParser.jay: Added D_STACKRESERVE token.
+
+       (prop_head, event_head): Allow it to take a compound name (for explicit
+       interface implementations of properties).
+
 2004-07-21  Jackson Harper  <jackson@ximian.com>
 
        * ILParser.jay: Clones ExternTypeRefInsts as well as
index f6b787ba9bf06081c5b139300396014378822c9c..6e6dfbcc475501e5ca63f7dcbb4fb5880a2245db 100644 (file)
@@ -190,6 +190,7 @@ namespace Mono.ILASM {
 %token D_REMOVEON\r
 %token D_SET\r
 %token D_SIZE\r
+%token D_STACKRESERVE\r
 %token D_SUBSYSTEM\r
 %token D_TITLE\r
 %token D_TRY\r
@@ -2184,7 +2185,7 @@ event_all         : event_head OPEN_BRACE event_decls CLOSE_BRACE
                           }\r
                        ;\r
 \r
-event_head             : D_EVENT event_attr type_spec id\r
+event_head             : D_EVENT event_attr type_spec comp_name\r
                           {\r
                                 EventDef event_def = new EventDef ((FeatureAttr) $2,\r
                                         (ITypeRef) $3, (string) $4);\r
@@ -2242,7 +2243,7 @@ prop_all          : prop_head OPEN_BRACE prop_decls CLOSE_BRACE
                           }\r
                        ;\r
 \r
-prop_head              : D_PROPERTY prop_attr type id OPEN_PARENS type_list CLOSE_PARENS init_opt\r
+prop_head              : D_PROPERTY prop_attr type comp_name OPEN_PARENS type_list CLOSE_PARENS init_opt\r
                           {\r
                                 PropertyDef prop_def = new PropertyDef ((FeatureAttr) $2, (ITypeRef) $3,\r
                                         (string) $4, (ArrayList) $6);\r
index e4024e2870570dff9321efb8870245df52b77bc3..a1626085a8520d2af41645e3b01af411564ecec2 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * ILTable.cs: Add new .stackreserve token.
+
 2004-07-27  Martin Baulig  <martin@ximian.com>
 
        * ILTokenizer.cs (ILTokenizer.Location): New public property.
index 5012547d4a878205291d1041553d6e3bd2a62114..01c3d1df3f2c4cb666f39442f11e699f7a46a16f 100644 (file)
@@ -98,6 +98,7 @@ namespace Mono.ILASM {
                                 directives [".removeon"] = new ILToken (Token.D_REMOVEON, ".removeon");\r
                                 directives [".set"] = new ILToken (Token.D_SET, ".set");\r
                                 directives [".size"] = new ILToken (Token.D_SIZE, ".size");\r
+                               directives [".stackreserve"] = new ILToken (Token.D_STACKRESERVE, ".stackreserve");\r
                                 directives [".subsystem"] = new ILToken (Token.D_SUBSYSTEM, ".subsystem");\r
                                 directives [".title"] = new ILToken (Token.D_TITLE, ".title");\r
                                 directives [".try"] = new ILToken (Token.D_TRY, ".try");\r
index ab10cc761fd6a8ec4a5fa6c9763eaafc4c393a10..aad39927083d96cc9204fbc82bbaf18e78e91b49 100755 (executable)
@@ -1,3 +1,93 @@
+2004-12-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * delegate.cs: Only allow this on new versions of the language. 
+
+2004-12-02  Duncan Mak  <duncan@ximian.com>
+
+       * ecore.cs (PropertyExpr.IsAccessorAccessible): Moved to
+       Expression class.
+       (Expression.IsAccessorAccessible): Moved from the PropertyExpr to
+       here as a static method. Take an additional bool out parameter
+       `must_do_cs1540_check' for signaling to InstanceResolve.
+       (PropertyExpr.InstanceResolve): Removed the `must_do_cs1540_check'
+       member field from PropertyExpr class and made it an argument of
+       the method instead.
+       (EventExpr.InstanceResolve): Copied from PropertyExpr, removed the
+       check for MarshalByRefObject, and report CS0122 instead of CS1540.
+       (EventExpr.DoResolve): Call IsAccessorAccessible on `add_accessor'
+       and `remove_accessor' as well as InstanceResolve: report CS0122
+       where applicable.
+
+       Fixes #70129.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       Fix test-327.cs, test-328.cs, and put in early infrastructure
+       for eventually fixing #52697.
+       * namespace.cs (NamespaceEntry.LookupForUsing): New method.
+       (NamespaceEntry.LookupNamespaceOrType): New method, refactored
+       from other methods.
+       (NamespaceEntry.Lookup): Remove 'ignore_using' flag.
+       (AliasEntry.Resolve, UsingEntry.Resolve): Use 'LookupForUsing'.
+       (VerifyUsing, error246): Update.
+       * rootcontext.cs (RootContext.NamespaceLookup): Just use
+       'NamespaceEntry.LookupNamespaceOrType'.
+
+2004-12-03  Martin Baulig  <martin@ximian.com>
+
+       * delegate.cs (NewDelegate.DoResolve): If we have an anonymous
+       method as our child, call AnonymousMethod.Compatible() on it.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       Disable XML documentation support in 'basic' profile.
+       * decl.cs, class.cs [BOOTSTRAP_WITH_OLDLIB]: Don't import System.Xml.
+       Redirect XmlElement to System.Object.
+       * driver.cs, enum.cs, rootcontext.cs: Don't reference System.Xml.
+       * doc.cs [BOOTSTRAP_WITH_OLDLIB]: Disable compile.
+       * mcs.exe.sources: Add doc-bootstrap.cs.
+       * doc-bootstrap.cs: New file.  Contains empty stub implementation
+       of doc.cs.
+
+2004-12-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * cs-tokenizer.cs : Only '////' is rejected. Other non-whitespace
+         comments are allowed.
+
+2004-12-03  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * delegate.cs: Add checks for subtypes in paramaters and return values
+       in VerifyMethod () to add support for Covariance/Contravariance
+       in delegates.
+       
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * report.cs: Remove extra closing parenthesis.
+
+       * convert.cs (Error_CannotImplicitConversion): If the name of the
+       types are the same, provide some extra information.
+
+       * class.cs (FieldBase): Use an unused bit field from the field to
+       encode the `has_offset' property from the FieldMember.  This saves
+       a couple of Ks on bootstrap compilation.
+
+       * delegate.cs (NewDelegate.DoResolve): If we have an anonymous
+       method as our child, return the AnonymousMethod resolved
+       expression.
+
+       * expression.cs (New.DoResolve): Allow return values from
+       NewDelegate to also include AnonymousMethods.
+
+       Fixes #70150.
+
+2004-12-02  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #70102
+       * attribute.cs (Resolve): Improved implementation of params
+        attribute arguments.
+
+       * support.cs (ParameterData): Add HasParams to be faster.
+
 2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
 
        all things are for /doc support:
index 3c011a67d71680a0b2a15a3191f149f31e3b9b73..d7f01ae8d0d97da4a841206a15221e3a4ba61be5 100755 (executable)
@@ -418,7 +418,7 @@ namespace Mono.CSharp {
                                return null;
 
                        }
-                       
+
                        if (target_type == source_type){
                                if (source is New && target_type.IsValueType &&
                                    (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){
index 6edc418602614c9542a3f96b239dbd3093303740..7dd1deb4d1adb0b933cac5207d1330181ba416e6 100644 (file)
@@ -492,10 +492,17 @@ namespace Mono.CSharp {
 
                        ParameterData pd = Invocation.GetParameterData (constructor);
 
-                       int group_in_params_array = Int32.MaxValue;
-                       int pc = pd.Count;
-                       if (pc > 0 && pd.ParameterModifier (pc-1) == Parameter.Modifier.PARAMS)
-                               group_in_params_array = pc-1;
+                       int last_real_param = pd.Count;
+                       if (pd.HasParams) {
+                               // When the params is not filled we need to put one
+                               if (last_real_param > pos_arg_count) {
+                                       object [] new_pos_values = new object [pos_arg_count + 1];
+                                       pos_values.CopyTo (new_pos_values, 0);
+                                       new_pos_values [pos_arg_count] = new object [] {} ;
+                                       pos_values = new_pos_values;
+                               }
+                               last_real_param--;
+                       }
 
                        for (int j = 0; j < pos_arg_count; ++j) {
                                Argument a = (Argument) pos_args [j];
@@ -505,32 +512,24 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               if (j < group_in_params_array)
+                               if (j < last_real_param)
                                        continue;
                                
-                               if (j == group_in_params_array){
-                                       object v = pos_values [j];
-                                       int count = pos_arg_count - j;
-
-                                       object [] array = new object [count];
+                               if (j == last_real_param) {
+                                       object [] array = new object [pos_arg_count - last_real_param];
+                                       array [0] = pos_values [j];
                                        pos_values [j] = array;
-                                       array [0] = v;
-                               } else {
-                                       object [] array = (object []) pos_values [group_in_params_array];
-
-                                       array [j - group_in_params_array] = pos_values [j];
+                                       continue;
                                }
+
+                               object [] params_array = (object []) pos_values [last_real_param];
+                               params_array [j - last_real_param] = pos_values [j];
                        }
 
-                       //
                        // Adjust the size of the pos_values if it had params
-                       //
-                       if (group_in_params_array != Int32.MaxValue){
-                               int argc = group_in_params_array+1;
-                               object [] new_pos_values = new object [argc];
-
-                               for (int p = 0; p < argc; p++)
-                                       new_pos_values [p] = pos_values [p];
+                       if (last_real_param != pos_arg_count) {
+                               object [] new_pos_values = new object [last_real_param + 1];
+                               Array.Copy (pos_values, new_pos_values, last_real_param + 1);
                                pos_values = new_pos_values;
                        }
 
index 4a0a3416d2a84e336f6d8874ca4243e9850dd94e..6ba610aee39662ede9e1f95cb6d9e5bc4de0026d 100755 (executable)
@@ -41,7 +41,12 @@ using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Permissions;
 using System.Text;
+
+#if BOOTSTRAP_WITH_OLDLIB
+using XmlElement = System.Object;
+#else
 using System.Xml;
+#endif
 
 using Mono.CompilerServices.SymbolWriter;
 
@@ -5039,7 +5044,8 @@ namespace Mono.CSharp {
                [Flags]
                public enum Status : byte {
                        ASSIGNED = 1,
-                       USED = 2
+                       USED = 2,
+                       HAS_OFFSET = 4          // Used by FieldMember.
                }
 
                static string[] attribute_targets = new string [] { "field" };
@@ -5200,7 +5206,7 @@ namespace Mono.CSharp {
 
        public abstract class FieldMember: FieldBase
        {
-               bool has_field_offset = false;
+               
 
                protected FieldMember (TypeContainer parent, Expression type, int mod,
                        int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
@@ -5212,7 +5218,7 @@ namespace Mono.CSharp {
                {
                        if (a.Type == TypeManager.field_offset_attribute_type)
                        {
-                               has_field_offset = true;
+                               status |= Status.HAS_OFFSET;
 
                                if (!Parent.HasExplicitLayout) {
                                        Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
@@ -5265,7 +5271,7 @@ namespace Mono.CSharp {
 
                public override void Emit ()
                {
-                       if (Parent.HasExplicitLayout && !has_field_offset && (ModFlags & Modifiers.STATIC) == 0) {
+                       if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
                                Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
                        }
 
index 41e3fe1c618affa39a89d960310341746fb1d0a8..76d44d0394aa68b6b5ea116c25f778779a09f961 100644 (file)
@@ -1226,6 +1226,13 @@ namespace Mono.CSharp {
 
                static public void Error_CannotImplicitConversion (Location loc, Type source, Type target)
                {
+                       if (source.Name == target.Name){
+                               Report.ExtraInformation (loc,
+                                        String.Format (
+                                               "The type {0} has two conflicting definitons, one comes from {0} and the other from {1}",
+                                               source.Assembly.FullName, target.Assembly.FullName));
+                                                        
+                       }
                        Report.Error (29, loc, "Cannot convert implicitly from {0} to `{1}'",
                                      source == TypeManager.anonymous_method_type ?
                                      "anonymous method" : "`" + TypeManager.CSharpName (source) + "'",
index 995a33783de2cb4f772b2a66689670ab6c5e166b..02fa2d2f647af4da7416ef0876b4bdcc5ae0d052 100755 (executable)
@@ -1902,9 +1902,8 @@ namespace Mono.CSharp
                                                getChar ();
                                                if (RootContext.Documentation != null && peekChar () == '/') {
                                                        getChar ();
-                                                       // Allow only ///ws.
                                                        // Don't allow ////.
-                                                       if ((d = peekChar ()) == ' ' || d == '\t') {
+                                                       if ((d = peekChar ()) != '/') {
                                                                if (doc_state == XmlCommentState.Allowed)
                                                                        handle_one_line_xml_comment ();
                                                                else if (doc_state == XmlCommentState.NotAllowed)
index d747102c73b65b444ae8881abc3f7f49b2181cc5..5910ddf73248b02a973340d769e18f5e533a908b 100755 (executable)
@@ -17,7 +17,12 @@ using System.Collections;
 using System.Globalization;
 using System.Reflection.Emit;
 using System.Reflection;
+
+#if BOOTSTRAP_WITH_OLDLIB
+using XmlElement = System.Object;
+#else
 using System.Xml;
+#endif
 
 namespace Mono.CSharp {
 
index c7a82c88aa70a7faf6c1326b108cb6d6a89987a7..7f5326ef5a7b029eaa869bc065f506ce909a5b90 100644 (file)
@@ -429,18 +429,40 @@ namespace Mono.CSharp {
                        for (int i = pd_count; i > 0; ) {
                                i--;
 
-                               if (invoke_pd.ParameterType (i) == pd.ParameterType (i) &&
-                                   invoke_pd.ParameterModifier (i) == pd.ParameterModifier (i))
+                               Type invoke_pd_type = invoke_pd.ParameterType (i);
+                               Type pd_type = pd.ParameterType (i);
+                               Parameter.Modifier invoke_pd_type_mod = invoke_pd.ParameterModifier (i);
+                               Parameter.Modifier pd_type_mod = pd.ParameterModifier (i);
+
+                               if (invoke_pd_type == pd_type &&
+                                   invoke_pd_type_mod == pd_type_mod)
                                        continue;
-                               else {
-                                       return null;
-                               }
+                               
+                               if (invoke_pd_type.IsSubclassOf (pd_type) && 
+                                               invoke_pd_type_mod == pd_type_mod)
+                                       if (RootContext.Version == LanguageVersion.ISO_1) {
+                                               Report.FeatureIsNotStandardized (loc, "contravariance");
+                                               return null;
+                                       } else
+                                               continue;
+                                       
+                               return null;
                        }
 
-                       if (((MethodInfo) invoke_mb).ReturnType == ((MethodInfo) mb).ReturnType)
+                       Type invoke_mb_retval = ((MethodInfo) invoke_mb).ReturnType;
+                       Type mb_retval = ((MethodInfo) mb).ReturnType;
+                       if (invoke_mb_retval == mb_retval)
                                return mb;
-                       else
-                               return null;
+                       
+                       if (mb_retval.IsSubclassOf (invoke_mb_retval))
+                               if (RootContext.Version == LanguageVersion.ISO_1) {
+                                       Report.FeatureIsNotStandardized (loc, "covariance");
+                                       return null;
+                               }
+                               else
+                                       return mb;
+                       
+                       return null;
                }
 
                // <summary>
@@ -843,6 +865,9 @@ namespace Mono.CSharp {
                        
                        Expression e = a.Expr;
 
+                       if (e is AnonymousMethod && RootContext.Version != LanguageVersion.ISO_1)
+                               return ((AnonymousMethod) e).Compatible (ec, type, false);
+
                        MethodGroupExpr mg = e as MethodGroupExpr;
                        if (mg != null)
                                return ResolveMethodGroupExpr (ec, mg);
diff --git a/mcs/mcs/doc-bootstrap.cs b/mcs/mcs/doc-bootstrap.cs
new file mode 100644 (file)
index 0000000..fb1092c
--- /dev/null
@@ -0,0 +1,59 @@
+//
+// doc-bootstrap.cs: Stub support for XML documentation.
+//
+// Author:
+//     Raja R Harinath <rharinath@novell.com>
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2004 Novell, Inc.
+//
+//
+
+#if BOOTSTRAP_WITH_OLDLIB
+
+using XmlElement = System.Object;
+
+namespace Mono.CSharp {
+       public class DocUtil
+       {
+               internal static void GenerateTypeDocComment (TypeContainer t, DeclSpace ds)
+               {
+               }
+
+               internal static void GenerateDocComment (MemberCore mc, DeclSpace ds)
+               {
+               }
+
+               public static string GetMethodDocCommentName (MethodCore mc, DeclSpace ds)
+               {
+                       return "";
+               }
+
+               internal static void OnMethodGenerateDocComment (MethodCore mc, DeclSpace ds, XmlElement el)
+               {
+               }
+
+               public static void GenerateEnumDocComment (Enum e, DeclSpace ds)
+               {
+               }
+       }
+
+       public class Documentation
+       {
+               public Documentation (string xml_output_filename)
+               {
+               }
+
+               public bool OutputDocComment (string asmfilename)
+               {
+                       return true;
+               }
+
+               public void GenerateDocComment ()
+               {
+               }
+       }
+}
+
+#endif
index c33e0e1ef68a019101dcdfcfc9ab4e5aa78c9376..20c720c3cd351155989bc8177b40678c6dc8ef69 100755 (executable)
@@ -9,6 +9,8 @@
 // (C) 2004 Novell, Inc.
 //
 //
+
+#if ! BOOTSTRAP_WITH_OLDLIB
 using System;
 using System.Collections;
 using System.Collections.Specialized;
@@ -807,3 +809,5 @@ namespace Mono.CSharp {
                }
        }
 }
+
+#endif
index 1e5f48814985541031083b2079d9efcdff105867..cfd883c64e00b06138cd3880b062dc09d1234564 100755 (executable)
@@ -18,7 +18,6 @@ namespace Mono.CSharp
        using System.IO;
        using System.Text;
        using System.Globalization;
-       using System.Xml;
        using System.Diagnostics;
 
        public enum Target {
index 8d548cec79d4c33fe5aeddb2e1fa57b94cf651bc..e0b786f6cddf983cc90253dfa0db0a76044414f0 100755 (executable)
@@ -207,6 +207,55 @@ namespace Mono.CSharp {
                        AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, loc);
                }
 
+               public static bool IsAccessorAccessible (Type invocation_type, MethodInfo mi, out bool must_do_cs1540_check)
+               {
+                       MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+
+                       must_do_cs1540_check = false; // by default we do not check for this
+
+                       //
+                       // If only accessible to the current class or children
+                       //
+                       if (ma == MethodAttributes.Private) {
+                               Type declaring_type = mi.DeclaringType;
+                                       
+                               if (invocation_type != declaring_type)
+                                       return TypeManager.IsSubclassOrNestedChildOf (invocation_type, declaring_type);
+
+                               return true;
+                       }
+                       //
+                       // FamAndAssem requires that we not only derivate, but we are on the
+                       // same assembly.  
+                       //
+                       if (ma == MethodAttributes.FamANDAssem){
+                               return (mi.DeclaringType.Assembly != invocation_type.Assembly);
+                       }
+
+                       // Assembly and FamORAssem succeed if we're in the same assembly.
+                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
+                               if (mi.DeclaringType.Assembly == invocation_type.Assembly)
+                                       return true;
+                       }
+
+                       // We already know that we aren't in the same assembly.
+                       if (ma == MethodAttributes.Assembly)
+                               return false;
+
+                       // Family and FamANDAssem require that we derive.
+                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
+                               if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
+                                       return false;
+
+                               if (!TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType))
+                                       must_do_cs1540_check = true;
+
+                               return true;
+                       }
+
+                       return true;
+               }
+
                /// <summary>
                ///   Performs semantic analysis on the Expression
                /// </summary>
@@ -2941,7 +2990,6 @@ namespace Mono.CSharp {
                public bool IsBase;
                MethodInfo getter, setter;
                bool is_static;
-               bool must_do_cs1540_check;
                
                Expression instance_expr;
                LocalTemporary temp;
@@ -3042,53 +3090,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               bool IsAccessorAccessible (Type invocation_type, MethodInfo mi)
-               {
-                       MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
-
-                       //
-                       // If only accessible to the current class or children
-                       //
-                       if (ma == MethodAttributes.Private) {
-                               Type declaring_type = mi.DeclaringType;
-                                       
-                               if (invocation_type != declaring_type)
-                                       return TypeManager.IsSubclassOrNestedChildOf (invocation_type, declaring_type);
-
-                               return true;
-                       }
-                       //
-                       // FamAndAssem requires that we not only derivate, but we are on the
-                       // same assembly.  
-                       //
-                       if (ma == MethodAttributes.FamANDAssem){
-                               return (mi.DeclaringType.Assembly != invocation_type.Assembly);
-                       }
-
-                       // Assembly and FamORAssem succeed if we're in the same assembly.
-                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
-                               if (mi.DeclaringType.Assembly == invocation_type.Assembly)
-                                       return true;
-                       }
-
-                       // We already know that we aren't in the same assembly.
-                       if (ma == MethodAttributes.Assembly)
-                               return false;
-
-                       // Family and FamANDAssem require that we derive.
-                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
-                               if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
-                                       return false;
-
-                               if (!TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType))
-                                       must_do_cs1540_check = true;
-
-                               return true;
-                       }
-
-                       return true;
-               }
-
                //
                // We also perform the permission checking here, as the PropertyInfo does not
                // hold the information for the accessibility of its setter/getter
@@ -3100,7 +3101,7 @@ namespace Mono.CSharp {
                        is_static = getter != null ? getter.IsStatic : setter.IsStatic;
                }
 
-               bool InstanceResolve (EmitContext ec)
+               bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
                {
                        if ((instance_expr == null) && ec.IsStatic && !is_static) {
                                SimpleName.Error_ObjectRefRequired (ec, loc, PropertyInfo.Name);
@@ -3161,12 +3162,13 @@ namespace Mono.CSharp {
                                return null;
                        } 
 
-                       if (!IsAccessorAccessible (ec.ContainerType, getter)) {
+                       bool must_do_cs1540_check;
+                       if (!IsAccessorAccessible (ec.ContainerType, getter, out must_do_cs1540_check)) {
                                Report.Error (122, loc, "'{0}.get' is inaccessible due to its protection level", PropertyInfo.Name);
                                return null;
                        }
                        
-                       if (!InstanceResolve (ec))
+                       if (!InstanceResolve (ec, must_do_cs1540_check))
                                return null;
 
                        //
@@ -3208,12 +3210,13 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (!IsAccessorAccessible (ec.ContainerType, setter)) {
+                       bool must_do_cs1540_check;
+                       if (!IsAccessorAccessible (ec.ContainerType, setter, out must_do_cs1540_check)) {
                                Report.Error (122, loc, "'{0}.set' is inaccessible due to its protection level", PropertyInfo.Name);
                                return null;
                        }
                        
-                       if (!InstanceResolve (ec))
+                       if (!InstanceResolve (ec, must_do_cs1540_check))
                                return null;
                        
                        //
@@ -3399,6 +3402,36 @@ namespace Mono.CSharp {
                        }
                }
 
+               bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
+               {
+                       if ((instance_expr == null) && ec.IsStatic && !is_static) {
+                               SimpleName.Error_ObjectRefRequired (ec, loc, EventInfo.Name);
+                               return false;
+                       }
+
+                       if (instance_expr != null) {
+                               instance_expr = instance_expr.DoResolve (ec);
+                               if (instance_expr == null)
+                                       return false;
+                       }
+
+                       //
+                       // This is using the same mechanism as the CS1540 check in PropertyExpr.
+                       // However, in the Event case, we reported a CS0122 instead.
+                       //
+                       if (must_do_cs1540_check && (instance_expr != null)) {
+                               if ((instance_expr.Type != ec.ContainerType) &&
+                                       ec.ContainerType.IsSubclassOf (instance_expr.Type)) {
+                                       Report.Error (122, loc, "'{0}' is inaccessible due to its protection level",
+                                               DeclaringType.Name + "." + EventInfo.Name);
+
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+
                public override Expression DoResolve (EmitContext ec)
                {
                        if (instance_expr != null) {
@@ -3407,9 +3440,20 @@ namespace Mono.CSharp {
                                        return null;
                        }
 
+                       bool must_do_cs1540_check;
+                       if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check)
+                                   && IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
+                               
+                               Report.Error (122, loc, "'{0}' is inaccessible due to its protection level",
+                                               DeclaringType.Name + "." + EventInfo.Name);
+                               return null;
+                       }
+
+                       if (!InstanceResolve (ec, must_do_cs1540_check))
+                               return null;
                        
                        return this;
-               }
+               }               
 
                public override void Emit (EmitContext ec)
                {
index ad984a9d3c37b11fff7d1f64ff567fa3557ebc87..5b4a76023f3dd9d5641fc9328f18c1360e7059b0 100755 (executable)
@@ -14,7 +14,6 @@ using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Globalization;
-using System.Xml;
 
 namespace Mono.CSharp {
 
index 1c0f3763b6d6d0ea45aa1e938edb746adc0901f9..2ca402281b086df8e4c10f1b6318d9f84c9358ee 100755 (executable)
@@ -5713,7 +5713,7 @@ namespace Mono.CSharp {
                        if (IsDelegate){
                                RequestedType = (new NewDelegate (type, Arguments, loc)).Resolve (ec);
                                if (RequestedType != null)
-                                       if (!(RequestedType is NewDelegate))
+                                       if (!(RequestedType is DelegateCreation))
                                                throw new Exception ("NewDelegate.Resolve returned a non NewDelegate: " + RequestedType.GetType ());
                                return RequestedType;
                        }
index 7b572cadaceb8e4ff2125533aea67b8c72093bca..a981252af40679f801f4beb5a6315e8e88054185 100644 (file)
@@ -13,6 +13,7 @@ convert.cs
 decl.cs
 delegate.cs
 doc.cs
+doc-bootstrap.cs
 enum.cs
 ecore.cs
 expression.cs
index 5a06e8034229906c8cef2945defb1be50b142eca..95e9a3c55bb0f628fa5b1667c5c17209821b7e7b 100755 (executable)
@@ -217,14 +217,8 @@ namespace Mono.CSharp {
                                if (resolved_ns != null)
                                        return resolved_ns;
 
-                               Namespace curr_ns = NamespaceEntry.NS;
-                               while ((curr_ns != null) && (resolved_ns == null)) {
-                                       resolved_ns = curr_ns.GetNamespace (Name, false);
-
-                                       if (resolved_ns == null)
-                                               curr_ns = curr_ns.Parent;
-                               }
-
+                               object resolved = NamespaceEntry.LookupForUsing (Name, Location);
+                               resolved_ns = resolved as Namespace;
                                return resolved_ns;
                        }
                }
@@ -252,19 +246,7 @@ namespace Mono.CSharp {
 
                                string alias = Alias.GetPartialName ();
 
-                               // According to section 16.3.1, the namespace-or-type-name is resolved
-                               // as if the immediately containing namespace body has no using-directives.
-                               resolved = NamespaceEntry.Lookup (null, alias, true, Location);
-
-                               NamespaceEntry curr_ns = NamespaceEntry.Parent;
-
-                               while ((curr_ns != null) && (resolved == null)) {
-                                       resolved = curr_ns.Lookup (null, alias, false, Location);
-
-                                       if (resolved == null)
-                                               curr_ns = curr_ns.Parent;
-                               }
-
+                               resolved = NamespaceEntry.LookupForUsing (alias, Location);
                                return resolved;
                        }
                }
@@ -399,7 +381,49 @@ namespace Mono.CSharp {
                                return ((Type) resolved).FullName;
                }
 
-               public object Lookup (DeclSpace ds, string name, bool ignore_using, Location loc)
+               //
+               // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is 
+               // resolved as if the immediately containing namespace body has no using-directives.
+               //
+               // Section 16.3.2 says that the same rule is applied when resolving the namespace-name
+               // in the using-namespace-directive.
+               //
+               public object LookupForUsing (string dotted_name, Location loc)
+               {
+                       int pos = dotted_name.IndexOf ('.');
+                       string simple_name = dotted_name;
+                       string rest = null;
+                       if (pos >= 0) {
+                               simple_name = dotted_name.Substring (0, pos);
+                               rest = dotted_name.Substring (pos + 1);
+                       }
+
+                       object o = NS.Lookup (null, simple_name);
+                       if (o == null && ImplicitParent != null)
+                               o = ImplicitParent.LookupNamespaceOrType (null, simple_name, loc);
+
+                       if (o == null || rest == null)
+                               return o;
+
+                       Namespace ns = o as Namespace;
+                       if (ns != null)
+                               return ns.Lookup (null, rest);
+                       
+                       Type nested = TypeManager.LookupType ((((Type) o).Name + "." + rest));
+                       return nested;
+               }
+
+               public object LookupNamespaceOrType (DeclSpace ds, string name, Location loc)
+               {
+                       object resolved = null;
+                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
+                               if ((resolved = curr_ns.Lookup (ds, name, loc)) != null)
+                                       break;
+                       }
+                       return resolved;
+               }
+
+               private object Lookup (DeclSpace ds, string name, Location loc)
                {
                        object o;
                        Namespace ns;
@@ -407,12 +431,17 @@ namespace Mono.CSharp {
                        //
                        // If name is of the form `N.I', first lookup `N', then search a member `I' in it.
                        //
+                       // FIXME: Remove this block.  Only simple names should come here.
+                       //        The bug: The loop in LookupNamespaceOrType continues if 
+                       //        the lookup for N succeeds but the nested lookup for I fails.
+                       //        This is one part of #52697.
+                       //
                        int pos = name.IndexOf ('.');
                        if (pos >= 0) {
                                string first = name.Substring (0, pos);
                                string last = name.Substring (pos + 1);
 
-                               o = Lookup (ds, first, ignore_using, loc);
+                               o = Lookup (ds, first, loc);
                                if (o == null)
                                        return null;
 
@@ -428,15 +457,12 @@ namespace Mono.CSharp {
                        }
 
                        //
-                       // Check whether it's a namespace.
+                       // Check whether it's in the namespace.
                        //
                        o = NS.Lookup (ds, name);
                        if (o != null)
                                return o;
 
-                       if (ignore_using)
-                               return null;
-
                        //
                        // Check aliases.
                        //
@@ -536,46 +562,29 @@ namespace Mono.CSharp {
 
                protected void error246 (Location loc, string name)
                {
-                       if (TypeManager.LookupType (name) != null)
-                               Report.Error (138, loc, "The using keyword only lets you specify a namespace, " +
-                                             "`" + name + "' is a class not a namespace.");
-                       else {
-                               Report.Error (246, loc, "The namespace `" + name +
-                                             "' can not be found (missing assembly reference?)");
-
-                               switch (name){
-                               case "Gtk": case "GtkSharp":
-                                       MsgtryPkg ("gtk-sharp");
-                                       break;
-
-                               case "Gdk": case "GdkSharp":
-                                       MsgtryPkg ("gdk-sharp");
-                                       break;
-
-                               case "Glade": case "GladeSharp":
-                                       MsgtryPkg ("glade-sharp");
-                                       break;
-                                                       
-                               case "System.Drawing":
-                                       MsgtryRef ("System.Drawing");
-                                       break;
-                                                       
-                               case "System.Web.Services":
-                                       MsgtryRef ("System.Web.Services");
-                                       break;
-
-                               case "System.Web":
-                                       MsgtryRef ("System.Web");
-                                       break;
-                                                       
-                               case "System.Data":
-                                       MsgtryRef ("System.Data");
-                                       break;
-
-                               case "System.Windows.Forms":
-                                       MsgtryRef ("System.Windows.Forms");
-                                       break;
-                               }
+                       Report.Error (246, loc, "The namespace `" + name +
+                                     "' can not be found (missing assembly reference?)");
+
+                       switch (name) {
+                       case "Gtk": case "GtkSharp":
+                               MsgtryPkg ("gtk-sharp");
+                               break;
+
+                       case "Gdk": case "GdkSharp":
+                               MsgtryPkg ("gdk-sharp");
+                               break;
+
+                       case "Glade": case "GladeSharp":
+                               MsgtryPkg ("glade-sharp");
+                               break;
+
+                       case "System.Drawing":
+                       case "System.Web.Services":
+                       case "System.Web":
+                       case "System.Data":
+                       case "System.Windows.Forms":
+                               MsgtryRef (name);
+                               break;
                        }
                }
 
@@ -590,7 +599,12 @@ namespace Mono.CSharp {
                                        if (ue.Resolve () != null)
                                                continue;
 
-                                       error246 (ue.Location, ue.Name);
+                                       if (LookupForUsing (ue.Name, ue.Location) == null)
+                                               error246 (ue.Location, ue.Name);
+                                       else
+                                               Report.Error (138, ue.Location, "The using keyword only lets you specify a namespace, " +
+                                                             "`" + ue.Name + "' is a class not a namespace.");
+
                                }
                        }
 
index 7749d6f5866bf3e36769ca90734e1277a3c086f2..4adde10bfe732243f4dc1ef4490ae0632ae95c3a 100644 (file)
@@ -94,7 +94,7 @@ namespace Mono.CSharp {
                                Console.Error.WriteLine (msg.ToString ());
 
                                foreach (string s in extra_information) 
-                                       Console.Error.WriteLine (s + MessageType + ")");
+                                       Console.Error.WriteLine (s + MessageType);
 
                                extra_information.Clear ();
 
index 146f6a6a6f238705686793dbe01cc85da1fb6e94..f9cc920d2adabce8f5cb92fe44ea05cc0385e08b 100755 (executable)
@@ -14,7 +14,6 @@ using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
-using System.Xml;
 
 namespace Mono.CSharp {
 
@@ -490,19 +489,12 @@ namespace Mono.CSharp {
 
                static Type NamespaceLookup (DeclSpace ds, string name, Location loc)
                {
-                       //
-                       // Try in the current namespace and all its implicit parents
-                       //
-                       for (NamespaceEntry ns = ds.NamespaceEntry; ns != null; ns = ns.ImplicitParent) {
-                               object result = ns.Lookup (ds, name, false, loc);
-                               if (result == null)
-                                       continue;
-
-                               if (result is Type)
-                                       return (Type) result;
-
+                       object result = ds.NamespaceEntry.LookupNamespaceOrType (ds, name, loc);
+                       if (result == null)
                                return null;
-                       }
+
+                       if (result is Type)
+                               return (Type) result;
 
                        return null;
                }
index c040ebe328c64fc57d8ff342371ede6e07aab76c..de7f0232b7fe7b31aa3cf9b3098fc83ee174444e 100755 (executable)
@@ -21,6 +21,7 @@ namespace Mono.CSharp {
        public interface ParameterData {
                Type ParameterType (int pos);
                int  Count { get; }
+               bool HasParams { get; }
                string ParameterName (int pos);
                string ParameterDesc (int pos);
                Parameter.Modifier ParameterModifier (int pos);
@@ -130,6 +131,12 @@ namespace Mono.CSharp {
                                return is_varargs ? pi.Length + 1 : pi.Length;
                        }
                }
+
+               public bool HasParams {
+                       get {
+                               return this.last_arg_is_params;
+                       }
+               }
                
        }
 
@@ -159,6 +166,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool HasParams {
+                       get {
+                               return Parameters.ArrayParameter != null;
+                       }
+               }
+
                Parameter GetParameter (int pos)
                {
                        Parameter [] fixed_pars = Parameters.FixedParameters;
index 8e513928d0543dfd3f7968e3cc29c468c7f3bd6c..e83f069a179c72eea28fdaf744193dd164fc61c8 100644 (file)
@@ -1,3 +1,13 @@
+2004-12-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlResultVisitor.cs : ... was still broken.
+
+2004-12-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XmlResultVisitor.cs : Local fix - don't use WriteCData() which
+         cannot escape invalid characters. It broke VB unit test. See also:
+         http://sourceforge.net/tracker/?group_id=10749&atid=110749&func=detail&aid=1073539
+
 2004-11-23  Raja R Harinath  <rharinath@novell.com>
 
        * Makefile (NO_INSTALL) [PROFILE=net_2_0]: Don't install dll.
index 8de6378d8c1e2b73919667d74d13656f3332584d..a28c7bff4944c927a177f9ef3355514a0e4e0be9 100755 (executable)
@@ -103,12 +103,12 @@ namespace NUnit.Util
                                                xmlWriter.WriteStartElement("error");
                                
                                        xmlWriter.WriteStartElement("message");
-                                       xmlWriter.WriteCData( EncodeCData( caseResult.Message ) );
+                                       xmlWriter.WriteString( caseResult.Message );
                                        xmlWriter.WriteEndElement();
                                
                                        xmlWriter.WriteStartElement("stack-trace");
                                        if(caseResult.StackTrace != null)
-                                               xmlWriter.WriteCData( EncodeCData( StackTraceFilter.Filter( caseResult.StackTrace ) ) );
+                                               xmlWriter.WriteString( StackTraceFilter.Filter( caseResult.StackTrace ) );
                                        xmlWriter.WriteEndElement();
                                
                                        xmlWriter.WriteEndElement();
index 438abe03e8d2a2d5f8e5e3df300f4d33f2750732..28c8f14e95a412ce0dbc177e6e445bf73480464d 100755 (executable)
@@ -1,3 +1,52 @@
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * gen-116.cs: New test for #69781.
+
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * gen-115.cs: New test for #58305.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (NEW_TEST_SOURCES_common): Add test-327 and test-328.
+
+       * test-326.cs (Main): Set return type to int, not void.
+
+2004-12-02  Marek Safar <marek.safar@seznam.cz>
+
+       * test-325.cs: New test for #70102.
+
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * xml-025.inc : was missing.
+
+2004-12-02  Marek Safar <marek.safar@seznam.cz>
+
+       * test-324.cs: New test.
+
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Makefile : added lines for /doc test files.
+       * harness.nk : added xmldoc test lines.
+       * xmldocdiff.cs : small test tool for verifying /doc output.
+       * xml-001.cs, xml-001-ref.xml, xml-002.cs, xml-002-ref.xml,
+         xml-003.cs, xml-003-ref.xml, xml-004.cs, xml-004-ref.xml,
+         xml-005.cs, xml-005-ref.xml, xml-006.cs, xml-006-ref.xml,
+         xml-007.cs, xml-007-ref.xml, xml-008.cs, xml-008-ref.xml,
+         xml-009.cs, xml-009-ref.xml, xml-010.cs, xml-010-ref.xml,
+         xml-011.cs, xml-011-ref.xml, xml-012.cs, xml-012-ref.xml,
+         xml-013.cs, xml-013-ref.xml, xml-014.cs, xml-014-ref.xml,
+         xml-015.cs, xml-015-ref.xml, xml-016.cs, xml-016-ref.xml,
+         xml-017.cs, xml-017-ref.xml, xml-018.cs, xml-018-ref.xml,
+         xml-019.cs, xml-019-ref.xml, xml-020.cs, xml-020-ref.xml,
+         xml-021.cs, xml-021-ref.xml, xml-022.cs, xml-022-ref.xml,
+         xml-023.cs, xml-023-ref.xml, xml-024.cs, xml-024-ref.xml,
+         xml-025.cs, xml-025-ref.xml, xml-026.cs, xml-026-ref.xml,
+         xml-027.cs, xml-027-ref.xml, xml-028.cs, xml-028-ref.xml,
+         xml-029.cs, xml-029-ref.xml, xml-030.cs, xml-030-ref.xml,
+         xml-031.cs, xml-031-ref.xml, xml-032.cs, xml-032-ref.xml :
+         tests for /doc feature.
+
 2004-11-30  Martin Baulig  <martin@ximian.com>
 
        * Makefile: Enable gen-110; it's about virtual generic methods and
index d88ae2bbfd5c23414936a997c8acdf5991c24fe1..6923e9e2bda3d0e8cc979e7d8746decea020d376 100644 (file)
@@ -26,7 +26,10 @@ USE_MCS_FLAGS :=
 # He may also move some to TEST_EXCLUDE_net_2_0 if some of the merges are inappropriate for GMCS.
 #
 NEW_TEST_SOURCES_common = test-294 test-304 test-305 test-306 test-307 test-318 mtest-5-dll mtest-5-exe \
-                       test-319-dll test-319-exe test-320 test-323 test-40
+                       test-319-dll test-319-exe test-320 test-323 test-324 test-325 test-326 \
+                       test-327 test-328 test-40 \
+                       covariance-1 covariance-2 covariance-3 \
+                       $(TEST_SOURCES_XML)
 
 #
 # Please do _not_ add any tests here - all new tests should go into NEW_TEST_SOURCES_common
@@ -103,7 +106,7 @@ TEST_SOURCES_net_2_0 = \
        gen-81  gen-82  gen-83  gen-84  gen-85  gen-86  gen-87  gen-88  gen-89  gen-90  \
        gen-91  gen-92  gen-93  gen-94  gen-95  gen-96  gen-97                  gen-100 \
        gen-101 gen-102 gen-103 gen-104 gen-105 gen-106 gen-107 gen-108 gen-109 gen-110 \
-       gen-111 gen-112
+       gen-111 gen-112 gen-113 gen-114 gen-115 gen-116
 
 TEST_EXCLUDES_net_2_0 = $(NEW_TEST_SOURCES_common)
 
@@ -175,7 +178,7 @@ TEST_TAG = mcs
 endif
 
 .PHONY: test-harness test-harness-run
-test-harness:
+test-harness: xmldocdiff.exe
        @$(MAKE) -s test-harness-run
 
 exe_tests := $(filter %-exe, $(TEST_SOURCES))
@@ -218,3 +221,22 @@ ilasm:
        $(INTERNAL_ILASM) /dll property-il.il
        $(CSCOMPILE) /r:property-il.dll property-main.cs /out:property-main.exe
        $(TEST_RUNTIME) property-main.exe
+
+
+#
+# Test for /doc option; need to compare result documentation files.
+#
+
+TEST_SOURCES_XML = \
+       xml-001 xml-002 xml-003 xml-004 xml-005 xml-006 xml-007 xml-008 xml-009 xml-010 \
+       xml-011 xml-012 xml-013 xml-014 xml-015 xml-016 xml-017 xml-018 xml-019 xml-020 \
+       xml-021 xml-022 xml-023 xml-024 xml-025 xml-026 xml-028 xml-029 xml-030
+
+# currently no formalization on 'cref' attribute was found, so there are some
+# differences between MS.NET and mono.
+TEST_SOURCES_XML_PENDING = xml-027
+
+xml-doc-tests := $(filter xml-%, $(TEST_SOURCES))
+
+xmldocdiff.exe:
+       $(CSCOMPILE) xmldocdiff.cs
diff --git a/mcs/tests/covariance-1.cs b/mcs/tests/covariance-1.cs
new file mode 100644 (file)
index 0000000..9eba405
--- /dev/null
@@ -0,0 +1,79 @@
+// Compiler options: -langversion:default
+// Test for covariance support in delegates
+//
+
+using System;
+
+ public class A {
+        protected string name;
+        
+        public A (string name)
+        {
+                this.name = "A::" + name;
+        }
+
+        public A ()
+        {
+        }
+
+        public string Name {
+                get {
+                        return name;
+                }
+        }
+ }
+
+ public class B : A {
+        public B (string name)
+        {
+                this.name = "B::" + name;
+        }
+
+        public B ()
+        {
+        }
+ }
+
+ public class C : B {
+        public C (string name)
+        {
+                this.name = "C::" + name;
+        }
+ }
+
+ public class Tester {
+
+        delegate A MethodHandler (string name);
+
+        static A MethodSampleA (string name)
+        {
+                return new A (name);
+        }
+
+        static B MethodSampleB (string name)
+        {
+                return new B (name);
+        }
+
+        static C MethodSampleC (string name)
+        {
+                return new C (name);
+        }
+
+        static void Main ()
+        {
+                MethodHandler a = MethodSampleA;
+                MethodHandler b = MethodSampleB;
+                MethodHandler c = MethodSampleC;
+
+                A instance1 = a ("Hello");
+                A instance2 = b ("World");
+                A instance3 = c ("!");
+
+                Console.WriteLine (instance1.Name);
+                Console.WriteLine (instance2.Name);
+                Console.WriteLine (instance3.Name);
+        }
+       
+ }
+
diff --git a/mcs/tests/covariance-2.cs b/mcs/tests/covariance-2.cs
new file mode 100644 (file)
index 0000000..d1fd42e
--- /dev/null
@@ -0,0 +1,89 @@
+// Compiler options: -langversion:default
+//
+// Test for contravariance support in delegates
+//
+
+using System;
+
+ public class A {
+        protected string name;
+        
+        public A (string name)
+        {
+                this.name = "A::" + name;
+        }
+
+        public A ()
+        {
+        }
+
+        public string Name {
+                get {
+                        return name;
+                }
+        }
+ }
+
+ public class B : A {
+        public B (string name)
+        {
+                this.name = "B::" + name;
+        }
+
+        public B ()
+        {
+        }
+ }
+
+ public class C : B {
+        string value;
+
+        public C (string name, string value)
+        {
+                this.name = "C::" + name;
+                this.value = value;
+        }
+
+        public string Value {
+                get {
+                        return value;
+                }
+        }
+ }
+
+ public class Tester {
+
+        delegate string MethodHandler (C c);
+
+        static string MethodSampleA (A value)
+        {
+                return value.Name;
+        }
+
+        static string MethodSampleB (B value)
+        {
+                return value.Name;
+        }
+
+        static string MethodSampleC (C value)
+        {
+                return value.Name + " " + value.Value;
+        }
+
+        static void Main ()
+        {
+                MethodHandler da = MethodSampleA;
+                MethodHandler db = MethodSampleB;
+                MethodHandler dc = MethodSampleC;
+
+                C a = new C ("Hello", "hello");
+                C b = new C ("World", "world");
+                C c = new C ("!", "!!!");
+
+                Console.WriteLine (da (a));
+                Console.WriteLine (db (b));
+                Console.WriteLine (dc (c));
+        }
+       
+ }
+
diff --git a/mcs/tests/covariance-3.cs b/mcs/tests/covariance-3.cs
new file mode 100644 (file)
index 0000000..e63ebc7
--- /dev/null
@@ -0,0 +1,77 @@
+// Compiler options: -langversion:default
+//
+// Test for contravariance support in delegates
+//
+
+using System;
+
+ public class A {
+        protected string name;
+        
+        public A (string name)
+        {
+                this.name = "A::" + name;
+        }
+
+        public A ()
+        {
+        }
+
+        public string Name {
+                get {
+                        return name;
+                }
+        }
+ }
+
+ public class B : A {
+        public B (string name)
+        {
+                this.name = "B::" + name;
+        }
+
+        public B ()
+        {
+        }
+ }
+
+ public class C : B {
+        string value;
+
+        public C (string name, string value)
+        {
+                this.name = "C::" + name;
+                this.value = value;
+        }
+
+        public string Value {
+                get {
+                        return value;
+                }
+        }
+ }
+
+ public class Tester {
+
+        delegate void MethodHandler (C c1, C c2, C c3);
+
+        static void MethodSample (B b, A a, C c)
+        {
+                Console.WriteLine ("b = {0}", b.Name);
+                Console.WriteLine ("a = {0}", a.Name);
+                Console.WriteLine ("c = {0}, {1}", c.Name, c.Value);
+        }
+
+        static void Main ()
+        {
+                MethodHandler mh = MethodSample;
+
+                C a = new C ("Hello", "hello");
+                C b = new C ("World", "world");
+                C c = new C ("!", "!!!");
+
+                mh (b, a, c);
+        }
+       
+ }
+
diff --git a/mcs/tests/gen-113.cs b/mcs/tests/gen-113.cs
new file mode 100644 (file)
index 0000000..93215c2
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+public delegate V Mapper<T,V> (T item);
+
+public class List<T>
+{
+       public void Map<V> (Mapper<T,V> mapper)
+       { }
+}
+
+class X
+{
+       static void Main ()
+       {
+               List<int> list = new List<int> ();
+               list.Map (new Mapper<int,double> (delegate (int i) { return i/10.0; }));
+       }
+}
+
diff --git a/mcs/tests/gen-114.cs b/mcs/tests/gen-114.cs
new file mode 100644 (file)
index 0000000..49b0026
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+
+public class NaturalComparer<T> : IComparer<T>
+       where T: IComparable<T>
+{
+       public int Compare (T a, T b)
+       {
+               return a.CompareTo (b);
+       }
+}
+
+public class X
+{
+       class Test : IComparable<Test>
+       {
+               public int CompareTo (Test that)
+               {
+                       return 0;
+               }
+
+               public bool Equals (Test that)
+               {
+                       return false;
+               }
+       }
+
+       static void Main ()
+       {
+               IComparer<Test> cmp = new NaturalComparer<Test> ();
+               Test a = new Test ();
+               Test b = new Test ();
+               cmp.Compare (a, b);
+       }
+}
diff --git a/mcs/tests/gen-115.cs b/mcs/tests/gen-115.cs
new file mode 100644 (file)
index 0000000..f8aa4be
--- /dev/null
@@ -0,0 +1,286 @@
+//-- ex-gen-class-linkedlist
+//-- ex-anonymous-method-linkedlist
+//-- ex-gen-printable
+//-- ex-gen-interface-ilist
+//-- ex-gen-linkedlist-map
+//-- ex-gen-linkedlistenumerator
+//-- ex-gen-delegate-fun
+
+// A generic LinkedList class
+
+using System;
+using System.IO;                        // TextWriter
+using System.Collections.Generic;       // IEnumerable<T>, IEnumerator<T>
+
+public delegate R Mapper<A,R>(A x);
+
+public interface IMyList<T> : IEnumerable<T> {
+  int Count { get; }                    // Number of elements
+  T this[int i] { get; set; }           // Get or set element at index i
+  void Add(T item);                     // Add element at end
+  void Insert(int i, T item);           // Insert element at index i
+  void RemoveAt(int i);                 // Remove element at index i
+  IMyList<U> Map<U>(Mapper<T,U> f);     // Map f over all elements
+}
+
+public class LinkedList<T> : IMyList<T> {
+  protected int size;               // Number of elements in the list
+  protected Node first, last;       // Invariant: first==null iff last==null
+
+  protected class Node {
+    public Node prev, next;
+    public T item;
+
+    public Node(T item) {
+      this.item = item; 
+    }
+
+    public Node(T item, Node prev, Node next) {
+      this.item = item; this.prev = prev; this.next = next; 
+    }
+  }
+
+  public LinkedList() {
+    first = last = null;
+    size = 0;
+  }
+
+  public LinkedList(params T[] arr) : this() {
+    foreach (T x in arr) 
+      Add(x);
+  }
+
+  public int Count {
+    get { return size; }
+  }
+
+  public T this[int i] {
+    get { return get(i).item; }
+    set { get(i).item = value; }
+  }      
+
+  private Node get(int n) {
+    if (n < 0 || n >= size)
+      throw new IndexOutOfRangeException();
+    else if (n < size/2) {              // Closer to front
+      Node node = first;
+      for (int i=0; i<n; i++)
+        node = node.next;
+      return node;
+    } else {                            // Closer to end
+      Node node = last;
+      for (int i=size-1; i>n; i--)
+        node = node.prev;
+      return node;
+    }
+  }
+
+  public void Add(T item) { 
+    Insert(size, item); 
+  }
+
+  public void Insert(int i, T item) { 
+    if (i == 0) {
+      if (first == null) // and thus last == null
+        first = last = new Node(item);
+      else {
+        Node tmp = new Node(item, null, first);
+        first.prev = tmp;
+        first = tmp;
+      }
+      size++;
+    } else if (i == size) {
+      if (last == null) // and thus first = null
+        first = last = new Node(item);
+      else {
+        Node tmp = new Node(item, last, null);
+        last.next = tmp;
+        last = tmp;
+      }
+      size++; 
+    } else {
+      Node node = get(i);
+      // assert node.prev != null;
+      Node newnode = new Node(item, node.prev, node);
+      node.prev.next = newnode;
+      node.prev = newnode;
+      size++;
+    }
+  }
+
+  public void RemoveAt(int i) {
+    Node node = get(i);
+    if (node.prev == null) 
+      first = node.next;
+    else
+      node.prev.next = node.next;
+    if (node.next == null) 
+      last = node.prev;
+    else
+      node.next.prev = node.prev;       
+    size--;
+  }
+
+  public override bool Equals(Object that) {
+    if (that != null && GetType() == that.GetType() 
+       && this.size == ((IMyList<T>)that).Count) {
+      Node thisnode = this.first;
+      IEnumerator<T> thatenm = ((IMyList<T>)that).GetEnumerator();
+      while (thisnode != null) {
+        if (!thatenm.MoveNext())
+          throw new ApplicationException("Impossible: LinkedList<T>.Equals");
+        // assert MoveNext() was true (because of the above size test)
+        if (!thisnode.item.Equals(thatenm.Current))
+          return false;
+        thisnode = thisnode.next; 
+      }
+      // assert !MoveNext(); // because of the size test
+      return true;
+    } else
+      return false;
+  }
+
+  public override int GetHashCode() {
+    int hash = 0;
+    foreach (T x in this)
+      hash ^= x.GetHashCode();
+    return hash;
+  }
+
+  public static explicit operator LinkedList<T>(T[] arr) {
+    return new LinkedList<T>(arr);
+  }
+
+  public static LinkedList<T> operator +(LinkedList<T> xs1, LinkedList<T> xs2) {
+    LinkedList<T> res = new LinkedList<T>();
+    foreach (T x in xs1) 
+      res.Add(x);
+    foreach (T x in xs2) 
+      res.Add(x);
+    return res;
+  }
+
+  public IMyList<U> Map<U>(Mapper<T,U> f) {
+    LinkedList<U> res = new LinkedList<U>();
+    foreach (T x in this) 
+      res.Add(f(x));
+    return res;
+  }
+
+  public IEnumerator<T> GetEnumerator() {
+    return new LinkedListEnumerator(this);
+  }
+
+  private class LinkedListEnumerator : IEnumerator<T> {
+    T curr;                     // The enumerator's current element
+    bool valid;                 // Is the current element valid?
+    Node next;                  // Node holding the next element, or null
+
+    public LinkedListEnumerator(LinkedList<T> lst) {
+      next = lst.first; valid = false;
+    }
+    
+    public T Current {
+      get { 
+        if (valid) 
+          return curr; 
+        else
+          throw new InvalidOperationException();
+      }
+    }
+    
+    public bool MoveNext() {
+      if (next != null)  {
+        curr = next.item; next = next.next; valid = true;
+      } else 
+        valid = false; 
+      return valid;
+    }
+
+    public void Dispose() {
+      curr = default(T); next = null; valid = false;
+    }
+  }
+}
+
+class SortedList<T> : LinkedList<T> where T : IComparable<T> {
+  // Sorted insertion
+  public void Insert(T x) { 
+    Node node = first;
+    while (node != null && x.CompareTo(node.item) > 0) 
+      node = node.next;
+    if (node == null)           // x > all elements; insert at end
+      Add(x);
+    else {                      // x <= node.item; insert before node
+      Node newnode = new Node(x);
+      if (node.prev == null)    // insert as first element
+        first = newnode;
+      else 
+        node.prev.next = newnode;
+      newnode.next = node;
+      newnode.prev = node.prev;
+      node.prev = newnode;
+    }
+  }
+}
+
+interface IPrintable {
+  void Print(TextWriter fs);
+}
+class PrintableLinkedList<T> : LinkedList<T>, IPrintable where T : IPrintable {
+  public void Print(TextWriter fs) {
+    bool firstElement = true;
+    foreach (T x in this) {
+      x.Print(fs);
+      if (firstElement) 
+        firstElement = false;
+      else
+        fs.Write(", ");
+    }
+  }
+}
+
+class MyString : IComparable<MyString> {
+  private readonly String s;
+  public MyString(String s) {
+    this.s = s;
+  }
+  public int CompareTo(MyString that) {
+    return String.Compare(that.Value, s);       // Reverse ordering
+  }
+  public bool Equals(MyString that) {
+    return that.Value == s;
+  }
+  public String Value {
+    get { return s; }
+  }
+}
+
+class MyTest {
+  public static void Main(String[] args) {
+    LinkedList<double> dLst = new LinkedList<double>(7.0, 9.0, 13.0, 0.0);
+    foreach (double d in dLst)
+      Console.Write("{0} ", d);
+    Console.WriteLine();
+    IMyList<int> iLst = 
+      dLst.Map<int>(new Mapper<double, int>(Math.Sign));
+    foreach (int i in iLst)
+      Console.Write("{0} ", i);
+    Console.WriteLine();
+    IMyList<String> sLst = 
+      dLst.Map<String>(delegate(double d) { return "s" + d; });
+    foreach (String s in sLst)
+      Console.Write("{0} ", s);
+    Console.WriteLine();
+    // Testing SortedList<MyString>
+    SortedList<MyString> sortedLst = new SortedList<MyString>();
+    sortedLst.Insert(new MyString("New York"));
+    sortedLst.Insert(new MyString("Rome"));
+    sortedLst.Insert(new MyString("Dublin"));
+    sortedLst.Insert(new MyString("Riyadh"));
+    sortedLst.Insert(new MyString("Tokyo"));
+    foreach (MyString s in sortedLst)
+      Console.Write("{0}   ", s.Value);
+    Console.WriteLine();
+  }
+}
diff --git a/mcs/tests/gen-116.cs b/mcs/tests/gen-116.cs
new file mode 100644 (file)
index 0000000..4fe091b
--- /dev/null
@@ -0,0 +1,51 @@
+using System;
+
+namespace Slow
+{
+       public interface ITest
+       {
+               void DoNothing<T>()
+                       where T : class;
+       }
+
+       public class Test : ITest
+       {
+               public void DoNothing<T>()
+                       where T : class
+               {
+                       T x = null;
+               }
+       }
+
+       class Program
+       {
+               static void Main(string[] args)
+               {
+                       const int iterations = 10000;
+
+                       Test test = new Test ();
+            
+                       DateTime start = DateTime.Now;
+                       Console.Write ("Calling Test.DoNothing<Program>() on an object reference...  ");
+                       for (int i = 0; i < iterations; ++i)
+                       {
+                               test.DoNothing<Program> ();
+                       }
+                       DateTime end = DateTime.Now;
+                       TimeSpan duration = end - start;
+                       Console.WriteLine ("Took " + duration.TotalMilliseconds + " ms.");
+           
+                       ITest testInterface = test;
+
+                       start = DateTime.Now;
+                       Console.Write ("Calling Test.DoNothing<Program>() on an interface reference...  ");
+                       for (int i = 0; i < iterations; ++i)
+                       {
+                               testInterface.DoNothing<Program> ();
+                       }
+                       end = DateTime.Now;
+                       duration = end - start;
+                       Console.WriteLine ("Took " + duration.TotalMilliseconds + " ms.");
+               }
+       }
+}
index c99375c69fd5ca30db179dcebb917936aee59198..326dc7d93b69a5b1a15c12c2def6be73611ce57f 100644 (file)
@@ -9,6 +9,8 @@ ifeq (default, $(PROFILE))
 MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_MCS)
 endif
 
+XMLDOCDIFF = $(TEST_RUNTIME) ../xmldocdiff.exe
+
 all-local $(STD_TARGETS:=-local):
 
 %.res:
@@ -20,8 +22,17 @@ all-local $(STD_TARGETS:=-local):
          if test -f $*.exe; then \
            echo '*** $(TEST_RUNTIME) -O=-all ./$*.exe' >> $$testlogfile ; \
              if $(TEST_RUNTIME) -O=-all ./$*.exe >> $$testlogfile 2>&1 ; then \
-               echo "PASS: $*" > $@ ; \
-               rm -f $$testlogfile ; \
+               if test -f $*.xml; then \
+                 if $(XMLDOCDIFF) ../$*-ref.xml $*.xml >> $$testlogfile ; then \
+                   echo "PASS: $*: xml comparison" > $@ ; \
+                   rm -f $$testlogfile ; \
+                 else \
+                   echo "FAIL: $*: xml comparison" > $@ ; \
+                 fi \
+               else \
+                 echo "PASS: $*" > $@ ; \
+                 rm -f $$testlogfile ; \
+               fi \
              else \
                echo "Exit code: $$?" >> $$testlogfile ; \
                echo "FAIL: $*" > $@ ; \
diff --git a/mcs/tests/test-324.cs b/mcs/tests/test-324.cs
new file mode 100644 (file)
index 0000000..20dde5e
--- /dev/null
@@ -0,0 +1,30 @@
+using System;
+
+public class A {
+        public void DoStuff ()
+        {
+                Console.WriteLine ("stuff");
+        }
+}
+
+public struct B {
+    public bool Val {
+        get {
+            return false;
+        }
+    }
+}
+
+public class T : MarshalByRefObject {
+        internal static A a = new A ();
+        public static B b;
+}
+
+public class Driver {
+
+        public static void Main ()
+        {
+                T.a.DoStuff ();
+                bool b = T.b.Val;
+        }
+}
diff --git a/mcs/tests/test-325.cs b/mcs/tests/test-325.cs
new file mode 100644 (file)
index 0000000..92b97fe
--- /dev/null
@@ -0,0 +1,21 @@
+using System; 
+public class RequestAttribute: Attribute { 
+       public RequestAttribute(string a, string b, params string[] c) 
+       { 
+        
+       } 
+} 
+public class MyClass { 
+       [Request("somereq", "result")] 
+       public static int SomeRequest() 
+       { 
+               return 0; 
+       } 
+        
+       public static void Main() 
+       { 
+               SomeRequest(); 
+       } 
+}
diff --git a/mcs/tests/test-326.cs b/mcs/tests/test-326.cs
new file mode 100644 (file)
index 0000000..5bb9a0f
--- /dev/null
@@ -0,0 +1,20 @@
+// Compiler options: -langversion:default
+// Anonymous method fix, implicit conversion inside an old-style constructor
+// Bug 70150
+using System;
+public delegate double Mapper (int item);
+
+class X
+{
+        static int Main ()
+        {
+                Mapper mapper = new Mapper (delegate (int i){
+                       return i * 12; });
+
+               if (mapper (3) == 36)
+                       return 0;
+
+               // Failure
+               return 1;
+        }
+}
diff --git a/mcs/tests/test-327.cs b/mcs/tests/test-327.cs
new file mode 100644 (file)
index 0000000..91df691
--- /dev/null
@@ -0,0 +1,14 @@
+class X2 {}
+namespace A {
+       enum X1 { x1 };
+       enum X2 { x2 };
+}
+namespace A.B {
+       using Y1 = X1;
+       using Y2 = X2;
+       class Tester {
+               internal static Y1 y1 = Y1.x1;
+               internal static Y2 y2 = Y2.x2;
+               static void Main() { }
+       }
+}
diff --git a/mcs/tests/test-328.cs b/mcs/tests/test-328.cs
new file mode 100644 (file)
index 0000000..f0bc4c4
--- /dev/null
@@ -0,0 +1,13 @@
+namespace X {
+       enum Z { x };
+}
+namespace A {
+       using Y = X;
+       namespace B {
+               using Y;
+               class Tester {
+                       internal static Z z = Z.x;
+                       static void Main() { }
+               }
+       }
+}
diff --git a/mcs/tests/xml-001-ref.xml b/mcs/tests/xml-001-ref.xml
new file mode 100755 (executable)
index 0000000..d507f84
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-001</name>\r
+    </assembly>\r
+    <members>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-001.cs b/mcs/tests/xml-001.cs
new file mode 100755 (executable)
index 0000000..bc1d859
--- /dev/null
@@ -0,0 +1,16 @@
+// Compiler options: -doc:xml-001.xml
+using System;
+
+/// <summary>
+/// xml comment on namespace ... is not allowed.
+/// </summary>
+namespace Testing
+{
+       public class A
+       {               
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-002-ref.xml b/mcs/tests/xml-002-ref.xml
new file mode 100755 (executable)
index 0000000..b9ca61a
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-002</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test">\r
+            <summary>
+            comment on class
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.Test2" -->\r
+        <member name="T:Testing.Test3">\r
+                       <summary>
+                       another Java-style documentation style
+                       </summary>
+        </member>\r
+        <member name="T:Testing.Test4">\r
+            indentation level test <seealso
+            cref="T:Testing.Test" />.
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-002.cs b/mcs/tests/xml-002.cs
new file mode 100755 (executable)
index 0000000..f18e324
--- /dev/null
@@ -0,0 +1,39 @@
+// Compiler options: -doc:xml-002.xml
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment on class
+       /// </summary>
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+
+       /// <summary>
+       /// Incorrect comment markup. See <see cref="T:Testing.Test" /> too.
+       /// </incorrect>
+       public class Test2
+       {
+       }
+
+       /**
+               <summary>
+               another Java-style documentation style
+               </summary>
+       */
+       public class Test3
+       {
+       }
+
+               /// indentation level test <seealso
+               ///     cref="T:Testing.Test" />.
+public class Test4
+{
+}
+
+}
+
diff --git a/mcs/tests/xml-003-ref.xml b/mcs/tests/xml-003-ref.xml
new file mode 100755 (executable)
index 0000000..02268c5
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-003</name>\r
+    </assembly>\r
+    <members>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-003.cs b/mcs/tests/xml-003.cs
new file mode 100755 (executable)
index 0000000..6840438
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:xml-003.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+                       /// here is an extraneous comment
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-004-ref.xml b/mcs/tests/xml-004-ref.xml
new file mode 100755 (executable)
index 0000000..a8e5e51
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-004</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.StructTest">\r
+            <summary> 
+            comment for struct
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.StructTest2" -->\r
+        <member name="T:Testing.StructTest3">\r
+                       <summary>
+                       Java style commet
+                       </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-004.cs b/mcs/tests/xml-004.cs
new file mode 100755 (executable)
index 0000000..7fca084
--- /dev/null
@@ -0,0 +1,36 @@
+// Compiler options: -doc:xml-004.xml
+using System;
+
+namespace Testing
+{
+       /// <summary> 
+       /// comment for struct
+       /// </summary>
+       public struct StructTest
+       {
+       }
+
+       /// <summary> 
+       /// incorrect markup comment for struct
+       /// </incorrect>
+       public struct StructTest2
+       {
+       }
+
+       /**
+               <summary>
+               Java style commet
+               </summary>
+       */
+       public struct StructTest3
+       {
+       }
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-005-ref.xml b/mcs/tests/xml-005-ref.xml
new file mode 100755 (executable)
index 0000000..77005a3
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-005</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.InterfaceTest">\r
+            <summary>
+            comment for interface
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.InterfaceTest2" -->\r
+        <member name="T:Testing.InterfaceTest3">\r
+                       <summary>
+                       Java style comment for interface
+                       </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-005.cs b/mcs/tests/xml-005.cs
new file mode 100755 (executable)
index 0000000..7d33136
--- /dev/null
@@ -0,0 +1,36 @@
+// Compiler options: -doc:xml-005.xml
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment for interface
+       /// </summary>
+       public interface InterfaceTest
+       {
+       }
+
+       /// <summary>
+       /// incorrect markup comment for interface
+       /// </incorrect>
+       public interface InterfaceTest2
+       {
+       }
+
+       /**
+               <summary>
+               Java style comment for interface
+               </summary>
+       */
+       public interface InterfaceTest3
+       {
+       }
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-006-ref.xml b/mcs/tests/xml-006-ref.xml
new file mode 100755 (executable)
index 0000000..6c779a3
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-006</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.EnumTest">\r
+            <summary>
+            comment for enum type
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.EnumTest2" -->\r
+        <member name="T:Testing.EnumTest3">\r
+               <summary>
+               Java style comment for enum type
+               </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-006.cs b/mcs/tests/xml-006.cs
new file mode 100755 (executable)
index 0000000..217a982
--- /dev/null
@@ -0,0 +1,42 @@
+// Compiler options: -doc:xml-006.xml
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment for enum type
+       /// </summary>
+       public enum EnumTest
+       {
+               Foo,
+               Bar,
+       }
+
+       /// <summary>
+       /// comment for enum type
+       /// </incorrect>
+       public enum EnumTest2
+       {
+               Foo,
+               Bar,
+       }
+
+       /**
+       <summary>
+       Java style comment for enum type
+       </summary>
+       */
+       public enum EnumTest3
+       {
+               Foo,
+               Bar,
+       }
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-007-ref.xml b/mcs/tests/xml-007-ref.xml
new file mode 100755 (executable)
index 0000000..70cb947
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-007</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.MyDelegate">\r
+            <summary>
+            comment for delegate type
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.MyDelegate2" -->\r
+        <member name="T:Testing.MyDelegate3">\r
+               <summary>
+               Javadoc comment for delegate type
+               </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-007.cs b/mcs/tests/xml-007.cs
new file mode 100755 (executable)
index 0000000..17758d3
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:xml-007.xml
+using System;
+
+namespace Testing
+{
+       /// <summary>
+       /// comment for delegate type
+       /// </summary>
+       public delegate void MyDelegate (object o, EventArgs e);
+
+       /// <summary>
+       /// comment for delegate type
+       /// </incorrect>
+       public delegate void MyDelegate2 (object o, EventArgs e);
+
+       /**
+       <summary>
+       Javadoc comment for delegate type
+       </summary>
+       */
+       public delegate void MyDelegate3 (object o, EventArgs e);
+
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-008-ref.xml b/mcs/tests/xml-008-ref.xml
new file mode 100755 (executable)
index 0000000..d2153a0
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-008</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test">\r
+            comment without markup on class - it is allowed
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.Test2" -->\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.Test3" -->\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-008.cs b/mcs/tests/xml-008.cs
new file mode 100755 (executable)
index 0000000..a44e4c6
--- /dev/null
@@ -0,0 +1,24 @@
+// Compiler options: -doc:xml-008.xml
+using System;
+
+namespace Testing
+{
+       /// comment without markup on class - it is allowed
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+       }
+
+       /// <6roken> broken markup
+       public class Test2
+       {
+       }
+
+       /// <dont-forget-close-tag>
+       public class Test3
+       {
+       }
+}
+
diff --git a/mcs/tests/xml-009-ref.xml b/mcs/tests/xml-009-ref.xml
new file mode 100755 (executable)
index 0000000..952f4c2
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-009</name>\r
+    </assembly>\r
+    <members>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-009.cs b/mcs/tests/xml-009.cs
new file mode 100755 (executable)
index 0000000..9f4ac8c
--- /dev/null
@@ -0,0 +1,24 @@
+// Compiler options: -doc:xml-009.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+                       /// inside method - not allowed.
+               }
+       }
+
+       public class Test2
+       {
+               /// no target
+       }
+
+       public class Test3
+       {
+       }
+       /// no target case 2.
+}
+
diff --git a/mcs/tests/xml-010-ref.xml b/mcs/tests/xml-010-ref.xml
new file mode 100755 (executable)
index 0000000..137fa27
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-010</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="F:Testing.Test.Constant">\r
+            <summary>
+            comment for const declaration
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "F:Testing.Test.Constant2" -->\r
+        <member name="F:Testing.Test.Constant3">\r
+                       <summary>
+                       Javaism comment for const declaration
+                       </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-010.cs b/mcs/tests/xml-010.cs
new file mode 100755 (executable)
index 0000000..c2f19a0
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:xml-010.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               /// <summary>
+               /// comment for const declaration
+               /// </summary>
+               const string Constant = "CONSTANT STRING";
+
+               /// <summary>
+               /// invalid comment for const declaration
+               /// </invalid>
+               const string Constant2 = "CONSTANT STRING";
+
+               /**
+               <summary>
+               Javaism comment for const declaration
+               </summary>
+               */
+               const string Constant3 = "CONSTANT STRING";
+
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-011-ref.xml b/mcs/tests/xml-011-ref.xml
new file mode 100755 (executable)
index 0000000..5c8a688
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-011</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="F:Testing.Test.PublicField">\r
+            <summary>
+            comment for public field
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "F:Testing.Test.PublicField2" -->\r
+        <member name="F:Testing.Test.PublicField3">\r
+                        <summary>
+                        Javadoc comment for public field
+                        </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-011.cs b/mcs/tests/xml-011.cs
new file mode 100755 (executable)
index 0000000..774c411
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:xml-011.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               /// <summary>
+               /// comment for public field
+               /// </summary>
+               public string PublicField;
+
+               /// <summary>
+               /// comment for public field
+               /// </invalid>
+               public string PublicField2;
+
+               /**
+                <summary>
+                Javadoc comment for public field
+                </summary>
+               */
+               public string PublicField3;
+
+               public static void Main ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-012-ref.xml b/mcs/tests/xml-012-ref.xml
new file mode 100755 (executable)
index 0000000..d8b27f4
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-012</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="F:Testing.Test.PrivateField">\r
+            <summary>
+            comment for private field
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "F:Testing.Test.PrivateField2" -->\r
+        <member name="F:Testing.Test.PrivateField3">\r
+                       <summary>
+                       Javadoc comment for private field
+                       </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-012.cs b/mcs/tests/xml-012.cs
new file mode 100755 (executable)
index 0000000..63ca584
--- /dev/null
@@ -0,0 +1,30 @@
+// Compiler options: -doc:xml-012.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for private field
+               /// </summary>
+               private string PrivateField;
+
+               /// <summary>
+               /// incorrect markup comment for private field
+               /// </incorrect>
+               private string PrivateField2;
+
+               /**
+               <summary>
+               Javadoc comment for private field
+               </summary>
+               */
+               private string PrivateField3;
+       }
+}
+
diff --git a/mcs/tests/xml-013-ref.xml b/mcs/tests/xml-013-ref.xml
new file mode 100755 (executable)
index 0000000..6bda2e1
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-013</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="P:Testing.Test.PublicProperty">\r
+            <summary>
+            comment for public property
+            </summary>
+        </member>\r
+        <!-- Badly formed XML comment ignored for member "P:Testing.Test.PublicProperty2" -->\r
+        <member name="P:Testing.Test.PublicProperty3">\r
+                       <summary>
+                       Javadoc comment for public property
+                       </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-013.cs b/mcs/tests/xml-013.cs
new file mode 100755 (executable)
index 0000000..b7f7ec3
--- /dev/null
@@ -0,0 +1,54 @@
+// Compiler options: -doc:xml-013.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for public property
+               /// </summary>
+               public string PublicProperty {
+                       /// <summary>
+                       /// On public getter - no effect
+                       /// </summary>
+                       get { return null; }
+                       /// <summary>
+                       /// On public setter - no effect
+                       /// </summary>
+                       set { }
+               }
+
+               /// <summary>
+               /// incorrect comment for public property
+               /// </incorrect>
+               public string PublicProperty2 {
+                       get { return null; }
+               }
+
+               /**
+               <summary>
+               Javadoc comment for public property
+               </summary>
+               */
+               public string PublicProperty3 {
+                       /**
+                       <summary>
+                       On public getter - no effect
+                       </summary>
+                       */
+                       get { return null; }
+                       /**
+                       <summary>
+                       On public setter - no effect
+                       </summary>
+                       */
+                       set { }
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-014-ref.xml b/mcs/tests/xml-014-ref.xml
new file mode 100755 (executable)
index 0000000..503e923
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-014</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="P:Testing.Test.PrivateProperty">\r
+            <summary>
+            comment for private property
+            </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-014.cs b/mcs/tests/xml-014.cs
new file mode 100755 (executable)
index 0000000..6ef31ea
--- /dev/null
@@ -0,0 +1,21 @@
+// Compiler options: -doc:xml-014.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for private property
+               /// </summary>
+               private string PrivateProperty {
+                       get { return null; }
+                       set { }
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-015-ref.xml b/mcs/tests/xml-015-ref.xml
new file mode 100755 (executable)
index 0000000..9475716
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-015</name>\r
+    </assembly>\r
+    <members>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-015.cs b/mcs/tests/xml-015.cs
new file mode 100755 (executable)
index 0000000..9374b76
--- /dev/null
@@ -0,0 +1,22 @@
+// Compiler options: -doc:xml-015.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               private string PrivateProperty {
+                       get { return null; }
+                       /// <summary>
+                       /// comment for private property setter - no effect
+                       /// </summary>
+                       set { }
+               }
+
+       }
+}
+
diff --git a/mcs/tests/xml-016-ref.xml b/mcs/tests/xml-016-ref.xml
new file mode 100755 (executable)
index 0000000..ec9a1a6
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-016</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="E:Testing.Test.MyEvent">\r
+            <summary>
+            public event EventHandler MyEvent
+            </summary>
+        </member>\r
+        <member name="E:Testing.Test.MyEvent2">\r
+            private event EventHandler MyEvent; without markup - it is OK.
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-016.cs b/mcs/tests/xml-016.cs
new file mode 100755 (executable)
index 0000000..13fbe51
--- /dev/null
@@ -0,0 +1,21 @@
+// Compiler options: -doc:xml-016.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// public event EventHandler MyEvent
+               /// </summary>
+               public event EventHandler MyEvent;
+
+               /// private event EventHandler MyEvent; without markup - it is OK.
+               private event EventHandler MyEvent2;
+       }
+}
+
diff --git a/mcs/tests/xml-017-ref.xml b/mcs/tests/xml-017-ref.xml
new file mode 100755 (executable)
index 0000000..10bc385
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-017</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Testing.Test.Foo">\r
+            comment on method without parameter
+        </member>\r
+        <member name="M:Testing.Test.Foo(System.Int64,Testing.Test,System.Collections.ArrayList)">\r
+            here is a documentation with parameters (and has same name)
+        </member>\r
+        <member name="M:Testing.Test.Foo(System.String[])">\r
+            here is a documentation with parameters (and has same name)
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-017.cs b/mcs/tests/xml-017.cs
new file mode 100755 (executable)
index 0000000..d53d46f
--- /dev/null
@@ -0,0 +1,28 @@
+// Compiler options: -doc:xml-017.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// comment on method without parameter
+               public static void Foo ()
+               {
+               }
+
+               /// here is a documentation with parameters (and has same name)
+               public static void Foo (long l, Test t, System.Collections.ArrayList al)
+               {
+               }
+
+               /// here is a documentation with parameters (and has same name)
+               public static void Foo (params string [] param)
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-018-ref.xml b/mcs/tests/xml-018-ref.xml
new file mode 100755 (executable)
index 0000000..a1651f0
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-018</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="P:Testing.Test.Item(System.Int32)">\r
+            <summary>
+            comment for indexer
+            </summary>
+        </member>\r
+        <member name="P:Testing.Test.Item(System.String)">\r
+            <summary>
+            comment for indexer
+            </summary>
+        </member>\r
+        <member name="P:Testing.Test.Item(System.Int32,Testing.Test)">\r
+            <summary>
+            comment for indexer wit multiple parameters
+            </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-018.cs b/mcs/tests/xml-018.cs
new file mode 100755 (executable)
index 0000000..194f44f
--- /dev/null
@@ -0,0 +1,35 @@
+// Compiler options: -doc:xml-018.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for indexer
+               /// </summary>
+               public string this [int i] {
+                       get { return null; }
+               }
+
+               /// <summary>
+               /// comment for indexer
+               /// </summary>
+               public string this [string s] {
+                       get { return null; }
+               }
+
+               /// <summary>
+               /// comment for indexer wit multiple parameters
+               /// </summary>
+               public string this [int i, Test t] {
+                       get { return null; }
+               }
+
+       }
+}
+
diff --git a/mcs/tests/xml-019-ref.xml b/mcs/tests/xml-019-ref.xml
new file mode 100755 (executable)
index 0000000..7871adc
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-019</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Testing.Test.op_LogicalNot(Testing.Test)">\r
+            <summary>
+            comment for unary operator
+            </summary>
+        </member>\r
+        <member name="M:Testing.Test.op_Addition(Testing.Test,System.Int32)">\r
+            <summary>
+            comment for binary operator
+            </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-019.cs b/mcs/tests/xml-019.cs
new file mode 100755 (executable)
index 0000000..81a563c
--- /dev/null
@@ -0,0 +1,29 @@
+// Compiler options: -doc:xml-019.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <summary>
+               /// comment for unary operator
+               /// </summary>
+               public static bool operator ! (Test t)
+               {
+                       return false;
+               }
+
+               /// <summary>
+               /// comment for binary operator
+               /// </summary>
+               public static int operator + (Test t, int b)
+               {
+                       return b;
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-020-ref.xml b/mcs/tests/xml-020-ref.xml
new file mode 100755 (executable)
index 0000000..a6f01b7
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-020</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Testing.Test.#ctor">\r
+            comment for constructor
+        </member>\r
+        <member name="M:Testing.Test.Finalize">\r
+            comment for destructor
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-020.cs b/mcs/tests/xml-020.cs
new file mode 100755 (executable)
index 0000000..da30bdf
--- /dev/null
@@ -0,0 +1,23 @@
+// Compiler options: -doc:xml-020.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// comment for constructor
+               public Test ()
+               {
+               }
+
+               /// comment for destructor
+               ~Test ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-021-ref.xml b/mcs/tests/xml-021-ref.xml
new file mode 100755 (executable)
index 0000000..53785fe
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-021</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test.InternalClass">\r
+            comment for internal class
+        </member>\r
+        <member name="T:Testing.Test.InternalStruct">\r
+            comment for internal struct
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-021.cs b/mcs/tests/xml-021.cs
new file mode 100755 (executable)
index 0000000..542e278
--- /dev/null
@@ -0,0 +1,23 @@
+// Compiler options: -doc:xml-021.xml
+using System;
+
+namespace Testing
+{
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// comment for internal class
+               public class InternalClass
+               {
+               }
+
+               /// comment for internal struct
+               public struct InternalStruct
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-022-ref.xml b/mcs/tests/xml-022-ref.xml
new file mode 100755 (executable)
index 0000000..d338d6f
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-022</name>\r
+    </assembly>\r
+    <members>\r
+        <!-- Badly formed XML comment ignored for member "T:Testing.Test2" -->\r
+        <member name="M:Testing.Test2.Foo">\r
+                               another documentation style (Java-mimic)
+        </member>\r
+        <member name="T:Testing.StructTest">\r
+            testing indentation <summary> test test ;-)
+            comment for struct
+            </summary>
+        </member>\r
+        <member name="T:Testing.InterfaceTest">\r
+            <summary>
+            comment for interface
+            </summary>
+        </member>\r
+        <member name="T:Testing.EnumTest">\r
+            <summary>
+            comment for enum type
+            </summary>
+        </member>\r
+        <member name="F:Testing.EnumTest.Foo">\r
+            <summary>
+            comment for enum field
+            </summary>
+        </member>\r
+        <member name="T:Testing.Dummy">\r
+            <summary>
+            comment for dummy type
+            </summary>
+        </member>\r
+        <member name="T:Testing.MyDelegate">\r
+            <summary>
+            comment for delegate type
+            </summary>
+        </member>\r
+        <member name="T:Testing.Test">\r
+            <summary>
+            description for class Test
+            </summary>
+        </member>\r
+        <member name="F:Testing.Test.Constant">\r
+            comment for const declaration
+        </member>\r
+        <member name="F:Testing.Test.BadPublicField">\r
+            comment for public field
+        </member>\r
+        <member name="F:Testing.Test.PrivateField">\r
+            comment for private field
+        </member>\r
+        <member name="M:Testing.Test.Foo">\r
+            here is a documentation!!!
+        </member>\r
+        <member name="M:Testing.Test.Foo(System.Int64,Testing.Test,System.Collections.ArrayList)">\r
+            here is a documentation with parameters
+        </member>\r
+        <member name="M:Testing.Test.op_LogicalNot(Testing.Test)">\r
+            <summary>
+            comment for unary operator
+            </summary>
+        </member>\r
+        <member name="M:Testing.Test.op_Addition(Testing.Test,System.Int32)">\r
+            <summary>
+            comment for binary operator
+            </summary>
+        </member>\r
+        <member name="M:Testing.Test.Finalize">\r
+            comment for destructor
+        </member>\r
+        <member name="M:Testing.Test.#ctor">\r
+            comment for .ctor()
+        </member>\r
+        <member name="M:Testing.Test.#ctor(System.String,System.String[])">\r
+            comment for .ctor(string arg, string [] args)
+        </member>\r
+        <member name="P:Testing.Test.PublicProperty">\r
+            comment for public property
+        </member>\r
+        <member name="P:Testing.Test.PrivateProperty">\r
+            comment for private property
+        </member>\r
+        <member name="E:Testing.Test.MyEvent">\r
+            public event EventHandler MyEvent ;-)
+        </member>\r
+        <member name="P:Testing.Test.Item(System.Int32)">\r
+            comment for indexer
+        </member>\r
+        <member name="P:Testing.Test.Item(System.Int32,Testing.Test)">\r
+            comment for indexer wit multiple parameters
+        </member>\r
+        <member name="T:Testing.Test.InternalClass">\r
+            comment for internal class
+        </member>\r
+        <member name="T:Testing.Test.InternalStruct">\r
+            comment for internal struct
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-022.cs b/mcs/tests/xml-022.cs
new file mode 100755 (executable)
index 0000000..b7eb5aa
--- /dev/null
@@ -0,0 +1,161 @@
+// Compiler options: -doc:xml-022.xml
+//
+// Combined tests (for detecting incorrect markup targeting).
+//
+using System;
+
+/// <summary>
+/// xml comment is not allowed here.
+/// </summary>
+namespace Testing
+{
+       /// <summary>
+       /// </incorrect>
+       public class Test2
+       {
+               /**
+                       another documentation style (Java-mimic)
+               */
+               public static void Foo ()
+               {
+                       /// here is an extraneous comment
+               }
+
+               public static void Main ()
+               {
+               }
+       }
+
+       /// testing indentation <summary> test test ;-)
+       /// comment for struct
+       /// </summary>
+       public struct StructTest
+       {
+       }
+
+       /// <summary>
+       /// comment for interface
+       /// </summary>
+       public interface InterfaceTest
+       {
+       }
+
+       /// <summary>
+       /// comment for enum type
+       /// </summary>
+       public enum EnumTest
+       {
+               /// <summary>
+               /// comment for enum field
+               /// </summary>
+               Foo,
+               Bar,
+       }
+
+       /// <summary>
+       /// comment for dummy type
+       /// </summary>
+       public class Dummy {}
+
+       /// <summary>
+       /// comment for delegate type
+       /// </summary>
+       public delegate void MyDelegate (object o, EventArgs e);
+
+       /// <summary>
+       /// description for class Test
+       /// </summary>
+       public class Test
+       {
+               /// comment for const declaration
+               const string Constant = "CONSTANT STRING";
+
+               /// comment for public field
+               public string BadPublicField;
+
+               /// comment for private field
+               private string PrivateField;
+
+               /// comment for public property
+               public string PublicProperty {
+                       /// comment for private property getter
+                       get { return null; }
+               }
+
+               /// comment for private property
+               private string PrivateProperty {
+                       get { return null; }
+                       /// comment for private property setter
+                       set { }
+               }
+
+               int x;
+
+               /// public event EventHandler MyEvent ;-)
+               public event EventHandler MyEvent;
+
+               int y;
+
+               /// here is a documentation!!!
+               public static void Foo ()
+               {
+               }
+
+               /// here is a documentation with parameters
+               public static void Foo (long l, Test t, System.Collections.ArrayList al)
+               {
+               }
+
+               /// comment for indexer
+               public string this [int i] {
+                       get { return null; }
+               }
+
+               /// comment for indexer wit multiple parameters
+               public string this [int i, Test t] {
+                       get { return null; }
+               }
+
+               /// <summary>
+               /// comment for unary operator
+               /// </summary>
+               public static bool operator ! (Test t)
+               {
+                       return false;
+               }
+
+               /// <summary>
+               /// comment for binary operator
+               /// </summary>
+               public static int operator + (Test t, int b)
+               {
+                       return b;
+               }
+
+               /// comment for destructor
+               ~Test ()
+               {
+               }
+
+               /// comment for .ctor()
+               public Test ()
+               {
+               }
+
+               /// comment for .ctor(string arg, string [] args)
+               public Test (string arg, string [] args)
+               {
+               }
+
+               /// comment for internal class
+               public class InternalClass
+               {
+               }
+
+               /// comment for internal struct
+               public struct InternalStruct
+               {
+               }
+       }
+}
+
diff --git a/mcs/tests/xml-023-ref.xml b/mcs/tests/xml-023-ref.xml
new file mode 100755 (executable)
index 0000000..a977f4b
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-023</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Test.Foo(Test.A,System.Int32)">\r
+            here is a documentation
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-023.cs b/mcs/tests/xml-023.cs
new file mode 100755 (executable)
index 0000000..9748779
--- /dev/null
@@ -0,0 +1,15 @@
+// Compiler options: -doc:xml-023.xml
+   public class Test
+   {
+       public class A {}
+
+       public static void Main ()
+       {
+       }
+
+       /// here is a documentation
+       public static void Foo (A a, int x)
+       {
+       }
+   }
+
diff --git a/mcs/tests/xml-024-ref.xml b/mcs/tests/xml-024-ref.xml
new file mode 100755 (executable)
index 0000000..36162af
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-024</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test">\r
+            <!-- Include tag is invalid --><include/>\r
+        </member>\r
+        <member name="M:Testing.Test.Main">\r
+            <!-- Include tag is invalid --><include file="a"/>\r
+        </member>\r
+        <member name="M:Testing.Test.Bar(System.Int32)">\r
+            <!-- Include tag is invalid --><include path="/foo/bar"/>\r
+        </member>\r
+        <member name="M:Testing.Test.Baz(System.Int32)">\r
+            <!-- Badly formed XML file "c:\cygwin\home\_\cvs\mcs\tests\there-is-no-such-file" cannot be included -->\r
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-024.cs b/mcs/tests/xml-024.cs
new file mode 100755 (executable)
index 0000000..f1e870b
--- /dev/null
@@ -0,0 +1,27 @@
+// Compiler options: -doc:xml-024.xml
+
+namespace Testing
+{
+   /// <include/>
+   public class Test
+   {
+       // warning
+       /// <include file='a' />
+       public static void Main ()
+       {
+       }
+
+       // warning
+       /// <include path='/foo/bar' />
+       public void Bar (int x)
+       {
+       }
+
+       // warning
+       /// <include file='there-is-no-such-file' path='/foo/bar' />
+       public void Baz (int x)
+       {
+       }
+   }
+}
+
diff --git a/mcs/tests/xml-025-ref.xml b/mcs/tests/xml-025-ref.xml
new file mode 100755 (executable)
index 0000000..01a0149
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-025</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test">\r
+            <!-- No matching elements were found for the following include tag --><include file="../xml-025.inc" path="/foo"/>\r
+        </member>\r
+        <member name="F:Testing.Test.S1">\r
+            <root attr="is attribute allowed?">\r
+  includes XML markup.\r
+  <child>test</child>\r
+  <child>test2</child>\r
+</root>\r
+        </member>\r
+        <member name="F:Testing.Test.S2">\r
+            <child>test</child><child>test2</child>\r
+        </member>\r
+        <member name="F:Testing.Test.S3">\r
+            <!-- Failed to insert some or all of included XML -->\r
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-025.cs b/mcs/tests/xml-025.cs
new file mode 100755 (executable)
index 0000000..bd3341a
--- /dev/null
@@ -0,0 +1,24 @@
+// Compiler options: -doc:xml-025.xml
+// Note that it could not be compiled to generate reference output as it is.
+// csc needs '\\' instead of '/' for file specification.
+
+namespace Testing
+{
+   /// <include file='../xml-025.inc' path='/foo' />
+   public class Test
+   {
+       public static void Main ()
+       {
+       }
+
+       /// <include file='../xml-025.inc' path='/root'/>
+       public string S1;
+
+       /// <include file='../xml-025.inc' path='/root/child'/>
+       public string S2;
+
+       /// <include file='../xml-025.inc' path='/root/@attr'/>
+       public string S3;
+   }
+}
+
diff --git a/mcs/tests/xml-025.inc b/mcs/tests/xml-025.inc
new file mode 100755 (executable)
index 0000000..6e4076c
--- /dev/null
@@ -0,0 +1,5 @@
+<root attr='is attribute allowed?'>
+  includes XML markup.
+  <child>test</child>
+  <child>test2</child>
+</root>
diff --git a/mcs/tests/xml-026-ref.xml b/mcs/tests/xml-026-ref.xml
new file mode 100755 (executable)
index 0000000..af0add6
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-026</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test">\r
+            test class
+        </member>\r
+        <member name="M:Testing.Test.Foo(System.Int32)">\r
+            <param>anonymous</param>
+        </member>\r
+        <member name="M:Testing.Test.Bar(System.Int32)">\r
+            <param name='i'>correct</param>
+            <param name='i'>duplicate</param>
+        </member>\r
+        <member name="M:Testing.Test.Baz(System.Int32)">\r
+            <param name='mismatch'>mismatch</param>
+        </member>\r
+        <member name="M:Testing.Test.Var(System.Int32[])">\r
+            <param name='arr'>varargs</param>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-026.cs b/mcs/tests/xml-026.cs
new file mode 100755 (executable)
index 0000000..4ef8485
--- /dev/null
@@ -0,0 +1,24 @@
+// Compiler options: -doc:xml-026.xml
+namespace Testing
+{
+       /// test class
+       public class Test
+       {
+               public static void Main ()
+               {
+               }
+
+               /// <param>anonymous</param>
+               public void Foo (int i) {}
+
+               /// <param name='i'>correct</param>
+               /// <param name='i'>duplicate</param>
+               public void Bar (int i) {}
+
+               /// <param name='mismatch'>mismatch</param>
+               public void Baz (int i) {}
+
+               /// <param name='arr'>varargs</param>
+               public void Var (params int [] arr) {}
+       }
+}
diff --git a/mcs/tests/xml-027-ref.xml b/mcs/tests/xml-027-ref.xml
new file mode 100755 (executable)
index 0000000..d46d678
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-027</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Testing.Test">\r
+            <summary>\r
+            <see/>\r
+            <see cref="!:!!!!!"/>\r
+            <see cref="!:nonexist"/>\r
+            <see cref="T:Testing.Test"/>\r
+            <see cref="T:Testing.Test"/>\r
+            <see cref="T:Test"/>\r
+            <see cref="_:Test"/>\r
+            <see cref="P:Bar"/>\r
+            <see cref="F:Bar"/>\r
+            <see cref="F:Testing.Test.Bar"/>\r
+            <see cref="P:Baz"/>\r
+            <see cref="F:Baz"/>\r
+            <see cref="P:Testing.Test.Baz"/>\r
+            <see cref="!:nonexist.Foo()"/>\r
+            <see cref="M:Testing.Test.Foo"/>\r
+            <see cref="M:Testing.Test.Foo"/>\r
+            <see cref="!:Test.Bar()"/>\r
+            <see cref="!:Test.Foo(System.Int32)"/>\r
+            </summary>\r
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-027.cs b/mcs/tests/xml-027.cs
new file mode 100755 (executable)
index 0000000..8543ae2
--- /dev/null
@@ -0,0 +1,38 @@
+// Compiler options: -doc:xml-027.xml
+using ZZZ = Testing.Test;
+
+namespace Testing
+{
+       /// <summary>
+       /// <see />
+       /// <see cref='!!!!!' />
+       /// <see cref='nonexist' />
+       /// <see cref='Test' />
+       /// <see cref='ZZZ' />
+       /// <see cref='T:Test' />
+       /// <see cref='_:Test' />
+       /// <see cref='P:Bar' />
+       /// <see cref='F:Bar' />
+       /// <see cref='Bar' />
+       /// <see cref='P:Baz' />
+       /// <see cref='F:Baz' />
+       /// <see cref='Baz' />
+       /// <see cref='nonexist.Foo()' />
+       /// <see cref='Test.Foo()' />
+       /// <see cref='ZZZ.Foo()' />
+       /// <see cref='Test.Bar()' />
+       /// <see cref='Test.Foo(System.Int32)' />
+       /// </summary>
+       class Test
+       {
+               public static void Main () { System.Console.Error.WriteLine ("xml-027 is running fine ;-)"); }
+
+               // I don't put any documentation here, but cref still works.
+               public void Foo () {}
+
+               public string Bar;
+
+               public string Baz { get { return ""; } }
+       }
+}
+
diff --git a/mcs/tests/xml-028-ref.xml b/mcs/tests/xml-028-ref.xml
new file mode 100755 (executable)
index 0000000..94ea925
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-028</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="T:Test">\r
+            <summary>\r
+            Partial comment #2\r
+            Partial comment #1\r
+            </summary>\r
+        </member>\r
+        <member name="T:Test.Inner">\r
+            <summary>\r
+            Partial inner class!\r
+            ... is still available.\r
+            </summary>\r
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-028.cs b/mcs/tests/xml-028.cs
new file mode 100644 (file)
index 0000000..2b5c01b
--- /dev/null
@@ -0,0 +1,33 @@
+// Compiler options: -doc:xml-028.xml
+using System;
+
+/// <summary>
+/// Partial comment #2
+public partial class Test
+{
+       string Bar;
+
+       public static void Main () {}
+
+       /// <summary>
+       /// Partial inner class!
+       internal partial class Inner
+       {
+               public string Hoge;
+       }
+}
+
+/// Partial comment #1
+/// </summary>
+public partial class Test
+{
+       public string Foo;
+
+       /// ... is still available.
+       /// </summary>
+       internal partial class Inner
+       {
+               string Fuga;
+       }
+}
+
diff --git a/mcs/tests/xml-029-ref.xml b/mcs/tests/xml-029-ref.xml
new file mode 100755 (executable)
index 0000000..65c4fb5
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-029</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Test1.Foo">\r
+            <summary>
+            Some test documentation
+            </summary>
+        </member>\r
+        <member name="T:ITest2">\r
+            <summary>
+            Publicly available interface
+            </summary>
+        </member>\r
+        <member name="M:ITest2.Foo">\r
+            <summary>
+            Some test documentation
+            </summary>
+        </member>\r
+        <member name="P:ITest2.Bar">\r
+            <summary>
+            Some test documentation
+            </summary>
+        </member>\r
+        <member name="E:ITest2.EventRaised">\r
+            <summary>
+            Some test documentation
+            </summary>
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-029.cs b/mcs/tests/xml-029.cs
new file mode 100644 (file)
index 0000000..76d90a9
--- /dev/null
@@ -0,0 +1,34 @@
+// Compiler options: -doc:xml-029.xml
+using System;
+
+class Test1 {
+       /// <summary>
+       /// Some test documentation
+       /// </summary>
+       void Foo(){}
+
+       public static void Main () {}
+}
+
+/// <summary>
+/// Publicly available interface
+/// </summary>
+public interface ITest2 {
+
+       /// <summary>
+       /// Some test documentation
+       /// </summary>
+       void Foo();
+
+       /// <summary>
+       /// Some test documentation
+       /// </summary>
+       long Bar { get; }
+
+       /// <summary>
+       /// Some test documentation
+       /// </summary>
+       event EventHandler EventRaised;
+}
+
+
diff --git a/mcs/tests/xml-030-ref.xml b/mcs/tests/xml-030-ref.xml
new file mode 100755 (executable)
index 0000000..d6711b8
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-030</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Test.foo2">\r
+            <summary>\r
+            some summary\r
+            </summary>\r
+            <value>\r
+            <see cref="T:Test[]"/>\r
+            <see cref="T:System.Text.RegularExpressions.Regex"/>\r
+            <see cref="T:System.Text.RegularExpressions.Regex"/>\r
+            <see cref="N:System.Text.RegularExpressions"/>\r
+            <see cref="T:System.Text.RegularExpressions.Regex[]"/>\r
+            </value>\r
+        </member>\r
+        <member name="M:Test.foo3(System.String,System.Object[])">\r
+            <summary>\r
+            <see cref="M:System.String.Format(System.String,System.Object[])"/>.\r
+            <see cref="M:System.String.Format(System.String,System.Object[])"/>.\r
+            <see cref="M:System.String.Format(System.String,System.Object[])"/>.\r
+            <see cref="M:System.String.Format(System.String,System.Object[])"/>.\r
+            </summary>\r
+            <param name="line">The formatting string.</param>\r
+            <param name="args">The object array to write into format string.</param>\r
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-030.cs b/mcs/tests/xml-030.cs
new file mode 100644 (file)
index 0000000..3b2cdd9
--- /dev/null
@@ -0,0 +1,35 @@
+// Compiler options: -doc:xml-030.xml -warn:4 -warnaserror
+using System;
+
+class Test
+{
+       static void Main () {}
+
+       /// <summary>
+       /// some summary
+       /// </summary>
+       /// <value>
+       /// <see cref="T:Test[]"/>
+       /// <see cref="T:System.Text.RegularExpressions.Regex"/>
+       /// <see cref="System.Text.RegularExpressions.Regex"/>
+       /// <see cref="System.Text.RegularExpressions"/>
+       /// <see cref="T:System.Text.RegularExpressions.Regex[]"/>
+       /// </value>
+       //
+       // <see cref="T:System.Text.RegularExpressions"/> .. csc incorrectly allows it
+       // <see cref="System.Text.RegularExpressions.Regex[]"/> ... csc does not allow it.
+       //
+       public void foo2() {
+       }
+
+       /// <summary>
+       /// <see cref="String.Format(string, object[])" />.
+       /// <see cref="string.Format(string, object[])" />.
+       /// <see cref="String.Format(string, object [ ])" />.
+       /// <see cref="string.Format(string, object [ ])" />.
+       /// </summary>
+       /// <param name="line">The formatting string.</param>
+       /// <param name="args">The object array to write into format string.</param>
+       public void foo3(string line, params object[] args) {
+       }
+}
diff --git a/mcs/tests/xml-031-ref.xml b/mcs/tests/xml-031-ref.xml
new file mode 100755 (executable)
index 0000000..2a5a67a
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-031</name>\r
+    </assembly>\r
+    <members>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-031.cs b/mcs/tests/xml-031.cs
new file mode 100644 (file)
index 0000000..872e0a7
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: -doc:xml-031.xml -warn:4 -warnaserror
+//// Some comment
+////how about this line?
+using System;
+using System.IO;
+
+class Test
+{
+       public static void Main ()
+       {
+       }
+}
+
diff --git a/mcs/tests/xml-032-ref.xml b/mcs/tests/xml-032-ref.xml
new file mode 100755 (executable)
index 0000000..c588132
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>xml-032</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:Test.#ctor(System.String)">\r
+            <exception cref="T:System.ArgumentNullException"><paramref name="wrongref"/> is <see langword="null"/>.</exception>\r
+            <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="wrongRefAgain"/> is a zero-length <see cref="T:System.String"/>.</exception>\r
+        </member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/xml-032.cs b/mcs/tests/xml-032.cs
new file mode 100644 (file)
index 0000000..30ce28b
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -doc:xml-032.xml -warn:4 -warnaserror
+using System;
+
+class Test
+{
+       /// <exception cref="ArgumentNullException"><paramref name="wrongref" /> is <see langword="null" />.</exception>
+       /// <exception cref="ArgumentOutOfRangeException"><paramref name="wrongRefAgain" /> is a zero-length <see cref="string" />.</exception>
+       protected Test(string name) 
+       {
+       }
+
+       static void Main () {}
+}
+
diff --git a/mcs/tests/xmldocdiff.cs b/mcs/tests/xmldocdiff.cs
new file mode 100755 (executable)
index 0000000..17cc095
--- /dev/null
@@ -0,0 +1,122 @@
+using System;
+using System.Collections;
+using System.Xml;
+
+public class Test
+{
+       public class ComparisonException : Exception
+       {
+               public ComparisonException (string message)
+                       : base (message)
+               {
+               }
+       }
+
+       static bool debug = false;
+       static bool error = false;
+
+       public static void Main (string [] args)
+       {
+               if (args.Length < 2) {
+                       Console.Error.WriteLine ("Usage: xmldocdiff [reference_output.xml] [actual_output.xml]");
+                       return;
+               }
+               if (args.Length > 2 && args [2].EndsWith ("-debug"))
+                       debug = true;
+
+               try {
+                       Run (args);
+               } catch (Exception ex) {
+                       Console.WriteLine ("FAIL: " + args [1]);
+                       throw ex;
+               }
+               Console.WriteLine ("PASS: " + args [1]);
+       }
+
+       private static void Run (string [] args)
+       {
+               XmlDocument doc1 = new XmlDocument ();
+               doc1.Load (args [0]);
+               XmlDocument doc2 = new XmlDocument ();
+               doc2.Load (args [1]);
+
+               XmlNodeList memberList1 = doc1.SelectNodes ("/doc/members/member");
+               XmlNodeList memberList2 = doc2.SelectNodes ("/doc/members/member");
+
+               Hashtable namedItems = new Hashtable ();
+
+               foreach (XmlElement el in memberList1)
+                       namedItems.Add (el.GetAttribute ("name"), el);
+               foreach (XmlElement el2 in memberList2) {
+                       string name = el2.GetAttribute ("name");
+                       XmlElement el1 = namedItems [name] as XmlElement;
+                       if (el1 == null) {
+                               Report ("Extraneous element found. Name is '{0}'", name);
+                               continue;
+                       }
+                       namedItems.Remove (name);
+
+                       CompareNodes (el1, el2);
+
+               }
+               foreach (string name in namedItems.Keys)
+                       Report ("Expected comment was not found. Name is {0}, XML is {1}", name, ((XmlElement) namedItems [name]).OuterXml);
+
+               // finally, check other nodes than members
+               doc1.SelectSingleNode ("/doc/members").RemoveAll ();
+               doc2.SelectSingleNode ("/doc/members").RemoveAll ();
+               string xml1 = doc1.OuterXml.Replace ("\r", "").Trim ();
+               string xml2 = doc2.OuterXml.Replace ("\r", "").Trim ();
+               if (xml1 != xml2)
+                       Report (@"Either of doc, assembly, name, members elements  are different.
+doc1: {0}
+doc2: {1}", xml1, xml2);
+       }
+
+       private static void CompareNodes (XmlNode n1, XmlNode n2)
+       {
+               if (n2 == null) {
+                       Report (@"Nodes does not exist:
+Node1: {0}", n1.OuterXml);
+                       return;
+               }
+               if (n1.NodeType != n2.NodeType) {
+                       Report (@"Nodes differ:
+Node1: {0}
+Node2: {1}", n1.OuterXml, n2.OuterXml);
+                       return;
+               }
+               if (n1.Name != n2.Name) {
+                       Report (@"Node names differ:
+Node1: {0}
+Node2: {1}", n1.OuterXml, n2.OuterXml);
+                       return;
+               }
+               if (n1 is XmlElement) {
+                       for (int i = 0; i < n1.Attributes.Count; i++)
+                               CompareNodes (n1.Attributes [i],
+                                       n2.Attributes [i]);
+                       for (int i = 0; i < n1.ChildNodes.Count; i++)
+                               CompareNodes (n1.ChildNodes [i],
+                                       n2.ChildNodes [i]);
+               }
+               if (n1.NodeType != XmlNodeType.Comment && n1.Value != null) {
+                       string v1 = n1.Value.Trim ().Replace ("\r", "");
+                       string v2 = n2.Value.Trim ().Replace ("\r", "");
+                       if (v1 != v2)
+                               Report (@"Node values differ:
+Node1: {0}
+Node2: {1}", v1, v2);
+               }
+       }
+
+       static void Report (string format, params object [] args)
+       {
+               error = true;
+               if (debug)
+                       Console.WriteLine (format, args);
+               else
+                       throw new ComparisonException (String.Format (format, args));
+       }
+}
+
index 78573aaa0ba1185cb191b8bf508302c9a0fa2f34..4d1738ffd36556e2c732065b1efe5ba8c12b96b2 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * monop.cs : csc build fix. See bug #70185 for details.
+
 2004-11-30  Duncan Mak  <duncan@ximian.com>
 
        * monop.cs (GetAssemblyNamesFromGAC): New method, calls out to
index fc95214b15ba5c16a426b60a5e650580b60250be..777bcc0a3737b130d1b6da0f6c72b0c31fe8c2ea 100644 (file)
@@ -259,6 +259,7 @@ class MonoP {
                        return;
                }
 
+               string message = null;
                string tname = args [i];
                Type t = GetType (tname);
 
@@ -271,7 +272,6 @@ class MonoP {
                        }
                }
 
-               string message = null;
                if (t == null) {
                        foreach (string assm in GetAssemblyNamesFromGAC ()) {
                                try {
index 17162963cd1ea542eef8a00faa262ce495d1fd6c..0c1c2e3ad53d86c8a9ec482d01e08697cc4249e3 100644 (file)
@@ -1,8 +1,7 @@
 # the handles dir doesn't apply to windows
-if PLATFORM_WIN32
-SUBDIRS = utils io-layer monoburg os metadata cil dis \
-       arch monograph interpreter mini tests benchmark profiler
-else
-SUBDIRS = utils io-layer monoburg os metadata cil dis \
-       arch monograph interpreter mini tests benchmark handles profiler
+if ! PLATFORM_WIN32
+HANDLES = handles
 endif
+
+SUBDIRS = utils io-layer monoburg os cil metadata dis \
+      arch monograph interpreter mini tests benchmark $(HANDLES) profiler
index 9ad799f4ba9fd81002318a8bdbc1330ccb9bd228..ea4ab48958aeeb5d84e4ced219ed4096318afba7 100644 (file)
@@ -10,7 +10,7 @@
  |\r
  | Author: Sergey Chaban\r
  |\r
- | $Id: make-opcode-def.xsl,v 1.1 2001/07/13 01:04:23 miguel Exp $\r
+ | $Id$\r
   -->\r
 \r
 \r
index d7911fb728bbbdf44d43cac65caf90527c00aada..466d56fa9e409ccb3e1fbaf5ee6f8d08ed566f05 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * main.c: Rename compilercontrolled to privatescope
+
+       * get.c (get_class_name): Correct implementation that correctly
+       handles nested classes.
+
 2004-11-26  Miguel de Icaza  <miguel@ximian.com>
 
        * main.c: Better implementation of the quote keyword, list all of
index d86afa7217ceccb0f84af89b262c93a13d53e018..5fa56fe0b963344b05b28dec99d5148fa6743270 100644 (file)
@@ -699,12 +699,30 @@ dis_stringify_function_ptr (MonoImage *m, MonoMethodSignature *method)
        return retval;
 }
 
+static char *
+get_class_name (MonoClass *c)
+{
+       if (c->nested_in){
+               char *part_a = get_class_name (c->nested_in);
+               char *result;
+
+               result = g_strdup_printf ("%s/%s", part_a, c->name);
+               g_free (part_a);
+               return result;
+       }
+       if (*c->name_space)
+               return g_strdup_printf ("%s.%s", c->name_space, c->name);
+       else
+               return g_strdup (c->name);
+}
+
 char *
 dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
 {
        /* FIXME: handle MONO_TYPE_OBJECT ... */
        const char *otype = c->byval_arg.type == MONO_TYPE_VALUETYPE ? "valuetype" : "class" ;
        char *assemblyref = NULL, *result, *esname, *generic = NULL;
+       
        if (m != c->image) {
                if (c->image->assembly_name) {
                        /* we cheat */
@@ -721,14 +739,7 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
                }
        }
 
-       if (c->nested_in) {
-               result = g_strdup_printf ("%s%s%s/%s", c->nested_in->name_space, 
-                               *c->nested_in->name_space?".":"", c->nested_in->name,
-                               c->name);
-       } else {
-               result = g_strdup_printf ("%s%s%s", c->name_space, 
-                               *c->name_space?".":"", c->name);
-       }
+       result = get_class_name (c);
        
        esname = get_escaped_name (result);
        g_free (result);
@@ -1153,7 +1164,7 @@ param_flags (guint32 f)
 }
 
 static dis_map_t field_access_map [] = {
-       { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
+       { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "privatescope " },
        { FIELD_ATTRIBUTE_PRIVATE,             "private " },
        { FIELD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
        { FIELD_ATTRIBUTE_ASSEMBLY,            "assembly " },
index 08f1afa24462891a47597ba1ccd6862a21c4d954..98b5cc36e99b5e75ad80a4547e5eaa9d1d634722 100644 (file)
@@ -413,7 +413,7 @@ dis_field_list (MonoImage *m, guint32 start, guint32 end)
 }
 
 static dis_map_t method_access_map [] = {
-       { METHOD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
+       { METHOD_ATTRIBUTE_COMPILER_CONTROLLED, "privatescope " },
        { METHOD_ATTRIBUTE_PRIVATE,             "private " },
        { METHOD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
        { METHOD_ATTRIBUTE_ASSEM,               "assembly " },
index 8a70c06c377ae616a53409cd0d17e7e69b065882..d2fb579e8d8745d2a0cf42b78db003148530951b 100644 (file)
@@ -1,3 +1,13 @@
+2004-12-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * interp.c: fix the build. Dunno if it's correct.
+
+2004-12-02  Bernie Solomon  <bernard@ugsolutions.com>
+
+       * mintops.def:
+       * transform.c:
+       * interp.c: cope with new thread interruption icall
+
 2004-11-12  Ben Maurer  <bmaurer@ximian.com>
 
        * transform.c: Fix bug with delegates in interp.
index 851059219318bf438e1a9b788a7874c73bf67c84..eb4a291206d63c78d5f0758ae3882729409063b6 100644 (file)
@@ -1239,6 +1239,11 @@ do_icall (ThreadContext *context, int op, stackval *sp, gpointer ptr)
        context->managed_code = 0;
 
        switch (op) {
+       case MINT_ICALL_V_V: {
+               void (*func)() = ptr;
+               func ();
+               break;
+       }
        case MINT_ICALL_P_V: {
                void (*func)(gpointer) = ptr;
                func (sp [-1].data.p);
@@ -3488,6 +3493,7 @@ array_constructed:
                        }
                        goto handle_finally;
                        MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_ICALL_V_V) 
                MINT_IN_CASE(MINT_ICALL_P_V) 
                MINT_IN_CASE(MINT_ICALL_P_P)
                MINT_IN_CASE(MINT_ICALL_PP_V)
@@ -4409,8 +4415,11 @@ mono_interp_init(const char *file)
        mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers", mono_runtime_install_handlers);
        mono_add_internal_call ("System.Delegate::CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal);
 
+       mono_register_jit_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", mono_create_icall_signature ("void"), FALSE);
+
        mono_runtime_init (domain, NULL, NULL);
 
+
        mono_thread_attach (domain);
        return domain;
 }
index 5ecdbb6baa2890f65458cd1eaf9c77ab0fe881e7..550ba655629449b97f03fa4e5751ca724068d6fc 100644 (file)
@@ -493,7 +493,8 @@ OPDEF(MINT_GETCHR, "getchr", 1, MintOpNoArgs)
 OPDEF(MINT_STRLEN, "strlen", 1, MintOpNoArgs)
 OPDEF(MINT_ARRAY_RANK, "array_rank", 1, MintOpNoArgs)
 
-OPDEF(MINT_ICALL_P_V, "mono_icall_p_v", 2, MintOpClassToken) /* not really */
+OPDEF(MINT_ICALL_V_V, "mono_icall_v_v", 2, MintOpClassToken) /* not really */
+OPDEF(MINT_ICALL_P_V, "mono_icall_p_v", 2, MintOpClassToken)
 OPDEF(MINT_ICALL_P_P, "mono_icall_p_p", 2, MintOpClassToken)
 OPDEF(MINT_ICALL_PP_V, "mono_icall_pp_v", 2, MintOpClassToken)
 OPDEF(MINT_ICALL_PI_V, "mono_icall_pi_v", 2, MintOpClassToken)
index 81f1fbd126c85fa32a4964695c8f76dcfea3fd2a..e89fe1bc7fc7ae9dd795b6550e73e68be42f8873 100644 (file)
@@ -2398,6 +2398,12 @@ generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
 
                                        CHECK_STACK (&td, info->sig->param_count);
                                        switch (info->sig->param_count) {
+                                       case 0:
+                                               if (MONO_TYPE_IS_VOID (info->sig->ret))
+                                                       ADD_CODE (&td,MINT_ICALL_V_V);
+                                               else
+                                                       g_assert_not_reached();
+                                               break;
                                        case 1:
                                                if (MONO_TYPE_IS_VOID (info->sig->ret))
                                                        ADD_CODE (&td,MINT_ICALL_P_V);
index f67f653d3fc920394234b3f9cf0cd7f2176f130e..fca4d16e6bc09e57a55f597945ec7b8cd6b14843 100644 (file)
@@ -1,3 +1,72 @@
+2004-12-04  Zoltan Varga  <vargaz@freemail.hu>
+
+       * image.c: Add unbox_wrapper_cache.
+
+       * class-internals.h debug-helpers.c: Add MONO_WRAPPER_UNBOX.
+
+       * marshal.h marshal.c (mono_marshal_get_unbox_wrapper): New wrapper
+       function generator.
+       
+       * object.c (mono_delegate_ctor): Call unbox wrapper if neccesary.
+       Fixes #70173.
+
+       * metadata-internals.h image.c: Add MonoImage->unbox_wrapper_cache.
+       
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * loader.c (mono_method_get_signature_full): New public function;
+       like mono_method_get_signature(), but with an additional
+       `MonoGenericContext *' argument.
+
+       * class.c (mono_class_inflate_generic_signature): Formerly known
+       as inflate_generic_signature(); make this public.
+
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * metadata.c
+       (mono_metadata_parse_type_full): Take a `MonoGenericContext *'
+       instead of a `MonoGenericContainer *'.  
+       (mono_metadata_parse_array_full): Likewise.
+       (mono_metadata_parse_signature_full): Likewise.
+       (mono_metadata_parse_method_signature_full): Likewise.
+       (mono_metadata_parse_generic_inst): Likewise.
+       (mono_metadata_parse_generic_param): Likewise.
+       (mono_metadata_parse_mh_full): Likewise.
+       (mono_type_create_from_typespec_full): Likewise.
+
+2004-12-03  Martin Baulig  <martin@ximian.com>
+
+       * class-internals.h (MonoGenericContainer): Replaced the
+       `MonoGenericContext * pointer with a `MonoGenericContext'
+       structure and made it the first element.
+
+2004-12-03  Martin Baulig  <martin@ximian.com>
+
+       * class.c
+       (inflate_generic_type): Set the `context->container' when creating
+       a new MonoGenericContext.
+       (mono_class_inflate_generic_method): Likewise.
+       (mono_class_create_from_typespec): Just use `context->container'
+       to get the container.
+
+       * loader.c (method_from_methodspec): Set `context->parent' from
+       `context->container' - and if that's a method container, use its
+       parent.  Also set the `context->container' when creating a new
+       MonoGenericContext.
+       (mono_get_method_from_token): Use just `context->container' to get
+       the container.
+
+       * metadata.c (do_mono_metadata_parse_generic_class): Also set
+       `gclass->context->container'.
+
+       * reflection.c (do_mono_reflection_bind_generic_parameters): Set
+       the `context->container' when creating a new MonoGenericContext.
+
+2004-12-03  Zoltan Varga  <vargaz@freemail.hu>
+
+       * reflection.c (compare_genericparam): Sort params with identical
+       owner by their number. Fixes gen-111 on sparc.
+
 2004-12-02  Zoltan Varga  <vargaz@freemail.hu>
 
        * threadpool.c (async_invoke_thread): Call push/pop_appdomain_ref
 
        * reflection.c: Fix some memory leaks.
        
+2004-12-02  Martin Baulig  <martin@ximian.com>
+
+       * metadata-internals.h (MonoImage): Removed `generic_class_cache'.
+
+       * metadata.c (generic_class_cache): New static hashtable.
+       (mono_metadata_lookup_generic_class): New public method.
+
+2004-12-02  Martin Baulig  <martin@ximian.com>
+
+       * class.c (mono_class_create_from_typedef): Call
+       mono_class_setup_parent() and mono_class_create_mono_type() before
+       parsing the interfaces.
+
 2004-12-02  Martin Baulig  <martin@ximian.com>
 
        * metadata.c (generic_inst_cache): New static hashtable.
index b7f8db6b5ec0e65274754d6d91a557d6f2d0c166..c91d66dd0b842e0729646c4d55802a9f4f729a3b 100644 (file)
@@ -37,6 +37,7 @@ typedef enum {
        MONO_WRAPPER_CASTCLASS,
        MONO_WRAPPER_PROXY_ISINST,
        MONO_WRAPPER_STELEMREF,
+       MONO_WRAPPER_UNBOX,
        MONO_WRAPPER_UNKNOWN
 } MonoWrapperType;
 
@@ -349,8 +350,8 @@ struct _MonoGenericContext {
 };
 
 struct _MonoGenericContainer {
+       MonoGenericContext context;
        MonoGenericContainer *parent;
-       MonoGenericContext *context;
        GHashTable *method_hash;
        MonoClass *klass;
        int type_argc    : 6;
@@ -536,5 +537,8 @@ mono_find_jit_icall_by_name (const char *name);
 MonoJitICallInfo *
 mono_find_jit_icall_by_addr (gconstpointer addr);
 
+MonoMethodSignature*
+mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context);
+
 #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */
 
index 5b3e55392bb5373747200bdb1ecf401290821039..49241019357791b1a12cf5dd2856afd757c19d6e 100644 (file)
@@ -300,11 +300,14 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
                ngclass->klass = NULL;
 
                ngclass->context = g_new0 (MonoGenericContext, 1);
+               ngclass->context->container = ngclass->container;
                ngclass->context->gclass = ngclass;
 
-               mono_loader_lock ();
-               cached = g_hash_table_lookup (ogclass->klass->image->generic_class_cache, ngclass);
+               ngclass->dynamic_info = NULL;
+               ngclass->initialized = FALSE;
 
+               mono_loader_lock ();
+               cached = mono_metadata_lookup_generic_class (ngclass);
                if (cached) {
                        g_free (ngclass);
                        mono_loader_unlock ();
@@ -314,9 +317,6 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
                        return nt;
                }
 
-               ngclass->dynamic_info = NULL;
-               ngclass->initialized = FALSE;
-
                mono_class_create_generic (ngclass);
                mono_class_create_generic_2 (ngclass);
 
@@ -327,7 +327,6 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
 
                nt = dup_type (type, type);
                nt->data.generic_class = ngclass;
-               g_hash_table_insert (ogclass->klass->image->generic_class_cache, ngclass, ngclass);
                mono_loader_unlock ();
                return nt;
        }
@@ -349,9 +348,8 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context)
        return inflated;
 }
 
-static MonoMethodSignature*
-inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig,
-                          MonoGenericContext *context)
+MonoMethodSignature*
+mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context)
 {
        MonoMethodSignature *res;
        gboolean is_open;
@@ -421,11 +419,12 @@ mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *conte
                rklass = result->nmethod.method.klass = mono_class_from_mono_type (declaring);
        }
 
-       result->nmethod.method.signature = inflate_generic_signature (
+       result->nmethod.method.signature = mono_class_inflate_generic_signature (
                method->klass->image, method->signature, context);
 
        if (context->gmethod) {
                result->context = g_new0 (MonoGenericContext, 1);
+               result->context->container = context->gmethod->container;
                result->context->gmethod = context->gmethod;
                result->context->gclass = rklass->generic_class;
 
@@ -525,7 +524,8 @@ class_compute_field_layout (MonoClass *class)
                        container = class->generic_class->container;
                }
                field->type = mono_metadata_parse_type_full (
-                       m, container, MONO_PARSE_FIELD, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
+                       m, (MonoGenericContext *) container, MONO_PARSE_FIELD,
+                       cols [MONO_FIELD_FLAGS], sig + 1, &sig);
                if (mono_field_is_deleted (field))
                        continue;
                if (class->generic_class) {
@@ -1857,6 +1857,11 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        if (cols [MONO_TYPEDEF_EXTENDS])
                parent = mono_class_get_full (
                        image, mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS]), context);
+
+       mono_class_setup_parent (class, parent);
+
+       mono_class_setup_mono_type (class);
+
        interfaces = mono_metadata_interfaces_from_typedef_full (image, type_token, &icount, context);
 
        class->interfaces = interfaces;
@@ -1873,10 +1878,6 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 
        /*g_print ("Load class %s\n", name);*/
 
-       mono_class_setup_parent (class, parent);
-
-       mono_class_setup_mono_type (class);
-
        /*
         * Compute the field and method lists
         */
@@ -2235,21 +2236,9 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec,
                                 MonoGenericContext *context)
 {
        MonoType *type, *inflated;
-       MonoGenericContainer *container = NULL;
        MonoClass *class;
 
-       if (context) {
-               if (context->gmethod && context->gmethod->container) {
-                       g_assert (context->gmethod->container);
-                       container = context->gmethod->container;
-               } else if (context->gclass) {
-                       g_assert (context->gclass->container);
-                       container = context->gclass->container;
-               } else if (context->container)
-                       container = context->container;
-       }
-
-       type = mono_type_create_from_typespec_full (image, container, type_spec);
+       type = mono_type_create_from_typespec_full (image, context, type_spec);
 
        switch (type->type) {
        case MONO_TYPE_ARRAY:
index 7a918105eded5b3b85a512b71c35d3653451974e..5a22906b7e3bc62f071e1219815ab0526e476e57 100644 (file)
@@ -35,6 +35,7 @@ static const char *wrapper_type_names [] = {
        "cancast",
        "proxy_isinst",
        "stelemref",
+       "unbox",
        "unknown"
 };
 
index b6ac3052ee7cae718863d7656e84eae6ebacc6e5..19aee1acc578ca983a9d281a294282c591a40404 100644 (file)
@@ -607,14 +607,11 @@ mono_image_init (MonoImage *image)
        image->native_wrapper_cache = g_hash_table_new (NULL, NULL);
        image->remoting_invoke_cache = g_hash_table_new (NULL, NULL);
        image->synchronized_cache = g_hash_table_new (NULL, NULL);
+       image->unbox_wrapper_cache = g_hash_table_new (NULL, NULL);
 
        image->typespec_cache = g_hash_table_new (NULL, NULL);
        image->memberref_signatures = g_hash_table_new (NULL, NULL);
        image->helper_signatures = g_hash_table_new (g_str_hash, g_str_equal);
-
-       image->generic_class_cache =
-               g_hash_table_new ((GHashFunc)mono_metadata_generic_class_hash,
-                                 (GCompareFunc)mono_metadata_generic_class_equal);
 }
 
 static MonoImage *
@@ -1030,8 +1027,9 @@ mono_image_close (MonoImage *image)
        g_hash_table_foreach (image->remoting_invoke_cache, free_remoting_wrappers, NULL);
        g_hash_table_destroy (image->remoting_invoke_cache);
        g_hash_table_destroy (image->runtime_invoke_cache);
+       g_hash_table_destroy (image->synchronized_cache);
+       g_hash_table_destroy (image->unbox_wrapper_cache);
        g_hash_table_destroy (image->typespec_cache);
-       g_hash_table_destroy (image->generic_class_cache);
        g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL);
        g_hash_table_destroy (image->memberref_signatures);
        g_hash_table_foreach (image->helper_signatures, free_mr_signatures, NULL);
index 1b1ff8426923308b0e497b33ad11f6cc33ebab56..e0ab7fc1bb2718a0b4bd92cc7a77e62efc274a47 100644 (file)
@@ -246,7 +246,7 @@ find_method (MonoClass *klass, MonoClass *ic, const char* name, MonoMethodSignat
  * token is the method_ref or method_def token used in a call IL instruction.
  */
 MonoMethodSignature*
-mono_method_get_signature (MonoMethod *method, MonoImage *image, guint32 token)
+mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context)
 {
        int table = mono_metadata_token_table (token);
        int idx = mono_metadata_token_index (token);
@@ -279,13 +279,21 @@ mono_method_get_signature (MonoMethod *method, MonoImage *image, guint32 token)
        
                ptr = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
                mono_metadata_decode_blob_size (ptr, &ptr);
-               sig = mono_metadata_parse_method_signature (image, 0, ptr, NULL);
+               sig = mono_metadata_parse_method_signature_full (image, context, 0, ptr, NULL);
                g_hash_table_insert (image->memberref_signatures, GUINT_TO_POINTER (token), sig);
        }
 
+       sig = mono_class_inflate_generic_signature (image, sig, context);
+
        return sig;
 }
 
+MonoMethodSignature*
+mono_method_get_signature (MonoMethod *method, MonoImage *image, guint32 token)
+{
+       return mono_method_get_signature_full (method, image, token, NULL);
+}
+
 static MonoMethod *
 method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *context)
 {
@@ -347,7 +355,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *contex
 
        ptr = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
        mono_metadata_decode_blob_size (ptr, &ptr);
-       sig = mono_metadata_parse_method_signature_full (image, container, 0, ptr, NULL);
+       sig = mono_metadata_parse_method_signature_full (image, (MonoGenericContext *) container, 0, ptr, NULL);
 
        switch (class) {
        case MONO_MEMBERREF_PARENT_TYPEREF:
@@ -457,17 +465,18 @@ method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 i
        g_assert (container && container->is_method);
 
        if (context) {
-               if (context->gclass) {
-                       g_assert (context->gclass->container);
-                       container->parent = context->gclass->container;
-               } else
-                       container->parent = context->container;
+               g_assert (context->container);
+               container->parent = context->container;
+               if (container->parent->is_method)
+                       container->parent = container->parent->parent;
        }
 
        gmethod = g_new0 (MonoGenericMethod, 1);
        gmethod->container = container;
 
-       gmethod->inst = mono_metadata_parse_generic_inst (image, container, param_count, ptr, &ptr);
+       gmethod->inst = mono_metadata_parse_generic_inst (
+               image, (MonoGenericContext *) container, param_count, ptr, &ptr);
+
        if (context)
                gmethod->inst = mono_metadata_inflate_generic_inst (gmethod->inst, context);
 
@@ -483,11 +492,13 @@ method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 i
 
        if (!context) {
                new_context = g_new0 (MonoGenericContext, 1);
+               new_context->container = container;
                new_context->gmethod = gmethod;
 
                context = new_context;
        } else {
                new_context = g_new0 (MonoGenericContext, 1);
+               new_context->container = container;
                new_context->gmethod = gmethod;
                new_context->gclass = context->gclass;
 
@@ -809,11 +820,8 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
        if (table != MONO_TABLE_METHOD) {
                MonoGenericContainer *generic_container = NULL;
                if (context) {
-                       if (context->gclass) {
-                               g_assert (context->gclass->container);
-                               generic_container = context->gclass->container;
-                       } else
-                               generic_container = context->container;
+                       g_assert (context->container);
+                       generic_container = context->container;
                }
                if (table == MONO_TABLE_METHODSPEC)
                        return method_from_methodspec (image, context, idx);
@@ -856,7 +864,8 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
        if (!sig) /* already taken from the methodref */
                sig = mono_metadata_blob_heap (image, cols [4]);
        size = mono_metadata_decode_blob_size (sig, &sig);
-       result->signature = mono_metadata_parse_method_signature_full (image, container, idx, sig, NULL);
+       result->signature = mono_metadata_parse_method_signature_full (
+               image, (MonoGenericContext *) container, idx, sig, NULL);
 
        if (!result->klass) {
                guint32 type = mono_metadata_typedef_from_method (image, token);
@@ -930,7 +939,8 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
                    !(result->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) && container) {
                        gpointer loc = mono_image_rva_map (image, cols [0]);
                        g_assert (loc);
-                       ((MonoMethodNormal *) result)->header = mono_metadata_parse_mh_full (image, container, loc);
+                       ((MonoMethodNormal *) result)->header = mono_metadata_parse_mh_full (
+                               image, (MonoGenericContext *) container, loc);
                }
                
                ((MonoMethodNormal *) result)->generic_container = generic_container;
@@ -1324,7 +1334,7 @@ mono_method_get_header (MonoMethod *method)
        
        g_assert (loc);
        
-       mn->header = mono_metadata_parse_mh_full (img, mn->generic_container, loc);
+       mn->header = mono_metadata_parse_mh_full (img, (MonoGenericContext *) mn->generic_container, loc);
        
        mono_loader_unlock ();
        return mn->header;
index 08f4aca2862da28aeb222a624d1027cea3fc64cd..f48b361f177e85b1eec7ebc03ebc2d5621c6c847 100644 (file)
@@ -6433,6 +6433,44 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        return res;     
 }
 
+
+/*
+ * the returned method calls 'method' unboxing the this argument
+ */
+MonoMethod *
+mono_marshal_get_unbox_wrapper (MonoMethod *method)
+{
+       MonoMethodSignature *sig = method->signature;
+       int i;
+       MonoMethodBuilder *mb;
+       MonoMethod *res;
+       GHashTable *cache;
+
+       cache = method->klass->image->unbox_wrapper_cache;
+       if ((res = mono_marshal_find_in_cache (cache, method)))
+               return res;
+
+       mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_UNBOX);
+
+       g_assert (sig->hasthis);
+       
+       mono_mb_emit_ldarg (mb, 0); 
+       mono_mb_emit_icon (mb, sizeof (MonoObject));
+       mono_mb_emit_byte (mb, CEE_ADD);
+       for (i = 0; i < sig->param_count; ++i)
+               mono_mb_emit_ldarg (mb, i + 1);
+       mono_mb_emit_managed_call (mb, method, NULL);
+       mono_mb_emit_byte (mb, CEE_RET);
+
+       res = mono_mb_create_and_cache (cache, method,
+                                                                                mb, sig, sig->param_count + 16);
+       mono_mb_free (mb);
+
+       /* printf ("CODE FOR %s: \n%s.\n", mono_method_full_name (res, TRUE), mono_disasm_code (0, res, ((MonoMethodNormal*)res)->header->code, ((MonoMethodNormal*)res)->header->code + ((MonoMethodNormal*)res)->header->code_size)); */
+
+       return res;     
+}
+
 MonoMethod*
 mono_marshal_get_stelemref ()
 {
index 43004118ac120419169efe772626f5dab28b52ef..be1ac9e5f835ad5bb7c4730b4f5d040368cfa452 100644 (file)
@@ -209,6 +209,9 @@ mono_marshal_get_ldfld_wrapper (MonoType *type);
 MonoMethod *
 mono_marshal_get_synchronized_wrapper (MonoMethod *method);
 
+MonoMethod *
+mono_marshal_get_unbox_wrapper (MonoMethod *method);
+
 MonoMethod *
 mono_marshal_get_isinst (MonoClass *klass);
 
index a141b9b404d9aacc02fa70189cc0b14b5425f91f..1a210139ed6d69af13e56f6528c782928b166153 100644 (file)
@@ -100,11 +100,6 @@ struct _MonoImage {
        GHashTable *memberref_signatures;
        GHashTable *helper_signatures;
 
-       /*
-        * Indexed by MonoGenericClass.
-        */
-       GHashTable *generic_class_cache;
-
        /*
         * Indexes namespaces to hash tables that map class name to typedef token.
         */
@@ -131,6 +126,7 @@ struct _MonoImage {
        GHashTable *native_wrapper_cache;
        GHashTable *remoting_invoke_cache;
        GHashTable *synchronized_cache;
+       GHashTable *unbox_wrapper_cache;
 
        void *reflection_info;
 
@@ -234,13 +230,13 @@ mono_metadata_interfaces_from_typedef_full  (MonoImage             *image,
 
 MonoArrayType *
 mono_metadata_parse_array_full              (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             const char            *ptr,
                                             const char           **rptr);
 
 MonoType *
 mono_metadata_parse_type_full               (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             MonoParseTypeMode      mode,
                                             short                  opt_attrs,
                                             const char            *ptr,
@@ -248,24 +244,24 @@ mono_metadata_parse_type_full               (MonoImage             *image,
 
 MonoType *
 mono_type_create_from_typespec_full         (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             guint32                type_spec);
 
 MonoMethodSignature *
 mono_metadata_parse_signature_full          (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             guint32                token);
 
 MonoMethodSignature *
 mono_metadata_parse_method_signature_full   (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             int                     def,
                                             const char             *ptr,
                                             const char            **rptr);
 
 MonoMethodHeader *
 mono_metadata_parse_mh_full                 (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             const char            *ptr);
 
 guint
@@ -277,7 +273,7 @@ mono_metadata_generic_method_equal          (MonoGenericMethod     *g1,
 
 MonoGenericInst *
 mono_metadata_parse_generic_inst            (MonoImage             *image,
-                                            MonoGenericContainer  *generic_container,
+                                            MonoGenericContext    *generic_context,
                                             int                    count,
                                             const char            *ptr,
                                             const char           **rptr);
@@ -285,6 +281,9 @@ mono_metadata_parse_generic_inst            (MonoImage             *image,
 MonoGenericInst *
 mono_metadata_lookup_generic_inst           (MonoGenericInst       *ginst);
 
+MonoGenericClass *
+mono_metadata_lookup_generic_class          (MonoGenericClass      *gclass);
+
 MonoGenericInst *
 mono_metadata_inflate_generic_inst          (MonoGenericInst       *ginst,
                                             MonoGenericContext    *context);
index 28f2119acfe80ef43a1c17959cca8aabb9cfcb0c..7d77c99efdaabfa7d5d81623db8cdf2a32cec666 100644 (file)
 #include "private.h"
 #include "class.h"
 
-static void do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *generic_container,
+static void do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContext *generic_context,
                                         const char *ptr, const char **rptr);
 
 static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only);
+static gboolean _mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2,
+                                                   gboolean signature_only);
 
 /*
  * Encoding of the "description" argument:
@@ -1057,14 +1059,14 @@ mono_metadata_parse_custom_mod (MonoImage *m, MonoCustomMod *dest, const char *p
  * and dimensions.
  */
 MonoArrayType *
-mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_array_full (MonoImage *m, MonoGenericContext *generic_context,
                                const char *ptr, const char **rptr)
 {
        int i;
        MonoArrayType *array = g_new0 (MonoArrayType, 1);
        MonoType *etype;
        
-       etype = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       etype = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
        array->eklass = mono_class_from_mono_type (etype);
        array->rank = mono_metadata_decode_value (ptr, &ptr);
 
@@ -1157,6 +1159,7 @@ builtin_types[] = {
 
 static GHashTable *type_cache = NULL;
 static GHashTable *generic_inst_cache = NULL;
+static GHashTable *generic_class_cache = NULL;
 static int next_generic_inst_id = 0;
 
 /*
@@ -1204,6 +1207,22 @@ mono_generic_inst_equal (gconstpointer ka, gconstpointer kb)
        return TRUE;
 }
 
+static guint
+mono_generic_class_hash (gconstpointer data)
+{
+       const MonoGenericClass *gclass = (const MonoGenericClass *) data;
+       return mono_metadata_type_hash (gclass->generic_type);
+}
+
+static gboolean
+mono_generic_class_equal (gconstpointer ka, gconstpointer kb)
+{
+       const MonoGenericClass *a = (const MonoGenericClass *) ka;
+       const MonoGenericClass *b = (const MonoGenericClass *) kb;
+
+       return _mono_metadata_generic_class_equal (a, b, FALSE);
+}
+
 /**
  * mono_metadata_init:
  *
@@ -1216,6 +1235,7 @@ mono_metadata_init (void)
 
        type_cache = g_hash_table_new (mono_type_hash, mono_type_equal);
        generic_inst_cache = g_hash_table_new (mono_generic_inst_hash, mono_generic_inst_equal);
+       generic_class_cache = g_hash_table_new (mono_generic_class_hash, mono_generic_class_equal);
 
        for (i = 0; i < NBUILTIN_TYPES (); ++i)
                g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
@@ -1244,7 +1264,7 @@ mono_metadata_init (void)
  * Returns: a #MonoType structure representing the decoded type.
  */
 MonoType*
-mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *generic_container, MonoParseTypeMode mode,
+mono_metadata_parse_type_full (MonoImage *m, MonoGenericContext *generic_context, MonoParseTypeMode mode,
                               short opt_attrs, const char *ptr, const char **rptr)
 {
        MonoType *type, *cached;
@@ -1324,7 +1344,7 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *generic_conta
        type->byref = byref;
        type->pinned = pinned ? 1 : 0;
 
-       do_mono_metadata_parse_type (type, m, generic_container, ptr, &ptr);
+       do_mono_metadata_parse_type (type, m, generic_context, ptr, &ptr);
 
        if (rptr)
                *rptr = ptr;
@@ -1370,7 +1390,7 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
  * Returns: a MonoMethodSignature describing the signature.
  */
 MonoMethodSignature *
-mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 token)
+mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContext *generic_context, guint32 token)
 {
        MonoTableInfo *tables = image->tables;
        guint32 idx = mono_metadata_token_index (token);
@@ -1387,7 +1407,7 @@ mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *gene
        ptr = mono_metadata_blob_heap (image, sig);
        mono_metadata_decode_blob_size (ptr, &ptr);
 
-       return mono_metadata_parse_method_signature_full (image, generic_container, FALSE, ptr, NULL); 
+       return mono_metadata_parse_method_signature_full (image, generic_context, FALSE, ptr, NULL); 
 }
 
 MonoMethodSignature *
@@ -1430,7 +1450,7 @@ mono_metadata_signature_dup (MonoMethodSignature *sig)
  * Returns: a MonoMethodSignature describing the signature.
  */
 MonoMethodSignature *
-mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContext *generic_context,
                                           int def, const char *ptr, const char **rptr)
 {
        MonoMethodSignature *method;
@@ -1438,7 +1458,7 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *g
        guint32 hasthis = 0, explicit_this = 0, call_convention, param_count;
        guint32 gen_param_count = 0;
        gboolean is_open = FALSE;
-       MonoGenericContainer *container = NULL;
+       MonoGenericContext *context = NULL;
 
        if (*ptr & 0x10)
                gen_param_count = 1;
@@ -1480,13 +1500,15 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *g
        if (gen_param_count)
                method->has_type_parameters = 1;
 
-       if (gen_param_count && (!generic_container || !generic_container->is_method)) {
-               container = g_new0 (MonoGenericContainer, 1);
-               container->parent = generic_container;
+       if (gen_param_count && (!generic_context || !generic_context->container->is_method)) {
+               MonoGenericContainer *container = g_new0 (MonoGenericContainer, 1);
+
+               if (generic_context)
+                       container->parent = generic_context->container;
                container->is_signature = 1;
 
-               container->context = g_new0 (MonoGenericContext, 1);
-               container->context->container = container;
+               context = &container->context;
+               container->context.container = container;
 
                container->type_argc = gen_param_count;
                container->type_params = g_new0 (MonoGenericParam, gen_param_count);
@@ -1496,10 +1518,10 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *g
                        container->type_params [i].num = i;
                }
        } else
-               container = generic_container;
+               context = generic_context;
 
        if (call_convention != 0xa) {
-               method->ret = mono_metadata_parse_type_full (m, container, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
+               method->ret = mono_metadata_parse_type_full (m, context, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
                is_open = mono_class_is_open_constructed_type (method->ret);
        }
 
@@ -1514,7 +1536,7 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *g
                                ptr++;
                        }
                        method->params [i] = mono_metadata_parse_type_full (
-                               m, container, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
+                               m, context, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
                        if (!is_open)
                                is_open = mono_class_is_open_constructed_type (method->params [i]);
                }
@@ -1579,6 +1601,20 @@ mono_metadata_lookup_generic_inst (MonoGenericInst *ginst)
        return ginst;
 }
 
+MonoGenericClass *
+mono_metadata_lookup_generic_class (MonoGenericClass *gclass)
+{
+       MonoGenericClass *cached;
+       int i;
+
+       cached = g_hash_table_lookup (generic_class_cache, gclass);
+       if (cached)
+               return cached;
+
+       g_hash_table_insert (generic_class_cache, gclass, gclass);
+       return NULL;
+}
+
 MonoGenericInst *
 mono_metadata_inflate_generic_inst (MonoGenericInst *ginst, MonoGenericContext *context)
 {
@@ -1602,7 +1638,7 @@ mono_metadata_inflate_generic_inst (MonoGenericInst *ginst, MonoGenericContext *
 }
 
 MonoGenericInst *
-mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContext *generic_context,
                                  int count, const char *ptr, const char **rptr)
 {
        MonoGenericInst *ginst;
@@ -1613,7 +1649,7 @@ mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContainer *generic_co
        ginst->type_argv = g_new0 (MonoType*, count);
 
        for (i = 0; i < ginst->type_argc; i++) {
-               MonoType *t = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_TYPE, 0, ptr, &ptr);
+               MonoType *t = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
 
                ginst->type_argv [i] = t;
                if (!ginst->is_open)
@@ -1627,7 +1663,7 @@ mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContainer *generic_co
 }
 
 static void
-do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericContainer *generic_container,
+do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericContext *generic_context,
                                      const char *ptr, const char **rptr)
 {
        MonoGenericClass *gclass = g_new0 (MonoGenericClass, 1);
@@ -1643,10 +1679,10 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
 
        gclass->klass = g_new0 (MonoClass, 1);
 
-       gclass->generic_type = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_TYPE, 0, ptr, &ptr);
+       gclass->generic_type = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
 
        gklass = mono_class_from_mono_type (gclass->generic_type);
-       g_assert ((gclass->container = gklass->generic_container) != NULL);
+       g_assert ((gclass->context->container = gclass->container = gklass->generic_container) != NULL);
 
        count = mono_metadata_decode_value (ptr, &ptr);
 
@@ -1660,7 +1696,7 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
 
        mono_class_create_generic (gclass);
 
-       gclass->inst = mono_metadata_parse_generic_inst (m, generic_container, count, ptr, &ptr);
+       gclass->inst = mono_metadata_parse_generic_inst (m, generic_context, count, ptr, &ptr);
 
        mono_class_create_generic_2 (gclass);
 
@@ -1681,7 +1717,7 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
         * type.
         */
 
-       cached = g_hash_table_lookup (m->generic_class_cache, gclass);
+       cached = g_hash_table_lookup (generic_class_cache, gclass);
        if (cached) {
                g_free (gclass->klass);
                g_free (gclass);
@@ -1689,7 +1725,7 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
                type->data.generic_class = cached;
                return;
        } else {
-               g_hash_table_insert (m->generic_class_cache, gclass, gclass);
+               g_hash_table_insert (generic_class_cache, gclass, gclass);
 
                mono_stats.generic_instance_count++;
                mono_stats.generics_metadata_size += sizeof (MonoGenericClass) +
@@ -1707,15 +1743,19 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
  * Internal routine to parse a generic type parameter.
  */
 static MonoGenericParam *
-mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContext *generic_context,
                                   gboolean is_mvar, const char *ptr, const char **rptr)
 {
+       MonoGenericContainer *generic_container;
        int index;
 
        index = mono_metadata_decode_value (ptr, &ptr);
        if (rptr)
                *rptr = ptr;
 
+       g_assert (generic_context);
+       generic_container = generic_context->container;
+
        if (!is_mvar) {
                g_assert (generic_container);
                if (generic_container->parent) {
@@ -1752,7 +1792,7 @@ mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContainer *generic_c
  * This extracts a Type as specified in Partition II (22.2.12) 
  */
 static void
-do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *generic_container,
+do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContext *generic_context,
                             const char *ptr, const char **rptr)
 {
        type->type = mono_metadata_decode_value (ptr, &ptr);
@@ -1785,31 +1825,31 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer
                break;
        }
        case MONO_TYPE_SZARRAY: {
-               MonoType *etype = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
+               MonoType *etype = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
                type->data.klass = mono_class_from_mono_type (etype);
                mono_metadata_free_type (etype);
                break;
        }
        case MONO_TYPE_PTR:
-               type->data.type = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
+               type->data.type = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
                break;
        case MONO_TYPE_FNPTR:
-               type->data.method = mono_metadata_parse_method_signature_full (m, generic_container, 0, ptr, &ptr);
+               type->data.method = mono_metadata_parse_method_signature_full (m, generic_context, 0, ptr, &ptr);
                break;
        case MONO_TYPE_ARRAY:
-               type->data.array = mono_metadata_parse_array_full (m, generic_container, ptr, &ptr);
+               type->data.array = mono_metadata_parse_array_full (m, generic_context, ptr, &ptr);
                break;
 
        case MONO_TYPE_MVAR:
-               type->data.generic_param = mono_metadata_parse_generic_param (m, generic_container, TRUE, ptr, &ptr);
+               type->data.generic_param = mono_metadata_parse_generic_param (m, generic_context, TRUE, ptr, &ptr);
                break;
 
        case MONO_TYPE_VAR:
-               type->data.generic_param = mono_metadata_parse_generic_param (m, generic_container, FALSE, ptr, &ptr);
+               type->data.generic_param = mono_metadata_parse_generic_param (m, generic_context, FALSE, ptr, &ptr);
                break;
 
        case MONO_TYPE_GENERICINST:
-               do_mono_metadata_parse_generic_class (type, m, generic_container, ptr, &ptr);
+               do_mono_metadata_parse_generic_class (type, m, generic_context, ptr, &ptr);
                break;
                
        default:
@@ -1979,7 +2019,7 @@ parse_section_data (MonoImage *m, MonoMethodHeader *mh, const unsigned char *ptr
  * Returns: a MonoMethodHeader.
  */
 MonoMethodHeader *
-mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *generic_container, const char *ptr)
+mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContext *generic_context, const char *ptr)
 {
        MonoMethodHeader *mh;
        unsigned char flags = *(const unsigned char *) ptr;
@@ -2062,7 +2102,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *generic_contain
                mh->num_locals = len;
                for (i = 0; i < len; ++i)
                        mh->locals [i] = mono_metadata_parse_type_full (
-                               m, generic_container, MONO_PARSE_LOCAL, 0, locals_ptr, &locals_ptr);
+                               m, generic_context, MONO_PARSE_LOCAL, 0, locals_ptr, &locals_ptr);
        } else {
                mh = g_new0 (MonoMethodHeader, 1);
        }
@@ -2788,12 +2828,6 @@ mono_metadata_generic_class_is_valuetype (MonoGenericClass *gclass)
        return MONO_TYPE_ISSTRUCT (gclass->generic_type);
 }
 
-guint
-mono_metadata_generic_class_hash (MonoGenericClass *gclass)
-{
-       return mono_metadata_type_hash (gclass->generic_type);
-}
-
 static gboolean
 _mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2, gboolean signature_only)
 {
@@ -2810,12 +2844,6 @@ _mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2,
        return TRUE;
 }
 
-gboolean
-mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2)
-{
-       return _mono_metadata_generic_class_equal (g1, g2, FALSE);
-}
-
 guint
 mono_metadata_generic_method_hash (MonoGenericMethod *gmethod)
 {
@@ -2852,7 +2880,7 @@ mono_metadata_type_hash (MonoType *t1)
        case MONO_TYPE_ARRAY:
                return ((hash << 5) - hash) ^ mono_metadata_type_hash (&t1->data.array->eklass->byval_arg);
        case MONO_TYPE_GENERICINST:
-               return ((hash << 5) - hash) ^ mono_metadata_generic_class_hash (t1->data.generic_class);
+               return ((hash << 5) - hash) ^ mono_generic_class_hash (t1->data.generic_class);
        }
        return hash;
 }
@@ -3357,7 +3385,7 @@ mono_metadata_implmap_from_method (MonoImage *meta, guint32 method_idx)
  * token.
  */
 MonoType *
-mono_type_create_from_typespec_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 type_spec)
+mono_type_create_from_typespec_full (MonoImage *image, MonoGenericContext *generic_context, guint32 type_spec)
 {
        guint32 idx = mono_metadata_token_index (type_spec);
        MonoTableInfo *t;
@@ -3388,7 +3416,7 @@ mono_type_create_from_typespec_full (MonoImage *image, MonoGenericContainer *gen
                ptr++;
        }
 
-       do_mono_metadata_parse_type (type, image, generic_container, ptr, &ptr);
+       do_mono_metadata_parse_type (type, image, generic_context, ptr, &ptr);
 
        mono_loader_unlock ();
 
@@ -3803,11 +3831,10 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token)
        container->type_argc = n;
        container->type_params = params;
 
-       container->context = g_new0 (MonoGenericContext, 1);
-       container->context->container = container;
+       container->context.container = container;
 
        for (i = 0; i < n; i++)
-               params [i].constraints = get_constraints (image, i + 1, container->context);
+               params [i].constraints = get_constraints (image, i + 1, &container->context);
 
        return container;
 }
index 6c9121acd87913e7543dd514b6c6931e0e6a8053..27dc6c079cc30f8cf14315c3d30a09ece1d647a9 100644 (file)
@@ -979,5 +979,8 @@ mono_array_full_copy (MonoArray *src, MonoArray *dest);
 gpointer
 mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *real_proxy);
 
+MonoMethodSignature*
+mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context);
+
 #endif /* __MONO_OBJECT_INTERNALS_H__ */
 
index 6e3b6c954e3f3753d5f61fe13e6c0b63e3ef5a8d..9ea6665ce5bf2cbe83f0573caa572cc6ba19934b 100644 (file)
@@ -723,7 +723,7 @@ mono_class_vtable (MonoDomain *domain, MonoClass *class)
        for (i = 0; i < class->vtable_size; ++i) {
                MonoMethod *cm;
               
-               if (cm = class->vtable [i]) {
+               if ((cm = class->vtable [i])) {
                        if (cm->signature->generic_param_count)
                                vt->vtable [i] = cm;
                        else
@@ -3260,6 +3260,10 @@ mono_delegate_ctor (MonoObject *this, MonoObject *target, gpointer addr)
                method = mono_marshal_get_remoting_invoke (method);
                delegate->method_ptr = mono_compile_method (method);
                delegate->target = target;
+       } else if (method->signature->hasthis && method->klass->valuetype) {
+               method = mono_marshal_get_unbox_wrapper (method);
+               delegate->method_ptr = mono_compile_method (method);
+               delegate->target = target;
        } else {
                delegate->method_ptr = addr;
                delegate->target = target;
index 6f92804134657a8a7c9debb6e5c472d187da569c..66bdbc5233ab5f30bc31c171e5217b9d2c1bb09a 100644 (file)
@@ -3230,7 +3230,12 @@ compare_genericparam (const void *a, const void *b)
        const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
        const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
 
-       return (*b_entry)->owner - (*a_entry)->owner;
+       if ((*b_entry)->owner == (*a_entry)->owner)
+               return 
+                       (*a_entry)->gparam->type.type->data.generic_param->num - 
+                       (*b_entry)->gparam->type.type->data.generic_param->num;
+       else
+               return (*b_entry)->owner - (*a_entry)->owner;
 }
 
 static int
@@ -7350,8 +7355,7 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
        tb->generic_container = g_new0 (MonoGenericContainer, 1);
        tb->generic_container->klass = klass;
 
-       tb->generic_container->context = g_new0 (MonoGenericContext, 1);
-       tb->generic_container->context->container = tb->generic_container;
+       tb->generic_container->context.container = tb->generic_container;
 }
 
 /*
@@ -7838,6 +7842,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
                MonoGenericClass *ogclass = gclass;
 
                ogclass->context = g_new0 (MonoGenericContext, 1);
+               ogclass->context->container = ogclass->container;
                ogclass->context->gclass = ogclass;
 
                gclass = g_new0 (MonoGenericClass, 1);
@@ -7863,7 +7868,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        geninst = g_new0 (MonoType, 1);
        geninst->type = MONO_TYPE_GENERICINST;
 
-       cached = g_hash_table_lookup (klass->image->generic_class_cache, gclass);
+       cached = mono_metadata_lookup_generic_class (gclass);
        if (cached) {
                g_free (gclass);
                mono_loader_unlock ();
@@ -7879,6 +7884,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        gclass->parent = parent;
 
        gclass->context = g_new0 (MonoGenericContext, 1);
+       gclass->context->container = gclass->container;
        gclass->context->gclass = gclass;
 
        if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
@@ -7917,8 +7923,6 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        mono_class_create_generic (gclass);
        mono_class_create_generic_2 (gclass);
 
-       g_hash_table_insert (klass->image->generic_class_cache, gclass, gclass);
-
        mono_loader_unlock ();
 
        return geninst;
@@ -8027,6 +8031,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        ginst = mono_metadata_lookup_generic_inst (ginst);
 
        gmethod = g_new0 (MonoGenericMethod, 1);
+       gmethod->container = container;
        gmethod->inst = ginst;
 
        inflated = g_hash_table_lookup (container->method_hash, gmethod);
@@ -8039,6 +8044,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        gmethod->reflection_info = rmethod;
 
        context = g_new0 (MonoGenericContext, 1);
+       context->container = container;
        context->gclass = method->klass->generic_class;
        context->gmethod = gmethod;
 
@@ -8074,6 +8080,7 @@ inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoO
        }
 
        context = g_new0 (MonoGenericContext, 1);
+       context->container = gclass->container;
        context->gclass = gclass;
        context->gmethod = gmethod;
 
index 7ef51c8066405c294cdb4aa07e99c880e2547bec..f8afa9fd75c5146867a4c38494def492968b5a92 100644 (file)
@@ -1,3 +1,18 @@
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * mini.c (mono_method_to_ir): In CEE_CALLVIRT, use the new
+       mono_method_get_signature_full().       
+
+2004-12-03  Massimiliano Mantione  <massi@ximian.com>
+
+       * mini.c: Added removal of critical edges (prerequisite for SSAPRE),
+       and some utility functions (always for SSAPRE), integrated SSAPRE.
+       * mini.h: Likewise.
+       * driver.c: Added ssapre option.
+       * ssa.c: Small fix on OP_ARG handling.
+       * ssapre.c, ssapre.h: Added files containing SSAPRE implementation.
+       * Makefile.am: Likewise.
+
 2004-12-02  Zoltan Varga  <vargaz@freemail.hu>
 
        * tramp-x86.c (mono_arch_create_jit_trampoline): Remove code which is
index 2c13777629344b705e09980ab07eb3dd886410df..779753d1eb553e6e81ff3379e4cc928923c384d5 100644 (file)
@@ -159,6 +159,8 @@ common_sources = \
        ssa.c           \
        abcremoval.c    \
        abcremoval.h    \
+       ssapre.c        \
+       ssapre.h        \
        driver.c        \
        debug-mini.c    \
        linear-scan.c   \
@@ -341,4 +343,3 @@ EXTRA_DIST = $(common_BURGSRC) jit-icalls.c cprop.c TestDriver.cs ldscript $(tes
        $(sparc_sources) inssel-sparc.brg cpu-sparc.md \
        $(s390_sources) inssel-s390.brg cpu-s390.md \
        $(s390x_sources) inssel-s390x.brg cpu-s390x.md
-
index e07095aac46627805d94ee5ba3bba85c2a555833..d6094be730f92f679eb6e1836a9663d817208c62 100644 (file)
@@ -79,7 +79,8 @@ opt_names [] = {
        {"leaf",     "Leaf procedures optimizations"},
        {"aot",      "Usage of Ahead Of Time compiled code"},
        {"precomp",  "Precompile all methods before executing Main"},
-       {"abcrem",   "Array bound checks removal"}
+       {"abcrem",   "Array bound checks removal"},     
+       {"ssapre",   "SSA based Partial Redundancy Elimination"}
 };
 
 #define DEFAULT_OPTIMIZATIONS (        \
@@ -89,7 +90,7 @@ opt_names [] = {
        MONO_OPT_LINEARS |      \
        MONO_OPT_INTRINS |  \
        MONO_OPT_LOOP |  \
-    MONO_OPT_AOT)
+       MONO_OPT_AOT)
 
 #define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP)
 
@@ -228,6 +229,7 @@ opt_sets [] = {
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM,
+       MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_SSAPRE,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM | MONO_OPT_SHARED
 };
 
@@ -958,5 +960,3 @@ mono_jit_cleanup (MonoDomain *domain)
 {
        mini_cleanup (domain);
 }
-
-
index 0c1a9138d35852004eb5db46779e5559c5868cb6..cb54c38f66951967ff9d59d6d928d60457d41753 100644 (file)
@@ -1436,6 +1436,39 @@ mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
        return inst;
 }
 
+/*
+ * Transform a MonoInst into a load from the variable of index var_index.
+ */
+void
+mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index) {
+       memset (dest, 0, sizeof (MonoInst));
+       dest->ssa_op = MONO_SSA_LOAD;
+       dest->inst_i0 = cfg->varinfo [var_index];
+       dest->opcode = mono_type_to_ldind (dest->inst_i0->inst_vtype);
+       type_to_eval_stack_type (dest->inst_i0->inst_vtype, dest);
+       dest->klass = dest->inst_i0->klass;
+}
+
+/*
+ * Create a MonoInst that is a load from the variable of index var_index.
+ */
+MonoInst*
+mono_compile_create_var_load (MonoCompile *cfg, gssize var_index) {
+       MonoInst *dest;
+       NEW_TEMPLOAD (cfg,dest,var_index);
+       return dest;
+}
+
+/*
+ * Create a MonoInst that is a store of the given value into the variable of index var_index.
+ */
+MonoInst*
+mono_compile_create_var_store (MonoCompile *cfg, gssize var_index, MonoInst *value) {
+       MonoInst *dest;
+       NEW_TEMPSTORE (cfg, dest, var_index, value);
+       return dest;
+}
+
 static MonoType*
 type_from_stack_type (MonoInst *ins) {
        switch (ins->type) {
@@ -1452,6 +1485,11 @@ type_from_stack_type (MonoInst *ins) {
        return NULL;
 }
 
+MonoType*
+mono_type_from_stack_type (MonoInst *ins) {
+       return type_from_stack_type (ins);
+}
+
 static MonoClass*
 array_access_to_klass (int opcode)
 {
@@ -1492,7 +1530,7 @@ array_access_to_klass (int opcode)
        return NULL;
 }
 
-static void
+void
 mono_add_ins_to_end (MonoBasicBlock *bb, MonoInst *inst)
 {
        MonoInst *prev;
@@ -2814,7 +2852,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
        if (method->signature->is_inflated)
                generic_context = ((MonoMethodInflated *) method)->context;
        else if (generic_container)
-               generic_context = generic_container->context;
+               generic_context = &generic_container->context;
 
        g_assert (!method->signature->has_type_parameters);
 
@@ -3342,7 +3380,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                                MonoMethod *wrapper = mono_marshal_get_native_wrapper (cmethod);
                                                fsig = wrapper->signature;
                                } else {
-                                       fsig = mono_method_get_signature (cmethod, image, token);
+                                       fsig = mono_method_get_signature_full (cmethod, image, token, generic_context);
                                }
 
                                n = fsig->param_count + fsig->hasthis;
@@ -6002,6 +6040,7 @@ mono_print_tree (MonoInst *tree) {
                printf ("[%s] <- [%s + 0x%x]", mono_arch_regname (tree->dreg), mono_arch_regname (tree->inst_basereg), tree->inst_offset);
                break;
        case CEE_BR:
+       case OP_CALL_HANDLER:
                printf ("[B%d]", tree->inst_target_bb->block_num);
                break;
        case CEE_SWITCH:
@@ -7152,8 +7191,12 @@ mono_compile_create_vars (MonoCompile *cfg)
        if (sig->hasthis)
                mono_compile_create_var (cfg, &cfg->method->klass->this_arg, OP_ARG);
 
-       for (i = 0; i < sig->param_count; ++i)
+       for (i = 0; i < sig->param_count; ++i) {
                mono_compile_create_var (cfg, sig->params [i], OP_ARG);
+               if (sig->params [i]->byref) {
+                       cfg->disable_ssa = TRUE;
+               }
+       }
 
        cfg->locals_start = cfg->num_varinfo;
 
@@ -7697,6 +7740,136 @@ mono_local_cprop (MonoCompile *cfg)
        }
 }
 
+static void
+remove_critical_edges (MonoCompile *cfg) {
+       MonoBasicBlock *bb;
+       
+       if (cfg->verbose_level > 3) {
+               for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+                       int i;
+                       printf ("remove_critical_edges %s, BEFORE BB%d (in:", mono_method_full_name (cfg->method, TRUE), bb->block_num);
+                       for (i = 0; i < bb->in_count; i++) {
+                               printf (" %d", bb->in_bb [i]->block_num);
+                       }
+                       printf (") (out:");
+                       for (i = 0; i < bb->out_count; i++) {
+                               printf (" %d", bb->out_bb [i]->block_num);
+                       }
+                       printf (")");
+                       if (bb->last_ins != NULL) {
+                               printf (" ");
+                               mono_print_tree (bb->last_ins);
+                       }
+                       printf ("\n");
+               }
+       }
+       
+       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+               if (bb->out_count > 1) {
+                       int out_bb_index;
+                       for (out_bb_index = 0; out_bb_index < bb->out_count; out_bb_index++) {
+                               MonoBasicBlock *out_bb = bb->out_bb [out_bb_index];
+                               if (out_bb->in_count > 1) {
+                                       MonoInst *inst;
+                                       MonoBasicBlock *new_bb = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock));
+                                       new_bb->block_num = cfg->num_bblocks++;
+                                       new_bb->next_bb = bb->next_bb;
+                                       bb->next_bb = new_bb;
+                                       new_bb->in_bb = mono_mempool_alloc ((cfg)->mempool, sizeof (MonoBasicBlock*));
+                                       new_bb->in_bb [0] = bb;
+                                       new_bb->in_count = 1;
+                                       new_bb->out_bb = mono_mempool_alloc ((cfg)->mempool, sizeof (MonoBasicBlock*));
+                                       new_bb->out_bb [0] = out_bb;
+                                       new_bb->out_count = 1;
+                                       replace_out_block (bb, out_bb, new_bb);
+                                       replace_in_block (out_bb, bb, new_bb);
+                                       for (inst = bb->code; inst != NULL; inst = inst->next) {
+                                               if (inst->opcode == OP_CALL_HANDLER) {
+                                                       if (inst->inst_target_bb == out_bb) {
+                                                               inst->inst_target_bb = new_bb;
+                                                       }
+                                               }
+                                       }
+                                       if (bb->last_ins != NULL) {
+                                               switch (bb->last_ins->opcode) {
+                                               case CEE_BR:
+                                                       if (bb->last_ins->inst_target_bb == out_bb) {
+                                                               bb->last_ins->inst_target_bb = new_bb;
+                                                       }
+                                                       break;
+                                               case CEE_SWITCH: {
+                                                       int i;
+                                                       int n = GPOINTER_TO_INT (bb->last_ins->klass);
+                                                       for (i = 0; i < n; i++ ) {
+                                                               if (bb->last_ins->inst_many_bb [i] == out_bb) {
+                                                                       bb->last_ins->inst_many_bb [i] = new_bb;
+                                                                       break;
+                                                               }
+                                                       }
+                                                       break;
+                                               }
+                                               case CEE_BNE_UN:
+                                               case CEE_BEQ:
+                                               case CEE_BLT:
+                                               case CEE_BLT_UN:
+                                               case CEE_BGT:
+                                               case CEE_BGT_UN:
+                                               case CEE_BGE:
+                                               case CEE_BGE_UN:
+                                               case CEE_BLE:
+                                               case CEE_BLE_UN:
+                                                       if (bb->last_ins->inst_true_bb == out_bb) {
+                                                               bb->last_ins->inst_true_bb = new_bb;
+                                                       }
+                                                       if (bb->last_ins->inst_false_bb == out_bb) {
+                                                               bb->last_ins->inst_false_bb = new_bb;
+                                                       }
+                                                       break;
+                                               default:
+                                                       break;
+                                               }
+                                       }
+//                                     new_bb->real_offset = bb->real_offset;
+                                       new_bb->region = bb->region;
+                                       
+                                       if (new_bb->next_bb != out_bb) {
+                                               MonoInst *jump;
+                                               MONO_INST_NEW (cfg, jump, CEE_BR);
+                                               MONO_ADD_INS (new_bb, jump);
+                                               jump->cil_code = bb->cil_code;
+                                               jump->inst_target_bb = out_bb;
+                                       }
+                                       
+                                       if (cfg->verbose_level > 2) {
+                                               printf ("remove_critical_edges %s, removed critical edge from BB%d to BB%d (added BB%d)\n", mono_method_full_name (cfg->method, TRUE), bb->block_num, out_bb->block_num, new_bb->block_num);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       if (cfg->verbose_level > 3) {
+               for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+                       int i;
+                       printf ("remove_critical_edges %s, AFTER BB%d (in:", mono_method_full_name (cfg->method, TRUE), bb->block_num);
+                       for (i = 0; i < bb->in_count; i++) {
+                               printf (" %d", bb->in_bb [i]->block_num);
+                       }
+                       printf (") (out:");
+                       for (i = 0; i < bb->out_count; i++) {
+                               printf (" %d", bb->out_bb [i]->block_num);
+                       }
+                       printf (")");
+                       if (bb->last_ins != NULL) {
+                               printf (" ");
+                               mono_print_tree (bb->last_ins);
+                       }
+                       printf ("\n");
+               }
+       }
+}
+
+
 MonoCompile*
 mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gboolean run_cctors, int parts)
 {
@@ -7751,12 +7924,16 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        }
        /*g_print ("numblocks = %d\n", cfg->num_bblocks);*/
 
-       /* Depth-first ordering on basic blocks */
-       cfg->bblocks = mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1));
-
        if (cfg->opt & MONO_OPT_BRANCH)
                optimize_branches (cfg);
 
+       if ((cfg->opt & MONO_OPT_SSAPRE) && ! (cfg->opt & (MONO_OPT_CONSPROP|MONO_OPT_COPYPROP))) {
+               remove_critical_edges (cfg);
+       }
+
+       /* Depth-first ordering on basic blocks */
+       cfg->bblocks = mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1));
+
        df_visit (cfg->bb_entry, &dfn, cfg->bblocks);
        if (cfg->num_bblocks != dfn + 1) {
                MonoBasicBlock *bb;
@@ -7801,7 +7978,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 #else 
 
        /* fixme: add all optimizations which requires SSA */
-       if (cfg->opt & (MONO_OPT_DEADCE | MONO_OPT_ABCREM)) {
+       if (cfg->opt & (MONO_OPT_DEADCE | MONO_OPT_ABCREM | MONO_OPT_SSAPRE)) {
                if (!(cfg->comp_done & MONO_COMP_SSA) && !header->num_clauses && !cfg->disable_ssa) {
                        mono_local_cprop (cfg);
                        mono_ssa_compute (cfg);
@@ -7817,7 +7994,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        if (parts == 2)
                return cfg;
 
-       if ((cfg->opt & MONO_OPT_CONSPROP) ||  (cfg->opt & MONO_OPT_COPYPROP)) {
+       if ((cfg->opt & MONO_OPT_CONSPROP) || (cfg->opt & MONO_OPT_COPYPROP)) {
                if (cfg->comp_done & MONO_COMP_SSA) {
                        mono_ssa_cprop (cfg);
                } else {
@@ -7832,7 +8009,10 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 
                if ((cfg->flags & MONO_CFG_HAS_LDELEMA) && (cfg->opt & MONO_OPT_ABCREM))
                        mono_perform_abc_removal (cfg);
-
+               
+               if ((cfg->opt & MONO_OPT_SSAPRE) && ! (cfg->opt & (MONO_OPT_CONSPROP|MONO_OPT_COPYPROP)))
+                       mono_perform_ssapre (cfg);
+               
                mono_ssa_remove (cfg);
 
                if (cfg->opt & MONO_OPT_BRANCH)
index 5828657143f8a9ed87bceb2de34712f9693aefef..60278a72de18ad254b25b702ae640d1187238373 100644 (file)
@@ -464,7 +464,8 @@ enum {
        MONO_OPT_LEAF     = 1 << 15,
        MONO_OPT_AOT      = 1 << 16,
        MONO_OPT_PRECOMP  = 1 << 17,
-       MONO_OPT_ABCREM   = 1 << 18
+       MONO_OPT_ABCREM   = 1 << 18,
+       MONO_OPT_SSAPRE   = 1 << 19
 };
 
 /* Bit-fields in the MonoBasicBlock.region */
@@ -696,6 +697,10 @@ void      mono_constant_fold_inst           (MonoInst *inst, gpointer data);
 int       mono_is_power_of_two              (guint32 val);
 void      mono_cprop_local                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **acp, int acp_size);
 MonoInst* mono_compile_create_var           (MonoCompile *cfg, MonoType *type, int opcode);
+void      mono_compile_make_var_load        (MonoCompile *cfg, MonoInst *dest, gssize var_index);
+MonoInst* mono_compile_create_var_load      (MonoCompile *cfg, gssize var_index);
+MonoInst* mono_compile_create_var_store     (MonoCompile *cfg, gssize var_index, MonoInst *value);
+MonoType* mono_type_from_stack_type         (MonoInst *ins);
 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet *set, const char *name, guint idom);
 void      mono_print_tree                   (MonoInst *tree);
 void      mono_print_tree_nl                (MonoInst *tree);
@@ -728,6 +733,7 @@ void      mono_register_opcode_emulation    (int opcode, const char* name, MonoM
 void      mono_arch_register_lowlevel_calls (void);
 void      mono_draw_graph                   (MonoCompile *cfg, MonoGraphOptions draw_options);
 void      mono_add_varcopy_to_end           (MonoCompile *cfg, MonoBasicBlock *bb, int src, int dest);
+void      mono_add_ins_to_end               (MonoBasicBlock *bb, MonoInst *inst);
 
 int               mono_find_method_opcode      (MonoMethod *method);
 MonoJitICallInfo *mono_find_jit_icall_by_name  (const char *name);
@@ -840,5 +846,7 @@ gboolean       mono_trace_eval                  (MonoMethod *method);
 
 extern void
 mono_perform_abc_removal (MonoCompile *cfg);
+extern void
+mono_perform_ssapre (MonoCompile *cfg);
 
-#endif /* __MONO_MINI_H__ */  
+#endif /* __MONO_MINI_H__ */
index dfb09e65abf9a830031fae5a62dddbee0d26e497..f346975b07cd156471f7560f378b5ce3c28cb668 100644 (file)
@@ -147,7 +147,7 @@ extends_live (MonoInst *inst)
        arity = mono_burg_arity [inst->opcode];
 
        if (inst->ssa_op == MONO_SSA_LOAD && 
-           (inst->inst_i0->opcode == OP_LOCAL /*|| inst->inst_i0->opcode == OP_ARG*/)) {
+           (inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
                return 1;
        } else {
                if (arity) {
diff --git a/mono/mini/ssapre.c b/mono/mini/ssapre.c
new file mode 100644 (file)
index 0000000..1b226c9
--- /dev/null
@@ -0,0 +1,1817 @@
+/*
+ * ssapre.h: SSA Partial Redundancy Elimination
+ *
+ * Author:
+ *   Massimiliano Mantione (massi@ximian.com)
+ *
+ * (C) 2004 Novell, Inc.  http://www.novell.com
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/opcodes.h>
+
+#include "inssel.h"
+
+#include "ssapre.h"
+
+extern guint8 mono_burg_arity [];
+
+/* Logging conditions */
+#define DUMP_LEVEL (4)
+#define TRACE_LEVEL (3)
+#define STATISTICS_LEVEL (2)
+#define LOG_LEVEL (1)
+#define DUMP_SSAPRE (area->cfg->verbose_level >= DUMP_LEVEL)
+#define TRACE_SSAPRE (area->cfg->verbose_level >= TRACE_LEVEL)
+#define STATISTICS_SSAPRE (area->cfg->verbose_level >= STATISTICS_LEVEL)
+#define LOG_SSAPRE (area->cfg->verbose_level >= LOG_LEVEL)
+
+/* "Bottom" symbol definition (see paper) */
+#define BOTTOM_REDUNDANCY_CLASS (-1)
+
+/* Various printing functions... */
+static void
+print_argument (MonoSsapreExpressionArgument *argument) {
+       switch (argument->type) {
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY:
+                       printf ("ANY");
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_NOT_PRESENT:
+                       printf ("NONE");
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE:
+                       printf ("ORIGINAL_VARIABLE %d", argument->argument.original_variable);
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE:
+                       printf ("SSA_VARIABLE %d", argument->argument.ssa_variable);
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_INTEGER_CONSTANT:
+                       printf ("INTEGER_CONSTANT %d", argument->argument.integer_constant);
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_LONG_COSTANT:
+                       printf ("LONG_COSTANT %lld", *(argument->argument.long_constant));
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_FLOAT_COSTANT:
+                       printf ("FLOAT_COSTANT %f", *(argument->argument.float_constant));
+                       break;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_DOUBLE_COSTANT:
+                       printf ("DOUBLE_COSTANT %f", *(argument->argument.double_constant));
+                       break;
+               default:
+                       printf ("UNKNOWN: %d", argument->type);
+       }
+}
+
+
+static void
+print_expression_description (MonoSsapreExpressionDescription *expression_description) {
+       if (expression_description->opcode != 0) {
+               printf ("%s ([", mono_inst_name (expression_description->opcode) );
+               print_argument (&(expression_description->left_argument));
+               printf ("],[");
+               print_argument (&(expression_description->right_argument));
+               printf ("])");
+       } else {
+               printf ("ANY");
+       }
+}
+
+#define GBOOLEAN_TO_STRING(b) ((b)?"TRUE":"FALSE")
+
+static void
+print_expression_occurrence (MonoSsapreExpressionOccurrence *occurrence, int number) {
+       printf (" ([%d][bb %d [ID %d]][class %d]: ", number, occurrence->bb_info->cfg_dfn, occurrence->bb_info->bb->block_num, occurrence->redundancy_class);
+       print_expression_description (&(occurrence->description));
+       if (occurrence->is_first_in_bb) {
+               printf (" [FIRST in BB]");
+       }
+       if (occurrence->is_last_in_bb) {
+               printf (" [LAST in BB]");
+       }
+       printf (" (save = %s)", GBOOLEAN_TO_STRING (occurrence->save));
+       printf (" (reload = %s)", GBOOLEAN_TO_STRING (occurrence->reload));
+       printf ("\n");
+       occurrence = occurrence->next;
+}
+
+static void
+print_expression_occurrences (MonoSsapreExpressionOccurrence *occurrences) {
+       int i = 0;
+       while (occurrences != NULL) {
+               i++;
+               print_expression_occurrence (occurrences, i);
+               occurrences = occurrences->next;
+       }
+}
+
+static void
+print_worklist (MonoSsapreExpression *expression) {
+       if (expression != NULL) {
+               print_worklist (expression->previous);
+               
+               printf ("{%d}: ", expression->tree_size);
+               print_expression_description (&(expression->description));
+               printf ("\n");
+               print_expression_occurrences (expression->occurrences);
+               
+               print_worklist (expression->next);
+       }
+}
+
+static void
+print_bb_info (MonoSsapreBBInfo *bb_info, gboolean print_occurrences) {
+       int i;
+       MonoSsapreExpressionOccurrence *current_occurrence = bb_info->first_expression_in_bb;
+       
+       printf ("bb %d [ID %d]: IN { ", bb_info->cfg_dfn, bb_info->bb->block_num);
+       for (i = 0; i < bb_info->in_count; i++) {
+               printf ("%d [ID %d] ", bb_info->in_bb [i]->cfg_dfn, bb_info->in_bb [i]->bb->block_num);
+       }
+       printf ("}, OUT {");
+       for (i = 0; i < bb_info->out_count; i++) {
+               printf ("%d [ID %d] ", bb_info->out_bb [i]->cfg_dfn, bb_info->out_bb [i]->bb->block_num);
+       }
+       printf ("}");
+       if (bb_info->next_interesting_bb != NULL) {
+               printf (", NEXT %d [ID %d]", bb_info->next_interesting_bb->cfg_dfn, bb_info->next_interesting_bb->bb->block_num);
+       }
+       printf ("\n");
+       if (bb_info->has_phi) {
+               printf (" PHI, class %d [ ", bb_info->phi_redundancy_class);
+               for (i = 0; i < bb_info->in_count; i++) {
+                       int argument_class = bb_info->phi_arguments_classes [i];
+                       if (argument_class != BOTTOM_REDUNDANCY_CLASS) {
+                               printf ("%d ", argument_class);
+                       } else {
+                               printf ("BOTTOM ");
+                       }
+               }
+               printf ("]\n(phi_defines_a_real_occurrence:%s) (phi_is_down_safe:%s) (phi_can_be_available:%s) (phi_is_later:%s)\n",
+                               GBOOLEAN_TO_STRING (bb_info->phi_defines_a_real_occurrence), GBOOLEAN_TO_STRING (bb_info->phi_is_down_safe),
+                               GBOOLEAN_TO_STRING (bb_info->phi_can_be_available), GBOOLEAN_TO_STRING (bb_info->phi_is_later));
+       }
+       if (print_occurrences) {
+               i = 0;
+               while ((current_occurrence != NULL) && (current_occurrence->bb_info == bb_info)) {
+                       print_expression_occurrence (current_occurrence, i);
+                       current_occurrence = current_occurrence->next;
+                       i++;
+               }
+       }
+       if (bb_info->has_phi_argument) {
+               printf (" PHI ARGUMENT, class ");
+               if (bb_info->phi_argument_class != BOTTOM_REDUNDANCY_CLASS) {
+                       printf ("%d ", bb_info->phi_argument_class);
+               } else {
+                       printf ("BOTTOM ");
+               }
+               if (bb_info->phi_argument_defined_by_real_occurrence != NULL) {
+                       printf ("(Defined by real occurrence %d)", bb_info->phi_argument_defined_by_real_occurrence->redundancy_class);
+               } else if (bb_info->phi_argument_defined_by_phi != NULL) {
+                       printf ("(Defined by phi %d)", bb_info->phi_argument_defined_by_phi->phi_redundancy_class);
+               } else {
+                       printf ("(Undefined)");
+               }
+               printf (" (real occurrence arguments: left ");
+               if (bb_info->phi_argument_left_argument_version != BOTTOM_REDUNDANCY_CLASS) {
+                       printf ("%d ", bb_info->phi_argument_left_argument_version);
+               } else {
+                       printf ("NONE ");
+               }
+               printf (", right ");
+               if (bb_info->phi_argument_right_argument_version != BOTTOM_REDUNDANCY_CLASS) {
+                       printf ("%d ", bb_info->phi_argument_right_argument_version);
+               } else {
+                       printf ("NONE ");
+               }
+               printf (")\n(phi_argument_has_real_use:%s) (phi_argument_needs_insert:%s) (phi_argument_has_been_processed:%s)\n",
+                               GBOOLEAN_TO_STRING (bb_info->phi_argument_has_real_use), GBOOLEAN_TO_STRING (bb_info->phi_argument_needs_insert),
+                               GBOOLEAN_TO_STRING (bb_info->phi_argument_has_been_processed));
+       }
+}
+
+static void
+print_bb_infos (MonoSsapreWorkArea *area) {
+       int i;
+       for (i = 0; i < area->num_bblocks; i++) {
+               MonoSsapreBBInfo *bb_info = &(area->bb_infos [i]);
+               print_bb_info (bb_info, TRUE);
+       }
+}
+
+static void
+print_interesting_bb_infos (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               print_bb_info (current_bb, FALSE);
+       }
+}
+
+static void dump_code (MonoSsapreWorkArea *area) {
+       int i;
+       
+       for (i = 0; i < area->num_bblocks; i++) {
+               MonoSsapreBBInfo *current_bb = &(area->bb_infos [i]);
+               MonoInst *current_inst;
+               
+               print_bb_info (current_bb, TRUE);
+               for (current_inst = current_bb->bb->code; current_inst != NULL; current_inst = current_inst->next) {
+                       mono_print_tree_nl (current_inst);
+               }
+       }
+}
+
+/*
+ * Given a MonoInst, it tries to describe it as an expression argument.
+ * If this is not possible, the result will be of type
+ * MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY.
+ */
+static void
+analyze_argument (MonoInst *argument, MonoSsapreExpressionArgument *result) {
+       switch (argument->opcode) {
+       case CEE_LDIND_I1:
+       case CEE_LDIND_U1:
+       case CEE_LDIND_I2:
+       case CEE_LDIND_U2:
+       case CEE_LDIND_I4:
+       case CEE_LDIND_U4:
+       case CEE_LDIND_I8:
+       case CEE_LDIND_I:
+       case CEE_LDIND_R4:
+       case CEE_LDIND_R8:
+       case CEE_LDIND_REF:
+               analyze_argument (argument->inst_left, result);
+               break;
+       case OP_ICONST:
+               result->type = MONO_SSAPRE_EXPRESSION_ARGUMENT_INTEGER_CONSTANT;
+               result->argument.integer_constant = argument->inst_c0;
+               break;
+       case OP_I8CONST:
+               result->type = MONO_SSAPRE_EXPRESSION_ARGUMENT_LONG_COSTANT;
+               result->argument.long_constant = &(argument->inst_l);
+               break;
+       case OP_R4CONST:
+               result->type = MONO_SSAPRE_EXPRESSION_ARGUMENT_FLOAT_COSTANT;
+               result->argument.float_constant = (float*)argument->inst_p0;
+               break;
+       case OP_R8CONST:
+               result->type = MONO_SSAPRE_EXPRESSION_ARGUMENT_DOUBLE_COSTANT;
+               result->argument.double_constant = (double*)argument->inst_p0;
+               break;
+       case OP_ARG:
+       case OP_LOCAL:
+               result->type = MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE;
+               result->argument.ssa_variable = argument->inst_c0;
+               break;
+       default:
+               result->type = MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY;
+       }
+}
+
+/*
+ * Given a MonoInst, it tries to describe it as an expression.
+ * If this is not possible, the result will have opcode 0.
+ */
+static void
+analyze_expression (MonoInst *expression, MonoSsapreExpressionDescription *result) {
+       switch (expression->opcode) {
+       case CEE_LDIND_I1:
+       case CEE_LDIND_U1:
+       case CEE_LDIND_I2:
+       case CEE_LDIND_U2:
+       case CEE_LDIND_I4:
+       case CEE_LDIND_U4:
+       case CEE_LDIND_I8:
+       case CEE_LDIND_I:
+       case CEE_LDIND_R4:
+       case CEE_LDIND_R8:
+       case CEE_LDIND_REF:
+               analyze_expression (expression->inst_left, result);
+               break;
+       case CEE_SWITCH:
+       case CEE_ISINST:
+       case CEE_CASTCLASS:
+       case OP_OUTARG:
+       case OP_CALL_REG:
+       case OP_FCALL_REG:
+       case OP_LCALL_REG:
+       case OP_VCALL_REG:
+       case OP_VOIDCALL_REG:
+       case CEE_CALL:
+       case CEE_CALLVIRT:
+       case OP_FCALL:
+       case OP_FCALLVIRT:
+       case OP_LCALL:
+       case OP_LCALLVIRT:
+       case OP_VCALL:
+       case OP_VCALLVIRT:
+       case OP_VOIDCALL:
+       case OP_VOIDCALLVIRT:
+       case OP_RENAME:
+       case OP_RETARG:
+//     case OP_OUTARG:
+       case OP_OUTARG_REG:
+       case OP_OUTARG_IMM:
+       case OP_OUTARG_R4:
+       case OP_OUTARG_R8:
+       case OP_OUTARG_VT:
+       case CEE_NOP:
+       case CEE_JMP:
+       case CEE_BREAK:
+       case OP_COMPARE:
+       case OP_COMPARE_IMM:
+       case OP_FCOMPARE:
+       case OP_LCOMPARE:
+       case OP_ICOMPARE:
+       case OP_ICOMPARE_IMM:
+               result->opcode = 0;
+               break;
+       default:
+               if ( (expression->type == STACK_I4) ||
+                               (expression->type == STACK_I8) ||
+                               (expression->type == STACK_R8) ) {
+                       if (mono_burg_arity [expression->opcode] > 0) {
+                               analyze_argument (expression->inst_left, &(result->left_argument));
+                               if (result->left_argument.type != MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY) {
+                                       if (mono_burg_arity [expression->opcode] > 1) {
+                                               analyze_argument (expression->inst_right, &(result->right_argument));
+                                               if (result->right_argument.type != MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY) {
+                                                       result->opcode = expression->opcode;
+                                               } else {
+                                                       result->opcode = 0;
+                                               }
+                                       } else {
+                                               result->right_argument.type = MONO_SSAPRE_EXPRESSION_ARGUMENT_NOT_PRESENT;
+                                               result->opcode = expression->opcode;
+                                       }
+                               } else {
+                                       result->opcode = 0;
+                               }
+                       } else {
+                               result->opcode = 0;
+                       }
+               } else {
+                       result->opcode = 0;
+               }
+       }
+}
+
+/*
+ * Given an expression description, if any of its arguments has type
+ * MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE it transforms it to a
+ * MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE, converting the
+ * variable index to its "original" one.
+ * The resulting description is OK for a "MonoSsapreExpression" (the
+ * initial description came from a "MonoSsapreExpressionOccurrence").
+ */
+static void
+convert_ssa_variables_to_original_names (MonoSsapreExpressionDescription *result, MonoSsapreExpressionDescription *expression, MonoCompile *cfg) {
+       gssize original_variable;
+       
+       result->opcode = expression->opcode;
+       if (expression->left_argument.type != MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE) {
+               result->left_argument = expression->left_argument;
+       } else {
+               result->left_argument.type = MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE;
+               original_variable = cfg->vars [expression->left_argument.argument.ssa_variable]->reg;
+               if (original_variable >= 0) {
+                       result->left_argument.argument.original_variable = original_variable;
+               } else {
+                       result->left_argument.argument.original_variable = expression->left_argument.argument.ssa_variable;
+               }
+       }
+       if (expression->right_argument.type != MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE) {
+               result->right_argument = expression->right_argument;
+       } else {
+               result->right_argument.type = MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE;
+               original_variable = cfg->vars [expression->right_argument.argument.ssa_variable]->reg;
+               if (original_variable >= 0) {
+                       result->right_argument.argument.original_variable = original_variable;
+               } else {
+                       result->right_argument.argument.original_variable = expression->right_argument.argument.ssa_variable;
+               }
+       }
+}
+
+/*
+ * Given a MonoInst, checks if it is a phi definition.
+ */
+static gboolean
+is_phi_definition (MonoInst *definition) {
+       if (definition != NULL) {
+               switch (definition->opcode) {
+               case CEE_STIND_REF:
+               case CEE_STIND_I:
+               case CEE_STIND_I4:
+               case CEE_STIND_I1:
+               case CEE_STIND_I2:
+               case CEE_STIND_I8:
+               case CEE_STIND_R4:
+               case CEE_STIND_R8:
+                       if ((definition->inst_left->opcode == OP_LOCAL) &&
+                                       (definition->inst_right->opcode == OP_PHI)) {
+                               return TRUE;
+                       } else {
+                               return FALSE;
+                       }
+               default:
+                       return FALSE;
+               }
+       } else {
+               return FALSE;
+       }
+}
+
+/*
+ * Given a variable index, checks if it is a phi definition
+ * (it assumes the "area" is visible).
+ */
+#define IS_PHI_DEFINITION(v) is_phi_definition (area->cfg->vars [v]->def)
+
+/*
+ * Given a variable index, checks if it is a phi definition.
+ * If it is so, it returns the array of integers pointed to by the phi MonoInst
+ * (the one containing the length and the phi arguments), otherwise returns NULL.
+ */
+static int*
+get_phi_definition (MonoCompile *cfg, gssize variable) {
+       MonoInst *definition = cfg->vars [variable]->def;
+       if (is_phi_definition (definition) && (definition->inst_left->inst_c0 == variable)) {
+               return definition->inst_right->inst_phi_args;
+       } else {
+               return NULL;
+       }
+}
+
+/*
+ * Given a variable index, returns the BB where the variable is defined.
+ * If the variable appears to have no definition, it returns the entry BB
+ * (the logic is that if it has no definition it is an argument, or a sort
+ * of constant, and in both cases it is defined in the entry BB).
+ */
+static MonoSsapreBBInfo*
+get_bb_info_of_definition (MonoSsapreWorkArea *area, gssize variable) {
+       MonoBasicBlock *def_bb = area->cfg->vars [variable]->def_bb;
+       if (def_bb != NULL) {
+               return area->bb_infos_in_cfg_dfn_order [def_bb->dfn];
+       } else {
+               return area->bb_infos;
+       }
+}
+
+/*
+ * Given:
+ * - a variable index,
+ * - a BB (the "current" BB), and
+ * - a "phi argument index" (or index in the "in_bb" of the current BB),
+ * it checks if the variable is a phi.
+ * If it is so, it returns the variable index at the in_bb corresponding to
+ * the given index, otherwise it return the variable index unchanged.
+ * The logic is to return the variable version at the given predecessor BB.
+ */
+static gssize
+get_variable_version_at_predecessor_bb (MonoSsapreWorkArea *area, gssize variable, MonoSsapreBBInfo *current_bb, int phi_operand) {
+       MonoSsapreBBInfo *definition_bb = get_bb_info_of_definition (area, variable);
+       int *phi_definition = get_phi_definition (area->cfg, variable);
+       if ((definition_bb == current_bb) && (phi_definition != NULL)) {
+               return phi_definition [phi_operand + 1];
+       } else {
+               return variable;
+       }
+}
+
+/*
+ * Adds an expression to an autobalancing binary tree of expressions.
+ * Returns the new tree root (it can be different from "tree" because of the
+ * autobalancing).
+ */
+static MonoSsapreExpression*
+add_expression_to_tree (MonoSsapreExpression *tree, MonoSsapreExpression *expression) {
+       MonoSsapreExpression *subtree;
+       MonoSsapreExpression **subtree_reference;
+       int comparison;
+       gssize max_tree_depth, max_subtree_size;
+       
+       if (tree == NULL) {
+               expression->previous = NULL;
+               expression->next = NULL;
+               expression->tree_size = 1;
+               return expression;
+       }
+       
+       tree->tree_size++;
+       
+       comparison = MONO_COMPARE_SSAPRE_EXPRESSION_DESCRIPTIONS (expression->description, tree->description);
+       if (comparison > 0) {
+               if (tree->next != NULL) {
+                       subtree = tree->next;
+                       subtree_reference = &(tree->next);
+               } else {
+                       tree->next = expression;
+                       expression->father = tree;
+                       expression->previous = NULL;
+                       expression->next = NULL;
+                       expression->tree_size = 1;
+                       return tree;
+               }
+       } else if (comparison < 0) {
+               if (tree->previous != NULL) {
+                       subtree = tree->previous;
+                       subtree_reference = &(tree->previous);
+               } else {
+                       tree->previous = expression;
+                       expression->father = tree;
+                       expression->previous = NULL;
+                       expression->next = NULL;
+                       expression->tree_size = 1;
+                       return tree;
+               }
+       } else {
+               g_assert_not_reached ();
+               return NULL;
+       }
+       
+       MONO_SSAPRE_MAX_TREE_DEPTH (tree->tree_size, max_tree_depth);
+       max_subtree_size = (1 << max_tree_depth) -1;
+       
+       if (subtree->tree_size < max_subtree_size) {
+               *subtree_reference = add_expression_to_tree (subtree, expression);
+               (*subtree_reference)->father = tree;
+               return tree;
+       } else {
+               MonoSsapreExpression *other_subtree;
+               MonoSsapreExpression *border_expression;
+               MonoSsapreExpression *border_expression_subtree;
+               MonoSsapreExpression **border_expression_reference_from_father;
+               int comparison_with_border;
+               
+               border_expression = subtree;
+               if (comparison > 0) {
+                       other_subtree = tree->previous;
+                       MONO_SSAPRE_GOTO_FIRST_EXPRESSION (border_expression);
+                       border_expression_subtree = border_expression->next;
+                       border_expression_reference_from_father = &(border_expression->father->previous);
+               } else if (comparison < 0) {
+                       other_subtree = tree->next;
+                       MONO_SSAPRE_GOTO_LAST_EXPRESSION (border_expression);
+                       border_expression_subtree = border_expression->previous;
+                       border_expression_reference_from_father = &(border_expression->father->next);
+               } else {
+                       g_assert_not_reached ();
+                       return NULL;
+               }
+               comparison_with_border = MONO_COMPARE_SSAPRE_EXPRESSION_DESCRIPTIONS (expression->description, border_expression->description);
+               
+               if ((comparison + comparison_with_border) != 0) {
+                       MonoSsapreExpression *border_expression_iterator = border_expression->father;
+                       while (border_expression_iterator != tree) {
+                               border_expression_iterator->tree_size--;
+                               border_expression_iterator = border_expression_iterator->father;
+                       }
+                       
+                       if (border_expression != subtree) {
+                               *border_expression_reference_from_father = border_expression_subtree;
+                       } else {
+                               subtree = border_expression_subtree;
+                       }
+                       if (border_expression_subtree != NULL) {
+                               border_expression_subtree->father = border_expression->father;
+                       }
+                       
+                       if (comparison > 0) {
+                               border_expression->previous = add_expression_to_tree (other_subtree, tree);
+                               border_expression->next = add_expression_to_tree (subtree, expression);
+                       } else if (comparison < 0) {
+                               border_expression->previous = add_expression_to_tree (subtree, expression);
+                               border_expression->next = add_expression_to_tree (other_subtree, tree);
+                       } else {
+                               g_assert_not_reached ();
+                               return NULL;
+                       }
+                       border_expression->tree_size = 1 + border_expression->previous->tree_size + border_expression->next->tree_size;
+                       return border_expression;
+               } else {
+                       if (comparison > 0) {
+                               expression->previous = add_expression_to_tree (other_subtree, tree);
+                               expression->next = subtree;
+                       } else if (comparison < 0) {
+                               expression->previous = subtree;
+                               expression->next = add_expression_to_tree (other_subtree, tree);
+                       } else {
+                               g_assert_not_reached ();
+                               return NULL;
+                       }
+                       expression->tree_size = 1 + expression->previous->tree_size + expression->next->tree_size;
+                       return expression;
+               }
+       }
+}
+
+/*
+ * Adds an expression to the worklist (putting the given occurrence as first
+ * occurrence of this expression).
+ */
+static void
+add_expression_to_worklist (MonoSsapreWorkArea *area, MonoSsapreExpressionOccurrence *occurrence) {
+       MonoSsapreExpression *expression;
+       
+       expression = (MonoSsapreExpression*) mono_mempool_alloc (area->mempool, sizeof (MonoSsapreExpression));
+       
+       convert_ssa_variables_to_original_names (&(expression->description), &(occurrence->description), area->cfg);
+       expression->type = mono_type_from_stack_type (occurrence->occurrence);
+       expression->occurrences = NULL;
+       expression->last_occurrence = NULL;
+       MONO_SSAPRE_ADD_EXPRESSION_OCCURRANCE (expression, occurrence);
+       
+       area->worklist = add_expression_to_tree (area->worklist, expression);
+       area->worklist->father = NULL;
+}
+
+/*
+ * Adds an expression occurrence to the worklist.
+ * If its expression is not yet in the worklist, it is created.
+ */
+static void
+add_occurrence_to_worklist (MonoSsapreWorkArea *area, MonoSsapreExpressionOccurrence *occurrence) {
+       MonoSsapreExpressionDescription description;
+       MonoSsapreExpression *current_expression;
+       int comparison;
+       
+       convert_ssa_variables_to_original_names (&description, &(occurrence->description), area->cfg);
+       current_expression = area->worklist;
+       
+       do {
+               if (current_expression != NULL) {
+                       comparison = MONO_COMPARE_SSAPRE_EXPRESSION_DESCRIPTIONS (description, current_expression->description);
+
+                       if (comparison > 0) {
+                               current_expression = current_expression->next;
+                       } else if (comparison < 0) {
+                               current_expression = current_expression->previous;
+                       } else {
+                               MONO_SSAPRE_ADD_EXPRESSION_OCCURRANCE (current_expression, occurrence);
+                       }
+               } else {
+                       add_expression_to_worklist (area, occurrence);
+                       comparison = 0;
+               }
+       } while (comparison != 0);
+}
+
+/*
+ * Process a MonoInst, and of it is a valid expression add it to the worklist.
+ */
+static MonoSsapreExpressionOccurrence*
+process_inst (MonoSsapreWorkArea *area, MonoInst* inst, MonoInst* previous_inst, MonoSsapreBBInfo *bb_info, MonoSsapreExpressionOccurrence *current_occurrence) {
+       
+       /* Ugly hack to fix missing variable definitions */
+       /* (the SSA construction code should have done it already!) */
+       switch (inst->opcode) {
+       case CEE_STIND_REF:
+       case CEE_STIND_I:
+       case CEE_STIND_I4:
+       case CEE_STIND_I1:
+       case CEE_STIND_I2:
+       case CEE_STIND_I8:
+       case CEE_STIND_R4:
+       case CEE_STIND_R8:
+               if ((inst->inst_left->opcode == OP_LOCAL) || (inst->inst_left->opcode == OP_ARG)) {
+                       int variable_index = inst->inst_left->inst_c0;
+                       
+                       if (area->cfg->vars [variable_index]->def_bb == NULL) {
+                               if (area->cfg->verbose_level >= 4) {
+                                       printf ("SSAPRE WARNING: variable %d has no definition, fixing.\n", variable_index);
+                               }
+                               area->cfg->vars [variable_index]->def_bb = bb_info->bb;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+       
+       if (mono_burg_arity [inst->opcode] > 0) {
+               current_occurrence = process_inst (area, inst->inst_left, previous_inst, bb_info, current_occurrence);
+               if (mono_burg_arity [inst->opcode] > 1) {
+                       current_occurrence = process_inst (area, inst->inst_right, previous_inst, bb_info, current_occurrence);
+               }
+       }
+       
+       analyze_expression (inst, &(current_occurrence->description));
+       if (current_occurrence->description.opcode != 0) {
+               current_occurrence->occurrence = inst;
+               current_occurrence->previous_tree = previous_inst;
+               current_occurrence->bb_info = bb_info;
+               current_occurrence->is_first_in_bb = FALSE;
+               current_occurrence->is_last_in_bb = FALSE;
+               add_occurrence_to_worklist (area, current_occurrence);
+               current_occurrence = (MonoSsapreExpressionOccurrence*) mono_mempool_alloc (area->mempool, sizeof (MonoSsapreExpressionOccurrence));
+       }
+       
+       return current_occurrence;
+}
+
+/*
+ * Process a BB, and (recursively) all its children in the dominator tree.
+ * The result is that all the expressions end up in the worklist, and the
+ * auxiliary MonoSsapreBBInfo fields (dt_dfn, dt_descendants) are initialized
+ * (with all the info that comes from the MonoBasicBlock).
+ */
+static MonoSsapreExpressionOccurrence*
+process_bb (MonoSsapreWorkArea *area, MonoBasicBlock *bb, int *dt_dfn, int *upper_descendants, MonoSsapreExpressionOccurrence *current_occurrence) {
+       MonoSsapreBBInfo *bb_info;
+       int descendants;
+       GList *dominated_bb;
+       MonoInst* current_inst;
+       MonoInst* previous_inst;
+       
+       bb_info = &(area->bb_infos [*dt_dfn]);
+       bb_info->dt_dfn = *dt_dfn;
+       (*dt_dfn)++;
+       bb_info->cfg_dfn = bb->dfn;
+       area->bb_infos_in_cfg_dfn_order [bb->dfn] = bb_info;
+       bb_info->in_count = bb->in_count;
+       bb_info->out_count = bb->out_count;
+       bb_info->dfrontier = bb->dfrontier;
+       bb_info->bb = bb;
+       bb_info->in_bb = (MonoSsapreBBInfo**) mono_mempool_alloc (area->mempool, sizeof (MonoSsapreBBInfo*) * (bb->in_count));
+       bb_info->out_bb = (MonoSsapreBBInfo**) mono_mempool_alloc (area->mempool, sizeof (MonoSsapreBBInfo*) * (bb->out_count));
+       bb_info->phi_arguments_classes = (gssize*) mono_mempool_alloc (area->mempool, sizeof (gssize) * (bb->in_count));
+       
+       bb_info->phi_insertion_point = NULL;
+       
+       current_inst = bb->code;
+       previous_inst = NULL;
+       while (current_inst != NULL) {
+               if (is_phi_definition (current_inst)) {
+                       bb_info->phi_insertion_point = current_inst;
+               }
+               current_occurrence = process_inst (area, current_inst, previous_inst, bb_info, current_occurrence);
+               previous_inst = current_inst;
+               current_inst = current_inst->next;
+       }
+       
+       descendants = 0;
+       for (dominated_bb = g_list_first (bb->dominated); dominated_bb != NULL; dominated_bb = g_list_next (dominated_bb)) {
+               current_occurrence = process_bb (area, (MonoBasicBlock*) (dominated_bb->data), dt_dfn, &descendants, current_occurrence);
+       }
+       bb_info->dt_descendants = descendants;
+       *upper_descendants += (descendants + 1);
+       
+       return current_occurrence;
+}
+
+/*
+ * Reset the MonoSsapreBBInfo fields that must be recomputed for each expression.
+ */
+static void
+clean_bb_infos (MonoSsapreWorkArea *area) {
+       int i;
+       for (i = 0; i < area->num_bblocks; i++) {
+               MonoSsapreBBInfo *bb_info = &(area->bb_infos [i]);
+               bb_info->has_phi = FALSE;
+               bb_info->phi_defines_a_real_occurrence = FALSE;
+               bb_info->phi_is_down_safe = FALSE;
+               bb_info->phi_can_be_available = FALSE;
+               bb_info->phi_is_later = FALSE;
+               bb_info->phi_redundancy_class = BOTTOM_REDUNDANCY_CLASS;
+               bb_info->phi_variable_index = BOTTOM_REDUNDANCY_CLASS;
+               bb_info->has_phi_argument = FALSE;
+               bb_info->phi_argument_has_real_use = FALSE;
+               bb_info->phi_argument_needs_insert = FALSE;
+               bb_info->phi_argument_has_been_processed = FALSE;
+               bb_info->phi_argument_class = BOTTOM_REDUNDANCY_CLASS;
+               bb_info->phi_argument_variable_index = BOTTOM_REDUNDANCY_CLASS;
+               bb_info->phi_argument_defined_by_real_occurrence = NULL;
+               bb_info->phi_argument_defined_by_phi = NULL;
+               bb_info->phi_argument_left_argument_version = BOTTOM_REDUNDANCY_CLASS;
+               bb_info->phi_argument_right_argument_version = BOTTOM_REDUNDANCY_CLASS;
+               bb_info->first_expression_in_bb = NULL;
+               bb_info->next_interesting_bb = NULL;
+               bb_info->next_in_renaming_stack = NULL;
+               bb_info->top_of_local_renaming_stack = NULL;
+       }
+}
+
+/*
+ * Reset the MonoSsapreWorkArea fields that must be recomputed for each expression.
+ */
+static void
+clean_area_infos (MonoSsapreWorkArea *area) {
+       mono_bitset_clear_all (area->left_argument_bb_bitset);
+       mono_bitset_clear_all (area->right_argument_bb_bitset);
+       area->num_vars = area->cfg->num_varinfo;
+       area->top_of_renaming_stack = NULL;
+       area->bb_on_top_of_renaming_stack = NULL;
+       area->first_interesting_bb = NULL;
+       area->saved_occurrences = 0;
+       area->reloaded_occurrences = 0;
+       area->inserted_occurrences = 0;
+       area->unaltered_occurrences = 0;
+       area->added_phis = 0;
+       clean_bb_infos (area);
+}
+
+/*
+ * Utility function to combine the dominance frontiers of a set of BBs.
+ */
+static void
+compute_combined_dfrontier (MonoSsapreWorkArea *area, MonoBitSet* result, MonoBitSet *bblocks) 
+{
+       int i;
+       mono_bitset_clear_all (result);
+       mono_bitset_foreach_bit (bblocks, i, area->num_bblocks) {
+               mono_bitset_union (result, area->bb_infos_in_cfg_dfn_order [i]->dfrontier);
+       }
+}
+
+/*
+ * Utility function to compute the combined dominance frontier of a set of BBs.
+ */
+static void
+compute_combined_iterated_dfrontier (MonoSsapreWorkArea *area, MonoBitSet *result, MonoBitSet *bblocks, MonoBitSet *buffer) 
+{
+       gboolean change = TRUE;
+
+       compute_combined_dfrontier (area, result, bblocks);
+       do {
+               change = FALSE;
+               compute_combined_dfrontier (area, buffer, result);
+               mono_bitset_union (buffer, result);
+
+               if (!mono_bitset_equal (buffer, result)) {
+                       mono_bitset_copyto (buffer, result);
+                       change = TRUE;
+               }
+       } while (change);
+}
+
+/*
+ * See paper, figure 18, function Set_var_phis
+ */
+static void process_phi_variable_in_phi_insertion (MonoSsapreWorkArea *area, gssize variable, MonoBitSet *phi_bbs) {
+       int* phi_definition = get_phi_definition (area->cfg, variable);
+       
+       if (phi_definition != NULL) {
+               int definition_bb = area->cfg->vars [variable]->def_bb->dfn;
+               if (! mono_bitset_test (phi_bbs, definition_bb)) {
+                       int i;
+                       mono_bitset_set (phi_bbs, definition_bb);
+                       for (i = 0; i < *phi_definition; i++) {
+                               process_phi_variable_in_phi_insertion (area, phi_definition [i+1], phi_bbs);
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 18, function phi_insertion
+ */
+static void
+phi_insertion (MonoSsapreWorkArea *area, MonoSsapreExpression *expression) {
+       MonoSsapreExpressionOccurrence *current_expression = NULL;
+       MonoSsapreExpressionOccurrence *previous_expression = NULL;
+       MonoSsapreBBInfo *current_bb = NULL;
+       MonoSsapreBBInfo *previous_interesting_bb = NULL;
+       int i, j, current_bb_dt_dfn;
+       
+       mono_bitset_clear_all (area->expression_occurrences_buffer);
+       for (current_expression = expression->occurrences; current_expression != NULL; current_expression = current_expression->next) {
+               mono_bitset_set (area->expression_occurrences_buffer, current_expression->bb_info->cfg_dfn);
+               if (current_expression->description.left_argument.type == MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE) {
+                       process_phi_variable_in_phi_insertion (area, current_expression->description.left_argument.argument.ssa_variable, area->left_argument_bb_bitset);
+               }
+               if (current_expression->description.right_argument.type == MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE) {
+                       process_phi_variable_in_phi_insertion (area, current_expression->description.right_argument.argument.ssa_variable, area->right_argument_bb_bitset);
+               }
+               
+               if (previous_expression != NULL) {
+                       if (previous_expression->bb_info != current_expression->bb_info) {
+                               previous_expression->is_last_in_bb = TRUE;
+                               current_expression->is_first_in_bb = TRUE;
+                               current_expression->bb_info->first_expression_in_bb = current_expression;
+                       }
+               } else {
+                       current_expression->is_first_in_bb = TRUE;
+                       current_expression->bb_info->first_expression_in_bb = current_expression;
+               }
+               
+               previous_expression = current_expression;
+       }
+       previous_expression->is_last_in_bb = TRUE;
+       
+       compute_combined_iterated_dfrontier (area, area->iterated_dfrontier_buffer, area->expression_occurrences_buffer, area->bb_iteration_buffer);
+       
+       mono_bitset_union (area->iterated_dfrontier_buffer, area->left_argument_bb_bitset);
+       mono_bitset_union (area->iterated_dfrontier_buffer, area->right_argument_bb_bitset);
+       
+       mono_bitset_foreach_bit (area->iterated_dfrontier_buffer, i, area->num_bblocks) {
+               area->bb_infos_in_cfg_dfn_order [i]->has_phi = TRUE;
+               area->bb_infos_in_cfg_dfn_order [i]->phi_can_be_available = TRUE;
+               for (j = 0; j < area->bb_infos_in_cfg_dfn_order [i]->in_count; j++) {
+                       area->bb_infos_in_cfg_dfn_order [i]->in_bb [j]->has_phi_argument = TRUE;
+               }
+       }
+       
+       for (current_bb = area->bb_infos, current_bb_dt_dfn = 0; current_bb_dt_dfn < area->num_bblocks; current_bb++, current_bb_dt_dfn++) {
+               if ((current_bb->first_expression_in_bb != NULL) || (current_bb->has_phi) || (current_bb->has_phi_argument)) {
+                       if (previous_interesting_bb != NULL) {
+                               previous_interesting_bb->next_interesting_bb = current_bb;
+                       } else {
+                               area->first_interesting_bb = current_bb;
+                       }
+                       previous_interesting_bb = current_bb;
+               }
+       }
+}
+
+/*
+ * Macro that pushes a real occurrence on the stack
+ */
+#define PUSH_REAL_OCCURRENCE(o) do{\
+                       if (area->bb_on_top_of_renaming_stack != (o)->bb_info) { \
+                               (o)->bb_info->next_in_renaming_stack = area->bb_on_top_of_renaming_stack; \
+                               area->bb_on_top_of_renaming_stack =(o)->bb_info; \
+                               (o)->next_in_renaming_stack = NULL; \
+                       } else { \
+                               (o)->next_in_renaming_stack = area->top_of_renaming_stack; \
+                       } \
+                       (o)->bb_info->top_of_local_renaming_stack = (o); \
+                       area->top_of_renaming_stack = (o); \
+                       area->bb_on_top_of_renaming_stack->phi_argument_has_real_use = FALSE; \
+               } while(0)
+
+/*
+ * Macro that pushes a PHI occurrence on the stack
+ */
+#define PUSH_PHI_OCCURRENCE(b) do{\
+                       if (area->bb_on_top_of_renaming_stack != (b)) { \
+                               (b)->next_in_renaming_stack = area->bb_on_top_of_renaming_stack; \
+                               area->bb_on_top_of_renaming_stack = (b); \
+                       } \
+                       (b)->top_of_local_renaming_stack = NULL; \
+                       area->top_of_renaming_stack = NULL; \
+                       area->bb_on_top_of_renaming_stack->phi_argument_has_real_use = FALSE; \
+               } while(0)
+
+/*
+ * See paper, section 5.1, definition of "Dominate"
+ */
+static gboolean
+dominates (MonoSsapreBBInfo *dominator, MonoSsapreBBInfo *dominated) {
+       if ((dominator->dt_dfn <= dominated->dt_dfn) && (dominated->dt_dfn <= (dominator->dt_dfn + dominator->dt_descendants))) {
+               return TRUE;
+       } else {
+               return FALSE;
+       }
+}
+
+/*
+ * See paper, section 5.4.
+ * The two passes are coded sequentially (no separate "rename1" and "rename2" functions).
+ */
+static void
+renaming_pass (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       MonoSsapreBBInfo *previous_bb = NULL;
+       MonoSsapreExpressionOccurrence *current_expression = NULL;
+       gssize current_class = 0;
+       
+       /* This loop is "rename1" */
+       for (current_bb = area->first_interesting_bb, previous_bb = NULL; current_bb != NULL; previous_bb = current_bb, current_bb = current_bb->next_interesting_bb) {
+               if ((previous_bb != NULL) && ! dominates (previous_bb, current_bb)) {
+                       if ((area->bb_on_top_of_renaming_stack != NULL) && (area->top_of_renaming_stack == NULL) && (previous_bb->phi_argument_has_real_use == FALSE)) {
+                               if (TRACE_SSAPRE) {
+                                       printf ("Clearing down safe in PHI %d because of backtracking (previous block is [bb %d [ID %d]])\n",
+                                                       area->bb_on_top_of_renaming_stack->phi_redundancy_class, previous_bb->cfg_dfn, previous_bb->bb->block_num);
+                               }
+                               area->bb_on_top_of_renaming_stack->phi_is_down_safe = FALSE;
+                       }
+                       while ((area->bb_on_top_of_renaming_stack != NULL) && ! dominates (area->bb_on_top_of_renaming_stack, current_bb)) {
+                               MonoSsapreBBInfo *top_bb = area->bb_on_top_of_renaming_stack;
+                               if (top_bb->next_in_renaming_stack != NULL) {
+                                       area->top_of_renaming_stack = top_bb->next_in_renaming_stack->top_of_local_renaming_stack;
+                               } else {
+                                       area->top_of_renaming_stack = NULL;
+                               }
+                               area->bb_on_top_of_renaming_stack = top_bb->next_in_renaming_stack;
+                       }
+               }
+               if (current_bb->idominator != NULL) {
+                       current_bb->phi_argument_has_real_use = current_bb->idominator->phi_argument_has_real_use;
+               } else {
+                       current_bb->phi_argument_has_real_use = FALSE;
+               }
+               
+               if (current_bb->has_phi) {
+                       current_bb->phi_is_down_safe = TRUE;
+                       current_bb->phi_redundancy_class = current_class;
+                       current_class++;
+                       PUSH_PHI_OCCURRENCE (current_bb);
+               }
+               
+               for (current_expression = current_bb->first_expression_in_bb; (current_expression != NULL) && (current_expression->bb_info == current_bb); current_expression = current_expression->next) {
+                       if (area->top_of_renaming_stack != NULL) {
+                               MonoSsapreExpressionOccurrence *top = area->top_of_renaming_stack;
+                               
+                               if (((current_expression->description.left_argument.type != MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE) ||
+                                               (current_expression->description.left_argument.argument.ssa_variable == top->description.left_argument.argument.ssa_variable)) &&
+                                               ((current_expression->description.right_argument.type != MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE) ||
+                                               (current_expression->description.right_argument.argument.ssa_variable == top->description.right_argument.argument.ssa_variable))) {
+                                       current_expression->redundancy_class = top->redundancy_class;
+                                       current_expression->defined_by_real_occurrence = top;
+                               } else {
+                                       current_expression->redundancy_class = current_class;
+                                       current_class++;
+                                       current_expression->defined_by_real_occurrence = NULL;
+                                       PUSH_REAL_OCCURRENCE (current_expression);
+                               }
+                               current_expression->defined_by_phi = NULL;
+                       } else if (area->bb_on_top_of_renaming_stack != NULL) {
+                               MonoSsapreBBInfo *phi_bb = area->bb_on_top_of_renaming_stack;
+                               gssize left_argument_version = ((current_expression->description.left_argument.type == MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE)?
+                                               (current_expression->description.left_argument.argument.ssa_variable):BOTTOM_REDUNDANCY_CLASS);
+                               gssize right_argument_version = ((current_expression->description.right_argument.type == MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE)?
+                                               (current_expression->description.right_argument.argument.ssa_variable):BOTTOM_REDUNDANCY_CLASS);
+                               
+                               /* See remark in section 5.4 about the dominance relation between PHI */
+                               /* occurrences and phi definitions */
+                               MonoSsapreBBInfo *left_argument_definition_bb = ((left_argument_version != BOTTOM_REDUNDANCY_CLASS)?
+                                               (get_bb_info_of_definition (area, left_argument_version)):NULL);
+                               MonoSsapreBBInfo *right_argument_definition_bb = ((right_argument_version != BOTTOM_REDUNDANCY_CLASS)?
+                                               (get_bb_info_of_definition (area, right_argument_version)):NULL);
+                               
+                               gboolean left_same_class_condition = ((left_argument_definition_bb == NULL) || ((left_argument_definition_bb != phi_bb) ? dominates (left_argument_definition_bb, phi_bb) :
+                                               (IS_PHI_DEFINITION (left_argument_version) ? TRUE : FALSE)));
+                               gboolean right_same_class_condition = ((right_argument_definition_bb == NULL) || ((right_argument_definition_bb != phi_bb) ? dominates (right_argument_definition_bb, phi_bb) :
+                                               (IS_PHI_DEFINITION (right_argument_version) ? TRUE : FALSE)));
+                                       
+                               if (left_same_class_condition && right_same_class_condition) {
+                                       int phi_argument;
+                                       
+                                       phi_bb->phi_defines_a_real_occurrence = TRUE;
+                                       current_bb->phi_argument_has_real_use = TRUE;
+                                       current_expression->redundancy_class = phi_bb->phi_redundancy_class;
+                                       current_expression->defined_by_phi = phi_bb;
+                                       
+                                       /*
+                                        * Major difference from the paper here...
+                                        * Instead of maintaining "set_for_rename2" (see figure 20), we just
+                                        * compute "phi_argument_left_argument_version" (and right) here, and
+                                        * use that in rename2, saving us the hassle of maintaining a set
+                                        * data structure (and the related allocations).
+                                        */
+                                       for (phi_argument = 0; phi_argument < phi_bb->in_count; phi_argument++) {
+                                               MonoSsapreBBInfo *previous_bb = phi_bb->in_bb [phi_argument];
+                                               if (left_argument_version != BOTTOM_REDUNDANCY_CLASS) {
+                                                       previous_bb->phi_argument_left_argument_version = get_variable_version_at_predecessor_bb (area,
+                                                                       left_argument_version, phi_bb, phi_argument);
+                                               }
+                                               if (right_argument_version != BOTTOM_REDUNDANCY_CLASS) {
+                                                       previous_bb->phi_argument_right_argument_version = get_variable_version_at_predecessor_bb (area,
+                                                                       right_argument_version, phi_bb, phi_argument);
+                                               }
+                                       }
+                               } else {
+                                       current_expression->redundancy_class = current_class;
+                                       current_class++;
+                                       current_expression->defined_by_phi = NULL;
+                                       PUSH_REAL_OCCURRENCE (current_expression);
+                                       phi_bb->phi_is_down_safe = FALSE;
+                                       if (TRACE_SSAPRE) {
+                                               printf ("Clearing down safe in PHI %d because of real occurrence %d\n",
+                                                               phi_bb->phi_redundancy_class, current_expression->redundancy_class);
+                                       }
+                               }
+                               current_expression->defined_by_real_occurrence = NULL;
+                       } else {
+                               current_expression->redundancy_class = current_class;
+                               current_class++;
+                               current_expression->defined_by_real_occurrence = NULL;
+                               current_expression->defined_by_phi = NULL;
+                               PUSH_REAL_OCCURRENCE (current_expression);
+                       }
+               }
+               
+               if (current_bb->has_phi_argument) {
+                       if (area->top_of_renaming_stack != NULL) {
+                               current_bb->phi_argument_defined_by_real_occurrence = area->top_of_renaming_stack;
+                               current_bb->phi_argument_class = area->top_of_renaming_stack->redundancy_class;
+                       } else if (area->bb_on_top_of_renaming_stack != NULL) {
+                               current_bb->phi_argument_defined_by_phi = area->bb_on_top_of_renaming_stack;
+                               current_bb->phi_argument_class = area->bb_on_top_of_renaming_stack->phi_redundancy_class;
+                       } else {
+                               current_bb->phi_argument_class = BOTTOM_REDUNDANCY_CLASS;
+                       }
+               }
+       }
+       if ((area->bb_on_top_of_renaming_stack != NULL) && (area->top_of_renaming_stack == NULL) && (previous_bb->phi_argument_has_real_use == FALSE)) {
+               if (TRACE_SSAPRE) {
+                       printf ("Clearing down safe in PHI %d because of backtracking (previous block is [bb %d [ID %d]])\n",
+                                       area->bb_on_top_of_renaming_stack->phi_redundancy_class, previous_bb->cfg_dfn, previous_bb->bb->block_num);
+               }
+               area->bb_on_top_of_renaming_stack->phi_is_down_safe = FALSE;
+       }
+       area->number_of_classes = current_class;
+       
+       /* This loop is "rename2" */
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi_argument) {
+                       if ((current_bb->phi_argument_left_argument_version != BOTTOM_REDUNDANCY_CLASS) || (current_bb->phi_argument_right_argument_version != BOTTOM_REDUNDANCY_CLASS)) {
+                               if (current_bb->phi_argument_defined_by_real_occurrence != NULL) {
+                                       if (((current_bb->phi_argument_left_argument_version != BOTTOM_REDUNDANCY_CLASS) &&
+                                                       (current_bb->phi_argument_left_argument_version != current_bb->phi_argument_defined_by_real_occurrence->description.left_argument.argument.ssa_variable)) ||
+                                                       ((current_bb->phi_argument_right_argument_version != BOTTOM_REDUNDANCY_CLASS) &&
+                                                       (current_bb->phi_argument_right_argument_version != current_bb->phi_argument_defined_by_real_occurrence->description.right_argument.argument.ssa_variable))) {
+                                               current_bb->phi_argument_class = BOTTOM_REDUNDANCY_CLASS;
+                                       }
+                               } else if (current_bb->phi_argument_defined_by_phi != NULL) {
+                                       MonoSsapreBBInfo *phi_bb = current_bb->phi_argument_defined_by_phi;
+                                       MonoSsapreBBInfo *left_argument_definition_bb = (current_bb->phi_argument_left_argument_version != BOTTOM_REDUNDANCY_CLASS) ?
+                                                       get_bb_info_of_definition (area, current_bb->phi_argument_left_argument_version) : NULL;
+                                       MonoSsapreBBInfo *right_argument_definition_bb = (current_bb->phi_argument_right_argument_version != BOTTOM_REDUNDANCY_CLASS) ?
+                                                       get_bb_info_of_definition (area, current_bb->phi_argument_right_argument_version) : NULL;
+                                       /* See remark in section 5.4 about the dominance relation between PHI */
+                                       /* occurrences and phi definitions */
+                                       gboolean left_bottom_condition = ((left_argument_definition_bb != NULL) && ! ((left_argument_definition_bb != phi_bb) ? dominates (left_argument_definition_bb, phi_bb) :
+                                                       (IS_PHI_DEFINITION (current_bb->phi_argument_left_argument_version) ? TRUE : FALSE)));
+                                       gboolean right_bottom_condition = ((right_argument_definition_bb != NULL) && ! ((right_argument_definition_bb != phi_bb) ? dominates (right_argument_definition_bb, phi_bb) :
+                                                       (IS_PHI_DEFINITION (current_bb->phi_argument_right_argument_version) ? TRUE : FALSE)));
+                                       
+                                       if (left_bottom_condition || right_bottom_condition) {
+                                               current_bb->phi_argument_class = BOTTOM_REDUNDANCY_CLASS;
+                                       }
+                               } else {
+                                       current_bb->phi_argument_class = BOTTOM_REDUNDANCY_CLASS;
+                               }
+                       } else {
+                               current_bb->phi_argument_class = BOTTOM_REDUNDANCY_CLASS;
+                       }
+                       
+                       if (current_bb->phi_argument_class == BOTTOM_REDUNDANCY_CLASS) {
+                               if ((current_bb->phi_argument_defined_by_phi != NULL) && (! current_bb->phi_argument_has_real_use)) {
+                                       if (TRACE_SSAPRE) {
+                                               printf ("Clearing down safe in PHI %d because PHI argument in block [bb %d [ID %d]] is BOTTOM\n",
+                                                               current_bb->phi_argument_defined_by_phi->phi_redundancy_class, current_bb->cfg_dfn, current_bb->bb->block_num);
+                                       }
+                                       current_bb->phi_argument_defined_by_phi->phi_is_down_safe = FALSE;
+                               }
+                               current_bb->phi_argument_has_real_use = FALSE;
+                       }
+               }
+       }
+       
+       /* Final quick pass to copy the result of "rename2" into PHI nodes */
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       int i;
+                       for (i = 0; i < current_bb->in_count; i++) {
+                               current_bb->phi_arguments_classes [i] = current_bb->in_bb [i]->phi_argument_class;
+                       }
+               }
+       }
+}
+
+#undef PUSH_REAL_OCCURRENCE
+#undef PUSH_PHI_OCCURRENCE
+
+/*
+ * See paper, figure 8
+ */
+static void
+reset_down_safe (MonoSsapreBBInfo *phi_argument) {
+       if ((phi_argument->phi_argument_class != BOTTOM_REDUNDANCY_CLASS) && (! phi_argument->phi_argument_has_real_use) && (phi_argument->phi_argument_defined_by_phi != NULL) && (phi_argument->phi_argument_defined_by_phi->phi_is_down_safe)) {
+               int i;
+               MonoSsapreBBInfo *phi = phi_argument->phi_argument_defined_by_phi;
+//             if (TRACE_SSAPRE) {
+//                     printf ("Clearing down safe in PHI %d inside reset_down_safe\n", phi->phi_redundancy_class);
+//             }
+               phi->phi_is_down_safe = FALSE;
+               for (i = 0; i < phi->in_count; i++) {
+                       reset_down_safe (phi->in_bb [i]);
+               }
+       }
+}
+
+/*
+ * See paper, figure 8
+ */
+static void
+down_safety (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       if (! current_bb->phi_is_down_safe) {
+                               int i;
+                               for (i = 0; i < current_bb->in_count; i++) {
+                                       reset_down_safe (current_bb->in_bb [i]);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 10
+ */
+static void
+reset_can_be_available (MonoSsapreWorkArea *area, MonoSsapreBBInfo *phi) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       
+       phi->phi_can_be_available = FALSE;
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       gboolean phi_is_interesting = FALSE;
+                       int i;
+                       
+                       for (i = 0; i < current_bb->in_count; i++) {
+                               MonoSsapreBBInfo *phi_argument = current_bb->in_bb [i];
+                               if ((phi_argument->phi_argument_class == current_bb->phi_redundancy_class) && (! phi_argument->phi_argument_has_real_use)) {
+                                       phi_is_interesting = TRUE;
+                                       break;
+                               }
+                       }
+                       
+                       if (phi_is_interesting && (! current_bb->phi_is_down_safe) && (current_bb->phi_can_be_available)) {
+                               reset_can_be_available (area, current_bb);
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 10
+ */
+static void
+compute_can_be_available (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       if ((! current_bb->phi_is_down_safe) && (current_bb->phi_can_be_available)) {
+                               gboolean phi_is_interesting = FALSE;
+                               int i;
+                               
+                               for (i = 0; i < current_bb->in_count; i++) {
+                                       if (current_bb->phi_arguments_classes [i] == BOTTOM_REDUNDANCY_CLASS) {
+                                               phi_is_interesting = TRUE;
+                                               break;
+                                       }
+                               }
+                               
+                               if (phi_is_interesting) {
+                                       reset_can_be_available (area, current_bb);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 10
+ */
+static void
+reset_later (MonoSsapreWorkArea *area, MonoSsapreBBInfo *phi) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       
+       if (phi->phi_is_later) {
+               phi->phi_is_later = FALSE;
+               for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+                       if (current_bb->has_phi) {
+                               gboolean phi_is_interesting = FALSE;
+                               int i;
+                               
+                               for (i = 0; i < current_bb->in_count; i++) {
+                                       MonoSsapreBBInfo *phi_argument = current_bb->in_bb [i];
+                                       if (phi_argument->phi_argument_class == current_bb->phi_redundancy_class) {
+                                               phi_is_interesting = TRUE;
+                                               break;
+                                       }
+                               }
+                               
+                               if (phi_is_interesting) {
+                                       reset_later (area, current_bb);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 10
+ */
+static void
+compute_later (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       current_bb->phi_is_later = current_bb->phi_can_be_available;
+               }
+       }
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       if (current_bb->phi_is_later) {
+                               gboolean phi_is_interesting = FALSE;
+                               int i;
+                               
+                               for (i = 0; i < current_bb->in_count; i++) {
+                                       MonoSsapreBBInfo *phi_argument = current_bb->in_bb [i];
+                                       if ((phi_argument->phi_argument_class != BOTTOM_REDUNDANCY_CLASS) && (phi_argument->phi_argument_has_real_use)) {
+                                               phi_is_interesting = TRUE;
+                                               break;
+                                       }
+                               }
+                               
+                               if (phi_is_interesting) {
+                                       reset_later (area, current_bb);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 12, function Finalize_1
+ */
+static void finalize_availability_and_reload (MonoSsapreWorkArea *area, MonoSsapreAvailabilityTableElement *availability_table) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       MonoSsapreExpressionOccurrence *current_expression = NULL;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->has_phi) {
+                       if (current_bb->phi_can_be_available && ! current_bb->phi_is_later) {
+                               availability_table [current_bb->phi_redundancy_class].class_defined_by_phi = current_bb;
+                       }
+               }
+               
+               for (current_expression = current_bb->first_expression_in_bb; (current_expression != NULL) && (current_expression->bb_info == current_bb); current_expression = current_expression->next) {
+                       MonoSsapreBBInfo *defining_bb = availability_table [current_expression->redundancy_class].class_defined_by_phi;
+                       if (defining_bb == NULL && availability_table [current_expression->redundancy_class].class_defined_by_real_occurrence != NULL) {
+                               defining_bb = availability_table [current_expression->redundancy_class].class_defined_by_real_occurrence->bb_info;
+                       }
+                       if (defining_bb != NULL) {
+                               if (! dominates (defining_bb, current_bb)) {
+                                       defining_bb = NULL;
+                               }
+                       }
+                       
+                       if (defining_bb == NULL) {
+                               current_expression->reload = FALSE;
+                               availability_table [current_expression->redundancy_class].class_defined_by_real_occurrence = current_expression;
+                       } else {
+                               current_expression->reload = TRUE;
+                               current_expression->defined_by_phi = availability_table [current_expression->redundancy_class].class_defined_by_phi;
+                               current_expression->defined_by_real_occurrence = availability_table [current_expression->redundancy_class].class_defined_by_real_occurrence;
+                       }
+                       
+                       current_expression->save = FALSE;
+               }
+               
+               if (current_bb->has_phi_argument) {
+                       MonoSsapreBBInfo *phi_bb = current_bb->out_bb [0];
+                       if (((phi_bb->phi_can_be_available) && (! phi_bb->phi_is_later)) &&
+                                       ((current_bb->phi_argument_class == BOTTOM_REDUNDANCY_CLASS) ||
+                                       ((current_bb->phi_argument_has_real_use == FALSE) && (current_bb->phi_argument_defined_by_phi != NULL) &&
+                                               (! ((current_bb->phi_argument_defined_by_phi->phi_can_be_available) && (! current_bb->phi_argument_defined_by_phi->phi_is_later)))
+                                       ))) {
+                               current_bb->phi_argument_needs_insert = TRUE;
+                               current_bb->phi_argument_defined_by_real_occurrence = NULL;
+                               current_bb->phi_argument_defined_by_phi = NULL;
+                       } else {
+                               current_bb->phi_argument_needs_insert = FALSE;
+                               if (current_bb->phi_argument_class != BOTTOM_REDUNDANCY_CLASS) {
+                                       current_bb->phi_argument_defined_by_real_occurrence = availability_table [current_bb->phi_argument_class].class_defined_by_real_occurrence;
+                                       current_bb->phi_argument_defined_by_phi = availability_table [current_bb->phi_argument_class].class_defined_by_phi;
+                               }
+                       }
+                       
+                       current_bb->phi_argument_has_been_processed = FALSE;
+               }
+       }
+}
+
+/*
+ * See paper, figure 13, function Set_save
+ */
+static void set_save (MonoSsapreBBInfo *phi_occurrance, MonoSsapreExpressionOccurrence *real_occurrance) {
+       if (real_occurrance != NULL) {
+               real_occurrance->save = TRUE;
+       } else if (phi_occurrance != NULL) {
+               int i;
+               for (i = 0; i < phi_occurrance->in_count; i++) {
+                       MonoSsapreBBInfo *phi_argument = phi_occurrance->in_bb [i];
+                       if (! phi_argument->phi_argument_has_been_processed) {
+                               phi_argument->phi_argument_has_been_processed = TRUE;
+                               set_save (phi_argument->phi_argument_defined_by_phi, phi_argument->phi_argument_defined_by_real_occurrence);
+                       }
+               }
+       }
+}
+
+/*
+ * See paper, figure 13, function Finalize_2 (note that we still don't do
+ * extraneous PHI elimination, see function Set_replacement)
+ */
+static void finalize_save (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       MonoSsapreExpressionOccurrence *current_expression = NULL;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               for (current_expression = current_bb->first_expression_in_bb; (current_expression != NULL) && (current_expression->bb_info == current_bb); current_expression = current_expression->next) {
+                       if (current_expression->reload) {
+                               set_save (current_expression->defined_by_phi, current_expression->defined_by_real_occurrence);
+                       }
+               }
+               
+               if ((current_bb->has_phi_argument) &&
+                               (! current_bb->phi_argument_needs_insert) &&
+                               (current_bb->phi_argument_class != BOTTOM_REDUNDANCY_CLASS) &&
+                               (current_bb->phi_argument_defined_by_real_occurrence != NULL)) {
+                       current_bb->phi_argument_defined_by_real_occurrence->save = TRUE;
+               }
+       }
+}
+
+/*
+ * Perform all "finalize" steps
+ */
+static void finalize (MonoSsapreWorkArea *area) {
+       MonoSsapreAvailabilityTableElement *availability_table = alloca (sizeof (MonoSsapreAvailabilityTableElement) * (area->number_of_classes));
+       int i;
+       
+       for (i = 0; i < area->number_of_classes; i++) {
+               availability_table[i].class_defined_by_phi = NULL;
+               availability_table[i].class_defined_by_real_occurrence = NULL;
+       }
+       
+       finalize_availability_and_reload (area, availability_table);
+       finalize_save (area);
+}
+
+/*
+ * Macros that help in creating constants
+ */
+#define NEW_INST(dest,op) do { \
+               (dest) = mono_mempool_alloc0 (area->cfg->mempool, sizeof (MonoInst));   \
+               (dest)->opcode = (op);  \
+       } while (0)
+
+#define NEW_I4(dest,val) do {  \
+               NEW_INST ((dest), OP_ICONST); \
+               (dest)->inst_c0 = (val);        \
+               (dest)->type = STACK_I4;        \
+       } while (0)
+
+#define NEW_I8(dest,val) do {  \
+               NEW_INST ((dest), OP_I8CONST); \
+               (dest)->inst_l = (val); \
+               (dest)->type = STACK_I8;        \
+       } while (0)
+
+#define NEW_R4(dest,f) do {    \
+               NEW_INST ((dest), OP_R4CONST); \
+               (dest)->inst_p0 = f;    \
+               (dest)->type = STACK_R8;        \
+       } while (0)
+
+#define NEW_R8(dest,d) do {    \
+               NEW_INST ((dest), OP_R8CONST); \
+               (dest)->inst_p0 = d;    \
+               (dest)->type = STACK_R8;        \
+       } while (0)
+
+/*
+ * Create a MonoInst that represents an expression argument
+ */
+static MonoInst*
+create_expression_argument (MonoSsapreWorkArea *area, MonoSsapreExpressionArgument *argument) {
+       MonoInst *result;
+       
+       switch (argument->type) {
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_NOT_PRESENT:
+                       return NULL;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE:
+                       return mono_compile_create_var_load (area->cfg, argument->argument.ssa_variable);
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_INTEGER_CONSTANT:
+                       NEW_I4 (result, argument->argument.integer_constant);
+                       return result;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_LONG_COSTANT:
+                       NEW_I8 (result, *(argument->argument.long_constant));
+                       return result;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_FLOAT_COSTANT:
+                       NEW_R4 (result, argument->argument.float_constant);
+                       return result;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_DOUBLE_COSTANT:
+                       NEW_R8 (result, argument->argument.double_constant);
+                       return result;
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE:
+               case MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY:
+               default:
+                       g_assert_not_reached ();
+                       return NULL;
+       }
+}
+
+/*
+ * Create a MonoInst that represents an expression
+ */
+static MonoInst*
+create_expression (MonoSsapreWorkArea *area, MonoSsapreExpressionDescription *expression) {
+       MonoInst *result;
+       NEW_INST (result, expression->opcode);
+       result->inst_left = create_expression_argument (area, &(expression->left_argument));
+       result->inst_right = create_expression_argument (area, &(expression->right_argument));
+       return result;
+}
+
+/*
+ * See paper, section 3.6
+ */
+static void code_motion (MonoSsapreWorkArea *area) {
+       MonoSsapreBBInfo *current_bb = NULL;
+       MonoSsapreExpressionOccurrence *current_expression = NULL;
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {       
+               if ((current_bb->has_phi) && (current_bb->phi_can_be_available && ! current_bb->phi_is_later)) {
+                       MonoInst *new_var = mono_compile_create_var (area->cfg, area->current_expression->type, OP_LOCAL);
+                       current_bb->phi_variable_index = new_var->inst_c0;
+               } else {
+                       current_bb->phi_variable_index = BOTTOM_REDUNDANCY_CLASS;
+               }
+               
+               for (current_expression = current_bb->first_expression_in_bb; (current_expression != NULL) && (current_expression->bb_info == current_bb); current_expression = current_expression->next) {
+                       if (current_expression->save) {
+                               MonoInst *new_var = mono_compile_create_var (area->cfg, area->current_expression->type, OP_LOCAL);
+                               current_expression->variable_index = new_var->inst_c0;
+                       } else {
+                               current_expression->variable_index = BOTTOM_REDUNDANCY_CLASS;
+                       }
+               }
+               
+               if ((current_bb->has_phi_argument) && (current_bb->phi_argument_needs_insert)) {
+                       MonoInst *new_var = mono_compile_create_var (area->cfg, area->current_expression->type, OP_LOCAL);
+                       current_bb->phi_argument_variable_index = new_var->inst_c0;
+               } else {
+                       current_bb->phi_argument_variable_index = BOTTOM_REDUNDANCY_CLASS;
+               }
+       }
+       
+       for (current_bb = area->first_interesting_bb; current_bb != NULL; current_bb = current_bb->next_interesting_bb) {
+               if (current_bb->phi_variable_index != BOTTOM_REDUNDANCY_CLASS) {
+                       MonoInst *phi;
+                       MonoInst *store;
+                       int in_bb;
+                       
+                       NEW_INST (phi, OP_PHI);
+                       phi->inst_phi_args = mono_mempool_alloc (area->cfg->mempool, (sizeof (int) * ((current_bb->in_count) + 1)));
+                       phi->inst_phi_args [0] = current_bb->in_count;
+                       for (in_bb = 0; in_bb < current_bb->in_count; in_bb++) {
+                               gssize phi_argument_variable_index = current_bb->in_bb [in_bb]->phi_argument_variable_index;
+                               if (phi_argument_variable_index == BOTTOM_REDUNDANCY_CLASS) {
+                                       MonoSsapreBBInfo *phi_argument_bb = current_bb->in_bb [in_bb];
+                                       if (phi_argument_bb->phi_argument_defined_by_phi !=NULL) {
+                                               phi_argument_variable_index = phi_argument_bb->phi_argument_defined_by_phi->phi_variable_index;
+                                       } else if (phi_argument_bb->phi_argument_defined_by_real_occurrence !=NULL) {
+                                               phi_argument_variable_index = phi_argument_bb->phi_argument_defined_by_real_occurrence->variable_index;
+                                       } else {
+                                               g_assert_not_reached ();
+                                       }
+                               }
+                               phi->inst_phi_args [in_bb + 1] = phi_argument_variable_index;
+                       }
+                       store = mono_compile_create_var_store (area->cfg, current_bb->phi_variable_index, phi);
+                       if (current_bb->phi_insertion_point != NULL) {
+                               store->next = current_bb->phi_insertion_point->next;
+                               current_bb->phi_insertion_point->next = store;
+                       } else {
+                               store->next = current_bb->bb->code;
+                               current_bb->bb->code = store;
+                       }
+                       current_bb->phi_insertion_point = store;
+                       
+                       area->added_phis ++;
+               }
+               
+               for (current_expression = current_bb->first_expression_in_bb; (current_expression != NULL) && (current_expression->bb_info == current_bb); current_expression = current_expression->next) {
+                       gboolean altered = FALSE;
+                       if (current_expression->reload) {
+                               gssize variable_index;
+                               if (current_expression->defined_by_phi != NULL) {
+                                       variable_index = current_expression->defined_by_phi->phi_variable_index;
+                               } else if (current_expression->defined_by_real_occurrence != NULL) {
+                                       variable_index = current_expression->defined_by_real_occurrence->variable_index;
+                               } else {
+                                       variable_index = BOTTOM_REDUNDANCY_CLASS;
+                                       g_assert_not_reached ();
+                               }
+                               mono_compile_make_var_load (area->cfg, current_expression->occurrence, variable_index);
+                               
+                               area->reloaded_occurrences ++;
+                               altered = TRUE;
+                       }
+                       if (current_expression->save) {
+                               MonoInst *store;
+                               MonoInst *moved_expression = mono_mempool_alloc (area->cfg->mempool, sizeof (MonoInst));
+                               *moved_expression = *(current_expression->occurrence);
+                               store = mono_compile_create_var_store (area->cfg, current_expression->variable_index, moved_expression);
+                               if (current_expression->previous_tree != NULL) {
+                                       store->next = current_expression->previous_tree->next;
+                                       current_expression->previous_tree->next = store;
+                               } else {
+                                       store->next = current_bb->bb->code;
+                                       current_bb->bb->code = store;
+                               }
+                               mono_compile_make_var_load (area->cfg, current_expression->occurrence, current_expression->variable_index);
+                               
+                               area->saved_occurrences ++;
+                               altered = TRUE;
+                       }
+                       if (! altered) {
+                               area->unaltered_occurrences ++;
+                       }
+               }
+               
+               if (current_bb->phi_argument_variable_index != BOTTOM_REDUNDANCY_CLASS) {
+                       MonoSsapreExpressionDescription expression_description;
+                       MonoInst *inserted_expression;
+                       MonoInst *store;
+                       
+                       expression_description = area->current_expression->description;
+                       if (expression_description.left_argument.type == MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE) {
+                               expression_description.left_argument.argument.ssa_variable = current_bb->phi_argument_left_argument_version;
+                               expression_description.left_argument.type = MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE;
+                       }
+                       if (expression_description.right_argument.type == MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE) {
+                               expression_description.right_argument.argument.ssa_variable = current_bb->phi_argument_right_argument_version;
+                               expression_description.right_argument.type = MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE;
+                       }
+                       
+                       inserted_expression = create_expression (area, &expression_description);
+                       store = mono_compile_create_var_store (area->cfg, current_bb->phi_argument_variable_index, inserted_expression);
+                       store->next = NULL;
+                       mono_add_ins_to_end (current_bb->bb, store);
+                       
+                       area->inserted_occurrences ++;
+               }
+       }
+}
+
+/*
+ * Perform all SSAPRE steps for an expression
+ */
+static void
+process_expression (MonoSsapreWorkArea *area, MonoSsapreExpression *expression) {
+       if (area->cfg->verbose_level >= TRACE_LEVEL) {
+               printf ("SSAPRE STARTS PROCESSING EXPRESSION ");
+               print_expression_description (&(expression->description));
+               printf ("\n");
+       }
+       
+       clean_area_infos (area);
+       
+       area->current_expression = expression;
+       phi_insertion (area, expression);
+       renaming_pass (area);
+       
+       if (area->cfg->verbose_level >= TRACE_LEVEL) {
+               printf ("START SUMMARY OF BB INFOS\n");
+               print_bb_infos (area);
+               printf ("END SUMMARY OF BB INFOS\n");
+       }
+       
+       down_safety (area);
+       compute_can_be_available (area);
+       compute_later (area);
+       finalize (area);
+       code_motion (area);
+       
+       if (area->cfg->verbose_level >= DUMP_LEVEL) {
+               printf ("START DUMP OF BB INFOS\n");
+               dump_code (area);
+               printf ("END DUMP OF BB INFOS\n");
+       } else if (area->cfg->verbose_level >= TRACE_LEVEL) {
+               printf ("START SUMMARY OF BB INFOS\n");
+               print_interesting_bb_infos (area);
+               printf ("END SUMMARY OF BB INFOS\n");
+       }
+       
+       if (area->cfg->verbose_level >= STATISTICS_LEVEL) {
+               printf ("STATISTICS: saved_occurrences = %d, reloaded_occurrences = %d, inserted_occurrences = %d, unaltered_occurrences = %d, added_phis = %d\n",
+                       area->saved_occurrences, area->reloaded_occurrences, area->inserted_occurrences, area->unaltered_occurrences, area->added_phis);
+       }
+       
+       if (area->cfg->verbose_level >= TRACE_LEVEL) {
+               printf ("SSAPRE ENDS PROCESSING EXPRESSION ");
+               print_expression_description (&(expression->description));
+               printf ("\n");
+       }
+}
+
+/*
+ * Perform all SSAPRE steps for all the expressions in the worklist
+ */
+static void
+process_worklist (MonoSsapreWorkArea *area, MonoSsapreExpression *expression) {
+       if (expression != NULL) {
+               process_worklist (area, expression->previous);
+               process_expression (area, expression);
+               process_worklist (area, expression->next);
+       }
+}
+
+/*
+ * Hack to apply SSAPRE only to a given method (invaluable in debugging)
+ */
+#define APPLY_SSAPRE_TO_SINGLE_METHOD 0
+#if (APPLY_SSAPRE_TO_SINGLE_METHOD)
+static char *mono_ssapre_method_name = NULL;
+static gboolean check_ssapre_method_name (MonoCompile *cfg) {
+       if (mono_ssapre_method_name == NULL) {
+               mono_ssapre_method_name = getenv ("MONO_SSAPRE_METHOD_NAME");
+       }
+       if (mono_ssapre_method_name != NULL) {
+               char *method_name = mono_method_full_name (cfg->method, TRUE);
+               if (strstr (mono_ssapre_method_name, method_name) != NULL) {
+                       return TRUE;
+               } else {
+                       return FALSE;
+               }
+       } else {
+               return TRUE;
+       }
+}
+#endif
+
+/*
+ * Apply SSAPRE to a MonoCompile
+ */
+void
+mono_perform_ssapre (MonoCompile *cfg) {
+       MonoSsapreWorkArea area;
+       MonoSsapreExpressionOccurrence *current_occurrence;
+       int dt_dfn, descendants, block, i;
+       
+#if (APPLY_SSAPRE_TO_SINGLE_METHOD)
+       if (! check_ssapre_method_name (cfg)) return;
+#endif
+       
+       area.cfg = cfg;
+       area.mempool = mono_mempool_new ();
+       
+       area.num_bblocks = cfg->num_bblocks;
+       area.bb_infos = (MonoSsapreBBInfo*) mono_mempool_alloc (area.mempool, sizeof (MonoSsapreBBInfo) * (cfg->num_bblocks));
+       area.bb_infos_in_cfg_dfn_order = (MonoSsapreBBInfo**) mono_mempool_alloc (area.mempool, sizeof (MonoSsapreBBInfo*) * (cfg->num_bblocks));
+       
+       area.sizeof_bb_bitset = mono_bitset_alloc_size (cfg->num_bblocks, 0);
+       area.expression_occurrences_buffer = mono_bitset_mem_new (mono_mempool_alloc (area.mempool, area.sizeof_bb_bitset), area.num_bblocks, 0);
+       area.bb_iteration_buffer = mono_bitset_mem_new (mono_mempool_alloc (area.mempool, area.sizeof_bb_bitset), area.num_bblocks, 0);
+       area.iterated_dfrontier_buffer = mono_bitset_mem_new (mono_mempool_alloc (area.mempool, area.sizeof_bb_bitset), area.num_bblocks, 0);
+       area.left_argument_bb_bitset = mono_bitset_mem_new (mono_mempool_alloc (area.mempool, area.sizeof_bb_bitset), area.num_bblocks, 0);
+       area.right_argument_bb_bitset = mono_bitset_mem_new (mono_mempool_alloc (area.mempool, area.sizeof_bb_bitset), area.num_bblocks, 0);
+       
+       area.worklist = NULL;
+       
+       if (area.cfg->verbose_level >= LOG_LEVEL) {
+               printf ("SSAPRE STARTS PROCESSING METHOD %s\n", mono_method_full_name (cfg->method, TRUE));
+       }
+       
+       current_occurrence = (MonoSsapreExpressionOccurrence*) mono_mempool_alloc (area.mempool, sizeof (MonoSsapreExpressionOccurrence));
+       dt_dfn = 0;
+       descendants = 0;
+       process_bb (&area, cfg->bblocks [0], &dt_dfn, &descendants, current_occurrence);
+       for (block = 0; block < area.num_bblocks; block++) {
+               MonoSsapreBBInfo *bb_info = &(area.bb_infos [block]);
+               MonoBasicBlock *bb = bb_info->bb;
+               if (bb->idom != NULL) {
+                       bb_info->idominator = area.bb_infos_in_cfg_dfn_order [bb->idom->dfn];
+               } else {
+                       bb_info->idominator = NULL;
+               }
+               for (i = 0; i < bb->in_count; i++) {
+                       bb_info->in_bb [i] = area.bb_infos_in_cfg_dfn_order [bb->in_bb [i]->dfn];
+               }
+               for (i = 0; i < bb->out_count; i++) {
+                       bb_info->out_bb [i] = area.bb_infos_in_cfg_dfn_order [bb->out_bb [i]->dfn];
+               }
+       }
+       
+       if (area.cfg->verbose_level >= TRACE_LEVEL) {
+               printf ("SSAPRE START WORKLIST\n");
+               print_worklist (area.worklist);
+               printf ("SSAPRE END WORKLIST\n");
+       }
+       
+       process_worklist (&area, area.worklist);
+       
+       if (area.cfg->verbose_level >= TRACE_LEVEL) {
+               printf ("SSAPRE ENDS PROCESSING METHOD %s\n", mono_method_full_name (cfg->method, TRUE));
+       }
+       
+       mono_mempool_destroy (area.mempool);
+}
diff --git a/mono/mini/ssapre.h b/mono/mini/ssapre.h
new file mode 100644 (file)
index 0000000..ca00c4f
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * ssapre.h: SSA Partial Redundancy Elimination
+ *
+ * Author:
+ *   Massimiliano Mantione (massi@ximian.com)
+ *
+ * (C) 2004 Novell, Inc.  http://www.novell.com
+ */
+
+#ifndef __MONO_SSAPRE_H__
+#define __MONO_SSAPRE_H__
+
+
+#include "mini.h"
+#include <mono/metadata/mempool.h>
+
+/*
+ * All the different kind of arguments we can handle.
+ * "ANY" means the argument is unknown or cannot be handled, and "NOT_PRESENT"
+ * that the expression does not have this argument (has not "enough" arity).
+ */
+typedef enum {
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_ANY,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_NOT_PRESENT,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_INTEGER_CONSTANT,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_LONG_COSTANT,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_FLOAT_COSTANT,
+       MONO_SSAPRE_EXPRESSION_ARGUMENT_DOUBLE_COSTANT
+} MonoSsapreExpressionArgumentType;
+
+/*
+ * A struct representing an expression argument (the used branch in the
+ * union depends on the value of the type field).
+ */
+typedef struct MonoSsapreExpressionArgument {
+       MonoSsapreExpressionArgumentType type;
+       union {
+               gssize original_variable;
+               gssize ssa_variable;
+               gssize integer_constant;
+               gint64* long_constant;
+               float* float_constant;
+               double* double_constant;
+       } argument;
+} MonoSsapreExpressionArgument;
+
+/*
+ * Macros used when comparing expression arguments, which return -1,0 or 1.
+ */
+#define MONO_COMPARE_SSAPRE_DIRECT_VALUES(v1,v2) (((v2)>(v1)?(1):((v2)<(v1)?(-1):(0))))
+#define MONO_COMPARE_SSAPRE_POINTER_VALUES(p1,p2) (((*p2)>(*p1)?(1):((*p2)<(*p1)?(-1):(0))))
+
+#define MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENT_VALUES(t,v1,v2) (\
+               (t)==MONO_SSAPRE_EXPRESSION_ARGUMENT_ORIGINAL_VARIABLE?\
+                       MONO_COMPARE_SSAPRE_DIRECT_VALUES ((v1).original_variable,(v2).original_variable):(\
+               (t)==MONO_SSAPRE_EXPRESSION_ARGUMENT_SSA_VARIABLE?\
+                       MONO_COMPARE_SSAPRE_DIRECT_VALUES ((v1).ssa_variable,(v2).ssa_variable):(\
+               (t)==MONO_SSAPRE_EXPRESSION_ARGUMENT_INTEGER_CONSTANT?\
+                       MONO_COMPARE_SSAPRE_DIRECT_VALUES ((v1).integer_constant,(v2).integer_constant):(\
+               (t)==MONO_SSAPRE_EXPRESSION_ARGUMENT_LONG_COSTANT?\
+                       MONO_COMPARE_SSAPRE_POINTER_VALUES ((v1).long_constant,(v2).long_constant):(\
+               (t)==MONO_SSAPRE_EXPRESSION_ARGUMENT_FLOAT_COSTANT?\
+                       MONO_COMPARE_SSAPRE_POINTER_VALUES ((v1).float_constant,(v2).float_constant):(\
+               (t)==MONO_SSAPRE_EXPRESSION_ARGUMENT_DOUBLE_COSTANT?\
+                       MONO_COMPARE_SSAPRE_POINTER_VALUES ((v1).double_constant,(v2).double_constant):(\
+               0)))))))
+
+#define MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENTS(a1,a2) (\
+               MONO_COMPARE_SSAPRE_DIRECT_VALUES ((a1).type,(a2).type)!=0?\
+                       MONO_COMPARE_SSAPRE_DIRECT_VALUES ((a1).type,(a2).type):\
+               MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENT_VALUES ((a1).type,(a1).argument,(a2).argument) )
+
+
+/*
+ * A struct representing an expression, with its opcode and two arguments
+ * (if the opcode has arity 1 right_argument is MONO_SSAPRE_EXPRESSION_ARGUMENT_NOT_PRESENT).
+ */
+typedef struct MonoSsapreExpressionDescription {
+       guint16 opcode;
+       MonoSsapreExpressionArgument left_argument;
+       MonoSsapreExpressionArgument right_argument;
+} MonoSsapreExpressionDescription;
+
+/*
+ * Macro that compares two expression descriptions (returns -1, 0 or 1).
+ */
+#define MONO_COMPARE_SSAPRE_EXPRESSION_DESCRIPTIONS(d1,d2) (\
+               MONO_COMPARE_SSAPRE_DIRECT_VALUES ((d1).opcode,(d2).opcode)!=0?\
+                       MONO_COMPARE_SSAPRE_DIRECT_VALUES ((d1).opcode,(d2).opcode):(\
+               MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENTS ((d1).left_argument,(d2).left_argument)!=0?\
+                       MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENTS ((d1).left_argument,(d2).left_argument):(\
+               MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENTS ((d1).right_argument,(d2).right_argument)!=0?\
+                       MONO_COMPARE_SSAPRE_EXPRESSION_ARGUMENTS ((d1).right_argument,(d2).right_argument):(\
+               0))))
+
+/*
+ * Struct that contains all the information related to a BB.
+ * Some of them are taken from the corresponding MonoBasicBlock, some are
+ * constant during the compilation of the whole method, others must be
+ * recomputed for each expression.
+ */
+typedef struct MonoSsapreBBInfo {
+       /* Information constant during the compilation of the whole method: */
+       
+       /* Depth First Number relative to a traversal of the dominator tree */
+       gint32 dt_dfn;
+       /* Depth First Number relative to a traversal of the CFG */
+       gint32 cfg_dfn;
+       /* Number of descendants in the dominator tree (is equal to the number of strictly dominated BBs) */
+       int dt_descendants;
+       /* In and out count (taken from the corresponding MonoBasicBlock) */
+       gint16 in_count, out_count;
+       /* Idominator (taken from the corresponding MonoBasicBlock, but pointing */
+       /* to the MonoSsapreBBInfo for convenience) */
+       struct MonoSsapreBBInfo *idominator;
+       /* In and out BBs (taken from the corresponding MonoBasicBlock, but pointing */
+       /* to the MonoSsapreBBInfo for convenience) */
+       struct MonoSsapreBBInfo **in_bb;
+       struct MonoSsapreBBInfo **out_bb;
+       /* Dominance frontier (taken from the corresponding MonoBasicBlock) */
+       MonoBitSet *dfrontier;
+       
+       /* MonoInst where new phi definitions must be added in the BB */
+       /* (the last existing phi definition, or NULL if there is none) */
+       MonoInst *phi_insertion_point;
+       
+       /* Information reused during the analysis of each expression: */
+       
+       /* True if this BB has a PHI occurrence */
+       gboolean has_phi;
+       /* True if this PHI defines a real occurrence */
+       gboolean phi_defines_a_real_occurrence;
+       /* True if this PHI is down safe */
+       gboolean phi_is_down_safe;
+       /* True if this PHI can be available */
+       gboolean phi_can_be_available;
+       /* True if this PHI is "later" */
+       gboolean phi_is_later;
+       /* The PHI class number */
+       gssize phi_redundancy_class;
+       /* The index of this PHI in the cfg->vars array */
+       gssize phi_variable_index;
+       /* Array of the class numbers of the PHI arguments (has "in_count" elements) */
+       gssize *phi_arguments_classes;
+       
+       
+       /* True if this BB has a PHI argument */
+       gboolean has_phi_argument;
+       /* True if this PHI argument "has real use" */
+       gboolean phi_argument_has_real_use;
+       /* True if this PHI argument needs the insertion of a new occurrence */
+       gboolean phi_argument_needs_insert;
+       /* True if this PHI argument has been processed (see "set_save") */
+       gboolean phi_argument_has_been_processed;
+       /* The PHI argument class number */
+       gssize phi_argument_class;
+       /* The index of this PHI argument in the cfg->vars array */
+       gssize phi_argument_variable_index;
+       /* Points to the real occurrence defining this PHI argument (NULL otherwise) */
+       struct MonoSsapreExpressionOccurrence *phi_argument_defined_by_real_occurrence;
+       /* Points to the BB containing the PHI defining this PHI argument (NULL otherwise) */
+       struct MonoSsapreBBInfo *phi_argument_defined_by_phi;
+       /* Variable version of the left argument og the PHI argument "expected" at */
+       /* the PHI (or BOTTOM_REDUNDANCY_CLASS otherwise), see "renaming_pass" */
+       gssize phi_argument_left_argument_version;
+       /* As above, but for the right argument */
+       gssize phi_argument_right_argument_version;
+       
+       /* The first real occurrence in this BB (NULL if there is none) */
+       struct MonoSsapreExpressionOccurrence *first_expression_in_bb;
+       /* Next BB which has either a real occurrence, a PHI or a PHI argument */
+       /* (NULL if there is none, BBs are in dominator tree depth first preorder) */
+       struct MonoSsapreBBInfo *next_interesting_bb;
+       
+       /* Used in maintaining the renaming stack */
+       struct MonoSsapreBBInfo *next_in_renaming_stack;
+       struct MonoSsapreExpressionOccurrence *top_of_local_renaming_stack;
+       
+       /* MonoBasicBlock representing this BB in the CFG (this is obviously constant) */
+       MonoBasicBlock *bb;
+} MonoSsapreBBInfo;
+
+
+/*
+ * A "real" occurrence.
+ */
+typedef struct MonoSsapreExpressionOccurrence {
+       /* The occurrence in the CFG */
+       MonoInst *occurrence;
+       /* The tree just before the occurrence in the CFG (if the occurrence must */
+       /* saved into a temporary, the definition will be placed just after that tree) */
+       MonoInst *previous_tree;
+       /* The BB where this occurrence is found */
+       MonoSsapreBBInfo *bb_info;
+       /* The description of the occurrence */
+       MonoSsapreExpressionDescription description;
+       /* Next occurrence of this expression */
+       struct MonoSsapreExpressionOccurrence *next;
+       /* Previois occurrence of this expression */
+       struct MonoSsapreExpressionOccurrence *previous;
+       /* True if this occurrence is the first in its BB */
+       gboolean is_first_in_bb;
+       /* True if this occurrence is the last in its BB */
+       gboolean is_last_in_bb;
+       /* "reload" flag (see "finalize") */
+       gboolean reload;
+       /* "save" flag (see "finalize") */
+       gboolean save;
+       
+       /* Used in maintaining the renaming stack */
+       struct MonoSsapreExpressionOccurrence *next_in_renaming_stack;
+       
+       /* Class number of this occurrence */
+       gssize redundancy_class;
+       /* The index of the temporary of this occurrence in the cfg->vars array */
+       gssize variable_index;
+       /* Points to the real occurrence defining this occurrence (NULL otherwise) */
+       struct MonoSsapreExpressionOccurrence *defined_by_real_occurrence;
+       /* Points to the BB containing the PHI defining this occurrence (NULL otherwise) */
+       struct MonoSsapreBBInfo *defined_by_phi;
+} MonoSsapreExpressionOccurrence;
+
+
+/*
+ * An expression to be processed (in the worklist).
+ */
+typedef struct MonoSsapreExpression {
+       /* The description of the expression */
+       MonoSsapreExpressionDescription description;
+       /* The type to use when creating values of this expression */
+       MonoType *type;
+       /* The list of expression occurrences */
+       MonoSsapreExpressionOccurrence *occurrences;
+       /* The last expression occurrence in the list */
+       MonoSsapreExpressionOccurrence *last_occurrence;
+       
+       /* Used in maintaining the worklist (an autobalancing binary tree) */
+       struct MonoSsapreExpression *father;
+       struct MonoSsapreExpression *previous;
+       struct MonoSsapreExpression *next;
+       gssize tree_size;
+} MonoSsapreExpression;
+
+/*
+ * Macros used to maintain the worklist
+ */
+#define MONO_SSAPRE_GOTO_FIRST_EXPRESSION(e) do{\
+               while ((e)->previous != NULL) (e) = (e)->previous;\
+       } while (0)
+#define MONO_SSAPRE_REMOVE_FIRST_EXPRESSION(e) do{\
+               if ((e)->father != NULL) {\
+                       (e)->father->previous = (e)->next;\
+               }\
+       } while (0)
+#define MONO_SSAPRE_GOTO_LAST_EXPRESSION(e) do{\
+               while ((e)->next != NULL) (e) = (e)->next;\
+       } while (0)
+#define MONO_SSAPRE_REMOVE_LAST_EXPRESSION(e) do{\
+               if ((e)->father != NULL) {\
+                       (e)->father->next = (e)->previous;\
+               }\
+       } while (0)
+
+#define MONO_SSAPRE_MAX_TREE_DEPTH(size,depth) do{\
+               unsigned __mask__ = ~1;\
+               (depth) = 1;\
+               while (((size)&__mask__)!=0) {\
+                       __mask__ <<= 1;\
+                       (depth)++;\
+               }\
+       } while (0)
+
+#define MONO_SSAPRE_ADD_EXPRESSION_OCCURRANCE(e,o) do{\
+               if ((e)->occurrences == NULL) {\
+                       (e)->occurrences = (o);\
+               } else {\
+                       (e)->last_occurrence->next = (o);\
+               }\
+               (o)->next = NULL;\
+               (o)->previous = (e)->last_occurrence;\
+               (e)->last_occurrence = (o);\
+       } while (0)
+#define MONO_SSAPRE_REMOVE_EXPRESSION_OCCURRANCE(e,o) do{\
+               if ((e)->occurrences == (o)) {\
+                       (e)->occurrences = (o)->next;\
+               }\
+               if ((e)->last_occurrence == (o)) {\
+                       (e)->last_occurrence = (o)->previous;\
+               }\
+               if ((o)->previous != NULL) {\
+                       (o)->previous->next = (o)->next;\
+               }\
+               if ((o)->next != NULL) {\
+                       (o)->next->previous = (o)->previous;\
+               }\
+               (o)->next = NULL;\
+               (o)->previous = NULL;\
+       } while (0)
+
+
+/*
+ * Availability table element (see "finalize"), one for each redundancy class
+ */
+typedef struct MonoSsapreAvailabilityTableElement {
+       /* Points to the real occurrence defining this redundancy class (NULL otherwise) */
+       struct MonoSsapreExpressionOccurrence *class_defined_by_real_occurrence;
+       /* Points to the BB containing the PHI defining this redundancy class (NULL otherwise) */
+       struct MonoSsapreBBInfo *class_defined_by_phi;
+} MonoSsapreAvailabilityTableElement;
+
+/*
+ * The "main" work area for the algorithm.
+ */
+typedef struct MonoSsapreWorkArea {
+       /* The CFG */
+       MonoCompile *cfg;
+       /* The SSAPRE specific mempool */
+       MonoMemPool *mempool;
+       
+       /* Number of BBs in the CFG (from cfg) */
+       int num_bblocks;
+       /* BB information, in dominator tree depth first preorder */
+       MonoSsapreBBInfo *bb_infos;
+       /* Pointers to BB information, in CFG depth first preorder */
+       MonoSsapreBBInfo **bb_infos_in_cfg_dfn_order;
+       
+       /* Number of variables in the CFG */
+       int num_vars;
+       /* Size of bitset for BBs */
+       int sizeof_bb_bitset;
+       /* Various bitsets used when working with iterated dfrontiers */
+       MonoBitSet *expression_occurrences_buffer;
+       MonoBitSet *bb_iteration_buffer;
+       MonoBitSet *iterated_dfrontier_buffer;
+       MonoBitSet *left_argument_bb_bitset;
+       MonoBitSet *right_argument_bb_bitset;
+       
+       /* The expression worklist */
+       MonoSsapreExpression *worklist;
+       
+       /* The expression being processed */
+       MonoSsapreExpression *current_expression;
+       
+       /* The BB on top of the renaming stack (if "top_of_renaming_stack" is NULL */
+       /* but this is not, then the top of the stack is the PHI in this BB) */
+       struct MonoSsapreBBInfo *bb_on_top_of_renaming_stack;
+       /* The top of the renaming stack */
+       struct MonoSsapreExpressionOccurrence *top_of_renaming_stack;
+       
+       /* The head of the list of "interesting" BBs */
+       struct MonoSsapreBBInfo *first_interesting_bb;
+       
+       /* The number of generated class numbers */
+       int number_of_classes;
+       
+       /* Statistics fields (per expression)  */
+       int saved_occurrences;
+       int reloaded_occurrences;
+       int inserted_occurrences;
+       int unaltered_occurrences;
+       int added_phis;
+} MonoSsapreWorkArea;
+
+
+#endif /* __MONO_SSAPRE_H__ */
index 55e25aa972feda131b43b39b35a7dfd312f4c66e..49b34f334b4f2398eeb0cdcbfd9046c7cda2cb03 100644 (file)
@@ -1,5 +1,12 @@
+2004-12-04  Zoltan Varga  <vargaz@freemail.hu>
+
+       * delegate.cs: Add test for unboxing and delegates.
+
 2004-12-02  Zoltan Varga  <vargaz@freemail.hu>
 
+       * appdomain-unload.cs: Add tests for unloading an appdomain from inside
+       the appdomain.
+       
        * appdomain-unload.cs: Stop the foreground thread created by one of the
        tests.
 
index 22d698251518ba1ba4197edd598778e570d32e3e..607f91aae253b03ada0bf6ff38b6c1d308219a13 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: ackermann.cs,v 1.3 2002/05/23 13:03:04 lupus Exp $
+// $Id$
 // http://www.bagley.org/~doug/shootout/
 
 public class ackermann {
index e07cb81cd54f0847afccdda9bc357517f4b54d9a..f0a8967f4b50efd0d8f29bd0ac332951c9b84efb 100644 (file)
@@ -161,6 +161,42 @@ public class Tests
                return 1;
        }
 
+       public static void DoUnload (object state) {
+               AppDomain.Unload (AppDomain.CurrentDomain);
+       }
+
+       public static void Callback () {
+               Console.WriteLine (AppDomain.CurrentDomain);
+               WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
+               ThreadPool.QueueUserWorkItem (unloadDomainCallback);
+       }               
+
+       public static int test_0_unload_inside_appdomain_async () {
+               AppDomain domain = AppDomain.CreateDomain ("Test3");
+
+               domain.DoCallBack (new CrossAppDomainDelegate (Callback));
+
+               return 0;
+       }
+
+       public static void SyncCallback () {
+               AppDomain.Unload (AppDomain.CurrentDomain);
+       }               
+
+       public static int test_0_unload_inside_appdomain_sync () {
+               AppDomain domain = AppDomain.CreateDomain ("Test3");
+
+               try {
+                       domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
+               }
+               catch (Exception ex) {
+                       /* Should throw a ThreadAbortException */
+                       Thread.ResetAbort ();
+               }
+
+               return 0;
+       }
+
        // FIXME: This does not work yet, because the thread is finalized too
        // early
        /*
index 7a3987a56c5cf21d2a2ceda41d76406d102a9758..b411d390f8658485fbd28705d217b4639e54e19f 100644 (file)
@@ -23,6 +23,8 @@ class Test {
        delegate void SimpleDelegate ();
        delegate string NotSimpleDelegate (int a);
        delegate int AnotherDelegate (string s);
+
+       delegate string StringDelegate (); 
        
        public int data;
        
@@ -85,6 +87,12 @@ class Test {
                Console.WriteLine (d4.Method);
                Console.WriteLine (d4.Method.Name);
                Console.WriteLine (d4.Method.DeclaringType);
+
+               // Check unboxing of this argument
+               int x = 10;
+               StringDelegate d5 = new StringDelegate (x.ToString);
+               if (d5 () != "10")
+                       return 1;
                
                return 0;
 
index 0f4b3e8d88df4021709826005bc9537fc912a20c..95d343e5d9d8e4d7637a33420bc43664c0d720dc 100644 (file)
@@ -1,5 +1,5 @@
 /* -*- mode: c -*-
- * $Id: sieve.cs,v 1.2 2003/07/18 13:06:43 lupus Exp $
+ * $Id$
  * http://www.bagley.org/~doug/shootout/
  */
 
index a11eb6f3692cd93317df9f863c0e557b54bafb18..df54e44b83e0b820bc4f0cf0d866de93c9dae01c 100644 (file)
@@ -35,7 +35,9 @@ install: install-exec install-data
 
 # override automake
 install-exec:
-       d=`pwd`; cd $(mcs_topdir) && $(MAKE) RUNTIME=$$d/mono-wrapper prefix=$(exec_prefix) PROFILES='$(build_profiles)' install-profiles
+       d=`pwd`; \
+       cd $(mcs_topdir) && $(MAKE) prefix='$(exec_prefix)' PROFILES='$(build_profiles)' \
+                                   RUNTIME=$$d/mono-wrapper RUNTIME_HAS_CONSISTENT_GACDIR=yes install-profiles
 
 # override automake
 install-data:
@@ -52,13 +54,25 @@ else
 TEST_SUPPORT_FILES = $(tmpinst)/bin/mcs $(tmpinst)/bin/mbas $(tmpinst)/bin/ilasm
 endif
 
-check-local:
+if ENABLE_NUNIT_TESTS
+test_select =
+else
+test_select = TEST_SUBDIRS='tests errors'
+endif
+
+mcs-do-test-profiles:
+       d=`pwd`; cd $(mcs_topdir) && $(MAKE) RUNTIME=$$d/mono-wrapper PROFILES='$(build_profiles)' test-profiles
+
+mcs-do-run-test-profiles:
        $(mkinstalldirs) $(tmpinst)/bin
        $(MAKE) $(TEST_SUPPORT_FILES)
        d=`pwd`; PATH=$$d/$(tmpinst)/bin:$$PATH ; export PATH ; \
        ( cd $(mcs_topdir) && $(MAKE) RUNTIME=$$d/mono-wrapper PROFILES='$(build_profiles)' run-test-profiles ) || ret=false ; \
        rm -fr $(tmpinst) ; $$ret
 
+check-local: mcs-do-test-profiles
+       $(MAKE) $(test_select) mcs-do-run-test-profiles
+
 $(tmpinst)/bin/mcs:
        $(MAKE) test-support-file target=$@ file=class/lib/default/mcs.exe
 
index 9ca89285219ffbeec8384b4a448b2c52759ff8ea..f947faa33e73c902dedaccf810858b310eb4c06a 100644 (file)
@@ -178,8 +178,8 @@ benefits:
 
 This mechanism works very well for GNOME and other projects.
 
-Q: Should I use any of the special RCS keywords like $Id: devel-faq,v 1.1 2001/07/31 21:13:05 miguel Exp $, $Author: miguel $,
-   $Date: 2001/07/31 21:13:05 $, or $Revision: 1.1 $?
+Q: Should I use any of the special RCS keywords like $Id$, $Author$,
+   $Date$, or $Revision: 1.1 $?
 
 A: Please avoid using those in the source code in the CVS.  They
    are not really useful, and they cause a lot of conflicts when