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 :
25 :
26 : using namespace ::rtl;
27 :
28 1019597 : sal_Bool isGlobal(const OString& scopedName)
29 : {
30 1019597 : if (scopedName.isEmpty() || (scopedName.indexOf(':') == 0))
31 : {
32 78278 : return sal_True;
33 : }
34 941319 : return sal_False;
35 : }
36 :
37 442924 : AstScope::AstScope(NodeType nodeType)
38 442924 : : m_nodeType(nodeType)
39 : {
40 :
41 442924 : }
42 :
43 216174 : AstScope::~AstScope()
44 : {
45 :
46 216174 : }
47 :
48 545843 : AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
49 : {
50 545843 : AstDeclaration* pDeclaration = NULL;
51 :
52 545843 : if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
53 : {
54 7567 : if (pDecl->getNodeType() == NT_union_branch )
55 : {
56 0 : m_declarations.push_back(pDecl);
57 0 : return pDecl;
58 : }
59 7567 : if ( pDecl->hasAncestor(pDeclaration) )
60 : {
61 0 : idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
62 0 : return NULL;
63 : }
64 15262 : if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
65 7567 : (pDecl->getNodeType() == NT_sequence
66 64 : || pDecl->getNodeType() == NT_array
67 64 : || pDecl->getNodeType() == NT_instantiated_struct) )
68 : {
69 7567 : return pDeclaration;
70 : }
71 0 : if ( (pDeclaration->getNodeType() == NT_interface)
72 0 : && (pDecl->getNodeType() == NT_interface)
73 0 : && !((AstInterface*)pDeclaration)->isDefined() )
74 : {
75 0 : m_declarations.push_back(pDecl);
76 0 : return pDecl;
77 : }
78 0 : if ( (NT_service == m_nodeType) &&
79 0 : ( ((pDecl->getNodeType() == NT_interface_member)
80 0 : && (pDeclaration->getNodeType() == NT_interface)) ||
81 0 : ((pDecl->getNodeType() == NT_service_member)
82 0 : && (pDeclaration->getNodeType() == NT_service)) )
83 : )
84 : {
85 0 : m_declarations.push_back(pDecl);
86 0 : return pDecl;
87 : }
88 :
89 0 : idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
90 0 : return NULL;
91 : }
92 :
93 538276 : m_declarations.push_back(pDecl);
94 538276 : return pDecl;
95 : }
96 :
97 34296 : sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
98 : {
99 34296 : DeclList::const_iterator iter = getIteratorBegin();
100 34296 : DeclList::const_iterator end = getIteratorEnd();
101 34296 : AstDeclaration* pDecl = NULL;
102 34296 : sal_uInt16 count = 0;
103 :
104 229222 : while ( iter != end )
105 : {
106 160630 : pDecl = *iter;
107 160630 : if ( pDecl->getNodeType() == nodeType )
108 22030 : count++;
109 160630 : ++iter;
110 : }
111 34296 : return count;
112 : }
113 :
114 1019597 : AstDeclaration* AstScope::lookupByName(const OString& scopedName)
115 : {
116 1019597 : AstDeclaration* pDecl = NULL;
117 1019597 : AstScope* pScope = NULL;
118 1019597 : if (scopedName.isEmpty())
119 0 : return NULL;
120 :
121 : // If name starts with "::" start look up in global scope
122 1019597 : if ( isGlobal(scopedName) )
123 : {
124 78278 : pDecl = scopeAsDecl(this);
125 78278 : if ( !pDecl )
126 0 : return NULL;
127 :
128 78278 : pScope = pDecl->getScope();
129 : // If this is the global scope ...
130 78278 : if ( !pScope )
131 : {
132 : // look up the scopedName part after "::"
133 13063 : OString subName = scopedName.copy(2);
134 13063 : pDecl = lookupByName(subName);
135 13063 : return pDecl;
136 : //return pScope->lookupByName();
137 : }
138 : // OK, not global scope yet, so simply iterate with parent scope
139 65215 : pDecl = pScope->lookupByName(scopedName);
140 65215 : return pDecl;
141 : }
142 :
143 : // The name does not start with "::"
144 : // Look up in the local scope and start with the first scope
145 941319 : sal_Int32 nIndex = scopedName.indexOf(':');
146 941319 : OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
147 941319 : sal_Bool bFindFirstScope = sal_True;
148 941319 : pDecl = lookupByNameLocal(firstScope);
149 941319 : if ( !pDecl )
150 : {
151 741817 : bFindFirstScope = sal_False;
152 :
153 : // OK, not found. Go down parent scope chain
154 741817 : pDecl = scopeAsDecl(this);
155 741817 : if ( pDecl )
156 : {
157 741817 : pScope = pDecl->getScope();
158 741817 : if ( pScope )
159 741812 : pDecl = pScope->lookupByName(scopedName);
160 : else
161 5 : pDecl = NULL;
162 :
163 : // Special case for scope which is an interface. We
164 : // have to look in the inherited interfaces as well.
165 741817 : if ( !pDecl )
166 : {
167 133402 : if (m_nodeType == NT_interface)
168 0 : pDecl = lookupInInherited(scopedName);
169 : }
170 : }
171 : }
172 :
173 941319 : if ( bFindFirstScope && (firstScope != scopedName) )
174 : {
175 160706 : sal_Int32 i = 0;
176 160706 : sal_Int32 nOffset = 2;
177 610758 : do
178 : {
179 643960 : pScope = declAsScope(pDecl);
180 643960 : if( pScope )
181 : {
182 643960 : pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
183 643960 : nOffset = 1;
184 : }
185 643960 : if( !pDecl )
186 33202 : break;
187 : } while( i != -1 );
188 :
189 160706 : if ( !pDecl )
190 : {
191 : // last try if is not the global scope and the scopeName isn't specify global too
192 33202 : pDecl = scopeAsDecl(this);
193 33202 : if ( pDecl && (pDecl->getLocalName() != "") )
194 : {
195 0 : pScope = pDecl->getScope();
196 0 : if ( pScope )
197 0 : pDecl = pScope->lookupByName(scopedName);
198 : } else
199 : {
200 33202 : pDecl = NULL;
201 : }
202 : }
203 :
204 : }
205 :
206 941319 : return pDecl;
207 : }
208 :
209 2559279 : AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
210 : {
211 2559279 : DeclList::const_iterator iter(m_declarations.begin());
212 2559279 : DeclList::const_iterator end(m_declarations.end());
213 2559279 : AstDeclaration* pDecl = NULL;
214 :
215 17617335 : while ( iter != end )
216 : {
217 13709798 : pDecl = *iter;
218 13709798 : if ( pDecl->getLocalName() == name )
219 1211021 : return pDecl;
220 12498777 : ++iter;
221 : }
222 1348258 : return NULL;
223 : }
224 :
225 0 : AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
226 : {
227 0 : AstInterface* pInterface = (AstInterface*)this;
228 :
229 0 : if ( !pInterface )
230 0 : return NULL;
231 :
232 : // Can't look in an interface which was not yet defined
233 0 : if ( !pInterface->getScope() )
234 : {
235 0 : idlc()->error()->forwardLookupError(pInterface, scopedName);
236 : }
237 :
238 : // OK, loop through inherited interfaces. Stop when you find it
239 : AstInterface::InheritedInterfaces::const_iterator iter(
240 0 : pInterface->getAllInheritedInterfaces().begin());
241 : AstInterface::InheritedInterfaces::const_iterator end(
242 0 : pInterface->getAllInheritedInterfaces().end());
243 0 : while ( iter != end )
244 : {
245 0 : AstInterface const * resolved = iter->getResolved();
246 0 : AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
247 0 : if ( pDecl )
248 0 : return pDecl;
249 0 : pDecl = resolved->lookupInInherited(scopedName);
250 0 : if ( pDecl )
251 0 : return pDecl;
252 0 : ++iter;
253 : }
254 : // Not found
255 0 : return NULL;
256 : }
257 :
258 184158 : AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
259 : {
260 184158 : AstDeclaration* pDecl = NULL;
261 184158 : AstScope* pScope = NULL;
262 184158 : AstBaseType* pBaseType = NULL;
263 184158 : OString typeName;
264 184158 : pDecl = scopeAsDecl(this);
265 184158 : if ( !pDecl )
266 0 : return NULL;
267 184158 : pScope = pDecl->getScope();
268 184158 : if ( pScope)
269 0 : return pScope->lookupPrimitiveType(type);
270 :
271 184158 : switch (type)
272 : {
273 : case ET_none:
274 : OSL_ASSERT(false);
275 0 : break;
276 : case ET_short:
277 14449 : typeName = OString("short");
278 14449 : break;
279 : case ET_ushort:
280 3458 : typeName = OString("unsigned short");
281 3458 : break;
282 : case ET_long:
283 29353 : typeName = OString("long");
284 29353 : break;
285 : case ET_ulong:
286 4282 : typeName = OString("unsigned long");
287 4282 : break;
288 : case ET_hyper:
289 218 : typeName = OString("hyper");
290 218 : break;
291 : case ET_uhyper:
292 16 : typeName = OString("unsigned hyper");
293 16 : break;
294 : case ET_float:
295 1386 : typeName = OString("float");
296 1386 : break;
297 : case ET_double:
298 2496 : typeName = OString("double");
299 2496 : break;
300 : case ET_char:
301 906 : typeName = OString("char");
302 906 : break;
303 : case ET_byte:
304 1951 : typeName = OString("byte");
305 1951 : break;
306 : case ET_boolean:
307 18690 : typeName = OString("boolean");
308 18690 : break;
309 : case ET_any:
310 17036 : typeName = OString("any");
311 17036 : break;
312 : case ET_void:
313 43798 : typeName = OString("void");
314 43798 : break;
315 : case ET_type:
316 5572 : typeName = OString("type");
317 5572 : break;
318 : case ET_string:
319 40547 : typeName = OString("string");
320 40547 : break;
321 : }
322 :
323 184158 : pDecl = lookupByNameLocal(typeName);
324 :
325 184158 : if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
326 : {
327 184158 : pBaseType = (AstBaseType*)pDecl;
328 :
329 184158 : if ( pBaseType->getExprType() == type )
330 184158 : return pDecl;
331 : }
332 :
333 0 : return NULL;
334 : }
335 :
336 789842 : AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
337 : {
338 789842 : if ( !pDecl )
339 0 : return NULL;
340 :
341 789842 : AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
342 :
343 789842 : return pRetDecl;
344 : }
345 :
346 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|