11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/*
21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License.
61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at
71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software
111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and
141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License.
151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ValueVisitor.h"
18ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
19ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <string>
20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
21cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include "ResourceValues.h"
22d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski#include "test/Test.h"
23d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski#include "util/Util.h"
24d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski
251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct SingleReferenceVisitor : public ValueVisitor {
28ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  using ValueVisitor::Visit;
291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
30cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Reference* visited = nullptr;
311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Visit(Reference* ref) override { visited = ref; }
331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct StyleVisitor : public ValueVisitor {
36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  using ValueVisitor::Visit;
371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::list<Reference*> visited_refs;
39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Style* visited_style = nullptr;
401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Visit(Reference* ref) override { visited_refs.push_back(ref); }
421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
43ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  void Visit(Style* style) override {
44ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    visited_style = style;
45ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    ValueVisitor::Visit(style);
46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
491ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiTEST(ValueVisitorTest, VisitsReference) {
50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  Reference ref(ResourceName{"android", ResourceType::kAttr, "foo"});
51cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  SingleReferenceVisitor visitor;
52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ref.Accept(&visitor);
531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
54cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  EXPECT_EQ(visitor.visited, &ref);
551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
571ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiTEST(ValueVisitorTest, VisitsReferencesInStyle) {
58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::unique_ptr<Style> style =
59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      test::StyleBuilder()
60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .SetParent("android:style/foo")
61ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddItem("android:attr/one", test::BuildReference("android:id/foo"))
62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .Build();
631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  StyleVisitor visitor;
65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  style->Accept(&visitor);
661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
67ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_EQ(style.get(), visitor.visited_style);
681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Entry attribute references, plus the parent reference, plus one value
70cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // reference.
71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_EQ(style->entries.size() + 2, visitor.visited_refs.size());
721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
741ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiTEST(ValueVisitorTest, ValueCast) {
75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::unique_ptr<Reference> ref = test::BuildReference("android:color/white");
76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_NE(ValueCast<Reference>(ref.get()), nullptr);
77cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
78cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::unique_ptr<Style> style =
79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      test::StyleBuilder()
80ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddItem("android:attr/foo",
81ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                   test::BuildReference("android:color/black"))
82ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .Build();
83ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_NE(ValueCast<Style>(style.get()), nullptr);
84ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(ValueCast<Reference>(style.get()), nullptr);
851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}
861ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
87cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
88