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