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 1077003 : sal_Bool isGlobal(const OString& scopedName)
29 : {
30 1077003 : if (scopedName.isEmpty() || (scopedName.indexOf(':') == 0))
31 : {
32 90220 : return sal_True;
33 : }
34 986783 : return sal_False;
35 : }
36 :
37 466258 : AstScope::AstScope(NodeType nodeType)
38 466258 : : m_nodeType(nodeType)
39 : {
40 :
41 466258 : }
42 :
43 226421 : AstScope::~AstScope()
44 : {
45 :
46 226421 : }
47 :
48 580709 : AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
49 : {
50 580709 : AstDeclaration* pDeclaration = NULL;
51 :
52 580709 : if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
53 : {
54 7932 : if (pDecl->getNodeType() == NT_union_branch )
55 : {
56 0 : m_declarations.push_back(pDecl);
57 0 : return pDecl;
58 : }
59 7932 : if ( pDecl->hasAncestor(pDeclaration) )
60 : {
61 0 : idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
62 0 : return NULL;
63 : }
64 23794 : if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
65 7932 : (pDecl->getNodeType() == NT_sequence
66 66 : || pDecl->getNodeType() == NT_array
67 66 : || pDecl->getNodeType() == NT_instantiated_struct) )
68 : {
69 7930 : return pDeclaration;
70 : }
71 4 : if ( (pDeclaration->getNodeType() == NT_interface)
72 0 : && (pDecl->getNodeType() == NT_interface)
73 2 : && !((AstInterface*)pDeclaration)->isDefined() )
74 : {
75 0 : m_declarations.push_back(pDecl);
76 0 : return pDecl;
77 : }
78 3 : if ( (NT_service == m_nodeType) &&
79 1 : ( ((pDecl->getNodeType() == NT_interface_member)
80 1 : && (pDeclaration->getNodeType() == NT_interface)) ||
81 1 : ((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 2 : idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
90 2 : return NULL;
91 : }
92 :
93 572777 : m_declarations.push_back(pDecl);
94 572777 : return pDecl;
95 : }
96 :
97 35329 : sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
98 : {
99 35329 : DeclList::const_iterator iter = getIteratorBegin();
100 35329 : DeclList::const_iterator end = getIteratorEnd();
101 35329 : AstDeclaration* pDecl = NULL;
102 35329 : sal_uInt16 count = 0;
103 :
104 237918 : while ( iter != end )
105 : {
106 167260 : pDecl = *iter;
107 167260 : if ( pDecl->getNodeType() == nodeType )
108 22450 : count++;
109 167260 : ++iter;
110 : }
111 35329 : return count;
112 : }
113 :
114 1077003 : AstDeclaration* AstScope::lookupByName(const OString& scopedName)
115 : {
116 1077003 : AstDeclaration* pDecl = NULL;
117 1077003 : AstScope* pScope = NULL;
118 1077003 : if (scopedName.isEmpty())
119 0 : return NULL;
120 :
121 : // If name starts with "::" start look up in global scope
122 1077003 : if ( isGlobal(scopedName) )
123 : {
124 90220 : pDecl = scopeAsDecl(this);
125 90220 : if ( !pDecl )
126 0 : return NULL;
127 :
128 90220 : pScope = pDecl->getScope();
129 : // If this is the global scope ...
130 90220 : if ( !pScope )
131 : {
132 : // look up the scopedName part after "::"
133 15135 : OString subName = scopedName.copy(2);
134 15135 : pDecl = lookupByName(subName);
135 15135 : return pDecl;
136 : //return pScope->lookupByName();
137 : }
138 : // OK, not global scope yet, so simply iterate with parent scope
139 75085 : pDecl = pScope->lookupByName(scopedName);
140 75085 : 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 986783 : sal_Int32 nIndex = scopedName.indexOf(':');
146 986783 : OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
147 986783 : sal_Bool bFindFirstScope = sal_True;
148 986783 : pDecl = lookupByNameLocal(firstScope);
149 986783 : if ( !pDecl )
150 : {
151 776090 : bFindFirstScope = sal_False;
152 :
153 : // OK, not found. Go down parent scope chain
154 776090 : pDecl = scopeAsDecl(this);
155 776090 : if ( pDecl )
156 : {
157 776090 : pScope = pDecl->getScope();
158 776090 : if ( pScope )
159 775878 : pDecl = pScope->lookupByName(scopedName);
160 : else
161 212 : pDecl = NULL;
162 :
163 : // Special case for scope which is an interface. We
164 : // have to look in the inherited interfaces as well.
165 776090 : if ( !pDecl )
166 : {
167 139916 : if (m_nodeType == NT_interface)
168 0 : pDecl = lookupInInherited(scopedName);
169 : }
170 : }
171 : }
172 :
173 986783 : if ( bFindFirstScope && (firstScope != scopedName) )
174 : {
175 169410 : sal_Int32 i = 0;
176 169410 : sal_Int32 nOffset = 2;
177 644207 : do
178 : {
179 678957 : pScope = declAsScope(pDecl);
180 678957 : if( pScope )
181 : {
182 678957 : pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
183 678957 : nOffset = 1;
184 : }
185 678957 : if( !pDecl )
186 34750 : break;
187 644207 : } while( i != -1 );
188 :
189 169410 : if ( !pDecl )
190 : {
191 : // last try if is not the global scope and the scopeName isn't specify global too
192 34750 : pDecl = scopeAsDecl(this);
193 34750 : if ( pDecl && (pDecl->getLocalName() != "") )
194 : {
195 0 : pScope = pDecl->getScope();
196 0 : if ( pScope )
197 0 : pDecl = pScope->lookupByName(scopedName);
198 : } else
199 : {
200 34750 : pDecl = NULL;
201 : }
202 : }
203 :
204 : }
205 :
206 986783 : return pDecl;
207 : }
208 :
209 2695470 : AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
210 : {
211 2695470 : DeclList::const_iterator iter(m_declarations.begin());
212 2695470 : DeclList::const_iterator end(m_declarations.end());
213 2695470 : AstDeclaration* pDecl = NULL;
214 :
215 18550724 : while ( iter != end )
216 : {
217 14435553 : pDecl = *iter;
218 14435553 : if ( pDecl->getLocalName() == name )
219 1275769 : return pDecl;
220 13159784 : ++iter;
221 : }
222 1419701 : 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 194163 : AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
259 : {
260 194163 : AstDeclaration* pDecl = NULL;
261 194163 : AstScope* pScope = NULL;
262 194163 : OString typeName;
263 194163 : pDecl = scopeAsDecl(this);
264 194163 : if ( !pDecl )
265 0 : return NULL;
266 194163 : pScope = pDecl->getScope();
267 194163 : if ( pScope)
268 0 : return pScope->lookupPrimitiveType(type);
269 :
270 194163 : switch (type)
271 : {
272 : case ET_none:
273 : OSL_ASSERT(false);
274 0 : break;
275 : case ET_short:
276 15185 : typeName = OString("short");
277 15185 : break;
278 : case ET_ushort:
279 3427 : typeName = OString("unsigned short");
280 3427 : break;
281 : case ET_long:
282 30545 : typeName = OString("long");
283 30545 : break;
284 : case ET_ulong:
285 4591 : typeName = OString("unsigned long");
286 4591 : break;
287 : case ET_hyper:
288 229 : typeName = OString("hyper");
289 229 : break;
290 : case ET_uhyper:
291 19 : typeName = OString("unsigned hyper");
292 19 : break;
293 : case ET_float:
294 1405 : typeName = OString("float");
295 1405 : break;
296 : case ET_double:
297 2691 : typeName = OString("double");
298 2691 : break;
299 : case ET_char:
300 943 : typeName = OString("char");
301 943 : break;
302 : case ET_byte:
303 2071 : typeName = OString("byte");
304 2071 : break;
305 : case ET_boolean:
306 19445 : typeName = OString("boolean");
307 19445 : break;
308 : case ET_any:
309 18118 : typeName = OString("any");
310 18118 : break;
311 : case ET_void:
312 46610 : typeName = OString("void");
313 46610 : break;
314 : case ET_type:
315 6082 : typeName = OString("type");
316 6082 : break;
317 : case ET_string:
318 42802 : typeName = OString("string");
319 42802 : break;
320 : }
321 :
322 194163 : pDecl = lookupByNameLocal(typeName);
323 :
324 194163 : if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
325 : {
326 194163 : AstBaseType* pBaseType = (AstBaseType*)pDecl;
327 :
328 194163 : if ( pBaseType->getExprType() == type )
329 194163 : return pDecl;
330 : }
331 :
332 0 : return NULL;
333 : }
334 :
335 835567 : AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
336 : {
337 835567 : if ( !pDecl )
338 0 : return NULL;
339 :
340 835567 : AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
341 :
342 835567 : return pRetDecl;
343 : }
344 :
345 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|