summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-10-22 08:46:12 -0400
committerGitHub <noreply@github.com>2020-10-22 08:46:12 -0400
commit10e1bae34733f1cdb5abc001666b1aafa1c1f406 (patch)
treead9571c071b7b7c2384cdd42426851d257fc5f7b
parentc0943661e5441bfb996430c4f67fb4dddea9dfcf (diff)
Single pass C++ extraction (#1583)
* #include an absolute path didn't work - because paths were taken to always be relative. * Added CharUtil. Added TypeSet to extractor. First pass at being able to specify all headers for multiple output headers. * Fix includes for new C++ extractor convension. Update premake5 to use new extractor mechanisms. * Small improvements around StringUtil. * Split out NameConventionUtil. * Use a 'convert' to convert between convention types. * Fix output of build message for C++ extractor. Improve NameConventionUtil interface. * Improve comments. * Fix warning on gcc. * Fix clang warning. * Fix some typos in NameConventionUtil. * Small fix to premake5.lua * Fix generated includes. * Remove m_reflectType as no longer applicable with TypeSet. * Fix .gitignore for slang-generated-* files. Added getConvention to determine convention from slice. Add versions of split and convert that infer the from convention * Fix typo in spliting camel. * LineWhitespace -> HorizontalWhitespace * Improve CharUtil comments.
-rw-r--r--.gitignore3
-rw-r--r--premake5.lua94
-rw-r--r--source/core/core.vcxproj4
-rw-r--r--source/core/core.vcxproj.filters12
-rw-r--r--source/core/slang-char-util.cpp48
-rw-r--r--source/core/slang-char-util.h51
-rw-r--r--source/core/slang-name-convention-util.cpp213
-rw-r--r--source/core/slang-name-convention-util.h54
-rw-r--r--source/core/slang-string-util.h1
-rw-r--r--source/core/slang-string.cpp20
-rw-r--r--source/core/slang-string.h1
-rw-r--r--source/slang/run-generators.vcxproj29
-rw-r--r--source/slang/run-generators.vcxproj.filters3
-rw-r--r--source/slang/slang-ast-base.h2
-rw-r--r--source/slang/slang-ast-decl.cpp2
-rw-r--r--source/slang/slang-ast-dump.cpp2
-rw-r--r--source/slang/slang-ast-reflect.cpp14
-rw-r--r--source/slang/slang-ast-reflect.h2
-rw-r--r--source/slang/slang-ast-substitutions.cpp2
-rw-r--r--source/slang/slang-ast-support-types.h9
-rw-r--r--source/slang/slang-ast-type.cpp2
-rw-r--r--source/slang/slang-ast-val.cpp2
-rw-r--r--source/slang/slang-diagnostics.cpp53
-rw-r--r--source/slang/slang-ref-object-reflect.cpp4
-rw-r--r--source/slang/slang-ref-object-reflect.h2
-rw-r--r--source/slang/slang-serialize-ast.cpp4
-rw-r--r--source/slang/slang-serialize-reflection.h2
-rw-r--r--source/slang/slang-visitor.h6
-rw-r--r--source/slang/slang.vcxproj14
-rw-r--r--source/slang/slang.vcxproj.filters42
-rw-r--r--tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h3
-rw-r--r--tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp763
32 files changed, 971 insertions, 492 deletions
diff --git a/.gitignore b/.gitignore
index f03caafb7..5e6985759 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,8 +37,7 @@ tests/**/*.slang-module
*.spv
# Intermediate source files generated during build process
-/source/slang/slang-ast-generated.h
-/source/slang/slang-ast-generated-macro.h
+/source/slang/slang-generated-*.h
/source/slang/hlsl.meta.slang.h
/source/slang/core.meta.slang.h
prelude/*.h.cpp
diff --git a/premake5.lua b/premake5.lua
index 23d7d3e60..1bbfa26a7 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -773,40 +773,6 @@ tool "gfx"
-- might be able to do pic(true)
buildoptions{"-fPIC"}
-
-function runCPPExtractor(sourcePath, name, inputFiles, stripPrefix, typeName, markSuffix)
-
- local generatedName = "slang-" .. name .. "-generated.h"
- local generatedMacroName = "slang-" .. name .. "-generated-macro.h"
-
- local options = { "-strip-prefix", stripPrefix, "-reflect-type", typeName, " ", "-o", "slang-" .. name .. "-generated", "-output-fields", "-mark-suffix", markSuffix}
-
- -- Specify the actual command to run for this action.
- --
- -- Note that we use a single-quoted Lua string and wrap the path
- -- to the `slang-cpp-extractor` command in double quotes to avoid
- -- confusing the Windows shell. It seems that Premake outputs that
- -- path with forward slashes, which confused the shell if we don't
- -- quote the executable path.
-
- local buildcmd = '"%{cfg.targetdir}/slang-cpp-extractor" -d ' .. sourcePath .. " " .. table.concat(inputFiles, " ") .. " " .. table.concat(options, " ")
-
- buildcommands { buildcmd }
-
- -- Specify the files output by the extactor - so custom action will run when these files are needed.
- --
- buildoutputs { sourcePath .. generatedName, sourcePath .. generatedMacroName}
-
- -- Make it depend on the extractor tool itself
- local buildInputTable = { "%{cfg.targetdir}/slang-cpp-extractor" .. getExecutableSuffix() }
- for key, inputFile in ipairs(inputFiles) do
- table.insert(buildInputTable, sourcePath .. "/" .. inputFile)
- end
-
- --
- buildinputs(buildInputTable)
-end
-
--
-- The `slangc` command-line application is just a very thin wrapper
-- around the Slang dynamic library, so its build is extermely simple.
@@ -832,7 +798,6 @@ generatorProject("run-generators", "source/slang/")
{
"source/slang/*.meta.slang", -- The stdlib files
"source/slang/slang-ast-reflect.h", -- C++ reflection
- "source/slang/slang-ref-object-reflect.h", -- More C++ reflection
"prelude/*.h", -- The prelude files
--
@@ -854,24 +819,55 @@ generatorProject("run-generators", "source/slang/")
-- We need to run the C++ extractor to generate some include files
if executeBinary then
- local sourcePath = "%{file.directory}"
-
- filter "files:**/slang-ast-reflect.h"
+ filter "files:**/slang-ast-reflect.h"
+ do
+ buildmessage "C++ Extractor %{file.relpath}"
- buildmessage "slang-cpp-extractor value%{file.relpath}"
-
- runCPPExtractor(sourcePath, "value", { "slang-ast-support-types.h" }, "slang-", "Value", "_VALUE_CLASS")
+ local sourcePath = "%{file.directory}"
- filter "files:**/slang-ast-reflect.h"
- buildmessage "slang-cpp-extractor ref-object %{file.relpath}"
-
- runCPPExtractor(sourcePath, "ref-object", { "slang-ast-support-types.h" }, "slang-", "RefObject", "_OBJ_CLASS")
+ -- Work out the output files
- filter "files:**/slang-ast-reflect.h"
- do
- local inputFiles = { "slang-ast-base.h", "slang-ast-decl.h", "slang-ast-expr.h", "slang-ast-modifier.h", "slang-ast-stmt.h", "slang-ast-type.h", "slang-ast-val.h" }
- runCPPExtractor(sourcePath, "ast", inputFiles, "slang-ast", "ASTNode", "_AST_CLASS")
+ local outputTypes = { "obj", "ast", "value" };
+
+ local outputTable = {}
+
+ for key, outputType in ipairs(outputTypes) do
+ table.insert(outputTable, sourcePath .. "/slang-generated-" .. outputType .. ".h")
+ table.insert(outputTable, sourcePath .. "/slang-generated-" .. outputType .. "-macro.h")
+ end
+
+ -- List all of the input files to be scanned
+
+ local inputFiles = { "slang-ast-support-types.h", "slang-ast-base.h", "slang-ast-decl.h", "slang-ast-expr.h", "slang-ast-modifier.h", "slang-ast-stmt.h", "slang-ast-type.h", "slang-ast-val.h" }
+
+ local options = { "-strip-prefix", "slang-", "-o", "slang-generated", "-output-fields", "-mark-suffix", "_CLASS"}
+
+ -- Specify the actual command to run for this action.
+ --
+ -- Note that we use a single-quoted Lua string and wrap the path
+ -- to the `slang-cpp-extractor` command in double quotes to avoid
+ -- confusing the Windows shell. It seems that Premake outputs that
+ -- path with forward slashes, which confused the shell if we don't
+ -- quote the executable path.
+
+ local buildcmd = '"%{cfg.targetdir}/slang-cpp-extractor" -d ' .. sourcePath .. " " .. table.concat(inputFiles, " ") .. " " .. table.concat(options, " ")
+
+ buildcommands { buildcmd }
+
+ -- Specify the files output by the extactor - so custom action will run when these files are needed.
+ --
+ buildoutputs(outputTable)
+
+ -- Make it depend on the extractor tool itself
+ local buildInputTable = { "%{cfg.targetdir}/slang-cpp-extractor" .. getExecutableSuffix() }
+ for key, inputFile in ipairs(inputFiles) do
+ table.insert(buildInputTable, sourcePath .. "/" .. inputFile)
+ end
+
+ --
+ buildinputs(buildInputTable)
end
+
end
-- Next, we want to add a custom build rule for each of the
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj
index 38f06b407..063d1aa0b 100644
--- a/source/core/core.vcxproj
+++ b/source/core/core.vcxproj
@@ -176,6 +176,7 @@
<ClInclude Include="slang-basic.h" />
<ClInclude Include="slang-blob.h" />
<ClInclude Include="slang-byte-encode-util.h" />
+ <ClInclude Include="slang-char-util.h" />
<ClInclude Include="slang-common.h" />
<ClInclude Include="slang-dictionary.h" />
<ClInclude Include="slang-downstream-compiler.h" />
@@ -189,6 +190,7 @@
<ClInclude Include="slang-list.h" />
<ClInclude Include="slang-math.h" />
<ClInclude Include="slang-memory-arena.h" />
+ <ClInclude Include="slang-name-convention-util.h" />
<ClInclude Include="slang-nvrtc-compiler.h" />
<ClInclude Include="slang-offset-container.h" />
<ClInclude Include="slang-platform.h" />
@@ -219,12 +221,14 @@
<ItemGroup>
<ClCompile Include="slang-blob.cpp" />
<ClCompile Include="slang-byte-encode-util.cpp" />
+ <ClCompile Include="slang-char-util.cpp" />
<ClCompile Include="slang-downstream-compiler.cpp" />
<ClCompile Include="slang-free-list.cpp" />
<ClCompile Include="slang-gcc-compiler-util.cpp" />
<ClCompile Include="slang-hex-dump-util.cpp" />
<ClCompile Include="slang-io.cpp" />
<ClCompile Include="slang-memory-arena.cpp" />
+ <ClCompile Include="slang-name-convention-util.cpp" />
<ClCompile Include="slang-nvrtc-compiler.cpp" />
<ClCompile Include="slang-offset-container.cpp" />
<ClCompile Include="slang-platform.cpp" />
diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters
index 7514fa1c9..afae1d124 100644
--- a/source/core/core.vcxproj.filters
+++ b/source/core/core.vcxproj.filters
@@ -27,6 +27,9 @@
<ClInclude Include="slang-byte-encode-util.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-char-util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-common.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -66,6 +69,9 @@
<ClInclude Include="slang-memory-arena.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-name-convention-util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-nvrtc-compiler.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -152,6 +158,9 @@
<ClCompile Include="slang-byte-encode-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-char-util.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-downstream-compiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -170,6 +179,9 @@
<ClCompile Include="slang-memory-arena.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-name-convention-util.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-nvrtc-compiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/core/slang-char-util.cpp b/source/core/slang-char-util.cpp
new file mode 100644
index 000000000..53dd98541
--- /dev/null
+++ b/source/core/slang-char-util.cpp
@@ -0,0 +1,48 @@
+#include "slang-char-util.h"
+
+namespace Slang {
+
+static const CharUtil::CharFlagMap _calcCharFlagsMap()
+{
+ typedef CharUtil::Flag Flag;
+
+ CharUtil::CharFlagMap map;
+ memset(&map, 0, sizeof(map));
+
+ {
+ for (Index i = 'a'; i <= 'z'; ++i)
+ {
+ map.flags[i] |= Flag::Lower;
+ }
+ }
+ {
+ for (Index i = 'A'; i <= 'Z'; ++i)
+ {
+ map.flags[i] |= Flag::Upper;
+ }
+ }
+ {
+ for (Index i = '0'; i <= '9'; ++i)
+ {
+ map.flags[i] |= Flag::Digit | Flag::HexDigit;
+ }
+ }
+ {
+ for (Index i = 'a'; i <= 'f'; ++i)
+ {
+ map.flags[i] |= Flag::HexDigit;
+ map.flags[size_t(CharUtil::toUpper(char(i)))] |= Flag::HexDigit;
+ }
+ }
+
+ {
+ map.flags[size_t(' ')] |= Flag::HorizontalWhitespace;
+ map.flags[size_t('\t')] |= Flag::HorizontalWhitespace;
+ }
+
+ return map;
+}
+
+/* static */const CharUtil::CharFlagMap CharUtil::g_charFlagMap = _calcCharFlagsMap();
+
+} // namespace Slang
diff --git a/source/core/slang-char-util.h b/source/core/slang-char-util.h
new file mode 100644
index 000000000..810cde0b1
--- /dev/null
+++ b/source/core/slang-char-util.h
@@ -0,0 +1,51 @@
+#ifndef SLANG_CORE_CHAR_UTIL_H
+#define SLANG_CORE_CHAR_UTIL_H
+
+#include "slang-string.h"
+
+namespace Slang {
+
+struct CharUtil
+{
+ typedef uint8_t Flags;
+ struct Flag
+ {
+ enum Enum : Flags
+ {
+ Upper = 0x01, ///< A-Z
+ Lower = 0x02, ///< a-z
+ Digit = 0x04, ///< 0-9
+ HorizontalWhitespace = 0x08, ///< Whitespace that can appear horizontally (ie excluding CR/LF)
+ HexDigit = 0x10, ///< 0-9, a-f, A-F
+ };
+ };
+
+ SLANG_FORCE_INLINE static bool isDigit(char c) { return c >= '0' && c <= '9'; }
+ SLANG_FORCE_INLINE static bool isLower(char c) { return c >= 'a' && c <= 'z'; }
+ SLANG_FORCE_INLINE static bool isUpper(char c) { return c >= 'A' && c <= 'Z'; }
+ SLANG_FORCE_INLINE static bool isHorizontalWhitespace(char c) { return c == ' ' || c == '\t'; }
+
+ /// True if it's alpha
+ SLANG_FORCE_INLINE static bool isAlpha(char c) { return (getFlags(c) & (Flag::Upper | Flag::Lower)) != 0; }
+
+ SLANG_FORCE_INLINE static bool isHexDigit(char c) { return (getFlags(c) & Flag::HexDigit) != 0; }
+
+ /// For a given character get the associated flags
+ SLANG_FORCE_INLINE static Flags getFlags(char c) { return g_charFlagMap.flags[size_t(c)]; }
+
+ /// Given a character return the lower case equivalent
+ SLANG_FORCE_INLINE static char toLower(char c) { return (c >= 'A' && c <= 'Z') ? (c -'A' + 'a') : c; }
+ /// Given a character return the upper case equivalent
+ SLANG_FORCE_INLINE static char toUpper(char c) { return (c >= 'a' && c <= 'z') ? (c -'a' + 'A') : c; }
+
+ struct CharFlagMap
+ {
+ Flags flags[0x100];
+ };
+
+ static const CharFlagMap g_charFlagMap;
+};
+
+} // namespace Slang
+
+#endif // SLANG_CHAR_UTIL_H
diff --git a/source/core/slang-name-convention-util.cpp b/source/core/slang-name-convention-util.cpp
new file mode 100644
index 000000000..a5acc6370
--- /dev/null
+++ b/source/core/slang-name-convention-util.cpp
@@ -0,0 +1,213 @@
+
+#include "slang-name-convention-util.h"
+
+#include "slang-char-util.h"
+#include "slang-string-util.h"
+
+namespace Slang
+{
+
+/* static */NameConvention NameConventionUtil::getConvention(const UnownedStringSlice& slice)
+{
+ for (const char c : slice)
+ {
+ switch (c)
+ {
+ case '-': return NameConvention::Kabab;
+ case '_': return NameConvention::Snake;
+ default: break;
+ }
+ }
+ return NameConvention::Camel;
+}
+
+/* static */void NameConventionUtil::split(NameConvention convention, const UnownedStringSlice& slice, List<UnownedStringSlice>& out)
+{
+ switch (convention)
+ {
+ case NameConvention::Kabab:
+ {
+ StringUtil::split(slice, '-', out);
+ break;
+ }
+ case NameConvention::Snake:
+ {
+ StringUtil::split(slice, '_', out);
+ break;
+ }
+ case NameConvention::Camel:
+ {
+ typedef CharUtil::Flags CharFlags;
+ typedef CharUtil::Flag CharFlag;
+
+ CharFlags prevFlags = 0;
+ const char*const end = slice.end();
+
+ const char* start = slice.begin();
+ for (const char* cur = start; cur < end; ++cur)
+ {
+ const char c = *cur;
+ const CharUtil::Flags flags = CharUtil::getFlags(c);
+
+ if (flags & CharFlag::Upper)
+ {
+ if (prevFlags & CharFlag::Lower)
+ {
+ // If we go from lower to upper, we have a transition
+ out.add(UnownedStringSlice(start, cur));
+ start = cur;
+ }
+ else if ((prevFlags & CharFlag::Upper) && cur + 1 < end)
+ {
+ // This works with capital or uncapitalized acronyms, but if we have two capitalized acronyms following each other - it can't split.
+ //
+ // For example
+ // "IAABBSystem" -> "IAABB", "System"
+ //
+ // If it only accepted lower case acronyms the logic could be changed such that the following could be produced
+ // "IAabbSystem" -> "I", "Aabb", "System"
+ //
+ // Since Slang source largely goes with upper case acronyms, we work with the heuristic here..
+
+ if (CharUtil::isLower(cur[1]))
+ {
+ out.add(UnownedStringSlice(start, cur));
+ start = cur;
+ }
+ }
+ }
+
+ prevFlags = flags;
+ }
+
+ // Add any end section
+ if (start < end)
+ {
+ out.add(UnownedStringSlice(start, end));
+ }
+ break;
+ }
+ }
+}
+
+void NameConventionUtil::split(const UnownedStringSlice& slice, List<UnownedStringSlice>& out)
+{
+ split(getConvention(slice), slice, out);
+}
+
+/* static */void NameConventionUtil::join(const UnownedStringSlice* slices, Index slicesCount, CharCase charCase, char joinChar, StringBuilder& out)
+{
+ if (slicesCount <= 0)
+ {
+ return;
+ }
+
+ Index totalSize = slicesCount - 1;
+ for (Index i = 0; i < slicesCount; ++i)
+ {
+ totalSize += slices[i].getLength();
+ }
+
+ char*const dstStart = out.prepareForAppend(totalSize);
+ char* dst = dstStart;
+
+ for (Index i = 0; i < slicesCount; ++i)
+ {
+ const UnownedStringSlice& slice = slices[i];
+ const Index count = slice.getLength();
+ const char*const src = slice.begin();
+
+ if (i > 0)
+ {
+ *dst++ = joinChar;
+ }
+
+ switch (charCase)
+ {
+ case CharCase::Upper:
+ {
+ for (Index j = 0; j < count; ++j)
+ {
+ dst[j] = CharUtil::toUpper(src[j]);
+ }
+ break;
+ }
+ case CharCase::Lower:
+ {
+ for (Index j = 0; j < count; ++j)
+ {
+ dst[j] = CharUtil::toLower(src[j]);
+ }
+ break;
+ }
+ }
+
+ dst += count;
+ }
+
+ SLANG_ASSERT(dstStart + totalSize == dst);
+ out.appendInPlace(dstStart, totalSize);
+}
+
+/* static */void NameConventionUtil::join(const UnownedStringSlice* slices, Index slicesCount, CharCase charCase, NameConvention convention, StringBuilder& out)
+{
+ switch (convention)
+ {
+ case NameConvention::Kabab: return join(slices, slicesCount, charCase, '-', out);
+ case NameConvention::Snake: return join(slices, slicesCount, charCase, '_', out);
+ case NameConvention::Camel:
+ {
+ Index totalSize = 0;
+
+ for (Index i = 0; i < slicesCount; ++i)
+ {
+ totalSize += slices[i].getLength();
+ }
+
+ char*const dstStart = out.prepareForAppend(totalSize);
+ char* dst = dstStart;
+
+ for (Index i = 0; i < slicesCount; ++i)
+ {
+ const UnownedStringSlice& slice = slices[i];
+ Index count = slice.getLength();
+ const char* src = slice.begin();
+
+ Int j = 0;
+
+ if (count > 0 && !(i == 0 && charCase == CharCase::Lower))
+ {
+ // Capitalize first letter of each word, unless on first word and 'lower'
+ dst[j] = CharUtil::toUpper(src[j]);
+ j++;
+ }
+
+ for (; j < count; ++j)
+ {
+ dst[j] = CharUtil::toLower(src[j]);
+ }
+
+ dst += count;
+ }
+ break;
+ }
+ }
+}
+
+/* static */void NameConventionUtil::convert(NameConvention fromConvention, const UnownedStringSlice& slice, CharCase charCase, NameConvention toConvention, StringBuilder& out)
+{
+ // Split into slices
+ List<UnownedStringSlice> slices;
+ split(fromConvention, slice, slices);
+
+ // Join the slices in the toConvention
+ join(slices.getBuffer(), slices.getCount(), charCase, toConvention, out);
+}
+
+/* static */void NameConventionUtil::convert(const UnownedStringSlice& slice, CharCase charCase, NameConvention toConvention, StringBuilder& out)
+{
+ convert(getConvention(slice), slice, charCase, toConvention, out);
+}
+
+}
+
diff --git a/source/core/slang-name-convention-util.h b/source/core/slang-name-convention-util.h
new file mode 100644
index 000000000..d4a984ca0
--- /dev/null
+++ b/source/core/slang-name-convention-util.h
@@ -0,0 +1,54 @@
+#ifndef SLANG_CORE_NAME_CONVENTION_UTIL_H
+#define SLANG_CORE_NAME_CONVENTION_UTIL_H
+
+#include "slang-string.h"
+#include "slang-list.h"
+
+namespace Slang
+{
+
+enum class NameConvention
+{
+ Kabab, /// Words are separated with -. WORDS-ARE-SEPARATED
+ Snake, /// Words are separated with _. WORDS_ARE_SEPARATED
+ Camel, /// Words start with a capital. (Upper will make first words character capitalized, aka PascalCase)
+};
+
+enum class CharCase
+{
+ Upper,
+ Lower,
+};
+
+/* This utility is to enable easy conversion and interpretation of names that use standard conventions, typically in programming
+languages. The conventions are largely how to represent multiple words together.
+
+Split is used to split up a name into it's constituent 'words' based on a convention.
+Join is used to combine words based on a convention/character case
+
+Convert uses split and join to allow easy conversion between conventions.
+*/
+struct NameConventionUtil
+{
+ /// Given a slice tries to determine the convention used.
+ /// If no separators are found, will assume Camel
+ static NameConvention getConvention(const UnownedStringSlice& slice);
+
+ /// Given a slice and a naming convention, split into it's constituent parts. If convention isn't specified, will infer from slice using getConvention.
+ static void split(NameConvention convention, const UnownedStringSlice& slice, List<UnownedStringSlice>& out);
+ static void split(const UnownedStringSlice& slice, List<UnownedStringSlice>& out);
+
+ /// Given slices, join together with the specified convention into out
+ static void join(const UnownedStringSlice* slices, Index slicesCount, CharCase charCase, NameConvention convention, StringBuilder& out);
+
+ /// Join with a join char, and potentially changing case of input slices
+ static void join(const UnownedStringSlice* slices, Index slicesCount, CharCase charCase, char joinChar, StringBuilder& out);
+
+ /// Convert from one convention to another. If fromConvention isn't specified, will infer from slice using getConvention.
+ static void convert(NameConvention fromConvention, const UnownedStringSlice& slice, CharCase charCase, NameConvention toConvention, StringBuilder& out);
+ static void convert(const UnownedStringSlice& slice, CharCase charCase, NameConvention toConvention, StringBuilder& out);
+};
+
+}
+
+#endif // SLANG_CORE_NAME_CONVENTION_UTIL_H
diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h
index 9f1508cb1..dee4c7d66 100644
--- a/source/core/slang-string-util.h
+++ b/source/core/slang-string-util.h
@@ -93,6 +93,7 @@ struct StringUtil
/// Convert in to int. Returns SLANG_FAIL on error
static SlangResult parseInt(const UnownedStringSlice& in, Int& outValue);
+
};
/* A helper class that allows parsing of lines from text with iteration. Uses StringUtil::extractLine for the actual underlying implementation. */
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index bcf5853d5..3ce4c7ec9 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -1,6 +1,8 @@
#include "slang-string.h"
#include "slang-text-io.h"
+#include "slang-char-util.h"
+
namespace Slang
{
// TODO: this belongs in a different file:
@@ -12,11 +14,6 @@ namespace Slang
throw InternalError(message);
}
- SLANG_FORCE_INLINE static bool _isWhiteSpace(char c)
- {
- return c == ' ' || c == '\t';
- }
-
// OSString
OSString::OSString()
@@ -112,11 +109,20 @@ namespace Slang
const char* start = m_begin;
const char* end = m_end;
- while (start < end && _isWhiteSpace(*start)) start++;
- while (end > start && _isWhiteSpace(end[-1])) end--;
+ while (start < end && CharUtil::isHorizontalWhitespace(*start)) start++;
+ while (end > start && CharUtil::isHorizontalWhitespace(end[-1])) end--;
return UnownedStringSlice(start, end);
}
+ UnownedStringSlice UnownedStringSlice::trim(char c) const
+ {
+ const char* start = m_begin;
+ const char* end = m_end;
+
+ while (start < end && *start == c) start++;
+ while (end > start && end[-1] == c) end--;
+ return UnownedStringSlice(start, end);
+ }
// StringSlice
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 25bf99023..75c282a58 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -174,6 +174,7 @@ namespace Slang
UnownedStringSlice trim() const;
+ UnownedStringSlice trim(char c) const;
HashCode getHashCode() const
{
diff --git a/source/slang/run-generators.vcxproj b/source/slang/run-generators.vcxproj
index 599f221b1..e38f9dc2d 100644
--- a/source/slang/run-generators.vcxproj
+++ b/source/slang/run-generators.vcxproj
@@ -156,7 +156,6 @@
<ItemGroup>
<ClInclude Include="..\..\prelude\slang-cpp-scalar-intrinsics.h" />
<ClInclude Include="..\..\prelude\slang-cpp-types.h" />
- <ClInclude Include="slang-ref-object-reflect.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\core\slang-string.cpp" />
@@ -229,24 +228,16 @@
</CustomBuild>
<CustomBuild Include="slang-ast-reflect.h">
<FileType>Document</FileType>
- <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
-"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
-"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _AST_CLASS</Command>
- <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
-"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
-"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _AST_CLASS</Command>
- <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
-"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
-"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _AST_CLASS</Command>
- <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
-"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
-"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast -reflect-type ASTNode -o slang-ast-generated -output-fields -mark-suffix _AST_CLASS</Command>
- <Outputs>../slangslang-value-generated.h;../slangslang-value-generated-macro.h;../slangslang-ref-object-generated.h;../slangslang-ref-object-generated-macro.h;../slangslang-ast-generated.h;../slangslang-ast-generated-macro.h</Outputs>
- <Message>slang-cpp-extractor ref-object %(Identity)</Message>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">slang-ast-support-types.h;../../bin/windows-x86/debug/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">slang-ast-support-types.h;../../bin/windows-x64/debug/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">slang-ast-support-types.h;../../bin/windows-x86/release/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
- <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">slang-ast-support-types.h;../../bin/windows-x64/release/slang-cpp-extractor.exe;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"../../bin/windows-x86/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang- -o slang-generated -output-fields -mark-suffix _CLASS</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"../../bin/windows-x64/debug/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang- -o slang-generated -output-fields -mark-suffix _CLASS</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"../../bin/windows-x86/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang- -o slang-generated -output-fields -mark-suffix _CLASS</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"../../bin/windows-x64/release/slang-cpp-extractor" -d %(RootDir)%(Directory) slang-ast-support-types.h slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang- -o slang-generated -output-fields -mark-suffix _CLASS</Command>
+ <Outputs>slang-generated-obj.h;slang-generated-obj-macro.h;slang-generated-ast.h;slang-generated-ast-macro.h;slang-generated-value.h;slang-generated-value-macro.h</Outputs>
+ <Message>C++ Extractor %(Identity)</Message>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../bin/windows-x86/debug/slang-cpp-extractor.exe;slang-ast-support-types.h;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../bin/windows-x64/debug/slang-cpp-extractor.exe;slang-ast-support-types.h;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../bin/windows-x86/release/slang-cpp-extractor.exe;slang-ast-support-types.h;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../bin/windows-x64/release/slang-cpp-extractor.exe;slang-ast-support-types.h;slang-ast-base.h;slang-ast-decl.h;slang-ast-expr.h;slang-ast-modifier.h;slang-ast-stmt.h;slang-ast-type.h;slang-ast-val.h</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/source/slang/run-generators.vcxproj.filters b/source/slang/run-generators.vcxproj.filters
index 9ec19c0d7..e8ec8394a 100644
--- a/source/slang/run-generators.vcxproj.filters
+++ b/source/slang/run-generators.vcxproj.filters
@@ -15,9 +15,6 @@
<ClInclude Include="..\..\prelude\slang-cpp-types.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="slang-ref-object-reflect.h">
- <Filter>Header Files</Filter>
- </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\core\slang-string.cpp">
diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h
index 5cbfd1e45..931f0d5bd 100644
--- a/source/slang/slang-ast-base.h
+++ b/source/slang/slang-ast-base.h
@@ -4,7 +4,7 @@
#include "slang-ast-support-types.h"
-#include "slang-ast-generated.h"
+#include "slang-generated-ast.h"
#include "slang-ast-reflect.h"
#include "slang-serialize-reflection.h"
diff --git a/source/slang/slang-ast-decl.cpp b/source/slang/slang-ast-decl.cpp
index a10411ebb..edc79c030 100644
--- a/source/slang/slang-ast-decl.cpp
+++ b/source/slang/slang-ast-decl.cpp
@@ -2,7 +2,7 @@
#include "slang-ast-builder.h"
#include <assert.h>
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
namespace Slang {
diff --git a/source/slang/slang-ast-dump.cpp b/source/slang/slang-ast-dump.cpp
index 688e99031..552c97d7f 100644
--- a/source/slang/slang-ast-dump.cpp
+++ b/source/slang/slang-ast-dump.cpp
@@ -6,7 +6,7 @@
#include "../core/slang-string.h"
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
namespace Slang {
diff --git a/source/slang/slang-ast-reflect.cpp b/source/slang/slang-ast-reflect.cpp
index 520592e73..b16568d2e 100644
--- a/source/slang/slang-ast-reflect.cpp
+++ b/source/slang/slang-ast-reflect.cpp
@@ -11,7 +11,7 @@
#include "slang-visitor.h"
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
namespace Slang
{
@@ -54,11 +54,11 @@ struct ASTConstructAccess
#define SLANG_GET_SUPER_INNER(SUPER) &SUPER::kReflectClassInfo
#define SLANG_GET_SUPER_LEAF(SUPER) &SUPER::kReflectClassInfo
-#define SLANG_GET_CREATE_FUNC_ABSTRACT(NAME) nullptr
-#define SLANG_GET_CREATE_FUNC_NONE(NAME) &ASTConstructAccess::Impl<NAME>::create
+#define SLANG_GET_CREATE_FUNC_ABSTRACT_AST(NAME) nullptr
+#define SLANG_GET_CREATE_FUNC_AST(NAME) &ASTConstructAccess::Impl<NAME>::create
-#define SLANG_GET_DESTROY_FUNC_ABSTRACT(NAME) nullptr
-#define SLANG_GET_DESTROY_FUNC_NONE(NAME) &ASTConstructAccess::Impl<NAME>::destroy
+#define SLANG_GET_DESTROY_FUNC_ABSTRACT_AST(NAME) nullptr
+#define SLANG_GET_DESTROY_FUNC_AST(NAME) &ASTConstructAccess::Impl<NAME>::destroy
#define SLANG_REFLECT_CLASS_INFO(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
/* static */const ReflectClassInfo NAME::kReflectClassInfo = { uint32_t(ASTNodeType::NAME), uint32_t(ASTNodeType::LAST), SLANG_GET_SUPER_##TYPE(SUPER), #NAME, SLANG_GET_CREATE_FUNC_##MARKER(NAME), SLANG_GET_DESTROY_FUNC_##MARKER(NAME), uint32_t(sizeof(NAME)), uint8_t(SLANG_ALIGN_OF(NAME)) };
@@ -66,8 +66,8 @@ struct ASTConstructAccess
SLANG_ALL_ASTNode_NodeBase(SLANG_REFLECT_CLASS_INFO, _)
// We dispatch to non 'abstract' types
-#define SLANG_CASE_NONE(NAME) case ASTNodeType::NAME: return visitor->dispatch_##NAME(static_cast<NAME*>(this), extra);
-#define SLANG_CASE_ABSTRACT(NAME)
+#define SLANG_CASE_AST(NAME) case ASTNodeType::NAME: return visitor->dispatch_##NAME(static_cast<NAME*>(this), extra);
+#define SLANG_CASE_ABSTRACT_AST(NAME)
#define SLANG_CASE_DISPATCH(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) SLANG_CASE_##MARKER(NAME)
diff --git a/source/slang/slang-ast-reflect.h b/source/slang/slang-ast-reflect.h
index 6ba895f71..457e88d0d 100644
--- a/source/slang/slang-ast-reflect.h
+++ b/source/slang/slang-ast-reflect.h
@@ -5,7 +5,7 @@
#include "slang-serialize-reflection.h"
-#include "slang-ast-generated.h"
+#include "slang-generated-ast.h"
// Implementation for SLANG_ABSTRACT_CLASS(x) using reflection from C++ extractor in slang-ast-generated.h
#define SLANG_AST_CLASS_REFLECT_IMPL(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \
diff --git a/source/slang/slang-ast-substitutions.cpp b/source/slang/slang-ast-substitutions.cpp
index 8a54a1d74..acff8201e 100644
--- a/source/slang/slang-ast-substitutions.cpp
+++ b/source/slang/slang-ast-substitutions.cpp
@@ -2,7 +2,7 @@
#include "slang-ast-builder.h"
#include <assert.h>
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
namespace Slang {
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 4cc76804c..a2fa16b53 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -9,7 +9,7 @@
#include "../core/slang-semantic-version.h"
-#include "slang-ast-generated.h"
+#include "slang-generated-ast.h"
#include "slang-serialize-reflection.h"
@@ -1007,8 +1007,13 @@ namespace Slang
};
class SerialRefObject;
+
// Make sure C++ extractor can see the base class.
- SLANG_PRE_DECLARE(_OBJ_CLASS, class SerialRefObject)
+ SLANG_PRE_DECLARE(OBJ, class SerialRefObject)
+
+ SLANG_TYPE_SET(OBJ, RefObject)
+ SLANG_TYPE_SET(VALUE, Value)
+ SLANG_TYPE_SET(AST, ASTNode)
class LookupResultItem_Breadcrumb : public SerialRefObject
{
diff --git a/source/slang/slang-ast-type.cpp b/source/slang/slang-ast-type.cpp
index 55bb9a1e5..2c2557233 100644
--- a/source/slang/slang-ast-type.cpp
+++ b/source/slang/slang-ast-type.cpp
@@ -5,7 +5,7 @@
#include "slang-syntax.h"
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
namespace Slang {
diff --git a/source/slang/slang-ast-val.cpp b/source/slang/slang-ast-val.cpp
index 76ddb644c..7dbda6e86 100644
--- a/source/slang/slang-ast-val.cpp
+++ b/source/slang/slang-ast-val.cpp
@@ -3,7 +3,7 @@
#include <assert.h>
#include <typeinfo>
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
#include "slang-syntax.h"
diff --git a/source/slang/slang-diagnostics.cpp b/source/slang/slang-diagnostics.cpp
index d16e8e84e..c3b7e27a2 100644
--- a/source/slang/slang-diagnostics.cpp
+++ b/source/slang/slang-diagnostics.cpp
@@ -5,6 +5,8 @@
#include "../core/slang-memory-arena.h"
#include "../core/slang-dictionary.h"
+#include "../core/slang-string-util.h"
+#include "../core/slang-name-convention-util.h"
#include <assert.h>
@@ -302,60 +304,17 @@ public:
return singleton;
}
- typedef uint8_t CharFlags;
- struct CharFlag
- {
- enum Enum : CharFlags
- {
- Upper = 0x1,
- Lower = 0x2,
- };
- };
-
- static CharFlags _classifyChar(char c)
- {
- CharFlags flags = 0;
- flags |= (c >= 'a' && c <= 'z') ? CharFlag::Lower : 0;
- flags |= (c >= 'A' && c <= 'Z') ? CharFlag::Upper : 0;
- return flags;
- }
protected:
void _add(const char* name, Index index)
{
- m_map.Add(UnownedStringSlice(name), index);
+ UnownedStringSlice nameSlice(name);
+ m_map.Add(nameSlice, index);
- // Add a dashed version
+ // Add a dashed version (KababCase)
{
m_work.Clear();
- CharFlags prevFlags = 0;
- for (const char* cur = name; *cur; cur++)
- {
- char c = *cur;
- const CharFlags flags = _classifyChar(c);
-
- if (flags & CharFlag::Upper)
- {
- if (prevFlags & CharFlag::Lower)
- {
- // If we go from lower to upper, insert a dash. aA -> a-a
- m_work << '-';
- }
- else if (prevFlags & CharFlag::Upper)
- {
- // Could be an acronym, if the next character is lower, we need to insert a - here
- if (_classifyChar(cur[1]) & CharFlag::Lower)
- {
- m_work << '-';
- }
- }
- // Make it lower
- c = c - 'A' + 'a';
- }
- m_work << c;
-
- prevFlags = flags;
- }
+ NameConventionUtil::convert(NameConvention::Camel, nameSlice, CharCase::Lower, NameConvention::Kabab, m_work);
UnownedStringSlice dashSlice(m_arena.allocateString(m_work.getBuffer(), m_work.getLength()), m_work.getLength());
m_map.AddIfNotExists(dashSlice, index);
diff --git a/source/slang/slang-ref-object-reflect.cpp b/source/slang/slang-ref-object-reflect.cpp
index caf8eb6a3..f07dcbba7 100644
--- a/source/slang/slang-ref-object-reflect.cpp
+++ b/source/slang/slang-ref-object-reflect.cpp
@@ -2,8 +2,8 @@
#include "slang-ref-object-reflect.h"
-#include "slang-ref-object-generated.h"
-#include "slang-ref-object-generated-macro.h"
+#include "slang-generated-obj.h"
+#include "slang-generated-obj-macro.h"
#include "slang-ast-support-types.h"
diff --git a/source/slang/slang-ref-object-reflect.h b/source/slang/slang-ref-object-reflect.h
index cf50c010a..1fda8ee69 100644
--- a/source/slang/slang-ref-object-reflect.h
+++ b/source/slang/slang-ref-object-reflect.h
@@ -5,7 +5,7 @@
#include "slang-serialize-reflection.h"
-#include "slang-ref-object-generated.h"
+#include "slang-generated-obj.h"
#include "../core/slang-smart-pointer.h"
diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp
index 8310c155b..0e8acc3b3 100644
--- a/source/slang/slang-serialize-ast.cpp
+++ b/source/slang/slang-serialize-ast.cpp
@@ -1,8 +1,8 @@
// slang-serialize-ast.cpp
#include "slang-serialize-ast.h"
-#include "slang-ast-generated.h"
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast.h"
+#include "slang-generated-ast-macro.h"
#include "slang-ast-dump.h"
diff --git a/source/slang/slang-serialize-reflection.h b/source/slang/slang-serialize-reflection.h
index a6889f795..7eaf8543c 100644
--- a/source/slang/slang-serialize-reflection.h
+++ b/source/slang/slang-serialize-reflection.h
@@ -63,6 +63,8 @@ struct ReflectClassInfo
#define SLANG_PRE_DECLARE(SUFFIX, DEF)
+#define SLANG_TYPE_SET(SUFFIX, ...)
+
// Use these macros to help define Super, and making the base definition NOT have a Super definition.
// For example something like...
diff --git a/source/slang/slang-visitor.h b/source/slang/slang-visitor.h
index 449fda917..25e0aafe4 100644
--- a/source/slang/slang-visitor.h
+++ b/source/slang/slang-visitor.h
@@ -7,15 +7,15 @@
#include "slang-syntax.h"
-#include "slang-ast-generated-macro.h"
+#include "slang-generated-ast-macro.h"
namespace Slang {
// Macros to generate from ast-generated-macro file the vistors
// Only runs 'param' macro if the marker is NONE (ie not ABSTRACT here)
-#define SLANG_CLASS_ONLY_ABSTRACT(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param)
-#define SLANG_CLASS_ONLY_NONE(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) param(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param)
+#define SLANG_CLASS_ONLY_ABSTRACT_AST(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param)
+#define SLANG_CLASS_ONLY_AST(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) param(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param)
#define SLANG_CLASS_ONLY(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) SLANG_CLASS_ONLY_##MARKER(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param)
diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj
index ec3066778..bb4293b8f 100644
--- a/source/slang/slang.vcxproj
+++ b/source/slang/slang.vcxproj
@@ -195,8 +195,6 @@
<ClInclude Include="slang-ast-decl.h" />
<ClInclude Include="slang-ast-dump.h" />
<ClInclude Include="slang-ast-expr.h" />
- <ClInclude Include="slang-ast-generated-macro.h" />
- <ClInclude Include="slang-ast-generated.h" />
<ClInclude Include="slang-ast-modifier.h" />
<ClInclude Include="slang-ast-reflect.h" />
<ClInclude Include="slang-ast-stmt.h" />
@@ -217,6 +215,12 @@
<ClInclude Include="slang-emit-source-writer.h" />
<ClInclude Include="slang-emit.h" />
<ClInclude Include="slang-file-system.h" />
+ <ClInclude Include="slang-generated-ast-macro.h" />
+ <ClInclude Include="slang-generated-ast.h" />
+ <ClInclude Include="slang-generated-obj-macro.h" />
+ <ClInclude Include="slang-generated-obj.h" />
+ <ClInclude Include="slang-generated-value-macro.h" />
+ <ClInclude Include="slang-generated-value.h" />
<ClInclude Include="slang-glsl-extension-tracker.h" />
<ClInclude Include="slang-hlsl-intrinsic-set.h" />
<ClInclude Include="slang-image-format-defs.h" />
@@ -281,7 +285,13 @@
<ClInclude Include="slang-preprocessor.h" />
<ClInclude Include="slang-profile-defs.h" />
<ClInclude Include="slang-profile.h" />
+ <ClInclude Include="slang-ref-object-generated-ast-macro.h" />
+ <ClInclude Include="slang-ref-object-generated-ast.h" />
<ClInclude Include="slang-ref-object-generated-macro.h" />
+ <ClInclude Include="slang-ref-object-generated-obj-macro.h" />
+ <ClInclude Include="slang-ref-object-generated-obj.h" />
+ <ClInclude Include="slang-ref-object-generated-value-macro.h" />
+ <ClInclude Include="slang-ref-object-generated-value.h" />
<ClInclude Include="slang-ref-object-generated.h" />
<ClInclude Include="slang-ref-object-reflect.h" />
<ClInclude Include="slang-reflection.h" />
diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters
index d69ff3059..aad88a15f 100644
--- a/source/slang/slang.vcxproj.filters
+++ b/source/slang/slang.vcxproj.filters
@@ -36,12 +36,6 @@
<ClInclude Include="slang-ast-expr.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="slang-ast-generated-macro.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="slang-ast-generated.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="slang-ast-modifier.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -102,6 +96,24 @@
<ClInclude Include="slang-file-system.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-generated-ast-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-generated-ast.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-generated-obj-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-generated-obj.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-generated-value-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-generated-value.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-glsl-extension-tracker.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -294,9 +306,27 @@
<ClInclude Include="slang-profile.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-ref-object-generated-ast-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-ref-object-generated-ast.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-ref-object-generated-macro.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="slang-ref-object-generated-obj-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-ref-object-generated-obj.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-ref-object-generated-value-macro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="slang-ref-object-generated-value.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="slang-ref-object-generated.h">
<Filter>Header Files</Filter>
</ClInclude>
diff --git a/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h b/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h
index 97bc8eea0..3ab133414 100644
--- a/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h
+++ b/tools/slang-cpp-extractor/slang-cpp-extractor-diagnostic-defs.h
@@ -23,7 +23,7 @@ DIAGNOSTIC(-1, Note, seeOpen, "see open $0")
DIAGNOSTIC(1, Error, cannotOpenFile, "cannot open file '$0'.")
-DIAGNOSTIC(1, Error, extractorFailed, "C++ Extractor failed for '$0'")
+DIAGNOSTIC(1, Error, extractorFailed, "C++ Extractor failed")
DIAGNOSTIC(1, Error, internalError, "Unknown internal error in C++ Extractor, aborted!")
// Parsing errors
@@ -40,6 +40,7 @@ DIAGNOSTIC(100009, Error, unexpectedUnbalancedToken, "Unexpected unbalanced toke
DIAGNOSTIC(100010, Error, unexpectedEndOfFile, "Unexpected end of file")
DIAGNOSTIC(100011, Error, expectingTypeKeyword, "Expecting type keyword - struct or class, found $0")
+DIAGNOSTIC(100011, Error, typeInDifferentTypeSet, "Type $0 in different type set $1 from super class $2")
// Command line errors 100100
diff --git a/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp b/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
index fc5c3d1f9..210369e97 100644
--- a/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
+++ b/tools/slang-cpp-extractor/slang-cpp-extractor-main.cpp
@@ -13,6 +13,7 @@
#include "../../source/core/slang-io.h"
#include "../../source/core/slang-string-slice-pool.h"
#include "../../source/core/slang-writer.h"
+#include "../../source/core/slang-name-convention-util.h"
#include "../../source/slang/slang-source-loc.h"
#include "../../source/slang/slang-lexer.h"
@@ -25,15 +26,7 @@
/*
Some command lines:
-For AST
--d source/slang slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang-ast- -o slang-ast-generated -output-fields -mark-suffix _CLASS
-
-For RefObjects
--d source/slang slang-ast-support-types.h -strip-prefix slang- -reflect-type RefObject -o slang-ref-object-generated -output-fields -mark-suffix _OBJ_CLASS
-
-For Values
-
--d source/slang slang-ast-support-types.h -strip-prefix slang- -reflect-type Value -o slang-value-generated -output-fields -mark-suffix _VALUE_CLASS
+-d source/slang slang-ast-support-types.h slang-ast-base.h slang-ast-decl.h slang-ast-expr.h slang-ast-modifier.h slang-ast-stmt.h slang-ast-type.h slang-ast-val.h -strip-prefix slang- -o slang-generated -output-fields -mark-suffix _CLASS
*/
namespace SlangExperimental
@@ -48,6 +41,7 @@ enum class IdentifierStyle
Identifier, ///< Just an identifier
PreDeclare, ///< Declare a type (not visible in C++ code)
+ TypeSet, ///< TypeSet
TypeModifier, ///< const, volatile etc
Keyword, ///< A keyword C/C++ keyword that is not another type
@@ -79,6 +73,7 @@ static const IdentifierFlags kIdentifierFlags[Index(IdentifierStyle::CountOf)] =
0, /// None
0, /// Identifier
0, /// Declare type
+ 0, /// Type set
IdentifierFlag::Keyword, /// TypeModifier
IdentifierFlag::Keyword, /// Keyword
IdentifierFlag::Keyword | IdentifierFlag::StartScope | IdentifierFlag::ClassLike, /// Class
@@ -159,6 +154,8 @@ enum class ReflectionType
Reflected,
};
+// Pre-declare
+class TypeSet;
class SourceOrigin;
class Node : public RefObject
@@ -255,7 +252,8 @@ public:
m_reflectionType(ReflectionType::NotReflected),
m_reflectionOverride(ReflectionType::Reflected),
m_superNode(nullptr),
- m_origin(nullptr)
+ m_origin(nullptr),
+ m_typeSet(nullptr)
{
m_anonymousNamespace = nullptr;
}
@@ -291,8 +289,10 @@ public:
Token m_super; ///< Super class name
Token m_marker; ///< The marker associated with this scope (typically the marker is SLANG_CLASS etc, that is used to identify reflectedType)
+ TypeSet* m_typeSet; ///< The typeset this type belongs to.
+
Node* m_parentScope; ///< The scope this type/scope is defined in
- Node* m_superNode; ///< If this is a class/struct, the type it is derived from (or nullptr if base)
+ Node* m_superNode; ///< If this is a class/struct, the type it is derived from (or nullptr if base)
};
class SourceOrigin : public RefObject
@@ -331,6 +331,19 @@ public:
List<RefPtr<Node> > m_nodes;
};
+class TypeSet : public RefObject
+{
+public:
+
+ /// This is the looked up name.
+ UnownedStringSlice m_macroName; ///< The name extracted from the macro SLANG_ABSTRACT_AST_CLASS -> AST
+
+ String m_typeName; ///< The enum type name associated with this type for AST it is ASTNode
+ String m_fileMark; ///< This 'mark' becomes of the output filename
+
+ List<Node*> m_baseTypes; ///< The base types for this type set
+};
+
struct Options;
class CPPExtractor
@@ -351,20 +364,23 @@ public:
/// Parse the contents of the source file
SlangResult parse(SourceFile* sourceFile, const Options* options);
- /// When parsing we don't lookup all up super types/add derived types. This is because
- /// we allow files to be processed in any order, so we have to do the type lookup as a separate operation
+ /// When parsing we don't lookup all up super types/add derived types. This is because
+ /// we allow files to be processed in any order, so we have to do the type lookup as a separate operation
SlangResult calcDerivedTypes();
/// Find the name starting in specified scope
Node* findNode(Node* scope, const UnownedStringSlice& name);
- /// Only valid after calcDerivedTypes has been executed
- const List<Node*>& getBaseTypes() const { return m_baseTypes; }
-
/// Get all of the parsed source origins
const List<RefPtr<SourceOrigin> >& getSourceOrigins() const { return m_origins; }
- /// Get the root node
+ TypeSet* getTypeSet(const UnownedStringSlice& slice);
+ TypeSet* getOrAddTypeSet(const UnownedStringSlice& slice);
+
+ /// Get all of the type sets
+ const List<RefPtr<TypeSet>>& getTypeSets() const { return m_typeSets; }
+
+ /// Get the root node
Node* getRootNode() const { return m_rootNode; }
CPPExtractor(StringSlicePool* typePool, NamePool* namePool, DiagnosticSink* sink, IdentifierLookup* identifierLookup);
@@ -375,6 +391,7 @@ protected:
bool _isMarker(const UnownedStringSlice& name);
SlangResult _parsePreDeclare();
+ SlangResult _parseTypeSet();
SlangResult _maybeParseNode(Node::Type type);
SlangResult _maybeParseField();
@@ -405,8 +422,6 @@ protected:
RefPtr<Node> m_rootNode; ///< The root scope
- List<Node*> m_baseTypes; ///< All of the types which are base. Only set after calcDerivedTypes
-
SourceOrigin* m_origin;
DiagnosticSink* m_sink;
@@ -417,8 +432,11 @@ protected:
const Options* m_options;
+ StringSlicePool m_typeSetPool; ///< Pool for type set names
+ List<RefPtr<TypeSet> > m_typeSets; ///< The type sets
+
IdentifierLookup* m_identifierLookup;
- StringSlicePool* m_typePool;
+ StringSlicePool* m_typePool; ///< Pool for just types
};
@@ -707,9 +725,9 @@ struct Options
List<String> m_inputPaths; ///< The input paths to the files to be processed
- String m_outputPath; ///< The ouput path. Note that the extractor can generate multiple output files, and this will actually be the 'stem' of several files
+ String m_outputPath; ///< The output path. Note that the extractor can generate multiple output files, and this will actually be the 'stem' of several files
+
String m_inputDirectory; ///< The input directory that is by default used for reading m_inputPaths from.
- String m_reflectType; ///< The typename used for output
String m_markPrefix; ///< The prefix of the 'marker' used to identify a reflected type
String m_markSuffix; ///< The postfix of the 'marker' used to identify a reflected type
String m_stripFilePrefix; ///< Used for the 'origin' information, this is stripped from the source filename, and the remainder of the filename (without extension) is 'macroized'
@@ -813,11 +831,6 @@ SlangResult OptionsParser::parse(int argc, const char*const* argv, DiagnosticSin
m_index++;
continue;
}
- else if (arg == "-reflect-type")
- {
- SLANG_RETURN_ON_FAIL(_parseArgWithValue("-reflect-type", outOptions.m_reflectType));
- continue;
- }
else if (arg == "-mark-prefix")
{
SLANG_RETURN_ON_FAIL(_parseArgReplaceValue("-mark-prefix", outOptions.m_markPrefix));
@@ -861,12 +874,6 @@ SlangResult OptionsParser::parse(int argc, const char*const* argv, DiagnosticSin
return SLANG_FAIL;
}
- // Set default name
- if (outOptions.m_reflectType.getLength() == 0)
- {
- outOptions.m_reflectType = "ASTNode";
- }
-
return SLANG_OK;
}
@@ -876,12 +883,41 @@ CPPExtractor::CPPExtractor(StringSlicePool* typePool, NamePool* namePool, Diagno
m_typePool(typePool),
m_sink(sink),
m_namePool(namePool),
- m_identifierLookup(identifierLookup)
+ m_identifierLookup(identifierLookup),
+ m_typeSetPool(StringSlicePool::Style::Empty)
{
m_rootNode = new Node(Node::Type::Namespace);
m_rootNode->m_reflectionType = ReflectionType::Reflected;
}
+TypeSet* CPPExtractor::getTypeSet(const UnownedStringSlice& slice)
+{
+ Index index = m_typeSetPool.findIndex(slice);
+ if (index < 0)
+ {
+ return nullptr;
+ }
+ return m_typeSets[index];
+}
+
+TypeSet* CPPExtractor::getOrAddTypeSet(const UnownedStringSlice& slice)
+{
+ const Index index = Index(m_typeSetPool.add(slice));
+ if (index >= m_typeSets.getCount())
+ {
+ SLANG_ASSERT(m_typeSets.getCount() == index);
+ TypeSet* typeSet = new TypeSet;
+
+ m_typeSets.add(typeSet);
+ typeSet->m_macroName = m_typeSetPool.getSlice(StringSlicePool::Handle(index));
+ return typeSet;
+ }
+ else
+ {
+ return m_typeSets[index];
+ }
+}
+
bool CPPExtractor::_isMarker(const UnownedStringSlice& name)
{
return name.startsWith(m_options->m_markPrefix.getUnownedSlice()) && name.endsWith(m_options->m_markSuffix.getUnownedSlice());
@@ -1099,7 +1135,7 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier));
// Next is the class name
SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &name));
-
+
if (m_reader.peekTokenType() == TokenType::Semicolon)
{
// pre declaration;
@@ -1189,6 +1225,29 @@ SlangResult CPPExtractor::_maybeParseNode(Node::Type type)
return SLANG_OK;
}
+ // Let's extract the type set
+ {
+ UnownedStringSlice slice(node->m_marker.getContent());
+
+ SLANG_ASSERT(_isMarker(slice));
+
+ // Strip the prefix and suffix
+ slice = UnownedStringSlice(slice.begin() + m_options->m_markPrefix.getLength(), slice.end() - m_options->m_markSuffix.getLength());
+
+ // Strip ABSTRACT_ if it's there
+ UnownedStringSlice abstractSlice("ABSTRACT_");
+ if (slice.startsWith(abstractSlice))
+ {
+ slice = UnownedStringSlice(slice.begin() + abstractSlice.getLength(), slice.end());
+ }
+
+ // TODO: We could strip other stuff or have other heuristics there, but this is
+ // probably okay for now
+
+ // Set the typeSet
+ node->m_typeSet = getOrAddTypeSet(slice);
+ }
+
// Okay now looking for ( identifier)
Token typeNameToken;
@@ -1636,15 +1695,10 @@ SlangResult CPPExtractor::_parsePreDeclare()
SLANG_RETURN_ON_FAIL(expect(TokenType::LParent));
- bool hasMatchingSuffix = false;
-
- // Get the suffix
- {
- Token suffix;
- SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &suffix));
-
- hasMatchingSuffix = _trimUnderscorePrefix(m_options->m_markSuffix.getUnownedSlice()) == _trimUnderscorePrefix(suffix.getContent());
- }
+ // Get the typeSet
+ Token typeSetToken;
+ SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &typeSetToken));
+ TypeSet* typeSet = getOrAddTypeSet(typeSetToken.getContent());
SLANG_RETURN_ON_FAIL(expect(TokenType::Comma));
@@ -1676,24 +1730,48 @@ SlangResult CPPExtractor::_parsePreDeclare()
SLANG_RETURN_ON_FAIL(expect(TokenType::RParent));
- if (hasMatchingSuffix)
- {
- RefPtr<Node> node(new Node(nodeType));
+ RefPtr<Node> node(new Node(nodeType));
- node->m_name = name;
- node->m_super = super;
+ node->m_name = name;
+ node->m_super = super;
+ node->m_typeSet = typeSet;
- // Assume it is reflected
- node->m_reflectionType = ReflectionType::Reflected;
+ // Assume it is reflected
+ node->m_reflectionType = ReflectionType::Reflected;
- SLANG_RETURN_ON_FAIL(pushNode(node));
- // Pop out of it
- popBrace();
- }
+ SLANG_RETURN_ON_FAIL(pushNode(node));
+ // Pop out of the node
+ popBrace();
return SLANG_OK;
}
+SlangResult CPPExtractor::_parseTypeSet()
+{
+ // Skip the declare type token
+ m_reader.advanceToken();
+
+ SLANG_RETURN_ON_FAIL(expect(TokenType::LParent));
+
+ Token typeSetToken;
+ SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &typeSetToken));
+
+ TypeSet* typeSet = getOrAddTypeSet(typeSetToken.getContent());
+
+ SLANG_RETURN_ON_FAIL(expect(TokenType::Comma));
+
+ // Get the type of type
+ Token typeToken;
+ SLANG_RETURN_ON_FAIL(expect(TokenType::Identifier, &typeToken));
+
+ SLANG_RETURN_ON_FAIL(expect(TokenType::RParent));
+
+ // Set the typename
+ typeSet->m_typeName = typeToken.getContent();
+
+ return SLANG_OK;
+}
+
SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
{
SLANG_ASSERT(options);
@@ -1741,6 +1819,11 @@ SlangResult CPPExtractor::parse(SourceFile* sourceFile, const Options* options)
SLANG_RETURN_ON_FAIL(_parsePreDeclare());
break;
}
+ case IdentifierStyle::TypeSet:
+ {
+ SLANG_RETURN_ON_FAIL(_parseTypeSet());
+ break;
+ }
case IdentifierStyle::Reflected:
{
m_reader.advanceToken();
@@ -1889,8 +1972,13 @@ SlangResult CPPExtractor::_calcDerivedTypesRec(Node* node)
return SLANG_FAIL;
}
- // The base class must be defined in same scope (as we didn't allow different scopes for base classes)
+ if (superType->m_typeSet != node->m_typeSet)
+ {
+ m_sink->diagnose(node->m_name, CPPDiagnostics::typeInDifferentTypeSet, node->m_name.getContent(), node->m_typeSet->m_macroName, superType->m_typeSet->m_macroName);
+ return SLANG_FAIL;
+ }
+ // The base class must be defined in same scope (as we didn't allow different scopes for base classes)
superType->addDerived(node);
}
}
@@ -1899,7 +1987,7 @@ SlangResult CPPExtractor::_calcDerivedTypesRec(Node* node)
// Add the root nodes
if (node->isReflected())
{
- m_baseTypes.add(node);
+ node->m_typeSet->m_baseTypes.add(node);
}
}
}
@@ -1917,42 +2005,26 @@ SlangResult CPPExtractor::calcDerivedTypes()
return _calcDerivedTypesRec(m_rootNode);
}
-
/* static */String CPPExtractor::_calcMacroOrigin(const String& filePath, const Options& options)
{
+ // Get the filename without extension
String fileName = Path::getFileNameWithoutExt(filePath);
- if (options.m_stripFilePrefix.getLength() && fileName.startsWith(options.m_stripFilePrefix))
+ // We can work on just the slice
+ UnownedStringSlice slice = fileName.getUnownedSlice();
+
+ // Filename prefix
+ if (options.m_stripFilePrefix.getLength() && slice.startsWith(options.m_stripFilePrefix.getUnownedSlice()))
{
const Index len = options.m_stripFilePrefix.getLength();
- fileName = UnownedStringSlice(fileName.begin() + len, fileName.end());
+ slice = UnownedStringSlice(slice.begin() + len, slice.end());
}
- const char* start = fileName.begin();
- const char* end = fileName.end();
-
- // Trim any -
- while (start < end && *start == '-') ++start;
- while (end - 1 > start && end[-1] == '-') --end;
+ // Trim -
+ slice = slice.trim('-');
StringBuilder out;
-
- // Make into macro like name
- for (; start < end; ++start)
- {
- char c = *start;
-
- if (c == '-')
- {
- c = '_';
- }
- else if (c >= 'a' && c <= 'z')
- {
- c = c - 'a' + 'A';
- }
- out.append(c);
- }
-
+ NameConventionUtil::convert(slice, CharCase::Upper, NameConvention::Snake, out);
return out;
}
@@ -1977,8 +2049,9 @@ public:
SlangResult writeDefs(CPPExtractor& extractor);
/// Calculate the header
- SlangResult calcHeader(CPPExtractor& extractor, StringBuilder& out);
- SlangResult calcChildrenHeader(CPPExtractor& exctractor, StringBuilder& out);
+ SlangResult calcTypeHeader(CPPExtractor& extractor, TypeSet* typeSet, StringBuilder& out);
+ SlangResult calcChildrenHeader(CPPExtractor& exctractor, TypeSet* typeSet, StringBuilder& out);
+ SlangResult calcOriginHeader(CPPExtractor& extractor, StringBuilder& out);
SlangResult calcDef(CPPExtractor& extractor, SourceOrigin* origin, StringBuilder& out);
@@ -2072,287 +2145,300 @@ SlangResult CPPExtractorApp::calcDef(CPPExtractor& extractor, SourceOrigin* orig
return SLANG_OK;
}
-SlangResult CPPExtractorApp::calcChildrenHeader(CPPExtractor& extractor, StringBuilder& out)
+SlangResult CPPExtractorApp::calcChildrenHeader(CPPExtractor& extractor, TypeSet* typeSet, StringBuilder& out)
{
- const List<Node*>& baseTypes = extractor.getBaseTypes();
-
- const String& reflectTypeName = m_options.m_reflectType;
+ const List<Node*>& baseTypes = typeSet->m_baseTypes;
+ const String& reflectTypeName = typeSet->m_typeName;
out << "#pragma once\n\n";
out << "// Do not edit this file is generated from slang-cpp-extractor tool\n\n";
+ List<Node*> nodes;
for (Index i = 0; i < baseTypes.getCount(); ++i)
{
- Node* baseType = baseTypes[i];
-
- List<Node*> nodes;
+ Node* baseType = baseTypes[i];
baseType->calcDerivedDepthFirst(nodes);
- Node::filter(Node::isClassLike, nodes);
+ }
- List<Node*> derivedTypes;
+ Node::filter(Node::isClassLike, nodes);
- out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHILDREN !!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \n\n";
+ List<Node*> derivedTypes;
- // Now the children
- for (Node* node : nodes)
- {
- node->getReflectedDerivedTypes(derivedTypes);
+ out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHILDREN !!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \n\n";
- // Define the derived types
- out << "#define " << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
+ // Now the children
+ for (Node* node : nodes)
+ {
+ node->getReflectedDerivedTypes(derivedTypes);
+
+ // Define the derived types
+ out << "#define " << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
- if (derivedTypes.getCount())
+ if (derivedTypes.getCount())
+ {
+ out << " \\\n";
+ for (Index j = 0; j < derivedTypes.getCount(); ++j)
{
- out << " \\\n";
- for (Index j = 0; j < derivedTypes.getCount(); ++j)
+ Node* derivedType = derivedTypes[j];
+ _indent(1, out);
+ out << m_options.m_markPrefix << "ALL_" << reflectTypeName << "_" << derivedType->m_name.getContent() << "(x, param)";
+ if (j < derivedTypes.getCount() - 1)
{
- Node* derivedType = derivedTypes[j];
- _indent(1, out);
- out << m_options.m_markPrefix << "ALL_" << reflectTypeName << "_" << derivedType->m_name.getContent() << "(x, param)";
- if (j < derivedTypes.getCount() - 1)
- {
- out << "\\\n";
- }
- }
- }
- out << "\n\n";
+ out << "\\\n";
+ }
+ }
}
+ out << "\n\n";
+ }
- out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ALL !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n";
+ out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ALL !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n";
- for (Node* node : nodes)
+ for (Node* node : nodes)
+ {
+ // Define the derived types
+ out << "#define " << m_options.m_markPrefix << "ALL_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param) \\\n";
+ _indent(1, out);
+ out << m_options.m_markPrefix << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
+
+ // If has derived types output them
+ if (node->hasReflectedDerivedType())
{
- // Define the derived types
- out << "#define " << m_options.m_markPrefix << "ALL_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param) \\\n";
+ out << " \\\n";
_indent(1, out);
- out << m_options.m_markPrefix << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
-
- // If has derived types output them
- if (node->hasReflectedDerivedType())
- {
- out << " \\\n";
- _indent(1, out);
- out << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
- }
- out << "\n\n";
+ out << m_options.m_markPrefix << "CHILDREN_" << reflectTypeName << "_" << node->m_name.getContent() << "(x, param)";
}
+ out << "\n\n";
+ }
+
+ if (m_options.m_outputFields)
+ {
+ out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! FIELDS !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n";
- if (m_options.m_outputFields)
+ for (Node* node : nodes)
{
- out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! FIELDS !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n";
+ // Define the derived types
+ out << "#define " << m_options.m_markPrefix << "FIELDS_" << reflectTypeName << "_" << node->m_name.getContent() << "(_x_, _param_)";
- for (Node* node : nodes)
+ if (node->m_fields.getCount() > 0)
{
- // Define the derived types
- out << "#define " << m_options.m_markPrefix << "FIELDS_" << reflectTypeName << "_" << node->m_name.getContent() << "(_x_, _param_)";
+ out << "\\\n";
- if (node->m_fields.getCount() > 0)
+ const Index fieldsCount = node->m_fields.getCount();
+ bool previousField = false;
+ for (Index j = 0; j < fieldsCount; ++j)
{
- out << "\\\n";
-
- const Index fieldsCount = node->m_fields.getCount();
- bool previousField = false;
- for (Index j = 0; j < fieldsCount; ++j)
- {
- const auto& field = node->m_fields[j];
+ const auto& field = node->m_fields[j];
- if (field.isReflected())
+ if (field.isReflected())
+ {
+ if (previousField)
{
- if (previousField)
- {
- out << "\\\n";
- }
+ out << "\\\n";
+ }
- _indent(1, out);
+ _indent(1, out);
- // NOTE! We put the type field in brackets, such that there is no issue with templates containing a comma.
- // If stringified
- out << "_x_(" << field.name.getContent() << ", (" << field.type << "), _param_)";
- previousField = true;
- }
+ // NOTE! We put the type field in brackets, such that there is no issue with templates containing a comma.
+ // If stringified
+ out << "_x_(" << field.name.getContent() << ", (" << field.type << "), _param_)";
+ previousField = true;
}
}
-
- out << "\n\n";
}
+
+ out << "\n\n";
}
}
return SLANG_OK;
}
-SlangResult CPPExtractorApp::calcHeader(CPPExtractor& extractor, StringBuilder& out)
+SlangResult CPPExtractorApp::calcOriginHeader(CPPExtractor& extractor, StringBuilder& out)
{
- const List<Node*>& baseTypes = extractor.getBaseTypes();
+ // Do macros by origin
- const String& reflectTypeName = m_options.m_reflectType;
+ out << "// Origin macros\n\n";
+
+ for (SourceOrigin* origin : extractor.getSourceOrigins())
+ {
+ out << "#define " << m_options.m_markPrefix << "ORIGIN_" << origin->m_macroOrigin << "(x, param) \\\n";
+
+ for (Node* node : origin->m_nodes)
+ {
+ if (!(node->isReflected() && node->isClassLike()))
+ {
+ continue;
+ }
+
+ _indent(1, out);
+ out << "x(" << node->m_name.getContent() << ", param) \\\n";
+ }
+ out << "/* */\n\n";
+ }
+
+ return SLANG_OK;
+}
+
+SlangResult CPPExtractorApp::calcTypeHeader(CPPExtractor& extractor, TypeSet* typeSet, StringBuilder& out)
+{
+ const List<Node*>& baseTypes = typeSet->m_baseTypes;
+ const String& reflectTypeName = typeSet->m_typeName;
out << "#pragma once\n\n";
out << "// Do not edit this file is generated from slang-cpp-extractor tool\n\n";
- for (Index i = 0; i < baseTypes.getCount(); ++i)
+ if (baseTypes.getCount() == 0)
{
- Node* baseType = baseTypes[i];
-
- List<Node*> baseScopePath;
- baseType->calcScopePath(baseScopePath);
+ return SLANG_OK;
+ }
- // Remove the global scope
- baseScopePath.removeAt(0);
- // Remove the type itself
- baseScopePath.removeLast();
+ // Set up the scope
+ List<Node*> baseScopePath;
+ baseTypes[0]->calcScopePath(baseScopePath);
- for (Node* scopeNode : baseScopePath)
- {
- SLANG_ASSERT(scopeNode->m_type == Node::Type::Namespace);
- out << "namespace " << scopeNode->m_name.getContent() << " {\n";
- }
+ // Remove the global scope
+ baseScopePath.removeAt(0);
+ // Remove the type itself
+ baseScopePath.removeLast();
- List<Node*> nodes;
+ for (Node* scopeNode : baseScopePath)
+ {
+ SLANG_ASSERT(scopeNode->m_type == Node::Type::Namespace);
+ out << "namespace " << scopeNode->m_name.getContent() << " {\n";
+ }
+
+ // Add all the base types, with in order traversals
+ List<Node*> nodes;
+ for (Index i = 0; i < baseTypes.getCount(); ++i)
+ {
+ Node* baseType = baseTypes[i];
baseType->calcDerivedDepthFirst(nodes);
- Node::filter(Node::isClassLikeAndReflected, nodes);
+ }
+
+ Node::filter(Node::isClassLikeAndReflected, nodes);
+
+ // Write out the types
+ {
+ out << "\n";
+ out << "enum class " << reflectTypeName << "Type\n";
+ out << "{\n";
- // Write out the types
+ Index typeIndex = 0;
+ for (Node* node : nodes)
{
- out << "\n";
- out << "enum class " << reflectTypeName << "Type\n";
- out << "{\n";
+ // Okay first we are going to output the enum values
+ const Index depth = node->calcDerivedDepth() - 1;
+ _indent(depth, out);
+ out << node->m_name.getContent() << " = " << typeIndex << ",\n";
+ typeIndex++;
+ }
- Index typeIndex = 0;
- for (Node* node : nodes)
- {
- // Okay first we are going to output the enum values
- const Index depth = node->calcDerivedDepth() - 1;
- _indent(depth, out);
- out << node->m_name.getContent() << " = " << typeIndex << ",\n";
- typeIndex++;
- }
+ _indent(1, out);
+ out << "CountOf\n";
- _indent(1, out);
- out << "CountOf\n";
+ out << "};\n\n";
+ }
- out << "};\n\n";
- }
+ // TODO(JS):
+ // Strictly speaking if we wanted the types to be in different scopes, we would have to
+ // change the namespaces here
- // Predeclare the classes
+ // Predeclare the classes
+ {
+ out << "// Predeclare\n\n";
+ for (Node* node : nodes)
{
- out << "// Predeclare\n\n";
- for (Node* node : nodes)
+ SLANG_ASSERT(node->isClassLike());
+ // If it's not reflected we don't output, in the enum list
+ if (node->isReflected())
{
- SLANG_ASSERT(node->isClassLike());
- // If it's not reflected we don't output, in the enum list
- if (node->isReflected())
- {
- const char* type = (node->m_type == Node::Type::ClassType) ? "class" : "struct";
- out << type << " " << node->m_name.getContent() << ";\n";
- }
+ const char* type = (node->m_type == Node::Type::ClassType) ? "class" : "struct";
+ out << type << " " << node->m_name.getContent() << ";\n";
}
}
+ }
- // Do the macros for each of the types
-
- {
- out << "// Type macros\n\n";
+ // Do the macros for each of the types
- out << "// Order is (NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \n";
- out << "// NAME - is the class name\n";
- out << "// SUPER - is the super class name (or NO_SUPER)\n";
- out << "// ORIGIN - where the definition was found\n";
- out << "// LAST - is the class name for the last in the range (or NO_LAST)\n";
- out << "// MARKER - is the text inbetween in the prefix/postix (like ABSTRACT). If no inbetween text is is 'NONE'\n";
- out << "// TYPE - Can be BASE, INNER or LEAF for the overall base class, an INNER class, or a LEAF class\n";
- out << "// param is a user defined parameter that can be parsed to the invoked x macro\n\n";
+ {
+ out << "// Type macros\n\n";
- // Output all of the definitions for each type
- for (Node* node : nodes)
- {
- out << "#define " << m_options.m_markPrefix << reflectTypeName << "_" << node->m_name.getContent() << "(x, param) ";
+ out << "// Order is (NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \n";
+ out << "// NAME - is the class name\n";
+ out << "// SUPER - is the super class name (or NO_SUPER)\n";
+ out << "// ORIGIN - where the definition was found\n";
+ out << "// LAST - is the class name for the last in the range (or NO_LAST)\n";
+ out << "// MARKER - is the text inbetween in the prefix/postix (like ABSTRACT). If no inbetween text is is 'NONE'\n";
+ out << "// TYPE - Can be BASE, INNER or LEAF for the overall base class, an INNER class, or a LEAF class\n";
+ out << "// param is a user defined parameter that can be parsed to the invoked x macro\n\n";
- // Output the X macro part
- _indent(1, out);
- out << "x(" << node->m_name.getContent() << ", ";
+ // Output all of the definitions for each type
+ for (Node* node : nodes)
+ {
+ out << "#define " << m_options.m_markPrefix << reflectTypeName << "_" << node->m_name.getContent() << "(x, param) ";
- if (node->m_superNode)
- {
- out << node->m_superNode->m_name.getContent() << ", ";
- }
- else
- {
- out << "NO_SUPER, ";
- }
+ // Output the X macro part
+ _indent(1, out);
+ out << "x(" << node->m_name.getContent() << ", ";
- // Output the (file origin)
- out << node->m_origin->m_macroOrigin;
- out << ", ";
+ if (node->m_superNode)
+ {
+ out << node->m_superNode->m_name.getContent() << ", ";
+ }
+ else
+ {
+ out << "NO_SUPER, ";
+ }
- // The last type
- Node* lastDerived = node->findLastDerived();
- if (lastDerived)
- {
- out << lastDerived->m_name.getContent() << ", ";
- }
- else
- {
- out << "NO_LAST, ";
- }
+ // Output the (file origin)
+ out << node->m_origin->m_macroOrigin;
+ out << ", ";
- // Output any specifics of the markup
- UnownedStringSlice marker = node->m_marker.getContent();
- // Need to extract the name
- if (marker.getLength() > m_options.m_markPrefix.getLength() + m_options.m_markSuffix.getLength())
- {
- marker = UnownedStringSlice(marker.begin() + m_options.m_markPrefix.getLength(), marker.end() - m_options.m_markSuffix.getLength());
- }
- else
- {
- marker = UnownedStringSlice::fromLiteral("NONE");
- }
- out << marker << ", ";
+ // The last type
+ Node* lastDerived = node->findLastDerived();
+ if (lastDerived)
+ {
+ out << lastDerived->m_name.getContent() << ", ";
+ }
+ else
+ {
+ out << "NO_LAST, ";
+ }
- if (node->m_superNode == nullptr)
- {
- out << "BASE, ";
- }
- else if (node->hasReflectedDerivedType())
- {
- out << "INNER, ";
- }
- else
- {
- out << "LEAF, ";
- }
- out << "param)\n";
+ // Output any specifics of the markup
+ UnownedStringSlice marker = node->m_marker.getContent();
+ // Need to extract the name
+ if (marker.getLength() > m_options.m_markPrefix.getLength() + m_options.m_markSuffix.getLength())
+ {
+ marker = UnownedStringSlice(marker.begin() + m_options.m_markPrefix.getLength(), marker.end() - m_options.m_markSuffix.getLength());
}
- }
+ else
+ {
+ marker = UnownedStringSlice::fromLiteral("NONE");
+ }
+ out << marker << ", ";
-
- // Now pop the scope in revers
- for (Index j = baseScopePath.getCount() - 1; j >= 0; j--)
- {
- Node* scopeNode = baseScopePath[j];
- out << "} // namespace " << scopeNode->m_name.getContent() << "\n";
+ if (node->m_superNode == nullptr)
+ {
+ out << "BASE, ";
+ }
+ else if (node->hasReflectedDerivedType())
+ {
+ out << "INNER, ";
+ }
+ else
+ {
+ out << "LEAF, ";
+ }
+ out << "param)\n";
}
}
- // Do macros by origin
-
- out << "// Origin macros\n\n";
-
- for (SourceOrigin* origin : extractor.getSourceOrigins())
+ // Now pop the scope in revers
+ for (Index j = baseScopePath.getCount() - 1; j >= 0; j--)
{
- out << "#define " << m_options.m_markPrefix << "ORIGIN_" << origin->m_macroOrigin << "_" << reflectTypeName << "(x, param) \\\n";
-
- for (Node* node : origin->m_nodes)
- {
- if (!(node->isReflected() && node->isClassLike()))
- {
- continue;
- }
-
- _indent(1, out);
- out << "x(" << node->m_name.getContent() << ", param) \\\n";
- }
- out << "/* */\n\n";
+ Node* scopeNode = baseScopePath[j];
+ out << "} // namespace " << scopeNode->m_name.getContent() << "\n";
}
return SLANG_OK;
@@ -2409,30 +2495,30 @@ SlangResult CPPExtractorApp::writeOutput(CPPExtractor& extractor)
// Strip the extension if set
path = Path::getPathWithoutExt(path);
+ for (TypeSet* typeSet : extractor.getTypeSets())
{
- /// Calculate the header
- StringBuilder header;
- SLANG_RETURN_ON_FAIL(calcHeader(extractor, header));
+ {
+ /// Calculate the header
+ StringBuilder header;
+ SLANG_RETURN_ON_FAIL(calcTypeHeader(extractor, typeSet, header));
- // Write it out
+ // Write it out
- StringBuilder headerPath;
- headerPath << path << "." << ext;
- SLANG_RETURN_ON_FAIL(writeAllText(headerPath, header.getUnownedSlice()));
- }
+ StringBuilder headerPath;
+ headerPath << path << "-" << typeSet->m_fileMark << "." << ext;
+ SLANG_RETURN_ON_FAIL(writeAllText(headerPath, header.getUnownedSlice()));
+ }
- {
- StringBuilder childrenHeader;
- SLANG_RETURN_ON_FAIL(calcChildrenHeader(extractor, childrenHeader));
+ {
+ StringBuilder childrenHeader;
+ SLANG_RETURN_ON_FAIL(calcChildrenHeader(extractor, typeSet, childrenHeader));
- StringBuilder headerPath;
- headerPath << path << "-macro." + ext;
- SLANG_RETURN_ON_FAIL(writeAllText(headerPath, childrenHeader.getUnownedSlice()));
+ StringBuilder headerPath;
+ headerPath << path << "-" << typeSet->m_fileMark << "-macro." + ext;
+ SLANG_RETURN_ON_FAIL(writeAllText(headerPath, childrenHeader.getUnownedSlice()));
+ }
}
- // Write to output
- // m_sink->writer->write(header.getBuffer(), header.getLength());
-
return SLANG_OK;
}
@@ -2454,32 +2540,19 @@ SlangResult CPPExtractorApp::writeOutput(CPPExtractor& extractor)
// Special markers
{
- {
- const char* names[] = { "const", "volatile" };
- StringBuilder buf;
- buf << options.m_markPrefix;
- buf << "PRE_DECLARE";
-
- outLookup.set(buf.getUnownedSlice(), IdentifierStyle::PreDeclare);
- }
-
- {
- StringBuilder buf;
- buf << options.m_markPrefix;
- buf << "REFLECTED";
+ const char* names[] = {"PRE_DECLARE", "TYPE_SET", "REFLECTED", "UNREFLECTED"};
+ const IdentifierStyle styles[] = { IdentifierStyle::PreDeclare, IdentifierStyle::TypeSet, IdentifierStyle::Reflected, IdentifierStyle::Unreflected };
+ SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(names) == SLANG_COUNT_OF(styles));
- outLookup.set(buf.getUnownedSlice(), IdentifierStyle::Reflected);
- }
+ StringBuilder buf;
+ for (Index i = 0; i < SLANG_COUNT_OF(names); ++i)
{
- StringBuilder buf;
- buf << options.m_markPrefix;
- buf << "UNREFLECTED";
-
- outLookup.set(buf.getUnownedSlice(), IdentifierStyle::Unreflected);
+ buf.Clear();
+ buf << options.m_markPrefix << names[i];
+ outLookup.set(buf.getUnownedSlice(), styles[i]);
}
}
-
// Keywords which introduce types/scopes
{
outLookup.set("struct", IdentifierStyle::Struct);
@@ -2530,6 +2603,32 @@ SlangResult CPPExtractorApp::execute(const Options& options)
SLANG_RETURN_ON_FAIL(extractor.calcDerivedTypes());
+ // Okay let's check out the typeSets
+ {
+ for (TypeSet* typeSet : extractor.getTypeSets())
+ {
+ // The macro name is in upper snake, so split it
+ List<UnownedStringSlice> slices;
+ NameConventionUtil::split(typeSet->m_macroName, slices);
+
+ if (typeSet->m_fileMark.getLength() == 0)
+ {
+ StringBuilder buf;
+ // Let's guess a 'fileMark' (it becomes part of the filename) based on the macro name. Use lower kabab.
+ NameConventionUtil::join(slices.getBuffer(), slices.getCount(), CharCase::Lower, NameConvention::Kabab, buf);
+ typeSet->m_fileMark = buf.ProduceString();
+ }
+
+ if (typeSet->m_typeName.getLength() == 0)
+ {
+ // Let's guess a typename if not set -> go with upper camel
+ StringBuilder buf;
+ NameConventionUtil::join(slices.getBuffer(), slices.getCount(), CharCase::Upper, NameConvention::Camel, buf);
+ typeSet->m_typeName = buf.ProduceString();
+ }
+ }
+ }
+
// Dump out the tree
if (options.m_dump)
{
@@ -2539,8 +2638,9 @@ SlangResult CPPExtractorApp::execute(const Options& options)
m_sink->writer->write(buf.getBuffer(), buf.getLength());
}
+ for (TypeSet* typeSet : extractor.getTypeSets())
{
- const List<Node*>& baseTypes = extractor.getBaseTypes();
+ const List<Node*>& baseTypes = typeSet->m_baseTypes;
for (Node* baseType : baseTypes)
{
@@ -2598,19 +2698,18 @@ int main(int argc, const char*const* argv)
{
if (SLANG_FAILED(app.executeWithArgs(argc - 1, argv + 1)))
{
- sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed, app.getOptions().m_reflectType);
+ sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed);
return 1;
}
if (sink.getErrorCount())
{
- sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed, app.getOptions().m_reflectType);
+ sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed);
return 1;
}
}
catch (...)
{
sink.diagnose(SourceLoc(), CPPDiagnostics::internalError);
- sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed, app.getOptions().m_reflectType);
return 1;
}
}