Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <idlc/astscope.hxx>
21 : #include <idlc/astbasetype.hxx>
22 : #include <idlc/astinterface.hxx>
23 : #include <idlc/errorhandler.hxx>
24 : #include <osl/diagnose.h>
25 :
26 :
27 1623 : bool isGlobal(const OString& scopedName)
28 : {
29 1623 : return scopedName.isEmpty() || scopedName.startsWith(":");
30 : }
31 :
32 4126 : AstScope::AstScope(NodeType nodeType)
33 4126 : : m_nodeType(nodeType)
34 : {
35 :
36 4126 : }
37 :
38 442 : AstScope::~AstScope()
39 : {
40 :
41 442 : }
42 :
43 13959 : AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
44 : {
45 13959 : AstDeclaration* pDeclaration = NULL;
46 :
47 13959 : if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
48 : {
49 4 : if ( pDecl->hasAncestor(pDeclaration) )
50 : {
51 0 : ErrorHandler::error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
52 0 : return NULL;
53 : }
54 7 : if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
55 3 : (pDecl->getNodeType() == NT_sequence
56 3 : || pDecl->getNodeType() == NT_instantiated_struct) )
57 : {
58 0 : return pDeclaration;
59 : }
60 8 : if ( (pDeclaration->getNodeType() == NT_interface)
61 0 : && (pDecl->getNodeType() == NT_interface)
62 4 : && !(static_cast<AstInterface*>(pDeclaration)->isDefined()) )
63 : {
64 0 : m_declarations.push_back(pDecl);
65 0 : return pDecl;
66 : }
67 5 : if ( (NT_service == m_nodeType) &&
68 1 : ( ((pDecl->getNodeType() == NT_interface_member)
69 1 : && (pDeclaration->getNodeType() == NT_interface)) ||
70 1 : ((pDecl->getNodeType() == NT_service_member)
71 0 : && (pDeclaration->getNodeType() == NT_service)) )
72 : )
73 : {
74 0 : m_declarations.push_back(pDecl);
75 0 : return pDecl;
76 : }
77 :
78 4 : ErrorHandler::error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
79 4 : return NULL;
80 : }
81 :
82 13955 : m_declarations.push_back(pDecl);
83 13955 : return pDecl;
84 : }
85 :
86 384 : sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
87 : {
88 384 : DeclList::const_iterator iter = getIteratorBegin();
89 384 : DeclList::const_iterator end = getIteratorEnd();
90 384 : AstDeclaration* pDecl = NULL;
91 384 : sal_uInt16 count = 0;
92 :
93 3663 : while ( iter != end )
94 : {
95 2895 : pDecl = *iter;
96 2895 : if ( pDecl->getNodeType() == nodeType )
97 171 : count++;
98 2895 : ++iter;
99 : }
100 384 : return count;
101 : }
102 :
103 1623 : AstDeclaration* AstScope::lookupByName(const OString& scopedName)
104 : {
105 1623 : AstDeclaration* pDecl = NULL;
106 1623 : AstScope* pScope = NULL;
107 1623 : if (scopedName.isEmpty())
108 0 : return NULL;
109 :
110 : // If name starts with "::" start look up in global scope
111 1623 : if ( isGlobal(scopedName) )
112 : {
113 454 : pDecl = scopeAsDecl(this);
114 454 : if ( !pDecl )
115 0 : return NULL;
116 :
117 454 : pScope = pDecl->getScope();
118 : // If this is the global scope ...
119 454 : if ( !pScope )
120 : {
121 : // look up the scopedName part after "::"
122 193 : OString subName = scopedName.copy(2);
123 193 : pDecl = lookupByName(subName);
124 193 : return pDecl;
125 : //return pScope->lookupByName();
126 : }
127 : // OK, not global scope yet, so simply iterate with parent scope
128 261 : pDecl = pScope->lookupByName(scopedName);
129 261 : return pDecl;
130 : }
131 :
132 : // The name does not start with "::"
133 : // Look up in the local scope and start with the first scope
134 1169 : sal_Int32 nIndex = scopedName.indexOf(':');
135 1169 : OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
136 1169 : bool bFindFirstScope = true;
137 1169 : pDecl = lookupByNameLocal(firstScope);
138 1169 : if ( !pDecl )
139 : {
140 596 : bFindFirstScope = false;
141 :
142 : // OK, not found. Go down parent scope chain
143 596 : pDecl = scopeAsDecl(this);
144 596 : if ( pDecl )
145 : {
146 596 : pScope = pDecl->getScope();
147 596 : if ( pScope )
148 369 : pDecl = pScope->lookupByName(scopedName);
149 : else
150 227 : pDecl = NULL;
151 :
152 : // Special case for scope which is an interface. We
153 : // have to look in the inherited interfaces as well.
154 596 : if ( !pDecl )
155 : {
156 299 : if (m_nodeType == NT_interface)
157 0 : pDecl = lookupInInherited(scopedName);
158 : }
159 : }
160 : }
161 :
162 1169 : if ( bFindFirstScope && (firstScope != scopedName) )
163 : {
164 224 : sal_Int32 i = 0;
165 224 : sal_Int32 nOffset = 2;
166 867 : do
167 : {
168 884 : pScope = declAsScope(pDecl);
169 884 : if( pScope )
170 : {
171 884 : pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
172 884 : nOffset = 1;
173 : }
174 884 : if( !pDecl )
175 17 : break;
176 867 : } while( i != -1 );
177 :
178 224 : if ( !pDecl )
179 : {
180 : // last try if is not the global scope and the scopeName isn't specify global too
181 17 : pDecl = scopeAsDecl(this);
182 17 : if ( pDecl && !pDecl->getLocalName().isEmpty() )
183 : {
184 0 : pScope = pDecl->getScope();
185 0 : if ( pScope )
186 0 : pDecl = pScope->lookupByName(scopedName);
187 : } else
188 : {
189 17 : pDecl = NULL;
190 : }
191 : }
192 :
193 : }
194 :
195 1169 : return pDecl;
196 : }
197 :
198 17693 : AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
199 : {
200 17693 : DeclList::const_iterator iter(m_declarations.begin());
201 17693 : DeclList::const_iterator end(m_declarations.end());
202 17693 : AstDeclaration* pDecl = NULL;
203 :
204 153652 : while ( iter != end )
205 : {
206 121317 : pDecl = *iter;
207 121317 : if ( pDecl->getLocalName() == name )
208 3051 : return pDecl;
209 118266 : ++iter;
210 : }
211 14642 : return NULL;
212 : }
213 :
214 0 : AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
215 : {
216 0 : const AstInterface* pInterface = dynamic_cast<const AstInterface*>(this);
217 :
218 0 : if ( !pInterface )
219 0 : return NULL;
220 :
221 : // Can't look in an interface which was not yet defined
222 0 : if ( !pInterface->getScope() )
223 : {
224 0 : ErrorHandler::forwardLookupError(pInterface, scopedName);
225 : }
226 :
227 : // OK, loop through inherited interfaces. Stop when you find it
228 : AstInterface::InheritedInterfaces::const_iterator iter(
229 0 : pInterface->getAllInheritedInterfaces().begin());
230 : AstInterface::InheritedInterfaces::const_iterator end(
231 0 : pInterface->getAllInheritedInterfaces().end());
232 0 : while ( iter != end )
233 : {
234 0 : AstInterface const * resolved = iter->getResolved();
235 0 : AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
236 0 : if ( pDecl )
237 0 : return pDecl;
238 0 : pDecl = resolved->lookupInInherited(scopedName);
239 0 : if ( pDecl )
240 0 : return pDecl;
241 0 : ++iter;
242 : }
243 : // Not found
244 0 : return NULL;
245 : }
246 :
247 1500 : AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
248 : {
249 1500 : AstDeclaration* pDecl = NULL;
250 1500 : AstScope* pScope = NULL;
251 1500 : OString typeName;
252 1500 : pDecl = scopeAsDecl(this);
253 1500 : if ( !pDecl )
254 0 : return NULL;
255 1500 : pScope = pDecl->getScope();
256 1500 : if ( pScope)
257 0 : return pScope->lookupPrimitiveType(type);
258 :
259 1500 : switch (type)
260 : {
261 : case ET_none:
262 : OSL_ASSERT(false);
263 0 : break;
264 : case ET_short:
265 3 : typeName = OString("short");
266 3 : break;
267 : case ET_ushort:
268 5 : typeName = OString("unsigned short");
269 5 : break;
270 : case ET_long:
271 120 : typeName = OString("long");
272 120 : break;
273 : case ET_ulong:
274 1 : typeName = OString("unsigned long");
275 1 : break;
276 : case ET_hyper:
277 0 : typeName = OString("hyper");
278 0 : break;
279 : case ET_uhyper:
280 1 : typeName = OString("unsigned hyper");
281 1 : break;
282 : case ET_float:
283 0 : typeName = OString("float");
284 0 : break;
285 : case ET_double:
286 0 : typeName = OString("double");
287 0 : break;
288 : case ET_char:
289 1 : typeName = OString("char");
290 1 : break;
291 : case ET_byte:
292 0 : typeName = OString("byte");
293 0 : break;
294 : case ET_boolean:
295 0 : typeName = OString("boolean");
296 0 : break;
297 : case ET_any:
298 341 : typeName = OString("any");
299 341 : break;
300 : case ET_void:
301 698 : typeName = OString("void");
302 698 : break;
303 : case ET_type:
304 329 : typeName = OString("type");
305 329 : break;
306 : case ET_string:
307 1 : typeName = OString("string");
308 1 : break;
309 : }
310 :
311 1500 : pDecl = lookupByNameLocal(typeName);
312 :
313 1500 : if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
314 : {
315 1500 : AstBaseType* pBaseType = static_cast<AstBaseType*>(pDecl);
316 :
317 1500 : if ( pBaseType->getExprType() == type )
318 1500 : return pDecl;
319 : }
320 :
321 0 : return NULL;
322 : }
323 :
324 14140 : AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
325 : {
326 14140 : if ( !pDecl )
327 0 : return NULL;
328 :
329 14140 : AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
330 :
331 14140 : return pRetDecl;
332 : }
333 :
334 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|