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