diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/combine_labels.cpp')
-rw-r--r-- | debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/combine_labels.cpp | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/combine_labels.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/combine_labels.cpp new file mode 100644 index 00000000..72e91b1a --- /dev/null +++ b/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/combine_labels.cpp @@ -0,0 +1,443 @@ +/** + * @file combine_labels.cpp + * + * @author Guy Maurel + * @license GPL v2+ + * extract from combine.h + */ + +#include "combine_labels.h" + +#include "chunk.h" +#include "cs_top_is_question.h" +#include "uncrustify.h" + + +Chunk *chunk_get_next_local(Chunk *pc, E_Scope scope = E_Scope::ALL) +{ + Chunk *tmp = pc; + + if (tmp == nullptr) + { + tmp = Chunk::NullChunkPtr; + } + + do + { + tmp = tmp->GetNext(scope); + } while ( tmp->IsNotNullChunk() + && ( tmp->IsComment() + || chunk_is_token(tmp, CT_NOEXCEPT))); + + return(tmp); +} + + +Chunk *chunk_get_prev_local(Chunk *pc, E_Scope scope = E_Scope::ALL) +{ + Chunk *tmp = pc; + + if (tmp == nullptr) + { + tmp = Chunk::NullChunkPtr; + } + + do + { + tmp = tmp->GetPrev(scope); + } while ( tmp->IsNotNullChunk() + && ( tmp->IsComment() + || chunk_is_newline(tmp) + || chunk_is_token(tmp, CT_NOEXCEPT))); + + return(tmp); +} + + +void combine_labels(void) +{ + LOG_FUNC_ENTRY(); + bool hit_case = false; + bool hit_class = false; + + cpd.unc_stage = unc_stage_e::COMBINE_LABELS; + + // stack to handle nesting inside of OC messages, which reset the scope + ChunkStack cs; + + Chunk *prev = Chunk::GetHead(); + + if (prev->IsNullChunk()) + { + return; + } + Chunk *cur = prev->GetNextNc(); + + if (cur->IsNullChunk()) + { + return; + } + Chunk *next = cur->GetNextNc(); + + // unlikely that the file will start with a label... + // prev cur next + while ( next != nullptr + && next->IsNotNullChunk()) + { + if (chunk_is_token(next, CT_NEWLINE)) + { + LOG_FMT(LFCN, "%s(%d): next->orig_line is %zu, next->orig_col is %zu, <Newline>, nl is %zu\n", + __func__, __LINE__, next->orig_line, next->orig_col, next->nl_count); + } + else if (chunk_is_token(next, CT_VBRACE_OPEN)) + { + LOG_FMT(LFCN, "%s(%d): next->orig_line is %zu, next->orig_col is %zu, VBRACE_OPEN\n", + __func__, __LINE__, next->orig_line, next->orig_col); + } + else if (chunk_is_token(next, CT_VBRACE_CLOSE)) + { + LOG_FMT(LFCN, "%s(%d): next->orig_line is %zu, next->orig_col is %zu, VBRACE_CLOSE\n", + __func__, __LINE__, next->orig_line, next->orig_col); + } + else + { + LOG_FMT(LFCN, "%s(%d): next->orig_line is %zu, next->orig_col is %zu, Text() '%s'\n", + __func__, __LINE__, next->orig_line, next->orig_col, next->Text()); + } + + if ( !next->flags.test(PCF_IN_OC_MSG) // filter OC case of [self class] msg send + && ( chunk_is_token(next, CT_CLASS) + || chunk_is_token(next, CT_OC_CLASS) + || chunk_is_token(next, CT_TEMPLATE))) + { + hit_class = true; + } + + if ( chunk_is_semicolon(next) + || chunk_is_token(next, CT_BRACE_OPEN)) + { + hit_class = false; + } + + if ( chunk_is_token(prev, CT_SQUARE_OPEN) + && get_chunk_parent_type(prev) == CT_OC_MSG) + { + cs.Push_Back(prev); + } + else if ( chunk_is_token(next, CT_SQUARE_CLOSE) + && get_chunk_parent_type(next) == CT_OC_MSG) + { + // pop until we hit '[' + while (!cs.Empty()) + { + Chunk *t2 = cs.Top()->m_pc; + cs.Pop_Back(); + + if (chunk_is_token(t2, CT_SQUARE_OPEN)) + { + break; + } + } + } + + if ( chunk_is_token(next, CT_QUESTION) + && !next->flags.test(PCF_IN_TEMPLATE)) + { + cs.Push_Back(next); + } + else if (chunk_is_token(next, CT_CASE)) + { + if (chunk_is_token(cur, CT_GOTO)) + { + // handle "goto case x;" + set_chunk_type(next, CT_QUALIFIER); + } + else + { + hit_case = true; + } + } + else if ( chunk_is_token(next, CT_COLON) + || ( chunk_is_token(next, CT_OC_COLON) + && cs_top_is_question(cs, next->level))) + { + if (chunk_is_token(cur, CT_DEFAULT)) + { + set_chunk_type(cur, CT_CASE); + hit_case = true; + } + + if (cs_top_is_question(cs, next->level)) + { + set_chunk_type(next, CT_COND_COLON); + cs.Pop_Back(); + } + else if (hit_case) + { + hit_case = false; + set_chunk_type(next, CT_CASE_COLON); + Chunk *tmp = next->GetNextNcNnlNpp(); // Issue #2150 + + if (chunk_is_token(tmp, CT_BRACE_OPEN)) + { + set_chunk_parent(tmp, CT_CASE); + tmp = tmp->GetNextType(CT_BRACE_CLOSE, tmp->level); + + if (tmp->IsNotNullChunk()) + { + set_chunk_parent(tmp, CT_CASE); + } + } + + if ( chunk_is_token(cur, CT_NUMBER) + && chunk_is_token(prev, CT_ELLIPSIS)) + { + Chunk *pre_elipsis = prev->GetPrevNcNnlNpp(); + + if (chunk_is_token(pre_elipsis, CT_NUMBER)) + { + set_chunk_type(prev, CT_CASE_ELLIPSIS); + } + } + } + else if (cur->flags.test(PCF_IN_WHERE_SPEC)) + { + /* leave colons in where-constraint clauses alone */ + } + else + { + LOG_FMT(LFCN, "%s(%d): prev->Text() is '%s', orig_line is %zu, orig_col is %zu\n", + __func__, __LINE__, prev->Text(), prev->orig_line, prev->orig_col); + LOG_FMT(LFCN, "%s(%d): cur->Text() is '%s', orig_line is %zu, orig_col is %zu\n", + __func__, __LINE__, cur->Text(), cur->orig_line, cur->orig_col); + LOG_FMT(LFCN, "%s(%d): next->Text() is '%s', orig_line is %zu, orig_col is %zu\n", + __func__, __LINE__, next->Text(), next->orig_line, next->orig_col); + Chunk *nextprev = chunk_get_prev_local(next); // Issue #2279 + + if (nextprev == nullptr) + { + return; + } + + if (language_is_set(LANG_PAWN)) + { + if ( chunk_is_token(cur, CT_WORD) + || chunk_is_token(cur, CT_BRACE_CLOSE)) + { + E_Token new_type = CT_TAG; + + Chunk *tmp = next->GetNextNc(); + + if (tmp->IsNullChunk()) + { + return; + } + + if ( chunk_is_newline(prev) + && chunk_is_newline(tmp)) + { + new_type = CT_LABEL; + set_chunk_type(next, CT_LABEL_COLON); + } + else + { + set_chunk_type(next, CT_TAG_COLON); + } + + if (chunk_is_token(cur, CT_WORD)) + { + set_chunk_type(cur, new_type); + } + } + } + else if (next->flags.test(PCF_IN_ARRAY_ASSIGN)) + { + set_chunk_type(next, CT_D_ARRAY_COLON); + } + else if (next->flags.test(PCF_IN_FOR)) + { + set_chunk_type(next, CT_FOR_COLON); + } + else if (next->flags.test(PCF_OC_BOXED)) + { + set_chunk_type(next, CT_OC_DICT_COLON); + } + else if (chunk_is_token(cur, CT_WORD)) + { + Chunk *tmp = next->GetNextNc(E_Scope::PREPROC); + + // Issue #1187 + if (tmp->IsNullChunk()) + { + return; + } + LOG_FMT(LFCN, "%s(%d): orig_line is %zu, orig_col is %zu, tmp '%s': ", + __func__, __LINE__, tmp->orig_line, tmp->orig_col, + (chunk_is_token(tmp, CT_NEWLINE)) ? "<Newline>" : tmp->Text()); + log_pcf_flags(LGUY, tmp->flags); + + if (next->flags.test(PCF_IN_FCN_CALL)) + { + // Must be a macro thingy, assume some sort of label + set_chunk_type(next, CT_LABEL_COLON); + } + else if ( tmp->IsNullChunk() + || ( chunk_is_not_token(tmp, CT_NUMBER) + && chunk_is_not_token(tmp, CT_DECLTYPE) + && chunk_is_not_token(tmp, CT_SIZEOF) + && get_chunk_parent_type(tmp) != CT_SIZEOF + && !tmp->flags.test_any(PCF_IN_STRUCT | PCF_IN_CLASS)) + || chunk_is_token(tmp, CT_NEWLINE)) + { + /* + * the CT_SIZEOF isn't great - test 31720 happens to use a sizeof expr, + * but this really should be able to handle any constant expr + */ + // Fix for #1242 + // For MIDL_INTERFACE classes class name is tokenized as Label. + // Corrected the identification of Label in c style languages. + if ( language_is_set(LANG_C | LANG_CPP | LANG_CS) + && (!language_is_set(LANG_OC))) + { + Chunk *labelPrev = prev; + + if (chunk_is_token(labelPrev, CT_NEWLINE)) + { + labelPrev = prev->GetPrevNcNnlNi(); // Issue #2279 + } + + if ( labelPrev->IsNotNullChunk() + && chunk_is_not_token(labelPrev, CT_FPAREN_CLOSE)) + { + set_chunk_type(cur, CT_LABEL); + set_chunk_type(next, CT_LABEL_COLON); + } + } + else + { + set_chunk_type(cur, CT_LABEL); + set_chunk_type(next, CT_LABEL_COLON); + } + } + else if (next->flags.test_any(PCF_IN_STRUCT | PCF_IN_CLASS | PCF_IN_TYPEDEF)) + { + set_chunk_type(next, CT_BIT_COLON); + + Chunk *nnext = next->GetNext(); + + if (nnext->IsNullChunk()) + { + return; + } + + while ((nnext = nnext->GetNext())->IsNotNullChunk()) + { + if (chunk_is_token(nnext, CT_SEMICOLON)) + { + break; + } + + if (chunk_is_token(nnext, CT_COLON)) + { + set_chunk_type(nnext, CT_BIT_COLON); + } + } + } + } + else if (chunk_is_token(nextprev, CT_FPAREN_CLOSE)) + { + LOG_FMT(LFCN, "%s(%d): nextprev->Text() is '%s', orig_line is %zu, orig_col is %zu, type is %s\n", + __func__, __LINE__, nextprev->Text(), nextprev->orig_line, nextprev->orig_col, + get_token_name(nextprev->type)); + LOG_FMT(LFCN, "%s(%d): next->Text() is '%s', orig_line is %zu, orig_col is %zu, type is %s\n", + __func__, __LINE__, next->Text(), next->orig_line, next->orig_col, + get_token_name(next->type)); + + // Issue #2172 + if (get_chunk_parent_type(next) == CT_FUNC_DEF) + { + LOG_FMT(LFCN, "%s(%d): it's a construct colon\n", __func__, __LINE__); + // it's a construct colon + set_chunk_type(next, CT_CONSTR_COLON); + } + else + { + LOG_FMT(LFCN, "%s(%d): it's a class colon\n", __func__, __LINE__); + // it's a class colon + set_chunk_type(next, CT_CLASS_COLON); + } + } + else if (next->level > next->brace_level) + { + // ignore it, as it is inside a paren + } + else if ( chunk_is_token(cur, CT_TYPE) + || chunk_is_token(cur, CT_ENUM) // Issue #2584 + || chunk_is_token(nextprev, CT_TYPE) + || chunk_is_token(nextprev, CT_ENUM)) // Issue #2584 + { + set_chunk_type(next, CT_BIT_COLON); + } + else if ( chunk_is_token(cur, CT_ENUM) + || chunk_is_token(cur, CT_ACCESS) + || chunk_is_token(cur, CT_QUALIFIER) + || get_chunk_parent_type(cur) == CT_ALIGN) + { + // ignore it - bit field, align or public/private, etc + } + else if ( chunk_is_token(cur, CT_ANGLE_CLOSE) + || hit_class) + { + // ignore it - template thingy + } + else if (get_chunk_parent_type(cur) == CT_SQL_EXEC) + { + // ignore it - SQL variable name + } + else if (get_chunk_parent_type(next) == CT_ASSERT) + { + // ignore it - Java assert thing + } + else if (get_chunk_parent_type(next) == CT_STRUCT) + { + // ignore it + } + else + { + Chunk *tmp = next->GetNextNcNnl(); + + //tmp = chunk_get_next_local(next); + if (tmp->IsNotNullChunk()) + { + LOG_FMT(LFCN, "%s(%d): tmp->Text() is '%s', orig_line is %zu, orig_col is %zu, type is %s\n", + __func__, __LINE__, tmp->Text(), tmp->orig_line, tmp->orig_col, + get_token_name(tmp->type)); + + if ( chunk_is_token(tmp, CT_BASE) + || chunk_is_token(tmp, CT_THIS)) + { + // ignore it, as it is a C# base thingy + } + else if (language_is_set(LANG_CS | LANG_D)) + { + // there should be a better solution for that + } + else + { + LOG_FMT(LWARN, "%s(%d): %s:%zu unexpected colon in col %zu n-parent=%s c-parent=%s l=%zu bl=%zu\n", + __func__, __LINE__, + cpd.filename.c_str(), next->orig_line, next->orig_col, + get_token_name(get_chunk_parent_type(next)), + get_token_name(get_chunk_parent_type(cur)), + next->level, next->brace_level); + cpd.error_count++; + } + } + } + } + } + prev = cur; + cur = next; + next = chunk_get_next_local(next); + } +} // combine_labels |