123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147(* Copyright (C) 2023 Antonio Nuno Monteiro
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition to the permissions granted to you by the LGPL, you may combine
* or link a "work that uses the Library" with a publicly distributed version
* of this file to produce a combined library or application, then distribute
* that combined work under the terms of your choosing, with no requirement
* to comply with the obligations normally placed on you by section 4 of the
* LGPL version 3 (or the corresponding section of a later version of the LGPL
* should you choose to use a later version).
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)moduleAst=Ppxlib_ast.AstmoduleCompiler_version=Ppxlib_ast.Compiler_versionmoduletypeOCaml_version=Ppxlib_ast.OCaml_versionmoduleIntf_or_impl=structtypet=IntfofParsetree.signature|ImplofParsetree.structureendtypeinput_version=(moduleOCaml_version)letfall_back_input_version=(moduleCompiler_version:OCaml_version)(* This should only be used when the input version can't be determined due to
loading or preprocessing errors *)typet={input_name:string;input_version:input_version;ast:Intf_or_impl.t;}typeread_error=|Not_a_binary_ast|Unknown_versionofstring*input_version|Source_parse_errorofPpxlib_ast.Location_error.t*input_version|System_errorofPpxlib_ast.Location_error.t*input_versiontypeinput_source=Stdin|Fileofstringtypeinput_kind=|Possibly_source of{filename:string;parse_fun:Lexing.lexbuf ->Intf_or_impl.t;}|Necessarily_binaryletread_error_to_string(error :read_error)=matcherrorwith|Not_a_binary_ast ->"Error: Not a binary ast"|Unknown_version(s,_)->"Error: Unknown version"^s|Source_parse_error(loc,_)->"Source parse error:"^Ppxlib_ast.Location_error.messageloc|System_error(loc,_)->"System error: "^Ppxlib_ast.Location_error.messagelocletmagic_length=String.lengthAstlib.Config.ast_impl_magic_numberletread_magicic=letbuf=Bytes.createmagic_lengthinletlen=inputicbuf0magic_lengthinlets=Bytes.sub_stringbuf0leniniflen=magic_length thenOkselseErrorsletfrom_channelch~input_kind:(t,read_error)result =let input_version=(moduleCompiler_version:OCaml_version)inletmoduleConvert=Ppxlib_ast.ConvertinletmoduleFind_version=Ppxlib_ast__.Versions.Find_versioninletmoduleJs=Ppxlib_ast__.Import.Jsinlethandle_non_binary()=matchinput_kindwith|Possibly_source{filename;parse_fun}->seek_inch0;letlexbuf=Lexing.from_channelchinLocation.initlexbuffilename;letast=parse_fun lexbuf inOk {input_name =filename;input_version;ast}|Necessarily_binary->ErrorNot_a_binary_astinmatchread_magicchwith|Error_->handle_non_binary()|Oks->(matchFind_version.from_magicswith|Intf(moduleInput_version:OCaml_version)->letinput_name:string=input_valuechinLocation.set_input_name input_name;letast=input_valuechinlet moduleInput_to_ppxlib =Convert(Input_version)(Js)inOk{input_name;input_version=(moduleInput_version:OCaml_version);ast=Intf(Input_to_ppxlib.copy_signatureast|>Melange_ppxlib_ast.Of_ppxlib.copy_signature);}|Impl(moduleInput_version:OCaml_version)->letinput_name:string=input_valuechinLocation.set_input_name input_name;letast=input_valuechinlet moduleInput_to_ppxlib =Convert(Input_version)(Js)inOk{input_name;input_version=(moduleInput_version:OCaml_version);ast=Impl(Input_to_ppxlib.copy_structureast|>Melange_ppxlib_ast.Of_ppxlib.copy_structure);}|Unknown->ifString.equal(String.subs09)(String.subAstlib.Config.ast_impl_magic_number09)||String.equal(String.subs09)(String.subAstlib.Config.ast_intf_magic_number09)thenError(Unknown_version(s,fall_back_input_version))elsehandle_non_binary())letreadinput_source~input_kind =trymatchinput_source with|Stdin->from_channel stdin~input_kind|Filefn->Stdppx.In_channel.with_filefn~f:(from_channel~input_kind)withexn->(matchPpxlib_ast.Location_error.of_exnexnwith|None->raiseexn|Someerror->Error(System_error(error,fall_back_input_version)))let read_exninput_source~input_kind=matchreadinput_source~input_kindwith|Okret->ret|Errore->raise(Arg.Bad(read_error_to_stringe))