<commit_before>#include "astutil.h"
#include "expr.h"
#include "passes.h"
#include "runtime.h"
#include "stringutil.h"
#include "symbol.h"
#include "symscope.h"


/*** name_matches_method
 ***   returns true iff function name matches a method name in class
 ***/
static bool
name_matches_method(const char* name, Type* type) {
  if (!strcmp(name, type->symbol->name))
    return false;
  forv_Vec(Symbol, method, type->methods) {
    if (method && !strcmp(name, method->name))
      return true;
  }
  forv_Vec(Type, pt, type->dispatchParents) {
    if (name_matches_method(name, pt))
      return true;
  }
  if (ClassType* ct = toClassType(type)) {
    Type *outerType = ct->symbol->defPoint->parentSymbol->type;
    if (ClassType* outer = toClassType(outerType))
      if (name_matches_method(name, outer))
        return true;
  }
  return false;
}


/*** name_matches_method_local
 ***   returns true iff function name matches a method name in class
 ***   not including any classes this class is nested in
 ***/
static bool
name_matches_method_local(const char* name, Type* type) {
  if (!strcmp(name, type->symbol->name))
    return false;
  forv_Vec(Symbol, method, type->methods) {
    if (method && !strcmp(name, method->name))
      return true;
  }
  forv_Vec(Type, pt, type->dispatchParents) {
    if (name_matches_method(name, pt))
      return true;
  }
  return false;
} 


static BlockStmt*
find_outer_loop(Expr* stmt) {
  if (BlockStmt* block = toBlockStmt(stmt))
    if (block->isLoop())
      return block;
  if (stmt->parentExpr)
    return find_outer_loop(stmt->parentExpr);
  return NULL;
}


static void
resolveGotoLabel(GotoStmt* gotoStmt) {
  if (gotoStmt->label->var == gNil) {
    BlockStmt* loop = find_outer_loop(gotoStmt);
    if (!loop)
      USR_FATAL(gotoStmt, "break or continue is not in a loop");
    if (gotoStmt->gotoTag == GOTO_BREAK)
      gotoStmt->label->replace(new SymExpr(loop->post_loop));
    else if (gotoStmt->gotoTag == GOTO_CONTINUE)
      gotoStmt->label->replace(new SymExpr(loop->pre_loop));
    else
      INT_FATAL(gotoStmt, "Unexpected goto type");
  } else if (!gotoStmt->label->var) {
    const char* name = gotoStmt->label->unresolved;
    if (gotoStmt->gotoTag == GOTO_BREAK)
      name = astr("_post", name);
    Vec<BaseAST*> asts;
    collect_asts(&asts, gotoStmt->parentSymbol);
    forv_Vec(BaseAST, ast, asts) {
      if (LabelSymbol* ls = toLabelSymbol(ast)) {
        if (!strcmp(ls->name, name))
          gotoStmt->label->replace(new SymExpr(ls));
      }
    }
  }
}


