177788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall/*
277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * Copyright (C) 2016 The Android Open Source Project
377788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall *
477788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * Licensed under the Apache License, Version 2.0 (the "License");
577788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * you may not use this file except in compliance with the License.
677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * You may obtain a copy of the License at
777788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall *
877788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall *      http://www.apache.org/licenses/LICENSE-2.0
977788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall *
1077788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * Unless required by applicable law or agreed to in writing, software
1177788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * distributed under the License is distributed on an "AS IS" BASIS,
1277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1377788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * See the License for the specific language governing permissions and
1477788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall * limitations under the License.
1577788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall */
1677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
1777788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall#include "DominatorTree.h"
1877788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
1977788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall#include <sstream>
2077788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall#include <string>
2177788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall#include <vector>
2277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "test/Test.h"
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "util/Util.h"
25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
2677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwallnamespace aapt {
2777788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
2877788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwallnamespace {
2977788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
3077788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwallclass PrettyPrinter : public DominatorTree::Visitor {
31cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  explicit PrettyPrinter(const int indent = 2) : indent_(indent) {}
3377788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void VisitTree(const std::string& product,
35cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                 DominatorTree::Node* root) override {
36cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    for (auto& child : root->children()) {
37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      VisitNode(child.get(), 0);
3877788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall    }
39cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
40cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::string ToString(DominatorTree* tree) {
42ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    buffer_.str("");
43ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    buffer_.clear();
44ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    tree->Accept(this);
45ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    return buffer_.str();
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private:
49ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void VisitConfig(const DominatorTree::Node* node, const int indent) {
50ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    auto config_string = node->value()->config.toString();
51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    buffer_ << std::string(indent, ' ')
52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            << (config_string.isEmpty() ? "<default>" : config_string)
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski            << std::endl;
54cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
55cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
56ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void VisitNode(const DominatorTree::Node* node, const int indent) {
57ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    VisitConfig(node, indent);
58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    for (const auto& child : node->children()) {
59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      VisitNode(child.get(), indent + indent_);
6077788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall    }
61cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
6277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
63ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::stringstream buffer_;
64ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const int indent_ = 2;
6577788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall};
6677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace
6877788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
6977788eb4cf0c5dba0f7370192e40364fe853050aAlexandria CornwallTEST(DominatorTreeTest, DefaultDominatesEverything) {
70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription default_config = {};
71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription land_config = test::ParseConfigOrDie("land");
72ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription sw600dp_land_config =
73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("sw600dp-land-v13");
74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
78cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  configs.push_back(
79ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));
80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
81cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  DominatorTree tree(configs);
82cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  PrettyPrinter printer;
83cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
84cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string expected =
85cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "<default>\n"
86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  land\n"
87cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  sw600dp-land-v13\n";
88ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(expected, printer.ToString(&tree));
8977788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
9077788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
9177788eb4cf0c5dba0f7370192e40364fe853050aAlexandria CornwallTEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription default_config = {};
93ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription land_config = test::ParseConfigOrDie("land");
94ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription sw600dp_land_config =
95ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("sw600dp-land-v13");
96cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
97cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
98ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
99ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
100cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  configs.push_back(
101ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<ResourceConfigValue>(default_config, "phablet"));
102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  configs.push_back(
103ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));
104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
105cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  DominatorTree tree(configs);
106cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  PrettyPrinter printer;
107cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string expected =
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "<default>\n"
110cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  land\n"
111cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "<default>\n"
112cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  sw600dp-land-v13\n";
113ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(expected, printer.ToString(&tree));
11477788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
11577788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
11677788eb4cf0c5dba0f7370192e40364fe853050aAlexandria CornwallTEST(DominatorTreeTest, MoreSpecificConfigurationsAreDominated) {
117ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription default_config = {};
118ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription en_config = test::ParseConfigOrDie("en");
119ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
120ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
121ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription ldrtl_xhdpi_config =
122ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("ldrtl-xhdpi-v4");
123ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription sw300dp_config =
124ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("sw300dp-v13");
125ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription sw540dp_config =
126ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("sw540dp-v14");
127ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription sw600dp_config =
128ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("sw600dp-v14");
129ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription sw720dp_config =
130ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      test::ParseConfigOrDie("sw720dp-v13");
131ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const ConfigDescription v20_config = test::ParseConfigOrDie("v20");
132cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
134ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
135ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
136ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
137ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
138cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  configs.push_back(
139ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
140ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
141ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
142ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
143ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(sw720dp_config, ""));
144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  configs.push_back(util::make_unique<ResourceConfigValue>(v20_config, ""));
145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  DominatorTree tree(configs);
147cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  PrettyPrinter printer;
148cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::string expected =
150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "<default>\n"
151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  en\n"
152cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "    en-v21\n"
153cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  ldrtl-v4\n"
154cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "    ldrtl-xhdpi-v4\n"
155cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  sw300dp-v13\n"
156cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "    sw540dp-v14\n"
157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "      sw600dp-v14\n"
158cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "    sw720dp-v13\n"
159cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      "  v20\n";
160ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(expected, printer.ToString(&tree));
16177788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall}
16277788eb4cf0c5dba0f7370192e40364fe853050aAlexandria Cornwall
163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
164