update dev300-m58
[ooovba.git] / idlc / source / astinterface.cxx
blobe228f0efdfc8afb43f02a640c53ecbd39caef9ed
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: astinterface.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_idlc.hxx"
33 #include <idlc/astinterface.hxx>
34 #include <idlc/astattribute.hxx>
35 #include <idlc/astoperation.hxx>
36 #include "idlc/idlc.hxx"
38 #include "registry/version.h"
39 #include "registry/writer.hxx"
41 using namespace ::rtl;
43 AstInterface::AstInterface(const ::rtl::OString& name,
44 AstInterface const * pInherits,
45 AstScope* pScope)
46 : AstType(NT_interface, name, pScope)
47 , AstScope(NT_interface)
48 , m_mandatoryInterfaces(0)
49 , m_bIsDefined(false)
50 , m_bForwarded(sal_False)
51 , m_bForwardedInSameFile(sal_False)
52 , m_bSingleInheritance(pInherits != 0)
54 if (pInherits != 0) {
55 addInheritedInterface(pInherits, false, rtl::OUString());
59 AstInterface::~AstInterface()
63 AstInterface::DoubleDeclarations AstInterface::checkInheritedInterfaceClashes(
64 AstInterface const * ifc, bool optional) const
66 DoubleDeclarations doubleDecls;
67 std::set< rtl::OString > seen;
68 checkInheritedInterfaceClashes(
69 doubleDecls, seen, ifc, true, optional, optional);
70 return doubleDecls;
73 void AstInterface::addInheritedInterface(
74 AstType const * ifc, bool optional, rtl::OUString const & documentation)
76 m_inheritedInterfaces.push_back(
77 InheritedInterface(ifc, optional, documentation));
78 if (!optional) {
79 ++m_mandatoryInterfaces;
81 AstInterface const * resolved = resolveInterfaceTypedefs(ifc);
82 addVisibleInterface(resolved, true, optional);
83 if (optional) {
84 addOptionalVisibleMembers(resolved);
88 AstInterface::DoubleMemberDeclarations AstInterface::checkMemberClashes(
89 AstDeclaration const * member) const
91 DoubleMemberDeclarations doubleMembers;
92 checkMemberClashes(doubleMembers, member, true);
93 return doubleMembers;
96 void AstInterface::addMember(AstDeclaration /*TODO: const*/ * member) {
97 addDeclaration(member);
98 m_visibleMembers.insert(
99 VisibleMembers::value_type(
100 member->getLocalName(), VisibleMember(member)));
103 void AstInterface::forwardDefined(AstInterface const & def)
105 setImported(def.isImported());
106 setInMainfile(def.isInMainfile());
107 setLineNumber(def.getLineNumber());
108 setFileName(def.getFileName());
109 setDocumentation(def.getDocumentation());
110 m_inheritedInterfaces = def.m_inheritedInterfaces;
111 m_mandatoryInterfaces = def.m_mandatoryInterfaces;
112 m_bIsDefined = true;
115 sal_Bool AstInterface::dump(RegistryKey& rKey)
117 if ( !isDefined() )
118 return sal_True;
120 RegistryKey localKey;
121 if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey))
123 fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n",
124 idlc()->getOptions()->getProgramName().getStr(),
125 getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
126 return sal_False;
129 if (m_mandatoryInterfaces > SAL_MAX_UINT16
130 || m_inheritedInterfaces.size() - m_mandatoryInterfaces
131 > SAL_MAX_UINT16)
133 fprintf(
134 stderr, "%s: interface %s has too many direct base interfaces\n",
135 idlc()->getOptions()->getProgramName().getStr(),
136 getScopedName().getStr());
137 return false;
139 sal_uInt16 nBaseTypes = static_cast< sal_uInt16 >(m_mandatoryInterfaces);
140 sal_uInt16 nAttributes = 0;
141 sal_uInt16 nMethods = 0;
142 sal_uInt16 nReferences = static_cast< sal_uInt16 >(
143 m_inheritedInterfaces.size() - m_mandatoryInterfaces);
144 typereg_Version version
145 = (nBaseTypes <= 1 && nReferences == 0 && !m_bPublished
146 ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1);
147 {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
148 ++i)
150 switch ((*i)->getNodeType()) {
151 case NT_attribute:
153 if (!increment(&nAttributes, "attributes")) {
154 return false;
156 // AstAttribute * attr = static_cast< AstAttribute * >(*i);
157 AstAttribute * attr = (AstAttribute *)(*i);
158 if (attr->isBound()) {
159 version = TYPEREG_VERSION_1;
161 DeclList::size_type getCount = attr->getGetExceptionCount();
162 if (getCount > SAL_MAX_UINT16) {
163 fprintf(
164 stderr,
165 ("%s: raises clause of getter for attribute %s of"
166 " interface %s is too long\n"),
167 idlc()->getOptions()->getProgramName().getStr(),
168 (*i)->getLocalName().getStr(),
169 getScopedName().getStr());
170 return false;
172 if (getCount > 0) {
173 version = TYPEREG_VERSION_1;
174 if (!increment(&nMethods, "attributes")) {
175 return false;
178 DeclList::size_type setCount = attr->getSetExceptionCount();
179 if (setCount > SAL_MAX_UINT16) {
180 fprintf(
181 stderr,
182 ("%s: raises clause of setter for attribute %s of"
183 " interface %s is too long\n"),
184 idlc()->getOptions()->getProgramName().getStr(),
185 (*i)->getLocalName().getStr(),
186 getScopedName().getStr());
187 return false;
189 if (setCount > 0) {
190 version = TYPEREG_VERSION_1;
191 if (!increment(&nMethods, "attributes")) {
192 return false;
195 break;
198 case NT_operation:
199 if (!increment(&nMethods, "methods")) {
200 return false;
202 break;
204 default:
205 OSL_ASSERT(false);
206 break;
210 OUString emptyStr;
211 typereg::Writer aBlob(
212 version, getDocumentation(), emptyStr, RT_TYPE_INTERFACE, m_bPublished,
213 OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), nBaseTypes,
214 nAttributes, nMethods, nReferences);
216 sal_uInt16 superTypeIndex = 0;
217 sal_uInt16 referenceIndex = 0;
218 {for (InheritedInterfaces::iterator i = m_inheritedInterfaces.begin();
219 i != m_inheritedInterfaces.end(); ++i)
221 if (i->isOptional()) {
222 aBlob.setReferenceData(
223 referenceIndex++, i->getDocumentation(), RT_REF_SUPPORTS,
224 RT_ACCESS_OPTIONAL,
225 OStringToOUString(
226 i->getInterface()->getRelativName(),
227 RTL_TEXTENCODING_UTF8));
228 } else {
229 aBlob.setSuperTypeName(
230 superTypeIndex++,
231 OStringToOUString(
232 i->getInterface()->getRelativName(),
233 RTL_TEXTENCODING_UTF8));
237 sal_uInt16 attributeIndex = 0;
238 sal_uInt16 methodIndex = 0;
239 {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd();
240 ++i)
242 switch ((*i)->getNodeType()) {
243 case NT_attribute:
244 // static_cast< AstAttribute * >(*i)->dumpBlob(
246 ((AstAttribute *)(*i))->dumpBlob(
247 aBlob, attributeIndex++, &methodIndex);
248 break;
250 case NT_operation:
251 // static_cast< AstOperation * >(*i)->dumpBlob(aBlob, methodIndex++);
252 ((AstOperation *)(*i))->dumpBlob(aBlob, methodIndex++);
253 break;
255 default:
256 OSL_ASSERT(false);
257 break;
261 sal_uInt32 aBlobSize;
262 void const * pBlob = aBlob.getBlob(&aBlobSize);
264 if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize))
266 fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n",
267 idlc()->getOptions()->getProgramName().getStr(),
268 getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr());
269 return sal_False;
272 return true;
275 void AstInterface::checkInheritedInterfaceClashes(
276 DoubleDeclarations & doubleDeclarations,
277 std::set< rtl::OString > & seenInterfaces, AstInterface const * ifc,
278 bool direct, bool optional, bool mainOptional) const
280 if (direct || optional
281 || seenInterfaces.insert(ifc->getScopedName()).second)
283 VisibleInterfaces::const_iterator visible(
284 m_visibleInterfaces.find(ifc->getScopedName()));
285 if (visible != m_visibleInterfaces.end()) {
286 switch (visible->second) {
287 case INTERFACE_INDIRECT_OPTIONAL:
288 if (direct && optional) {
289 doubleDeclarations.interfaces.push_back(ifc);
290 return;
292 break;
294 case INTERFACE_DIRECT_OPTIONAL:
295 if (direct || !mainOptional) {
296 doubleDeclarations.interfaces.push_back(ifc);
298 return;
300 case INTERFACE_INDIRECT_MANDATORY:
301 if (direct) {
302 doubleDeclarations.interfaces.push_back(ifc);
304 return;
306 case INTERFACE_DIRECT_MANDATORY:
307 if (direct || (!optional && !mainOptional)) {
308 doubleDeclarations.interfaces.push_back(ifc);
310 return;
313 if (direct || !optional) {
314 {for (DeclList::const_iterator i(ifc->getIteratorBegin());
315 i != ifc->getIteratorEnd(); ++i)
317 checkMemberClashes(
318 doubleDeclarations.members, *i, !mainOptional);
320 {for (InheritedInterfaces::const_iterator i(
321 ifc->m_inheritedInterfaces.begin());
322 i != ifc->m_inheritedInterfaces.end(); ++i)
324 checkInheritedInterfaceClashes(
325 doubleDeclarations, seenInterfaces, i->getResolved(),
326 false, i->isOptional(), mainOptional);
332 void AstInterface::checkMemberClashes(
333 DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member,
334 bool checkOptional) const
336 VisibleMembers::const_iterator i(
337 m_visibleMembers.find(member->getLocalName()));
338 if (i != m_visibleMembers.end()) {
339 if (i->second.mandatory != 0) {
340 if (i->second.mandatory->getScopedName() != member->getScopedName())
342 DoubleMemberDeclaration d;
343 d.first = i->second.mandatory;
344 d.second = member;
345 doubleMembers.push_back(d);
347 } else if (checkOptional) {
348 for (VisibleMember::Optionals::const_iterator j(
349 i->second.optionals.begin());
350 j != i->second.optionals.end(); ++j)
352 if (j->second->getScopedName() != member->getScopedName()) {
353 DoubleMemberDeclaration d;
354 d.first = j->second;
355 d.second = member;
356 doubleMembers.push_back(d);
363 void AstInterface::addVisibleInterface(
364 AstInterface const * ifc, bool direct, bool optional)
366 InterfaceKind kind = optional
367 ? direct ? INTERFACE_DIRECT_OPTIONAL : INTERFACE_INDIRECT_OPTIONAL
368 : direct ? INTERFACE_DIRECT_MANDATORY : INTERFACE_INDIRECT_MANDATORY;
369 std::pair< VisibleInterfaces::iterator, bool > result(
370 m_visibleInterfaces.insert(
371 VisibleInterfaces::value_type(ifc->getScopedName(), kind)));
372 bool seen = !result.second
373 && result.first->second >= INTERFACE_INDIRECT_MANDATORY;
374 if (!result.second && kind > result.first->second) {
375 result.first->second = kind;
377 if (!optional && !seen) {
378 {for (DeclList::const_iterator i(ifc->getIteratorBegin());
379 i != ifc->getIteratorEnd(); ++i)
381 m_visibleMembers.insert(
382 VisibleMembers::value_type(
383 (*i)->getLocalName(), VisibleMember(*i)));
385 {for (InheritedInterfaces::const_iterator i(
386 ifc->m_inheritedInterfaces.begin());
387 i != ifc->m_inheritedInterfaces.end(); ++i)
389 addVisibleInterface(i->getResolved(), false, i->isOptional());
394 void AstInterface::addOptionalVisibleMembers(AstInterface const * ifc) {
395 {for (DeclList::const_iterator i(ifc->getIteratorBegin());
396 i != ifc->getIteratorEnd(); ++i)
398 VisibleMembers::iterator visible(
399 m_visibleMembers.find((*i)->getLocalName()));
400 if (visible == m_visibleMembers.end()) {
401 visible = m_visibleMembers.insert(
402 VisibleMembers::value_type(
403 (*i)->getLocalName(), VisibleMember())).first;
405 if (visible->second.mandatory == 0) {
406 visible->second.optionals.insert(
407 VisibleMember::Optionals::value_type(ifc->getScopedName(), *i));
410 {for (InheritedInterfaces::const_iterator i(
411 ifc->m_inheritedInterfaces.begin());
412 i != ifc->m_inheritedInterfaces.end(); ++i)
414 if (!i->isOptional()) {
415 addOptionalVisibleMembers(i->getResolved());
420 bool AstInterface::increment(sal_uInt16 * counter, char const * sort) const {
421 if (*counter == SAL_MAX_UINT16) {
422 fprintf(
423 stderr, "%s: interface %s has too many direct %s\n",
424 idlc()->getOptions()->getProgramName().getStr(),
425 getScopedName().getStr(), sort);
426 return false;
428 ++*counter;
429 return true;