<commit_before>// @(#)root/core/utils:$Id: SelectionRules.cxx 41697 2011-11-01 21:03:41Z pcanal $
// Author: <NAME> September 2010

/*************************************************************************
 * Copyright (C) 1995-2011, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/**
\class SelectionRules
The class representing the collection of selection rules.
*/

#include "SelectionRules.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include "TString.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"

#include "cling/Interpreter/Interpreter.h"

const clang::CXXRecordDecl *R__ScopeSearch(const char *name, const clang::Type** resultType = 0) ;

void SelectionRules::AddClassSelectionRule(const ClassSelectionRule& classSel)
{
   fRulesCounter++;
   fClassSelectionRules.push_front(classSel);
   if (!classSel.HasInterpreter())
      fClassSelectionRules.begin()->SetInterpreter(fInterp);
   if (classSel.GetIndex() < 0)
      fClassSelectionRules.begin()->SetIndex(fRulesCounter);
}

void SelectionRules::AddFunctionSelectionRule(const FunctionSelectionRule& funcSel)
{
   fRulesCounter++;
   fFunctionSelectionRules.push_back(funcSel);
   if (!funcSel.HasInterpreter())
      fFunctionSelectionRules.begin()->SetInterpreter(fInterp);
   if (funcSel.GetIndex() < 0)
      fFunctionSelectionRules.begin()->SetIndex(fRulesCounter);
}

void SelectionRules::AddVariableSelectionRule(const  VariableSelectionRule& varSel)
{
   fRulesCounter++;
   fVariableSelectionRules.push_back(varSel);
   if (!varSel.HasInterpreter())
      fVariableSelectionRules.begin()->SetInterpreter(fInterp);
   if (varSel.GetIndex() < 0)
      fVariableSelectionRules.begin()->SetIndex(fRulesCounter);
}

void SelectionRules::AddEnumSelectionRule(const EnumSelectionRule& enumSel)
{
   fRulesCounter++;
   fEnumSelectionRules.push_back(enumSel);
   if (!enumSel.HasInterpreter())
      fEnumSelectionRules.begin()->SetInterpreter(fInterp);
   if (enumSel.GetIndex() < 0)
      fEnumSelectionRules.begin()->SetIndex( fRulesCounter );
}

void SelectionRules::PrintSelectionRules() const
{
   std::cout<<"Printing Selection Rules:"<<std::endl;
   if (!fClassSelectionRules.empty()) {
      int i = 0;
      for(std::list<ClassSelectionRule>::const_iterator it = fClassSelectionRules.begin();
          it != fClassSelectionRules.end(); ++it, ++i) {
         std::cout<<"\tClass sel rule "<<i<<":"<<std::endl;
         std::cout<< *it;
      }
   }
   else {
      std::cout<<"\tNo Class Selection Rules"<<std::endl;
   }

   if (!fFunctionSelectionRules.empty()) {
      //std::cout<<""<<std::endl;
      std::list<FunctionSelectionRule>::const_iterator it2;
      int i = 0;

      for (it2 = fFunctionSelectionRules.begin(); it2 != fFunctionSelectionRules.end(); ++it2, ++i) {
         std::cout<<"\tFunction sel rule "<<i<<":"<<std::endl;
         std::cout<<"\t\tSelected: ";
         switch(it2->GetSelected()){
            case BaseSelectionRule::kYes: std::cout<<"Yes"<<std::endl;
               break;
            case BaseSelectionRule::kNo: std::cout<<"No"<<std::endl;
               break;
            case BaseSelectionRule::kDontCare: std::cout<<"Don't Care"<<std::endl;
               break;
            default: std::cout<<"Unspecified"<<std::endl;
         }
         it2->PrintAttributes(std::cout,2);
      }
   }
   else {
      std::cout<<"\tNo function sel rules"<<std::endl;
   }

   if (!fVariableSelectionRules.empty()) {
      std::list<VariableSelectionRule>::const_iterator it3;
      int i = 0;

      for (it3 = fVariableSelectionRules.begin(); it3 != fVariableSelectionRules.end(); ++it3, ++i) {
         std::cout<<"\tVariable sel rule "<<i<<":"<<std::endl;
         std::cout<<"\t\tSelected: ";
         switch(it3->GetSelected()){
            case BaseSelectionRule::kYes: std::cout<<"Yes"<<std::endl;
               break;
            case BaseSelectionRule::kNo: std::cout<<"No"<<std::endl;
               break;
            case BaseSelectionRule::kDontCare: std::cout<<"Don't Care"<<std::endl;
               break;
            default: std::cout<<"Unspecified"<<std::endl;
         }
         it3->PrintAttributes(std::cout,2);
      }
   }
   else {
      std::cout<<"\tNo variable sel rules"<<std::endl;
   }

   if (!fEnumSelectionRules.empty()) {
      std::list<EnumSelectionRule>::const_iterator it4;
      int i = 0;

      for (it4 = fEnumSelectionRules.begin(); it4 != fEnumSelectionRules.end(); ++it4, ++i) {
         std::cout<<"\tEnum sel rule "<<i<<":"<<std::endl;
         std::cout<<"\t\tSelected: ";
         switch(it4->GetSelected()){
            case BaseSelectionRule::kYes: std::cout<<"Yes"<<std::endl;
               break;
            case BaseSelectionRule::kNo: std::cout<<"No"<<std::endl;
               break;
            case BaseSelectionRule::kDontCare: std::cout<<"Don't Care"<<std::endl;
               break;
            default: std::cout<<"Unspecified"<<std::endl;
         }
         it4->PrintAttributes(std::cout,2);
      }
   }
   else {
      std::cout<<"\tNo enum sel rules"<<std::endl;
   }
}

