update dev300-m58
[ooovba.git] / idlc / source / astscope.cxx
blob08ffa51217b21da3064d204054c58a41f27aa384
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: astscope.cxx,v $
10 * $Revision: 1.13 $
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/astscope.hxx>
34 #include <idlc/astbasetype.hxx>
35 #ifndef _IDLC_ASTINERFACE_HXX_
36 #include <idlc/astinterface.hxx>
37 #endif
38 #include <idlc/errorhandler.hxx>
41 using namespace ::rtl;
43 sal_Bool isGlobal(const OString& scopedName)
45 if ((scopedName.getLength() == 0) || (scopedName.indexOf(':') == 0))
47 return sal_True;
49 return sal_False;
52 AstScope::AstScope(NodeType nodeType)
53 : m_nodeType(nodeType)
58 AstScope::~AstScope()
63 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
65 AstDeclaration* pDeclaration = NULL;
67 if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
69 if (pDecl->getNodeType() == NT_union_branch )
71 m_declarations.push_back(pDecl);
72 return pDecl;
74 if ( pDecl->hasAncestor(pDeclaration) )
76 idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
77 return NULL;
79 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
80 (pDecl->getNodeType() == NT_sequence
81 || pDecl->getNodeType() == NT_array
82 || pDecl->getNodeType() == NT_instantiated_struct) )
84 return pDeclaration;
86 if ( (pDeclaration->getNodeType() == NT_interface)
87 && (pDecl->getNodeType() == NT_interface)
88 && !((AstInterface*)pDeclaration)->isDefined() )
90 m_declarations.push_back(pDecl);
91 return pDecl;
93 if ( (NT_service == m_nodeType) &&
94 ( ((pDecl->getNodeType() == NT_interface_member)
95 && (pDeclaration->getNodeType() == NT_interface)) ||
96 ((pDecl->getNodeType() == NT_service_member)
97 && (pDeclaration->getNodeType() == NT_service)) )
100 m_declarations.push_back(pDecl);
101 return pDecl;
104 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
105 return NULL;
108 m_declarations.push_back(pDecl);
109 return pDecl;
112 sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
114 DeclList::const_iterator iter = getIteratorBegin();
115 DeclList::const_iterator end = getIteratorEnd();
116 AstDeclaration* pDecl = NULL;
117 sal_uInt16 count = 0;
119 while ( iter != end )
121 pDecl = *iter;
122 if ( pDecl->getNodeType() == nodeType )
123 count++;
124 ++iter;
126 return count;
129 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
131 AstDeclaration* pDecl = NULL;
132 AstScope* pScope = NULL;
133 if (scopedName.getLength() == 0)
134 return NULL;
136 // If name starts with "::" start look up in global scope
137 if ( isGlobal(scopedName) )
139 pDecl = scopeAsDecl(this);
140 if ( !pDecl )
141 return NULL;
143 pScope = pDecl->getScope();
144 // If this is the global scope ...
145 if ( !pScope )
147 // look up the scopedName part after "::"
148 OString subName = scopedName.copy(2);
149 pDecl = lookupByName(subName);
150 return pDecl;
151 //return pScope->lookupByName();
153 // OK, not global scope yet, so simply iterate with parent scope
154 pDecl = pScope->lookupByName(scopedName);
155 return pDecl;
158 // The name does not start with "::"
159 // Look up in the local scope and start with the first scope
160 sal_Int32 nIndex = scopedName.indexOf(':');
161 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
162 sal_Bool bFindFirstScope = sal_True;
163 pDecl = lookupByNameLocal(firstScope);
164 if ( !pDecl )
166 bFindFirstScope = sal_False;
168 // OK, not found. Go down parent scope chain
169 pDecl = scopeAsDecl(this);
170 if ( pDecl )
172 pScope = pDecl->getScope();
173 if ( pScope )
174 pDecl = pScope->lookupByName(scopedName);
175 else
176 pDecl = NULL;
178 // Special case for scope which is an interface. We
179 // have to look in the inherited interfaces as well.
180 if ( !pDecl )
182 if (m_nodeType == NT_interface)
183 pDecl = lookupInInherited(scopedName);
188 if ( bFindFirstScope && (firstScope != scopedName) )
190 sal_Int32 i = 0;
191 sal_Int32 nOffset = 2;
194 pScope = declAsScope(pDecl);
195 if( pScope )
197 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
198 nOffset = 1;
200 if( !pDecl )
201 break;
202 } while( i != -1 );
204 if ( !pDecl )
206 // last try if is not the global scope and the scopeName isn't specify global too
207 pDecl = scopeAsDecl(this);
208 if ( pDecl && (pDecl->getLocalName() != "") )
210 pScope = pDecl->getScope();
211 if ( pScope )
212 pDecl = pScope->lookupByName(scopedName);
213 } else
215 pDecl = NULL;
221 return pDecl;
224 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
226 DeclList::const_iterator iter(m_declarations.begin());
227 DeclList::const_iterator end(m_declarations.end());
228 AstDeclaration* pDecl = NULL;
230 while ( iter != end )
232 pDecl = *iter;
233 if ( pDecl->getLocalName() == name )
234 return pDecl;
235 ++iter;
237 return NULL;
240 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
242 AstInterface* pInterface = (AstInterface*)this;
244 if ( !pInterface )
245 return NULL;
247 // Can't look in an interface which was not yet defined
248 if ( !pInterface->getScope() )
250 idlc()->error()->forwardLookupError(pInterface, scopedName);
253 // OK, loop through inherited interfaces. Stop when you find it
254 AstInterface::InheritedInterfaces::const_iterator iter(
255 pInterface->getAllInheritedInterfaces().begin());
256 AstInterface::InheritedInterfaces::const_iterator end(
257 pInterface->getAllInheritedInterfaces().end());
258 while ( iter != end )
260 AstInterface const * resolved = iter->getResolved();
261 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
262 if ( pDecl )
263 return pDecl;
264 pDecl = resolved->lookupInInherited(scopedName);
265 if ( pDecl )
266 return pDecl;
267 ++iter;
269 // Not found
270 return NULL;
273 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
275 AstDeclaration* pDecl = NULL;
276 AstScope* pScope = NULL;
277 AstBaseType* pBaseType = NULL;
278 OString typeName;
279 pDecl = scopeAsDecl(this);
280 if ( !pDecl )
281 return NULL;
282 pScope = pDecl->getScope();
283 if ( pScope)
284 return pScope->lookupPrimitiveType(type);
286 switch (type)
288 case ET_none:
289 OSL_ASSERT(false);
290 break;
291 case ET_short:
292 typeName = OString("short");
293 break;
294 case ET_ushort:
295 typeName = OString("unsigned short");
296 break;
297 case ET_long:
298 typeName = OString("long");
299 break;
300 case ET_ulong:
301 typeName = OString("unsigned long");
302 break;
303 case ET_hyper:
304 typeName = OString("hyper");
305 break;
306 case ET_uhyper:
307 typeName = OString("unsigned hyper");
308 break;
309 case ET_float:
310 typeName = OString("float");
311 break;
312 case ET_double:
313 typeName = OString("double");
314 break;
315 case ET_char:
316 typeName = OString("char");
317 break;
318 case ET_byte:
319 typeName = OString("byte");
320 break;
321 case ET_boolean:
322 typeName = OString("boolean");
323 break;
324 case ET_any:
325 typeName = OString("any");
326 break;
327 case ET_void:
328 typeName = OString("void");
329 break;
330 case ET_type:
331 typeName = OString("type");
332 break;
333 case ET_string:
334 typeName = OString("string");
335 break;
338 pDecl = lookupByNameLocal(typeName);
340 if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
342 pBaseType = (AstBaseType*)pDecl;
344 if ( pBaseType->getExprType() == type )
345 return pDecl;
348 return NULL;
351 AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
353 if ( !pDecl )
354 return NULL;
356 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
358 return pRetDecl;