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 #include <osl/interlck.h> 29 #include <rtl/alloc.h> 30 #include <codemaker/dependency.hxx> 31 32 using namespace rtl; 33 34 TypeDependency::TypeDependency() 35 { 36 m_pImpl = new TypeDependencyImpl(); 37 acquire(); 38 } 39 40 TypeDependency::~TypeDependency() 41 { 42 release(); 43 } 44 45 void TypeDependency::acquire() 46 { 47 osl_incrementInterlockedCount(&m_pImpl->m_refCount); 48 } 49 50 void TypeDependency::release() 51 { 52 if (0 == osl_decrementInterlockedCount(&m_pImpl->m_refCount)) 53 { 54 delete m_pImpl; 55 } 56 } 57 58 sal_Bool TypeDependency::insert(const OString& type, const OString& depend, sal_uInt16 use) 59 { 60 sal_Bool ret = sal_False; 61 62 if (type.getLength() > 0 && depend.getLength() > 0) 63 { 64 if (m_pImpl->m_dependencies.count(type) > 0) 65 { 66 TypeUsing typeUsing(depend, use); 67 TypeUsingSet::iterator iter; 68 if ((iter = m_pImpl->m_dependencies[type].find(typeUsing)) != m_pImpl->m_dependencies[type].end()) 69 { 70 (((TypeUsing *) &(*iter))->m_use) = (*iter).m_use | use; 71 } else 72 { 73 m_pImpl->m_dependencies[type].insert(typeUsing); 74 } 75 } else 76 { 77 TypeUsing typeUsing(depend, use); 78 TypeUsingSet tmpSet; 79 tmpSet.insert(typeUsing); 80 m_pImpl->m_dependencies[type]=tmpSet; 81 } 82 } 83 84 return ret; 85 } 86 87 TypeUsingSet TypeDependency::getDependencies(const OString& type) 88 { 89 if (type.getLength() > 0) 90 { 91 if (m_pImpl->m_dependencies.count(type) > 0) 92 { 93 return m_pImpl->m_dependencies[type]; 94 } 95 } 96 97 return TypeUsingSet(); 98 } 99 100 sal_Bool TypeDependency::hasDependencies(const OString& type) 101 { 102 if (type.getLength() > 0) 103 { 104 if (m_pImpl->m_dependencies.count(type) > 0) 105 { 106 return sal_True; 107 } 108 } 109 110 return sal_False; 111 } 112 113 void TypeDependency::setGenerated(const OString& type, sal_uInt16 genFlag) 114 { 115 // m_pImpl->m_generatedTypes.insert(type); 116 if (m_pImpl->m_generatedTypes.count(type) > 0) 117 m_pImpl->m_generatedTypes[type]= m_pImpl->m_generatedTypes[type] | genFlag; 118 else 119 m_pImpl->m_generatedTypes[type]=genFlag; 120 } 121 122 sal_Bool TypeDependency::isGenerated(const OString& type, sal_uInt16 genFlag) 123 { 124 /* 125 if (m_pImpl->m_generatedTypes.count(type) > 0) 126 return sal_True; 127 128 return sal_False; 129 */ 130 if (m_pImpl->m_generatedTypes.count(type) > 0 && 131 m_pImpl->m_generatedTypes[type] & genFlag) 132 { 133 return sal_True; 134 } 135 136 return sal_False; 137 } 138 139 static sal_Bool checkFieldDependencies(TypeManager& typeMgr, TypeDependency& dependencies, 140 TypeReader& reader, const OString& type) 141 { 142 sal_uInt32 count = reader.getFieldCount(); 143 144 if (count == 0 || reader.getTypeClass() == RT_TYPE_ENUM) 145 return sal_True; 146 147 OString fieldType; 148 for (sal_uInt16 i=0; i < count; i++) 149 { 150 fieldType = reader.getFieldType(i); 151 152 if (fieldType.getLength() > 0) 153 { 154 dependencies.insert(type, fieldType, TYPEUSE_MEMBER); 155 checkTypeDependencies(typeMgr, dependencies, fieldType); 156 } 157 } 158 159 return sal_True; 160 } 161 162 static sal_Bool checkMethodDependencies(TypeManager& typeMgr, TypeDependency& dependencies, 163 TypeReader& reader, const OString& type) 164 { 165 sal_uInt32 count = reader.getMethodCount(); 166 167 if (count == 0) 168 return sal_True; 169 170 OString returnType, paramType, excType; 171 sal_uInt32 paramCount = 0; 172 sal_uInt32 excCount = 0; 173 RTParamMode paramMode = RT_PARAM_INVALID; 174 for (sal_uInt16 i=0; i < count; i++) 175 { 176 returnType = reader.getMethodReturnType(i); 177 178 dependencies.insert(type, returnType, TYPEUSE_RETURN); 179 checkTypeDependencies(typeMgr, dependencies, returnType); 180 181 paramCount = reader.getMethodParamCount(i); 182 excCount = reader.getMethodExcCount(i); 183 184 sal_uInt16 j; 185 for (j=0; j < paramCount; j++) 186 { 187 paramType = reader.getMethodParamType(i, j); 188 paramMode = reader.getMethodParamMode(i, j); 189 190 switch (paramMode) 191 { 192 case RT_PARAM_IN: 193 dependencies.insert(type, paramType, TYPEUSE_INPARAM); 194 break; 195 case RT_PARAM_OUT: 196 dependencies.insert(type, paramType, TYPEUSE_OUTPARAM); 197 break; 198 case RT_PARAM_INOUT: 199 dependencies.insert(type, paramType, TYPEUSE_INOUTPARAM); 200 break; 201 default: 202 break; 203 } 204 205 checkTypeDependencies(typeMgr, dependencies, paramType); 206 } 207 208 for (j=0; j < excCount; j++) 209 { 210 excType = reader.getMethodExcType(i, j); 211 dependencies.insert(type, excType, TYPEUSE_EXCEPTION); 212 checkTypeDependencies(typeMgr, dependencies, excType); 213 } 214 215 } 216 217 return sal_True; 218 } 219 220 static sal_Bool checkReferenceDependencies(TypeManager& typeMgr, TypeDependency& dependencies, 221 TypeReader& reader, const OString& type) 222 { 223 sal_uInt32 count = reader.getReferenceCount(); 224 225 if (count == 0) 226 return sal_True; 227 228 OString referenceName; 229 for (sal_uInt16 i=0; i < count; i++) 230 { 231 referenceName = reader.getReferenceName(i); 232 233 dependencies.insert(type, referenceName, TYPEUSE_NORMAL); 234 checkTypeDependencies(typeMgr, dependencies, referenceName); 235 } 236 237 return sal_True; 238 } 239 240 sal_Bool checkTypeDependencies(TypeManager& typeMgr, TypeDependency& dependencies, const OString& type, sal_Bool bDepend) 241 { 242 if (!typeMgr.isValidType(type)) 243 return sal_False; 244 245 if (dependencies.hasDependencies(type)) 246 return sal_True; 247 248 TypeReader reader = typeMgr.getTypeReader(type); 249 250 if ( !reader.isValid() ) 251 { 252 if (type.equals("/")) 253 return sal_True; 254 else 255 return sal_False; 256 } 257 258 if ( bDepend && reader.getTypeClass() == RT_TYPE_MODULE) 259 { 260 checkFieldDependencies(typeMgr, dependencies, reader, type); 261 return sal_True; 262 } 263 264 for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) { 265 OString superType(reader.getSuperTypeName(i)); 266 dependencies.insert(type, superType, TYPEUSE_SUPER); 267 checkTypeDependencies(typeMgr, dependencies, superType); 268 } 269 270 if (reader.getTypeClass() == RT_TYPE_INTERFACE) 271 { 272 dependencies.insert(type, "com/sun/star/uno/RuntimeException", TYPEUSE_EXCEPTION); 273 dependencies.insert(type, "com/sun/star/uno/TypeClass", TYPEUSE_NORMAL); 274 checkTypeDependencies(typeMgr, dependencies, "com/sun/star/uno/RuntimeException", bDepend); 275 } 276 277 checkFieldDependencies(typeMgr, dependencies, reader, type); 278 checkMethodDependencies(typeMgr, dependencies, reader, type); 279 checkReferenceDependencies(typeMgr, dependencies, reader, type); 280 281 // make the scope modules as dependencies 282 sal_Int32 nPos = type.lastIndexOf( '/' ); 283 284 if ( nPos >= 0 ) 285 { 286 OString aScope( type.copy( 0, nPos ) ); 287 OStringBuffer tmpBuf(aScope.getLength()); 288 289 nPos = 0; 290 do 291 { 292 tmpBuf.append(aScope.getToken(0, '/', nPos)); 293 dependencies.insert(type, tmpBuf.getStr(), TYPEUSE_SCOPE); 294 tmpBuf.append('/'); 295 } while( nPos != -1 ); 296 } 297 298 return sal_True; 299 } 300 301 302