Пример #1
0
void ReflectionParser::Parse(void)
{
    m_index = clang_createIndex( true, m_options.displayDiagnostics );

    std::vector<const char *> arguments;

#if defined(SYSTEM_INCLUDE_DIRECTORY)

    arguments.emplace_back( "-I" SYSTEM_INCLUDE_DIRECTORY );

#endif

    for (auto &argument : m_options.arguments)
        arguments.emplace_back( argument.c_str( ) );

    if (m_options.displayDiagnostics)
    {
        for (auto *argument : arguments)
            std::cout << argument << std::endl;
    }

    m_translationUnit = clang_createTranslationUnitFromSourceFile(
        m_index,
        m_options.inputSourceFile.c_str( ),
        static_cast<int>( arguments.size( ) ),
        arguments.data( ),
        0,
        nullptr
    );

    auto cursor = clang_getTranslationUnitCursor( m_translationUnit );

    Namespace tempNamespace;

    buildClasses( cursor, tempNamespace );

    tempNamespace.clear( );

    buildGlobals( cursor, tempNamespace );

    tempNamespace.clear( );

    buildGlobalFunctions( cursor, tempNamespace );

    tempNamespace.clear( );

    buildEnums( cursor, tempNamespace );
}
bool ReflectionParser::ProcessFile(std::string const & fileName, bool InProcessModule)
{
  if (!InProcessModule && !m_sourceCache->RequestGenerate(fileName))
    return true;

  Clear();

  m_currentFile = fileName;
  m_index = clang_createIndex(true, false);

  std::vector<const char *> arguments;

  for (auto &argument : m_options.arguments)
  {
    // unescape flags
    boost::algorithm::replace_all(argument, "\\-", "-");

    arguments.emplace_back(argument.c_str());
  }

  m_translationUnit = clang_createTranslationUnitFromSourceFile(
        m_index,
        fileName.c_str(),
        static_cast<int>(arguments.size()),
        arguments.data(),
        0,
        nullptr
        );

  auto cursor = clang_getTranslationUnitCursor(m_translationUnit);

  try
  {
    Namespace tempNamespace;
    buildClasses(cursor, tempNamespace);
    tempNamespace.clear();

    if (ContainsModule() && !InProcessModule)
    {
      if (m_classes.size() > 1)
      {
        EMIT_ERROR("You can't implement any other classes in one file with module class");
      }
      return false;
    }

    if (RequestGenerate())
    {
      std::string fileId = GetFileID(fileName);
      std::stringstream outCode;

      // includes
      outCode << "#include <memory>\n\n";
      outCode << "#include \"sc-memory/cpp/sc_memory.hpp\"\n\n\n";
      outCode << "#include \"sc-memory/cpp/sc_event.hpp\"\n\n\n";

      for (auto it = m_classes.begin(); it != m_classes.end(); ++it)
      {
        Class const * klass = *it;
        if (klass->ShouldGenerate())
        {
          klass->GenerateCode(fileId, outCode, this);
        }
      }

      /// write ScFileID definition
      outCode << "\n\n#undef ScFileID\n";
      outCode << "#define ScFileID " << fileId;

      // generate output file
      boost::filesystem::path outputPath(m_options.outputPath);
      outputPath /= boost::filesystem::path(GetOutputFileName(fileName));
      std::ofstream outputFile(outputPath.string());
      outputFile << outCode.str();
      outputFile << std::endl << std::endl;
      outputFile.close();
    }

    clang_disposeIndex(m_index);
    clang_disposeTranslationUnit(m_translationUnit);

  } catch (Exception e)
  {
    clang_disposeIndex(m_index);
    clang_disposeTranslationUnit(m_translationUnit);

    EMIT_ERROR(e.GetDescription());
  }


  return true;
}