blob: 6d45b5d59ded07b6fa0f7eb7bd23edfec0a7e4a4 [file] [log] [blame]
Alexandria Cornwall77788eb2016-09-06 15:16:49 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef AAPT_DOMINATOR_TREE_H
18#define AAPT_DOMINATOR_TREE_H
19
20#include "ResourceTable.h"
21
22#include <map>
23#include <memory>
24#include <string>
25#include <vector>
26
27namespace aapt {
28
29/**
30 * A dominator tree of configurations as defined by resolution rules for Android
31 * resources.
32 *
33 * A node in the tree represents a resource configuration.
34 *
35 * The tree has the following property:
36 *
37 * Each child of a given configuration defines a strict superset of qualifiers
38 * and has a value that is at least as specific as that of its ancestors. A
39 * value is "at least as specific" if it is either identical or it represents a
40 * stronger requirement.
41 * For example, v21 is more specific than v11, and w1200dp is more specific than
42 * w800dp.
43 *
44 * The dominator tree relies on the underlying configurations passed to it. If
45 * the configurations passed to the dominator tree go out of scope, the tree
46 * will exhibit undefined behavior.
47 */
48class DominatorTree {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070049 public:
50 explicit DominatorTree(
51 const std::vector<std::unique_ptr<ResourceConfigValue>>& configs);
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070052
Adam Lesinskicacb28f2016-10-19 12:18:14 -070053 class Node {
54 public:
55 explicit Node(ResourceConfigValue* value = nullptr, Node* parent = nullptr)
56 : mValue(value), mParent(parent) {}
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070057
Adam Lesinskicacb28f2016-10-19 12:18:14 -070058 inline ResourceConfigValue* value() const { return mValue; }
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070059
Adam Lesinskicacb28f2016-10-19 12:18:14 -070060 inline Node* parent() const { return mParent; }
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070061
Adam Lesinskicacb28f2016-10-19 12:18:14 -070062 inline bool isRootNode() const { return !mValue; }
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070063
Adam Lesinskicacb28f2016-10-19 12:18:14 -070064 inline const std::vector<std::unique_ptr<Node>>& children() const {
65 return mChildren;
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070066 }
67
Adam Lesinskicacb28f2016-10-19 12:18:14 -070068 bool tryAddChild(std::unique_ptr<Node> newChild);
Alexandria Cornwall77788eb2016-09-06 15:16:49 -070069
Adam Lesinskicacb28f2016-10-19 12:18:14 -070070 private:
71 bool addChild(std::unique_ptr<Node> newChild);
72 bool dominates(const Node* other) const;
73
74 ResourceConfigValue* mValue;
75 Node* mParent;
76 std::vector<std::unique_ptr<Node>> mChildren;
77
78 DISALLOW_COPY_AND_ASSIGN(Node);
79 };
80
81 struct Visitor {
82 virtual ~Visitor() = default;
83 virtual void visitTree(const std::string& product, Node* root) = 0;
84 };
85
86 class BottomUpVisitor : public Visitor {
87 public:
88 virtual ~BottomUpVisitor() = default;
89
90 void visitTree(const std::string& product, Node* root) override {
91 for (auto& child : root->children()) {
92 visitNode(child.get());
93 }
94 }
95
96 virtual void visitConfig(Node* node) = 0;
97
98 private:
99 void visitNode(Node* node) {
100 for (auto& child : node->children()) {
101 visitNode(child.get());
102 }
103 visitConfig(node);
104 }
105 };
106
107 void accept(Visitor* visitor);
108
109 inline const std::map<std::string, Node>& getProductRoots() const {
110 return mProductRoots;
111 }
112
113 private:
114 DISALLOW_COPY_AND_ASSIGN(DominatorTree);
115
116 std::map<std::string, Node> mProductRoots;
Alexandria Cornwall77788eb2016-09-06 15:16:49 -0700117};
118
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700119} // namespace aapt
Alexandria Cornwall77788eb2016-09-06 15:16:49 -0700120
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700121#endif // AAPT_DOMINATOR_TREE_H