typeload.ml 149 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114
  1. (*
  2. The Haxe Compiler
  3. Copyright (C) 2005-2016 Haxe Foundation
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. *)
  16. open Ast
  17. open Type
  18. open Common
  19. open Typecore
  20. exception Build_canceled of build_state
  21. let locate_macro_error = ref true
  22. let transform_abstract_field com this_t a_t a f =
  23. let stat = List.mem AStatic f.cff_access in
  24. let p = f.cff_pos in
  25. match f.cff_kind with
  26. | FProp (("get" | "never"),("set" | "never"),_,_) when not stat ->
  27. (* TODO: hack to avoid issues with abstract property generation on As3 *)
  28. if Common.defined com Define.As3 then f.cff_meta <- (Meta.Extern,[],p) :: f.cff_meta;
  29. { f with cff_access = AStatic :: f.cff_access; cff_meta = (Meta.Impl,[],p) :: f.cff_meta }
  30. | FProp _ when not stat ->
  31. error "Member property accessors must be get/set or never" p;
  32. | FFun fu when f.cff_name = "new" && not stat ->
  33. let init p = (EVars ["this",Some this_t,None],p) in
  34. let cast e = (ECast(e,None)),pos e in
  35. let ret p = (EReturn (Some (cast (EConst (Ident "this"),p))),p) in
  36. let meta = (Meta.Impl,[],p) :: f.cff_meta in
  37. let meta = if Meta.has Meta.MultiType a.a_meta then begin
  38. if List.mem AInline f.cff_access then error "MultiType constructors cannot be inline" f.cff_pos;
  39. if fu.f_expr <> None then error "MultiType constructors cannot have a body" f.cff_pos;
  40. (Meta.Extern,[],f.cff_pos) :: meta
  41. end else
  42. meta
  43. in
  44. let fu = {
  45. fu with
  46. f_expr = (match fu.f_expr with
  47. | None -> if Meta.has Meta.MultiType a.a_meta then Some (EConst (Ident "null"),p) else None
  48. | Some (EBlock el,p) -> Some (EBlock (init p :: el @ [ret p]),p)
  49. | Some e -> Some (EBlock [init p;e;ret p],p)
  50. );
  51. f_type = Some a_t;
  52. } in
  53. { f with cff_name = "_new"; cff_access = AStatic :: f.cff_access; cff_kind = FFun fu; cff_meta = meta }
  54. | FFun fu when not stat ->
  55. if Meta.has Meta.From f.cff_meta then error "@:from cast functions must be static" f.cff_pos;
  56. let fu = { fu with f_args = (if List.mem AMacro f.cff_access then fu.f_args else ("this",false,Some this_t,None) :: fu.f_args) } in
  57. { f with cff_kind = FFun fu; cff_access = AStatic :: f.cff_access; cff_meta = (Meta.Impl,[],p) :: f.cff_meta }
  58. | _ ->
  59. f
  60. let make_module ctx mpath file loadp =
  61. let m = {
  62. m_id = alloc_mid();
  63. m_path = mpath;
  64. m_types = [];
  65. m_extra = module_extra (Common.unique_full_path file) (Common.get_signature ctx.com) (file_time file) (if ctx.in_macro then MMacro else MCode);
  66. } in
  67. m
  68. (*
  69. Build module structure : should be atomic - no type loading is possible
  70. *)
  71. let module_pass_1 ctx m tdecls loadp =
  72. let com = ctx.com in
  73. let decls = ref [] in
  74. let make_path name priv =
  75. if List.exists (fun (t,_) -> snd (t_path t) = name) !decls then error ("Type name " ^ name ^ " is already defined in this module") loadp;
  76. if priv then (fst m.m_path @ ["_" ^ snd m.m_path], name) else (fst m.m_path, name)
  77. in
  78. let pt = ref None in
  79. let rec make_decl acc decl =
  80. let p = snd decl in
  81. let acc = (match fst decl with
  82. | EImport _ | EUsing _ ->
  83. (match !pt with
  84. | None -> acc
  85. | Some _ -> error "import and using may not appear after a type declaration" p)
  86. | EClass d ->
  87. if String.length d.d_name > 0 && d.d_name.[0] = '$' then error "Type names starting with a dollar are not allowed" p;
  88. pt := Some p;
  89. let priv = List.mem HPrivate d.d_flags in
  90. let path = make_path d.d_name priv in
  91. let c = mk_class m path p in
  92. (* we shouldn't load any other type until we propertly set cl_build *)
  93. c.cl_build <- (fun() -> assert false);
  94. c.cl_module <- m;
  95. c.cl_private <- priv;
  96. c.cl_doc <- d.d_doc;
  97. c.cl_meta <- d.d_meta;
  98. decls := (TClassDecl c, decl) :: !decls;
  99. acc
  100. | EEnum d ->
  101. if String.length d.d_name > 0 && d.d_name.[0] = '$' then error "Type names starting with a dollar are not allowed" p;
  102. pt := Some p;
  103. let priv = List.mem EPrivate d.d_flags in
  104. let path = make_path d.d_name priv in
  105. let e = {
  106. e_path = path;
  107. e_module = m;
  108. e_pos = p;
  109. e_doc = d.d_doc;
  110. e_meta = d.d_meta;
  111. e_params = [];
  112. e_private = priv;
  113. e_extern = List.mem EExtern d.d_flags;
  114. e_constrs = PMap.empty;
  115. e_names = [];
  116. e_type = {
  117. t_path = [], "Enum<" ^ (s_type_path path) ^ ">";
  118. t_module = m;
  119. t_doc = None;
  120. t_pos = p;
  121. t_type = mk_mono();
  122. t_private = true;
  123. t_params = [];
  124. t_meta = [];
  125. };
  126. } in
  127. decls := (TEnumDecl e, decl) :: !decls;
  128. acc
  129. | ETypedef d ->
  130. if String.length d.d_name > 0 && d.d_name.[0] = '$' then error "Type names starting with a dollar are not allowed" p;
  131. pt := Some p;
  132. let priv = List.mem EPrivate d.d_flags in
  133. let path = make_path d.d_name priv in
  134. let t = {
  135. t_path = path;
  136. t_module = m;
  137. t_pos = p;
  138. t_doc = d.d_doc;
  139. t_private = priv;
  140. t_params = [];
  141. t_type = mk_mono();
  142. t_meta = d.d_meta;
  143. } in
  144. (* failsafe in case the typedef is not initialized (see #3933) *)
  145. delay ctx PBuildModule (fun () ->
  146. match t.t_type with
  147. | TMono r -> (match !r with None -> r := Some com.basic.tvoid | _ -> ())
  148. | _ -> ()
  149. );
  150. decls := (TTypeDecl t, decl) :: !decls;
  151. acc
  152. | EAbstract d ->
  153. if String.length d.d_name > 0 && d.d_name.[0] = '$' then error "Type names starting with a dollar are not allowed" p;
  154. let priv = List.mem APrivAbstract d.d_flags in
  155. let path = make_path d.d_name priv in
  156. let a = {
  157. a_path = path;
  158. a_private = priv;
  159. a_module = m;
  160. a_pos = p;
  161. a_doc = d.d_doc;
  162. a_params = [];
  163. a_meta = d.d_meta;
  164. a_from = [];
  165. a_to = [];
  166. a_from_field = [];
  167. a_to_field = [];
  168. a_ops = [];
  169. a_unops = [];
  170. a_impl = None;
  171. a_array = [];
  172. a_this = mk_mono();
  173. a_resolve = None;
  174. } in
  175. decls := (TAbstractDecl a, decl) :: !decls;
  176. match d.d_data with
  177. | [] when Meta.has Meta.CoreType a.a_meta ->
  178. a.a_this <- t_dynamic;
  179. acc
  180. | fields ->
  181. let a_t =
  182. let params = List.map (fun t -> TPType (CTPath { tname = t.tp_name; tparams = []; tsub = None; tpackage = [] })) d.d_params in
  183. CTPath { tpackage = []; tname = d.d_name; tparams = params; tsub = None }
  184. in
  185. let rec loop = function
  186. | [] -> a_t
  187. | AIsType t :: _ -> t
  188. | _ :: l -> loop l
  189. in
  190. let this_t = loop d.d_flags in
  191. let fields = List.map (transform_abstract_field com this_t a_t a) fields in
  192. let meta = ref [] in
  193. if has_meta Meta.Dce a.a_meta then meta := (Meta.Dce,[],p) :: !meta;
  194. let acc = make_decl acc (EClass { d_name = d.d_name ^ "_Impl_"; d_flags = [HPrivate]; d_data = fields; d_doc = None; d_params = []; d_meta = !meta },p) in
  195. (match !decls with
  196. | (TClassDecl c,_) :: _ ->
  197. List.iter (fun m -> match m with
  198. | ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpConstants | Meta.PhpGlobal),_,_) ->
  199. c.cl_meta <- m :: c.cl_meta;
  200. | _ ->
  201. ()
  202. ) a.a_meta;
  203. a.a_impl <- Some c;
  204. c.cl_kind <- KAbstractImpl a
  205. | _ -> assert false);
  206. acc
  207. ) in
  208. decl :: acc
  209. in
  210. let tdecls = List.fold_left make_decl [] tdecls in
  211. let decls = List.rev !decls in
  212. decls, List.rev tdecls
  213. let parse_file_from_lexbuf com file p lexbuf =
  214. let t = Common.timer "parsing" in
  215. Lexer.init file true;
  216. incr stats.s_files_parsed;
  217. let data = (try Parser.parse com lexbuf with e -> t(); raise e) in
  218. t();
  219. Common.log com ("Parsed " ^ file);
  220. data
  221. let parse_file_from_string com file p string =
  222. parse_file_from_lexbuf com file p (Lexing.from_string string)
  223. let parse_file com file p =
  224. let use_stdin = (Common.defined com Define.DisplayStdin) && (Common.unique_full_path file) = !Parser.resume_display.pfile in
  225. let ch = if use_stdin then stdin else (try open_in_bin file with _ -> error ("Could not open " ^ file) p) in
  226. Std.finally (fun() -> close_in ch) (parse_file_from_lexbuf com file p) (Lexing.from_channel ch)
  227. let parse_hook = ref parse_file
  228. let type_module_hook = ref (fun _ _ _ -> None)
  229. let type_function_params_rec = ref (fun _ _ _ _ -> assert false)
  230. let return_partial_type = ref false
  231. let type_function_arg ctx t e opt p =
  232. if opt then
  233. let e = (match e with None -> Some (EConst (Ident "null"),p) | _ -> e) in
  234. ctx.t.tnull t, e
  235. else
  236. let t = match e with Some (EConst (Ident "null"),p) -> ctx.t.tnull t | _ -> t in
  237. t, e
  238. let type_var_field ctx t e stat p =
  239. if stat then ctx.curfun <- FunStatic else ctx.curfun <- FunMember;
  240. let e = type_expr ctx e (WithType t) in
  241. let e = (!cast_or_unify_ref) ctx t e p in
  242. match t with
  243. | TType ({ t_path = ([],"UInt") },[]) | TAbstract ({ a_path = ([],"UInt") },[]) when stat -> { e with etype = t }
  244. | _ -> e
  245. let apply_macro ctx mode path el p =
  246. let cpath, meth = (match List.rev (ExtString.String.nsplit path ".") with
  247. | meth :: name :: pack -> (List.rev pack,name), meth
  248. | _ -> error "Invalid macro path" p
  249. ) in
  250. ctx.g.do_macro ctx mode cpath meth el p
  251. (** since load_type_def and load_instance are used in PASS2, they should not access the structure of a type **)
  252. (*
  253. load a type or a subtype definition
  254. *)
  255. let rec load_type_def ctx p t =
  256. let no_pack = t.tpackage = [] in
  257. let tname = (match t.tsub with None -> t.tname | Some n -> n) in
  258. try
  259. if t.tsub <> None then raise Not_found;
  260. List.find (fun t2 ->
  261. let tp = t_path t2 in
  262. tp = (t.tpackage,tname) || (no_pack && snd tp = tname)
  263. ) (ctx.m.curmod.m_types @ ctx.m.module_types)
  264. with
  265. Not_found ->
  266. let next() =
  267. let t, m = (try
  268. t, ctx.g.do_load_module ctx (t.tpackage,t.tname) p
  269. with Error (Module_not_found _,p2) as e when p == p2 ->
  270. match t.tpackage with
  271. | "std" :: l ->
  272. let t = { t with tpackage = l } in
  273. t, ctx.g.do_load_module ctx (t.tpackage,t.tname) p
  274. | _ -> raise e
  275. ) in
  276. let tpath = (t.tpackage,tname) in
  277. try
  278. List.find (fun t -> not (t_infos t).mt_private && t_path t = tpath) m.m_types
  279. with
  280. Not_found -> raise (Error (Type_not_found (m.m_path,tname),p))
  281. in
  282. (* lookup in wildcard imported packages *)
  283. try
  284. if not no_pack then raise Exit;
  285. let rec loop = function
  286. | [] -> raise Exit
  287. | wp :: l ->
  288. try
  289. load_type_def ctx p { t with tpackage = wp }
  290. with
  291. | Error (Module_not_found _,p2)
  292. | Error (Type_not_found _,p2) when p == p2 -> loop l
  293. in
  294. loop ctx.m.wildcard_packages
  295. with Exit ->
  296. (* lookup in our own package - and its upper packages *)
  297. let rec loop = function
  298. | [] -> raise Exit
  299. | (_ :: lnext) as l ->
  300. try
  301. load_type_def ctx p { t with tpackage = List.rev l }
  302. with
  303. | Error (Module_not_found _,p2)
  304. | Error (Type_not_found _,p2) when p == p2 -> loop lnext
  305. in
  306. try
  307. if not no_pack then raise Exit;
  308. (match fst ctx.m.curmod.m_path with
  309. | [] -> raise Exit
  310. | x :: _ ->
  311. (* this can occur due to haxe remoting : a module can be
  312. already defined in the "js" package and is not allowed
  313. to access the js classes *)
  314. try
  315. (match PMap.find x ctx.com.package_rules with
  316. | Forbidden -> raise Exit
  317. | _ -> ())
  318. with Not_found -> ());
  319. loop (List.rev (fst ctx.m.curmod.m_path));
  320. with
  321. Exit -> next()
  322. let check_param_constraints ctx types t pl c p =
  323. match follow t with
  324. | TMono _ -> ()
  325. | _ ->
  326. let ctl = (match c.cl_kind with KTypeParameter l -> l | _ -> []) in
  327. List.iter (fun ti ->
  328. let ti = apply_params types pl ti in
  329. let ti = (match follow ti with
  330. | TInst ({ cl_kind = KGeneric } as c,pl) ->
  331. (* if we solve a generic contraint, let's substitute with the actual generic instance before unifying *)
  332. let _,_, f = ctx.g.do_build_instance ctx (TClassDecl c) p in
  333. f pl
  334. | _ -> ti
  335. ) in
  336. try
  337. unify_raise ctx t ti p
  338. with Error(Unify l,p) ->
  339. if not ctx.untyped then display_error ctx (error_msg (Unify (Constraint_failure (s_type_path c.cl_path) :: l))) p;
  340. ) ctl
  341. let requires_value_meta com co =
  342. Common.defined com Define.DocGen || (match co with
  343. | None -> false
  344. | Some c -> c.cl_extern || Meta.has Meta.Rtti c.cl_meta)
  345. let generate_value_meta com co cf args =
  346. if requires_value_meta com co then begin
  347. let values = List.fold_left (fun acc (name,_,_,eo) -> match eo with Some e -> (name,e) :: acc | _ -> acc) [] args in
  348. match values with
  349. | [] -> ()
  350. | _ -> cf.cf_meta <- ((Meta.Value,[EObjectDecl values,cf.cf_pos],cf.cf_pos) :: cf.cf_meta)
  351. end
  352. (* build an instance from a full type *)
  353. let rec load_instance ctx t p allow_no_params =
  354. try
  355. if t.tpackage <> [] || t.tsub <> None then raise Not_found;
  356. let pt = List.assoc t.tname ctx.type_params in
  357. if t.tparams <> [] then error ("Class type parameter " ^ t.tname ^ " can't have parameters") p;
  358. pt
  359. with Not_found ->
  360. let mt = load_type_def ctx p t in
  361. let is_generic,is_generic_build = match mt with
  362. | TClassDecl {cl_kind = KGeneric} -> true,false
  363. | TClassDecl {cl_kind = KGenericBuild _} -> false,true
  364. | _ -> false,false
  365. in
  366. let types , path , f = ctx.g.do_build_instance ctx mt p in
  367. let is_rest = is_generic_build && (match types with ["Rest",_] -> true | _ -> false) in
  368. if allow_no_params && t.tparams = [] && not is_rest then begin
  369. let pl = ref [] in
  370. pl := List.map (fun (name,t) ->
  371. match follow t with
  372. | TInst (c,_) ->
  373. let t = mk_mono() in
  374. if c.cl_kind <> KTypeParameter [] || is_generic then delay ctx PCheckConstraint (fun() -> check_param_constraints ctx types t (!pl) c p);
  375. t;
  376. | _ -> assert false
  377. ) types;
  378. f (!pl)
  379. end else if path = ([],"Dynamic") then
  380. match t.tparams with
  381. | [] -> t_dynamic
  382. | [TPType t] -> TDynamic (load_complex_type ctx p t)
  383. | _ -> error "Too many parameters for Dynamic" p
  384. else begin
  385. if not is_rest && List.length types <> List.length t.tparams then error ("Invalid number of type parameters for " ^ s_type_path path) p;
  386. let tparams = List.map (fun t ->
  387. match t with
  388. | TPExpr e ->
  389. let name = (match fst e with
  390. | EConst (String s) -> "S" ^ s
  391. | EConst (Int i) -> "I" ^ i
  392. | EConst (Float f) -> "F" ^ f
  393. | _ -> "Expr"
  394. ) in
  395. let c = mk_class null_module ([],name) p in
  396. c.cl_kind <- KExpr e;
  397. TInst (c,[])
  398. | TPType t -> load_complex_type ctx p t
  399. ) t.tparams in
  400. let rec loop tl1 tl2 is_rest = match tl1,tl2 with
  401. | t :: tl1,(name,t2) :: tl2 ->
  402. let check_const c =
  403. let is_expression = (match t with TInst ({ cl_kind = KExpr _ },_) -> true | _ -> false) in
  404. let expects_expression = name = "Const" || Meta.has Meta.Const c.cl_meta in
  405. let accepts_expression = name = "Rest" in
  406. if is_expression then begin
  407. if not expects_expression && not accepts_expression then
  408. error "Constant value unexpected here" p
  409. end else if expects_expression then
  410. error "Constant value excepted as type parameter" p
  411. in
  412. let is_rest = is_rest || name = "Rest" && is_generic_build in
  413. let t = match follow t2 with
  414. | TInst ({ cl_kind = KTypeParameter [] } as c, []) when not is_generic ->
  415. check_const c;
  416. t
  417. | TInst (c,[]) ->
  418. check_const c;
  419. let r = exc_protect ctx (fun r ->
  420. r := (fun() -> t);
  421. delay ctx PCheckConstraint (fun() -> check_param_constraints ctx types t tparams c p);
  422. t
  423. ) "constraint" in
  424. delay ctx PForce (fun () -> ignore(!r()));
  425. TLazy r
  426. | _ -> assert false
  427. in
  428. t :: loop tl1 tl2 is_rest
  429. | [],[] ->
  430. []
  431. | [],["Rest",_] when is_generic_build ->
  432. []
  433. | [],_ ->
  434. error ("Not enough type parameters for " ^ s_type_path path) p
  435. | t :: tl,[] ->
  436. if is_rest then
  437. t :: loop tl [] true
  438. else
  439. error ("Too many parameters for " ^ s_type_path path) p
  440. in
  441. let params = loop tparams types false in
  442. f params
  443. end
  444. (*
  445. build an instance from a complex type
  446. *)
  447. and load_complex_type ctx p t =
  448. match t with
  449. | CTParent t -> load_complex_type ctx p t
  450. | CTPath t -> load_instance ctx t p false
  451. | CTOptional _ -> error "Optional type not allowed here" p
  452. | CTExtend (tl,l) ->
  453. (match load_complex_type ctx p (CTAnonymous l) with
  454. | TAnon a as ta ->
  455. let is_redefined cf1 a2 =
  456. try
  457. let cf2 = PMap.find cf1.cf_name a2.a_fields in
  458. let st = s_type (print_context()) in
  459. if not (type_iseq cf1.cf_type cf2.cf_type) then begin
  460. display_error ctx ("Cannot redefine field " ^ cf1.cf_name ^ " with different type") p;
  461. display_error ctx ("First type was " ^ (st cf1.cf_type)) cf1.cf_pos;
  462. error ("Second type was " ^ (st cf2.cf_type)) cf2.cf_pos
  463. end else
  464. true
  465. with Not_found ->
  466. false
  467. in
  468. let mk_extension t =
  469. match follow t with
  470. | TInst ({cl_kind = KTypeParameter _},_) ->
  471. error "Cannot structurally extend type parameters" p
  472. | TInst (c,tl) ->
  473. ctx.com.warning "Structurally extending classes is deprecated and will be removed" p;
  474. let c2 = mk_class null_module (fst c.cl_path,"+" ^ snd c.cl_path) p in
  475. c2.cl_private <- true;
  476. PMap.iter (fun f _ ->
  477. try
  478. ignore(class_field c tl f);
  479. error ("Cannot redefine field " ^ f) p
  480. with
  481. Not_found -> ()
  482. ) a.a_fields;
  483. (* do NOT tag as extern - for protect *)
  484. c2.cl_kind <- KExtension (c,tl);
  485. c2.cl_super <- Some (c,tl);
  486. c2.cl_fields <- a.a_fields;
  487. TInst (c2,[])
  488. | TMono _ ->
  489. error "Loop found in cascading signatures definitions. Please change order/import" p
  490. | TAnon a2 ->
  491. PMap.iter (fun _ cf -> ignore(is_redefined cf a2)) a.a_fields;
  492. TAnon { a_fields = (PMap.foldi PMap.add a.a_fields a2.a_fields); a_status = ref (Extend [t]); }
  493. | _ -> error "Can only extend classes and structures" p
  494. in
  495. let loop t = match follow t with
  496. | TAnon a2 ->
  497. PMap.iter (fun f cf ->
  498. if not (is_redefined cf a) then
  499. a.a_fields <- PMap.add f cf a.a_fields
  500. ) a2.a_fields
  501. | _ ->
  502. error "Multiple structural extension is only allowed for structures" p
  503. in
  504. let il = List.map (fun t -> load_instance ctx t p false) tl in
  505. let tr = ref None in
  506. let t = TMono tr in
  507. let r = exc_protect ctx (fun r ->
  508. r := (fun _ -> t);
  509. tr := Some (match il with
  510. | [i] ->
  511. mk_extension i
  512. | _ ->
  513. List.iter loop il;
  514. a.a_status := Extend il;
  515. ta);
  516. t
  517. ) "constraint" in
  518. delay ctx PForce (fun () -> ignore(!r()));
  519. TLazy r
  520. | _ -> assert false)
  521. | CTAnonymous l ->
  522. let rec loop acc f =
  523. let n = f.cff_name in
  524. let p = f.cff_pos in
  525. if PMap.mem n acc then error ("Duplicate field declaration : " ^ n) p;
  526. let topt = function
  527. | None -> error ("Explicit type required for field " ^ n) p
  528. | Some t -> load_complex_type ctx p t
  529. in
  530. if n = "new" then ctx.com.warning "Structures with new are deprecated, use haxe.Constraints.Constructible instead" p;
  531. let no_expr = function
  532. | None -> ()
  533. | Some (_,p) -> error "Expression not allowed here" p
  534. in
  535. let pub = ref true in
  536. let dyn = ref false in
  537. let params = ref [] in
  538. List.iter (fun a ->
  539. match a with
  540. | APublic -> ()
  541. | APrivate -> pub := false;
  542. | ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
  543. | AStatic | AOverride | AInline | ADynamic | AMacro -> error ("Invalid access " ^ Ast.s_access a) p
  544. ) f.cff_access;
  545. let t , access = (match f.cff_kind with
  546. | FVar (Some (CTPath({tpackage=[];tname="Void"})), _) | FProp (_,_,Some (CTPath({tpackage=[];tname="Void"})),_) ->
  547. error "Fields of type Void are not allowed in structures" p
  548. | FVar (t, e) ->
  549. no_expr e;
  550. topt t, Var { v_read = AccNormal; v_write = AccNormal }
  551. | FFun fd ->
  552. params := (!type_function_params_rec) ctx fd f.cff_name p;
  553. no_expr fd.f_expr;
  554. let old = ctx.type_params in
  555. ctx.type_params <- !params @ old;
  556. let args = List.map (fun (name,o,t,e) -> no_expr e; name, o, topt t) fd.f_args in
  557. let t = TFun (args,topt fd.f_type), Method (if !dyn then MethDynamic else MethNormal) in
  558. ctx.type_params <- old;
  559. t
  560. | FProp (i1,i2,t,e) ->
  561. no_expr e;
  562. let access m get =
  563. match m with
  564. | "null" -> AccNo
  565. | "never" -> AccNever
  566. | "default" -> AccNormal
  567. | "dynamic" -> AccCall
  568. | "get" when get -> AccCall
  569. | "set" when not get -> AccCall
  570. | x when get && x = "get_" ^ n -> AccCall
  571. | x when not get && x = "set_" ^ n -> AccCall
  572. | _ ->
  573. error "Custom property access is no longer supported in Haxe 3" f.cff_pos;
  574. in
  575. let t = (match t with None -> error "Type required for structure property" p | Some t -> t) in
  576. load_complex_type ctx p t, Var { v_read = access i1 true; v_write = access i2 false }
  577. ) in
  578. let t = if Meta.has Meta.Optional f.cff_meta then ctx.t.tnull t else t in
  579. let cf = {
  580. cf_name = n;
  581. cf_type = t;
  582. cf_pos = p;
  583. cf_public = !pub;
  584. cf_kind = access;
  585. cf_params = !params;
  586. cf_expr = None;
  587. cf_doc = f.cff_doc;
  588. cf_meta = f.cff_meta;
  589. cf_overloads = [];
  590. } in
  591. init_meta_overloads ctx None cf;
  592. PMap.add n cf acc
  593. in
  594. mk_anon (List.fold_left loop PMap.empty l)
  595. | CTFunction (args,r) ->
  596. match args with
  597. | [CTPath { tpackage = []; tparams = []; tname = "Void" }] ->
  598. TFun ([],load_complex_type ctx p r)
  599. | _ ->
  600. TFun (List.map (fun t ->
  601. let t, opt = (match t with CTOptional t -> t, true | _ -> t,false) in
  602. "",opt,load_complex_type ctx p t
  603. ) args,load_complex_type ctx p r)
  604. and init_meta_overloads ctx co cf =
  605. let overloads = ref [] in
  606. let filter_meta m = match m with
  607. | ((Meta.Overload | Meta.Value),_,_) -> false
  608. | _ -> true
  609. in
  610. let cf_meta = List.filter filter_meta cf.cf_meta in
  611. cf.cf_meta <- List.filter (fun m ->
  612. match m with
  613. | (Meta.Overload,[(EFunction (fname,f),p)],_) ->
  614. if fname <> None then error "Function name must not be part of @:overload" p;
  615. (match f.f_expr with Some (EBlock [], _) -> () | _ -> error "Overload must only declare an empty method body {}" p);
  616. let old = ctx.type_params in
  617. (match cf.cf_params with
  618. | [] -> ()
  619. | l -> ctx.type_params <- List.filter (fun t -> not (List.mem t l)) ctx.type_params);
  620. let params = (!type_function_params_rec) ctx f cf.cf_name p in
  621. ctx.type_params <- params @ ctx.type_params;
  622. let topt = function None -> error "Explicit type required" p | Some t -> load_complex_type ctx p t in
  623. let args = List.map (fun (a,opt,t,_) -> a,opt,topt t) f.f_args in
  624. let cf = { cf with cf_type = TFun (args,topt f.f_type); cf_params = params; cf_meta = cf_meta} in
  625. generate_value_meta ctx.com co cf f.f_args;
  626. overloads := cf :: !overloads;
  627. ctx.type_params <- old;
  628. false
  629. | (Meta.Overload,[],_) when ctx.com.config.pf_overload ->
  630. let topt (n,_,t) = match t with | TMono t when !t = None -> error ("Explicit type required for overload functions\nFor function argument '" ^ n ^ "'") cf.cf_pos | _ -> () in
  631. (match follow cf.cf_type with
  632. | TFun (args,_) -> List.iter topt args
  633. | _ -> () (* could be a variable *));
  634. true
  635. | (Meta.Overload,[],p) ->
  636. error "This platform does not support this kind of overload declaration. Try @:overload(function()... {}) instead" p
  637. | (Meta.Overload,_,p) ->
  638. error "Invalid @:overload metadata format" p
  639. | _ ->
  640. true
  641. ) cf.cf_meta;
  642. cf.cf_overloads <- (List.rev !overloads)
  643. let hide_params ctx =
  644. let old_m = ctx.m in
  645. let old_type_params = ctx.type_params in
  646. let old_deps = ctx.g.std.m_extra.m_deps in
  647. ctx.m <- {
  648. curmod = ctx.g.std;
  649. module_types = [];
  650. module_using = [];
  651. module_globals = PMap.empty;
  652. wildcard_packages = [];
  653. module_imports = [];
  654. };
  655. ctx.type_params <- [];
  656. (fun() ->
  657. ctx.m <- old_m;
  658. ctx.type_params <- old_type_params;
  659. (* restore dependencies that might be have been wronly inserted *)
  660. ctx.g.std.m_extra.m_deps <- old_deps;
  661. )
  662. (*
  663. load a type while ignoring the current imports or local types
  664. *)
  665. let load_core_type ctx name =
  666. let show = hide_params ctx in
  667. let t = load_instance ctx { tpackage = []; tname = name; tparams = []; tsub = None; } null_pos false in
  668. show();
  669. add_dependency ctx.m.curmod (match t with
  670. | TInst (c,_) -> c.cl_module
  671. | TType (t,_) -> t.t_module
  672. | TAbstract (a,_) -> a.a_module
  673. | TEnum (e,_) -> e.e_module
  674. | _ -> assert false);
  675. t
  676. let t_iterator ctx =
  677. let show = hide_params ctx in
  678. match load_type_def ctx null_pos { tpackage = []; tname = "Iterator"; tparams = []; tsub = None } with
  679. | TTypeDecl t ->
  680. show();
  681. add_dependency ctx.m.curmod t.t_module;
  682. if List.length t.t_params <> 1 then assert false;
  683. let pt = mk_mono() in
  684. apply_params t.t_params [pt] t.t_type, pt
  685. | _ ->
  686. assert false
  687. (*
  688. load either a type t or Null<Unknown> if not defined
  689. *)
  690. let load_type_opt ?(opt=false) ctx p t =
  691. let t = (match t with None -> mk_mono() | Some t -> load_complex_type ctx p t) in
  692. if opt then ctx.t.tnull t else t
  693. (* ---------------------------------------------------------------------- *)
  694. (* Structure check *)
  695. let valid_redefinition ctx f1 t1 f2 t2 =
  696. let valid t1 t2 =
  697. Type.unify t1 t2;
  698. if is_null t1 <> is_null t2 || ((follow t1) == t_dynamic && (follow t2) != t_dynamic) then raise (Unify_error [Cannot_unify (t1,t2)]);
  699. in
  700. let t1, t2 = (match f1.cf_params, f2.cf_params with
  701. | [], [] -> t1, t2
  702. | l1, l2 when List.length l1 = List.length l2 ->
  703. let to_check = ref [] in
  704. let monos = List.map2 (fun (name,p1) (_,p2) ->
  705. (match follow p1, follow p2 with
  706. | TInst ({ cl_kind = KTypeParameter ct1 } as c1,pl1), TInst ({ cl_kind = KTypeParameter ct2 } as c2,pl2) ->
  707. (match ct1, ct2 with
  708. | [], [] -> ()
  709. | _, _ when List.length ct1 = List.length ct2 ->
  710. (* if same constraints, they are the same type *)
  711. let check monos =
  712. List.iter2 (fun t1 t2 ->
  713. try
  714. let t1 = apply_params l1 monos (apply_params c1.cl_params pl1 t1) in
  715. let t2 = apply_params l2 monos (apply_params c2.cl_params pl2 t2) in
  716. type_eq EqStrict t1 t2
  717. with Unify_error l ->
  718. raise (Unify_error (Unify_custom "Constraints differ" :: l))
  719. ) ct1 ct2
  720. in
  721. to_check := check :: !to_check;
  722. | _ ->
  723. raise (Unify_error [Unify_custom "Different number of constraints"]))
  724. | _ -> ());
  725. TInst (mk_class null_module ([],name) Ast.null_pos,[])
  726. ) l1 l2 in
  727. List.iter (fun f -> f monos) !to_check;
  728. apply_params l1 monos t1, apply_params l2 monos t2
  729. | _ ->
  730. (* ignore type params, will create other errors later *)
  731. t1, t2
  732. ) in
  733. match f1.cf_kind,f2.cf_kind with
  734. | Method m1, Method m2 when not (m1 = MethDynamic) && not (m2 = MethDynamic) ->
  735. begin match follow t1, follow t2 with
  736. | TFun (args1,r1) , TFun (args2,r2) -> (
  737. if not (List.length args1 = List.length args2) then raise (Unify_error [Unify_custom "Different number of function arguments"]);
  738. try
  739. List.iter2 (fun (n,o1,a1) (_,o2,a2) ->
  740. if o1 <> o2 then raise (Unify_error [Not_matching_optional n]);
  741. (try valid a2 a1 with Unify_error _ -> raise (Unify_error [Cannot_unify(a1,a2)]))
  742. ) args1 args2;
  743. valid r1 r2
  744. with Unify_error l ->
  745. raise (Unify_error (Cannot_unify (t1,t2) :: l)))
  746. | _ ->
  747. assert false
  748. end
  749. | _,(Var { v_write = AccNo | AccNever }) ->
  750. (* write variance *)
  751. valid t1 t2
  752. | _,(Var { v_read = AccNo | AccNever }) ->
  753. (* read variance *)
  754. valid t2 t1
  755. | _ , _ ->
  756. (* in case args differs, or if an interface var *)
  757. type_eq EqStrict t1 t2;
  758. if is_null t1 <> is_null t2 then raise (Unify_error [Cannot_unify (t1,t2)])
  759. let copy_meta meta_src meta_target sl =
  760. let meta = ref meta_target in
  761. List.iter (fun (m,e,p) ->
  762. if List.mem m sl then meta := (m,e,p) :: !meta
  763. ) meta_src;
  764. !meta
  765. let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
  766. let get_vmtype = match get_vmtype with
  767. | None -> (fun f -> f)
  768. | Some f -> f
  769. in
  770. if List.length f1.cf_params <> List.length f2.cf_params then
  771. false
  772. else
  773. let rec follow_skip_null t = match t with
  774. | TMono r ->
  775. (match !r with
  776. | Some t -> follow_skip_null t
  777. | _ -> t)
  778. | TLazy f ->
  779. follow_skip_null (!f())
  780. | TType ({ t_path = [],"Null" } as t, [p]) ->
  781. TType(t,[follow p])
  782. | TType (t,tl) ->
  783. follow_skip_null (apply_params t.t_params tl t.t_type)
  784. | _ -> t
  785. in
  786. let same_arg t1 t2 =
  787. let t1 = get_vmtype (follow_skip_null t1) in
  788. let t2 = get_vmtype (follow_skip_null t2) in
  789. match t1, t2 with
  790. | TType _, TType _ -> type_iseq t1 t2
  791. | TType _, _
  792. | _, TType _ -> false
  793. | _ -> type_iseq t1 t2
  794. in
  795. match follow (apply_params f1.cf_params (List.map (fun (_,t) -> t) f2.cf_params) t1), follow t2 with
  796. | TFun(a1,_), TFun(a2,_) ->
  797. (try
  798. List.for_all2 (fun (_,_,t1) (_,_,t2) ->
  799. same_arg t1 t2) a1 a2
  800. with | Invalid_argument("List.for_all2") ->
  801. false)
  802. | _ -> assert false
  803. (** retrieves all overloads from class c and field i, as (Type.t * tclass_field) list *)
  804. let rec get_overloads c i =
  805. let ret = try
  806. let f = PMap.find i c.cl_fields in
  807. match f.cf_kind with
  808. | Var _ ->
  809. (* @:libType may generate classes that have a variable field in a superclass of an overloaded method *)
  810. []
  811. | Method _ ->
  812. (f.cf_type, f) :: (List.map (fun f -> f.cf_type, f) f.cf_overloads)
  813. with | Not_found -> []
  814. in
  815. let rsup = match c.cl_super with
  816. | None when c.cl_interface ->
  817. let ifaces = List.concat (List.map (fun (c,tl) ->
  818. List.map (fun (t,f) -> apply_params c.cl_params tl t, f) (get_overloads c i)
  819. ) c.cl_implements) in
  820. ret @ ifaces
  821. | None -> ret
  822. | Some (c,tl) ->
  823. ret @ ( List.map (fun (t,f) -> apply_params c.cl_params tl t, f) (get_overloads c i) )
  824. in
  825. ret @ (List.filter (fun (t,f) -> not (List.exists (fun (t2,f2) -> same_overload_args t t2 f f2) ret)) rsup)
  826. let check_overloads ctx c =
  827. (* check if field with same signature was declared more than once *)
  828. List.iter (fun f ->
  829. if Meta.has Meta.Overload f.cf_meta then
  830. List.iter (fun f2 ->
  831. try
  832. ignore (List.find (fun f3 -> f3 != f2 && same_overload_args f2.cf_type f3.cf_type f2 f3) (f :: f.cf_overloads));
  833. display_error ctx ("Another overloaded field of same signature was already declared : " ^ f2.cf_name) f2.cf_pos
  834. with | Not_found -> ()
  835. ) (f :: f.cf_overloads)) (c.cl_ordered_fields @ c.cl_ordered_statics)
  836. let check_overriding ctx c =
  837. match c.cl_super with
  838. | None ->
  839. (match c.cl_overrides with
  840. | [] -> ()
  841. | i :: _ ->
  842. display_error ctx ("Field " ^ i.cf_name ^ " is declared 'override' but doesn't override any field") i.cf_pos)
  843. | _ when c.cl_extern && Meta.has Meta.CsNative c.cl_meta -> () (* -net-lib specific: do not check overrides on extern CsNative classes *)
  844. | Some (csup,params) ->
  845. PMap.iter (fun i f ->
  846. let p = f.cf_pos in
  847. let check_field f get_super_field is_overload = try
  848. (if is_overload && not (Meta.has Meta.Overload f.cf_meta) then
  849. display_error ctx ("Missing @:overload declaration for field " ^ i) p);
  850. let t, f2 = get_super_field csup i in
  851. (* allow to define fields that are not defined for this platform version in superclass *)
  852. (match f2.cf_kind with
  853. | Var { v_read = AccRequire _ } -> raise Not_found;
  854. | _ -> ());
  855. if ctx.com.config.pf_overload && (Meta.has Meta.Overload f2.cf_meta && not (Meta.has Meta.Overload f.cf_meta)) then
  856. display_error ctx ("Field " ^ i ^ " should be declared with @:overload since it was already declared as @:overload in superclass") p
  857. else if not (List.memq f c.cl_overrides) then
  858. display_error ctx ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass " ^ Ast.s_type_path csup.cl_path) p
  859. else if not f.cf_public && f2.cf_public then
  860. display_error ctx ("Field " ^ i ^ " has less visibility (public/private) than superclass one") p
  861. else (match f.cf_kind, f2.cf_kind with
  862. | _, Method MethInline ->
  863. display_error ctx ("Field " ^ i ^ " is inlined and cannot be overridden") p
  864. | a, b when a = b -> ()
  865. | Method MethInline, Method MethNormal ->
  866. () (* allow to redefine a method as inlined *)
  867. | _ ->
  868. display_error ctx ("Field " ^ i ^ " has different property access than in superclass") p);
  869. if has_meta Meta.Final f2.cf_meta then display_error ctx ("Cannot override @:final method " ^ i) p;
  870. try
  871. let t = apply_params csup.cl_params params t in
  872. valid_redefinition ctx f f.cf_type f2 t
  873. with
  874. Unify_error l ->
  875. display_error ctx ("Field " ^ i ^ " overloads parent class with different or incomplete type") p;
  876. display_error ctx ("Base field is defined here") f2.cf_pos;
  877. display_error ctx (error_msg (Unify l)) p;
  878. with
  879. Not_found ->
  880. if List.memq f c.cl_overrides then
  881. let msg = if is_overload then
  882. ("Field " ^ i ^ " is declared 'override' but no compatible overload was found")
  883. else
  884. ("Field " ^ i ^ " is declared 'override' but doesn't override any field")
  885. in
  886. display_error ctx msg p
  887. in
  888. if ctx.com.config.pf_overload && Meta.has Meta.Overload f.cf_meta then begin
  889. let overloads = get_overloads csup i in
  890. List.iter (fun (t,f2) ->
  891. (* check if any super class fields are vars *)
  892. match f2.cf_kind with
  893. | Var _ ->
  894. display_error ctx ("A variable named '" ^ f2.cf_name ^ "' was already declared in a superclass") f.cf_pos
  895. | _ -> ()
  896. ) overloads;
  897. List.iter (fun f ->
  898. (* find the exact field being overridden *)
  899. check_field f (fun csup i ->
  900. List.find (fun (t,f2) ->
  901. same_overload_args f.cf_type (apply_params csup.cl_params params t) f f2
  902. ) overloads
  903. ) true
  904. ) (f :: f.cf_overloads)
  905. end else
  906. check_field f (fun csup i ->
  907. let _, t, f2 = raw_class_field (fun f -> f.cf_type) csup params i in
  908. t, f2) false
  909. ) c.cl_fields
  910. let class_field_no_interf c i =
  911. try
  912. let f = PMap.find i c.cl_fields in
  913. f.cf_type , f
  914. with Not_found ->
  915. match c.cl_super with
  916. | None ->
  917. raise Not_found
  918. | Some (c,tl) ->
  919. (* rec over class_field *)
  920. let _, t , f = raw_class_field (fun f -> f.cf_type) c tl i in
  921. apply_params c.cl_params tl t , f
  922. let rec return_flow ctx e =
  923. let error() =
  924. display_error ctx (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.ret)) e.epos; raise Exit
  925. in
  926. let return_flow = return_flow ctx in
  927. let rec uncond e = match e.eexpr with
  928. | TIf _ | TWhile _ | TSwitch _ | TTry _ | TFunction _ -> ()
  929. | TReturn _ | TThrow _ -> raise Exit
  930. | _ -> Type.iter uncond e
  931. in
  932. let has_unconditional_flow e = try uncond e; false with Exit -> true in
  933. match e.eexpr with
  934. | TReturn _ | TThrow _ -> ()
  935. | TParenthesis e | TMeta(_,e) ->
  936. return_flow e
  937. | TBlock el ->
  938. let rec loop = function
  939. | [] -> error()
  940. | [e] -> return_flow e
  941. | e :: _ when has_unconditional_flow e -> ()
  942. | _ :: l -> loop l
  943. in
  944. loop el
  945. | TIf (_,e1,Some e2) ->
  946. return_flow e1;
  947. return_flow e2;
  948. | TSwitch (v,cases,Some e) ->
  949. List.iter (fun (_,e) -> return_flow e) cases;
  950. return_flow e
  951. | TSwitch ({eexpr = TMeta((Meta.Exhaustive,_,_),_)},cases,None) ->
  952. List.iter (fun (_,e) -> return_flow e) cases;
  953. | TTry (e,cases) ->
  954. return_flow e;
  955. List.iter (fun (_,e) -> return_flow e) cases;
  956. | TWhile({eexpr = (TConst (TBool true))},e,_) ->
  957. (* a special case for "inifite" while loops that have no break *)
  958. let rec loop e = match e.eexpr with
  959. (* ignore nested loops to not accidentally get one of its breaks *)
  960. | TWhile _ | TFor _ -> ()
  961. | TBreak -> error()
  962. | _ -> Type.iter loop e
  963. in
  964. loop e
  965. | _ ->
  966. error()
  967. (* ---------------------------------------------------------------------- *)
  968. (* PASS 1 & 2 : Module and Class Structure *)
  969. let is_generic_parameter ctx c =
  970. (* first check field parameters, then class parameters *)
  971. try
  972. ignore (List.assoc (snd c.cl_path) ctx.curfield.cf_params);
  973. Meta.has Meta.Generic ctx.curfield.cf_meta
  974. with Not_found -> try
  975. ignore(List.assoc (snd c.cl_path) ctx.type_params);
  976. (match ctx.curclass.cl_kind with | KGeneric -> true | _ -> false);
  977. with Not_found ->
  978. false
  979. let type_function_arg_value ctx t c =
  980. match c with
  981. | None -> None
  982. | Some e ->
  983. let p = pos e in
  984. let e = ctx.g.do_optimize ctx (type_expr ctx e (WithType t)) in
  985. unify ctx e.etype t p;
  986. let rec loop e = match e.eexpr with
  987. | TConst c -> Some c
  988. | TCast(e,None) -> loop e
  989. | _ -> display_error ctx "Parameter default value should be constant" p; None
  990. in
  991. loop e
  992. (**** strict meta ****)
  993. let get_native_repr md pos =
  994. let path, meta = match md with
  995. | TClassDecl cl -> cl.cl_path, cl.cl_meta
  996. | TEnumDecl e -> e.e_path, e.e_meta
  997. | TTypeDecl t -> t.t_path, t.t_meta
  998. | TAbstractDecl a -> a.a_path, a.a_meta
  999. in
  1000. let rec loop acc = function
  1001. | (Meta.JavaCanonical,[EConst(String pack),_; EConst(String name),_],_) :: _ ->
  1002. ExtString.String.nsplit pack ".", name
  1003. | (Meta.Native,[EConst(String name),_],_) :: meta ->
  1004. loop (Ast.parse_path name) meta
  1005. | _ :: meta ->
  1006. loop acc meta
  1007. | [] ->
  1008. acc
  1009. in
  1010. let pack, name = loop path meta in
  1011. match pack with
  1012. | [] ->
  1013. (EConst(Ident(name)), pos)
  1014. | hd :: tl ->
  1015. let rec loop pack expr = match pack with
  1016. | hd :: tl ->
  1017. loop tl (EField(expr,hd),pos)
  1018. | [] ->
  1019. (EField(expr,name),pos)
  1020. in
  1021. loop tl (EConst(Ident(hd)),pos)
  1022. let rec process_meta_argument ?(toplevel=true) ctx expr = match expr.eexpr with
  1023. | TField(e,f) ->
  1024. (EField(process_meta_argument ~toplevel:false ctx e,field_name f),expr.epos)
  1025. | TConst(TInt i) ->
  1026. (EConst(Int (Int32.to_string i)), expr.epos)
  1027. | TConst(TFloat f) ->
  1028. (EConst(Float f), expr.epos)
  1029. | TConst(TString s) ->
  1030. (EConst(String s), expr.epos)
  1031. | TConst TNull ->
  1032. (EConst(Ident "null"), expr.epos)
  1033. | TConst(TBool b) ->
  1034. (EConst(Ident (string_of_bool b)), expr.epos)
  1035. | TCast(e,_) | TMeta(_,e) | TParenthesis(e) ->
  1036. process_meta_argument ~toplevel ctx e
  1037. | TTypeExpr md when toplevel ->
  1038. let p = expr.epos in
  1039. if ctx.com.platform = Cs then
  1040. (ECall( (EConst(Ident "typeof"), p), [get_native_repr md expr.epos] ), p)
  1041. else
  1042. (EField(get_native_repr md expr.epos, "class"), p)
  1043. | TTypeExpr md ->
  1044. get_native_repr md expr.epos
  1045. | _ ->
  1046. display_error ctx "This expression is too complex to be a strict metadata argument" expr.epos;
  1047. (EConst(Ident "null"), expr.epos)
  1048. let make_meta ctx texpr extra =
  1049. match texpr.eexpr with
  1050. | TNew(c,_,el) ->
  1051. ECall(get_native_repr (TClassDecl c) texpr.epos, (List.map (process_meta_argument ctx) el) @ extra), texpr.epos
  1052. | TTypeExpr(md) ->
  1053. ECall(get_native_repr md texpr.epos, extra), texpr.epos
  1054. | _ ->
  1055. display_error ctx "Unexpected expression" texpr.epos; assert false
  1056. let field_to_type_path ctx e =
  1057. let rec loop e pack name = match e with
  1058. | EField(e,f),p when Char.lowercase (String.get f 0) <> String.get f 0 -> (match name with
  1059. | [] | _ :: [] ->
  1060. loop e pack (f :: name)
  1061. | _ -> (* too many name paths *)
  1062. display_error ctx ("Unexpected " ^ f) p;
  1063. raise Exit)
  1064. | EField(e,f),_ ->
  1065. loop e (f :: pack) name
  1066. | EConst(Ident f),_ ->
  1067. let pack, name, sub = match name with
  1068. | [] ->
  1069. let fchar = String.get f 0 in
  1070. if Char.uppercase fchar = fchar then
  1071. pack, f, None
  1072. else begin
  1073. display_error ctx "A class name must start with an uppercase character" (snd e);
  1074. raise Exit
  1075. end
  1076. | [name] ->
  1077. f :: pack, name, None
  1078. | [name; sub] ->
  1079. f :: pack, name, Some sub
  1080. | _ ->
  1081. assert false
  1082. in
  1083. { tpackage=pack; tname=name; tparams=[]; tsub=sub }
  1084. | _,pos ->
  1085. display_error ctx "Unexpected expression when building strict meta" pos;
  1086. raise Exit
  1087. in
  1088. loop e [] []
  1089. let handle_fields ctx fields_to_check with_type_expr =
  1090. List.map (fun (name,expr) ->
  1091. let pos = snd expr in
  1092. let field = (EField(with_type_expr,name), pos) in
  1093. let fieldexpr = (EConst(Ident name),pos) in
  1094. let left_side = match ctx.com.platform with
  1095. | Cs -> field
  1096. | Java -> (ECall(field,[]),pos)
  1097. | _ -> assert false
  1098. in
  1099. let left = type_expr ctx left_side NoValue in
  1100. let right = type_expr ctx expr (WithType left.etype) in
  1101. unify ctx left.etype right.etype (snd expr);
  1102. (EBinop(Ast.OpAssign,fieldexpr,process_meta_argument ctx right), pos)
  1103. ) fields_to_check
  1104. let get_strict_meta ctx params pos =
  1105. let pf = ctx.com.platform in
  1106. let changed_expr, fields_to_check, ctype = match params with
  1107. | [ECall(ef, el),p] ->
  1108. (* check last argument *)
  1109. let el, fields = match List.rev el with
  1110. | (EObjectDecl(decl),_) :: el ->
  1111. List.rev el, decl
  1112. | _ ->
  1113. el, []
  1114. in
  1115. let tpath = field_to_type_path ctx ef in
  1116. if pf = Cs then
  1117. (ENew(tpath, el), p), fields, CTPath tpath
  1118. else
  1119. ef, fields, CTPath tpath
  1120. | [EConst(Ident i),p as expr] ->
  1121. let tpath = { tpackage=[]; tname=i; tparams=[]; tsub=None } in
  1122. if pf = Cs then
  1123. (ENew(tpath, []), p), [], CTPath tpath
  1124. else
  1125. expr, [], CTPath tpath
  1126. | [ (EField(_),p as field) ] ->
  1127. let tpath = field_to_type_path ctx field in
  1128. if pf = Cs then
  1129. (ENew(tpath, []), p), [], CTPath tpath
  1130. else
  1131. field, [], CTPath tpath
  1132. | _ ->
  1133. display_error ctx "A @:strict metadata must contain exactly one parameter. Please check the documentation for more information" pos;
  1134. raise Exit
  1135. in
  1136. let texpr = type_expr ctx changed_expr NoValue in
  1137. let with_type_expr = (ECheckType( (EConst (Ident "null"), pos), ctype ), pos) in
  1138. let extra = handle_fields ctx fields_to_check with_type_expr in
  1139. Meta.Meta, [make_meta ctx texpr extra], pos
  1140. let check_strict_meta ctx metas =
  1141. let pf = ctx.com.platform in
  1142. match pf with
  1143. | Cs | Java ->
  1144. let ret = ref [] in
  1145. List.iter (function
  1146. | Meta.Strict,params,pos -> (try
  1147. ret := get_strict_meta ctx params pos :: !ret
  1148. with | Exit -> ())
  1149. | _ -> ()
  1150. ) metas;
  1151. !ret
  1152. | _ -> []
  1153. (**** end of strict meta handling *****)
  1154. let add_constructor ctx c force_constructor p =
  1155. match c.cl_constructor, c.cl_super with
  1156. | None, Some ({ cl_constructor = Some cfsup } as csup,cparams) when not c.cl_extern ->
  1157. let cf = {
  1158. cfsup with
  1159. cf_pos = p;
  1160. cf_meta = List.filter (fun (m,_,_) -> m = Meta.CompilerGenerated) cfsup.cf_meta;
  1161. cf_doc = None;
  1162. cf_expr = None;
  1163. } in
  1164. let r = exc_protect ctx (fun r ->
  1165. let t = mk_mono() in
  1166. r := (fun() -> t);
  1167. let ctx = { ctx with
  1168. curfield = cf;
  1169. pass = PTypeField;
  1170. } in
  1171. ignore (follow cfsup.cf_type); (* make sure it's typed *)
  1172. (if ctx.com.config.pf_overload then List.iter (fun cf -> ignore (follow cf.cf_type)) cf.cf_overloads);
  1173. let map_arg (v,def) =
  1174. (*
  1175. let's optimize a bit the output by not always copying the default value
  1176. into the inherited constructor when it's not necessary for the platform
  1177. *)
  1178. match ctx.com.platform, def with
  1179. | _, Some _ when not ctx.com.config.pf_static -> v, (Some TNull)
  1180. | Flash, Some (TString _) -> v, (Some TNull)
  1181. | Cpp, Some (TString _) -> v, def
  1182. | Cpp, Some _ -> { v with v_type = ctx.t.tnull v.v_type }, (Some TNull)
  1183. | _ -> v, def
  1184. in
  1185. let args = (match cfsup.cf_expr with
  1186. | Some { eexpr = TFunction f } ->
  1187. List.map map_arg f.tf_args
  1188. | _ ->
  1189. let values = get_value_meta cfsup.cf_meta in
  1190. match follow cfsup.cf_type with
  1191. | TFun (args,_) ->
  1192. List.map (fun (n,o,t) ->
  1193. let def = try type_function_arg_value ctx t (Some (PMap.find n values)) with Not_found -> if o then Some TNull else None in
  1194. map_arg (alloc_var n (if o then ctx.t.tnull t else t) p,def) (* TODO: var pos *)
  1195. ) args
  1196. | _ -> assert false
  1197. ) in
  1198. let p = c.cl_pos in
  1199. let vars = List.map (fun (v,def) -> alloc_var v.v_name (apply_params csup.cl_params cparams v.v_type) v.v_pos, def) args in
  1200. let super_call = mk (TCall (mk (TConst TSuper) (TInst (csup,cparams)) p,List.map (fun (v,_) -> mk (TLocal v) v.v_type p) vars)) ctx.t.tvoid p in
  1201. let constr = mk (TFunction {
  1202. tf_args = vars;
  1203. tf_type = ctx.t.tvoid;
  1204. tf_expr = super_call;
  1205. }) (TFun (List.map (fun (v,c) -> v.v_name, c <> None, v.v_type) vars,ctx.t.tvoid)) p in
  1206. cf.cf_expr <- Some constr;
  1207. cf.cf_type <- t;
  1208. unify ctx t constr.etype p;
  1209. t
  1210. ) "add_constructor" in
  1211. cf.cf_type <- TLazy r;
  1212. c.cl_constructor <- Some cf;
  1213. delay ctx PForce (fun() -> ignore((!r)()));
  1214. | None,_ when force_constructor ->
  1215. let constr = mk (TFunction {
  1216. tf_args = [];
  1217. tf_type = ctx.t.tvoid;
  1218. tf_expr = mk (TBlock []) ctx.t.tvoid p;
  1219. }) (tfun [] ctx.t.tvoid) p in
  1220. let cf = mk_field "new" constr.etype p in
  1221. cf.cf_expr <- Some constr;
  1222. cf.cf_type <- constr.etype;
  1223. cf.cf_meta <- [Meta.CompilerGenerated,[],p];
  1224. cf.cf_kind <- Method MethNormal;
  1225. c.cl_constructor <- Some cf;
  1226. | _ ->
  1227. (* nothing to do *)
  1228. ()
  1229. let check_struct_init_constructor ctx c p = match c.cl_constructor with
  1230. | Some _ ->
  1231. ()
  1232. | None ->
  1233. let params = List.map snd c.cl_params in
  1234. let ethis = mk (TConst TThis) (TInst(c,params)) p in
  1235. let args,el,tl = List.fold_left (fun (args,el,tl) cf -> match cf.cf_kind with
  1236. | Var _ ->
  1237. let opt = Meta.has Meta.Optional cf.cf_meta in
  1238. let t = if opt then ctx.t.tnull cf.cf_type else cf.cf_type in
  1239. let v = alloc_var cf.cf_name t p in
  1240. let ef = mk (TField(ethis,FInstance(c,params,cf))) t p in
  1241. let ev = mk (TLocal v) v.v_type p in
  1242. let e = mk (TBinop(OpAssign,ef,ev)) ev.etype p in
  1243. (v,None) :: args,e :: el,(cf.cf_name,opt,t) :: tl
  1244. | Method _ ->
  1245. args,el,tl
  1246. ) ([],[],[]) (List.rev c.cl_ordered_fields) in
  1247. let tf = {
  1248. tf_args = args;
  1249. tf_type = ctx.t.tvoid;
  1250. tf_expr = mk (TBlock el) ctx.t.tvoid p
  1251. } in
  1252. let e = mk (TFunction tf) (TFun(tl,ctx.t.tvoid)) p in
  1253. let cf = mk_field "new" e.etype p in
  1254. cf.cf_expr <- Some e;
  1255. cf.cf_type <- e.etype;
  1256. cf.cf_meta <- [Meta.CompilerGenerated,[],p];
  1257. cf.cf_kind <- Method MethNormal;
  1258. c.cl_constructor <- Some cf
  1259. module Inheritance = struct
  1260. let check_extends ctx c t p = match follow t with
  1261. | TInst ({ cl_path = [],"Array"; cl_extern = basic_extern },_)
  1262. | TInst ({ cl_path = [],"String"; cl_extern = basic_extern },_)
  1263. | TInst ({ cl_path = [],"Date"; cl_extern = basic_extern },_)
  1264. | TInst ({ cl_path = [],"Xml"; cl_extern = basic_extern },_) when not (c.cl_extern && basic_extern) ->
  1265. error "Cannot extend basic class" p;
  1266. | TInst (csup,params) ->
  1267. if is_parent c csup then error "Recursive class" p;
  1268. begin match csup.cl_kind with
  1269. | KTypeParameter _ when not (is_generic_parameter ctx csup) -> error "Cannot extend non-generic type parameters" p
  1270. | _ -> csup,params
  1271. end
  1272. | _ -> error "Should extend by using a class" p
  1273. let rec check_interface ctx c intf params =
  1274. let p = c.cl_pos in
  1275. let rec check_field i f =
  1276. (if ctx.com.config.pf_overload then
  1277. List.iter (function
  1278. | f2 when f != f2 ->
  1279. check_field i f2
  1280. | _ -> ()) f.cf_overloads);
  1281. let is_overload = ref false in
  1282. try
  1283. let t2, f2 = class_field_no_interf c i in
  1284. let t2, f2 =
  1285. if ctx.com.config.pf_overload && (f2.cf_overloads <> [] || Meta.has Meta.Overload f2.cf_meta) then
  1286. let overloads = get_overloads c i in
  1287. is_overload := true;
  1288. let t = (apply_params intf.cl_params params f.cf_type) in
  1289. List.find (fun (t1,f1) -> same_overload_args t t1 f f1) overloads
  1290. else
  1291. t2, f2
  1292. in
  1293. ignore(follow f2.cf_type); (* force evaluation *)
  1294. let p = (match f2.cf_expr with None -> p | Some e -> e.epos) in
  1295. let mkind = function
  1296. | MethNormal | MethInline -> 0
  1297. | MethDynamic -> 1
  1298. | MethMacro -> 2
  1299. in
  1300. if f.cf_public && not f2.cf_public && not (Meta.has Meta.CompilerGenerated f.cf_meta) then
  1301. display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
  1302. else if not (unify_kind f2.cf_kind f.cf_kind) || not (match f.cf_kind, f2.cf_kind with Var _ , Var _ -> true | Method m1, Method m2 -> mkind m1 = mkind m2 | _ -> false) then
  1303. display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path ^ " (" ^ s_kind f2.cf_kind ^ " should be " ^ s_kind f.cf_kind ^ ")") p
  1304. else try
  1305. valid_redefinition ctx f2 t2 f (apply_params intf.cl_params params f.cf_type)
  1306. with
  1307. Unify_error l ->
  1308. if not (Meta.has Meta.CsNative c.cl_meta && c.cl_extern) then begin
  1309. display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
  1310. display_error ctx ("Interface field is defined here") f.cf_pos;
  1311. display_error ctx (error_msg (Unify l)) p;
  1312. end
  1313. with
  1314. | Not_found when not c.cl_interface ->
  1315. let msg = if !is_overload then
  1316. let ctx = print_context() in
  1317. let args = match follow f.cf_type with | TFun(args,_) -> String.concat ", " (List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ " : " ^ (s_type ctx t)) args) | _ -> assert false in
  1318. "No suitable overload for " ^ i ^ "( " ^ args ^ " ), as needed by " ^ s_type_path intf.cl_path ^ " was found"
  1319. else
  1320. ("Field " ^ i ^ " needed by " ^ s_type_path intf.cl_path ^ " is missing")
  1321. in
  1322. display_error ctx msg p
  1323. | Not_found -> ()
  1324. in
  1325. PMap.iter check_field intf.cl_fields;
  1326. List.iter (fun (i2,p2) ->
  1327. check_interface ctx c i2 (List.map (apply_params intf.cl_params params) p2)
  1328. ) intf.cl_implements
  1329. let check_interfaces ctx c =
  1330. match c.cl_path with
  1331. | "Proxy" :: _ , _ -> ()
  1332. | _ when c.cl_extern && Meta.has Meta.CsNative c.cl_meta -> ()
  1333. | _ ->
  1334. List.iter (fun (intf,params) -> check_interface ctx c intf params) c.cl_implements
  1335. let set_heritance ctx c herits p =
  1336. let is_lib = Meta.has Meta.LibType c.cl_meta in
  1337. let ctx = { ctx with curclass = c; type_params = c.cl_params; } in
  1338. let old_meta = c.cl_meta in
  1339. let process_meta csup =
  1340. List.iter (fun m ->
  1341. match m with
  1342. | Meta.Final, _, _ -> if not (Meta.has Meta.Hack c.cl_meta || (match c.cl_kind with KTypeParameter _ -> true | _ -> false)) then error "Cannot extend a final class" p;
  1343. | Meta.AutoBuild, el, p -> c.cl_meta <- (Meta.Build,el,p) :: m :: c.cl_meta
  1344. | _ -> ()
  1345. ) csup.cl_meta
  1346. in
  1347. let check_cancel_build csup =
  1348. match csup.cl_build() with
  1349. | Built -> ()
  1350. | state ->
  1351. (* for macros reason, our super class is not yet built - see #2177 *)
  1352. (* let's reset our build and delay it until we are done *)
  1353. c.cl_meta <- old_meta;
  1354. raise (Build_canceled state)
  1355. in
  1356. let has_interf = ref false in
  1357. (*
  1358. resolve imports before calling build_inheritance, since it requires full paths.
  1359. that means that typedefs are not working, but that's a fair limitation
  1360. *)
  1361. let resolve_imports t =
  1362. match t.tpackage with
  1363. | _ :: _ -> t
  1364. | [] ->
  1365. try
  1366. let find = List.find (fun lt -> snd (t_path lt) = t.tname) in
  1367. let lt = try find ctx.m.curmod.m_types with Not_found -> find ctx.m.module_types in
  1368. { t with tpackage = fst (t_path lt) }
  1369. with
  1370. Not_found -> t
  1371. in
  1372. let herits = ExtList.List.filter_map (function
  1373. | HExtends t -> Some(true,resolve_imports t)
  1374. | HImplements t -> Some(false,resolve_imports t)
  1375. | t -> None
  1376. ) herits in
  1377. let herits = List.filter (ctx.g.do_inherit ctx c p) herits in
  1378. (* Pass 1: Check and set relations *)
  1379. let fl = List.map (fun (is_extends,t) ->
  1380. let t = load_instance ctx t p false in
  1381. if is_extends then begin
  1382. if c.cl_super <> None then error "Cannot extend several classes" p;
  1383. let csup,params = check_extends ctx c t p in
  1384. if c.cl_interface then begin
  1385. if not csup.cl_interface then error "Cannot extend by using a class" p;
  1386. c.cl_implements <- (csup,params) :: c.cl_implements;
  1387. if not !has_interf then begin
  1388. if not is_lib then delay ctx PForce (fun() -> check_interfaces ctx c);
  1389. has_interf := true;
  1390. end
  1391. end else begin
  1392. if csup.cl_interface then error "Cannot extend by using an interface" p;
  1393. c.cl_super <- Some (csup,params)
  1394. end;
  1395. (fun () ->
  1396. check_cancel_build csup;
  1397. process_meta csup;
  1398. )
  1399. end else begin match follow t with
  1400. | TInst ({ cl_path = [],"ArrayAccess"; cl_extern = true; },[t]) ->
  1401. if c.cl_array_access <> None then error "Duplicate array access" p;
  1402. c.cl_array_access <- Some t;
  1403. (fun () -> ())
  1404. | TInst (intf,params) ->
  1405. if is_parent c intf then error "Recursive class" p;
  1406. if c.cl_interface then error "Interfaces cannot implement another interface (use extends instead)" p;
  1407. if not intf.cl_interface then error "You can only implement an interface" p;
  1408. c.cl_implements <- (intf, params) :: c.cl_implements;
  1409. if not !has_interf && not is_lib && not (Meta.has (Meta.Custom "$do_not_check_interf") c.cl_meta) then begin
  1410. delay ctx PForce (fun() -> check_interfaces ctx c);
  1411. has_interf := true;
  1412. end;
  1413. (fun () ->
  1414. check_cancel_build intf;
  1415. process_meta intf;
  1416. )
  1417. | TDynamic t ->
  1418. if c.cl_dynamic <> None then error "Cannot have several dynamics" p;
  1419. c.cl_dynamic <- Some t;
  1420. (fun () -> ())
  1421. | _ ->
  1422. error "Should implement by using an interface" p
  1423. end
  1424. ) herits in
  1425. fl
  1426. end
  1427. let rec type_type_param ?(enum_constructor=false) ctx path get_params p tp =
  1428. let n = tp.tp_name in
  1429. let c = mk_class ctx.m.curmod (fst path @ [snd path],n) p in
  1430. c.cl_params <- type_type_params ctx c.cl_path get_params p tp.tp_params;
  1431. c.cl_kind <- KTypeParameter [];
  1432. c.cl_meta <- tp.Ast.tp_meta;
  1433. if enum_constructor then c.cl_meta <- (Meta.EnumConstructorParam,[],c.cl_pos) :: c.cl_meta;
  1434. let t = TInst (c,List.map snd c.cl_params) in
  1435. match tp.tp_constraints with
  1436. | [] ->
  1437. n, t
  1438. | _ ->
  1439. let r = exc_protect ctx (fun r ->
  1440. r := (fun _ -> t);
  1441. let ctx = { ctx with type_params = ctx.type_params @ get_params() } in
  1442. let constr = List.map (load_complex_type ctx p) tp.tp_constraints in
  1443. (* check against direct recursion *)
  1444. let rec loop t =
  1445. match follow t with
  1446. | TInst (c2,_) when c == c2 -> error "Recursive constraint parameter is not allowed" p
  1447. | TInst ({ cl_kind = KTypeParameter cl },_) ->
  1448. List.iter loop cl
  1449. | _ ->
  1450. ()
  1451. in
  1452. List.iter loop constr;
  1453. c.cl_kind <- KTypeParameter constr;
  1454. t
  1455. ) "constraint" in
  1456. delay ctx PForce (fun () -> ignore(!r()));
  1457. n, TLazy r
  1458. and type_type_params ?(enum_constructor=false) ctx path get_params p tpl =
  1459. let names = ref [] in
  1460. List.map (fun tp ->
  1461. if List.mem tp.tp_name !names then display_error ctx ("Duplicate type parameter name: " ^ tp.tp_name) p;
  1462. names := tp.tp_name :: !names;
  1463. type_type_param ~enum_constructor ctx path get_params p tp
  1464. ) tpl
  1465. let type_function_params ctx fd fname p =
  1466. let params = ref [] in
  1467. params := type_type_params ctx ([],fname) (fun() -> !params) p fd.f_params;
  1468. !params
  1469. module Display = struct
  1470. let is_display_file ctx p = match ctx.com.display with
  1471. | DMNone -> false
  1472. | DMResolve s ->
  1473. let mt = load_type_def ctx p {tname = s; tpackage = []; tsub = None; tparams = []} in
  1474. let p = (t_infos mt).mt_pos in
  1475. raise (DisplayPosition [p]);
  1476. | _ ->
  1477. Common.unique_full_path p.pfile = (!Parser.resume_display).pfile
  1478. let encloses_position p_target p =
  1479. p.pmin <= p_target.pmin && p.pmax >= p_target.pmax
  1480. let find_enclosing com e =
  1481. let display_pos = ref (!Parser.resume_display) in
  1482. let mk_null p = (EDisplay(((EConst(Ident "null")),p),false),p) in
  1483. let encloses_display_pos p =
  1484. if encloses_position !display_pos p then begin
  1485. let p = !display_pos in
  1486. display_pos := { pfile = ""; pmin = -2; pmax = -2 };
  1487. Some p
  1488. end else
  1489. None
  1490. in
  1491. let rec loop e = match fst e with
  1492. | EBlock el ->
  1493. let p = pos e in
  1494. (* We want to find the innermost block which contains the display position. *)
  1495. let el = List.map loop el in
  1496. let el = match encloses_display_pos p with
  1497. | None ->
  1498. el
  1499. | Some p2 ->
  1500. let b,el = List.fold_left (fun (b,el) e ->
  1501. let p = pos e in
  1502. if b || p.pmax <= p2.pmin then begin
  1503. (b,e :: el)
  1504. end else begin
  1505. let e_d = (EDisplay(mk_null p,false)),p in
  1506. (true,e :: e_d :: el)
  1507. end
  1508. ) (false,[]) el in
  1509. let el = if b then
  1510. el
  1511. else begin
  1512. mk_null p :: el
  1513. end in
  1514. List.rev el
  1515. in
  1516. (EBlock el),(pos e)
  1517. | _ ->
  1518. Ast.map_expr loop e
  1519. in
  1520. loop e
  1521. let find_before_pos com e =
  1522. let display_pos = ref (!Parser.resume_display) in
  1523. let is_annotated p =
  1524. if p.pmin <= !display_pos.pmin && p.pmax >= !display_pos.pmax then begin
  1525. display_pos := { pfile = ""; pmin = -2; pmax = -2 };
  1526. true
  1527. end else
  1528. false
  1529. in
  1530. let rec loop e =
  1531. if is_annotated (pos e) then
  1532. (EDisplay(e,false),(pos e))
  1533. else
  1534. e
  1535. in
  1536. let rec map e =
  1537. loop (Ast.map_expr map e)
  1538. in
  1539. map e
  1540. end
  1541. let type_function ctx args ret fmode f do_display p =
  1542. let locals = save_locals ctx in
  1543. let fargs = List.map (fun (n,c,t) ->
  1544. if n.[0] = '$' then error "Function argument names starting with a dollar are not allowed" p;
  1545. let c = type_function_arg_value ctx t c in
  1546. let v,c = add_local ctx n t p, c in (* TODO: var pos *)
  1547. if n = "this" then v.v_meta <- (Meta.This,[],p) :: v.v_meta;
  1548. v,c
  1549. ) args in
  1550. let old_ret = ctx.ret in
  1551. let old_fun = ctx.curfun in
  1552. let old_opened = ctx.opened in
  1553. ctx.curfun <- fmode;
  1554. ctx.ret <- ret;
  1555. ctx.opened <- [];
  1556. let e = match f.f_expr with None -> error "Function body required" p | Some e -> e in
  1557. let e = if not do_display then
  1558. type_expr ctx e NoValue
  1559. else begin
  1560. let e = match ctx.com.display with
  1561. | DMToplevel -> Display.find_enclosing ctx.com e
  1562. | DMPosition | DMUsage | DMType -> Display.find_before_pos ctx.com e
  1563. | _ -> e
  1564. in
  1565. try
  1566. if Common.defined ctx.com Define.NoCOpt then raise Exit;
  1567. type_expr ctx (Optimizer.optimize_completion_expr e) NoValue
  1568. with
  1569. | Parser.TypePath (_,None,_) | Exit ->
  1570. type_expr ctx e NoValue
  1571. | DisplayTypes [t] when (match follow t with TMono _ -> true | _ -> false) ->
  1572. type_expr ctx (if ctx.com.display = DMToplevel then Display.find_enclosing ctx.com e else e) NoValue
  1573. end in
  1574. let e = match e.eexpr with
  1575. | TMeta((Meta.MergeBlock,_,_), ({eexpr = TBlock el} as e1)) -> e1
  1576. | _ -> e
  1577. in
  1578. let has_return e =
  1579. let rec loop e =
  1580. match e.eexpr with
  1581. | TReturn (Some _) -> raise Exit
  1582. | TFunction _ -> ()
  1583. | _ -> Type.iter loop e
  1584. in
  1585. try loop e; false with Exit -> true
  1586. in
  1587. begin match follow ret with
  1588. | TAbstract({a_path=[],"Void"},_) -> ()
  1589. (* We have to check for the presence of return expressions here because
  1590. in the case of Dynamic ctx.ret is still a monomorph. If we indeed
  1591. don't have a return expression we can link the monomorph to Void. We
  1592. can _not_ use type_iseq to avoid the Void check above because that
  1593. would turn Dynamic returns to Void returns. *)
  1594. | TMono t when not (has_return e) -> ignore(link t ret ctx.t.tvoid)
  1595. | _ -> (try return_flow ctx e with Exit -> ())
  1596. end;
  1597. let rec loop e =
  1598. match e.eexpr with
  1599. | TCall ({ eexpr = TConst TSuper },_) -> raise Exit
  1600. | TFunction _ -> ()
  1601. | _ -> Type.iter loop e
  1602. in
  1603. let has_super_constr() =
  1604. match ctx.curclass.cl_super with
  1605. | None ->
  1606. None
  1607. | Some (csup,tl) ->
  1608. try
  1609. let _,cf = get_constructor (fun f->f.cf_type) csup in
  1610. Some (Meta.has Meta.CompilerGenerated cf.cf_meta,TInst(csup,tl))
  1611. with Not_found ->
  1612. None
  1613. in
  1614. let e = if fmode <> FunConstructor then
  1615. e
  1616. else match has_super_constr() with
  1617. | Some (was_forced,t_super) ->
  1618. (try
  1619. loop e;
  1620. if was_forced then
  1621. let e_super = mk (TConst TSuper) t_super e.epos in
  1622. let e_super_call = mk (TCall(e_super,[])) ctx.t.tvoid e.epos in
  1623. concat e_super_call e
  1624. else begin
  1625. display_error ctx "Missing super constructor call" p;
  1626. e
  1627. end
  1628. with
  1629. Exit -> e);
  1630. | None ->
  1631. e
  1632. in
  1633. locals();
  1634. let e = match ctx.curfun, ctx.vthis with
  1635. | (FunMember|FunConstructor), Some v ->
  1636. let ev = mk (TVar (v,Some (mk (TConst TThis) ctx.tthis p))) ctx.t.tvoid p in
  1637. (match e.eexpr with
  1638. | TBlock l -> { e with eexpr = TBlock (ev::l) }
  1639. | _ -> mk (TBlock [ev;e]) e.etype p)
  1640. | _ -> e
  1641. in
  1642. List.iter (fun r -> r := Closed) ctx.opened;
  1643. ctx.ret <- old_ret;
  1644. ctx.curfun <- old_fun;
  1645. ctx.opened <- old_opened;
  1646. e , fargs
  1647. let load_core_class ctx c =
  1648. let ctx2 = (match ctx.g.core_api with
  1649. | None ->
  1650. let com2 = Common.clone ctx.com in
  1651. com2.defines <- PMap.empty;
  1652. Common.define com2 Define.CoreApi;
  1653. Common.define com2 Define.Sys;
  1654. if ctx.in_macro then Common.define com2 Define.Macro;
  1655. com2.class_path <- ctx.com.std_path;
  1656. let ctx2 = ctx.g.do_create com2 in
  1657. ctx.g.core_api <- Some ctx2;
  1658. ctx2
  1659. | Some c ->
  1660. c
  1661. ) in
  1662. let tpath = match c.cl_kind with
  1663. | KAbstractImpl a -> { tpackage = fst a.a_path; tname = snd a.a_path; tparams = []; tsub = None; }
  1664. | _ -> { tpackage = fst c.cl_path; tname = snd c.cl_path; tparams = []; tsub = None; }
  1665. in
  1666. let t = load_instance ctx2 tpath c.cl_pos true in
  1667. flush_pass ctx2 PFinal "core_final";
  1668. match t with
  1669. | TInst (ccore,_) | TAbstract({a_impl = Some ccore}, _) ->
  1670. ccore
  1671. | _ ->
  1672. assert false
  1673. let init_core_api ctx c =
  1674. let ccore = load_core_class ctx c in
  1675. begin try
  1676. List.iter2 (fun (n1,t1) (n2,t2) -> match follow t1, follow t2 with
  1677. | TInst({cl_kind = KTypeParameter l1},_),TInst({cl_kind = KTypeParameter l2},_) ->
  1678. begin try
  1679. List.iter2 (fun t1 t2 -> type_eq EqCoreType t2 t1) l1 l2
  1680. with
  1681. | Invalid_argument _ ->
  1682. error "Type parameters must have the same number of constraints as core type" c.cl_pos
  1683. | Unify_error l ->
  1684. display_error ctx ("Type parameter " ^ n2 ^ " has different constraint than in core type") c.cl_pos;
  1685. display_error ctx (error_msg (Unify l)) c.cl_pos
  1686. end
  1687. | t1,t2 ->
  1688. Printf.printf "%s %s" (s_type (print_context()) t1) (s_type (print_context()) t2);
  1689. assert false
  1690. ) ccore.cl_params c.cl_params;
  1691. with Invalid_argument _ ->
  1692. error "Class must have the same number of type parameters as core type" c.cl_pos
  1693. end;
  1694. (match c.cl_doc with
  1695. | None -> c.cl_doc <- ccore.cl_doc
  1696. | Some _ -> ());
  1697. let compare_fields f f2 =
  1698. let p = (match f2.cf_expr with None -> c.cl_pos | Some e -> e.epos) in
  1699. (try
  1700. type_eq EqCoreType (apply_params ccore.cl_params (List.map snd c.cl_params) f.cf_type) f2.cf_type
  1701. with Unify_error l ->
  1702. display_error ctx ("Field " ^ f.cf_name ^ " has different type than in core type") p;
  1703. display_error ctx (error_msg (Unify l)) p);
  1704. if f2.cf_public <> f.cf_public then error ("Field " ^ f.cf_name ^ " has different visibility than core type") p;
  1705. (match f2.cf_doc with
  1706. | None -> f2.cf_doc <- f.cf_doc
  1707. | Some _ -> ());
  1708. if f2.cf_kind <> f.cf_kind then begin
  1709. match f2.cf_kind, f.cf_kind with
  1710. | Method MethInline, Method MethNormal -> () (* allow to add 'inline' *)
  1711. | Method MethNormal, Method MethInline -> () (* allow to disable 'inline' *)
  1712. | _ ->
  1713. error ("Field " ^ f.cf_name ^ " has different property access than core type") p;
  1714. end;
  1715. (match follow f.cf_type, follow f2.cf_type with
  1716. | TFun (pl1,_), TFun (pl2,_) ->
  1717. if List.length pl1 != List.length pl2 then error "Argument count mismatch" p;
  1718. List.iter2 (fun (n1,_,_) (n2,_,_) ->
  1719. if n1 <> n2 then error ("Method parameter name '" ^ n2 ^ "' should be '" ^ n1 ^ "'") p;
  1720. ) pl1 pl2;
  1721. | _ -> ());
  1722. in
  1723. let check_fields fcore fl =
  1724. PMap.iter (fun i f ->
  1725. if not f.cf_public then () else
  1726. let f2 = try PMap.find f.cf_name fl with Not_found -> error ("Missing field " ^ i ^ " required by core type") c.cl_pos in
  1727. compare_fields f f2;
  1728. ) fcore;
  1729. PMap.iter (fun i f ->
  1730. let p = (match f.cf_expr with None -> c.cl_pos | Some e -> e.epos) in
  1731. if f.cf_public && not (Meta.has Meta.Hack f.cf_meta) && not (PMap.mem f.cf_name fcore) && not (List.memq f c.cl_overrides) then error ("Public field " ^ i ^ " is not part of core type") p;
  1732. ) fl;
  1733. in
  1734. check_fields ccore.cl_fields c.cl_fields;
  1735. check_fields ccore.cl_statics c.cl_statics;
  1736. (match ccore.cl_constructor, c.cl_constructor with
  1737. | None, None -> ()
  1738. | Some { cf_public = false }, _ -> ()
  1739. | Some f, Some f2 -> compare_fields f f2
  1740. | None, Some { cf_public = false } -> ()
  1741. | _ -> error "Constructor differs from core type" c.cl_pos)
  1742. let check_global_metadata ctx f_add mpath tpath so =
  1743. let sl1 = full_dot_path mpath tpath in
  1744. let sl1,field_mode = match so with None -> sl1,false | Some s -> sl1 @ [s],true in
  1745. List.iter (fun (sl2,m,(recursive,to_types,to_fields)) ->
  1746. let add = ((field_mode && to_fields) || (not field_mode && to_types)) && (match_path recursive sl1 sl2) in
  1747. if add then f_add m
  1748. ) ctx.g.global_metadata
  1749. let patch_class ctx c fields =
  1750. let path = match c.cl_kind with
  1751. | KAbstractImpl a -> a.a_path
  1752. | _ -> c.cl_path
  1753. in
  1754. let h = (try Some (Hashtbl.find ctx.g.type_patches path) with Not_found -> None) in
  1755. match h with
  1756. | None -> fields
  1757. | Some (h,hcl) ->
  1758. c.cl_meta <- c.cl_meta @ hcl.tp_meta;
  1759. let rec loop acc = function
  1760. | [] -> acc
  1761. | f :: l ->
  1762. (* patch arguments types *)
  1763. (match f.cff_kind with
  1764. | FFun ff ->
  1765. let param ((n,opt,t,e) as p) =
  1766. try
  1767. let t2 = (try Hashtbl.find h (("$" ^ f.cff_name ^ "__" ^ n),false) with Not_found -> Hashtbl.find h (("$" ^ n),false)) in
  1768. n, opt, t2.tp_type, e
  1769. with Not_found ->
  1770. p
  1771. in
  1772. f.cff_kind <- FFun { ff with f_args = List.map param ff.f_args }
  1773. | _ -> ());
  1774. (* other patches *)
  1775. match (try Some (Hashtbl.find h (f.cff_name,List.mem AStatic f.cff_access)) with Not_found -> None) with
  1776. | None -> loop (f :: acc) l
  1777. | Some { tp_remove = true } -> loop acc l
  1778. | Some p ->
  1779. f.cff_meta <- f.cff_meta @ p.tp_meta;
  1780. (match p.tp_type with
  1781. | None -> ()
  1782. | Some t ->
  1783. f.cff_kind <- match f.cff_kind with
  1784. | FVar (_,e) -> FVar (Some t,e)
  1785. | FProp (get,set,_,eo) -> FProp (get,set,Some t,eo)
  1786. | FFun f -> FFun { f with f_type = Some t });
  1787. loop (f :: acc) l
  1788. in
  1789. List.rev (loop [] fields)
  1790. let string_list_of_expr_path (e,p) =
  1791. try string_list_of_expr_path_raise (e,p)
  1792. with Exit -> error "Invalid path" p
  1793. let build_enum_abstract ctx c a fields p =
  1794. List.iter (fun field ->
  1795. match field.cff_kind with
  1796. | FVar(ct,eo) when not (List.mem AStatic field.cff_access) ->
  1797. field.cff_access <- [AStatic; if (List.mem APrivate field.cff_access) then APrivate else APublic];
  1798. field.cff_meta <- (Meta.Enum,[],field.cff_pos) :: (Meta.Impl,[],field.cff_pos) :: field.cff_meta;
  1799. let ct = match ct with
  1800. | Some _ -> ct
  1801. | None -> Some (TExprToExpr.convert_type (TAbstract(a,List.map snd a.a_params)))
  1802. in
  1803. begin match eo with
  1804. | None ->
  1805. if not c.cl_extern then error "Value required" field.cff_pos
  1806. else field.cff_kind <- FProp("default","never",ct,None)
  1807. | Some e ->
  1808. field.cff_access <- AInline :: field.cff_access;
  1809. let e = (ECast(e,None),field.cff_pos) in
  1810. field.cff_kind <- FVar(ct,Some e)
  1811. end
  1812. | _ ->
  1813. ()
  1814. ) fields;
  1815. EVars ["",Some (CTAnonymous fields),None],p
  1816. let is_java_native_function meta = try
  1817. match Meta.get Meta.Native meta with
  1818. | (Meta.Native,[],_) -> true
  1819. | _ -> false
  1820. with | Not_found -> false
  1821. let build_module_def ctx mt meta fvars context_init fbuild =
  1822. let loop (f_build,f_enum) = function
  1823. | Meta.Build,args,p -> (fun () ->
  1824. let epath, el = (match args with
  1825. | [ECall (epath,el),p] -> epath, el
  1826. | _ -> error "Invalid build parameters" p
  1827. ) in
  1828. let s = try String.concat "." (List.rev (string_list_of_expr_path epath)) with Error (_,p) -> error "Build call parameter must be a class path" p in
  1829. if ctx.in_macro then error "You cannot use @:build inside a macro : make sure that your enum is not used in macro" p;
  1830. let old = ctx.g.get_build_infos in
  1831. ctx.g.get_build_infos <- (fun() -> Some (mt, List.map snd (t_infos mt).mt_params, fvars()));
  1832. context_init();
  1833. let r = try apply_macro ctx MBuild s el p with e -> ctx.g.get_build_infos <- old; raise e in
  1834. ctx.g.get_build_infos <- old;
  1835. (match r with
  1836. | None -> error "Build failure" p
  1837. | Some e -> fbuild e)
  1838. ) :: f_build,f_enum
  1839. | Meta.Enum,_,p -> f_build,Some (fun () ->
  1840. begin match mt with
  1841. | TClassDecl ({cl_kind = KAbstractImpl a} as c) ->
  1842. context_init();
  1843. let e = build_enum_abstract ctx c a (fvars()) p in
  1844. fbuild e;
  1845. | _ ->
  1846. ()
  1847. end
  1848. )
  1849. | _ ->
  1850. f_build,f_enum
  1851. in
  1852. (* let errors go through to prevent resume if build fails *)
  1853. let f_build,f_enum = List.fold_left loop ([],None) meta in
  1854. List.iter (fun f -> f()) (List.rev f_build);
  1855. (match f_enum with None -> () | Some f -> f())
  1856. module ClassInitializer = struct
  1857. type class_init_ctx = {
  1858. tclass : tclass; (* I don't trust ctx.curclass because it's mutable. *)
  1859. is_lib : bool;
  1860. is_native : bool;
  1861. is_core_api : bool;
  1862. is_display_file : bool;
  1863. extends_public : bool;
  1864. abstract : tabstract option;
  1865. context_init : unit -> unit;
  1866. completion_position : pos;
  1867. mutable delayed_expr : (typer * (unit -> t) ref option) list;
  1868. mutable force_constructor : bool;
  1869. }
  1870. type field_kind =
  1871. | FKNormal
  1872. | FKConstructor
  1873. | FKInit
  1874. type field_init_ctx = {
  1875. is_inline : bool;
  1876. is_static : bool;
  1877. is_override : bool;
  1878. is_extern : bool;
  1879. is_macro : bool;
  1880. is_abstract_member : bool;
  1881. is_display_field : bool;
  1882. field_kind : field_kind;
  1883. mutable do_bind : bool;
  1884. mutable do_add : bool;
  1885. }
  1886. let create_class_context ctx c context_init p =
  1887. locate_macro_error := true;
  1888. incr stats.s_classes_built;
  1889. let abstract = match c.cl_kind with
  1890. | KAbstractImpl a -> Some a
  1891. | _ -> None
  1892. in
  1893. let ctx = {
  1894. ctx with
  1895. curclass = c;
  1896. type_params = c.cl_params;
  1897. pass = PBuildClass;
  1898. tthis = (match abstract with
  1899. | Some a ->
  1900. (match a.a_this with
  1901. | TMono r when !r = None -> TAbstract (a,List.map snd c.cl_params)
  1902. | t -> t)
  1903. | None -> TInst (c,List.map snd c.cl_params));
  1904. on_error = (fun ctx msg ep ->
  1905. ctx.com.error msg ep;
  1906. (* macros expressions might reference other code, let's recall which class we are actually compiling *)
  1907. if !locate_macro_error && (ep.pfile <> c.cl_pos.pfile || ep.pmax < c.cl_pos.pmin || ep.pmin > c.cl_pos.pmax) then ctx.com.error "Defined in this class" c.cl_pos
  1908. );
  1909. } in
  1910. (* a lib type will skip most checks *)
  1911. let is_lib = Meta.has Meta.LibType c.cl_meta in
  1912. if is_lib && not c.cl_extern then ctx.com.error "@:libType can only be used in extern classes" c.cl_pos;
  1913. (* a native type will skip one check: the static vs non-static field *)
  1914. let is_native = Meta.has Meta.JavaNative c.cl_meta || Meta.has Meta.CsNative c.cl_meta in
  1915. if Meta.has Meta.Macro c.cl_meta then display_error ctx "Macro classes are no longer allowed in haxe 3" c.cl_pos;
  1916. let rec extends_public c =
  1917. Meta.has Meta.PublicFields c.cl_meta ||
  1918. match c.cl_super with
  1919. | None -> false
  1920. | Some (c,_) -> extends_public c
  1921. in
  1922. let is_display_file = Display.is_display_file ctx p in
  1923. let cctx = {
  1924. tclass = c;
  1925. is_lib = is_lib;
  1926. is_native = is_native;
  1927. is_core_api = Meta.has Meta.CoreApi c.cl_meta;
  1928. extends_public = extends_public c;
  1929. is_display_file = is_display_file;
  1930. abstract = abstract;
  1931. context_init = context_init;
  1932. completion_position = !Parser.resume_display;
  1933. force_constructor = false;
  1934. delayed_expr = [];
  1935. } in
  1936. ctx,cctx
  1937. let create_field_context (ctx,cctx) c cff =
  1938. let ctx = {
  1939. ctx with
  1940. pass = PBuildClass; (* will be set later to PTypeExpr *)
  1941. } in
  1942. let is_static = List.mem AStatic cff.cff_access in
  1943. let is_extern = Meta.has Meta.Extern cff.cff_meta || c.cl_extern in
  1944. let allow_inline = cctx.abstract <> None || match cff.cff_kind with
  1945. | FFun _ -> ctx.g.doinline || is_extern
  1946. | _ -> true
  1947. in
  1948. let is_inline = allow_inline && List.mem AInline cff.cff_access in
  1949. let is_override = List.mem AOverride cff.cff_access in
  1950. let is_macro = List.mem AMacro cff.cff_access in
  1951. let field_kind = match cff.cff_name with
  1952. | "new" -> FKConstructor
  1953. | "__init__" when is_static -> FKInit
  1954. | _ -> FKNormal
  1955. in
  1956. let fctx = {
  1957. is_inline = is_inline;
  1958. is_static = is_static;
  1959. is_override = is_override;
  1960. is_macro = is_macro;
  1961. is_extern = is_extern;
  1962. is_display_field = cctx.is_display_file && Display.encloses_position cctx.completion_position cff.cff_pos;
  1963. is_abstract_member = cctx.abstract <> None && Meta.has Meta.Impl cff.cff_meta;
  1964. field_kind = field_kind;
  1965. do_bind = (((not c.cl_extern || is_inline) && not c.cl_interface) || field_kind = FKInit);
  1966. do_add = true;
  1967. } in
  1968. ctx,fctx
  1969. let is_public (ctx,cctx) access parent =
  1970. let c = cctx.tclass in
  1971. if List.mem APrivate access then
  1972. false
  1973. else if List.mem APublic access then
  1974. true
  1975. else match parent with
  1976. | Some { cf_public = p } -> p
  1977. | _ -> c.cl_extern || c.cl_interface || cctx.extends_public
  1978. let rec get_parent c name =
  1979. match c.cl_super with
  1980. | None -> None
  1981. | Some (csup,_) ->
  1982. try
  1983. Some (PMap.find name csup.cl_fields)
  1984. with
  1985. Not_found -> get_parent csup name
  1986. let add_field c cf is_static =
  1987. if is_static then begin
  1988. c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics;
  1989. c.cl_ordered_statics <- cf :: c.cl_ordered_statics;
  1990. end else begin
  1991. c.cl_fields <- PMap.add cf.cf_name cf c.cl_fields;
  1992. c.cl_ordered_fields <- cf :: c.cl_ordered_fields;
  1993. end
  1994. let type_opt (ctx,cctx) p t =
  1995. let c = cctx.tclass in
  1996. match t with
  1997. | None when c.cl_extern || c.cl_interface ->
  1998. display_error ctx "Type required for extern classes and interfaces" p;
  1999. t_dynamic
  2000. | None when cctx.is_core_api ->
  2001. display_error ctx "Type required for core api classes" p;
  2002. t_dynamic
  2003. | _ ->
  2004. load_type_opt ctx p t
  2005. let build_fields (ctx,cctx) c fields =
  2006. let fields = ref fields in
  2007. let get_fields() = !fields in
  2008. let pending = ref [] in
  2009. c.cl_build <- (fun() -> BuildMacro pending);
  2010. build_module_def ctx (TClassDecl c) c.cl_meta get_fields cctx.context_init (fun (e,p) ->
  2011. match e with
  2012. | EVars [_,Some (CTAnonymous f),None] ->
  2013. let f = List.map (fun f ->
  2014. let f = match cctx.abstract with
  2015. | Some a ->
  2016. let a_t = TExprToExpr.convert_type (TAbstract(a,List.map snd a.a_params)) in
  2017. let this_t = TExprToExpr.convert_type a.a_this in
  2018. transform_abstract_field ctx.com this_t a_t a f
  2019. | None ->
  2020. f
  2021. in
  2022. if List.mem AMacro f.cff_access then
  2023. (match ctx.g.macros with
  2024. | Some (_,mctx) when Hashtbl.mem mctx.g.types_module c.cl_path ->
  2025. (* assume that if we had already a macro with the same name, it has not been changed during the @:build operation *)
  2026. if not (List.exists (fun f2 -> f2.cff_name = f.cff_name && List.mem AMacro f2.cff_access) (!fields)) then
  2027. error "Class build macro cannot return a macro function when the class has already been compiled into the macro context" p
  2028. | _ -> ());
  2029. f
  2030. ) f in
  2031. fields := f
  2032. | _ -> error "Class build macro must return a single variable with anonymous fields" p
  2033. );
  2034. c.cl_build <- (fun() -> Building);
  2035. List.iter (fun f -> f()) !pending;
  2036. !fields
  2037. let bind_type (ctx,cctx,fctx) cf r p =
  2038. let c = cctx.tclass in
  2039. let rec is_full_type t =
  2040. match t with
  2041. | TFun (args,ret) -> is_full_type ret && List.for_all (fun (_,_,t) -> is_full_type t) args
  2042. | TMono r -> (match !r with None -> false | Some t -> is_full_type t)
  2043. | TAbstract _ | TInst _ | TEnum _ | TLazy _ | TDynamic _ | TAnon _ | TType _ -> true
  2044. in
  2045. match ctx.com.display with
  2046. | DMNone | DMUsage ->
  2047. if fctx.is_macro && not ctx.in_macro then
  2048. ()
  2049. else begin
  2050. cf.cf_type <- TLazy r;
  2051. (* is_lib ? *)
  2052. cctx.delayed_expr <- (ctx,Some r) :: cctx.delayed_expr;
  2053. end
  2054. | _ ->
  2055. if fctx.is_display_field then begin
  2056. if fctx.is_macro && not ctx.in_macro then
  2057. (* force macro system loading of this class in order to get completion *)
  2058. delay ctx PTypeField (fun() -> ignore(ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name [] p))
  2059. else begin
  2060. cf.cf_type <- TLazy r;
  2061. cctx.delayed_expr <- (ctx,Some r) :: cctx.delayed_expr;
  2062. end
  2063. end else begin
  2064. if not (is_full_type cf.cf_type) then begin
  2065. cctx.delayed_expr <- (ctx, None) :: cctx.delayed_expr;
  2066. cf.cf_type <- TLazy r;
  2067. end;
  2068. end
  2069. let check_display (ctx,fctx) cf p =
  2070. if fctx.is_display_field && not ctx.display_handled then begin
  2071. (* We're in our display field but didn't exit yet, so the position must be on the field itself.
  2072. It could also be one of its arguments, but at the moment we cannot detect that. *)
  2073. match ctx.com.display with
  2074. | DMPosition -> raise (DisplayPosition [cf.cf_pos]);
  2075. | DMUsage -> cf.cf_meta <- (Meta.Usage,[],p) :: cf.cf_meta;
  2076. | DMType -> raise (DisplayTypes [cf.cf_type])
  2077. | _ -> ()
  2078. end
  2079. let bind_var (ctx,cctx,fctx) cf e =
  2080. let c = cctx.tclass in
  2081. let p = cf.cf_pos in
  2082. let rec get_declared f = function
  2083. | None -> None
  2084. | Some (c,a) when PMap.exists f c.cl_fields ->
  2085. Some (c,a)
  2086. | Some (c,_) ->
  2087. let ret = get_declared f c.cl_super in
  2088. match ret with
  2089. | Some r -> Some r
  2090. | None ->
  2091. let rec loop ifaces = match ifaces with
  2092. | [] -> None
  2093. | i :: ifaces -> match get_declared f (Some i) with
  2094. | Some r -> Some r
  2095. | None -> loop ifaces
  2096. in
  2097. loop c.cl_implements
  2098. in
  2099. if not fctx.is_static && not cctx.is_lib then begin match get_declared cf.cf_name c.cl_super with
  2100. | None -> ()
  2101. | Some (csup,_) ->
  2102. (* this can happen on -net-lib generated classes if a combination of explicit interfaces and variables with the same name happens *)
  2103. if not (csup.cl_interface && Meta.has Meta.CsNative c.cl_meta) then
  2104. error ("Redefinition of variable " ^ cf.cf_name ^ " in subclass is not allowed. Previously declared at " ^ (Ast.s_type_path csup.cl_path) ) p
  2105. end;
  2106. let t = cf.cf_type in
  2107. match e with
  2108. | None ->
  2109. check_display (ctx,fctx) cf p
  2110. | Some e ->
  2111. if requires_value_meta ctx.com (Some c) then cf.cf_meta <- ((Meta.Value,[e],cf.cf_pos) :: cf.cf_meta);
  2112. let check_cast e =
  2113. (* insert cast to keep explicit field type (issue #1901) *)
  2114. if type_iseq e.etype cf.cf_type then
  2115. e
  2116. else begin match e.eexpr,follow cf.cf_type with
  2117. | TConst (TInt i),TAbstract({a_path=[],"Float"},_) ->
  2118. (* turn int constant to float constant if expected type is float *)
  2119. {e with eexpr = TConst (TFloat (Int32.to_string i))}
  2120. | _ ->
  2121. mk_cast e cf.cf_type e.epos
  2122. end
  2123. in
  2124. let r = exc_protect ctx (fun r ->
  2125. (* type constant init fields (issue #1956) *)
  2126. if not !return_partial_type || (match fst e with EConst _ -> true | _ -> false) then begin
  2127. r := (fun() -> t);
  2128. cctx.context_init();
  2129. if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.in_macro then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ cf.cf_name);
  2130. let e = type_var_field ctx t e fctx.is_static p in
  2131. let maybe_run_analyzer e = match e.eexpr with
  2132. | TConst _ | TLocal _ | TFunction _ -> e
  2133. | _ -> !analyzer_run_on_expr_ref ctx.com e
  2134. in
  2135. let require_constant_expression e msg =
  2136. if ctx.com.display <> DMNone then
  2137. e
  2138. else match Optimizer.make_constant_expression ctx (maybe_run_analyzer e) with
  2139. | Some e -> e
  2140. | None -> display_error ctx msg p; e
  2141. in
  2142. let e = (match cf.cf_kind with
  2143. | Var v when c.cl_extern || Meta.has Meta.Extern cf.cf_meta ->
  2144. if not fctx.is_static then begin
  2145. display_error ctx "Extern non-static variables may not be initialized" p;
  2146. e
  2147. end else if not fctx.is_inline then begin
  2148. display_error ctx "Extern non-inline variables may not be initialized" p;
  2149. e
  2150. end else require_constant_expression e "Extern variable initialization must be a constant value"
  2151. | Var v when is_extern_field cf ->
  2152. (* disallow initialization of non-physical fields (issue #1958) *)
  2153. display_error ctx "This field cannot be initialized because it is not a real variable" p; e
  2154. | Var v when not fctx.is_static ->
  2155. let e = match Optimizer.make_constant_expression ctx (maybe_run_analyzer e) with
  2156. | Some e -> e
  2157. | None ->
  2158. let rec has_this e = match e.eexpr with
  2159. | TConst TThis ->
  2160. display_error ctx "Cannot access this or other member field in variable initialization" e.epos;
  2161. | TLocal v when (match ctx.vthis with Some v2 -> v == v2 | None -> false) ->
  2162. display_error ctx "Cannot access this or other member field in variable initialization" e.epos;
  2163. | _ ->
  2164. Type.iter has_this e
  2165. in
  2166. has_this e;
  2167. e
  2168. in
  2169. e
  2170. | Var v when v.v_read = AccInline ->
  2171. let e = require_constant_expression e "Inline variable initialization must be a constant value" in
  2172. begin match c.cl_kind with
  2173. | KAbstractImpl a when Meta.has Meta.Enum cf.cf_meta && Meta.has Meta.Enum a.a_meta ->
  2174. unify ctx t (TAbstract(a,(List.map (fun _ -> mk_mono()) a.a_params))) p;
  2175. begin match e.eexpr with
  2176. | TCast(e1,None) -> unify ctx e1.etype a.a_this e1.epos
  2177. | _ -> assert false
  2178. end
  2179. | _ ->
  2180. ()
  2181. end;
  2182. e
  2183. | _ ->
  2184. e
  2185. ) in
  2186. let e = check_cast e in
  2187. check_display (ctx,fctx) cf p;
  2188. cf.cf_expr <- Some e;
  2189. cf.cf_type <- t;
  2190. end;
  2191. t
  2192. ) "bind_var" in
  2193. if not fctx.is_static then cctx.force_constructor <- true;
  2194. bind_type (ctx,cctx,fctx) cf r (snd e)
  2195. let create_variable (ctx,cctx,fctx) c f t eo p =
  2196. if not fctx.is_static && cctx.abstract <> None then error (f.cff_name ^ ": Cannot declare member variable in abstract") p;
  2197. if fctx.is_inline && not fctx.is_static then error (f.cff_name ^ ": Inline variable must be static") p;
  2198. if fctx.is_inline && eo = None then error (f.cff_name ^ ": Inline variable must be initialized") p;
  2199. let t = (match t with
  2200. | None when not fctx.is_static && eo = None ->
  2201. error ("Type required for member variable " ^ f.cff_name) p;
  2202. | None ->
  2203. mk_mono()
  2204. | Some t ->
  2205. (* TODO is_lib: only load complex type if needed *)
  2206. let old = ctx.type_params in
  2207. if fctx.is_static then ctx.type_params <- [];
  2208. let t = load_complex_type ctx p t in
  2209. if fctx.is_static then ctx.type_params <- old;
  2210. t
  2211. ) in
  2212. let cf = {
  2213. cf_name = f.cff_name;
  2214. cf_doc = f.cff_doc;
  2215. cf_meta = f.cff_meta;
  2216. cf_type = t;
  2217. cf_pos = f.cff_pos;
  2218. cf_kind = Var (if fctx.is_inline then { v_read = AccInline ; v_write = AccNever } else { v_read = AccNormal; v_write = AccNormal });
  2219. cf_expr = None;
  2220. cf_public = is_public (ctx,cctx) f.cff_access None;
  2221. cf_params = [];
  2222. cf_overloads = [];
  2223. } in
  2224. ctx.curfield <- cf;
  2225. bind_var (ctx,cctx,fctx) cf eo;
  2226. cf
  2227. let check_abstract (ctx,cctx,fctx) c cf fd t ret p =
  2228. match cctx.abstract with
  2229. | Some a ->
  2230. let m = mk_mono() in
  2231. let ta = TAbstract(a, List.map (fun _ -> mk_mono()) a.a_params) in
  2232. let tthis = if fctx.is_abstract_member || Meta.has Meta.To cf.cf_meta then monomorphs a.a_params a.a_this else a.a_this in
  2233. let allows_no_expr = ref (Meta.has Meta.CoreType a.a_meta) in
  2234. let rec loop ml = match ml with
  2235. | (Meta.From,_,_) :: _ ->
  2236. let r = fun () ->
  2237. (* the return type of a from-function must be the abstract, not the underlying type *)
  2238. if not fctx.is_macro then (try type_eq EqStrict ret ta with Unify_error l -> error (error_msg (Unify l)) p);
  2239. match t with
  2240. | TFun([_,_,t],_) -> t
  2241. | _ -> error (cf.cf_name ^ ": @:from cast functions must accept exactly one argument") p
  2242. in
  2243. a.a_from_field <- (TLazy (ref r),cf) :: a.a_from_field;
  2244. | (Meta.To,_,_) :: _ ->
  2245. if fctx.is_macro then error (cf.cf_name ^ ": Macro cast functions are not supported") p;
  2246. (* TODO: this doesn't seem quite right... *)
  2247. if not (Meta.has Meta.Impl cf.cf_meta) then cf.cf_meta <- (Meta.Impl,[],cf.cf_pos) :: cf.cf_meta;
  2248. let resolve_m args =
  2249. (try unify_raise ctx t (tfun (tthis :: args) m) cf.cf_pos with Error (Unify l,p) -> error (error_msg (Unify l)) p);
  2250. match follow m with
  2251. | TMono _ when (match t with TFun(_,r) -> r == t_dynamic | _ -> false) -> t_dynamic
  2252. | m -> m
  2253. in
  2254. let r = exc_protect ctx (fun r ->
  2255. let args = if Meta.has Meta.MultiType a.a_meta then begin
  2256. let ctor = try
  2257. PMap.find "_new" c.cl_statics
  2258. with Not_found ->
  2259. error "Constructor of multi-type abstract must be defined before the individual @:to-functions are" cf.cf_pos
  2260. in
  2261. (* delay ctx PFinal (fun () -> unify ctx m tthis f.cff_pos); *)
  2262. let args = match follow (monomorphs a.a_params ctor.cf_type) with
  2263. | TFun(args,_) -> List.map (fun (_,_,t) -> t) args
  2264. | _ -> assert false
  2265. in
  2266. args
  2267. end else
  2268. []
  2269. in
  2270. let t = resolve_m args in
  2271. r := (fun() -> t);
  2272. t
  2273. ) "@:to" in
  2274. delay ctx PForce (fun() -> ignore ((!r)()));
  2275. a.a_to_field <- (TLazy r, cf) :: a.a_to_field
  2276. | ((Meta.ArrayAccess,_,_) | (Meta.Op,[(EArrayDecl _),_],_)) :: _ ->
  2277. if fctx.is_macro then error (cf.cf_name ^ ": Macro array-access functions are not supported") p;
  2278. a.a_array <- cf :: a.a_array;
  2279. | (Meta.Op,[EBinop(op,_,_),_],_) :: _ ->
  2280. if fctx.is_macro then error (cf.cf_name ^ ": Macro operator functions are not supported") p;
  2281. let targ = if fctx.is_abstract_member then tthis else ta in
  2282. let left_eq,right_eq = match follow t with
  2283. | TFun([(_,_,t1);(_,_,t2)],_) ->
  2284. type_iseq targ t1,type_iseq targ t2
  2285. | _ ->
  2286. if fctx.is_abstract_member then
  2287. error (cf.cf_name ^ ": Member @:op functions must accept exactly one argument") cf.cf_pos
  2288. else
  2289. error (cf.cf_name ^ ": Static @:op functions must accept exactly two arguments") cf.cf_pos
  2290. in
  2291. if not (left_eq || right_eq) then error (cf.cf_name ^ ": The left or right argument type must be " ^ (s_type (print_context()) targ)) cf.cf_pos;
  2292. if right_eq && Meta.has Meta.Commutative cf.cf_meta then error (cf.cf_name ^ ": @:commutative is only allowed if the right argument is not " ^ (s_type (print_context()) targ)) cf.cf_pos;
  2293. a.a_ops <- (op,cf) :: a.a_ops;
  2294. allows_no_expr := true;
  2295. | (Meta.Op,[EUnop(op,flag,_),_],_) :: _ ->
  2296. if fctx.is_macro then error (cf.cf_name ^ ": Macro operator functions are not supported") p;
  2297. let targ = if fctx.is_abstract_member then tthis else ta in
  2298. (try type_eq EqStrict t (tfun [targ] (mk_mono())) with Unify_error l -> raise (Error ((Unify l),cf.cf_pos)));
  2299. a.a_unops <- (op,flag,cf) :: a.a_unops;
  2300. allows_no_expr := true;
  2301. | (Meta.Impl,_,_) :: ml when cf.cf_name <> "_new" && not fctx.is_macro ->
  2302. begin match follow t with
  2303. | TFun((_,_,t1) :: _, _) when type_iseq tthis t1 ->
  2304. ()
  2305. | _ ->
  2306. display_error ctx ("First argument of implementation function must be " ^ (s_type (print_context()) tthis)) cf.cf_pos
  2307. end;
  2308. loop ml
  2309. | ((Meta.Resolve,_,_) | (Meta.Op,[EField _,_],_)) :: _ ->
  2310. if a.a_resolve <> None then error "Multiple resolve methods are not supported" cf.cf_pos;
  2311. let targ = if fctx.is_abstract_member then tthis else ta in
  2312. begin match follow t with
  2313. | TFun([(_,_,t1);(_,_,t2)],_) ->
  2314. if not fctx.is_macro then begin
  2315. if not (type_iseq targ t1) then error ("First argument type must be " ^ (s_type (print_context()) targ)) cf.cf_pos;
  2316. if not (type_iseq ctx.t.tstring t2) then error ("Second argument type must be String") cf.cf_pos
  2317. end
  2318. | _ ->
  2319. error ("Field type of resolve must be " ^ (s_type (print_context()) targ) ^ " -> String -> T") cf.cf_pos
  2320. end;
  2321. a.a_resolve <- Some cf;
  2322. | _ :: ml ->
  2323. loop ml
  2324. | [] ->
  2325. ()
  2326. in
  2327. loop cf.cf_meta;
  2328. let check_bind () =
  2329. if fd.f_expr = None then begin
  2330. if fctx.is_inline then error (cf.cf_name ^ ": Inline functions must have an expression") cf.cf_pos;
  2331. begin match fd.f_type with
  2332. | None -> error (cf.cf_name ^ ": Functions without expressions must have an explicit return type") cf.cf_pos
  2333. | Some _ -> ()
  2334. end;
  2335. cf.cf_meta <- (Meta.NoExpr,[],cf.cf_pos) :: cf.cf_meta;
  2336. fctx.do_bind <- false;
  2337. if not (Meta.has Meta.CoreType a.a_meta) then fctx.do_add <- false;
  2338. end
  2339. in
  2340. if cf.cf_name = "_new" && Meta.has Meta.MultiType a.a_meta then fctx.do_bind <- false;
  2341. if !allows_no_expr then check_bind()
  2342. | _ ->
  2343. ()
  2344. let create_method (ctx,cctx,fctx) c f fd p =
  2345. let params = type_function_params ctx fd f.cff_name p in
  2346. if Meta.has Meta.Generic f.cff_meta then begin
  2347. if params = [] then error (f.cff_name ^ ": Generic functions must have type parameters") p;
  2348. end;
  2349. let fd = if fctx.is_macro && not ctx.in_macro && not fctx.is_static then
  2350. (* remove display of first argument which will contain the "this" expression *)
  2351. { fd with f_args = match fd.f_args with [] -> [] | _ :: l -> l }
  2352. else
  2353. fd
  2354. in
  2355. let fd = if not fctx.is_macro then
  2356. fd
  2357. else begin
  2358. if ctx.in_macro then begin
  2359. (* a class with a macro cannot be extern in macro context (issue #2015) *)
  2360. c.cl_extern <- false;
  2361. let texpr = CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tparams = []; tsub = None } in
  2362. (* ExprOf type parameter might contain platform-specific type, let's replace it by Expr *)
  2363. let no_expr_of = function
  2364. | CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType _] }
  2365. | CTPath { tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType _] } -> Some texpr
  2366. | t -> Some t
  2367. in
  2368. {
  2369. f_params = fd.f_params;
  2370. f_type = (match fd.f_type with None -> Some texpr | Some t -> no_expr_of t);
  2371. f_args = List.map (fun (a,o,t,e) -> a,o,(match t with None -> Some texpr | Some t -> no_expr_of t),e) fd.f_args;
  2372. f_expr = fd.f_expr;
  2373. }
  2374. end else
  2375. let tdyn = Some (CTPath { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None }) in
  2376. let to_dyn = function
  2377. | { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType t] } -> Some t
  2378. | { tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType t] } -> Some t
  2379. | { tpackage = ["haxe"]; tname = ("PosInfos"); tsub = None; tparams = [] } -> error "haxe.PosInfos is not allowed on macro functions, use Context.currentPos() instead" p
  2380. | _ -> tdyn
  2381. in
  2382. {
  2383. f_params = fd.f_params;
  2384. f_type = (match fd.f_type with Some (CTPath t) -> to_dyn t | _ -> tdyn);
  2385. f_args = List.map (fun (a,o,t,_) -> a,o,(match t with Some (CTPath t) -> to_dyn t | _ -> tdyn),None) fd.f_args;
  2386. f_expr = None;
  2387. }
  2388. end in
  2389. begin match c.cl_interface,fctx.field_kind with
  2390. | true,FKConstructor ->
  2391. error "An interface cannot have a constructor" p;
  2392. | true,_ ->
  2393. if not fctx.is_static && fd.f_expr <> None then error (f.cff_name ^ ": An interface method cannot have a body") p;
  2394. if fctx.is_inline && c.cl_interface then error (f.cff_name ^ ": You can't declare inline methods in interfaces") p;
  2395. | false,FKConstructor ->
  2396. if fctx.is_static then error "A constructor must not be static" p;
  2397. begin match fd.f_type with
  2398. | None | Some (CTPath { tpackage = []; tname = "Void" }) -> ()
  2399. | _ -> error "A class constructor can't have a return value" p;
  2400. end
  2401. | false,_ ->
  2402. ()
  2403. end;
  2404. let parent = (if not fctx.is_static then get_parent c f.cff_name else None) in
  2405. let dynamic = List.mem ADynamic f.cff_access || (match parent with Some { cf_kind = Method MethDynamic } -> true | _ -> false) in
  2406. if fctx.is_inline && dynamic then error (f.cff_name ^ ": You can't have both 'inline' and 'dynamic'") p;
  2407. ctx.type_params <- (match cctx.abstract with
  2408. | Some a when fctx.is_abstract_member ->
  2409. params @ a.a_params
  2410. | _ ->
  2411. if fctx.is_static then params else params @ ctx.type_params);
  2412. (* TODO is_lib: avoid forcing the return type to be typed *)
  2413. let ret = if fctx.field_kind = FKConstructor then ctx.t.tvoid else type_opt (ctx,cctx) p fd.f_type in
  2414. let rec loop args = match args with
  2415. | (name,opt,t,ct) :: args ->
  2416. (* TODO is_lib: avoid forcing the field to be typed *)
  2417. let t, ct = type_function_arg ctx (type_opt (ctx,cctx) p t) ct opt p in
  2418. delay ctx PTypeField (fun() -> match follow t with
  2419. | TAbstract({a_path = ["haxe";"extern"],"Rest"},_) ->
  2420. if not c.cl_extern then error "Rest argument are only supported for extern methods" p;
  2421. if opt then error "Rest argument cannot be optional" p;
  2422. if ct <> None then error "Rest argument cannot have default value" p;
  2423. if args <> [] then error "Rest should only be used for the last function argument" p;
  2424. | _ ->
  2425. ()
  2426. );
  2427. (name, ct, t) :: (loop args)
  2428. | [] ->
  2429. []
  2430. in
  2431. let args = loop fd.f_args in
  2432. let t = TFun (fun_args args,ret) in
  2433. let cf = {
  2434. cf_name = f.cff_name;
  2435. cf_doc = f.cff_doc;
  2436. cf_meta = f.cff_meta;
  2437. cf_type = t;
  2438. cf_pos = f.cff_pos;
  2439. cf_kind = Method (if fctx.is_macro then MethMacro else if fctx.is_inline then MethInline else if dynamic then MethDynamic else MethNormal);
  2440. cf_expr = None;
  2441. cf_public = is_public (ctx,cctx) f.cff_access parent;
  2442. cf_params = params;
  2443. cf_overloads = [];
  2444. } in
  2445. cf.cf_meta <- List.map (fun (m,el,p) -> match m,el with
  2446. | Meta.AstSource,[] -> (m,(match fd.f_expr with None -> [] | Some e -> [e]),p)
  2447. | _ -> m,el,p
  2448. ) cf.cf_meta;
  2449. generate_value_meta ctx.com (Some c) cf fd.f_args;
  2450. check_abstract (ctx,cctx,fctx) c cf fd t ret p;
  2451. init_meta_overloads ctx (Some c) cf;
  2452. ctx.curfield <- cf;
  2453. let r = exc_protect ctx (fun r ->
  2454. if not !return_partial_type then begin
  2455. r := (fun() -> t);
  2456. cctx.context_init();
  2457. incr stats.s_methods_typed;
  2458. if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.in_macro then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ f.cff_name);
  2459. let fmode = (match cctx.abstract with
  2460. | Some _ ->
  2461. (match args with
  2462. | ("this",_,_) :: _ -> FunMemberAbstract
  2463. | _ when f.cff_name = "_new" -> FunMemberAbstract
  2464. | _ -> FunStatic)
  2465. | None ->
  2466. if fctx.field_kind = FKConstructor then FunConstructor else if fctx.is_static then FunStatic else FunMember
  2467. ) in
  2468. match ctx.com.platform with
  2469. | Java when is_java_native_function cf.cf_meta ->
  2470. if fd.f_expr <> None then
  2471. ctx.com.warning "@:native function definitions shouldn't include an expression. This behaviour is deprecated." cf.cf_pos;
  2472. cf.cf_expr <- None;
  2473. cf.cf_type <- t
  2474. | _ ->
  2475. let e , fargs = type_function ctx args ret fmode fd fctx.is_display_field p in
  2476. check_display (ctx,fctx) cf p;
  2477. let tf = {
  2478. tf_args = fargs;
  2479. tf_type = ret;
  2480. tf_expr = e;
  2481. } in
  2482. if fctx.field_kind = FKInit then
  2483. (match e.eexpr with
  2484. | TBlock [] | TBlock [{ eexpr = TConst _ }] | TConst _ | TObjectDecl [] -> ()
  2485. | _ -> c.cl_init <- Some e);
  2486. cf.cf_expr <- Some (mk (TFunction tf) t p);
  2487. cf.cf_type <- t;
  2488. end;
  2489. t
  2490. ) "type_fun" in
  2491. if fctx.do_bind then bind_type (ctx,cctx,fctx) cf r (match fd.f_expr with Some e -> snd e | None -> f.cff_pos);
  2492. cf
  2493. let create_property (ctx,cctx,fctx) c f (get,set,t,eo) p =
  2494. (match cctx.abstract with
  2495. | Some a when fctx.is_abstract_member ->
  2496. ctx.type_params <- a.a_params;
  2497. | _ -> ());
  2498. (* TODO is_lib: lazify load_complex_type *)
  2499. let ret = (match t, eo with
  2500. | None, None -> error (f.cff_name ^ ": Property must either define a type or a default value") p;
  2501. | None, _ -> mk_mono()
  2502. | Some t, _ -> load_complex_type ctx p t
  2503. ) in
  2504. let t_get,t_set = match cctx.abstract with
  2505. | Some a when fctx.is_abstract_member ->
  2506. if Meta.has Meta.IsVar f.cff_meta then error (f.cff_name ^ ": Abstract properties cannot be real variables") f.cff_pos;
  2507. let ta = apply_params a.a_params (List.map snd a.a_params) a.a_this in
  2508. tfun [ta] ret, tfun [ta;ret] ret
  2509. | _ -> tfun [] ret, TFun(["value",false,ret],ret)
  2510. in
  2511. let check_method m t req_name =
  2512. if ctx.com.display <> DMNone then () else
  2513. try
  2514. let overloads =
  2515. (* on pf_overload platforms, the getter/setter may have been defined as an overloaded function; get all overloads *)
  2516. if ctx.com.config.pf_overload then
  2517. if fctx.is_static then
  2518. let f = PMap.find m c.cl_statics in
  2519. (f.cf_type, f) :: (List.map (fun f -> f.cf_type, f) f.cf_overloads)
  2520. else
  2521. get_overloads c m
  2522. else
  2523. [ if fctx.is_static then
  2524. let f = PMap.find m c.cl_statics in
  2525. f.cf_type, f
  2526. else match class_field c (List.map snd c.cl_params) m with
  2527. | _, t,f -> t,f ]
  2528. in
  2529. (* choose the correct overload if and only if there is more than one overload found *)
  2530. let rec get_overload overl = match overl with
  2531. | [tf] -> tf
  2532. | (t2,f2) :: overl ->
  2533. if type_iseq t t2 then
  2534. (t2,f2)
  2535. else
  2536. get_overload overl
  2537. | [] ->
  2538. if c.cl_interface then
  2539. raise Not_found
  2540. else
  2541. raise (Error (Custom
  2542. (Printf.sprintf "No overloaded method named %s was compatible with the property %s with expected type %s" m f.cff_name (s_type (print_context()) t)
  2543. ), p))
  2544. in
  2545. let t2, f2 = get_overload overloads in
  2546. (* accessors must be public on As3 (issue #1872) *)
  2547. if Common.defined ctx.com Define.As3 then f2.cf_meta <- (Meta.Public,[],p) :: f2.cf_meta;
  2548. (match f2.cf_kind with
  2549. | Method MethMacro ->
  2550. display_error ctx (f2.cf_name ^ ": Macro methods cannot be used as property accessor") p;
  2551. display_error ctx (f2.cf_name ^ ": Accessor method is here") f2.cf_pos;
  2552. | _ -> ());
  2553. unify_raise ctx t2 t f2.cf_pos;
  2554. if (fctx.is_abstract_member && not (Meta.has Meta.Impl f2.cf_meta)) || (Meta.has Meta.Impl f2.cf_meta && not (fctx.is_abstract_member)) then
  2555. display_error ctx "Mixing abstract implementation and static properties/accessors is not allowed" f2.cf_pos;
  2556. (match req_name with None -> () | Some n -> display_error ctx ("Please use " ^ n ^ " to name your property access method") f2.cf_pos);
  2557. f2.cf_meta <- List.fold_left (fun acc ((m,_,_) as meta) -> match m with
  2558. | Meta.Deprecated -> meta :: acc
  2559. | _ -> acc
  2560. ) f2.cf_meta f.cff_meta;
  2561. with
  2562. | Error (Unify l,p) -> raise (Error (Stack (Custom ("In method " ^ m ^ " required by property " ^ f.cff_name),Unify l),p))
  2563. | Not_found ->
  2564. if req_name <> None then display_error ctx (f.cff_name ^ ": Custom property accessor is no longer supported, please use get/set") p else
  2565. if c.cl_interface then begin
  2566. let cf = mk_field m t p in
  2567. cf.cf_meta <- [Meta.CompilerGenerated,[],p];
  2568. cf.cf_kind <- Method MethNormal;
  2569. c.cl_fields <- PMap.add cf.cf_name cf c.cl_fields;
  2570. c.cl_ordered_fields <- cf :: c.cl_ordered_fields;
  2571. end else if not c.cl_extern then begin
  2572. try
  2573. let _, _, f2 = (if not fctx.is_static then let f = PMap.find m c.cl_statics in None, f.cf_type, f else class_field c (List.map snd c.cl_params) m) in
  2574. display_error ctx (Printf.sprintf "Method %s is no valid accessor for %s because it is %sstatic" m f.cff_name (if fctx.is_static then "not " else "")) f2.cf_pos
  2575. with Not_found ->
  2576. display_error ctx ("Method " ^ m ^ " required by property " ^ f.cff_name ^ " is missing") p
  2577. end
  2578. in
  2579. let get = (match get with
  2580. | "null" -> AccNo
  2581. | "dynamic" -> AccCall
  2582. | "never" -> AccNever
  2583. | "default" -> AccNormal
  2584. | _ ->
  2585. let get = if get = "get" then "get_" ^ f.cff_name else get in
  2586. if not cctx.is_lib then delay ctx PTypeField (fun() -> check_method get t_get (if get <> "get" && get <> "get_" ^ f.cff_name then Some ("get_" ^ f.cff_name) else None));
  2587. AccCall
  2588. ) in
  2589. let set = (match set with
  2590. | "null" ->
  2591. (* standard flash library read-only variables can't be accessed for writing, even in subclasses *)
  2592. if c.cl_extern && (match c.cl_path with "flash" :: _ , _ -> true | _ -> false) && ctx.com.platform = Flash then
  2593. AccNever
  2594. else
  2595. AccNo
  2596. | "never" -> AccNever
  2597. | "dynamic" -> AccCall
  2598. | "default" -> AccNormal
  2599. | _ ->
  2600. let set = if set = "set" then "set_" ^ f.cff_name else set in
  2601. if not cctx.is_lib then delay ctx PTypeField (fun() -> check_method set t_set (if set <> "set" && set <> "set_" ^ f.cff_name then Some ("set_" ^ f.cff_name) else None));
  2602. AccCall
  2603. ) in
  2604. if set = AccNormal && (match get with AccCall -> true | _ -> false) then error (f.cff_name ^ ": Unsupported property combination") p;
  2605. let cf = {
  2606. cf_name = f.cff_name;
  2607. cf_doc = f.cff_doc;
  2608. cf_meta = f.cff_meta;
  2609. cf_pos = f.cff_pos;
  2610. cf_kind = Var { v_read = get; v_write = set };
  2611. cf_expr = None;
  2612. cf_type = ret;
  2613. cf_public = is_public (ctx,cctx) f.cff_access None;
  2614. cf_params = [];
  2615. cf_overloads = [];
  2616. } in
  2617. ctx.curfield <- cf;
  2618. bind_var (ctx,cctx,fctx) cf eo;
  2619. cf
  2620. let init_field (ctx,cctx,fctx) f =
  2621. let c = cctx.tclass in
  2622. check_global_metadata ctx (fun m -> f.cff_meta <- m :: f.cff_meta) c.cl_module.m_path c.cl_path (Some f.cff_name);
  2623. let p = f.cff_pos in
  2624. if f.cff_name.[0] = '$' && ctx.com.display = DMNone then error "Field names starting with a dollar are not allowed" p;
  2625. List.iter (fun acc ->
  2626. match (acc, f.cff_kind) with
  2627. | APublic, _ | APrivate, _ | AStatic, _ -> ()
  2628. | ADynamic, FFun _ | AOverride, FFun _ | AMacro, FFun _ | AInline, FFun _ | AInline, FVar _ -> ()
  2629. | _, FVar _ -> error ("Invalid accessor '" ^ Ast.s_access acc ^ "' for variable " ^ f.cff_name) p
  2630. | _, FProp _ -> error ("Invalid accessor '" ^ Ast.s_access acc ^ "' for property " ^ f.cff_name) p
  2631. ) f.cff_access;
  2632. if fctx.is_override then (match c.cl_super with None -> error ("Invalid override on field '" ^ f.cff_name ^ "': class has no super class") p | _ -> ());
  2633. match f.cff_kind with
  2634. | FVar (t,e) ->
  2635. create_variable (ctx,cctx,fctx) c f t e p
  2636. | FFun fd ->
  2637. create_method (ctx,cctx,fctx) c f fd p
  2638. | FProp (get,set,t,eo) ->
  2639. create_property (ctx,cctx,fctx) c f (get,set,t,eo) p
  2640. let init_class ctx c p context_init herits fields =
  2641. let ctx,cctx = create_class_context ctx c context_init p in
  2642. let fields = patch_class ctx c fields in
  2643. let fields = build_fields (ctx,cctx) c fields in
  2644. if cctx.is_core_api && ctx.com.display = DMNone then delay ctx PForce (fun() -> init_core_api ctx c);
  2645. if not cctx.is_lib then begin
  2646. (match c.cl_super with None -> () | Some _ -> delay ctx PForce (fun() -> check_overriding ctx c));
  2647. if ctx.com.config.pf_overload then delay ctx PForce (fun() -> check_overloads ctx c)
  2648. end;
  2649. let rec has_field f = function
  2650. | None -> false
  2651. | Some (c,_) ->
  2652. PMap.exists f c.cl_fields || has_field f c.cl_super || List.exists (fun i -> has_field f (Some i)) c.cl_implements
  2653. in
  2654. let rec check_require = function
  2655. | [] -> None
  2656. | (Meta.Require,conds,_) :: l ->
  2657. let rec loop = function
  2658. | [] -> check_require l
  2659. | e :: l ->
  2660. let sc = match fst e with
  2661. | EConst (Ident s) -> s
  2662. | EBinop ((OpEq|OpNotEq|OpGt|OpGte|OpLt|OpLte) as op,(EConst (Ident s),_),(EConst ((Int _ | Float _ | String _) as c),_)) -> s ^ s_binop op ^ s_constant c
  2663. | _ -> ""
  2664. in
  2665. if not (Parser.is_true (Parser.eval ctx.com e)) then
  2666. Some (sc,(match List.rev l with (EConst (String msg),_) :: _ -> Some msg | _ -> None))
  2667. else
  2668. loop l
  2669. in
  2670. loop conds
  2671. | _ :: l ->
  2672. check_require l
  2673. in
  2674. let rec check_if_feature = function
  2675. | [] -> []
  2676. | (Meta.IfFeature,el,_) :: _ -> List.map (fun (e,p) -> match e with EConst (String s) -> s | _ -> error "String expected" p) el
  2677. | _ :: l -> check_if_feature l
  2678. in
  2679. let cl_if_feature = check_if_feature c.cl_meta in
  2680. let cl_req = check_require c.cl_meta in
  2681. List.iter (fun f ->
  2682. let p = f.cff_pos in
  2683. try
  2684. let ctx,fctx = create_field_context (ctx,cctx) c f in
  2685. let cf = init_field (ctx,cctx,fctx) f in
  2686. if fctx.is_static && c.cl_interface && fctx.field_kind <> FKInit && not cctx.is_lib then error "You can't declare static fields in interfaces" p;
  2687. let set_feature s =
  2688. ctx.m.curmod.m_extra.m_if_feature <- (s,(c,cf,fctx.is_static)) :: ctx.m.curmod.m_extra.m_if_feature
  2689. in
  2690. List.iter set_feature cl_if_feature;
  2691. List.iter set_feature (check_if_feature cf.cf_meta);
  2692. let req = check_require f.cff_meta in
  2693. let req = (match req with None -> if fctx.is_static || fctx.field_kind = FKConstructor then cl_req else None | _ -> req) in
  2694. (match req with
  2695. | None -> ()
  2696. | Some r -> cf.cf_kind <- Var { v_read = AccRequire (fst r, snd r); v_write = AccRequire (fst r, snd r) });
  2697. begin match fctx.field_kind with
  2698. | FKConstructor ->
  2699. begin match c.cl_constructor with
  2700. | None ->
  2701. c.cl_constructor <- Some cf
  2702. | Some ctor when ctx.com.config.pf_overload ->
  2703. if Meta.has Meta.Overload cf.cf_meta && Meta.has Meta.Overload ctor.cf_meta then
  2704. ctor.cf_overloads <- cf :: ctor.cf_overloads
  2705. else
  2706. display_error ctx ("If using overloaded constructors, all constructors must be declared with @:overload") (if Meta.has Meta.Overload cf.cf_meta then ctor.cf_pos else cf.cf_pos)
  2707. | Some ctor ->
  2708. display_error ctx "Duplicate constructor" p
  2709. end
  2710. | FKInit ->
  2711. ()
  2712. | FKNormal ->
  2713. let dup = if fctx.is_static then PMap.exists cf.cf_name c.cl_fields || has_field cf.cf_name c.cl_super else PMap.exists cf.cf_name c.cl_statics in
  2714. if not cctx.is_native && not c.cl_extern && dup then error ("Same field name can't be use for both static and instance : " ^ cf.cf_name) p;
  2715. if List.mem AOverride f.cff_access then c.cl_overrides <- cf :: c.cl_overrides;
  2716. let is_var f = match cf.cf_kind with | Var _ -> true | _ -> false in
  2717. if PMap.mem cf.cf_name (if fctx.is_static then c.cl_statics else c.cl_fields) then
  2718. if ctx.com.config.pf_overload && Meta.has Meta.Overload cf.cf_meta && not (is_var f) then
  2719. let mainf = PMap.find cf.cf_name (if fctx.is_static then c.cl_statics else c.cl_fields) in
  2720. if is_var mainf then display_error ctx "Cannot declare a variable with same name as a method" mainf.cf_pos;
  2721. (if not (Meta.has Meta.Overload mainf.cf_meta) then display_error ctx ("Overloaded methods must have @:overload metadata") mainf.cf_pos);
  2722. mainf.cf_overloads <- cf :: mainf.cf_overloads
  2723. else
  2724. display_error ctx ("Duplicate class field declaration : " ^ cf.cf_name) p
  2725. else
  2726. if fctx.do_add then add_field c cf (fctx.is_static || fctx.is_macro && ctx.in_macro)
  2727. end
  2728. with Error (Custom str,p2) when p = p2 ->
  2729. display_error ctx str p
  2730. ) fields;
  2731. (match cctx.abstract with
  2732. | Some a ->
  2733. a.a_to_field <- List.rev a.a_to_field;
  2734. a.a_from_field <- List.rev a.a_from_field;
  2735. a.a_ops <- List.rev a.a_ops;
  2736. a.a_unops <- List.rev a.a_unops;
  2737. a.a_array <- List.rev a.a_array;
  2738. | None -> ());
  2739. c.cl_ordered_statics <- List.rev c.cl_ordered_statics;
  2740. c.cl_ordered_fields <- List.rev c.cl_ordered_fields;
  2741. (*
  2742. make sure a default contructor with same access as super one will be added to the class structure at some point.
  2743. *)
  2744. (* add_constructor does not deal with overloads correctly *)
  2745. if not ctx.com.config.pf_overload then add_constructor ctx c cctx.force_constructor p;
  2746. if Meta.has Meta.StructInit c.cl_meta then check_struct_init_constructor ctx c p;
  2747. (* check overloaded constructors *)
  2748. (if ctx.com.config.pf_overload && not cctx.is_lib then match c.cl_constructor with
  2749. | Some ctor ->
  2750. delay ctx PTypeField (fun() ->
  2751. List.iter (fun f ->
  2752. try
  2753. (* TODO: consider making a broader check, and treat some types, like TAnon and type parameters as Dynamic *)
  2754. ignore(List.find (fun f2 -> f != f2 && same_overload_args f.cf_type f2.cf_type f f2) (ctor :: ctor.cf_overloads));
  2755. display_error ctx ("Another overloaded field of same signature was already declared : " ^ f.cf_name) f.cf_pos;
  2756. with Not_found -> ()
  2757. ) (ctor :: ctor.cf_overloads)
  2758. )
  2759. | _ -> ());
  2760. (* push delays in reverse order so they will be run in correct order *)
  2761. List.iter (fun (ctx,r) ->
  2762. init_class_done ctx;
  2763. (match r with
  2764. | None -> ()
  2765. | Some r -> delay ctx PTypeField (fun() -> ignore((!r)())))
  2766. ) cctx.delayed_expr
  2767. end
  2768. let resolve_typedef t =
  2769. match t with
  2770. | TClassDecl _ | TEnumDecl _ | TAbstractDecl _ -> t
  2771. | TTypeDecl td ->
  2772. match follow td.t_type with
  2773. | TEnum (e,_) -> TEnumDecl e
  2774. | TInst (c,_) -> TClassDecl c
  2775. | TAbstract (a,_) -> TAbstractDecl a
  2776. | _ -> t
  2777. let check_module_types ctx m p t =
  2778. let t = t_infos t in
  2779. try
  2780. let m2 = Hashtbl.find ctx.g.types_module t.mt_path in
  2781. if m.m_path <> m2 && String.lowercase (s_type_path m2) = String.lowercase (s_type_path m.m_path) then error ("Module " ^ s_type_path m2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
  2782. error ("Type name " ^ s_type_path t.mt_path ^ " is redefined from module " ^ s_type_path m2) p
  2783. with
  2784. Not_found ->
  2785. Hashtbl.add ctx.g.types_module t.mt_path m.m_path
  2786. let add_module ctx m p =
  2787. List.iter (check_module_types ctx m p) m.m_types;
  2788. Hashtbl.add ctx.g.modules m.m_path m
  2789. (*
  2790. In this pass, we can access load and access other modules types, but we cannot follow them or access their structure
  2791. since they have not been setup. We also build a context_init list that will be evaluated the first time we evaluate
  2792. an expression into the context
  2793. *)
  2794. let init_module_type ctx context_init do_init (decl,p) =
  2795. let get_type name =
  2796. try List.find (fun t -> snd (t_infos t).mt_path = name) ctx.m.curmod.m_types with Not_found -> assert false
  2797. in
  2798. match decl with
  2799. | EImport (path,mode) ->
  2800. ctx.m.module_imports <- (path,mode) :: ctx.m.module_imports;
  2801. let rec loop acc = function
  2802. | x :: l when is_lower_ident (fst x) -> loop (x::acc) l
  2803. | rest -> List.rev acc, rest
  2804. in
  2805. let pack, rest = loop [] path in
  2806. (match rest with
  2807. | [] ->
  2808. (match mode with
  2809. | IAll ->
  2810. ctx.m.wildcard_packages <- List.map fst pack :: ctx.m.wildcard_packages
  2811. | _ ->
  2812. (match List.rev path with
  2813. | [] -> assert false
  2814. | (_,p) :: _ -> error "Module name must start with an uppercase letter" p))
  2815. | (tname,p2) :: rest ->
  2816. let p1 = (match pack with [] -> p2 | (_,p1) :: _ -> p1) in
  2817. let p_type = punion p1 p2 in
  2818. let md = ctx.g.do_load_module ctx (List.map fst pack,tname) p_type in
  2819. let types = md.m_types in
  2820. let no_private t = not (t_infos t).mt_private in
  2821. let chk_private t p = if (t_infos t).mt_private then error "You can't import a private type" p in
  2822. let has_name name t = snd (t_infos t).mt_path = name in
  2823. let get_type tname =
  2824. let t = (try List.find (has_name tname) types with Not_found -> error (StringError.string_error tname (List.map (fun mt -> snd (t_infos mt).mt_path) types) ("Module " ^ s_type_path md.m_path ^ " does not define type " ^ tname)) p_type) in
  2825. chk_private t p_type;
  2826. t
  2827. in
  2828. let rebind t name =
  2829. if not (name.[0] >= 'A' && name.[0] <= 'Z') then
  2830. error "Type aliases must start with an uppercase letter" p;
  2831. let _, _, f = ctx.g.do_build_instance ctx t p_type in
  2832. (* create a temp private typedef, does not register it in module *)
  2833. TTypeDecl {
  2834. t_path = (fst md.m_path @ ["_" ^ snd md.m_path],name);
  2835. t_module = md;
  2836. t_pos = p;
  2837. t_private = true;
  2838. t_doc = None;
  2839. t_meta = [];
  2840. t_params = (t_infos t).mt_params;
  2841. t_type = f (List.map snd (t_infos t).mt_params);
  2842. }
  2843. in
  2844. let add_static_init t name s =
  2845. let name = (match name with None -> s | Some n -> n) in
  2846. match resolve_typedef t with
  2847. | TClassDecl c ->
  2848. ignore(c.cl_build());
  2849. ignore(PMap.find s c.cl_statics);
  2850. ctx.m.module_globals <- PMap.add name (TClassDecl c,s) ctx.m.module_globals
  2851. | TEnumDecl e ->
  2852. ignore(PMap.find s e.e_constrs);
  2853. ctx.m.module_globals <- PMap.add name (TEnumDecl e,s) ctx.m.module_globals
  2854. | _ ->
  2855. raise Not_found
  2856. in
  2857. (match mode with
  2858. | INormal | IAsName _ ->
  2859. let name = (match mode with IAsName n -> Some n | _ -> None) in
  2860. (match rest with
  2861. | [] ->
  2862. (match name with
  2863. | None ->
  2864. ctx.m.module_types <- List.filter no_private types @ ctx.m.module_types
  2865. | Some newname ->
  2866. ctx.m.module_types <- rebind (get_type tname) newname :: ctx.m.module_types);
  2867. | [tsub,p2] ->
  2868. let p = punion p1 p2 in
  2869. (try
  2870. let tsub = List.find (has_name tsub) types in
  2871. chk_private tsub p;
  2872. ctx.m.module_types <- (match name with None -> tsub | Some n -> rebind tsub n) :: ctx.m.module_types
  2873. with Not_found ->
  2874. (* this might be a static property, wait later to check *)
  2875. let tmain = get_type tname in
  2876. context_init := (fun() ->
  2877. try
  2878. add_static_init tmain name tsub
  2879. with Not_found ->
  2880. error (s_type_path (t_infos tmain).mt_path ^ " has no field or subtype " ^ tsub) p
  2881. ) :: !context_init)
  2882. | (tsub,p2) :: (fname,p3) :: rest ->
  2883. (match rest with
  2884. | [] -> ()
  2885. | (n,p) :: _ -> error ("Unexpected " ^ n) p);
  2886. let tsub = get_type tsub in
  2887. context_init := (fun() ->
  2888. try
  2889. add_static_init tsub name fname
  2890. with Not_found ->
  2891. error (s_type_path (t_infos tsub).mt_path ^ " has no field " ^ fname) (punion p p3)
  2892. ) :: !context_init;
  2893. )
  2894. | IAll ->
  2895. let t = (match rest with
  2896. | [] -> get_type tname
  2897. | [tsub,_] -> get_type tsub
  2898. | _ :: (n,p) :: _ -> error ("Unexpected " ^ n) p
  2899. ) in
  2900. context_init := (fun() ->
  2901. match resolve_typedef t with
  2902. | TClassDecl c
  2903. | TAbstractDecl {a_impl = Some c} ->
  2904. ignore(c.cl_build());
  2905. PMap.iter (fun _ cf -> if not (has_meta Meta.NoImportGlobal cf.cf_meta) then ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name) ctx.m.module_globals) c.cl_statics
  2906. | TEnumDecl e ->
  2907. PMap.iter (fun _ c -> if not (has_meta Meta.NoImportGlobal c.ef_meta) then ctx.m.module_globals <- PMap.add c.ef_name (TEnumDecl e,c.ef_name) ctx.m.module_globals) e.e_constrs
  2908. | _ ->
  2909. error "No statics to import from this type" p
  2910. ) :: !context_init
  2911. ))
  2912. | EUsing t ->
  2913. (* do the import first *)
  2914. let types = (match t.tsub with
  2915. | None ->
  2916. let md = ctx.g.do_load_module ctx (t.tpackage,t.tname) p in
  2917. let types = List.filter (fun t -> not (t_infos t).mt_private) md.m_types in
  2918. ctx.m.module_types <- types @ ctx.m.module_types;
  2919. types
  2920. | Some _ ->
  2921. let t = load_type_def ctx p t in
  2922. ctx.m.module_types <- t :: ctx.m.module_types;
  2923. [t]
  2924. ) in
  2925. (* delay the using since we need to resolve typedefs *)
  2926. let filter_classes types =
  2927. let rec loop acc types = match types with
  2928. | td :: l ->
  2929. (match resolve_typedef td with
  2930. | TClassDecl c | TAbstractDecl({a_impl = Some c}) ->
  2931. loop (c :: acc) l
  2932. | td ->
  2933. loop acc l)
  2934. | [] ->
  2935. acc
  2936. in
  2937. loop [] types
  2938. in
  2939. context_init := (fun() -> ctx.m.module_using <- filter_classes types @ ctx.m.module_using) :: !context_init
  2940. | EClass d ->
  2941. let c = (match get_type d.d_name with TClassDecl c -> c | _ -> assert false) in
  2942. check_global_metadata ctx (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None;
  2943. let herits = d.d_flags in
  2944. if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric;
  2945. if Meta.has Meta.GenericBuild c.cl_meta then begin
  2946. if ctx.in_macro then error "@:genericBuild cannot be used in macros" c.cl_pos;
  2947. c.cl_kind <- KGenericBuild d.d_data;
  2948. end;
  2949. if c.cl_path = (["haxe";"macro"],"MacroType") then c.cl_kind <- KMacroType;
  2950. c.cl_extern <- List.mem HExtern herits;
  2951. c.cl_interface <- List.mem HInterface herits;
  2952. let build() =
  2953. let fl = Inheritance.set_heritance ctx c herits p in
  2954. let rec build() =
  2955. c.cl_build <- (fun()-> Building);
  2956. try
  2957. List.iter (fun f -> f()) fl;
  2958. ClassInitializer.init_class ctx c p do_init d.d_flags d.d_data;
  2959. c.cl_build <- (fun()-> Built);
  2960. List.iter (fun (_,t) -> ignore(follow t)) c.cl_params;
  2961. Built;
  2962. with Build_canceled state ->
  2963. c.cl_build <- make_pass ctx build;
  2964. let rebuild() =
  2965. delay_late ctx PBuildClass (fun() -> ignore(c.cl_build()));
  2966. in
  2967. (match state with
  2968. | Built -> assert false
  2969. | Building -> rebuild()
  2970. | BuildMacro f -> f := rebuild :: !f);
  2971. state
  2972. | exn ->
  2973. c.cl_build <- (fun()-> Built);
  2974. raise exn
  2975. in
  2976. build()
  2977. in
  2978. ctx.pass <- PBuildClass;
  2979. ctx.curclass <- c;
  2980. c.cl_build <- make_pass ctx build;
  2981. ctx.pass <- PBuildModule;
  2982. ctx.curclass <- null_class;
  2983. delay ctx PBuildClass (fun() -> ignore(c.cl_build()));
  2984. if (ctx.com.platform = Java || ctx.com.platform = Cs) && not c.cl_extern then
  2985. delay ctx PTypeField (fun () ->
  2986. let metas = check_strict_meta ctx c.cl_meta in
  2987. if metas <> [] then c.cl_meta <- metas @ c.cl_meta;
  2988. let rec run_field cf =
  2989. let metas = check_strict_meta ctx cf.cf_meta in
  2990. if metas <> [] then cf.cf_meta <- metas @ cf.cf_meta;
  2991. List.iter run_field cf.cf_overloads
  2992. in
  2993. List.iter run_field c.cl_ordered_statics;
  2994. List.iter run_field c.cl_ordered_fields;
  2995. match c.cl_constructor with
  2996. | Some f -> run_field f
  2997. | _ -> ()
  2998. );
  2999. | EEnum d ->
  3000. let e = (match get_type d.d_name with TEnumDecl e -> e | _ -> assert false) in
  3001. let ctx = { ctx with type_params = e.e_params } in
  3002. let h = (try Some (Hashtbl.find ctx.g.type_patches e.e_path) with Not_found -> None) in
  3003. check_global_metadata ctx (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None;
  3004. (match h with
  3005. | None -> ()
  3006. | Some (h,hcl) ->
  3007. Hashtbl.iter (fun _ _ -> error "Field type patch not supported for enums" e.e_pos) h;
  3008. e.e_meta <- e.e_meta @ hcl.tp_meta);
  3009. let constructs = ref d.d_data in
  3010. let get_constructs() =
  3011. List.map (fun c ->
  3012. {
  3013. cff_name = c.ec_name;
  3014. cff_doc = c.ec_doc;
  3015. cff_meta = c.ec_meta;
  3016. cff_pos = c.ec_pos;
  3017. cff_access = [];
  3018. cff_kind = (match c.ec_args, c.ec_params with
  3019. | [], [] -> FVar (c.ec_type,None)
  3020. | _ -> FFun { f_params = c.ec_params; f_type = c.ec_type; f_expr = None; f_args = List.map (fun (n,o,t) -> n,o,Some t,None) c.ec_args });
  3021. }
  3022. ) (!constructs)
  3023. in
  3024. let init () = List.iter (fun f -> f()) !context_init in
  3025. build_module_def ctx (TEnumDecl e) e.e_meta get_constructs init (fun (e,p) ->
  3026. match e with
  3027. | EVars [_,Some (CTAnonymous fields),None] ->
  3028. constructs := List.map (fun f ->
  3029. let args, params, t = (match f.cff_kind with
  3030. | FVar (t,None) -> [], [], t
  3031. | FFun { f_params = pl; f_type = t; f_expr = (None|Some (EBlock [],_)); f_args = al } ->
  3032. let al = List.map (fun (n,o,t,_) -> match t with None -> error "Missing function parameter type" f.cff_pos | Some t -> n,o,t) al in
  3033. al, pl, t
  3034. | _ ->
  3035. error "Invalid enum constructor in @:build result" p
  3036. ) in
  3037. {
  3038. ec_name = f.cff_name;
  3039. ec_doc = f.cff_doc;
  3040. ec_meta = f.cff_meta;
  3041. ec_pos = f.cff_pos;
  3042. ec_args = args;
  3043. ec_params = params;
  3044. ec_type = t;
  3045. }
  3046. ) fields
  3047. | _ -> error "Enum build macro must return a single variable with anonymous object fields" p
  3048. );
  3049. let et = TEnum (e,List.map snd e.e_params) in
  3050. let names = ref [] in
  3051. let index = ref 0 in
  3052. let is_flat = ref true in
  3053. let fields = ref PMap.empty in
  3054. let is_display_file = Display.is_display_file ctx p in
  3055. List.iter (fun c ->
  3056. let p = c.ec_pos in
  3057. let params = ref [] in
  3058. params := type_type_params ~enum_constructor:true ctx ([],c.ec_name) (fun() -> !params) c.ec_pos c.ec_params;
  3059. let params = !params in
  3060. let ctx = { ctx with type_params = params @ ctx.type_params } in
  3061. let rt = (match c.ec_type with
  3062. | None -> et
  3063. | Some t ->
  3064. let t = load_complex_type ctx p t in
  3065. (match follow t with
  3066. | TEnum (te,_) when te == e ->
  3067. ()
  3068. | _ ->
  3069. error "Explicit enum type must be of the same enum type" p);
  3070. t
  3071. ) in
  3072. let t = (match c.ec_args with
  3073. | [] -> rt
  3074. | l ->
  3075. is_flat := false;
  3076. let pnames = ref PMap.empty in
  3077. TFun (List.map (fun (s,opt,t) ->
  3078. (match t with CTPath({tpackage=[];tname="Void"}) -> error "Arguments of type Void are not allowed in enum constructors" c.ec_pos | _ -> ());
  3079. if PMap.mem s (!pnames) then error ("Duplicate parameter '" ^ s ^ "' in enum constructor " ^ c.ec_name) p;
  3080. pnames := PMap.add s () (!pnames);
  3081. s, opt, load_type_opt ~opt ctx p (Some t)
  3082. ) l, rt)
  3083. ) in
  3084. if PMap.mem c.ec_name e.e_constrs then error ("Duplicate constructor " ^ c.ec_name) p;
  3085. let f = {
  3086. ef_name = c.ec_name;
  3087. ef_type = t;
  3088. ef_pos = p;
  3089. ef_doc = c.ec_doc;
  3090. ef_index = !index;
  3091. ef_params = params;
  3092. ef_meta = c.ec_meta;
  3093. } in
  3094. let cf = {
  3095. cf_name = f.ef_name;
  3096. cf_public = true;
  3097. cf_type = f.ef_type;
  3098. cf_kind = (match follow f.ef_type with
  3099. | TFun _ -> Method MethNormal
  3100. | _ -> Var { v_read = AccNormal; v_write = AccNo }
  3101. );
  3102. cf_pos = p;
  3103. cf_doc = f.ef_doc;
  3104. cf_meta = no_meta;
  3105. cf_expr = None;
  3106. cf_params = f.ef_params;
  3107. cf_overloads = [];
  3108. } in
  3109. if is_display_file && Display.encloses_position !Parser.resume_display p then begin match ctx.com.display with
  3110. | DMPosition -> raise (DisplayPosition [p]);
  3111. | DMUsage -> f.ef_meta <- (Meta.Usage,[],p) :: f.ef_meta;
  3112. | DMType -> raise (DisplayTypes [f.ef_type])
  3113. | _ -> ()
  3114. end;
  3115. e.e_constrs <- PMap.add f.ef_name f e.e_constrs;
  3116. fields := PMap.add cf.cf_name cf !fields;
  3117. incr index;
  3118. names := c.ec_name :: !names;
  3119. ) (!constructs);
  3120. e.e_names <- List.rev !names;
  3121. e.e_extern <- e.e_extern;
  3122. e.e_type.t_params <- e.e_params;
  3123. e.e_type.t_type <- TAnon {
  3124. a_fields = !fields;
  3125. a_status = ref (EnumStatics e);
  3126. };
  3127. if !is_flat then e.e_meta <- (Meta.FlatEnum,[],e.e_pos) :: e.e_meta;
  3128. if (ctx.com.platform = Java || ctx.com.platform = Cs) && not e.e_extern then
  3129. delay ctx PTypeField (fun () ->
  3130. let metas = check_strict_meta ctx e.e_meta in
  3131. e.e_meta <- metas @ e.e_meta;
  3132. PMap.iter (fun _ ef ->
  3133. let metas = check_strict_meta ctx ef.ef_meta in
  3134. if metas <> [] then ef.ef_meta <- metas @ ef.ef_meta
  3135. ) e.e_constrs
  3136. );
  3137. | ETypedef d ->
  3138. let t = (match get_type d.d_name with TTypeDecl t -> t | _ -> assert false) in
  3139. check_global_metadata ctx (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None;
  3140. let ctx = { ctx with type_params = t.t_params } in
  3141. let tt = load_complex_type ctx p d.d_data in
  3142. let tt = (match d.d_data with
  3143. | CTExtend _ -> tt
  3144. | CTPath { tpackage = ["haxe";"macro"]; tname = "MacroType" } ->
  3145. (* we need to follow MacroType immediately since it might define other module types that we will load afterwards *)
  3146. if t.t_type == follow tt then error "Recursive typedef is not allowed" p;
  3147. tt
  3148. | _ ->
  3149. TLazy (exc_protect ctx (fun r ->
  3150. if t.t_type == follow tt then error "Recursive typedef is not allowed" p;
  3151. r := (fun() -> tt);
  3152. tt
  3153. ) "typedef_rec_check")
  3154. ) in
  3155. (match t.t_type with
  3156. | TMono r ->
  3157. (match !r with
  3158. | None -> r := Some tt;
  3159. | Some _ -> assert false);
  3160. | _ -> assert false);
  3161. if ctx.com.platform = Cs && t.t_meta <> [] then
  3162. delay ctx PTypeField (fun () ->
  3163. let metas = check_strict_meta ctx t.t_meta in
  3164. if metas <> [] then t.t_meta <- metas @ t.t_meta;
  3165. );
  3166. | EAbstract d ->
  3167. let a = (match get_type d.d_name with TAbstractDecl a -> a | _ -> assert false) in
  3168. check_global_metadata ctx (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None;
  3169. let ctx = { ctx with type_params = a.a_params } in
  3170. let is_type = ref false in
  3171. let load_type t from =
  3172. let t = load_complex_type ctx p t in
  3173. let t = if not (Meta.has Meta.CoreType a.a_meta) then begin
  3174. if !is_type then begin
  3175. let r = exc_protect ctx (fun r ->
  3176. r := (fun() -> t);
  3177. let at = monomorphs a.a_params a.a_this in
  3178. (try (if from then Type.unify t at else Type.unify at t) with Unify_error _ -> error "You can only declare from/to with compatible types" p);
  3179. t
  3180. ) "constraint" in
  3181. delay ctx PForce (fun () -> ignore(!r()));
  3182. TLazy r
  3183. end else
  3184. error "Missing underlying type declaration or @:coreType declaration" p;
  3185. end else begin
  3186. if Meta.has Meta.Callable a.a_meta then
  3187. error "@:coreType abstracts cannot be @:callable" p;
  3188. t
  3189. end in
  3190. t
  3191. in
  3192. List.iter (function
  3193. | AFromType t -> a.a_from <- (load_type t true) :: a.a_from
  3194. | AToType t -> a.a_to <- (load_type t false) :: a.a_to
  3195. | AIsType t ->
  3196. if a.a_impl = None then error "Abstracts with underlying type must have an implementation" a.a_pos;
  3197. if Meta.has Meta.CoreType a.a_meta then error "@:coreType abstracts cannot have an underlying type" p;
  3198. let at = load_complex_type ctx p t in
  3199. delay ctx PForce (fun () ->
  3200. begin match follow at with
  3201. | TAbstract(a2,_) when a == a2 -> error "Abstract underlying type cannot be recursive" a.a_pos
  3202. | _ -> ()
  3203. end;
  3204. );
  3205. a.a_this <- at;
  3206. is_type := true;
  3207. | AExtern ->
  3208. (match a.a_impl with Some c -> c.cl_extern <- true | None -> (* Hmmmm.... *) ())
  3209. | APrivAbstract -> ()
  3210. ) d.d_flags;
  3211. if not !is_type then begin
  3212. if Meta.has Meta.CoreType a.a_meta then
  3213. a.a_this <- TAbstract(a,List.map snd a.a_params)
  3214. else
  3215. error "Abstract is missing underlying type declaration" a.a_pos
  3216. end
  3217. let module_pass_2 ctx m decls tdecls p =
  3218. (* here is an additional PASS 1 phase, which define the type parameters for all module types.
  3219. Constraints are handled lazily (no other type is loaded) because they might be recursive anyway *)
  3220. List.iter (fun d ->
  3221. match d with
  3222. | (TClassDecl c, (EClass d, p)) ->
  3223. c.cl_params <- type_type_params ctx c.cl_path (fun() -> c.cl_params) p d.d_params;
  3224. | (TEnumDecl e, (EEnum d, p)) ->
  3225. e.e_params <- type_type_params ctx e.e_path (fun() -> e.e_params) p d.d_params;
  3226. | (TTypeDecl t, (ETypedef d, p)) ->
  3227. t.t_params <- type_type_params ctx t.t_path (fun() -> t.t_params) p d.d_params;
  3228. | (TAbstractDecl a, (EAbstract d, p)) ->
  3229. a.a_params <- type_type_params ctx a.a_path (fun() -> a.a_params) p d.d_params;
  3230. | _ ->
  3231. assert false
  3232. ) decls;
  3233. (* setup module types *)
  3234. let context_init = ref [] in
  3235. let do_init() =
  3236. match !context_init with
  3237. | [] -> ()
  3238. | l -> context_init := []; List.iter (fun f -> f()) (List.rev l)
  3239. in
  3240. List.iter (init_module_type ctx context_init do_init) tdecls
  3241. (*
  3242. Creates a module context for [m] and types [tdecls] using it.
  3243. *)
  3244. let type_types_into_module ctx m tdecls p =
  3245. let decls, tdecls = module_pass_1 ctx m tdecls p in
  3246. let types = List.map fst decls in
  3247. List.iter (check_module_types ctx m p) types;
  3248. m.m_types <- m.m_types @ types;
  3249. (* define the per-module context for the next pass *)
  3250. let ctx = {
  3251. com = ctx.com;
  3252. g = ctx.g;
  3253. t = ctx.t;
  3254. m = {
  3255. curmod = m;
  3256. module_types = ctx.g.std.m_types;
  3257. module_using = [];
  3258. module_globals = PMap.empty;
  3259. wildcard_packages = [];
  3260. module_imports = [];
  3261. };
  3262. meta = [];
  3263. this_stack = [];
  3264. with_type_stack = [];
  3265. call_argument_stack = [];
  3266. pass = PBuildModule;
  3267. on_error = (fun ctx msg p -> ctx.com.error msg p);
  3268. macro_depth = ctx.macro_depth;
  3269. curclass = null_class;
  3270. curfield = null_field;
  3271. tthis = ctx.tthis;
  3272. ret = ctx.ret;
  3273. locals = PMap.empty;
  3274. type_params = [];
  3275. curfun = FunStatic;
  3276. untyped = false;
  3277. in_macro = ctx.in_macro;
  3278. in_display = false;
  3279. display_handled = false;
  3280. in_loop = false;
  3281. opened = [];
  3282. in_call_args = false;
  3283. vthis = None;
  3284. } in
  3285. if ctx.g.std != null_module then begin
  3286. add_dependency m ctx.g.std;
  3287. (* this will ensure both String and (indirectly) Array which are basic types which might be referenced *)
  3288. ignore(load_core_type ctx "String");
  3289. end;
  3290. module_pass_2 ctx m decls tdecls p
  3291. let handle_import_hx ctx m decls p =
  3292. let path_split = List.tl (List.rev (get_path_parts m.m_extra.m_file)) in
  3293. let join l = String.concat (if Sys.os_type = "Win32" || Sys.os_type = "Cygwin" then "\\" else "/") (List.rev ("import.hx" :: l)) in
  3294. let rec loop path pack = match path,pack with
  3295. | _,[] -> [join path]
  3296. | (p :: path),(_ :: pack) -> (join (p :: path)) :: (loop path pack)
  3297. | _ -> []
  3298. in
  3299. let candidates = loop path_split (fst m.m_path) in
  3300. let make_import_module path r =
  3301. Hashtbl.replace ctx.com.parser_cache path r;
  3302. (* We use the file path as module name to make it unique. This may or may not be a good idea... *)
  3303. let m_import = make_module ctx ([],path) path p in
  3304. add_module ctx m_import p;
  3305. m_import
  3306. in
  3307. List.fold_left (fun acc path ->
  3308. let decls = try
  3309. let r = Hashtbl.find ctx.com.parser_cache path in
  3310. let mimport = Hashtbl.find ctx.g.modules ([],path) in
  3311. if mimport.m_extra.m_kind <> MFake then add_dependency m mimport;
  3312. r
  3313. with Not_found ->
  3314. if Sys.file_exists path then begin
  3315. let _,r = parse_file ctx.com path p in
  3316. List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> error "Only import and using is allowed in import.hx files" p) r;
  3317. add_dependency m (make_import_module path r);
  3318. r
  3319. end else begin
  3320. let r = [] in
  3321. (* Add empty decls so we don't check the file system all the time. *)
  3322. (make_import_module path r).m_extra.m_kind <- MFake;
  3323. r
  3324. end
  3325. in
  3326. decls @ acc
  3327. ) decls candidates
  3328. (*
  3329. Creates a new module and types [tdecls] into it.
  3330. *)
  3331. let type_module ctx mpath file ?(is_extern=false) tdecls p =
  3332. let m = make_module ctx mpath file p in
  3333. Hashtbl.add ctx.g.modules m.m_path m;
  3334. let tdecls = handle_import_hx ctx m tdecls p in
  3335. type_types_into_module ctx m tdecls p;
  3336. if is_extern then m.m_extra.m_kind <- MExtern;
  3337. m
  3338. let resolve_module_file com m remap p =
  3339. let forbid = ref false in
  3340. let file = (match m with
  3341. | [] , name -> name
  3342. | x :: l , name ->
  3343. let x = (try
  3344. match PMap.find x com.package_rules with
  3345. | Forbidden -> forbid := true; x
  3346. | Directory d -> d
  3347. | Remap d -> remap := d :: l; d
  3348. with Not_found -> x
  3349. ) in
  3350. String.concat "/" (x :: l) ^ "/" ^ name
  3351. ) ^ ".hx" in
  3352. let file = Common.find_file com file in
  3353. let file = (match String.lowercase (snd m) with
  3354. | "con" | "aux" | "prn" | "nul" | "com1" | "com2" | "com3" | "lpt1" | "lpt2" | "lpt3" when Sys.os_type = "Win32" ->
  3355. (* these names are reserved by the OS - old DOS legacy, such files cannot be easily created but are reported as visible *)
  3356. if (try (Unix.stat file).Unix.st_size with _ -> 0) > 0 then file else raise Not_found
  3357. | _ -> file
  3358. ) in
  3359. (* if we try to load a std.xxxx class and resolve a real std file, the package name is not valid, ignore *)
  3360. (match fst m with
  3361. | "std" :: _ ->
  3362. let file = Common.unique_full_path file in
  3363. if List.exists (fun path -> ExtString.String.starts_with file (try Common.unique_full_path path with _ -> path)) com.std_path then raise Not_found;
  3364. | _ -> ());
  3365. if !forbid then begin
  3366. let _, decls = (!parse_hook) com file p in
  3367. let rec loop decls = match decls with
  3368. | ((EImport _,_) | (EUsing _,_)) :: decls -> loop decls
  3369. | (EClass d,_) :: _ -> d.d_meta
  3370. | (EEnum d,_) :: _ -> d.d_meta
  3371. | (EAbstract d,_) :: _ -> d.d_meta
  3372. | (ETypedef d,_) :: _ -> d.d_meta
  3373. | [] -> []
  3374. in
  3375. let meta = loop decls in
  3376. if not (Meta.has Meta.NoPackageRestrict meta) then begin
  3377. let x = (match fst m with [] -> assert false | x :: _ -> x) in
  3378. raise (Forbid_package ((x,m,p),[],if Common.defined com Define.Macro then "macro" else platform_name com.platform));
  3379. end;
  3380. end;
  3381. file
  3382. let parse_module ctx m p =
  3383. let remap = ref (fst m) in
  3384. let file = resolve_module_file ctx.com m remap p in
  3385. let pack, decls = (!parse_hook) ctx.com file p in
  3386. if pack <> !remap then begin
  3387. let spack m = if m = [] then "<empty>" else String.concat "." m in
  3388. if p == Ast.null_pos then
  3389. display_error ctx ("Invalid commandline class : " ^ s_type_path m ^ " should be " ^ s_type_path (pack,snd m)) p
  3390. else
  3391. display_error ctx ("Invalid package : " ^ spack (fst m) ^ " should be " ^ spack pack) p
  3392. end;
  3393. file, if !remap <> fst m then
  3394. (* build typedefs to redirect to real package *)
  3395. List.rev (List.fold_left (fun acc (t,p) ->
  3396. let build f d =
  3397. let priv = List.mem f d.d_flags in
  3398. (ETypedef {
  3399. d_name = d.d_name;
  3400. d_doc = None;
  3401. d_meta = [];
  3402. d_params = d.d_params;
  3403. d_flags = if priv then [EPrivate] else [];
  3404. d_data = CTPath (if priv then { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; } else
  3405. {
  3406. tpackage = !remap;
  3407. tname = d.d_name;
  3408. tparams = List.map (fun tp ->
  3409. TPType (CTPath { tpackage = []; tname = tp.tp_name; tparams = []; tsub = None; })
  3410. ) d.d_params;
  3411. tsub = None;
  3412. });
  3413. },p) :: acc
  3414. in
  3415. match t with
  3416. | EClass d -> build HPrivate d
  3417. | EEnum d -> build EPrivate d
  3418. | ETypedef d -> build EPrivate d
  3419. | EAbstract d -> build APrivAbstract d
  3420. | EImport _ | EUsing _ -> acc
  3421. ) [(EImport (List.map (fun s -> s,null_pos) (!remap @ [snd m]),INormal),null_pos)] decls)
  3422. else
  3423. decls
  3424. let load_module ctx m p =
  3425. let m2 = (try
  3426. Hashtbl.find ctx.g.modules m
  3427. with
  3428. Not_found ->
  3429. match !type_module_hook ctx m p with
  3430. | Some m -> m
  3431. | None ->
  3432. let is_extern = ref false in
  3433. let file, decls = (try
  3434. parse_module ctx m p
  3435. with Not_found ->
  3436. let rec loop = function
  3437. | [] ->
  3438. raise (Error (Module_not_found m,p))
  3439. | load :: l ->
  3440. match load m p with
  3441. | None -> loop l
  3442. | Some (file,(_,a)) -> file, a
  3443. in
  3444. is_extern := true;
  3445. loop ctx.com.load_extern_type
  3446. ) in
  3447. let is_extern = !is_extern in
  3448. try
  3449. type_module ctx m file ~is_extern decls p
  3450. with Forbid_package (inf,pl,pf) when p <> Ast.null_pos ->
  3451. raise (Forbid_package (inf,p::pl,pf))
  3452. ) in
  3453. add_dependency ctx.m.curmod m2;
  3454. if ctx.pass = PTypeField then flush_pass ctx PBuildClass "load_module";
  3455. m2
  3456. ;;
  3457. type_function_params_rec := type_function_params
  3458. (* former codegen.ml stuff starting here *)
  3459. (* -------------------------------------------------------------------------- *)
  3460. (* REMOTING PROXYS *)
  3461. let extend_remoting ctx c t p async prot =
  3462. if c.cl_super <> None then error "Cannot extend several classes" p;
  3463. (* remove forbidden packages *)
  3464. let rules = ctx.com.package_rules in
  3465. ctx.com.package_rules <- PMap.foldi (fun key r acc -> match r with Forbidden -> acc | _ -> PMap.add key r acc) rules PMap.empty;
  3466. (* parse module *)
  3467. let path = (t.tpackage,t.tname) in
  3468. let new_name = (if async then "Async_" else "Remoting_") ^ t.tname in
  3469. (* check if the proxy already exists *)
  3470. let t = (try
  3471. load_type_def ctx p { tpackage = fst path; tname = new_name; tparams = []; tsub = None }
  3472. with
  3473. Error (Module_not_found _,p2) when p == p2 ->
  3474. (* build it *)
  3475. Common.log ctx.com ("Building proxy for " ^ s_type_path path);
  3476. let file, decls = (try
  3477. parse_module ctx path p
  3478. with
  3479. | Not_found -> ctx.com.package_rules <- rules; error ("Could not load proxy module " ^ s_type_path path ^ (if fst path = [] then " (try using absolute path)" else "")) p
  3480. | e -> ctx.com.package_rules <- rules; raise e) in
  3481. ctx.com.package_rules <- rules;
  3482. let base_fields = [
  3483. { cff_name = "__cnx"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = []; cff_kind = FVar (Some (CTPath { tpackage = ["haxe";"remoting"]; tname = if async then "AsyncConnection" else "Connection"; tparams = []; tsub = None }),None) };
  3484. { cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun { f_args = ["c",false,None,None]; f_type = None; f_expr = Some (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p); f_params = [] } };
  3485. ] in
  3486. let tvoid = CTPath { tpackage = []; tname = "Void"; tparams = []; tsub = None } in
  3487. let build_field is_public acc f =
  3488. if f.cff_name = "new" then
  3489. acc
  3490. else match f.cff_kind with
  3491. | FFun fd when (is_public || List.mem APublic f.cff_access) && not (List.mem AStatic f.cff_access) ->
  3492. if List.exists (fun (_,_,t,_) -> t = None) fd.f_args then error ("Field " ^ f.cff_name ^ " type is not complete and cannot be used by RemotingProxy") p;
  3493. let eargs = [EArrayDecl (List.map (fun (a,_,_,_) -> (EConst (Ident a),p)) fd.f_args),p] in
  3494. let ftype = (match fd.f_type with Some (CTPath { tpackage = []; tname = "Void" }) -> None | _ -> fd.f_type) in
  3495. let fargs, eargs = if async then match ftype with
  3496. | Some tret -> fd.f_args @ ["__callb",true,Some (CTFunction ([tret],tvoid)),None], eargs @ [EConst (Ident "__callb"),p]
  3497. | _ -> fd.f_args, eargs @ [EConst (Ident "null"),p]
  3498. else
  3499. fd.f_args, eargs
  3500. in
  3501. let id = (EConst (String f.cff_name), p) in
  3502. let id = if prot then id else ECall ((EConst (Ident "__unprotect__"),p),[id]),p in
  3503. let expr = ECall (
  3504. (EField (
  3505. (ECall ((EField ((EConst (Ident "__cnx"),p),"resolve"),p),[id]),p),
  3506. "call")
  3507. ,p),eargs),p
  3508. in
  3509. let expr = if async || ftype = None then expr else (EReturn (Some expr),p) in
  3510. let fd = {
  3511. f_params = fd.f_params;
  3512. f_args = fargs;
  3513. f_type = if async then None else ftype;
  3514. f_expr = Some (EBlock [expr],p);
  3515. } in
  3516. { cff_name = f.cff_name; cff_pos = f.cff_pos; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun fd } :: acc
  3517. | _ -> acc
  3518. in
  3519. let decls = List.map (fun d ->
  3520. match d with
  3521. | EClass c, p when c.d_name = t.tname ->
  3522. let is_public = List.mem HExtern c.d_flags || List.mem HInterface c.d_flags in
  3523. let fields = List.rev (List.fold_left (build_field is_public) base_fields c.d_data) in
  3524. (EClass { c with d_flags = []; d_name = new_name; d_data = fields },p)
  3525. | _ -> d
  3526. ) decls in
  3527. let m = type_module ctx (t.tpackage,new_name) file decls p in
  3528. add_dependency ctx.m.curmod m;
  3529. try
  3530. List.find (fun tdecl -> snd (t_path tdecl) = new_name) m.m_types
  3531. with Not_found ->
  3532. error ("Module " ^ s_type_path path ^ " does not define type " ^ t.tname) p
  3533. ) in
  3534. match t with
  3535. | TClassDecl c2 when c2.cl_params = [] -> ignore(c2.cl_build()); c.cl_super <- Some (c2,[]);
  3536. | _ -> error "Remoting proxy must be a class without parameters" p
  3537. (* -------------------------------------------------------------------------- *)
  3538. (* HAXE.RTTI.GENERIC *)
  3539. exception Generic_Exception of string * Ast.pos
  3540. type generic_context = {
  3541. ctx : typer;
  3542. subst : (t * t) list;
  3543. name : string;
  3544. p : pos;
  3545. mutable mg : module_def option;
  3546. }
  3547. let make_generic ctx ps pt p =
  3548. let rec loop l1 l2 =
  3549. match l1, l2 with
  3550. | [] , [] -> []
  3551. | (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
  3552. | (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
  3553. | _ -> assert false
  3554. in
  3555. let name =
  3556. String.concat "_" (List.map2 (fun (s,_) t ->
  3557. let s_type_path_underscore (p,s) = match p with [] -> s | _ -> String.concat "_" p ^ "_" ^ s in
  3558. let rec loop top t = match follow t with
  3559. | TInst(c,tl) -> (s_type_path_underscore c.cl_path) ^ (loop_tl tl)
  3560. | TEnum(en,tl) -> (s_type_path_underscore en.e_path) ^ (loop_tl tl)
  3561. | TAbstract(a,tl) -> (s_type_path_underscore a.a_path) ^ (loop_tl tl)
  3562. | _ when not top -> "_" (* allow unknown/incompatible types as type parameters to retain old behavior *)
  3563. | TMono _ -> raise (Generic_Exception (("Could not determine type for parameter " ^ s), p))
  3564. | TDynamic _ -> "Dynamic"
  3565. | t -> raise (Generic_Exception (("Type parameter must be a class or enum instance (found " ^ (s_type (print_context()) t) ^ ")"), p))
  3566. and loop_tl tl = match tl with
  3567. | [] -> ""
  3568. | tl -> "_" ^ String.concat "_" (List.map (loop false) tl)
  3569. in
  3570. loop true t
  3571. ) ps pt)
  3572. in
  3573. {
  3574. ctx = ctx;
  3575. subst = loop ps pt;
  3576. name = name;
  3577. p = p;
  3578. mg = None;
  3579. }
  3580. let rec generic_substitute_type gctx t =
  3581. match t with
  3582. | TInst ({ cl_kind = KGeneric } as c2,tl2) ->
  3583. (* maybe loop, or generate cascading generics *)
  3584. let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c2) gctx.p in
  3585. let t = f (List.map (generic_substitute_type gctx) tl2) in
  3586. (match follow t,gctx.mg with TInst(c,_), Some m -> add_dependency m c.cl_module | _ -> ());
  3587. t
  3588. | _ ->
  3589. try
  3590. generic_substitute_type gctx (List.assq t gctx.subst)
  3591. with Not_found ->
  3592. Type.map (generic_substitute_type gctx) t
  3593. let generic_substitute_expr gctx e =
  3594. let vars = Hashtbl.create 0 in
  3595. let build_var v =
  3596. try
  3597. Hashtbl.find vars v.v_id
  3598. with Not_found ->
  3599. let v2 = alloc_var v.v_name (generic_substitute_type gctx v.v_type) v.v_pos in
  3600. v2.v_meta <- v.v_meta;
  3601. Hashtbl.add vars v.v_id v2;
  3602. v2
  3603. in
  3604. let rec build_expr e =
  3605. match e.eexpr with
  3606. | TField(e1, FInstance({cl_kind = KGeneric} as c,tl,cf)) ->
  3607. let _, _, f = gctx.ctx.g.do_build_instance gctx.ctx (TClassDecl c) gctx.p in
  3608. let t = f (List.map (generic_substitute_type gctx) tl) in
  3609. let fa = try
  3610. quick_field t cf.cf_name
  3611. with Not_found ->
  3612. error (Printf.sprintf "Type %s has no field %s (possible typing order issue)" (s_type (print_context()) t) cf.cf_name) e.epos
  3613. in
  3614. build_expr {e with eexpr = TField(e1,fa)}
  3615. | TTypeExpr (TClassDecl ({cl_kind = KTypeParameter _;} as c)) when Meta.has Meta.Const c.cl_meta ->
  3616. let rec loop subst = match subst with
  3617. | (t1,t2) :: subst ->
  3618. begin match follow t1 with
  3619. | TInst(c2,_) when c == c2 -> t2
  3620. | _ -> loop subst
  3621. end
  3622. | [] -> raise Not_found
  3623. in
  3624. begin try
  3625. let t = loop gctx.subst in
  3626. begin match follow t with
  3627. | TInst({cl_kind = KExpr e},_) -> type_expr gctx.ctx e Value
  3628. | _ -> error "Only Const type parameters can be used as value" e.epos
  3629. end
  3630. with Not_found ->
  3631. e
  3632. end
  3633. | _ ->
  3634. map_expr_type build_expr (generic_substitute_type gctx) build_var e
  3635. in
  3636. build_expr e
  3637. let get_short_name =
  3638. let i = ref (-1) in
  3639. (fun () ->
  3640. incr i;
  3641. Printf.sprintf "Hx___short___hx_type_%i" !i
  3642. )
  3643. let rec build_generic ctx c p tl =
  3644. let pack = fst c.cl_path in
  3645. let recurse = ref false in
  3646. let rec check_recursive t =
  3647. match follow t with
  3648. | TInst (c2,tl) ->
  3649. (match c2.cl_kind with
  3650. | KTypeParameter tl ->
  3651. if not (is_generic_parameter ctx c2) && has_ctor_constraint c2 then
  3652. error "Type parameters with a constructor cannot be used non-generically" p;
  3653. recurse := true
  3654. | _ -> ());
  3655. List.iter check_recursive tl;
  3656. | _ ->
  3657. ()
  3658. in
  3659. List.iter check_recursive tl;
  3660. if !recurse || ctx.com.display <> DMNone then begin
  3661. TInst (c,tl) (* build a normal instance *)
  3662. end else begin
  3663. let gctx = make_generic ctx c.cl_params tl p in
  3664. let name = (snd c.cl_path) ^ "_" ^ gctx.name in
  3665. try
  3666. load_instance ctx { tpackage = pack; tname = name; tparams = []; tsub = None } p false
  3667. with Error(Module_not_found path,_) when path = (pack,name) ->
  3668. let m = (try Hashtbl.find ctx.g.modules (Hashtbl.find ctx.g.types_module c.cl_path) with Not_found -> assert false) in
  3669. let ctx = { ctx with m = { ctx.m with module_types = m.m_types @ ctx.m.module_types } } in
  3670. ignore(c.cl_build()); (* make sure the super class is already setup *)
  3671. let mg = {
  3672. m_id = alloc_mid();
  3673. m_path = (pack,name);
  3674. m_types = [];
  3675. m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake;
  3676. } in
  3677. gctx.mg <- Some mg;
  3678. let cg = mk_class mg (pack,name) c.cl_pos in
  3679. mg.m_types <- [TClassDecl cg];
  3680. Hashtbl.add ctx.g.modules mg.m_path mg;
  3681. add_dependency mg m;
  3682. add_dependency ctx.m.curmod mg;
  3683. (* ensure that type parameters are set in dependencies *)
  3684. let dep_stack = ref [] in
  3685. let rec loop t =
  3686. if not (List.memq t !dep_stack) then begin
  3687. dep_stack := t :: !dep_stack;
  3688. match t with
  3689. | TInst (c,tl) -> add_dep c.cl_module tl
  3690. | TEnum (e,tl) -> add_dep e.e_module tl
  3691. | TType (t,tl) -> add_dep t.t_module tl
  3692. | TAbstract (a,tl) -> add_dep a.a_module tl
  3693. | TMono r ->
  3694. (match !r with
  3695. | None -> ()
  3696. | Some t -> loop t)
  3697. | TLazy f ->
  3698. loop ((!f)());
  3699. | TDynamic t2 ->
  3700. if t == t2 then () else loop t2
  3701. | TAnon a ->
  3702. PMap.iter (fun _ f -> loop f.cf_type) a.a_fields
  3703. | TFun (args,ret) ->
  3704. List.iter (fun (_,_,t) -> loop t) args;
  3705. loop ret
  3706. end
  3707. and add_dep m tl =
  3708. add_dependency mg m;
  3709. List.iter loop tl
  3710. in
  3711. List.iter loop tl;
  3712. let build_field cf_old =
  3713. (* We have to clone the type parameters (issue #4672). We cannot substitute the constraints immediately because
  3714. we need the full substitution list first. *)
  3715. let param_subst,params = List.fold_left (fun (subst,params) (s,t) -> match follow t with
  3716. | TInst(c,tl) as t ->
  3717. let t2 = TInst({c with cl_pos = c.cl_pos;},tl) in
  3718. (t,t2) :: subst,(s,t2) :: params
  3719. | _ -> assert false
  3720. ) ([],[]) cf_old.cf_params in
  3721. let gctx = {gctx with subst = param_subst @ gctx.subst} in
  3722. let cf_new = {cf_old with cf_pos = cf_old.cf_pos} in (* copy *)
  3723. (* Type parameter constraints are substituted here. *)
  3724. cf_new.cf_params <- List.rev_map (fun (s,t) -> match follow t with
  3725. | TInst({cl_kind = KTypeParameter tl1} as c,_) ->
  3726. let tl1 = List.map (generic_substitute_type gctx) tl1 in
  3727. c.cl_kind <- KTypeParameter tl1;
  3728. s,t
  3729. | _ -> assert false
  3730. ) params;
  3731. let f () =
  3732. let t = generic_substitute_type gctx cf_old.cf_type in
  3733. ignore (follow t);
  3734. begin try (match cf_old.cf_expr with
  3735. | None ->
  3736. begin match cf_old.cf_kind with
  3737. | Method _ when not c.cl_interface && not c.cl_extern ->
  3738. display_error ctx (Printf.sprintf "Field %s has no expression (possible typing order issue)" cf_new.cf_name) cf_new.cf_pos;
  3739. display_error ctx (Printf.sprintf "While building %s" (s_type_path cg.cl_path)) p;
  3740. | _ ->
  3741. ()
  3742. end
  3743. | Some e ->
  3744. cf_new.cf_expr <- Some (generic_substitute_expr gctx e)
  3745. ) with Unify_error l ->
  3746. error (error_msg (Unify l)) cf_new.cf_pos
  3747. end;
  3748. t
  3749. in
  3750. let r = exc_protect ctx (fun r ->
  3751. let t = mk_mono() in
  3752. r := (fun() -> t);
  3753. unify_raise ctx (f()) t p;
  3754. t
  3755. ) "build_generic" in
  3756. delay ctx PForce (fun() -> ignore ((!r)()));
  3757. cf_new.cf_type <- TLazy r;
  3758. cf_new
  3759. in
  3760. if c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
  3761. List.iter (fun cf -> match cf.cf_kind with
  3762. | Method MethMacro when not ctx.in_macro -> ()
  3763. | _ -> error "A generic class can't have static fields" cf.cf_pos
  3764. ) c.cl_ordered_statics;
  3765. cg.cl_super <- (match c.cl_super with
  3766. | None -> None
  3767. | Some (cs,pl) ->
  3768. let find_class subst =
  3769. let rec loop subst = match subst with
  3770. | (TInst(c,[]),t) :: subst when c == cs -> t
  3771. | _ :: subst -> loop subst
  3772. | [] -> raise Not_found
  3773. in
  3774. try
  3775. if pl <> [] then raise Not_found;
  3776. let t = loop subst in
  3777. (* extended type parameter: concrete type must have a constructor, but generic base class must not have one *)
  3778. begin match follow t,c.cl_constructor with
  3779. | TInst(cs,_),None ->
  3780. ignore(cs.cl_build());
  3781. begin match cs.cl_constructor with
  3782. | None -> error ("Cannot use " ^ (s_type_path cs.cl_path) ^ " as type parameter because it is extended and has no constructor") p
  3783. | _ -> ()
  3784. end;
  3785. | _,Some cf -> error "Generics extending type parameters cannot have constructors" cf.cf_pos
  3786. | _ -> ()
  3787. end;
  3788. t
  3789. with Not_found ->
  3790. apply_params c.cl_params tl (TInst(cs,pl))
  3791. in
  3792. let ts = follow (find_class gctx.subst) in
  3793. let cs,pl = Inheritance.check_extends ctx c ts p in
  3794. match cs.cl_kind with
  3795. | KGeneric ->
  3796. (match build_generic ctx cs p pl with
  3797. | TInst (cs,pl) -> Some (cs,pl)
  3798. | _ -> assert false)
  3799. | _ -> Some(cs,pl)
  3800. );
  3801. add_constructor ctx cg false p;
  3802. cg.cl_kind <- KGenericInstance (c,tl);
  3803. cg.cl_meta <- (Meta.NoDoc,[],p) :: cg.cl_meta;
  3804. if has_meta Meta.Keep c.cl_meta then cg.cl_meta <- (Meta.Keep,[],p) :: cg.cl_meta;
  3805. cg.cl_interface <- c.cl_interface;
  3806. cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
  3807. | _, Some cf, _ -> Some (build_field cf)
  3808. | Some ctor, _, _ -> Some ctor
  3809. | None, None, None -> None
  3810. | _ -> error "Please define a constructor for this class in order to use it as generic" c.cl_pos
  3811. );
  3812. cg.cl_implements <- List.map (fun (i,tl) ->
  3813. (match follow (generic_substitute_type gctx (TInst (i, List.map (generic_substitute_type gctx) tl))) with
  3814. | TInst (i,tl) -> i, tl
  3815. | _ -> assert false)
  3816. ) c.cl_implements;
  3817. cg.cl_ordered_fields <- List.map (fun f ->
  3818. let f = build_field f in
  3819. cg.cl_fields <- PMap.add f.cf_name f cg.cl_fields;
  3820. f
  3821. ) c.cl_ordered_fields;
  3822. cg.cl_overrides <- List.map (fun f ->
  3823. try PMap.find f.cf_name cg.cl_fields with Not_found -> assert false
  3824. ) c.cl_overrides;
  3825. (* In rare cases the class name can become too long, so let's shorten it (issue #3090). *)
  3826. if String.length (snd cg.cl_path) > 254 then begin
  3827. let n = get_short_name () in
  3828. cg.cl_meta <- (Meta.Native,[EConst(String (n)),p],p) :: cg.cl_meta;
  3829. end;
  3830. TInst (cg,[])
  3831. end
  3832. (* -------------------------------------------------------------------------- *)
  3833. (* HAXE.XML.PROXY *)
  3834. let extend_xml_proxy ctx c t file p =
  3835. let t = load_complex_type ctx p t in
  3836. let file = (try Common.find_file ctx.com file with Not_found -> file) in
  3837. add_dependency c.cl_module (create_fake_module ctx file);
  3838. let used = ref PMap.empty in
  3839. let print_results() =
  3840. PMap.iter (fun id used ->
  3841. if not used then ctx.com.warning (id ^ " is not used") p;
  3842. ) (!used)
  3843. in
  3844. let check_used = Common.defined ctx.com Define.CheckXmlProxy in
  3845. if check_used then ctx.g.hook_generate <- print_results :: ctx.g.hook_generate;
  3846. try
  3847. let rec loop = function
  3848. | Xml.Element (_,attrs,childs) ->
  3849. (try
  3850. let id = List.assoc "id" attrs in
  3851. if PMap.mem id c.cl_fields then error ("Duplicate id " ^ id) p;
  3852. let t = if not check_used then t else begin
  3853. used := PMap.add id false (!used);
  3854. let ft() = used := PMap.add id true (!used); t in
  3855. TLazy (ref ft)
  3856. end in
  3857. let f = {
  3858. cf_name = id;
  3859. cf_type = t;
  3860. cf_public = true;
  3861. cf_pos = p;
  3862. cf_doc = None;
  3863. cf_meta = no_meta;
  3864. cf_kind = Var { v_read = AccResolve; v_write = AccNo };
  3865. cf_params = [];
  3866. cf_expr = None;
  3867. cf_overloads = [];
  3868. } in
  3869. c.cl_fields <- PMap.add id f c.cl_fields;
  3870. with
  3871. Not_found -> ());
  3872. List.iter loop childs;
  3873. | Xml.PCData _ -> ()
  3874. in
  3875. loop (Xml.parse_file file)
  3876. with
  3877. | Xml.Error e -> error ("XML error " ^ Xml.error e) p
  3878. | Xml.File_not_found f -> error ("XML File not found : " ^ f) p
  3879. (* -------------------------------------------------------------------------- *)
  3880. (* MACRO TYPE *)
  3881. let get_macro_path ctx e args p =
  3882. let rec loop e =
  3883. match fst e with
  3884. | EField (e,f) -> f :: loop e
  3885. | EConst (Ident i) -> [i]
  3886. | _ -> error "Invalid macro call" p
  3887. in
  3888. let path = match e with
  3889. | (EConst(Ident i)),_ ->
  3890. let path = try
  3891. if not (PMap.mem i ctx.curclass.cl_statics) then raise Not_found;
  3892. ctx.curclass.cl_path
  3893. with Not_found -> try
  3894. (t_infos (fst (PMap.find i ctx.m.module_globals))).mt_path
  3895. with Not_found ->
  3896. error "Invalid macro call" p
  3897. in
  3898. i :: (snd path) :: (fst path)
  3899. | _ ->
  3900. loop e
  3901. in
  3902. (match path with
  3903. | meth :: cl :: path -> (List.rev path,cl), meth, args
  3904. | _ -> error "Invalid macro call" p)
  3905. let build_macro_type ctx pl p =
  3906. let path, field, args = (match pl with
  3907. | [TInst ({ cl_kind = KExpr (ECall (e,args),_) },_)]
  3908. | [TInst ({ cl_kind = KExpr (EArrayDecl [ECall (e,args),_],_) },_)] ->
  3909. get_macro_path ctx e args p
  3910. | _ ->
  3911. error "MacroType requires a single expression call parameter" p
  3912. ) in
  3913. let old = ctx.ret in
  3914. let t = (match ctx.g.do_macro ctx MMacroType path field args p with
  3915. | None -> mk_mono()
  3916. | Some _ -> ctx.ret
  3917. ) in
  3918. ctx.ret <- old;
  3919. t
  3920. let build_macro_build ctx c pl cfl p =
  3921. let path, field, args = match Meta.get Meta.GenericBuild c.cl_meta with
  3922. | _,[ECall(e,args),_],_ -> get_macro_path ctx e args p
  3923. | _ -> error "genericBuild requires a single expression call parameter" p
  3924. in
  3925. let old = ctx.ret,ctx.g.get_build_infos in
  3926. ctx.g.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl));
  3927. let t = (match ctx.g.do_macro ctx MMacroType path field args p with
  3928. | None -> mk_mono()
  3929. | Some _ -> ctx.ret
  3930. ) in
  3931. ctx.ret <- fst old;
  3932. ctx.g.get_build_infos <- snd old;
  3933. t
  3934. (* -------------------------------------------------------------------------- *)
  3935. (* API EVENTS *)
  3936. let build_instance ctx mtype p =
  3937. match mtype with
  3938. | TClassDecl c ->
  3939. if ctx.pass > PBuildClass then ignore(c.cl_build());
  3940. let build f s =
  3941. let r = exc_protect ctx (fun r ->
  3942. let t = mk_mono() in
  3943. r := (fun() -> t);
  3944. let tf = (f()) in
  3945. unify_raise ctx tf t p;
  3946. link_dynamic t tf;
  3947. t
  3948. ) s in
  3949. delay ctx PForce (fun() -> ignore ((!r)()));
  3950. TLazy r
  3951. in
  3952. let ft = (fun pl ->
  3953. match c.cl_kind with
  3954. | KGeneric ->
  3955. build (fun () -> build_generic ctx c p pl) "build_generic"
  3956. | KMacroType ->
  3957. build (fun () -> build_macro_type ctx pl p) "macro_type"
  3958. | KGenericBuild cfl ->
  3959. build (fun () -> build_macro_build ctx c pl cfl p) "generic_build"
  3960. | _ ->
  3961. TInst (c,pl)
  3962. ) in
  3963. c.cl_params , c.cl_path , ft
  3964. | TEnumDecl e ->
  3965. e.e_params , e.e_path , (fun t -> TEnum (e,t))
  3966. | TTypeDecl t ->
  3967. t.t_params , t.t_path , (fun tl -> TType(t,tl))
  3968. | TAbstractDecl a ->
  3969. a.a_params, a.a_path, (fun tl -> TAbstract(a,tl))
  3970. let on_inherit ctx c p (is_extends,tp) =
  3971. if not is_extends then
  3972. true
  3973. else match tp with
  3974. | { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t)] } ->
  3975. extend_remoting ctx c t p false true;
  3976. false
  3977. | { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t)] } ->
  3978. extend_remoting ctx c t p true true;
  3979. false
  3980. | { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType t] } ->
  3981. extend_xml_proxy ctx c t file p;
  3982. true
  3983. | _ ->
  3984. true