summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.73.0/src/semicolons.cpp
blob: bfb6510706db237efe87d27733740f9ec153d555 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
 * @file semicolons.cpp
 * Removes extra semicolons
 *
 * @author  Ben Gardner
 * @license GPL v2+
 */

#include "semicolons.h"

#include "prototypes.h"


static void remove_semicolon(chunk_t *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_t *semi, chunk_t *brace_close);


static void remove_semicolon(chunk_t *pc)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LDELSEMI, "%s(%d): Removed semicolon: orig_line is %zu, orig_col is %zu",
           __func__, __LINE__, pc->orig_line, pc->orig_col);
   log_func_stack_inline(LDELSEMI);
   // TODO: do we want to shift stuff back a column?
   chunk_del(pc);
}


void remove_extra_semicolons(void)
{
   LOG_FUNC_ENTRY();

   chunk_t *pc = chunk_get_head();

   while (pc != nullptr)
   {
      chunk_t *next = chunk_get_next_ncnnl(pc);
      chunk_t *prev;

      if (  chunk_is_token(pc, CT_SEMICOLON)
         && !pc->flags.test(PCF_IN_PREPROC)
         && (prev = chunk_get_prev_ncnnl(pc)) != nullptr)
      {
         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->orig_line, pc->orig_col, get_token_name(get_chunk_parent_type(pc)),
                 prev->text(),
                 get_token_name(prev->type), get_token_name(get_chunk_parent_type(prev)));

         if (get_chunk_parent_type(pc) == CT_TYPEDEF)
         {
            // keep it
         }
         else if (  chunk_is_token(prev, CT_BRACE_CLOSE)
                 && (  get_chunk_parent_type(prev) == CT_IF
                    || get_chunk_parent_type(prev) == CT_ELSEIF
                    || get_chunk_parent_type(prev) == CT_ELSE
                    || get_chunk_parent_type(prev) == CT_SWITCH
                    || get_chunk_parent_type(prev) == CT_WHILE
                    || get_chunk_parent_type(prev) == CT_USING_STMT
                    || get_chunk_parent_type(prev) == CT_FOR
                    || get_chunk_parent_type(prev) == CT_FUNC_DEF
                    || get_chunk_parent_type(prev) == CT_OC_MSG_DECL
                    || get_chunk_parent_type(prev) == CT_FUNC_CLASS_DEF
                    || get_chunk_parent_type(prev) == CT_NAMESPACE))
         {
            remove_semicolon(pc);
         }
         else if (  chunk_is_token(prev, CT_BRACE_CLOSE)
                 && get_chunk_parent_type(prev) == CT_NONE)
         {
            check_unknown_brace_close(pc, prev);
         }
         else if (  chunk_is_token(prev, CT_SEMICOLON)
                 && get_chunk_parent_type(prev) != CT_FOR)
         {
            remove_semicolon(pc);
         }
         else if (  language_is_set(LANG_D)
                 && (  get_chunk_parent_type(prev) == CT_ENUM
                    || get_chunk_parent_type(prev) == CT_UNION
                    || get_chunk_parent_type(prev) == CT_STRUCT))
         {
            remove_semicolon(pc);
         }
         else if (  language_is_set(LANG_JAVA)
                 && get_chunk_parent_type(prev) == CT_SYNCHRONIZED)
         {
            remove_semicolon(pc);
         }
         else if (chunk_is_token(prev, CT_BRACE_OPEN))
         {
            remove_semicolon(pc);
         }
      }
      pc = next;
   }
} // remove_extra_semicolons


static void check_unknown_brace_close(chunk_t *semi, chunk_t *brace_close)
{
   LOG_FUNC_ENTRY();
   chunk_t *pc = chunk_get_prev_type(brace_close, CT_BRACE_OPEN, brace_close->level);

   pc = chunk_get_prev_ncnnl(pc);

   if (  pc != nullptr
      && pc->type != CT_RETURN
      && pc->type != CT_WORD
      && pc->type != CT_TYPE
      && pc->type != CT_SQUARE_CLOSE
      && pc->type != CT_ANGLE_CLOSE
      && pc->type != CT_TSQUARE
      && !chunk_is_paren_close(pc))
   {
      remove_semicolon(semi);
   }
}