vcl: support rendering multiple PDF pages to bitmap
[LibreOffice.git] / idlc / source / astscope.cxx
blob5fd9d5339d687d2c2fb89fb759884fa9667cc5de
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 <astscope.hxx>
21 #include <astbasetype.hxx>
22 #include <astinterface.hxx>
23 #include <errorhandler.hxx>
24 #include <osl/diagnose.h>
27 bool isGlobal(const OString& scopedName)
29 return scopedName.isEmpty() || scopedName.startsWith(":");
32 AstScope::AstScope(NodeType nodeType)
33 : m_nodeType(nodeType)
38 AstScope::~AstScope()
43 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
45 AstDeclaration* pDeclaration = nullptr;
47 if ((pDeclaration = lookupForAdd(pDecl)) != nullptr)
49 if ( pDecl->hasAncestor(pDeclaration) )
51 ErrorHandler::error2(ErrorCode::RedefScope, pDecl, pDeclaration);
52 return nullptr;
54 if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
55 (pDecl->getNodeType() == NT_sequence
56 || pDecl->getNodeType() == NT_instantiated_struct) )
58 return pDeclaration;
60 if ( (pDeclaration->getNodeType() == NT_interface)
61 && (pDecl->getNodeType() == NT_interface)
62 && !(static_cast<AstInterface*>(pDeclaration)->isDefined()) )
64 m_declarations.push_back(pDecl);
65 return pDecl;
67 if ( (NT_service == m_nodeType) &&
68 ( ((pDecl->getNodeType() == NT_interface_member)
69 && (pDeclaration->getNodeType() == NT_interface)) ||
70 ((pDecl->getNodeType() == NT_service_member)
71 && (pDeclaration->getNodeType() == NT_service)) )
74 m_declarations.push_back(pDecl);
75 return pDecl;
78 ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(this), pDecl);
79 return nullptr;
82 m_declarations.push_back(pDecl);
83 return pDecl;
86 sal_uInt16 AstScope::getNodeCount(NodeType nodeType) const
88 DeclList::const_iterator iter = getIteratorBegin();
89 DeclList::const_iterator end = getIteratorEnd();
90 sal_uInt16 count = 0;
92 while ( iter != end )
94 AstDeclaration* pDecl = *iter;
95 if ( pDecl->getNodeType() == nodeType )
96 count++;
97 ++iter;
99 return count;
102 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
104 AstDeclaration* pDecl = nullptr;
105 AstScope* pScope = nullptr;
106 if (scopedName.isEmpty())
107 return nullptr;
109 // If name starts with "::" start look up in global scope
110 if ( isGlobal(scopedName) )
112 pDecl = scopeAsDecl(this);
113 if ( !pDecl )
114 return nullptr;
116 pScope = pDecl->getScope();
117 // If this is the global scope ...
118 if ( !pScope )
120 // look up the scopedName part after "::"
121 OString subName = scopedName.copy(2);
122 pDecl = lookupByName(subName);
123 return pDecl;
124 //return pScope->lookupByName();
126 // OK, not global scope yet, so simply iterate with parent scope
127 pDecl = pScope->lookupByName(scopedName);
128 return pDecl;
131 // The name does not start with "::"
132 // Look up in the local scope and start with the first scope
133 sal_Int32 nIndex = scopedName.indexOf(':');
134 OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
135 bool bFindFirstScope = true;
136 pDecl = lookupByNameLocal(firstScope);
137 if ( !pDecl )
139 bFindFirstScope = false;
141 // OK, not found. Go down parent scope chain
142 pDecl = scopeAsDecl(this);
143 if ( pDecl )
145 pScope = pDecl->getScope();
146 if ( pScope )
147 pDecl = pScope->lookupByName(scopedName);
148 else
149 pDecl = nullptr;
151 // Special case for scope which is an interface. We
152 // have to look in the inherited interfaces as well.
153 if ( !pDecl )
155 if (m_nodeType == NT_interface)
156 pDecl = lookupInInherited(scopedName);
161 if ( bFindFirstScope && (firstScope != scopedName) )
163 sal_Int32 i = 0;
164 sal_Int32 nOffset = 2;
167 pScope = declAsScope(pDecl);
168 if( pScope )
170 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
171 nOffset = 1;
173 if( !pDecl )
174 break;
175 } while( i != -1 );
177 if ( !pDecl )
179 // last try if is not the global scope and the scopeName isn't specify global too
180 pDecl = scopeAsDecl(this);
181 if ( pDecl && !pDecl->getLocalName().isEmpty() )
183 pScope = pDecl->getScope();
184 if ( pScope )
185 pDecl = pScope->lookupByName(scopedName);
186 } else
188 pDecl = nullptr;
194 return pDecl;
197 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
199 for (auto const& declaration : m_declarations)
201 if ( declaration->getLocalName() == name )
202 return declaration;
204 return nullptr;
207 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
209 const AstInterface* pInterface = dynamic_cast<const AstInterface*>(this);
211 if ( !pInterface )
212 return nullptr;
214 // Can't look in an interface which was not yet defined
215 if ( !pInterface->getScope() )
217 ErrorHandler::forwardLookupError(pInterface, scopedName);
220 // OK, loop through inherited interfaces. Stop when you find it
221 for (auto const& elem : pInterface->getAllInheritedInterfaces())
223 AstInterface const * resolved = elem.getResolved();
224 AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
225 if ( pDecl )
226 return pDecl;
227 pDecl = resolved->lookupInInherited(scopedName);
228 if ( pDecl )
229 return pDecl;
231 // Not found
232 return nullptr;
235 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
237 AstDeclaration* pDecl = nullptr;
238 AstScope* pScope = nullptr;
239 OString typeName;
240 pDecl = scopeAsDecl(this);
241 if ( !pDecl )
242 return nullptr;
243 pScope = pDecl->getScope();
244 if ( pScope)
245 return pScope->lookupPrimitiveType(type);
247 switch (type)
249 case ET_none:
250 OSL_ASSERT(false);
251 break;
252 case ET_short:
253 typeName = OString("short");
254 break;
255 case ET_ushort:
256 typeName = OString("unsigned short");
257 break;
258 case ET_long:
259 typeName = OString("long");
260 break;
261 case ET_ulong:
262 typeName = OString("unsigned long");
263 break;
264 case ET_hyper:
265 typeName = OString("hyper");
266 break;
267 case ET_uhyper:
268 typeName = OString("unsigned hyper");
269 break;
270 case ET_float:
271 typeName = OString("float");
272 break;
273 case ET_double:
274 typeName = OString("double");
275 break;
276 case ET_char:
277 typeName = OString("char");
278 break;
279 case ET_byte:
280 typeName = OString("byte");
281 break;
282 case ET_boolean:
283 typeName = OString("boolean");
284 break;
285 case ET_any:
286 typeName = OString("any");
287 break;
288 case ET_void:
289 typeName = OString("void");
290 break;
291 case ET_type:
292 typeName = OString("type");
293 break;
294 case ET_string:
295 typeName = OString("string");
296 break;
299 pDecl = lookupByNameLocal(typeName);
301 if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
303 AstBaseType* pBaseType = static_cast<AstBaseType*>(pDecl);
305 if ( pBaseType->getExprType() == type )
306 return pDecl;
309 return nullptr;
312 AstDeclaration* AstScope::lookupForAdd(AstDeclaration const * pDecl) const
314 if ( !pDecl )
315 return nullptr;
317 AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
319 return pRetDecl;
322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */