@@ -46,6 +46,14 @@ void NameStyleRuleMatcher::Diagnosis(DiagnosisContext& ctx, std::shared_ptr<Chec
4646 }
4747 break ;
4848 }
49+ case NameStyleType::UpperSnakeCase:
50+ {
51+ if (UpperSnakeCase (checkElement))
52+ {
53+ return ;
54+ }
55+ break ;
56+ }
4957 case NameStyleType::CamelCase:
5058 {
5159 if (CamelCase (checkElement))
@@ -64,7 +72,7 @@ void NameStyleRuleMatcher::Diagnosis(DiagnosisContext& ctx, std::shared_ptr<Chec
6472 }
6573 case NameStyleType::Same:
6674 {
67- if (Same (checkElement, rule.Param ))
75+ if (Same (ctx, checkElement, rule.Param ))
6876 {
6977 return ;
7078 }
@@ -100,10 +108,14 @@ void NameStyleRuleMatcher::Diagnosis(DiagnosisContext& ctx, std::shared_ptr<Chec
100108 }
101109 case NameStyleType::Same:
102110 {
103- // if (Same(checkElement, rule.Param))
104- // {
105- // return;
106- // }
111+ if (rule.Param .size () == 1 )
112+ {
113+ ruleMessage.append (format (" same({})" , rule.Param [0 ]));
114+ }
115+ else if (rule.Param .size () == 2 )
116+ {
117+ ruleMessage.append (format (" same({},{})" , rule.Param [0 ], rule.Param [1 ]));
118+ }
107119 break ;
108120 }
109121 default :
@@ -151,6 +163,7 @@ void NameStyleRuleMatcher::ParseRule(std::string_view rule)
151163 }
152164
153165 _rulers.emplace_back (type, param);
166+ tokenParser->Next ();
154167 }
155168 else if (lookAhead.TokenType == TK_EOS || lookAhead.TokenType == ' |' )
156169 {
@@ -167,6 +180,10 @@ void NameStyleRuleMatcher::ParseRule(std::string_view rule)
167180 {
168181 _rulers.emplace_back (NameStyleType::PascalCase);
169182 }
183+ else if (currentText == " upper_snake_case" )
184+ {
185+ _rulers.emplace_back (NameStyleType::UpperSnakeCase);
186+ }
170187 }
171188
172189 if (lookAhead.TokenType == ' |' )
@@ -224,7 +241,7 @@ bool NameStyleRuleMatcher::UpperSnakeCase(std::shared_ptr<CheckElement> checkEle
224241 {
225242 return false ;
226243 }
227-
244+
228245 else if (!::isupper (ch))
229246 {
230247 if (ch == ' _' )
@@ -307,7 +324,7 @@ bool NameStyleRuleMatcher::PascalCase(std::shared_ptr<CheckElement> checkElement
307324 }
308325 }
309326 }
310- // 我又没办法分词简单处理下
327+ // 我又没办法分词简单处理下
311328 else if (!::isalnum (ch))
312329 {
313330 return false ;
@@ -316,7 +333,226 @@ bool NameStyleRuleMatcher::PascalCase(std::shared_ptr<CheckElement> checkElement
316333 return true ;
317334}
318335
319- bool NameStyleRuleMatcher::Same (std::shared_ptr<CheckElement> checkElement, std::vector<std::string>& param)
336+ bool NameStyleRuleMatcher::Same (DiagnosisContext& ctx, std::shared_ptr<CheckElement> checkElement,
337+ std::vector<std::string>& param)
338+ {
339+ if (param.empty ())
340+ {
341+ return true ;
342+ }
343+
344+ auto & firstParam = param.front ();
345+
346+ if (firstParam == " first_param" )
347+ {
348+ // 可空判断太长了
349+ if (!checkElement->ExtraInfoNode )
350+ {
351+ return true ;
352+ }
353+ if (checkElement->ExtraInfoNode ->GetType () != LuaAstNodeType::CallArgList)
354+ {
355+ return true ;
356+ }
357+
358+ auto firstParamNode = checkElement->ExtraInfoNode ->FindFirstOf (LuaAstNodeType::LiteralExpression);
359+
360+ if (!firstParamNode)
361+ {
362+ auto expressionList = checkElement->ExtraInfoNode ->FindFirstOf (LuaAstNodeType::ExpressionList);
363+ if (!expressionList)
364+ {
365+ return true ;
366+ }
367+ auto expressionNode = expressionList->FindFirstOf (LuaAstNodeType::Expression);
368+ if (!expressionNode)
369+ {
370+ return true ;
371+ }
372+ firstParamNode = expressionNode->FindFirstOf (LuaAstNodeType::LiteralExpression);
373+ if (!firstParamNode)
374+ {
375+ return true ;
376+ }
377+ }
378+
379+ std::string_view firstText = firstParamNode->GetText ();
380+
381+ if (firstText.size () <= 2 )
382+ {
383+ return true ;
384+ }
385+
386+ firstText = firstText.substr (1 , firstText.size () - 2 );
387+ if (param.size () == 2 )
388+ {
389+ auto & secondParam = param[1 ];
390+
391+ if (secondParam == " snake_case" )
392+ {
393+ return SameSnake (firstText, checkElement);
394+ }
395+ else if (secondParam == " camel_case" )
396+ {
397+ return SameCamel (firstText, checkElement);
398+ }
399+ else if (secondParam == " pascal_case" )
400+ {
401+ return SamePascal (firstText, checkElement);
402+ }
403+ }
404+ else
405+ {
406+ return SameSimple (firstText, checkElement);
407+ }
408+ }
409+ else if (firstParam == " filename" )
410+ {
411+ auto filename = ctx.GetParser ()->GetFilename ();
412+
413+ if (param.size () == 2 )
414+ {
415+ auto & secondParam = param[1 ];
416+
417+ if (secondParam == " snake_case" )
418+ {
419+ return SameSnake (filename, checkElement);
420+ }
421+ else if (secondParam == " camel_case" )
422+ {
423+ return SameCamel (filename, checkElement);
424+ }
425+ else if (secondParam == " pascal_case" )
426+ {
427+ return SamePascal (filename, checkElement);
428+ }
429+ }
430+ else
431+ {
432+ return SameSimple (filename, checkElement);
433+ }
434+ }
435+ else if (firstParam.size () > 2 && (firstParam.starts_with (" \' " ) || firstParam.starts_with (" \" " )))
436+ {
437+ auto name = firstParam.substr (1 , firstParam.size () - 2 );
438+ return checkElement->Node ->GetText () == name;
439+ }
440+
441+ return true ;
442+ }
443+
444+ bool NameStyleRuleMatcher::SameSimple (std::string_view text, std::shared_ptr<CheckElement> checkElement)
445+ {
446+ auto checkText = checkElement->Node ->GetText ();
447+ return checkText == text;
448+ }
449+
450+ bool NameStyleRuleMatcher::SameSnake (std::string_view text, std::shared_ptr<CheckElement> checkElement)
451+ {
452+ if (!SnakeCase (checkElement))
453+ {
454+ return false ;
455+ }
456+
457+ auto checkText = checkElement->Node ->GetText ();
458+ auto textParts = SplitPart (text);
459+ auto checkParts = SplitPart (checkText);
460+
461+ if (checkParts.size () > textParts.size ())
462+ {
463+ return false ;
464+ }
465+
466+ for (std::size_t i = 1 ; i <= checkParts.size (); i++)
467+ {
468+ if (checkParts[checkParts.size () - i] != textParts[textParts.size () - i])
469+ {
470+ return false ;
471+ }
472+ }
473+
474+ return true ;
475+ }
476+
477+ bool NameStyleRuleMatcher::SameCamel (std::string_view text, std::shared_ptr<CheckElement> checkElement)
320478{
479+ if (!CamelCase (checkElement))
480+ {
481+ return false ;
482+ }
483+
484+ auto checkText = checkElement->Node ->GetText ();
485+ auto textParts = SplitPart (text);
486+
487+
488+ for (int i = textParts.size () - 1 ; i >= 0 ; i--)
489+ {
490+ if (checkText.ends_with (textParts[i]))
491+ {
492+ if (checkText.size () == textParts[i].size ())
493+ {
494+ return true ;
495+ }
496+ checkText = checkText.substr (0 , checkText.size () - textParts[i].size ());
497+ }
498+ else
499+ {
500+ return false ;
501+ }
502+ }
503+
504+ return true ;
505+ }
506+
507+ bool NameStyleRuleMatcher::SamePascal (std::string_view text, std::shared_ptr<CheckElement> checkElement)
508+ {
509+ if (!PascalCase (checkElement))
510+ {
511+ return false ;
512+ }
513+
514+ auto checkText = checkElement->Node ->GetText ();
515+ auto textParts = SplitPart (text);
516+
517+
518+ for (int i = textParts.size () - 1 ; i >= 0 ; i--)
519+ {
520+ if (checkText.ends_with (textParts[i]))
521+ {
522+ if (checkText.size () == textParts[i].size ())
523+ {
524+ return true ;
525+ }
526+ checkText = checkText.substr (0 , checkText.size () - textParts[i].size ());
527+ }
528+ else
529+ {
530+ return false ;
531+ }
532+ }
533+
321534 return true ;
322535}
536+
537+ std::vector<std::string_view> NameStyleRuleMatcher::SplitPart (std::string_view source)
538+ {
539+ std::vector<std::string_view> result;
540+ std::size_t lastIndex = 0 ;
541+ for (std::size_t index = 0 ; index < source.size (); index++)
542+ {
543+ char ch = source[index];
544+
545+ if ((ch == ' .' || ch == ' _' || ch == ' -' || ch == ' /' || ch == ' \\ ' ) && index != 0 )
546+ {
547+ result.push_back (source.substr (lastIndex, index - lastIndex));
548+ lastIndex = index + 1 ;
549+ }
550+ }
551+
552+ if (lastIndex < source.size ())
553+ {
554+ result.push_back (source.substr (lastIndex, source.size () - lastIndex));
555+ }
556+
557+ return result;
558+ }
0 commit comments