From 62253eed3a7998a3db888ce561b3a9a88c0b14fe Mon Sep 17 00:00:00 2001 From: "reed@reedloden.com" Date: Mon, 12 Nov 2007 21:23:22 -0800 Subject: [PATCH] Bug 353116 - ""has no properties" is misleading and should be replaced with "is null or undefined"" [p=rich@rd.gen.nz (Rich Dougherty) r=brendan r=crowder a1.9=damons] --- js/src/js.msg | 1 + js/src/jscntxt.c | 34 ++++++++++++++++++++++++++++++++++ js/src/jscntxt.h | 7 +++++++ js/src/jsinterp.c | 3 +-- js/src/jsobj.c | 6 ++---- 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/js/src/js.msg b/js/src/js.msg index ee97c24adb9b..cbbe15ebb84d 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -301,3 +301,4 @@ MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 218, 0, JSEXN_TYPEERR, "reduce of empty ar MSG_DEF(JSMSG_NON_LIST_XML_METHOD, 219, 2, JSEXN_TYPEERR, "cannot call {0} method on an XML list with {1} elements") MSG_DEF(JSMSG_BAD_DELETE_OPERAND, 220, 0, JSEXN_SYNTAXERR, "invalid delete operand") MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 221, 0, JSEXN_SYNTAXERR, "invalid increment/decrement operand") +MSG_DEF(JSMSG_NULL_OR_UNDEFINED, 222, 2, JSEXN_TYPEERR, "{0} is {1}") diff --git a/js/src/jscntxt.c b/js/src/jscntxt.c index 74966e65bc3b..4fa09738d33c 100644 --- a/js/src/jscntxt.c +++ b/js/src/jscntxt.c @@ -1218,6 +1218,40 @@ js_ReportIsNotDefined(JSContext *cx, const char *name) JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_DEFINED, name); } +JSBool +js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v, + JSString *fallback) +{ + char *bytes; + JSBool ok; + + bytes = js_DecompileValueGenerator(cx, spindex, v, fallback); + if (!bytes) + return JS_FALSE; + + if (strcmp(bytes, js_undefined_str) == 0 || + strcmp(bytes, js_null_str) == 0) { + ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, + js_GetErrorMessage, NULL, + JSMSG_NO_PROPERTIES, bytes, + NULL, NULL); + } else if (JSVAL_IS_VOID(v)) { + ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, + js_GetErrorMessage, NULL, + JSMSG_NULL_OR_UNDEFINED, bytes, + js_undefined_str, NULL); + } else { + JS_ASSERT(JSVAL_IS_NULL(v)); + ok = JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, + js_GetErrorMessage, NULL, + JSMSG_NULL_OR_UNDEFINED, bytes, + js_null_str, NULL); + } + + JS_free(cx, bytes); + return ok; +} + JSBool js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber, intN spindex, jsval v, JSString *fallback, diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 85bf3ccf6a81..6bb4b4c21316 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -977,6 +977,13 @@ js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report); extern void js_ReportIsNotDefined(JSContext *cx, const char *name); +/* + * Report an attempt to access the property of a null or undefined value (v). + */ +extern JSBool +js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, jsval v, + JSString *fallback); + /* * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as * the first argument for the error message. If the error message has less diff --git a/js/src/jsinterp.c b/js/src/jsinterp.c index 0655752e1204..46e685a33c50 100644 --- a/js/src/jsinterp.c +++ b/js/src/jsinterp.c @@ -5852,8 +5852,7 @@ interrupt: i = JSProto_Boolean; } else { JS_ASSERT(JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)); - js_ReportValueError(cx, JSMSG_NO_PROPERTIES, -2, lval, - NULL); + js_ReportIsNullOrUndefined(cx, -2, lval, NULL); ok = JS_FALSE; goto out; } diff --git a/js/src/jsobj.c b/js/src/jsobj.c index 1794a8c51a1d..28368bae01be 100644 --- a/js/src/jsobj.c +++ b/js/src/jsobj.c @@ -4651,10 +4651,8 @@ js_ValueToNonNullObject(JSContext *cx, jsval v) if (!js_ValueToObject(cx, v, &obj)) return NULL; - if (!obj) { - js_ReportValueError(cx, JSMSG_NO_PROPERTIES, - JSDVG_SEARCH_STACK, v, NULL); - } + if (!obj) + js_ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, v, NULL); return obj; }