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/astinterface.hxx> 27 #include <idlc/astattribute.hxx> 28 #include <idlc/astoperation.hxx> 29 #include "idlc/idlc.hxx" 30 31 #include "registry/version.h" 32 #include "registry/writer.hxx" 33 34 using namespace ::rtl; 35 36 AstInterface::AstInterface(const ::rtl::OString& name, 37 AstInterface const * pInherits, 38 AstScope* pScope) 39 : AstType(NT_interface, name, pScope) 40 , AstScope(NT_interface) 41 , m_mandatoryInterfaces(0) 42 , m_bIsDefined(false) 43 , m_bForwarded(sal_False) 44 , m_bForwardedInSameFile(sal_False) 45 , m_bSingleInheritance(pInherits != 0) 46 { 47 if (pInherits != 0) { 48 addInheritedInterface(pInherits, false, rtl::OUString()); 49 } 50 } 51 52 AstInterface::~AstInterface() 53 { 54 } 55 56 AstInterface::DoubleDeclarations AstInterface::checkInheritedInterfaceClashes( 57 AstInterface const * ifc, bool optional) const 58 { 59 DoubleDeclarations doubleDecls; 60 std::set< rtl::OString > seen; 61 checkInheritedInterfaceClashes( 62 doubleDecls, seen, ifc, true, optional, optional); 63 return doubleDecls; 64 } 65 66 void AstInterface::addInheritedInterface( 67 AstType const * ifc, bool optional, rtl::OUString const & documentation) 68 { 69 m_inheritedInterfaces.push_back( 70 InheritedInterface(ifc, optional, documentation)); 71 if (!optional) { 72 ++m_mandatoryInterfaces; 73 } 74 AstInterface const * resolved = resolveInterfaceTypedefs(ifc); 75 addVisibleInterface(resolved, true, optional); 76 if (optional) { 77 addOptionalVisibleMembers(resolved); 78 } 79 } 80 81 AstInterface::DoubleMemberDeclarations AstInterface::checkMemberClashes( 82 AstDeclaration const * member) const 83 { 84 DoubleMemberDeclarations doubleMembers; 85 checkMemberClashes(doubleMembers, member, true); 86 return doubleMembers; 87 } 88 89 void AstInterface::addMember(AstDeclaration /*TODO: const*/ * member) { 90 addDeclaration(member); 91 m_visibleMembers.insert( 92 VisibleMembers::value_type( 93 member->getLocalName(), VisibleMember(member))); 94 } 95 96 void AstInterface::forwardDefined(AstInterface const & def) 97 { 98 setImported(def.isImported()); 99 setInMainfile(def.isInMainfile()); 100 setLineNumber(def.getLineNumber()); 101 setFileName(def.getFileName()); 102 setDocumentation(def.getDocumentation()); 103 m_inheritedInterfaces = def.m_inheritedInterfaces; 104 m_mandatoryInterfaces = def.m_mandatoryInterfaces; 105 m_bIsDefined = true; 106 } 107 108 sal_Bool AstInterface::dump(RegistryKey& rKey) 109 { 110 if ( !isDefined() ) 111 return sal_True; 112 113 RegistryKey localKey; 114 if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) 115 { 116 fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", 117 idlc()->getOptions()->getProgramName().getStr(), 118 getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 119 return sal_False; 120 } 121 122 if (m_mandatoryInterfaces > SAL_MAX_UINT16 123 || m_inheritedInterfaces.size() - m_mandatoryInterfaces 124 > SAL_MAX_UINT16) 125 { 126 fprintf( 127 stderr, "%s: interface %s has too many direct base interfaces\n", 128 idlc()->getOptions()->getProgramName().getStr(), 129 getScopedName().getStr()); 130 return false; 131 } 132 sal_uInt16 nBaseTypes = static_cast< sal_uInt16 >(m_mandatoryInterfaces); 133 sal_uInt16 nAttributes = 0; 134 sal_uInt16 nMethods = 0; 135 sal_uInt16 nReferences = static_cast< sal_uInt16 >( 136 m_inheritedInterfaces.size() - m_mandatoryInterfaces); 137 typereg_Version version 138 = (nBaseTypes <= 1 && nReferences == 0 && !m_bPublished 139 ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1); 140 {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); 141 ++i) 142 { 143 switch ((*i)->getNodeType()) { 144 case NT_attribute: 145 { 146 if (!increment(&nAttributes, "attributes")) { 147 return false; 148 } 149 // AstAttribute * attr = static_cast< AstAttribute * >(*i); 150 AstAttribute * attr = (AstAttribute *)(*i); 151 if (attr->isBound()) { 152 version = TYPEREG_VERSION_1; 153 } 154 DeclList::size_type getCount = attr->getGetExceptionCount(); 155 if (getCount > SAL_MAX_UINT16) { 156 fprintf( 157 stderr, 158 ("%s: raises clause of getter for attribute %s of" 159 " interface %s is too long\n"), 160 idlc()->getOptions()->getProgramName().getStr(), 161 (*i)->getLocalName().getStr(), 162 getScopedName().getStr()); 163 return false; 164 } 165 if (getCount > 0) { 166 version = TYPEREG_VERSION_1; 167 if (!increment(&nMethods, "attributes")) { 168 return false; 169 } 170 } 171 DeclList::size_type setCount = attr->getSetExceptionCount(); 172 if (setCount > SAL_MAX_UINT16) { 173 fprintf( 174 stderr, 175 ("%s: raises clause of setter for attribute %s of" 176 " interface %s is too long\n"), 177 idlc()->getOptions()->getProgramName().getStr(), 178 (*i)->getLocalName().getStr(), 179 getScopedName().getStr()); 180 return false; 181 } 182 if (setCount > 0) { 183 version = TYPEREG_VERSION_1; 184 if (!increment(&nMethods, "attributes")) { 185 return false; 186 } 187 } 188 break; 189 } 190 191 case NT_operation: 192 if (!increment(&nMethods, "methods")) { 193 return false; 194 } 195 break; 196 197 default: 198 OSL_ASSERT(false); 199 break; 200 } 201 }} 202 203 OUString emptyStr; 204 typereg::Writer aBlob( 205 version, getDocumentation(), emptyStr, RT_TYPE_INTERFACE, m_bPublished, 206 OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), nBaseTypes, 207 nAttributes, nMethods, nReferences); 208 209 sal_uInt16 superTypeIndex = 0; 210 sal_uInt16 referenceIndex = 0; 211 {for (InheritedInterfaces::iterator i = m_inheritedInterfaces.begin(); 212 i != m_inheritedInterfaces.end(); ++i) 213 { 214 if (i->isOptional()) { 215 aBlob.setReferenceData( 216 referenceIndex++, i->getDocumentation(), RT_REF_SUPPORTS, 217 RT_ACCESS_OPTIONAL, 218 OStringToOUString( 219 i->getInterface()->getRelativName(), 220 RTL_TEXTENCODING_UTF8)); 221 } else { 222 aBlob.setSuperTypeName( 223 superTypeIndex++, 224 OStringToOUString( 225 i->getInterface()->getRelativName(), 226 RTL_TEXTENCODING_UTF8)); 227 } 228 }} 229 230 sal_uInt16 attributeIndex = 0; 231 sal_uInt16 methodIndex = 0; 232 {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); 233 ++i) 234 { 235 switch ((*i)->getNodeType()) { 236 case NT_attribute: 237 // static_cast< AstAttribute * >(*i)->dumpBlob( 238 239 ((AstAttribute *)(*i))->dumpBlob( 240 aBlob, attributeIndex++, &methodIndex); 241 break; 242 243 case NT_operation: 244 // static_cast< AstOperation * >(*i)->dumpBlob(aBlob, methodIndex++); 245 ((AstOperation *)(*i))->dumpBlob(aBlob, methodIndex++); 246 break; 247 248 default: 249 OSL_ASSERT(false); 250 break; 251 } 252 }} 253 254 sal_uInt32 aBlobSize; 255 void const * pBlob = aBlob.getBlob(&aBlobSize); 256 257 if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize)) 258 { 259 fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", 260 idlc()->getOptions()->getProgramName().getStr(), 261 getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); 262 return sal_False; 263 } 264 265 return true; 266 } 267 268 void AstInterface::checkInheritedInterfaceClashes( 269 DoubleDeclarations & doubleDeclarations, 270 std::set< rtl::OString > & seenInterfaces, AstInterface const * ifc, 271 bool direct, bool optional, bool mainOptional) const 272 { 273 if (direct || optional 274 || seenInterfaces.insert(ifc->getScopedName()).second) 275 { 276 VisibleInterfaces::const_iterator visible( 277 m_visibleInterfaces.find(ifc->getScopedName())); 278 if (visible != m_visibleInterfaces.end()) { 279 switch (visible->second) { 280 case INTERFACE_INDIRECT_OPTIONAL: 281 if (direct && optional) { 282 doubleDeclarations.interfaces.push_back(ifc); 283 return; 284 } 285 break; 286 287 case INTERFACE_DIRECT_OPTIONAL: 288 if (direct || !mainOptional) { 289 doubleDeclarations.interfaces.push_back(ifc); 290 } 291 return; 292 293 case INTERFACE_INDIRECT_MANDATORY: 294 if (direct) { 295 doubleDeclarations.interfaces.push_back(ifc); 296 } 297 return; 298 299 case INTERFACE_DIRECT_MANDATORY: 300 if (direct || (!optional && !mainOptional)) { 301 doubleDeclarations.interfaces.push_back(ifc); 302 } 303 return; 304 } 305 } 306 if (direct || !optional) { 307 {for (DeclList::const_iterator i(ifc->getIteratorBegin()); 308 i != ifc->getIteratorEnd(); ++i) 309 { 310 checkMemberClashes( 311 doubleDeclarations.members, *i, !mainOptional); 312 }} 313 {for (InheritedInterfaces::const_iterator i( 314 ifc->m_inheritedInterfaces.begin()); 315 i != ifc->m_inheritedInterfaces.end(); ++i) 316 { 317 checkInheritedInterfaceClashes( 318 doubleDeclarations, seenInterfaces, i->getResolved(), 319 false, i->isOptional(), mainOptional); 320 }} 321 } 322 } 323 } 324 325 void AstInterface::checkMemberClashes( 326 DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member, 327 bool checkOptional) const 328 { 329 VisibleMembers::const_iterator i( 330 m_visibleMembers.find(member->getLocalName())); 331 if (i != m_visibleMembers.end()) { 332 if (i->second.mandatory != 0) { 333 if (i->second.mandatory->getScopedName() != member->getScopedName()) 334 { 335 DoubleMemberDeclaration d; 336 d.first = i->second.mandatory; 337 d.second = member; 338 doubleMembers.push_back(d); 339 } 340 } else if (checkOptional) { 341 for (VisibleMember::Optionals::const_iterator j( 342 i->second.optionals.begin()); 343 j != i->second.optionals.end(); ++j) 344 { 345 if (j->second->getScopedName() != member->getScopedName()) { 346 DoubleMemberDeclaration d; 347 d.first = j->second; 348 d.second = member; 349 doubleMembers.push_back(d); 350 } 351 } 352 } 353 } 354 } 355 356 void AstInterface::addVisibleInterface( 357 AstInterface const * ifc, bool direct, bool optional) 358 { 359 InterfaceKind kind = optional 360 ? direct ? INTERFACE_DIRECT_OPTIONAL : INTERFACE_INDIRECT_OPTIONAL 361 : direct ? INTERFACE_DIRECT_MANDATORY : INTERFACE_INDIRECT_MANDATORY; 362 std::pair< VisibleInterfaces::iterator, bool > result( 363 m_visibleInterfaces.insert( 364 VisibleInterfaces::value_type(ifc->getScopedName(), kind))); 365 bool seen = !result.second 366 && result.first->second >= INTERFACE_INDIRECT_MANDATORY; 367 if (!result.second && kind > result.first->second) { 368 result.first->second = kind; 369 } 370 if (!optional && !seen) { 371 {for (DeclList::const_iterator i(ifc->getIteratorBegin()); 372 i != ifc->getIteratorEnd(); ++i) 373 { 374 m_visibleMembers.insert( 375 VisibleMembers::value_type( 376 (*i)->getLocalName(), VisibleMember(*i))); 377 }} 378 {for (InheritedInterfaces::const_iterator i( 379 ifc->m_inheritedInterfaces.begin()); 380 i != ifc->m_inheritedInterfaces.end(); ++i) 381 { 382 addVisibleInterface(i->getResolved(), false, i->isOptional()); 383 }} 384 } 385 } 386 387 void AstInterface::addOptionalVisibleMembers(AstInterface const * ifc) { 388 {for (DeclList::const_iterator i(ifc->getIteratorBegin()); 389 i != ifc->getIteratorEnd(); ++i) 390 { 391 VisibleMembers::iterator visible( 392 m_visibleMembers.find((*i)->getLocalName())); 393 if (visible == m_visibleMembers.end()) { 394 visible = m_visibleMembers.insert( 395 VisibleMembers::value_type( 396 (*i)->getLocalName(), VisibleMember())).first; 397 } 398 if (visible->second.mandatory == 0) { 399 visible->second.optionals.insert( 400 VisibleMember::Optionals::value_type(ifc->getScopedName(), *i)); 401 } 402 }} 403 {for (InheritedInterfaces::const_iterator i( 404 ifc->m_inheritedInterfaces.begin()); 405 i != ifc->m_inheritedInterfaces.end(); ++i) 406 { 407 if (!i->isOptional()) { 408 addOptionalVisibleMembers(i->getResolved()); 409 } 410 }} 411 } 412 413 bool AstInterface::increment(sal_uInt16 * counter, char const * sort) const { 414 if (*counter == SAL_MAX_UINT16) { 415 fprintf( 416 stderr, "%s: interface %s has too many direct %s\n", 417 idlc()->getOptions()->getProgramName().getStr(), 418 getScopedName().getStr(), sort); 419 return false; 420 } 421 ++*counter; 422 return true; 423 } 424