Merge pull request #5353 from jonpryor/jonp-mono-api-html-ignore-class-removal
[mono.git] / mono / dis / get.c
index 3dbc1f7a79b1b7a9c355a889158c28a34cf61554..f5b64acdd0dab72058234fb16f54291d593a7e47 100755 (executable)
@@ -6,6 +6,7 @@
  *
  * (C) 2001 Ximian, Inc.
  * Copyright 2012 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
 #include <stdio.h>
@@ -24,6 +25,9 @@
 
 extern gboolean substitute_with_mscorlib_p;
 
+static char *
+get_token_comment (const char *prefix, guint32 token);
+
 static MonoGenericContainer *
 get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container);
 
@@ -58,7 +62,7 @@ get_typedef (MonoImage *m, int idx)
         /* Check if this is a nested type */
         token = MONO_TOKEN_TYPE_DEF | (idx);
         token = mono_metadata_nested_in_typedef (m, token);
-       tstring = show_tokens ? g_strdup_printf ("/*%08x*/", token) : NULL;
+       tstring = get_token_comment (NULL, token);
         if (token) {
                 char *outer;
                 
@@ -257,11 +261,12 @@ get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContainer *
 
        if (show_tokens) {
                int token = mono_metadata_make_token (MONO_TABLE_TYPESPEC, idx);
-               result = g_strdup_printf ("%s/*%08x*/", res->str, token);
-       } else
+               result = get_token_comment (res->str, token);
+               g_string_free (res, TRUE);
+       } else {
                result = res->str;
-
-       g_string_free (res, FALSE);
+               g_string_free (res, FALSE);
+       }
 
        return result;
 }
@@ -315,7 +320,7 @@ get_typeref (MonoImage *m, int idx)
 
        if (show_tokens) {
                int token = mono_metadata_make_token (MONO_TABLE_TYPEREF, idx);
-               char *temp = g_strdup_printf ("%s/*%08x*/", ret, token);
+               char *temp = get_token_comment (ret, token);
                g_free (ret);
                ret = temp;
        }
@@ -1102,8 +1107,8 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gb
 
        esname = get_escaped_class_name (c);
 
-       if (c->generic_class) {
-               MonoGenericClass *gclass = c->generic_class;
+       if (mono_class_is_ginst (c)) {
+               MonoGenericClass *gclass = mono_class_get_generic_class (c);
                MonoGenericInst *inst = gclass->context.class_inst;
                GString *str = g_string_new ("");
                int i;
@@ -1269,6 +1274,7 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
 const char *
 get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContainer *container)
 {
+       MonoError error;
        const char *start = ptr;
        guint32 type;
        MonoType *t;
@@ -1282,15 +1288,17 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS: {
                guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
-               MonoClass *klass = mono_class_get (m, token);
+               MonoClass *klass = mono_class_get_checked (m, token, &error);
                char *temp;
-               if (klass)
+               if (klass) {
                        temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE);
-               else
-                       temp = g_strdup_printf ("<BROKEN CLASS token_%8x>", token);
+               } else  {
+                       temp = g_strdup_printf ("<BROKEN CLASS token_%8x due to %s>", token, mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
+               }
 
                if (show_tokens) {
-                       *result = g_strdup_printf ("%s/*%08x*/", temp, token);
+                       *result = get_token_comment (temp, token);
                        g_free (temp);
                } else
                        *result = temp;
@@ -1323,23 +1331,12 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
        }
 
        default:
-               t = mono_metadata_parse_type_full (m, container, 0, start, &ptr);
+               t = mono_metadata_parse_type_checked (m, container, 0, FALSE, start, &ptr, &error);
                if (t) {
                        *result = dis_stringify_type (m, t, is_def);
                } else {
-                       GString *err = g_string_new ("@!#$<InvalidType>$#!@");
-                       if (container)
-                               t = mono_metadata_parse_type_full (m, NULL, 0, start, &ptr);
-                       if (t) {
-                               char *name = dis_stringify_type (m, t, is_def);
-                               g_warning ("Encountered a generic type inappropriate for its context");
-                               g_string_append (err, " // ");
-                               g_string_append (err, name);
-                               g_free (name);
-                       } else {
-                               g_warning ("Encountered an invalid type");
-                       }
-                       *result = g_string_free (err, FALSE);
+                       *result = g_strdup_printf ("Invalid type due to %s", mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
                }
 
                break;
@@ -1776,6 +1773,25 @@ get_fieldref_signature (MonoImage *m, int idx, MonoGenericContainer *container)
         return full_sig;
 }
 
+/**
+ * get_token_comment:
+ *
+ * If show_tokens is TRUE, return "prefix""token(table)".
+ * If show_tokens is FALSE, return "prefix" or NULL if prefix is NULL.
+ * Caller is responsible for freeing.
+ */
+char *
+get_token_comment (const char *prefix, guint32 token)
+{
+       if (!show_tokens)
+               return prefix ? g_strdup_printf ("%s", prefix) : NULL;
+       gint32 tableidx = mono_metadata_token_table (token);
+       if ((tableidx < 0) || (tableidx > MONO_TABLE_LAST))
+               return g_strdup_printf ("%s/*%08x*/", prefix ? prefix : "", token);
+       else
+               return g_strdup_printf ("%s/*%08x(%s)*/", prefix ? prefix : "", token, mono_meta_table_name (tableidx));
+}
+
 /**
  * get_field:
  * @m: metadata context
@@ -1790,7 +1806,7 @@ get_field (MonoImage *m, guint32 token, MonoGenericContainer *container)
 {
        int idx = mono_metadata_token_index (token);
        guint32 cols [MONO_FIELD_SIZE];
-       char *sig, *res, *type, *estype, *esname;
+       char *sig, *res, *type, *estype, *esname, *token_comment;
        guint32 type_idx;
 
        /*
@@ -1819,16 +1835,20 @@ get_field (MonoImage *m, guint32 token, MonoGenericContainer *container)
        type = get_typedef (m, type_idx);
        estype = get_escaped_name (type);
        esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
-       res = g_strdup_printf ("%s %s%s%s",
+       token_comment = get_token_comment (NULL, token);
+       res = g_strdup_printf ("%s %s%s%s%s",
                        sig, 
                        estype ? estype : "",
                        estype ? "::" : "",
-                       esname);
+                       esname,
+                       token_comment ? token_comment : ""
+               );
 
        g_free (type);
        g_free (sig);
        g_free (estype);
        g_free (esname);
+       g_free (token_comment);
 
        return res;
 }
@@ -1854,7 +1874,7 @@ get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *
        case 4: /* TypeSpec */
                klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, (MonoGenericContext *) container);
                g_assert (klass);
-               return klass->generic_class ? klass->generic_class->container_class->generic_container : NULL;
+               return mono_class_is_ginst (klass) ? mono_class_get_generic_container (mono_class_get_generic_class (klass)->container_class) : NULL;
        }
        g_assert_not_reached ();
        return NULL;
