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