void SelectionRules::ClearSelectionRules()
{
   fClassSelectionRules.clear();
   fFunctionSelectionRules.clear();
   fVariableSelectionRules.clear();
   fEnumSelectionRules.clear();
}

template<class RULE>
static bool HasDuplicate(RULE* rule, 
                         std::unordered_map<std::string,RULE*>& storedRules,
                         const std::string& attrName){
   auto itRetCodePair = storedRules.emplace( attrName, rule );

   if (!itRetCodePair.second) {
      std::stringstream sstr; sstr << "Rule:\n";
      rule->Print(sstr);
      sstr << "Conflicting rule already stored:\n";
      storedRules[attrName]->Print(sstr);
      ROOT::TMetaUtils::Warning("SelectionRules::CheckDuplicates",
                                "Duplicated rule with name found.\n%s\n",sstr.str().c_str());
      return true;
   }
   return false;
}

template<class RULESCOLLECTIONS, class RULE = typename RULESCOLLECTIONS::value_type>
static int CheckDuplicatesImp(RULESCOLLECTIONS& rules){
   int nDuplicates = 0;
   std::unordered_map<std::string, RULE*> patterns,names;
   for (auto&& rule : rules){
      if (rule.HasAttributeName() && HasDuplicate(&rule,names,rule.GetAttributeName())) nDuplicates++;
      if (rule.HasAttributePattern() && HasDuplicate(&rule,patterns,rule.GetAttributePattern())) nDuplicates++;
   }
   return nDuplicates;
}

int SelectionRules::CheckDuplicates(){

   // Check for identical patterns and names
   FillCache();

   int nDuplicates = 0;
   nDuplicates += CheckDuplicatesImp(fClassSelectionRules);
   nDuplicates += CheckDuplicatesImp(fFunctionSelectionRules);
   nDuplicates += CheckDuplicatesImp(fVariableSelectionRules);
   nDuplicates += CheckDuplicatesImp(fEnumSelectionRules);
   if (0 != nDuplicates){
      ROOT::TMetaUtils::Error("SelectionRules::CheckDuplicates",<commit_msg>Refine the definition of "conflicting rule"<commit_after>// @(#)root/core/utils:$Id: SelectionRules.cxx 41697 2011-11-01 21:03:41Z pcanal $
// Author: <NAME>ova September 2010

/*************************************************************************
 * Copyright (C) 1995-2011, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/**
\class SelectionRules
The class representing the collection of selection rules.
*/

#include "SelectionRules.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include "TString.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"

#include "cling/Interpreter/Interpreter.h"

const clang::CXXRecordDecl *R__ScopeSearch(const char *name, const clang::Type** resultType = 0) ;

void SelectionRules::AddClassSelectionRule(const ClassSelectionRule& classSel)
{
   fRulesCounter++;
   fClassSelectionRules.push_front(classSel);
   if (!classSel.HasInterpreter())
      fClassSelectionRules.begin()->SetInterpreter(fInterp);
   if (classSel.GetIndex() < 0)
      fClassSelectionRules.begin()->SetIndex(fRulesCounter);
}

void SelectionRules::AddFunctionSelectionRule(const FunctionSelectionRule& funcSel)
{
   fRulesCounter++;
   fFunctionSelectionRules.push_back(funcSel);
   if (!funcSel.HasInterpreter())
      fFunctionSelectionRules.begin()->SetInterpreter(fInterp);
   if (funcSel.GetIndex() < 0)
      fFunctionSelectionRules.begin()->SetIndex(fRulesCounter);
}

void SelectionRules::AddVariableSelectionRule(const  VariableSelectionRule& varSel)
{
   fRulesCounter++;
   fVariableSelectionRules.push_back(varSel);
   if (!varSel.HasInterpreter())
      fVariableSelectionRules.begin()->SetInterpreter(fInterp);
   if (varSel.GetIndex() < 0)
      fVariableSelectionRules.begin()->SetIndex(fRulesCounter);
}

void SelectionRules::AddEnumSelectionRule(const EnumSelectionRule& enumSel)
{
   fRulesCounter++;
   fEnumSelectionRules.push_back(enumSel);
   if (!enumSel.HasInterpreter())
      fEnumSelectionRules.begin()->SetInterpreter(fInterp);
   if (enumSel.GetIndex() < 0)
      fEnumSelectionRules.begin()->SetIndex( fRulesCounter );
}

void SelectionRules::PrintSelectionRules() const
{
   std::cout<<"Printing Selection Rules:"<<std::endl;
   if (!fClassSelectionRules.empty()) {
      int i = 0;
      for(std::list<ClassSelectionRule>::const_iterator it = fClassSelectionRules.begin();
          it != fClassSelectionRules.end(); ++it, ++i) {
         std::cout<<"\tClass sel rule "<<i<<":"<<std::endl;
         std::cout<< *it;
      }
   }
   else {
      std::cout<<"\tNo Class Selection Rules"<<std::endl;
   }

   if (!fFunctionSelectionRules.empty()) {
      //std::cout<<""<<std::endl;
      std::list<FunctionSelectionRule>::const_iterator it2;
      int i = 0;

      for (it2 = fFunctionSelectionRules.begin(); it2 != fFunctionSelectionRules.end(); ++it2, ++i) {
         std::cout<<"\tFunction sel rule "<<i<<":"<<std::endl;
         std::cout<<"\t\tSelected: ";
         switch(it2->GetSelected()){
            case BaseSelectionRule::kYes: std::cout<<"Yes"<<std::endl;
               break;
            case BaseSelectionRule::kNo: std::cout<<"No"<<std::endl;
               break;
            case BaseSelectionRule::kDontCare: std::cout<<"Don't Care"<<std::endl;
               break;
            default: std::cout<<"Unspecified"<<std::endl;
         }
         it2->PrintAttributes(std::cout,2);
      }
   }
   else {
      std::cout<<"\tNo function sel rules"<<std::endl;
   }

   if (!fVariableSelectionRules.empty()) {
      std::list<VariableSelectionRule>::const_iterator it3;
      int i = 0;

      for (it3 = fVariableSelectionRules.begin(); it3 != fVariableSelectionRules.end(); ++it3, ++i) {
         std::cout<<"\tVariable sel rule "<<i<<":"<<std::endl;
         std::cout<<"\t\tSelected: ";
         switch(it3->GetSelected()){
            case BaseSelectionRule::kYes: std::cout<<"Yes"<<std::endl;
               break;
            case BaseSelectionRule::kNo: std::cout<<"No"<<std::endl;
               break;
            case BaseSelectionRule::kDontCare: std::cout<<"Don't Care"<<std::endl;
               break;
            default: std::cout<<"Unspecified"<<std::endl;
         }
         it3->PrintAttributes(std::cout,2);
      }
   }
   else {
      std::cout<<"\tNo variable sel rules"<<std::endl;
   }

   if (!fEnumSelectionRules.empty()) {
      std::list<EnumSelectionRule>::const_iterator it4;
      int i = 0;

      for (it4 = fEnumSelectionRules.begin(); it4 != fEnumSelectionRules.end(); ++it4, ++i) {
         std::cout<<"\tEnum sel rule "<<i<<":"<<std::endl;
         std::cout<<"\t\tSelected: ";
         switch(it4->GetSelected()){
            case BaseSelectionRule::kYes: std::cout<<"Yes"<<std::endl;
               break;
            case BaseSelectionRule::kNo: std::cout<<"No"<<std::endl;
               break;
            case BaseSelectionRule::kDontCare: std::cout<<"Don't Care"<<std::endl;
               break;
            default: std::cout<<"Unspecified"<<std::endl;
         }
         it4->PrintAttributes(std::cout,2);
      }
   }
   else {
      std::cout<<"\tNo enum sel rules"<<std::endl;
   }
}

void SelectionRules::ClearSelectionRules()
{
   fClassSelectionRules.clear();
   fFunctionSelectionRules.clear();
   fVariableSelectionRules.clear();
   fEnumSelectionRules.clear();
}

template<class RULE>
static bool HasDuplicate(RULE* rule, 
                         std::unordered_map<std::string,RULE*>& storedRules,
                         const std::string& attrName){
   auto itRetCodePair = storedRules.emplace( attrName, rule );

   auto storedRule = storedRules[attrName];
   
   if (!itRetCodePair.second && storedRule->GetSelected() == rule->GetSelected()) {
      std::stringstream sstr; sstr << "Rule:\n";
      rule->Print(sstr);
      sstr << "Conflicting rule already stored:\n";
      storedRule->Print(sstr);
      
      auto differentAttributes = storedRule->GetAttributes() !=rule->GetAttributes();
      if (differentAttributes){
         ROOT::TMetaUtils::Warning("SelectionRules::CheckDuplicates",
                                   "Duplicated rule with name found.\n%s\n",sstr.str().c_str());
         return true;
      }
      
   }
   return false;
}

template<class RULESCOLLECTIONS, class RULE = typename RULESCOLLECTIONS::value_type>
static int CheckDuplicatesImp(RULESCOLLECTIONS& rules){
   int nDuplicates = 0;
   std::unordered_map<std::string, RULE*> patterns,names;
   for (auto&& rule : rules){
      if (rule.HasAttributeName() && HasDuplicate(&rule,names,rule.GetAttributeName())) nDuplicates++;
      if (rule.HasAttributePattern() && HasDuplicate(&rule,patterns,rule.GetAttributePattern())) nDuplicates++;
   }
   return nDuplicates;
}

int SelectionRules::CheckDuplicates(){

   // Check for identical patterns and names
   FillCache();

   int nDuplicates = 0;
   nDuplicates += CheckDuplicatesImp(fClassSelectionRules);
   nDuplicates += CheckDuplicatesImp(fFunctionSelectionRules);
   nDuplicates += CheckDuplicatesImp(fVariableSelectionRules);
   nDuplicates += CheckDuplicatesImp(fEnumSelectionRules);
   if (0 != nDuplicates){
      ROOT::TMetaUtils::Error("SelectionRules::CheckDuplicates",
{'fraction_non_alphanumeric': 0.16612657892996496, 'fraction_numerical': 0.008465048607896304, 'mean_word_length': 3.3156392694063928, 'pattern_counts': {'":': 8, '<': 271, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5815112', 'n_tokens_mistral': 4660, 'n_tokens_neox': 4494, 'n_words': 777}