Apply CleanPath() before comparing paths
Paths are sometimes prefixed with "./". CleanPath() is moved from
FakeIoDelegate to IoDelegate so that Parser uses it before comparing
paths.
Ideally, we should use std::filesystem::path::lexically_normal(), but
it's not available on windows platform which we support.
Removing "./" is good enough for most cases. To be specific, this
happens when we pass "-I.".
Bug: n/a
Test: m (aidl_unittests)
Change-Id: Ied6eaf1b264102d997306ac0cc2c32934056b27c
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 0218561..81931a1 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -962,7 +962,7 @@
TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
const string expected_stderr =
- "ERROR: ./o/WhoKnowsWhat.aidl:1.22-35: o.WhoKnowsWhat is not structured, but this is a "
+ "ERROR: o/WhoKnowsWhat.aidl:1.22-35: o.WhoKnowsWhat is not structured, but this is a "
"structured interface.\n";
io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl", "package o; parcelable WhoKnowsWhat;");
import_paths_.emplace("");
diff --git a/io_delegate.cpp b/io_delegate.cpp
index 45ef65a..c05f4b1 100644
--- a/io_delegate.cpp
+++ b/io_delegate.cpp
@@ -43,6 +43,7 @@
using android::base::Error;
using android::base::Result;
using android::base::Split;
+using android::base::StartsWith;
namespace android {
namespace aidl {
@@ -244,5 +245,12 @@
}
#endif
+string IoDelegate::CleanPath(const string& path) {
+ if (base::StartsWith(path, string{'.', OS_PATH_SEPARATOR})) {
+ return path.substr(2);
+ }
+ return path;
+}
+
} // namespace android
} // namespace aidl
diff --git a/io_delegate.h b/io_delegate.h
index 6c1ef96..e0b7252 100644
--- a/io_delegate.h
+++ b/io_delegate.h
@@ -44,6 +44,9 @@
static bool GetAbsolutePath(const std::string& path,
std::string* absolute_path);
+ // Remove leading "./" from |path|.
+ static std::string CleanPath(const std::string& path);
+
// Returns a unique_ptr to the contents of |filename|.
// Will append the optional |content_suffix| to the returned contents.
virtual std::unique_ptr<std::string> GetFileContents(
diff --git a/parser.cpp b/parser.cpp
index 93770bb..abe1dbf 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -28,16 +28,17 @@
const AidlDocument* Parser::Parse(const std::string& filename,
const android::aidl::IoDelegate& io_delegate,
AidlTypenames& typenames) {
+ auto clean_path = android::aidl::IoDelegate::CleanPath(filename);
// reuse pre-parsed document from typenames
for (auto& doc : typenames.AllDocuments()) {
- if (doc->GetLocation().GetFile() == filename) {
+ if (doc->GetLocation().GetFile() == clean_path) {
return doc.get();
}
}
// Make sure we can read the file first, before trashing previous state.
- unique_ptr<string> raw_buffer = io_delegate.GetFileContents(filename);
+ unique_ptr<string> raw_buffer = io_delegate.GetFileContents(clean_path);
if (raw_buffer == nullptr) {
- AIDL_ERROR(filename) << "Error while opening file for parsing";
+ AIDL_ERROR(clean_path) << "Error while opening file for parsing";
return nullptr;
}
@@ -45,7 +46,7 @@
// nulls at the end.
raw_buffer->append(2u, '\0');
- Parser parser(filename, *raw_buffer, typenames);
+ Parser parser(clean_path, *raw_buffer, typenames);
if (yy::parser(&parser).parse() != 0 || parser.HasError()) {
return nullptr;
diff --git a/tests/fake_io_delegate.cpp b/tests/fake_io_delegate.cpp
index a99a20a..5e912ce 100644
--- a/tests/fake_io_delegate.cpp
+++ b/tests/fake_io_delegate.cpp
@@ -167,16 +167,6 @@
return false;
}
-string FakeIoDelegate::CleanPath(const string& path) const {
- string clean_path = path;
- while (clean_path.length() >= 2 &&
- clean_path[0] == '.' &&
- clean_path[1] == OS_PATH_SEPARATOR) {
- clean_path = clean_path.substr(2);
- }
- return clean_path;
-}
-
} // namespace test
} // namespace aidl
} // namespace android
diff --git a/tests/fake_io_delegate.h b/tests/fake_io_delegate.h
index 6f24678..0e278f4 100644
--- a/tests/fake_io_delegate.h
+++ b/tests/fake_io_delegate.h
@@ -68,9 +68,6 @@
bool PathWasRemoved(const std::string& path);
private:
- // Remove leading "./" from |path|.
- std::string CleanPath(const std::string& path) const;
-
std::map<std::string, std::string> file_contents_;
// Normally, writing to files leaves the IoDelegate unchanged, so
// GetCodeWriter is a const method. However, for tests, we break this