Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / idlc / source / astscope.cxx
blob3d26b3a1182f0ebd9861d6662eb383772cd23977
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <idlc/astscope.hxx>
21 #include <idlc/astbasetype.hxx>
22 #include <idlc/astinterface.hxx>
23 #include <idlc/errorhandler.hxx>
26 using namespace ::rtl;
28 sal_Bool isGlobal(const OString& scopedName)
30 if (scopedName.isEmpty() || (scopedName.indexOf(':') == 0))
32 return sal_True;
34 return sal_False;
37 AstScope::AstScope(NodeType nodeType)
38 : m_nodeType(nodeType)
43 AstScope::~AstScope()
48 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
50 AstDeclaration* pDeclaration = NULL;
52 if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
54 if (pDecl->getNodeType() == NT_union_branch )
56 m_declarations.push_back(pDecl);
57 return pDecl;
59 if ( pDecl->hasAncestor(pDeclaration) )
61 idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
62 return NULL;
64 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
65 (pDecl->getNodeType() == NT_sequence
66 || pDecl->getNodeType() == NT_array
67 || pDecl->getNodeType() == NT_instantiated_struct) )
69 return pDeclaration;
71 if ( (pDeclaration->getNodeType() == NT_interface)
72 && (pDecl->getNodeType() == NT_interface)
73 && !((AstInterface*)pDeclaration)->isDefined() )
75 m_declarations.push_back(pDecl);
76 return pDecl;
78 if ( (NT_service == m_nodeType) &&
79 ( ((pDecl->getNodeType() == NT_interface_member)
80 && (pDeclaration->getNodeType() == NT_interface)) ||
81 ((pDecl->getNodeType() == NT_service_member)
82 && (pDeclaration->getNodeType() == NT_service)) )
85 m_declarations.push_back(pDecl);
86 return pDecl;
89 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
90 return NULL;
93 m_declarations.push_back(pDecl);
94 return pDecl;
97 sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
99 DeclList::const_iterator iter = getIteratorBegin();
100 DeclList::const_iterator end = getIteratorEnd();
101 AstDeclaration* pDecl = NULL;
102 sal_uInt16 count = 0;
104 while ( iter != end )
106 pDecl = *iter;
107 if ( pDecl->getNodeType() == nodeType )
108 count++;
109 ++iter;
111 return count;
114 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
116 AstDeclaration* pDecl = NULL;
117 AstScope* pScope = NULL;
118 if (scopedName.isEmpty())
119 return NULL;
121 // If name starts with "::" start look up in global scope
122 if ( isGlobal(scopedName) )
124 pDecl = scopeAsDecl(this);
125 if ( !pDecl )
126 return NULL;
128 pScope = pDecl->getScope();
129 // If this is the global scope ...
130 if ( !pScope )
132 // look up the scopedName part after "::"
133 OString subName = scopedName.copy(2);
134 pDecl = lookupByName(subName);
135 return pDecl;
136 //return pScope->lookupByName();
138 // OK, not global scope yet, so simply iterate with parent scope
139 pDecl = pScope->lookupByName(scopedName);
140 return pDecl;
143 // The name does not start with "::"
144 // Look up in the local scope and start with the first scope
145 sal_Int32 nIndex = scopedName.indexOf(':');
146 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
147 sal_Bool bFindFirstScope = sal_True;
148 pDecl = lookupByNameLocal(firstScope);
149 if ( !pDecl )
151 bFindFirstScope = sal_False;
153 // OK, not found. Go down parent scope chain
154 pDecl = scopeAsDecl(this);
155 if ( pDecl )
157 pScope = pDecl->getScope();
158 if ( pScope )
159 pDecl = pScope->lookupByName(scopedName);
160 else
161 pDecl = NULL;
163 // Special case for scope which is an interface. We
164 // have to look in the inherited interfaces as well.
165 if ( !pDecl )
167 if (m_nodeType == NT_interface)
168 pDecl = lookupInInherited(scopedName);
173 if ( bFindFirstScope && (firstScope != scopedName) )
175 sal_Int32 i = 0;
176 sal_Int32 nOffset = 2;
179 pScope = declAsScope(pDecl);
180 if( pScope )
182 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
183 nOffset = 1;
185 if( !pDecl )
186 break;
187 } while( i != -1 );
189 if ( !pDecl )
191 // last try if is not the global scope and the scopeName isn't specify global too
192 pDecl = scopeAsDecl(this);
193 if ( pDecl && (pDecl->getLocalName() != "") )
195 pScope = pDecl->getScope();
196 if ( pScope )
197 pDecl = pScope->lookupByName(scopedName);
198 } else
200 pDecl = NULL;
206 return pDecl;
209 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
211 DeclList::const_iterator iter(m_declarations.begin());
212 DeclList::const_iterator end(m_declarations.end());
213 AstDeclaration* pDecl = NULL;
215 while ( iter != end )
217 pDecl = *iter;
218 if ( pDecl->getLocalName() == name )
219 return pDecl;
220 ++iter;
222 return NULL;
225 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
227 AstInterface* pInterface = (AstInterface*)this;
229 if ( !pInterface )
230 return NULL;
232 // Can't look in an interface which was not yet defined
233 if ( !pInterface->getScope() )
235 idlc()->error()->forwardLookupError(pInterface, scopedName);
238 // OK, loop through inherited interfaces. Stop when you find it
239 AstInterface::InheritedInterfaces::const_iterator iter(
240 pInterface->getAllInheritedInterfaces().begin());
241 AstInterface::InheritedInterfaces::const_iterator end(
242 pInterface->getAllInheritedInterfaces().end());
243 while ( iter != end )
245 AstInterface const * resolved = iter->getResolved();
246 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
247 if ( pDecl )
248 return pDecl;
249 pDecl = resolved->lookupInInherited(scopedName);
250 if ( pDecl )
251 return pDecl;
252 ++iter;
254 // Not found
255 return NULL;
258 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
260 AstDeclaration* pDecl = NULL;
261 AstScope* pScope = NULL;
262 AstBaseType* pBaseType = NULL;
263 OString typeName;
264 pDecl = scopeAsDecl(this);
265 if ( !pDecl )
266 return NULL;
267 pScope = pDecl->getScope();
268 if ( pScope)
269 return pScope->lookupPrimitiveType(type);
271 switch (type)
273 case ET_none:
274 OSL_ASSERT(false);
275 break;
276 case ET_short:
277 typeName = OString("short");
278 break;
279 case ET_ushort:
280 typeName = OString("unsigned short");
281 break;
282 case ET_long:
283 typeName = OString("long");
284 break;
285 case ET_ulong:
286 typeName = OString("unsigned long");
287 break;
288 case ET_hyper:
289 typeName = OString("hyper");
290 break;
291 case ET_uhyper:
292 typeName = OString("unsigned hyper");
293 break;
294 case ET_float:
295 typeName = OString("float");
296 break;
297 case ET_double:
298 typeName = OString("double");
299 break;
300 case ET_char:
301 typeName = OString("char");
302 break;
303 case ET_byte:
304 typeName = OString("byte");
305 break;
306 case ET_boolean:
307 typeName = OString("boolean");
308 break;
309 case ET_any:
310 typeName = OString("any");
311 break;
312 case ET_void:
313 typeName = OString("void");
314 break;
315 case ET_type:
316 typeName = OString("type");
317 break;
318 case ET_string:
319 typeName = OString("string");
320 break;
323 pDecl = lookupByNameLocal(typeName);
325 if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
327 pBaseType = (AstBaseType*)pDecl;
329 if ( pBaseType->getExprType() == type )
330 return pDecl;
333 return NULL;
336 AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
338 if ( !pDecl )
339 return NULL;
341 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
343 return pRetDecl;
346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */