Bump version to 4.3-4
[LibreOffice.git] / idlc / source / astscope.cxx
blobcc081266418113fede2e4407003e2a158d5e49b7
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->hasAncestor(pDeclaration) )
52 idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
53 return NULL;
55 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
56 (pDecl->getNodeType() == NT_sequence
57 || pDecl->getNodeType() == NT_instantiated_struct) )
59 return pDeclaration;
61 if ( (pDeclaration->getNodeType() == NT_interface)
62 && (pDecl->getNodeType() == NT_interface)
63 && !((AstInterface*)pDeclaration)->isDefined() )
65 m_declarations.push_back(pDecl);
66 return pDecl;
68 if ( (NT_service == m_nodeType) &&
69 ( ((pDecl->getNodeType() == NT_interface_member)
70 && (pDeclaration->getNodeType() == NT_interface)) ||
71 ((pDecl->getNodeType() == NT_service_member)
72 && (pDeclaration->getNodeType() == NT_service)) )
75 m_declarations.push_back(pDecl);
76 return pDecl;
79 idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
80 return NULL;
83 m_declarations.push_back(pDecl);
84 return pDecl;
87 sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
89 DeclList::const_iterator iter = getIteratorBegin();
90 DeclList::const_iterator end = getIteratorEnd();
91 AstDeclaration* pDecl = NULL;
92 sal_uInt16 count = 0;
94 while ( iter != end )
96 pDecl = *iter;
97 if ( pDecl->getNodeType() == nodeType )
98 count++;
99 ++iter;
101 return count;
104 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
106 AstDeclaration* pDecl = NULL;
107 AstScope* pScope = NULL;
108 if (scopedName.isEmpty())
109 return NULL;
111 // If name starts with "::" start look up in global scope
112 if ( isGlobal(scopedName) )
114 pDecl = scopeAsDecl(this);
115 if ( !pDecl )
116 return NULL;
118 pScope = pDecl->getScope();
119 // If this is the global scope ...
120 if ( !pScope )
122 // look up the scopedName part after "::"
123 OString subName = scopedName.copy(2);
124 pDecl = lookupByName(subName);
125 return pDecl;
126 //return pScope->lookupByName();
128 // OK, not global scope yet, so simply iterate with parent scope
129 pDecl = pScope->lookupByName(scopedName);
130 return pDecl;
133 // The name does not start with "::"
134 // Look up in the local scope and start with the first scope
135 sal_Int32 nIndex = scopedName.indexOf(':');
136 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
137 bool bFindFirstScope = true;
138 pDecl = lookupByNameLocal(firstScope);
139 if ( !pDecl )
141 bFindFirstScope = false;
143 // OK, not found. Go down parent scope chain
144 pDecl = scopeAsDecl(this);
145 if ( pDecl )
147 pScope = pDecl->getScope();
148 if ( pScope )
149 pDecl = pScope->lookupByName(scopedName);
150 else
151 pDecl = NULL;
153 // Special case for scope which is an interface. We
154 // have to look in the inherited interfaces as well.
155 if ( !pDecl )
157 if (m_nodeType == NT_interface)
158 pDecl = lookupInInherited(scopedName);
163 if ( bFindFirstScope && (firstScope != scopedName) )
165 sal_Int32 i = 0;
166 sal_Int32 nOffset = 2;
169 pScope = declAsScope(pDecl);
170 if( pScope )
172 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
173 nOffset = 1;
175 if( !pDecl )
176 break;
177 } while( i != -1 );
179 if ( !pDecl )
181 // last try if is not the global scope and the scopeName isn't specify global too
182 pDecl = scopeAsDecl(this);
183 if ( pDecl && (pDecl->getLocalName() != "") )
185 pScope = pDecl->getScope();
186 if ( pScope )
187 pDecl = pScope->lookupByName(scopedName);
188 } else
190 pDecl = NULL;
196 return pDecl;
199 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
201 DeclList::const_iterator iter(m_declarations.begin());
202 DeclList::const_iterator end(m_declarations.end());
203 AstDeclaration* pDecl = NULL;
205 while ( iter != end )
207 pDecl = *iter;
208 if ( pDecl->getLocalName() == name )
209 return pDecl;
210 ++iter;
212 return NULL;
215 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
217 AstInterface* pInterface = (AstInterface*)this;
219 if ( !pInterface )
220 return NULL;
222 // Can't look in an interface which was not yet defined
223 if ( !pInterface->getScope() )
225 idlc()->error()->forwardLookupError(pInterface, scopedName);
228 // OK, loop through inherited interfaces. Stop when you find it
229 AstInterface::InheritedInterfaces::const_iterator iter(
230 pInterface->getAllInheritedInterfaces().begin());
231 AstInterface::InheritedInterfaces::const_iterator end(
232 pInterface->getAllInheritedInterfaces().end());
233 while ( iter != end )
235 AstInterface const * resolved = iter->getResolved();
236 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
237 if ( pDecl )
238 return pDecl;
239 pDecl = resolved->lookupInInherited(scopedName);
240 if ( pDecl )
241 return pDecl;
242 ++iter;
244 // Not found
245 return NULL;
248 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
250 AstDeclaration* pDecl = NULL;
251 AstScope* pScope = NULL;
252 OString typeName;
253 pDecl = scopeAsDecl(this);
254 if ( !pDecl )
255 return NULL;
256 pScope = pDecl->getScope();
257 if ( pScope)
258 return pScope->lookupPrimitiveType(type);
260 switch (type)
262 case ET_none:
263 OSL_ASSERT(false);
264 break;
265 case ET_short:
266 typeName = OString("short");
267 break;
268 case ET_ushort:
269 typeName = OString("unsigned short");
270 break;
271 case ET_long:
272 typeName = OString("long");
273 break;
274 case ET_ulong:
275 typeName = OString("unsigned long");
276 break;
277 case ET_hyper:
278 typeName = OString("hyper");
279 break;
280 case ET_uhyper:
281 typeName = OString("unsigned hyper");
282 break;
283 case ET_float:
284 typeName = OString("float");
285 break;
286 case ET_double:
287 typeName = OString("double");
288 break;
289 case ET_char:
290 typeName = OString("char");
291 break;
292 case ET_byte:
293 typeName = OString("byte");
294 break;
295 case ET_boolean:
296 typeName = OString("boolean");
297 break;
298 case ET_any:
299 typeName = OString("any");
300 break;
301 case ET_void:
302 typeName = OString("void");
303 break;
304 case ET_type:
305 typeName = OString("type");
306 break;
307 case ET_string:
308 typeName = OString("string");
309 break;
312 pDecl = lookupByNameLocal(typeName);
314 if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
316 AstBaseType* pBaseType = (AstBaseType*)pDecl;
318 if ( pBaseType->getExprType() == type )
319 return pDecl;
322 return NULL;
325 AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
327 if ( !pDecl )
328 return NULL;
330 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
332 return pRetDecl;
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */