diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/tokenize_cleanup.cpp')
-rw-r--r-- | debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/tokenize_cleanup.cpp | 1223 |
1 files changed, 0 insertions, 1223 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/tokenize_cleanup.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/tokenize_cleanup.cpp deleted file mode 100644 index 831e1aae..00000000 --- a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/tokenize_cleanup.cpp +++ /dev/null @@ -1,1223 +0,0 @@ -/** - * @file tokenize_cleanup.cpp - * Looks at simple sequences to refine the chunk types. - * Examples: - * - change '[' + ']' into '[]'/ - * - detect "version = 10;" vs "version (xxx) {" - * - * @author Ben Gardner - * @author Guy Maurel 2015, 2022 - * @license GPL v2+ - */ - -#include "tokenize_cleanup.h" - -#include "check_template.h" -#include "combine.h" -#include "combine_skip.h" -#include "flag_braced_init_list.h" -#include "flag_decltype.h" -#include "keywords.h" -#include "prototypes.h" -#include "punctuators.h" -#include "space.h" -#include "unc_ctype.h" - - -using namespace uncrustify; - - -/** - * Marks ObjC specific chunks in property declaration, by setting - * parent types and chunk types. - */ -static void cleanup_objc_property(Chunk *start); - - -/** - * Marks ObjC specific chunks in property declaration (getter/setter attribute) - * Will mark 'test4Setter'and ':' in '@property (setter=test4Setter:, strong) int test4;' as CT_OC_SEL_NAME - */ -static void mark_selectors_in_property_with_open_paren(Chunk *open_paren); - - -/** - * Marks ObjC specific chunks in property declaration ( attributes) - * Changes all the CT_WORD and CT_TYPE to CT_OC_PROPERTY_ATTR - */ -static void mark_attributes_in_property_with_open_paren(Chunk *open_paren); - - -void split_off_angle_close(Chunk *pc) -{ - const chunk_tag_t *ct = find_punctuator(pc->Text() + 1, cpd.lang_flags); - - if (ct == nullptr) - { - return; - } - Chunk nc = *pc; - - pc->Str().resize(1); - pc->SetOrigColEnd(pc->GetOrigCol() + 1); - pc->SetType(CT_ANGLE_CLOSE); - - nc.SetType(ct->type); - nc.Str().pop_front(); - nc.SetOrigCol(nc.GetOrigCol() + 1); - nc.SetColumn(nc.GetColumn() + 1); - nc.CopyAndAddAfter(pc); -} - - -void tokenize_trailing_return_types() -{ - // Issue #2330 - // auto max(int a, int b) -> int; - // Issue #2460 - // auto f01() -> bool; - // auto f02() noexcept -> bool; - // auto f03() noexcept(true) -> bool; - // auto f04() noexcept(false) -> bool; - // auto f05() noexcept -> bool = delete; - // auto f06() noexcept(true) -> bool = delete; - // auto f07() noexcept(false) -> bool = delete; - // auto f11() const -> bool; - // auto f12() const noexcept -> bool; - // auto f13() const noexcept(true) -> bool; - // auto f14() const noexcept(false) -> bool; - // auto f15() const noexcept -> bool = delete; - // auto f16() const noexcept(true) -> bool = delete; - // auto f17() const noexcept(false) -> bool = delete; - // auto f21() throw() -> bool; - // auto f22() throw() -> bool = delete; - // auto f23() const throw() -> bool; - // auto f24() const throw() -> bool = delete; - - for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNextNcNnl()) - { - char copy[1000]; - LOG_FMT(LNOTE, "%s(%d): orig line is %zu, orig col is %zu, Text() is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->ElidedText(copy)); - - if ( pc->Is(CT_MEMBER) - && (strcmp(pc->Text(), "->") == 0)) - { - Chunk *tmp = pc->GetPrevNcNnl(); - Chunk *tmp_2; - Chunk *open_paren; - - if (tmp->Is(CT_QUALIFIER)) - { - // auto max(int a, int b) const -> int; - // auto f11() const -> bool; - tmp = tmp->GetPrevNcNnl(); - } - else if (tmp->Is(CT_NOEXCEPT)) - { - // noexcept is present - tmp_2 = tmp->GetPrevNcNnl(); - - if (tmp_2->Is(CT_QUALIFIER)) - { - // auto f12() const noexcept -> bool; - // auto f15() const noexcept -> bool = delete; - tmp = tmp_2->GetPrevNcNnl(); - } - else - { - // auto f02() noexcept -> bool; - // auto f05() noexcept -> bool = delete; - tmp = tmp_2; - } - } - else if (tmp->Is(CT_PAREN_CLOSE)) - { - open_paren = tmp->GetPrevType(CT_PAREN_OPEN, tmp->GetLevel()); - tmp = open_paren->GetPrevNcNnl(); - - if (tmp->Is(CT_NOEXCEPT)) - { - // noexcept is present - tmp_2 = tmp->GetPrevNcNnl(); - - if (tmp_2->Is(CT_QUALIFIER)) - { - // auto f13() const noexcept(true) -> bool; - // auto f14() const noexcept(false) -> bool; - // auto f16() const noexcept(true) -> bool = delete; - // auto f17() const noexcept(false) -> bool = delete; - tmp = tmp_2->GetPrevNcNnl(); - } - else - { - // auto f03() noexcept(true) -> bool; - // auto f04() noexcept(false) -> bool; - // auto f06() noexcept(true) -> bool = delete; - // auto f07() noexcept(false) -> bool = delete; - tmp = tmp_2; - } - } - else if (tmp->Is(CT_THROW)) - { - // throw is present - tmp_2 = tmp->GetPrevNcNnl(); - - if (tmp_2->Is(CT_QUALIFIER)) - { - // auto f23() const throw() -> bool; - // auto f24() const throw() -> bool = delete; - tmp = tmp_2->GetPrevNcNnl(); - } - else - { - // auto f21() throw() -> bool; - // auto f22() throw() -> bool = delete; - tmp = tmp_2; - } - } - else - { - LOG_FMT(LNOTE, "%s(%d): NOT COVERED\n", __func__, __LINE__); - } - } - else - { - LOG_FMT(LNOTE, "%s(%d): NOT COVERED\n", __func__, __LINE__); - } - - if ( tmp->Is(CT_FPAREN_CLOSE) - && ( tmp->GetParentType() == CT_FUNC_PROTO - || tmp->GetParentType() == CT_FUNC_DEF)) - { - pc->SetType(CT_TRAILING_RET); - LOG_FMT(LNOTE, "%s(%d): set trailing return type for Text() is '%s'\n", - __func__, __LINE__, pc->Text()); // Issue #3222 - // TODO - // https://en.cppreference.com/w/cpp/language/function - // noptr-declarator ( parameter-list ) cv(optional) ref(optional) except(optional) attr(optional) -> trailing - Chunk *next = pc->GetNextNcNnl(); - - if (next->Is(CT_DECLTYPE)) - { - // TODO - } - else if (next->Is(CT_WORD)) - { - next->SetType(CT_TYPE); // Issue #3222 - next = next->GetNextNcNnl(); - - if (next->Is(CT_ARITH)) - { - if (next->GetStr()[0] == '*') - { - next->SetType(CT_PTR_TYPE); - } - else if (next->GetStr()[0] == '&') // Issue #3407 - { - next->SetType(CT_BYREF); - } - } - } - else - { - // TODO - } - } - } - } -} // tokenize_trailing_return_types - - -void tokenize_cleanup() -{ - LOG_FUNC_ENTRY(); - - Chunk *prev = Chunk::NullChunkPtr; - Chunk *next; - bool in_type_cast = false; - - cpd.unc_stage = unc_stage_e::TOKENIZE_CLEANUP; - - /* - * Since [] is expected to be TSQUARE for the 'operator', we need to make - * this change in the first pass. - */ - Chunk *pc; - - for (pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNextNcNnl()) - { - if (pc->Is(CT_SQUARE_OPEN)) - { - next = pc->GetNextNcNnl(); - - if (next->Is(CT_SQUARE_CLOSE)) - { - // Change '[' + ']' into '[]' - pc->SetType(CT_TSQUARE); - pc->Str() = "[]"; - /* - * bug #664: The original m_origColEnd of CT_SQUARE_CLOSE is - * stored at m_origColEnd of CT_TSQUARE. - * pc->SetOrigColEnd(pc->GetOrigColEnd() + 1); - */ - pc->SetOrigColEnd(next->GetOrigColEnd()); - Chunk::Delete(next); - } - } - - if ( pc->Is(CT_SEMICOLON) - && pc->TestFlags(PCF_IN_PREPROC) - && !pc->GetNextNcNnl(E_Scope::PREPROC)) - { - LOG_FMT(LNOTE, "%s(%d): %s:%zu Detected a macro that ends with a semicolon. Possible failures if used.\n", - __func__, __LINE__, cpd.filename.c_str(), pc->GetOrigLine()); - } - } - - // change := to CT_SQL_ASSIGN Issue #527 - for (pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNextNcNnl()) - { - if (pc->Is(CT_COLON)) - { - next = pc->GetNextNcNnl(); - - if (next->Is(CT_ASSIGN)) - { - // Change ':' + '=' into ':=' - pc->SetType(CT_SQL_ASSIGN); - pc->Str() = ":="; - pc->SetOrigColEnd(next->GetOrigColEnd()); - Chunk::Delete(next); - } - } - } - - // We can handle everything else in the second pass - pc = Chunk::GetHead(); - next = pc->GetNextNcNnl(); - - while ( pc->IsNotNullChunk() - && next->IsNotNullChunk()) - { - if ( pc->Is(CT_DOT) - && language_is_set(LANG_ALLC)) - { - pc->SetType(CT_MEMBER); - } - - if ( pc->Is(CT_NULLCOND) - && language_is_set(LANG_CS)) - { - pc->SetType(CT_MEMBER); - } - - // Determine the version stuff (D only) - if (pc->Is(CT_D_VERSION)) - { - if (next->Is(CT_PAREN_OPEN)) - { - pc->SetType(CT_D_VERSION_IF); - } - else - { - if (next->IsNot(CT_ASSIGN)) - { - LOG_FMT(LERR, "%s(%d): %s:%zu: version: Unexpected token %s\n", - __func__, __LINE__, cpd.filename.c_str(), pc->GetOrigLine(), get_token_name(next->GetType())); - exit(EX_SOFTWARE); - } - pc->SetType(CT_WORD); - } - } - - // Determine the scope stuff (D only) - if (pc->Is(CT_D_SCOPE)) - { - if (next->Is(CT_PAREN_OPEN)) - { - pc->SetType(CT_D_SCOPE_IF); - } - else - { - pc->SetType(CT_TYPE); - } - } - - /* - * Change CT_BASE before CT_PAREN_OPEN to CT_WORD. - * public myclass() : base() {} - * -or- - * var x = (T)base.y; - */ - if ( pc->Is(CT_BASE) - && ( next->Is(CT_PAREN_OPEN) - || next->Is(CT_DOT))) - { - pc->SetType(CT_WORD); - } - - if ( pc->Is(CT_ENUM) - && ( next->Is(CT_STRUCT) - || next->Is(CT_CLASS))) - { - next->SetType(CT_ENUM_CLASS); - } - Chunk *next_non_attr = language_is_set(LANG_CPP) ? skip_attribute_next(next) : next; - - /* - * Change CT_WORD after CT_ENUM, CT_UNION, CT_STRUCT, or CT_CLASS to CT_TYPE - * Change CT_WORD before CT_WORD to CT_TYPE - */ - if (next_non_attr->Is(CT_WORD)) - { - if (pc->IsClassEnumStructOrUnion()) - { - next_non_attr->SetType(CT_TYPE); - } - - if (pc->Is(CT_WORD)) - { - pc->SetType(CT_TYPE); - } - } - - /* - * change extern to qualifier if extern isn't followed by a string or - * an open parenthesis - */ - if (pc->Is(CT_EXTERN)) - { - if (next->Is(CT_STRING)) - { - // Probably 'extern "C"' - } - else if (next->Is(CT_PAREN_OPEN)) - { - // Probably 'extern (C)' - } - else - { - // Something else followed by a open brace - Chunk *tmp = next->GetNextNcNnl(); - - if ( tmp->IsNullChunk() - || tmp->IsNot(CT_BRACE_OPEN)) - { - pc->SetType(CT_QUALIFIER); - } - } - } - - /* - * Change CT_STAR to CT_PTR_TYPE if preceded by - * CT_TYPE, CT_QUALIFIER, or CT_PTR_TYPE - * or by a - * CT_WORD which is preceded by CT_DC_MEMBER: '::aaa *b' - */ - if ( (next->Is(CT_STAR)) - || ( language_is_set(LANG_CPP) - && (next->Is(CT_CARET))) - || ( language_is_set(LANG_CS | LANG_VALA) - && (next->Is(CT_QUESTION)) - && (strcmp(pc->Text(), "null") != 0))) - { - if ( pc->Is(CT_TYPE) - || pc->Is(CT_QUALIFIER) - || pc->Is(CT_PTR_TYPE)) - { - next->SetType(CT_PTR_TYPE); - } - } - - if ( pc->Is(CT_TYPE_CAST) - && next->Is(CT_ANGLE_OPEN)) - { - next->SetParentType(CT_TYPE_CAST); - in_type_cast = true; - } - - if (pc->Is(CT_DECLTYPE)) - { - flag_cpp_decltype(pc); - } - - // Change angle open/close to CT_COMPARE, if not a template thingy - if ( pc->Is(CT_ANGLE_OPEN) - && pc->GetParentType() != CT_TYPE_CAST) - { - /* - * pretty much all languages except C use <> for something other than - * comparisons. "#include<xxx>" is handled elsewhere. - */ - if (language_is_set(LANG_OC | LANG_CPP | LANG_CS | LANG_JAVA | LANG_VALA)) - { - // bug #663 - check_template(pc, in_type_cast); - } - else - { - // convert CT_ANGLE_OPEN to CT_COMPARE - pc->SetType(CT_COMPARE); - } - } - - if ( pc->Is(CT_ANGLE_CLOSE) - && pc->GetParentType() != CT_TEMPLATE) - { - if (in_type_cast) - { - in_type_cast = false; - pc->SetParentType(CT_TYPE_CAST); - } - else - { - next = handle_double_angle_close(pc); - } - } - - if (language_is_set(LANG_D)) - { - // Check for the D string concat symbol '~' - if ( pc->Is(CT_INV) - && ( prev->Is(CT_STRING) - || prev->Is(CT_WORD) - || next->Is(CT_STRING))) - { - pc->SetType(CT_CONCAT); - } - - // Check for the D template symbol '!' (word + '!' + word or '(') - if ( pc->Is(CT_NOT) - && prev->Is(CT_WORD) - && ( next->Is(CT_PAREN_OPEN) - || next->Is(CT_WORD) - || next->Is(CT_TYPE) - || next->Is(CT_NUMBER) - || next->Is(CT_NUMBER_FP) - || next->Is(CT_STRING) - || next->Is(CT_STRING_MULTI))) - { - pc->SetType(CT_D_TEMPLATE); - } - - // handle "version(unittest) { }" vs "unittest { }" - if ( pc->Is(CT_UNITTEST) - && prev->Is(CT_PAREN_OPEN)) - { - pc->SetType(CT_WORD); - } - - // handle 'static if' and merge the tokens - if ( pc->Is(CT_IF) - && prev->IsString("static")) - { - // delete PREV and merge with IF - pc->Str().insert(0, ' '); - pc->Str().insert(0, prev->GetStr()); - pc->SetOrigCol(prev->GetOrigCol()); - pc->SetOrigLine(prev->GetOrigLine()); - Chunk *to_be_deleted = prev; - prev = prev->GetPrevNcNnl(); - - if (prev->IsNotNullChunk()) - { - Chunk::Delete(to_be_deleted); - } - } - } - - if (language_is_set(LANG_CPP)) - { - // Change Word before '::' into a type - if ( pc->Is(CT_WORD) - && next->Is(CT_DC_MEMBER)) - { - prev = pc->GetPrev(); - - if (prev->IsNullChunk()) // Issue #3010 - { - pc->SetType(CT_TYPE); - } - else - { - if (prev->Is(CT_COLON)) - { - // nothing to do - } - else - { - pc->SetType(CT_TYPE); - } - } - } - - // Set parent type for 'if constexpr' - if ( prev->Is(CT_IF) - && pc->Is(CT_QUALIFIER) - && pc->IsString("constexpr")) - { - pc->SetType(CT_CONSTEXPR); - } - } - - // Change get/set to CT_WORD if not followed by a brace open - if ( pc->Is(CT_GETSET) - && next->IsNot(CT_BRACE_OPEN)) - { - if ( next->Is(CT_SEMICOLON) - && ( prev->Is(CT_BRACE_CLOSE) - || prev->Is(CT_BRACE_OPEN) - || prev->Is(CT_SEMICOLON))) - { - pc->SetType(CT_GETSET_EMPTY); - next->SetParentType(CT_GETSET); - } - else - { - pc->SetType(CT_WORD); - } - } - - /* - * Interface is only a keyword in MS land if followed by 'class' or 'struct' - * likewise, 'class' may be a member name in Java. - */ - if ( pc->Is(CT_CLASS) - && !CharTable::IsKw1(next->GetStr()[0])) - { - if ( next->IsNot(CT_DC_MEMBER) - && next->IsNot(CT_ATTRIBUTE)) // Issue #2570 - { - pc->SetType(CT_WORD); - } - else if ( prev->Is(CT_DC_MEMBER) - || prev->Is(CT_TYPE)) - { - pc->SetType(CT_TYPE); - } - else if (next->Is(CT_DC_MEMBER)) - { - Chunk *next2 = next->GetNextNcNnlNet(); - - if ( next2->Is(CT_INV) // CT_INV hasn't turned into CT_DESTRUCTOR just yet - || ( next2->Is(CT_CLASS) // constructor isn't turned into CT_FUNC* just yet - && !strcmp(pc->Text(), next2->Text()))) - { - pc->SetType(CT_TYPE); - } - } - } - - /* - * Change item after operator (>=, ==, etc) to a CT_OPERATOR_VAL - * Usually the next item is part of the operator. - * In a few cases the next few tokens are part of it: - * operator + - common case - * operator >> - need to combine '>' and '>' - * operator () - * operator [] - already converted to TSQUARE - * operator new [] - * operator delete [] - * operator const char * - * operator const B& - * operator std::allocator<U> - * - * In all cases except the last, this will put the entire operator value - * in one chunk. - */ - if (pc->Is(CT_OPERATOR)) - { - Chunk *tmp2 = next->GetNext(); - - // Handle special case of () operator -- [] already handled - if (next->Is(CT_PAREN_OPEN)) - { - Chunk *tmp = next->GetNext(); - - if (tmp->Is(CT_PAREN_CLOSE)) - { - next->Str() = "()"; - next->SetType(CT_OPERATOR_VAL); - Chunk::Delete(tmp); - next->SetOrigColEnd(next->GetOrigColEnd() + 1); - } - } - else if ( next->Is(CT_ANGLE_CLOSE) - && tmp2->Is(CT_ANGLE_CLOSE) - && tmp2->GetOrigCol() == next->GetOrigColEnd()) - { - next->Str().append('>'); - next->SetOrigColEnd(next->GetOrigColEnd() + 1); - next->SetType(CT_OPERATOR_VAL); - Chunk::Delete(tmp2); - } - else if (next->TestFlags(PCF_PUNCTUATOR)) - { - next->SetType(CT_OPERATOR_VAL); - } - else - { - next->SetType(CT_TYPE); - - /* - * Replace next with a collection of all tokens that are part of - * the type. - */ - tmp2 = next; - Chunk *tmp; - - while ((tmp = tmp2->GetNext())->IsNotNullChunk()) - { - if ( tmp->IsNot(CT_WORD) - && tmp->IsNot(CT_TYPE) - && tmp->IsNot(CT_QUALIFIER) - && tmp->IsNot(CT_STAR) - && tmp->IsNot(CT_CARET) - && tmp->IsNot(CT_AMP) - && tmp->IsNot(CT_TSQUARE)) - { - break; - } - // Change tmp into a type so that space_needed() works right - make_type(tmp); - size_t num_sp = space_needed(tmp2, tmp); - - while (num_sp-- > 0) - { - next->Str().append(" "); - } - next->Str().append(tmp->GetStr()); - tmp2 = tmp; - } - - while ((tmp2 = next->GetNext()) != tmp) - { - Chunk::Delete(tmp2); - } - next->SetType(CT_OPERATOR_VAL); - - next->SetOrigColEnd(next->GetOrigCol() + next->Len()); - } - next->SetParentType(CT_OPERATOR); - - LOG_FMT(LOPERATOR, "%s(%d): %zu:%zu operator '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), next->Text()); - } - - // Change private, public, protected into either a qualifier or label - if (pc->Is(CT_ACCESS)) - { - // Handle Qt slots - maybe should just check for a CT_WORD? - if ( next->IsString("slots") - || next->IsString("Q_SLOTS")) - { - Chunk *tmp = next->GetNext(); - - if (tmp->Is(CT_COLON)) - { - next = tmp; - } - } - - if (next->Is(CT_COLON)) - { - next->SetType(CT_ACCESS_COLON); - Chunk *tmp; - - if ((tmp = next->GetNextNcNnl())->IsNotNullChunk()) - { - tmp->SetFlagBits(PCF_STMT_START | PCF_EXPR_START); - log_ruleStart("start statementi/ expression", tmp); - } - } - else - { - pc->SetType(( pc->IsString("signals") - || pc->IsString("Q_SIGNALS")) - ? CT_WORD : CT_QUALIFIER); - } - } - - // Look for <newline> 'EXEC' 'SQL' - if ( ( pc->IsString("EXEC", false) - && next->IsString("SQL", false)) - || ( (*pc->GetStr().c_str() == '$') - && pc->IsNot(CT_SQL_WORD) - /* but avoid breaking tokenization for C# 6 interpolated strings. */ - && ( !language_is_set(LANG_CS) - || ( pc->Is(CT_STRING) - && (!pc->GetStr().startswith("$\"")) - && (!pc->GetStr().startswith("$@\"")))))) - { - Chunk *tmp = pc->GetPrev(); - - if (tmp->IsNewline()) - { - if (*pc->GetStr().c_str() == '$') - { - pc->SetType(CT_SQL_EXEC); - - if (pc->Len() > 1) - { - // SPLIT OFF '$' - Chunk nc; - - nc = *pc; - pc->Str().resize(1); - pc->SetOrigColEnd(pc->GetOrigCol() + 1); - - nc.SetType(CT_SQL_WORD); - nc.Str().pop_front(); - nc.SetOrigCol(nc.GetOrigCol() + 1); - nc.SetColumn(nc.GetColumn() + 1); - nc.CopyAndAddAfter(pc); - - next = pc->GetNext(); - } - } - tmp = next->GetNext(); - - if (tmp->IsString("BEGIN", false)) - { - pc->SetType(CT_SQL_BEGIN); - } - else if (tmp->IsString("END", false)) - { - pc->SetType(CT_SQL_END); - } - else - { - pc->SetType(CT_SQL_EXEC); - } - - // Change words into CT_SQL_WORD until CT_SEMICOLON - while (tmp->IsNotNullChunk()) - { - if (tmp->Is(CT_SEMICOLON)) - { - break; - } - - if ( (tmp->Len() > 0) - && ( unc_isalpha(*tmp->GetStr().c_str()) - || (*tmp->GetStr().c_str() == '$'))) - { - tmp->SetType(CT_SQL_WORD); - } - tmp = tmp->GetNextNcNnl(); - } - } - } - - // handle MS abomination 'for each' - if ( pc->Is(CT_FOR) - && next->IsString("each") - && (next == pc->GetNext())) - { - // merge the two with a space between - pc->Str().append(' '); - pc->Str() += next->GetStr(); - pc->SetOrigColEnd(next->GetOrigColEnd()); - Chunk::Delete(next); - next = pc->GetNextNcNnl(); - - // label the 'in' - if (next->Is(CT_PAREN_OPEN)) - { - Chunk *tmp = next->GetNextNcNnl(); - - while ( tmp->IsNotNullChunk() - && tmp->IsNot(CT_PAREN_CLOSE)) - { - if (tmp->IsString("in")) - { - tmp->SetType(CT_IN); - break; - } - tmp = tmp->GetNextNcNnl(); - } - } - } - - /* - * ObjectiveC allows keywords to be used as identifiers in some situations - * This is a dirty hack to allow some of the more common situations. - */ - if (language_is_set(LANG_OC)) - { - if ( ( pc->Is(CT_IF) - || pc->Is(CT_FOR) - || pc->Is(CT_WHILE)) - && !next->Is(CT_PAREN_OPEN)) - { - pc->SetType(CT_WORD); - } - - if ( pc->Is(CT_DO) - && ( prev->Is(CT_MINUS) - || next->Is(CT_SQUARE_CLOSE))) - { - pc->SetType(CT_WORD); - } - - // Fix self keyword back to word when mixing c++/objective-c - if ( pc->Is(CT_THIS) - && !strcmp(pc->Text(), "self") - && ( next->Is(CT_COMMA) - || next->Is(CT_PAREN_CLOSE))) - { - pc->SetType(CT_WORD); - } - - // Fix self keyword back to word when mixing c++/objective-c - if ( pc->Is(CT_THIS) - && !strcmp(pc->Text(), "self") - && ( next->Is(CT_COMMA) - || next->Is(CT_PAREN_CLOSE))) - { - pc->SetType(CT_WORD); - } - } - - // Vala allows keywords to be used as identifiers - if (language_is_set(LANG_VALA)) - { - if ( find_keyword_type(pc->Text(), pc->Len()) != CT_WORD - && ( prev->Is(CT_DOT) - || next->Is(CT_DOT) - || prev->Is(CT_MEMBER) - || next->Is(CT_MEMBER) - || prev->Is(CT_TYPE))) - { - pc->SetType(CT_WORD); - } - } - - // Another hack to clean up more keyword abuse - if ( pc->Is(CT_CLASS) - && ( prev->Is(CT_DOT) - || next->Is(CT_DOT) - || prev->Is(CT_MEMBER) // Issue #3031 - || next->Is(CT_MEMBER))) - { - pc->SetType(CT_WORD); - } - - // Detect Objective C class name - if ( pc->Is(CT_OC_IMPL) - || pc->Is(CT_OC_INTF) - || pc->Is(CT_OC_PROTOCOL)) - { - if (next->IsNot(CT_PAREN_OPEN)) - { - next->SetType(CT_OC_CLASS); - } - next->SetParentType(pc->GetType()); - - Chunk *tmp = next->GetNextNcNnl(); - - if (tmp->IsNotNullChunk()) - { - tmp->SetFlagBits(PCF_STMT_START | PCF_EXPR_START); - log_ruleStart("start statementi/ expression", tmp); - } - tmp = pc->GetNextType(CT_OC_END, pc->GetLevel()); - - if (tmp->IsNotNullChunk()) - { - tmp->SetParentType(pc->GetType()); - } - } - - if (pc->Is(CT_OC_INTF)) - { - Chunk *tmp = pc->GetNextNcNnl(E_Scope::PREPROC); - - while ( tmp->IsNotNullChunk() - && tmp->IsNot(CT_OC_END)) - { - if (get_token_pattern_class(tmp->GetType()) != pattern_class_e::NONE) - { - LOG_FMT(LOBJCWORD, "%s(%d): @interface %zu:%zu change '%s' (%s) to CT_WORD\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), tmp->Text(), - get_token_name(tmp->GetType())); - tmp->SetType(CT_WORD); - } - tmp = tmp->GetNextNcNnl(E_Scope::PREPROC); - } - } - - /* - * Detect Objective-C categories and class extensions: - * @interface ClassName (CategoryName) - * @implementation ClassName (CategoryName) - * @interface ClassName () - * @implementation ClassName () - */ - if ( ( pc->GetParentType() == CT_OC_IMPL - || pc->GetParentType() == CT_OC_INTF - || pc->Is(CT_OC_CLASS)) - && next->Is(CT_PAREN_OPEN)) - { - next->SetParentType(pc->GetParentType()); - - Chunk *tmp = next->GetNext(); - - if ( tmp->IsNotNullChunk() - && tmp->GetNext()->IsNotNullChunk()) - { - if (tmp->Is(CT_PAREN_CLOSE)) - { - //tmp->SetType(CT_OC_CLASS_EXT); - tmp->SetParentType(pc->GetParentType()); - } - else - { - tmp->SetType(CT_OC_CATEGORY); - tmp->SetParentType(pc->GetParentType()); - } - } - tmp = pc->GetNextType(CT_PAREN_CLOSE, pc->GetLevel()); - - if (tmp->IsNotNullChunk()) - { - tmp->SetParentType(pc->GetParentType()); - } - } - - /* - * Detect Objective C @property: - * @property NSString *stringProperty; - * @property(nonatomic, retain) NSMutableDictionary *shareWith; - */ - if (pc->Is(CT_OC_PROPERTY)) - { - if (next->IsNot(CT_PAREN_OPEN)) - { - next->SetFlagBits(PCF_STMT_START | PCF_EXPR_START); - log_ruleStart("start statement/ expression", next); - } - else - { - cleanup_objc_property(pc); - } - } - - /* - * Detect Objective C @selector: - * @selector(msgNameWithNoArg) - * @selector(msgNameWith1Arg:) - * @selector(msgNameWith2Args:arg2Name:) - */ - if ( pc->Is(CT_OC_SEL) - && next->Is(CT_PAREN_OPEN)) - { - next->SetParentType(pc->GetType()); - - Chunk *tmp = next->GetNext(); - - if (tmp->IsNotNullChunk()) - { - tmp->SetType(CT_OC_SEL_NAME); - tmp->SetParentType(pc->GetType()); - - while ((tmp = tmp->GetNextNcNnl())->IsNotNullChunk()) - { - if (tmp->Is(CT_PAREN_CLOSE)) - { - tmp->SetParentType(CT_OC_SEL); - break; - } - tmp->SetType(CT_OC_SEL_NAME); - tmp->SetParentType(pc->GetType()); - } - } - } - - // Handle special preprocessor junk - if (pc->Is(CT_PREPROC)) - { - pc->SetParentType(next->GetType()); - } - - // Detect "pragma region" and "pragma endregion" - if ( pc->Is(CT_PP_PRAGMA) - && next->Is(CT_PREPROC_BODY)) - { - if ( (strncmp(next->GetStr().c_str(), "region", 6) == 0) - || (strncmp(next->GetStr().c_str(), "endregion", 9) == 0)) - // TODO: probably better use strncmp - { - pc->SetType((*next->GetStr().c_str() == 'r') ? CT_PP_REGION : CT_PP_ENDREGION); - - prev->SetParentType(pc->GetType()); - } - } - - // Change 'default(' into a sizeof-like statement - if ( language_is_set(LANG_CS) - && pc->Is(CT_DEFAULT) - && next->Is(CT_PAREN_OPEN)) - { - pc->SetType(CT_SIZEOF); - } - - if ( pc->Is(CT_UNSAFE) - && next->IsNot(CT_BRACE_OPEN)) - { - pc->SetType(CT_QUALIFIER); - } - - if ( ( pc->Is(CT_USING) - || ( pc->Is(CT_TRY) - && language_is_set(LANG_JAVA))) - && next->Is(CT_PAREN_OPEN)) - { - pc->SetType(CT_USING_STMT); - } - - // Add minimal support for C++0x rvalue references - if ( pc->Is(CT_BOOL) - && language_is_set(LANG_CPP) - && pc->IsString("&&")) - { - if (prev->Is(CT_TYPE)) - { - // Issue # 1002 - if (!pc->TestFlags(PCF_IN_TEMPLATE)) - { - pc->SetType(CT_BYREF); - } - } - } - - /* - * HACK: treat try followed by a colon as a qualifier to handle this: - * A::A(int) try : B() { } catch (...) { } - */ - if ( pc->Is(CT_TRY) - && pc->IsString("try") - && next->Is(CT_COLON)) - { - pc->SetType(CT_QUALIFIER); - } - - /* - * If Java's 'synchronized' is in a method declaration, it should be - * a qualifier. - */ - if ( language_is_set(LANG_JAVA) - && pc->Is(CT_SYNCHRONIZED) - && next->IsNot(CT_PAREN_OPEN)) - { - pc->SetType(CT_QUALIFIER); - } - - // change CT_DC_MEMBER + CT_FOR into CT_DC_MEMBER + CT_FUNC_CALL - if ( pc->Is(CT_FOR) - && pc->GetPrev()->Is(CT_DC_MEMBER)) - { - pc->SetType(CT_FUNC_CALL); - } - // TODO: determine other stuff here - - prev = pc; - pc = next; - next = pc->GetNextNcNnl(); - } -} // tokenize_cleanup - - -static void cleanup_objc_property(Chunk *start) -{ - assert(start->Is(CT_OC_PROPERTY)); - - Chunk *open_paren = start->GetNextType(CT_PAREN_OPEN, start->GetLevel()); - - if (open_paren->IsNullChunk()) - { - LOG_FMT(LTEMPL, "%s(%d): Property is not followed by opening paren\n", __func__, __LINE__); - return; - } - open_paren->SetParentType(start->GetType()); - - Chunk *tmp = start->GetNextType(CT_PAREN_CLOSE, start->GetLevel()); - - if (tmp->IsNotNullChunk()) - { - tmp->SetParentType(start->GetType()); - tmp = tmp->GetNextNcNnl(); - - if (tmp->IsNotNullChunk()) - { - tmp->SetFlagBits(PCF_STMT_START | PCF_EXPR_START); - log_ruleStart("start statement/ expression", tmp); - - tmp = tmp->GetNextType(CT_SEMICOLON, start->GetLevel()); - - if (tmp->IsNotNullChunk()) - { - tmp->SetParentType(start->GetType()); - } - } - } - mark_selectors_in_property_with_open_paren(open_paren); - mark_attributes_in_property_with_open_paren(open_paren); -} - - -static void mark_selectors_in_property_with_open_paren(Chunk *open_paren) -{ - assert(open_paren->Is(CT_PAREN_OPEN)); - - Chunk *tmp = open_paren; - - while (tmp->IsNot(CT_PAREN_CLOSE)) - { - if ( tmp->Is(CT_WORD) - && ( tmp->IsString("setter") - || tmp->IsString("getter"))) - { - tmp = tmp->GetNext(); - - while ( tmp->IsNotNullChunk() - && tmp->IsNot(CT_COMMA) - && tmp->IsNot(CT_PAREN_CLOSE)) - { - if ( tmp->Is(CT_WORD) - || tmp->IsString(":")) - { - tmp->SetType(CT_OC_SEL_NAME); - } - tmp = tmp->GetNext(); - } - } - else - { - tmp = tmp->GetNext(); - } - } -} - - -static void mark_attributes_in_property_with_open_paren(Chunk *open_paren) -{ - assert(open_paren->Is(CT_PAREN_OPEN)); - - Chunk *tmp = open_paren; - - while (tmp->IsNot(CT_PAREN_CLOSE)) - { - Chunk *next = tmp->GetNext(); - - if ( ( tmp->Is(CT_COMMA) - || tmp->Is(CT_PAREN_OPEN)) - && ( next->Is(CT_WORD) - || next->Is(CT_TYPE))) - { - next->SetType(CT_OC_PROPERTY_ATTR); - } - tmp = next; - } -} |