static void resolveEnumeratedTypes() {
  forv_Vec(BaseAST, ast, gAsts) {
    if (CallExpr* call = toCallExpr(ast)) {
      if (call->isNamed(".")) {
        if (SymExpr* first = toSymExpr(call->get(1))) {
          if (SymExpr* second = toSymExpr(call->get(2))) {
            if (!first->unresolved) {
              if (EnumType* type = toEnumType(first->var->type)) {
                VarSymbol* var = toVarSymbol(second->var);
                const char* name;
                if (var) {
                  if (var->immediate &&
                      var->immediate->const_kind == CONST_KIND_STRING) {
                    name = var->immediate->v_string;
                    INT_ASSERT(name);
                  }
                } else {
                  name = second->unresolved;
                }
                for_alist(constant, type->constants) {
                  DefExpr* def = toDefExpr(constant);
                  INT_ASSERT(def);
                  if (!strcmp(def->sym->name, name)) {
                    call->replace(new SymExpr(def->sym));
                  }
                }<commit_msg>Clean up enum field access code.<commit_after>#include "astutil.h"
#include "expr.h"
#include "passes.h"
#include "runtime.h"
#include "stringutil.h"
#include "symbol.h"
#include "symscope.h"


/*** name_matches_method
 ***   returns true iff function name matches a method name in class
 ***/
static bool
name_matches_method(const char* name, Type* type) {
  if (!strcmp(name, type->symbol->name))
    return false;
  forv_Vec(Symbol, method, type->methods) {
    if (method && !strcmp(name, method->name))
      return true;
  }
  forv_Vec(Type, pt, type->dispatchParents) {
    if (name_matches_method(name, pt))
      return true;
  }
  if (ClassType* ct = toClassType(type)) {
    Type *outerType = ct->symbol->defPoint->parentSymbol->type;
    if (ClassType* outer = toClassType(outerType))
      if (name_matches_method(name, outer))
        return true;
  }
  return false;
}


/*** name_matches_method_local
 ***   returns true iff function name matches a method name in class
 ***   not including any classes this class is nested in
 ***/
static bool
name_matches_method_local(const char* name, Type* type) {
  if (!strcmp(name, type->symbol->name))
    return false;
  forv_Vec(Symbol, method, type->methods) {
    if (method && !strcmp(name, method->name))
      return true;
  }
  forv_Vec(Type, pt, type->dispatchParents) {
    if (name_matches_method(name, pt))
      return true;
  }
  return false;
} 


static BlockStmt*
find_outer_loop(Expr* stmt) {
  if (BlockStmt* block = toBlockStmt(stmt))
    if (block->isLoop())
      return block;
  if (stmt->parentExpr)
    return find_outer_loop(stmt->parentExpr);
  return NULL;
}


static void
resolveGotoLabel(GotoStmt* gotoStmt) {
  if (gotoStmt->label->var == gNil) {
    BlockStmt* loop = find_outer_loop(gotoStmt);
    if (!loop)
      USR_FATAL(gotoStmt, "break or continue is not in a loop");
    if (gotoStmt->gotoTag == GOTO_BREAK)
      gotoStmt->label->replace(new SymExpr(loop->post_loop));
    else if (gotoStmt->gotoTag == GOTO_CONTINUE)
      gotoStmt->label->replace(new SymExpr(loop->pre_loop));
    else
      INT_FATAL(gotoStmt, "Unexpected goto type");
  } else if (!gotoStmt->label->var) {
    const char* name = gotoStmt->label->unresolved;
    if (gotoStmt->gotoTag == GOTO_BREAK)
      name = astr("_post", name);
    Vec<BaseAST*> asts;
    collect_asts(&asts, gotoStmt->parentSymbol);
    forv_Vec(BaseAST, ast, asts) {
      if (LabelSymbol* ls = toLabelSymbol(ast)) {
        if (!strcmp(ls->name, name))
          gotoStmt->label->replace(new SymExpr(ls));
      }
    }
  }
}


//
// Resolve EnumTypeName.fieldName to the symbol named fieldName in the
// enumerated type named EnumTypeName.
//
static void resolveEnumeratedTypes() {
  forv_Vec(BaseAST, ast, gAsts) {
    if (CallExpr* call = toCallExpr(ast)) {
      if (call->isNamed(".")) {
        if (SymExpr* first = toSymExpr(call->get(1))) {
          if (first->unresolved)
            continue; // EnumTypeName should be resolved already
          if (EnumType* type = toEnumType(first->var->type)) {
            if (SymExpr* second = toSymExpr(call->get(2))) {
              const char* name;
              INT_ASSERT(get_string(second, &name));
              for_enums(constant, type) {
                if (!strcmp(constant->sym->name, name)) {
                  call->replace(new SymExpr(constant->sym));
                }
{'fraction_non_alphanumeric': 0.13830392714854867, 'fraction_numerical': 0.0005691519635742744, 'mean_word_length': 2.811822125813449, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5086431', 'n_tokens_mistral': 2295, 'n_tokens_neox': 2296, 'n_words': 535}