xref: /trunk/main/idlc/source/astdump.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_idlc.hxx"
30 #include <idlc/astmodule.hxx>
31 #include <idlc/asttypedef.hxx>
32 #include <idlc/astservice.hxx>
33 #include <idlc/astconstant.hxx>
34 #include <idlc/astattribute.hxx>
35 #include <idlc/astinterfacemember.hxx>
36 #ifndef _IDLC_ASTSERVICEEMEMBER_HXX_
37 #include <idlc/astservicemember.hxx>
38 #endif
39 #include <idlc/astobserves.hxx>
40 #include <idlc/astneeds.hxx>
41 #include <idlc/astsequence.hxx>
42 #include "idlc/astoperation.hxx"
43 
44 #include "registry/version.h"
45 #include "registry/writer.hxx"
46 
47 using namespace ::rtl;
48 
49 sal_Bool AstModule::dump(RegistryKey& rKey)
50 {
51     OUString emptyStr;
52     RegistryKey localKey;
53     if ( getNodeType() == NT_root )
54     {
55         localKey = rKey;
56     }else
57     {
58         if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
59         {
60             fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
61                     idlc()->getOptions()->getProgramName().getStr(),
62                     getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
63             return sal_False;
64         }
65     }
66 
67     sal_uInt16          nConst = getNodeCount(NT_const);
68 
69     if ( nConst > 0 )
70     {
71         RTTypeClass typeClass = RT_TYPE_MODULE;
72         if ( getNodeType() == NT_constants )
73             typeClass = RT_TYPE_CONSTANTS;
74 
75         typereg::Writer aBlob(
76             m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
77             getDocumentation(), emptyStr, typeClass,
78             m_bPublished,
79             OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0,
80             nConst, 0, 0);
81 
82         DeclList::const_iterator iter = getIteratorBegin();
83         DeclList::const_iterator end = getIteratorEnd();
84         AstDeclaration* pDecl = NULL;
85         sal_uInt16 index = 0;
86         while ( iter != end )
87         {
88             pDecl = *iter;
89             if ( pDecl->getNodeType() == NT_const &&
90                  pDecl->isInMainfile() )
91             {
92                 ((AstConstant*)pDecl)->dumpBlob(
93                     aBlob, index++,
94                     getNodeType() == NT_module && pDecl->isPublished());
95             }
96             ++iter;
97         }
98 
99         sal_uInt32 aBlobSize;
100         void const * pBlob = aBlob.getBlob(&aBlobSize);
101 
102         if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY,
103                               (RegValue)pBlob, aBlobSize))
104         {
105             fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
106                     idlc()->getOptions()->getProgramName().getStr(),
107                     getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
108             return sal_False;
109         }
110     } else
111     {
112         RTTypeClass typeClass = RT_TYPE_MODULE;
113         if ( getNodeType() == NT_constants )
114             typeClass = RT_TYPE_CONSTANTS;
115 
116         typereg::Writer aBlob(
117             m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
118             getDocumentation(), emptyStr, typeClass, m_bPublished,
119             OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, 0, 0,
120             0);
121 
122         sal_uInt32 aBlobSize;
123         void const * pBlob = aBlob.getBlob(&aBlobSize);
124 
125         if ( getNodeType() != NT_root )
126         {
127             if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY,
128                                   (RegValue)pBlob, aBlobSize))
129             {
130                 fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
131                         idlc()->getOptions()->getProgramName().getStr(),
132                         getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
133                 return sal_False;
134             }
135         }
136     }
137     if ( getNodeType() == NT_root )
138     {
139         localKey.releaseKey();
140     }
141     return AstDeclaration::dump(rKey);
142 }
143 
144 sal_Bool AstTypeDef::dump(RegistryKey& rKey)
145 {
146     OUString emptyStr;
147     RegistryKey localKey;
148     if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
149     {
150         fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
151                 idlc()->getOptions()->getProgramName().getStr(),
152                 getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
153         return sal_False;
154     }
155 
156     typereg::Writer aBlob(
157         m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0,
158         getDocumentation(), emptyStr, RT_TYPE_TYPEDEF, m_bPublished,
159         OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1, 0, 0, 0);
160     aBlob.setSuperTypeName(
161         0,
162         OStringToOUString(
163             getBaseType()->getRelativName(), RTL_TEXTENCODING_UTF8));
164 
165     sal_uInt32 aBlobSize;
166     void const * pBlob = aBlob.getBlob(&aBlobSize);
167 
168     if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize))
169     {
170         fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
171                 idlc()->getOptions()->getProgramName().getStr(),
172                 getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
173         return sal_False;
174     }
175 
176     return sal_True;
177 }
178 
179 sal_Bool AstService::dump(RegistryKey& rKey)
180 {
181     OUString emptyStr;
182     typereg_Version version = m_bPublished
183         ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0;
184     OString superName;
185     sal_uInt16 constructors = 0;
186     sal_uInt16 properties = 0;
187     sal_uInt16 references = 0;
188     {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
189           ++i)
190     {
191         switch ((*i)->getNodeType()) {
192         case NT_interface:
193         case NT_typedef:
194             version = TYPEREG_VERSION_1;
195             OSL_ASSERT(superName.getLength() == 0);
196             superName = (*i)->getRelativName();
197             break;
198 
199         case NT_operation:
200             OSL_ASSERT(getNodeType() == NT_service);
201             ++constructors;
202             break;
203 
204         case NT_property:
205             OSL_ASSERT(getNodeType() == NT_service);
206             ++properties;
207             break;
208 
209         case NT_service_member:
210             if (getNodeType() == NT_singleton) {
211                 OSL_ASSERT(superName.getLength() == 0);
212                 superName = ((AstServiceMember *)(*i))->
213                     getRealService()->getRelativName();
214                 break;
215             }
216         case NT_interface_member:
217         case NT_observes:
218         case NT_needs:
219             OSL_ASSERT(getNodeType() == NT_service);
220             ++references;
221             break;
222 
223         default:
224             OSL_ASSERT(false);
225             break;
226         }
227     }}
228     OSL_ASSERT(constructors == 0 || !m_defaultConstructor);
229     if (m_defaultConstructor) {
230         constructors = 1;
231     }
232     RegistryKey localKey;
233     if (rKey.createKey(
234             rtl::OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8),
235             localKey)) {
236         fprintf(
237             stderr, "%s: warning, could not create key '%s' in '%s'\n",
238             idlc()->getOptions()->getProgramName().getStr(),
239             getFullName().getStr(),
240             rtl::OUStringToOString(
241                 rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
242         return false;
243     }
244     typereg::Writer writer(
245         version, getDocumentation(), emptyStr,
246         getNodeType() == NT_singleton ? RT_TYPE_SINGLETON : RT_TYPE_SERVICE,
247         m_bPublished,
248         rtl::OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8),
249         superName.getLength() == 0 ? 0 : 1, properties, constructors,
250         references);
251     if (superName.getLength() != 0) {
252         writer.setSuperTypeName(
253             0, rtl::OStringToOUString(superName, RTL_TEXTENCODING_UTF8));
254     }
255     sal_uInt16 constructorIndex = 0;
256     sal_uInt16 propertyIndex = 0;
257     sal_uInt16 referenceIndex = 0;
258     {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
259           ++i)
260     {
261         switch ((*i)->getNodeType()) {
262         case NT_operation:
263 //           static_cast< AstOperation * >(*i)->dumpBlob(
264             ((AstOperation *)(*i))->dumpBlob(
265                 writer, constructorIndex++);
266             break;
267 
268         case NT_property:
269 //            static_cast< AstAttribute * >(*i)->dumpBlob(
270             ((AstAttribute *)(*i))->dumpBlob(
271                 writer, propertyIndex++, 0);
272             break;
273 
274         case NT_interface_member:
275             {
276 //               AstInterfaceMember * decl = static_cast< AstInterfaceMember *>(*i);
277                 AstInterfaceMember * decl = (AstInterfaceMember *)(*i);
278                 writer.setReferenceData(
279                     referenceIndex++, decl->getDocumentation(), RT_REF_SUPPORTS,
280                     (decl->isOptional()
281                      ? RT_ACCESS_OPTIONAL : RT_ACCESS_INVALID),
282                     rtl::OStringToOUString(
283                         decl->getRealInterface()->getRelativName(),
284                         RTL_TEXTENCODING_UTF8));
285                 break;
286             }
287 
288         case NT_service_member:
289             if (getNodeType() == NT_service) {
290 //              AstServiceMember * decl = static_cast< AstServiceMember * >(*i);
291                 AstServiceMember * decl = (AstServiceMember *)(*i);
292                 writer.setReferenceData(
293                     referenceIndex++, decl->getDocumentation(), RT_REF_EXPORTS,
294                     (decl->isOptional()
295                      ? RT_ACCESS_OPTIONAL : RT_ACCESS_INVALID),
296                     rtl::OStringToOUString(
297                         decl->getRealService()->getRelativName(),
298                         RTL_TEXTENCODING_UTF8));
299             }
300             break;
301 
302         case NT_observes:
303             {
304 //              AstObserves * decl = static_cast< AstObserves * >(*i);
305                 AstObserves * decl = (AstObserves *)(*i);
306                 writer.setReferenceData(
307                     referenceIndex++, decl->getDocumentation(), RT_REF_OBSERVES,
308                     RT_ACCESS_INVALID,
309                     rtl::OStringToOUString(
310                         decl->getRealInterface()->getRelativName(),
311                         RTL_TEXTENCODING_UTF8));
312                 break;
313             }
314 
315         case NT_needs:
316             {
317 //              AstNeeds * decl = static_cast< AstNeeds * >(*i);
318                 AstNeeds * decl = (AstNeeds *)(*i);
319                 writer.setReferenceData(
320                     referenceIndex++, decl->getDocumentation(), RT_REF_NEEDS,
321                     RT_ACCESS_INVALID,
322                     rtl::OStringToOUString(
323                         decl->getRealService()->getRelativName(),
324                         RTL_TEXTENCODING_UTF8));
325                 break;
326             }
327 
328         default:
329             OSL_ASSERT(
330                 (*i)->getNodeType() == NT_interface
331                 || (*i)->getNodeType() == NT_typedef);
332             break;
333         }
334     }}
335     if (m_defaultConstructor) {
336         writer.setMethodData(
337             constructorIndex++, emptyStr, RT_MODE_TWOWAY,
338             emptyStr, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")),
339             0, 0);
340     }
341     sal_uInt32 size;
342     void const * blob = writer.getBlob(&size);
343     if (localKey.setValue(
344             emptyStr, RG_VALUETYPE_BINARY, const_cast< void * >(blob),
345             size))
346     {
347         fprintf(
348             stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
349             idlc()->getOptions()->getProgramName().getStr(),
350             getFullName().getStr(),
351             rtl::OUStringToOString(
352                 localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
353         return false;
354     }
355     return true;
356 }
357 
358 sal_Bool AstAttribute::dumpBlob(
359     typereg::Writer & rBlob, sal_uInt16 index, sal_uInt16 * methodIndex)
360 {
361     RTFieldAccess accessMode = RT_ACCESS_INVALID;
362 
363     if (isReadonly())
364     {
365         accessMode |= RT_ACCESS_READONLY;
366     } else
367     {
368         accessMode |= RT_ACCESS_READWRITE;
369     }
370     if (isOptional())
371     {
372         accessMode |= RT_ACCESS_OPTIONAL;
373     }
374     if (isBound())
375     {
376         accessMode |= RT_ACCESS_BOUND;
377     }
378     if (isMayBeVoid())
379     {
380         accessMode |= RT_ACCESS_MAYBEVOID;
381     }
382     if (isConstrained())
383     {
384         accessMode |= RT_ACCESS_CONSTRAINED;
385     }
386     if (isTransient())
387     {
388         accessMode |= RT_ACCESS_TRANSIENT;
389     }
390     if (isMayBeAmbiguous())
391     {
392         accessMode |= RT_ACCESS_MAYBEAMBIGUOUS;
393     }
394     if (isMayBeDefault())
395     {
396         accessMode |= RT_ACCESS_MAYBEDEFAULT;
397     }
398     if (isRemoveable())
399     {
400         accessMode |= RT_ACCESS_REMOVEABLE;
401     }
402 
403     OUString name(OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8));
404     rBlob.setFieldData(
405         index, getDocumentation(), OUString(), accessMode, name,
406         OStringToOUString(getType()->getRelativName(), RTL_TEXTENCODING_UTF8),
407         RTConstValue());
408     dumpExceptions(
409         rBlob, m_getDocumentation, m_getExceptions, RT_MODE_ATTRIBUTE_GET,
410         methodIndex);
411     dumpExceptions(
412         rBlob, m_setDocumentation, m_setExceptions, RT_MODE_ATTRIBUTE_SET,
413         methodIndex);
414 
415     return sal_True;
416 }
417 
418 void AstAttribute::dumpExceptions(
419     typereg::Writer & writer, rtl::OUString const & documentation,
420     DeclList const & exceptions, RTMethodMode flags, sal_uInt16 * methodIndex)
421 {
422     if (!exceptions.empty()) {
423         OSL_ASSERT(methodIndex != 0);
424         sal_uInt16 idx = (*methodIndex)++;
425         // exceptions.size() <= SAL_MAX_UINT16 already checked in
426         // AstInterface::dump:
427         writer.setMethodData(
428             idx, documentation, flags,
429             OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8),
430             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), 0,
431             static_cast< sal_uInt16 >(exceptions.size()));
432         sal_uInt16 exceptionIndex = 0;
433         for (DeclList::const_iterator i(exceptions.begin());
434              i != exceptions.end(); ++i)
435         {
436             writer.setMethodExceptionTypeName(
437                 idx, exceptionIndex++,
438                 rtl::OStringToOUString(
439                     (*i)->getRelativName(), RTL_TEXTENCODING_UTF8));
440         }
441     }
442 }
443 
444 const sal_Char* AstSequence::getRelativName() const
445 {
446     if ( !m_pRelativName )
447     {
448         m_pRelativName = new OString("[]");
449         AstDeclaration const * pType = resolveTypedefs( m_pMemberType );
450         *m_pRelativName += pType->getRelativName();
451     }
452 
453     return m_pRelativName->getStr();
454 }
455