xref: /trunk/main/idlc/source/astscope.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_idlc.hxx"
30 #include <idlc/astscope.hxx>
31 #include <idlc/astbasetype.hxx>
32 #ifndef _IDLC_ASTINERFACE_HXX_
33 #include <idlc/astinterface.hxx>
34 #endif
35 #include <idlc/errorhandler.hxx>
36 
37 
38 using namespace ::rtl;
39 
40 sal_Bool isGlobal(const OString& scopedName)
41 {
42     if ((scopedName.getLength() == 0) || (scopedName.indexOf(':') == 0))
43     {
44         return sal_True;
45     }
46     return sal_False;
47 }
48 
49 AstScope::AstScope(NodeType nodeType)
50     : m_nodeType(nodeType)
51 {
52 
53 }
54 
55 AstScope::~AstScope()
56 {
57 
58 }
59 
60 AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl)
61 {
62     AstDeclaration* pDeclaration = NULL;
63 
64     if ((pDeclaration = lookupForAdd(pDecl)) != NULL)
65     {
66         if (pDecl->getNodeType() == NT_union_branch )
67         {
68             m_declarations.push_back(pDecl);
69             return pDecl;
70         }
71         if ( pDecl->hasAncestor(pDeclaration) )
72         {
73             idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration);
74             return NULL;
75         }
76         if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) &&
77              (pDecl->getNodeType() == NT_sequence
78               || pDecl->getNodeType() == NT_array
79               || pDecl->getNodeType() == NT_instantiated_struct) )
80         {
81             return pDeclaration;
82         }
83         if ( (pDeclaration->getNodeType() == NT_interface)
84              && (pDecl->getNodeType() == NT_interface)
85              && !((AstInterface*)pDeclaration)->isDefined() )
86         {
87             m_declarations.push_back(pDecl);
88             return pDecl;
89         }
90         if ( (NT_service == m_nodeType) &&
91              ( ((pDecl->getNodeType() == NT_interface_member)
92                 && (pDeclaration->getNodeType() == NT_interface)) ||
93                ((pDecl->getNodeType() == NT_service_member)
94                 && (pDeclaration->getNodeType() == NT_service)) )
95             )
96         {
97             m_declarations.push_back(pDecl);
98             return pDecl;
99         }
100 
101         idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl);
102         return NULL;
103     }
104 
105     m_declarations.push_back(pDecl);
106     return pDecl;
107 }
108 
109 sal_uInt16 AstScope::getNodeCount(NodeType nodeType)
110 {
111     DeclList::const_iterator iter = getIteratorBegin();
112     DeclList::const_iterator end = getIteratorEnd();
113     AstDeclaration* pDecl = NULL;
114     sal_uInt16 count = 0;
115 
116     while ( iter != end )
117     {
118         pDecl = *iter;
119         if ( pDecl->getNodeType() == nodeType )
120             count++;
121         ++iter;
122     }
123     return count;
124 }
125 
126 AstDeclaration* AstScope::lookupByName(const OString& scopedName)
127 {
128     AstDeclaration* pDecl = NULL;
129     AstScope*       pScope = NULL;
130     if (scopedName.getLength() == 0)
131         return NULL;
132 
133     // If name starts with "::" start look up in global scope
134     if ( isGlobal(scopedName) )
135     {
136         pDecl = scopeAsDecl(this);
137         if ( !pDecl )
138             return NULL;
139 
140         pScope = pDecl->getScope();
141         // If this is the global scope ...
142         if ( !pScope )
143         {
144             // look up the scopedName part after "::"
145             OString subName = scopedName.copy(2);
146             pDecl = lookupByName(subName);
147             return pDecl;
148             //return pScope->lookupByName();
149         }
150         // OK, not global scope yet, so simply iterate with parent scope
151         pDecl = pScope->lookupByName(scopedName);
152         return pDecl;
153     }
154 
155     // The name does not start with "::"
156     // Look up in the local scope and start with the first scope
157     sal_Int32 nIndex = scopedName.indexOf(':');
158     OString firstScope =  nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName;
159     sal_Bool    bFindFirstScope = sal_True;
160     pDecl = lookupByNameLocal(firstScope);
161     if ( !pDecl )
162     {
163         bFindFirstScope = sal_False;
164 
165         // OK, not found. Go down parent scope chain
166         pDecl = scopeAsDecl(this);
167         if ( pDecl )
168         {
169             pScope = pDecl->getScope();
170             if ( pScope )
171                 pDecl = pScope->lookupByName(scopedName);
172             else
173                 pDecl = NULL;
174 
175             // Special case for scope which is an interface. We
176             // have to look in the inherited interfaces as well.
177             if ( !pDecl )
178             {
179                 if (m_nodeType == NT_interface)
180                     pDecl = lookupInInherited(scopedName);
181             }
182        }
183     }
184 
185     if ( bFindFirstScope && (firstScope != scopedName) )
186     {
187         sal_Int32 i = 0;
188         sal_Int32 nOffset = 2;
189         do
190         {
191             pScope = declAsScope(pDecl);
192             if( pScope )
193             {
194                 pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i ));
195                 nOffset = 1;
196             }
197             if( !pDecl )
198                 break;
199         } while( i != -1 );
200 
201         if ( !pDecl )
202         {
203             // last try if is not the global scope and the scopeName isn't specify global too
204             pDecl = scopeAsDecl(this);
205             if ( pDecl && (pDecl->getLocalName() != "") )
206             {
207                 pScope = pDecl->getScope();
208                 if ( pScope )
209                     pDecl = pScope->lookupByName(scopedName);
210             } else
211             {
212                 pDecl = NULL;
213             }
214         }
215 
216     }
217 
218     return pDecl;
219 }
220 
221 AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const
222 {
223     DeclList::const_iterator iter(m_declarations.begin());
224     DeclList::const_iterator end(m_declarations.end());
225     AstDeclaration* pDecl = NULL;
226 
227     while ( iter != end )
228     {
229         pDecl = *iter;
230         if ( pDecl->getLocalName() == name )
231             return pDecl;
232         ++iter;
233     }
234     return NULL;
235 }
236 
237 AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const
238 {
239     AstInterface* pInterface = (AstInterface*)this;
240 
241     if ( !pInterface )
242         return NULL;
243 
244     // Can't look in an interface which was not yet defined
245     if ( !pInterface->getScope() )
246     {
247         idlc()->error()->forwardLookupError(pInterface, scopedName);
248     }
249 
250     // OK, loop through inherited interfaces. Stop when you find it
251     AstInterface::InheritedInterfaces::const_iterator iter(
252         pInterface->getAllInheritedInterfaces().begin());
253     AstInterface::InheritedInterfaces::const_iterator end(
254         pInterface->getAllInheritedInterfaces().end());
255     while ( iter != end )
256     {
257         AstInterface const * resolved = iter->getResolved();
258         AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName);
259         if ( pDecl )
260             return pDecl;
261         pDecl = resolved->lookupInInherited(scopedName);
262         if ( pDecl )
263             return pDecl;
264         ++iter;
265     }
266     // Not found
267     return NULL;
268 }
269 
270 AstDeclaration* AstScope::lookupPrimitiveType(ExprType type)
271 {
272     AstDeclaration* pDecl = NULL;
273     AstScope*       pScope = NULL;
274     AstBaseType*    pBaseType = NULL;
275     OString         typeName;
276     pDecl = scopeAsDecl(this);
277     if ( !pDecl )
278         return NULL;
279     pScope = pDecl->getScope();
280     if ( pScope)
281         return pScope->lookupPrimitiveType(type);
282 
283     switch (type)
284     {
285         case ET_none:
286             OSL_ASSERT(false);
287             break;
288         case ET_short:
289             typeName = OString("short");
290             break;
291         case ET_ushort:
292             typeName = OString("unsigned short");
293             break;
294         case ET_long:
295             typeName = OString("long");
296             break;
297         case ET_ulong:
298             typeName = OString("unsigned long");
299             break;
300         case ET_hyper:
301             typeName = OString("hyper");
302             break;
303         case ET_uhyper:
304             typeName = OString("unsigned hyper");
305             break;
306         case ET_float:
307             typeName = OString("float");
308             break;
309         case ET_double:
310             typeName = OString("double");
311             break;
312         case ET_char:
313             typeName = OString("char");
314             break;
315         case ET_byte:
316             typeName = OString("byte");
317             break;
318         case ET_boolean:
319             typeName = OString("boolean");
320             break;
321         case ET_any:
322             typeName = OString("any");
323             break;
324         case ET_void:
325             typeName = OString("void");
326             break;
327         case ET_type:
328             typeName = OString("type");
329             break;
330         case ET_string:
331             typeName = OString("string");
332             break;
333     }
334 
335     pDecl = lookupByNameLocal(typeName);
336 
337     if ( pDecl && (pDecl->getNodeType() == NT_predefined) )
338     {
339         pBaseType = (AstBaseType*)pDecl;
340 
341         if ( pBaseType->getExprType() == type )
342             return pDecl;
343     }
344 
345     return NULL;
346 }
347 
348 AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl)
349 {
350     if ( !pDecl )
351         return NULL;
352 
353     AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName());
354 
355    return pRetDecl;
356 }
357