Skip to content

Commit

Permalink
Translate libclang error codes to exceptions
Browse files Browse the repository at this point in the history
Do not silence the exceptions.
  • Loading branch information
micbou committed Jan 27, 2018
1 parent c39c7c6 commit 4eacc49
Show file tree
Hide file tree
Showing 14 changed files with 189 additions and 208 deletions.
40 changes: 2 additions & 38 deletions cpp/ycm/ClangCompleter/ClangCompleter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// along with ycmd. If not, see <http://www.gnu.org/licenses/>.

#include "ClangCompleter.h"
#include "exceptions.h"
#include "Result.h"
#include "Candidate.h"
#include "TranslationUnit.h"
Expand Down Expand Up @@ -84,22 +83,15 @@ std::vector< Diagnostic > ClangCompleter::UpdateTranslationUnit(
flags,
translation_unit_created );

if ( !unit ) {
return std::vector< Diagnostic >();
}

try {
return unit->Reparse( unsaved_files );
}

catch ( ClangParseError & ) {
} catch ( const ClangParseError & ) {
// If unit->Reparse fails, then the underlying TranslationUnit object is not
// valid anymore and needs to be destroyed and removed from the filename ->
// TU map.
translation_unit_store_.Remove( filename );
throw;
}

return std::vector< Diagnostic >();
}


Expand All @@ -114,10 +106,6 @@ ClangCompleter::CandidatesForLocationInFile(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return std::vector< CompletionData >();
}

return unit->CandidatesForLocation( line,
column,
unsaved_files );
Expand All @@ -135,10 +123,6 @@ Location ClangCompleter::GetDeclarationLocation(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return Location();
}

return unit->GetDeclarationLocation( line, column, unsaved_files, reparse );
}

Expand All @@ -154,10 +138,6 @@ Location ClangCompleter::GetDefinitionLocation(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return Location();
}

return unit->GetDefinitionLocation( line, column, unsaved_files, reparse );
}

Expand All @@ -173,10 +153,6 @@ std::string ClangCompleter::GetTypeAtLocation(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return "no unit";
}

return unit->GetTypeAtLocation( line, column, unsaved_files, reparse );
}

Expand All @@ -192,10 +168,6 @@ std::string ClangCompleter::GetEnclosingFunctionAtLocation(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return "no unit";
}

