You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.5 KiB
152 lines
4.5 KiB
/**
|
|
* @file semicolons.cpp
|
|
* Removes extra semicolons
|
|
*
|
|
* @author Ben Gardner
|
|
* @license GPL v2+
|
|
*/
|
|
|
|
#include "semicolons.h"
|
|
|
|
#include "prototypes.h"
|
|
|
|
|
|
static void remove_semicolon(Chunk *pc);
|
|
|
|
|
|
/**
|
|
* We are on a semicolon that is after an unidentified brace close.
|
|
* Check for what is before the brace open.
|
|
* Do not remove if it is a square close, word, type, or paren close.
|
|
*/
|
|
static void check_unknown_brace_close(Chunk *semi, Chunk *brace_close);
|
|
|
|
|
|
static void remove_semicolon(Chunk *pc)
|
|
{
|
|
LOG_FUNC_ENTRY();
|
|
LOG_FMT(LDELSEMI, "%s(%d): Removed semicolon: orig line is %zu, orig col is %zu",
|
|
__func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol());
|
|
log_func_stack_inline(LDELSEMI);
|
|
// TODO: do we want to shift stuff back a column?
|
|
Chunk::Delete(pc);
|
|
}
|
|
|
|
|
|
void remove_extra_semicolons()
|
|
{
|
|
LOG_FUNC_ENTRY();
|
|
|
|
Chunk *pc = Chunk::GetHead();
|
|
|
|
while (pc->IsNotNullChunk())
|
|
{
|
|
Chunk *next = pc->GetNextNcNnl();
|
|
Chunk *prev;
|
|
|
|
if ( pc->Is(CT_SEMICOLON)
|
|
&& !pc->TestFlags(PCF_IN_PREPROC)
|
|
&& (prev = pc->GetPrevNcNnl())->IsNotNullChunk())
|
|
{
|
|
LOG_FMT(LSCANSEMI, "%s(%d): Semi orig line is %zu, orig col is %zu, parent is %s, prev = '%s' [%s/%s]\n",
|
|
__func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), get_token_name(pc->GetParentType()),
|
|
prev->Text(),
|
|
get_token_name(prev->GetType()), get_token_name(prev->GetParentType()));
|
|
|
|
if (pc->GetParentType() == CT_TYPEDEF)
|
|
{
|
|
// keep it
|
|
}
|
|
else if ( prev->Is(CT_BRACE_CLOSE)
|
|
&& ( prev->GetParentType() == CT_ELSE
|
|
|| prev->GetParentType() == CT_ELSEIF
|
|
|| prev->GetParentType() == CT_FOR
|
|
|| prev->GetParentType() == CT_FUNC_CLASS_DEF
|
|
|| prev->GetParentType() == CT_FUNC_DEF
|
|
|| prev->GetParentType() == CT_IF
|
|
|| prev->GetParentType() == CT_NAMESPACE
|
|
|| prev->GetParentType() == CT_OC_MSG_DECL
|
|
|| prev->GetParentType() == CT_SWITCH
|
|
|| prev->GetParentType() == CT_USING_STMT
|
|
|| prev->GetParentType() == CT_WHILE))
|
|
{
|
|
// looking for code block vs. initialisation
|
|
bool code_block_found = true;
|
|
Chunk *closing_brace = pc->GetPrevNcNnl(); // Issue #3506
|
|
|
|
if (closing_brace->IsNotNullChunk())
|
|
{
|
|
Chunk *opening_brace = closing_brace->GetOpeningParen();
|
|
|
|
if (opening_brace->IsNotNullChunk())
|
|
{
|
|
Chunk *equal_sign = opening_brace->GetPrevNcNnl();
|
|
|
|
if ( equal_sign->IsNotNullChunk()
|
|
&& equal_sign->Is(CT_ASSIGN))
|
|
{
|
|
// initialisation found
|
|
code_block_found = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (code_block_found)
|
|
{
|
|
// code block found
|
|
remove_semicolon(pc);
|
|
}
|
|
}
|
|
else if ( prev->Is(CT_BRACE_CLOSE)
|
|
&& prev->GetParentType() == CT_NONE)
|
|
{
|
|
check_unknown_brace_close(pc, prev);
|
|
}
|
|
else if ( prev->Is(CT_SEMICOLON)
|
|
&& prev->GetParentType() != CT_FOR)
|
|
{
|
|
remove_semicolon(pc);
|
|
}
|
|
else if ( language_is_set(LANG_D)
|
|
&& ( prev->GetParentType() == CT_ENUM
|
|
|| prev->GetParentType() == CT_STRUCT
|
|
|| prev->GetParentType() == CT_UNION))
|
|
{
|
|
remove_semicolon(pc);
|
|
}
|
|
else if ( language_is_set(LANG_JAVA)
|
|
&& prev->GetParentType() == CT_SYNCHRONIZED)
|
|
{
|
|
remove_semicolon(pc);
|
|
}
|
|
else if (prev->Is(CT_BRACE_OPEN))
|
|
{
|
|
remove_semicolon(pc);
|
|
}
|
|
}
|
|
pc = next;
|
|
}
|
|
} // remove_extra_semicolons
|
|
|
|
|
|
static void check_unknown_brace_close(Chunk *semi, Chunk *brace_close)
|
|
{
|
|
LOG_FUNC_ENTRY();
|
|
Chunk *pc = brace_close->GetPrevType(CT_BRACE_OPEN, brace_close->GetLevel());
|
|
|
|
pc = pc->GetPrevNcNnl();
|
|
|
|
if ( pc->IsNotNullChunk()
|
|
&& pc->IsNot(CT_ANGLE_CLOSE)
|
|
&& pc->IsNot(CT_COND_COLON) // Issue #3920
|
|
&& pc->IsNot(CT_RETURN)
|
|
&& pc->IsNot(CT_SQUARE_CLOSE)
|
|
&& pc->IsNot(CT_TSQUARE)
|
|
&& pc->IsNot(CT_TYPE)
|
|
&& pc->IsNot(CT_WORD)
|
|
&& !pc->IsParenClose())
|
|
{
|
|
remove_semicolon(semi);
|
|
}
|
|
}
|