Closed Bug 13424 Opened 25 years ago Closed 15 years ago

xpidl could use component declarations in idl

Categories

(Core :: XPCOM, defect, P5)

defect

Tracking

()

RESOLVED WONTFIX
Future

People

(Reporter: jband_mozilla, Assigned: dbradley)

References

Details

from... news://news.mozilla.org/37A13C72.7F1D8CC7%40netscape.com I think that xpcom needs something like what MS calls a 'coclass'. This is a way to declare information about components - what interfaces they expose, their CLSID, and progid, etc. Ideally this is expressed in idl. We were thinking of punting on this, but it is a pretty important thing to have. Brendan has offered to look at implementing this. I am writing to express my thoughts as a baseline for discussion of a spec to be worked out (in code if nowhere else :). We need component declarations for a number of reasons... 1) There are many existing components that do (and must) expose multiple interfaces. Knowledge about which interfaces these components expose is implicit rather than explicit. 2) XPConnect wants to use information about the set of interfaces exposed by particular classes of components in order to 'flatten' those interfaces. This means that from JavaScript any method of any of the interfaces on the object could be called without having to QI the object to one particular interface. This is a big simplification for JS programmers. It is also a requirement for eventually moving the DOM to use xpconnect. 3) We don't have generic places to declare progids and clsids. Now we'd have a standard way. 4) We want to implement components in languages other than C++. This is going to require extensions to the component manager apis to have plugable component loaders for different 'types' of components; e.g. JavaScript components loaded from .js files, or Java components loaded from .jar files, or whatever. Each type will require some sort of mechanism for doing the equivalent of 'NSRegisterSelf'. We could use a generic declarative representation of a component's registration data (expressed in idl) and then format that data into the appropriate form to pass on to the component manager. We can use this for C++ components too! For C++ components this might be compilable C++ code to be #included into the body of the NSRegisterSelf function. For other components this might be a series of xpconnected (interpreted) calls to the component manager. 5) Our 'interface' declaration in our .idl files is the place to describe *and* document interfaces. However, it is bad form to assume that all interfaces are implemented by one and only one component. Thus, we need a place to describe and document component implementations. This is the place. I propose that we use the keyword 'component' in our .idl files to use in place of what MS calls 'coclass'. What I propose is somewhat different from the MS scheme. It would look like: /** * ...JavaDoc style documentation here... */ [ uuid(xxx-xxx...), progid(some.prog.id), impersonates(some.other.prog.id), type(aplication/x-xpjs), location(@location) ] component { interface nsIFoo; interface nsIBar; }; Details: - 'uuid' is the clsid for this particular implementation of the component. It is required for this all to have meaning. - 'progid' is the progid to be associated with that cid. It is optional but highly recommended. It is 'any' string. - 'impersonates' is an idea I'm kicking around. It is to be used if in the future the component manager supports the idea that a component can register that it impersonates some other component. This way component 'A' could claim to impersonate component 'B'. So any calls to create a 'B' object would get routed to the 'A' factory. We might want a way to do more than one of these? Obviously this is optional. - 'type' is a way to declare the 'loader' type of the component. This ought to look like a mime type. This will tell the component manager which kind of loader to use in order to load the factory to make this component. Optional - default to whatever type string we use to mean "native code in a dll" - 'location' is the string passed to the loader to tell it where to find this component. This is the equivalent of the 'path' param passed to NSRegisterSelf. The a given loader this might mean a filename, a name in a given jar, a database id where the code lives, whatever. It is loader specific. NOTE that there is no identifier after the keyword 'component'. If we always had simple identifiers for progids this would be the place to put it. But we do not. The keyword 'interface' is used before each interface mentioned. This might seem unnecessary, But, though we only support listing interfaces in the body of the declaration now, we may want to put other stuff there in the future. We also might want to have attributes on these lines; e.g. [default] interface nsIFoo; At this point I don't think that there are any attributes we need (like default) for these lines, but something might come up. For the component attribute strings (e.g. 'type' or 'location') we might want to have some way to identify if they are to be quoted or not in the final output. Perhaps requiring that they be explicitly quoted in the input is enough. I bring this up because sometimes we have an exact string to use in the idl file and sometimes we only want to pass through some identifier to be used in the generated code. e.g... [... location(myClass)...] might be used to reference a particular named classfile in a known jar and emit code like: cm.RegisterComponent(..., "myclass",...); OR we might want it to be an identifier that is assumed to be defined in the #including code: [... location(aPath)...] emits into "mycomponent.inc": rv = cm->RegisterComponent(..., aPath,...); and is used like: NSRegisterSelf(...,const char* aPath) { ... #include "mycomponent.inc" ... } We have not generally been quoting strings in attributes, so location("myClass") might be an atypical way to produce the more typical output for the first case. We might quote the output by default and require some symbol to mean 'don't quote'; e.g. location(#aPath) or location(%aPath) or something. I don't know. I just wanted to bring it up. The list of interface names keyed to the CLSID in the declaration is not something that would currently go via the component manager into the registry. I expect that we will either: create a new service that handles moving these lists into and out of the registry, or extend the component manager to do this for us. The component manager is already going to be owning the branch of the registry where 'per CLSID' information is stored. Either way we'll expose an api into C++ and JS to which we can use xpidl to generate code to store these lists. And.. I expect that rather than store the interface names in the registry, we'll use the nsInterfaceInfoManager at that time to resolve the interface names into IIDs. We'll work this out I'm imagining that we'll have at least two output 'formats': 1) blocks of C++ component manager calls and 2) blocks of JS component manager calls. We might want some other format(s). It might be tempting to determine the format based on the content of the input files, but I think that this is counter to how we do other file generation from xpidl. Even though these component declarations are specific to a specific implementation, I still think it is fine to generate each type into its own output file to be used or ignored by other code. Running xpidl is pretty cheap. I've been assuming that the output gets merged into the registry via the component manager one way or another. A reasonable question is: "why not put this in typelibs like the interface stuff?". We've discussed this a bit and the consensus so far is that this is all implementation specific stuff that generally belongs in the component manager's branch of the registry is not really generic interface information at all. That's all I can think of. There is a lot to be worked out - and some is based on component manager methods (and their reflection into JS) that are not yet written.
Status: NEW → ASSIGNED
Target Milestone: M14
Assignee: brendan → mccabe
Status: ASSIGNED → NEW
Status: NEW → ASSIGNED
Marking as assigned. Working on it currently.
Blocks: 12915
Pushing to m16. I don't think I'm going to get this in for beta.
Target Milestone: M14 → M16
OS: Windows NT → All
Hardware: PC → All
M16 has been out for a while now, these bugs target milestones need to be updated.
[SPAM] Marking milestone 'future' as part of nsbeta3 triage.
Target Milestone: M16 → Future
Mass-reassigning mccabe's non-JS, non-Rhino bugs to jband (34 total). Would like to cc mccabe; but the mass-reassign page does not allow this. I'll leave it up to mccabe to decide if he wants to be cc'ed on these -
Assignee: mike+mozilla → jband
Status: ASSIGNED → NEW
mass reassign of xpidl bugs to dbradley@netscape.com
Assignee: jband → dbradley
Status: NEW → ASSIGNED
Priority: P3 → P5
Component: xpidl → XPCOM
QA Contact: mike+mozilla → xpcom
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.