displayTexpr.ml 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. open Globals
  2. open Common
  3. open Ast
  4. open Type
  5. open Typecore
  6. open DisplayPosition
  7. open CompilationCache
  8. let find_field_by_position sc p =
  9. List.find (fun cff ->
  10. if pos cff.cff_name = p then true else false
  11. ) sc.d_data
  12. let find_enum_field_by_position sc p =
  13. List.find (fun eff ->
  14. if pos eff.ec_name = p then true else false
  15. ) sc.d_data
  16. let find_class_by_position decls p =
  17. let rec loop dl = match dl with
  18. | (EClass c,_) :: dl when pos c.d_name = p -> c
  19. | _ :: dl -> loop dl
  20. | [] -> raise Not_found
  21. in
  22. loop decls
  23. let find_module_static_by_position decls p =
  24. let rec loop dl = match dl with
  25. | (EStatic d,_) :: dl when pos d.d_name = p -> d
  26. | _ :: dl -> loop dl
  27. | [] -> raise Not_found
  28. in
  29. loop decls
  30. let find_enum_by_position decls p =
  31. let rec loop dl = match dl with
  32. | (EEnum en,_) :: dl when pos en.d_name = p -> en
  33. | _ :: dl -> loop dl
  34. | [] -> raise Not_found
  35. in
  36. loop decls
  37. let find_typedef_by_position decls p =
  38. let rec loop dl = match dl with
  39. | (ETypedef td,_) :: dl when pos td.d_name = p -> td
  40. | _ :: dl -> loop dl
  41. | [] -> raise Not_found
  42. in
  43. loop decls
  44. let find_abstract_by_position decls p =
  45. let rec loop dl = match dl with
  46. | (EAbstract a,_) :: dl when pos a.d_name = p -> a
  47. | _ :: dl -> loop dl
  48. | [] -> raise Not_found
  49. in
  50. loop decls
  51. let actually_check_display_field ctx c cff p =
  52. let context_init = new TypeloadFields.context_init in
  53. let cctx = TypeloadFields.create_class_context c context_init p in
  54. let ctx = TypeloadFields.create_typer_context_for_class ctx cctx p in
  55. let cff = TypeloadFields.transform_field (ctx,cctx) c cff (ref []) (pos cff.cff_name) in
  56. let display_modifier = Typeload.check_field_access ctx cff in
  57. let fctx = TypeloadFields.create_field_context ctx cctx cff true display_modifier in
  58. let cf = TypeloadFields.init_field (ctx,cctx,fctx) cff in
  59. flush_pass ctx PTypeField "check_display_field";
  60. ignore(follow cf.cf_type)
  61. let check_display_field ctx sc c cf =
  62. let cff = find_field_by_position sc cf.cf_name_pos in
  63. actually_check_display_field ctx c cff cf.cf_pos
  64. let check_display_class ctx decls c =
  65. let check_field sc cf =
  66. if display_position#enclosed_in cf.cf_pos then
  67. check_display_field ctx sc c cf;
  68. DisplayEmitter.check_display_metadata ctx cf.cf_meta
  69. in
  70. let check_field sc cf =
  71. check_field sc cf;
  72. List.iter (check_field sc) cf.cf_overloads
  73. in
  74. match c.cl_kind with
  75. | KAbstractImpl a ->
  76. let sa = find_abstract_by_position decls c.cl_name_pos in
  77. let check_field = check_field sa in
  78. List.iter check_field c.cl_ordered_statics;
  79. | _ ->
  80. let sc = find_class_by_position decls c.cl_name_pos in
  81. ignore(Typeload.type_type_params ctx TPHType c.cl_path (fun() -> c.cl_params) null_pos sc.d_params);
  82. List.iter (function
  83. | (HExtends(ct,p) | HImplements(ct,p)) when display_position#enclosed_in p ->
  84. ignore(Typeload.load_instance ~allow_display:true ctx (ct,p) false)
  85. | _ ->
  86. ()
  87. ) sc.d_flags;
  88. let check_field = check_field sc in
  89. List.iter check_field c.cl_ordered_statics;
  90. List.iter check_field c.cl_ordered_fields;
  91. Option.may check_field c.cl_constructor
  92. let check_display_enum ctx decls en =
  93. let se = find_enum_by_position decls en.e_name_pos in
  94. ignore(Typeload.type_type_params ctx TPHType en.e_path (fun() -> en.e_params) null_pos se.d_params);
  95. PMap.iter (fun _ ef ->
  96. if display_position#enclosed_in ef.ef_pos then begin
  97. let sef = find_enum_field_by_position se ef.ef_name_pos in
  98. ignore(TypeloadModule.TypeLevel.load_enum_field ctx en (TEnum (en,extract_param_types en.e_params)) (ref false) (ref 0) sef)
  99. end
  100. ) en.e_constrs
  101. let check_display_typedef ctx decls td =
  102. let st = find_typedef_by_position decls td.t_name_pos in
  103. ignore(Typeload.type_type_params ctx TPHType td.t_path (fun() -> td.t_params) null_pos st.d_params);
  104. ignore(Typeload.load_complex_type ctx true st.d_data)
  105. let check_display_abstract ctx decls a =
  106. let sa = find_abstract_by_position decls a.a_name_pos in
  107. ignore(Typeload.type_type_params ctx TPHType a.a_path (fun() -> a.a_params) null_pos sa.d_params);
  108. List.iter (function
  109. | (AbOver(ct,p) | AbFrom(ct,p) | AbTo(ct,p)) when display_position#enclosed_in p ->
  110. ignore(Typeload.load_complex_type ctx true (ct,p))
  111. | _ ->
  112. ()
  113. ) sa.d_flags
  114. let check_display_module_fields ctx decls m =
  115. Option.may (fun c ->
  116. List.iter (fun cf ->
  117. if display_position#enclosed_in cf.cf_pos then begin
  118. let cff = find_module_static_by_position decls cf.cf_name_pos in
  119. actually_check_display_field ctx c (TypeloadModule.field_of_static_definition cff cf.cf_pos) cf.cf_pos;
  120. end;
  121. DisplayEmitter.check_display_metadata ctx cf.cf_meta
  122. ) c.cl_ordered_statics
  123. ) m.m_statics
  124. let check_display_module ctx decls m =
  125. let imports = List.filter (function
  126. | (EImport _ | EUsing _),_ -> true
  127. | _ -> false
  128. ) decls in
  129. let imports = TypeloadModule.ModuleLevel.handle_import_hx ctx m imports null_pos in
  130. let ctx = TypeloadModule.type_types_into_module ctx m imports null_pos in
  131. List.iter (fun md ->
  132. let infos = t_infos md in
  133. if display_position#enclosed_in infos.mt_name_pos then
  134. DisplayEmitter.display_module_type ctx md infos.mt_name_pos;
  135. begin if display_position#enclosed_in infos.mt_pos then match md with
  136. | TClassDecl c ->
  137. check_display_class ctx decls c
  138. | TEnumDecl en ->
  139. check_display_enum ctx decls en
  140. | TTypeDecl td ->
  141. check_display_typedef ctx decls td
  142. | TAbstractDecl a ->
  143. check_display_abstract ctx decls a
  144. end;
  145. DisplayEmitter.check_display_metadata ctx infos.mt_meta
  146. ) m.m_types;
  147. check_display_module_fields ctx decls m
  148. let check_display_file ctx cs =
  149. match ctx.com.cache with
  150. | Some cc ->
  151. begin try
  152. let p = DisplayPosition.display_position#get in
  153. let cfile = cc#find_file (ctx.com.file_keys#get p.pfile) in
  154. let path = (cfile.c_package,get_module_name_of_cfile p.pfile cfile) in
  155. TypeloadParse.PdiHandler.handle_pdi ctx.com cfile.c_pdi;
  156. (* We have to go through type_module_hook because one of the module's dependencies could be
  157. invalid (issue #8991). *)
  158. begin match !TypeloadModule.type_module_hook ctx path null_pos with
  159. | None -> raise Not_found
  160. | Some m -> check_display_module ctx cfile.c_decls m
  161. end
  162. with Not_found ->
  163. let fkey = DisplayPosition.display_position#get_file_key in
  164. (* force parsing again : if the completion point have been changed *)
  165. cs#remove_files fkey;
  166. cs#taint_modules fkey "check_display_file";
  167. end
  168. | None ->
  169. ()