<commit_before>(*
 * Copyright (c) 2016 - present Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *)

open! Utils
open CFrontend_utils

let rec do_frontend_checks_stmt (context:CLintersContext.context) stmt =
  let open Clang_ast_t in
  let context' = CFrontend_errors.run_frontend_checkers_on_stmt context stmt in
  let do_all_checks_on_stmts stmt =
    (match stmt with
     | DeclStmt (_, _, decl_list) ->
         IList.iter (do_frontend_checks_decl context') decl_list
     | BlockExpr (_, _, _, decl) ->
         IList.iter (do_frontend_checks_decl context') [decl]
     | _ -> ());
    do_frontend_checks_stmt context' stmt in
  let stmts = Ast_utils.get_stmts_from_stmt stmt in
  IList.iter (do_all_checks_on_stmts) stmts

and do_frontend_checks_decl context decl =
  let open Clang_ast_t in
  let info = Clang_ast_proj.get_decl_tuple decl in
  CLocation.update_curr_file info;
  (match decl with
   | FunctionDecl(_, _, _, fdi)
   | CXXMethodDecl (_, _, _, fdi, _)
   | CXXConstructorDecl (_, _, _, fdi, _)
   | CXXConversionDecl (_, _, _, fdi, _)
   | CXXDestructorDecl (_, _, _, fdi, _) ->
       (match fdi.Clang_ast_t.fdi_body with
        | Some stmt ->
            let context = {context with CLintersContext.current_method = Some decl } in
            do_frontend_checks_stmt context stmt
        | None -> ())
   | ObjCMethodDecl (_, _, mdi) ->
       (match mdi.Clang_ast_t.omdi_body with
        | Some stmt ->
            let context = {context with CLintersContext.current_method = Some decl } in
            do_frontend_checks_stmt context stmt
        | None -> ())
   | BlockDecl (_, block_decl_info) ->
       (match block_decl_info.Clang_ast_t.bdi_body with
        | Some stmt ->
            let context = {context with CLintersContext.current_method = Some decl } in
            do_frontend_checks_stmt context stmt
        | None -> ())
   | _ -> ());
  let context' = CFrontend_errors.run_frontend_checkers_on_decl context decl in
  match Clang_ast_proj.get_decl_context_tuple decl with
  | Some (decls, _) -> IList.iter (do_frontend_checks_decl context') decls
  | None -> ()

let context_with_ck_set context decl_list =
  let is_ck = context.CLintersContext.is_ck_translation_unit
              || ComponentKit.contains_ck_impl decl_list in
  if is_ck then
    { context with CLintersContext.is_ck_translation_unit = true }
  else
    context

let store_issues source_file =
  let abbrev_source_file = DB.source_file_encoding source_file in
  let lint_issues_dir = Config.results_dir // Config.lint_issues_dir_name in
  DB.create_dir lint_issues_dir;
  let lint_issues_file =
    DB.filename_from_string (Filename.concat lint_issues_dir (abbrev_source_file ^ ".issue")) in
  LintIssues.store_issues lint_issues_file !LintIssues.errLogMap

let do_frontend_checks source_file ast =
  Logging.out "Start linting file %s\n" (DB.source_file_to_string source_file);
  match ast with
  | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) ->
      let context = context_with_ck_set CLintersContext.empty decl_list in
      let is_decl_allowed decl =
        let decl_info = Clang_ast_proj.get_decl_tuple decl in
        CLocation.should_do_frontend_check decl_info.Clang_ast_t.di_source_range in
      let allowed_decls = IList.filter is_decl_allowed decl_list in
      IList.iter (do_frontend_checks_decl context) allowed_decls;
      if (LintIssues.exists_issues ()) then
        store_issues source_file;
      Logging.out "End linting file %s\n" (DB.source_file_to_string source_file)
  | _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *)
<commit_msg>[linters] Pass the current method in the context to the checks about the methods or functions declarations<commit_after>(*
 * Copyright (c) 2016 - present Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *)

open! Utils
open CFrontend_utils

let rec do_frontend_checks_stmt (context:CLintersContext.context) stmt =
  let open Clang_ast_t in
  let context' = CFrontend_errors.run_frontend_checkers_on_stmt context stmt in
  let do_all_checks_on_stmts stmt =
    (match stmt with
     | DeclStmt (_, _, decl_list) ->
         IList.iter (do_frontend_checks_decl context') decl_list
     | BlockExpr (_, _, _, decl) ->
         IList.iter (do_frontend_checks_decl context') [decl]
     | _ -> ());
    do_frontend_checks_stmt context' stmt in
  let stmts = Ast_utils.get_stmts_from_stmt stmt in
  IList.iter (do_all_checks_on_stmts) stmts

and do_frontend_checks_decl context decl =
  let open Clang_ast_t in
  let info = Clang_ast_proj.get_decl_tuple decl in
  CLocation.update_curr_file info;
  let context' =
    (match decl with
     | FunctionDecl(_, _, _, fdi)
     | CXXMethodDecl (_, _, _, fdi, _)
     | CXXConstructorDecl (_, _, _, fdi, _)
     | CXXConversionDecl (_, _, _, fdi, _)
     | CXXDestructorDecl (_, _, _, fdi, _) ->
         let context' = {context with CLintersContext.current_method = Some decl } in
         (match fdi.Clang_ast_t.fdi_body with
          | Some stmt ->
              do_frontend_checks_stmt context' stmt
          | None -> ());
         context'
     | ObjCMethodDecl (_, _, mdi) ->
         let context' = {context with CLintersContext.current_method = Some decl } in
         (match mdi.Clang_ast_t.omdi_body with
          | Some stmt ->
              do_frontend_checks_stmt context' stmt
          | None -> ());
         context'
     | BlockDecl (_, block_decl_info) ->
         let context' = {context with CLintersContext.current_method = Some decl } in
         (match block_decl_info.Clang_ast_t.bdi_body with
          | Some stmt ->
              do_frontend_checks_stmt context' stmt
          | None -> ());
         context'
     | _ -> context) in
  let context'' = CFrontend_errors.run_frontend_checkers_on_decl context' decl in
  let context_with_orig_current_method =
    {context'' with CLintersContext.current_method = context.CLintersContext.current_method } in
  match Clang_ast_proj.get_decl_context_tuple decl with
  | Some (decls, _) -> IList.iter (do_frontend_checks_decl context_with_orig_current_method) decls
  | None -> ()

let context_with_ck_set context decl_list =
  let is_ck = context.CLintersContext.is_ck_translation_unit
              || ComponentKit.contains_ck_impl decl_list in
  if is_ck then
    { context with CLintersContext.is_ck_translation_unit = true }
  else
    context

let store_issues source_file =
  let abbrev_source_file = DB.source_file_encoding source_file in
  let lint_issues_dir = Config.results_dir // Config.lint_issues_dir_name in
  DB.create_dir lint_issues_dir;
  let lint_issues_file =
    DB.filename_from_string (Filename.concat lint_issues_dir (abbrev_source_file ^ ".issue")) in
  LintIssues.store_issues lint_issues_file !LintIssues.errLogMap

let do_frontend_checks source_file ast =
  Logging.out "Start linting file %s\n" (DB.source_file_to_string source_file);
  match ast with
  | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) ->
      let context = context_with_ck_set CLintersContext.empty decl_list in
      let is_decl_allowed decl =
        let decl_info = Clang_ast_proj.get_decl_tuple decl in
        CLocation.should_do_frontend_check decl_info.Clang_ast_t.di_source_range in
      let allowed_decls = IList.filter is_decl_allowed decl_list in
      IList.iter (do_frontend_checks_decl context) allowed_decls;
      if (LintIssues.exists_issues ()) then
        store_issues source_file;
      Logging.out "End linting file %s\n" (DB.source_file_to_string source_file)
  | _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *)

{'fraction_non_alphanumeric': 0.0752261742471186, 'fraction_numerical': 0.0009914487544925021, 'mean_word_length': 3.4316309719934104, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4900961', 'n_tokens_mistral': 2679, 'n_tokens_neox': 2624, 'n_words': 652}