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