clang: lib/Format/IntegerLiteralSeparatorFixer.cpp Source File (original) (raw)

24

28 }

29

31

33 case 'b':

34 case 'B':

36 case 'x':

37 case 'X':

39 default:

41 }

42}

46 const FormatStyle &Style) {

47 switch (Style.Language) {

48 case FormatStyle::LK_CSharp:

49 case FormatStyle::LK_Java:

50 case FormatStyle::LK_JavaScript:

51 Separator = '_';

52 break;

53 case FormatStyle::LK_Cpp:

54 case FormatStyle::LK_ObjC:

55 if (Style.Standard >= FormatStyle::LS_Cpp14) {

56 Separator = '\'';

57 break;

58 }

59 [[fallthrough]];

60 default:

61 return {};

62 }

63

64 const auto &Option = Style.IntegerLiteralSeparator;

65 const auto Binary = Option.Binary;

66 const auto Decimal = Option.Decimal;

67 const auto Hex = Option.Hex;

68 const bool SkipBinary = Binary == 0;

69 const bool SkipDecimal = Decimal == 0;

70 const bool SkipHex = Hex == 0;

71

72 if (SkipBinary && SkipDecimal && SkipHex)

73 return {};

74

75 auto CalcMinAndMax = [](int DigitsPerGroup, int MinDigitsInsert,

76 int MaxDigitsRemove) {

77 MinDigitsInsert = std::max(MinDigitsInsert, DigitsPerGroup + 1);

78 if (MinDigitsInsert < 1)

79 MaxDigitsRemove = 0;

80 else if (MaxDigitsRemove < 1 || MaxDigitsRemove >= MinDigitsInsert)

81 MaxDigitsRemove = MinDigitsInsert - 1;

82 return std::pair(MinDigitsInsert, MaxDigitsRemove);

83 };

84

85 const auto [BinaryMinDigitsInsert, BinaryMaxDigitsRemove] = CalcMinAndMax(

86 Binary, Option.BinaryMinDigitsInsert, Option.BinaryMaxDigitsRemove);

87 const auto [DecimalMinDigitsInsert, DecimalMaxDigitsRemove] = CalcMinAndMax(

88 Decimal, Option.DecimalMinDigitsInsert, Option.DecimalMaxDigitsRemove);

89 const auto [HexMinDigitsInsert, HexMaxDigitsRemove] =

90 CalcMinAndMax(Hex, Option.HexMinDigitsInsert, Option.HexMaxDigitsRemove);

91

94

97 Lexer Lex(ID, SourceMgr.getBufferOrFake(ID), SourceMgr, LangOpts);

99

102

104 auto Length = Tok.getLength();

105 if (Length < 2)

106 continue;

107 auto Location = Tok.getLocation();

108 auto Text = StringRef(SourceMgr.getCharacterData(Location), Length);

109 if (Tok.is(tok::comment)) {

113 Skip = false;

114 continue;

115 }

116 if (Skip || Tok.isNot(tok::numeric_constant) || Text[0] == '.' ||

119 continue;

120 }

124 const bool IsBase16 = B == Base::Hex;

125 if ((IsBase2 && SkipBinary) || (IsBase10 && SkipDecimal) ||

126 (IsBase16 && SkipHex) || B == Base::Other) {

127 continue;

128 }

129 if (Style.isCpp()) {

130

131 static constexpr StringRef Suffixes("_himnsuyd");

132 if (const auto Pos =

134 Pos != StringRef::npos) {

136 Length = Pos;

137 }

138 }

139 if ((IsBase10 && Text.find_last_of(".eEfFdDmM") != StringRef::npos) ||

140 (IsBase16 && Text.find_last_of(".pP") != StringRef::npos)) {

141 continue;

142 }

143 const auto Start = Text[0] == '0' ? 2 : 0;

144 auto End = Text.find_first_of("uUlLzZn", Start);

145 if (End == StringRef::npos)

146 End = Length;

147 if (Start > 0 || End < Length) {

148 Length = End - Start;

149 Text = Text.substr(Start, Length);

150 }

151 auto DigitsPerGroup = Decimal;

152 auto MinDigitsInsert = DecimalMinDigitsInsert;

153 auto MaxDigitsRemove = DecimalMaxDigitsRemove;

154 if (IsBase2) {

155 DigitsPerGroup = Binary;

156 MinDigitsInsert = BinaryMinDigitsInsert;

157 MaxDigitsRemove = BinaryMaxDigitsRemove;

158 } else if (IsBase16) {

159 DigitsPerGroup = Hex;

160 MinDigitsInsert = HexMinDigitsInsert;

161 MaxDigitsRemove = HexMaxDigitsRemove;

162 }

163 const auto SeparatorCount = Text.count(Separator);

164 const int DigitCount = Length - SeparatorCount;

165 if (DigitCount > MaxDigitsRemove && DigitCount < MinDigitsInsert)

166 continue;

167 const bool RemoveSeparator =

168 DigitsPerGroup < 0 || DigitCount <= MaxDigitsRemove;

169 if (RemoveSeparator && SeparatorCount == 0)

170 continue;

171 if (!RemoveSeparator && SeparatorCount > 0 &&

172 checkSeparator(Text, DigitsPerGroup)) {

173 continue;

174 }

175 const auto &Formatted =

176 format(Text, DigitsPerGroup, DigitCount, RemoveSeparator);

177 assert(Formatted != Text);

178 if (Start > 0)

179 Location = Location.getLocWithOffset(Start);

182 }

183

185}