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/astscope.hxx> 31 #include <idlc/astbasetype.hxx> 32 #ifndef _IDLC_ASTINERFACE_HXX_ 33 #include <idlc/astinterface.hxx> 34 #endif 35 #include <idlc/errorhandler.hxx> 36 37 38 using namespace ::rtl; 39 40 sal_Bool isGlobal(const OString& scopedName) 41 { 42 if ((scopedName.getLength() == 0) || (scopedName.indexOf(':') == 0)) 43 { 44 return sal_True; 45 } 46 return sal_False; 47 } 48 49 AstScope::AstScope(NodeType nodeType) 50 : m_nodeType(nodeType) 51 { 52 53 } 54 55 AstScope::~AstScope() 56 { 57 58 } 59 60 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl) 61 { 62 AstDeclaration* pDeclaration = NULL; 63 64 if ((pDeclaration = lookupForAdd(pDecl)) != NULL) 65 { 66 if (pDecl->getNodeType() == NT_union_branch ) 67 { 68 m_declarations.push_back(pDecl); 69 return pDecl; 70 } 71 if ( pDecl->hasAncestor(pDeclaration) ) 72 { 73 idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration); 74 return NULL; 75 } 76 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) && 77 (pDecl->getNodeType() == NT_sequence 78 || pDecl->getNodeType() == NT_array 79 || pDecl->getNodeType() == NT_instantiated_struct) ) 80 { 81 return pDeclaration; 82 } 83 if ( (pDeclaration->getNodeType() == NT_interface) 84 && (pDecl->getNodeType() == NT_interface) 85 && !((AstInterface*)pDeclaration)->isDefined() ) 86 { 87 m_declarations.push_back(pDecl); 88 return pDecl; 89 } 90 if ( (NT_service == m_nodeType) && 91 ( ((pDecl->getNodeType() == NT_interface_member) 92 && (pDeclaration->getNodeType() == NT_interface)) || 93 ((pDecl->getNodeType() == NT_service_member) 94 && (pDeclaration->getNodeType() == NT_service)) ) 95 ) 96 { 97 m_declarations.push_back(pDecl); 98 return pDecl; 99 } 100 101 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl); 102 return NULL; 103 } 104 105 m_declarations.push_back(pDecl); 106 return pDecl; 107 } 108 109 sal_uInt16 AstScope::getNodeCount(NodeType nodeType) 110 { 111 DeclList::const_iterator iter = getIteratorBegin(); 112 DeclList::const_iterator end = getIteratorEnd(); 113 AstDeclaration* pDecl = NULL; 114 sal_uInt16 count = 0; 115 116 while ( iter != end ) 117 { 118 pDecl = *iter; 119 if ( pDecl->getNodeType() == nodeType ) 120 count++; 121 ++iter; 122 } 123 return count; 124 } 125 126 AstDeclaration* AstScope::lookupByName(const OString& scopedName) 127 { 128 AstDeclaration* pDecl = NULL; 129 AstScope* pScope = NULL; 130 if (scopedName.getLength() == 0) 131 return NULL; 132 133 // If name starts with "::" start look up in global scope 134 if ( isGlobal(scopedName) ) 135 { 136 pDecl = scopeAsDecl(this); 137 if ( !pDecl ) 138 return NULL; 139 140 pScope = pDecl->getScope(); 141 // If this is the global scope ... 142 if ( !pScope ) 143 { 144 // look up the scopedName part after "::" 145 OString subName = scopedName.copy(2); 146 pDecl = lookupByName(subName); 147 return pDecl; 148 //return pScope->lookupByName(); 149 } 150 // OK, not global scope yet, so simply iterate with parent scope 151 pDecl = pScope->lookupByName(scopedName); 152 return pDecl; 153 } 154 155 // The name does not start with "::" 156 // Look up in the local scope and start with the first scope 157 sal_Int32 nIndex = scopedName.indexOf(':'); 158 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName; 159 sal_Bool bFindFirstScope = sal_True; 160 pDecl = lookupByNameLocal(firstScope); 161 if ( !pDecl ) 162 { 163 bFindFirstScope = sal_False; 164 165 // OK, not found. Go down parent scope chain 166 pDecl = scopeAsDecl(this); 167 if ( pDecl ) 168 { 169 pScope = pDecl->getScope(); 170 if ( pScope ) 171 pDecl = pScope->lookupByName(scopedName); 172 else 173 pDecl = NULL; 174 175 // Special case for scope which is an interface. We 176 // have to look in the inherited interfaces as well. 177 if ( !pDecl ) 178 { 179 if (m_nodeType == NT_interface) 180 pDecl = lookupInInherited(scopedName); 181 } 182 } 183 } 184 185 if ( bFindFirstScope && (firstScope != scopedName) ) 186 { 187 sal_Int32 i = 0; 188 sal_Int32 nOffset = 2; 189 do 190 { 191 pScope = declAsScope(pDecl); 192 if( pScope ) 193 { 194 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i )); 195 nOffset = 1; 196 } 197 if( !pDecl ) 198 break; 199 } while( i != -1 ); 200 201 if ( !pDecl ) 202 { 203 // last try if is not the global scope and the scopeName isn't specify global too 204 pDecl = scopeAsDecl(this); 205 if ( pDecl && (pDecl->getLocalName() != "") ) 206 { 207 pScope = pDecl->getScope(); 208 if ( pScope ) 209 pDecl = pScope->lookupByName(scopedName); 210 } else 211 { 212 pDecl = NULL; 213 } 214 } 215 216 } 217 218 return pDecl; 219 } 220 221 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const 222 { 223 DeclList::const_iterator iter(m_declarations.begin()); 224 DeclList::const_iterator end(m_declarations.end()); 225 AstDeclaration* pDecl = NULL; 226 227 while ( iter != end ) 228 { 229 pDecl = *iter; 230 if ( pDecl->getLocalName() == name ) 231 return pDecl; 232 ++iter; 233 } 234 return NULL; 235 } 236 237 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const 238 { 239 AstInterface* pInterface = (AstInterface*)this; 240 241 if ( !pInterface ) 242 return NULL; 243 244 // Can't look in an interface which was not yet defined 245 if ( !pInterface->getScope() ) 246 { 247 idlc()->error()->forwardLookupError(pInterface, scopedName); 248 } 249 250 // OK, loop through inherited interfaces. Stop when you find it 251 AstInterface::InheritedInterfaces::const_iterator iter( 252 pInterface->getAllInheritedInterfaces().begin()); 253 AstInterface::InheritedInterfaces::const_iterator end( 254 pInterface->getAllInheritedInterfaces().end()); 255 while ( iter != end ) 256 { 257 AstInterface const * resolved = iter->getResolved(); 258 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName); 259 if ( pDecl ) 260 return pDecl; 261 pDecl = resolved->lookupInInherited(scopedName); 262 if ( pDecl ) 263 return pDecl; 264 ++iter; 265 } 266 // Not found 267 return NULL; 268 } 269 270 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type) 271 { 272 AstDeclaration* pDecl = NULL; 273 AstScope* pScope = NULL; 274 AstBaseType* pBaseType = NULL; 275 OString typeName; 276 pDecl = scopeAsDecl(this); 277 if ( !pDecl ) 278 return NULL; 279 pScope = pDecl->getScope(); 280 if ( pScope) 281 return pScope->lookupPrimitiveType(type); 282 283 switch (type) 284 { 285 case ET_none: 286 OSL_ASSERT(false); 287 break; 288 case ET_short: 289 typeName = OString("short"); 290 break; 291 case ET_ushort: 292 typeName = OString("unsigned short"); 293 break; 294 case ET_long: 295 typeName = OString("long"); 296 break; 297 case ET_ulong: 298 typeName = OString("unsigned long"); 299 break; 300 case ET_hyper: 301 typeName = OString("hyper"); 302 break; 303 case ET_uhyper: 304 typeName = OString("unsigned hyper"); 305 break; 306 case ET_float: 307 typeName = OString("float"); 308 break; 309 case ET_double: 310 typeName = OString("double"); 311 break; 312 case ET_char: 313 typeName = OString("char"); 314 break; 315 case ET_byte: 316 typeName = OString("byte"); 317 break; 318 case ET_boolean: 319 typeName = OString("boolean"); 320 break; 321 case ET_any: 322 typeName = OString("any"); 323 break; 324 case ET_void: 325 typeName = OString("void"); 326 break; 327 case ET_type: 328 typeName = OString("type"); 329 break; 330 case ET_string: 331 typeName = OString("string"); 332 break; 333 } 334 335 pDecl = lookupByNameLocal(typeName); 336 337 if ( pDecl && (pDecl->getNodeType() == NT_predefined) ) 338 { 339 pBaseType = (AstBaseType*)pDecl; 340 341 if ( pBaseType->getExprType() == type ) 342 return pDecl; 343 } 344 345 return NULL; 346 } 347 348 AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl) 349 { 350 if ( !pDecl ) 351 return NULL; 352 353 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName()); 354 355 return pRetDecl; 356 } 357