From d6f06c33f7492ae1803824abea5f3bb3b0ad9d72 Mon Sep 17 00:00:00 2001 From: Derek Bailey Date: Mon, 22 Aug 2022 18:59:24 -0700 Subject: [PATCH] Reworked keep prefix (#7456) * reworked keep prefix * checking in missing schema * fix flatc path for build scripts --- .github/workflows/build.yml | 4 + src/idl_gen_cpp.cpp | 40 ++-- tests/flatc/bar/bar_with_foo.fbs | 6 + tests/flatc/flatc_cpp_tests.py | 342 ++++++++++++++++++++----------- tests/flatc/flatc_test.py | 2 +- tests/flatc/main.py | 2 - 6 files changed, 258 insertions(+), 138 deletions(-) create mode 100644 tests/flatc/bar/bar_with_foo.fbs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 82aad9297c5..f4b533149e5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,6 +80,8 @@ jobs: run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64 - name: test run: Release\flattests.exe + - name: flatc tests + run: python3 tests/flatc/main.py --flatc Release\flatc.exe - name: upload build artifacts uses: actions/upload-artifact@v1 with: @@ -181,6 +183,8 @@ jobs: run: | chmod +x _build/Release/flatc ./_build/Release/flatc --version + - name: flatc tests + run: python3 tests/flatc/main.py --flatc ./_build/Release/flatc - name: upload build artifacts uses: actions/upload-artifact@v1 with: diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index e5092717159..dadd474ab41 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -239,22 +239,34 @@ class CppGenerator : public BaseGenerator { // interdependence between them. std::stable_sort(included_files.begin(), included_files.end()); - // Get any prefix of the file being parsed, so that included filed can be - // properly stripped. - auto prefix = flatbuffers::StripFileName(parser_.file_being_parsed_) + - flatbuffers::kPathSeparator; + // The absolute path of the file being parsed. + const std::string parsed_path = + flatbuffers::StripFileName(AbsolutePath(parser_.file_being_parsed_)); for (const std::string &included_file : included_files) { - auto file_without_extension = flatbuffers::StripExtension(included_file); - code_ += - "#include \"" + - GeneratedFileName( - opts_.include_prefix, - opts_.keep_prefix - ? flatbuffers::StripPrefix(file_without_extension, prefix) - : flatbuffers::StripPath(file_without_extension), - opts_) + - "\""; + // The base name of the file, without path or extensions. + std::string basename = + flatbuffers::StripPath(flatbuffers::StripExtension(included_file)); + + // If we are keeping the prefix + if (opts_.keep_prefix) { + // The absolute path of the included file. + const std::string included_path = + flatbuffers::StripFileName(AbsolutePath(included_file)); + + // The relative path of the parsed file to the included file. + const std::string relative_path = + RelativeToRootPath(parsed_path, included_path).substr(2); + + // Only consider cases where the included path is a subdirectory of the + // parsed path. + if (strncmp("..", relative_path.c_str(), 2) != 0) { + basename = relative_path + kPathSeparator + basename; + } + } + + code_ += "#include \"" + + GeneratedFileName(opts_.include_prefix, basename, opts_) + "\""; } if (!parser_.native_included_files_.empty() || !included_files.empty()) { diff --git a/tests/flatc/bar/bar_with_foo.fbs b/tests/flatc/bar/bar_with_foo.fbs new file mode 100644 index 00000000000..d5c0f9c3f76 --- /dev/null +++ b/tests/flatc/bar/bar_with_foo.fbs @@ -0,0 +1,6 @@ +include "foo.fbs"; +include "baz/baz.fbs"; + +table BarWithFoo { + foo:Foo; +} \ No newline at end of file diff --git a/tests/flatc/flatc_cpp_tests.py b/tests/flatc/flatc_cpp_tests.py index 609eeccd36f..72b2e9df58f 100755 --- a/tests/flatc/flatc_cpp_tests.py +++ b/tests/flatc/flatc_cpp_tests.py @@ -14,141 +14,241 @@ from flatc_test import * -class CppTests(): - def Flatten(self): - # Generate just foo with a "flatten" import of bar. - flatc(["--cpp", "foo.fbs"]) +class CppTests: + def Flatten(self): + # Generate just foo with a "flatten" import of bar. + flatc(["--cpp", "foo.fbs"]) - # Foo should be generated in place and include bar flatten - assert_file_and_contents("foo_generated.h", '#include "bar_generated.h"') + # Foo should be generated in place and include bar flatten + assert_file_and_contents("foo_generated.h", '#include "bar_generated.h"') - def FlattenAbsolutePath(self): - # Generate just foo with a "flatten" import of bar. - flatc(["--cpp", make_absolute("foo.fbs")]) + def FlattenAbsolutePath(self): + # Generate just foo with a "flatten" import of bar. + flatc(["--cpp", make_absolute("foo.fbs")]) - # Foo should be generated in place and include bar flatten - assert_file_and_contents("foo_generated.h", '#include "bar_generated.h"') + # Foo should be generated in place and include bar flatten + assert_file_and_contents("foo_generated.h", '#include "bar_generated.h"') - def FlattenSubDirectory(self): - # Generate just foo with a "flatten" import of bar. - flatc(["--cpp", "bar/bar.fbs"]) - - # Bar should be generated in place and include baz - assert_file_and_contents("bar_generated.h", '#include "baz_generated.h"') + def FlattenSubDirectory(self): + # Generate just foo with a "flatten" import of bar. + flatc(["--cpp", "bar/bar.fbs"]) - def FlattenOutPath(self): - # Generate just foo with a "flatten" import of bar. - flatc(["--cpp", "-o", ".tmp", "foo.fbs"]) + # Bar should be generated in place and include baz + assert_file_and_contents("bar_generated.h", '#include "baz_generated.h"') - # Foo should be generated in the out path and include bar flatten to the out path. - assert_file_and_contents(".tmp/foo_generated.h", '#include "bar_generated.h"') + def FlattenOutPath(self): + # Generate just foo with a "flatten" import of bar. + flatc(["--cpp", "-o", ".tmp", "foo.fbs"]) - def FlattenOutPathSuperDirectory(self): - # Generate just foo with a "flatten" import of bar. - flatc(["--cpp", "-o", "../.tmp", "foo.fbs"]) + # Foo should be generated in the out path and include bar flatten to the out path. + assert_file_and_contents(".tmp/foo_generated.h", '#include "bar_generated.h"') - # Foo should be generated in the out path and include bar flatten to the out path. - assert_file_and_contents("../.tmp/foo_generated.h", '#include "bar_generated.h"') + def FlattenOutPathSuperDirectory(self): + # Generate just foo with a "flatten" import of bar. + flatc(["--cpp", "-o", "../.tmp", "foo.fbs"]) - def FlattenOutPathSubDirectory(self): - # Generate just foo with a "flatten" import of bar. - flatc(["--cpp", "-o", ".tmp", "bar/bar.fbs"]) + # Foo should be generated in the out path and include bar flatten to the out path. + assert_file_and_contents( + "../.tmp/foo_generated.h", '#include "bar_generated.h"' + ) - # Bar should be generated in the out path and include baz flatten to the out path. - assert_file_and_contents(".tmp/bar_generated.h", '#include "baz_generated.h"') + def FlattenOutPathSubDirectory(self): + # Generate just foo with a "flatten" import of bar. + flatc(["--cpp", "-o", ".tmp", "bar/bar.fbs"]) - def KeepPrefix(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "foo.fbs"]) + # Bar should be generated in the out path and include baz flatten to the out path. + assert_file_and_contents(".tmp/bar_generated.h", '#include "baz_generated.h"') - assert_file_and_contents("foo_generated.h", '#include "bar/bar_generated.h"') + def KeepPrefix(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", "foo.fbs"]) - def KeepPrefixAbsolutePath(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", make_absolute("foo.fbs")]) + assert_file_and_contents("foo_generated.h", '#include "bar/bar_generated.h"') - assert_file_and_contents("foo_generated.h", '#include "bar/bar_generated.h"') + def KeepPrefixAbsolutePath(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", make_absolute("foo.fbs")]) - def KeepPrefixSubDirectory(self): - # Generate with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "bar/bar.fbs"]) + assert_file_and_contents("foo_generated.h", '#include "bar/bar_generated.h"') - assert_file_and_contents("bar_generated.h", '#include "baz/baz_generated.h"') - - def KeepPrefixOutPath(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "-o", ".tmp", "foo.fbs"]) - - assert_file_and_contents(".tmp/foo_generated.h", '#include "bar/bar_generated.h"') - - def KeepPrefixOutPathSubDirectory(self): - # Generate with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "-o", ".tmp", "bar/bar.fbs"]) - - assert_file_and_contents(".tmp/bar_generated.h", '#include "baz/baz_generated.h"') - - def IncludePrefix(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--include-prefix", "test", "foo.fbs"]) - - assert_file_and_contents("foo_generated.h", '#include "test/bar_generated.h"') - - def IncludePrefixAbolutePath(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--include-prefix", "test", make_absolute("foo.fbs")]) - - assert_file_and_contents("foo_generated.h", '#include "test/bar_generated.h"') - - def IncludePrefixSubDirectory(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--include-prefix", "test", "bar/bar.fbs"]) - - assert_file_and_contents("bar_generated.h", '#include "test/baz_generated.h"') - - def IncludePrefixOutPath(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--include-prefix", "test", "-o", ".tmp", "foo.fbs"]) - - assert_file_and_contents(".tmp/foo_generated.h", '#include "test/bar_generated.h"') - - def IncludePrefixOutPathSubDirectory(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--include-prefix", "test", "-o", ".tmp", "bar/bar.fbs"]) - - assert_file_and_contents(".tmp/bar_generated.h", '#include "test/baz_generated.h"') - - def KeepPrefixIncludePrefix(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", "foo.fbs"]) - - # The include prefix should come first, with the kept prefix next. - assert_file_and_contents("foo_generated.h", '#include "test/bar/bar_generated.h"') - - def KeepPrefixIncludePrefixAbsolutePath(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", make_absolute("foo.fbs")]) - - # The include prefix should come first, with the kept prefix next. - assert_file_and_contents("foo_generated.h", '#include "test/bar/bar_generated.h"') - - def KeepPrefixIncludePrefixSubDirectory(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", "bar/bar.fbs"]) - - # The include prefix should come first, with the kept prefix next. - assert_file_and_contents("bar_generated.h", '#include "test/baz/baz_generated.h"') - - def KeepPrefixIncludePrefixOutPathSubDirectory(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", "-o", ".tmp", "bar/bar.fbs"]) - - # The include prefix should come first, with the kept prefix next. - assert_file_and_contents(".tmp/bar_generated.h", '#include "test/baz/baz_generated.h"') - - def KeepPrefixIncludePrefixOutPathSuperDirectory(self): - # Generate just foo with the import of bar keeping the prefix of where it is located. - flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", "-o", "../.tmp", "bar/bar.fbs"]) - - # The include prefix should come first, with the kept prefix next. - assert_file_and_contents("../.tmp/bar_generated.h", '#include "test/baz/baz_generated.h"') \ No newline at end of file + def KeepPrefixSubDirectory(self): + # Generate with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", "bar/bar.fbs"]) + + assert_file_and_contents("bar_generated.h", '#include "baz/baz_generated.h"') + + def KeepPrefixOutPath(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", "-o", ".tmp", "foo.fbs"]) + + assert_file_and_contents( + ".tmp/foo_generated.h", + '#include "bar/bar_generated.h"', + ) + + def KeepPrefixOutPathSubDirectory(self): + # Generate with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", "-o", ".tmp", "bar/bar.fbs"]) + + assert_file_and_contents( + ".tmp/bar_generated.h", '#include "baz/baz_generated.h"' + ) + + def IncludePrefix(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--include-prefix", "test", "foo.fbs"]) + + assert_file_and_contents("foo_generated.h", '#include "test/bar_generated.h"') + + def IncludePrefixAbolutePath(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--include-prefix", "test", make_absolute("foo.fbs")]) + + assert_file_and_contents("foo_generated.h", '#include "test/bar_generated.h"') + + def IncludePrefixSubDirectory(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--include-prefix", "test", "bar/bar.fbs"]) + + assert_file_and_contents("bar_generated.h", '#include "test/baz_generated.h"') + + def IncludePrefixOutPath(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--include-prefix", "test", "-o", ".tmp", "foo.fbs"]) + + assert_file_and_contents( + ".tmp/foo_generated.h", '#include "test/bar_generated.h"' + ) + + def IncludePrefixOutPathSubDirectory(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--include-prefix", "test", "-o", ".tmp", "bar/bar.fbs"]) + + assert_file_and_contents( + ".tmp/bar_generated.h", '#include "test/baz_generated.h"' + ) + + def KeepPrefixIncludePrefix(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", "foo.fbs"]) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + "foo_generated.h", '#include "test/bar/bar_generated.h"' + ) + + def KeepPrefixIncludePrefixAbsolutePath(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc( + [ + "--cpp", + "--keep-prefix", + "--include-prefix", + "test", + make_absolute("foo.fbs"), + ] + ) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + "foo_generated.h", '#include "test/bar/bar_generated.h"' + ) + + def KeepPrefixIncludePrefixSubDirectory(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc(["--cpp", "--keep-prefix", "--include-prefix", "test", "bar/bar.fbs"]) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + "bar_generated.h", '#include "test/baz/baz_generated.h"' + ) + + def KeepPrefixIncludePrefixOutPathSubDirectory(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc( + [ + "--cpp", + "--keep-prefix", + "--include-prefix", + "test", + "-o", + ".tmp", + "bar/bar.fbs", + ] + ) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + ".tmp/bar_generated.h", '#include "test/baz/baz_generated.h"' + ) + + def KeepPrefixIncludePrefixOutPathSuperDirectory(self): + # Generate just foo with the import of bar keeping the prefix of where it is located. + flatc( + [ + "--cpp", + "--keep-prefix", + "--include-prefix", + "test", + "-o", + "../.tmp", + "bar/bar.fbs", + ] + ) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + "../.tmp/bar_generated.h", '#include "test/baz/baz_generated.h"' + ) + + def KeepPrefixIncludePrefixoutPathAbsoluePaths_SuperDirectoryReference(self): + # Generate bar_with_foo that references a type in a super directory. + flatc( + [ + "--cpp", + "--keep-prefix", + "--include-prefix", + "generated", + "-I", + str(script_path.absolute()), + "-o", + str(Path(script_path, ".tmp").absolute()), + str(Path(script_path, "bar/bar_with_foo.fbs").absolute()), + ] + ) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + ".tmp/bar_with_foo_generated.h", + [ + '#include "generated/baz/baz_generated.h"', + '#include "generated/foo_generated.h"', + ], + ) + + def KeepPrefixIncludePrefixoutPath_SuperDirectoryReference(self): + # Generate bar_with_foo that references a type in a super directory. + flatc( + [ + "--cpp", + "--keep-prefix", + "--include-prefix", + "generated", + "-I", + "./", + "-o", + ".tmp", + "bar/bar_with_foo.fbs", + ] + ) + + # The include prefix should come first, with the kept prefix next. + assert_file_and_contents( + ".tmp/bar_with_foo_generated.h", + [ + '#include "generated/baz/baz_generated.h"', + '#include "generated/foo_generated.h"', + ], + unlink=False, + ) diff --git a/tests/flatc/flatc_test.py b/tests/flatc/flatc_test.py index 41889384cb6..fcc32c6c274 100755 --- a/tests/flatc/flatc_test.py +++ b/tests/flatc/flatc_test.py @@ -52,7 +52,7 @@ def flatc(options, cwd=script_path): def make_absolute(filename, path=script_path): - return Path(path, filename).absolute() + return str(Path(path, filename).absolute()) def assert_file_exists(filename, path=script_path): diff --git a/tests/flatc/main.py b/tests/flatc/main.py index 656bc4698de..1b6bee90d7c 100755 --- a/tests/flatc/main.py +++ b/tests/flatc/main.py @@ -27,5 +27,3 @@ if failing > 0: sys.exit(1) - -# TsTests().Base() \ No newline at end of file