diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog index 9dac79c7b64e2..77275fad6aa3c 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog @@ -1,3 +1,8 @@ +2010-09-29 Veerapuram Varadhan + + ** Fixes failed test for smallmoney + * Tds70.cs (WriteParameterInfo): Round money values to 4 decimals, for smallmoney too. + 2010-07-13 Veerapuram Varadhan ** Fixes #613845 diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs index 3bba914bf1538..08b29f6efccd0 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs @@ -645,7 +645,8 @@ private void WriteParameterInfo (TdsMetaParameter param) break; } case "smallmoney": { - Decimal val = (decimal) param.Value; + // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits + Decimal val = Decimal.Round ((decimal) param.Value, 4); if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) throw new OverflowException (string.Format ( CultureInfo.InvariantCulture, diff --git a/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollection.cs b/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollection.cs index b3cb6d442b343..d2ecc4ab520e4 100644 --- a/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollection.cs +++ b/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollection.cs @@ -39,9 +39,19 @@ public sealed class CommaDelimitedStringCollection : StringCollection { bool modified; bool readOnly; + int originalStringHash = 0; public bool IsModified { - get { return modified; } + get { + if (modified) + return true; + + string str = ToString (); + if (str == null) + return false; + + return str.GetHashCode () != originalStringHash; + } } public new bool IsReadOnly { @@ -89,6 +99,7 @@ public CommaDelimitedStringCollection Clone () CopyTo (contents, 0); col.AddRange (contents); + col.originalStringHash = originalStringHash; return col; } @@ -125,6 +136,15 @@ public override string ToString () return String.Join (",", contents); } + + internal void UpdateStringHash () + { + string str = ToString (); + if (str == null) + originalStringHash = 0; + else + originalStringHash = str.GetHashCode (); + } } } diff --git a/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollectionConverter.cs b/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollectionConverter.cs index 1ce8d3dc31e07..5959d1cd7af9f 100644 --- a/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollectionConverter.cs +++ b/mcs/class/System.Configuration/System.Configuration/CommaDelimitedStringCollectionConverter.cs @@ -48,6 +48,7 @@ public override object ConvertFrom (ITypeDescriptorContext ctx, CultureInfo ci, foreach (string datum in datums) col.Add (datum.Trim()); + col.UpdateStringHash (); return col; } diff --git a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog index 675a72a5c37cb..c43bf957255ea 100644 --- a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog +++ b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog @@ -1,3 +1,9 @@ +2010-10-01 Veerapuram Varadhan + + ** Fixes #561667 + * SqlCommand.cs (Dispose): While Disposing, set connection's datareader + to null so as the connection can be reused with another datareader. + 2010-07-28 Veerapuram Varadhan ** Fixes #584833 diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs index e9cf8c112fead..b0962359876ee 100644 --- a/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs +++ b/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs @@ -706,6 +706,8 @@ protected override void Dispose (bool disposing) if (disposed) return; if (disposing) { parameters.Clear(); + if (Connection != null) + Connection.DataReader = null; } base.Dispose (disposing); disposed = true; diff --git a/mcs/class/System.Data/System.Data/ChangeLog b/mcs/class/System.Data/System.Data/ChangeLog index df742a18a7645..6b08b529da9d6 100644 --- a/mcs/class/System.Data/System.Data/ChangeLog +++ b/mcs/class/System.Data/System.Data/ChangeLog @@ -1,3 +1,11 @@ +2010-10-01 Veerapuram Varadhan + + ** Fixes #582732 - Patch by Jeffrey Alvarez + * DataColumn.cs (Clone): Deep copy the ExtendedProperties collection. + * XmlSchemaDataImporter.cs: Support import of extended properties. + * XmlSchemaWriter.cs: Fix exception by writing the extended properties + before simpletype element. + 2010-07-23 Veerapuram Varadhan ** Fixes #623451 diff --git a/mcs/class/System.Data/System.Data/DataColumn.cs b/mcs/class/System.Data/System.Data/DataColumn.cs index f5d84c5622066..95667fcc8f5a5 100644 --- a/mcs/class/System.Data/System.Data/DataColumn.cs +++ b/mcs/class/System.Data/System.Data/DataColumn.cs @@ -704,6 +704,13 @@ internal DataColumn Clone () // Use the property to set the expression as it updates compiledExpression, if any. copy.Expression = _expression; //Copy.ExtendedProperties + if (_extendedProperties.Count > 0) { + Array extPropArray = Array.CreateInstance (typeof (object), _extendedProperties.Count); + _extendedProperties.CopyTo (extPropArray, 0); + for (var i = 0; i < _extendedProperties.Count; i++) + copy.ExtendedProperties.Add (extPropArray.GetValue(i), + ExtendedProperties[extPropArray.GetValue(i)]); + } copy._maxLength = _maxLength; copy._nameSpace = _nameSpace; copy._prefix = _prefix; @@ -715,7 +722,6 @@ internal DataColumn Clone () if (DataType == typeof (DateTime)) copy.DateTimeMode = _datetimeMode; #endif - copy._extendedProperties = _extendedProperties; return copy; } diff --git a/mcs/class/System.Data/System.Data/XmlSchemaDataImporter.cs b/mcs/class/System.Data/System.Data/XmlSchemaDataImporter.cs index d494474c77fe6..829cf13520937 100644 --- a/mcs/class/System.Data/System.Data/XmlSchemaDataImporter.cs +++ b/mcs/class/System.Data/System.Data/XmlSchemaDataImporter.cs @@ -535,6 +535,14 @@ private void ProcessDataSetElement (XmlSchemaElement el) attr.NamespaceURI == XmlConstants.MsdataNamespace) useCurrent = true; #endif + + if (attr.NamespaceURI == XmlConstants.MspropNamespace && + !dataset.ExtendedProperties.ContainsKey(attr.Name)) + { + dataset.ExtendedProperties.Add (attr.Name, attr.Value); + continue; + } + if (attr.LocalName == "Locale" && attr.NamespaceURI == XmlConstants.MsdataNamespace) { CultureInfo ci = new CultureInfo (attr.Value); @@ -593,6 +601,13 @@ private void ProcessDataTableElement (XmlSchemaElement el) // Find Locale if (el.UnhandledAttributes != null) { foreach (XmlAttribute attr in el.UnhandledAttributes) { + + if (attr.NamespaceURI == XmlConstants.MspropNamespace) + { + table.ExtendedProperties.Add (attr.Name, attr.Value); + continue; + } + if (attr.LocalName == "Locale" && attr.NamespaceURI == XmlConstants.MsdataNamespace) table.Locale = new CultureInfo (attr.Value); @@ -783,6 +798,12 @@ private void ImportColumnMetaInfo (XmlSchemaAnnotated obj, XmlQualifiedName name { if (obj.UnhandledAttributes != null) { foreach (XmlAttribute attr in obj.UnhandledAttributes) { + if (attr.NamespaceURI == XmlConstants.MspropNamespace) + { + col.ExtendedProperties.Add (attr.Name, attr.Value); + continue; + } + if (attr.NamespaceURI != XmlConstants.MsdataNamespace) continue; switch (attr.LocalName) { diff --git a/mcs/class/System.Data/System.Data/XmlSchemaWriter.cs b/mcs/class/System.Data/System.Data/XmlSchemaWriter.cs index 4a94e6ec86698..ae107ef00c7d5 100644 --- a/mcs/class/System.Data/System.Data/XmlSchemaWriter.cs +++ b/mcs/class/System.Data/System.Data/XmlSchemaWriter.cs @@ -734,12 +734,12 @@ private void WriteTableTypeParticles (DataColumn col) // XmlConstants.MsdataNamespace, // col.Ordinal.ToString ()); + AddExtendedPropertyAttributes (col.ExtendedProperties); + // Write SimpleType if column have MaxLength if (col.MaxLength > -1) WriteSimpleType (col); - AddExtendedPropertyAttributes (col.ExtendedProperties); - w.WriteEndElement (); // sequence } diff --git a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog index 579c7219b6832..8f8e700079046 100644 --- a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog +++ b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog @@ -1,3 +1,19 @@ +2010-10-01 Veerapuram Varadhan + + * SqlCommandTest.cs: Add test for bug#561667 + +2010-09-20 Veerapuram Varadhan + + * SqlDataReaderTest.cs: Add test for bug#613087 + +2010-09-16 Veerapuram Varadhan + + * SqlCommandTest.cs: Add test for bug#569543 + +2010-09-16 Veerapuram Varadhan + + * SqlCommandTest.cs: Add test for bug#584833 + 2010-04-21 Veerapuram Varadhan * SqlParameterTest.cs: Add test for bug#595918. diff --git a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlCommandTest.cs b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlCommandTest.cs index b779fe19b64cb..50ad553ebe93b 100644 --- a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlCommandTest.cs +++ b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlCommandTest.cs @@ -1014,6 +1014,17 @@ public void Prepare () Assert.IsNotNull (ex.Message, "#B4"); } + // Test Exception is not thrown if DbType is set - #569543 + try { + cmd.CommandText = "select type_guid from string_family where type_guid=@p1"; + cmd.Parameters.Clear (); + cmd.Parameters.Add ("@p1", SqlDbType.UniqueIdentifier); + cmd.Parameters ["@p1"].Value = new Guid ("1C47DD1D-891B-47E8-AAC8-F36608B31BC5"); + cmd.Prepare (); + } catch (Exception ex) { + Assert.Fail ("#B5 "+ex.Message); + } + // Test Exception is not thrown for Stored Procs cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "ABFSDSFSF"; @@ -2878,6 +2889,167 @@ public void bug326182_OutputParamMixupTest_RValFirst () Assert.AreEqual (100, param0Val); } + [Test] + public void DeriveParameterTest_FullSchema () + { + string create_tbl = "CREATE TABLE decimalCheck (deccheck DECIMAL (19, 5) null)"; + string create_sp = "CREATE PROCEDURE sp_bug584833(@deccheck decimal(19,5) OUT)" + + "AS " + Environment.NewLine + + "BEGIN" + Environment.NewLine + + "INSERT INTO decimalCheck values (@deccheck)" + Environment.NewLine + + "SELECT @deccheck=deccheck from decimalCheck" + Environment.NewLine + + "END"; + + try { + conn = (SqlConnection) ConnectionManager.Singleton.Connection; + ConnectionManager.Singleton.OpenConnection (); + + cmd = conn.CreateCommand (); + cmd.CommandText = create_tbl; + cmd.ExecuteNonQuery (); + + cmd.CommandText = create_sp; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "monotest.dbo.sp_bug584833"; + cmd.CommandType = CommandType.StoredProcedure; + + SqlCommandBuilder.DeriveParameters (cmd); + Assert.AreEqual (2, cmd.Parameters.Count, "#DPT - FullSchema - Parameter count mismatch"); + Assert.AreEqual ("@deccheck", cmd.Parameters[1].ParameterName, "#DPT - FullSchema - Parameter name mismatch"); + Assert.AreEqual (SqlDbType.Decimal, cmd.Parameters[1].SqlDbType, "#DPT - FullSchema - Parameter type mismatch"); + } finally { + cmd.Parameters.Clear (); + cmd.CommandText = "drop procedure sp_bug584833"; + cmd.CommandType = CommandType.Text; + cmd.ExecuteNonQuery (); + cmd.CommandText = "drop table decimalCheck"; + cmd.ExecuteNonQuery (); + cmd.Dispose (); + cmd = null; + ConnectionManager.Singleton.CloseConnection (); + conn = null; + } + + } + + [Test] + public void DeriveParameterTest_SPName () + { + string create_tbl = "CREATE TABLE decimalCheck (deccheck DECIMAL (19, 5) null)"; + string create_sp = "CREATE PROCEDURE sp_bug584833(@deccheck decimal(19,5) OUT)" + + "AS " + Environment.NewLine + + "BEGIN" + Environment.NewLine + + "INSERT INTO decimalCheck values (@deccheck)" + Environment.NewLine + + "SELECT @deccheck=deccheck from decimalCheck" + Environment.NewLine + + "END"; + + try { + conn = (SqlConnection) ConnectionManager.Singleton.Connection; + ConnectionManager.Singleton.OpenConnection (); + + cmd = conn.CreateCommand (); + cmd.CommandText = create_tbl; + cmd.ExecuteNonQuery (); + + cmd.CommandText = create_sp; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "sp_bug584833"; + cmd.CommandType = CommandType.StoredProcedure; + + SqlCommandBuilder.DeriveParameters (cmd); + Assert.AreEqual (2, cmd.Parameters.Count, "#DPT - SPName - Parameter count mismatch"); + Assert.AreEqual ("@deccheck", cmd.Parameters[1].ParameterName, "#DPT - SPName - Parameter name mismatch"); + Assert.AreEqual (SqlDbType.Decimal, cmd.Parameters[1].SqlDbType, "#DPT - SPName - Parameter type mismatch"); + } finally { + cmd.Parameters.Clear (); + cmd.CommandType = CommandType.Text; + cmd.CommandText = "drop procedure sp_bug584833"; + cmd.ExecuteNonQuery (); + cmd.CommandText = "drop table decimalCheck"; + cmd.ExecuteNonQuery (); + cmd.Dispose (); + cmd = null; + ConnectionManager.Singleton.CloseConnection (); + conn = null; + } + } + + [Test] + public void DeriveParameterTest_UserSchema () + { + string create_tbl = "CREATE TABLE decimalCheck (deccheck DECIMAL (19, 5) null)"; + string create_sp = "CREATE PROCEDURE sp_bug584833(@deccheck decimal(19,5) OUT)" + + "AS " + Environment.NewLine + + "BEGIN" + Environment.NewLine + + "INSERT INTO decimalCheck values (@deccheck)" + Environment.NewLine + + "SELECT @deccheck=deccheck from decimalCheck" + Environment.NewLine + + "END"; + + try { + conn = (SqlConnection) ConnectionManager.Singleton.Connection; + ConnectionManager.Singleton.OpenConnection (); + + cmd = conn.CreateCommand (); + cmd.CommandText = create_tbl; + cmd.ExecuteNonQuery (); + + cmd.CommandText = create_sp; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "dbo.sp_bug584833"; + cmd.CommandType = CommandType.StoredProcedure; + + SqlCommandBuilder.DeriveParameters (cmd); + Assert.AreEqual (2, cmd.Parameters.Count, "#DPT - user schema - Parameter count mismatch"); + Assert.AreEqual ("@deccheck", cmd.Parameters[1].ParameterName, "#DPT - user schema - Parameter name mismatch"); + Assert.AreEqual (SqlDbType.Decimal, cmd.Parameters[1].SqlDbType, "#DPT - user schema - Parameter type mismatch"); + } finally { + cmd.Parameters.Clear (); + cmd.CommandType = CommandType.Text; + cmd.CommandText = "drop procedure dbo.sp_bug584833"; + cmd.ExecuteNonQuery (); + cmd.CommandText = "drop table decimalCheck"; + cmd.ExecuteNonQuery (); + cmd.Dispose (); + cmd = null; + ConnectionManager.Singleton.CloseConnection (); + conn = null; + } + } + + [Test] // bug#561667 + public void CmdDispose_DataReaderReset () + { + try { + conn = (SqlConnection) ConnectionManager.Singleton.Connection; + ConnectionManager.Singleton.OpenConnection (); + string query1 = "SELECT fname FROM employee where lname='kumar'"; + string query2 = "SELECT type_int FROM numeric_family where type_bit = 1"; + DataTable t = null; + + t = GetColumns(conn, query1); + Assert.AreEqual ("suresh", t.Rows[0][0], "CmdDD#1: Query1 result mismatch"); + t = GetColumns(conn, query2); + Assert.AreEqual (int.MaxValue, t.Rows[0][0], "CmdDD#2: Query2 result mismatch"); + } finally { + ConnectionManager.Singleton.CloseConnection (); + conn = null; + } + } + + private DataTable GetColumns(DbConnection connection, string query) + { + DataTable t = new DataTable("Columns"); + using (DbCommand c = connection.CreateCommand()) + { + c.CommandText = query; + t.Load(c.ExecuteReader()); + } + return t; + } + // used as workaround for bugs in NUnit 2.2.0 static void AreEqual (object x, object y, string msg) { diff --git a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlDataReaderTest.cs b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlDataReaderTest.cs index 5020da2fb7f21..9163be1ae8675 100644 --- a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlDataReaderTest.cs +++ b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlDataReaderTest.cs @@ -397,6 +397,82 @@ public void GetDecimalTest () reader.Close (); } + //#613087, #620860 Test + [Test] + public void GetDecimalOfInt64Test_Max () + { + string crTable = "CREATE TABLE #613087 (decimalint64 decimal(20,0))"; + //string drTable = "drop table #613087"; + + cmd.CommandText = crTable; + cmd.CommandType = CommandType.Text; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "INSERT INTO #613087 VALUES (@decimalint64)"; + SqlParameter param = new SqlParameter (); + param.ParameterName = "@decimalint64"; + param.Value = new SqlDecimal ((long)Int64.MaxValue); + cmd.Parameters.Add (param); + cmd.ExecuteNonQuery (); + + cmd.Parameters.Clear (); + cmd.CommandText = "Select * from #613087"; + reader = cmd.ExecuteReader(); + reader.Read (); + Assert.AreEqual (param.Value, reader.GetSqlDecimal (0), "SqlDecimalFromInt64_Max Test failed"); + } + + //#613087, #620860 Test + [Test] + public void GetDecimalOfInt64Test_Min () + { + string crTable = "CREATE TABLE #613087 (decimalint64 decimal(20,0))"; + //string drTable = "drop table #613087"; + + cmd.CommandText = crTable; + cmd.CommandType = CommandType.Text; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "INSERT INTO #613087 VALUES (@decimalint64)"; + SqlParameter param = new SqlParameter (); + param.ParameterName = "@decimalint64"; + param.Value = new SqlDecimal ((long)Int64.MinValue); + cmd.Parameters.Add (param); + cmd.ExecuteNonQuery (); + + cmd.Parameters.Clear (); + cmd.CommandText = "Select * from #613087"; + reader = cmd.ExecuteReader(); + reader.Read (); + Assert.AreEqual (param.Value, reader.GetSqlDecimal (0), "SqlDecimalFromInt64_Min Test failed"); + } + + //#613087, #620860 Test + [Test] + public void GetDecimalOfInt64Test_Any () + { + string crTable = "CREATE TABLE #613087 (decimalint64 decimal(20,0))"; + //string drTable = "drop table #613087"; + + cmd.CommandText = crTable; + cmd.CommandType = CommandType.Text; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "INSERT INTO #613087 VALUES (@decimalint64)"; + SqlParameter param = new SqlParameter (); + param.ParameterName = "@decimalint64"; + param.DbType = DbType.Decimal; + param.Value = ulong.MaxValue; + cmd.Parameters.Add (param); + cmd.ExecuteNonQuery (); + + cmd.Parameters.Clear (); + cmd.CommandText = "Select * from #613087"; + reader = cmd.ExecuteReader(); + reader.Read (); + Assert.AreEqual (param.Value, (ulong)reader.GetSqlDecimal (0).Value, "SqlDecimalFromInt64_Any Test failed"); + } + [Test] public void GetSqlMoneyTest () { diff --git a/mcs/class/System.Data/Test/System.Data/ChangeLog b/mcs/class/System.Data/Test/System.Data/ChangeLog index 8efa86e57ac94..da23a8fe8311e 100644 --- a/mcs/class/System.Data/Test/System.Data/ChangeLog +++ b/mcs/class/System.Data/Test/System.Data/ChangeLog @@ -1,3 +1,7 @@ +2010-10-01 Veerapuram Varadhan + + * DataSetReadXmlTest.cs: Added new test for #582732. + 2010-07-23 Veerapuram Varadhan * DataColumnTest.cs (B623451_SetOrdinalTest): Added new. diff --git a/mcs/class/System.Data/Test/System.Data/DataSetReadXmlTest.cs b/mcs/class/System.Data/Test/System.Data/DataSetReadXmlTest.cs index dd050fcf86505..6a63a23207ea7 100644 --- a/mcs/class/System.Data/Test/System.Data/DataSetReadXmlTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DataSetReadXmlTest.cs @@ -784,5 +784,45 @@ public void TestSameColumnName () XmlReadMode.Auto, XmlReadMode.IgnoreSchema, "NewDataSet", 1); } + + [Test] + public void DataSetExtendedPropertiesTest() + { + DataSet dataSet1 = new DataSet(); + dataSet1.ExtendedProperties.Add("DS1", "extended0"); + DataTable table = new DataTable("TABLE1"); + table.ExtendedProperties.Add("T1", "extended1"); + table.Columns.Add("C1", typeof(int)); + table.Columns[0].MaxLength = 10; + table.Columns.Add("C2", typeof(string)); + table.Columns[0].MaxLength = 20; + table.Columns[0].ExtendedProperties.Add("C1Ext1", "extended2"); + table.Columns[1].ExtendedProperties.Add("C2Ext1", "extended3"); + dataSet1.Tables.Add(table); + table.LoadDataRow(new object[]{1, "One"}, false); + table.LoadDataRow(new object[]{2, "Two"}, false); + try { + dataSet1.WriteXml("Test/System.Data/schemas/test.xml", XmlWriteMode.WriteSchema); + } + catch (Exception ex) { + Assert.Fail ("DSExtPropTest failed: WriteXml failed with : "+ex.Message); + } finally { + File.Delete ("Test/System.Data/schemas/test.xml"); + } + + DataSet dataSet2 = new DataSet(); + dataSet2.ReadXml("Test/System.Data/schemas/b582732.xml", XmlReadMode.ReadSchema); + Assert.AreEqual (dataSet1.ExtendedProperties["DS1"], dataSet2.ExtendedProperties["DS1"], + "DSExtProp#1: DS extended properties mismatch"); + + Assert.AreEqual (dataSet1.Tables[0].ExtendedProperties["T1"], dataSet2.Tables[0].ExtendedProperties["T1"], + "DSExtProp#2: DS Table extended properties mismatch"); + Assert.AreEqual (dataSet1.Tables[0].Columns[0].ExtendedProperties["C1Ext1"], + dataSet2.Tables[0].Columns[0].ExtendedProperties["C1Ext1"], + "DSExtProp#3: DS Table Column 1 extended properties mismatch"); + Assert.AreEqual (dataSet1.Tables[0].Columns[1].ExtendedProperties["C2Ext1"], + dataSet2.Tables[0].Columns[1].ExtendedProperties["C2Ext1"], + "DSExtProp#4: DS Table Column 2 extended properties mismatch"); + } } } diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractResolver.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractResolver.cs index eac98ed4eb204..60a3e66ba28aa 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractResolver.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractResolver.cs @@ -33,7 +33,6 @@ namespace System.Runtime.Serialization { // See http://msdn.microsoft.com/en-us/library/ee358759.aspx #if NET_4_0 - [MonoTODO ("not in use yet")] public #else internal @@ -44,4 +43,40 @@ abstract class DataContractResolver public abstract bool TryResolveType (Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace); } + + internal class DefaultDataContractResolver : DataContractResolver + { + public DefaultDataContractResolver (DataContractSerializer serializer) + { + this.serializer = serializer; + } + + DataContractSerializer serializer; + XmlDictionary dictionary; + + public override Type ResolveName (string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver) + { + var map = serializer.InternalKnownTypes.FindUserMap (new XmlQualifiedName (typeName, typeNamespace)); + if (map == null) + serializer.InternalKnownTypes.Add (declaredType); + if (map != null) + return map.RuntimeType; + return null; + } + + public override bool TryResolveType (Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace) + { + var map = serializer.InternalKnownTypes.FindUserMap (type); + if (map == null) { + typeName = null; + typeNamespace = null; + return false; + } else { + dictionary = dictionary ?? new XmlDictionary (); + typeName = dictionary.Add (map.XmlName.Name); + typeNamespace = dictionary.Add (map.XmlName.Namespace); + return true; + } + } + } } diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs index 6693daa0e7260..d44a4162a06e5 100755 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs @@ -52,6 +52,7 @@ public sealed class DataContractSerializer : XmlObjectSerializer ReadOnlyCollection returned_known_types; KnownTypeCollection known_types; IDataContractSurrogate surrogate; + DataContractResolver resolver, default_resolver; int max_items = 0x10000; // FIXME: could be from config. @@ -70,9 +71,8 @@ public DataContractSerializer (Type type) if (type == null) throw new ArgumentNullException ("type"); this.type = type; - known_types = new KnownTypeCollection (); PopulateTypes (knownTypes); - known_types.TryRegister (type); + known_types.Add (type); QName qname = known_types.GetQName (type); FillDictionaryString (qname.Name, qname.Namespace); @@ -220,7 +220,7 @@ void PopulateTypes (IEnumerable knownTypes) if (knownTypes != null) { foreach (Type t in knownTypes) - known_types.TryRegister (t); + known_types.Add (t); } Type elementType = type; @@ -231,7 +231,7 @@ void PopulateTypes (IEnumerable knownTypes) object [] attrs = elementType.GetCustomAttributes (typeof (KnownTypeAttribute), true); for (int i = 0; i < attrs.Length; i ++) { KnownTypeAttribute kt = (KnownTypeAttribute) attrs [i]; - known_types.TryRegister (kt.Type); + known_types.Add (kt.Type); } } @@ -255,8 +255,6 @@ void FillDictionaryString (string name, string ns) ignore_ext = ignoreExtensionDataObject; preserve_refs = preserveObjectReferences; surrogate = dataContractSurrogate; - - PopulateTypes (Type.EmptyTypes); } #if NET_4_0 @@ -264,7 +262,13 @@ void FillDictionaryString (string name, string ns) #else internal #endif - DataContractResolver DataContractResolver { get; private set; } + DataContractResolver DataContractResolver { + get { return resolver; } + private set { + resolver = value; + default_resolver = default_resolver ?? new DefaultDataContractResolver (this); + } + } public bool IgnoreExtensionDataObject { get { return ignore_ext; } @@ -278,6 +282,10 @@ void FillDictionaryString (string name, string ns) } } + internal KnownTypeCollection InternalKnownTypes { + get { return known_types; } + } + public IDataContractSurrogate DataContractSurrogate { get { return surrogate; } } @@ -323,7 +331,7 @@ public override object ReadObject (XmlDictionaryReader reader, bool verifyObject bool isEmpty = reader.IsEmptyElement; object ret = XmlFormatterDeserializer.Deserialize (reader, type, - known_types, surrogate, DataContractResolver, root_name.Value, root_ns.Value, verifyObjectName); + known_types, surrogate, DataContractResolver, default_resolver, root_name.Value, root_ns.Value, verifyObjectName); // remove temporarily-added known types for // rootType and object graph type. @@ -399,8 +407,8 @@ public override void WriteObjectContent (XmlDictionaryWriter writer, object grap int startTypeCount = known_types.Count; XmlFormatterSerializer.Serialize (writer, graph, - known_types, - ignore_ext, max_items, root_ns.Value, preserve_refs); + type, known_types, + ignore_ext, max_items, root_ns.Value, preserve_refs, DataContractResolver, default_resolver); // remove temporarily-added known types for // rootType and object graph type. @@ -440,8 +448,21 @@ public override void WriteObjectContent (XmlWriter writer, object graph) return; } - QName instName = null; - QName root_qname = known_types.GetQName (rootType); + QName rootQName = null; + XmlDictionaryString name, ns; + if (DataContractResolver != null && DataContractResolver.TryResolveType (graph.GetType (), type, default_resolver, out name, out ns)) + rootQName = new QName (name.Value, ns.Value); + + // It is error unless 1) TypeResolver resolved the type name, 2) the object is the exact type, 3) the object is known or 4) the type is primitive. + + if (rootQName == null && + graph.GetType () != type && + !known_types.Contains (graph.GetType ()) && + KnownTypeCollection.GetPrimitiveTypeName (graph.GetType ()) == QName.Empty) + throw new SerializationException (String.Format ("Type '{0}' is unexpected. The type should either be registered as a known type, or DataContractResolver should be used.", graph.GetType ())); + + QName instName = rootQName; + rootQName = rootQName ?? known_types.GetQName (rootType); QName graph_qname = known_types.GetQName (graph.GetType ()); known_types.Add (graph.GetType ()); @@ -450,24 +471,23 @@ public override void WriteObjectContent (XmlWriter writer, object graph) writer.WriteStartElement (root_name.Value, root_ns.Value); else writer.WriteStartElement (root_name, root_ns); - if (root_ns.Value != root_qname.Namespace) - if (root_qname.Namespace != KnownTypeCollection.MSSimpleNamespace) - writer.WriteXmlnsAttribute (null, root_qname.Namespace); - if (root_qname == graph_qname) { - if (root_qname.Namespace != KnownTypeCollection.MSSimpleNamespace && - !rootType.IsEnum) - //FIXME: Hack, when should the "i:type" be written? - //Not used in case of enums - writer.WriteXmlnsAttribute ("i", XmlSchema.InstanceNamespace); + if (rootQName != graph_qname || rootQName.Namespace != KnownTypeCollection.MSSimpleNamespace && !rootType.IsEnum) + //FIXME: Hack, when should the "i:type" be written? + //Not used in case of enums + writer.WriteXmlnsAttribute ("i", XmlSchema.InstanceNamespace); + if (root_ns.Value != rootQName.Namespace) + if (rootQName.Namespace != KnownTypeCollection.MSSimpleNamespace) + writer.WriteXmlnsAttribute (null, rootQName.Namespace); + + if (rootQName == graph_qname) return; - } /* Different names */ known_types.Add (rootType); - instName = KnownTypeCollection.GetPredefinedTypeName (graph.GetType ()); + instName = instName ?? KnownTypeCollection.GetPredefinedTypeName (graph.GetType ()); if (instName == QName.Empty) /* Not a primitive type */ instName = graph_qname; @@ -475,10 +495,12 @@ public override void WriteObjectContent (XmlWriter writer, object graph) /* FIXME: Hack, .. see test WriteObject7 () */ instName = new QName (instName.Name, XmlSchema.Namespace); +/* // disabled as it now generates extraneous i:type output. // output xsi:type as rootType is not equivalent to the graph's type. writer.WriteStartAttribute ("i", "type", XmlSchema.InstanceNamespace); writer.WriteQualifiedName (instName.Name, instName.Namespace); writer.WriteEndAttribute (); +*/ } public override void WriteEndObject (XmlDictionaryWriter writer) diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs index 20b4297ed6f75..4b9e0e379ebfc 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs @@ -451,7 +451,7 @@ List GetMembers (Type type, QName qname, bool declared_only) GetDataMemberAttribute (pi); if (dma == null) continue; - KnownTypes.TryRegister (pi.PropertyType); + KnownTypes.Add (pi.PropertyType); var map = KnownTypes.FindUserMap (pi.PropertyType); if (!pi.CanRead || (!pi.CanWrite && !(map is ICollectionTypeMap))) throw new InvalidDataContractException (String.Format ( diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterDeserializer.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterDeserializer.cs index 3491c2f0ef78a..945ac651961d2 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterDeserializer.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterDeserializer.cs @@ -43,15 +43,15 @@ internal class XmlFormatterDeserializer { KnownTypeCollection types; IDataContractSurrogate surrogate; - DataContractResolver resolver; // new in 4.0. + DataContractResolver resolver, default_resolver; // new in 4.0. // 3.5 SP1 supports deserialization by reference (id->obj). // Though unlike XmlSerializer, it does not support forward- // reference resolution i.e. a referenced object must appear // before any references to it. Hashtable references = new Hashtable (); - public static object Deserialize (XmlReader reader, Type type, - KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, DataContractResolver resolver, + public static object Deserialize (XmlReader reader, Type declaredType, + KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, DataContractResolver resolver, DataContractResolver defaultResolver, string name, string ns, bool verifyObjectName) { reader.MoveToContent (); @@ -60,14 +60,14 @@ internal class XmlFormatterDeserializer reader.LocalName != name || reader.NamespaceURI != ns) throw new SerializationException (String.Format ("Expected element '{0}' in namespace '{1}', but found {2} node '{3}' in namespace '{4}'", name, ns, reader.NodeType, reader.LocalName, reader.NamespaceURI)); -// Verify (knownTypes, type, name, ns, reader); - return new XmlFormatterDeserializer (knownTypes, surrogate, resolver).Deserialize (type, reader); +// Verify (knownTypes, declaredType, name, ns, reader); + return new XmlFormatterDeserializer (knownTypes, surrogate, resolver, defaultResolver).Deserialize (declaredType, reader); } // Verify the top element name and namespace. private static void Verify (KnownTypeCollection knownTypes, Type type, string name, string Namespace, XmlReader reader) { - QName graph_qname = new QName (reader.Name, reader.NamespaceURI); + QName graph_qname = new QName (reader.LocalName, reader.NamespaceURI); if (graph_qname.Name == name && graph_qname.Namespace == Namespace) return; @@ -90,11 +90,13 @@ private static void Verify (KnownTypeCollection knownTypes, Type type, string na private XmlFormatterDeserializer ( KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, - DataContractResolver resolver) + DataContractResolver resolver, + DataContractResolver defaultResolver) { this.types = knownTypes; this.surrogate = surrogate; this.resolver = resolver; + this.default_resolver = defaultResolver; } public Hashtable References { @@ -135,6 +137,9 @@ public object Deserialize (Type type, XmlReader reader) throw new SerializationException (String.Format ("Value type {0} cannot be null.", type)); } + if (resolver != null) + type = resolver.ResolveName (graph_qname.Name, graph_qname.Namespace, type, default_resolver) ?? type; + if (KnownTypeCollection.GetPrimitiveTypeFromName (graph_qname.Name) != null) { string id = reader.GetAttribute ("Id", KnownTypeCollection.MSSimpleNamespace); @@ -168,7 +173,7 @@ object DeserializeByMap (QName name, Type type, XmlReader reader) name.Namespace == KnownTypeCollection.MSArraysNamespace || name.Namespace.StartsWith (KnownTypeCollection.DefaultClrNamespaceBase, StringComparison.Ordinal))) { var it = GetTypeFromNamePair (name.Name, name.Namespace); - types.TryRegister (it); + types.Add (it); map = types.FindUserMap (name); } if (map == null) diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterSerializer.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterSerializer.cs index d137ed8374cb0..cd37388452e3f 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterSerializer.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XmlFormatterSerializer.cs @@ -47,28 +47,30 @@ internal class XmlFormatterSerializer bool save_id; bool ignore_unknown; IDataContractSurrogate surrogate; + DataContractResolver resolver, default_resolver; // new in 4.0 int max_items; ArrayList objects = new ArrayList (); Hashtable references = new Hashtable (); // preserve possibly referenced objects to ids. (new in 3.5 SP1) - public static void Serialize (XmlDictionaryWriter writer, object graph, - KnownTypeCollection types, - bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences) + public static void Serialize (XmlDictionaryWriter writer, object graph, Type declaredType, KnownTypeCollection types, + bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences, DataContractResolver resolver, DataContractResolver defaultResolver) { - new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns, preserveObjectReferences) - .Serialize (graph != null ? graph.GetType () : null, graph); + new XmlFormatterSerializer (writer, types, ignoreUnknown, maxItems, root_ns, preserveObjectReferences, resolver, defaultResolver) + .Serialize (/*graph != null ? graph.GetType () : */declaredType, graph); // FIXME: I believe it should always use declaredType, but such a change brings some test breakages. } - public XmlFormatterSerializer (XmlDictionaryWriter writer, - KnownTypeCollection types, - bool ignoreUnknown, int maxItems, string root_ns, bool preserveObjectReferences) + public XmlFormatterSerializer (XmlDictionaryWriter writer, KnownTypeCollection types, bool ignoreUnknown, + int maxItems, string root_ns, bool preserveObjectReferences, + DataContractResolver resolver, DataContractResolver defaultResolver) { this.writer = writer; this.types = types; ignore_unknown = ignoreUnknown; max_items = maxItems; PreserveObjectReferences = preserveObjectReferences; + this.resolver = resolver; + this.default_resolver = defaultResolver; } public bool PreserveObjectReferences { get; private set; } @@ -90,9 +92,17 @@ public void Serialize (Type type, object graph) if (graph == null) writer.WriteAttributeString ("nil", XmlSchema.InstanceNamespace, "true"); else { + QName resolvedQName = null; + if (resolver != null) { + XmlDictionaryString rname, rns; + if (resolver.TryResolveType (graph != null ? graph.GetType () : typeof (object), type, default_resolver, out rname, out rns)) + resolvedQName = new QName (rname.Value, rns.Value); + } + Type actualType = graph.GetType (); - SerializationMap map = types.FindUserMap (actualType); + SerializationMap map; + map = types.FindUserMap (actualType); // For some collection types, the actual type does not matter. So get nominal serialization type instead. // (The code below also covers the lines above, but I don't remove above lines to avoid extra search cost.) if (map == null) { @@ -106,7 +116,7 @@ public void Serialize (Type type, object graph) } if (actualType != type && (map == null || map.OutputXsiType)) { - QName qname = types.GetXmlName (actualType); + QName qname = resolvedQName ?? types.GetXmlName (actualType); string name = qname.Name; string ns = qname.Namespace; if (qname == QName.Empty) { @@ -116,7 +126,7 @@ public void Serialize (Type type, object graph) ns = XmlSchema.Namespace; if (writer.LookupPrefix (ns) == null) // it goes first (extraneous, but it makes att order compatible) writer.WriteXmlnsAttribute (null, ns); - writer.WriteStartAttribute ("type", XmlSchema.InstanceNamespace); + writer.WriteStartAttribute ("i", "type", XmlSchema.InstanceNamespace); writer.WriteQualifiedName (name, ns); writer.WriteEndAttribute (); } diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter.cs index 27bde112d6423..d752a4afb51e9 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter.cs @@ -172,7 +172,7 @@ public bool CanExport (Type type) if (predefined_types.FirstOrDefault (i => i.ClrType == type) != null) return true; - known_types.TryRegister (type); + known_types.Add (type); return known_types.FindUserMap (type) != null; } @@ -219,7 +219,7 @@ bool ExportCore (Type type, bool rejectNonContract) if (imported_types.FirstOrDefault (i => i.ClrType == type) != null) return false; - known_types.TryRegister (type); + known_types.Add (type); var map = known_types.FindUserMap (type); if (map == null) return false; diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources index 9a705b859d23d..31881839db532 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization_test.dll.sources @@ -1,3 +1,4 @@ +System.Runtime.Serialization/DataContractResolverTest.cs System.Runtime.Serialization/XmlObjectSerializerTest.cs System.Runtime.Serialization/XsdDataContractExporterTest.cs System.Runtime.Serialization/XsdDataContractImporterTest.cs diff --git a/mcs/class/System.Runtime.Serialization/System.Xml/XmlDictionaryWriter.cs b/mcs/class/System.Runtime.Serialization/System.Xml/XmlDictionaryWriter.cs index d73ccffcaa672..eb126942fab73 100644 --- a/mcs/class/System.Runtime.Serialization/System.Xml/XmlDictionaryWriter.cs +++ b/mcs/class/System.Runtime.Serialization/System.Xml/XmlDictionaryWriter.cs @@ -36,16 +36,13 @@ public abstract partial class XmlDictionaryWriter : XmlWriter { static readonly Encoding utf8_unmarked = new UTF8Encoding (false); - int depth; - protected XmlDictionaryWriter () { } - internal int Depth { - get { return depth; } - set { depth = value; } - } + internal int Depth { get; set; } + + internal int NSIndex { get; set; } public virtual bool CanCanonicalize { get { return false; } @@ -138,6 +135,8 @@ public static XmlDictionaryWriter CreateDictionaryWriter (XmlWriter writer) return CreateDictionaryWriter (XmlWriter.Create (stream, s)); } + + public virtual void EndCanonicalization () { throw new NotSupportedException (); @@ -388,8 +387,10 @@ public virtual void WriteXmlAttribute (string localName, string value) // writer how it is determined in the output. (When // there is a duplicate, then it will be further // modified.) - if (prefix == null) - prefix = "d" + Depth + "p1"; + if (prefix == null && String.IsNullOrEmpty (namespaceUri)) + prefix = String.Empty; + else if (prefix == null) + prefix = "d" + Depth + "p" + (++NSIndex); if (prefix == String.Empty) WriteAttributeString ("xmlns", namespaceUri); diff --git a/mcs/class/System.Runtime.Serialization/System.Xml/XmlSimpleDictionaryWriter.cs b/mcs/class/System.Runtime.Serialization/System.Xml/XmlSimpleDictionaryWriter.cs index 9eb5d3aa06b7c..2afb6bc9cbb02 100644 --- a/mcs/class/System.Runtime.Serialization/System.Xml/XmlSimpleDictionaryWriter.cs +++ b/mcs/class/System.Runtime.Serialization/System.Xml/XmlSimpleDictionaryWriter.cs @@ -105,6 +105,7 @@ public override void WriteEndDocument () public override void WriteEndElement () { Depth--; + NSIndex = 0; writer.WriteEndElement (); } @@ -171,6 +172,7 @@ public override void WriteStartDocument () public override void WriteStartElement (string prefix, string localName, string ns) { Depth++; + NSIndex = 0; writer.WriteStartElement (prefix, localName, ns); } diff --git a/mcs/class/System.Transactions/Makefile b/mcs/class/System.Transactions/Makefile index 6b640bf404060..12f3b7f900e4d 100644 --- a/mcs/class/System.Transactions/Makefile +++ b/mcs/class/System.Transactions/Makefile @@ -2,8 +2,18 @@ thisdir = class/System.Transactions SUBDIRS = include ../../build/rules.make +MOBILE_PROFILE := $(filter monotouch monodroid, $(PROFILE)) + LIBRARY = System.Transactions.dll +<<<<<<< HEAD LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll /r:System.Configuration.dll +======= +ifdef MOBILE_PROFILE +LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll +else +LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll /r:System.Configuration.dll /define:MOBILE +endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be TEST_MCS_FLAGS = /nowarn:1595 $(LIB_MCS_FLAGS) diff --git a/mcs/class/System.Transactions/System.Transactions/Configuration/DefaultSettingsSection.cs b/mcs/class/System.Transactions/System.Transactions/Configuration/DefaultSettingsSection.cs index 2992a730c47aa..21414552ecd8c 100644 --- a/mcs/class/System.Transactions/System.Transactions/Configuration/DefaultSettingsSection.cs +++ b/mcs/class/System.Transactions/System.Transactions/Configuration/DefaultSettingsSection.cs @@ -1,3 +1,4 @@ +<<<<<<< HEAD // // DefaultSettingsSection.cs // @@ -8,6 +9,18 @@ // #if NET_2_0 +======= +// +// DefaultSettingsSection.cs +// +// Author: +// Pablo Ruiz +// +// (C) 2010 Pablo Ruiz. +// + +#if NET_2_0 && !MOBILE +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be using System; using System.Collections.Generic; @@ -37,4 +50,8 @@ public class DefaultSettingsSection : ConfigurationSection } } } -#endif \ No newline at end of file +<<<<<<< HEAD +#endif +======= +#endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be diff --git a/mcs/class/System.Transactions/System.Transactions/Configuration/MachineSettingsSection.cs b/mcs/class/System.Transactions/System.Transactions/Configuration/MachineSettingsSection.cs index 5de518665fa45..079ecc6ffa2b8 100644 --- a/mcs/class/System.Transactions/System.Transactions/Configuration/MachineSettingsSection.cs +++ b/mcs/class/System.Transactions/System.Transactions/Configuration/MachineSettingsSection.cs @@ -1,3 +1,4 @@ +<<<<<<< HEAD // // MachineSettingsSection.cs // @@ -8,6 +9,18 @@ // #if NET_2_0 +======= +// +// MachineSettingsSection.cs +// +// Author: +// Pablo Ruiz +// +// (C) 2010 Pablo Ruiz. +// + +#if NET_2_0 && !MOBILE +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be using System; using System.Collections.Generic; @@ -30,4 +43,8 @@ public class MachineSettingsSection : ConfigurationSection } } } -#endif \ No newline at end of file +<<<<<<< HEAD +#endif +======= +#endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be diff --git a/mcs/class/System.Transactions/System.Transactions/Configuration/TransactionsSectionGroup.cs b/mcs/class/System.Transactions/System.Transactions/Configuration/TransactionsSectionGroup.cs index a43d9a99313fc..3d04e9391a898 100644 --- a/mcs/class/System.Transactions/System.Transactions/Configuration/TransactionsSectionGroup.cs +++ b/mcs/class/System.Transactions/System.Transactions/Configuration/TransactionsSectionGroup.cs @@ -1,3 +1,4 @@ +<<<<<<< HEAD // // TransactionSectionGroup.cs // @@ -8,6 +9,18 @@ // #if NET_2_0 +======= +// +// TransactionSectionGroup.cs +// +// Author: +// Pablo Ruiz +// +// (C) 2010 Pablo Ruiz. +// + +#if NET_2_0 && !MOBILE +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be using System; using System.Collections.Generic; @@ -40,4 +53,8 @@ public MachineSettingsSection MachineSettings } } } -#endif \ No newline at end of file +<<<<<<< HEAD +#endif +======= +#endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be diff --git a/mcs/class/System.Transactions/System.Transactions/PreparingEnlistment.cs b/mcs/class/System.Transactions/System.Transactions/PreparingEnlistment.cs index 031d840430aa1..5892911a02e68 100644 --- a/mcs/class/System.Transactions/System.Transactions/PreparingEnlistment.cs +++ b/mcs/class/System.Transactions/System.Transactions/PreparingEnlistment.cs @@ -62,11 +62,19 @@ public void Prepared () internal WaitHandle WaitHandle { get { return waitHandle; } +<<<<<<< HEAD } internal IEnlistmentNotification EnlistmentNotification { get { return enlisted; } +======= + } + + internal IEnlistmentNotification EnlistmentNotification + { + get { return enlisted; } +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } } } diff --git a/mcs/class/System.Transactions/System.Transactions/Transaction.cs b/mcs/class/System.Transactions/System.Transactions/Transaction.cs index b4d8b12b38313..9a5ad711903b6 100644 --- a/mcs/class/System.Transactions/System.Transactions/Transaction.cs +++ b/mcs/class/System.Transactions/System.Transactions/Transaction.cs @@ -232,11 +232,19 @@ public void Rollback (Exception ex) } internal void Rollback (Exception ex, IEnlistmentNotification enlisted) +<<<<<<< HEAD { if (aborted) { FireCompleted (); return; +======= + { + if (aborted) + { + FireCompleted (); + return; +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } /* See test ExplicitTransaction7 */ @@ -252,8 +260,13 @@ internal void Rollback (Exception ex, IEnlistmentNotification enlisted) if (durables.Count > 0 && durables [0] != enlisted) durables [0].Rollback (e); +<<<<<<< HEAD Aborted = true; +======= + Aborted = true; + +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be FireCompleted (); } @@ -297,6 +310,7 @@ internal void CommitInternal () try { DoCommit (); } +<<<<<<< HEAD catch (TransactionException) { throw; @@ -304,6 +318,15 @@ internal void CommitInternal () catch (Exception ex) { throw new TransactionAbortedException("Transaction failed", ex); +======= + catch (TransactionException) + { + throw; + } + catch (Exception ex) + { + throw new TransactionAbortedException("Transaction failed", ex); +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } } @@ -314,6 +337,7 @@ private void DoCommit () /* See test ExplicitTransaction8 */ Rollback (null, null); CheckAborted (); +<<<<<<< HEAD } if (volatiles.Count == 1 && durables.Count == 0) @@ -338,6 +362,32 @@ private void DoCommit () DoCommitPhase(); Complete(); +======= + } + + if (volatiles.Count == 1 && durables.Count == 0) + { + /* Special case */ + ISinglePhaseNotification single = volatiles[0] as ISinglePhaseNotification; + if (single != null) + { + DoSingleCommit(single); + Complete(); + return; + } + } + + if (volatiles.Count > 0) + DoPreparePhase(); + + if (durables.Count > 0) + DoSingleCommit(durables[0]); + + if (volatiles.Count > 0) + DoCommitPhase(); + + Complete(); +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } private void Complete () @@ -346,9 +396,15 @@ private void Complete () committed = true; if (!aborted) +<<<<<<< HEAD info.Status = TransactionStatus.Committed; FireCompleted (); +======= + info.Status = TransactionStatus.Committed; + + FireCompleted (); +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } internal void InitScope (TransactionScope scope) @@ -369,6 +425,7 @@ static void PrepareCallbackWrapper(object state) enlist.EnlistmentNotification.Prepare(enlist); } +<<<<<<< HEAD void DoPreparePhase () { // Call prepare on all volatile managers. @@ -394,6 +451,39 @@ void DoPreparePhase () Aborted = true; break; } +======= + static void PrepareCallbackWrapper(object state) + { + PreparingEnlistment enlist = state as PreparingEnlistment; + enlist.EnlistmentNotification.Prepare(enlist); + } + + void DoPreparePhase () + { + // Call prepare on all volatile managers. + foreach (IEnlistmentNotification enlist in volatiles) + { + PreparingEnlistment pe = new PreparingEnlistment (this, enlist); + ThreadPool.QueueUserWorkItem (new WaitCallback(PrepareCallbackWrapper), pe); + + /* Wait (with timeout) for manager to prepare */ + TimeSpan timeout = Scope != null ? Scope.Timeout : TransactionManager.DefaultTimeout; + + // FIXME: Should we managers in parallel or on-by-one? + if (!pe.WaitHandle.WaitOne(timeout, true)) + { + this.Aborted = true; + throw new TimeoutException("Transaction timedout"); + } + + if (!pe.IsPrepared) + { + /* FIXME: if not prepared & !aborted as yet, then + this is inDoubt ? . For now, setting aborted = true */ + Aborted = true; + break; + } +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } /* Either InDoubt(tmp) or Prepare failed and @@ -432,6 +522,12 @@ void FireCompleted () TransactionCompleted (this, new TransactionEventArgs(this)); } + void FireCompleted () + { + if (TransactionCompleted != null) + TransactionCompleted (this, new TransactionEventArgs(this)); + } + static void EnsureIncompleteCurrentScope () { if (CurrentInternal == null) diff --git a/mcs/class/System.Transactions/System.Transactions/TransactionEventArgs.cs b/mcs/class/System.Transactions/System.Transactions/TransactionEventArgs.cs index 92eea07d1d668..91c9a3ff5fd7a 100644 --- a/mcs/class/System.Transactions/System.Transactions/TransactionEventArgs.cs +++ b/mcs/class/System.Transactions/System.Transactions/TransactionEventArgs.cs @@ -12,6 +12,7 @@ namespace System.Transactions { public class TransactionEventArgs : EventArgs +<<<<<<< HEAD { private Transaction transaction; @@ -23,6 +24,19 @@ internal TransactionEventArgs(Transaction transaction) : this() { this.transaction = transaction; +======= + { + private Transaction transaction; + + public TransactionEventArgs() + { + } + + internal TransactionEventArgs(Transaction transaction) + : this() + { + this.transaction = transaction; +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } public Transaction Transaction { diff --git a/mcs/class/System.Transactions/System.Transactions/TransactionManager.cs b/mcs/class/System.Transactions/System.Transactions/TransactionManager.cs index a7a62b6388e55..41cbcd3c82dc8 100644 --- a/mcs/class/System.Transactions/System.Transactions/TransactionManager.cs +++ b/mcs/class/System.Transactions/System.Transactions/TransactionManager.cs @@ -8,15 +8,24 @@ // (C)2005 Novell Inc, // (C)2006 Novell Inc, // +<<<<<<< HEAD #if NET_2_0 using System.Configuration; using System.Transactions.Configuration; +======= +#if NET_2_0 +using System.Configuration; +#if !MOBILE +using System.Transactions.Configuration; +#endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be namespace System.Transactions { public static class TransactionManager { static TransactionManager () +<<<<<<< HEAD { defaultSettings = ConfigurationManager.GetSection ("system.transactions/defaultSettings") as DefaultSettingsSection; machineSettings = ConfigurationManager.GetSection ("system.transactions/machineSettings") as MachineSettingsSection; @@ -37,6 +46,34 @@ static TransactionManager () if (defaultSettings != null) return defaultSettings.Timeout; +======= + { +#if !MOBILE + defaultSettings = ConfigurationManager.GetSection ("system.transactions/defaultSettings") as DefaultSettingsSection; + machineSettings = ConfigurationManager.GetSection ("system.transactions/machineSettings") as MachineSettingsSection; +#endif + } + +#if !MOBILE + static DefaultSettingsSection defaultSettings; + static MachineSettingsSection machineSettings; +#endif + + static TimeSpan defaultTimeout = new TimeSpan (0, 1, 0); /* 60 secs */ + static TimeSpan maxTimeout = new TimeSpan (0, 10, 0); /* 10 mins */ + + public static TimeSpan DefaultTimeout { + get { + // Obtain timeout from configuration setting.. + // - http://msdn.microsoft.com/en-us/library/ms973865.aspx + // - http://sankarsan.wordpress.com/2009/02/01/transaction-timeout-in-systemtransactions/ + // 1. sys.txs/defaultSettings[@timeout] + // 2. defaultTimeout +#if !MOBILE + if (defaultSettings != null) + return defaultSettings.Timeout; +#endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be return defaultTimeout; } @@ -49,10 +86,18 @@ static TransactionManager () } public static TimeSpan MaximumTimeout { +<<<<<<< HEAD get { if (machineSettings != null) return machineSettings.MaxTimeout; +======= + get { +#if !MOBILE + if (machineSettings != null) + return machineSettings.MaxTimeout; +#endif +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be return maxTimeout; } diff --git a/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs b/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs index d6138bee2846b..89f58a70f29a2 100644 --- a/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs +++ b/mcs/class/System.Transactions/System.Transactions/TransactionScope.cs @@ -22,7 +22,11 @@ public sealed class TransactionScope : IDisposable Transaction transaction; Transaction oldTransaction; +<<<<<<< HEAD TransactionScope parentScope; +======= + TransactionScope parentScope; +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be TimeSpan timeout; /* Num of non-disposed nested scopes */ @@ -91,7 +95,11 @@ public TransactionScope (TransactionScopeOption option) { completed = false; isRoot = false; +<<<<<<< HEAD nested = 0; +======= + nested = 0; +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be this.timeout = timeout; oldTransaction = Transaction.CurrentInternal; @@ -148,6 +156,11 @@ internal TimeSpan Timeout get { return timeout; } } + internal TimeSpan Timeout + { + get { return timeout; } + } + public void Dispose () { if (disposed) diff --git a/mcs/class/System.Transactions/Test/EnlistTest.cs b/mcs/class/System.Transactions/Test/EnlistTest.cs index 9d820c18b8529..0b90b6840325e 100644 --- a/mcs/class/System.Transactions/Test/EnlistTest.cs +++ b/mcs/class/System.Transactions/Test/EnlistTest.cs @@ -257,7 +257,11 @@ public void Vol2_Dur1_Fail1 () [Test] [Ignore ( "Correct this test, it should throw TimeOutException or something" )] public void Vol2_Dur1_Fail2 () +<<<<<<< HEAD { +======= + { +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be TransactionAbortedException exception = null; IntResourceManager [] irm = new IntResourceManager [4]; irm [0] = new IntResourceManager (1); @@ -288,6 +292,7 @@ public void Vol2_Dur1_Fail2 () /* Volatile RMs get 2PC Prepare, and then get rolled back */ for (int i = 1; i < 4; i++) +<<<<<<< HEAD irm [i].Check ( 0, 1, 0, 1, 0, "irm [" + i + "]" ); exception = ex; @@ -344,6 +349,64 @@ public void Vol2_Dur1_Fail2b() Assert.IsNotNull(exception, "Expected TransactionAbortedException not thrown!"); Assert.IsNotNull(exception.InnerException, "TransactionAbortedException has no inner exception!"); Assert.AreEqual(typeof(TimeoutException), exception.InnerException.GetType()); +======= + irm [i].Check ( 0, 1, 0, 1, 0, "irm [" + i + "]" ); + + exception = ex; + } + + Assert.IsNotNull(exception, "Expected TransactionAbortedException not thrown!"); + Assert.IsNotNull(exception.InnerException, "TransactionAbortedException has no inner exception!"); + Assert.AreEqual(typeof(TimeoutException), exception.InnerException.GetType()); + } + + /* Same as Vol2_Dur1_Fail2, but with a volatile manager timming out */ + [Test] + [Ignore ( "Correct this test, it should throw TimeOutException or something" )] + public void Vol2_Dur1_Fail2b() + { + TransactionAbortedException exception = null; + IntResourceManager[] irm = new IntResourceManager[4]; + irm[0] = new IntResourceManager(1); + irm[1] = new IntResourceManager(3); + irm[2] = new IntResourceManager(5); + irm[3] = new IntResourceManager(7); + + irm[0].IgnoreSPC = true; + irm[1].Volatile = false; + + for (int i = 0; i < 4; i++) + irm[i].UseSingle = true; + + /* Durable RM irm[2] does on SPC, so + * all volatile RMs get Rollback */ + try + { + using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 5))) + { + irm[0].Value = 2; + irm[1].Value = 6; + irm[2].Value = 10; + irm[3].Value = 14; + + scope.Complete(); + } + } + catch (TransactionAbortedException ex) + { + irm[0].CheckSPC("irm [0]"); + + /* Volatile RMs get 2PC Prepare, and then get rolled back */ + for (int i = 1; i < 4; i++) + irm[i].Check(0, 1, 0, 1, 0, "irm [" + i + "]"); + + exception = ex; + } + + Assert.IsNotNull(exception, "Expected TransactionAbortedException not thrown!"); + Assert.IsNotNull(exception.InnerException, "TransactionAbortedException has no inner exception!"); + Assert.AreEqual(typeof(TimeoutException), exception.InnerException.GetType()); +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be } /* >1vol + 1 durable @@ -583,6 +646,37 @@ public void TransactionCompleted_Rollback () Assert.IsTrue (called, "TransactionCompleted event handler not called!"); } +<<<<<<< HEAD +======= + + [Test] + public void TransactionCompleted_Committed () + { + bool called = false; + using (var ts = new TransactionScope ()) + { + var tr = Transaction.Current; + tr.TransactionCompleted += (s, e) => called = true; + ts.Complete (); + } + + Assert.IsTrue (called, "TransactionCompleted event handler not called!"); + } + + [Test] + public void TransactionCompleted_Rollback () + { + bool called = false; + using (var ts = new TransactionScope ()) + { + var tr = Transaction.Current; + tr.TransactionCompleted += (s, e) => called = true; + // Not calling ts.Complete() on purpose.. + } + + Assert.IsTrue (called, "TransactionCompleted event handler not called!"); + } +>>>>>>> 3d577e4060dccd67d1450b790ef12bc0781198be #endregion } diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRule.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRule.cs index c2e064af73f94..cd538963c5070 100644 --- a/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRule.cs +++ b/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRule.cs @@ -49,7 +49,8 @@ public sealed class AuthorizationRule : ConfigurationElement static ConfigurationPropertyCollection properties; AuthorizationRuleAction action; - + ConfigurationSaveMode saveMode = ConfigurationSaveMode.Full; + static AuthorizationRule () { rolesProp = new ConfigurationProperty ("roles", typeof (StringCollection), null, @@ -130,7 +131,10 @@ public override int GetHashCode () [MonoTODO ("Not implemented")] protected override bool IsModified () { - throw new NotImplementedException (); + if (((CommaDelimitedStringCollection)Roles).IsModified || ((CommaDelimitedStringCollection)Users).IsModified || ((CommaDelimitedStringCollection)Verbs).IsModified) + return true; + + return false; } void VerifyData () @@ -168,6 +172,9 @@ protected override void ResetModified () protected override bool SerializeElement (XmlWriter writer, bool serializeCollectionKey) { + if (saveMode != ConfigurationSaveMode.Full && !IsModified ()) + return true; + PreSerialize (writer); writer.WriteStartElement (action == AuthorizationRuleAction.Allow ? "allow" : "deny"); @@ -191,6 +198,7 @@ protected override void SetReadOnly () protected override void Unmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode) { base.Unmerge (sourceElement, parentElement, saveMode); + this.saveMode = saveMode; } public AuthorizationRuleAction Action { diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRuleCollection.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRuleCollection.cs index 0c1a39d5933d7..e824eb44644de 100644 --- a/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRuleCollection.cs +++ b/mcs/class/System.Web/System.Web.Configuration_2.0/AuthorizationRuleCollection.cs @@ -108,9 +108,8 @@ public void Set (int index, AuthorizationRule rule) get { return ConfigurationElementCollectionType.BasicMapAlternate; } } - [MonoTODO ("is it okay to return a comma delimited string here?")] protected override string ElementName { - get { return "allow,deny"; } + get { return String.Empty; } } public AuthorizationRule this [int index] { diff --git a/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs b/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs index 227aa96b59f83..4b9244793f4af 100644 --- a/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs +++ b/mcs/class/System.Web/System.Web.Security/FormsAuthentication.cs @@ -230,7 +230,7 @@ public static bool Authenticate (string name, string password) password = HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.MD5); break; case FormsAuthPasswordFormat.SHA1: - password = HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.MD5); + password = HashPasswordForStoringInConfigFile (password, FormsAuthPasswordFormat.SHA1); break; } diff --git a/mcs/class/System.Web/Test/System.Web.Security/FormsAuthenticationTest.cs b/mcs/class/System.Web/Test/System.Web.Security/FormsAuthenticationTest.cs index b31d721332235..66a2ea6e4d510 100644 --- a/mcs/class/System.Web/Test/System.Web.Security/FormsAuthenticationTest.cs +++ b/mcs/class/System.Web/Test/System.Web.Security/FormsAuthenticationTest.cs @@ -87,7 +87,7 @@ public void HashPasswordForStoringInConfigFile_MD5 () // ä (C3-A4) s = Encoding.UTF8.GetString (new byte [2] { 0xC3, 0xA4 }); - Assert.AreEqual ("8419B71C87A225A2C70B50486FBEE545", FormsAuthentication.HashPasswordForStoringInConfigFile (s, "MD5")); + Assert.AreEqual ("8419B71C87A225A2C70B50486FBEE545", FormsAuthentication.HashPasswordForStoringInConfigFile (s, "md5")); } [Test] @@ -99,7 +99,7 @@ public void HashPasswordForStoringInConfigFile_SHA1 () // ä (C3-A4) s = Encoding.UTF8.GetString (new byte [2] { 0xC3, 0xA4 }); - Assert.AreEqual ("961FA22F61A56E19F3F5F8867901AC8CF5E6D11F", FormsAuthentication.HashPasswordForStoringInConfigFile (s, "SHA1")); + Assert.AreEqual ("961FA22F61A56E19F3F5F8867901AC8CF5E6D11F", FormsAuthentication.HashPasswordForStoringInConfigFile (s, "sha1")); } [Test] diff --git a/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs b/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs index 2baf023b61896..f738929e5250f 100644 --- a/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs +++ b/mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs @@ -175,11 +175,17 @@ public static IEnumerable GetAllReadWriteMembers (this XamlType type yield break; } + // Note that unless the XamlType has the default constructor, we don't need "Arguments". + var args = type.ConstructionRequiresArguments ? type.GetConstructorArguments () : null; + if (args != null && args.Any ()) + yield return XamlLanguage.Arguments; + if (type.IsContentValue ()) yield return XamlLanguage.Initialization; foreach (var m in type.GetAllMembers ()) - yield return m; + if (args == null || !args.Contains (m)) // do not read/write constructor arguments twice (they are written inside Arguments). + yield return m; } public static bool ListEquals (this IList a1, IList a2) @@ -195,5 +201,29 @@ public static bool ListEquals (this IList a1, IList a2) return false; return true; } + + public static IEnumerable GetSortedConstructorArguments (this XamlType type) + { + var args = type.GetConstructorArguments ().ToArray (); + var ci = type.UnderlyingType.GetConstructors ().FirstOrDefault (c => c.GetParameters ().Length == args.Length); + if (ci == null) + throw new ArgumentException (String.Format ("Type '{0}' is expected to have constructor with {1} arguments, but was not find.", type.Name, args.Length)); + var pis = ci.GetParameters (); + return args.OrderBy (c => pis.FindParameterWithName (c.ConstructorArgumentName ()).Position); + } + + static ParameterInfo FindParameterWithName (this IEnumerable pis, string name) + { + var ret = pis.FirstOrDefault (pi => pi.Name == name); + if (ret == null) + throw new ArgumentException (String.Format ("Constructor argument '{0}' is expected, but was not found.", name)); + return ret; + } + + public static string ConstructorArgumentName (this XamlMember xm) + { + var caa = xm.CustomAttributeProvider.GetCustomAttribute (false); + return caa.ArgumentName; + } } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs index aa8c8d043f449..c5ac64ef43159 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs @@ -140,7 +140,7 @@ public XamlObjectReader (object instance, XamlSchemaContext schemaContext, XamlO if (!type.IsPublic) throw new XamlObjectReaderException (String.Format ("instance type '{0}' must be public and non-nested.", type)); root_type = SchemaContext.GetXamlType (instance.GetType ()); - if (root_type.ConstructionRequiresArguments && root_type.TypeConverter == null) + if (root_type.ConstructionRequiresArguments && !root_type.GetConstructorArguments ().Any () && root_type.TypeConverter == null) throw new XamlObjectReaderException (String.Format ("instance type '{0}' has no default constructor.", type)); } else @@ -162,6 +162,9 @@ public XamlObjectReader (object instance, XamlSchemaContext schemaContext, XamlO XamlNodeType node_type = XamlNodeType.None; bool is_eof; + // Unlike object stack, this can be Dictionary, since an there should not be the same object within the stack, and we can just get current stack with "objects" stack. + Dictionary> constructor_arguments_stack = new Dictionary> (); + public virtual object Instance { get { return NodeType == XamlNodeType.StartObject && objects.Count > 0 ? objects.Peek () : null; } } @@ -208,7 +211,9 @@ public override bool Read () throw new ObjectDisposedException ("reader"); if (IsEof) return false; + XamlType type; IEnumerator members; + IEnumerator arguments; switch (NodeType) { case XamlNodeType.None: default: @@ -248,7 +253,20 @@ public override bool Read () return true; case XamlNodeType.StartMember: - if (!members_stack.Peek ().Current.IsContentValue ()) + var curMember = members_stack.Peek ().Current; + if (curMember == XamlLanguage.Arguments) { + type = types.Peek (); + var args = type.GetSortedConstructorArguments (); + var obj = objects.Peek (); + var l = new List (); + foreach (var arg in args) + l.Add (arg.Invoker.GetValue (obj)); + arguments = l.GetEnumerator (); + constructor_arguments_stack [obj] = arguments; + arguments.MoveNext (); + StartNextObject (arguments.Current); + } + else if (!curMember.IsContentValue ()) StartNextObject (); else { var obj = GetMemberValueOrRootInstance (); @@ -286,10 +304,20 @@ public override bool Read () is_eof = true; return false; } - members = members_stack.Peek (); - if (members.MoveNext ()) { - StartNextMemberOrNamespace (); - return true; + + if (constructor_arguments_stack.TryGetValue (objects.Peek (), out arguments)) { + if (arguments.MoveNext ()) { + StartNextObject (arguments.Current); + return true; + } + // else -> end of Arguments + constructor_arguments_stack.Remove (objects.Peek ()); + } else { + members = members_stack.Peek (); + if (members.MoveNext ()) { + StartNextMemberOrNamespace (); + return true; + } } // then, move to the end of current object member. node_type = XamlNodeType.EndMember; @@ -329,7 +357,11 @@ void StartNextMemberOrNamespace () void StartNextObject () { - var obj = GetMemberValueOrRootInstance (); + StartNextObject (GetMemberValueOrRootInstance ()); + } + + void StartNextObject (object obj) + { var xt = Object.ReferenceEquals (obj, instance) ? root_type : obj != null ? SchemaContext.GetXamlType (obj.GetType ()) : XamlLanguage.Null; // FIXME: enable these lines. diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs index c4abc3d322b31..2c263e0e06dca 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriter.cs @@ -51,7 +51,7 @@ public XamlObjectWriter (XamlSchemaContext schemaContext, XamlObjectWriterSettin Stack types = new Stack (); Stack members = new Stack (); - List arguments = new List (); + List arguments = new List (); // FIXME: so far it has no contents. string factory_method; bool object_instantiated; List contents = new List (); @@ -120,6 +120,14 @@ protected virtual bool OnSetValue (object eventSender, XamlMember member, object return false; } + void SetValue (XamlMember member, object value) + { + if (member.IsDirective) + return; + if (!OnSetValue (this, member, value)) + member.Invoker.SetValue (objects.Peek (), value); + } + public void SetLineInfo (int lineNumber, int linePosition) { line = lineNumber; @@ -134,7 +142,11 @@ public override void WriteEndMember () var xm = members.Pop (); var xt = xm.Type; - if (xt.IsArray) { + if (xm == XamlLanguage.Arguments) { + InitializeObjectWithArguments (contents.ToArray ()); + } else if (xm == XamlLanguage.Initialization) { + // ... and no need to do anything. The object value to pop *is* the return value. + } else if (xt.IsArray) { throw new NotImplementedException (); } else if (xt.IsCollection) { var obj = objects.Peek (); @@ -146,10 +158,9 @@ public override void WriteEndMember () if (contents.Count > 1) throw new XamlDuplicateMemberException (String.Format ("Value for {0} is assigned more than once", xm.Name)); if (contents.Count == 1) { - var value = GetCorrectlyTypedValue (xm, contents [0]); + var value = GetCorrectlyTypedValue (xm.Type, contents [0]); if (!objects_from_getter.Remove (value)) - if (!OnSetValue (this, xm, value)) - xm.Invoker.SetValue (objects.Peek (), value); + SetValue (xm, value); } } @@ -157,9 +168,8 @@ public override void WriteEndMember () written_properties_stack.Peek ().Add (xm); } - object GetCorrectlyTypedValue (XamlMember xm, object value) + object GetCorrectlyTypedValue (XamlType xt, object value) { - var xt = xm.Type; if (IsAllowedType (xt, value)) return value; if (xt.TypeConverter != null && value != null) { @@ -181,7 +191,7 @@ public override void WriteEndObject () { manager.EndObject (types.Count > 0); - InitializeObjectIfRequired (); // this is required for such case that there was no StartMember call. + InitializeObjectIfRequired (null); // this is required for such case that there was no StartMember call. types.Pop (); written_properties_stack.Pop (); @@ -233,14 +243,15 @@ public override void WriteStartMember (XamlMember property) wpl.Add (property); members.Push (property); + } - if (property == XamlLanguage.Initialization) - return; - else - InitializeObjectIfRequired (); + void InitializeObjectWithArguments (object [] args) + { + var obj = types.Peek ().Invoker.CreateInstance (args); + ObjectInitialized (obj); } - void InitializeObjectIfRequired () + void InitializeObjectIfRequired (XamlMember property) { if (object_instantiated) return; @@ -249,7 +260,7 @@ void InitializeObjectIfRequired () // http://msdn.microsoft.com/en-us/library/system.xaml.xamllanguage.factorymethod%28VS.100%29.aspx object obj; var args = arguments.ToArray (); - if (factory_method != null) + if (factory_method != null) // FIXME: it must be verified with tests. obj = types.Peek ().UnderlyingType.GetMethod (factory_method).Invoke (null, args); else obj = types.Peek ().Invoker.CreateInstance (args); @@ -268,6 +279,9 @@ public override void WriteStartObject (XamlType xamlType) object_instantiated = false; written_properties_stack.Push (new List ()); + + if (!xamlType.IsContentValue ()) // FIXME: there could be more conditions. + InitializeObjectIfRequired (null); } public override void WriteValue (object value) @@ -277,9 +291,7 @@ public override void WriteValue (object value) var xm = members.Peek (); if (xm == XamlLanguage.Initialization) - ObjectInitialized (value); - else if (xm == XamlLanguage.Arguments) - arguments.Add (value); + ObjectInitialized (GetCorrectlyTypedValue (types.Peek (), value)); else if (xm == XamlLanguage.FactoryMethod) factory_method = (string) value; else diff --git a/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs b/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs index 82bae1091283b..82f121e1aec39 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs @@ -206,11 +206,6 @@ protected internal virtual XamlType GetXamlType (string xamlNamespace, string na // If the type was not found, it just returns null. return ret; } - - internal void AddInternal (XamlType type) - { - run_time_types.Add (type); - } bool TypeMatches (XamlType t, string ns, string name, XamlType [] typeArgs) { diff --git a/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs b/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs index 9a583aab6c972..2dc52774f9edc 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlXmlWriter.cs @@ -252,7 +252,8 @@ void DoWriteStartMemberElement (XamlMember xm) { var xt = GetCurrentType (); string prefix = GetPrefix (xm.PreferredXamlNamespace); - w.WriteStartElement (prefix, String.Concat (xt.Name, ".", xm.Name), xm.PreferredXamlNamespace); + string name = xm.IsDirective ? xm.Name : String.Concat (xt.Name, ".", xm.Name); + w.WriteStartElement (prefix, name, xm.PreferredXamlNamespace); WriteAndClearNamespaces (); } diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlLanguageTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlLanguageTest.cs index b5834c6c57bd4..529e706a61fbb 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlLanguageTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlLanguageTest.cs @@ -522,6 +522,12 @@ public void Int32 () var t = XamlLanguage.Int32; TestXamlTypePrimitive (t, "Int32", typeof (int), false, false); + try { + t.Invoker.CreateInstance (new object [] {1}); + Assert.Fail ("Should expect .ctor() and fail"); + } catch (MissingMethodException) { + } + /* Those properties are pointless regarding practical use. Those "members" does not participate in serialization. var l = t.GetAllAttachableMembers ().ToArray (); Assert.AreEqual (1, l.Length, "#32"); @@ -575,6 +581,12 @@ public void String () Assert.IsNotNull (XamlLanguage.AllTypes.First (tt => tt.Name == "String").ValueSerializer, "#x"); Assert.IsNotNull (XamlLanguage.String.ValueSerializer, "#y"); + try { + t.Invoker.CreateInstance (new object [] {"foo"}); + Assert.Fail ("Should expect .ctor() and fail"); + } catch (MissingMethodException) { + } + /* Those properties are pointless regarding practical use. Those "members" does not participate in serialization. var l = t.GetAllAttachableMembers ().ToArray (); Assert.AreEqual (0, l.Length, "#32"); diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs index 6c74d43e99210..cd13c05b159bf 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs @@ -701,6 +701,17 @@ public void Read_CustomMarkupExtension2 () Assert.IsFalse (r.Read (), "#9"); } + [Test] + public void Read_ArgumentAttributed () + { + var obj = new ArgumentAttributed ("foo", "bar"); + var r = new XamlObjectReader (obj); + Read_CommonClrType (r, obj, new KeyValuePair ("x", XamlLanguage.Xaml2006Namespace)); + var args = Read_AttributedArguments_String (r, new string [] {"arg1", "arg2"}); + Assert.AreEqual ("foo", args [0], "#1"); + Assert.AreEqual ("bar", args [1], "#2"); + } + void SimpleReadStandardType (object instance) { var r = new XamlObjectReader (instance); @@ -733,6 +744,36 @@ string Read_Initialization (XamlObjectReader r, object comparableValue) return ret; } + object [] Read_AttributedArguments_String (XamlObjectReader r, string [] argNames) // valid only for string arguments. + { + object [] ret = new object [argNames.Length]; + + Assert.IsTrue (r.Read (), "attarg.Arguments.Start1"); + Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "attarg.Arguments.Start2"); + Assert.IsNotNull (r.Member, "attarg.Arguments.Start3"); + Assert.AreEqual (XamlLanguage.Arguments, r.Member, "attarg.Arguments.Start4"); + for (int i = 0; i < argNames.Length; i++) { + string arg = argNames [i]; + Assert.IsTrue (r.Read (), "attarg.ArgStartObject1." + arg); + Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "attarg.ArgStartObject2." + arg); + Assert.AreEqual (typeof (string), r.Type.UnderlyingType, "attarg.ArgStartObject3." + arg); + Assert.IsTrue (r.Read (), "attarg.ArgStartMember1." + arg); + Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "attarg.ArgStartMember2." + arg); + Assert.AreEqual (XamlLanguage.Initialization, r.Member, "attarg.ArgStartMember3." + arg); // (as the argument is string here by definition) + Assert.IsTrue (r.Read (), "attarg.ArgValue1." + arg); + Assert.AreEqual (XamlNodeType.Value, r.NodeType, "attarg.ArgValue2." + arg); + Assert.AreEqual (typeof (string), r.Value.GetType (), "attarg.ArgValue3." + arg); + ret [i] = r.Value; + Assert.IsTrue (r.Read (), "attarg.ArgEndMember1." + arg); + Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "attarg.ArgEndMember2." + arg); + Assert.IsTrue (r.Read (), "attarg.ArgEndObject1." + arg); + Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "attarg.ArgEndObject2." + arg); + } + Assert.IsTrue (r.Read (), "attarg.Arguments.End1"); + Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "attarg.Arguments.End2"); + return ret; + } + // from initial to StartObject void Read_CommonXamlType (XamlObjectReader r) { @@ -748,7 +789,7 @@ void Read_CommonXamlType (XamlObjectReader r) } // from initial to StartObject - void Read_CommonClrType (XamlObjectReader r, object obj) + void Read_CommonClrType (XamlObjectReader r, object obj, params KeyValuePair [] additionalNamespaces) { Assert.IsTrue (r.Read (), "ct#1"); Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "ct#2"); @@ -756,13 +797,13 @@ void Read_CommonClrType (XamlObjectReader r, object obj) Assert.AreEqual (String.Empty, r.Namespace.Prefix, "ct#3-2"); Assert.AreEqual ("clr-namespace:" + obj.GetType ().Namespace + ";assembly=" + obj.GetType ().Assembly.GetName ().Name, r.Namespace.Namespace, "ct#3-3"); -/* - Assert.IsTrue (r.Read (), "ct#4"); - Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "ct#5"); - Assert.IsNotNull (r.Namespace, "ct#6"); - Assert.AreEqual ("x", r.Namespace.Prefix, "ct#6-2"); - Assert.AreEqual (XamlLanguage.Xaml2006Namespace, r.Namespace.Namespace, "ct#6-3"); -*/ + foreach (var kvp in additionalNamespaces) { + Assert.IsTrue (r.Read (), "ct#4." + kvp.Key); + Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "ct#5." + kvp.Key); + Assert.IsNotNull (r.Namespace, "ct#6." + kvp.Key); + Assert.AreEqual (kvp.Key, r.Namespace.Prefix, "ct#6-2." + kvp.Key); + Assert.AreEqual (kvp.Value, r.Namespace.Namespace, "ct#6-3." + kvp.Key); + } Assert.IsTrue (r.Read (), "ct#7"); Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "ct#8"); diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs index 3ad17658d6699..e1af489ef921b 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlObjectWriterTest.cs @@ -293,6 +293,7 @@ public void DuplicateAssignment2 () [Test] //[ExpectedException (typeof (ArgumentException))] // oh? XamlXmlWriter raises this. + [Category ("NotWorking")] // so, it's not worthy of passing. public void WriteValueTypeMismatch () { var xw = new XamlObjectWriter (sctx, null); diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlTypeTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlTypeTest.cs index 33096f3856515..60ba8b3f6a375 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlTypeTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlTypeTest.cs @@ -478,6 +478,48 @@ public void DefaultValuesSeverlyAttributed () Assert.AreEqual (sctx, t.SchemaContext, "#30"); } + [Test] + public void DefaultValuesArgumentAttributed () + { + var t = new XamlType (typeof (ArgumentAttributed), sctx); + Assert.IsNotNull (t.Invoker, "#1"); + Assert.IsTrue (t.IsNameValid, "#2"); + Assert.IsFalse (t.IsUnknown, "#3"); + Assert.AreEqual ("ArgumentAttributed", t.Name, "#4"); + Assert.AreEqual ("clr-namespace:MonoTests.System.Xaml;assembly=" + GetType ().Assembly.GetName ().Name, t.PreferredXamlNamespace, "#5"); + Assert.IsNull (t.TypeArguments, "#6"); + Assert.AreEqual (typeof (ArgumentAttributed), t.UnderlyingType, "#7"); + Assert.IsTrue (t.ConstructionRequiresArguments, "#8"); + Assert.IsFalse (t.IsArray, "#9"); + Assert.IsFalse (t.IsCollection, "#10"); + Assert.IsTrue (t.IsConstructible, "#11"); + Assert.IsFalse (t.IsDictionary, "#12"); + Assert.IsFalse (t.IsGeneric, "#13"); + Assert.IsFalse (t.IsMarkupExtension, "#14"); + Assert.IsFalse (t.IsNameScope, "#15"); + Assert.IsTrue (t.IsNullable, "#16"); + Assert.IsTrue (t.IsPublic, "#17"); + Assert.IsFalse (t.IsUsableDuringInitialization, "#18"); + Assert.IsFalse (t.IsWhitespaceSignificantCollection, "#19"); + Assert.IsFalse (t.IsXData, "#20"); + Assert.IsFalse (t.TrimSurroundingWhitespace, "#21"); + Assert.IsFalse (t.IsAmbient, "#22"); + Assert.IsNull (t.AllowedContentTypes, "#23"); + Assert.IsNull (t.ContentWrappers, "#24"); + Assert.IsNull (t.TypeConverter, "#25"); + Assert.IsNull (t.ValueSerializer, "#26"); + Assert.IsNull (t.ContentProperty, "#27"); + // Assert.IsNull (t.DeferringLoader, "#28"); + Assert.IsNull (t.MarkupExtensionReturnType, "#29"); + Assert.AreEqual (sctx, t.SchemaContext, "#30"); + + var members = t.GetAllMembers (); + Assert.AreEqual (2, members.Count, "#31"); + string [] names = {"Arg1", "Arg2"}; + foreach (var member in members) + Assert.IsTrue (Array.IndexOf (names, member.Name) >= 0, "#32"); + } + [Test] public void TypeConverter () { @@ -608,4 +650,19 @@ public MyXamlType (string fullName, IList typeArguments, XamlSchemaCon { } } + + public class ArgumentAttributed + { + public ArgumentAttributed (string s1, string s2) + { + Arg1 = s1; + Arg2 = s2; + } + + [ConstructorArgument ("s1")] + public string Arg1 { get; set; } + + [ConstructorArgument ("s2")] + public string Arg2 { get; set; } + } } diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs index 8c492212720a4..fd6a1d492273d 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlReaderTest.cs @@ -56,38 +56,43 @@ void ReadTest (string filename) r.Read (); } - void LoadTest (string filename, Type type) + object LoadTest (string filename, Type type) { var obj = XamlServices.Load (GetReader (filename)); Assert.AreEqual (type, obj.GetType (), "type"); + return obj; } [Test] public void Read_String () { ReadTest ("String.xml"); - //LoadTest ("String.xml", typeof (string)); + var ret = LoadTest ("String.xml", typeof (string)); + Assert.AreEqual ("foo", ret, "ret"); } [Test] public void Read_Int32 () { ReadTest ("Int32.xml"); - //LoadTest ("Int32.xml", typeof (int)); + var ret = LoadTest ("Int32.xml", typeof (int)); + Assert.AreEqual (5, ret, "ret"); } [Test] public void Read_DateTime () { ReadTest ("DateTime.xml"); - //LoadTest ("DateTime.xml", typeof (DateTime)); + var ret = LoadTest ("DateTime.xml", typeof (DateTime)); + Assert.AreEqual (new DateTime (2010, 4, 14), ret, "ret"); } [Test] public void Read_TimeSpan () { ReadTest ("TimeSpan.xml"); - //LoadTest ("TimeSpan.xml", typeof (TimeSpan)); + var ret = LoadTest ("TimeSpan.xml", typeof (TimeSpan)); + Assert.AreEqual (TimeSpan.FromMinutes (7), ret, "ret"); } [Test] @@ -332,5 +337,46 @@ public void Read4 () Assert.IsFalse (r.Read (), "end"); } + + [Test] + public void Read5 () + { + var r = GetReader ("String.xml"); + + Assert.IsTrue (r.Read (), "ns#1"); + Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "ns#2"); + Assert.AreEqual (XamlLanguage.Xaml2006Namespace, r.Namespace.Namespace, "ns#3"); + + Assert.IsTrue (r.Read (), "so#1"); + Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "so#2"); + Assert.AreEqual (XamlLanguage.String, r.Type, "so#3"); + + Assert.IsTrue (r.Read (), "sbase#1"); + Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "sbase#2"); + Assert.AreEqual (XamlLanguage.Base, r.Member, "sbase#3"); + + Assert.IsTrue (r.Read (), "vbase#1"); + Assert.AreEqual (XamlNodeType.Value, r.NodeType, "vbase#2"); + Assert.IsTrue (r.Value is string, "vbase#3"); + + Assert.IsTrue (r.Read (), "ebase#1"); + Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "ebase#2"); + + Assert.IsTrue (r.Read (), "sinit#1"); + Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "sinit#2"); + Assert.AreEqual (XamlLanguage.Initialization, r.Member, "sinit#3"); + + Assert.IsTrue (r.Read (), "vinit#1"); + Assert.AreEqual (XamlNodeType.Value, r.NodeType, "vinit#2"); + Assert.AreEqual ("foo", r.Value, "vinit#3"); // string + + Assert.IsTrue (r.Read (), "einit#1"); + Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "einit#2"); + + Assert.IsTrue (r.Read (), "eo#1"); + Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "eo#2"); + + Assert.IsFalse (r.Read (), "end"); + } } } diff --git a/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlWriterTest.cs b/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlWriterTest.cs index c18019b860558..ae6afa443040e 100644 --- a/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlWriterTest.cs +++ b/mcs/class/System.Xaml/Test/System.Xaml/XamlXmlWriterTest.cs @@ -606,5 +606,17 @@ public void WriteNode2 () w.Close (); Assert.AreEqual ("foo", w.Result, "#1"); } + + [Test] + public void ConstructorArguments () + { + string xml = String.Format (@"xxxyyy", GetType ().Assembly.GetName ().Name); + Assert.IsFalse (sctx.FullyQualifyAssemblyNamesInClrNamespaces, "premise0"); + var r = new XamlObjectReader (new ArgumentAttributed ("xxx", "yyy"), sctx); + var sw = new StringWriter (); + var w = new XamlXmlWriter (sw, sctx, null); + XamlServices.Transform (r, w); + Assert.AreEqual (xml, sw.ToString ().Replace ('"', '\''), "#1"); + } } } diff --git a/mcs/class/System/System.Net/HttpWebRequest.cs b/mcs/class/System/System.Net/HttpWebRequest.cs index 6764954e7e95f..fcad9f21c7361 100644 --- a/mcs/class/System/System.Net/HttpWebRequest.cs +++ b/mcs/class/System/System.Net/HttpWebRequest.cs @@ -1240,6 +1240,7 @@ internal void SetResponseData (WebConnectionData data) if (r != null) { if (wexc != null) { + haveResponse = true; r.SetCompleted (false, wexc); r.DoCallback (); return; diff --git a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs index 5bace9415d48a..fcdd71f72251e 100644 --- a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs +++ b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs @@ -71,7 +71,17 @@ internal MonoGenericClass (Type tb, Type[] args) { this.generic_type = tb; this.type_arguments = args; - register_with_runtime (this); /*Temporary hack while*/ + /* + This is a temporary hack until we can fix the rest of the runtime + to properly handle this class to be a complete UT. + + We must not regisrer this with the runtime after the type is created + otherwise created_type.MakeGenericType will return an instance of MonoGenericClass, + which is very very broken. + */ + if (tb is TypeBuilder && !(tb as TypeBuilder).is_created) + register_with_runtime (this); + } diff --git a/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs b/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs index 17b1b2896cc99..9116054f10c16 100644 --- a/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs @@ -186,6 +186,24 @@ public void MethodsThatRaiseNotSupported () Assert.Fail ("#13"); } catch (NotSupportedException) { } } + + [Test] + public void ClassMustNotBeRegisteredAfterTypeBuilderIsFinished () + { + TypeBuilder tb = module.DefineType ("foo.type"); + tb.DefineGenericParameters ("T"); + + var c = tb.CreateType (); + + var sreInst = tb.MakeGenericType (typeof (int)); + var rtInst = c.MakeGenericType (typeof (int)); + + Assert.AreNotSame (sreInst, rtInst, "#1"); + + /*This must not throw*/ + rtInst.IsDefined (typeof (int), true); + } } + #endif } diff --git a/mcs/class/corlib/Test/System/TypeTest.cs b/mcs/class/corlib/Test/System/TypeTest.cs index 518c01eadcfdc..6afd86d82d8c7 100644 --- a/mcs/class/corlib/Test/System/TypeTest.cs +++ b/mcs/class/corlib/Test/System/TypeTest.cs @@ -2961,13 +2961,11 @@ public void TestMakeGenericType_UserDefinedType_DotNet20SP1 () public void MakeGenericType_BadUserType () { Type ut = new UserType (null); - try { - Type t = typeof (Foo<>).MakeGenericType (ut); - Assert.Fail ("#1"); - } catch (ArgumentException) { - } + Type t = typeof (Foo<>).MakeGenericType (ut); + var g0 = t.GetGenericArguments () [0]; + Assert.AreSame (g0, ut, "#1"); } - + [Test] public void MakeGenericType_WrongNumOfArguments () { diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index 49898c65bba9f..c9a910ffc1b4c 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -1791,8 +1791,18 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET soc *error = 0; - ret=convert_sockopt_level_and_name(level, name, &system_level, - &system_name); +#if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR) + if (level == SocketOptionLevel_Socket && name == SocketOptionName_ExclusiveAddressUse) { + system_level = SOL_SOCKET; + system_name = SO_REUSEADDR; + ret = 0; + } else +#endif + { + + ret = convert_sockopt_level_and_name (level, name, &system_level, &system_name); + } + if(ret==-1) { *error = WSAENOPROTOOPT; return; @@ -1899,9 +1909,12 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET soc #endif default: +#if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR) + if (level == SocketOptionLevel_Socket && name == SocketOptionName_ExclusiveAddressUse) + val = val ? 0 : 1; +#endif obj = int_to_object (domain, val); } - *obj_val=obj; } @@ -2016,6 +2029,15 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g ret=convert_sockopt_level_and_name(level, name, &system_level, &system_name); + +#if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR) + if (level == SocketOptionLevel_Socket && name == SocketOptionName_ExclusiveAddressUse) { + system_name = SO_REUSEADDR; + int_val = int_val ? 0 : 1; + ret = 0; + } +#endif + if(ret==-1) { *error = WSAENOPROTOOPT; return; diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c index ea7c067800665..fd91db80ae524 100644 --- a/mono/metadata/threadpool.c +++ b/mono/metadata/threadpool.c @@ -1995,11 +1995,7 @@ async_invoke_thread (gpointer data) MonoClass *klass; klass = exc->vtable->klass; - unloaded = (klass->image == mono_defaults.corlib); - if (unloaded) { - unloaded = is_appdomainunloaded_exception (klass); - } - + unloaded = is_appdomainunloaded_exception (klass); if (!unloaded && klass != mono_defaults.threadabortexception_class) { mono_unhandled_exception (exc); exit (255); diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index ba635554cb7eb..c3f67b9badbaa 100644 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -376,13 +376,17 @@ TEST_CS_SRC_DIST= \ async-exc-compilation.cs \ filter-stack.cs +TEST_CS_SRC_GEN = \ + runtime-invoke.gen.cs \ + imt_big_iface_test.cs + if AMD64 -TEST_CS_SRC = $(BASE_TEST_CS_SRC) async-exc-compilation.cs +TEST_CS_SRC = $(BASE_TEST_CS_SRC) $(TEST_CS_SRC_GEN) async-exc-compilation.cs else if X86 -TEST_CS_SRC = $(BASE_TEST_CS_SRC) async-exc-compilation.cs +TEST_CS_SRC = $(BASE_TEST_CS_SRC) $(TEST_CS_SRC_GEN) async-exc-compilation.cs else -TEST_CS_SRC = $(BASE_TEST_CS_SRC) +TEST_CS_SRC = $(BASE_TEST_CS_SRC) $(TEST_CS_SRC_GEN) endif endif @@ -550,7 +554,7 @@ endif # test_messages fails on the buildbots #test: assemblyresolve/test/asm.dll testjit test-type-load test-generic-sharing test_platform test_2_1 test_messages -test: assemblyresolve/test/asm.dll testjit test-type-load test-generic-sharing test_platform test-runtime-invoke test-imt-big-iface test_2_1 test-process-exit +test: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test_platform test_2_1 test-process-exit assemblyresolve/test/asm.dll: $(MAKE) -C assemblyresolve prereq @@ -672,18 +676,14 @@ test-type-load: TestDriver.dll # Generated tests for runtime invoke EXTRA_DIST += gen-runtime-invoke.cs -test-runtime-invoke: TestDriver.dll gen-runtime-invoke.exe - @$(RUNTIME) gen-runtime-invoke.exe > runtime-invoke.gen.cs - @$(MCS) -out:runtime-invoke.gen.exe -r:TestDriver.dll runtime-invoke.gen.cs - @echo "Testing runtime-invoke.gen.exe..." - @$(RUNTIME) runtime-invoke.gen.exe > runtime-invoke.gen.exe.stdout 2> runtime-invoke.gen.exe.stderr +runtime-invoke.gen.exe: TestDriver.dll gen-runtime-invoke.exe + $(RUNTIME) gen-runtime-invoke.exe > runtime-invoke.gen.cs + $(MCS) -out:runtime-invoke.gen.exe -r:TestDriver.dll runtime-invoke.gen.cs EXTRA_DIST += make-imt-test.cs -test-imt-big-iface: TestDriver.dll make-imt-test.exe - @$(RUNTIME) make-imt-test.exe > imt_big_iface_test.cs - @$(MCS) -out:imt_big_iface_test.exe -r:TestDriver.dll imt_big_iface_test.cs - @echo "Testing imt_big_iface_test.exe..." - @$(RUNTIME) imt_big_iface_test.exe > imt_big_iface_test.exe.stdout 2> imt_big_iface_test.exe.stderr +imt_big_iface_test.exe: TestDriver.dll make-imt-test.exe + $(RUNTIME) make-imt-test.exe > imt_big_iface_test.cs + $(MCS) -out:imt_big_iface_test.exe -r:TestDriver.dll imt_big_iface_test.cs EXTRA_DIST += test-inline-call-stack-library.cs test-inline-call-stack.cs test-inline-call-stack-library.dll: TestDriver.dll $(srcdir)/test-inline-call-stack-library.cs