diff options
Diffstat (limited to 'tools/slang-cpp-extractor/macro-writer.cpp')
| -rw-r--r-- | tools/slang-cpp-extractor/macro-writer.cpp | 452 |
1 files changed, 0 insertions, 452 deletions
diff --git a/tools/slang-cpp-extractor/macro-writer.cpp b/tools/slang-cpp-extractor/macro-writer.cpp deleted file mode 100644 index 324a48efd..000000000 --- a/tools/slang-cpp-extractor/macro-writer.cpp +++ /dev/null @@ -1,452 +0,0 @@ -#include "macro-writer.h" - -#include "compiler-core/slang-diagnostic-sink.h" -#include "core/slang-io.h" -#include "core/slang-list.h" -#include "core/slang-string.h" -#include "core/slang-writer.h" -#include "slang-com-helper.h" -#include "slang-cpp-parser/diagnostics.h" -#include "slang-cpp-parser/file-util.h" -#include "slang-cpp-parser/node-tree.h" -#include "slang-cpp-parser/options.h" - -namespace CppExtract -{ -using namespace Slang; -using namespace CppParse; - -SLANG_FORCE_INLINE static void _indent(Index indentCount, StringBuilder& out) -{ - return FileUtil::indent(indentCount, out); -} - -SlangResult MacroWriter::calcDef(NodeTree* tree, SourceOrigin* origin, StringBuilder& out) -{ - for (Node* node : origin->m_nodes) - { - if (node->isReflected()) - { - if (auto classLikeNode = as<ClassLikeNode>(node)) - { - if (classLikeNode->m_marker.getContent().indexOf( - UnownedStringSlice::fromLiteral("ABSTRACT")) >= 0) - { - out << "ABSTRACT_"; - } - - out << "SYNTAX_CLASS(" << node->m_name.getContent() << ", " - << classLikeNode->m_super.getContent() << ")\n"; - out << "END_SYNTAX_CLASS()\n\n"; - } - } - } - return SLANG_OK; -} - -SlangResult MacroWriter::calcChildrenHeader(NodeTree* tree, TypeSet* typeSet, StringBuilder& out) -{ - const List<ClassLikeNode*>& 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<ClassLikeNode*> classNodes; - for (Index i = 0; i < baseTypes.getCount(); ++i) - { - ClassLikeNode* baseType = baseTypes[i]; - baseType->calcDerivedDepthFirst(classNodes); - } - - // Node::filter(Node::isClassLike, nodes); - - List<ClassLikeNode*> derivedTypes; - - out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHILDREN !!!!!!!!!!!!!!!!!!!!!!!!!!!! */ \n\n"; - - // Now the children - for (ClassLikeNode* classNode : classNodes) - { - classNode->getReflectedDerivedTypes(derivedTypes); - - // Define the derived types - out << "#define " << m_options->m_markPrefix << "CHILDREN_" << reflectTypeName << "_" - << classNode->m_name.getContent() << "(x, param)"; - - if (derivedTypes.getCount()) - { - 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) - { - out << "\\\n"; - } - } - } - out << "\n\n"; - } - - out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ALL !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n"; - - for (ClassLikeNode* classNode : classNodes) - { - // Define the derived types - out << "#define " << m_options->m_markPrefix << "ALL_" << reflectTypeName << "_" - << classNode->m_name.getContent() << "(x, param) \\\n"; - _indent(1, out); - out << m_options->m_markPrefix << reflectTypeName << "_" << classNode->m_name.getContent() - << "(x, param)"; - - // If has derived types output them - if (classNode->hasReflectedDerivedType()) - { - out << " \\\n"; - _indent(1, out); - out << m_options->m_markPrefix << "CHILDREN_" << reflectTypeName << "_" - << classNode->m_name.getContent() << "(x, param)"; - } - out << "\n\n"; - } - - if (m_options->m_outputFields) - { - out << "\n\n /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! FIELDS !!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n"; - - for (ClassLikeNode* classNode : classNodes) - { - // Define the derived types - out << "#define " << m_options->m_markPrefix << "FIELDS_" << reflectTypeName << "_" - << classNode->m_name.getContent() << "(_x_, _param_)"; - - // Find all of the instance fields fields - List<FieldNode*> fields; - for (Node* child : classNode->m_children) - { - if (auto field = as<FieldNode>(child)) - { - if (!field->m_isStatic) - { - fields.add(field); - } - } - } - - if (fields.getCount() > 0) - { - out << "\\\n"; - - const Index fieldsCount = fields.getCount(); - bool previousField = false; - for (Index j = 0; j < fieldsCount; ++j) - { - const FieldNode* field = fields[j]; - - if (field->isReflected()) - { - if (previousField) - { - out << "\\\n"; - } - - _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->m_name.getContent() << ", (" << field->m_fieldType - << "), _param_)"; - previousField = true; - } - } - } - - out << "\n\n"; - } - } - - return SLANG_OK; -} - -SlangResult MacroWriter::calcOriginHeader(NodeTree* tree, StringBuilder& out) -{ - // Do macros by origin - - out << "// Origin macros\n\n"; - - for (SourceOrigin* origin : tree->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 MacroWriter::calcTypeHeader(NodeTree* tree, TypeSet* typeSet, StringBuilder& out) -{ - const List<ClassLikeNode*>& 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"; - - if (baseTypes.getCount() == 0) - { - return SLANG_OK; - } - - // Set up the scope - List<Node*> baseScopePath; - baseTypes[0]->calcScopePath(baseScopePath); - - // Remove the global scope - baseScopePath.removeAt(0); - // Remove the type itself - baseScopePath.removeLast(); - - for (Node* scopeNode : baseScopePath) - { - SLANG_ASSERT(scopeNode->m_kind == Node::Kind::Namespace); - out << "namespace " << scopeNode->m_name.getContent() << " {\n"; - } - - // Add all the base types, with in order traversals - List<ClassLikeNode*> nodes; - for (Index i = 0; i < baseTypes.getCount(); ++i) - { - ClassLikeNode* baseType = baseTypes[i]; - baseType->calcDerivedDepthFirst(nodes); - } - - Node::filter(Node::isClassLikeAndReflected, nodes); - - // Write out the types - { - out << "\n"; - out << "enum class " << reflectTypeName << "Type\n"; - out << "{\n"; - - Index typeIndex = 0; - for (ClassLikeNode* 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"; - - 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 - { - out << "// Predeclare\n\n"; - for (ClassLikeNode* node : nodes) - { - // If it's not reflected we don't output, in the enum list - if (node->isReflected()) - { - const char* type = (node->m_kind == Node::Kind::ClassType) ? "class" : "struct"; - out << type << " " << node->m_name.getContent() << ";\n"; - } - } - } - - // Do the macros for each of the types - - { - out << "// Type macros\n\n"; - - 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 all of the definitions for each type - for (ClassLikeNode* node : nodes) - { - out << "#define " << m_options->m_markPrefix << reflectTypeName << "_" - << node->m_name.getContent() << "(x, param) "; - - // Output the X macro part - _indent(1, out); - out << "x(" << node->m_name.getContent() << ", "; - - if (node->m_superNode) - { - out << node->m_superNode->m_name.getContent() << ", "; - } - else - { - out << "NO_SUPER, "; - } - - // Output the (file origin) - out << node->m_origin->m_macroOrigin; - out << ", "; - - // The last type - Node* lastDerived = node->findLastDerived(); - if (lastDerived) - { - out << lastDerived->m_name.getContent() << ", "; - } - else - { - out << "NO_LAST, "; - } - - // 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 << ", "; - - if (node->m_superNode == nullptr) - { - out << "BASE, "; - } - else if (node->hasReflectedDerivedType()) - { - out << "INNER, "; - } - else - { - out << "LEAF, "; - } - out << "param)\n"; - } - } - - // 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"; - } - - return SLANG_OK; -} - -SlangResult MacroWriter::writeDefs(NodeTree* tree) -{ - const auto& origins = tree->getSourceOrigins(); - - for (SourceOrigin* origin : origins) - { - const String path = origin->m_sourceFile->getPathInfo().foundPath; - - // We need to work out the name of the def file - - String ext = Path::getPathExt(path); - String pathWithoutExt = Path::getPathWithoutExt(path); - - // The output path - - StringBuilder outPath; - outPath << pathWithoutExt << "-defs." << ext; - - StringBuilder content; - SLANG_RETURN_ON_FAIL(calcDef(tree, origin, content)); - - // Write the defs file - SLANG_RETURN_ON_FAIL(FileUtil::writeAllText(outPath, m_sink, content.getUnownedSlice())); - } - - return SLANG_OK; -} - -SlangResult MacroWriter::writeOutput(NodeTree* tree) -{ - String path; - if (m_options->m_inputDirectory.getLength()) - { - path = Path::combine(m_options->m_inputDirectory, m_options->m_outputPath); - } - else - { - path = m_options->m_outputPath; - } - - // Get the ext - String ext = Path::getPathExt(path); - if (ext.getLength() == 0) - { - // Default to .h if not specified - ext = "h"; - } - - // Strip the extension if set - path = Path::getPathWithoutExt(path); - - for (TypeSet* typeSet : tree->getTypeSets()) - { - { - /// Calculate the header - StringBuilder header; - SLANG_RETURN_ON_FAIL(calcTypeHeader(tree, typeSet, header)); - - // Write it out - - StringBuilder headerPath; - headerPath << path << "-" << typeSet->m_fileMark << "." << ext; - SLANG_RETURN_ON_FAIL( - FileUtil::writeAllText(headerPath, m_sink, header.getUnownedSlice())); - } - - { - StringBuilder childrenHeader; - SLANG_RETURN_ON_FAIL(calcChildrenHeader(tree, typeSet, childrenHeader)); - - StringBuilder headerPath; - headerPath << path << "-" << typeSet->m_fileMark << "-macro." + ext; - SLANG_RETURN_ON_FAIL( - FileUtil::writeAllText(headerPath, m_sink, childrenHeader.getUnownedSlice())); - } - } - - return SLANG_OK; -} - -} // namespace CppExtract |
