Skip to content
This repository
tag: v1666
Fetching contributors…

Cannot retrieve contributors at this time

file 130 lines (114 sloc) 5.223 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
(*
Copyright © 2011 MLstate

This file is part of OPA.

OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.

OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.

You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)
(* rebel open *)
open SurfaceAst
open SurfaceAstHelper
open OpaEnv
open SurfaceAstPassesTypes

(* refactoring in progress *)

(* alias *)
module C = SurfaceAstCons.ExprIdentCons
module CS = SurfaceAstCons.StringCons



let pass_load_objects ~options (special_parsed_files, user_parsed_files) k =
  let extract_package_decl = function
    | (Package ((`declaration | `import) as kind, name), label) ->
        Some (kind, name, label.QmlLoc.pos)
    | _ -> None in
  let extract_current_package_name = function
    | Package (`declaration, name), _label -> Some(name)
    | _ -> None in
  let package_name code = Base.List.find_map extract_current_package_name code in
  let label s = {QmlLoc.pos=FilePos.nopos ("i18n, import "^s); QmlLoc.notes=SurfaceAstCons.Fresh.id()} in
  let map { parsedFile_lcode = code; parsedFile_filename = name; parsedFile_content = content } =
    let exists = ObjectFiles.exists_package ~extrapath:options.OpaEnv.extrapath in
    let package = package_name code in
    (* adding internationalisation import *)
    let i18n_to_import = I18nAndComputedString.may_import_package ?package ~exists ~options in
    let imports = List.map (fun s -> Package(`import, s), label s) i18n_to_import in
    (name,content,imports @ code)
  in
  ObjectFiles.set_extrapaths ~no_stdlib:(not options.OpaEnv.stdlib) options.OpaEnv.extrapath;
  ObjectFiles.load
    ~extrajs:(
      (*
TODO(if needed): we can patch ObjectFiles for passing the conf as well
*)
      List.map fst options.OpaEnv.extrajs
    )
    ~no_stdlib:(not options.OpaEnv.stdlib)
    extract_package_decl
    (SurfaceAstStaticInclude.pass_analyse_static_include_deps ~options)
    (List.map map special_parsed_files @ List.map map user_parsed_files)
    k

let pass_parser_generation
    ~options:_ (env : (string,parsing_directive) env_both_lcodes)
    : (string,renaming_directive) env_both_lcodes =
  let rewrite code =
    (* map_down because the directive `xml_parser may contain parsers *)
    SurfaceAstTraversal.ExprTraverse.Heterogeneous.lift_map_down_to_fixpoint
      (function (* the filter function, to make the typer happy *)
         | #renaming_directive as x -> x
         | #parsing_directive -> assert false)
      (function (* the actual mapping function *)
         | (Directive (`parser_ e, [], _), label) ->
             SurfaceAstCons.with_label' label SurfaceAstTrx.translate_rule e
         | (Directive (`xml_parser xml_parser, [], _), label) as e ->
             SurfaceAstCons.with_label' label (SurfaceAstXmlPattern.process_parser e) xml_parser
         | e -> e) code in
  { env with
      lcodeNotUser = rewrite env.lcodeNotUser;
      lcodeUser = rewrite env.lcodeUser;
  }

(**
Check for duplication of idents and some more.

This pass
- checks for level-0 identifiers with two definitions -- having two definitions of the same level-0 identifier
is either a warning or an error, depending on options
- renames all identifiers to make them unique

If the option [--warn-error duplicateL0] is set, having two level-0 identifiers with the same name is cause for
an error. Otherwise, it's an warning.
*)

let pass_check_duplication
    compiler_inserted_names compiler_inserted_types ~options:_
    (env : (string,renaming_directive) env_both_lcodes)
    : (Ident.t,dependency_directive) env_both_lcodes =
  let envs = SurfaceAstRenaming.init_env compiler_inserted_names compiler_inserted_types in
  let envs = SurfaceAstRenaming.load_env envs in
  let envs, lcodeNotUser = SurfaceAstRenaming.code envs env.lcodeNotUser in
  let envs, lcodeUser = SurfaceAstRenaming.code envs env.lcodeUser in
  SurfaceAstRenaming.save_env envs;
  {
    env with
      lcodeNotUser ;
      lcodeUser ;
      lcodeTypeRenaming = SurfaceAstRenaming.extract_types_in_scope envs;
      exported_values_idents = SurfaceAstRenaming.get_exported_values envs
  }


let pass_tuple_types ~options:_ lcode =
  SurfaceAstCons.with_builtin_position
    (fun () ->
       let intmap = SurfaceAstRenaming.get_tuple_int_map () in
       let typedefs =
         IntMap.fold
           (fun n ident acc ->
              let name = Printf.sprintf "tuple_%d" n in
              let var d = Printf.sprintf "%s_%d" name d in
              let vars = List.init n (fun n -> Ident.next (var n)) in
              C.T.typedef
                SurfaceAst.TDV_public ident ~tyvs: (List.map flatvar vars)
                (C.T.tuple (List.map C.T.var vars))
              :: acc)
           intmap [] in
       let defs = List.map C.C.newtype typedefs in
       defs @ lcode)
Something went wrong with that request. Please try again.