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