Vuo 2.4.4
Loading...
Searching...
No Matches
VuoCompilerCompoundType.cc
Go to the documentation of this file.
1
11#include "VuoCompiler.hh"
13#include "VuoCompilerIssue.hh"
14#include "VuoGenericType.hh"
15#include "VuoJsonUtilities.hh"
16#include "VuoNodeSet.hh"
17#include "VuoStringUtilities.hh"
18#include "VuoType.hh"
19#include <sstream>
20
29VuoCompilerCompoundType * VuoCompilerCompoundType::newType(const string &typeName, VuoCompiler *compiler, dispatch_queue_t llvmQueue)
30{
31 auto getVuoType = [compiler] (const string &moduleKey) { return compiler->getType(moduleKey); };
32
33 VuoCompilerType *genericType = parseGenericCompoundType(typeName, getVuoType);
34 if (! genericType)
35 return nullptr;
36
37 map<string, string> specializedForGenericTypeName = parseSpecializedTypes(typeName, genericType->getBase()->getModuleKey());
38
39 string sourcePath;
40 string sourceCode = getSourceCode(genericType, sourcePath);
41
42 if (sourceCode.empty())
43 {
44 VuoCompilerIssue issue(VuoCompilerIssue::Error, "specializing compound type", "",
45 "Missing source code",
46 "%module uses generic types, but its source code isn't included in its node set.");
47 issue.setModule(genericType->getBase());
48 throw VuoCompilerException(issue);
49 }
50
51 VuoModuleCompilerResults results = compiler->compileModuleInMemory(sourcePath, sourceCode, specializedForGenericTypeName);
52
53 __block VuoCompilerCompoundType *type = nullptr;
54 dispatch_sync(llvmQueue, ^{
55 type = new VuoCompilerCompoundType(typeName, results.module);
56 });
57
58 type->makeDependencies = results.makeDependencies;
59
60 return type;
61}
62
66VuoCompilerCompoundType * VuoCompilerCompoundType::newType(const string &typeName, Module *module)
67{
68 if (isSpecializedModule(module, typeName))
69 return new VuoCompilerCompoundType(typeName, module);
70
71 return nullptr;
72}
73
77VuoCompilerCompoundType::VuoCompilerCompoundType(const string &typeName, Module *module) :
78 VuoCompilerType(typeName, module)
79{
80 json_object *specializedDetails = nullptr;
81 if (json_object_object_get_ex(moduleDetails, "specializedModule", &specializedDetails))
82 {
83 string title = VuoJsonUtilities::parseString(specializedDetails, "title");
84 if (! title.empty())
85 getBase()->setDefaultTitle(title);
86
87 string genericTypeName = VuoJsonUtilities::parseString(specializedDetails, "genericModule");
88 dependencies.insert(genericTypeName);
89
90 map<string, string> specializedTypes = VuoJsonUtilities::parseObjectWithStringValues(specializedDetails, "specializedTypes");
91 for (auto i : specializedTypes)
92 dependencies.insert(i.second);
93 }
94}
95
99VuoCompilerType * VuoCompilerCompoundType::parseGenericCompoundType(const string &specializedCompoundTypeName,
100 std::function<VuoCompilerType *(const string &)> getVuoType)
101{
102 vector<string> parts = VuoStringUtilities::split(specializedCompoundTypeName, '_');
103 for (size_t i = 1; i < parts.size(); ++i)
104 {
105 vector<string> firstParts(parts.begin(), parts.begin() + i);
106 string potentialGenericTypeName = VuoStringUtilities::join(firstParts, '_');
107
108 VuoCompilerType *genericType = getVuoType(potentialGenericTypeName);
109 if (genericType)
110 return genericType;
111 }
112
113 return nullptr;
114}
115
119string VuoCompilerCompoundType::parseGenericCompoundTypeName(const string &specializedCompoundTypeName, size_t genericTypeCount)
120{
121 vector<string> parts = VuoStringUtilities::split(specializedCompoundTypeName, '_');
122 vector<string> genericNameParts(parts.begin(), parts.begin() + parts.size() - genericTypeCount);
123 return VuoStringUtilities::join(genericNameParts, '_');
124}
125
130map<string, string> VuoCompilerCompoundType::parseSpecializedTypes(const string &specializedCompoundTypeName, const string &genericCompoundTypeName)
131{
132 map<string, string> specializedForGenericTypeName;
133
134 string specializedTypeNames = VuoStringUtilities::substrAfter(specializedCompoundTypeName, genericCompoundTypeName + "_");
135 if (! specializedTypeNames.empty())
136 {
137 vector<string> specializedParts = VuoStringUtilities::split(specializedTypeNames, '_');
138 for (size_t i = 0; i < specializedParts.size(); ++i)
139 {
140 ostringstream genericTypeName;
141 genericTypeName << "VuoGenericType" << (i + 1);
142 specializedForGenericTypeName[genericTypeName.str()] = specializedParts[i];
143 }
144 }
145
146 return specializedForGenericTypeName;
147}
148
153string VuoCompilerCompoundType::buildSpecializedCompoundTypeName(const string &genericCompoundTypeName, const vector<string> &specializedTypeNames)
154{
155 return genericCompoundTypeName + "_" + VuoStringUtilities::join(specializedTypeNames, "_");
156}
157
162string VuoCompilerCompoundType::buildUnspecializedCompoundTypeName(const string &genericCompoundTypeName, size_t genericTypeCount)
163{
164 vector<string> genericTypeNames;
165 for (size_t i = 0; i < genericTypeCount; ++i)
166 {
167 ostringstream genericTypeName;
168 genericTypeName << "VuoGenericType" << (i + 1);
169 genericTypeNames.push_back(genericTypeName.str());
170 }
171
172 return buildSpecializedCompoundTypeName(genericCompoundTypeName, genericTypeNames);
173}
174
178json_object * VuoCompilerCompoundType::buildSpecializedModuleDetails(VuoCompilerType *genericCompoundType, const map<string, string> &specializedForGenericTypeName,
179 const map<string, VuoCompilerType *> &specializedTypes)
180{
181 json_object *specializedDetails = json_object_new_object();
182
183 string title = buildDefaultTitle(genericCompoundType, specializedForGenericTypeName, specializedTypes);
184 json_object_object_add(specializedDetails, "title", json_object_new_string(title.c_str()));
185
186 json_object_object_add(specializedDetails, "genericModule", json_object_new_string(genericCompoundType->getBase()->getModuleKey().c_str()));
187
188 json_object *specializedTypesObj = json_object_new_object();
189 json_object_object_add(specializedDetails, "specializedTypes", specializedTypesObj);
190 for (auto i : specializedForGenericTypeName)
191 json_object_object_add(specializedTypesObj, i.first.c_str(), json_object_new_string(i.second.c_str()));
192
193 return specializedDetails;
194}
195
199string VuoCompilerCompoundType::buildDefaultTitle(const string &specializedCompoundTypeName,
200 std::function<VuoCompilerType *(const string &)> getVuoType)
201{
202 VuoCompilerType *genericCompoundType = parseGenericCompoundType(specializedCompoundTypeName, getVuoType);
203 map<string, string> specializedForGenericTypeName = parseSpecializedTypes(specializedCompoundTypeName, genericCompoundType->getBase()->getModuleKey());
204
205 map<string, VuoCompilerType *> specializedTypes;
206 for (auto i : specializedForGenericTypeName)
207 specializedTypes[i.second] = getVuoType(i.second);
208
209 return buildDefaultTitle(genericCompoundType, specializedForGenericTypeName, specializedTypes);
210}
211
215string VuoCompilerCompoundType::buildDefaultTitle(VuoCompilerType *genericCompoundType, const map<string, string> &specializedForGenericTypeName,
216 const map<string, VuoCompilerType *> &specializedTypes)
217{
218 string title = genericCompoundType->getBase()->getDefaultTitle();
219
220 map<string, string> specializedTitleForGenericTypeName;
221 for (auto i : specializedForGenericTypeName)
222 {
223 auto specializedTypeIter = specializedTypes.find(i.second);
224 specializedTitleForGenericTypeName[i.first] = specializedTypeIter != specializedTypes.end() ?
225 specializedTypeIter->second->getBase()->getDefaultTitle() :
226 i.second;
227 }
228
229 vector<string> unused;
230 VuoGenericType::replaceGenericTypeNamesInString(title, specializedTitleForGenericTypeName, unused);
231
232 return title;
233}
234
238string VuoCompilerCompoundType::getSourceCode(VuoCompilerType *genericCompoundType, string &sourcePath)
239{
240 string sourceCode;
241
242 VuoNodeSet *nodeSet = genericCompoundType->getBase()->getNodeSet();
243 if (nodeSet)
244 {
245 string relativePath = nodeSet->getModuleSourcePath( genericCompoundType->getBase()->getModuleKey() );
246 sourceCode = nodeSet->getFileContents(relativePath);
247 sourcePath = nodeSet->getArchivePath() + "/" + relativePath;
248 }
249 else
250 {
251 sourceCode = genericCompoundType->getSourceCode();
252 sourcePath = genericCompoundType->getSourcePath();
253 }
254
255 return sourceCode;
256}