xref: /aoo4110/main/idlc/source/astscope.cxx (revision b1cdbd2c)
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