1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <idlc/astscope.hxx>
21 #include <idlc/astbasetype.hxx>
22 #include <idlc/astinterface.hxx>
23 #include <idlc/errorhandler.hxx>
26 using namespace ::rtl
;
28 bool isGlobal(const OString
& scopedName
)
30 return scopedName
.isEmpty() || scopedName
.startsWith(":");
33 AstScope::AstScope(NodeType nodeType
)
34 : m_nodeType(nodeType
)
44 AstDeclaration
* AstScope::addDeclaration(AstDeclaration
* pDecl
)
46 AstDeclaration
* pDeclaration
= NULL
;
48 if ((pDeclaration
= lookupForAdd(pDecl
)) != NULL
)
50 if ( pDecl
->hasAncestor(pDeclaration
) )
52 idlc()->error()->error2(EIDL_REDEF_SCOPE
, pDecl
, pDeclaration
);
55 if ( (pDecl
->getNodeType() == pDeclaration
->getNodeType()) &&
56 (pDecl
->getNodeType() == NT_sequence
57 || pDecl
->getNodeType() == NT_instantiated_struct
) )
61 if ( (pDeclaration
->getNodeType() == NT_interface
)
62 && (pDecl
->getNodeType() == NT_interface
)
63 && !((AstInterface
*)pDeclaration
)->isDefined() )
65 m_declarations
.push_back(pDecl
);
68 if ( (NT_service
== m_nodeType
) &&
69 ( ((pDecl
->getNodeType() == NT_interface_member
)
70 && (pDeclaration
->getNodeType() == NT_interface
)) ||
71 ((pDecl
->getNodeType() == NT_service_member
)
72 && (pDeclaration
->getNodeType() == NT_service
)) )
75 m_declarations
.push_back(pDecl
);
79 idlc()->error()->error2(EIDL_REDEF_SCOPE
, scopeAsDecl(this), pDecl
);
83 m_declarations
.push_back(pDecl
);
87 sal_uInt16
AstScope::getNodeCount(NodeType nodeType
)
89 DeclList::const_iterator iter
= getIteratorBegin();
90 DeclList::const_iterator end
= getIteratorEnd();
91 AstDeclaration
* pDecl
= NULL
;
97 if ( pDecl
->getNodeType() == nodeType
)
104 AstDeclaration
* AstScope::lookupByName(const OString
& scopedName
)
106 AstDeclaration
* pDecl
= NULL
;
107 AstScope
* pScope
= NULL
;
108 if (scopedName
.isEmpty())
111 // If name starts with "::" start look up in global scope
112 if ( isGlobal(scopedName
) )
114 pDecl
= scopeAsDecl(this);
118 pScope
= pDecl
->getScope();
119 // If this is the global scope ...
122 // look up the scopedName part after "::"
123 OString subName
= scopedName
.copy(2);
124 pDecl
= lookupByName(subName
);
126 //return pScope->lookupByName();
128 // OK, not global scope yet, so simply iterate with parent scope
129 pDecl
= pScope
->lookupByName(scopedName
);
133 // The name does not start with "::"
134 // Look up in the local scope and start with the first scope
135 sal_Int32 nIndex
= scopedName
.indexOf(':');
136 OString firstScope
= nIndex
> 0 ? scopedName
.copy(0, nIndex
) : scopedName
;
137 bool bFindFirstScope
= true;
138 pDecl
= lookupByNameLocal(firstScope
);
141 bFindFirstScope
= false;
143 // OK, not found. Go down parent scope chain
144 pDecl
= scopeAsDecl(this);
147 pScope
= pDecl
->getScope();
149 pDecl
= pScope
->lookupByName(scopedName
);
153 // Special case for scope which is an interface. We
154 // have to look in the inherited interfaces as well.
157 if (m_nodeType
== NT_interface
)
158 pDecl
= lookupInInherited(scopedName
);
163 if ( bFindFirstScope
&& (firstScope
!= scopedName
) )
166 sal_Int32 nOffset
= 2;
169 pScope
= declAsScope(pDecl
);
172 pDecl
= pScope
->lookupByNameLocal(scopedName
.getToken(nOffset
, ':', i
));
181 // last try if is not the global scope and the scopeName isn't specify global too
182 pDecl
= scopeAsDecl(this);
183 if ( pDecl
&& (pDecl
->getLocalName() != "") )
185 pScope
= pDecl
->getScope();
187 pDecl
= pScope
->lookupByName(scopedName
);
199 AstDeclaration
* AstScope::lookupByNameLocal(const OString
& name
) const
201 DeclList::const_iterator
iter(m_declarations
.begin());
202 DeclList::const_iterator
end(m_declarations
.end());
203 AstDeclaration
* pDecl
= NULL
;
205 while ( iter
!= end
)
208 if ( pDecl
->getLocalName() == name
)
215 AstDeclaration
* AstScope::lookupInInherited(const OString
& scopedName
) const
217 AstInterface
* pInterface
= (AstInterface
*)this;
222 // Can't look in an interface which was not yet defined
223 if ( !pInterface
->getScope() )
225 idlc()->error()->forwardLookupError(pInterface
, scopedName
);
228 // OK, loop through inherited interfaces. Stop when you find it
229 AstInterface::InheritedInterfaces::const_iterator
iter(
230 pInterface
->getAllInheritedInterfaces().begin());
231 AstInterface::InheritedInterfaces::const_iterator
end(
232 pInterface
->getAllInheritedInterfaces().end());
233 while ( iter
!= end
)
235 AstInterface
const * resolved
= iter
->getResolved();
236 AstDeclaration
* pDecl
= resolved
->lookupByNameLocal(scopedName
);
239 pDecl
= resolved
->lookupInInherited(scopedName
);
248 AstDeclaration
* AstScope::lookupPrimitiveType(ExprType type
)
250 AstDeclaration
* pDecl
= NULL
;
251 AstScope
* pScope
= NULL
;
253 pDecl
= scopeAsDecl(this);
256 pScope
= pDecl
->getScope();
258 return pScope
->lookupPrimitiveType(type
);
266 typeName
= OString("short");
269 typeName
= OString("unsigned short");
272 typeName
= OString("long");
275 typeName
= OString("unsigned long");
278 typeName
= OString("hyper");
281 typeName
= OString("unsigned hyper");
284 typeName
= OString("float");
287 typeName
= OString("double");
290 typeName
= OString("char");
293 typeName
= OString("byte");
296 typeName
= OString("boolean");
299 typeName
= OString("any");
302 typeName
= OString("void");
305 typeName
= OString("type");
308 typeName
= OString("string");
312 pDecl
= lookupByNameLocal(typeName
);
314 if ( pDecl
&& (pDecl
->getNodeType() == NT_predefined
) )
316 AstBaseType
* pBaseType
= (AstBaseType
*)pDecl
;
318 if ( pBaseType
->getExprType() == type
)
325 AstDeclaration
* AstScope::lookupForAdd(AstDeclaration
* pDecl
)
330 AstDeclaration
* pRetDecl
= lookupByNameLocal(pDecl
->getLocalName());
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */