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
TypeDependency()30 TypeDependency::TypeDependency()
31 {
32 m_pImpl = new TypeDependencyImpl();
33 acquire();
34 }
35
~TypeDependency()36 TypeDependency::~TypeDependency()
37 {
38 release();
39 }
40
acquire()41 void TypeDependency::acquire()
42 {
43 osl_incrementInterlockedCount(&m_pImpl->m_refCount);
44 }
45
release()46 void TypeDependency::release()
47 {
48 if (0 == osl_decrementInterlockedCount(&m_pImpl->m_refCount))
49 {
50 delete m_pImpl;
51 }
52 }
53
insert(const OString & type,const OString & depend,sal_uInt16 use)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
getDependencies(const OString & type)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
hasDependencies(const OString & type)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
setGenerated(const OString & type,sal_uInt16 genFlag)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
isGenerated(const OString & type,sal_uInt16 genFlag)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
checkFieldDependencies(TypeManager & typeMgr,TypeDependency & dependencies,TypeReader & reader,const OString & type)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
checkMethodDependencies(TypeManager & typeMgr,TypeDependency & dependencies,TypeReader & reader,const OString & type)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
checkReferenceDependencies(TypeManager & typeMgr,TypeDependency & dependencies,TypeReader & reader,const OString & type)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
checkTypeDependencies(TypeManager & typeMgr,TypeDependency & dependencies,const OString & type,sal_Bool bDepend)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