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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_codemaker.hxx"
26 
27 #include "codemaker/dependencies.hxx"
28 
29 #include "codemaker/typemanager.hxx"
30 #include "codemaker/unotype.hxx"
31 
32 #include "osl/diagnose.h"
33 #include "registry/reader.hxx"
34 #include "rtl/string.hxx"
35 #include "rtl/textcvt.h"
36 #include "rtl/textenc.h"
37 #include "rtl/ustring.hxx"
38 #include "sal/types.h"
39 
40 #include <vector>
41 
42 using codemaker::Dependencies;
43 
44 namespace {
45 
46 struct Bad {};
47 
48 }
49 
Dependencies(TypeManager const & manager,rtl::OString const & type)50 Dependencies::Dependencies(
51     TypeManager const & manager, rtl::OString const & type):
52     m_voidDependency(false), m_booleanDependency(false),
53     m_byteDependency(false), m_shortDependency(false),
54     m_unsignedShortDependency(false), m_longDependency(false),
55     m_unsignedLongDependency(false), m_hyperDependency(false),
56     m_unsignedHyperDependency(false), m_floatDependency(false),
57     m_doubleDependency(false), m_charDependency(false),
58     m_stringDependency(false), m_typeDependency(false), m_anyDependency(false),
59     m_sequenceDependency(false)
60 {
61     typereg::Reader reader(manager.getTypeReader(type));
62     m_valid = reader.isValid();
63     if (m_valid) {
64         // Not everything is checked for consistency, just things that are cheap
65         // to test:
66         try {
67             RTTypeClass tc = reader.getTypeClass();
68             if (tc != RT_TYPE_SERVICE) {
69                 for (sal_Int16 i = 0; i < reader.getSuperTypeCount(); ++i) {
70                     insert(reader.getSuperTypeName(i), true);
71                 }
72             }
73             if (tc != RT_TYPE_ENUM) {
74                 {for (sal_Int16 i = 0; i < reader.getFieldCount(); ++i) {
75                     if ((reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE)
76                         == 0)
77                     {
78                         insert(reader.getFieldTypeName(i), false);
79                     }
80                 }}
81             }
82             for (sal_Int16 i = 0; i < reader.getMethodCount(); ++i) {
83                 insert(reader.getMethodReturnTypeName(i), false);
84                 for (sal_Int16 j = 0; j < reader.getMethodParameterCount(i);
85                       ++j)
86                 {
87                     if ((reader.getMethodParameterFlags(i, j) & RT_PARAM_REST)
88                         != 0)
89                     {
90                         m_sequenceDependency = true;
91                     }
92                     insert(reader.getMethodParameterTypeName(i, j), false);
93                 }
94                 for (sal_Int16 j = 0; j < reader.getMethodExceptionCount(i);
95                       ++j)
96                 {
97                     insert(reader.getMethodExceptionTypeName(i, j), false);
98                 }
99             }
100             for (sal_Int16 i = 0; i < reader.getReferenceCount(); ++i) {
101                 if (reader.getReferenceSort(i) != RT_REF_TYPE_PARAMETER) {
102                     insert(reader.getReferenceTypeName(i), false);
103                 }
104             }
105         } catch (Bad &) {
106             m_map.clear();
107             m_valid = false;
108             m_voidDependency = false;
109             m_booleanDependency = false;
110             m_byteDependency = false;
111             m_shortDependency = false;
112             m_unsignedShortDependency = false;
113             m_longDependency = false;
114             m_unsignedLongDependency = false;
115             m_hyperDependency = false;
116             m_unsignedHyperDependency = false;
117             m_floatDependency = false;
118             m_doubleDependency = false;
119             m_charDependency = false;
120             m_stringDependency = false;
121             m_typeDependency = false;
122             m_anyDependency = false;
123             m_sequenceDependency = false;
124         }
125     }
126 }
127 
~Dependencies()128 Dependencies::~Dependencies()
129 {}
130 
insert(rtl::OUString const & type,bool base)131 void Dependencies::insert(rtl::OUString const & type, bool base) {
132     rtl::OString t;
133     if (!type.convertToString(
134             &t, RTL_TEXTENCODING_UTF8,
135             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
136              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
137     {
138         throw Bad();
139     }
140     insert(t, base);
141 }
142 
insert(rtl::OString const & type,bool base)143 void Dependencies::insert(rtl::OString const & type, bool base) {
144     sal_Int32 rank;
145     std::vector< rtl::OString > args;
146     rtl::OString t(UnoType::decompose(type, &rank, &args));
147     if (rank > 0) {
148         m_sequenceDependency = true;
149     }
150     switch (UnoType::getSort(t)) {
151     case UnoType::SORT_VOID:
152         if (rank != 0 || !args.empty()) {
153             throw Bad();
154         }
155         m_voidDependency = true;
156         break;
157 
158     case UnoType::SORT_BOOLEAN:
159         if (!args.empty()) {
160             throw Bad();
161         }
162         m_booleanDependency = true;
163         break;
164 
165     case UnoType::SORT_BYTE:
166         if (!args.empty()) {
167             throw Bad();
168         }
169         m_byteDependency = true;
170         break;
171 
172     case UnoType::SORT_SHORT:
173         if (!args.empty()) {
174             throw Bad();
175         }
176         m_shortDependency = true;
177         break;
178 
179     case UnoType::SORT_UNSIGNED_SHORT:
180         if (!args.empty()) {
181             throw Bad();
182         }
183         m_unsignedShortDependency = true;
184         break;
185 
186     case UnoType::SORT_LONG:
187         if (!args.empty()) {
188             throw Bad();
189         }
190         m_longDependency = true;
191         break;
192 
193     case UnoType::SORT_UNSIGNED_LONG:
194         if (!args.empty()) {
195             throw Bad();
196         }
197         m_unsignedLongDependency = true;
198         break;
199 
200     case UnoType::SORT_HYPER:
201         if (!args.empty()) {
202             throw Bad();
203         }
204         m_hyperDependency = true;
205         break;
206 
207     case UnoType::SORT_UNSIGNED_HYPER:
208         if (!args.empty()) {
209             throw Bad();
210         }
211         m_unsignedHyperDependency = true;
212         break;
213 
214     case UnoType::SORT_FLOAT:
215         if (!args.empty()) {
216             throw Bad();
217         }
218         m_floatDependency = true;
219         break;
220 
221     case UnoType::SORT_DOUBLE:
222         if (!args.empty()) {
223             throw Bad();
224         }
225         m_doubleDependency = true;
226         break;
227 
228     case UnoType::SORT_CHAR:
229         if (!args.empty()) {
230             throw Bad();
231         }
232         m_charDependency = true;
233         break;
234 
235     case UnoType::SORT_STRING:
236         if (!args.empty()) {
237             throw Bad();
238         }
239         m_stringDependency = true;
240         break;
241 
242     case UnoType::SORT_TYPE:
243         if (!args.empty()) {
244             throw Bad();
245         }
246         m_typeDependency = true;
247         break;
248 
249     case UnoType::SORT_ANY:
250         if (!args.empty()) {
251             throw Bad();
252         }
253         m_anyDependency = true;
254         break;
255 
256     case UnoType::SORT_COMPLEX:
257         {
258             {for (std::vector< rtl::OString >::iterator i(args.begin());
259                   i != args.end(); ++i)
260             {
261                 insert(*i, false);
262             }}
263             Map::iterator i(m_map.find(t));
264             if (i == m_map.end()) {
265                 m_map.insert(
266                     Map::value_type(t, base ? KIND_BASE : KIND_NO_BASE));
267             } else if (base) {
268                 i->second = KIND_BASE;
269             }
270             break;
271         }
272 
273     default:
274         OSL_ASSERT(false);
275         break;
276     }
277 }
278