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