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