xref: /trunk/main/rdbmaker/source/codemaker/dependency.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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