return unit->GetEnclosingFunctionAtLocation( line,
column,
unsaved_files,
Expand All @@ -216,10 +188,6 @@ ClangCompleter::GetFixItsForLocationInFile(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return std::vector< FixIt >();
}

return unit->GetFixItsForLocationInFile( line,
column,
unsaved_files,
Expand All @@ -240,10 +208,6 @@ DocumentationData ClangCompleter::GetDocsForLocationInFile(
shared_ptr< TranslationUnit > unit =
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );

if ( !unit ) {
return DocumentationData();
}

return unit->GetDocsForLocationInFile( line,
column,
unsaved_files,
Expand Down
25 changes: 25 additions & 0 deletions cpp/ycm/ClangCompleter/ClangUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,29 @@ std::string ClangVersion() {
return CXStringToString( clang_getClangVersion() );
}

const char *CXErrorCodeToString( CXErrorCode code ) {
switch ( code ) {
case CXError_Success:
return "No error encountered while parsing the translation unit.";
case CXError_Failure:
return "Failed to parse the translation unit.";
case CXError_Crashed:
return "Libclang crashed while parsing the translation unit.";
case CXError_InvalidArguments:
return "Invalid arguments supplied when parsing the translation unit.";
case CXError_ASTReadError:
return "An AST deserialization error occurred "
"while parsing the translation unit.";
}
return "Unknown error while parsing the translation unit.";
}

ClangParseError::ClangParseError( const char *what_arg )
: std::runtime_error( what_arg ) {
};

ClangParseError::ClangParseError( CXErrorCode code )
: ClangParseError( CXErrorCodeToString( code ) ) {
};

} // namespace YouCompleteMe
11 changes: 11 additions & 0 deletions cpp/ycm/ClangCompleter/ClangUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define CLANGUTILS_H_9MVHQLJS

#include <clang-c/Index.h>
#include <stdexcept>
#include <string>

namespace YouCompleteMe {
Expand All @@ -37,6 +38,16 @@ std::string CXFileToFilepath( CXFile file );

std::string ClangVersion();

const char *CXErrorCodeToString( CXErrorCode code );

/**
* Thrown when libclang fails to parse (or reparse) the translation unit.
*/
struct YCM_EXPORT ClangParseError : std::runtime_error {
ClangParseError( const char *what_arg );
ClangParseError( CXErrorCode code );
};

} // namespace YouCompleteMe

#endif /* end of include guard: CLANGUTILS_H_9MVHQLJS */
Expand Down
41 changes: 21 additions & 20 deletions cpp/ycm/ClangCompleter/TranslationUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include "TranslationUnit.h"
#include "CompletionData.h"
#include "exceptions.h"
#include "ClangUtils.h"
#include "ClangHelpers.h"

Expand Down Expand Up @@ -95,18 +94,17 @@ TranslationUnit::TranslationUnit(
? &cxunsaved_files[ 0 ] : nullptr;

// Actually parse the translation unit.
CXErrorCode result = clang_parseTranslationUnit2FullArgv(
clang_index,
filename.c_str(),
&pointer_flags[ 0 ],
pointer_flags.size(),
const_cast<CXUnsavedFile *>( unsaved ),
cxunsaved_files.size(),
EditingOptions(),
&clang_translation_unit_ );

if ( result != CXError_Success ) {
throw( ClangParseError() );
CXErrorCode failure = clang_parseTranslationUnit2FullArgv(
clang_index,
filename.c_str(),
&pointer_flags[ 0 ],
pointer_flags.size(),
const_cast<CXUnsavedFile *>( unsaved ),
cxunsaved_files.size(),
EditingOptions(),
&clang_translation_unit_ );
if ( failure != CXError_Success ) {
throw ClangParseError( failure );
}
}

Expand Down Expand Up @@ -374,7 +372,7 @@ void TranslationUnit::Reparse(
// param though.
void TranslationUnit::Reparse( std::vector< CXUnsavedFile > &unsaved_files,
size_t parse_options ) {
int failure = 0;
CXErrorCode failure;
{
unique_lock< mutex > lock( clang_access_mutex_ );

Expand All @@ -385,15 +383,18 @@ void TranslationUnit::Reparse( std::vector< CXUnsavedFile > &unsaved_files,
CXUnsavedFile *unsaved = unsaved_files.size() > 0
? &unsaved_files[ 0 ] : nullptr;

failure = clang_reparseTranslationUnit( clang_translation_unit_,
unsaved_files.size(),
unsaved,
parse_options );
// This function should technically return a CXErrorCode enum but return an
// int instead.
failure = static_cast< CXErrorCode >(
clang_reparseTranslationUnit( clang_translation_unit_,
unsaved_files.size(),
unsaved,
parse_options ) );
}

if ( failure ) {
if ( failure != CXError_Success ) {
Destroy();
throw( ClangParseError() );
throw ClangParseError( failure );
}

UpdateLatestDiagnostics();
Expand Down
2 changes: 1 addition & 1 deletion cpp/ycm/ClangCompleter/TranslationUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class TranslationUnit {

YCM_EXPORT bool IsCurrentlyUpdating() const;

std::vector< Diagnostic > Reparse(
YCM_EXPORT std::vector< Diagnostic > Reparse(
const std::vector< UnsavedFile > &unsaved_files );

YCM_EXPORT std::vector< CompletionData > CandidatesForLocation(
Expand Down
5 changes: 2 additions & 3 deletions cpp/ycm/ClangCompleter/TranslationUnitStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "TranslationUnitStore.h"
#include "TranslationUnit.h"
#include "Utils.h"
#include "exceptions.h"

#include <functional>

Expand Down Expand Up @@ -106,9 +105,9 @@ shared_ptr< TranslationUnit > TranslationUnitStore::GetOrCreate(
unsaved_files,
flags,
clang_index_ );
} catch ( ClangParseError & ) {
} catch ( const ClangParseError & ) {
Remove( filename );
return unit;
throw;
}

{
Expand Down
36 changes: 36 additions & 0 deletions cpp/ycm/PythonSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,42 @@ YCM_EXPORT boost::python::list FilterAndSortCandidates(
/// a string. Supports newstr and newbytes from python-future on Python 2.
std::string GetUtf8String( const boost::python::object &value );

/// Expose the C++ exception |CppException| as a Python exception inheriting
/// from the base exception |base_exception| (default being Exception) with the
/// fully qualified name <module>.|name| where <module> is the current
/// Boost.Python module. |CppException| must define a what() method (easiest way
/// is to derive it from std::runtime_error). This templated class should be
/// instantiated inside the BOOST_PYTHON_MODULE macro.
template< typename CppException >
class PythonException {
public:

PythonException( const char* name,
PyObject* base_exception = PyExc_Exception ) {
std::string module_name = boost::python::extract< std::string >(
boost::python::scope().attr( "__name__" ) );
std::string fully_qualified_name = module_name + "." + name;
// PyErr_NewException does not modify the exception name so it's safe to
// cast away constness.
char *raw_name = const_cast< char * >( fully_qualified_name.c_str() );
python_exception_ = PyErr_NewException( raw_name, base_exception, NULL );

// Add the Python exception to the current Boost.Python module.
boost::python::scope().attr( name ) = boost::python::handle<>(
python_exception_ );

boost::python::register_exception_translator< CppException >( *this );
};

void operator() ( const CppException &cpp_exception ) const {
PyErr_SetString( python_exception_, cpp_exception.what() );
}

private:
PyObject* python_exception_;

};

} // namespace YouCompleteMe

#endif /* end of include guard: PYTHONSUPPORT_H_KWGFEX0V */
Expand Down
8 changes: 0 additions & 8 deletions cpp/ycm/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,4 @@ std::string ReadUtf8File( const fs::path &filepath ) {
return std::string();
}


void WriteUtf8File( const fs::path &filepath, const std::string &contents ) {
fs::ofstream file;
file.open( filepath );
file << contents;
file.close();
}

} // namespace YouCompleteMe
5 changes: 0 additions & 5 deletions cpp/ycm/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,6 @@ YCM_EXPORT inline std::string SwapCase( const std::string &text ) {
// an exception is thrown.
std::string ReadUtf8File( const fs::path &filepath );

// Writes the entire contents of the specified file. If the file does not exist,
// an exception is thrown.
YCM_EXPORT void WriteUtf8File( const fs::path &filepath,
const std::string &contents );

template <class Container, class Key>
typename Container::mapped_type &
GetValueElseInsert( Container &container,
Expand Down
35 changes: 0 additions & 35 deletions cpp/ycm/exceptions.h

This file was deleted.

Loading

0 comments on commit 4eacc49

Please sign in to comment.