Ejemplo n.º 1
0
int test_main(int argc, char * argv[])
{
   try
   { 
      // setup log
      initializeStderrLog("coredev", ::core::system::kLogLevelWarning);

      // ignore sigpipe
      Error error = ::core::system::ignoreSignal(::core::system::SigPipe);
      if (error)
         LOG_ERROR(error);

      // write a C++ file
      std::string cpp =
        "#include <string>\n"
        "class X { public:\n"
        "   void test(int y, int x = 10);\n"
        "}\n"
        "void X::test(int y, int x) {}\n"
        "void foobar() {\n"
        "   X x;\n"
        "   x."
        "}";
      std::ofstream ostr("foo.cpp");
      ostr << cpp;
      ostr.close();

      // load libclang
      using namespace libclang;
      std::string diagnostics;
      clang().load(EmbeddedLibrary(), LibraryVersion(3,4,0), &diagnostics);
      if (!clang().isLoaded())
      {
         std::cerr << "Failed to load libclang: " << diagnostics << std::endl;
         return EXIT_FAILURE;
      }

      // create a source index and get a translation unit for it
      SourceIndex sourceIndex;
      TranslationUnit tu = sourceIndex.getTranslationUnit("foo.cpp");
      if (tu.empty())
      {
         std::cerr << "No translation unit foo.cpp" << std::endl;
         return EXIT_FAILURE;
      }

      // code complete
      CodeCompleteResults results = tu.codeCompleteAt("foo.cpp", 8, 6);
      for (unsigned i = 0; i<results.getNumResults(); i++) {
        std::cout << results.getResult(i).getTypedText() << std::endl;
        std::cout << "   " << results.getResult(i).getText() << std::endl;
      }

      return EXIT_SUCCESS;
   }
   CATCH_UNEXPECTED_EXCEPTION
   
   // if we got this far we had an unexpected exception
   return EXIT_FAILURE ;
}
Ejemplo n.º 2
0
Error getCppCompletions(const core::json::JsonRpcRequest& request,
                        core::json::JsonRpcResponse* pResponse)
{
   // get params
   std::string docPath, userText;
   int line, column;
   Error error = json::readParams(request.params,
                                  &docPath,
                                  &line,
                                  &column,
                                  &userText);
   if (error)
      return error;

   // resolve the docPath if it's aliased
   FilePath filePath = module_context::resolveAliasedPath(docPath);

   // get the translation unit and do the code completion
   std::string filename = filePath.absolutePath();
   TranslationUnit tu = rSourceIndex().getTranslationUnit(filename);

   if (!tu.empty())
   {
      std::string lastTypedText;
      json::Array completionsJson;
      boost::shared_ptr<CodeCompleteResults> pResults =
                              tu.codeCompleteAt(filename, line, column);
      if (!pResults->empty())
      {
         // get results
         for (unsigned i = 0; i<pResults->getNumResults(); i++)
         {
            CodeCompleteResult result = pResults->getResult(i);

            // filter on user text if we have it
            if (!userText.empty() &&
                !boost::algorithm::starts_with(result.getTypedText(), userText))
            {
               continue;
            }

            // check whether this completion is valid and bail if not
            if (result.getAvailability() != CXAvailability_Available)
            {
               continue;
            }

            std::string typedText = result.getTypedText();

            // if we have the same typed text then just ammend previous result
            if ((typedText == lastTypedText) && !completionsJson.empty())
            {
               json::Object& res = completionsJson.back().get_obj();
               json::Array& text = res["text"].get_array();
               text.push_back(friendlyCompletionText(result));
            }
            else
            {
               completionsJson.push_back(toJson(result));
            }

            lastTypedText = typedText;
         }
      }

      json::Object resultJson;
      resultJson["completions"] = completionsJson;
      pResponse->setResult(resultJson);
   }
   else
   {
      // set null result indicating this file doesn't support completions
      pResponse->setResult(json::Value());
   }

   return Success();
}
Ejemplo n.º 3
0
core::Error findReferences(const core::libclang::FileLocation& location,
                           std::string* pSpelling,
                           std::vector<core::libclang::FileRange>* pRefs)
{
   Cursor cursor = rSourceIndex().referencedCursorForFileLocation(location);
   if (!cursor.isValid() || !cursor.isDeclaration())
      return Success();

   // get it's USR (bail if it doesn't have one)
   std::string USR = cursor.getUSR();
   if (USR.empty())
      return Success();

   // determine what translation units to look in -- if this is a package
   // then we look throughout all the source code in the package.
   if (rCompilationDatabase().hasTranslationUnit(
                                         location.filePath.absolutePath()))
   {
      // get all translation units to search
      std::vector<std::string> files = rCompilationDatabase()
                                                .translationUnits();

      // get translation units we've already indexed
      std::map<std::string,TranslationUnit> indexedUnits =
                           rSourceIndex().getIndexedTranslationUnits();

      for (const std::string& filename : files)
      {
         // first look in already indexed translation units
         // (this will pickup unsaved files)
         std::map<std::string,TranslationUnit>::iterator it =
                                                   indexedUnits.find(filename);
         if (it != indexedUnits.end())
         {
            findReferences(USR,
                           it->second.getCXTranslationUnit(),
                           pSpelling,
                           pRefs);
         }
         else
         {
            // get the compilation arguments for this file and use them to
            // create a temporary translation unit to search
            std::vector<std::string> compileArgs =
               rCompilationDatabase().compileArgsForTranslationUnit(filename,
                                                                    true);

            if (compileArgs.empty())
               continue;

            // create temporary index
            CXIndex index = libclang::clang().createIndex(
                              1 /* Exclude PCH */,
                              (rSourceIndex().verbose() > 0) ? 1 : 0);

            // get args in form clang expects
            core::system::ProcessArgs argsArray(compileArgs);

            // parse the translation unit
            CXTranslationUnit tu = libclang::clang().parseTranslationUnit(
                                  index,
                                  filename.c_str(),
                                  argsArray.args(),
                                  gsl::narrow_cast<int>(argsArray.argCount()),
                                  nullptr, 0, // no unsaved files
                                  CXTranslationUnit_None |
                                  CXTranslationUnit_Incomplete);

            // find references
            findReferences(USR, tu, pSpelling, pRefs);

            // dispose translation unit and index
            libclang::clang().disposeTranslationUnit(tu);
            libclang::clang().disposeIndex(index);
         }
      }
   }
   // not a package, just search locally
   else
   {
      TranslationUnit tu = rSourceIndex().getTranslationUnit(
                                             location.filePath.absolutePath(),
                                             true);
      if (!tu.empty())
         findReferences(USR, tu.getCXTranslationUnit(), pSpelling, pRefs);
   }

   return Success();

}