2023-11-02 13:05:35 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
#include "IdentifyContainers.h"
|
|
|
|
|
|
|
|
#include "TypeGraph.h"
|
|
|
|
#include "oi/ContainerInfo.h"
|
|
|
|
|
|
|
|
namespace oi::detail::type_graph {
|
|
|
|
|
|
|
|
Pass IdentifyContainers::createPass(
|
|
|
|
const std::vector<std::unique_ptr<ContainerInfo>>& containers) {
|
|
|
|
auto fn = [&containers](TypeGraph& typeGraph, NodeTracker&) {
|
|
|
|
IdentifyContainers typeId{typeGraph, containers};
|
|
|
|
for (auto& type : typeGraph.rootTypes()) {
|
|
|
|
type = typeId.mutate(type);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return Pass("IdentifyContainers", fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
IdentifyContainers::IdentifyContainers(
|
|
|
|
TypeGraph& typeGraph,
|
|
|
|
const std::vector<std::unique_ptr<ContainerInfo>>& containers)
|
|
|
|
: tracker_(typeGraph.size()),
|
|
|
|
typeGraph_(typeGraph),
|
|
|
|
containers_(containers) {
|
|
|
|
}
|
|
|
|
|
|
|
|
Type& IdentifyContainers::mutate(Type& type) {
|
|
|
|
if (Type* mutated = tracker_.get(type))
|
|
|
|
return *mutated;
|
|
|
|
|
|
|
|
Type& mutated = type.accept(*this);
|
2023-12-13 16:23:47 +00:00
|
|
|
tracker_.set(type, &mutated);
|
2023-11-02 13:05:35 +00:00
|
|
|
return mutated;
|
|
|
|
}
|
|
|
|
|
|
|
|
Type& IdentifyContainers::visit(Class& c) {
|
|
|
|
for (const auto& containerInfo : containers_) {
|
2024-01-23 18:15:43 +00:00
|
|
|
if (!containerInfo->matches(c.fqName())) {
|
2023-11-02 13:05:35 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-12-14 16:15:43 +00:00
|
|
|
auto& container =
|
|
|
|
typeGraph_.makeType<Container>(*containerInfo, c.size(), &c);
|
2023-11-02 13:05:35 +00:00
|
|
|
container.templateParams = c.templateParams;
|
|
|
|
|
2023-12-13 16:23:47 +00:00
|
|
|
tracker_.set(c, &container);
|
2023-12-14 16:15:43 +00:00
|
|
|
visit(container);
|
2023-11-02 13:05:35 +00:00
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
2023-12-13 16:23:47 +00:00
|
|
|
tracker_.set(c, &c);
|
2023-11-02 13:05:35 +00:00
|
|
|
RecursiveMutator::visit(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2023-12-14 16:15:43 +00:00
|
|
|
Type& IdentifyContainers::visit(Container& c) {
|
|
|
|
for (auto& param : c.templateParams) {
|
|
|
|
param.setType(mutate(param.type()));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not mutate the underlying class further here as that would result in it
|
|
|
|
// getting replaced with this Container node
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2023-11-02 13:05:35 +00:00
|
|
|
} // namespace oi::detail::type_graph
|