xref: /aoo42x/main/idlc/source/astdump.cxx (revision cdf0e10c)
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