bump product version to 7.2.5.1
[LibreOffice.git] / idlc / source / astscope.cxx
blobc77ad48ceb1d5024836f333e36922ba58780cc02
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 <sal/config.h>
22 #include <algorithm>
24 #include <astscope.hxx>
25 #include <astbasetype.hxx>
26 #include <astinterface.hxx>
27 #include <errorhandler.hxx>
28 #include <osl/diagnose.h>
31 static bool isGlobal(const OString& scopedName)
33 return scopedName.isEmpty() || scopedName.startsWith(":");
36 AstScope::AstScope(NodeType nodeType)
37 : m_nodeType(nodeType)
42 AstScope::~AstScope()
47 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
49 AstDeclaration* pDeclaration = nullptr;
51 if ((pDeclaration = lookupForAdd(pDecl)) != nullptr)
53 if ( pDecl->hasAncestor(pDeclaration) )
55 ErrorHandler::error2(ErrorCode::RedefScope, pDecl, pDeclaration);
56 return nullptr;
58 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
59 (pDecl->getNodeType() == NT_sequence
60 || pDecl->getNodeType() == NT_instantiated_struct) )
62 return pDeclaration;
64 if ( (pDeclaration->getNodeType() == NT_interface)
65 && (pDecl->getNodeType() == NT_interface)
66 && !(static_cast<AstInterface*>(pDeclaration)->isDefined()) )
68 m_declarations.push_back(pDecl);
69 return pDecl;
71 if ( (NT_service == m_nodeType) &&
72 ( ((pDecl->getNodeType() == NT_interface_member)
73 && (pDeclaration->getNodeType() == NT_interface)) ||
74 ((pDecl->getNodeType() == NT_service_member)
75 && (pDeclaration->getNodeType() == NT_service)) )
78 m_declarations.push_back(pDecl);
79 return pDecl;
82 ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(this), pDecl);
83 return nullptr;
86 m_declarations.push_back(pDecl);
87 return pDecl;
90 sal_uInt16 AstScope::getNodeCount(NodeType nodeType) const
92 return static_cast<sal_uInt16>(std::count_if(getIteratorBegin(), getIteratorEnd(),
93 [&nodeType](const AstDeclaration* pDecl) { return pDecl->getNodeType() == nodeType; }));
96 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
98 AstDeclaration* pDecl = nullptr;
99 AstScope* pScope = nullptr;
100 if (scopedName.isEmpty())
101 return nullptr;
103 // If name starts with "::" start look up in global scope
104 if ( isGlobal(scopedName) )
106 pDecl = scopeAsDecl(this);
107 if ( !pDecl )
108 return nullptr;
110 pScope = pDecl->getScope();
111 // If this is the global scope ...
112 if ( !pScope )
114 // look up the scopedName part after "::"
115 OString subName = scopedName.copy(2);
116 pDecl = lookupByName(subName);
117 return pDecl;
118 //return pScope->lookupByName();
120 // OK, not global scope yet, so simply iterate with parent scope
121 pDecl = pScope->lookupByName(scopedName);
122 return pDecl;
125 // The name does not start with "::"
126 // Look up in the local scope and start with the first scope
127 sal_Int32 nIndex = scopedName.indexOf(':');
128 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
129 bool bFindFirstScope = true;
130 pDecl = lookupByNameLocal(firstScope);
131 if ( !pDecl )
133 bFindFirstScope = false;
135 // OK, not found. Go down parent scope chain
136 pDecl = scopeAsDecl(this);
137 if ( pDecl )
139 pScope = pDecl->getScope();
140 if ( pScope )
141 pDecl = pScope->lookupByName(scopedName);
142 else
143 pDecl = nullptr;
145 // Special case for scope which is an interface. We
146 // have to look in the inherited interfaces as well.
147 if ( !pDecl && m_nodeType == NT_interface )
148 pDecl = lookupInInherited(scopedName);
152 if ( bFindFirstScope && (firstScope != scopedName) )
154 sal_Int32 i = 0;
155 sal_Int32 nOffset = 2;
158 pScope = declAsScope(pDecl);
159 if( pScope )
161 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
162 nOffset = 1;
164 if( !pDecl )
165 break;
166 } while( i != -1 );
168 if ( !pDecl )
170 // last try if is not the global scope and the scopeName isn't specify global too
171 pDecl = scopeAsDecl(this);
172 if ( pDecl && !pDecl->getLocalName().isEmpty() )
174 pScope = pDecl->getScope();
175 if ( pScope )
176 pDecl = pScope->lookupByName(scopedName);
177 } else
179 pDecl = nullptr;
185 return pDecl;
188 AstDeclaration* AstScope::lookupByNameLocal(std::string_view name) const
190 for (auto const& declaration : m_declarations)
192 if ( declaration->getLocalName() == name )
193 return declaration;
195 return nullptr;
198 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
200 const AstInterface* pInterface = dynamic_cast<const AstInterface*>(this);
202 if ( !pInterface )
203 return nullptr;
205 // Can't look in an interface which was not yet defined
206 if ( !pInterface->getScope() )
208 ErrorHandler::forwardLookupError(pInterface, scopedName);
211 // OK, loop through inherited interfaces. Stop when you find it
212 for (auto const& elem : pInterface->getAllInheritedInterfaces())
214 AstInterface const * resolved = elem.getResolved();
215 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
216 if ( pDecl )
217 return pDecl;
218 pDecl = resolved->lookupInInherited(scopedName);
219 if ( pDecl )
220 return pDecl;
222 // Not found
223 return nullptr;
226 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
228 AstDeclaration* pDecl = nullptr;
229 AstScope* pScope = nullptr;
230 OString typeName;
231 pDecl = scopeAsDecl(this);
232 if ( !pDecl )
233 return nullptr;
234 pScope = pDecl->getScope();
235 if ( pScope)
236 return pScope->lookupPrimitiveType(type);
238 switch (type)
240 case ET_none:
241 OSL_ASSERT(false);
242 break;
243 case ET_short:
244 typeName = OString("short");
245 break;
246 case ET_ushort:
247 typeName = OString("unsigned short");
248 break;
249 case ET_long:
250 typeName = OString("long");
251 break;
252 case ET_ulong:
253 typeName = OString("unsigned long");
254 break;
255 case ET_hyper:
256 typeName = OString("hyper");
257 break;
258 case ET_uhyper:
259 typeName = OString("unsigned hyper");
260 break;
261 case ET_float:
262 typeName = OString("float");
263 break;
264 case ET_double:
265 typeName = OString("double");
266 break;
267 case ET_char:
268 typeName = OString("char");
269 break;
270 case ET_byte:
271 typeName = OString("byte");
272 break;
273 case ET_boolean:
274 typeName = OString("boolean");
275 break;
276 case ET_any:
277 typeName = OString("any");
278 break;
279 case ET_void:
280 typeName = OString("void");
281 break;
282 case ET_type:
283 typeName = OString("type");
284 break;
285 case ET_string:
286 typeName = OString("string");
287 break;
290 pDecl = lookupByNameLocal(typeName);
292 if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
294 AstBaseType* pBaseType = static_cast<AstBaseType*>(pDecl);
296 if ( pBaseType->getExprType() == type )
297 return pDecl;
300 return nullptr;
303 AstDeclaration* AstScope::lookupForAdd(AstDeclaration const * pDecl) const
305 if ( !pDecl )
306 return nullptr;
308 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
310 return pRetDecl;
313 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */