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