1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: astinterface.cxx,v $
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
,
46 : AstType(NT_interface
, name
, pScope
)
47 , AstScope(NT_interface
)
48 , m_mandatoryInterfaces(0)
50 , m_bForwarded(sal_False
)
51 , m_bForwardedInSameFile(sal_False
)
52 , m_bSingleInheritance(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
);
73 void AstInterface::addInheritedInterface(
74 AstType
const * ifc
, bool optional
, rtl::OUString
const & documentation
)
76 m_inheritedInterfaces
.push_back(
77 InheritedInterface(ifc
, optional
, documentation
));
79 ++m_mandatoryInterfaces
;
81 AstInterface
const * resolved
= resolveInterfaceTypedefs(ifc
);
82 addVisibleInterface(resolved
, true, optional
);
84 addOptionalVisibleMembers(resolved
);
88 AstInterface::DoubleMemberDeclarations
AstInterface::checkMemberClashes(
89 AstDeclaration
const * member
) const
91 DoubleMemberDeclarations doubleMembers
;
92 checkMemberClashes(doubleMembers
, member
, true);
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
;
115 sal_Bool
AstInterface::dump(RegistryKey
& rKey
)
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());
129 if (m_mandatoryInterfaces
> SAL_MAX_UINT16
130 || m_inheritedInterfaces
.size() - m_mandatoryInterfaces
134 stderr
, "%s: interface %s has too many direct base interfaces\n",
135 idlc()->getOptions()->getProgramName().getStr(),
136 getScopedName().getStr());
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();
150 switch ((*i
)->getNodeType()) {
153 if (!increment(&nAttributes
, "attributes")) {
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
) {
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());
173 version
= TYPEREG_VERSION_1
;
174 if (!increment(&nMethods
, "attributes")) {
178 DeclList::size_type setCount
= attr
->getSetExceptionCount();
179 if (setCount
> SAL_MAX_UINT16
) {
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());
190 version
= TYPEREG_VERSION_1
;
191 if (!increment(&nMethods
, "attributes")) {
199 if (!increment(&nMethods
, "methods")) {
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
,
226 i
->getInterface()->getRelativName(),
227 RTL_TEXTENCODING_UTF8
));
229 aBlob
.setSuperTypeName(
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();
242 switch ((*i
)->getNodeType()) {
244 // static_cast< AstAttribute * >(*i)->dumpBlob(
246 ((AstAttribute
*)(*i
))->dumpBlob(
247 aBlob
, attributeIndex
++, &methodIndex
);
251 // static_cast< AstOperation * >(*i)->dumpBlob(aBlob, methodIndex++);
252 ((AstOperation
*)(*i
))->dumpBlob(aBlob
, methodIndex
++);
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());
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
);
294 case INTERFACE_DIRECT_OPTIONAL
:
295 if (direct
|| !mainOptional
) {
296 doubleDeclarations
.interfaces
.push_back(ifc
);
300 case INTERFACE_INDIRECT_MANDATORY
:
302 doubleDeclarations
.interfaces
.push_back(ifc
);
306 case INTERFACE_DIRECT_MANDATORY
:
307 if (direct
|| (!optional
&& !mainOptional
)) {
308 doubleDeclarations
.interfaces
.push_back(ifc
);
313 if (direct
|| !optional
) {
314 {for (DeclList::const_iterator
i(ifc
->getIteratorBegin());
315 i
!= ifc
->getIteratorEnd(); ++i
)
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
;
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
;
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
) {
423 stderr
, "%s: interface %s has too many direct %s\n",
424 idlc()->getOptions()->getProgramName().getStr(),
425 getScopedName().getStr(), sort
);