Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "sal/config.h"
21 :
22 : #include <cstdlib>
23 : #include <cstring>
24 : #include <vector>
25 :
26 : #include "codemaker/global.hxx"
27 : #include "codemaker/typemanager.hxx"
28 : #include "rtl/ref.hxx"
29 : #include "rtl/ustring.hxx"
30 : #include "unoidl/unoidl.hxx"
31 :
32 15 : TypeManager::TypeManager(): manager_(new unoidl::Manager) {}
33 :
34 30 : TypeManager::~TypeManager() {}
35 :
36 31 : void TypeManager::loadProvider(OUString const & uri, bool primary) {
37 31 : rtl::Reference< unoidl::Provider > prov(manager_->addProvider(uri));
38 31 : if (primary) {
39 16 : primaryProviders_.push_back(prov);
40 31 : }
41 31 : }
42 :
43 16239 : bool TypeManager::foundAtPrimaryProvider(OUString const & name) const {
44 16239 : if (name.isEmpty()) {
45 15 : return !primaryProviders_.empty();
46 : }
47 51699 : for (std::vector< rtl::Reference< unoidl::Provider > >::const_iterator i(
48 16224 : primaryProviders_.begin());
49 34466 : i != primaryProviders_.end(); ++i)
50 : {
51 16248 : if ((*i)->findEntity(name).is()) {
52 15239 : return true;
53 : }
54 : }
55 985 : if (!manager_->findEntity(name).is()) {
56 0 : throw CannotDumpException("Unknown entity '" + name + "'");
57 : }
58 985 : return false;
59 : }
60 :
61 383615 : codemaker::UnoType::Sort TypeManager::getSort(
62 : OUString const & name, rtl::Reference< unoidl::Entity > * entity,
63 : rtl::Reference< unoidl::MapCursor > * cursor) const
64 : {
65 383615 : if (name.isEmpty()) {
66 15 : if (cursor != 0) {
67 15 : *cursor = manager_->createCursor("");
68 : }
69 15 : return codemaker::UnoType::SORT_MODULE;
70 : }
71 383600 : if (name == "void") {
72 24045 : return codemaker::UnoType::SORT_VOID;
73 : }
74 359555 : if (name == "boolean") {
75 17214 : return codemaker::UnoType::SORT_BOOLEAN;
76 : }
77 342341 : if (name == "byte") {
78 2617 : return codemaker::UnoType::SORT_BYTE;
79 : }
80 339724 : if (name == "short") {
81 11320 : return codemaker::UnoType::SORT_SHORT;
82 : }
83 328404 : if (name == "unsigned short") {
84 923 : return codemaker::UnoType::SORT_UNSIGNED_SHORT;
85 : }
86 327481 : if (name == "long") {
87 29597 : return codemaker::UnoType::SORT_LONG;
88 : }
89 297884 : if (name == "unsigned long") {
90 798 : return codemaker::UnoType::SORT_UNSIGNED_LONG;
91 : }
92 297086 : if (name == "hyper") {
93 1252 : return codemaker::UnoType::SORT_HYPER;
94 : }
95 295834 : if (name == "unsigned hyper") {
96 144 : return codemaker::UnoType::SORT_UNSIGNED_HYPER;
97 : }
98 295690 : if (name == "float") {
99 864 : return codemaker::UnoType::SORT_FLOAT;
100 : }
101 294826 : if (name == "double") {
102 5953 : return codemaker::UnoType::SORT_DOUBLE;
103 : }
104 288873 : if (name == "char") {
105 586 : return codemaker::UnoType::SORT_CHAR;
106 : }
107 288287 : if (name == "string") {
108 42632 : return codemaker::UnoType::SORT_STRING;
109 : }
110 245655 : if (name == "type") {
111 810 : return codemaker::UnoType::SORT_TYPE;
112 : }
113 244845 : if (name == "any") {
114 12570 : return codemaker::UnoType::SORT_ANY;
115 : }
116 232275 : if (name.startsWith("[")) {
117 3355 : return codemaker::UnoType::SORT_SEQUENCE_TYPE;
118 : }
119 228920 : if (name.indexOf('<') != -1) {
120 397 : return codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE;
121 : }
122 228523 : rtl::Reference< unoidl::Entity > ent(manager_->findEntity(name));
123 228523 : if (!ent.is()) {
124 0 : throw CannotDumpException("Unknown entity '" + name + "'");
125 : }
126 228523 : if (entity != 0) {
127 114951 : *entity = ent;
128 : }
129 228523 : switch (ent->getSort()) {
130 : case unoidl::Entity::SORT_MODULE:
131 457 : if (cursor != 0) {
132 457 : *cursor = manager_->createCursor(name);
133 : }
134 457 : return codemaker::UnoType::SORT_MODULE;
135 : case unoidl::Entity::SORT_ENUM_TYPE:
136 10783 : return codemaker::UnoType::SORT_ENUM_TYPE;
137 : case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
138 34748 : return codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE;
139 : case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
140 722 : return codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE;
141 : case unoidl::Entity::SORT_EXCEPTION_TYPE:
142 47694 : return codemaker::UnoType::SORT_EXCEPTION_TYPE;
143 : case unoidl::Entity::SORT_INTERFACE_TYPE:
144 121183 : return codemaker::UnoType::SORT_INTERFACE_TYPE;
145 : case unoidl::Entity::SORT_TYPEDEF:
146 2283 : return codemaker::UnoType::SORT_TYPEDEF;
147 : case unoidl::Entity::SORT_CONSTANT_GROUP:
148 5015 : return codemaker::UnoType::SORT_CONSTANT_GROUP;
149 : case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
150 2066 : return codemaker::UnoType::SORT_SINGLE_INTERFACE_BASED_SERVICE;
151 : case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
152 3114 : return codemaker::UnoType::SORT_ACCUMULATION_BASED_SERVICE;
153 : case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
154 457 : return codemaker::UnoType::SORT_INTERFACE_BASED_SINGLETON;
155 : case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
156 1 : return codemaker::UnoType::SORT_SERVICE_BASED_SINGLETON;
157 : default:
158 0 : for (;;) { std::abort(); } // this cannot happen
159 228523 : }
160 : }
161 :
162 35054 : codemaker::UnoType::Sort TypeManager::decompose(
163 : OUString const & name, bool resolveTypedefs, OUString * nucleus,
164 : sal_Int32 * rank, std::vector< OUString > * arguments,
165 : rtl::Reference< unoidl::Entity > * entity) const
166 : {
167 : sal_Int32 k;
168 35054 : std::vector< OString > args;
169 70108 : OUString n = b2u(codemaker::UnoType::decompose(u2b(name), &k, &args));
170 : for (;;) {
171 35382 : rtl::Reference< unoidl::Entity > ent;
172 35382 : codemaker::UnoType::Sort s = getSort(n, &ent);
173 70764 : if (args.empty()
174 35382 : != (s != codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE))
175 : {
176 : throw CannotDumpException(
177 0 : "template arguments mismatch for \"" + n
178 0 : + "\" resolved from \"" + name + "\"");
179 : }
180 35382 : switch (s) {
181 : case codemaker::UnoType::SORT_TYPEDEF:
182 333 : if (resolveTypedefs) {
183 656 : n = dynamic_cast<unoidl::TypedefEntity&>(*ent.get()).
184 328 : getType();
185 754 : while (n.startsWith("[]")) {
186 98 : ++k; //TODO: overflow
187 98 : n = n.copy(std::strlen("[]"));
188 : }
189 328 : break;
190 : }
191 : // fall through
192 : case codemaker::UnoType::SORT_VOID:
193 : case codemaker::UnoType::SORT_BOOLEAN:
194 : case codemaker::UnoType::SORT_BYTE:
195 : case codemaker::UnoType::SORT_SHORT:
196 : case codemaker::UnoType::SORT_UNSIGNED_SHORT:
197 : case codemaker::UnoType::SORT_LONG:
198 : case codemaker::UnoType::SORT_UNSIGNED_LONG:
199 : case codemaker::UnoType::SORT_HYPER:
200 : case codemaker::UnoType::SORT_UNSIGNED_HYPER:
201 : case codemaker::UnoType::SORT_FLOAT:
202 : case codemaker::UnoType::SORT_DOUBLE:
203 : case codemaker::UnoType::SORT_CHAR:
204 : case codemaker::UnoType::SORT_STRING:
205 : case codemaker::UnoType::SORT_TYPE:
206 : case codemaker::UnoType::SORT_ANY:
207 : case codemaker::UnoType::SORT_ENUM_TYPE:
208 : case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
209 : case codemaker::UnoType::SORT_EXCEPTION_TYPE:
210 : case codemaker::UnoType::SORT_INTERFACE_TYPE:
211 34855 : if (nucleus != 0) {
212 34855 : *nucleus = n;
213 : }
214 34855 : if (rank != 0) {
215 34836 : *rank = k;
216 : }
217 34855 : if (arguments != 0) {
218 30006 : arguments->clear();
219 : }
220 34855 : if (entity != 0) {
221 2059 : *entity = ent;
222 : }
223 34855 : return s;
224 : case codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
225 398 : if (args.size()
226 : != (dynamic_cast<
227 199 : unoidl::PolymorphicStructTypeTemplateEntity * >(ent.get())->
228 199 : getTypeParameters().size()))
229 : {
230 : throw CannotDumpException(
231 0 : "bad number of template arguments for \"" + n
232 0 : + "\" resolved from \"" + name + "\"");
233 : }
234 199 : if (nucleus != 0) {
235 199 : *nucleus = n;
236 : }
237 199 : if (rank != 0) {
238 199 : *rank = k;
239 : }
240 199 : if (arguments != 0) {
241 192 : arguments->clear();
242 1314 : for (std::vector< OString >::iterator i(args.begin());
243 876 : i != args.end(); ++i)
244 : {
245 246 : arguments->push_back(b2u(*i));
246 : }
247 : }
248 199 : if (entity != 0) {
249 2 : *entity = ent;
250 : }
251 : return
252 199 : codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE;
253 : case codemaker::UnoType::SORT_SEQUENCE_TYPE:
254 : assert(false); // this cannot happen
255 : // fall through
256 : default:
257 : throw CannotDumpException(
258 0 : "unexpected \"" + n + "\" resolved from \"" + name
259 0 : + ("\"in call to TypeManager::decompose"));
260 : }
261 35382 : }
262 : }
263 :
264 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|