xref: /trunk/main/idlc/source/idlc.cxx (revision cdf0e10c)
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/idlc.hxx>
31 #include <idlc/errorhandler.hxx>
32 #include <idlc/astscope.hxx>
33 #include <idlc/astmodule.hxx>
34 #include <idlc/astservice.hxx>
35 #include <idlc/astconstants.hxx>
36 #include <idlc/astexception.hxx>
37 #include <idlc/astunion.hxx>
38 #include <idlc/astenum.hxx>
39 #include <idlc/astinterface.hxx>
40 #include <idlc/astoperation.hxx>
41 #include <idlc/astbasetype.hxx>
42 #include "idlc/astdeclaration.hxx"
43 #include "idlc/astparameter.hxx"
44 #include "idlc/astsequence.hxx"
45 #include "idlc/asttype.hxx"
46 #include "idlc/asttypedef.hxx"
47 
48 #include "osl/diagnose.h"
49 
50 using namespace ::rtl;
51 
52 AstDeclaration* SAL_CALL scopeAsDecl(AstScope* pScope)
53 {
54 	if (pScope == NULL) return NULL;
55 
56 	switch( pScope->getScopeNodeType() )
57 	{
58 		case NT_service:
59 		case NT_singleton:
60 			return (AstService*)(pScope);
61 		case NT_module:
62 		case NT_root:
63 			return (AstModule*)(pScope);
64 		case NT_constants:
65 			return (AstConstants*)(pScope);
66 		case NT_interface:
67 			return (AstInterface*)(pScope);
68 		case NT_operation:
69 			return (AstOperation*)(pScope);
70 		case NT_exception:
71 			return (AstException*)(pScope);
72 		case NT_union:
73 			return (AstUnion*)(pScope);
74 		case NT_struct:
75 			return (AstStruct*)(pScope);
76 		case NT_enum:
77 			return (AstEnum*)(pScope);
78 		default:
79 			return NULL;
80 	}
81 }
82 
83 AstScope* SAL_CALL declAsScope(AstDeclaration* pDecl)
84 {
85 	if (pDecl == NULL) return NULL;
86 
87 	switch(pDecl->getNodeType())
88 	{
89 		case NT_interface:
90 			return (AstInterface*)(pDecl);
91 		case NT_service:
92 		case NT_singleton:
93 			return (AstService*)(pDecl);
94 		case NT_module:
95 		case NT_root:
96 			return (AstModule*)(pDecl);
97 		case NT_constants:
98 			return (AstConstants*)(pDecl);
99 		case NT_exception:
100 			return (AstException*)(pDecl);
101 		case NT_union:
102 			return (AstUnion*)(pDecl);
103 		case NT_struct:
104 			return (AstStruct*)(pDecl);
105 		case NT_enum:
106 			return (AstEnum*)(pDecl);
107 		case NT_operation:
108 			return (AstOperation*)(pDecl);
109 		default:
110 			return NULL;
111    }
112 }
113 
114 static void SAL_CALL predefineXInterface(AstModule* pRoot)
115 {
116     // define the modules  com::sun::star::uno
117     AstModule* pParentScope = pRoot;
118     AstModule* pModule = new AstModule(OString("com"), pParentScope);
119     pModule->setPredefined(true);
120     pParentScope->addDeclaration(pModule);
121     pParentScope = pModule;
122     pModule = new AstModule(OString("sun"), pParentScope);
123     pModule->setPredefined(true);
124     pParentScope->addDeclaration(pModule);
125     pParentScope = pModule;
126     pModule = new AstModule(OString("star"), pParentScope);
127     pModule->setPredefined(true);
128     pParentScope->addDeclaration(pModule);
129     pParentScope = pModule;
130     pModule = new AstModule(OString("uno"), pParentScope);
131     pModule->setPredefined(true);
132     pParentScope->addDeclaration(pModule);
133     pParentScope = pModule;
134 
135     // define XInterface
136     AstInterface* pInterface = new AstInterface(OString("XInterface"), NULL, pParentScope);
137     pInterface->setDefined();
138     pInterface->setPredefined(true);
139     pInterface->setPublished();
140     pParentScope->addDeclaration(pInterface);
141 
142     // define XInterface::queryInterface
143     AstOperation* pOp = new AstOperation(0, (AstType*)(pRoot->lookupPrimitiveType(ET_any)),
144                                          OString("queryInterface"), pInterface);
145     AstParameter* pParam = new AstParameter(DIR_IN, false,
146                                             (AstType*)(pRoot->lookupPrimitiveType(ET_type)),
147                                             OString("aType"), pOp);
148     pOp->addDeclaration(pParam);
149     pInterface->addMember(pOp);
150 
151     // define XInterface::acquire
152     pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)),
153                                          OString("acquire"), pInterface);
154     pInterface->addMember(pOp);
155 
156     // define XInterface::release
157     pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)),
158                                          OString("release"), pInterface);
159     pInterface->addMember(pOp);
160 }
161 
162 static void SAL_CALL initializePredefinedTypes(AstModule* pRoot)
163 {
164 	AstBaseType* pPredefined = NULL;
165 	if ( pRoot )
166 	{
167 		 pPredefined = new AstBaseType(ET_long, OString("long"), pRoot);
168 		 pRoot->addDeclaration(pPredefined);
169 
170 		 pPredefined = new AstBaseType(ET_ulong, OString("unsigned long"), pRoot);
171 		 pRoot->addDeclaration(pPredefined);
172 
173 		 pPredefined = new AstBaseType(ET_hyper, OString("hyper"), pRoot);
174 		 pRoot->addDeclaration(pPredefined);
175 
176 		 pPredefined = new AstBaseType(ET_uhyper, OString("unsigned hyper"), pRoot);
177 		 pRoot->addDeclaration(pPredefined);
178 
179 		 pPredefined = new AstBaseType(ET_short, OString("short"), pRoot);
180 		 pRoot->addDeclaration(pPredefined);
181 
182 		 pPredefined = new AstBaseType(ET_ushort, OString("unsigned short"), pRoot);
183 		 pRoot->addDeclaration(pPredefined);
184 
185 		 pPredefined = new AstBaseType(ET_float, OString("float"), pRoot);
186 		 pRoot->addDeclaration(pPredefined);
187 
188 		 pPredefined = new AstBaseType(ET_double, OString("double"), pRoot);
189 		 pRoot->addDeclaration(pPredefined);
190 
191 		 pPredefined = new AstBaseType(ET_char, OString("char"), pRoot);
192 		 pRoot->addDeclaration(pPredefined);
193 
194 		 pPredefined = new AstBaseType(ET_byte, OString("byte"), pRoot);
195 		 pRoot->addDeclaration(pPredefined);
196 
197 		 pPredefined = new AstBaseType(ET_any, OString("any"), pRoot);
198 		 pRoot->addDeclaration(pPredefined);
199 
200 		 pPredefined = new AstBaseType(ET_string, OString("string"), pRoot);
201 		 pRoot->addDeclaration(pPredefined);
202 
203 		 pPredefined = new AstBaseType(ET_type, OString("type"), pRoot);
204 		 pRoot->addDeclaration(pPredefined);
205 
206 		 pPredefined = new AstBaseType(ET_boolean, OString("boolean"), pRoot);
207 		 pRoot->addDeclaration(pPredefined);
208 
209 		 pPredefined = new AstBaseType(ET_void, OString("void"), pRoot);
210 		 pRoot->addDeclaration(pPredefined);
211 	}
212 }
213 
214 Idlc::Idlc(Options* pOptions)
215 	: m_pOptions(pOptions)
216 	, m_bIsDocValid(sal_False)
217 	, m_bIsInMainfile(sal_True)
218 	, m_published(false)
219 	, m_errorCount(0)
220 	, m_warningCount(0)
221 	, m_lineNumber(0)
222 	, m_parseState(PS_NoState)
223 {
224 	m_pScopes = new AstStack();
225 	// init root object after construction
226 	m_pRoot = NULL;
227 	m_pErrorHandler = new ErrorHandler();
228 	m_bGenerateDoc = m_pOptions->isValid("-C");
229 }
230 
231 Idlc::~Idlc()
232 {
233 	if (m_pRoot)
234 		delete m_pRoot;
235 	if (m_pScopes)
236 		delete m_pScopes;
237 	if (m_pErrorHandler)
238 		delete m_pErrorHandler;
239 }
240 
241 void Idlc::init()
242 {
243 	if ( m_pRoot )
244 		delete m_pRoot;
245 
246 	m_pRoot = new AstModule(NT_root, OString(), NULL);
247 
248 	// push the root node on the stack
249 	m_pScopes->push(m_pRoot);
250 	initializePredefinedTypes(m_pRoot);
251     predefineXInterface(m_pRoot);
252 }
253 
254 void Idlc::reset()
255 {
256 	m_bIsDocValid = sal_False;
257 	m_bIsInMainfile = sal_True;
258     m_published = false;
259 
260 	m_errorCount = 0;
261 	m_warningCount = 0;
262 	m_lineNumber = 0;
263 	m_parseState = PS_NoState;
264 
265 	m_fileName = OString();
266 	m_mainFileName = OString();
267 	m_realFileName = OString();
268 	m_documentation = OString();
269 
270 	m_pScopes->clear();
271 	if ( m_pRoot)
272 		delete m_pRoot;
273 
274 	m_pRoot = new AstModule(NT_root, OString(), NULL);
275 
276 	// push the root node on the stack
277 	m_pScopes->push(m_pRoot);
278 	initializePredefinedTypes(m_pRoot);
279 }
280 
281 sal_Bool Idlc::isDocValid()
282 {
283 	if ( m_bGenerateDoc )
284 		return m_bIsDocValid;
285 	return sal_False;;
286 }
287 
288 static Idlc* pStaticIdlc = NULL;
289 
290 Idlc* SAL_CALL idlc()
291 {
292 	return pStaticIdlc;
293 }
294 
295 Idlc* SAL_CALL setIdlc(Options* pOptions)
296 {
297 	if ( pStaticIdlc )
298 	{
299 		delete pStaticIdlc;
300 	}
301 	pStaticIdlc = new Idlc(pOptions);
302 	pStaticIdlc->init();
303 	return pStaticIdlc;
304 }
305 
306 AstDeclaration const * resolveTypedefs(AstDeclaration const * type) {
307     if (type != 0) {
308         while (type->getNodeType() == NT_typedef) {
309             type = static_cast< AstTypeDef const * >(type)->getBaseType();
310         }
311     }
312     return type;
313 }
314 
315 AstDeclaration const * deconstructAndResolveTypedefs(
316     AstDeclaration const * type, sal_Int32 * rank)
317 {
318     *rank = 0;
319     for (;;) {
320         if (type == 0) {
321             return 0;
322         }
323         switch (type->getNodeType()) {
324         case NT_typedef:
325             type = static_cast< AstTypeDef const * >(type)->getBaseType();
326             break;
327         case NT_sequence:
328             ++(*rank);
329             type = static_cast< AstSequence const * >(type)->getMemberType();
330             break;
331         default:
332             return type;
333         }
334     }
335 }
336 
337 AstInterface const * resolveInterfaceTypedefs(AstType const * type) {
338     AstDeclaration const * decl = resolveTypedefs(type);
339     OSL_ASSERT(decl->getNodeType() == NT_interface);
340     return static_cast< AstInterface const * >(decl);
341 }
342