Bug 1251790 - Add help for "interface objects", r=terrence

This commit is contained in:
Steve Fink 2016-02-26 18:16:09 -08:00
parent 6167ae3827
commit aca186c061
5 changed files with 107 additions and 19 deletions

View File

@ -756,14 +756,21 @@ DefineOS(JSContext* cx, HandleObject global, bool fuzzingSafe)
return false;
}
if (!GenerateInterfaceHelp(cx, osfile, "os.file"))
return false;
RootedObject ospath(cx, JS_NewPlainObject(cx));
if (!ospath ||
!JS_DefineFunctionsWithHelp(cx, ospath, ospath_functions) ||
!JS_DefineProperty(cx, obj, "path", ospath, 0))
!JS_DefineProperty(cx, obj, "path", ospath, 0) ||
!GenerateInterfaceHelp(cx, ospath, "os.path"))
{
return false;
}
if (!GenerateInterfaceHelp(cx, obj, "os"))
return false;
// For backwards compatibility, expose various os.file.* functions as
// direct methods on the global.
RootedValue val(cx);

View File

@ -5650,32 +5650,40 @@ PrintHelp(JSContext* cx, HandleObject obj)
return PrintHelpString(cx, usage) && PrintHelpString(cx, help);
}
static bool
PrintEnumeratedHelp(JSContext* cx, HandleObject obj, bool brief)
{
AutoIdVector idv(cx);
if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &idv))
return false;
for (size_t i = 0; i < idv.length(); i++) {
RootedValue v(cx);
RootedId id(cx, idv[i]);
if (!JS_GetPropertyById(cx, obj, id, &v))
return false;
if (v.isObject()) {
RootedObject funcObj(cx, &v.toObject());
if (!PrintHelp(cx, funcObj))
return false;
}
}
return true;
}
static bool
Help(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
fprintf(gOutFile, "%s\n", JS_GetImplementationVersion());
RootedObject obj(cx);
if (args.length() == 0) {
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
Rooted<IdVector> ida(cx, IdVector(cx));
if (!JS_Enumerate(cx, global, &ida))
return false;
fprintf(gOutFile, "%s\n", JS_GetImplementationVersion());
for (size_t i = 0; i < ida.length(); i++) {
RootedValue v(cx);
RootedId id(cx, ida[i]);
if (!JS_GetPropertyById(cx, global, id, &v))
return false;
if (v.isPrimitive()) {
JS_ReportError(cx, "primitive arg");
return false;
}
obj = v.toObjectOrNull();
if (!PrintHelp(cx, obj))
return false;
}
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
if (!PrintEnumeratedHelp(cx, global, false))
return false;
} else {
for (unsigned i = 0; i < args.length(); i++) {
if (args[i].isPrimitive()) {

69
js/src/shell/jsshell.cpp Normal file
View File

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// jsshell.cpp - Utilities for the JS shell
#include "shell/jsshell.h"
#include "jsapi.h"
namespace js {
namespace shell {
bool
GenerateInterfaceHelp(JSContext* cx, HandleObject obj, const char* name)
{
AutoIdVector idv(cx);
if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &idv))
return false;
StringBuffer buf(cx);
if (!buf.append(' '))
return false;
for (size_t i = 0; i < idv.length(); i++) {
RootedValue v(cx);
RootedId id(cx, idv[i]);
if (!JS_GetPropertyById(cx, obj, id, &v))
return false;
if (!v.isObject())
continue;
bool hasHelp = false;
RootedObject prop(cx, &v.toObject());
if (!JS_GetProperty(cx, prop, "usage", &v))
return false;
if (v.isString())
hasHelp = true;
if (!JS_GetProperty(cx, prop, "help", &v))
return false;
if (v.isString())
hasHelp = true;
if (hasHelp) {
if (!buf.append(' ') ||
!buf.append(name, strlen(name)) ||
!buf.append('.') ||
!buf.append(JSID_TO_FLAT_STRING(id)))
{
return false;
}
}
}
RootedString s(cx, buf.finishString());
if (!s || !JS_DefineProperty(cx, obj, "help", s, 0))
return false;
if (!buf.append(name, strlen(name)) || !buf.append(" - interface object", 20))
return false;
s = buf.finishString();
if (!s || !JS_DefineProperty(cx, obj, "usage", s, 0))
return false;
return true;
}
} // namespace shell
} // namespace js

View File

@ -26,6 +26,9 @@ my_GetErrorMessage(void* userRef, const unsigned errorNumber);
void
my_ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report);
bool
GenerateInterfaceHelp(JSContext* cx, HandleObject obj, const char* name);
JSString*
FileAsString(JSContext* cx, const char* pathname);

View File

@ -13,6 +13,7 @@ if CONFIG['JS_SHELL_NAME']:
UNIFIED_SOURCES += [
'js.cpp',
'jsoptparse.cpp',
'jsshell.cpp',
'OSObject.cpp'
]