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