From: Douglas Gregor Date: Fri, 19 Feb 2010 18:16:06 +0000 (+0000) Subject: Simplify the CIndex fix-it API, now that we have half-open CXSourceRanges. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=473d7019bb54f8a2f0140dca9e9644a935cc6b20;p=clang Simplify the CIndex fix-it API, now that we have half-open CXSourceRanges. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96685 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 0130b72b6f..5426256d43 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -389,28 +389,6 @@ enum CXDiagnosticSeverity { CXDiagnostic_Fatal = 4 }; -/** - * \brief Describes the kind of fix-it hint expressed within a - * diagnostic. - */ -enum CXFixItKind { - /** - * \brief A fix-it hint that inserts code at a particular position. - */ - CXFixIt_Insertion = 0, - - /** - * \brief A fix-it hint that removes code within a range. - */ - CXFixIt_Removal = 1, - - /** - * \brief A fix-it hint that replaces the code within a range with another - * string. - */ - CXFixIt_Replacement = 2 -}; - /** * \brief A single diagnostic, containing the diagnostic's severity, * location, text, source ranges, and fix-it hints. @@ -561,69 +539,33 @@ CINDEX_LINKAGE CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic, CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic); /** - * \brief Retrieve the kind of the given fix-it. - * - * \param Diagnostic the diagnostic whose fix-its are being queried. - * - * \param FixIt the zero-based index of the fix-it to query. - */ -CINDEX_LINKAGE enum CXFixItKind -clang_getDiagnosticFixItKind(CXDiagnostic Diagnostic, unsigned FixIt); - -/** - * \brief Retrieve the insertion information for an insertion fix-it. + * \brief Retrieve the replacement information for a given fix-it. * - * For a fix-it that describes an insertion into a text buffer, - * retrieve the source location where the text should be inserted and - * the text to be inserted. + * Fix-its are described in terms of a source range whose contents + * should be replaced by a string. This approach generalizes over + * three kinds of operations: removal of source code (the range covers + * the code to be removed and the replacement string is empty), + * replacement of source code (the range covers the code to be + * replaced and the replacement string provides the new code), and + * insertion (both the start and end of the range point at the + * insertion location, and the replacement string provides the text to + * insert). * - * \param Diagnostic the diagnostic whose fix-its are being queried. + * \param Diagnostic The diagnostic whose fix-its are being queried. * - * \param FixIt the zero-based index of the insertion fix-it. + * \param FixIt The zero-based index of the fix-it. * - * \param Location will be set to the location where text should be - * inserted. + * \param ReplacementRange The source range whose contents will be + * replaced with the returned replacement string. Note that source + * ranges are half-open ranges [a, b), so the source code should be + * replaced from a and up to (but not including) b. * - * \returns the text string to insert at the given location. + * \returns A string containing text that should be replace the source + * code indicated by the \c ReplacementRange. */ -CINDEX_LINKAGE CXString -clang_getDiagnosticFixItInsertion(CXDiagnostic Diagnostic, unsigned FixIt, - CXSourceLocation *Location); - -/** - * \brief Retrieve the removal information for a removal fix-it. - * - * For a fix-it that describes a removal from a text buffer, retrieve - * the source range that should be removed. - * - * \param Diagnostic the diagnostic whose fix-its are being queried. - * - * \param FixIt the zero-based index of the removal fix-it. - * - * \returns a source range describing the text that should be removed - * from the buffer. - */ -CINDEX_LINKAGE CXSourceRange -clang_getDiagnosticFixItRemoval(CXDiagnostic Diagnostic, unsigned FixIt); - -/** - * \brief Retrieve the replacement information for an replacement fix-it. - * - * For a fix-it that describes replacement of text in the text buffer - * with alternative text. - * - * \param Diagnostic the diagnostic whose fix-its are being queried. - * - * \param FixIt the zero-based index of the replacement fix-it. - * - * \param Range will be set to the source range whose text should be - * replaced with the returned text. - * - * \returns the text string to use as replacement text. - */ -CINDEX_LINKAGE CXString -clang_getDiagnosticFixItReplacement(CXDiagnostic Diagnostic, unsigned FixIt, - CXSourceRange *Range); +CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, + unsigned FixIt, + CXSourceRange *ReplacementRange); /** * @} diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index 449bb95a94..e32e9d598c 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -32,10 +32,7 @@ _clang_getCursorSpelling _clang_getCursorUSR _clang_getDefinitionSpellingAndExtent _clang_getDiagnostic -_clang_getDiagnosticFixItInsertion -_clang_getDiagnosticFixItKind -_clang_getDiagnosticFixItRemoval -_clang_getDiagnosticFixItReplacement +_clang_getDiagnosticFixIt _clang_getDiagnosticLocation _clang_getDiagnosticNumFixIts _clang_getDiagnosticNumRanges diff --git a/tools/CIndex/CIndexDiagnostic.cpp b/tools/CIndex/CIndexDiagnostic.cpp index 07c1983672..97d5017077 100644 --- a/tools/CIndex/CIndexDiagnostic.cpp +++ b/tools/CIndex/CIndexDiagnostic.cpp @@ -184,74 +184,42 @@ unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { return StoredDiag->Diag.fixit_size(); } -enum CXFixItKind clang_getDiagnosticFixItKind(CXDiagnostic Diag, - unsigned FixIt) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size()) - return CXFixIt_Insertion; - - const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - if (Hint.RemoveRange.isInvalid()) - return CXFixIt_Insertion; - if (Hint.InsertionLoc.isInvalid()) - return CXFixIt_Removal; - - return CXFixIt_Replacement; -} - -CXString clang_getDiagnosticFixItInsertion(CXDiagnostic Diag, - unsigned FixIt, - CXSourceLocation *Location) { - if (Location) - *Location = clang_getNullLocation(); - - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size()) - return createCXString(""); - - const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - - if (Location && StoredDiag->Diag.getLocation().isValid()) - *Location = translateSourceLocation( - StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - Hint.InsertionLoc); - return createCXString(Hint.CodeToInsert); -} - -CXSourceRange clang_getDiagnosticFixItRemoval(CXDiagnostic Diag, - unsigned FixIt) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || - StoredDiag->Diag.getLocation().isInvalid()) - return clang_getNullRange(); - - const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - return translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - Hint.RemoveRange); -} - -CXString clang_getDiagnosticFixItReplacement(CXDiagnostic Diag, - unsigned FixIt, - CXSourceRange *Range) { - if (Range) - *Range = clang_getNullRange(); - - CXStoredDiagnostic *StoredDiag = static_cast(Diag); +CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, unsigned FixIt, + CXSourceRange *ReplacementRange) { + CXStoredDiagnostic *StoredDiag + = static_cast(Diagnostic); if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || StoredDiag->Diag.getLocation().isInvalid()) { - if (Range) - *Range = clang_getNullRange(); + if (ReplacementRange) + *ReplacementRange = clang_getNullRange(); return createCXString(""); } const CodeModificationHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - if (Range) - *Range = translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - Hint.RemoveRange); + if (ReplacementRange) { + if (Hint.RemoveRange.isInvalid()) { + // Create an empty range that refers to a single source + // location (which is the insertion point). + CXSourceRange Range = { + { (void *)&StoredDiag->Diag.getLocation().getManager(), + (void *)&StoredDiag->LangOpts }, + Hint.InsertionLoc.getRawEncoding(), + Hint.InsertionLoc.getRawEncoding() + }; + + *ReplacementRange = Range; + } else { + // Create a range that covers the entire replacement (or + // removal) range, adjusting the end of the range to point to + // the end of the token. + *ReplacementRange + = translateSourceRange(StoredDiag->Diag.getLocation().getManager(), + StoredDiag->LangOpts, + Hint.RemoveRange); + } + } + return createCXString(Hint.CodeToInsert); } diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index c5f8431c34..2207364266 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -198,7 +198,6 @@ typedef void (*PostVisitTU)(CXTranslationUnit); void PrintDiagnostic(CXDiagnostic Diagnostic) { FILE *out = stderr; CXFile file; - CXString text; unsigned display_opts = CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges; unsigned i, num_fixits; @@ -214,58 +213,37 @@ void PrintDiagnostic(CXDiagnostic Diagnostic) { num_fixits = clang_getDiagnosticNumFixIts(Diagnostic); for (i = 0; i != num_fixits; ++i) { - switch (clang_getDiagnosticFixItKind(Diagnostic, i)) { - case CXFixIt_Insertion: { - CXSourceLocation insertion_loc; - CXFile insertion_file; - unsigned insertion_line, insertion_column; - text = clang_getDiagnosticFixItInsertion(Diagnostic, i, &insertion_loc); - clang_getInstantiationLocation(insertion_loc, &insertion_file, - &insertion_line, &insertion_column, 0); - if (insertion_file == file) + CXSourceRange range; + CXString insertion_text = clang_getDiagnosticFixIt(Diagnostic, i, &range); + CXSourceLocation start = clang_getRangeStart(range); + CXSourceLocation end = clang_getRangeEnd(range); + unsigned start_line, start_column, end_line, end_column; + CXFile start_file, end_file; + clang_getInstantiationLocation(start, &start_file, &start_line, + &start_column, 0); + clang_getInstantiationLocation(end, &end_file, &end_line, &end_column, 0); + if (clang_equalLocations(start, end)) { + /* Insertion. */ + if (start_file == file) fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n", - clang_getCString(text), insertion_line, insertion_column); - clang_disposeString(text); - break; - } - - case CXFixIt_Removal: { - CXFile start_file, end_file; - unsigned start_line, start_column, end_line, end_column; - CXSourceRange remove_range - = clang_getDiagnosticFixItRemoval(Diagnostic, i); - clang_getInstantiationLocation(clang_getRangeStart(remove_range), - &start_file, &start_line, &start_column, - 0); - clang_getInstantiationLocation(clang_getRangeEnd(remove_range), - &end_file, &end_line, &end_column, 0); + clang_getCString(insertion_text), start_line, start_column); + } else if (strcmp(clang_getCString(insertion_text), "") == 0) { + /* Removal. */ if (start_file == file && end_file == file) { fprintf(out, "FIX-IT: Remove "); PrintExtent(out, start_line, start_column, end_line, end_column); fprintf(out, "\n"); } - break; - } - - case CXFixIt_Replacement: { - CXFile start_file, end_file; - unsigned start_line, start_column, end_line, end_column; - CXSourceRange remove_range; - text = clang_getDiagnosticFixItReplacement(Diagnostic, i,&remove_range); - clang_getInstantiationLocation(clang_getRangeStart(remove_range), - &start_file, &start_line, &start_column, - 0); - clang_getInstantiationLocation(clang_getRangeEnd(remove_range), - &end_file, &end_line, &end_column, 0); + } else { + /* Replacement. */ if (start_file == end_file) { fprintf(out, "FIX-IT: Replace "); PrintExtent(out, start_line, start_column, end_line, end_column); - fprintf(out, " with \"%s\"\n", clang_getCString(text)); + fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text)); } - clang_disposeString(text); break; } - } + clang_disposeString(insertion_text); } }