Stop leaking all ScPostIt instances.
[LibreOffice.git] / idlc / source / astscope.cxx
blobba06611feb1a2fa836ac44e1e9422a66c7098e36
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 bool isGlobal(const OString& scopedName)
30 return scopedName.isEmpty() || scopedName.startsWith(":");
33 AstScope::AstScope(NodeType nodeType)
34 : m_nodeType(nodeType)
39 AstScope::~AstScope()
44 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
46 AstDeclaration* pDeclaration = NULL;
48 if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
50 if (pDecl->getNodeType() == NT_union_branch )
52 m_declarations.push_back(pDecl);
53 return pDecl;
55 if ( pDecl->hasAncestor(pDeclaration) )
57 idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
58 return NULL;
60 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
61 (pDecl->getNodeType() == NT_sequence
62 || pDecl->getNodeType() == NT_array
63 || pDecl->getNodeType() == NT_instantiated_struct) )
65 return pDeclaration;
67 if ( (pDeclaration->getNodeType() == NT_interface)
68 && (pDecl->getNodeType() == NT_interface)
69 && !((AstInterface*)pDeclaration)->isDefined() )
71 m_declarations.push_back(pDecl);
72 return pDecl;
74 if ( (NT_service == m_nodeType) &&
75 ( ((pDecl->getNodeType() == NT_interface_member)
76 && (pDeclaration->getNodeType() == NT_interface)) ||
77 ((pDecl->getNodeType() == NT_service_member)
78 && (pDeclaration->getNodeType() == NT_service)) )
81 m_declarations.push_back(pDecl);
82 return pDecl;
85 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
86 return NULL;
89 m_declarations.push_back(pDecl);
90 return pDecl;
93 sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
95 DeclList::const_iterator iter = getIteratorBegin();
96 DeclList::const_iterator end = getIteratorEnd();
97 AstDeclaration* pDecl = NULL;
98 sal_uInt16 count = 0;
100 while ( iter != end )
102 pDecl = *iter;
103 if ( pDecl->getNodeType() == nodeType )
104 count++;
105 ++iter;
107 return count;
110 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
112 AstDeclaration* pDecl = NULL;
113 AstScope* pScope = NULL;
114 if (scopedName.isEmpty())
115 return NULL;
117 // If name starts with "::" start look up in global scope
118 if ( isGlobal(scopedName) )
120 pDecl = scopeAsDecl(this);
121 if ( !pDecl )
122 return NULL;
124 pScope = pDecl->getScope();
125 // If this is the global scope ...
126 if ( !pScope )
128 // look up the scopedName part after "::"
129 OString subName = scopedName.copy(2);
130 pDecl = lookupByName(subName);
131 return pDecl;
132 //return pScope->lookupByName();
134 // OK, not global scope yet, so simply iterate with parent scope
135 pDecl = pScope->lookupByName(scopedName);
136 return pDecl;
139 // The name does not start with "::"
140 // Look up in the local scope and start with the first scope
141 sal_Int32 nIndex = scopedName.indexOf(':');
142 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
143 sal_Bool bFindFirstScope = sal_True;
144 pDecl = lookupByNameLocal(firstScope);
145 if ( !pDecl )
147 bFindFirstScope = sal_False;
149 // OK, not found. Go down parent scope chain
150 pDecl = scopeAsDecl(this);
151 if ( pDecl )
153 pScope = pDecl->getScope();
154 if ( pScope )
155 pDecl = pScope->lookupByName(scopedName);
156 else
157 pDecl = NULL;
159 // Special case for scope which is an interface. We
160 // have to look in the inherited interfaces as well.
161 if ( !pDecl )
163 if (m_nodeType == NT_interface)
164 pDecl = lookupInInherited(scopedName);
169 if ( bFindFirstScope && (firstScope != scopedName) )
171 sal_Int32 i = 0;
172 sal_Int32 nOffset = 2;
175 pScope = declAsScope(pDecl);
176 if( pScope )
178 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
179 nOffset = 1;
181 if( !pDecl )
182 break;
183 } while( i != -1 );
185 if ( !pDecl )
187 // last try if is not the global scope and the scopeName isn't specify global too
188 pDecl = scopeAsDecl(this);
189 if ( pDecl && (pDecl->getLocalName() != "") )
191 pScope = pDecl->getScope();
192 if ( pScope )
193 pDecl = pScope->lookupByName(scopedName);
194 } else
196 pDecl = NULL;
202 return pDecl;
205 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
207 DeclList::const_iterator iter(m_declarations.begin());
208 DeclList::const_iterator end(m_declarations.end());
209 AstDeclaration* pDecl = NULL;
211 while ( iter != end )
213 pDecl = *iter;
214 if ( pDecl->getLocalName() == name )
215 return pDecl;
216 ++iter;
218 return NULL;
221 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
223 AstInterface* pInterface = (AstInterface*)this;
225 if ( !pInterface )
226 return NULL;
228 // Can't look in an interface which was not yet defined
229 if ( !pInterface->getScope() )
231 idlc()->error()->forwardLookupError(pInterface, scopedName);
234 // OK, loop through inherited interfaces. Stop when you find it
235 AstInterface::InheritedInterfaces::const_iterator iter(
236 pInterface->getAllInheritedInterfaces().begin());
237 AstInterface::InheritedInterfaces::const_iterator end(
238 pInterface->getAllInheritedInterfaces().end());
239 while ( iter != end )
241 AstInterface const * resolved = iter->getResolved();
242 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
243 if ( pDecl )
244 return pDecl;
245 pDecl = resolved->lookupInInherited(scopedName);
246 if ( pDecl )
247 return pDecl;
248 ++iter;
250 // Not found
251 return NULL;
254 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
256 AstDeclaration* pDecl = NULL;
257 AstScope* pScope = NULL;
258 OString typeName;
259 pDecl = scopeAsDecl(this);
260 if ( !pDecl )
261 return NULL;
262 pScope = pDecl->getScope();
263 if ( pScope)
264 return pScope->lookupPrimitiveType(type);
266 switch (type)
268 case ET_none:
269 OSL_ASSERT(false);
270 break;
271 case ET_short:
272 typeName = OString("short");
273 break;
274 case ET_ushort:
275 typeName = OString("unsigned short");
276 break;
277 case ET_long:
278 typeName = OString("long");
279 break;
280 case ET_ulong:
281 typeName = OString("unsigned long");
282 break;
283 case ET_hyper:
284 typeName = OString("hyper");
285 break;
286 case ET_uhyper:
287 typeName = OString("unsigned hyper");
288 break;
289 case ET_float:
290 typeName = OString("float");
291 break;
292 case ET_double:
293 typeName = OString("double");
294 break;
295 case ET_char:
296 typeName = OString("char");
297 break;
298 case ET_byte:
299 typeName = OString("byte");
300 break;
301 case ET_boolean:
302 typeName = OString("boolean");
303 break;
304 case ET_any:
305 typeName = OString("any");
306 break;
307 case ET_void:
308 typeName = OString("void");
309 break;
310 case ET_type:
311 typeName = OString("type");
312 break;
313 case ET_string:
314 typeName = OString("string");
315 break;
318 pDecl = lookupByNameLocal(typeName);
320 if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
322 AstBaseType* pBaseType = (AstBaseType*)pDecl;
324 if ( pBaseType->getExprType() == type )
325 return pDecl;
328 return NULL;
331 AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
333 if ( !pDecl )
334 return NULL;
336 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
338 return pRetDecl;
341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */