diff --git a/extensions/interfaceinfo/public/makefile.win b/extensions/interfaceinfo/public/makefile.win index 4350049960b..e69de29bb2d 100644 --- a/extensions/interfaceinfo/public/makefile.win +++ b/extensions/interfaceinfo/public/makefile.win @@ -1,31 +0,0 @@ -#!nmake -# -# The contents of this file are subject to the Netscape Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/NPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): - -DEPTH=..\..\.. - -MODULE=iiextras - -XPIDLSRCS = \ - .\nsIGenericInterfaceInfoSet.idl \ - .\nsIScriptableInterfaceInfo.idl \ - $(NULL) - -include <$(DEPTH)\config\rules.mak> diff --git a/extensions/interfaceinfo/public/nsIInterfaceInfoToIDL.idl b/extensions/interfaceinfo/public/nsIInterfaceInfoToIDL.idl new file mode 100644 index 00000000000..40611ac833a --- /dev/null +++ b/extensions/interfaceinfo/public/nsIInterfaceInfoToIDL.idl @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIInterfaceInfoToIDL public declaration.*/ + +#include "nsISupports.idl" + +[scriptable, uuid(b01eb40c-026b-49c9-af55-25e8c9d034c8)] +interface nsIInterfaceInfoToIDL : nsISupports +{ + string generateIDL(in nsIIDRef aIID); +}; + diff --git a/extensions/interfaceinfo/src/makefile.win b/extensions/interfaceinfo/src/makefile.win index 7e78970d4dc..95fe91693af 100644 --- a/extensions/interfaceinfo/src/makefile.win +++ b/extensions/interfaceinfo/src/makefile.win @@ -61,3 +61,6 @@ LLIBS= $(LIBNSPR) \ $(NULL) include <$(DEPTH)\config\rules.mak> + +libs:: $(DLL) + $(MAKE_INSTALL) nsInterfaceInfoToIDL.js $(DIST)\bin\components diff --git a/extensions/interfaceinfo/src/nsInterfaceInfoToIDL.js b/extensions/interfaceinfo/src/nsInterfaceInfoToIDL.js new file mode 100644 index 00000000000..3a52ac5c152 --- /dev/null +++ b/extensions/interfaceinfo/src/nsInterfaceInfoToIDL.js @@ -0,0 +1,524 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsInterfaceInfoToIDL implementation.*/ + + +/***************************************************************************/ +// nsInterfaceInfoToIDL part... + +const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", + "nsIScriptableInterfaceInfo", + "init"); + +const nsIDataType = Components.interfaces.nsIDataType; +const nsISupports = Components.interfaces.nsISupports; + +const PARAM_NAME_PREFIX = "arg"; + +// helpers... + +/********************************************************/ +// accumulate a string with a stream-ish abstraction + +function Buffer() { + this.buffer = ""; +} + +Buffer.prototype = { + write : function(s) { + if(s) + this.buffer += s; + }, + + writeln : function(s) { + if(s) + this.buffer += s + "\n"; + else + this.buffer += "\n"; + } +} + +/********************************************************/ + +/** +* takes: {xxx} +* returns: uuid(xxx) +*/ +function formatID(str) +{ + return "uuid("+str.substring(1,str.length-1)+")"; +} + +function formatConstType(type) +{ + switch(type) + { + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + default: + return "!!!! bad const type !!!"; + } +} + +function formatTypeName(info, methodIndex, param, dimension) +{ + var type = param.type; + + switch(type.dataType) + { + case nsIDataType.VTYPE_INT8 : + return "PRInt8"; + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_INT64: + return "PRInt64"; + case nsIDataType.VTYPE_UINT8: + return "PRUint8"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + case nsIDataType.VTYPE_UINT64: + return "PRUint64"; + case nsIDataType.VTYPE_FLOAT: + return "float"; + case nsIDataType.VTYPE_DOUBLE: + return "double"; + case nsIDataType.VTYPE_BOOL: + return "PRBool"; + case nsIDataType.VTYPE_CHAR: + return "char"; + case nsIDataType.VTYPE_WCHAR: + return "PRUnichar"; + case nsIDataType.VTYPE_VOID: + if(type.isPointer) + return "voidPtr"; + return "void"; + case nsIDataType.VTYPE_ID: + // order matters here... + if(type.isReference) + return "nsIDRef"; + if(type.isPointer) + return "nsIDPtr"; + return "nsID"; + case nsIDataType.VTYPE_ASTRING: + return "aString"; + case nsIDataType.VTYPE_CHAR_STR: + return "string"; + case nsIDataType.VTYPE_WCHAR_STR: + return "wstring"; + case nsIDataType.VTYPE_INTERFACE: + return info.getInfoForParam(methodIndex, param).name; + case nsIDataType.VTYPE_INTERFACE_IS: + return "nsQIResult"; + case nsIDataType.VTYPE_ARRAY: + return formatTypeName(info, methodIndex, param, dimension+1); + case nsIDataType.VTYPE_STRING_SIZE_IS: + return "string"; + case nsIDataType.VTYPE_WSTRING_SIZE_IS: + return "wstring"; + default: + return "!!!! bad data type !!!"; + } +} + +function formatBracketForParam(info, methodIndex, param) +{ + var type = param.type; + var str = "["; + var found = 0; + var size_is_ArgNum; + var length_is_ArgNum; + + if(param.isRetval) + { + if(found++) + str += ", "; + str += "retval" + } + + if(param.isShared) + { + if(found++) + str += ", "; + str += "shared" + } + + if(type.isArray) + { + if(found++) + str += ", "; + str += "array" + } + + if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) + { + if(found++) + str += ", "; + str += "iid_is("+ + PARAM_NAME_PREFIX + + info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; + } + + if(type.isArray || + type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || + type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) + { + if(found++) + str += ", "; + + size_is_ArgNum = + info.getSizeIsArgNumberForParam(methodIndex, param, 0); + + str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; + + length_is_ArgNum = + info.getLengthIsArgNumberForParam(methodIndex, param, 0); + + if(length_is_ArgNum != size_is_ArgNum) + { + str += ", "; + str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; + } + } + + if(!found) + return ""; + str += "] "; + return str +} + +function doInterface(out, iid) +{ + var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; + + var info = new IInfo(iid); + var parent = info.parent; + + var constBaseIndex = parent ? parent.constantCount : 0; + var constTotalCount = info.constantCount; + var constLocalCount = constTotalCount - constBaseIndex; + + var methodBaseIndex = parent ? parent.methodCount : 0; + var methodTotalCount = info.methodCount; + var methodLocalCount = methodTotalCount - methodBaseIndex; + + + // maybe recurring to emit parent declarations is not a good idea... +// if(parent) +// doInterface(parent.interfaceID); + + out.writeln(); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// out.writeln("/*\n"); + + out.writeln("[" + (info.isScriptable ? "scriptable, " : "") + + formatID(info.interfaceID.number) + "]"); + + out.writeln("interface "+ info.name + + (parent ? (" : "+parent.name) : "") + " {"); + + if(constLocalCount) + { + for(i = constBaseIndex; i < constTotalCount; i++) + { + c = info.getConstant(i); + out.writeln(" const " + formatConstType(c.type.dataType) + " " + + c.name + " = " + c.value + ";"); + } + } + + if(constLocalCount && methodLocalCount) + out.writeln(); + + if(methodLocalCount) + { + for(i = methodBaseIndex; i < methodTotalCount; i++) + { + m = info.getMethodInfo(i); + + if(m.isNotXPCOM) + bracketed = "[notxpcom] " + else if(m.isHidden) + bracketed = "[noscript] " + else + bracketed = ""; + + if(m.isGetter) + { + // Is an attribute + + // figure out if this is readonly + m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; + readonly = !m2 || m2.name != m.name; + + out.writeln(" " + bracketed + (readonly ? "readonly " : "") + + "attribute " + + formatTypeName(info, i, m.getParam(0), 0) + + " " + m.name + ";\n"); + + if(!readonly) + i++; // skip the next one, we have it covered. + + continue; + } + // else... + + paramCount = m.paramCount; + + // 'last' param is used to figure out retvalTypeName + + p = paramCount ? m.getParam(paramCount-1) : null; + + if(m.isNotXPCOM) + retvalTypeName = formatTypeName(info, i, m.result, 0); + else if(p && "[retval] " == formatBracketForParam(info, i, p)) + { + // Check for the exact string above because anything else + // indicates that there either is no expilict retval + // or there are additional braketed attributes (meaning that + // the retval must appear in the param list and not + // preceeding the method name). + retvalTypeName = formatTypeName(info, i, p, 0); + // no need to print it in the param list + paramCount-- ; + } + else + retvalTypeName = "void"; + + // print method name + + out.writeln(" " + bracketed + retvalTypeName + " " + m.name + + "(" + (paramCount ? "" : ");")); + + // print params + + for(k = 0; k < paramCount; k++) + { + p = m.getParam(k); + out.writeln(" "+ + formatBracketForParam(info, i, p) + + (p.isOut ? p.isIn ? "inout " : "out " : "in ") + + formatTypeName(info, i, p, 0) + " " + + PARAM_NAME_PREFIX+k + + (k+1 == paramCount ? ");\n" : ", ")); + } + } + } + + out.writeln("};\n"); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// out.writeln("\n*/\n"); +} + +function appendForwardDeclarations(list, info) +{ + list.push(info.name); + if(info.parent) + appendForwardDeclarations(list, info.parent); + + var i, k, m, p; + + for(i = 0; i < info.methodCount; i++) + { + m = info.getMethodInfo(i); + + for(k = 0; k < m.paramCount; k++) + { + p = m.getParam(k); + + if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) + { + list.push(info.getInfoForParam(i, p).name); + } + } + } +} + +function doForwardDeclarations(out, iid) +{ + var i, cur, prev; + var list = []; + appendForwardDeclarations(list, new IInfo(iid)); + list.sort(); + + out.writeln("// forward declarations..."); + + for(i = 0; i < list.length; i++) + { + cur = list[i]; + if(cur != prev && cur != "nsISupports") + { + out.writeln("interface " + cur +";"); + prev = cur; + } + } + out.writeln(""); +} + +/*********************************************************/ + +/* Our Componenent ctor */ +function nsInterfaceInfoToIDL() {} + +/* decorate prototype to provide ``class'' methods and property accessors */ +nsInterfaceInfoToIDL.prototype = +{ + // nsIInterfaceInfoToIDL methods... + generateIDL : function (iid) { + var out = new Buffer; + out.writeln(); + out.writeln('#include "nsISupports.idl"'); + out.writeln(); + + doForwardDeclarations(out, iid) + doInterface(out, iid); + + return out.buffer; + }, + + // nsISupports methods... + QueryInterface: function (iid) { + if (!iid.equals(Components.interfaces.nsIInterfaceInfoToIDL) && + !iid.equals(Components.interfaces.nsISupports)) { + throw Components.results.NS_ERROR_NO_INTERFACE; + } + return this; + } +} + +/***************************************************************************/ +/***************************************************************************/ +// parts specific to my use of the the generic module code... + +const MODULE_NAME = "nsInterfaceInfoToIDL"; +const MODULE_CONTRACT_ID = "@mozilla.org/interfaceinfotoidl;1"; +const MODULE_CID = "{47d98974-a1b7-46a6-bc99-8abc374bba3f}"; +const MODULE_CTOR = nsInterfaceInfoToIDL; + +/***************************************************************************/ +/***************************************************************************/ +// generic nsIModule part... + +function NSGetModule(compMgr, fileSpec) { + return new GenericModule(MODULE_NAME, MODULE_CONTRACT_ID, + MODULE_CID, MODULE_CTOR); +} + +function GenericModule (name, contractID, CID, ctor) { + this.name = name; + this.contractID = contractID; + this.CID = Components.ID(CID); + this.ctor = ctor; +} + +GenericModule.prototype = { + /* + * RegisterSelf is called at registration time (component installation + * or the only-until-release startup autoregistration) and is responsible + * for notifying the component manager of all components implemented in + * this module. The fileSpec, location and type parameters are mostly + * opaque, and should be passed on to the registerComponent call + * unmolested. + */ + registerSelf: function (compMgr, fileSpec, location, type) { + compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentManagerObsolete); + compMgr.registerComponentWithType(this.CID, this.name, this.contractID, + fileSpec, location, true, true, type); + }, + + /* + * The GetClassObject method is responsible for producing Factory and + * SingletonFactory objects (the latter are specialized for services). + */ + getClassObject: function (compMgr, cid, iid) { + if (!cid.equals(this.CID)) + throw Components.results.NS_ERROR_NO_INTERFACE; + + if (!iid.equals(Components.interfaces.nsIFactory)) + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + + this.myFactory.ctor = this.ctor; + return this.myFactory; + }, + + /* factory object */ + myFactory: { + + /* + * Construct an instance of the interface specified by iid, possibly + * aggregating it with the provided outer. (If you don't know what + * aggregation is all about, you don't need to. It reduces even the + * mightiest of XPCOM warriors to snivelling cowards.) + */ + createInstance: function (outer, iid) { + if (outer != null) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return (new this.ctor()).QueryInterface(iid); + } + }, + + /* + * The canUnload method signals that the component is about to be unloaded. + * C++ components can return false to indicate that they don't wish to be + * unloaded, but the return value from JS components' canUnload is ignored: + * mark-and-sweep will keep everything around until it's no longer in use, + * making unconditional ``unload'' safe. + * + * You still need to provide a (likely useless) canUnload method, though: + * it's part of the nsIModule interface contract, and the JS loader _will_ + * call it. + */ + canUnload: function(compMgr) { + return true; + } +} + +/***************************************************************************/ diff --git a/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp b/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp index 4deb9b5d8d5..bb4d95dbf71 100644 --- a/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp +++ b/extensions/interfaceinfo/src/nsScriptableInterfaceInfo.cpp @@ -540,8 +540,34 @@ nsScriptableInterfaceInfo::SetInterfaceID(const nsIID * aInterfaceID) mInfo = nsnull; iim->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); - // XXX we want to look at additional managers here if not found! - + // If not found, then let's ask additional managers. + + // This entire block assumes the additional manager support from: + // http://bugzilla.mozilla.org/show_bug.cgi?id=103805 + // Disable it by setting '#if 0'. +#if 0 + PRBool yes; + nsCOMPtr list; + nsCOMPtr iism; + + if(!mInfo && (nsnull != (iism = do_QueryInterface(iim))) && + NS_SUCCEEDED(iism->HasAdditionalManagers(&yes)) && yes && + NS_SUCCEEDED(iism->EnumerateAdditionalManagers(getter_AddRefs(list))) && + list) + { + PRBool more; + nsCOMPtr current; + + while(NS_SUCCEEDED(list->HasMoreElements(&more)) && more && + NS_SUCCEEDED(list->GetNext(getter_AddRefs(current))) && current) + { + current->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); + if(mInfo) + break; + } + } +#endif + return mInfo ? NS_OK : NS_ERROR_NO_INTERFACE; } diff --git a/extensions/interfaceinfo/tests/ifaceinfotest.js b/extensions/interfaceinfo/tests/ifaceinfotest.js index f490462fd66..a186fc65022 100644 --- a/extensions/interfaceinfo/tests/ifaceinfotest.js +++ b/extensions/interfaceinfo/tests/ifaceinfotest.js @@ -1,364 +1,20 @@ -// test the nsIScriptableInterfaceInfo stuff... -// We ought to leverage this in SOAP code. -const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", - "nsIScriptableInterfaceInfo", - "init"); +const IDL_GENERATOR = + new Components.Constructor("@mozilla.org/interfaceinfotoidl;1", + "nsIInterfaceInfoToIDL"); -const nsIDataType = Components.interfaces.nsIDataType; -const nsISupports = Components.interfaces.nsISupports; -const PARAM_NAME_PREFIX = "arg"; - -/** -* takes: {xxx} -* returns: uuid(xxx) -*/ -function formatID(str) -{ - return "uuid("+str.substring(1,str.length-1)+")"; -} - -function formatConstType(type) -{ - switch(type) - { - case nsIDataType.VTYPE_INT16: - return "PRInt16"; - case nsIDataType.VTYPE_INT32: - return "PRInt32"; - case nsIDataType.VTYPE_UINT16: - return "PRUint16"; - case nsIDataType.VTYPE_UINT32: - return "PRUint32"; - default: - return "!!!! bad const type !!!"; - } -} - -function formatTypeName(info, methodIndex, param, dimension) -{ - var type = param.type; - - switch(type.dataType) - { - case nsIDataType.VTYPE_INT8 : - return "PRInt8"; - case nsIDataType.VTYPE_INT16: - return "PRInt16"; - case nsIDataType.VTYPE_INT32: - return "PRInt32"; - case nsIDataType.VTYPE_INT64: - return "PRInt64"; - case nsIDataType.VTYPE_UINT8: - return "PRUint8"; - case nsIDataType.VTYPE_UINT16: - return "PRUint16"; - case nsIDataType.VTYPE_UINT32: - return "PRUint32"; - case nsIDataType.VTYPE_UINT64: - return "PRUint64"; - case nsIDataType.VTYPE_FLOAT: - return "float"; - case nsIDataType.VTYPE_DOUBLE: - return "double"; - case nsIDataType.VTYPE_BOOL: - return "PRBool"; - case nsIDataType.VTYPE_CHAR: - return "char"; - case nsIDataType.VTYPE_WCHAR: - return "PRUnichar"; - case nsIDataType.VTYPE_VOID: - if(type.isPointer) - return "voidPtr"; - return "void"; - case nsIDataType.VTYPE_ID: - // order matters here... - if(type.isReference) - return "nsIDRef"; - if(type.isPointer) - return "nsIDPtr"; - return "nsID"; - case nsIDataType.VTYPE_ASTRING: - return "aString"; - case nsIDataType.VTYPE_CHAR_STR: - return "string"; - case nsIDataType.VTYPE_WCHAR_STR: - return "wstring"; - case nsIDataType.VTYPE_INTERFACE: - return info.getInfoForParam(methodIndex, param).name; - case nsIDataType.VTYPE_INTERFACE_IS: - return "nsQIResult"; - case nsIDataType.VTYPE_ARRAY: - return formatTypeName(info, methodIndex, param, dimension+1); - case nsIDataType.VTYPE_STRING_SIZE_IS: - return "string"; - case nsIDataType.VTYPE_WSTRING_SIZE_IS: - return "wstring"; - default: - return "!!!! bad data type !!!"; - } -} - -function formatBracketForParam(info, methodIndex, param) -{ - var type = param.type; - var str = "["; - var found = 0; - var size_is_ArgNum; - var length_is_ArgNum; - - if(param.isRetval) - { - if(found++) - str += ", "; - str += "retval" - } - - if(param.isShared) - { - if(found++) - str += ", "; - str += "shared" - } - - if(type.isArray) - { - if(found++) - str += ", "; - str += "array" - } - - if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) - { - if(found++) - str += ", "; - str += "iid_is("+ - PARAM_NAME_PREFIX + - info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; - } - - if(type.isArray || - type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || - type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) - { - if(found++) - str += ", "; - - size_is_ArgNum = - info.getSizeIsArgNumberForParam(methodIndex, param, 0); - - str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; - - length_is_ArgNum = - info.getLengthIsArgNumberForParam(methodIndex, param, 0); - - if(length_is_ArgNum != size_is_ArgNum) - { - str += ", "; - str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; - } - } - - if(!found) - return ""; - str += "] "; - return str -} - -function doInterface(iid) -{ - var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; - - var info = new IInfo(iid); - var parent = info.parent; - - var constBaseIndex = parent ? parent.constantCount : 0; - var constTotalCount = info.constantCount; - var constLocalCount = constTotalCount - constBaseIndex; - - var methodBaseIndex = parent ? parent.methodCount : 0; - var methodTotalCount = info.methodCount; - var methodLocalCount = methodTotalCount - methodBaseIndex; - - - // maybe recurring to emit parent declarations is not a good idea... -// if(parent) -// doInterface(parent.interfaceID); - - print(); - - // comment out nsISupports -// if(iid.equals(nsISupports)) -// print("/*\n"); - - print("[" + (info.isScriptable ? "scriptable, " : "") + - formatID(info.interfaceID.number) + "]"); - - print("interface "+ info.name + (parent ? (" : "+parent.name) : "") + " {"); - - if(constLocalCount) - { - for(i = constBaseIndex; i < constTotalCount; i++) - { - c = info.getConstant(i); - print(" const " + formatConstType(c.type.dataType) + " " + - c.name + " = " + c.value + ";"); - } - } - - if(constLocalCount && methodLocalCount) - print(); - - if(methodLocalCount) - { - for(i = methodBaseIndex; i < methodTotalCount; i++) - { - m = info.getMethodInfo(i); - - if(m.isNotXPCOM) - bracketed = "[notxpcom] " - else if(m.isHidden) - bracketed = "[noscript] " - else - bracketed = ""; - - if(m.isGetter) - { - // Is an attribute - - // figure out if this is readonly - m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; - readonly = !m2 || m2.name != m.name; - - print(" " + bracketed + (readonly ? "readonly " : "") + - "attribute " + - formatTypeName(info, i, m.getParam(0), 0) + - " " + m.name + ";\n"); - - if(!readonly) - i++; // skip the next one, we have it covered. - - continue; - } - // else... - - paramCount = m.paramCount; - - // 'last' param is used to figure out retvalTypeName - - p = paramCount ? m.getParam(paramCount-1) : null; - - if(m.isNotXPCOM) - retvalTypeName = formatTypeName(info, i, m.result, 0); - else if(p && "[retval] " == formatBracketForParam(info, i, p)) - { - // Check for the exact string above because anything else - // indicates that there either is no expilict retval - // or there are additional braketed attributes (meaning that - // the retval must appear in the param list and not - // preceeding the method name). - retvalTypeName = formatTypeName(info, i, p, 0); - // no need to print it in the param list - paramCount-- ; - } - else - retvalTypeName = "void"; - - // print method name - - print(" " + bracketed + retvalTypeName + " " + m.name + "(" + - (paramCount ? "" : ");")); - - // print params - - for(k = 0; k < paramCount; k++) - { - p = m.getParam(k); - print(" "+ - formatBracketForParam(info, i, p) + - (p.isOut ? p.isIn ? "inout " : "out " : "in ") + - formatTypeName(info, i, p, 0) + " " + - PARAM_NAME_PREFIX+k + - (k+1 == paramCount ? ");\n" : ", ")); - } - } - } - - print("};\n"); - - // comment out nsISupports -// if(iid.equals(nsISupports)) -// print("\n*/\n"); -} - -function appendForwardDeclarations(list, info) -{ - list.push(info.name); - if(info.parent) - appendForwardDeclarations(list, info.parent); - - var i, k, m, p; - - for(i = 0; i < info.methodCount; i++) - { - m = info.getMethodInfo(i); - - for(k = 0; k < m.paramCount; k++) - { - p = m.getParam(k); - - if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) - { - list.push(info.getInfoForParam(i, p).name); - } - } - } -} - -function doForwardDeclarations(iid) -{ - var i, cur, prev; - var list = []; - appendForwardDeclarations(list, new IInfo(iid)); - list.sort(); - - print("// forward declarations..."); - - for(i = 0; i < list.length; i++) - { - cur = list[i]; - if(cur != prev && cur != "nsISupports") - { - print("interface " + cur +";"); - prev = cur; - } - } - print(""); -} - -function info2IDL(iid) -{ - print(); - print('#include "nsISupports.idl"'); - print(); - - doForwardDeclarations(iid) - doInterface(iid); -} - -/***************************************************************************/ -/***************************************************************************/ -// test... +var gen = new IDL_GENERATOR(); print(); print(); -//info2IDL(Components.interfaces.nsISupports); +print(gen.generateIDL(Components.interfaces.nsISupports)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIDataType); +print(gen.generateIDL(Components.interfaces.nsIDataType)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIScriptableInterfaceInfo); +print(gen.generateIDL(Components.interfaces.nsIScriptableInterfaceInfo)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIVariant); +print(gen.generateIDL(Components.interfaces.nsIVariant)); print(); print(); + diff --git a/extensions/webservices/interfaceinfo/src/nsInterfaceInfoToIDL.js b/extensions/webservices/interfaceinfo/src/nsInterfaceInfoToIDL.js new file mode 100644 index 00000000000..3a52ac5c152 --- /dev/null +++ b/extensions/webservices/interfaceinfo/src/nsInterfaceInfoToIDL.js @@ -0,0 +1,524 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsInterfaceInfoToIDL implementation.*/ + + +/***************************************************************************/ +// nsInterfaceInfoToIDL part... + +const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", + "nsIScriptableInterfaceInfo", + "init"); + +const nsIDataType = Components.interfaces.nsIDataType; +const nsISupports = Components.interfaces.nsISupports; + +const PARAM_NAME_PREFIX = "arg"; + +// helpers... + +/********************************************************/ +// accumulate a string with a stream-ish abstraction + +function Buffer() { + this.buffer = ""; +} + +Buffer.prototype = { + write : function(s) { + if(s) + this.buffer += s; + }, + + writeln : function(s) { + if(s) + this.buffer += s + "\n"; + else + this.buffer += "\n"; + } +} + +/********************************************************/ + +/** +* takes: {xxx} +* returns: uuid(xxx) +*/ +function formatID(str) +{ + return "uuid("+str.substring(1,str.length-1)+")"; +} + +function formatConstType(type) +{ + switch(type) + { + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + default: + return "!!!! bad const type !!!"; + } +} + +function formatTypeName(info, methodIndex, param, dimension) +{ + var type = param.type; + + switch(type.dataType) + { + case nsIDataType.VTYPE_INT8 : + return "PRInt8"; + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_INT64: + return "PRInt64"; + case nsIDataType.VTYPE_UINT8: + return "PRUint8"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + case nsIDataType.VTYPE_UINT64: + return "PRUint64"; + case nsIDataType.VTYPE_FLOAT: + return "float"; + case nsIDataType.VTYPE_DOUBLE: + return "double"; + case nsIDataType.VTYPE_BOOL: + return "PRBool"; + case nsIDataType.VTYPE_CHAR: + return "char"; + case nsIDataType.VTYPE_WCHAR: + return "PRUnichar"; + case nsIDataType.VTYPE_VOID: + if(type.isPointer) + return "voidPtr"; + return "void"; + case nsIDataType.VTYPE_ID: + // order matters here... + if(type.isReference) + return "nsIDRef"; + if(type.isPointer) + return "nsIDPtr"; + return "nsID"; + case nsIDataType.VTYPE_ASTRING: + return "aString"; + case nsIDataType.VTYPE_CHAR_STR: + return "string"; + case nsIDataType.VTYPE_WCHAR_STR: + return "wstring"; + case nsIDataType.VTYPE_INTERFACE: + return info.getInfoForParam(methodIndex, param).name; + case nsIDataType.VTYPE_INTERFACE_IS: + return "nsQIResult"; + case nsIDataType.VTYPE_ARRAY: + return formatTypeName(info, methodIndex, param, dimension+1); + case nsIDataType.VTYPE_STRING_SIZE_IS: + return "string"; + case nsIDataType.VTYPE_WSTRING_SIZE_IS: + return "wstring"; + default: + return "!!!! bad data type !!!"; + } +} + +function formatBracketForParam(info, methodIndex, param) +{ + var type = param.type; + var str = "["; + var found = 0; + var size_is_ArgNum; + var length_is_ArgNum; + + if(param.isRetval) + { + if(found++) + str += ", "; + str += "retval" + } + + if(param.isShared) + { + if(found++) + str += ", "; + str += "shared" + } + + if(type.isArray) + { + if(found++) + str += ", "; + str += "array" + } + + if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) + { + if(found++) + str += ", "; + str += "iid_is("+ + PARAM_NAME_PREFIX + + info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; + } + + if(type.isArray || + type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || + type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) + { + if(found++) + str += ", "; + + size_is_ArgNum = + info.getSizeIsArgNumberForParam(methodIndex, param, 0); + + str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; + + length_is_ArgNum = + info.getLengthIsArgNumberForParam(methodIndex, param, 0); + + if(length_is_ArgNum != size_is_ArgNum) + { + str += ", "; + str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; + } + } + + if(!found) + return ""; + str += "] "; + return str +} + +function doInterface(out, iid) +{ + var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; + + var info = new IInfo(iid); + var parent = info.parent; + + var constBaseIndex = parent ? parent.constantCount : 0; + var constTotalCount = info.constantCount; + var constLocalCount = constTotalCount - constBaseIndex; + + var methodBaseIndex = parent ? parent.methodCount : 0; + var methodTotalCount = info.methodCount; + var methodLocalCount = methodTotalCount - methodBaseIndex; + + + // maybe recurring to emit parent declarations is not a good idea... +// if(parent) +// doInterface(parent.interfaceID); + + out.writeln(); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// out.writeln("/*\n"); + + out.writeln("[" + (info.isScriptable ? "scriptable, " : "") + + formatID(info.interfaceID.number) + "]"); + + out.writeln("interface "+ info.name + + (parent ? (" : "+parent.name) : "") + " {"); + + if(constLocalCount) + { + for(i = constBaseIndex; i < constTotalCount; i++) + { + c = info.getConstant(i); + out.writeln(" const " + formatConstType(c.type.dataType) + " " + + c.name + " = " + c.value + ";"); + } + } + + if(constLocalCount && methodLocalCount) + out.writeln(); + + if(methodLocalCount) + { + for(i = methodBaseIndex; i < methodTotalCount; i++) + { + m = info.getMethodInfo(i); + + if(m.isNotXPCOM) + bracketed = "[notxpcom] " + else if(m.isHidden) + bracketed = "[noscript] " + else + bracketed = ""; + + if(m.isGetter) + { + // Is an attribute + + // figure out if this is readonly + m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; + readonly = !m2 || m2.name != m.name; + + out.writeln(" " + bracketed + (readonly ? "readonly " : "") + + "attribute " + + formatTypeName(info, i, m.getParam(0), 0) + + " " + m.name + ";\n"); + + if(!readonly) + i++; // skip the next one, we have it covered. + + continue; + } + // else... + + paramCount = m.paramCount; + + // 'last' param is used to figure out retvalTypeName + + p = paramCount ? m.getParam(paramCount-1) : null; + + if(m.isNotXPCOM) + retvalTypeName = formatTypeName(info, i, m.result, 0); + else if(p && "[retval] " == formatBracketForParam(info, i, p)) + { + // Check for the exact string above because anything else + // indicates that there either is no expilict retval + // or there are additional braketed attributes (meaning that + // the retval must appear in the param list and not + // preceeding the method name). + retvalTypeName = formatTypeName(info, i, p, 0); + // no need to print it in the param list + paramCount-- ; + } + else + retvalTypeName = "void"; + + // print method name + + out.writeln(" " + bracketed + retvalTypeName + " " + m.name + + "(" + (paramCount ? "" : ");")); + + // print params + + for(k = 0; k < paramCount; k++) + { + p = m.getParam(k); + out.writeln(" "+ + formatBracketForParam(info, i, p) + + (p.isOut ? p.isIn ? "inout " : "out " : "in ") + + formatTypeName(info, i, p, 0) + " " + + PARAM_NAME_PREFIX+k + + (k+1 == paramCount ? ");\n" : ", ")); + } + } + } + + out.writeln("};\n"); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// out.writeln("\n*/\n"); +} + +function appendForwardDeclarations(list, info) +{ + list.push(info.name); + if(info.parent) + appendForwardDeclarations(list, info.parent); + + var i, k, m, p; + + for(i = 0; i < info.methodCount; i++) + { + m = info.getMethodInfo(i); + + for(k = 0; k < m.paramCount; k++) + { + p = m.getParam(k); + + if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) + { + list.push(info.getInfoForParam(i, p).name); + } + } + } +} + +function doForwardDeclarations(out, iid) +{ + var i, cur, prev; + var list = []; + appendForwardDeclarations(list, new IInfo(iid)); + list.sort(); + + out.writeln("// forward declarations..."); + + for(i = 0; i < list.length; i++) + { + cur = list[i]; + if(cur != prev && cur != "nsISupports") + { + out.writeln("interface " + cur +";"); + prev = cur; + } + } + out.writeln(""); +} + +/*********************************************************/ + +/* Our Componenent ctor */ +function nsInterfaceInfoToIDL() {} + +/* decorate prototype to provide ``class'' methods and property accessors */ +nsInterfaceInfoToIDL.prototype = +{ + // nsIInterfaceInfoToIDL methods... + generateIDL : function (iid) { + var out = new Buffer; + out.writeln(); + out.writeln('#include "nsISupports.idl"'); + out.writeln(); + + doForwardDeclarations(out, iid) + doInterface(out, iid); + + return out.buffer; + }, + + // nsISupports methods... + QueryInterface: function (iid) { + if (!iid.equals(Components.interfaces.nsIInterfaceInfoToIDL) && + !iid.equals(Components.interfaces.nsISupports)) { + throw Components.results.NS_ERROR_NO_INTERFACE; + } + return this; + } +} + +/***************************************************************************/ +/***************************************************************************/ +// parts specific to my use of the the generic module code... + +const MODULE_NAME = "nsInterfaceInfoToIDL"; +const MODULE_CONTRACT_ID = "@mozilla.org/interfaceinfotoidl;1"; +const MODULE_CID = "{47d98974-a1b7-46a6-bc99-8abc374bba3f}"; +const MODULE_CTOR = nsInterfaceInfoToIDL; + +/***************************************************************************/ +/***************************************************************************/ +// generic nsIModule part... + +function NSGetModule(compMgr, fileSpec) { + return new GenericModule(MODULE_NAME, MODULE_CONTRACT_ID, + MODULE_CID, MODULE_CTOR); +} + +function GenericModule (name, contractID, CID, ctor) { + this.name = name; + this.contractID = contractID; + this.CID = Components.ID(CID); + this.ctor = ctor; +} + +GenericModule.prototype = { + /* + * RegisterSelf is called at registration time (component installation + * or the only-until-release startup autoregistration) and is responsible + * for notifying the component manager of all components implemented in + * this module. The fileSpec, location and type parameters are mostly + * opaque, and should be passed on to the registerComponent call + * unmolested. + */ + registerSelf: function (compMgr, fileSpec, location, type) { + compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentManagerObsolete); + compMgr.registerComponentWithType(this.CID, this.name, this.contractID, + fileSpec, location, true, true, type); + }, + + /* + * The GetClassObject method is responsible for producing Factory and + * SingletonFactory objects (the latter are specialized for services). + */ + getClassObject: function (compMgr, cid, iid) { + if (!cid.equals(this.CID)) + throw Components.results.NS_ERROR_NO_INTERFACE; + + if (!iid.equals(Components.interfaces.nsIFactory)) + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + + this.myFactory.ctor = this.ctor; + return this.myFactory; + }, + + /* factory object */ + myFactory: { + + /* + * Construct an instance of the interface specified by iid, possibly + * aggregating it with the provided outer. (If you don't know what + * aggregation is all about, you don't need to. It reduces even the + * mightiest of XPCOM warriors to snivelling cowards.) + */ + createInstance: function (outer, iid) { + if (outer != null) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return (new this.ctor()).QueryInterface(iid); + } + }, + + /* + * The canUnload method signals that the component is about to be unloaded. + * C++ components can return false to indicate that they don't wish to be + * unloaded, but the return value from JS components' canUnload is ignored: + * mark-and-sweep will keep everything around until it's no longer in use, + * making unconditional ``unload'' safe. + * + * You still need to provide a (likely useless) canUnload method, though: + * it's part of the nsIModule interface contract, and the JS loader _will_ + * call it. + */ + canUnload: function(compMgr) { + return true; + } +} + +/***************************************************************************/ diff --git a/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp b/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp index 4deb9b5d8d5..bb4d95dbf71 100644 --- a/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp +++ b/extensions/webservices/interfaceinfo/src/nsScriptableInterfaceInfo.cpp @@ -540,8 +540,34 @@ nsScriptableInterfaceInfo::SetInterfaceID(const nsIID * aInterfaceID) mInfo = nsnull; iim->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); - // XXX we want to look at additional managers here if not found! - + // If not found, then let's ask additional managers. + + // This entire block assumes the additional manager support from: + // http://bugzilla.mozilla.org/show_bug.cgi?id=103805 + // Disable it by setting '#if 0'. +#if 0 + PRBool yes; + nsCOMPtr list; + nsCOMPtr iism; + + if(!mInfo && (nsnull != (iism = do_QueryInterface(iim))) && + NS_SUCCEEDED(iism->HasAdditionalManagers(&yes)) && yes && + NS_SUCCEEDED(iism->EnumerateAdditionalManagers(getter_AddRefs(list))) && + list) + { + PRBool more; + nsCOMPtr current; + + while(NS_SUCCEEDED(list->HasMoreElements(&more)) && more && + NS_SUCCEEDED(list->GetNext(getter_AddRefs(current))) && current) + { + current->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); + if(mInfo) + break; + } + } +#endif + return mInfo ? NS_OK : NS_ERROR_NO_INTERFACE; } diff --git a/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js b/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js index f490462fd66..a186fc65022 100644 --- a/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js +++ b/extensions/webservices/interfaceinfo/tests/ifaceinfotest.js @@ -1,364 +1,20 @@ -// test the nsIScriptableInterfaceInfo stuff... -// We ought to leverage this in SOAP code. -const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", - "nsIScriptableInterfaceInfo", - "init"); +const IDL_GENERATOR = + new Components.Constructor("@mozilla.org/interfaceinfotoidl;1", + "nsIInterfaceInfoToIDL"); -const nsIDataType = Components.interfaces.nsIDataType; -const nsISupports = Components.interfaces.nsISupports; -const PARAM_NAME_PREFIX = "arg"; - -/** -* takes: {xxx} -* returns: uuid(xxx) -*/ -function formatID(str) -{ - return "uuid("+str.substring(1,str.length-1)+")"; -} - -function formatConstType(type) -{ - switch(type) - { - case nsIDataType.VTYPE_INT16: - return "PRInt16"; - case nsIDataType.VTYPE_INT32: - return "PRInt32"; - case nsIDataType.VTYPE_UINT16: - return "PRUint16"; - case nsIDataType.VTYPE_UINT32: - return "PRUint32"; - default: - return "!!!! bad const type !!!"; - } -} - -function formatTypeName(info, methodIndex, param, dimension) -{ - var type = param.type; - - switch(type.dataType) - { - case nsIDataType.VTYPE_INT8 : - return "PRInt8"; - case nsIDataType.VTYPE_INT16: - return "PRInt16"; - case nsIDataType.VTYPE_INT32: - return "PRInt32"; - case nsIDataType.VTYPE_INT64: - return "PRInt64"; - case nsIDataType.VTYPE_UINT8: - return "PRUint8"; - case nsIDataType.VTYPE_UINT16: - return "PRUint16"; - case nsIDataType.VTYPE_UINT32: - return "PRUint32"; - case nsIDataType.VTYPE_UINT64: - return "PRUint64"; - case nsIDataType.VTYPE_FLOAT: - return "float"; - case nsIDataType.VTYPE_DOUBLE: - return "double"; - case nsIDataType.VTYPE_BOOL: - return "PRBool"; - case nsIDataType.VTYPE_CHAR: - return "char"; - case nsIDataType.VTYPE_WCHAR: - return "PRUnichar"; - case nsIDataType.VTYPE_VOID: - if(type.isPointer) - return "voidPtr"; - return "void"; - case nsIDataType.VTYPE_ID: - // order matters here... - if(type.isReference) - return "nsIDRef"; - if(type.isPointer) - return "nsIDPtr"; - return "nsID"; - case nsIDataType.VTYPE_ASTRING: - return "aString"; - case nsIDataType.VTYPE_CHAR_STR: - return "string"; - case nsIDataType.VTYPE_WCHAR_STR: - return "wstring"; - case nsIDataType.VTYPE_INTERFACE: - return info.getInfoForParam(methodIndex, param).name; - case nsIDataType.VTYPE_INTERFACE_IS: - return "nsQIResult"; - case nsIDataType.VTYPE_ARRAY: - return formatTypeName(info, methodIndex, param, dimension+1); - case nsIDataType.VTYPE_STRING_SIZE_IS: - return "string"; - case nsIDataType.VTYPE_WSTRING_SIZE_IS: - return "wstring"; - default: - return "!!!! bad data type !!!"; - } -} - -function formatBracketForParam(info, methodIndex, param) -{ - var type = param.type; - var str = "["; - var found = 0; - var size_is_ArgNum; - var length_is_ArgNum; - - if(param.isRetval) - { - if(found++) - str += ", "; - str += "retval" - } - - if(param.isShared) - { - if(found++) - str += ", "; - str += "shared" - } - - if(type.isArray) - { - if(found++) - str += ", "; - str += "array" - } - - if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) - { - if(found++) - str += ", "; - str += "iid_is("+ - PARAM_NAME_PREFIX + - info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; - } - - if(type.isArray || - type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || - type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) - { - if(found++) - str += ", "; - - size_is_ArgNum = - info.getSizeIsArgNumberForParam(methodIndex, param, 0); - - str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; - - length_is_ArgNum = - info.getLengthIsArgNumberForParam(methodIndex, param, 0); - - if(length_is_ArgNum != size_is_ArgNum) - { - str += ", "; - str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; - } - } - - if(!found) - return ""; - str += "] "; - return str -} - -function doInterface(iid) -{ - var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; - - var info = new IInfo(iid); - var parent = info.parent; - - var constBaseIndex = parent ? parent.constantCount : 0; - var constTotalCount = info.constantCount; - var constLocalCount = constTotalCount - constBaseIndex; - - var methodBaseIndex = parent ? parent.methodCount : 0; - var methodTotalCount = info.methodCount; - var methodLocalCount = methodTotalCount - methodBaseIndex; - - - // maybe recurring to emit parent declarations is not a good idea... -// if(parent) -// doInterface(parent.interfaceID); - - print(); - - // comment out nsISupports -// if(iid.equals(nsISupports)) -// print("/*\n"); - - print("[" + (info.isScriptable ? "scriptable, " : "") + - formatID(info.interfaceID.number) + "]"); - - print("interface "+ info.name + (parent ? (" : "+parent.name) : "") + " {"); - - if(constLocalCount) - { - for(i = constBaseIndex; i < constTotalCount; i++) - { - c = info.getConstant(i); - print(" const " + formatConstType(c.type.dataType) + " " + - c.name + " = " + c.value + ";"); - } - } - - if(constLocalCount && methodLocalCount) - print(); - - if(methodLocalCount) - { - for(i = methodBaseIndex; i < methodTotalCount; i++) - { - m = info.getMethodInfo(i); - - if(m.isNotXPCOM) - bracketed = "[notxpcom] " - else if(m.isHidden) - bracketed = "[noscript] " - else - bracketed = ""; - - if(m.isGetter) - { - // Is an attribute - - // figure out if this is readonly - m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; - readonly = !m2 || m2.name != m.name; - - print(" " + bracketed + (readonly ? "readonly " : "") + - "attribute " + - formatTypeName(info, i, m.getParam(0), 0) + - " " + m.name + ";\n"); - - if(!readonly) - i++; // skip the next one, we have it covered. - - continue; - } - // else... - - paramCount = m.paramCount; - - // 'last' param is used to figure out retvalTypeName - - p = paramCount ? m.getParam(paramCount-1) : null; - - if(m.isNotXPCOM) - retvalTypeName = formatTypeName(info, i, m.result, 0); - else if(p && "[retval] " == formatBracketForParam(info, i, p)) - { - // Check for the exact string above because anything else - // indicates that there either is no expilict retval - // or there are additional braketed attributes (meaning that - // the retval must appear in the param list and not - // preceeding the method name). - retvalTypeName = formatTypeName(info, i, p, 0); - // no need to print it in the param list - paramCount-- ; - } - else - retvalTypeName = "void"; - - // print method name - - print(" " + bracketed + retvalTypeName + " " + m.name + "(" + - (paramCount ? "" : ");")); - - // print params - - for(k = 0; k < paramCount; k++) - { - p = m.getParam(k); - print(" "+ - formatBracketForParam(info, i, p) + - (p.isOut ? p.isIn ? "inout " : "out " : "in ") + - formatTypeName(info, i, p, 0) + " " + - PARAM_NAME_PREFIX+k + - (k+1 == paramCount ? ");\n" : ", ")); - } - } - } - - print("};\n"); - - // comment out nsISupports -// if(iid.equals(nsISupports)) -// print("\n*/\n"); -} - -function appendForwardDeclarations(list, info) -{ - list.push(info.name); - if(info.parent) - appendForwardDeclarations(list, info.parent); - - var i, k, m, p; - - for(i = 0; i < info.methodCount; i++) - { - m = info.getMethodInfo(i); - - for(k = 0; k < m.paramCount; k++) - { - p = m.getParam(k); - - if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) - { - list.push(info.getInfoForParam(i, p).name); - } - } - } -} - -function doForwardDeclarations(iid) -{ - var i, cur, prev; - var list = []; - appendForwardDeclarations(list, new IInfo(iid)); - list.sort(); - - print("// forward declarations..."); - - for(i = 0; i < list.length; i++) - { - cur = list[i]; - if(cur != prev && cur != "nsISupports") - { - print("interface " + cur +";"); - prev = cur; - } - } - print(""); -} - -function info2IDL(iid) -{ - print(); - print('#include "nsISupports.idl"'); - print(); - - doForwardDeclarations(iid) - doInterface(iid); -} - -/***************************************************************************/ -/***************************************************************************/ -// test... +var gen = new IDL_GENERATOR(); print(); print(); -//info2IDL(Components.interfaces.nsISupports); +print(gen.generateIDL(Components.interfaces.nsISupports)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIDataType); +print(gen.generateIDL(Components.interfaces.nsIDataType)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIScriptableInterfaceInfo); +print(gen.generateIDL(Components.interfaces.nsIScriptableInterfaceInfo)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIVariant); +print(gen.generateIDL(Components.interfaces.nsIVariant)); print(); print(); + diff --git a/extensions/webservices/public/nsIInterfaceInfoToIDL.idl b/extensions/webservices/public/nsIInterfaceInfoToIDL.idl new file mode 100644 index 00000000000..40611ac833a --- /dev/null +++ b/extensions/webservices/public/nsIInterfaceInfoToIDL.idl @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIInterfaceInfoToIDL public declaration.*/ + +#include "nsISupports.idl" + +[scriptable, uuid(b01eb40c-026b-49c9-af55-25e8c9d034c8)] +interface nsIInterfaceInfoToIDL : nsISupports +{ + string generateIDL(in nsIIDRef aIID); +}; + diff --git a/extensions/xmlextras/interfaceinfo/public/makefile.win b/extensions/xmlextras/interfaceinfo/public/makefile.win index 4350049960b..e69de29bb2d 100644 --- a/extensions/xmlextras/interfaceinfo/public/makefile.win +++ b/extensions/xmlextras/interfaceinfo/public/makefile.win @@ -1,31 +0,0 @@ -#!nmake -# -# The contents of this file are subject to the Netscape Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/NPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): - -DEPTH=..\..\.. - -MODULE=iiextras - -XPIDLSRCS = \ - .\nsIGenericInterfaceInfoSet.idl \ - .\nsIScriptableInterfaceInfo.idl \ - $(NULL) - -include <$(DEPTH)\config\rules.mak> diff --git a/extensions/xmlextras/interfaceinfo/public/nsIInterfaceInfoToIDL.idl b/extensions/xmlextras/interfaceinfo/public/nsIInterfaceInfoToIDL.idl new file mode 100644 index 00000000000..40611ac833a --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/public/nsIInterfaceInfoToIDL.idl @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsIInterfaceInfoToIDL public declaration.*/ + +#include "nsISupports.idl" + +[scriptable, uuid(b01eb40c-026b-49c9-af55-25e8c9d034c8)] +interface nsIInterfaceInfoToIDL : nsISupports +{ + string generateIDL(in nsIIDRef aIID); +}; + diff --git a/extensions/xmlextras/interfaceinfo/src/makefile.win b/extensions/xmlextras/interfaceinfo/src/makefile.win index 7e78970d4dc..95fe91693af 100644 --- a/extensions/xmlextras/interfaceinfo/src/makefile.win +++ b/extensions/xmlextras/interfaceinfo/src/makefile.win @@ -61,3 +61,6 @@ LLIBS= $(LIBNSPR) \ $(NULL) include <$(DEPTH)\config\rules.mak> + +libs:: $(DLL) + $(MAKE_INSTALL) nsInterfaceInfoToIDL.js $(DIST)\bin\components diff --git a/extensions/xmlextras/interfaceinfo/src/nsInterfaceInfoToIDL.js b/extensions/xmlextras/interfaceinfo/src/nsInterfaceInfoToIDL.js new file mode 100644 index 00000000000..3a52ac5c152 --- /dev/null +++ b/extensions/xmlextras/interfaceinfo/src/nsInterfaceInfoToIDL.js @@ -0,0 +1,524 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* The nsInterfaceInfoToIDL implementation.*/ + + +/***************************************************************************/ +// nsInterfaceInfoToIDL part... + +const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", + "nsIScriptableInterfaceInfo", + "init"); + +const nsIDataType = Components.interfaces.nsIDataType; +const nsISupports = Components.interfaces.nsISupports; + +const PARAM_NAME_PREFIX = "arg"; + +// helpers... + +/********************************************************/ +// accumulate a string with a stream-ish abstraction + +function Buffer() { + this.buffer = ""; +} + +Buffer.prototype = { + write : function(s) { + if(s) + this.buffer += s; + }, + + writeln : function(s) { + if(s) + this.buffer += s + "\n"; + else + this.buffer += "\n"; + } +} + +/********************************************************/ + +/** +* takes: {xxx} +* returns: uuid(xxx) +*/ +function formatID(str) +{ + return "uuid("+str.substring(1,str.length-1)+")"; +} + +function formatConstType(type) +{ + switch(type) + { + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + default: + return "!!!! bad const type !!!"; + } +} + +function formatTypeName(info, methodIndex, param, dimension) +{ + var type = param.type; + + switch(type.dataType) + { + case nsIDataType.VTYPE_INT8 : + return "PRInt8"; + case nsIDataType.VTYPE_INT16: + return "PRInt16"; + case nsIDataType.VTYPE_INT32: + return "PRInt32"; + case nsIDataType.VTYPE_INT64: + return "PRInt64"; + case nsIDataType.VTYPE_UINT8: + return "PRUint8"; + case nsIDataType.VTYPE_UINT16: + return "PRUint16"; + case nsIDataType.VTYPE_UINT32: + return "PRUint32"; + case nsIDataType.VTYPE_UINT64: + return "PRUint64"; + case nsIDataType.VTYPE_FLOAT: + return "float"; + case nsIDataType.VTYPE_DOUBLE: + return "double"; + case nsIDataType.VTYPE_BOOL: + return "PRBool"; + case nsIDataType.VTYPE_CHAR: + return "char"; + case nsIDataType.VTYPE_WCHAR: + return "PRUnichar"; + case nsIDataType.VTYPE_VOID: + if(type.isPointer) + return "voidPtr"; + return "void"; + case nsIDataType.VTYPE_ID: + // order matters here... + if(type.isReference) + return "nsIDRef"; + if(type.isPointer) + return "nsIDPtr"; + return "nsID"; + case nsIDataType.VTYPE_ASTRING: + return "aString"; + case nsIDataType.VTYPE_CHAR_STR: + return "string"; + case nsIDataType.VTYPE_WCHAR_STR: + return "wstring"; + case nsIDataType.VTYPE_INTERFACE: + return info.getInfoForParam(methodIndex, param).name; + case nsIDataType.VTYPE_INTERFACE_IS: + return "nsQIResult"; + case nsIDataType.VTYPE_ARRAY: + return formatTypeName(info, methodIndex, param, dimension+1); + case nsIDataType.VTYPE_STRING_SIZE_IS: + return "string"; + case nsIDataType.VTYPE_WSTRING_SIZE_IS: + return "wstring"; + default: + return "!!!! bad data type !!!"; + } +} + +function formatBracketForParam(info, methodIndex, param) +{ + var type = param.type; + var str = "["; + var found = 0; + var size_is_ArgNum; + var length_is_ArgNum; + + if(param.isRetval) + { + if(found++) + str += ", "; + str += "retval" + } + + if(param.isShared) + { + if(found++) + str += ", "; + str += "shared" + } + + if(type.isArray) + { + if(found++) + str += ", "; + str += "array" + } + + if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) + { + if(found++) + str += ", "; + str += "iid_is("+ + PARAM_NAME_PREFIX + + info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; + } + + if(type.isArray || + type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || + type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) + { + if(found++) + str += ", "; + + size_is_ArgNum = + info.getSizeIsArgNumberForParam(methodIndex, param, 0); + + str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; + + length_is_ArgNum = + info.getLengthIsArgNumberForParam(methodIndex, param, 0); + + if(length_is_ArgNum != size_is_ArgNum) + { + str += ", "; + str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; + } + } + + if(!found) + return ""; + str += "] "; + return str +} + +function doInterface(out, iid) +{ + var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; + + var info = new IInfo(iid); + var parent = info.parent; + + var constBaseIndex = parent ? parent.constantCount : 0; + var constTotalCount = info.constantCount; + var constLocalCount = constTotalCount - constBaseIndex; + + var methodBaseIndex = parent ? parent.methodCount : 0; + var methodTotalCount = info.methodCount; + var methodLocalCount = methodTotalCount - methodBaseIndex; + + + // maybe recurring to emit parent declarations is not a good idea... +// if(parent) +// doInterface(parent.interfaceID); + + out.writeln(); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// out.writeln("/*\n"); + + out.writeln("[" + (info.isScriptable ? "scriptable, " : "") + + formatID(info.interfaceID.number) + "]"); + + out.writeln("interface "+ info.name + + (parent ? (" : "+parent.name) : "") + " {"); + + if(constLocalCount) + { + for(i = constBaseIndex; i < constTotalCount; i++) + { + c = info.getConstant(i); + out.writeln(" const " + formatConstType(c.type.dataType) + " " + + c.name + " = " + c.value + ";"); + } + } + + if(constLocalCount && methodLocalCount) + out.writeln(); + + if(methodLocalCount) + { + for(i = methodBaseIndex; i < methodTotalCount; i++) + { + m = info.getMethodInfo(i); + + if(m.isNotXPCOM) + bracketed = "[notxpcom] " + else if(m.isHidden) + bracketed = "[noscript] " + else + bracketed = ""; + + if(m.isGetter) + { + // Is an attribute + + // figure out if this is readonly + m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; + readonly = !m2 || m2.name != m.name; + + out.writeln(" " + bracketed + (readonly ? "readonly " : "") + + "attribute " + + formatTypeName(info, i, m.getParam(0), 0) + + " " + m.name + ";\n"); + + if(!readonly) + i++; // skip the next one, we have it covered. + + continue; + } + // else... + + paramCount = m.paramCount; + + // 'last' param is used to figure out retvalTypeName + + p = paramCount ? m.getParam(paramCount-1) : null; + + if(m.isNotXPCOM) + retvalTypeName = formatTypeName(info, i, m.result, 0); + else if(p && "[retval] " == formatBracketForParam(info, i, p)) + { + // Check for the exact string above because anything else + // indicates that there either is no expilict retval + // or there are additional braketed attributes (meaning that + // the retval must appear in the param list and not + // preceeding the method name). + retvalTypeName = formatTypeName(info, i, p, 0); + // no need to print it in the param list + paramCount-- ; + } + else + retvalTypeName = "void"; + + // print method name + + out.writeln(" " + bracketed + retvalTypeName + " " + m.name + + "(" + (paramCount ? "" : ");")); + + // print params + + for(k = 0; k < paramCount; k++) + { + p = m.getParam(k); + out.writeln(" "+ + formatBracketForParam(info, i, p) + + (p.isOut ? p.isIn ? "inout " : "out " : "in ") + + formatTypeName(info, i, p, 0) + " " + + PARAM_NAME_PREFIX+k + + (k+1 == paramCount ? ");\n" : ", ")); + } + } + } + + out.writeln("};\n"); + + // comment out nsISupports +// if(iid.equals(nsISupports)) +// out.writeln("\n*/\n"); +} + +function appendForwardDeclarations(list, info) +{ + list.push(info.name); + if(info.parent) + appendForwardDeclarations(list, info.parent); + + var i, k, m, p; + + for(i = 0; i < info.methodCount; i++) + { + m = info.getMethodInfo(i); + + for(k = 0; k < m.paramCount; k++) + { + p = m.getParam(k); + + if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) + { + list.push(info.getInfoForParam(i, p).name); + } + } + } +} + +function doForwardDeclarations(out, iid) +{ + var i, cur, prev; + var list = []; + appendForwardDeclarations(list, new IInfo(iid)); + list.sort(); + + out.writeln("// forward declarations..."); + + for(i = 0; i < list.length; i++) + { + cur = list[i]; + if(cur != prev && cur != "nsISupports") + { + out.writeln("interface " + cur +";"); + prev = cur; + } + } + out.writeln(""); +} + +/*********************************************************/ + +/* Our Componenent ctor */ +function nsInterfaceInfoToIDL() {} + +/* decorate prototype to provide ``class'' methods and property accessors */ +nsInterfaceInfoToIDL.prototype = +{ + // nsIInterfaceInfoToIDL methods... + generateIDL : function (iid) { + var out = new Buffer; + out.writeln(); + out.writeln('#include "nsISupports.idl"'); + out.writeln(); + + doForwardDeclarations(out, iid) + doInterface(out, iid); + + return out.buffer; + }, + + // nsISupports methods... + QueryInterface: function (iid) { + if (!iid.equals(Components.interfaces.nsIInterfaceInfoToIDL) && + !iid.equals(Components.interfaces.nsISupports)) { + throw Components.results.NS_ERROR_NO_INTERFACE; + } + return this; + } +} + +/***************************************************************************/ +/***************************************************************************/ +// parts specific to my use of the the generic module code... + +const MODULE_NAME = "nsInterfaceInfoToIDL"; +const MODULE_CONTRACT_ID = "@mozilla.org/interfaceinfotoidl;1"; +const MODULE_CID = "{47d98974-a1b7-46a6-bc99-8abc374bba3f}"; +const MODULE_CTOR = nsInterfaceInfoToIDL; + +/***************************************************************************/ +/***************************************************************************/ +// generic nsIModule part... + +function NSGetModule(compMgr, fileSpec) { + return new GenericModule(MODULE_NAME, MODULE_CONTRACT_ID, + MODULE_CID, MODULE_CTOR); +} + +function GenericModule (name, contractID, CID, ctor) { + this.name = name; + this.contractID = contractID; + this.CID = Components.ID(CID); + this.ctor = ctor; +} + +GenericModule.prototype = { + /* + * RegisterSelf is called at registration time (component installation + * or the only-until-release startup autoregistration) and is responsible + * for notifying the component manager of all components implemented in + * this module. The fileSpec, location and type parameters are mostly + * opaque, and should be passed on to the registerComponent call + * unmolested. + */ + registerSelf: function (compMgr, fileSpec, location, type) { + compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentManagerObsolete); + compMgr.registerComponentWithType(this.CID, this.name, this.contractID, + fileSpec, location, true, true, type); + }, + + /* + * The GetClassObject method is responsible for producing Factory and + * SingletonFactory objects (the latter are specialized for services). + */ + getClassObject: function (compMgr, cid, iid) { + if (!cid.equals(this.CID)) + throw Components.results.NS_ERROR_NO_INTERFACE; + + if (!iid.equals(Components.interfaces.nsIFactory)) + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + + this.myFactory.ctor = this.ctor; + return this.myFactory; + }, + + /* factory object */ + myFactory: { + + /* + * Construct an instance of the interface specified by iid, possibly + * aggregating it with the provided outer. (If you don't know what + * aggregation is all about, you don't need to. It reduces even the + * mightiest of XPCOM warriors to snivelling cowards.) + */ + createInstance: function (outer, iid) { + if (outer != null) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return (new this.ctor()).QueryInterface(iid); + } + }, + + /* + * The canUnload method signals that the component is about to be unloaded. + * C++ components can return false to indicate that they don't wish to be + * unloaded, but the return value from JS components' canUnload is ignored: + * mark-and-sweep will keep everything around until it's no longer in use, + * making unconditional ``unload'' safe. + * + * You still need to provide a (likely useless) canUnload method, though: + * it's part of the nsIModule interface contract, and the JS loader _will_ + * call it. + */ + canUnload: function(compMgr) { + return true; + } +} + +/***************************************************************************/ diff --git a/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp b/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp index 4deb9b5d8d5..bb4d95dbf71 100644 --- a/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp +++ b/extensions/xmlextras/interfaceinfo/src/nsScriptableInterfaceInfo.cpp @@ -540,8 +540,34 @@ nsScriptableInterfaceInfo::SetInterfaceID(const nsIID * aInterfaceID) mInfo = nsnull; iim->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); - // XXX we want to look at additional managers here if not found! - + // If not found, then let's ask additional managers. + + // This entire block assumes the additional manager support from: + // http://bugzilla.mozilla.org/show_bug.cgi?id=103805 + // Disable it by setting '#if 0'. +#if 0 + PRBool yes; + nsCOMPtr list; + nsCOMPtr iism; + + if(!mInfo && (nsnull != (iism = do_QueryInterface(iim))) && + NS_SUCCEEDED(iism->HasAdditionalManagers(&yes)) && yes && + NS_SUCCEEDED(iism->EnumerateAdditionalManagers(getter_AddRefs(list))) && + list) + { + PRBool more; + nsCOMPtr current; + + while(NS_SUCCEEDED(list->HasMoreElements(&more)) && more && + NS_SUCCEEDED(list->GetNext(getter_AddRefs(current))) && current) + { + current->GetInfoForIID(aInterfaceID, getter_AddRefs(mInfo)); + if(mInfo) + break; + } + } +#endif + return mInfo ? NS_OK : NS_ERROR_NO_INTERFACE; } diff --git a/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js b/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js index f490462fd66..a186fc65022 100644 --- a/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js +++ b/extensions/xmlextras/interfaceinfo/tests/ifaceinfotest.js @@ -1,364 +1,20 @@ -// test the nsIScriptableInterfaceInfo stuff... -// We ought to leverage this in SOAP code. -const IInfo = new Components.Constructor("@mozilla.org/scriptableInterfaceInfo;1", - "nsIScriptableInterfaceInfo", - "init"); +const IDL_GENERATOR = + new Components.Constructor("@mozilla.org/interfaceinfotoidl;1", + "nsIInterfaceInfoToIDL"); -const nsIDataType = Components.interfaces.nsIDataType; -const nsISupports = Components.interfaces.nsISupports; -const PARAM_NAME_PREFIX = "arg"; - -/** -* takes: {xxx} -* returns: uuid(xxx) -*/ -function formatID(str) -{ - return "uuid("+str.substring(1,str.length-1)+")"; -} - -function formatConstType(type) -{ - switch(type) - { - case nsIDataType.VTYPE_INT16: - return "PRInt16"; - case nsIDataType.VTYPE_INT32: - return "PRInt32"; - case nsIDataType.VTYPE_UINT16: - return "PRUint16"; - case nsIDataType.VTYPE_UINT32: - return "PRUint32"; - default: - return "!!!! bad const type !!!"; - } -} - -function formatTypeName(info, methodIndex, param, dimension) -{ - var type = param.type; - - switch(type.dataType) - { - case nsIDataType.VTYPE_INT8 : - return "PRInt8"; - case nsIDataType.VTYPE_INT16: - return "PRInt16"; - case nsIDataType.VTYPE_INT32: - return "PRInt32"; - case nsIDataType.VTYPE_INT64: - return "PRInt64"; - case nsIDataType.VTYPE_UINT8: - return "PRUint8"; - case nsIDataType.VTYPE_UINT16: - return "PRUint16"; - case nsIDataType.VTYPE_UINT32: - return "PRUint32"; - case nsIDataType.VTYPE_UINT64: - return "PRUint64"; - case nsIDataType.VTYPE_FLOAT: - return "float"; - case nsIDataType.VTYPE_DOUBLE: - return "double"; - case nsIDataType.VTYPE_BOOL: - return "PRBool"; - case nsIDataType.VTYPE_CHAR: - return "char"; - case nsIDataType.VTYPE_WCHAR: - return "PRUnichar"; - case nsIDataType.VTYPE_VOID: - if(type.isPointer) - return "voidPtr"; - return "void"; - case nsIDataType.VTYPE_ID: - // order matters here... - if(type.isReference) - return "nsIDRef"; - if(type.isPointer) - return "nsIDPtr"; - return "nsID"; - case nsIDataType.VTYPE_ASTRING: - return "aString"; - case nsIDataType.VTYPE_CHAR_STR: - return "string"; - case nsIDataType.VTYPE_WCHAR_STR: - return "wstring"; - case nsIDataType.VTYPE_INTERFACE: - return info.getInfoForParam(methodIndex, param).name; - case nsIDataType.VTYPE_INTERFACE_IS: - return "nsQIResult"; - case nsIDataType.VTYPE_ARRAY: - return formatTypeName(info, methodIndex, param, dimension+1); - case nsIDataType.VTYPE_STRING_SIZE_IS: - return "string"; - case nsIDataType.VTYPE_WSTRING_SIZE_IS: - return "wstring"; - default: - return "!!!! bad data type !!!"; - } -} - -function formatBracketForParam(info, methodIndex, param) -{ - var type = param.type; - var str = "["; - var found = 0; - var size_is_ArgNum; - var length_is_ArgNum; - - if(param.isRetval) - { - if(found++) - str += ", "; - str += "retval" - } - - if(param.isShared) - { - if(found++) - str += ", "; - str += "shared" - } - - if(type.isArray) - { - if(found++) - str += ", "; - str += "array" - } - - if(type.dataType == nsIDataType.VTYPE_INTERFACE_IS) - { - if(found++) - str += ", "; - str += "iid_is("+ - PARAM_NAME_PREFIX + - info.getInterfaceIsArgNumberForParam(methodIndex, param) + ")"; - } - - if(type.isArray || - type.dataType == nsIDataType.VTYPE_STRING_SIZE_IS || - type.dataType == nsIDataType.VTYPE_WSTRING_SIZE_IS) - { - if(found++) - str += ", "; - - size_is_ArgNum = - info.getSizeIsArgNumberForParam(methodIndex, param, 0); - - str += "size_is("+ PARAM_NAME_PREFIX + size_is_ArgNum + ")"; - - length_is_ArgNum = - info.getLengthIsArgNumberForParam(methodIndex, param, 0); - - if(length_is_ArgNum != size_is_ArgNum) - { - str += ", "; - str += "length_is("+ PARAM_NAME_PREFIX + length_is_ArgNum + ")"; - } - } - - if(!found) - return ""; - str += "] "; - return str -} - -function doInterface(iid) -{ - var i, k, t, m, m2, c, p, readonly, bracketed, paramCount, retvalTypeName; - - var info = new IInfo(iid); - var parent = info.parent; - - var constBaseIndex = parent ? parent.constantCount : 0; - var constTotalCount = info.constantCount; - var constLocalCount = constTotalCount - constBaseIndex; - - var methodBaseIndex = parent ? parent.methodCount : 0; - var methodTotalCount = info.methodCount; - var methodLocalCount = methodTotalCount - methodBaseIndex; - - - // maybe recurring to emit parent declarations is not a good idea... -// if(parent) -// doInterface(parent.interfaceID); - - print(); - - // comment out nsISupports -// if(iid.equals(nsISupports)) -// print("/*\n"); - - print("[" + (info.isScriptable ? "scriptable, " : "") + - formatID(info.interfaceID.number) + "]"); - - print("interface "+ info.name + (parent ? (" : "+parent.name) : "") + " {"); - - if(constLocalCount) - { - for(i = constBaseIndex; i < constTotalCount; i++) - { - c = info.getConstant(i); - print(" const " + formatConstType(c.type.dataType) + " " + - c.name + " = " + c.value + ";"); - } - } - - if(constLocalCount && methodLocalCount) - print(); - - if(methodLocalCount) - { - for(i = methodBaseIndex; i < methodTotalCount; i++) - { - m = info.getMethodInfo(i); - - if(m.isNotXPCOM) - bracketed = "[notxpcom] " - else if(m.isHidden) - bracketed = "[noscript] " - else - bracketed = ""; - - if(m.isGetter) - { - // Is an attribute - - // figure out if this is readonly - m2 = i+1 < methodTotalCount ? info.getMethodInfo(i+1) : null; - readonly = !m2 || m2.name != m.name; - - print(" " + bracketed + (readonly ? "readonly " : "") + - "attribute " + - formatTypeName(info, i, m.getParam(0), 0) + - " " + m.name + ";\n"); - - if(!readonly) - i++; // skip the next one, we have it covered. - - continue; - } - // else... - - paramCount = m.paramCount; - - // 'last' param is used to figure out retvalTypeName - - p = paramCount ? m.getParam(paramCount-1) : null; - - if(m.isNotXPCOM) - retvalTypeName = formatTypeName(info, i, m.result, 0); - else if(p && "[retval] " == formatBracketForParam(info, i, p)) - { - // Check for the exact string above because anything else - // indicates that there either is no expilict retval - // or there are additional braketed attributes (meaning that - // the retval must appear in the param list and not - // preceeding the method name). - retvalTypeName = formatTypeName(info, i, p, 0); - // no need to print it in the param list - paramCount-- ; - } - else - retvalTypeName = "void"; - - // print method name - - print(" " + bracketed + retvalTypeName + " " + m.name + "(" + - (paramCount ? "" : ");")); - - // print params - - for(k = 0; k < paramCount; k++) - { - p = m.getParam(k); - print(" "+ - formatBracketForParam(info, i, p) + - (p.isOut ? p.isIn ? "inout " : "out " : "in ") + - formatTypeName(info, i, p, 0) + " " + - PARAM_NAME_PREFIX+k + - (k+1 == paramCount ? ");\n" : ", ")); - } - } - } - - print("};\n"); - - // comment out nsISupports -// if(iid.equals(nsISupports)) -// print("\n*/\n"); -} - -function appendForwardDeclarations(list, info) -{ - list.push(info.name); - if(info.parent) - appendForwardDeclarations(list, info.parent); - - var i, k, m, p; - - for(i = 0; i < info.methodCount; i++) - { - m = info.getMethodInfo(i); - - for(k = 0; k < m.paramCount; k++) - { - p = m.getParam(k); - - if(p.type.dataType == nsIDataType.VTYPE_INTERFACE) - { - list.push(info.getInfoForParam(i, p).name); - } - } - } -} - -function doForwardDeclarations(iid) -{ - var i, cur, prev; - var list = []; - appendForwardDeclarations(list, new IInfo(iid)); - list.sort(); - - print("// forward declarations..."); - - for(i = 0; i < list.length; i++) - { - cur = list[i]; - if(cur != prev && cur != "nsISupports") - { - print("interface " + cur +";"); - prev = cur; - } - } - print(""); -} - -function info2IDL(iid) -{ - print(); - print('#include "nsISupports.idl"'); - print(); - - doForwardDeclarations(iid) - doInterface(iid); -} - -/***************************************************************************/ -/***************************************************************************/ -// test... +var gen = new IDL_GENERATOR(); print(); print(); -//info2IDL(Components.interfaces.nsISupports); +print(gen.generateIDL(Components.interfaces.nsISupports)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIDataType); +print(gen.generateIDL(Components.interfaces.nsIDataType)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIScriptableInterfaceInfo); +print(gen.generateIDL(Components.interfaces.nsIScriptableInterfaceInfo)); print("//------------------------------------------------------------"); -info2IDL(Components.interfaces.nsIVariant); +print(gen.generateIDL(Components.interfaces.nsIVariant)); print(); print(); +