Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file source_map.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2013 Hugo Heuzard
*
* 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, with linking exception;
* either version 2.1 of the License, or (at your option) any 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.
*)open!Stdlibtypemap={gen_line:int;gen_col:int;ori_source:int;ori_line:int;ori_col:int;ori_name:intoption}typemapping=maplisttypet={version:int;file:string;sourceroot:stringoption;mutablesources:stringlist;mutablesources_content:stringoptionlistoption;mutablenames:stringlist;mutablemappings:mapping}letmap_line_number~f=letfi=ifi<0thenielsefiinfunm->{mwithori_line=fm.ori_line;gen_line=fm.gen_line}letstring_of_mappingmapping=letmapping=(* The binary format encodes lines starting at zero, but
[ori_line] and [gen_line] are 1 based. *)List.mapmapping~f:(map_line_number~f:pred)inleta=Array.of_listmappinginletlen=Array.lengthainArray.stable_sort~cmp:(funt1t2->matchcomparet1.gen_linet2.gen_linewith|0->comparet1.gen_colt2.gen_col|n->n)a;letbuf=Buffer.create1024inletgen_line=ref0inletgen_col=ref0inletori_source=ref0inletori_line=ref0inletori_col=ref0inletori_name=ref0inletrecloopprevi=ifi<lenthenletc=a.(i)inifprev>=0&&c.ori_source=a.(prev).ori_source&&c.ori_line=a.(prev).ori_line&&c.ori_col=a.(prev).ori_colthen(* We already are at this location *)loopprev(i+1)elseifi+1<len&&c.gen_line=a.(i+1).gen_line&&c.gen_col=a.(i+1).gen_colthen(* Only keep one source location per generated location *)loopprev(i+1)else(if!gen_line<>c.gen_linethen(assert(!gen_line<c.gen_line);for_i=!gen_linetoc.gen_line-1doBuffer.add_charbuf';'done;gen_col:=0;gen_line:=c.gen_line)elseifi>0thenBuffer.add_charbuf',';letl=(c.gen_col-!gen_col)::(ifc.ori_source=-1then[]else(c.ori_source-!ori_source)::(c.ori_line-!ori_line)::(c.ori_col-!ori_col)::(matchc.ori_namewith|None->[]|Somen->letn'=!ori_nameinori_name:=n;[n-n']))ingen_col:=c.gen_col;ifc.ori_source<>-1then(ori_source:=c.ori_source;ori_line:=c.ori_line;ori_col:=c.ori_col);Vlq64.encode_lbufl;loopi(i+1))inloop(-1)0;Buffer.contentsbufletmapping_of_stringstr=lettotal_len=String.lengthstrinletgen_col=ref0inletori_source=ref0inletori_line=ref0inletori_col=ref0inletori_name=ref0inletrecreadlinelineposacc=ifpos>=total_lenthen(* The binary format encodes lines starting at zero, but
[ori_line] and [gen_line] are 1 based. *)List.rev_mapacc~f:(map_line_number~f:succ)elseletlast=tryString.index_fromstrpos';'withNot_found->total_leningen_col:=0;letpos,acc=read_tokenslineposlastaccinreadline(succline)posaccandread_tokenslinestartstopacc=letlast=trymin(String.index_fromstrstart',')stopwithNot_found->stopinletv=Vlq64.decode_lstr~pos:start~len:(last-start)inmatchvwith|[]->last+1,acc|v->letv=matchvwith|[g]->gen_col:=!gen_col+g;{gen_line=line;gen_col=!gen_col;ori_source=-1;ori_line=-1;ori_col=-1;ori_name=None}|[g;os;ol;oc]->gen_col:=!gen_col+g;ori_source:=!ori_source+os;ori_line:=!ori_line+ol;ori_col:=!ori_col+oc;{gen_line=line;gen_col=!gen_col;ori_source=!ori_source;ori_line=!ori_line;ori_col=!ori_col;ori_name=None}|[g;os;ol;oc;on]->gen_col:=!gen_col+g;ori_source:=!ori_source+os;ori_line:=!ori_line+ol;ori_col:=!ori_col+oc;ori_name:=!ori_name+on;{gen_line=line;gen_col=!gen_col;ori_source=!ori_source;ori_line=!ori_line;ori_col=!ori_col;ori_name=Some!ori_name}|_->invalid_arg"Source_map.mapping_of_string"inletacc=v::acciniflast=stopthenlast+1,accelseread_tokensline(last+1)stopaccinreadline00[]letmerge_sources_contentab=matcha,bwith|Somea,Someb->Some(a@b)|_->Noneletmaps~gen_line_offset~sources_offset~names_offsetx=letgen_line=x.gen_line+gen_line_offsetinletori_source=x.ori_source+sources_offsetinletori_name=matchx.ori_namewith|None->None|Someori_name->Some(ori_name+names_offset)in{xwithgen_line;ori_source;ori_name}letmerge=function|[]->None|(gen_line_offset,_file,x)::rest->letrecloopacc~sources_offset~names_offsetl=matchlwith|[]->acc|(gen_line_offset,_,sm)::rest->letacc={accwithsources=acc.sources@sm.sources;names=acc.names@sm.names;sources_content=merge_sources_contentacc.sources_contentsm.sources_content;mappings=acc.mappings@List.map~f:(maps~gen_line_offset~sources_offset~names_offset)sm.mappings}inloopacc~sources_offset:(sources_offset+List.lengthsm.sources)~names_offset:(names_offset+List.lengthsm.names)restinletacc={xwithmappings=List.mapx.mappings~f:(maps~gen_line_offset~sources_offset:0~names_offset:0)}inSome(loopacc~sources_offset:(List.lengthx.sources)~names_offset:(List.lengthx.names)rest)letempty={version=3;file="file";sourceroot=None;sources=[];sources_content=None;names=[];mappings=[]}