Manual pages and Mono documentation are covered by the MIT X11 license.
+* samples
+
+ The code in the "samples" directory is released under the MIT X11 license.
+
* The Licenses
These are the licenses used in Mono, the files are located:
+2008-05-01 Bill Holmes <billholmes54@gmail.com>
+
+ * src/glib.h : Adding declarations for g_ucs4_to_utf16 and g_utf16_to_ucs4.
+
+ * src/gutf8.c : Adding implementation for g_ucs4_to_utf16 and g_utf16_to_ucs4.
+
+ * test/utf8.c Adding tests for g_ucs4_to_utf16 and g_utf16_to_ucs4.
+
+ Contributed under MIT/X11 license.
+
2008-04-20 Geoff Norton <gnorton@novell.com>
* src/gspan.c: Fix the _NSGetEnviron define to prevent an impropoer
pointer dereference.
-2007-03-19 Bill Holmes <billholmes54@gmail.com>
+2008-03-19 Bill Holmes <billholmes54@gmail.com>
* src/gpath.c (g_path_is_absolute) : Adding a case for '/'
on Windows.
gunichar2 *g_utf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **error);
gchar *g_utf16_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **error);
+gunichar2 *g_ucs4_to_utf16 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **error);
+gunichar *g_utf16_to_ucs4 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **error);
#define u8to16(str) g_utf8_to_utf16(str, (glong)strlen(str), NULL, NULL, NULL)
return ret;
}
+static glong
+g_ucs4_to_utf16_len (const gunichar *str, glong len, glong *items_read, GError **error)
+{
+ glong retlen = 0;
+ glong errindex = 0;
+ const gunichar *lstr = str;
+
+ if (!str)
+ return 0;
+
+ while (*lstr != '\0' && len--) {
+ gunichar ch;
+ ch = *lstr++;
+ if (ch <= 0x0000FFFF) {
+ if (ch >= 0xD800 && ch <= 0xDFFF) {
+ errindex = (glong)(lstr - str)-1;
+ if (error)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ "Invalid sequence in conversion input");
+ if (items_read)
+ *items_read = errindex;
+ return 0;
+ } else {
+ retlen++;
+ }
+ } else if (ch > 0x10FFFF) {
+ errindex = (glong)(lstr - str)-1;
+ if (error)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ "Character out of range for UTF-16");
+ if (items_read)
+ *items_read = errindex;
+ return 0;
+
+ } else {
+ retlen+=2;
+ }
+ }
+
+ if (items_read)
+ *items_read = (glong)(lstr - str);
+ return retlen;
+}
+
gunichar2*
g_ucs4_to_utf16 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **error)
{
- g_assert_not_reached ();
+ glong allocsz;
+ gunichar2 *retstr = 0;
+ gunichar2 *retch = 0;
+ glong nwritten = 0;
+ GError *lerror =0 ;
+
+ allocsz = g_ucs4_to_utf16_len (str, len, items_read, &lerror);
+
+ if (!lerror) {
+ retch = retstr = g_malloc ((allocsz+1) * sizeof (gunichar2));
+ retstr[allocsz] = '\0';
+
+ while (*str != '\0' && len--) {
+ gunichar ch;
+ ch = *str++;
+ if (ch <= 0x0000FFFF && (ch < 0xD800 || ch > 0xDFFF)) {
+ *retch++ = (gunichar2)ch;
+ nwritten ++;
+ } else {
+ ch -= 0x0010000UL;
+ *retch++ = (gunichar2)((ch >> 10) + 0xD800);
+ *retch++ = (gunichar2)((ch & 0x3FFUL) + 0xDC00);
+ nwritten +=2;
+ }
+ }
+ }
+
+ if (items_written)
+ *items_written = nwritten;
+ if (error)
+ *error = lerror;
+
+ return retstr;
+}
+
+static glong
+g_utf16_to_ucs4_len (const gunichar2 *str, glong len, glong *items_read, GError **error)
+{
+ glong retlen = 0;
+ glong errindex = 0;
+ const gunichar2 *lstr = str;
+ gunichar2 ch,ch2;
- return NULL;
+ if (!str)
+ return 0;
+
+ while (*lstr != '\0' && len--) {
+ ch = *lstr++;
+ if (ch >= 0xD800 && ch <= 0xDBFF) {
+ if (!len--) {
+ lstr--;
+ break;
+ }
+ ch2 = *lstr;
+ if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+ lstr++;
+ } else {
+ errindex = (glong)(lstr - str);
+ if (error)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ "Invalid sequence in conversion input");
+ if (items_read)
+ *items_read = errindex;
+ return 0;
+ }
+ } else {
+ if (ch >= 0xDC00 && ch <= 0xDFFF) {
+ errindex = (glong)(lstr - str)-1;
+ if (error)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ "Invalid sequence in conversion input");
+ if (items_read)
+ *items_read = errindex;
+ return 0;
+ }
+ }
+ retlen++;
+ }
+
+ if (items_read)
+ *items_read = (glong)(lstr - str);
+
+ return retlen;
}
gunichar*
g_utf16_to_ucs4 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **error)
{
- g_assert_not_reached ();
+ glong allocsz;
+ gunichar *retstr = 0;
+ gunichar *retch = 0;
+ glong nwritten = 0;
+ GError *lerror =0 ;
+ gunichar ch,ch2;
+
+ allocsz = g_utf16_to_ucs4_len (str, len, items_read, &lerror);
+
+ if (!lerror) {
+ retch = retstr = g_malloc ((allocsz+1) * sizeof (gunichar));
+ retstr[allocsz] = '\0';
+ nwritten = allocsz;
+
+ while (*str != '\0' && allocsz--) {
+ ch = *str++;
+ if (ch >= 0xD800 && ch <= 0xDBFF) {
+ ch2 = *str++;
+ ch = ((ch - (gunichar)0xD800) << 10)
+ + (ch2 - (gunichar)0xDC00) + (gunichar)0x0010000UL;
+ }
+ *retch++ = ch;
+ }
+ }
+
+ if (items_written)
+ *items_written = nwritten;
+ if (error)
+ *error = lerror;
- return NULL;
+ return retstr;
}
return OK;
}
+static RESULT
+ucs4_to_utf16_check_result (const gunichar2 *result_str, const gunichar2 *expected_str,
+ glong result_items_read, glong expected_items_read,
+ glong result_items_written, glong expected_items_written,
+ GError* result_error, gboolean expect_error)
+{
+ glong i;
+ if (result_items_read != expected_items_read)
+ return FAILED("Incorrect number of items read %d", result_items_read);
+ if (result_items_written != expected_items_written)
+ return FAILED("Incorrect number of items written %d", result_items_written);
+ if (result_error && !expect_error)
+ return FAILED("There should not be an error code.");
+ if (!result_error && expect_error)
+ return FAILED("Unexpected error object.");
+ if (expect_error && result_str)
+ return FAILED("NULL should be returned when an error occurs.");
+ if (!expect_error && !result_str)
+ return FAILED("When no error occurs NULL should not be returned.");
+ for (i=0; i<expected_items_written;i++) {
+ if (result_str [i] != expected_str [i])
+ return FAILED("Incorrect value %d at index %d", result_str [i], i);
+ }
+ if (result_str && result_str[expected_items_written] != '\0')
+ return FAILED("Null termination not found at the end of the string.");
+
+ return OK;
+}
+
+RESULT
+test_ucs4_to_utf16 ()
+{
+ static gunichar str1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'};
+ static gunichar2 exp1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'};
+ static gunichar str2[3] = {'h',0x80000000,'\0'};
+ static gunichar2 exp2[2] = {'h','\0'};
+ static gunichar str3[3] = {'h',0xDA00,'\0'};
+ static gunichar str4[3] = {'h',0x10FFFF,'\0'};
+ static gunichar2 exp4[4] = {'h',0xdbff,0xdfff,'\0'};
+ static gunichar str5[7] = {0xD7FF,0xD800,0xDFFF,0xE000,0x110000,0x10FFFF,'\0'};
+ static gunichar2 exp5[5] = {0xD7FF,0xE000,0xdbff,0xdfff,'\0'};
+ static glong read_write[12] = {1,1,0,0,0,0,1,1,0,0,1,2};
+ gunichar2* res;
+ glong items_read, items_written, current_write_index;
+ GError* err=0;
+ RESULT check_result;
+ glong i;
+
+ res = g_ucs4_to_utf16 (str1, 12, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, exp1, items_read, 11, items_written, 11, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_ucs4_to_utf16 (str2, 0, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, exp2, items_read, 0, items_written, 0, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_ucs4_to_utf16 (str2, 1, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, exp2, items_read, 1, items_written, 1, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_ucs4_to_utf16 (str2, 2, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, 0, items_read, 1, items_written, 0, err, TRUE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ err = 0;
+ res = g_ucs4_to_utf16 (str3, 2, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, 0, items_read, 1, items_written, 0, err, TRUE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ err = 0;
+ res = g_ucs4_to_utf16 (str4, 5, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, exp4, items_read, 2, items_written, 3, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ // This loop tests the bounds of the conversion algorithm
+ current_write_index = 0;
+ for (i=0;i<6;i++) {
+ items_read = items_written = 0;
+ err = 0;
+ res = g_ucs4_to_utf16 (&str5[i], 1, &items_read, &items_written, &err);
+ check_result = ucs4_to_utf16_check_result (res, &exp5[current_write_index],
+ items_read, read_write[i*2], items_written, read_write[(i*2)+1], err, !read_write[(i*2)+1]);
+ if (check_result) return check_result;
+ g_free (res);
+ current_write_index += items_written;
+ }
+
+ return OK;
+}
+
+static RESULT
+utf16_to_ucs4_check_result (const gunichar *result_str, const gunichar *expected_str,
+ glong result_items_read, glong expected_items_read,
+ glong result_items_written, glong expected_items_written,
+ GError* result_error, gboolean expect_error)
+{
+ glong i;
+ if (result_items_read != expected_items_read)
+ return FAILED("Incorrect number of items read %d", result_items_read);
+ if (result_items_written != expected_items_written)
+ return FAILED("Incorrect number of items written %d", result_items_written);
+ if (result_error && !expect_error)
+ return FAILED("There should not be an error code.");
+ if (!result_error && expect_error)
+ return FAILED("Unexpected error object.");
+ if (expect_error && result_str)
+ return FAILED("NULL should be returned when an error occurs.");
+ if (!expect_error && !result_str)
+ return FAILED("When no error occurs NULL should not be returned.");
+ for (i=0; i<expected_items_written;i++) {
+ if (result_str [i] != expected_str [i])
+ return FAILED("Incorrect value %d at index %d", result_str [i], i);
+ }
+ if (result_str && result_str[expected_items_written] != '\0')
+ return FAILED("Null termination not found at the end of the string.");
+
+ return OK;
+}
+
+RESULT
+test_utf16_to_ucs4 ()
+{
+ static gunichar2 str1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'};
+ static gunichar exp1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'};
+ static gunichar2 str2[7] = {'H', 0xD800, 0xDC01,0xD800,0xDBFF,'l','\0'};
+ static gunichar exp2[3] = {'H',0x00010001,'\0'};
+ static gunichar2 str3[4] = {'H', 0xDC00 ,'l','\0'};
+ static gunichar exp3[2] = {'H','\0'};
+ static gunichar2 str4[20] = {0xDC00,0xDFFF,0xDFF,0xD800,0xDBFF,0xD800,0xDC00,0xD800,0xDFFF,
+ 0xD800,0xE000,0xDBFF,0xDBFF,0xDBFF,0xDC00,0xDBFF,0xDFFF,0xDBFF,0xE000,'\0'};
+ static gunichar exp4[6] = {0xDFF,0x10000,0x103ff,0x10fc00,0x10FFFF,'\0'};
+ static glong read_write[33] = {1,0,0,1,0,0,1,1,1,2,1,0,2,2,1,2,2,1,2,1,0,2,1,0,2,2,1,2,2,1,2,1,0};
+ gunichar* res;
+ glong items_read, items_written, current_read_index,current_write_index;
+ GError* err=0;
+ RESULT check_result;
+ glong i;
+
+ res = g_utf16_to_ucs4 (str1, 12, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp1, items_read, 11, items_written, 11, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_utf16_to_ucs4 (str2, 0, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 0, items_written, 0, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_utf16_to_ucs4 (str2, 1, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 1, items_written, 1, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_utf16_to_ucs4 (str2, 2, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 1, items_written, 1, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_utf16_to_ucs4 (str2, 3, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 3, items_written, 2, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_utf16_to_ucs4 (str2, 4, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 3, items_written, 2, err, FALSE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ res = g_utf16_to_ucs4 (str2, 5, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 4, items_written, 0, err, TRUE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ items_read = items_written = 0;
+ err = 0;
+ res = g_utf16_to_ucs4 (str3, 5, &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, exp3, items_read, 1, items_written, 0, err, TRUE);
+ if (check_result) return check_result;
+ g_free (res);
+
+ // This loop tests the bounds of the conversion algorithm
+ current_read_index = current_write_index = 0;
+ for (i=0;i<11;i++) {
+ items_read = items_written = 0;
+ err = 0;
+ res = g_utf16_to_ucs4 (&str4[current_read_index], read_write[i*3], &items_read, &items_written, &err);
+ check_result = utf16_to_ucs4_check_result (res, &exp4[current_write_index], items_read,
+ read_write[(i*3)+1], items_written, read_write[(i*3)+2], err,
+ !read_write[(i*3)+2]);
+ if (check_result) return check_result;
+ g_free (res);
+ current_read_index += read_write[i*3];
+ current_write_index += items_written;
+ }
+
+ return OK;
+}
+
/*
* test initialization
*/
{"g_utf8_seq", test_utf8_seq},
{"g_convert", test_convert },
{"g_unichar_xdigit_value", test_xdigit },
+ {"g_ucs4_to_utf16", test_ucs4_to_utf16 },
+ {"g_utf16_to_ucs4", test_utf16_to_ucs4 },
{NULL, NULL}
};
+2008-04-30 George Giolfan <georgegiolfan@yahoo.com>
+
+ * TabControlPainter.cs: Ordered usings.
+
2008-04-28 George Giolfan <georgegiolfan@yahoo.com>
* TabControlPainter.cs: Fixed duplication.
// Authors:
// George Giolfan (georgegiolfan@yahoo.com)
-using System.Windows.Forms.VisualStyles;
using System.Drawing;
+using System.Windows.Forms.VisualStyles;
namespace System.Windows.Forms.Theming.VisualStyles
{
class TabControlPainter : Default.TabControlPainter
+2008-05-01 Jonathan Pobst <monkey@jpobst.com>
+
+ * InputLanguageCollection.cs: Implement the collection better.
+ [Fixes bug #385506]
+
+2008-05-01 Jonathan Pobst <monkey@jpobst.com>
+
+ * ToolStripDropDownItem.cs: Get the correct event object for
+ DropDownItemClicked.
+ * ToolStripMenuItem.cs: Raise DropDownItemClicked on our owner.
+ [Fixes bug #385475]
+
+2008-05-01 Jonathan Pobst <monkey@jpobst.com>
+
+ * DataGridViewRowCollection.cs: We don't currently support shared
+ rows. Should fix test failures caused by previous commit.
+
+2008-04-30 Jonathan Pobst <monkey@jpobst.com>
+
+ * DataGridViewRow.cs: Fixes for cloning the row, ensure header cell's
+ datagridview gets set. Only paint cells in visible columns.
+ * DataGridViewCell.cs: Draw border after cell content.
+ * DataGridView.cs: Invalidate after setting some properties. Only
+ use visible columns. Fit hit test bug with areas in the col/row header
+ area but not in a row or col. Implement UpdateCell/Row methods.
+
+2008-04-30 Jonathan Pobst <monkey@jpobst.com>
+
+ * DataGridViewElement.cs: Don't throw NIEX.
+ * DataGridViewColumnHeaderCell.cs: Draw error icons for top left header cells.
+ * DataGridViewColumnDesignTimeVisibleAttribute.cs: Don't throw NIEX.
+ * DataGridViewCheckBoxColumn.cs: Implement ToString.
+ * DataGridViewCheckBoxCell.cs: Allow DBNull as a value.
+ * DataGridViewCell.cs: Don't raise CellFormatting for RowHeader cells,
+ if the user filled in the formatting Value, use it.
+
+2008-04-30 Jonathan Pobst <monkey@jpobst.com>
+
+ * DataGridViewTextBoxCell.cs: Fix for objects that cannot be cast
+ to a string.
+
2008-04-29 Carlos Alberto Cortez <calberto.cortez@gmail.com>
* BindingSource.cs: Some corrections to Filter property, as well as
allowUserToAddRows = value;
OnAllowUserToAddRowsChanged(EventArgs.Empty);
PrepareEditingRow (false, false);
+ Invalidate ();
}
}
}
}
}
}
+
autoSizeColumnsMode = value;
+ AutoResizeColumns (value);
+ Invalidate ();
}
}
throw new InvalidOperationException("Cant set this property to AllHeaders or DisplayedHeaders in this DataGridView.");
}
autoSizeRowsMode = value;
+ AutoResizeRows (value);
OnAutoSizeRowsModeChanged(new DataGridViewAutoSizeModeEventArgs(false));
+ Invalidate ();
////////////////////////////////////////////////////////////////
}
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
public DataGridViewRow RowTemplate {
get {
- if (rowTemplate == null) {
- return new DataGridViewRow();
- }
+ if (rowTemplate == null)
+ rowTemplate = new DataGridViewRow ();
+
return rowTemplate;
}
set {
DataGridViewRow row = GetRowInternal (rowIndex);
if (autoSizeRowMode == DataGridViewAutoSizeRowMode.RowHeader) {
- row.Height = row.HeaderCell.PreferredSize.Width;
+ row.Height = row.HeaderCell.PreferredSize.Height;
return;
}
if (autoSizeRowMode == DataGridViewAutoSizeRowMode.AllCellsExceptHeader)
row.Height = row_height;
else
- row.Height = Math.Max (row_height, row.HeaderCell.PreferredSize.Width);
+ row.Height = Math.Max (row_height, row.HeaderCell.PreferredSize.Height);
}
public void AutoResizeRowHeadersWidth (DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode)
List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
for (int i = first_col_index; i < cols.Count; i++) {
+ if (!cols[i].Visible)
+ continue;
+
if (cols[i].Index == columnIndex) {
w = cols[i].Width;
break;
List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
for (int i = first_col_index; i < cols.Count; i++) {
+ if (!cols[i].Visible)
+ continue;
+
if (cols[i].Index == columnIndex) {
w = cols[i].Width;
break;
List<DataGridViewColumn> cols = columns.ColumnDisplayIndexSortedArrayList;
for (int i = first_col_index; i < cols.Count; i++) {
+ if (!cols[i].Visible)
+ continue;
+
if (x > left && x <= (left + cols[i].Width)) {
colindex = cols[i].Index;
break;
if (colindex >= 0 && rowindex >= 0)
return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.Cell);
- if (isInColHeader)
+ if (isInColHeader && colindex > -1)
return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.ColumnHeader);
- if (isInRowHeader)
+ if (isInRowHeader && rowindex > -1)
return new HitTestInfo (colindex, x, rowindex, y, DataGridViewHitTestType.RowHeader);
return new HitTestInfo (-1, x, -1, y, DataGridViewHitTestType.None);
public void UpdateCellErrorText (int columnIndex, int rowIndex)
{
- throw new NotImplementedException();
+ if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+ throw new ArgumentOutOfRangeException ("columnIndex");
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ InvalidateCell (columnIndex, rowIndex);
}
public void UpdateCellValue (int columnIndex, int rowIndex)
{
- throw new NotImplementedException();
+ if (columnIndex < 0 || columnIndex > Columns.Count - 1)
+ throw new ArgumentOutOfRangeException ("columnIndex");
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ InvalidateCell (columnIndex, rowIndex);
}
public void UpdateRowErrorText (int rowIndex)
{
- throw new NotImplementedException();
+ if (rowIndex < 0 || rowIndex > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndex");
+
+ InvalidateRow (rowIndex);
}
- public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd) {
- throw new NotImplementedException();
+ public void UpdateRowErrorText (int rowIndexStart, int rowIndexEnd)
+ {
+ if (rowIndexStart < 0 || rowIndexStart > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndexStart");
+ if (rowIndexEnd < 0 || rowIndexEnd > Rows.Count - 1)
+ throw new ArgumentOutOfRangeException ("rowIndexEnd");
+ if (rowIndexEnd < rowIndexStart)
+ throw new ArgumentOutOfRangeException ("rowIndexEnd", "rowIndexEnd must be greater than rowIndexStart");
+
+ for (int i = rowIndexStart; i <= rowIndexEnd; i++)
+ InvalidateRow (i);
}
public void UpdateRowHeightInfo (int rowIndex, bool updateToEnd) {
for (int index = first_col_index; index < sortedColumns.Count; index++) {
DataGridViewColumn col = sortedColumns[index];
+ if (!col.Visible)
+ continue;
+
headerBounds.Width = col.Width;
DataGridViewCell cell = col.HeaderCell;
gridHeight = 0;
int rows_displayed = 0;
- int first_row_height = Rows.Count > 0 ? Rows[first_row_index].Height : 0;
+ int first_row_height = Rows.Count > 0 ? Rows[Math.Min (Rows.Count - 1, first_row_index)].Height : 0;
int room_left = this.Height;
// Reset all columns to !Displayed
// Set Displayed columns
for (int i = first_col_index; i < Columns.Count; i++) {
DataGridViewColumn col = Columns.ColumnDisplayIndexSortedArrayList[i];
-
+
+ if (!col.Visible)
+ continue;
+
col.DisplayedInternal = true;
gridWidth += col.Width;
bool is_first = row.Index == 0;
bool is_last = row.Index == rows.Count - 1;
- row.Paint (g, e.ClipRectangle, bounds, index, row.GetState (row.Index), is_first, is_last);
+ row.Paint (g, e.ClipRectangle, bounds, row.Index, row.GetState (row.Index), is_first, is_last);
bounds.Y += bounds.Height;
bounds.X = BorderWidth;
gridWidth = 0;
foreach (DataGridViewColumn col in sortedColumns)
- gridWidth += col.Width;
+ if (col.Visible)
+ gridWidth += col.Width;
gridHeight = 0;
protected virtual void SetSelectedCellCore (int columnIndex, int rowIndex, bool selected) {
rows [rowIndex].Cells [columnIndex].Selected = selected;
+
+ OnSelectionChanged (EventArgs.Empty);
}
internal void SetSelectedColumnCoreInternal (int columnIndex, bool selected) {
private DataGridViewCellStyle style;
private object tag;
private string toolTipText;
- private object valuex;
- private Type valueType;
+ internal object valuex;
+ internal Type valueType;
protected DataGridViewCell ()
{
DataGridViewCellFormattingEventArgs e = new DataGridViewCellFormattingEventArgs (ColumnIndex, rowIndex, value, FormattedValueType, cellStyle);
- DataGridView.OnCellFormattingInternal (e);
+ if (!(this is DataGridViewRowHeaderCell))
+ DataGridView.OnCellFormattingInternal (e);
- if (e.FormattingApplied) {
+ if (e.FormattingApplied || e.Value != null) {
return e.Value;
}
PaintPartBackground (graphics, cellBounds, cellStyle);
if ((paintParts & DataGridViewPaintParts.SelectionBackground) == DataGridViewPaintParts.SelectionBackground)
PaintPartSelectionBackground (graphics, cellBounds, cellState, cellStyle);
- if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border)
- PaintPartBorder (graphics, cellBounds, rowIndex);
if ((paintParts & DataGridViewPaintParts.ContentForeground) == DataGridViewPaintParts.ContentForeground)
PaintPartContent (graphics, cellBounds, rowIndex, cellState, cellStyle, formattedValue);
+ if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border)
+ PaintPartBorder (graphics, cellBounds, rowIndex);
if ((paintParts & DataGridViewPaintParts.Focus) == DataGridViewPaintParts.Focus)
PaintPartFocus (graphics, cellBounds);
if ((paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon)
formattedvalue = Value;
} else {
value = Value;
- formattedvalue = FormattedValue;
+ formattedvalue = GetFormattedValue (Value, rowIndex, ref cellStyle, null, null, DataGridViewDataErrorContexts.Formatting);
}
DataGridViewCellPaintingEventArgs pea = new DataGridViewCellPaintingEventArgs (DataGridView, graphics, clipBounds, cellBounds, rowIndex, columnIndex, cellState, value, formattedvalue, ErrorText, cellStyle, advancedBorderStyle, paintParts);
return false;
if (value == trueValue)
return true;
+ if (value == DBNull.Value)
+ return false;
return Convert.ToBoolean (value);
}
}
}
- public override string ToString () {
- throw new NotImplementedException();
+ public override string ToString ()
+ {
+ return string.Format ("DataGridViewCheckBoxColumn {{ Name={0}, Index={1} }}", Name, Index);
}
}
}
public override int GetHashCode () {
- throw new NotImplementedException();
+ return base.GetHashCode ();
}
public override bool IsDefaultAttribute () {
// Postpaint
DataGridViewPaintParts post = DataGridViewPaintParts.Border;
+
+ if (this is DataGridViewTopLeftHeaderCell)
+ post |= DataGridViewPaintParts.ErrorIcon;
+
post = post & paintParts;
base.Paint (graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, post);
get { return state; }
}
- protected virtual void OnDataGridViewChanged () {
- throw new NotImplementedException();
+ protected virtual void OnDataGridViewChanged ()
+ {
}
protected void RaiseCellClick (DataGridViewCellEventArgs e) {
if (headerCell != value) {
headerCell = value;
headerCell.SetOwningRow (this);
+
if (DataGridView != null) {
+ headerCell.SetDataGridView (DataGridView);
DataGridView.OnRowHeaderCellChanged(new DataGridViewRowEventArgs(this));
}
}
public override object Clone ()
{
- DataGridViewRow row = (DataGridViewRow) MemberwiseClone();
- row.HeaderCell.SetOwningRow (row);
- row.cells = new DataGridViewCellCollection(row);
- foreach (DataGridViewCell cell in cells) {
- row.cells.Add(cell.Clone() as DataGridViewCell);
- }
+ DataGridViewRow row = (DataGridViewRow)MemberwiseClone ();
+
+ row.HeaderCell = (DataGridViewRowHeaderCell)HeaderCell.Clone ();
+ row.SetIndex (-1);
+
+ row.cells = new DataGridViewCellCollection (row);
+
+ foreach (DataGridViewCell cell in cells)
+ row.cells.Add (cell.Clone () as DataGridViewCell);
+
+ row.SetDataGridView (null);
+
return row;
}
for (int i = DataGridView.first_col_index; i < sortedColumns.Count; i++) {
DataGridViewColumn col = sortedColumns[i];
+ if (!col.Visible)
+ continue;
+
if (!col.Displayed)
break;
private bool CanBeShared (DataGridViewRow row)
{
- foreach (DataGridViewCell cell in row.Cells) {
- if (cell.Value != null)
- return false;
- if (cell.ToolTipText != string.Empty)
- return false;
- if (cell.ContextMenuStrip != null)
- return false;
- }
-
- return true;
+ // We don't currently support shared rows
+ return false;
+
+ //foreach (DataGridViewCell cell in row.Cells) {
+ // if (cell.Value != null)
+ // return false;
+ // if (cell.ToolTipText != string.Empty)
+ // return false;
+ // if (cell.ContextMenuStrip != null)
+ // return false;
+ //}
+
+ //return true;
}
editingControl.EditingControlDataGridView = DataGridView;
editingControl.MaxLength = maxInputLength;
- if (initialFormattedValue == null || (string) initialFormattedValue == "") {
- editingControl.Text = "";
- }
- else {
- editingControl.Text = (string) initialFormattedValue;
- }
+
+ if (initialFormattedValue == null || initialFormattedValue.ToString () == string.Empty)
+ editingControl.Text = string.Empty;
+ else
+ editingControl.Text = initialFormattedValue.ToString ();
+
editingControl.ApplyCellStyleToEditingControl(dataGridViewCellStyle);
editingControl.PrepareEditingControlForEdit(true);
}
namespace System.Windows.Forms {
public class InputLanguageCollection : ReadOnlyCollectionBase {
- #region Local Variables
- internal InputLanguage[] list;
- #endregion // Local Variables
-
#region Private Constructor
internal InputLanguageCollection (InputLanguage[] data)
{
- list = data;
+ base.InnerList.AddRange (data);
}
#endregion // Private Constructor
#region Public Instance Methods
public InputLanguage this [int index] {
get {
- if (index>=list.Length) {
+ if (index >= base.InnerList.Count) {
throw new ArgumentOutOfRangeException("index");
}
- return list[index];
+ return base.InnerList[index] as InputLanguage;
}
}
public bool Contains(InputLanguage value) {
- for (int i=0; i<list.Length; i++) {
- if ((list[i].Culture==value.Culture) && (list[i].LayoutName==value.LayoutName)) {
+ for (int i = 0; i < base.InnerList.Count; i++) {
+ if ((this[i].Culture == value.Culture) && (this[i].LayoutName == value.LayoutName)) {
return true;
}
}
}
public void CopyTo(InputLanguage[] array, int index) {
- if (list.Length>0) {
- Array.Copy(list, 0, array, index, list.Length);
+ if (base.InnerList.Count > 0) {
+ base.InnerList.CopyTo (array, index);
}
}
public int IndexOf(InputLanguage value) {
- for (int i=0; i<list.Length; i++) {
- if ((list[i].Culture==value.Culture) && (list[i].LayoutName==value.LayoutName)) {
+ for (int i = 0; i < base.InnerList.Count; i++) {
+ if ((this[i].Culture == value.Culture) && (this[i].LayoutName == value.LayoutName)) {
return i;
}
}
protected internal virtual void OnDropDownItemClicked (ToolStripItemClickedEventArgs e)
{
- ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [DropDownClosedEvent]);
+ ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [DropDownItemClickedEvent]);
if (eh != null)
eh (this, e);
}
return;
}
+ if (this.OwnerItem is ToolStripDropDownItem)
+ (this.OwnerItem as ToolStripDropDownItem).OnDropDownItemClicked (new ToolStripItemClickedEventArgs (this));
+
if (this.IsOnDropDown)
this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
+2008-05-01 Jonathan Pobst <monkey@jpobst.com>
+
+ * DataGridViewRowCollectionTest.cs: Disable test requiring shared rows.
+ * DataGridViewRowTest.cs, DataGridViewCellTest.cs: Disable
+ tests requiring DGVComboBox.
+
+2008-05-01 Jonathan Pobst <monkey@jpobst.com>
+
+ * InputLanguageTest.cs: Add test for bug #385506.
+
2008-04-29 Carlos Alberto Cortez <calberto.cortez@gmail.com>
* BindingSourceTest.cs: New Filter/RemoveFilter tests.
}
[Test]
+ [NUnit.Framework.Category ("NotWorking")] // DGVComboBox not implemented
public void AddRow_Changes ()
{
using (DataGridView dgv = new DataGridView ()) {
}
[Test]
+ [NUnit.Framework.Category ("NotWorking")] // Don't currently support shared rows
public void AddTest ()
{
DataGridViewRow row;
[Test]
+ [NUnit.Framework.Category ("NotWorking")] // DGVComboBox not implemented
public void AddRow_Changes ()
{
Assert.IsNull (row.Tag, "#A row.Tag");
Assert.AreEqual (true, row.Visible, "#A row.Visible");
}
+
+ [Test]
+ public void Clone ()
+ {
+ DataGridView dgv = new DataGridView ();
+
+ dgv.Columns.Add ("Column 1", "Column 1");
+ dgv.Columns.Add ("Column 2", "Column 2");
+
+ dgv.Rows.Add ("Cell 1", "Cell 2");
+
+ DataGridViewRow row1 = dgv.Rows[0];
+
+ row1.ErrorText = "Yikes!";
+ row1.Tag = "Helo";
+ row1.ReadOnly = true;
+ row1.Visible = false;
+
+ DataGridViewRow row2 = (DataGridViewRow)row1.Clone ();
+
+ Assert.AreEqual (2, row2.Cells.Count, "A1");
+ Assert.AreEqual (null, row2.DataGridView, "A3");
+ Assert.AreEqual ("Yikes!", row2.ErrorText, "A4");
+ Assert.AreEqual (-1, row2.HeaderCell.RowIndex, "A5");
+ Assert.AreEqual (-1, row2.Index, "A6");
+ Assert.AreEqual (true, row2.ReadOnly, "A7");
+ Assert.AreEqual ("Helo", row2.Tag, "A8");
+ Assert.AreEqual (false, row2.Visible, "A9");
+ }
}
}
#endif
{
InputLanguage.CurrentInputLanguage = InputLanguage.DefaultInputLanguage;
}
+
+ [Test]
+ public void InstalledInputLanguages_HasAtLeastOneLanguage ()
+ {
+ Assert.IsTrue (InputLanguage.InstalledInputLanguages.Count > 0);
+ }
}
}
#endif
\ No newline at end of file
+2008-05-01 Jb Evain <jbevain@novell.com>
+
+ * System.Core-2008.csproj, System.Core.dll.sources: add new files.
+
2008-03-27 Leonid Freydovich <leonidf@mainsoft.com>
* Add some TARGET_JVM specific code
2007-12-04 Marek Safar <marek.safar@gmail.com>
* System.Core.dll.sources: System.Linq.Expression refresh.
-
+
2007-08-20 Marek Safar <marek.safar@gmail.com>
* Makefile: Hardcoded 3.5 define for now.
* Implemented somme missing stuff in BinaryExpression.
* The stuff in ExpressionUtils is very generic and does quite some
- redundant checks: I started splitting the stuff there into more
+ redundant checks: I started splitting the stuff there into more
"specific" methods that should be both understandable and fast.
* Fixed the StringBuilder problem, added unique IDs to all tests,
2007-03-29 Miguel de Icaza <miguel@novell.com>
* Reapply the patch from Antonello, and rework the code to not use
- extension methods on Enumerable.
+ extension methods on Enumerable.
2007-02-04 Marek Safar <marek.safar@gmail.com>
<Compile Include="System.Linq.Expressions\ParameterExpression.cs" />\r
<Compile Include="System.Linq.Expressions\TypeBinaryExpression.cs" />\r
<Compile Include="System.Linq.Expressions\UnaryExpression.cs" />\r
- <Compile Include="System.Linq\AOrderedEnumerable.cs" />\r
<Compile Include="System.Linq\Check.cs" />\r
+ <Compile Include="System.Linq\QuickSort.cs" />\r
+ <Compile Include="System.Linq\SortSequenceContext.cs" />\r
+ <Compile Include="System.Linq\SortContext.cs" />\r
<Compile Include="System.Linq\Enumerable.cs" />\r
+ <Compile Include="System.Linq\SortDirection.cs" />\r
<Compile Include="System.Linq\Grouping.cs" />\r
<Compile Include="System.Linq\IGrouping.cs" />\r
<Compile Include="System.Linq\ILookup_T.cs" />\r
- <Compile Include="System.Linq\InternalOrderedSequence.cs" />\r
<Compile Include="System.Linq\IOrderedEnumerable_T.cs" />\r
<Compile Include="System.Linq\IOrderedQueryable.cs" />\r
<Compile Include="System.Linq\IOrderedQueryable_T.cs" />\r
<Compile Include="System.Linq\IQueryable_T.cs" />\r
<Compile Include="System.Linq\IQueryProvider.cs" />\r
<Compile Include="System.Linq\Lookup.cs" />\r
+ <Compile Include="System.Linq\OrderedEnumerable.cs" />\r
+ <Compile Include="System.Linq\OrderedSequence.cs" />\r
<Compile Include="System.Linq\Queryable.cs" />\r
<Compile Include="System.Runtime.CompilerServices\ExecutionScope.cs" />\r
<Compile Include="System.Runtime.CompilerServices\ExtensionAttribute.cs" />\r
System.Linq/Enumerable.cs
System.Linq/Grouping.cs
System.Linq/IGrouping.cs
-System.Linq/InternalOrderedSequence.cs
System.Linq/IOrderedQueryable.cs
System.Linq/IOrderedQueryable_T.cs
System.Linq/IOrderedEnumerable_T.cs
System.Linq/IQueryable_T.cs
System.Linq/Lookup.cs
System.Linq/ILookup_T.cs
-System.Linq/AOrderedEnumerable.cs
+System.Linq/OrderedEnumerable.cs
+System.Linq/OrderedSequence.cs
System.Linq/Queryable.cs
+System.Linq/QuickSort.cs
+System.Linq/SortContext.cs
+System.Linq/SortDirection.cs
+System.Linq/SortSequenceContext.cs
System.Linq/IQueryProvider.cs
System.Linq.Expressions/BinaryExpression.cs
System.Linq.Expressions/ConditionalExpression.cs
+++ /dev/null
-//
-// AOrderedEnumerable.cs
-//
-// Authors:
-// Marek Safar <marek.safar@gmail.com>
-//
-// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace System.Linq
-{
- abstract class AOrderedEnumerable<TElement> : IOrderedEnumerable<TElement>
- {
- protected AOrderedEnumerable<TElement> parent;
-
- public abstract IEnumerator<TElement> GetEnumerator ();
- public abstract IEnumerable<TElement> Sort (IEnumerable<TElement> parentSource);
-
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return GetEnumerator ();
- }
-
- public IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey> (
- Func<TElement, TKey> selector, IComparer<TKey> comparer, bool descending)
- {
- parent = new InternalOrderedSequence<TElement, TKey> (this, selector, comparer, descending);
- return parent;
- }
- }
-}
-
+2008-05-01 Jb Evain <jbevain@novell.com>
+
+ * SortDirection.cs, SortContext.cs, SortSequenceContext.cs:
+ new infrastructure files for nested orderby/thenby calls.
+ * QuickSort.cs: refactored out of OrderedSequence.cs
+ * OrderedEnumerable.cs, OrderedSequence.cs: refactoring
+ to use the new SortContext infrastructure.
+
+2008-04-30 Jb Evain <jbevain@novell.com>
+
+ * Enumerable.cs: Average (int|long): properly compute
+ average.
+
2008-04-22 Jb Evain <jbevain@novell.com>
* Enumerable.cs (ToReadOnlyCollection): optimization, use
public static double Average (this IEnumerable<int> source)
{
- return Average (source, (a, b) => a + b, (a, b) => a / b);
+ return Average (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
}
public static double Average (this IEnumerable<long> source)
{
- return Average (source, (a, b) => a + b, (a, b) => a / b);
+ return Average (source, (a, b) => a + b, (a, b) => (double) a / (double) b);
}
public static double Average (this IEnumerable<double> source)
return OrderBy<TSource, TKey> (source, keySelector, null);
}
-
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey> (this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IComparer<TKey> comparer)
{
Check.SourceAndKeySelector (source, keySelector);
- return new InternalOrderedSequence<TSource, TKey> (
- source, keySelector, comparer, false);
+ return new OrderedSequence<TSource, TKey> (
+ source, keySelector, comparer, SortDirection.Ascending);
}
#endregion
return OrderByDescending<TSource, TKey> (source, keySelector, null);
}
-
public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey> (this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
Check.SourceAndKeySelector (source, keySelector);
- return new InternalOrderedSequence<TSource, TKey> (
- source, keySelector, comparer, true);
+ return new OrderedSequence<TSource, TKey> (
+ source, keySelector, comparer, SortDirection.Descending);
}
#endregion
return ThenBy<TSource, TKey> (source, keySelector, null);
}
-
public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey> (this IOrderedEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
return ThenByDescending<TSource, TKey> (source, keySelector, null);
}
-
public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey> (this IOrderedEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
+++ /dev/null
-//
-// InternalOrderedSequence.cs
-//
-// Authors:
-// Alejandro Serrano "Serras" (trupill@yahoo.es)
-// Marek Safar <marek.safar@gmail.com>
-//
-// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace System.Linq
-{
- sealed class InternalOrderedSequence<TElement, TKey> : AOrderedEnumerable<TElement>
- {
- readonly IEnumerable<TElement> source;
- readonly Func<TElement, TKey> key_selector;
- readonly IComparer<TKey> comparer;
- readonly bool descending;
-
- internal InternalOrderedSequence (IEnumerable<TElement> source, Func<TElement, TKey> keySelector,
- IComparer<TKey> comparer, bool descending)
- {
- this.source = source;
- this.key_selector = keySelector;
- this.comparer = comparer ?? Comparer<TKey>.Default;
- this.descending = descending;
- }
-
- public override IEnumerable<TElement> Sort (IEnumerable<TElement> parentSource)
- {
- if (parent != null)
- return parent.Sort (source);
- return PerformSort (parentSource);
- }
-
- public override IEnumerator<TElement> GetEnumerator ()
- {
- return PerformSort (source).GetEnumerator ();
- }
-
- List<TElement> source_list;
- TKey[] keys;
- int[] indexes;
-
- IEnumerable<TElement> PerformSort (IEnumerable<TElement> items)
- {
- // It first enumerates source, collecting all elements
- source_list = new List<TElement> (items);
-
- // If the source contains just zero or one element, there's no need to sort
- if (source_list.Count <= 1)
- return source_list;
-
- // Then evaluate the keySelector function for each element,
- // collecting the key values
- keys = new TKey [source_list.Count];
- indexes = new int [source_list.Count];
- for (int i = 0; i < source_list.Count; i++) {
- keys [i] = key_selector (source_list [i]);
- indexes [i] = i;
- }
-
- // Then sorts the elements according to the collected
- // key values and the selected ordering
- QuickSort(0, indexes.Length - 1);
-
- // Return the values as IEnumerable<TElement>
- TElement[] orderedList = new TElement [indexes.Length];
- for (int i = 0; i < indexes.Length; i++)
- orderedList [i] = source_list [indexes [i]];
- return orderedList;
- }
-
- int CompareItems (int firstIndex, int secondIndex)
- {
- int comparison = comparer.Compare (keys [firstIndex], keys [secondIndex]);
-
- // If descending, return the opposite comparison
- return (descending ? -comparison : comparison);
- }
-
- // We look at the first, middle, and last items in the subarray.
- // Then we put the largest on the right side, the smallest on
- // the left side, and the median becomes our pivot.
- int MedianOfThree (int left, int right)
- {
- int center = (left + right) / 2;
- if (CompareItems (indexes [center], indexes [left]) < 0)
- Swap (left, center);
- if (CompareItems (indexes [right], indexes [left]) < 0)
- Swap (left, right);
- if (CompareItems (indexes [right], indexes [center]) < 0)
- Swap (center, right);
- Swap (center, right - 1);
- return indexes [right - 1];
- }
-
- void QuickSort (int left, int right)
- {
- if (left + 3 <= right) {
- int l = left, r = right - 1, pivot = MedianOfThree (left, right);
- while (true) {
- while (CompareItems (indexes [++l], pivot) < 0) {}
- while (CompareItems (indexes [--r], pivot) > 0) {}
- if (l < r)
- Swap (l, r);
- else
- break;
- }
- // Restore pivot
- Swap (l, right - 1);
- // Partition and sort
- QuickSort (left, l - 1);
- QuickSort (l + 1, right);
- } else
- // If there are three items in the subarray, insertion sort is better
- InsertionSort (left, right);
- }
-
- void InsertionSort (int left, int right)
- {
- for (int i = left + 1; i <= right; i++) {
- int j, tmp = indexes [i];
- for (j = i; j > left && CompareItems (tmp, indexes [j - 1]) < 0; j--)
- indexes [j] = indexes [j - 1];
- indexes [j] = tmp;
- }
- }
-
- void Swap (int left, int right)
- {
- int temp = indexes [right];
- indexes [right] = indexes [left];
- indexes [left] = temp;
- }
-
- }
-}
--- /dev/null
+//
+// OrderedEnumerable.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+// Jb Evain <jbevain@novell.com>
+//
+// Copyright (C) 2007 - 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System.Linq {
+
+ abstract class OrderedEnumerable<TElement> : IOrderedEnumerable<TElement> {
+
+ IEnumerable<TElement> source;
+
+ protected OrderedEnumerable (IEnumerable<TElement> source)
+ {
+ this.source = source;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+
+ public IEnumerator<TElement> GetEnumerator ()
+ {
+ return Sort (source).GetEnumerator ();
+ }
+
+ public abstract SortContext<TElement> CreateContext (SortContext<TElement> current);
+
+ protected abstract IEnumerable<TElement> Sort (IEnumerable<TElement> source);
+
+ public IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey> (
+ Func<TElement, TKey> selector, IComparer<TKey> comparer, bool descending)
+ {
+ return new OrderedSequence<TElement, TKey> (this, source, selector, comparer,
+ descending ? SortDirection.Descending : SortDirection.Ascending);
+ }
+ }
+}
--- /dev/null
+//
+// OrderedSequence.cs
+//
+// Authors:
+// Alejandro Serrano "Serras" (trupill@yahoo.es)
+// Marek Safar <marek.safar@gmail.com>
+// Jb Evain <jbevain@novell.com>
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System.Linq {
+
+ class OrderedSequence<TElement, TKey> : OrderedEnumerable<TElement> {
+
+ OrderedEnumerable<TElement> parent;
+
+ Func<TElement, TKey> selector;
+ IComparer<TKey> comparer;
+ SortDirection direction;
+
+ internal OrderedSequence (IEnumerable<TElement> source, Func<TElement, TKey> key_selector, IComparer<TKey> comparer, SortDirection direction)
+ : base (source)
+ {
+ this.selector = key_selector;
+ this.comparer = comparer ?? Comparer<TKey>.Default;
+ this.direction = direction;
+ }
+
+ internal OrderedSequence (OrderedEnumerable<TElement> parent, IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, SortDirection direction)
+ : this (source, keySelector, comparer, direction)
+ {
+ this.parent = parent;
+ }
+
+ public override SortContext<TElement> CreateContext (SortContext<TElement> current)
+ {
+ SortContext<TElement> context = new SortSequenceContext<TElement, TKey> (selector, comparer, direction, current);
+
+ if (parent != null)
+ return parent.CreateContext (context);
+
+ return context;
+ }
+
+ protected override IEnumerable<TElement> Sort (IEnumerable<TElement> source)
+ {
+ return QuickSort<TElement>.Sort (source, CreateContext (null));
+ }
+ }
+}
--- /dev/null
+//
+// QuickSort.cs
+//
+// Authors:
+// Alejandro Serrano "Serras" (trupill@yahoo.es)
+// Marek Safar <marek.safar@gmail.com>
+// Jb Evain (jbevain@novell.com)
+//
+// (C) 2007 - 2008 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+
+namespace System.Linq {
+
+ class QuickSort<TElement> {
+
+ TElement [] elements;
+ int [] indexes;
+ SortContext<TElement> context;
+
+ QuickSort (IEnumerable<TElement> source, SortContext<TElement> context)
+ {
+ this.elements = source.ToArray ();
+ this.indexes = CreateIndexes (elements.Length);
+ this.context = context;
+ }
+
+ static int [] CreateIndexes (int length)
+ {
+ var indexes = new int [length];
+ for (int i = 0; i < length; i++)
+ indexes [i] = i;
+
+ return indexes;
+ }
+
+ void PerformSort ()
+ {
+ // If the source contains just zero or one element, there's no need to sort
+ if (elements.Length <= 1)
+ return;
+
+ context.Initialize (elements);
+
+ // Then sorts the elements according to the collected
+ // key values and the selected ordering
+ Sort (0, indexes.Length - 1);
+ }
+
+ int CompareItems (int first_index, int second_index)
+ {
+ return context.Compare (first_index, second_index);
+ }
+
+ // We look at the first, middle, and last items in the subarray.
+ // Then we put the largest on the right side, the smallest on
+ // the left side, and the median becomes our pivot.
+ int MedianOfThree (int left, int right)
+ {
+ int center = (left + right) / 2;
+ if (CompareItems (indexes [center], indexes [left]) < 0)
+ Swap (left, center);
+ if (CompareItems (indexes [right], indexes [left]) < 0)
+ Swap (left, right);
+ if (CompareItems (indexes [right], indexes [center]) < 0)
+ Swap (center, right);
+ Swap (center, right - 1);
+ return indexes [right - 1];
+ }
+
+ void Sort (int left, int right)
+ {
+ if (left + 3 <= right) {
+ int l = left, r = right - 1, pivot = MedianOfThree (left, right);
+ while (true) {
+ while (CompareItems (indexes [++l], pivot) < 0) { }
+ while (CompareItems (indexes [--r], pivot) > 0) { }
+ if (l < r)
+ Swap (l, r);
+ else
+ break;
+ }
+
+ // Restore pivot
+ Swap (l, right - 1);
+ // Partition and sort
+ Sort (left, l - 1);
+ Sort (l + 1, right);
+ } else
+ // If there are three items in the subarray, insertion sort is better
+ InsertionSort (left, right);
+ }
+
+ void InsertionSort (int left, int right)
+ {
+ for (int i = left + 1; i <= right; i++) {
+ int j, tmp = indexes [i];
+
+ for (j = i; j > left && CompareItems (tmp, indexes [j - 1]) < 0; j--)
+ indexes [j] = indexes [j - 1];
+
+ indexes [j] = tmp;
+ }
+ }
+
+ void Swap (int left, int right)
+ {
+ int temp = indexes [right];
+ indexes [right] = indexes [left];
+ indexes [left] = temp;
+ }
+
+ public static IEnumerable<TElement> Sort (IEnumerable<TElement> source, SortContext<TElement> context)
+ {
+ var sorter = new QuickSort<TElement> (source, context);
+
+ sorter.PerformSort ();
+
+ for (int i = 0; i < sorter.indexes.Length; i++)
+ yield return sorter.elements [sorter.indexes [i]];
+ }
+ }
+}
--- /dev/null
+//
+// SortContext.cs
+//
+// Author:
+// Jb Evain (jbevain@novell.com)
+//
+// (C) 2008 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Linq {
+
+ abstract class SortContext<TElement> {
+
+ protected SortDirection direction;
+ protected SortContext<TElement> child_context;
+
+ protected SortContext (SortDirection direction, SortContext<TElement> child_context)
+ {
+ this.direction = direction;
+ this.child_context = child_context;
+ }
+
+ public abstract void Initialize (TElement [] elements);
+
+ public abstract int Compare (int first_index, int second_index);
+ }
+}
--- /dev/null
+//
+// SortDirection.cs
+//
+// Author:
+// Jb Evain (jbevain@novell.com)
+//
+// (C) 2008 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Linq {
+
+ enum SortDirection {
+ Ascending,
+ Descending
+ }
+}
--- /dev/null
+//
+// SortSequenceContext.cs
+//
+// Author:
+// Jb Evain (jbevain@novell.com)
+//
+// (C) 2008 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+
+namespace System.Linq {
+
+ class SortSequenceContext<TElement, TKey> : SortContext<TElement> {
+
+ Func<TElement, TKey> selector;
+ IComparer<TKey> comparer;
+
+ TKey [] keys;
+
+ public SortSequenceContext (Func<TElement, TKey> selector, IComparer<TKey> comparer, SortDirection direction, SortContext<TElement> child_context)
+ : base (direction, child_context)
+ {
+ this.selector = selector;
+ this.comparer = comparer;
+ }
+
+ public override void Initialize (TElement [] elements)
+ {
+ if (child_context != null)
+ child_context.Initialize (elements);
+
+ keys = new TKey [elements.Length];
+ for (int i = 0; i < keys.Length; i++)
+ keys [i] = selector (elements [i]);
+ }
+
+ public override int Compare (int first_index, int second_index)
+ {
+ int comparison = comparer.Compare (keys [first_index], keys [second_index]);
+
+ if (comparison == 0 && child_context != null)
+ comparison = child_context.Compare (first_index, second_index);
+
+ return direction == SortDirection.Descending ? -comparison : comparison;
+ }
+ }
+}
Assert.IsNotNull (c.Method);
}
+ [Test]
+ [Category ("NotWorking")]
+ public void CompileConvertClassWithExplicitOp ()
+ {
+ var p = Expression.Parameter (typeof (Klang), "klang");
+ var c = Expression.Lambda<Func<Klang, int>> (
+ Expression.Convert (p, typeof (int)), p).Compile ();
+
+ Assert.AreEqual (42, c (new Klang (42)));
+ }
+
[Test]
public void ConvertClassWithExplicitOpToNullableInt ()
{
Assert.IsNotNull (c.Method);
}
- class Kling {
+ struct Kling {
int i;
public Kling (int i)
}
[Test]
- public void ConvertClassWithImplicitOp ()
+ public void ConvertStructWithImplicitOp ()
{
var c = Expression.Convert (Expression.Parameter (typeof (Kling), ""), typeof (int));
Assert.AreEqual (typeof (int), c.Type);
}
[Test]
- public void ConvertClassWithImplicitOpToNullableInt ()
+ [Category ("NotWorking")]
+ public void CompileConvertStructWithImplicitOp ()
+ {
+ var p = Expression.Parameter (typeof (Kling), "kling");
+ var c = Expression.Lambda<Func<Kling, int>> (
+ Expression.Convert (p, typeof (int)), p).Compile ();
+
+ Assert.AreEqual (42, c (new Kling (42)));
+ }
+
+ [Test]
+ public void ConvertStructWithImplicitOpToNullableInt ()
{
var c = Expression.Convert (Expression.Parameter (typeof (Kling), ""), typeof (int?));
Assert.AreEqual (typeof (int?), c.Type);
Assert.IsNotNull (c.Method);
}
+ [Test]
+ [Category ("NotWorking")]
+ public void ConvertNullableStructWithImplicitOpToNullableInt ()
+ {
+ var c = Expression.Convert (Expression.Parameter (typeof (Kling?), ""), typeof (int?));
+ Assert.AreEqual (typeof (int?), c.Type);
+ Assert.IsTrue (c.IsLifted);
+ Assert.IsTrue (c.IsLiftedToNull);
+ Assert.IsNotNull (c.Method);
+ }
+
[Test]
public void CompiledBoxing ()
{
Assert.AreEqual (b, foo);
}
+ [Test]
+ [Category ("NotWorking")]
+ public void CompileNotNullableToNullable ()
+ {
+ var p = Expression.Parameter (typeof (int), "i");
+ var c = Expression.Lambda<Func<int, int?>> (
+ Expression.Convert (p, typeof (int?)), p).Compile ();
+
+ Assert.AreEqual ((int?) 0, c (0));
+ Assert.AreEqual ((int?) 42, c (42));
+ }
+
+ [Test]
+ [Category ("NotWorking")]
+ public void CompileNullableToNotNullable ()
+ {
+ var p = Expression.Parameter (typeof (int?), "i");
+ var c = Expression.Lambda<Func<int?, int>> (
+ Expression.Convert (p, typeof (int)), p).Compile ();
+
+ Assert.AreEqual (0, c ((int?) 0));
+ Assert.AreEqual (42, c ((int?) 42));
+
+ Action a = () => c (null);
+
+ a.AssertThrows (typeof (InvalidOperationException));
+ }
+
[Test]
public void CompiledConvertToSameType ()
{
{
return Expression.Constant (t);
}
+
+ public static void AssertThrows (this Action action, Type type)
+ {
+ try {
+ action ();
+ Assert.Fail ();
+ } catch (Exception e) {
+ if (e.GetType () != type)
+ Assert.Fail ();
+ }
+ }
}
}
+2008-04-30 Jb Evain <jbevain@novell.com>
+
+ * EnumerableTest.cs: tests for average on int and long.
+
2008-04-22 Leonid Freydovich <leonidf@mainsoft.com>
* QueryableProviderTest.cs: add simple test for Queryable.
Assert.AreEqual (typeof (int []), array.GetType ());
}
-
- [Test]
- public void TestOrderBy ()
- {
- int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 };
- var q = from i in array
- orderby i
- select i;
- AssertIsOrdered (q);
- }
-
- static void AssertIsOrdered (IEnumerable<int> e)
- {
- int f = int.MinValue;
- foreach(int i in e) {
- Assert.IsTrue (f <= i);
- f = i;
- }
- }
+
+ [Test]
+ public void TestAverageOnInt32 ()
+ {
+ Assert.AreEqual (23.25, (new int [] { 24, 7, 28, 34 }).Average ());
+ }
+
+ [Test]
+ public void TestAverageOnInt64 ()
+ {
+ Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ());
+ }
+
+ [Test]
+ public void TestOrderBy ()
+ {
+ int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 };
+ var q = from i in array
+ orderby i
+ select i;
+ AssertIsOrdered (q);
+ }
+
+ class Baz {
+ string name;
+ int age;
+
+ public string Name
+ {
+ get {
+ if (string.IsNullOrEmpty (name))
+ return Age.ToString ();
+
+ return name + " (" + Age + ")";
+ }
+ }
+
+ public int Age
+ {
+ get { return age + 1; }
+ }
+
+ public Baz (string name, int age)
+ {
+ this.name = name;
+ this.age = age;
+ }
+
+ public override int GetHashCode ()
+ {
+ return this.Age ^ this.Name.GetHashCode ();
+ }
+
+ public override bool Equals (object obj)
+ {
+ Baz b = obj as Baz;
+ if (b == null)
+ return false;
+
+ return b.Age == this.Age && b.Name == this.Name;
+ }
+
+ public override string ToString ()
+ {
+ return this.Name;
+ }
+ }
+
+ static IEnumerable<Baz> CreateBazCollection ()
+ {
+ return new [] {
+ new Baz ("jb", 25),
+ new Baz ("ana", 20),
+ new Baz ("reg", 28),
+ new Baz ("ro", 25),
+ new Baz ("jb", 7),
+ };
+ }
+
+ [Test]
+ public void TestOrderByAgeAscendingTheByNameDescending ()
+ {
+ var q = from b in CreateBazCollection ()
+ orderby b.Age ascending, b.Name descending
+ select b;
+
+ var expected = new [] {
+ new Baz ("jb", 7),
+ new Baz ("ana", 20),
+ new Baz ("ro", 25),
+ new Baz ("jb", 25),
+ new Baz ("reg", 28),
+ };
+
+ AssertAreSame (expected, q);
+ }
+
+ static void AssertIsOrdered (IEnumerable<int> e)
+ {
+ int f = int.MinValue;
+ foreach(int i in e) {
+ Assert.IsTrue (f <= i);
+ f = i;
+ }
+ }
static void AssertAreSame<T> (IEnumerable<T> expected, IEnumerable<T> actual)
{
-using System;\r
-using System.Text;\r
-using System.Collections;\r
-using System.Collections.Generic;\r
-using System.Linq;\r
-using System.Linq.Expressions;\r
-using System.Reflection;\r
-using NUnit.Framework;\r
-\r
-\r
-namespace MonoTests.System.Linq\r
-{\r
-\r
- [TestFixture]\r
- public class QueryableProviderTest\r
- {\r
- QueryProvider _provider;\r
-\r
- Query<int> _src;\r
-\r
- int [] _array = { 1, 2, 3 };\r
- int [] _otherArray = { 0, 2 };\r
-\r
- public QueryableProviderTest ()\r
- {\r
- _provider = new QueryProvider ();\r
- _src = new Query<int> (_provider, _array);\r
-\r
- }\r
-\r
- [SetUp]\r
- public void MyTestCleanup ()\r
- {\r
- _provider.Init ();\r
- }\r
-\r
- [Test]\r
- public void TestAggregate ()\r
- {\r
- _src.Aggregate<int> ((n, m) => n + m);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
-\r
- }\r
-\r
- [Test]\r
- public void TestAll ()\r
- {\r
- _src.All<int> ((n) => true);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestAny ()\r
- {\r
- _src.Any<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestAverage ()\r
- {\r
- _src.Average<int> ((n) => n);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestCast ()\r
- {\r
- _src.Cast<int> ();\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestConcat ()\r
- {\r
- _src.Concat<int> (_otherArray);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestContains ()\r
- {\r
- _src.Contains<int> (3);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
-\r
- [Test]\r
- public void TestCount ()\r
- {\r
- _src.Count<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestDefaultIfEmpty ()\r
- {\r
- _src.DefaultIfEmpty<int> (0);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestDistinct ()\r
- {\r
- _src.Distinct<int> ();\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestElementAt ()\r
- {\r
- _src.ElementAt<int> (1);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestElementAtOrDefault ()\r
- {\r
- _src.ElementAtOrDefault<int> (1);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestExcept ()\r
- {\r
- _src.Except<int> (_otherArray);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestFirst ()\r
- {\r
- _src.First<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestFirstOrDefault ()\r
- {\r
- _src.FirstOrDefault<int> ((n) => n > 1);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestGroupBy ()\r
- {\r
- _src.GroupBy<int, bool> ((n) => n > 2);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestGroupJoin ()\r
- {\r
- _src.GroupJoin<int, int, bool, int> (_otherArray, (n) => n > 1, (n) => n > 1, (n, col) => n);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestIntersect ()\r
- {\r
- _src.Intersect<int> (_otherArray);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestJoin ()\r
- {\r
- _src.Join<int, int, int, int> (_otherArray, (n) => n, (n => n), (n, m) => n + m);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestLast ()\r
- {\r
- _src.Last<int> ((n) => n > 1);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestLastOrDefault ()\r
- {\r
- _src.LastOrDefault<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestLongCount ()\r
- {\r
- _src.LongCount<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestMax ()\r
- {\r
- _src.Max<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestMin ()\r
- {\r
- _src.Min<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestOfType ()\r
- {\r
- _src.OfType<int> ();\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestOrderBy ()\r
- {\r
- _src.OrderBy<int, bool> ((n) => n > 1);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestOrderByDescending ()\r
- {\r
- _src.OrderByDescending<int, bool> ((n) => n > 1);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestReverse ()\r
- {\r
- _src.Reverse<int> ();\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSelect ()\r
- {\r
- _src.Select<int, int> ((n) => n);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSelectMany ()\r
- {\r
- _src.SelectMany<int, int> ((n) => new int [] { n });\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSequenceEqual ()\r
- {\r
- _src.SequenceEqual<int> (_otherArray);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSingle ()\r
- {\r
- (new Query<int> (_provider, new int [] { 1 })).Single<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSingleOrDefault ()\r
- {\r
- (new Query<int> (_provider, new int [] { 1 })).SingleOrDefault<int> ();\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSkip ()\r
- {\r
- _src.Skip<int> (1);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSkipWhile ()\r
- {\r
- _src.SkipWhile<int> ((n) => n > 1);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestSum ()\r
- {\r
- _src.Sum<int> ((n) => n);\r
- Assert.AreEqual (StatusEnum.Execute, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestTake ()\r
- {\r
- _src.Take<int> (3);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
-\r
- [Test]\r
- public void TestTakeWhile ()\r
- {\r
- _src.TakeWhile<int> ((n) => n < 2);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestThenBy ()\r
- {\r
- _src.ThenBy<int, bool> ((n) => n < 2);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestThenByDescending ()\r
- {\r
- _src.ThenByDescending<int, bool> ((n) => n < 2);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestUnion ()\r
- {\r
- _src.Union<int> (_otherArray);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- [Test]\r
- public void TestWhere ()\r
- {\r
- _src.Where<int> ((n) => true);\r
- Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);\r
- }\r
-\r
- public class Query<T> : IQueryable<T>, IQueryable, IEnumerable<T>, IEnumerable, IOrderedQueryable<T>, IOrderedQueryable\r
- {\r
- IQueryProvider provider;\r
-\r
- Expression expression;\r
-\r
- IEnumerable<T> _context;\r
-\r
- public Query (IQueryProvider provider, IEnumerable<T> context)\r
- {\r
- _context = context;\r
- this.provider = provider;\r
- this.expression = Expression.Constant (this);\r
- }\r
-\r
- Expression IQueryable.Expression\r
- {\r
-\r
- get { return this.expression; }\r
-\r
- }\r
-\r
-\r
-\r
- Type IQueryable.ElementType\r
- {\r
-\r
- get { return typeof (T); }\r
-\r
- }\r
-\r
-\r
- IQueryProvider IQueryable.Provider\r
- {\r
-\r
- get { return this.provider; }\r
-\r
- }\r
-\r
-\r
- public IEnumerator<T> GetEnumerator ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- IEnumerator IEnumerable.GetEnumerator ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- }\r
-\r
- public enum StatusEnum { NotInitilized, Execute, CreateQuery }\r
-\r
- public class QueryProvider : IQueryProvider\r
- {\r
-\r
- private StatusEnum _status = StatusEnum.NotInitilized;\r
-\r
- public StatusEnum Status\r
- {\r
- get { return _status; }\r
- set { _status = value; }\r
- }\r
-\r
- public void Init ()\r
- {\r
- _status = StatusEnum.NotInitilized;\r
- }\r
-\r
- public QueryProvider ()\r
- {\r
- Init ();\r
- }\r
-\r
- #region IQueryProvider Members\r
-\r
- IQueryable<S> IQueryProvider.CreateQuery<S> (Expression expression)\r
- {\r
- Status = StatusEnum.CreateQuery;\r
- return null;\r
- }\r
-\r
- IQueryable IQueryProvider.CreateQuery (Expression expression)\r
- {\r
- Status = StatusEnum.CreateQuery;\r
- return null;\r
-\r
- }\r
-\r
- S IQueryProvider.Execute<S> (Expression expression)\r
- {\r
- Status = StatusEnum.Execute;\r
- return default (S);\r
- }\r
-\r
-\r
-\r
- object IQueryProvider.Execute (Expression expression)\r
- {\r
- Status = StatusEnum.Execute;\r
- return null;\r
-\r
- }\r
-\r
- #endregion\r
- }\r
- }\r
-}\r
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using NUnit.Framework;
+
+
+namespace MonoTests.System.Linq
+{
+
+ [TestFixture]
+ public class QueryableProviderTest
+ {
+ QueryProvider _provider;
+
+ Query<int> _src;
+
+ int [] _array = { 1, 2, 3 };
+ int [] _otherArray = { 0, 2 };
+
+ public QueryableProviderTest ()
+ {
+ _provider = new QueryProvider ();
+ _src = new Query<int> (_provider, _array);
+
+ }
+
+ [SetUp]
+ public void MyTestCleanup ()
+ {
+ _provider.Init ();
+ }
+
+ [Test]
+ public void TestAggregate ()
+ {
+ _src.Aggregate<int> ((n, m) => n + m);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+
+ }
+
+ [Test]
+ public void TestAll ()
+ {
+ _src.All<int> ((n) => true);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestAny ()
+ {
+ _src.Any<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestAverage ()
+ {
+ _src.Average<int> ((n) => n);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestCast ()
+ {
+ _src.Cast<int> ();
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestConcat ()
+ {
+ _src.Concat<int> (_otherArray);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestContains ()
+ {
+ _src.Contains<int> (3);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+
+ [Test]
+ public void TestCount ()
+ {
+ _src.Count<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestDefaultIfEmpty ()
+ {
+ _src.DefaultIfEmpty<int> (0);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestDistinct ()
+ {
+ _src.Distinct<int> ();
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestElementAt ()
+ {
+ _src.ElementAt<int> (1);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestElementAtOrDefault ()
+ {
+ _src.ElementAtOrDefault<int> (1);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestExcept ()
+ {
+ _src.Except<int> (_otherArray);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestFirst ()
+ {
+ _src.First<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestFirstOrDefault ()
+ {
+ _src.FirstOrDefault<int> ((n) => n > 1);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestGroupBy ()
+ {
+ _src.GroupBy<int, bool> ((n) => n > 2);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestGroupJoin ()
+ {
+ _src.GroupJoin<int, int, bool, int> (_otherArray, (n) => n > 1, (n) => n > 1, (n, col) => n);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestIntersect ()
+ {
+ _src.Intersect<int> (_otherArray);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestJoin ()
+ {
+ _src.Join<int, int, int, int> (_otherArray, (n) => n, (n => n), (n, m) => n + m);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestLast ()
+ {
+ _src.Last<int> ((n) => n > 1);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestLastOrDefault ()
+ {
+ _src.LastOrDefault<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestLongCount ()
+ {
+ _src.LongCount<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestMax ()
+ {
+ _src.Max<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestMin ()
+ {
+ _src.Min<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestOfType ()
+ {
+ _src.OfType<int> ();
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestOrderBy ()
+ {
+ _src.OrderBy<int, bool> ((n) => n > 1);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestOrderByDescending ()
+ {
+ _src.OrderByDescending<int, bool> ((n) => n > 1);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestReverse ()
+ {
+ _src.Reverse<int> ();
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestSelect ()
+ {
+ _src.Select<int, int> ((n) => n);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestSelectMany ()
+ {
+ _src.SelectMany<int, int> ((n) => new int [] { n });
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestSequenceEqual ()
+ {
+ _src.SequenceEqual<int> (_otherArray);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestSingle ()
+ {
+ (new Query<int> (_provider, new int [] { 1 })).Single<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestSingleOrDefault ()
+ {
+ (new Query<int> (_provider, new int [] { 1 })).SingleOrDefault<int> ();
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestSkip ()
+ {
+ _src.Skip<int> (1);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestSkipWhile ()
+ {
+ _src.SkipWhile<int> ((n) => n > 1);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestSum ()
+ {
+ _src.Sum<int> ((n) => n);
+ Assert.AreEqual (StatusEnum.Execute, _provider.Status);
+ }
+
+ [Test]
+ public void TestTake ()
+ {
+ _src.Take<int> (3);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+
+ [Test]
+ public void TestTakeWhile ()
+ {
+ _src.TakeWhile<int> ((n) => n < 2);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestThenBy ()
+ {
+ _src.ThenBy<int, bool> ((n) => n < 2);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestThenByDescending ()
+ {
+ _src.ThenByDescending<int, bool> ((n) => n < 2);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestUnion ()
+ {
+ _src.Union<int> (_otherArray);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ [Test]
+ public void TestWhere ()
+ {
+ _src.Where<int> ((n) => true);
+ Assert.AreEqual (StatusEnum.CreateQuery, _provider.Status);
+ }
+
+ public class Query<T> : IQueryable<T>, IQueryable, IEnumerable<T>, IEnumerable, IOrderedQueryable<T>, IOrderedQueryable
+ {
+ IQueryProvider provider;
+
+ Expression expression;
+
+ IEnumerable<T> _context;
+
+ public Query (IQueryProvider provider, IEnumerable<T> context)
+ {
+ _context = context;
+ this.provider = provider;
+ this.expression = Expression.Constant (this);
+ }
+
+ Expression IQueryable.Expression
+ {
+
+ get { return this.expression; }
+
+ }
+
+
+
+ Type IQueryable.ElementType
+ {
+
+ get { return typeof (T); }
+
+ }
+
+
+ IQueryProvider IQueryable.Provider
+ {
+
+ get { return this.provider; }
+
+ }
+
+
+ public IEnumerator<T> GetEnumerator ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ }
+
+ public enum StatusEnum { NotInitilized, Execute, CreateQuery }
+
+ public class QueryProvider : IQueryProvider
+ {
+
+ private StatusEnum _status = StatusEnum.NotInitilized;
+
+ public StatusEnum Status
+ {
+ get { return _status; }
+ set { _status = value; }
+ }
+
+ public void Init ()
+ {
+ _status = StatusEnum.NotInitilized;
+ }
+
+ public QueryProvider ()
+ {
+ Init ();
+ }
+
+ #region IQueryProvider Members
+
+ IQueryable<S> IQueryProvider.CreateQuery<S> (Expression expression)
+ {
+ Status = StatusEnum.CreateQuery;
+ return null;
+ }
+
+ IQueryable IQueryProvider.CreateQuery (Expression expression)
+ {
+ Status = StatusEnum.CreateQuery;
+ return null;
+
+ }
+
+ S IQueryProvider.Execute<S> (Expression expression)
+ {
+ Status = StatusEnum.Execute;
+ return default (S);
+ }
+
+
+
+ object IQueryProvider.Execute (Expression expression)
+ {
+ Status = StatusEnum.Execute;
+ return null;
+
+ }
+
+ #endregion
+ }
+ }
+}
+2008-04-30 Marek Habersack <mhabersack@novell.com>
+
+ * SiteMapDataSource.cs: when no starting node is found, return
+ null instead of Provider.RootNode. Fixes bug #323994
+
2008-04-24 Marek Habersack <mhabersack@novell.com>
* SqlDataSource.cs: raise the DataSourceChangedEvent when setting
starting_node = Provider.RootNode;
if (starting_node == null)
- return Provider.RootNode;
+ return null;
int i;
if (StartingNodeOffset < 0) {
+2008-04-30 Marek Habersack <mhabersack@novell.com>
+
+ * HttpApplication.cs: when the Start method is called in a new
+ thread, the thread's culture and ui culture are set to their
+ defaults, thus ignoring whatever their values were in the parent
+ thread. This is now fixed by passing an array containing the
+ culture values to the Start method, so that the new thread can be
+ properly initialized. Fixes bug #323566
+
+ * SiteMapNode.cs: the implicitResourceKey parameter to one of the
+ constructors sets the value of the ResourceKey property.
+ GetImplicitResourceString uses the provider's ResourceKey as the
+ global resource object key and the node's ResourceKey to construct
+ the resource name. Fixes bug #323994
+ ResourceKey setter throws an InvalidOperationException now, when
+ the node is read-only.
+
2008-04-29 Marek Habersack <mhabersack@novell.com>
* HttpException.cs: safe guard against context being null in
void Start (object x)
{
+ CultureInfo[] cultures = x as CultureInfo[];
+ if (cultures != null && cultures.Length == 2) {
+ Thread ct = Thread.CurrentThread;
+ ct.CurrentCulture = cultures [0];
+ ct.CurrentUICulture = cultures [1];
+ }
+
try {
InitOnce (true);
} catch (Exception e) {
begin_iar = new AsyncRequestState (done, cb, extraData);
+ CultureInfo[] cultures = new CultureInfo [2];
+ cultures [0] = Thread.CurrentThread.CurrentCulture;
+ cultures [1] = Thread.CurrentThread.CurrentUICulture;
+
#if TARGET_JVM
if (true)
#else
#endif
Start (null);
else
- ThreadPool.QueueUserWorkItem (new WaitCallback (Start), null);
+ ThreadPool.QueueUserWorkItem (new WaitCallback (Start), cultures);
return begin_iar;
}
this.roles = roles;
this.attributes = attributes;
this.resourceKeys = explicitResourceKeys;
- this.implicitResourceKey = implicitResourceKey;
+ this.resourceKey = implicitResourceKey;
}
public SiteMapDataSourceView GetDataSourceView (SiteMapDataSource owner, string viewName)
if (attributeName == null)
throw new ArgumentNullException ("attributeName");
- if (String.IsNullOrEmpty (implicitResourceKey))
+ string resourceKey = ResourceKey;
+ if (String.IsNullOrEmpty (resourceKey))
return null;
try {
- string reskey = provider.ResourceKey;
-
- if (!String.IsNullOrEmpty (reskey))
- reskey = reskey + "." + implicitResourceKey + "." + attributeName;
- else
- reskey = String.Concat (implicitResourceKey, ".", attributeName);
- object o = HttpContext.GetGlobalResourceObject ("Web.sitemap", reskey);
+ object o = HttpContext.GetGlobalResourceObject (provider.ResourceKey, resourceKey + "." + attributeName);
if (o is string)
return (string) o;
- }
- catch (MissingManifestResourceException) {
+ } catch (MissingManifestResourceException) {
}
return null;
public string ResourceKey {
get { return resourceKey; }
- set { resourceKey = value; }
+ set {
+ if (ReadOnly)
+ throw new InvalidOperationException ("The node is read-only.");
+ resourceKey = value;
+ }
}
public string Key { get { return key; } }
bool readOnly;
string resourceKey;
SiteMapNode parent;
- string implicitResourceKey;
SiteMapNodeCollection childNodes;
#endregion
+2008-04-30 Atsushi Enomoto <atsushi@ximian.com>
+
+ * XElement.cs, XNode.cs : XNode.ReadFrom() should not reuse
+ XElement.Load() which may create wrapper XmlReader.
+
2008-02-12 Atsushi Enomoto <atsushi@ximian.com>
* XElement.cs : Value is rather a value in XPath semantics than
}
}
- static XElement LoadCore (XmlReader r, LoadOptions options)
+ internal static XElement LoadCore (XmlReader r, LoadOptions options)
{
r.MoveToContent ();
if (r.NodeType != XmlNodeType.Element)
{
switch (r.NodeType) {
case XmlNodeType.Element:
- return XElement.Load (r, options);
+ return XElement.LoadCore (r, options);
case XmlNodeType.Whitespace:
case XmlNodeType.SignificantWhitespace:
case XmlNodeType.Text:
+2008-04-30 Atsushi Enomoto <atsushi@ximian.com>
+
+ * XNodeReaderTest.cs : added CreateReader3().
+
2008-02-12 Atsushi Enomoto <atsushi@ximian.com>
* XElementTest.cs : added test for Value (bug #360858).
Assert.AreEqual (xml.Replace ('\'', '"'), sw.ToString ());
}
+ [Test] // almost identical to CreateReader1().
+ public void CreateReader3 ()
+ {
+ string xml = "<root><foo a='v' /><bar></bar><baz>simple text<!-- comment --><mixed1 /><mixed2><![CDATA[cdata]]><?some-pi with-data ?></mixed2></baz></root>";
+ XDocument doc = XDocument.Parse (xml, LoadOptions.PreserveWhitespace);
+ XmlReader xr = doc.CreateReader ();
+ StringWriter sw = new StringWriter ();
+ XmlWriterSettings s = new XmlWriterSettings ();
+ s.OmitXmlDeclaration = true;
+ XmlWriter xw = XmlWriter.Create (sw, s);
+ while (!xr.EOF)
+ xw.WriteNode (xr, false);
+ xw.Close ();
+ Assert.AreEqual (xml.Replace ('\'', '"'), sw.ToString ());
+ }
+
[Test]
public void GetAttribute ()
{
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * VBCodeGenerator.cs: Fixed generated code for abstract properties.
+
2008-03-13 Rolf Bjarne Kvinge <RKvinge@novell.com>
* VBCodeGenerator.cs: Add quotes around the filename in ExternalSource
++Indent;
if (property.HasGet) {
output.WriteLine ("Get");
- ++Indent;
- GenerateStatements (property.GetStatements);
- --Indent;
- output.WriteLine ("End Get");
+ if (!IsAbstract (property.Attributes)) {
+ ++Indent;
+ GenerateStatements (property.GetStatements);
+ --Indent;
+ output.WriteLine ("End Get");
+ }
}
if (property.HasSet) {
output.WriteLine ("Set");
- ++Indent;
- GenerateStatements (property.SetStatements);
- --Indent;
- output.WriteLine ("End Set");
+ if (!IsAbstract (property.Attributes)) {
+ ++Indent;
+ GenerateStatements (property.SetStatements);
+ --Indent;
+ output.WriteLine ("End Set");
+ }
}
--Indent;
return baseType + "_" + property.Name;
}
+ static bool IsAbstract (MemberAttributes attributes)
+ {
+ return (attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract;
+ }
+
private enum LineHandling
{
InLine,
+2008-04-30 Miguel de Icaza <miguel@novell.com>
+
+ * WebPermission.cs (ToXml): To allow code that uses WebPermission
+ to be built.
+
2008-04-21 Gonzalo Paniagua Javier <gonzalo.mono@gmail.com>
* HttpWebResponse.cs: do not check the disposed status for properties
return root;
}
- [MonoTODO]
private void ToXml (SecurityElement root, string childName, IEnumerator enumerator)
{
- throw new NotImplementedException ();
+ SecurityElement child = new SecurityElement (childName, null);
+
+ root.AddChild (child);
+ while (enumerator.MoveNext ()){
+ WebPermissionInfo x = enumerator.Current as WebPermissionInfo;
+
+ if (x == null) continue;
+
+ SecurityElement uri = new SecurityElement ("URI");
+ uri.AddAttribute ("uri", x.Info);
+ child.AddChild (uri);
+ }
}
public override void FromXml (SecurityElement securityElement)
}
}
- [MonoTODO]
private void FromXml (ArrayList endpoints, NetworkAccess access)
{
throw new NotImplementedException ();
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * CodeGeneratorFromTypeTest.cs: Added tests for static and abstract
+ property.
+
2008-03-13 Rolf Bjarne Kvinge <RKvinge@novell.com>
* CodeGeneratorFromCompileUnitTest.cs: Added ExternalSourceTest.
"End Class{0}", NewLine), code);
}
+ [Test]
+ public void AbstractPropertyTest ()
+ {
+ string code = GenerateAbstractProperty (Options);
+ Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
+ "Public MustInherit Class Test1{0}" +
+ " {0}" +
+#if NET_2_0
+ " Public MustOverride Property Name() As String{0}" +
+#else
+ " Public MustOverride Property Name As String{0}" +
+#endif
+ " Get{0}" +
+ " Set{0}" +
+ " End Property{0}" +
+ "End Class{0}", NewLine), code);
+ }
+
+ [Test]
+ public void StaticPropertyTest ()
+ {
+ string code = GenerateStaticProperty (Options);
+ Assert.AreEqual (string.Format (CultureInfo.InvariantCulture,
+ "Public Class Test1{0}" +
+ " {0}" +
+#if NET_2_0
+ " Public Shared WriteOnly Property Name() As String{0}" +
+#else
+ " Public Shared WriteOnly Property Name As String{0}" +
+#endif
+ " Set{0}" +
+ " End Set{0}" +
+ " End Property{0}" +
+ "End Class{0}", NewLine), code);
+ }
+
[Test]
public override void PropertyMembersTypeTest1 ()
{
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * ExecutorTest.cs: Use Assert.Ignore when ping is not available.
+ Avoid using ExpectedException in ExecWait test, and added link to
+ MS bug report.
+
2008-04-08 Jb Evain <jbevain@novell.com>
* CodeGeneratorFromTypeTestBase.cs: add a generator for
using System.Runtime.InteropServices;
using System.Security.Principal;
-namespace MonoTests.System.CodeDom.Compiler {
-
+namespace MonoTests.System.CodeDom.Compiler
+{
[TestFixture]
- public class ExecutorTest {
-
+ public class ExecutorTest
+ {
private bool posix;
private bool cmdNotFound;
private int errcode;
public void ExecWait_NullTempFileCollection ()
{
if (cmdNotFound)
- throw new NullReferenceException ();
+ Assert.Ignore ("ping command not found.");
+
Executor.ExecWait (cmd, null);
}
[Test]
- [ExpectedException (typeof (ExternalException))]
- [Category ("NotWorking")]
+ [Category ("NotWorking")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=341293
public void ExecWait ()
{
if (cmdNotFound)
- return;
- // why does it fail ? any case that works ?
- Executor.ExecWait (cmd, tfc);
+ Assert.Ignore ("ping command not found.");
+
+ try {
+ Executor.ExecWait (cmd, new TempFileCollection ());
+ Assert.Fail ("#1");
+ } catch (ExternalException ex) {
+ // Cannot execute a program. The command being executed was .
+ Assert.AreEqual (typeof (ExternalException), ex.GetType (), "#2");
+ Assert.AreEqual (2, ex.ErrorCode, "#3");
+ Assert.IsNull (ex.InnerException, "#4");
+ Assert.IsNotNull (ex.Message, "#5");
+ }
}
[Test]
public void ExecWaitWithCapture ()
{
if (cmdNotFound)
- return;
+ Assert.Ignore ("ping command not found.");
+
string output = null;
string error = null;
TempFileCollection tfc = new TempFileCollection ();
public void ExecWaitWithCapture_CurrentDir ()
{
if (cmdNotFound)
- return;
+ Assert.Ignore ("ping command not found.");
+
string output = null;
string error = null;
TempFileCollection tfc = new TempFileCollection ();
public void ExecWaitWithCapture_Token ()
{
if (cmdNotFound)
- return;
+ Assert.Ignore ("ping command not found.");
+
string output = null;
string error = null;
TempFileCollection tfc = new TempFileCollection ();
public void ExecWaitWithCapture_Token_CurrentDir ()
{
if (cmdNotFound)
- return;
+ Assert.Ignore ("ping command not found.");
+
string output = null;
string error = null;
TempFileCollection tfc = new TempFileCollection ();
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * ComponentConverterTests.cs: Allow test to be compiled using csc 1.x.
+
2008-04-16 Marek Habersack <mhabersack@novell.com>
* ComponentConverterTests.cs: added tests for
public void DataSetConversions ()
{
TypeConverter converter = TypeDescriptor.GetConverter (typeof (DataSet));
- Assert.AreEqual (typeof (global::System.ComponentModel.ComponentConverter), converter != null ? converter.GetType () : null, "A1");
+ Assert.AreEqual (typeof (ComponentConverter), converter != null ? converter.GetType () : null, "A1");
DataSet ds = new DataSet ();
string s = (string) converter.ConvertTo (null, CultureInfo.InvariantCulture, ds, typeof (string));
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>>
+
+ * corlib_test.dll.sources: Added ConstructorOnTypeBuilderInstTest.cs.
+
2008-04-26 Gert Driesen <drieseng@users.sourceforge.net>
* corlib_test.dll.sources: Added MethodOnTypeBuilderInstTest.cs.
+2008-05-01 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * ConstructorBuilder.cs: Switch arguments for AORE.
+
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * ModuleBuilder.cs (DefineType): Do not perform lookup of in cache if
+ name is null to allow correct exception to be thrown (in TypeBuilder
+ ctor).
+ * TypeBuilder: Moved name argument check to TypeBuilder ctor. Modified
+ ArgumentException parameter names to match MS. Removed duplicate check
+ for data length from DefineInitializedData. Modified check_name to
+ only throw when first character is null char.
+ * ConstructorBuilder.cs (GetParameters): Throw NotSupportedException
+ (2.0) or InvalidOperationException (1.0) when type is not yet created
+ and we're not in compiler context. Return empty array when no
+ parameters are defined.
+ (MethodHandle): Always throw NotSupportedException.
+ (DefineParameter): Prevent NRE when parameters is null.
+ (GetCustomAttributes): When not in compiler context, always throw
+ NotSupportedException.
+ * ConstructorOnTypeBuilderInst.cs: Delegate to ConstructorBuilder
+ where possible. Fixed ContainsGenericParameters and IsGenericMethod
+ to always return false. In MethodBase.Invoke, throw an
+ InvalidOperationException instead of NIE.
+
2008-04-26 Gert Driesen <drieseng@users.sourceforge.net>
* MethodOnTypeBuilderInst.cs: Added overrides for ReturnType and
private Type[][] paramModOpt;
private RefEmitPermissionSet[] permissions;
- internal ConstructorBuilder (TypeBuilder tb, MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt) {
+ internal ConstructorBuilder (TypeBuilder tb, MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt)
+ {
attrs = attributes | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
call_conv = callingConvention;
if (parameterTypes != null) {
this.paramModOpt = paramModOpt;
table_idx = get_next_table_index (this, 0x06, true);
- ((ModuleBuilder)tb.Module).RegisterToken (this, GetToken ().Token);
+ ((ModuleBuilder) tb.Module).RegisterToken (this, GetToken ().Token);
}
#if NET_2_0
[MonoTODO]
public override CallingConventions CallingConvention {
- get { return call_conv; }
+ get {
+ return call_conv;
+ }
}
#endif
public bool InitLocals {
- get {return init_locals;}
- set {init_locals = value;}
+ get {
+ return init_locals;
+ }
+ set {
+ init_locals = value;
+ }
}
internal TypeBuilder TypeBuilder {
- get {return type;}
+ get {
+ return type;
+ }
}
- public override MethodImplAttributes GetMethodImplementationFlags() {
+ public override MethodImplAttributes GetMethodImplementationFlags ()
+ {
return iattrs;
}
- public override ParameterInfo[] GetParameters() {
+
+ public override ParameterInfo[] GetParameters ()
+ {
+ if (!type.is_created && !IsCompilerContext)
+ throw not_created ();
+
if (parameters == null)
- return null;
+ return new ParameterInfo [0];
ParameterInfo[] retval = new ParameterInfo [parameters.Length];
- for (int i = 0; i < parameters.Length; i++) {
- retval [i] = new ParameterInfo (pinfo == null ? null : pinfo [i+1], parameters [i], this, i + 1);
- }
+ for (int i = 0; i < parameters.Length; i++)
+ retval [i] = new ParameterInfo (pinfo == null ? null
+ : pinfo [i+1], parameters [i], this, i + 1);
return retval;
}
return parameters.Length;
}
- public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
+ public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
throw not_supported ();
}
- public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) {
+
+ public override object Invoke (BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
+ {
throw not_supported ();
}
- public override RuntimeMethodHandle MethodHandle {
+ public override RuntimeMethodHandle MethodHandle {
+ get {
+ throw not_supported ();
+ }
+ }
+
+ public override MethodAttributes Attributes {
+ get {
+ return attrs;
+ }
+ }
+
+ public override Type ReflectedType {
+ get {
+ return type;
+ }
+ }
+
+ public override Type DeclaringType {
get {
- return mhandle;
+ return type;
}
}
- public override MethodAttributes Attributes {
- get {return attrs;}
+ public Type ReturnType {
+ get {
+ return null;
+ }
}
- public override Type ReflectedType { get {return type;}}
- public override Type DeclaringType { get {return type;}}
- public Type ReturnType { get {return null;}}
- public override string Name {
- get {return (attrs & MethodAttributes.Static) != 0 ? ConstructorInfo.TypeConstructorName : ConstructorInfo.ConstructorName;}
+
+ public override string Name {
+ get {
+ return (attrs & MethodAttributes.Static) != 0 ? ConstructorInfo.TypeConstructorName : ConstructorInfo.ConstructorName;
+ }
}
+
public string Signature {
- get {return "constructor signature";}
+ get {
+ return "constructor signature";
+ }
}
- public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) {
+ public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset)
+ {
if (pset == null)
throw new ArgumentNullException ("pset");
if ((action == SecurityAction.RequestMinimum) ||
(action == SecurityAction.RequestOptional) ||
(action == SecurityAction.RequestRefuse))
- throw new ArgumentOutOfRangeException ("Request* values are not permitted", "action");
+ throw new ArgumentOutOfRangeException ("action", "Request* values are not permitted");
RejectIfCreated ();
attrs |= MethodAttributes.HasSecurity;
}
- public ParameterBuilder DefineParameter(int iSequence, ParameterAttributes attributes, string strParamName)
+ public ParameterBuilder DefineParameter (int iSequence, ParameterAttributes attributes, string strParamName)
{
- if ((iSequence < 1) || (iSequence > parameters.Length))
+ if (iSequence < 1 || iSequence > GetParameterCount ())
throw new ArgumentOutOfRangeException ("iSequence");
if (type.is_created)
throw not_after_created ();
return pb;
}
- public override bool IsDefined (Type attribute_type, bool inherit) {
+ public override bool IsDefined (Type attribute_type, bool inherit)
+ {
throw not_supported ();
}
- public override object [] GetCustomAttributes (bool inherit) {
+ public override object [] GetCustomAttributes (bool inherit)
+ {
/*
* On MS.NET, this always returns not_supported, but we can't do this
* since there would be no way to obtain custom attributes of
* dynamically created ctors.
*/
- if (type.is_created)
+ if (type.is_created && IsCompilerContext)
return MonoCustomAttrs.GetCustomAttributes (this, inherit);
else
throw not_supported ();
}
- public override object [] GetCustomAttributes (Type attributeType, bool inherit) {
- if (type.is_created)
+ public override object [] GetCustomAttributes (Type attributeType, bool inherit)
+ {
+ if (type.is_created && IsCompilerContext)
return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
else
throw not_supported ();
}
- public ILGenerator GetILGenerator () {
+ public ILGenerator GetILGenerator ()
+ {
return GetILGenerator (64);
}
#if NET_2_0
public
#else
- internal
+ internal
#endif
- ILGenerator GetILGenerator (int size) {
+ ILGenerator GetILGenerator (int size)
+ {
if (ilgen != null)
return ilgen;
ilgen = new ILGenerator (type.Module, ((ModuleBuilder)type.Module).GetTokenGenerator (), size);
return ilgen;
}
- public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
+ public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
+ {
if (customBuilder == null)
throw new ArgumentNullException ("customBuilder");
#if NET_2_0
[ComVisible (true)]
#endif
- public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
+ public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute)
+ {
if (con == null)
throw new ArgumentNullException ("con");
if (binaryAttribute == null)
SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
}
- public void SetImplementationFlags( MethodImplAttributes attributes) {
+
+ public void SetImplementationFlags (MethodImplAttributes attributes)
+ {
if (type.is_created)
throw not_after_created ();
iattrs = attributes;
}
- public Module GetModule() {
+
+ public Module GetModule ()
+ {
return type.Module;
}
- public MethodToken GetToken() {
+
+ public MethodToken GetToken ()
+ {
return new MethodToken (0x06000000 | table_idx);
}
[MonoTODO]
- public void SetSymCustomAttribute( string name, byte[] data) {
+ public void SetSymCustomAttribute (string name, byte[] data)
+ {
if (type.is_created)
throw not_after_created ();
}
}
#endif
- public override string ToString() {
+ public override string ToString ()
+ {
return "ConstructorBuilder ['" + type.Name + "']";
}
- internal void fixup () {
+ internal void fixup ()
+ {
if (((attrs & (MethodAttributes.Abstract | MethodAttributes.PinvokeImpl)) == 0) && ((iattrs & (MethodImplAttributes.Runtime | MethodImplAttributes.InternalCall)) == 0)) {
if ((ilgen == null) || (ILGenerator.Mono_GetCurrentOffset (ilgen) == 0))
throw new InvalidOperationException ("Method '" + Name + "' does not have a method body.");
}
}
- internal override int get_next_table_index (object obj, int table, bool inc) {
+ internal override int get_next_table_index (object obj, int table, bool inc)
+ {
return type.get_next_table_index (obj, table, inc);
}
- private void RejectIfCreated () {
+ private bool IsCompilerContext {
+ get {
+ ModuleBuilder mb = (ModuleBuilder) TypeBuilder.Module;
+ AssemblyBuilder ab = (AssemblyBuilder) mb.Assembly;
+ return ab.IsCompilerContext;
+ }
+ }
+
+ private void RejectIfCreated ()
+ {
if (type.is_created)
throw new InvalidOperationException ("Type definition of the method is complete.");
}
- private Exception not_supported () {
+ private Exception not_supported ()
+ {
return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
}
- private Exception not_after_created () {
+ private Exception not_after_created ()
+ {
return new InvalidOperationException ("Unable to change after type has been created.");
}
+ private Exception not_created ()
+ {
+#if NET_2_0
+ return new NotSupportedException ("The type is not yet created.");
+#else
+ return new InvalidOperationException ("The type is not yet created.");
+#endif
+ }
+
void _ConstructorBuilder.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException ();
ConstructorBuilder cb;
#endregion
- public ConstructorOnTypeBuilderInst (MonoGenericClass instantiation, ConstructorBuilder cb) {
+ public ConstructorOnTypeBuilderInst (MonoGenericClass instantiation, ConstructorBuilder cb)
+ {
this.instantiation = instantiation;
this.cb = cb;
}
}
}
- public override bool IsDefined (Type attributeType, bool inherit) {
- throw new NotSupportedException ();
+ public override bool IsDefined (Type attributeType, bool inherit)
+ {
+ return cb.IsDefined (attributeType, inherit);
}
- public override object [] GetCustomAttributes (bool inherit) {
- throw new NotSupportedException ();
+ public override object [] GetCustomAttributes (bool inherit)
+ {
+ return cb.GetCustomAttributes (inherit);
}
- public override object [] GetCustomAttributes (Type attributeType, bool inherit) {
- throw new NotSupportedException ();
+ public override object [] GetCustomAttributes (Type attributeType, bool inherit)
+ {
+ return cb.GetCustomAttributes (attributeType, inherit);
}
//
// MethodBase members
//
- public override MethodImplAttributes GetMethodImplementationFlags() {
+ public override MethodImplAttributes GetMethodImplementationFlags ()
+ {
return cb.GetMethodImplementationFlags ();
}
- public override ParameterInfo[] GetParameters() {
- throw new NotImplementedException ();
+ public override ParameterInfo[] GetParameters ()
+ {
+ return cb.GetParameters ();
}
- internal override int GetParameterCount () {
+ internal override int GetParameterCount ()
+ {
return cb.GetParameterCount ();
}
- public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
- throw new NotImplementedException ();
+ public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ return cb.Invoke (obj, invokeAttr, binder, parameters,
+ culture);
}
public override RuntimeMethodHandle MethodHandle {
get {
- throw new NotImplementedException ();
+ return cb.MethodHandle;
}
}
}
}
- public override Type [] GetGenericArguments () {
- throw new NotImplementedException ();
+ public override Type [] GetGenericArguments ()
+ {
+ return cb.GetGenericArguments ();
}
public override bool ContainsGenericParameters {
get {
- // FIXME:
- throw new NotImplementedException ();
+ return false;
}
}
public override bool IsGenericMethod {
get {
- return true;
+ return false;
}
}
//
public override object Invoke (BindingFlags invokeAttr, Binder binder, object[] parameters,
- CultureInfo culture) {
- throw new NotImplementedException ();
+ CultureInfo culture)
+ {
+ throw new InvalidOperationException ();
}
}
}
-#endif
+#endif\r
}
private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packsize, int typesize) {
- if (name_cache.Contains (name))
+ if (name != null && name_cache.Contains (name))
throw new ArgumentException ("Duplicate type name within an assembly.");
TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packsize, typesize, null);
this.class_size = type_size;
this.packing_size = packing_size;
this.nesting_type = nesting_type;
+
+ check_name ("fullname", name);
if (parent == null && (attr & TypeAttributes.Interface) != 0 && (attr & TypeAttributes.Abstract) == 0)
throw new InvalidOperationException ("Interface must be declared abstract.");
private TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces,
PackingSize packsize, int typesize)
{
- check_name ("name", name);
// Visibility must be NestedXXX
/* This breaks mcs
if (((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.Public) ||
!((attributes & MethodAttributes.Abstract) != 0) ||
!((attributes & MethodAttributes.Virtual) != 0)) &&
!(((attributes & MethodAttributes.Static) != 0)))
- throw new ArgumentException ("attributes", "Interface method must be abstract and virtual.");
+ throw new ArgumentException ("Interface method must be abstract and virtual.");
if (returnType == null)
returnType = pmodule.assemblyb.corlib_void_type;
check_name ("dllName", dllName);
check_name ("entryName", entryName);
if ((attributes & MethodAttributes.Abstract) != 0)
- throw new ArgumentException ("attributes", "PInvoke methods must be static and native and cannot be abstract.");
+ throw new ArgumentException ("PInvoke methods must be static and native and cannot be abstract.");
if (IsInterface)
- throw new ArgumentException ("PInvoke methods cannot exist on interfaces.");
+ throw new ArgumentException ("PInvoke methods cannot exist on interfaces.");
check_not_created ();
MethodBuilder res
{
check_name ("fieldName", fieldName);
if (type == typeof (void))
- throw new ArgumentException ("type", "Bad field type in defining field.");
+ throw new ArgumentException ("Bad field type in defining field.");
check_not_created ();
FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes, requiredCustomAttributes, optionalCustomAttributes);
{
check_name ("name", name);
if (eventtype == null)
- throw new ArgumentNullException ("eventtype");
+ throw new ArgumentNullException ("type");
check_not_created ();
EventBuilder res = new EventBuilder (this, name, attributes, eventtype);
public FieldBuilder DefineInitializedData (string name, byte[] data, FieldAttributes attributes) {
if (data == null)
throw new ArgumentNullException ("data");
- if ((data.Length == 0) || (data.Length > 0x3f0000))
- throw new ArgumentException ("data", "Data size must be > 0 and < 0x3f0000");
FieldBuilder res = DefineUninitializedData (name, data.Length, attributes);
res.SetRVAData (data);
-
return res;
}
static int UnmanagedDataCount = 0;
public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes)
- {
- check_name ("name", name);
+ {
+ if (name == null)
+ throw new ArgumentNullException ("name");
+ if (name.Length == 0)
+ throw new ArgumentException ("Empty name is not legal", "name");
if ((size <= 0) || (size > 0x3f0000))
- throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
+ throw new ArgumentException ("Data size must be > 0 and < 0x3f0000");
check_not_created ();
string typeName = "$ArrayType$" + size;
throw new ArgumentNullException (argName);
if (name.Length == 0)
throw new ArgumentException ("Empty name is not legal", argName);
- if (name.IndexOf ((char)0) != -1)
+ if (name [0] == ((char)0))
throw new ArgumentException ("Illegal name", argName);
}
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * ParameterInfo.cs: Name must default to null if no ParameterBuilder
+ is supplied.
+
2008-04-22 Zoltan Varga <vargaz@gmail.com>
* MonoGenericClass.cs (GetMethod): Construct a MethodOnTypeBuilderInst object
this.PositionImpl = pb.Position - 1; // ParameterInfo.Position is zero-based
this.AttrsImpl = (ParameterAttributes) pb.Attributes;
} else {
- this.NameImpl = "";
+ this.NameImpl = null;
this.PositionImpl = position - 1;
this.AttrsImpl = ParameterAttributes.None;
}
+2008-04-30 Alan McGovern <alan.mcgovern@gmail.com>
+
+ * SHA384Managed.cs: Inlined helper methods and made
+ some fields local vars. Gives about 1.70x faster performance.
+
+2008-04-30 Alan McGovern <alan.mcgovern@gmail.com>
+
+ * SHA256Managed.cs: Inlined helper methods removed
+ unnecessary casts and made a field a local var.
+ Gives about 1.70x faster performance.
+
+2008-04-27 Alan McGovern <alan.mcgovern@gmail.com>
+
+ * SHA1CryptoServiceProvider.cs: Performed loop unrolling and
+ re-rolling to reduce IL size significantly and improve
+ perf by over 30%.
+
2008-04-27 Sebastien Pouliot <sebastien@ximian.com>
* SHA1CryptoServiceProvider.cs: Quick optimization to get better
}
for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
- ProcessBlock (rgb, start+i);
+ ProcessBlock (rgb, (uint)(start+i));
}
if (size%BLOCK_SIZE_BYTES != 0) {
_H[4] = 0xC3D2E1F0;
}
- private void ProcessBlock(byte[] inputBuffer, int inputOffset)
+ private void ProcessBlock(byte[] inputBuffer, uint inputOffset)
{
uint a, b, c, d, e;
- int i;
count += BLOCK_SIZE_BYTES;
// abc removal would not work on the fields
uint[] _H = this._H;
uint[] buff = this.buff;
- for (i=0; i<16; i++) {
- buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
- | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
- | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
- | ((uint)(inputBuffer[inputOffset+4*i+3]));
- }
+ InitialiseBuff(buff, inputBuffer, inputOffset);
+ FillBuff(buff);
- uint zt;
- for (i=16; i<80; i++) {
- zt = buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16];
- buff[i] = ((zt << 1) | (zt >> 31));
- }
-
a = _H[0];
b = _H[1];
c = _H[2];
// This function was unrolled because it seems to be doubling our performance with current compiler/VM.
// Possibly roll up if this changes.
-
- // ---- Round 1 --------
-
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[0];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[1];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[2];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[3];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[4];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[5];
- b = (b << 30) | (b >> 2);
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[6];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[7];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[8];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[9];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[10];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[11];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[12];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[13];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[14];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[15];
- b = (b << 30) | (b >> 2);
+ // ---- Round 1 --------
+ int i=0;
+ while (i < 20)
+ {
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[i];
+ b = (b << 30) | (b >> 2);
- d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[16];
- a = (a << 30) | (a >> 2);
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[i+1];
+ a = (a << 30) | (a >> 2);
- c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[17];
- e = (e << 30) | (e >> 2);
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[i+2];
+ e = (e << 30) | (e >> 2);
- b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[18];
- d = (d << 30) | (d >> 2);
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[i+3];
+ d = (d << 30) | (d >> 2);
- a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[19];
- c = (c << 30) | (c >> 2);
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[i+4];
+ c = (c << 30) | (c >> 2);
+ i += 5;
+ }
// ---- Round 2 --------
-
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[20];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[21];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[22];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[23];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[24];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[25];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[26];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[27];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[28];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[29];
- c = (c << 30) | (c >> 2);
+ while (i < 40)
+ {
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[i];
+ b = (b << 30) | (b >> 2);
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[30];
- b = (b << 30) | (b >> 2);
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[i + 1];
+ a = (a << 30) | (a >> 2);
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[31];
- a = (a << 30) | (a >> 2);
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[i + 2];
+ e = (e << 30) | (e >> 2);
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[32];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[33];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[34];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[35];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[36];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[37];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[38];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[39];
- c = (c << 30) | (c >> 2);
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[i + 3];
+ d = (d << 30) | (d >> 2);
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[i + 4];
+ c = (c << 30) | (c >> 2);
+ i += 5;
+ }
+
// ---- Round 3 --------
-
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[40];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[41];
- a = (a << 30) | (a >> 2);
+ while (i < 60)
+ {
+ e += ((a << 5) | (a >> 27)) + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC + buff[i];
+ b = (b << 30) | (b >> 2);
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[42];
- e = (e << 30) | (e >> 2);
+ d += ((e << 5) | (e >> 27)) + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC + buff[i + 1];
+ a = (a << 30) | (a >> 2);
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[43];
- d = (d << 30) | (d >> 2);
+ c += ((d << 5) | (d >> 27)) + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC + buff[i + 2];
+ e = (e << 30) | (e >> 2);
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[44];
- c = (c << 30) | (c >> 2);
+ b += ((c << 5) | (c >> 27)) + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC + buff[i + 3];
+ d = (d << 30) | (d >> 2);
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[45];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[46];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[47];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[48];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[49];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[50];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[51];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[52];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[53];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[54];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[55];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[56];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[57];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[58];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[59];
- c = (c << 30) | (c >> 2);
+ a += ((b << 5) | (b >> 27)) + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC + buff[i + 4];
+ c = (c << 30) | (c >> 2);
+ i += 5;
+ }
// ---- Round 4 --------
-
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[60];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[61];
- a = (a << 30) | (a >> 2);
-
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[62];
- e = (e << 30) | (e >> 2);
-
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[63];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[64];
- c = (c << 30) | (c >> 2);
+ while (i < 80)
+ {
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[i];
+ b = (b << 30) | (b >> 2);
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[65];
- b = (b << 30) | (b >> 2);
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[i + 1];
+ a = (a << 30) | (a >> 2);
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[66];
- a = (a << 30) | (a >> 2);
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[i + 2];
+ e = (e << 30) | (e >> 2);
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[67];
- e = (e << 30) | (e >> 2);
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[i + 3];
+ d = (d << 30) | (d >> 2);
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[68];
- d = (d << 30) | (d >> 2);
-
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[69];
- c = (c << 30) | (c >> 2);
-
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[70];
- b = (b << 30) | (b >> 2);
-
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[71];
- a = (a << 30) | (a >> 2);
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[i + 4];
+ c = (c << 30) | (c >> 2);
+ i += 5;
+ }
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[72];
- e = (e << 30) | (e >> 2);
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ _H[4] += e;
+ }
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[73];
- d = (d << 30) | (d >> 2);
+ private static void InitialiseBuff(uint[] buff, byte[] input, uint inputOffset)
+ {
+ buff[0] = (uint)((input[inputOffset + 0] << 24) | (input[inputOffset + 1] << 16) | (input[inputOffset + 2] << 8) | (input[inputOffset + 3]));
+ buff[1] = (uint)((input[inputOffset + 4] << 24) | (input[inputOffset + 5] << 16) | (input[inputOffset + 6] << 8) | (input[inputOffset + 7]));
+ buff[2] = (uint)((input[inputOffset + 8] << 24) | (input[inputOffset + 9] << 16) | (input[inputOffset + 10] << 8) | (input[inputOffset + 11]));
+ buff[3] = (uint)((input[inputOffset + 12] << 24) | (input[inputOffset + 13] << 16) | (input[inputOffset + 14] << 8) | (input[inputOffset + 15]));
+ buff[4] = (uint)((input[inputOffset + 16] << 24) | (input[inputOffset + 17] << 16) | (input[inputOffset + 18] << 8) | (input[inputOffset + 19]));
+ buff[5] = (uint)((input[inputOffset + 20] << 24) | (input[inputOffset + 21] << 16) | (input[inputOffset + 22] << 8) | (input[inputOffset + 23]));
+ buff[6] = (uint)((input[inputOffset + 24] << 24) | (input[inputOffset + 25] << 16) | (input[inputOffset + 26] << 8) | (input[inputOffset + 27]));
+ buff[7] = (uint)((input[inputOffset + 28] << 24) | (input[inputOffset + 29] << 16) | (input[inputOffset + 30] << 8) | (input[inputOffset + 31]));
+ buff[8] = (uint)((input[inputOffset + 32] << 24) | (input[inputOffset + 33] << 16) | (input[inputOffset + 34] << 8) | (input[inputOffset + 35]));
+ buff[9] = (uint)((input[inputOffset + 36] << 24) | (input[inputOffset + 37] << 16) | (input[inputOffset + 38] << 8) | (input[inputOffset + 39]));
+ buff[10] = (uint)((input[inputOffset + 40] << 24) | (input[inputOffset + 41] << 16) | (input[inputOffset + 42] << 8) | (input[inputOffset + 43]));
+ buff[11] = (uint)((input[inputOffset + 44] << 24) | (input[inputOffset + 45] << 16) | (input[inputOffset + 46] << 8) | (input[inputOffset + 47]));
+ buff[12] = (uint)((input[inputOffset + 48] << 24) | (input[inputOffset + 49] << 16) | (input[inputOffset + 50] << 8) | (input[inputOffset + 51]));
+ buff[13] = (uint)((input[inputOffset + 52] << 24) | (input[inputOffset + 53] << 16) | (input[inputOffset + 54] << 8) | (input[inputOffset + 55]));
+ buff[14] = (uint)((input[inputOffset + 56] << 24) | (input[inputOffset + 57] << 16) | (input[inputOffset + 58] << 8) | (input[inputOffset + 59]));
+ buff[15] = (uint)((input[inputOffset + 60] << 24) | (input[inputOffset + 61] << 16) | (input[inputOffset + 62] << 8) | (input[inputOffset + 63]));
+ }
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[74];
- c = (c << 30) | (c >> 2);
+ private static void FillBuff(uint[] buff)
+ {
+ uint val;
+ for (int i = 16; i < 80; i += 8)
+ {
+ val = buff[i - 3] ^ buff[i - 8] ^ buff[i - 14] ^ buff[i - 16];
+ buff[i] = (val << 1) | (val >> 31);
- e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[75];
- b = (b << 30) | (b >> 2);
+ val = buff[i - 2] ^ buff[i - 7] ^ buff[i - 13] ^ buff[i - 15];
+ buff[i + 1] = (val << 1) | (val >> 31);
- d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[76];
- a = (a << 30) | (a >> 2);
+ val = buff[i - 1] ^ buff[i - 6] ^ buff[i - 12] ^ buff[i - 14];
+ buff[i + 2] = (val << 1) | (val >> 31);
- c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[77];
- e = (e << 30) | (e >> 2);
+ val = buff[i + 0] ^ buff[i - 5] ^ buff[i - 11] ^ buff[i - 13];
+ buff[i + 3] = (val << 1) | (val >> 31);
- b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[78];
- d = (d << 30) | (d >> 2);
+ val = buff[i + 1] ^ buff[i - 4] ^ buff[i - 10] ^ buff[i - 12];
+ buff[i + 4] = (val << 1) | (val >> 31);
- a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[79];
- c = (c << 30) | (c >> 2);
+ val = buff[i + 2] ^ buff[i - 3] ^ buff[i - 9] ^ buff[i - 11];
+ buff[i + 5] = (val << 1) | (val >> 31);
+ val = buff[i + 3] ^ buff[i - 2] ^ buff[i - 8] ^ buff[i - 10];
+ buff[i + 6] = (val << 1) | (val >> 31);
- _H[0] += a;
- _H[1] += b;
- _H[2] += c;
- _H[3] += d;
- _H[4] += e;
+ val = buff[i + 4] ^ buff[i - 1] ^ buff[i - 7] ^ buff[i - 9];
+ buff[i + 7] = (val << 1) | (val >> 31);
+ }
}
private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
private const int BLOCK_SIZE_BYTES = 64;
private const int HASH_SIZE_BYTES = 32;
private uint[] _H;
- private uint[] K;
private ulong count;
private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
Initialize ();
}
- private uint Ch (uint u, uint v, uint w)
- {
- return (u&v) ^ (~u&w);
- }
-
- private uint Maj (uint u, uint v, uint w)
- {
- return (u&v) ^ (u&w) ^ (v&w);
- }
-
- private uint Ro0 (uint x)
- {
- return ((x >> 7) | (x << 25))
- ^ ((x >> 18) | (x << 14))
- ^ (x >> 3);
- }
-
- private uint Ro1 (uint x)
- {
- return ((x >> 17) | (x << 15))
- ^ ((x >> 19) | (x << 13))
- ^ (x >> 10);
- }
-
- private uint Sig0 (uint x)
- {
- return ((x >> 2) | (x << 30))
- ^ ((x >> 13) | (x << 19))
- ^ ((x >> 22) | (x << 10));
- }
-
- private uint Sig1 (uint x)
- {
- return ((x >> 6) | (x << 26))
- ^ ((x >> 11) | (x << 21))
- ^ ((x >> 25) | (x << 7));
- }
-
protected override void HashCore (byte[] rgb, int start, int size)
{
int i;
uint a, b, c, d, e, f, g, h;
uint t1, t2;
int i;
+ uint[] K1 = SHAConstants.K1;
+ uint[] buff = this.buff;
count += BLOCK_SIZE_BYTES;
for (i=0; i<16; i++) {
- buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
- | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
- | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
- | ((uint)(inputBuffer[inputOffset+4*i+3]));
+ buff[i] = (uint)(((inputBuffer[inputOffset + 4 * i]) << 24)
+ | ((inputBuffer[inputOffset + 4 * i + 1]) << 16)
+ | ((inputBuffer[inputOffset + 4 * i + 2]) << 8)
+ | ((inputBuffer[inputOffset + 4 * i + 3])));
}
for (i=16; i<64; i++) {
- buff[i] = Ro1(buff[i-2]) + buff[i-7] + Ro0(buff[i-15]) + buff[i-16];
+ t1 = buff[i - 15];
+ t1 = (((t1 >> 7) | (t1 << 25)) ^ ((t1 >> 18) | (t1 << 14)) ^ (t1 >> 3));
+
+ t2 = buff[i - 2];
+ t2 = (((t2 >> 17) | (t2 << 15)) ^ ((t2 >> 19) | (t2 << 13)) ^ (t2 >> 10));
+ buff[i] = t2 + buff[i - 7] + t1 + buff[i - 16];
}
a = _H[0];
h = _H[7];
for (i=0; i<64; i++) {
- t1 = h + Sig1(e) + Ch(e,f,g) + SHAConstants.K1 [i] + buff[i];
- t2 = Sig0(a) + Maj(a,b,c);
+ t1 = h + (((e >> 6) | (e << 26)) ^ ((e >> 11) | (e << 21)) ^ ((e >> 25) | (e << 7))) + ((e & f) ^ (~e & g)) + K1[i] + buff[i];
+
+ t2 = (((a >> 2) | (a << 30)) ^ ((a >> 13) | (a << 19)) ^ ((a >> 22) | (a << 10)));
+ t2 = t2 + ((a & b) ^ (a & c) ^ (b & c));
h = g;
g = f;
f = e;
private void processBlock ()
{
+ ulong a, b, c, d, e, f, g, h;
+
+ // abcrem doesn't work on fields
+ ulong[] W = this.W;
+ ulong[] K2 = SHAConstants.K2;
+
adjustByteCounts ();
// expand 16 word block into 80 word blocks.
for (int t = 16; t <= 79; t++)
- W[t] = Sigma1 (W [t - 2]) + W [t - 7] + Sigma0 (W [t - 15]) + W [t - 16];
-
+ {
+ a = W[t-15];
+ a = ((a >> 1) | (a << 63)) ^ ((a >> 8) | (a << 56)) ^ (a >> 7);
+ b = W[t - 2];
+ b = ((b >> 19) | (b << 45)) ^ ((b >> 61) | (b << 3)) ^ (b >> 6);
+ W[t] = b + W[t - 7] + a + W[t - 16];
+ }
// set up working variables.
- ulong a = H1;
- ulong b = H2;
- ulong c = H3;
- ulong d = H4;
- ulong e = H5;
- ulong f = H6;
- ulong g = H7;
- ulong h = H8;
-
- for (int t = 0; t <= 79; t++) {
- ulong T1 = h + Sum1 (e) + Ch (e, f, g) + SHAConstants.K2 [t] + W [t];
- ulong T2 = Sum0 (a) + Maj (a, b, c);
+ a = H1;
+ b = H2;
+ c = H3;
+ d = H4;
+ e = H5;
+ f = H6;
+ g = H7;
+ h = H8;
+
+ for (int t = 0; t <= 79; t++)
+ {
+ ulong T1 = ((e >> 14) | (e << 50)) ^ ((e >> 18) | (e << 46)) ^ ((e >> 41) | (e << 23));
+ T1 += h + ((e & f) ^ ((~e) & g)) + SHAConstants.K2[t] + W[t];
+
+ ulong T2 = ((a >> 28) | (a << 36)) ^ ((a >> 34) | (a << 30)) ^ ((a >> 39) | (a << 25));
+ T2 += ((a & b) ^ (a & c) ^ (b & c));
+
h = g;
g = f;
f = e;
for (int i = 0; i != W.Length; i++)
W[i] = 0;
}
-
- private ulong rotateRight (ulong x, int n)
- {
- return (x >> n) | (x << (64 - n));
- }
-
- /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */
- private ulong Ch (ulong x, ulong y, ulong z)
- {
- return ((x & y) ^ ((~x) & z));
- }
-
- private ulong Maj (ulong x, ulong y, ulong z)
- {
- return ((x & y) ^ (x & z) ^ (y & z));
- }
-
- private ulong Sum0 (ulong x)
- {
- return rotateRight (x, 28) ^ rotateRight (x, 34) ^ rotateRight (x, 39);
- }
-
- private ulong Sum1 (ulong x)
- {
- return rotateRight (x, 14) ^ rotateRight (x, 18) ^ rotateRight (x, 41);
- }
-
- private ulong Sigma0 (ulong x)
- {
- return rotateRight (x, 1) ^ rotateRight(x, 8) ^ (x >> 7);
- }
-
- private ulong Sigma1 (ulong x)
- {
- return rotateRight (x, 19) ^ rotateRight (x, 61) ^ (x >> 6);
- }
}
}
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * DictionaryTest.cs: Added not working tests for bug #384723. Spaces
+ to tabs.
+
2008-03-21 Sebastien Pouliot <sebastien@ximian.com>
* EqualityComparerTest.cs: New. Add test cases for using null with
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
+using System.Threading;
+
using NUnit.Framework;
namespace MonoTests.System.Collections.Generic {
Assert.AreEqual (20, _dictionary2 [m2].Value, "#4");
}
+
+ [Test]
+ [Category ("NotWorking")]
+ public void Remove_ZeroOut ()
+ {
+ object key = new object ();
+ object value = new object ();
+
+ WeakReference wrKey = new WeakReference (key);
+ WeakReference wrValue = new WeakReference (value);
+
+ Dictionary <object, object> dictionary = new Dictionary <object, object> ();
+ dictionary.Add (key, value);
+ dictionary.Remove (key);
+
+ key = null;
+ value = null;
+ GC.Collect ();
+ Thread.Sleep (200);
+
+ Assert.IsNull (wrKey.Target, "#1");
+ Assert.IsNull (wrValue.Target, "#2");
+ }
[Test, ExpectedException(typeof(ArgumentNullException))]
public void IndexerSetNullTest()
Assert.AreEqual (0, _dictionary.Count, "Clear method failed!");
Assert.IsFalse (_dictionary.ContainsKey ("key2"));
}
-
+
+ [Test]
+ [Category ("NotWorking")]
+ public void Clear_ZeroOut ()
+ {
+ object key = new object ();
+ object value = new object ();
+
+ WeakReference wrKey = new WeakReference (key);
+ WeakReference wrValue = new WeakReference (value);
+
+ Dictionary <object, object> dictionary = new Dictionary <object, object> ();
+ dictionary.Add (key, value);
+ dictionary.Clear ();
+
+ key = null;
+ value = null;
+ GC.Collect ();
+ Thread.Sleep (200);
+
+ Assert.IsNull (wrKey.Target, "#1");
+ Assert.IsNull (wrValue.Target, "#2");
+ }
+
[Test]
public void ContainsKeyTest ()
{
return myt.Name.Equals (this.Name) &&
myt.RollNo.Equals (this.RollNo);
}
-
}
[Test]
KeyValuePair <string, object> entry = (KeyValuePair <string, object>)itr.Current;
}
Assert.AreEqual ("value4", _dictionary ["key4"].ToString (), "");
-
}
[Test]
DictionaryEntry entry = (DictionaryEntry) itr.Current;
}
Assert.AreEqual ("value4", _dictionary ["key4"].ToString (), "");
-
}
[Test]
[Test]
public void KeyValueEnumeratorTest ()
{
- IDictionary<int, int> d = new Dictionary<int, int>();
+ IDictionary<int, int> d = new Dictionary<int, int>();
// Values are chosen such that two keys map to the same bucket.
// Default dictionary table size == 10
- d [9] = 1;
- d [10] = 2;
- d [19] = 3;
+ d [9] = 1;
+ d [10] = 2;
+ d [19] = 3;
Assert.AreEqual (d.Count, d.Keys.Count, "d and d.Keys don't appear to match");
Assert.AreEqual (d.Values.Count, d.Keys.Count, "d.Keys and d.Values don't appear to match");
- int count = 0;
- foreach (int i in d.Values)
- ++count;
+ int count = 0;
+ foreach (int i in d.Values)
+ ++count;
Assert.AreEqual (count, d.Values.Count, "d.Values doesn't have the correct number of elements");
- count = 0;
+ count = 0;
foreach (int i in d.Keys)
++count;
Assert.AreEqual (count, d.Keys.Count, "d.Keys doesn't have the correct number of elements");
int nkeys = count;
count = 0;
- foreach (int i in d.Keys) {
+ foreach (int i in d.Keys) {
int foo = d [i];
if (count++ >= nkeys)
Assert.Fail ("Reading a value appears to trash enumerator state");
}
}
- [Test] // bug 75073
+ [Test] // bug 75073
public void SliceCollectionsEnumeratorTest ()
{
Dictionary<string, int> values = new Dictionary<string, int> ();
Assert.IsNull(d["foo"]);
}
- // Bug: #332534
- [Test]
+ [Test] // bug #332534
public void Dictionary_MoveNext ()
{
Dictionary<int,int> a = new Dictionary<int,int>();
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * DirectoryTest.cs: Do not use ExpectedException to avoid false
+ positives. Use String.Empty instead of "".
+
2008-04-22 Dick Porter <dick@ximian.com>
* FileTest.cs: Disable the test for bug 323389, as I've reverted
}\r
\r
[TearDown]\r
- public void TearDown () {\r
+ public void TearDown ()\r
+ {\r
if (Directory.Exists (TempFolder))\r
Directory.Delete (TempFolder, true);\r
}\r
DeleteDirectory (":");\r
try {\r
DirectoryInfo info = Directory.CreateDirectory (":");\r
- Assert.Fail ();\r
- } catch (ArgumentException) {\r
+ Assert.Fail ("#1");\r
+ } catch (ArgumentException ex) {\r
+ // The path is not of a legal form\r
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");\r
+ Assert.IsNull (ex.InnerException, "#3");\r
+ Assert.IsNotNull (ex.Message, "#4");\r
+ Assert.IsNull (ex.ParamName, "#5");\r
}\r
DeleteDirectory (":");\r
}\r
\r
[Test]\r
- [ExpectedException(typeof(ArgumentNullException))]\r
- public void CreateDirectoryArgumentNullException ()\r
+ public void CreateDirectory_Path_Null ()\r
{\r
- DirectoryInfo info = Directory.CreateDirectory (null as string);\r
+ try {\r
+ Directory.CreateDirectory (null as string);\r
+ Assert.Fail ("#1");\r
+ } catch (ArgumentNullException ex) {\r
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");\r
+ Assert.IsNull (ex.InnerException, "#3");\r
+ Assert.IsNotNull (ex.Message, "#4");\r
+ Assert.AreEqual ("path", ex.ParamName, "#5");\r
+ }\r
}\r
\r
[Test]\r
- [ExpectedException(typeof(ArgumentException))]\r
- public void CreateDirectoryArgumentException1 ()\r
+ public void CreateDirectory_Path_Empty ()\r
{\r
- DirectoryInfo info = Directory.CreateDirectory ("");\r
+ try {\r
+ Directory.CreateDirectory (string.Empty);\r
+ Assert.Fail ("#1");\r
+ } catch (ArgumentException ex) {\r
+ // Path cannot be the empty string or all whitespace\r
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");\r
+ Assert.IsNull (ex.InnerException, "#3");\r
+ Assert.IsNotNull (ex.Message, "#4");\r
+ Assert.IsNull (ex.ParamName, "#5");\r
+ }\r
}\r
\r
[Test]\r
- [ExpectedException(typeof(ArgumentException))]\r
- public void CreateDirectoryArgumentException2 ()\r
+ public void CreateDirectory_Path_Whitespace ()\r
{\r
- DirectoryInfo info = Directory.CreateDirectory (" ");\r
+ try {\r
+ Directory.CreateDirectory (" ");\r
+ Assert.Fail ("#1");\r
+ } catch (ArgumentException ex) {\r
+ // The path is not of a legal form\r
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");\r
+ Assert.IsNull (ex.InnerException, "#3");\r
+ Assert.IsNotNull (ex.Message, "#4");\r
+ Assert.IsNull (ex.ParamName, "#5");\r
+ }\r
}\r
\r
[Test]\r
- [ExpectedException(typeof(ArgumentException))]\r
- public void CreateDirectoryArgumentException3 ()\r
+ public void CreateDirectory_Path_InvalidChars ()\r
{\r
string path = TempFolder + DSC + "DirectoryTest.Test";\r
DeleteDirectory (path);\r
path += '\x00';\r
path += ".2";\r
DirectoryInfo info = Directory.CreateDirectory (path);\r
+ Assert.Fail ("#1");\r
+ } catch (ArgumentException ex) {\r
+ // The path contains illegal characters\r
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");\r
+ Assert.IsNull (ex.InnerException, "#3");\r
+ Assert.IsNotNull (ex.Message, "#4");\r
+ Assert.IsNull (ex.ParamName, "#5");\r
} finally {\r
DeleteDirectory (path);\r
}\r
[ExpectedException(typeof(ArgumentException))]\r
public void DeleteArgumentException ()\r
{\r
- Directory.Delete ("");\r
+ Directory.Delete (string.Empty);\r
}\r
\r
[Test] \r
[Category("TargetJvmNotSupported")] // GetCreationTime not supported for TARGET_JVM\r
public void GetCreationTimeException2 ()\r
{\r
- Directory.GetCreationTime ("");\r
+ Directory.GetCreationTime (string.Empty);\r
}\r
\r
[Test]\r
[Category("TargetJvmNotSupported")] // GetCreationTime not supported for TARGET_JVM\r
public void GetCreationTimeUtcException2 ()\r
{\r
- Directory.GetCreationTimeUtc ("");\r
+ Directory.GetCreationTimeUtc (string.Empty);\r
}\r
\r
[Test]\r
[Category("TargetJvmNotSupported")] // GetLastAccessTime not supported for TARGET_JVM\r
public void GetLastAccessTimeException2 ()\r
{\r
- Directory.GetLastAccessTime ("");\r
+ Directory.GetLastAccessTime (string.Empty);\r
}\r
\r
[Test]\r
[Category("TargetJvmNotSupported")] // GetLastAccessTime not supported for TARGET_JVM\r
public void GetLastAccessTimeUtcException2 ()\r
{\r
- Directory.GetLastAccessTimeUtc ("");\r
+ Directory.GetLastAccessTimeUtc (string.Empty);\r
}\r
\r
[Test]\r
[ExpectedException(typeof(ArgumentException))]\r
public void GetLastWriteTimeException2 ()\r
{\r
- Directory.GetLastWriteTime ("");\r
+ Directory.GetLastWriteTime (string.Empty);\r
}\r
\r
[Test]\r
[ExpectedException(typeof(ArgumentException))]\r
public void GetLastWriteTimeUtcException2 ()\r
{\r
- Directory.GetLastWriteTimeUtc ("");\r
+ Directory.GetLastWriteTimeUtc (string.Empty);\r
}\r
\r
[Test]\r
public void SetLastWriteTimeException2 ()\r
{\r
DateTime time = new DateTime (2003, 4, 6, 6, 4, 2);\r
- Directory.SetLastWriteTime ("", time);\r
+ Directory.SetLastWriteTime (string.Empty, time);\r
}\r
\r
[Test]\r
public void SetLastWriteTimeUtcException2 ()\r
{\r
DateTime time = new DateTime (2003, 4, 6, 6, 4, 2);\r
- Directory.SetLastWriteTimeUtc ("", time);\r
+ Directory.SetLastWriteTimeUtc (string.Empty, time);\r
}\r
\r
[Test]\r
public void SetLastAccessTimeException2 ()\r
{\r
DateTime time = new DateTime (2003, 4, 6, 6, 4, 2);\r
- Directory.SetLastAccessTime ("", time);\r
+ Directory.SetLastAccessTime (string.Empty, time);\r
}\r
\r
[Test]\r
public void SetLastAccessTimeUtcException2 ()\r
{\r
DateTime time = new DateTime (2003, 4, 6, 6, 4, 2);\r
- Directory.SetLastAccessTimeUtc ("", time);\r
+ Directory.SetLastAccessTimeUtc (string.Empty, time);\r
}\r
\r
[Test]\r
public void SetCreationTimeException2 ()\r
{\r
DateTime time = new DateTime (2003, 4, 6, 6, 4, 2);\r
- Directory.SetCreationTime ("", time);\r
+ Directory.SetCreationTime (string.Empty, time);\r
}\r
\r
[Test]\r
public void SetCreationTimeUtcException2 ()\r
{\r
DateTime time = new DateTime (2003, 4, 6, 6, 4, 2);\r
- Directory.SetCreationTimeUtc ("", time);\r
+ Directory.SetCreationTimeUtc (string.Empty, time);\r
}\r
\r
[Test]\r
+2008-05-01 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * ConstructorBuilderTest.cs: Use Assert class instead of deriving from
+ deprecated Assertion class. Improved some existing tests, and avoid
+ creating too much TypeBuilder instances.
+
+2008-04-30 Gert Driesen <drieseng@users.sourceforge.net>
+
+ * MethodOnTypeBuilderInstTest.cs: Fixed exception message in comments.
+ * TypeBuilderTest.cs: Do not use ExpectedException to avoid false
+ positives. Added argument check tests for DefineEvent, DefineField,
+ DefineMethod, DefinePInvokeMethod and DefinePropety. Use
+ Type.EmptyTypes instead of constructing empty array.
+ * ConstructorBuilderTest.cs: Added Test attributes. Added tests
+ for DefineParameter and Invoke overloads. Added tests for
+ GetCustomAttributes overloads. Avoid use of ExpectedException.
+ * ModuleBuilderTest.cs: Added tests for DefineType name argument
+ checks.
+ * ConstructorOnTypeBuilderInstTest.cs: Added basic set of tests.
+
2008-04-26 Gert Driesen <drieseng@users.sourceforge.net>
* MethodOnTypeBuilderInstTest.cs: Added basic set of tests.
namespace MonoTests.System.Reflection.Emit
{
-
[TestFixture]
-public class ConstructorBuilderTest : Assertion
-{
- private TypeBuilder genClass;
-
+public class ConstructorBuilderTest
+{
+ private TypeBuilder genClass;
private ModuleBuilder module;
private static int typeIndexer = 0;
[SetUp]
- protected void SetUp () {
+ public void SetUp ()
+ {
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "MonoTests.System.Reflection.Emit.ConstructorBuilderTest";
assemblyName, AssemblyBuilderAccess.Run);
module = assembly.DefineDynamicModule("module1");
-
- genClass = module.DefineType(genTypeName (),
- TypeAttributes.Public);
+ genClass = module.DefineType(genTypeName (), TypeAttributes.Public);
}
// Return a unique type name
- private string genTypeName () {
+ private string genTypeName ()
+ {
return "class" + (typeIndexer ++);
}
- public void TestAttributes () {
+ [Test]
+ public void Attributes ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
- MethodAttributes.Public, 0, new Type [0]);
+ MethodAttributes.Public, 0, new Type [0]);
- Assert ("Attributes works",
- (cb.Attributes & MethodAttributes.Public) != 0);
- Assert ("Attributes works",
- (cb.Attributes & MethodAttributes.SpecialName) != 0);
+ Assert.IsTrue ((cb.Attributes & MethodAttributes.Public) != 0, "#1");
+ Assert.IsTrue ((cb.Attributes & MethodAttributes.SpecialName) != 0, "#2");
}
- public void TestCallingConvention () {
+ [Test]
+ public void CallingConvention ()
+ {
/* This does not work under MS.NET
ConstructorBuilder cb3 = genClass.DefineConstructor (
0, CallingConventions.VarArgs, new Type [0]);
- AssertEquals ("CallingConvetion works",
- CallingConventions.VarArgs | CallingConventions.HasThis,
- cb3.CallingConvention);
+ Assert.AreEqual (CallingConventions.VarArgs | CallingConventions.HasThis,
+ cb3.CallingConvention, "#1");
*/
ConstructorBuilder cb4 = genClass.DefineConstructor (
MethodAttributes.Static, CallingConventions.Standard, new Type [0]);
- AssertEquals ("Static implies !HasThis",
- cb4.CallingConvention,
- CallingConventions.Standard);
+ Assert.AreEqual (CallingConventions.Standard,
+ cb4.CallingConvention, "#2");
}
- public void TestDeclaringType () {
+ [Test]
+ public void DeclaringType ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
- 0, 0, new Type[0]);
+ 0, 0, new Type[0]);
- AssertEquals ("DeclaringType works",
- cb.DeclaringType, genClass);
+ Assert.AreSame (genClass, cb.DeclaringType);
}
- public void TestInitLocals () {
+ [Test]
+ public void InitLocals ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
- 0, 0, new Type[0]);
+ 0, 0, new Type[0]);
- AssertEquals ("InitLocals defaults to true", cb.InitLocals, true);
+ Assert.IsTrue (cb.InitLocals, "#1");
cb.InitLocals = false;
- AssertEquals ("InitLocals is settable", cb.InitLocals, false);
+ Assert.IsFalse (cb.InitLocals, "#2");
}
[Test]
- [Category ("NotDotNet")]
- public void TestMethodHandle ()
+ public void MethodHandle ()
{
ConstructorBuilder cb = genClass.DefineConstructor (
- 0, 0, new Type [0]);
+ 0, 0, new Type [0]);
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
- RuntimeMethodHandle handle = cb.MethodHandle;
- // the previous line throws a NotSupportedException on MS 1.1 SP1
- }
+ try {
+ RuntimeMethodHandle handle = cb.MethodHandle;
+ Assert.Fail ("#A1:" + handle);
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
- public void TestName () {
- ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);
+ genClass.CreateType ();
- AssertEquals ("Name works", ".ctor", cb.Name);
+ try {
+ RuntimeMethodHandle handle = cb.MethodHandle;
+ Assert.Fail ("#B1:" + handle);
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
- ConstructorBuilder cb2 = genClass.DefineConstructor (MethodAttributes.Static, 0, new Type [0]);
- AssertEquals ("Static constructors have the right name", ".cctor", cb2.Name);
+ [Test]
+ public void Name ()
+ {
+ ConstructorBuilder cb;
+
+ cb = genClass.DefineConstructor (0, 0, new Type [0]);
+ Assert.AreEqual (".ctor", cb.Name, "#1");
+ cb = genClass.DefineConstructor (MethodAttributes.Static, 0, new Type [0]);
+ Assert.AreEqual (".cctor", cb.Name, "#2");
}
- public void TestReflectedType () {
+ [Test]
+ public void TestReflectedType ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);
- AssertEquals ("ReflectedType works",
- genClass, cb.ReflectedType);
+ Assert.AreSame (genClass, cb.ReflectedType);
}
- public void TestReturnType () {
- ConstructorBuilder cb = genClass.DefineConstructor (0, 0, new Type [0]);
-
- AssertEquals ("ReturnType works",
- null, cb.ReturnType);
+ [Test]
+ public void ReturnType ()
+ {
+ ConstructorBuilder cb;
+
+ cb = genClass.DefineConstructor (0, 0, new Type [] { typeof (string) });
+ Assert.IsNull (cb.ReturnType, "#1");
+ cb = genClass.DefineConstructor (MethodAttributes.Static, 0, new Type [0]);
+ Assert.IsNull (cb.ReturnType, "#2");
}
- public void TestDefineParameter () {
- TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
- ConstructorBuilder cb = tb.DefineConstructor (
- 0, 0, new Type [2] { typeof(int), typeof(int) });
+ [Test]
+ public void DefineParameter_Position_Negative ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [2] { typeof (int), typeof (int) });
- // index out of range
try {
- cb.DefineParameter (0, 0, "param1");
- Fail ();
- } catch (ArgumentOutOfRangeException) {
+ cb.DefineParameter (-1, ParameterAttributes.None, "param1");
+ Assert.Fail ("#1");
+ } catch (ArgumentOutOfRangeException ex) {
+ // Specified argument was out of the range of valid values
+ Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
+ Assert.IsNull (ex.ActualValue, "#3");
+ Assert.IsNull (ex.InnerException, "#4");
+ Assert.IsNotNull (ex.Message, "#5");
+ Assert.IsNotNull (ex.ParamName, "#6");
}
+ }
+
+ [Test]
+ public void DefineParameter_Position_Max ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [2] { typeof (int), typeof (int) });
+
try {
cb.DefineParameter (3, 0, "param1");
- Fail ();
- } catch (ArgumentOutOfRangeException) {
+ Assert.Fail ("#1");
+ } catch (ArgumentOutOfRangeException ex) {
+ // Specified argument was out of the range of valid values
+ Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
+ Assert.IsNull (ex.ActualValue, "#3");
+ Assert.IsNull (ex.InnerException, "#4");
+ Assert.IsNotNull (ex.Message, "#5");
+ Assert.IsNotNull (ex.ParamName, "#6");
+ }
+ }
+
+ [Test]
+#if NET_2_0
+ [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=341439
+#endif
+ public void DefineParameter_Position_Zero ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [2] { typeof (int), typeof (int) });
+
+ try {
+ cb.DefineParameter (0, ParameterAttributes.In, "param1");
+ Assert.Fail ("#1");
+ } catch (ArgumentOutOfRangeException ex) {
+ // Specified argument was out of the range of valid values
+ Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
+ Assert.IsNull (ex.ActualValue, "#3");
+ Assert.IsNull (ex.InnerException, "#4");
+ Assert.IsNotNull (ex.Message, "#5");
+ Assert.IsNotNull (ex.ParamName, "#6");
}
+ }
+
+ [Test]
+ public void DefineParameter ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [2] { typeof(int), typeof(int) });
- // Normal usage
cb.DefineParameter (1, 0, "param1");
cb.DefineParameter (1, 0, "param1");
cb.DefineParameter (2, 0, null);
- // Can not be called on a created type
cb.GetILGenerator ().Emit (OpCodes.Ret);
- tb.CreateType ();
+ genClass.CreateType ();
+
try {
cb.DefineParameter (1, 0, "param1");
- Fail ();
- }
- catch (InvalidOperationException) {
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
}
}
- public void TestGetCustomAttributes () {
+ [Test] // GetCustomAttributes (Boolean)
+ public void GetCustomAttributes1 ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
0, 0, new Type [1] {typeof(int)});
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
try {
cb.GetCustomAttributes (true);
- Fail ();
- } catch (NotSupportedException) {
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
}
+ genClass.CreateType ();
+
try {
- cb.GetCustomAttributes (null, true);
- Fail ();
- } catch (NotSupportedException) {
+ cb.GetCustomAttributes (true);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
}
}
- public void TestMethodImplementationFlags () {
+ [Test] // GetCustomAttributes (Type, Boolean)
+ public void GetCustomAttributes2 ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
- 0, 0, new Type [0]);
+ 0, 0, new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
- AssertEquals ("MethodImplementationFlags defaults to Managed+IL",
- cb.GetMethodImplementationFlags (),
- MethodImplAttributes.Managed | MethodImplAttributes.IL);
+ try {
+ cb.GetCustomAttributes (null, true);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
- cb.SetImplementationFlags (MethodImplAttributes.OPTIL);
+ genClass.CreateType ();
- AssertEquals ("SetImplementationFlags works",
- cb.GetMethodImplementationFlags (),
- MethodImplAttributes.OPTIL);
+ try {
+ cb.GetCustomAttributes (null, true);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test]
+ public void TestMethodImplementationFlags ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [0]);
+
+ Assert.AreEqual (MethodImplAttributes.Managed | MethodImplAttributes.IL,
+ cb.GetMethodImplementationFlags (), "#A1");
+ cb.SetImplementationFlags (MethodImplAttributes.OPTIL);
+ Assert.AreEqual (MethodImplAttributes.OPTIL,
+ cb.GetMethodImplementationFlags (), "#A2");
// Can not be called on a created type
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
tb.CreateType ();
try {
cb2.SetImplementationFlags (MethodImplAttributes.OPTIL);
- Fail ();
- }
- catch (InvalidOperationException) {
+ Assert.Fail ("#B1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
}
}
- public void TestGetModule () {
+ [Test]
+ public void GetModule ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
- 0, 0, new Type [0]);
+ 0, 0, new Type [0]);
- AssertEquals ("GetModule works",
- module, cb.GetModule ());
+ Assert.AreSame (module, cb.GetModule ());
}
- public void TestGetParameters () {
- TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
- ConstructorBuilder cb = tb.DefineConstructor (
- 0, 0, new Type [1] {typeof(int)});
+ [Test]
+ public void GetParameters_Complete1 ()
+ {
+ ConstructorBuilder cb;
+ ParameterInfo [] parameters;
+
+ cb = genClass.DefineConstructor (MethodAttributes.Public,
+ CallingConventions.Standard,
+ new Type [] { typeof (int), typeof (string), typeof (bool) });
+ cb.DefineParameter (3, ParameterAttributes.In, "param3a");
+ cb.DefineParameter (3, ParameterAttributes.In, "param3b");
+ cb.DefineParameter (2, ParameterAttributes.Out, "param2");
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+ genClass.CreateType ();
+
+ parameters = cb.GetParameters ();
+ Assert.IsNotNull (parameters, "#A1");
+ Assert.AreEqual (3, parameters.Length, "#A2");
+
+ Assert.AreEqual (ParameterAttributes.None, parameters [0].Attributes, "#B1");
+ Assert.IsNull (parameters [0].Name, "#B2");
+ Assert.AreEqual (typeof (int), parameters [0].ParameterType, "#B3");
+ Assert.AreEqual (0, parameters [0].Position, "#B4");
+
+ Assert.AreEqual (ParameterAttributes.Out, parameters [1].Attributes, "#C1");
+ Assert.AreEqual ("param2", parameters [1].Name, "#C2");
+ Assert.AreEqual (typeof (string), parameters [1].ParameterType, "#C3");
+ Assert.AreEqual (1, parameters [1].Position, "#C4");
+
+ Assert.AreEqual (ParameterAttributes.In, parameters [2].Attributes, "#D1");
+ Assert.AreEqual ("param3b", parameters [2].Name, "#D2");
+ Assert.AreEqual (typeof (bool), parameters [2].ParameterType, "#D3");
+ Assert.AreEqual (2, parameters [2].Position, "#D4");
+ }
+
+ [Test]
+#if ONLY_1_1
+ [Category ("NotDotNet")] // ArgumentNullException in GetParameters
+#endif
+ public void GetParameters_Complete2 ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ MethodAttributes.Public,
+ CallingConventions.Standard, null);
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+ genClass.CreateType ();
+
+ ParameterInfo [] parameters = cb.GetParameters ();
+ Assert.IsNotNull (parameters, "#1");
+ Assert.AreEqual (0, parameters.Length, "#2");
+ }
+
+ [Test]
+ public void GetParameters_Incomplete ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [2] { typeof (int), typeof (string) });
+ cb.DefineParameter (1, ParameterAttributes.In, "param1");
+ cb.DefineParameter (2, ParameterAttributes.In, "param2");
cb.GetILGenerator ().Emit (OpCodes.Ret);
- // Can't be called before CreateType ()
- /* This does not work under mono
try {
cb.GetParameters ();
- Fail ();
- } catch (InvalidOperationException) {
+ Assert.Fail ("#1");
+#if NET_2_0
+ } catch (NotSupportedException ex) {
+ // Type has not been created
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
}
- */
+#else
+ } catch (InvalidOperationException ex) {
+ // Type has not been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
+#endif
+ }
- tb.CreateType ();
+ [Test]
+ public void GetToken ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [1] { typeof(int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
- /* This does not work under MS.NET !
- cb.GetParameters ();
- */
+ MethodToken tokenA = cb.GetToken ();
+#if NET_2_0
+ Assert.IsFalse (tokenA == MethodToken.Empty, "#1");
+#else
+ Assert.IsFalse (tokenA.Token == MethodToken.Empty.Token, "#1");
+#endif
+
+ genClass.CreateType ();
+
+ MethodToken tokenB = cb.GetToken ();
+#if NET_2_0
+ Assert.AreEqual (tokenA, tokenB, "#2");
+#else
+ Assert.AreEqual (tokenA.Token, tokenB.Token, "#2");
+#endif
}
- public void TestGetToken () {
- TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
- ConstructorBuilder cb = tb.DefineConstructor (
- 0, 0, new Type [1] {typeof(void)});
+ [Test] // Invoke (Object [])
+ public void Invoke1 ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [1] { typeof(int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ try {
+ cb.Invoke (new object [1] { 42 });
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
- cb.GetToken ();
+ genClass.CreateType ();
+
+ try {
+ cb.Invoke (new object [1] { 42 });
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
}
- public void TestInvoke () {
+ [Test] // Invoke (Object, Object [])
+ public void Invoke2 ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
- 0, 0,
- new Type [1] {typeof(int)});
+ 0, 0, new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
try {
cb.Invoke (null, new object [1] { 42 });
- Fail ();
- } catch (NotSupportedException) {
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
}
+ genClass.CreateType ();
+
+ try {
+ cb.Invoke (null, new object [1] { 42 });
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test] // Invoke (BindingFlags, Binder, Object [], CultureInfo)
+ public void Invoke3 ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ try {
+ cb.Invoke (0, null, new object [1] { 42 }, null);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ genClass.CreateType ();
+
+ try {
+ cb.Invoke (0, null, new object [1] { 42 }, null);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test] // Invoke (Object, BindingFlags, Binder, Object [], CultureInfo)
+ public void Invoke4 ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ try {
+ cb.Invoke (null, 0, null, new object [1] { 42 }, null);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ genClass.CreateType ();
+
try {
cb.Invoke (null, 0, null, new object [1] { 42 }, null);
- Fail ();
- } catch (NotSupportedException) {
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
}
}
- public void TestIsDefined () {
+ [Test]
+ public void IsDefined ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
0, 0,
new Type [1] {typeof(int)});
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ try {
+ cb.IsDefined (null, true);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ genClass.CreateType ();
try {
cb.IsDefined (null, true);
- Fail ();
- } catch (NotSupportedException) {
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
}
}
- public void TestSetCustomAttribute () {
- TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
- ConstructorBuilder cb = tb.DefineConstructor (
- 0, 0,
- new Type [1] {typeof(int)});
+ [Test]
+ public void TestSetCustomAttribute ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ 0, 0, new Type [1] {typeof(int)});
cb.GetILGenerator ().Emit (OpCodes.Ret);
// Null argument
try {
cb.SetCustomAttribute (null);
- Fail ();
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("customBuilder", ex.ParamName, "#A5");
}
byte[] custAttrData = { 1, 0, 0, 0, 0};
// Null arguments again
try {
- cb.SetCustomAttribute (null, new byte[2]);
- Fail ();
- } catch (ArgumentNullException) {
+ cb.SetCustomAttribute (null, new byte [2]);
+ Assert.Fail ("#B1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("con", ex.ParamName, "#B5");
}
try {
cb.SetCustomAttribute (ctorInfo, null);
- Fail ();
- } catch (ArgumentNullException) {
+ Assert.Fail ("#C1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.AreEqual ("binaryAttribute", ex.ParamName, "#C5");
}
}
[Test]
- public void GetCustomAttributes () {
- TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
- ConstructorBuilder cb = tb.DefineConstructor (
+ public void GetCustomAttributes_Emitted ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
MethodAttributes.Public, 0,
new Type [1] {typeof(int)});
cb.GetILGenerator ().Emit (OpCodes.Ret);
cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
- Type t = tb.CreateType ();
+ Type t = genClass.CreateType ();
// Try the created type
{
ConstructorInfo ci = t.GetConstructors () [0];
object[] attrs = ci.GetCustomAttributes (true);
- AssertEquals (1, attrs.Length);
- Assert (attrs [0] is ObsoleteAttribute);
- AssertEquals ("FOO", ((ObsoleteAttribute)attrs [0]).Message);
+ Assert.AreEqual (1, attrs.Length, "#A1");
+ Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#A2");
+ Assert.AreEqual ("FOO", ((ObsoleteAttribute)attrs [0]).Message, "#A3");
}
// Try the type builder
{
- ConstructorInfo ci = tb.GetConstructors () [0];
+ ConstructorInfo ci = genClass.GetConstructors () [0];
object[] attrs = ci.GetCustomAttributes (true);
- AssertEquals (1, attrs.Length);
- Assert (attrs [0] is ObsoleteAttribute);
- AssertEquals ("FOO", ((ObsoleteAttribute)attrs [0]).Message);
+ Assert.AreEqual (1, attrs.Length, "#B1");
+ Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#B2");
+ Assert.AreEqual ("FOO", ((ObsoleteAttribute)attrs [0]).Message, "#B3");
}
+ }
+ [Test] // GetCustomAttributes (Boolean)
+ public void GetCustomAttributes1_Complete ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ MethodAttributes.Public, 0,
+ new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ Type attrType = typeof (ObsoleteAttribute);
+ ConstructorInfo ctorInfo =
+ attrType.GetConstructor (new Type [] { typeof (String) });
+ cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
+
+ genClass.CreateType ();
+
+ try {
+ cb.GetCustomAttributes (false);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
+ }
+
+ [Test] // GetCustomAttributes (Boolean)
+ public void GetCustomAttributes1_Incomplete ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ MethodAttributes.Public, 0,
+ new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ Type attrType = typeof (ObsoleteAttribute);
+ ConstructorInfo ctorInfo =
+ attrType.GetConstructor (new Type [] { typeof (String) });
+ cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
+
+ try {
+ cb.GetCustomAttributes (false);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
+ }
+
+ [Test] // GetCustomAttributes (Type, Boolean)
+ public void GetCustomAttributes2_Complete ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ MethodAttributes.Public, 0,
+ new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ Type attrType = typeof (ObsoleteAttribute);
+ ConstructorInfo ctorInfo =
+ attrType.GetConstructor (new Type [] { typeof (String) });
+ cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
+
+ genClass.CreateType ();
+
+ try {
+ cb.GetCustomAttributes (attrType, false);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
+ }
+
+ [Test] // GetCustomAttributes (Type, Boolean)
+ public void GetCustomAttributes2_Incomplete ()
+ {
+ ConstructorBuilder cb = genClass.DefineConstructor (
+ MethodAttributes.Public, 0,
+ new Type [1] { typeof (int) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
+
+ Type attrType = typeof (ObsoleteAttribute);
+ ConstructorInfo ctorInfo =
+ attrType.GetConstructor (new Type [] { typeof (String) });
+ cb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
+
+ try {
+ cb.GetCustomAttributes (attrType, false);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic
+ // module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
// Same as in MethodBuilderTest
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
- public void TestAddDeclarativeSecurityAlreadyCreated () {
+ public void AddDeclarativeSecurity_Complete ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
MethodAttributes.Public, 0, new Type [0]);
ILGenerator ilgen = cb.GetILGenerator ();
genClass.CreateType ();
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
- cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ try {
+ cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Type has not been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
- [ExpectedException (typeof (ArgumentNullException))]
- public void TestAddDeclarativeSecurityNullPermissionSet () {
+ public void AddDeclarativeSecurity_PSet_Null ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
MethodAttributes.Public, 0, new Type [0]);
- cb.AddDeclarativeSecurity (SecurityAction.Demand, null);
+ try {
+ cb.AddDeclarativeSecurity (SecurityAction.Demand, null);
+ Assert.Fail ("#1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("pset", ex.ParamName, "#5");
+ }
}
[Test]
- public void TestAddDeclarativeSecurityInvalidAction () {
+ public void AddDeclarativeSecurity_Action_Invalid ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
MethodAttributes.Public, 0, new Type [0]);
foreach (SecurityAction action in actions) {
try {
cb.AddDeclarativeSecurity (action, set);
- Fail ();
- } catch (ArgumentOutOfRangeException) {
+ Assert.Fail ("#1");
+ } catch (ArgumentOutOfRangeException ex) {
+ Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
+ Assert.IsNull (ex.ActualValue, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("action", ex.ParamName, "#5");
}
}
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
- public void TestAddDeclarativeSecurityDuplicateAction () {
+ public void AddDeclarativeSecurity_Action_Duplicate ()
+ {
ConstructorBuilder cb = genClass.DefineConstructor (
MethodAttributes.Public, 0, new Type [0]);
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
- cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ try {
+ cb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Type has not been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
}
}
--- /dev/null
+//
+// MethodOnTypeBuilderInstTest - NUnit Test Cases for MethodOnTypeBuilderInst
+//
+// Author:
+// Gert Driesen (drieseng@users.sourceforge.net)
+//
+// Copyright (C) 2008 Gert Driesen
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Reflection.Emit
+{
+ [TestFixture]
+ public class ConstructorOnTypeBuilderInstTest
+ {
+ private static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.ConstructorOnTypeBuilderInstTest";
+
+ private AssemblyBuilder assembly;
+ private ModuleBuilder module;
+ private Type typeBarOfInt32;
+ private ConstructorInfo ci;
+ private TypeBuilder tb;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ AssemblyName assemblyName = new AssemblyName ();
+ assemblyName.Name = ASSEMBLY_NAME;
+
+ assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (
+ assemblyName, AssemblyBuilderAccess.RunAndSave,
+ Path.GetTempPath ());
+
+ module = assembly.DefineDynamicModule ("module1");
+
+ tb = module.DefineType ("Bar");
+ GenericTypeParameterBuilder [] typeParams = tb.DefineGenericParameters ("T");
+
+ ConstructorBuilder cb = tb.DefineConstructor (MethodAttributes.Public,
+ CallingConventions.Standard,
+ new Type [] { typeof (string), typeof (int) });
+ ILGenerator ig = cb.GetILGenerator ();
+ ig.Emit (OpCodes.Ret);
+
+ typeBarOfInt32 = tb.MakeGenericType (typeof (int));
+ ci = TypeBuilder.GetConstructor (typeBarOfInt32, cb);
+ }
+
+ [Test]
+ [Category ("NotWorking")]
+ public void Attributes ()
+ {
+ Assert.AreEqual (MethodAttributes.PrivateScope |
+ MethodAttributes.Public | MethodAttributes.SpecialName,
+ ci.Attributes, "#1");
+ tb.CreateType ();
+ Assert.AreEqual (MethodAttributes.PrivateScope |
+ MethodAttributes.Public | MethodAttributes.SpecialName,
+ ci.Attributes, "#2");
+ }
+
+ [Test]
+ [Category ("NotWorking")]
+ public void CallingConvention ()
+ {
+ Assert.AreEqual (CallingConventions.HasThis,
+ ci.CallingConvention, "#1");
+ tb.CreateType ();
+ Assert.AreEqual (CallingConventions.HasThis,
+ ci.CallingConvention, "#2");
+ }
+
+ [Test]
+ public void ContainsGenericParameters ()
+ {
+ Assert.IsFalse (ci.ContainsGenericParameters, "#1");
+ tb.CreateType ();
+ Assert.IsFalse (ci.ContainsGenericParameters, "#2");
+ }
+
+ [Test]
+ public void DeclaringType ()
+ {
+ Assert.AreSame (typeBarOfInt32, ci.DeclaringType, "#1");
+ tb.CreateType ();
+ Assert.AreSame (typeBarOfInt32, ci.DeclaringType, "#2");
+ }
+
+ [Test] // GetCustomAttributes (Boolean)
+ public void GetCustomAttributes1 ()
+ {
+ try {
+ ci.GetCustomAttributes (false);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.GetCustomAttributes (false);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test] // GetCustomAttributes (Type, Boolean)
+ public void GetCustomAttributes2 ()
+ {
+ try {
+ ci.GetCustomAttributes (typeof (FlagsAttribute), false);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.GetCustomAttributes (typeof (FlagsAttribute), false);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test]
+ public void GetGenericArguments ()
+ {
+ try {
+ ci.GetGenericArguments ();
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // Derived classes must provide an implementation
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.GetGenericArguments ();
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // Derived classes must provide an implementation
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test]
+ public void GetMethodImplementationFlags ()
+ {
+ Assert.AreEqual (MethodImplAttributes.Managed,
+ ci.GetMethodImplementationFlags (), "#1");
+ tb.CreateType ();
+ Assert.AreEqual (MethodImplAttributes.Managed,
+ ci.GetMethodImplementationFlags (), "#2");
+ }
+
+ [Test]
+ public void GetParameters ()
+ {
+ try {
+ ci.GetParameters ();
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // Type has not been created
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ ParameterInfo [] parameters = ci.GetParameters ();
+ Assert.IsNotNull (parameters, "#B1");
+ Assert.AreEqual (2, parameters.Length, "#B2");
+
+ Assert.AreEqual (ParameterAttributes.None, parameters [0].Attributes, "#C1");
+ Assert.IsNull (parameters [0].Name, "#C2");
+ Assert.AreEqual (typeof (string), parameters [0].ParameterType, "#C3");
+ Assert.AreEqual (0, parameters [0].Position, "#C4");
+
+ Assert.AreEqual (ParameterAttributes.None, parameters [1].Attributes, "#D1");
+ Assert.IsNull (parameters [1].Name, "#D2");
+ Assert.AreEqual (typeof (int), parameters [1].ParameterType, "#D3");
+ Assert.AreEqual (1, parameters [1].Position, "#D4");
+ }
+
+ [Test] // Invoke (Object [])
+ public void Invoke1 ()
+ {
+ try {
+ ci.Invoke (new object [0]);
+ Assert.Fail ("#A1");
+ } catch (InvalidOperationException ex) {
+ // Operation is not valid due to the current
+ // state of the object
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.Invoke (new object [0]);
+ Assert.Fail ("#B1");
+ } catch (InvalidOperationException ex) {
+ // Operation is not valid due to the current
+ // state of the object
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test] // Invoke (Object, Object [])
+ public void Invoke2 ()
+ {
+ try {
+ ci.Invoke (null, new object [0]);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // Specified method is not supported
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.Invoke (null, new object [0]);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // Specified method is not supported
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test] // Invoke (BindingFlags, Binder, Object [], CultureInfo)
+ public void Invoke3 ()
+ {
+ try {
+ ci.Invoke (BindingFlags.Default, null, new object [0],
+ CultureInfo.InvariantCulture);
+ Assert.Fail ("#A1");
+ } catch (InvalidOperationException ex) {
+ // Operation is not valid due to the current
+ // state of the object
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.Invoke (BindingFlags.Default, null, new object [0],
+ CultureInfo.InvariantCulture);
+ Assert.Fail ("#B1");
+ } catch (InvalidOperationException ex) {
+ // Operation is not valid due to the current
+ // state of the object
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test] // Invoke (Object, BindingFlags, Binder, Object [], CultureInfo)
+ public void Invoke4 ()
+ {
+ try {
+ ci.Invoke (null, BindingFlags.Default, null,
+ new object [0], CultureInfo.InvariantCulture);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // Specified method is not supported
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.Invoke (null, BindingFlags.Default, null,
+ new object [0], CultureInfo.InvariantCulture);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // Specified method is not supported
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test]
+ public void IsDefined ()
+ {
+ try {
+ ci.IsDefined (typeof (FlagsAttribute), false);
+ Assert.Fail ("#A1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ ci.IsDefined (typeof (FlagsAttribute), false);
+ Assert.Fail ("#B1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test]
+ public void IsGenericMethodDefinition ()
+ {
+ Assert.IsFalse (ci.IsGenericMethodDefinition, "#1");
+ tb.CreateType ();
+ Assert.IsFalse (ci.IsGenericMethodDefinition, "#2");
+ }
+
+ [Test]
+ public void IsGenericMethod ()
+ {
+ Assert.IsFalse (ci.IsGenericMethod, "#1");
+ tb.CreateType ();
+ Assert.IsFalse (ci.IsGenericMethod, "#2");
+ }
+
+ [Test]
+ public void MemberType ()
+ {
+ Assert.AreEqual (MemberTypes.Constructor, ci.MemberType, "#1");
+ tb.CreateType ();
+ Assert.AreEqual (MemberTypes.Constructor, ci.MemberType, "#2");
+ }
+
+ [Test]
+ public void MethodHandle ()
+ {
+ try {
+ RuntimeMethodHandle handle = ci.MethodHandle;
+ Assert.Fail ("#A1:" + handle);
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ }
+
+ tb.CreateType ();
+
+ try {
+ RuntimeMethodHandle handle = ci.MethodHandle;
+ Assert.Fail ("#B1:" + handle);
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ }
+ }
+
+ [Test]
+ public void Module ()
+ {
+ Assert.AreSame (module, ci.Module, "#1");
+ tb.CreateType ();
+ Assert.AreSame (module, ci.Module, "#2");
+ }
+
+ [Test]
+ public void Name ()
+ {
+ Assert.AreEqual (".ctor", ci.Name, "#1");
+ tb.CreateType ();
+ Assert.AreEqual (".ctor", ci.Name, "#2");
+ }
+
+ [Test]
+ public void ReflectedType ()
+ {
+ Assert.AreSame (typeBarOfInt32, ci.ReflectedType, "#1");
+ tb.CreateType ();
+ Assert.AreSame (typeBarOfInt32, ci.ReflectedType, "#2");
+ }
+ }
+}
+
+#endif
method_create.GetCustomAttributes (false);
Assert.Fail ("#A1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
method_edit.GetCustomAttributes (false);
Assert.Fail ("#B1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
method_create.GetCustomAttributes (typeof (FlagsAttribute), false);
Assert.Fail ("#A1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
method_edit.GetCustomAttributes (typeof (FlagsAttribute), false);
Assert.Fail ("#B1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
method_create.GetParameters ();
Assert.Fail ("#A1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // Type has not been created
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
method_edit.GetParameters ();
Assert.Fail ("#B1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // Type has not been created
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
method_create.IsDefined (typeof (FlagsAttribute), false);
Assert.Fail ("#A1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
method_edit.IsDefined (typeof (FlagsAttribute), false);
Assert.Fail ("#B1");
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
RuntimeMethodHandle handle = method_create.MethodHandle;
Assert.Fail ("#A1:" + handle);
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
RuntimeMethodHandle handle = method_edit.MethodHandle;
Assert.Fail ("#B1:" + handle);
} catch (NotSupportedException ex) {
- // Specified method is not supported
+ // The invoked member is not supported in a dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
}
[Test]
- public void TestDefineType_InterfaceNotAbstract ()
+ public void DefineType_Name_Null ()
+ {
+ AssemblyBuilder ab = genAssembly ();
+ ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll", true);
+ try {
+ mb.DefineType ((string) null);
+ Assert.Fail ("#1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("fullname", ex.ParamName, "#5");
+ }
+ }
+
+ [Test]
+ public void DefineType_Name_Empty ()
+ {
+ AssemblyBuilder ab = genAssembly ();
+ ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll", true);
+ try {
+ mb.DefineType (string.Empty);
+ Assert.Fail ("#1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("fullname", ex.ParamName, "#5");
+ }
+ }
+
+ [Test]
+ public void DefineType_Name_NullChar ()
+ {
+ AssemblyBuilder ab = genAssembly ();
+ ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll", true);
+ try {
+ mb.DefineType ("\0test");
+ Assert.Fail ("#1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("fullname", ex.ParamName, "#5");
+ }
+
+ mb.DefineType ("te\0st");
+ }
+
+ [Test]
+ public void DefineType_InterfaceNotAbstract ()
{
AssemblyBuilder ab = genAssembly ();
ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll", true);
{
AssemblyBuilder ab = genAssembly ();
ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", "foo.dll");
-
- TypeBuilder tb1 = mb.DefineType("Foo", TypeAttributes.Public);
-
+
+ TypeBuilder tb1 = mb.DefineType("Foo", TypeAttributes.Public);
+
Type[] types = mb.GetTypes ();
Assert.AreEqual (1, types.Length);
Assert.AreEqual (tb1, types [0]);
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGUIDIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- Guid g = tb.GUID;
+ try {
+ Guid g = tb.GUID;
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test] // bug #71302
bool b = tb.HasElementType;
Assert.Fail ("#1: " + b);
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
bool b = tb.HasElementType;
Assert.Fail ("#1: " + b);
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
Assert.IsNull (ex.InnerException, "#A3");
Assert.IsNotNull (ex.Message, "#A4");
- Assert.IsNotNull (ex.ParamName, "#A5");
- Assert.AreEqual ("parent", ex.ParamName, "#A6");
+ Assert.AreEqual ("parent", ex.ParamName, "#A5");
}
#endif
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
Assert.IsNull (ex.InnerException, "#B3");
Assert.IsNotNull (ex.Message, "#B4");
- Assert.IsNotNull (ex.ParamName, "#B5");
- Assert.AreEqual ("parent", ex.ParamName, "#B6");
+ Assert.AreEqual ("parent", ex.ParamName, "#B5");
}
#endif
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void TestSetParentComplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
tb.CreateType ();
- tb.SetParent (typeof (Attribute));
+ try {
+ tb.SetParent (typeof (Attribute));
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestTypeHandle ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- RuntimeTypeHandle handle = tb.TypeHandle;
+ try {
+ RuntimeTypeHandle handle = tb.TypeHandle;
+ Assert.Fail ("#1:" + handle);
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestTypeInitializerIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- ConstructorInfo cb = tb.TypeInitializer;
+ try {
+ ConstructorInfo cb = tb.TypeInitializer;
+ Assert.Fail ("#1:" + (cb != null));
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- public void TestAddInterfaceImplementation ()
+ public void AddInterfaceImplementation_InterfaceType_Null ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
try {
tb.AddInterfaceImplementation (null);
Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("interfaceType", ex.ParamName, "#5");
}
+ }
+ [Test]
+ public void TestAddInterfaceImplementation ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
tb.AddInterfaceImplementation (typeof (AnInterface));
tb.AddInterfaceImplementation (typeof (AnInterface));
// Can not be called on a created type
try {
tb.DefineConstructor (0, 0, null);
- Assert.Fail ();
- } catch (InvalidOperationException) {
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
}
}
// Can not be called on a created type, altough the MSDN docs does not mention this
try {
tb.DefineDefaultConstructor (0);
- Assert.Fail ();
- } catch (InvalidOperationException) {
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
}
}
-
+
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void TestDefineDefaultConstructorParent ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.DefineConstructor (MethodAttributes.Public,
+ ConstructorBuilder cb = tb.DefineConstructor (
+ MethodAttributes.Public,
CallingConventions.Standard,
new Type [] { typeof (string) });
+ cb.GetILGenerator ().Emit (OpCodes.Ret);
Type type = tb.CreateType ();
// create TypeBuilder for type that derived from the
// you cannot create a type with a default ctor that
// derives from a type without a default ctor
- tb.CreateType ();
+ try {
+ tb.CreateType ();
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // Parent does not have a default constructor.
+ // The default constructor must be explicitly defined
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
+ }
+
+ [Test]
+ public void DefineEvent_Name_NullChar ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+
+ try {
+ tb.DefineEvent ("\0test", EventAttributes.None,
+ typeof (int));
+ Assert.Fail ("#A1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
+ }
+
+ EventBuilder eb = tb.DefineEvent ("te\0st", EventAttributes.None,
+ typeof (int));
+ Assert.IsNotNull (eb, "#B1");
}
[Test]
// Test invalid arguments
try {
tb.DefineEvent (null, 0, typeof (int));
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
}
try {
tb.DefineEvent ("FOO", 0, null);
- Assert.Fail ("#2");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#B1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("type", ex.ParamName, "#B5");
}
try {
- tb.DefineEvent ("", 0, typeof (int));
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ tb.DefineEvent (string.Empty, 0, typeof (int));
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.AreEqual ("name", ex.ParamName, "#C5");
}
tb.CreateType ();
+
// Can not be called on a created type
try {
tb.DefineEvent ("BAR", 0, typeof (int));
- Assert.Fail ("#4");
- } catch (InvalidOperationException) {
+ Assert.Fail ("#D1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
+ Assert.IsNull (ex.InnerException, "#D3");
+ Assert.IsNotNull (ex.Message, "#D4");
}
}
+ [Test]
+ public void DefineField_Name_NullChar ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+
+ try {
+ tb.DefineField ("\0test", typeof (int),
+ FieldAttributes.Private);
+ Assert.Fail ("#A1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("fieldName", ex.ParamName, "#A5");
+ }
+
+ FieldBuilder fb = tb.DefineField ("te\0st", typeof (int),
+ FieldAttributes.Private);
+ Assert.IsNotNull (fb, "#B1");
+ Assert.AreEqual ("te\0st", fb.Name, "#B2");
+ }
+
[Test]
public void TestDefineField ()
{
// Check invalid arguments
try {
tb.DefineField (null, typeof (int), 0);
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("fieldName", ex.ParamName, "#A5");
}
try {
- tb.DefineField ("", typeof (int), 0);
- Assert.Fail ("#2");
- } catch (ArgumentException) {
+ tb.DefineField (string.Empty, typeof (int), 0);
+ Assert.Fail ("#B1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("fieldName", ex.ParamName, "#B5");
}
try {
// Strangely, 'A<NULL>' is accepted...
string name = String.Format ("{0}", (char) 0);
tb.DefineField (name, typeof (int), 0);
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.AreEqual ("fieldName", ex.ParamName, "#C5");
}
try {
tb.DefineField ("A", typeof (void), 0);
- Assert.Fail ("#4");
- } catch (ArgumentException) {
+ Assert.Fail ("#D1");
+ } catch (ArgumentException ex) {
+ // Bad field type in defining field
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
+ Assert.IsNull (ex.InnerException, "#D3");
+ Assert.IsNotNull (ex.Message, "#D4");
+ Assert.IsNull (ex.ParamName, "#D5");
}
tb.CreateType ();
+
// Can not be called on a created type
try {
tb.DefineField ("B", typeof (int), 0);
- Assert.Fail ("#5");
- } catch (InvalidOperationException) {
+ Assert.Fail ("#E1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2");
+ Assert.IsNull (ex.InnerException, "#E3");
+ Assert.IsNotNull (ex.Message, "#E4");
}
}
// Check invalid arguments
try {
tb.DefineInitializedData (null, new byte [1], 0);
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
}
try {
tb.DefineInitializedData ("FOO", null, 0);
- Assert.Fail ("#2");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#B1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("data", ex.ParamName, "#B5");
}
try {
- tb.DefineInitializedData ("", new byte [1], 0);
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ tb.DefineInitializedData (string.Empty, new byte [1], 0);
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.AreEqual ("name", ex.ParamName, "#C5");
}
// The size of the data is less than or equal to zero ???
try {
tb.DefineInitializedData ("BAR", new byte [0], 0);
- Assert.Fail ("#4");
- } catch (ArgumentException) {
+ Assert.Fail ("#D1");
+ } catch (ArgumentException ex) {
+ // Data size must be > 0 and < 0x3f0000
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
+ Assert.IsNull (ex.InnerException, "#D3");
+ Assert.IsNotNull (ex.Message, "#D4");
+ Assert.IsNull (ex.ParamName, "#D5");
}
try {
string name = String.Format ("{0}", (char) 0);
tb.DefineInitializedData (name, new byte [1], 0);
- Assert.Fail ("#5");
- } catch (ArgumentException) {
+ Assert.Fail ("#E1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2");
+ Assert.IsNull (ex.InnerException, "#E3");
+ Assert.IsNotNull (ex.Message, "#E4");
+ Assert.AreEqual ("fieldName", ex.ParamName, "#E5");
}
tb.CreateType ();
// Can not be called on a created type, altough the MSDN docs does not mention this
try {
tb.DefineInitializedData ("BAR2", new byte [1], 0);
- Assert.Fail ("#6");
- } catch (InvalidOperationException) {
+ Assert.Fail ("#F1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#F2");
+ Assert.IsNull (ex.InnerException, "#F3");
+ Assert.IsNotNull (ex.Message, "#F4");
}
}
try {
tb.DefineUninitializedData (null, 1, 0);
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
}
try {
- tb.DefineUninitializedData ("", 1, 0);
- Assert.Fail ("#2");
- } catch (ArgumentException) {
+ tb.DefineUninitializedData (string.Empty, 1, 0);
+ Assert.Fail ("#B1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("name", ex.ParamName, "#B5");
}
// The size of the data is less than or equal to zero ???
try {
tb.DefineUninitializedData ("BAR", 0, 0);
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // Data size must be > 0 and < 0x3f0000
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.IsNull (ex.ParamName, "#C5");
}
try {
string name = String.Format ("{0}", (char) 0);
tb.DefineUninitializedData (name, 1, 0);
- Assert.Fail ("#4");
- } catch (ArgumentException) {
+ Assert.Fail ("#D1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
+ Assert.IsNull (ex.InnerException, "#D3");
+ Assert.IsNotNull (ex.Message, "#D4");
+ Assert.AreEqual ("fieldName", ex.ParamName, "#D5");
}
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void DefineUninitializedDataAlreadyCreated ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
tb.CreateType ();
- tb.DefineUninitializedData ("BAR2", 1, 0);
+ try {
+ tb.DefineUninitializedData ("BAR2", 1, 0);
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
Marshal.FreeHGlobal (ptr);
}
+ [Test]
+ public void DefineMethod_Name_NullChar ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+ try {
+ tb.DefineMethod ("\0test", MethodAttributes.Private,
+ typeof (string), Type.EmptyTypes);
+ Assert.Fail ("#A1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
+ }
+
+ MethodBuilder mb = tb.DefineMethod ("te\0st", MethodAttributes.Private,
+ typeof (string), Type.EmptyTypes);
+ Assert.IsNotNull (mb, "#B1");
+ Assert.AreEqual ("te\0st", mb.Name, "#B2");
+ }
+
[Test]
public void TestDefineMethod ()
{
// Check invalid arguments
try {
tb.DefineMethod (null, 0, null, null);
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
}
try {
- tb.DefineMethod ("", 0, null, null);
- Assert.Fail ("#2");
- } catch (ArgumentException) {
+ tb.DefineMethod (string.Empty, 0, null, null);
+ Assert.Fail ("#B1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("name", ex.ParamName, "#B5");
}
// Check non-virtual methods on an interface
TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
try {
tb2.DefineMethod ("FOO", MethodAttributes.Abstract, null, null);
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // Interface method must be abstract and virtual
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.IsNull (ex.ParamName, "#C5");
}
// Check static methods on an interface
// Can not be called on a created type
try {
tb.DefineMethod ("bar", 0, null, null);
- Assert.Fail ("#4");
- } catch (InvalidOperationException) {
+ Assert.Fail ("#D1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
+ Assert.IsNull (ex.InnerException, "#D3");
+ Assert.IsNotNull (ex.Message, "#D4");
}
}
// Check invalid arguments
try {
tb.DefineNestedType (null);
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("fullname", ex.ParamName, "#A5");
}
try {
- tb.DefineNestedType ("");
- Assert.Fail ("#2");
- } catch (ArgumentException) {
+ tb.DefineNestedType (string.Empty);
+ Assert.Fail ("#B1");
+ } catch (ArgumentException ex) {
+ // Empty name is not legal
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.AreEqual ("fullname", ex.ParamName, "#B5");
}
try {
tb.DefineNestedType (nullName ());
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+ Assert.IsNull (ex.InnerException, "#C3");
+ Assert.IsNotNull (ex.Message, "#C4");
+ Assert.AreEqual ("fullname", ex.ParamName, "#C5");
}
// If I fix the code so this works then mcs breaks -> how can mcs
try {
tb.DefineNestedType ("BB", TypeAttributes.NestedPublic, null,
new Type [1]);
- Assert.Fail ("#5");
- } catch (ArgumentException) {
+ Assert.Fail ("#D1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#D2");
+ Assert.IsNull (ex.InnerException, "#D3");
+ Assert.IsNotNull (ex.Message, "#D4");
+ Assert.AreEqual ("interfaces", ex.ParamName, "#D5");
}
// I think this should reject non-interfaces, but it does not
{
TypeBuilder nested = tb.DefineNestedType ("N1");
- Assert.AreEqual ("N1", nested.Name, "#6");
- Assert.AreEqual (typeof (object), nested.BaseType, "#7");
- Assert.AreEqual (TypeAttributes.NestedPrivate, nested.Attributes, "#8");
- Assert.AreEqual (0, nested.GetInterfaces ().Length, "#9");
+ Assert.AreEqual ("N1", nested.Name, "#E1");
+ Assert.AreEqual (typeof (object), nested.BaseType, "#E2");
+ Assert.AreEqual (TypeAttributes.NestedPrivate, nested.Attributes, "#E3");
+ Assert.AreEqual (0, nested.GetInterfaces ().Length, "#E4");
}
// TODO:
}
+ [Test]
+ public void DefinePInvokeMethod_Name_NullChar ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+ try {
+ tb.DefinePInvokeMethod ("\0test", "B", "C",
+ MethodAttributes.Private, CallingConventions.Standard,
+ typeof (string),Type.EmptyTypes, CallingConvention.Cdecl,
+ CharSet.Unicode);
+ Assert.Fail ("#A1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
+ }
+
+ MethodBuilder mb = tb.DefinePInvokeMethod ("te\0st", "B", "C",
+ MethodAttributes.Private, CallingConventions.Standard,
+ typeof (string), Type.EmptyTypes, CallingConvention.Cdecl,
+ CharSet.Unicode);
+ Assert.IsNotNull (mb, "#B1");
+ Assert.AreEqual ("te\0st", mb.Name, "#B2");
+ }
+
[Test]
public void TestDefinePInvokeMethod ()
{
// Try invalid parameters
try {
tb.DefinePInvokeMethod (null, "B", "C", 0, 0, null, null, 0, 0);
- Assert.Fail ("#1");
- } catch (ArgumentNullException) {
+ Assert.Fail ("#A1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
}
// etc...
// Try invalid attributes
try {
tb.DefinePInvokeMethod ("A2", "B", "C", MethodAttributes.Abstract, 0, null, null, 0, 0);
- Assert.Fail ("#2");
- } catch (ArgumentException) {
+ Assert.Fail ("#B1");
+ } catch (ArgumentException ex) {
+ // PInvoke methods must be static and native and
+ // cannot be abstract
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.IsNull (ex.ParamName, "#B5");
}
// Try an interface parent
try {
tb2.DefinePInvokeMethod ("A", "B", "C", 0, 0, null, null, 0, 0);
- Assert.Fail ("#3");
- } catch (ArgumentException) {
+ Assert.Fail ("#C1");
+ } catch (ArgumentException ex) {
+ // PInvoke methods cannot exist on interfaces
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+ Assert.IsNull (ex.InnerException, "#B3");
+ Assert.IsNotNull (ex.Message, "#B4");
+ Assert.IsNull (ex.ParamName, "#B5");
}
}
[Test]
- public void TestDefineProperty ()
+ public void DefineProperty_Name_NullChar ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- // Check null parameter types
try {
- tb.DefineProperty ("A", 0, null, new Type [1]);
- Assert.Fail ();
- } catch (ArgumentNullException) {
+ tb.DefineProperty ("\0test", 0, typeof (string), Type.EmptyTypes);
+ Assert.Fail ("#A1");
+ } catch (ArgumentException ex) {
+ // Illegal name
+ Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+ Assert.IsNull (ex.InnerException, "#A3");
+ Assert.IsNotNull (ex.Message, "#A4");
+ Assert.AreEqual ("name", ex.ParamName, "#A5");
+ }
+
+ PropertyBuilder pb = tb.DefineProperty ("te\0st", 0,
+ typeof (string), Type.EmptyTypes);
+ Assert.IsNotNull (pb, "#B1");
+ Assert.AreEqual ("te\0st", pb.Name, "#B2");
+ }
+
+ [Test]
+ public void DefineProperty_ParameterTypes_ItemNull ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+
+ try {
+ tb.DefineProperty ("A", 0, typeof (string), new Type [1]);
+ Assert.Fail ("#1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
}
}
+ [Test]
+ public void DefineProperty_ReturnType_Null ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+ tb.DefineProperty ("A", 0, null, Type.EmptyTypes);
+ }
+
#if NET_2_0
[Test]
// Test that changes made to the method builder after a call to GetMethod ()
#endif
[Test]
- [ExpectedException (typeof (NotSupportedException))]
[Category ("NotWorking")]
public void TestIsDefinedIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.IsDefined (typeof (int), true);
+ try {
+ tb.IsDefined (typeof (int), true);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
- Assert.IsNotNull (ex.ParamName, "#5");
- Assert.AreEqual ("attributeType", ex.ParamName, "#6");
+ Assert.AreEqual ("attributeType", ex.ParamName, "#5");
}
}
tb.GetConstructor (Type.EmptyTypes);
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
new ParameterModifier [0]);
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
tb.GetConstructors ();
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
BindingFlags.Instance);
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetCustomAttributesIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetCustomAttributes (false);
+ try {
+ tb.GetCustomAttributes (false);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetCustomAttributesOfTypeIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetCustomAttributes (typeof (ObsoleteAttribute), false);
+ try {
+ tb.GetCustomAttributes (typeof (ObsoleteAttribute), false);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (ArgumentNullException))]
public void TestGetCustomAttributesOfNullTypeComplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
tb.CreateType ();
- tb.GetCustomAttributes (null, false);
+ try {
+ tb.GetCustomAttributes (null, false);
+ Assert.Fail ("#1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("attributeType", ex.ParamName, "#5");
+ }
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
[Ignore ("mcs depends on this")]
public void TestGetEventsIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetEvents ();
+ try {
+ tb.GetEvents ();
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ throw;
+ }
}
[Test]
[Test]
- [ExpectedException (typeof (NotSupportedException))]
[Ignore ("mcs depends on this")]
public void TestGetEventsFlagsIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetEvents (BindingFlags.Public);
+ try {
+ tb.GetEvents (BindingFlags.Public);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ throw;
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
[Ignore ("mcs depends on this")]
public void TestGetEventIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetEvent ("FOO");
+ try {
+ tb.GetEvent ("FOO");
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ throw;
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
[Ignore ("mcs depends on this")]
public void TestGetEventFlagsIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetEvent ("FOO", BindingFlags.Public);
+ try {
+ tb.GetEvent ("FOO", BindingFlags.Public);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ throw;
+ }
}
[Test]
tb.GetFields (BindingFlags.Instance | BindingFlags.Public);
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
tb.GetField ("test");
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
tb.GetField ("test", BindingFlags.Public);
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetPropertyIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetProperty ("test");
+ try {
+ tb.GetProperty ("test");
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
tb.GetProperty ("CustomerName");
Assert.Fail ("#1");
} catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
Assert.IsNull (ex.InnerException, "#3");
Assert.IsNotNull (ex.Message, "#4");
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetPropertyFlagsIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetProperty ("test", BindingFlags.Public);
+ try {
+ tb.GetProperty ("test", BindingFlags.Public);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
TypeBuilder tb = module.DefineType (genTypeName (),
TypeAttributes.Abstract);
mb = tb.DefineMethod ("Hello", MethodAttributes.Public,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Run", MethodAttributes.Private,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Execute", MethodAttributes.Public |
MethodAttributes.Static,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Init", MethodAttributes.Public |
MethodAttributes.Abstract | MethodAttributes.Virtual,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
MethodInfo [] methods = tb.GetMethods ();
Assert.AreEqual (7, methods.Length, "#A");
TypeBuilder tb = module.DefineType (genTypeName (),
TypeAttributes.Abstract);
mb = tb.DefineMethod ("Hello", MethodAttributes.Public,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Run", MethodAttributes.Private,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Execute", MethodAttributes.Public |
MethodAttributes.Static,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Init", MethodAttributes.Public |
MethodAttributes.Abstract | MethodAttributes.Virtual,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
try {
tb.GetMethods ();
TypeBuilder tb = module.DefineType (genTypeName (),
TypeAttributes.Abstract);
mb = tb.DefineMethod ("Hello", MethodAttributes.Public,
- typeof (string), new Type [0]);
+ typeof (string), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ldstr, "Hi! ");
ilgen.Emit (OpCodes.Ldarg_1);
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Run", MethodAttributes.Private,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Execute", MethodAttributes.Public |
MethodAttributes.Static,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Init", MethodAttributes.Public |
MethodAttributes.Abstract | MethodAttributes.Virtual,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
Type emittedType = tb.CreateType ();
TypeBuilder tb = module.DefineType (genTypeName (),
TypeAttributes.Abstract);
mb = tb.DefineMethod ("Hello", MethodAttributes.Public,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Run", MethodAttributes.Private,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Execute", MethodAttributes.Public |
MethodAttributes.Static,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Init", MethodAttributes.Public |
MethodAttributes.Abstract | MethodAttributes.Virtual,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
methods = tb.GetMethods (BindingFlags.Public |
BindingFlags.Instance);
TypeBuilder tb = module.DefineType (genTypeName (),
TypeAttributes.Abstract);
mb = tb.DefineMethod ("Hello", MethodAttributes.Public,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Run", MethodAttributes.Private,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Execute", MethodAttributes.Public |
MethodAttributes.Static,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
ilgen = mb.GetILGenerator ();
ilgen.Emit (OpCodes.Ret);
mb = tb.DefineMethod ("Init", MethodAttributes.Public |
MethodAttributes.Abstract | MethodAttributes.Virtual,
- typeof (void), new Type [0]);
+ typeof (void), Type.EmptyTypes);
try {
tb.GetMethods (BindingFlags.Public | BindingFlags.Instance);
{
TypeBuilder tb = module.DefineType (genTypeName ());
MethodBuilder helloMethod = tb.DefineMethod ("HelloMethod",
- MethodAttributes.Public, typeof (string), new Type [0]);
+ MethodAttributes.Public, typeof (string), Type.EmptyTypes);
ILGenerator helloMethodIL = helloMethod.GetILGenerator ();
helloMethodIL.Emit (OpCodes.Ldstr, "Hi! ");
helloMethodIL.Emit (OpCodes.Ldarg_1);
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetMemberIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetMember ("FOO", MemberTypes.All, BindingFlags.Public);
+ try {
+ tb.GetMember ("FOO", MemberTypes.All, BindingFlags.Public);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetMembersIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetMembers ();
+ try {
+ tb.GetMembers ();
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetMembersFlagsIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetMembers (BindingFlags.Public);
+ try {
+ tb.GetMembers (BindingFlags.Public);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (NotSupportedException))]
public void TestGetInterfaceIncomplete ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
- tb.GetInterface ("FOO", true);
+ try {
+ tb.GetInterface ("FOO", true);
+ Assert.Fail ("#1");
+ } catch (NotSupportedException ex) {
+ // The invoked member is not supported in a
+ // dynamic module
+ Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void TestAddDeclarativeSecurityAlreadyCreated ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
tb.CreateType ();
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
- tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ try {
+ tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Unable to change after type has been created
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
- [ExpectedException (typeof (ArgumentNullException))]
public void TestAddDeclarativeSecurityNullPermissionSet ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
+ try {
+ tb.AddDeclarativeSecurity (SecurityAction.Demand, null);
+ Assert.Fail ("#1");
+ } catch (ArgumentNullException ex) {
+ Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.AreEqual ("pset", ex.ParamName, "#5");
+ }
- tb.AddDeclarativeSecurity (SecurityAction.Demand, null);
}
[Test]
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void TestAddDeclarativeSecurityDuplicateAction ()
{
TypeBuilder tb = module.DefineType (genTypeName ());
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
- tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ try {
+ tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Multiple permission sets specified with the
+ // same SecurityAction
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
TypeAttributes typeAttrs = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed;
TypeBuilder enumToCreate = module.DefineType (genTypeName (), typeAttrs,
typeof (Enum));
- enumToCreate.SetCustomAttribute (new CustomAttributeBuilder (typeof (FlagsAttribute).GetConstructors () [0], new Type [0]));
+ enumToCreate.SetCustomAttribute (new CustomAttributeBuilder (typeof (FlagsAttribute).GetConstructors () [0], Type.EmptyTypes));
// add value__ field, see DefineEnum method of ModuleBuilder
enumToCreate.DefineField ("value__", typeof (Int32),
FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
{
TypeBuilder tb = module.DefineType (genTypeName ());
ConstructorInfo attrCtor = typeof (SuppressUnmanagedCodeSecurityAttribute).
- GetConstructor (new Type [0]);
+ GetConstructor (Type.EmptyTypes);
CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (
attrCtor, new object [0]);
Assert.IsTrue ((tb.Attributes & TypeAttributes.HasSecurity) == 0, "#1");
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void EmptyMethodBody ()
{
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
tb.DefineMethod ("foo", MethodAttributes.Public, typeof (void), new Type [] { });
- tb.CreateType ();
+ try {
+ tb.CreateType ();
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void EmptyCtorBody ()
{
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
tb.DefineConstructor (0, CallingConventions.Standard, null);
- tb.CreateType ();
+ try {
+ tb.CreateType ();
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
[Test]
- [ExpectedException (typeof (InvalidOperationException))]
public void Fail_MakeGenericType ()
{
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
- tb.MakeGenericType (typeof (int));
+ try {
+ tb.MakeGenericType (typeof (int));
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ }
}
[Test]
}
#endif
- public interface IDelegateFactory {
+ public interface IDelegateFactory
+ {
Delegate Create (Delegate del);
}
+ [Test]
+ public void CreateType_Ctor_NoBody ()
+ {
+ TypeBuilder tb = module.DefineType (genTypeName ());
+ tb.DefineConstructor (MethodAttributes.Public,
+ CallingConventions.Standard,
+ new Type [] { typeof (string) });
+ try {
+ tb.CreateType ();
+ Assert.Fail ("#1");
+ } catch (InvalidOperationException ex) {
+ // Method '.ctor' does not have a method body
+ Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
+ Assert.IsNull (ex.InnerException, "#3");
+ Assert.IsNotNull (ex.Message, "#4");
+ Assert.IsTrue (ex.Message.IndexOf (".ctor") != -1, "#5");
+ }
+ }
+
[Test] //bug #361689
public void CreateTypeFailsWithInvalidMethodOverride ()
{
}
}
-
static MethodInfo GetMethodByName (MethodInfo [] methods, string name)
{
foreach (MethodInfo mi in methods)
System.Reflection.Emit/AssemblyBuilderTest.cs
System.Reflection.Emit/AssemblyBuilderAccessTest.cs
System.Reflection.Emit/ConstructorBuilderTest.cs
+System.Reflection.Emit/ConstructorOnTypeBuilderInstTest.cs
System.Reflection.Emit/CustomAttributeBuilderTest.cs
System.Reflection.Emit/DynamicMethodTest.cs
System.Reflection.Emit/EnumBuilderTest.cs
--- /dev/null
+// CS0831: An expression tree may not contain a base access
+// Line: 14
+
+using System;
+using System.Linq.Expressions;
+
+class B
+{
+ protected bool Core {
+ get {
+ return true;
+ }
+ }
+}
+
+class C : B
+{
+ public void Test ()
+ {
+ Expression<Func<bool>> e = () => base.Core;
+ }
+}
--- /dev/null
+// CS0831: An expression tree may not contain a base access
+// Line: 20
+
+using System;
+using System.Linq.Expressions;
+
+class B
+{
+ protected B this [int i] {
+ get {
+ return null;
+ }
+ }
+}
+
+class C : B
+{
+ public void Test ()
+ {
+ Expression<Func<B>> e = () => base [8];
+ }
+}
--- /dev/null
+// CS0831: An expression tree may not contain a base access
+// Line: 14
+
+using System;
+using System.Linq.Expressions;
+
+class B
+{
+ protected int Core ()
+ {
+ return 4;
+ }
+}
+
+class C : B
+{
+ public void Test ()
+ {
+ Expression<Func<int>> e = () => base.Core ();
+ }
+}
--- /dev/null
+// CS0832: An expression tree cannot contain an assignment operator
+// Line: 19
+
+using System;
+using System.Linq.Expressions;
+
+public delegate void EventHandler (int i, int j);
+
+public class Button
+{
+ public event EventHandler Click;
+}
+
+public class Blah
+{
+ public static void Main ()
+ {
+ Button b = new Button ();
+ Expression<Action> e = () => b.Click += new EventHandler (Button1_Click);
+ }
+
+ public static void Button1_Click (int i, int j)
+ {
+ }
+}
--- /dev/null
+// CS0843: An automatically implemented property `S.Short' must be fully assigned before control leaves the constructor. Consider calling default contructor
+// Line: 8
+
+using System;
+
+struct S
+{
+ public S (int value)
+ {
+ }
+
+ public short Short { get; set; }
+}
--- /dev/null
+// CS0845: An expression tree cannot contain a coalescing operator with null left side
+// Line: 11
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ public static void Main ()
+ {
+ Expression<Func<bool?, bool?>> e = (a) => null ?? a;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 15
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ unsafe delegate int* D (int i);
+
+ public static void Main ()
+ {
+ unsafe {
+ Expression<D> e = (int p) => &p;
+ }
+ }
+}
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 15
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ unsafe delegate int D (int* i);
+
+ public static void Main ()
+ {
+ unsafe {
+ Expression<D> e = p => *p;
+ }
+ }
+}
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 15
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ unsafe delegate int* D (int* i);
+
+ public static void Main ()
+ {
+ unsafe {
+ Expression<D> e = p => p + 1;
+ }
+ }
+}
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 13
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ public static void Main ()
+ {
+ unsafe {
+ Expression<Func<int>> e = () => sizeof (long*);
+ }
+ }
+}
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 14
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ unsafe delegate byte* D (int*[] d);
+ public static void Main ()
+ {
+ unsafe {
+ Expression<D> e6 = (p) => (byte*)p [10];
+ }
+ }
+}
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 15
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ unsafe delegate int* D ();
+
+ public static void Main ()
+ {
+ unsafe {
+ Expression<D> e = () => default (int*);
+ }
+ }
+}
--- /dev/null
+// CS1944: An expression tree cannot contain an unsafe pointer operation
+// Line: 14
+// Compiler options: -unsafe
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ public static void Main ()
+ {
+ unsafe {
+ int*[] p = null;
+ Expression<Func<int>> e6 = () => (int)p [10];
+ }
+ }
+}
--- /dev/null
+// CS1945: An expression tree cannot contain an anonymous method expression
+// Line: 11
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ public static void Main ()
+ {
+ Expression<Func<Func<int>>> e = () => delegate () { return 1; };
+ }
+}
--- /dev/null
+// CS1953: An expression tree cannot contain an expression with method group
+// Line: 11
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ public static void Main ()
+ {
+ Expression<Func<bool>> e = () => "1".ToString is string;
+ }
+}
\ No newline at end of file
+2008-05-01 Marek Safar <marek.safar@gmail.com>
+
+ * constant.cs, literal.cs: IsLiteral property for error reporting.
+
+ * ecore.cs, expression.cs: Implemented Property expression.
+
+2008-05-01 Marek Safar <marek.safar@gmail.com>
+
+ * class.cs, modifiers.cs, flowanalysis.cs: New BACKING_FIELD flag.
+
+ * nullable.cs: Implemented nullable coalescing null operator.
+
+ * ecore.cs, expression.cs: Expression trees work.
+
+2008-05-01 Marek Safar <marek.safar@gmail.com>
+
+ * ecore.cs: CreateExpressionTree is finally abstract.
+
+ * expression.cs, linq.cs: Updated.
+
+2008-05-01 Marek Safar <marek.safar@gmail.com>
+
+ * expression.cs, ecore.cs: Block base access expression inside expression
+ tree.
+
+2008-05-01 Marek Safar <marek.safar@gmail.com>
+
+ A fix for bug #385058
+ * expression.cs: User-defined operator implementations always take
+ precedence over predefined operator implementations.
+
+2008-04-30 Marek Safar <marek.safar@gmail.com>
+
+ * assign.cs, anonymous.cs, lambda.cs, nullable.cs, ecore.cs, linq.cs,
+ class.cs, iterators.cs, expression.cs, attribute.cs: Filled a few more
+ expression tree conversions.
+
+2008-04-30 Marek Safar <marek.safar@gmail.com>
+
+ * typemanager.cs, ecore.cs, class.cs, expression.cs, doc.cs: Merged all
+ operators method details to Operator class.
+
+2008-04-30 Marek Safar <marek.safar@gmail.com>
+
+ * anonymous.cs: Pass unsafe flags to anonymous container.
+
+ * ecore.cs, expression.cs, statement.cs: Block unsafe pointer operations
+ inside expression tree.
+
2008-04-29 Martin Baulig <martin@ximian.com>
* cs-tokenizer.cs (Tokenizer.Position): Added `line'.
get { return scope; }
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
if (scope_ctor != null)
}
protected virtual Expression CreateExpressionTree (EmitContext ec, Type delegate_type)
+ {
+ return CreateExpressionTree (ec);
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
{
Report.Error (1946, loc, "An anonymous method cannot be converted to an expression tree");
return null;
if (ec.IsInFieldInitializer)
flags |= EmitContext.Flags.InFieldInitializer;
+
+ if (ec.IsInUnsafeScope)
+ flags |= EmitContext.Flags.InUnsafe;
// HACK: Flag with 0 cannot be set
if (flags != 0)
return TypeManager.CSharpName (DelegateType);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Report.Error (1945, loc, "An expression tree cannot contain an anonymous method expression");
+ return null;
+ }
+
//
// Creates the host for the anonymous method
//
this.am = am;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return am.CreateExpressionTree (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
eclass = ExprClass.Value;
builder = null;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
return this;
this.loc = loc;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return new SimpleAssign (target, source).CreateExpressionTree (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
eclass = ExprClass.Value;
this.op = op;
}
+ // !!! What a stupid name
public class Helper : Expression {
Expression child;
public Helper (Expression child)
this.loc = child.Location;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
child = child.Resolve (ec);
return e.TypeArgument;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
throw new NotImplementedException ();
}
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
{
if (argument_list != null){
return true;
}
+ public override string GetSignatureForError ()
+ {
+ string s = base.GetSignatureForError ();
+ if ((ModFlags & Modifiers.BACKING_FIELD) == 0)
+ return s;
+
+ // Undecorate name mangling
+ int l = s.LastIndexOf ('>');
+ return s.Substring (0, l).Remove (s.LastIndexOf ('<'), 1);
+ }
+
protected override bool VerifyClsCompliance ()
{
if (!base.VerifyClsCompliance ())
// Make the field
Field field = new Field (
Parent, type_name,
- Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
+ Modifiers.BACKING_FIELD | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
"<" + Name + ">k__BackingField", null, Location);
((TypeContainer)Parent).AddField (field);
};
public readonly OpType OperatorType;
+
+ static readonly string [] [] names;
+
+ static Operator ()
+ {
+ names = new string[(int)OpType.TOP][];
+ names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
+ names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
+ names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
+ names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
+ names [(int) OpType.True] = new string [] { "true", "op_True" };
+ names [(int) OpType.False] = new string [] { "false", "op_False" };
+ names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
+ names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
+ names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
+ names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
+ names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
+ names [(int) OpType.Division] = new string [] { "/", "op_Division" };
+ names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
+ names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
+ names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
+ names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
+ names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
+ names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
+ names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
+ names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
+ names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
+ names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
+ names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
+ names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
+ names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
+ names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
+ }
public Operator (DeclSpace parent, OpType type, FullNamedExpression ret_type,
int mod_flags, Parameters parameters,
// imlicit and explicit operator of same types are not allowed
if (OperatorType == OpType.Explicit)
- Parent.MemberCache.CheckExistingMembersOverloads (this, "op_Implicit", Parameters);
+ Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), Parameters);
else if (OperatorType == OpType.Implicit)
- Parent.MemberCache.CheckExistingMembersOverloads (this, "op_Explicit", Parameters);
+ Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters);
if (MemberType == TypeManager.void_type) {
Report.Error (590, Location, "User-defined operators cannot return void");
public static string GetName (OpType ot)
{
- switch (ot){
- case OpType.LogicalNot:
- return "!";
- case OpType.OnesComplement:
- return "~";
- case OpType.Increment:
- return "++";
- case OpType.Decrement:
- return "--";
- case OpType.True:
- return "true";
- case OpType.False:
- return "false";
- case OpType.Addition:
- return "+";
- case OpType.Subtraction:
- return "-";
- case OpType.UnaryPlus:
- return "+";
- case OpType.UnaryNegation:
- return "-";
- case OpType.Multiply:
- return "*";
- case OpType.Division:
- return "/";
- case OpType.Modulus:
- return "%";
- case OpType.BitwiseAnd:
- return "&";
- case OpType.BitwiseOr:
- return "|";
- case OpType.ExclusiveOr:
- return "^";
- case OpType.LeftShift:
- return "<<";
- case OpType.RightShift:
- return ">>";
- case OpType.Equality:
- return "==";
- case OpType.Inequality:
- return "!=";
- case OpType.GreaterThan:
- return ">";
- case OpType.LessThan:
- return "<";
- case OpType.GreaterThanOrEqual:
- return ">=";
- case OpType.LessThanOrEqual:
- return "<=";
- case OpType.Implicit:
- return "implicit";
- case OpType.Explicit:
- return "explicit";
- default: return "";
+ return names [(int) ot] [0];
+ }
+
+ public static string GetName (string metadata_name)
+ {
+ for (int i = 0; i < names.Length; ++i) {
+ if (names [i] [1] == metadata_name)
+ return names [i] [0];
}
+ return null;
+ }
+
+ public static string GetMetadataName (OpType ot)
+ {
+ return names [(int) ot] [1];
+ }
+
+ public static string GetMetadataName (string name)
+ {
+ for (int i = 0; i < names.Length; ++i) {
+ if (names [i] [0] == name)
+ return names [i] [1];
+ }
+ return null;
}
public OpType GetMatchingOperator ()
}
}
- public static OpType GetOperatorType (string name)
- {
- if (name.StartsWith ("op_")){
- for (int i = 0; i < Unary.oper_names.Length; ++i) {
- if (Unary.oper_names [i] == name)
- return (OpType)i;
- }
-
- for (int i = 0; i < Binary.oper_names.Length; ++i) {
- if (Binary.oper_names [i] == name)
- return (OpType)i;
- }
- }
- return OpType.TOP;
- }
-
public override string GetSignatureForError ()
{
StringBuilder sb = new StringBuilder ();
return this;
}
+ public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
+ {
+ if (!expl && IsLiteral && type != TypeManager.string_type) {
+ Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
+ GetValue ().ToString (), TypeManager.CSharpName (target));
+ } else {
+ base.Error_ValueCannotBeConverted (ec, loc, target, expl);
+ }
+ }
+
public Constant ImplicitConversionRequired (Type type, Location loc)
{
Constant c = ConvertImplicitly (type);
get;
}
+ //
+ // When constant is declared as literal
+ //
+ public virtual bool IsLiteral {
+ get { return false; }
+ }
+
//
// Returns true iff 1) the stack type of this is one of Object,
// int32, int64 and 2) this == 0 or this == null.
string oper = null;
string return_type_name = null;
if (member_name.StartsWith ("implicit operator ")) {
- oper = "op_Implicit";
+ Operator.GetMetadataName (Operator.OpType.Implicit);
return_type_name = member_name.Substring (18).Trim (wsChars);
}
else if (member_name.StartsWith ("explicit operator ")) {
- oper = "op_Explicit";
+ oper = Operator.GetMetadataName (Operator.OpType.Explicit);
return_type_name = member_name.Substring (18).Trim (wsChars);
}
else if (member_name.StartsWith ("operator ")) {
// either unary or binary
case "+":
oper = param_list.Length == 2 ?
- Binary.GetOperatorMetadataName (Binary.Operator.Addition) :
- Unary.oper_names [(int) Unary.Operator.UnaryPlus];
+ Operator.GetMetadataName (Operator.OpType.Addition) :
+ Operator.GetMetadataName (Operator.OpType.UnaryPlus);
break;
case "-":
oper = param_list.Length == 2 ?
- Binary.GetOperatorMetadataName (Binary.Operator.Subtraction) :
- Unary.oper_names [(int) Unary.Operator.UnaryNegation];
+ Operator.GetMetadataName (Operator.OpType.Subtraction) :
+ Operator.GetMetadataName (Operator.OpType.UnaryNegation);
break;
- // unary
- case "!":
- oper = Unary.oper_names [(int) Unary.Operator.LogicalNot]; break;
- case "~":
- oper = Unary.oper_names [(int) Unary.Operator.OnesComplement]; break;
-
- case "++":
- oper = "op_Increment"; break;
- case "--":
- oper = "op_Decrement"; break;
- case "true":
- oper = "op_True"; break;
- case "false":
- oper = "op_False"; break;
- // binary
- case "*":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.Multiply); break;
- case "/":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.Division); break;
- case "%":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.Modulus); break;
- case "&":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.BitwiseAnd); break;
- case "|":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.BitwiseOr); break;
- case "^":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.ExclusiveOr); break;
- case "<<":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.LeftShift); break;
- case ">>":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.RightShift); break;
- case "==":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.Equality); break;
- case "!=":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.Inequality); break;
- case "<":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.LessThan); break;
- case ">":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.GreaterThan); break;
- case "<=":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.LessThanOrEqual); break;
- case ">=":
- oper = Binary.GetOperatorMetadataName (Binary.Operator.GreaterThanOrEqual); break;
default:
+ oper = Operator.GetMetadataName (oper);
+ if (oper != null)
+ break;
+
warning_type = 1584;
Report.Warning (1020, 1, mc.Location, "Overloadable {0} operator is expected", param_list.Length == 2 ? "binary" : "unary");
Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
return;
}
- if (Type != TypeManager.string_type && this is Constant && !(this is EmptyConstantCast)) {
- Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
- ((Constant)(this)).GetValue ().ToString (), TypeManager.CSharpName (target));
- return;
- }
-
Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'",
TypeManager.CSharpName (type),
TypeManager.CSharpName (target));
throw new NotImplementedException ();
}
+ protected void Error_PointerInsideExpressionTree ()
+ {
+ Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
+ }
+
/// <summary>
/// Returns an expression that can be used to invoke operator true
/// on the expression if it exists.
static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
{
MethodGroupExpr operator_group;
- operator_group = MethodLookup (ec.ContainerType, e.Type, is_true ? "op_True" : "op_False", loc) as MethodGroupExpr;
+ string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
+ operator_group = MethodLookup (ec.ContainerType, e.Type, mname, loc) as MethodGroupExpr;
if (operator_group == null)
return null;
return cloned;
}
- public virtual Expression CreateExpressionTree (EmitContext ec)
- {
- throw new NotImplementedException (
- "Expression tree conversion not implemented for " + GetType ());
- }
+ //
+ // Implementation of expression to expression tree conversion
+ //
+ public abstract Expression CreateExpressionTree (EmitContext ec);
protected Expression CreateExpressionFactoryCall (string name, ArrayList args)
{
ArrayList args = new ArrayList (2);
args.Add (new Argument (child.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+
+ if (type.IsPointer || child.Type.IsPointer)
+ Error_PointerInsideExpressionTree ();
+
return CreateExpressionFactoryCall (ec.CheckState ? "ConvertChecked" : "Convert", args);
}
ArrayList args = new ArrayList (2);
args.Add (new Argument (child.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+ if (type.IsPointer)
+ Error_PointerInsideExpressionTree ();
+
return CreateExpressionFactoryCall ("Convert", args);
}
/// section 10.8.1 (Fully Qualified Names).
/// </summary>
public abstract class FullNamedExpression : Expression {
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
{
return this;
"with an instance reference, qualify it with a type name instead", name);
}
+ public static void Error_BaseAccessInExpressionTree (Location loc)
+ {
+ Report.Error (831, loc, "An expression tree may not contain a base access");
+ }
+
// TODO: possible optimalization
// Cache resolved constant result in FieldBuilder <-> expression map
public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
public override Expression CreateExpressionTree (EmitContext ec)
{
+ if (best_candidate == null) {
+ Report.Error (1953, loc, "An expression tree cannot contain an expression with method group");
+ return null;
+ }
+
if (best_candidate.IsConstructor)
return new TypeOfConstructorInfo (best_candidate, loc);
+
+ IMethodData md = TypeManager.GetMethod (best_candidate);
+ if (md != null && md.IsExcluded ())
+ Report.Error (765, loc,
+ "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
return new TypeOfMethodInfo (best_candidate, loc);
}
public override Expression CreateExpressionTree (EmitContext ec)
{
- throw new NotSupportedException ();
+ throw new NotSupportedException ("ET");
}
public override Expression DoResolve (EmitContext ec)
public override Expression CreateExpressionTree (EmitContext ec)
{
+ ArrayList args;
if (IsSingleDimensionalArrayLength ()) {
- ArrayList args = new ArrayList (1);
+ args = new ArrayList (1);
args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
return CreateExpressionFactoryCall ("ArrayLength", args);
}
- // TODO: it's waiting for PropertyExpr refactoring
- //ArrayList args = new ArrayList (2);
- //args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
- //args.Add (getter expression);
- //return CreateExpressionFactoryCall ("Property", args);
- return base.CreateExpressionTree (ec);
+ if (is_base) {
+ Error_BaseAccessInExpressionTree (loc);
+ return null;
+ }
+
+ args = new ArrayList (2);
+ if (InstanceExpression == null)
+ args.Add (new Argument (new NullLiteral (loc)));
+ else
+ args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec)));
+ args.Add (new Argument (new TypeOfMethodInfo (getter, loc)));
+ return CreateExpressionFactoryCall ("Property", args);
}
public Expression CreateSetterTypeOfExpression ()
public override Expression CreateExpressionTree (EmitContext ec)
{
- throw new NotSupportedException ();
+ throw new NotSupportedException ("ET");
}
public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
this.loc = loc;
eclass = ExprClass.Value;
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
public override Expression DoResolve (EmitContext ec)
{
public ParenthesizedExpression (Expression expr)
{
this.Expr = expr;
+ this.loc = expr.Location;
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
}
public override Expression DoResolve (EmitContext ec)
throw new Exception ("Should not happen");
}
- public override Location Location
- {
- get {
- return Expr.Location;
- }
- }
-
protected override void CloneTo (CloneContext clonectx, Expression t)
{
ParenthesizedExpression target = (ParenthesizedExpression) t;
AddressOf, TOP
}
- public static readonly string [] oper_names;
static Type [] [] predefined_operators;
public readonly Operator Oper;
this.loc = loc;
}
- static Unary ()
- {
- oper_names = new string [(int)Operator.TOP];
-
- oper_names [(int) Operator.UnaryPlus] = "op_UnaryPlus";
- oper_names [(int) Operator.UnaryNegation] = "op_UnaryNegation";
- oper_names [(int) Operator.LogicalNot] = "op_LogicalNot";
- oper_names [(int) Operator.OnesComplement] = "op_OnesComplement";
- oper_names [(int) Operator.AddressOf] = "op_AddressOf";
- }
-
// <summary>
// This routine will attempt to simplify the unary expression when the
// argument is a constant.
{
string method_name;
switch (Oper) {
+ case Operator.AddressOf:
+ Error_PointerInsideExpressionTree ();
+ return null;
case Operator.UnaryNegation:
if (ec.CheckState && user_op == null && !IsFloat (type))
method_name = "NegateChecked";
//
protected virtual Expression ResolveUserOperator (EmitContext ec, Expression expr)
{
- string op_name = oper_names [(int) Oper];
+ CSharp.Operator.OpType op_type;
+ switch (Oper) {
+ case Operator.LogicalNot:
+ op_type = CSharp.Operator.OpType.LogicalNot; break;
+ case Operator.OnesComplement:
+ op_type = CSharp.Operator.OpType.OnesComplement; break;
+ case Operator.UnaryNegation:
+ op_type = CSharp.Operator.OpType.UnaryNegation; break;
+ case Operator.UnaryPlus:
+ op_type = CSharp.Operator.OpType.UnaryPlus; break;
+ default:
+ throw new InternalErrorException (Oper.ToString ());
+ }
+
+ string op_name = CSharp.Operator.GetMetadataName (op_type);
MethodGroupExpr user_op = MemberLookup (ec.ContainerType, expr.Type, op_name, MemberTypes.Method, AllBindingFlags, expr.Location) as MethodGroupExpr;
if (user_op == null)
return null;
this.expr = expr;
loc = l;
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Error_PointerInsideExpressionTree ();
+ return null;
+ }
public override void Emit (EmitContext ec)
{
string op_name;
if (mode == Mode.PreIncrement || mode == Mode.PostIncrement)
- op_name = "op_Increment";
- else
- op_name = "op_Decrement";
+ op_name = Operator.GetMetadataName (Operator.OpType.Increment);
+ else
+ op_name = Operator.GetMetadataName (Operator.OpType.Decrement);
mg = MemberLookup (ec.ContainerType, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
/// Implementation of the `is' operator.
/// </summary>
public class Is : Probe {
+ Nullable.Unwrap expr_unwrap;
+
public Is (Expression expr, Expression probe_type, Location l)
: base (expr, probe_type, l)
{
public override void Emit (EmitContext ec)
{
ILGenerator ig = ec.ig;
+ if (expr_unwrap != null) {
+ expr_unwrap.EmitCheck (ec);
+ return;
+ }
expr.Emit (ec);
ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
ILGenerator ig = ec.ig;
-
- expr.Emit (ec);
- ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
+ if (expr_unwrap != null) {
+ expr_unwrap.EmitCheck (ec);
+ } else {
+ expr.Emit (ec);
+ ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
+ }
ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
}
//
// D and T are the same value types but D can be null
//
- if (d_is_nullable && !t_is_nullable)
- return Nullable.HasValue.Create (expr, ec);
+ if (d_is_nullable && !t_is_nullable) {
+ expr_unwrap = Nullable.Unwrap.Create (expr, ec);
+ return this;
+ }
//
// The result is true if D and T are the same value types
get { return expr; }
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
expr = expr.Resolve (ec);
} else {
Constant c = New.Constantify (type);
if (c != null)
- return new EmptyConstantCast (c, type);
+ return c;
if (!TypeManager.IsValueType (type))
return new EmptyConstantCast (new NullLiteral (Location), type);
readonly bool is_compound;
Expression enum_conversion;
- // This must be kept in sync with Operator!!!
- public static readonly string [] oper_names;
-
static PredefinedOperator [] standard_operators;
static PredefinedOperator [] pointer_operators;
- static Binary ()
- {
- oper_names = new string [18];
-
- oper_names [(int) (Operator.Multiply & Operator.ValuesOnlyMask)] = "op_Multiply";
- oper_names [(int) (Operator.Division & Operator.ValuesOnlyMask)] = "op_Division";
- oper_names [(int) (Operator.Modulus & Operator.ValuesOnlyMask)] = "op_Modulus";
- oper_names [(int) (Operator.Addition & Operator.ValuesOnlyMask)] = "op_Addition";
- oper_names [(int) (Operator.Subtraction & Operator.ValuesOnlyMask)] = "op_Subtraction";
- oper_names [(int) (Operator.LeftShift & Operator.ValuesOnlyMask)] = "op_LeftShift";
- oper_names [(int) (Operator.RightShift & Operator.ValuesOnlyMask)] = "op_RightShift";
- oper_names [(int) (Operator.LessThan & Operator.ValuesOnlyMask)] = "op_LessThan";
- oper_names [(int) (Operator.GreaterThan & Operator.ValuesOnlyMask)] = "op_GreaterThan";
- oper_names [(int) (Operator.LessThanOrEqual & Operator.ValuesOnlyMask)] = "op_LessThanOrEqual";
- oper_names [(int) (Operator.GreaterThanOrEqual & Operator.ValuesOnlyMask)] = "op_GreaterThanOrEqual";
- oper_names [(int) (Operator.Equality & Operator.ValuesOnlyMask)] = "op_Equality";
- oper_names [(int) (Operator.Inequality & Operator.ValuesOnlyMask)] = "op_Inequality";
- oper_names [(int) (Operator.BitwiseAnd & Operator.ValuesOnlyMask)] = "op_BitwiseAnd";
- oper_names [(int) (Operator.BitwiseOr & Operator.ValuesOnlyMask)] = "op_BitwiseOr";
- oper_names [(int) (Operator.ExclusiveOr & Operator.ValuesOnlyMask)] = "op_ExclusiveOr";
- oper_names [(int) (Operator.LogicalOr & Operator.ValuesOnlyMask)] = "op_LogicalOr";
- oper_names [(int) (Operator.LogicalAnd & Operator.ValuesOnlyMask)] = "op_LogicalAnd";
- }
-
public Binary (Operator oper, Expression left, Expression right, bool isCompound)
: this (oper, left, right)
{
Error_OperatorCannotBeApplied (Location, OperName (oper), l, r);
}
- public static string GetOperatorMetadataName (Operator op)
+ static string GetOperatorMetadataName (Operator op)
{
- return oper_names [(int)(op & Operator.ValuesOnlyMask)];
+ CSharp.Operator.OpType op_type;
+ switch (op) {
+ case Operator.Addition:
+ op_type = CSharp.Operator.OpType.Addition; break;
+ case Operator.BitwiseAnd:
+ op_type = CSharp.Operator.OpType.BitwiseAnd; break;
+ case Operator.BitwiseOr:
+ op_type = CSharp.Operator.OpType.BitwiseOr; break;
+ case Operator.Division:
+ op_type = CSharp.Operator.OpType.Division; break;
+ case Operator.Equality:
+ op_type = CSharp.Operator.OpType.Equality; break;
+ case Operator.ExclusiveOr:
+ op_type = CSharp.Operator.OpType.ExclusiveOr; break;
+ case Operator.GreaterThan:
+ op_type = CSharp.Operator.OpType.GreaterThan; break;
+ case Operator.GreaterThanOrEqual:
+ op_type = CSharp.Operator.OpType.GreaterThanOrEqual; break;
+ case Operator.Inequality:
+ op_type = CSharp.Operator.OpType.Inequality; break;
+ case Operator.LeftShift:
+ op_type = CSharp.Operator.OpType.LeftShift; break;
+ case Operator.LessThan:
+ op_type = CSharp.Operator.OpType.LessThan; break;
+ case Operator.LessThanOrEqual:
+ op_type = CSharp.Operator.OpType.LessThanOrEqual; break;
+ case Operator.Modulus:
+ op_type = CSharp.Operator.OpType.Modulus; break;
+ case Operator.Multiply:
+ op_type = CSharp.Operator.OpType.Multiply; break;
+ case Operator.RightShift:
+ op_type = CSharp.Operator.OpType.RightShift; break;
+ case Operator.Subtraction:
+ op_type = CSharp.Operator.OpType.Subtraction; break;
+ default:
+ throw new InternalErrorException (op.ToString ());
+ }
+
+ return CSharp.Operator.GetMetadataName (op_type);
}
static bool IsUnsigned (Type t)
MethodInfo method;
ArrayList args = new ArrayList (2);
-
- args = new ArrayList (2);
args.Add (new Argument (left, Argument.AType.Expression));
args.Add (new Argument (right, Argument.AType.Expression));
method = TypeManager.delegate_remove_delegate_delegate;
}
- return new BinaryDelegate (l, method, args);
+ MethodGroupExpr mg = new MethodGroupExpr (new MemberInfo [] { method }, TypeManager.delegate_type, loc);
+ mg = mg.OverloadResolve (ec, ref args, false, loc);
+
+ return new ClassCast (new UserOperatorCall (mg, args, CreateExpressionTree, loc), l);
}
//
string op = GetOperatorMetadataName (user_oper);
- MethodGroupExpr union;
MethodGroupExpr left_operators = MemberLookup (ec.ContainerType, l, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
- if (!TypeManager.IsEqual (r, l)) {
- MethodGroupExpr right_operators = MemberLookup (
- ec.ContainerType, r, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
- union = MethodGroupExpr.MakeUnionSet (left_operators, right_operators, loc);
- } else
- union = left_operators;
+ MethodGroupExpr right_operators = null;
- if (union == null)
+ if (!TypeManager.IsEqual (r, l)) {
+ right_operators = MemberLookup (ec.ContainerType, r, op, MemberTypes.Method, AllBindingFlags, loc) as MethodGroupExpr;
+ if (right_operators == null && left_operators == null)
+ return null;
+ } else if (left_operators == null) {
return null;
+ }
ArrayList args = new ArrayList (2);
Argument larg = new Argument (left);
Argument rarg = new Argument (right);
args.Add (rarg);
+ MethodGroupExpr union;
+
+ //
+ // User-defined operator implementations always take precedence
+ // over predefined operator implementations
+ //
+ if (left_operators != null && right_operators != null) {
+ if (IsPredefinedUserOperator (l, user_oper)) {
+ union = right_operators.OverloadResolve (ec, ref args, true, loc);
+ if (union == null)
+ union = left_operators;
+ } else if (IsPredefinedUserOperator (r, user_oper)) {
+ union = left_operators.OverloadResolve (ec, ref args, true, loc);
+ if (union == null)
+ union = right_operators;
+ } else {
+ union = MethodGroupExpr.MakeUnionSet (left_operators, right_operators, loc);
+ }
+ } else if (left_operators != null) {
+ union = left_operators;
+ } else {
+ union = right_operators;
+ }
+
union = union.OverloadResolve (ec, ref args, true, loc);
if (union == null)
return null;
t == TypeManager.delegate_type || TypeManager.IsDelegateType (t);
}
+ static bool IsPredefinedUserOperator (Type t, Operator op)
+ {
+ //
+ // Some predefined types have user operators
+ //
+ return (op & Operator.EqualityMask) != 0 && (t == TypeManager.string_type || t == TypeManager.decimal_type);
+ }
+
private static bool IsTypeIntegral (Type type)
{
return type == TypeManager.uint64_type ||
return CreateExpressionFactoryCall (method_name, args);
}
}
-
- //
- // Object created by Binary when the binary operator uses an method instead of being
- // a binary operation that maps to a CIL binary operation.
- //
- public class BinaryMethod : Expression {
- public MethodBase method;
- public ArrayList Arguments;
-
- public BinaryMethod (Type t, MethodBase m, ArrayList args)
- {
- method = m;
- Arguments = args;
- type = t;
- eclass = ExprClass.Value;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- Invocation.EmitArguments (ec, Arguments, false, null);
-
- if (method is MethodInfo)
- ig.Emit (OpCodes.Call, (MethodInfo) method);
- else
- ig.Emit (OpCodes.Call, (ConstructorInfo) method);
- }
- }
//
// Represents the operation a + b [+ c [+ d [+ ...]]], where a is a string
}
}
- //
- // Object created with +/= on delegates
- //
- public class BinaryDelegate : Expression {
- MethodInfo method;
- ArrayList args;
-
- public BinaryDelegate (Type t, MethodInfo mi, ArrayList args)
- {
- method = mi;
- this.args = args;
- type = t;
- eclass = ExprClass.Value;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
-
- Invocation.EmitArguments (ec, args, false, null);
-
- ig.Emit (OpCodes.Call, (MethodInfo) method);
- ig.Emit (OpCodes.Castclass, type);
- }
-
- public Expression Right {
- get {
- Argument arg = (Argument) args [1];
- return arg.Expr;
- }
- }
-
- public bool IsAddition {
- get {
- return method == TypeManager.delegate_combine_delegate_delegate;
- }
- }
- }
-
//
// User-defined conditional logical operator
//
is_add = is_addition;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Error_PointerInsideExpressionTree ();
+ return null;
+ }
+
public override Expression DoResolve (EmitContext ec)
{
eclass = ExprClass.Variable;
public bool Resolve (EmitContext ec, Location loc)
{
+ if (Expr == null)
+ return false;
+
using (ec.With (EmitContext.Flags.DoFlowAnalysis, true)) {
// Verify that the argument is readable
if (ArgType != AType.Out)
}
}
+ if (mg.IsBase)
+ MemberExpr.Error_BaseAccessInExpressionTree (loc);
+
return CreateExpressionFactoryCall ("Call", args);
}
this.loc = expr.Location;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
//
{
ArrayList args;
- if (dimensions != 1) {
- if (initializers != null) {
- Report.Error (838, loc, "An expression tree cannot contain a multidimensional array initializer");
- return null;
- }
-
+ if (array_data == null) {
args = new ArrayList (arguments.Count + 1);
args.Add (new Argument (new TypeOf (new TypeExpression (array_element_type, loc), loc)));
- foreach (Argument a in arguments)
+ foreach (Argument a in arguments) {
+ if (arguments.Count == 1) {
+ Constant c = a.Expr as Constant;
+ if (c.IsDefaultValue)
+ return CreateExpressionFactoryCall ("NewArrayInit", args);
+ }
args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
+ }
return CreateExpressionFactoryCall ("NewArrayBounds", args);
}
+ if (dimensions > 1) {
+ Report.Error (838, loc, "An expression tree cannot contain a multidimensional array initializer");
+ return null;
+ }
+
args = new ArrayList (array_data == null ? 1 : array_data.Count + 1);
args.Add (new Argument (new TypeOf (new TypeExpression (array_element_type, loc), loc)));
if (array_data != null) {
this.loc = loc;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
eclass = ExprClass.Variable;
}
}
- //
- // This produces the value that renders an instance, used by the iterators code
- //
- public class ProxyInstance : Expression, IMemoryLocation {
- public override Expression DoResolve (EmitContext ec)
- {
- eclass = ExprClass.Variable;
- type = ec.ContainerType;
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- ec.ig.Emit (OpCodes.Ldarg_0);
-
- }
-
- public void AddressOf (EmitContext ec, AddressOp mode)
- {
- ec.ig.Emit (OpCodes.Ldarg_0);
- }
- }
-
/// <summary>
/// Implements the typeof operator
/// </summary>
this.loc = loc;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
if (TypeManager.fieldinfo_get_field_from_handle == null) {
loc = l;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Error_PointerInsideExpressionTree ();
+ return null;
+ }
+
public override Expression DoResolve (EmitContext ec)
{
TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec, false);
throw new NotImplementedException (at.ToString ());
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ ArrayList args = new ArrayList (arguments.Count + 2);
+ args.Add (new Argument (instance_expr.CreateExpressionTree (ec)));
+ args.Add (new Argument (new TypeOfMethodInfo (get, loc)));
+ foreach (Argument a in arguments)
+ args.Add (new Argument (a.Expr.CreateExpressionTree (ec)));
+
+ return CreateExpressionFactoryCall ("Call", args);
+ }
+
protected virtual bool CommonResolve (EmitContext ec)
{
indexer_type = instance_expr.Type;
this.args = args;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
Expression c = CommonResolve (ec);
return true;
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ MemberExpr.Error_BaseAccessInExpressionTree (loc);
+ return base.CreateExpressionTree (ec);
+ }
}
/// <summary>
eclass = ExprClass.Value;
loc = Location.Null;
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
public override Expression DoResolve (EmitContext ec)
{
loc = Location.Null;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return null;
+ }
+
public override void EmitStatement (EmitContext ec)
{
// Do nothing
public override Expression CreateExpressionTree (EmitContext ec)
{
- ArrayList args = new ArrayList (2);
+ ArrayList args = new ArrayList (3);
args.Add (new Argument (source.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
args.Add (new Argument (new TypeOfMethodInfo (method, loc)));
eclass = ExprClass.Value;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Error_PointerInsideExpressionTree ();
+ return null;
+ }
+
public override void Emit(EmitContext ec)
{
array.Emit (ec);
//
// Encapsulates a conversion rules required for array indexes
//
- public class ArrayIndexCast : Expression
+ public class ArrayIndexCast : TypeCast
{
- Expression expr;
-
public ArrayIndexCast (Expression expr)
+ : base (expr, expr.Type)
{
- this.expr = expr;
- this.loc = expr.Location;
}
public override Expression CreateExpressionTree (EmitContext ec)
{
ArrayList args = new ArrayList (2);
- args.Add (new Argument (expr.CreateExpressionTree (ec)));
+ args.Add (new Argument (child.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (TypeManager.int32_type, loc), loc)));
return CreateExpressionFactoryCall ("ConvertChecked", args);
}
- public override Expression DoResolve (EmitContext ec)
- {
- type = expr.Type;
- eclass = expr.eclass;
- return this;
- }
-
public override void Emit (EmitContext ec)
{
- expr.Emit (ec);
+ child.Emit (ec);
if (type == TypeManager.int32_type)
return;
}
}
- //
- // Used by the fixed statement
- //
- public class StringPtr : Expression {
- LocalBuilder b;
-
- public StringPtr (LocalBuilder b, Location l)
- {
- this.b = b;
- eclass = ExprClass.Value;
- type = TypeManager.char_ptr_type;
- loc = l;
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- // This should never be invoked, we are born in fully
- // initialized state.
-
- return this;
- }
-
- public override void Emit (EmitContext ec)
- {
- if (TypeManager.int_get_offset_to_string_data == null) {
- // TODO: Move to resolve !!
- TypeManager.int_get_offset_to_string_data = TypeManager.GetPredefinedMethod (
- TypeManager.runtime_helpers_type, "get_OffsetToStringData", loc, Type.EmptyTypes);
- }
-
- ILGenerator ig = ec.ig;
-
- ig.Emit (OpCodes.Ldloc, b);
- ig.Emit (OpCodes.Conv_I);
- ig.Emit (OpCodes.Call, TypeManager.int_get_offset_to_string_data);
- ig.Emit (OpCodes.Add);
- }
- }
-
//
// Implements the `stackalloc' keyword
//
loc = l;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
count = count.Resolve (ec);
public override Expression CreateExpressionTree (EmitContext ec)
{
// Should not be reached
- throw new NotSupportedException ();
+ throw new NotSupportedException ("ET");
}
public override Expression DoResolve (EmitContext ec)
return type;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
AnonymousTypeClass anonymous_type;
t.initializer = initializer.Clone (clonectx);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override bool Equals (object o)
{
AnonymousTypeParameter other = o as AnonymousTypeParameter;
FieldInfo field = struct_info.Fields [i];
if (!branching.IsFieldAssigned (vi, field.Name)) {
- Report.Error (171, loc,
- "Field `{0}' must be fully assigned before control leaves the constructor",
- TypeManager.GetFullNameSignature (field));
+ FieldBase fb = TypeManager.GetField (field);
+ if (fb != null && (fb.ModFlags & Modifiers.BACKING_FIELD) != 0) {
+ Report.Error (843, loc,
+ "An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling default contructor",
+ fb.GetSignatureForError ());
+ } else {
+ Report.Error (171, loc,
+ "Field `{0}' must be fully assigned before control leaves the constructor",
+ TypeManager.GetFullNameSignature (field));
+ }
ok = false;
}
}
}
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public static Iterator CreateIterator (IMethodData method, DeclSpace parent,
GenericMethod generic, int modifiers)
{
return "lambda expression";
}
}
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return Block.CreateExpressionTree (ec);
+ }
}
//
t.next = (AQueryClause)next.Clone (clonectx);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ // Should not be reached
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
return expr.DoResolve (ec);
LambdaExpression selector = new LambdaExpression (
null, null, (TypeContainer)ec.TypeContainer, p, ec.CurrentBlock, loc);
selector.Block = new SelectorBlock (ec.CurrentBlock, p, ti, loc);
- selector.Block.AddStatement (new Return (expr, loc));
+ selector.Block.AddStatement (new ContextualReturn (expr));
if (!ec.IsInProbingMode) {
selector.CreateAnonymousHelpers ();
// Nothing to clone
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ();
+ }
+
public override Expression DoResolve (EmitContext ec)
{
throw new NotSupportedException ();
get { return true; }
}
- public override bool IsNegative
- {
+ public override bool IsLiteral {
+ get { return true; }
+ }
+
+ public override bool IsNegative {
get { return false; }
}
get { return true; }
}
- public override bool IsZeroInteger
- {
+ public override bool IsZeroInteger {
get { return true; }
}
type = TypeManager.bool_type;
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class CharLiteral : CharConstant {
type = TypeManager.char_type;
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class IntLiteral : IntConstant {
return base.ConvertImplicitly (type);
}
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class UIntLiteral : UIntConstant {
type = TypeManager.uint32_type;
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class LongLiteral : LongConstant {
public override Expression DoResolve (EmitContext ec)
{
type = TypeManager.int64_type;
-
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class ULongLiteral : ULongConstant {
type = TypeManager.uint64_type;
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class FloatLiteral : FloatConstant {
type = TypeManager.float_type;
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
+
}
public class DoubleLiteral : DoubleConstant {
"Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",
type, suffix);
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
+
}
public class DecimalLiteral : DecimalConstant {
type = TypeManager.decimal_type;
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
}
public class StringLiteral : StringConstant {
return this;
}
+
+ public override bool IsLiteral {
+ get { return true; }
+ }
+
}
}
//
public const int METHOD_YIELDS = 0x8000;
public const int METHOD_GENERIC = 0x10000;
- public const int PARTIAL = 0x20000;
+ public const int PARTIAL = 0x20000;
public const int DEFAULT_ACCESS_MODIFER = 0x40000;
public const int METHOD_EXTENSION = 0x80000;
public const int COMPILER_GENERATED = 0x100000;
+ public const int BACKING_FIELD = 0x200000 | COMPILER_GENERATED;
public const int Accessibility =
PUBLIC | PROTECTED | INTERNAL | PRIVATE;
Constructor = type.GetConstructor (new Type[] { UnderlyingType });
}
}
-
- public class HasValue : Expression
- {
- Expression expr;
- NullableInfo info;
-
- private HasValue (Expression expr)
- {
- this.expr = expr;
- }
-
- public static Expression Create (Expression expr, EmitContext ec)
- {
- return new HasValue (expr).Resolve (ec);
- }
-
- public override void Emit (EmitContext ec)
- {
- IMemoryLocation memory_loc = expr as IMemoryLocation;
- if (memory_loc == null) {
- LocalTemporary temp = new LocalTemporary (expr.Type);
- expr.Emit (ec);
- temp.Store (ec);
- memory_loc = temp;
- }
- memory_loc.AddressOf (ec, AddressOp.LoadStore);
- ec.ig.EmitCall (OpCodes.Call, info.HasValue, null);
- }
-
- public override Expression DoResolve (EmitContext ec)
- {
- this.info = new NullableInfo (expr.Type);
-
- type = TypeManager.bool_type;
- eclass = expr.eclass;
- return this;
- }
- }
public class Unwrap : Expression, IMemoryLocation, IAssignMethod
{
eclass = ExprClass.Value;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
return this;
public override Expression CreateExpressionTree (EmitContext ec)
{
+ if (left is NullLiteral)
+ Report.Error (845, loc, "An expression tree cannot contain a coalescing operator with null left side");
+
UserCast uc = left as UserCast;
Expression conversion = null;
if (uc != null) {
type = expr.Type;
return this;
}
+ } else if (left.IsNull) {
+ if (!Convert.ImplicitConversionExists (ec, right, TypeManager.object_type)) {
+ Binary.Error_OperatorCannotBeApplied (loc, "??", ltype, rtype);
+ return null;
+ }
+
+ return ReducedExpression.Create (right, this).Resolve (ec);
} else if (!TypeManager.IsReferenceType (ltype)) {
Binary.Error_OperatorCannotBeApplied (loc, "??", ltype, rtype);
return null;
eclass = ExprClass.Value;
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return new SimpleAssign (this, this).CreateExpressionTree (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
expr = expr.Resolve (ec);
}
class StringEmitter : Emitter {
+ class StringPtr : Expression
+ {
+ LocalBuilder b;
+
+ public StringPtr (LocalBuilder b, Location l)
+ {
+ this.b = b;
+ eclass = ExprClass.Value;
+ type = TypeManager.char_ptr_type;
+ loc = l;
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ // This should never be invoked, we are born in fully
+ // initialized state.
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ if (TypeManager.int_get_offset_to_string_data == null) {
+ // TODO: Move to resolve !!
+ TypeManager.int_get_offset_to_string_data = TypeManager.GetPredefinedMethod (
+ TypeManager.runtime_helpers_type, "get_OffsetToStringData", loc, Type.EmptyTypes);
+ }
+
+ ILGenerator ig = ec.ig;
+
+ ig.Emit (OpCodes.Ldloc, b);
+ ig.Emit (OpCodes.Conv_I);
+ ig.Emit (OpCodes.Call, TypeManager.int_get_offset_to_string_data);
+ ig.Emit (OpCodes.Add);
+ }
+ }
+
LocalBuilder pinned_string;
Location loc;
int accessor_end = 0;
if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
- Operator.OpType ot = Operator.GetOperatorType (mb.Name);
- if (ot != Operator.OpType.TOP) {
+ string op_name = Operator.GetName (mb.Name);
+ if (op_name != null) {
sig.Append ("operator ");
- sig.Append (Operator.GetName (ot));
+ sig.Append (op_name);
sig.Append (parameters);
return sig.ToString ();
}
return true;
string name = mb.Name;
- if (name.StartsWith ("op_")){
- foreach (string oname in Unary.oper_names) {
- if (oname == name)
- return true;
- }
+ if (name.StartsWith ("op_"))
+ return Operator.GetName (name) != null;
- foreach (string oname in Binary.oper_names) {
- if (oname == name)
- return true;
- }
- }
return false;
}
--- /dev/null
+using System;
+
+class C
+{
+ public static int Main ()
+ {
+ string a = null;
+ string b = null ?? "a";
+ if (b != "a")
+ return 1;
+
+ int? i = null ?? null;
+ if (i != null)
+ return 2;
+
+ return 0;
+ }
+}
\ No newline at end of file
+// Compiler options: -unsafe
+
using System;
using System.Collections.Generic;
using System.Linq;
public struct MyType
{
int value;
-
- public MyType (int value)
+
+ public MyType (int value) : this ()
{
this.value = value;
}
+ public short ShortProp { get; set; }
+
public override int GetHashCode ()
{
throw new NotImplementedException ();
get {
return mt;
}
- }
+ }
+
+ public static string StaticProperty {
+ get {
+ return "alo";
+ }
+ }
}
enum MyEnum : byte
}
}
+class Indexer
+{
+ public int this [int i] { get { return i; } set { } }
+ public string this [params string[] i] { get { return string.Concat (i); } }
+}
+
// TODO: Add more nullable tests, follow AddTest pattern.
decimal [] [] array = { new decimal [] { 1, 9 }, new decimal [] { 10, 90 } };
Assert (90, e4.Compile ().Invoke (array, 1));
+
+ Expression<Func<int>> e5 = () => (new int [1]) [0];
+ AssertNodeType (e5, ExpressionType.ArrayIndex);
+ Assert (0, e5.Compile ().Invoke ());
}
void ArrayLengthTest ()
Assert (0, e.Compile ().Invoke (new double [0]));
Assert (9, e.Compile ().Invoke (new double [9]));
- //Expression<Func<string [,], int>> e2 = (string [,] a) => a.Length;
- //AssertNodeType (e2, ExpressionType.MemberAccess);
- //Assert (0, e2.Compile ().Invoke (new string [0, 0]));
+ Expression<Func<string [,], int>> e2 = (string [,] a) => a.Length;
+ AssertNodeType (e2, ExpressionType.MemberAccess);
+ Assert (0, e2.Compile ().Invoke (new string [0, 0]));
}
void CallTest ()
Expression<Action> e6 = () => Console.WriteLine ("call test");
AssertNodeType (e6, ExpressionType.Call);
- }
+
+ Expression<Func<Indexer, int, int>> e7 = (a, b) => a [b];
+ AssertNodeType (e7, ExpressionType.Call);
+ Assert (3, e7.Compile ().Invoke (new Indexer (), 3));
+
+ Expression<Func<Indexer, string, string, string, string>> e8 = (a, b, c , d) => a [b, c, d];
+ AssertNodeType (e8, ExpressionType.Call);
+ Assert ("zyb", e8.Compile ().Invoke (new Indexer (), "z", "y", "b"));
+
+ Expression<Action<int>> e9 = (a) => RefMethod (ref a);
+ AssertNodeType (e9, ExpressionType.Call);
+ e9.Compile ().Invoke (1);
+ }
void CoalesceTest ()
{
void ConstantTest ()
{
-// Expression<Func<int>> e1 = () => default (int);
-// AssertNodeType (e1, ExpressionType.Constant);
-// Assert (0, e1.Compile ().Invoke ());
+ Expression<Func<int>> e1 = () => default (int);
+ AssertNodeType (e1, ExpressionType.Constant);
+ Assert (0, e1.Compile ().Invoke ());
Expression<Func<int?>> e2 = () => default (int?);
AssertNodeType (e2, ExpressionType.Constant);
Expression<Func<MyEnum>> e12 = () => new MyEnum ();
AssertNodeType (e12, ExpressionType.Constant);
Assert<MyEnum> (0, e12.Compile ().Invoke ());
+
+ Expression<Func<int>> e13 = () => sizeof (byte);
+ AssertNodeType (e13, ExpressionType.Constant);
+ Assert (1, e13.Compile ().Invoke ());
+
+ unsafe {
+ Expression<Func<Type>> e14 = () => typeof (bool*);
+ AssertNodeType (e14, ExpressionType.Constant);
+ Assert (typeof (bool*), e14.Compile ().Invoke ());
+ }
}
void ConvertTest ()
Assert (true, e6.Compile ().Invoke (null, null));
Assert (true, e6.Compile ().Invoke (new MyType (120), new MyType (120)));
- // TODO: redundant return conversion
- // Expression<Func<MyTypeExplicit, int?>> e6 = x => (int?)x;
+ Expression<Func<MyTypeExplicit, int?>> e7 = x => (int?)x;
+ AssertNodeType (e7, ExpressionType.Convert);
+ Assert (33, e7.Compile ().Invoke (new MyTypeExplicit (33)));
- // TODO: redundant convert
- // TODO: pass null value
- // Expression<Func<int?, object>> ex = x => (object)x;
+ Expression<Func<int?, object>> e8 = x => (object)x;
+ AssertNodeType (e8, ExpressionType.Convert);
+ Assert (null, e8.Compile ().Invoke (null));
+ Assert (-100, e8.Compile ().Invoke (-100));
+
+ unsafe {
+ int*[] p = new int* [1];
+ Expression<Func<object>> e9 = () => (object)p;
+ AssertNodeType (e9, ExpressionType.Convert);
+ Assert (p, e9.Compile ().Invoke ());
+ }
+
+ Expression<Func<Func<int>, Delegate>> e10 = (a) => a + a;
+ AssertNodeType (e10, ExpressionType.Convert);
+ Assert (null, e10.Compile ().Invoke (null));
+ Assert (new Func<int> (TestInt) + new Func<int> (TestInt), e10.Compile ().Invoke (TestInt));
+
+ Expression<Func<Func<int>, Delegate>> e11 = (a) => a - a;
+ AssertNodeType (e11, ExpressionType.Convert);
+ Assert (null, e11.Compile ().Invoke (null));
+
+ Expression<Func<Func<int>>> e12 = () => TestInt;
+ AssertNodeType (e12, ExpressionType.Convert);
+ Assert (29, e12.Compile ().Invoke () ());
+
+ Expression<Func<decimal, sbyte>> e13 = a => (sbyte)a;
+ AssertNodeType (e13, ExpressionType.Convert);
+ Assert (6, e13.Compile ().Invoke (6));
+
+ Expression<Func<long, decimal>> e14 = a => a;
+ AssertNodeType (e14, ExpressionType.Convert);
+ Assert (-66, e14.Compile ().Invoke (-66));
+
+ Expression<Func<ulong?, decimal?>> e15 = a => a;
+ AssertNodeType (e15, ExpressionType.Convert);
+ Assert (null, e15.Compile ().Invoke (null));
+ Assert (9, e15.Compile ().Invoke (9));
}
void ConvertCheckedTest ()
var e5 = d.GetEvent ();
AssertNodeType (e5, ExpressionType.MemberAccess);
Assert (null, e5.Compile ().Invoke ());
+
+ Expression<Func<MyType>> e6 = () => d.MyTypeProperty;
+ AssertNodeType (e6, ExpressionType.MemberAccess);
+ Assert (new MyType (), e6.Compile ().Invoke ());
+
+ Expression<Func<MyType, short>> e7 = a => a.ShortProp;
+ AssertNodeType (e7, ExpressionType.MemberAccess);
+ MyType mt = new MyType ();
+ mt.ShortProp = 124;
+ Assert (124, e7.Compile ().Invoke (mt));
+
+ Expression<Func<string>> e8 = () => MemberAccessData.StaticProperty;
+ AssertNodeType (e8, ExpressionType.MemberAccess);
+ Assert ("alo", e8.Compile ().Invoke ());
+
+ string s = "localvar";
+ Expression<Func<string>> e9 = () => s;
+ // CSC emits this as MemberAccess
+ AssertNodeType (e9, ExpressionType.Constant);
+ Assert ("localvar", e9.Compile ().Invoke ());
}
void MemberInitTest ()
AssertNodeType (e2, ExpressionType.MemberInit);
var r2 = e2.Compile ().Invoke ();
Assert ("a", r2.ListValues [0]);
+
+ Expression<Func<short, MyType>> e3 = a => new MyType { ShortProp = a };
+ AssertNodeType (e3, ExpressionType.MemberInit);
+ var r3 = e3.Compile ().Invoke (33);
+ Assert (33, r3.ShortProp);
}
void ModuloTest ()
AssertNodeType (e, ExpressionType.NewArrayInit);
Assert (new int [0], e.Compile ().Invoke ());
- e = () => new int [] { };
- AssertNodeType (e, ExpressionType.NewArrayInit);
- Assert (new int [0], e.Compile ().Invoke ());
+ Expression<Func<int []>> e1 = () => new int [] { };
+ AssertNodeType (e1, ExpressionType.NewArrayInit);
+ Assert (new int [0], e1.Compile ().Invoke ());
Expression<Func<ushort, ulong? []>> e2 = (ushort a) => new ulong? [] { a };
AssertNodeType (e2, ExpressionType.NewArrayInit);
Expression<Func<int [,]>> e = () => new int [2,3];
AssertNodeType (e, ExpressionType.NewArrayBounds);
Assert (new int [2,3].Length, e.Compile ().Invoke ().Length);
+
+ Expression<Func<int[,]>> e2 = () => new int [0,0];
+ AssertNodeType (e2, ExpressionType.NewArrayBounds);
+ Assert (new int [0, 0].Length, e2.Compile ().Invoke ().Length);
}
void NewTest ()
Expression<Func<IntPtr, IntPtr>> e3 = a => a;
AssertNodeType (e3, ExpressionType.Parameter);
Assert (IntPtr.Zero, e3.Compile ().Invoke (IntPtr.Zero));
+
+ unsafe {
+ Expression<Func<int*[], int* []>> e4 = (a) => a;
+ AssertNodeType (e4, ExpressionType.Parameter);
+ Assert<int*[]> (null, e4.Compile ().Invoke (null));
+ int* e4_el = stackalloc int [5];
+ int*[] ptr = new int*[] { e4_el };
+ Assert<int*[]> (ptr, e4.Compile ().Invoke (ptr));
+ }
}
void QuoteTest ()
Expression<Func<bool>> e5 = () => 1 is int;
AssertNodeType (e5, ExpressionType.TypeIs);
Assert (true, e5.Compile ().Invoke ());
+
+ Expression<Func<int?, bool>> e6 = (a) => a is int;
+ AssertNodeType (e6, ExpressionType.TypeIs);
+ Assert (true, e6.Compile ().Invoke (1));
+ Assert (false, e6.Compile ().Invoke (null));
}
void UnaryPlus ()
{
return t;
}
-
+
+ static void RefMethod (ref int i)
+ {
+ i = 867;
+ }
public static int Main ()
{
+// Compiler options: -unsafe
+
using System;
using System.Linq.Expressions;
delegate void EmptyDelegate ();
+unsafe delegate int* UnsafeDelegate ();
class C
{
i += 9;
}
+ static unsafe int* Foo ()
+ {
+ return (int*)1;
+ }
+
public static int Main ()
{
Expression<Func<EmptyDelegate>> e = () => new EmptyDelegate (Test);
Expression<Func<EmptyDelegate>> e2 = () => Test;
if (e2.Body.ToString () != "Convert(CreateDelegate(EmptyDelegate, null, Void Test()))")
- return 1;
+ return 3;
var v2 = e2.Compile ();
v2.Invoke ()();
if (i != 18)
- return 2;
+ return 4;
+
+ unsafe {
+ Expression<Func<UnsafeDelegate>> e3 = () => new UnsafeDelegate (Foo);
+ if (e3.Body.ToString () != "Convert(CreateDelegate(UnsafeDelegate, null, Int32* Foo()))")
+ return 5;
+
+ var v3 = e3.Compile ();
+ if (v3.Invoke ()() != (int*)1)
+ return 6;
+ }
+ Console.WriteLine ("OK");
return 0;
}
}
+
--- /dev/null
+using System;
+
+public class Identifier
+{
+ public Identifier () { }
+
+ public static bool operator == (Identifier id1, Identifier id2)
+ {
+ return true;
+ }
+ public static bool operator != (Identifier id1, Identifier id2)
+ {
+ return true;
+ }
+
+ public static implicit operator Identifier (string identifier)
+ {
+ return null;
+ }
+
+ public static implicit operator String (Identifier id)
+ {
+ return null;
+ }
+
+ public static implicit operator decimal (Identifier id)
+ {
+ return -1;
+ }
+
+ static int Main ()
+ {
+ Identifier a = null;
+ string b = "a";
+
+ if (!(a == b))
+ return 1;
+
+ decimal d = 5;
+ if (a == d)
+ return 2;
+
+ return 0;
+ }
+}
+
<size>10</size>
</method>
<method name="Int32 TestC()">
- <size>34</size>
+ <size>36</size>
</method>
<method name="Int32 Main()">
<size>107</size>
</method>
</type>
</test>
+ <test name="gtest-391.cs">
+ <type name="C">
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ <method name="Int32 Main()">
+ <size>55</size>
+ </method>
+ </type>
+ </test>
<test name="gtest-anon-1.cs">
<type name="X">
<method name="Void .ctor()">
</method>
</type>
</test>
+ <test name="test-641.cs">
+ <type name="Identifier">
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ <method name="Int32 Main()">
+ <size>55</size>
+ </method>
+ <method name="Boolean op_Equality(Identifier, Identifier)">
+ <size>2</size>
+ </method>
+ <method name="Boolean op_Inequality(Identifier, Identifier)">
+ <size>2</size>
+ </method>
+ <method name="Identifier op_Implicit(System.String)">
+ <size>2</size>
+ </method>
+ <method name="System.String op_Implicit(Identifier)">
+ <size>2</size>
+ </method>
+ <method name="Decimal op_Implicit(Identifier)">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-65.cs">
<type name="X">
<method name="Void .ctor()">
+2008-05-01 Zoltan Varga <vargaz@gmail.com>
+
+ * sgen-gc.c: Implement thread-local allocation and a managed allocation routine.
+
+2008-05-01 Dick Porter <dick@ximian.com>
+
+ * process.c (process_get_fileversion): Only pass 16 bits of
+ language ID to VerLanguageName. Fixes bug 381204.
+
+2008-04-30 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * verify.c (mono_method_verify): Fix the comparison
+ operator for code bounds check.
+
+2008-04-30 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * verify.c (mono_method_verify): Check the bounds of
+ all access of the code array.
+
2008-04-29 Kornél Pál <kornelpal@gmail.com>
* appdomain.c: Use HAVE_SYS_UTIME_H that fixes MSVC build.
(trans_data[1] << 8) |
(trans_data[2] << 16) |
(trans_data[3] << 24);
- lang_count = VerLanguageName (lang, lang_buf, 128);
+ /* Only give the lower 16 bits
+ * to VerLanguageName, as
+ * Windows gets confused
+ * otherwise
+ */
+ lang_count = VerLanguageName (lang & 0xFFFF, lang_buf, 128);
if (lang_count) {
process_set_field_string (filever, "language", lang_buf, lang_count);
}
#include "metadata/threads.h"
#include "metadata/sgen-gc.h"
#include "metadata/mono-gc.h"
+#include "metadata/method-builder.h"
+#include "metadata/profiler-private.h"
#include "utils/mono-mmap.h"
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ a = i,
+
+enum {
+#include "mono/cil/opcode.def"
+ CEE_LAST
+};
+
+#undef OPDEF
+
/*
* ######################################################################
* ######## Types and constants used by the GC.
}
#define MAX_DEBUG_LEVEL 9
-#define DEBUG(level,a) do {if ((level) <= MAX_DEBUG_LEVEL && (level) <= gc_debug_level) a;} while (0)
+#define DEBUG(level,a) do {if (G_UNLIKELY ((level) <= MAX_DEBUG_LEVEL && (level) <= gc_debug_level)) a;} while (0)
#define TV_DECLARE(name) struct timeval name
#define TV_GETTIME(tv) gettimeofday (&(tv), NULL)
* We should start assigning threads very small fragments: if there are many
* threads the nursery will be full of reserved space that the threads may not
* use at all, slowing down allocation speed.
+ * Thread local allocation is done from areas of memory Hotspot calls Thread Local
+ * Allocation Buffers (TLABs).
*/
typedef struct _Fragment Fragment;
}
static inline gboolean
-is_half_constructed (MonoObject *o)
+is_maybe_half_constructed (MonoObject *o)
{
MonoClass *klass;
* The current allocation cursors
* We allocate objects in the nursery.
* The nursery is the area between nursery_start and nursery_real_end.
- * nursery_next is the pointer to the space where the next object will be allocated.
- * nursery_temp_end is the pointer to the end of the temporary space reserved for
- * the allocation: this allows us to allow allocations inside the fragments of the
- * nursery (the empty holes between pinned objects) and it allows us to set the
- * scan starts at reasonable intervals.
- * nursery_next and nursery_temp_end will become per-thread vars to allow lock-free
- * allocations.
+ * Allocation is done from a Thread Local Allocation Buffer (TLAB). TLABs are allocated
+ * from nursery fragments.
+ * tlab_next is the pointer to the space inside the TLAB where the next object will
+ * be allocated.
+ * tlab_temp_end is the pointer to the end of the temporary space reserved for
+ * the allocation: it allows us to set the scan starts at reasonable intervals.
+ * tlab_real_end points to the end of the TLAB.
+ * nursery_frag_real_end points to the end of the currently used nursery fragment.
* nursery_first_pinned_start points to the start of the first pinned object in the nursery
* nursery_last_pinned_end points to the end of the last pinned object in the nursery
* At the next allocation, the area of the nursery where objects can be present is
* between MIN(nursery_first_pinned_start, first_fragment_start) and
- * MAX(nursery_last_pinned_end, nursery_temp_end)
+ * MAX(nursery_last_pinned_end, nursery_frag_real_end)
*/
static char *nursery_start = NULL;
+
+/*
+ * FIXME: What is faster, a TLS variable pointing to a structure, or separate TLS
+ * variables for next+temp_end ?
+ */
+static __thread char *tlab_start;
+static __thread char *tlab_next;
+static __thread char *tlab_temp_end;
+static __thread char *tlab_real_end;
+/* Used by the managed allocator */
+static __thread char **tlab_next_addr;
static char *nursery_next = NULL;
-static char *nursery_temp_end = NULL;
-static char *nursery_real_end = NULL;
static char *nursery_frag_real_end = NULL;
+static char *nursery_real_end = NULL;
static char *nursery_first_pinned_start = NULL;
static char *nursery_last_pinned_end = NULL;
+/* The size of a TLAB */
+/* The bigger the value, the less often we have to go to the slow path to allocate a new
+ * one, but the more space is wasted by threads not allocating much memory.
+ * FIXME: Tune this.
+ * FIXME: Make this self-tuning for each thread.
+ */
+static guint32 tlab_size = (1024 * 4);
+
/* fragments that are free and ready to be used for allocation */
static Fragment *nursery_fragments = NULL;
/* freeelist of fragment structures */
static gboolean search_fragment_for_size (size_t size);
static void mark_pinned_from_addresses (PinnedChunk *chunk, void **start, void **end);
static void clear_remsets (void);
+static void clear_tlabs (void);
+static char *find_tlab_next_from_address (char *addr);
static void sweep_pinned_objects (void);
static void free_large_object (LOSObject *obj);
static void free_mem_section (GCMemSection *section);
data = get_os_memory (nursery_size, TRUE);
nursery_start = nursery_next = data;
nursery_real_end = data + nursery_size;
- nursery_temp_end = data + SCAN_START_SIZE;
UPDATE_HEAP_BOUNDARIES (nursery_start, nursery_real_end);
total_alloc += nursery_size;
DEBUG (4, fprintf (gc_debug_file, "Expanding heap size: %zd, total: %zd\n", nursery_size, total_alloc));
static int last_num_pinned = 0;
static void
-build_nursery_fragments (int start_pin, int end_pin, char *nursery_last_allocated)
+build_nursery_fragments (int start_pin, int end_pin)
{
char *frag_start, *frag_end;
size_t frag_size;
* (zero initialized) object. Find the end of the object by scanning forward.
*
*/
- if (is_half_constructed (pin_queue [i])) {
- /* Can't use nursery_next as the limit as it is modified in collect_nursery () */
- while ((frag_start < nursery_last_allocated) && *(mword*)frag_start == 0)
- frag_start += sizeof (mword);
+ if (is_maybe_half_constructed (pin_queue [i])) {
+ char *tlab_end;
+
+ /* This is also hit for zero length arrays/strings */
+
+ /* Find the end of the TLAB which contained this allocation */
+ tlab_end = find_tlab_next_from_address (pin_queue [i]);
+
+ if (tlab_end) {
+ while ((frag_start < tlab_end) && *(mword*)frag_start == 0)
+ frag_start += sizeof (mword);
+ } else {
+ /*
+ * FIXME: The object is either not allocated in a TLAB, or it isn't a
+ * half constructed object.
+ */
+ }
}
}
nursery_last_pinned_end = frag_start;
}
degraded_mode = 1;
}
+
+ /* Clear TLABs for all threads */
+ clear_tlabs ();
}
/* FIXME: later reduce code duplication here with the above
GCMemSection *section;
size_t max_garbage_amount;
int i;
- char *nursery_last_allocated;
TV_DECLARE (all_atv);
TV_DECLARE (all_btv);
TV_DECLARE (atv);
TV_DECLARE (btv);
degraded_mode = 0;
- nursery_last_allocated = nursery_next;
nursery_next = MAX (nursery_next, nursery_last_pinned_end);
/* FIXME: optimize later to use the higher address where an object can be present */
nursery_next = MAX (nursery_next, nursery_real_end);
* pinned objects as we go, memzero() the empty fragments so they are ready for the
* next allocations.
*/
- build_nursery_fragments (0, next_pin_slot, nursery_last_allocated);
+ build_nursery_fragments (0, next_pin_slot);
TV_GETTIME (atv);
DEBUG (2, fprintf (gc_debug_file, "Fragment creation: %d usecs, %zd bytes available\n", TV_ELAPSED (btv, atv), fragment_total));
* pinned objects as we go, memzero() the empty fragments so they are ready for the
* next allocations.
*/
- build_nursery_fragments (nursery_section->pin_queue_start, nursery_section->pin_queue_end, nursery_next);
+ build_nursery_fragments (nursery_section->pin_queue_start, nursery_section->pin_queue_end);
TV_GETTIME (all_btv);
mono_stats.major_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
if (!search_fragment_for_size (size)) {
int i;
/* TypeBuilder and MonoMethod are killing mcs with fragmentation */
- DEBUG (1, fprintf (gc_debug_file, "nursery collection didn't find enough room for %zd alloc (%d pinned)", size, last_num_pinned));
+ DEBUG (1, fprintf (gc_debug_file, "nursery collection didn't find enough room for %zd alloc (%d pinned)\n", size, last_num_pinned));
for (i = 0; i < last_num_pinned; ++i) {
DEBUG (3, fprintf (gc_debug_file, "Bastard pinning obj %p (%s), size: %d\n", pin_queue [i], safe_name (pin_queue [i]), safe_object_get_size (pin_queue [i])));
}
degraded_mode = 1;
+ /* This is needed by collect_nursery () to calculate nursery_last_allocated */
+ nursery_next = nursery_frag_real_end = NULL;
}
}
//report_internal_mem_usage ();
nursery_fragments = frag->next;
nursery_next = frag->fragment_start;
nursery_frag_real_end = frag->fragment_end;
- nursery_temp_end = MIN (nursery_frag_real_end, nursery_next + size + SCAN_START_SIZE);
DEBUG (4, fprintf (gc_debug_file, "Using nursery fragment %p-%p, size: %zd (req: %zd)\n", nursery_next, nursery_frag_real_end, nursery_frag_real_end - nursery_next, size));
frag->next = fragment_freelist;
{
/* FIXME: handle OOM */
void **p;
+ char *new_next;
int dummy;
+ gboolean res;
size += ALLOC_ALIGN - 1;
size &= ~(ALLOC_ALIGN - 1);
g_assert (vtable->gc_descr);
- LOCK_GC;
- if (collect_before_allocs) {
+ if (G_UNLIKELY (collect_before_allocs)) {
int dummy;
if (nursery_section) {
+ LOCK_GC;
+
update_current_thread_stack (&dummy);
stop_world ();
collect_nursery (0);
// FIXME:
g_assert_not_reached ();
}
+ UNLOCK_GC;
}
}
- p = (void**)nursery_next;
+ /* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */
+
+ p = (void**)tlab_next;
/* FIXME: handle overflow */
- nursery_next += size;
- if (nursery_next >= nursery_temp_end) {
- /* there are two cases: the object is too big or we need to collect */
- /* there can be another case (from ORP), if we cooperate with the runtime a bit:
- * objects that need finalizers can have the high bit set in their size
- * so the above check fails and we can readily add the object to the queue.
- * This avoids taking again the GC lock when registering, but this is moot when
- * doing thread-local allocation, so it may not be a good idea.
+ new_next = (char*)p + size;
+ tlab_next = new_next;
+
+ if (G_LIKELY (new_next < tlab_temp_end)) {
+ /* Fast path */
+
+ /*
+ * FIXME: We might need a memory barrier here so the change to tlab_next is
+ * visible before the vtable store.
*/
- if (size > MAX_SMALL_OBJ_SIZE) {
- /* get ready for possible collection */
- update_current_thread_stack (&dummy);
- nursery_next -= size;
- p = alloc_large_inner (vtable, size);
- } else {
- if (nursery_next >= nursery_frag_real_end) {
- nursery_next -= size;
- /* when running in degraded mode, we continue allocing that way
- * for a while, to decrease the number of useless nursery collections.
- */
- if (degraded_mode && degraded_mode < DEFAULT_NURSERY_SIZE) {
- p = alloc_degraded (vtable, size);
- UNLOCK_GC;
- return p;
- }
- if (!search_fragment_for_size (size)) {
- /* get ready for possible collection */
- update_current_thread_stack (&dummy);
- minor_collect_or_expand_inner (size);
- if (degraded_mode) {
- p = alloc_degraded (vtable, size);
- UNLOCK_GC;
- return p;
+
+ DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size));
+ *p = vtable;
+
+ return p;
+ }
+
+ /* Slow path */
+
+ /* there are two cases: the object is too big or we run out of space in the TLAB */
+ /* we also reach here when the thread does its first allocation after a minor
+ * collection, since the tlab_ variables are initialized to NULL.
+ * there can be another case (from ORP), if we cooperate with the runtime a bit:
+ * objects that need finalizers can have the high bit set in their size
+ * so the above check fails and we can readily add the object to the queue.
+ * This avoids taking again the GC lock when registering, but this is moot when
+ * doing thread-local allocation, so it may not be a good idea.
+ */
+ LOCK_GC;
+ if (size > MAX_SMALL_OBJ_SIZE) {
+ /* get ready for possible collection */
+ update_current_thread_stack (&dummy);
+ tlab_next -= size;
+ p = alloc_large_inner (vtable, size);
+ } else {
+ if (tlab_next >= tlab_real_end) {
+ /*
+ * Run out of space in the TLAB. When this happens, some amount of space
+ * remains in the TLAB, but not enough to satisfy the current allocation
+ * request. Currently, we retire the TLAB in all cases, later we could
+ * keep it if the remaining space is above a treshold, and satisfy the
+ * allocation directly from the nursery.
+ * FIXME: Currently, tlab_size < SCAN_START_SIZE, so scan_starts are not
+ * set.
+ */
+ tlab_next -= size;
+ /* when running in degraded mode, we continue allocing that way
+ * for a while, to decrease the number of useless nursery collections.
+ */
+ if (degraded_mode && degraded_mode < DEFAULT_NURSERY_SIZE) {
+ p = alloc_degraded (vtable, size);
+ UNLOCK_GC;
+ return p;
+ }
+
+ if (size > tlab_size) {
+ /* Allocate directly from the nursery */
+ if (nursery_next + size >= nursery_frag_real_end) {
+ if (!search_fragment_for_size (size)) {
+ /* get ready for possible collection */
+ update_current_thread_stack (&dummy);
+ minor_collect_or_expand_inner (size);
+ if (degraded_mode) {
+ p = alloc_degraded (vtable, size);
+ UNLOCK_GC;
+ return p;
+ }
}
}
- /* nursery_next changed by minor_collect_or_expand_inner () */
+
p = (void*)nursery_next;
nursery_next += size;
- if (nursery_next > nursery_temp_end) {
+ if (nursery_next > nursery_frag_real_end) {
// no space left
g_assert (0);
}
} else {
- /* record the scan start so we can find pinned objects more easily */
+ DEBUG (3, fprintf (gc_debug_file, "Retire TLAB: %p-%p [%ld]\n", tlab_start, tlab_real_end, (long)(tlab_real_end - tlab_next)));
+
+ if (nursery_next + tlab_size >= nursery_frag_real_end) {
+ res = search_fragment_for_size (tlab_size);
+ if (!res) {
+ /* get ready for possible collection */
+ update_current_thread_stack (&dummy);
+ minor_collect_or_expand_inner (tlab_size);
+ if (degraded_mode) {
+ p = alloc_degraded (vtable, size);
+ UNLOCK_GC;
+ return p;
+ }
+ }
+ }
+
+ /* Allocate a new TLAB from the current nursery fragment */
+ tlab_start = nursery_next;
+ nursery_next += tlab_size;
+ tlab_next = tlab_start;
+ tlab_real_end = tlab_start + tlab_size;
+ tlab_temp_end = tlab_start + MIN (SCAN_START_SIZE, tlab_size);
+
+ /* Allocate from the TLAB */
+ p = (void*)tlab_next;
+ tlab_next += size;
+ g_assert (tlab_next <= tlab_real_end);
+
nursery_section->scan_starts [((char*)p - (char*)nursery_section->data)/SCAN_START_SIZE] = (char*)p;
- /* we just bump nursery_temp_end as well */
- nursery_temp_end = MIN (nursery_frag_real_end, nursery_next + SCAN_START_SIZE);
- DEBUG (5, fprintf (gc_debug_file, "Expanding local alloc: %p-%p\n", nursery_next, nursery_temp_end));
}
+ } else {
+ /* Reached tlab_temp_end */
+
+ /* record the scan start so we can find pinned objects more easily */
+ nursery_section->scan_starts [((char*)p - (char*)nursery_section->data)/SCAN_START_SIZE] = (char*)p;
+ /* we just bump tlab_temp_end as well */
+ tlab_temp_end = MIN (tlab_real_end, tlab_next + SCAN_START_SIZE);
+ DEBUG (5, fprintf (gc_debug_file, "Expanding local alloc: %p-%p\n", tlab_next, tlab_temp_end));
}
}
+
DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size));
*p = vtable;
int skip;
void *stack_end;
void *stack_start;
+ char **tlab_next_addr;
+ char **tlab_start_addr;
+ char **tlab_temp_end_addr;
+ char **tlab_real_end_addr;
RememberedSet *remset;
};
}
}
+/*
+ * Clear the thread local TLAB variables for all threads.
+ */
+static void
+clear_tlabs (void)
+{
+ SgenThreadInfo *info;
+ int i;
+
+ for (i = 0; i < THREAD_HASH_SIZE; ++i) {
+ for (info = thread_table [i]; info; info = info->next) {
+ /* A new TLAB will be allocated when the thread does its first allocation */
+ *info->tlab_start_addr = NULL;
+ *info->tlab_next_addr = NULL;
+ *info->tlab_temp_end_addr = NULL;
+ *info->tlab_real_end_addr = NULL;
+ }
+ }
+}
+
+/*
+ * Find the tlab_next value of the TLAB which contains ADDR.
+ */
+static char*
+find_tlab_next_from_address (char *addr)
+{
+ SgenThreadInfo *info;
+ int i;
+
+ for (i = 0; i < THREAD_HASH_SIZE; ++i) {
+ for (info = thread_table [i]; info; info = info->next) {
+ if (addr >= *info->tlab_start_addr && addr < *info->tlab_next_addr)
+ return *info->tlab_next_addr;
+ }
+ }
+
+ return NULL;
+}
+
/* LOCKING: assumes the GC lock is held */
static SgenThreadInfo*
gc_register_current_thread (void *addr)
info->skip = 0;
info->signal = 0;
info->stack_start = NULL;
+ info->tlab_start_addr = &tlab_start;
+ info->tlab_next_addr = &tlab_next;
+ info->tlab_temp_end_addr = &tlab_temp_end;
+ info->tlab_real_end_addr = &tlab_real_end;
+
+ tlab_next_addr = &tlab_next;
/* try to get it with attributes first */
#if defined(HAVE_PTHREAD_GETATTR_NP) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
mono_gc_register_thread (&sinfo);
}
+enum {
+ ATYPE_NORMAL,
+ ATYPE_NUM
+};
+
+/* FIXME: Do this in the JIT, where specialized allocation sequences can be created
+ * for each class. This is currently not easy to do, as it is hard to generate basic
+ * blocks + branches, but it is easy with the linear IL codebase.
+ */
+static MonoMethod*
+create_allocator (int atype)
+{
+ int tlab_next_addr_offset = -1;
+ int tlab_temp_end_offset = -1;
+ int p_var, size_var, tlab_next_addr_var, new_next_var;
+ guint32 slowpath_branch;
+ MonoMethodBuilder *mb;
+ MonoMethod *res;
+ MonoMethodSignature *csig;
+ static gboolean registered = FALSE;
+
+ MONO_THREAD_VAR_OFFSET (tlab_next_addr, tlab_next_addr_offset);
+ MONO_THREAD_VAR_OFFSET (tlab_temp_end, tlab_temp_end_offset);
+
+ g_assert (tlab_next_addr_offset != -1);
+ g_assert (tlab_temp_end_offset != -1);
+
+ g_assert (atype == ATYPE_NORMAL);
+
+ if (!registered) {
+ mono_register_jit_icall (mono_gc_alloc_obj, "mono_gc_alloc_obj", mono_create_icall_signature ("object ptr int"), FALSE);
+ registered = TRUE;
+ }
+
+ csig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
+ csig->ret = &mono_defaults.object_class->byval_arg;
+ csig->params [0] = &mono_defaults.int_class->byval_arg;
+
+ mb = mono_mb_new (mono_defaults.object_class, "Alloc", MONO_WRAPPER_ALLOC);
+ size_var = mono_mb_add_local (mb, &mono_defaults.int32_class->byval_arg);
+ /* size = vtable->klass->instance_size; */
+ mono_mb_emit_ldarg (mb, 0);
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoVTable, klass));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoClass, instance_size));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ /* FIXME: assert instance_size stays a 4 byte integer */
+ mono_mb_emit_byte (mb, CEE_LDIND_U4);
+ mono_mb_emit_stloc (mb, size_var);
+
+ /* size += ALLOC_ALIGN - 1; */
+ mono_mb_emit_ldloc (mb, size_var);
+ mono_mb_emit_icon (mb, ALLOC_ALIGN - 1);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ /* size &= ~(ALLOC_ALIGN - 1); */
+ mono_mb_emit_icon (mb, ~(ALLOC_ALIGN - 1));
+ mono_mb_emit_byte (mb, CEE_AND);
+ mono_mb_emit_stloc (mb, size_var);
+
+ /*
+ * We need to modify tlab_next, but the JIT only supports reading, so we read
+ * another tls var holding its address instead.
+ */
+
+ /* tlab_next_addr (local) = tlab_next_addr (TLS var) */
+ tlab_next_addr_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_TLS);
+ mono_mb_emit_i4 (mb, tlab_next_addr_offset);
+ mono_mb_emit_stloc (mb, tlab_next_addr_var);
+
+ /* p = (void**)tlab_next; */
+ p_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+ mono_mb_emit_ldloc (mb, tlab_next_addr_var);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_stloc (mb, p_var);
+
+ /* new_next = (char*)p + size; */
+ new_next_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+ mono_mb_emit_ldloc (mb, p_var);
+ mono_mb_emit_ldloc (mb, size_var);
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_stloc (mb, new_next_var);
+
+ /* tlab_next = new_next */
+ mono_mb_emit_ldloc (mb, tlab_next_addr_var);
+ mono_mb_emit_ldloc (mb, new_next_var);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+
+ /* if (G_LIKELY (new_next < tlab_temp_end)) */
+ mono_mb_emit_ldloc (mb, new_next_var);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_TLS);
+ mono_mb_emit_i4 (mb, tlab_temp_end_offset);
+ slowpath_branch = mono_mb_emit_short_branch (mb, MONO_CEE_BLT_UN_S);
+
+ /* Slowpath */
+
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_NOT_TAKEN);
+
+ /* FIXME: mono_gc_alloc_obj takes a 'size_t' as an argument, not an int32 */
+ mono_mb_emit_ldarg (mb, 0);
+ mono_mb_emit_ldloc (mb, size_var);
+ mono_mb_emit_icall (mb, mono_gc_alloc_obj);
+ mono_mb_emit_byte (mb, CEE_RET);
+
+ /* Fastpath */
+ mono_mb_patch_short_branch (mb, slowpath_branch);
+
+ /* FIXME: Memory barrier */
+
+ /* *p = vtable; */
+ mono_mb_emit_ldloc (mb, p_var);
+ mono_mb_emit_ldarg (mb, 0);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+
+ /* return p */
+ mono_mb_emit_ldloc (mb, p_var);
+ mono_mb_emit_byte (mb, CEE_RET);
+
+ res = mono_mb_create_method (mb, csig, 8);
+ mono_mb_free (mb);
+ mono_method_get_header (res)->init_locals = FALSE;
+ return res;
+}
+
+static MonoMethod* alloc_method_cache [ATYPE_NUM];
+
+/*
+ * Generate an allocator method implementing the fast path of mono_gc_alloc_obj ().
+ * The signature of the called method is:
+ * object allocate (MonoVTable *vtable)
+ */
MonoMethod*
mono_gc_get_managed_allocator (MonoVTable *vtable, gboolean for_box)
{
- return NULL;
+ int tlab_next_offset = -1;
+ int tlab_temp_end_offset = -1;
+ MonoClass *klass = vtable->klass;
+ MONO_THREAD_VAR_OFFSET (tlab_next, tlab_next_offset);
+ MONO_THREAD_VAR_OFFSET (tlab_temp_end, tlab_temp_end_offset);
+
+ if (tlab_next_offset == -1 || tlab_temp_end_offset == -1)
+ return NULL;
+ if (klass->instance_size > tlab_size)
+ return NULL;
+ if (klass->has_finalize || klass->marshalbyref || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
+ return NULL;
+ if (klass->rank)
+ return NULL;
+ if (klass->byval_arg.type == MONO_TYPE_STRING)
+ return NULL;
+ if (collect_before_allocs)
+ return NULL;
+
+ return mono_gc_get_managed_allocator_by_type (0);
}
int
mono_gc_get_managed_allocator_type (MonoMethod *managed_alloc)
{
- return -1;
+ return 0;
}
MonoMethod*
mono_gc_get_managed_allocator_by_type (int atype)
{
- return NULL;
+ MonoMethod *res;
+
+ mono_loader_lock ();
+ res = alloc_method_cache [atype];
+ if (!res)
+ res = alloc_method_cache [atype] = create_allocator (atype);
+ mono_loader_unlock ();
+ return res;
}
#endif /* HAVE_SGEN_GC */
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Exception clauses overlap"));
}
+#define code_bounds_check(size) \
+ if (ip + size > end) {\
+ ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Code overrun starting with 0x%x at 0x%04x", *ip, ctx.ip_offset)); \
+ break; \
+ } \
+
/*
* FIXME: need to distinguish between valid and verifiable.
* Need to keep track of types on the stack.
MonoImage *image;
VerifyContext ctx;
GSList *tmp;
-
VERIFIER_DEBUG ( printf ("Verify IL for method %s %s %s\n", method->klass->name_space, method->klass->name, method->name); );
if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
case CEE_LDARG_S:
case CEE_LDARGA_S:
+ code_bounds_check (2);
push_arg (&ctx, ip [1], *ip == CEE_LDARGA_S);
ip += 2;
break;
break;
case CEE_STLOC_S:
+ code_bounds_check (2);
store_local (&ctx, ip [1]);
ip += 2;
break;
case CEE_STARG_S:
+ code_bounds_check (2);
store_arg (&ctx, ip [1]);
ip += 2;
break;
break;
case CEE_LDC_I4_S:
+ code_bounds_check (2);
if (check_overflow (&ctx))
stack_push_val (&ctx, TYPE_I4, &mono_defaults.int32_class->byval_arg);
ip += 2;
break;
case CEE_LDC_I4:
+ code_bounds_check (5);
if (check_overflow (&ctx))
stack_push_val (&ctx,TYPE_I4, &mono_defaults.int32_class->byval_arg);
ip += 5;
break;
case CEE_LDC_I8:
+ code_bounds_check (9);
if (check_overflow (&ctx))
stack_push_val (&ctx,TYPE_I8, &mono_defaults.int64_class->byval_arg);
ip += 9;
break;
case CEE_LDC_R4:
+ code_bounds_check (5);
if (check_overflow (&ctx))
stack_push_val (&ctx, TYPE_R8, &mono_defaults.double_class->byval_arg);
ip += 5;
break;
case CEE_LDC_R8:
+ code_bounds_check (9);
if (check_overflow (&ctx))
stack_push_val (&ctx, TYPE_R8, &mono_defaults.double_class->byval_arg);
ip += 9;
case CEE_BEQ_S:
case CEE_BNE_UN_S:
+ code_bounds_check (2);
do_branch_op (&ctx, (signed char)ip [1] + 2, cmp_br_eq_op);
ip += 2;
need_merge = 1;
case CEE_BGT_UN_S:
case CEE_BLE_UN_S:
case CEE_BLT_UN_S:
+ code_bounds_check (2);
do_branch_op (&ctx, (signed char)ip [1] + 2, cmp_br_op);
ip += 2;
need_merge = 1;
case CEE_BEQ:
case CEE_BNE_UN:
+ code_bounds_check (5);
do_branch_op (&ctx, (gint32)read32 (ip + 1) + 5, cmp_br_eq_op);
ip += 5;
need_merge = 1;
case CEE_BGT_UN:
case CEE_BLE_UN:
case CEE_BLT_UN:
+ code_bounds_check (5);
do_branch_op (&ctx, (gint32)read32 (ip + 1) + 5, cmp_br_op);
ip += 5;
need_merge = 1;
case CEE_LDLOC_S:
case CEE_LDLOCA_S:
+ code_bounds_check (2);
push_local (&ctx, ip[1], *ip == CEE_LDLOCA_S);
ip += 2;
break;
}
case CEE_JMP:
+ code_bounds_check (5);
if (ctx.eval.size)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Eval stack must be empty in jmp at 0x%04x", ip_offset));
token = read32 (ip + 1);
break;
case CEE_CALL:
case CEE_CALLVIRT:
+ code_bounds_check (5);
do_invoke_method (&ctx, read32 (ip + 1), *ip == CEE_CALLVIRT);
ip += 5;
break;
case CEE_CALLI:
+ code_bounds_check (5);
token = read32 (ip + 1);
/*
* FIXME: check signature, retval, arguments etc.
ip += 5;
break;
case CEE_BR_S:
+ code_bounds_check (2);
do_static_branch (&ctx, (signed char)ip [1] + 2);
need_merge = 1;
ip += 2;
case CEE_BRFALSE_S:
case CEE_BRTRUE_S:
+ code_bounds_check (2);
do_boolean_branch_op (&ctx, (signed char)ip [1] + 2);
ip += 2;
need_merge = 1;
break;
case CEE_BR:
+ code_bounds_check (5);
do_static_branch (&ctx, (gint32)read32 (ip + 1) + 5);
need_merge = 1;
ip += 5;
case CEE_BRFALSE:
case CEE_BRTRUE:
+ code_bounds_check (5);
do_boolean_branch_op (&ctx, (gint32)read32 (ip + 1) + 5);
ip += 5;
need_merge = 1;
break;
case CEE_SWITCH:
+ code_bounds_check (5);
n = read32 (ip + 1);
+ code_bounds_check (5 + sizeof (guint32) * n);
+
do_switch (&ctx, n, (ip + 5));
start = 1;
ip += 5 + sizeof (guint32) * n;
break;
case CEE_CPOBJ:
+ code_bounds_check (5);
do_cpobj (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_LDOBJ:
+ code_bounds_check (5);
do_ldobj_value (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_LDSTR:
+ code_bounds_check (5);
do_ldstr (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_NEWOBJ:
+ code_bounds_check (5);
do_newobj (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_CASTCLASS:
case CEE_ISINST:
+ code_bounds_check (5);
do_cast (&ctx, read32 (ip + 1), *ip == CEE_CASTCLASS ? "castclass" : "isinst");
ip += 5;
break;
case CEE_UNUSED1:
++ip; /* warn, error ? */
break;
+
case CEE_UNBOX:
+ code_bounds_check (5);
do_unbox_value (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_LDFLD:
case CEE_LDFLDA:
+ code_bounds_check (5);
do_push_field (&ctx, read32 (ip + 1), *ip == CEE_LDFLDA);
ip += 5;
break;
case CEE_LDSFLD:
case CEE_LDSFLDA:
+ code_bounds_check (5);
do_push_static_field (&ctx, read32 (ip + 1), *ip == CEE_LDSFLDA);
ip += 5;
break;
case CEE_STFLD:
+ code_bounds_check (5);
do_store_field (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_STSFLD:
+ code_bounds_check (5);
do_store_static_field (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_STOBJ:
+ code_bounds_check (5);
do_stobj (&ctx, read32 (ip + 1));
ip += 5;
break;
break;
case CEE_BOX:
+ code_bounds_check (5);
do_box_value (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_NEWARR:
+ code_bounds_check (5);
do_newarr (&ctx, read32 (ip + 1));
ip += 5;
break;
break;
case CEE_LDELEMA:
+ code_bounds_check (5);
do_ldelema (&ctx, read32 (ip + 1));
ip += 5;
break;
break;
case CEE_LDELEM_ANY:
+ code_bounds_check (5);
do_ldelem (&ctx, *ip, read32 (ip + 1));
ip += 5;
break;
case CEE_STELEM_ANY:
+ code_bounds_check (5);
do_stelem (&ctx, *ip, read32 (ip + 1));
ip += 5;
break;
case CEE_UNBOX_ANY:
+ code_bounds_check (5);
do_unbox_any (&ctx, read32 (ip + 1));
ip += 5;
break;
break;
case CEE_REFANYVAL:
+ code_bounds_check (5);
do_refanyval (&ctx, read32 (ip + 1));
ip += 5;
break;
break;
case CEE_MKREFANY:
+ code_bounds_check (5);
do_mkrefany (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_LDTOKEN:
+ code_bounds_check (5);
do_load_token (&ctx, read32 (ip + 1));
ip += 5;
break;
break;
case CEE_LEAVE:
+ code_bounds_check (5);
do_leave (&ctx, read32 (ip + 1) + 5);
ip += 5;
start = 1;
break;
case CEE_LEAVE_S:
+ code_bounds_check (2);
do_leave (&ctx, (signed char)ip [1] + 2);
ip += 2;
start = 1;
break;
case CEE_PREFIX1:
+ code_bounds_check (2);
++ip;
switch (*ip) {
case CEE_STLOC:
+ code_bounds_check (3);
store_local (&ctx, read16 (ip + 1));
ip += 3;
break;
break;
case CEE_STARG:
+ code_bounds_check (3);
store_arg (&ctx, read16 (ip + 1) );
ip += 3;
break;
break;
case CEE_LDFTN:
+ code_bounds_check (5);
do_load_function_ptr (&ctx, read32 (ip + 1), FALSE);
ip += 5;
break;
case CEE_LDVIRTFTN:
+ code_bounds_check (5);
do_load_function_ptr (&ctx, read32 (ip + 1), TRUE);
ip += 5;
break;
case CEE_LDARG:
case CEE_LDARGA:
+ code_bounds_check (3);
push_arg (&ctx, read16 (ip + 1), *ip == CEE_LDARGA);
ip += 3;
break;
case CEE_LDLOC:
case CEE_LDLOCA:
+ code_bounds_check (3);
push_local (&ctx, read16 (ip + 1), *ip == CEE_LDLOCA);
ip += 3;
break;
++ip;
break;
case CEE_UNALIGNED_:
+ code_bounds_check (2);
prefix |= PREFIX_UNALIGNED;
ip += 2;
break;
break;
case CEE_INITOBJ:
+ code_bounds_check (5);
do_initobj (&ctx, read32 (ip + 1));
ip += 5;
break;
case CEE_CONSTRAINED_:
+ code_bounds_check (5);
ctx.constrained_type = get_boxable_mono_type (&ctx, read32 (ip + 1), "constrained.");
prefix |= PREFIX_CONSTRAINED;
ip += 5;
break;
case CEE_SIZEOF:
+ code_bounds_check (5);
do_sizeof (&ctx, read32 (ip + 1));
ip += 5;
break;
--- /dev/null
+//
+// AssemblyRunner.cs
+//
+// Author:
+// Rodrigo Kumpera (rkumpera@novell.com)
+//
+// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.IO;
+using System.Reflection;
+
+
+namespace Verifier {
+ public class BatchCompiler : MarshalByRefObject {
+ static BatchCompiler NewBatchCompiler () {
+ AppDomain domain = AppDomain.CreateDomain ("test");
+ BatchCompiler compiler = (BatchCompiler) domain.CreateInstanceAndUnwrap(
+ Assembly.GetExecutingAssembly().FullName,
+ "Verifier.BatchCompiler");
+ return compiler;
+ }
+
+ public static void Main (String[] args) {
+ int total = 0;
+ BatchCompiler bc = NewBatchCompiler ();
+
+ foreach (string src in Directory.GetFiles (".", "*.il")) {
+ if (!bc.Compile (src))
+ bc = NewBatchCompiler ();
+ else
+ ++total;
+ }
+ Console.WriteLine ("Total compiled successfully {0}", total);
+ }
+
+ public bool Compile (String src) {
+ try {
+ Mono.ILASM.Driver.Main (new string[] { src });
+ string binary = src.Substring (0, src.Length - 3) + ".exe";
+ return File.Exists (binary);
+ } catch (Exception e) {
+ Console.WriteLine ("Error compiling {0}", e);
+ return false;
+ }
+ }
+ }
+}
+
+2008-05-01 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * unverifiable_ldsfld_no_fld.il: Fixed compilation
+ and renamed to invalid_ldsfld_no_fld.il.
+
+ * BatchCompiler.cs: New driver to fast compile the
+ verifier test suite. It's about 20x faster now.
+
+ * Makefile: Use the ilasm driver for faster compilation.
+
+2008-04-30 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * make_il_overflow_test.sh: New test generator
+ for a truncated IL stream.
+
+ * make_tests.sh: Fixed generation script. Added
+ tests using the new generator.
+
2008-04-23 Rodrigo Kumpera <rkumpera@novell.com>
* make_tests.sh: Add some tests for overlapping
%.exe: %.cil
- ilasm -out:$@ $<
+ ilasm2 -out:$@ $<
-compile-stamp: generate-stamp
- for i in *.il; do ilasm2 $$i; done
- for i in *.cs; do gmcs /unsafe $$i; done
+BatchCompiler.exe: BatchCompiler.cs
+ gmcs -r:../../../../mcs/class/lib/net_2_0/ilasm.exe BatchCompiler.cs
+
+compile-stamp: generate-stamp BatchCompiler.exe
+ for i in *.cs; do \
+ EXE="`echo $$i | cut -d. -f1`.exe"; \
+ if ! [ -f $$EXE ]; then \
+ gmcs /unsafe $$i; \
+ fi \
+ done
+ MONO_PATH=../../../../mcs/class/lib/net_2_0/ mono BatchCompiler.exe
touch compile-stamp
clean:
test: compile-stamp run-test
-run-test:
+run-test: compile-stamp
@for i in *.exe; do \
TEST=`echo $$i | cut -d '.' -f 1`; \
RES=99; \
then \
RES=3; \
fi; \
- if [ "$$FIRST" == "unverifiable" ]; \
+ if [ "$$FIRST" == "unverifiable" ] || [ "$FIRST" == "typeunverifiable" ]; \
then \
RES=2; \
fi; \
if [ $$R2 != 0 ]; then \
echo "$$TEST is type unverifiable but did not pass under non-strict check, got $${R2} but expected 0"; \
fi \
- else \
+ elif [ $RES != 99 ]; then \
../../metadata/pedump --verify error,warn,cls,code $$TEST.exe >/dev/null 2>/dev/null; \
R=$$?; \
if [ $$R != $$RES ]; then \
--- /dev/null
+// Invalid CIL which breaks the ECMA-335,III,4.14 rules.
+// This CIL should fail verification by a conforming CLI verifier.
+
+.assembly 'test_generated'
+{
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+
+
+.class public auto ansi beforefieldinit c
+ extends [mscorlib]System.Object
+{
+}
+
+.method public static int32 Main() cil managed
+{
+ .entrypoint
+ .maxstack 2
+ .locals init (
+ class c V_0
+ )
+ ldloc.0
+ ldsfld int32 c::invalid // Invalid, no field invalid in class c.
+ pop
+ ldc.i4.0
+ ret
+}
+
--- /dev/null
+#! /bin/sh
+
+TEST_NAME=$1
+TEST_VALIDITY=$2
+TEST_BYTE_0=$3
+TEST_BYTE_1=$4
+TEST_BYTE_2=$5
+TEST_BYTE_3=$6
+TEST_BYTE_4=$7
+
+
+if [ "$TEST_BYTE_1" != "" ] ; then
+ EMIT_BYTE_1=".emitbyte $TEST_BYTE_1";
+fi
+
+if [ "$TEST_BYTE_2" != "" ] ; then
+ EMIT_BYTE_2=".emitbyte $TEST_BYTE_2";
+fi
+
+if [ "$TEST_BYTE_3" != "" ] ; then
+ EMIT_BYTE_3=".emitbyte $TEST_BYTE_3";
+fi
+
+if [ "$TEST_BYTE_4" != "" ] ; then
+ EMIT_BYTE_4=".emitbyte $TEST_BYTE_4";
+fi
+
+if [ "$TEST_BYTE_5" != "" ] ; then
+ EMIT_BYTE_5=".emitbyte $TEST_BYTE_5";
+fi
+
+TEST_FILE=`echo ${TEST_VALIDITY}_${TEST_NAME} | sed -e 's/ /_/g' -e 's/\./_/g' -e 's/&/mp/g' -e 's/\[/_/g' -e 's/\]/_/g'`_generated.il
+echo $TEST_FILE
+sed -e "s/VALIDITY/${TEST_VALIDITY}/g" -e "s/BYTE_0/${TEST_BYTE_0}/g" -e "s/BYTE_1/${TEST_BYTE_1}/g" > $TEST_FILE <<//EOF
+
+// VALIDITY CIL which breaks the ECMA-335 rules.
+// this CIL should fail verification by a conforming CLI verifier.
+
+.assembly '${TEST_NAME}_generated'
+{
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+
+.method public static void Main() cil managed
+{
+ .entrypoint
+ .maxstack 2
+ .locals init ()
+
+ nop
+ nop
+ .emitbyte BYTE_0
+ ${EMIT_BYTE_1}
+ ${EMIT_BYTE_2}
+ ${EMIT_BYTE_3}
+ ${EMIT_BYTE_4}
+ ${EMIT_BYTE_5}
+}
+
+
+//EOF
./make_bin_test.sh bin_cgt_un_a_${I} unverifiable 'cgt.un' "${TYPE}" 'object'
./make_bin_test.sh bin_cgt_un_b_${I} unverifiable 'cgt.un' 'object' "${TYPE}"
I=`expr $I + 1`
+done
for OP in ceq
do
+#test for IL overflow
+
+for I in 0x0E 0x0F 0x10 0x11 0x12 0x13 0x1F 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0xDE 0xFE
+do
+ ./make_il_overflow_test.sh incomplete_op_${I} invalid $I
+done
+
+for I in 0x20 0x21 0x22 0x23 0x28 0x29 0x38 0x39 0x3A 0x3B 0x3C 0x3D 0x3E 0x3F 0x40 0x41 0x42 0x43 0x44 0x6F 0x70 0x71 0x72 0x73 0x74 0x75 0x79 0x7B 0x7C 0x7D 0x7E 0x7F 0x80 0x81 0x8D 0x8C 0x8F 0xA3 0xA4 0xA5 0xC2 0xC6 0xD0 0xDD
+do
+ ./make_il_overflow_test.sh incomplete_op_${I} invalid $I
+ ./make_il_overflow_test.sh incomplete_op_${I}_0x00 invalid $I 0x00
+ ./make_il_overflow_test.sh incomplete_op_${I}_0x00_0x00 invalid $I 0x00 0x00
+ ./make_il_overflow_test.sh incomplete_op_${I}_0x00_0x00_0x00 invalid $I 0x00 0x00
+done
+
+
+for I in 0x06 0x07 0x09 0x0A 0x0E 0x0B 0x0C 0x0D 0x12 0x15 0x16 0x19 0x1C
+do
+ ./make_il_overflow_test.sh incomplete_op_0xFE_${I} invalid 0xFE $I
+ ./make_il_overflow_test.sh incomplete_op_0xFE_${I}_0x00 invalid 0xFE $I 0x00
+done
+
+#switch
+./make_il_overflow_test.sh incomplete_switch_1 invalid 0x45
+./make_il_overflow_test.sh incomplete_switch_2 invalid 0x45 0x00
+./make_il_overflow_test.sh incomplete_switch_3 invalid 0x45 0x00 0x00
+./make_il_overflow_test.sh incomplete_switch_4 invalid 0x45 0x00 0x00
+
+./make_il_overflow_test.sh incomplete_switch_arg_1 invalid 0x45 0x00 0x00 0x00 0x01
+./make_il_overflow_test.sh incomplete_switch_arg_2 invalid 0x45 0x00 0x00 0x00 0x01 0x00
+
+
+
+++ /dev/null
-// Invalid CIL which breaks the ECMA-335,III,4.14 rules.
-// This CIL should fail verification by a conforming CLI verifier.
-
-.assembly 'test_generated'
-{
- .hash algorithm 0x00008004
- .ver 0:0:0:0
-}
-
-
-.class public auto ansi beforefieldinit c
- extends [mscorlib]System.Object
-{
-}
-
-.method public static int32 Main() cil managed
-{
- .entrypoint
- .maxstack 2
- .locals init (
- class c V_0
- )
- ldloc.0
- ldsfld int32 c::invalid // Invalid, no field invalid in class c.
- pop
- ldc.i4.0
- ret
-}
-// Invalid CIL which breaks the ECMA-335,III,4.14 rules.
-// This CIL should fail verification by a conforming CLI verifier.
-
-.assembly 'test_generated'
-{
- .hash algorithm 0x00008004
- .ver 0:0:0:0
-}
-
-
-.class public auto ansi beforefieldinit c
- extends [mscorlib]System.Object
-{
-}
-
-.method public static int32 Main() cil managed
-{
- .entrypoint
- .maxstack 2
- .locals init (
- class c V_0
- )
- ldloc.0
- ldsfld int32 c::invalid // Invalid, no field invalid in class c.
- pop
- ldc.i4.0
- ret
-}