@@ -1916,12 +1936,11 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConta
                        container = mono_method_get_generic_container (((MonoMethodInflated *) mh)->declaring);
                esname = get_escaped_name (mh->name);
                sig = dis_stringify_type (m, &mh->klass->byval_arg, TRUE);
-               if (show_tokens)
-                       name = g_strdup_printf ("%s/*%08x*/%s%s", sig ? sig : "", token, sig ? "::" : "", esname);
-               else
-                       name = g_strdup_printf ("%s%s%s", sig ? sig : "", sig ? "::" : "", esname);
+               char *token_comment = get_token_comment (NULL, token);
+               name = g_strdup_printf ("%s%s%s%s", sig ? sig : "", token_comment ? token_comment : "", sig ? "::" : "", esname);
                g_free (sig);
                g_free (esname);
+               g_free (token_comment);
        } else {
                name = NULL;
                mono_error_cleanup (&error);
@@ -1986,7 +2005,7 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConta
        }
        
        if (show_tokens) {
-               char *retval = g_strdup_printf ("%s /* %08x */", sig, token);
+               char *retval = get_token_comment (sig, token);
                g_free (sig);
                return retval;
        } else
@@ -3115,7 +3134,7 @@ get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *containe
                        MonoMethod *mh = NULL;
                        mh = mono_get_method_checked (m, decl, NULL, (MonoGenericContext *) container, &error);
 
-                       if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
+                       if (mh && (mh->klass && (mono_class_is_ginst (mh->klass) || mono_class_is_gtd (mh->klass)))) {
                                char *meth_str;
                                char *ret;
                                
@@ -3124,12 +3143,16 @@ get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *containe
                                g_free (meth_str);
                                return ret;
                        } else {
-                               char *meth_str = get_method_core (m, decl, FALSE, container);
-                               char *ret = g_strdup_printf ("Could not decode method override %s due to %s", meth_str, mono_error_get_message (&error));
+                               if (!mono_error_ok (&error)) {
+                                       char *meth_str = get_method_core (m, decl, FALSE, container);
+                                       char *ret = g_strdup_printf ("Could not decode method override %s due to %s", meth_str, mono_error_get_message (&error));
 
-                               mono_error_cleanup (&error);
-                               g_free (meth_str);
-                               return ret;
+                                       mono_error_cleanup (&error);
+                                       g_free (meth_str);
+                                       return ret;
+                               } else {
+                                       return get_method_core (m, decl, FALSE, container);
+                               }
                        }
                }
        }
@@ -3190,7 +3213,7 @@ cant_print_generic_param_name (MonoGenericParam *gparam)
        container = mono_generic_param_owner (gparam);
        check_ambiguous_genparams (container);
        return (!container || (mono_generic_params_with_ambiguous_names &&
-                       g_hash_table_lookup (mono_generic_params_with_ambiguous_names, gparam)));
+                       g_hash_table_lookup (mono_generic_params_with_ambiguous_names, gparam)) || !mono_generic_param_info (gparam));
 }