periplus-map 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. periplus/__init__.py +70 -0
  2. periplus/checkmap.py +80 -0
  3. periplus/cli.py +658 -0
  4. periplus/contract/schema/map.schema.json +138 -0
  5. periplus/contract/schema/navigation.schema.json +200 -0
  6. periplus/contract/schema/pack-file.schema.json +1405 -0
  7. periplus/contract/schema/pack-manifest.schema.json +245 -0
  8. periplus/contract/schema/project-settings.schema.json +85 -0
  9. periplus/contract/spec/engine.md +151 -0
  10. periplus/contract/spec/rules.md +352 -0
  11. periplus/detect.py +228 -0
  12. periplus/engine/__init__.py +5 -0
  13. periplus/engine/check.py +481 -0
  14. periplus/engine/emit.py +368 -0
  15. periplus/engine/packload.py +2321 -0
  16. periplus/engine/pattern.py +27 -0
  17. periplus/engine/rules.py +1946 -0
  18. periplus/engine/select.py +491 -0
  19. periplus/engine/source.py +172 -0
  20. periplus/engine/tree.py +424 -0
  21. periplus/errors.py +332 -0
  22. periplus/init.py +358 -0
  23. periplus/layout.py +28 -0
  24. periplus/manifest.py +498 -0
  25. periplus/map.py +364 -0
  26. periplus/navigate/__init__.py +1 -0
  27. periplus/navigate/find.py +143 -0
  28. periplus/navigate/ids.py +30 -0
  29. periplus/navigate/listing.py +42 -0
  30. periplus/navigate/mapfile.py +189 -0
  31. periplus/navigate/path.py +175 -0
  32. periplus/navigate/show.py +175 -0
  33. periplus/navigate/types.py +83 -0
  34. periplus/navigate/walk.py +138 -0
  35. periplus/packs/advancedqueue_basic@0.0.1/pack.yaml +14 -0
  36. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type.yaml +9 -0
  37. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_annotation.yaml +43 -0
  38. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_attribute.yaml +43 -0
  39. periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent.yaml +8 -0
  40. periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent_attribute.yaml +43 -0
  41. periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call.yaml +8 -0
  42. periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call_attribute.yaml +43 -0
  43. periplus/packs/ai_basic@0.0.1/pack.yaml +15 -0
  44. periplus/packs/config_pages_basic@0.0.1/bundle/config_pages_bundle_config.yaml +54 -0
  45. periplus/packs/config_pages_basic@0.0.1/pack.yaml +11 -0
  46. periplus/packs/crop_basic@0.0.1/bundle/crop_bundle_config.yaml +54 -0
  47. periplus/packs/crop_basic@0.0.1/pack.yaml +11 -0
  48. periplus/packs/drupal@0.1.0/block/block_placement.yaml +25 -0
  49. periplus/packs/drupal@0.1.0/block/block_placement_code.yaml +58 -0
  50. periplus/packs/drupal@0.1.0/block/block_placement_config.yaml +53 -0
  51. periplus/packs/drupal@0.1.0/block/block_plugin.yaml +52 -0
  52. periplus/packs/drupal@0.1.0/block/block_plugin_altered.yaml +61 -0
  53. periplus/packs/drupal@0.1.0/block/block_plugin_annotation.yaml +69 -0
  54. periplus/packs/drupal@0.1.0/block/block_plugin_attribute.yaml +56 -0
  55. periplus/packs/drupal@0.1.0/block/block_plugin_content.yaml +46 -0
  56. periplus/packs/drupal@0.1.0/block/block_plugin_derived.yaml +110 -0
  57. periplus/packs/drupal@0.1.0/block/block_plugin_deriver.yaml +30 -0
  58. periplus/packs/drupal@0.1.0/block/block_type.yaml +14 -0
  59. periplus/packs/drupal@0.1.0/block/block_type_code.yaml +43 -0
  60. periplus/packs/drupal@0.1.0/block/block_type_config.yaml +45 -0
  61. periplus/packs/drupal@0.1.0/cache/cache.yaml +18 -0
  62. periplus/packs/drupal@0.1.0/cache/cache_backend.yaml +31 -0
  63. periplus/packs/drupal@0.1.0/component/sdc.yaml +19 -0
  64. periplus/packs/drupal@0.1.0/component/sdc_definition.yaml +25 -0
  65. periplus/packs/drupal@0.1.0/component/sdc_use.yaml +25 -0
  66. periplus/packs/drupal@0.1.0/config/config_object.yaml +65 -0
  67. periplus/packs/drupal@0.1.0/display/display.yaml +32 -0
  68. periplus/packs/drupal@0.1.0/display/display_code.yaml +53 -0
  69. periplus/packs/drupal@0.1.0/display/display_config.yaml +95 -0
  70. periplus/packs/drupal@0.1.0/entity/entity.yaml +33 -0
  71. periplus/packs/drupal@0.1.0/entity/entity_class.yaml +60 -0
  72. periplus/packs/drupal@0.1.0/entity/entity_save.yaml +27 -0
  73. periplus/packs/drupal@0.1.0/entity/entity_type_annotation.yaml +85 -0
  74. periplus/packs/drupal@0.1.0/entity/entity_type_attribute.yaml +76 -0
  75. periplus/packs/drupal@0.1.0/field/field_instance_code.yaml +40 -0
  76. periplus/packs/drupal@0.1.0/field/field_instance_config.yaml +58 -0
  77. periplus/packs/drupal@0.1.0/field/field_storage.yaml +37 -0
  78. periplus/packs/drupal@0.1.0/field/field_storage_code.yaml +39 -0
  79. periplus/packs/drupal@0.1.0/field/field_storage_config.yaml +24 -0
  80. periplus/packs/drupal@0.1.0/form/form.yaml +48 -0
  81. periplus/packs/drupal@0.1.0/form/form_class.yaml +50 -0
  82. periplus/packs/drupal@0.1.0/form/form_id.yaml +48 -0
  83. periplus/packs/drupal@0.1.0/form/form_methods.yaml +39 -0
  84. periplus/packs/drupal@0.1.0/hook/hook.yaml +8 -0
  85. periplus/packs/drupal@0.1.0/hook/hook_attribute.yaml +28 -0
  86. periplus/packs/drupal@0.1.0/module/module.yaml +8 -0
  87. periplus/packs/drupal@0.1.0/module/module_info.yaml +50 -0
  88. periplus/packs/drupal@0.1.0/pack.yaml +184 -0
  89. periplus/packs/drupal@0.1.0/plugin/plugin.yaml +17 -0
  90. periplus/packs/drupal@0.1.0/plugin/plugin_annotation.yaml +120 -0
  91. periplus/packs/drupal@0.1.0/recommendations/recommendations.yaml +14 -0
  92. periplus/packs/drupal@0.1.0/service/service.yaml +19 -0
  93. periplus/packs/drupal@0.1.0/service/service_autowire.yaml +28 -0
  94. periplus/packs/drupal@0.1.0/service/service_definition.yaml +24 -0
  95. periplus/packs/drupal@0.1.0/service/service_use.yaml +43 -0
  96. periplus/packs/drupal_basic@0.3.0/action/action.yaml +9 -0
  97. periplus/packs/drupal_basic@0.3.0/action/action_annotation.yaml +43 -0
  98. periplus/packs/drupal_basic@0.3.0/action/action_attribute.yaml +43 -0
  99. periplus/packs/drupal_basic@0.3.0/block/block_placement.yaml +16 -0
  100. periplus/packs/drupal_basic@0.3.0/block/block_placement_config.yaml +51 -0
  101. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin.yaml +14 -0
  102. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_annotation.yaml +47 -0
  103. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_attribute.yaml +43 -0
  104. periplus/packs/drupal_basic@0.3.0/block_type/block_type.yaml +8 -0
  105. periplus/packs/drupal_basic@0.3.0/block_type/block_type_config.yaml +54 -0
  106. periplus/packs/drupal_basic@0.3.0/boundary/boundary_types.yaml +19 -0
  107. periplus/packs/drupal_basic@0.3.0/bundle/bundle.yaml +20 -0
  108. periplus/packs/drupal_basic@0.3.0/bundle/bundle_config.yaml +393 -0
  109. periplus/packs/drupal_basic@0.3.0/call/call.yaml +349 -0
  110. periplus/packs/drupal_basic@0.3.0/component/component.yaml +30 -0
  111. periplus/packs/drupal_basic@0.3.0/config/config_object.yaml +119 -0
  112. periplus/packs/drupal_basic@0.3.0/constraint/constraint.yaml +8 -0
  113. periplus/packs/drupal_basic@0.3.0/constraint/constraint_annotation.yaml +43 -0
  114. periplus/packs/drupal_basic@0.3.0/constraint/constraint_attribute.yaml +43 -0
  115. periplus/packs/drupal_basic@0.3.0/display/display.yaml +30 -0
  116. periplus/packs/drupal_basic@0.3.0/display/display_config.yaml +203 -0
  117. periplus/packs/drupal_basic@0.3.0/display/display_mode_config.yaml +60 -0
  118. periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_annotation.yaml +46 -0
  119. periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_attribute.yaml +43 -0
  120. periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_annotation.yaml +46 -0
  121. periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_attribute.yaml +43 -0
  122. periplus/packs/drupal_basic@0.3.0/entity_type/entity_type.yaml +16 -0
  123. periplus/packs/drupal_basic@0.3.0/field/field_instance_config.yaml +116 -0
  124. periplus/packs/drupal_basic@0.3.0/field/field_storage.yaml +21 -0
  125. periplus/packs/drupal_basic@0.3.0/field/field_storage_config.yaml +45 -0
  126. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter.yaml +8 -0
  127. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_annotation.yaml +46 -0
  128. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_attribute.yaml +43 -0
  129. periplus/packs/drupal_basic@0.3.0/field_type/field_type_annotation.yaml +46 -0
  130. periplus/packs/drupal_basic@0.3.0/field_type/field_type_attribute.yaml +50 -0
  131. periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_annotation.yaml +46 -0
  132. periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_attribute.yaml +50 -0
  133. periplus/packs/drupal_basic@0.3.0/form/form_id.yaml +80 -0
  134. periplus/packs/drupal_basic@0.3.0/hook/hook.yaml +100 -0
  135. periplus/packs/drupal_basic@0.3.0/hook/hook_attribute.yaml +64 -0
  136. periplus/packs/drupal_basic@0.3.0/hook/hook_theme_include.yaml +34 -0
  137. periplus/packs/drupal_basic@0.3.0/library/library.yaml +12 -0
  138. periplus/packs/drupal_basic@0.3.0/library/library_definition.yaml +58 -0
  139. periplus/packs/drupal_basic@0.3.0/local_action/local_action.yaml +12 -0
  140. periplus/packs/drupal_basic@0.3.0/local_action/local_action_definition.yaml +49 -0
  141. periplus/packs/drupal_basic@0.3.0/mail/mail.yaml +8 -0
  142. periplus/packs/drupal_basic@0.3.0/mail/mail_attribute.yaml +43 -0
  143. periplus/packs/drupal_basic@0.3.0/media_source/media_source.yaml +8 -0
  144. periplus/packs/drupal_basic@0.3.0/media_source/media_source_annotation.yaml +43 -0
  145. periplus/packs/drupal_basic@0.3.0/media_source/media_source_attribute.yaml +79 -0
  146. periplus/packs/drupal_basic@0.3.0/menu_link/menu_link.yaml +18 -0
  147. periplus/packs/drupal_basic@0.3.0/menu_link/menu_link_definition.yaml +48 -0
  148. periplus/packs/drupal_basic@0.3.0/module/module.yaml +7 -0
  149. periplus/packs/drupal_basic@0.3.0/module/module_info.yaml +58 -0
  150. periplus/packs/drupal_basic@0.3.0/pack.yaml +528 -0
  151. periplus/packs/drupal_basic@0.3.0/permission/permission.yaml +7 -0
  152. periplus/packs/drupal_basic@0.3.0/permission/permission_definition.yaml +27 -0
  153. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker.yaml +9 -0
  154. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_annotation.yaml +43 -0
  155. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_attribute.yaml +43 -0
  156. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource.yaml +8 -0
  157. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_annotation.yaml +43 -0
  158. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_attribute.yaml +43 -0
  159. periplus/packs/drupal_basic@0.3.0/role/role.yaml +14 -0
  160. periplus/packs/drupal_basic@0.3.0/role/role_config.yaml +44 -0
  161. periplus/packs/drupal_basic@0.3.0/route/route.yaml +42 -0
  162. periplus/packs/drupal_basic@0.3.0/route/route_definition.yaml +113 -0
  163. periplus/packs/drupal_basic@0.3.0/route/route_options.yaml +55 -0
  164. periplus/packs/drupal_basic@0.3.0/route/route_requirements.yaml +108 -0
  165. periplus/packs/drupal_basic@0.3.0/service/service.yaml +56 -0
  166. periplus/packs/drupal_basic@0.3.0/service/service_definition.yaml +181 -0
  167. periplus/packs/drupal_basic@0.3.0/template/template.yaml +86 -0
  168. periplus/packs/drupal_basic@0.3.0/template/template_route_link.yaml +30 -0
  169. periplus/packs/drupal_basic@0.3.0/theme/theme.yaml +15 -0
  170. periplus/packs/drupal_basic@0.3.0/theme/theme_info.yaml +61 -0
  171. periplus/packs/drupal_basic@0.3.0/theme_hook/template_suggestion.yaml +29 -0
  172. periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook.yaml +87 -0
  173. periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook_render.yaml +20 -0
  174. periplus/packs/drupal_basic@0.3.0/url/url.yaml +88 -0
  175. periplus/packs/drupal_basic@0.3.0/views_plugin/views_field_attribute.yaml +80 -0
  176. periplus/packs/drupal_basic@0.3.0/views_plugin/views_filter_attribute.yaml +80 -0
  177. periplus/packs/drupal_basic@0.3.0/views_plugin/views_plugin.yaml +15 -0
  178. periplus/packs/drupal_basic@0.3.0/views_plugin/views_style_attribute.yaml +80 -0
  179. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment.yaml +12 -0
  180. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php.yaml +15 -0
  181. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php_array.yaml +52 -0
  182. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_twig.yaml +26 -0
  183. periplus/packs/drupal_js_basic@0.0.1/attachment/php_function_holder.yaml +13 -0
  184. periplus/packs/drupal_js_basic@0.0.1/behavior/behavior.yaml +198 -0
  185. periplus/packs/drupal_js_basic@0.0.1/pack.yaml +153 -0
  186. periplus/packs/drupal_js_basic@0.0.1/setting/setting.yaml +13 -0
  187. periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_js.yaml +15 -0
  188. periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_php.yaml +92 -0
  189. periplus/packs/drush_basic@0.0.1/command/command.yaml +15 -0
  190. periplus/packs/drush_basic@0.0.1/command/command_annotation.yaml +60 -0
  191. periplus/packs/drush_basic@0.0.1/command/command_attribute.yaml +88 -0
  192. periplus/packs/drush_basic@0.0.1/pack.yaml +29 -0
  193. periplus/packs/eck_basic@0.0.1/bundle/eck_bundle_config.yaml +56 -0
  194. periplus/packs/eck_basic@0.0.1/entity_type/eck_entity_type_config.yaml +26 -0
  195. periplus/packs/eck_basic@0.0.1/pack.yaml +28 -0
  196. periplus/packs/go@0.0.2/interfaces/satisfies.yaml +47 -0
  197. periplus/packs/go@0.0.2/pack.yaml +51 -0
  198. periplus/packs/go@0.0.2/types/find_declarations.yaml +137 -0
  199. periplus/packs/go@0.0.2/types/node_types.yaml +36 -0
  200. periplus/packs/go_basic@0.0.3/pack.yaml +104 -0
  201. periplus/packs/go_basic@0.0.3/rules/calls.yaml +25 -0
  202. periplus/packs/go_basic@0.0.3/rules/declarations.yaml +40 -0
  203. periplus/packs/go_basic@0.0.3/rules/imports.yaml +16 -0
  204. periplus/packs/go_basic@0.0.3/types/node_types.yaml +15 -0
  205. periplus/packs/js_basic@0.0.1/function/function.yaml +68 -0
  206. periplus/packs/js_basic@0.0.1/pack.yaml +50 -0
  207. periplus/packs/laravel_basic@0.0.5/pack.yaml +313 -0
  208. periplus/packs/laravel_basic@0.0.5/rules/classes.yaml +42 -0
  209. periplus/packs/laravel_basic@0.0.5/rules/config.yaml +229 -0
  210. periplus/packs/laravel_basic@0.0.5/rules/routes.yaml +210 -0
  211. periplus/packs/laravel_basic@0.0.5/rules/types.yaml +50 -0
  212. periplus/packs/laravel_basic@0.0.5/rules/views.yaml +100 -0
  213. periplus/packs/paragraphs_basic@0.0.1/bundle/paragraph_bundle_config.yaml +54 -0
  214. periplus/packs/paragraphs_basic@0.0.1/pack.yaml +12 -0
  215. periplus/packs/php@0.1.0/edges/edge_kinds.yaml +64 -0
  216. periplus/packs/php@0.1.0/edges/find_calls.yaml +34 -0
  217. periplus/packs/php@0.1.0/edges/find_imports.yaml +18 -0
  218. periplus/packs/php@0.1.0/edges/find_member_access.yaml +22 -0
  219. periplus/packs/php@0.1.0/edges/find_structure.yaml +38 -0
  220. periplus/packs/php@0.1.0/embedded/embedded_regions.yaml +19 -0
  221. periplus/packs/php@0.1.0/imports/imports.yaml +20 -0
  222. periplus/packs/php@0.1.0/pack.yaml +117 -0
  223. periplus/packs/php@0.1.0/resolution/excluded_tokens.yaml +23 -0
  224. periplus/packs/php@0.1.0/resolution/resolution.yaml +35 -0
  225. periplus/packs/php@0.1.0/types/find_declarations.yaml +102 -0
  226. periplus/packs/php@0.1.0/types/node_types.yaml +55 -0
  227. periplus/packs/php_basic@0.2.0/edges/edge_kinds.yaml +48 -0
  228. periplus/packs/php_basic@0.2.0/edges/find_structure.yaml +750 -0
  229. periplus/packs/php_basic@0.2.0/imports/imports.yaml +19 -0
  230. periplus/packs/php_basic@0.2.0/pack.yaml +94 -0
  231. periplus/packs/php_basic@0.2.0/types/find_declarations.yaml +267 -0
  232. periplus/packs/php_basic@0.2.0/types/node_types.yaml +55 -0
  233. periplus/packs/profile_basic@0.0.1/bundle/profile_bundle_config.yaml +54 -0
  234. periplus/packs/profile_basic@0.0.1/pack.yaml +12 -0
  235. periplus/packs/salesforce_basic@0.0.1/event/salesforce_event.yaml +36 -0
  236. periplus/packs/salesforce_basic@0.0.1/pack.yaml +31 -0
  237. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping.yaml +19 -0
  238. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping_config.yaml +83 -0
  239. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field.yaml +8 -0
  240. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field_annotation.yaml +43 -0
  241. periplus/packs/twig@0.0.1/pack.yaml +26 -0
  242. periplus/packs/twig@0.0.1/types/template.yaml +57 -0
  243. periplus/packs/twig_basic@0.1.0/pack.yaml +11 -0
  244. periplus/packs/twig_tweak_basic@0.0.1/pack.yaml +27 -0
  245. periplus/packs/twig_tweak_basic@0.0.1/rules/block.yaml +20 -0
  246. periplus/packs/twig_tweak_basic@0.0.1/rules/entity.yaml +35 -0
  247. periplus/packs/twig_tweak_basic@0.0.1/rules/field.yaml +21 -0
  248. periplus/packs/twig_tweak_basic@0.0.1/rules/menu.yaml +21 -0
  249. periplus/packs/webform_basic@0.0.1/bundle/webform_submission_bundle_config.yaml +54 -0
  250. periplus/packs/webform_basic@0.0.1/pack.yaml +20 -0
  251. periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler.yaml +8 -0
  252. periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler_annotation.yaml +43 -0
  253. periplus/packs/yaml@0.0.1/pack.yaml +72 -0
  254. periplus/packs/yaml@0.0.1/types/find_mapping_entry.yaml +21 -0
  255. periplus/packs/yaml@0.0.1/types/yaml_types.yaml +44 -0
  256. periplus/packs/yaml_basic@0.1.0/pack.yaml +10 -0
  257. periplus/packs.py +447 -0
  258. periplus/preflight.py +102 -0
  259. periplus/py.typed +0 -0
  260. periplus/report.py +596 -0
  261. periplus/resolution.py +355 -0
  262. periplus/settings.py +617 -0
  263. periplus/settings.stub.yml +99 -0
  264. periplus/spec.py +774 -0
  265. periplus/update.py +197 -0
  266. periplus/validate.py +655 -0
  267. periplus_map-0.2.1.dist-info/METADATA +566 -0
  268. periplus_map-0.2.1.dist-info/RECORD +272 -0
  269. periplus_map-0.2.1.dist-info/WHEEL +4 -0
  270. periplus_map-0.2.1.dist-info/entry_points.txt +2 -0
  271. periplus_map-0.2.1.dist-info/licenses/LICENSE +202 -0
  272. periplus_map-0.2.1.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,64 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — the edge kinds this pack declares. Finding them is in edges/find_*.yaml.
4
+ #
5
+ # Endpoints take one type or a flat list of alternatives. Nesting a combination inside a
6
+ # list is not expressible — that is the grammar restriction that keeps validation cheap,
7
+ # and it can be widened later without breaking any pack written against it.
8
+
9
+ edge_kinds:
10
+
11
+ - kind: contains
12
+ from: [php.file, php.file_entry, php.class_like, php.callable]
13
+ to: [php.class_like, php.callable, php.property, php.class_constant, php.enum_case]
14
+ source: nearest_enclosing_container
15
+ # why: the containment source was hardcoded to the file node across 15 language
16
+ # configs, so a method's container was the file rather than its class.
17
+
18
+ - kind: inherits
19
+ from: php.class
20
+ to: php.class
21
+
22
+ - kind: implements
23
+ from: [php.class, php.enum]
24
+ to: php.interface
25
+
26
+ - kind: mixes_in
27
+ from: php.class_like
28
+ to: php.trait
29
+
30
+ - kind: instantiates
31
+ from: php.callable
32
+ to: php.class
33
+ # why: `object_creation_expression` was simply absent from the trigger set. On one
34
+ # 615-file corpus that was 505 `new X(` sites across 178 classes emitting nothing.
35
+ #
36
+ # Its own kind rather than folded into `calls`: instantiating a class and calling a
37
+ # method are different questions, and a reader asking "who constructs this" should not
38
+ # have to filter call edges.
39
+
40
+ - kind: calls
41
+ from: php.callable
42
+ to: php.callable
43
+
44
+ - kind: indirect_call
45
+ from: php.callable
46
+ to: php.callable
47
+ # why: `$obj->m(...)` creates a Closure and transfers control nowhere. Recording it as
48
+ # `calls` asserts something false; dropping it loses a real reference.
49
+
50
+ # Operational edges. Open in the design, drafted here so the shape can be argued with.
51
+ - kind: reads
52
+ from: php.callable
53
+ to: [php.property, php.class_constant, php.enum_case]
54
+
55
+ - kind: writes
56
+ from: php.callable
57
+ to: php.property
58
+ # Separate from `reads` rather than one relation with a direction field: the write is
59
+ # the half that answers "what changes this", and folding them together loses most of
60
+ # the value of having the edge at all.
61
+
62
+ - kind: imports
63
+ from: php.file
64
+ to: [php.class_like, php.function, php.class_constant]
@@ -0,0 +1,34 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — call edges. Three rules.
4
+ #
5
+ # A call site's shape constrains what it may bind to. A bare `name()` is a function call and
6
+ # can never resolve to a method.
7
+ # why: conflating them fabricated 848 edges from 368 files for `event()` alone, 290 for
8
+ # `config()`, 186 for `dispatch()`.
9
+
10
+ needs:
11
+ types: [php.callable, php.function, php.method]
12
+
13
+ rules:
14
+
15
+ - rule: plain_function_call
16
+ reads: file
17
+ in: [source]
18
+ match: {declaration: function_call_expression}
19
+ emits: [{edge: {kind: calls, from: enclosing_callable, to: {from: qualified_name}}}]
20
+ confidence: declared
21
+
22
+ - rule: static_call
23
+ reads: file
24
+ in: [source]
25
+ match: {declaration: scoped_call_expression}
26
+ emits: [{edge: {kind: calls, from: enclosing_callable, to: {from: qualified_name}}}]
27
+ confidence: declared
28
+
29
+ - rule: first_class_callable
30
+ reads: file
31
+ in: [source]
32
+ match: {declaration: first_class_callable}
33
+ emits: [{edge: {kind: indirect_call, from: enclosing_callable, to: {from: qualified_name}}}]
34
+ confidence: declared
@@ -0,0 +1,18 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — the imports edge. One rule.
4
+ #
5
+ # The facts a `use` statement carries are declared separately, in imports/imports.yaml. This
6
+ # rule only emits the edge.
7
+
8
+ needs:
9
+ types: [php.class_like, php.function, php.class_constant]
10
+
11
+ rules:
12
+
13
+ - rule: imports_edge
14
+ reads: file
15
+ in: [source]
16
+ match: {declaration: namespace_use_declaration}
17
+ emits: [{edge: {kind: imports, from: enclosing_file, to: {from: qualified_name}}}]
18
+ confidence: declared
@@ -0,0 +1,22 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — reads and writes of members. Two rules.
4
+
5
+ needs:
6
+ types: [php.property, php.class_constant, php.enum_case]
7
+
8
+ rules:
9
+
10
+ - rule: writes_property
11
+ reads: file
12
+ in: [source]
13
+ match: {declaration: assignment_expression_lhs}
14
+ emits: [{edge: {kind: writes, from: enclosing_callable, to: {from: qualified_name}}}]
15
+ confidence: declared
16
+
17
+ - rule: reads_member
18
+ reads: file
19
+ in: [source]
20
+ match: {declaration: member_access_expression}
21
+ emits: [{edge: {kind: reads, from: enclosing_callable, to: {from: qualified_name}}}]
22
+ confidence: declared
@@ -0,0 +1,38 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — the edges written at a declaration site. Four rules.
4
+
5
+ needs:
6
+ types: [php.class, php.class_like, php.interface, php.trait, php.enum]
7
+
8
+ rules:
9
+
10
+ - rule: inherits_from_base_clause
11
+ reads: file
12
+ in: [source]
13
+ match: {declaration: base_clause}
14
+ emits: [{edge: {kind: inherits, from: enclosing_class, to: {from: qualified_name}}}]
15
+ confidence: declared
16
+
17
+ - rule: implements_from_interface_clause
18
+ reads: file
19
+ in: [source]
20
+ match: {declaration: class_interface_clause}
21
+ emits: [{edge: {kind: implements, from: enclosing_class, to: {from: qualified_name}}}]
22
+ confidence: declared
23
+
24
+ - rule: mixes_in_from_use_declaration
25
+ reads: file
26
+ in: [source]
27
+ match: {declaration: use_declaration}
28
+ emits: [{edge: {kind: mixes_in, from: enclosing_class, to: {from: qualified_name}}}]
29
+ confidence: declared
30
+
31
+ - rule: instantiates_from_new
32
+ reads: file
33
+ in: [source]
34
+ match: {declaration: object_creation_expression}
35
+ emits: [{edge: {kind: instantiates, from: enclosing_callable, to: {from: qualified_name}}}]
36
+ confidence: declared
37
+ # why: absent from the trigger set entirely — 505 `new X(` sites across 178 classes
38
+ # emitting nothing, including 0 of 22 `$bus->dispatch(new SomeCommand())` sites.
@@ -0,0 +1,19 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — embedded sub-language regions.
4
+
5
+ # --------------------------------------------------------------------------------------
6
+ # Files that hold more than one language.
7
+ #
8
+ # why: inline `<script>` in `.php` was never indexed, so a helper and its caller both
9
+ # vanished along with the call between them.
10
+ # --------------------------------------------------------------------------------------
11
+ embedded_regions:
12
+ - open: "<script(?![^>]*\\bsrc=)[^>]*>"
13
+ close: "</script>"
14
+ language: javascript
15
+ line_offset: preserve
16
+ skip_when_empty: true
17
+ host_constructs_inside: ["<?= ?>", "<?php ?>"]
18
+ # Host tags inside the region are replaced with placeholders before the sub-language
19
+ # parses, or the sub-parse fails on syntax that is not its own.
@@ -0,0 +1,20 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — the import-statement facts this pack extracts.
4
+
5
+ # --------------------------------------------------------------------------------------
6
+ # Import statements are facts, not just a lookup table.
7
+ #
8
+ # why: the importer kept only the last path segment and discarded the rest, so
9
+ # `use function A\{render};` claimed `render` as a class and re-pointed a sibling's
10
+ # `extends Render`.
11
+ # --------------------------------------------------------------------------------------
12
+ imports:
13
+ - ast: namespace_use_declaration
14
+ group_ast: namespace_use_group
15
+ facts:
16
+ target_fqn: written_path
17
+ alias: as_clause
18
+ use_kind: declaration_keyword # `function` / `const` sits on the declaration in
19
+ # group form, not on each clause
20
+ binds_through_alias: true
@@ -0,0 +1,117 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-manifest.schema.json"
2
+
3
+ # PHP pack — first draft
4
+ #
5
+ # Every section below exists because something concrete went wrong when the same
6
+ # information was an engine constant instead of configuration. The `# why:` lines cite
7
+ # the failure, with the numbers the reporter measured. If a section has no `# why:`, it
8
+ # is a design choice and not yet evidence-backed.
9
+ #
10
+ # This is the DATA schema side only. Nothing here describes the emitted map.
11
+
12
+ pack: php
13
+ version: 0.1.0
14
+ depends: []
15
+ # A pack with no dependencies. Not a "language pack" — there is no such kind. It is the
16
+ # root of this dependency graph only because nothing sits beneath PHP.
17
+
18
+ # --------------------------------------------------------------------------------------
19
+ # The grammar this pack's rules are written against.
20
+ #
21
+ # The engine never parses source; an adapter does. So the pack has to say which grammar
22
+ # its AST node names belong to, or `class_declaration` is a magic string that means
23
+ # whatever the adapter happens to think.
24
+ # --------------------------------------------------------------------------------------
25
+ grammar:
26
+ provider: tree-sitter
27
+ provider_version: "0.26.13" # tree-sitter runtime, released 2026-08-23
28
+ language: php
29
+ grammar_version: "0.23.11" # tree-sitter-php
30
+ # Grammar versions are PINNED EXACTLY, never a range. Node type names are not guaranteed
31
+ # stable across a grammar's minor releases: tree-sitter issue #2611 records a JavaScript
32
+ # grammar rename, with the maintainer-adjacent line "just about any time a change is made
33
+ # to a grammar, the change is somehow breaking to consumers." A range would let a rule
34
+ # that matched yesterday silently match nothing today.
35
+ #
36
+ # tree-sitter PR #4135 (merged 2025-01-25, milestone 0.25) added a `semantic_version` field
37
+ # to TSLanguage and `ts_language_semantic_version()`, sourced from the grammar's
38
+ # tree-sitter.json manifest — so the engine can read which grammar it actually got and
39
+ # refuse a mismatch. It does not make grammar authors honour semver, which is why the pin
40
+ # is exact rather than caret.
41
+ #
42
+ # Two versions, because they move independently: the runtime that parses, and the grammar
43
+ # whose node names the rules below reference.
44
+
45
+ # --------------------------------------------------------------------------------------
46
+ # Which files are ours.
47
+ #
48
+ # A list, not a global map. A pack that depends on this one may add extensions, and the
49
+ # project settings file may override any of them. All three layers resolve before extraction.
50
+ #
51
+ # why: `.inc` was hard-mapped to a Pascal extractor. Identical bytes gave 7 nodes as
52
+ # `a.inc` and 471 as `b.php`; across 12 pfSense files, 20 nodes instead of 755. One
53
+ # 19,046-line file with 460 functions produced 7 nodes. Silently.
54
+ # --------------------------------------------------------------------------------------
55
+ # ======================================================================================
56
+ # NAMED FOLDERS
57
+ #
58
+ # A rule says `in: [source]`. It never writes a path. php the language has no opinion about
59
+ # where source lives, so the default is the repository root and the project settings file
60
+ # narrows it. A dependent pack overrides it with something meaningful — Drupal replaces it
61
+ # with custom_module and custom_theme.
62
+ # ======================================================================================
63
+ folders:
64
+ source: ./
65
+
66
+ files:
67
+ extensions: [php, phtml, php3, php4, php5, php7, phps]
68
+ # Deliberately NOT here: module, inc, install, theme, profile. Those are Drupal
69
+ # conventions, not PHP ones, and belong to the pack that knows they are PHP.
70
+
71
+ exclude: []
72
+ # A path the extractor never opens. Different from a boundary, and the difference
73
+ # matters:
74
+ # boundary — the file is not read, but a thing inside it can still be a node,
75
+ # because something first-party refers to it by name.
76
+ # exclude — the file does not exist as far as the map is concerned. Nothing from
77
+ # it appears, not even as the target of a reference.
78
+ #
79
+ # Enforced at file selection, before anything parses. Never "read it and drop the
80
+ # results": the map is a committed artifact, and a string literal or a variable name
81
+ # from an excluded file reaching a commit is not a mistake you can take back.
82
+ #
83
+ # Empty here on purpose. PHP the language excludes nothing. Every real exclusion is a
84
+ # convention of some framework or of one project, so it belongs to the pack or the
85
+ # overlay that knows the convention.
86
+
87
+ # The resolved language must reach the extraction cache key, or bytes cached under the
88
+ # previous language get served after an override changes it — in either direction.
89
+ cache_key_includes: [resolved_language]
90
+
91
+ # --------------------------------------------------------------------------------------
92
+ # Identity.
93
+ #
94
+ # The test for every rule here: does a declaration site and a reference site
95
+ # independently produce the same string?
96
+ #
97
+ # why: one global lowercased name-to-id map fused a PHP `Exception` with an unrelated
98
+ # TypeScript class — 12 phantom inheritance edges across 3 Composer packages, and it
99
+ # inflated the TS node into a top-10 hub. Separately, `App\Models\Page` and
100
+ # `Filament\Pages\Page` collapsed onto one node.
101
+ # --------------------------------------------------------------------------------------
102
+ identity:
103
+ qualified_name:
104
+ parts: [namespace, declared_name]
105
+ separator: "\\"
106
+ leading_separator: strip # `\Foo\Bar` and `Foo\Bar` name the same type
107
+ scope: pack # ids are namespaced to this pack; never a global name map
108
+
109
+ case_folding:
110
+ # PHP is case-insensitive for these and case-sensitive for the rest. Declared rather
111
+ # than assumed, because getting it backwards silently merges or splits nodes.
112
+ insensitive: [php.class, php.interface, php.trait, php.enum, php.function, php.method]
113
+ sensitive: [php.property, php.class_constant]
114
+
115
+ # why: id normalization that casefolded AND stripped underscores collided `_count` with
116
+ # `Count`. Normalization beyond what the language itself does is a defect.
117
+ never_normalize: [underscores, punctuation]
@@ -0,0 +1,23 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — tokens excluded from resolution.
4
+
5
+ # --------------------------------------------------------------------------------------
6
+ # Tokens that are never type names.
7
+ # --------------------------------------------------------------------------------------
8
+ excluded_tokens:
9
+
10
+ - group: relative_scope
11
+ tokens: [self, static, parent]
12
+ case_sensitive: false
13
+ positions: [type_reference, callee, supertype]
14
+ # why: treated as types, these minted one global node each, wired to a large fraction
15
+ # of all classes. `parent::setUp()` alone fabricated 1,698 inbound calls onto a
16
+ # single method. `STATIC` needs the same treatment, hence case-insensitive.
17
+
18
+ - group: builtin_bases
19
+ tokens: [Exception, Throwable, Error, ArrayObject, ArrayAccess, Countable,
20
+ Iterator, IteratorAggregate, Traversable, JsonSerializable, Stringable]
21
+ positions: [type_reference, callee, supertype]
22
+ # why: the supertype resolver never consulted the builtin list at all — it was applied
23
+ # at call sites only. Positions are declared here so that cannot recur.
@@ -0,0 +1,35 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — the name-resolution rules.
4
+
5
+ # --------------------------------------------------------------------------------------
6
+ # Resolution.
7
+ #
8
+ # These are the rules for turning a written name into a node, and most of the damage in
9
+ # the record came from here rather than from extraction.
10
+ # --------------------------------------------------------------------------------------
11
+ resolution:
12
+ scope: same_pack
13
+ # why: bare `extends Exception` in PHP bound to a TypeScript class because one global
14
+ # name map served every language.
15
+
16
+ match: qualified_name_exact
17
+ never_match_by: [prefix, substring, case_folded_and_stripped]
18
+ # why: a class whose name is a strict prefix of its siblings lost its entire fan-in —
19
+ # `Pivot` went from degree 4 to degree 1 once `PivotRepository` existed, and the
20
+ # "what depends on this" query then answered "nothing".
21
+
22
+ on_multiple_definitions: refuse
23
+ on_zero_definitions: unresolved
24
+ # `unresolved` emits a node recording which rule fired and what it looked for. It never
25
+ # drops the edge.
26
+ # why: every failure in this record was silent, and the graph still looked populated.
27
+
28
+ # Ambiguity is decided on evidence, not on a vocabulary list. These are two jobs and
29
+ # conflating them was load-bearing by accident: a shared builtin list suppressed 27–29
30
+ # of 29 names in most languages, and removing it recovered 45 edges of which 43 were
31
+ # phantom. The refusal rule above does that work; the list below does not.
32
+ detect_references_independently_of_imports: true
33
+ # why: 158 of 240 Eloquent relationships (65%) were unlinked because the edge tracked
34
+ # the `use` statement rather than the reference. 140 were same-namespace, so no
35
+ # import existed to track.
@@ -0,0 +1,102 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — finds every declaration the language has. Nine rules, one per construct.
4
+ #
5
+ # One rule per construct rather than one rule with a list, because each declares where its
6
+ # name lives and which child holds its body, and those differ. That difference is not
7
+ # cosmetic: `enum_declaration_list` differs from `declaration_list` by one word, and that
8
+ # single difference is what made all 119 enums invisible.
9
+
10
+ needs:
11
+ types: [php.class, php.interface, php.trait, php.enum, php.function, php.method,
12
+ php.property, php.class_constant, php.enum_case]
13
+
14
+ rules:
15
+
16
+ - rule: find_class
17
+ reads: file
18
+ in: [source]
19
+ match: {declaration: class_declaration, name_child: name, body_child: declaration_list}
20
+ id: {from: qualified_name}
21
+ emits: [{node: {type: php.class}}]
22
+ confidence: declared
23
+
24
+ - rule: find_interface
25
+ reads: file
26
+ in: [source]
27
+ match: {declaration: interface_declaration, name_child: name, body_child: declaration_list}
28
+ id: {from: qualified_name}
29
+ emits: [{node: {type: php.interface}}]
30
+ confidence: declared
31
+
32
+ - rule: find_trait
33
+ reads: file
34
+ in: [source]
35
+ match: {declaration: trait_declaration, name_child: name, body_child: declaration_list}
36
+ id: {from: qualified_name}
37
+ emits: [{node: {type: php.trait}}]
38
+ confidence: declared
39
+
40
+ - rule: find_enum
41
+ reads: file
42
+ in: [source]
43
+ match: {declaration: enum_declaration, name_child: name, body_child: enum_declaration_list}
44
+ id: {from: qualified_name}
45
+ emits: [{node: {type: php.enum}}]
46
+ confidence: declared
47
+ # why: this one child name differs from the other three, and that single difference is
48
+ # what made all 119 enums invisible. Declaring it per rule is the fix.
49
+
50
+ - rule: find_function
51
+ reads: file
52
+ in: [source]
53
+ match: {declaration: function_definition, name_child: name}
54
+ id: {from: qualified_name}
55
+ emits: [{node: {type: php.function}}]
56
+ confidence: declared
57
+
58
+ - rule: find_method
59
+ reads: file
60
+ in: [source]
61
+ match: {declaration: method_declaration, name_child: name}
62
+ id:
63
+ from: [namespace, enclosing_type, declared_name]
64
+ template: "{namespace}\\{enclosing_type}::{declared_name}"
65
+ emits: [{node: {type: php.method}}]
66
+ confidence: declared
67
+
68
+ - rule: find_property
69
+ reads: file
70
+ in: [source]
71
+ match: {declaration: property_declaration, name_child: name}
72
+ id:
73
+ from: [namespace, enclosing_type, declared_name]
74
+ template: "{namespace}\\{enclosing_type}::{declared_name}"
75
+ emits: [{node: {type: php.property}}]
76
+ confidence: declared
77
+
78
+ # why: the pack's own identity block is `parts: [namespace, declared_name]`, which is right
79
+ # for a class and wrong for everything inside one. Run against block_ways it merged
80
+ # four different build() methods on four different classes into one node —
81
+ # AnnotationBlock:31, AttributeBlock:30, ContextAwareBlock:40, DerivedBlock:33 — with
82
+ # no error. A member's id needs the type that holds it, so these four rules carry
83
+ # their own template, exactly as go's find_method carries its receiver.
84
+ - rule: find_class_constant
85
+ reads: file
86
+ in: [source]
87
+ match: {declaration: const_declaration, name_child: name}
88
+ id:
89
+ from: [namespace, enclosing_type, declared_name]
90
+ template: "{namespace}\\{enclosing_type}::{declared_name}"
91
+ emits: [{node: {type: php.class_constant}}]
92
+ confidence: declared
93
+
94
+ - rule: find_enum_case
95
+ reads: file
96
+ in: [source]
97
+ match: {declaration: enum_case, name_child: name}
98
+ id:
99
+ from: [namespace, enclosing_type, declared_name]
100
+ template: "{namespace}\\{enclosing_type}::{declared_name}"
101
+ emits: [{node: {type: php.enum_case}}]
102
+ confidence: declared
@@ -0,0 +1,55 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # php pack — the node types this pack declares. Finding them is in types/find_*.yaml.
4
+ #
5
+ # why: `class_types` held `class_declaration` only. 291 declarations minted no node —
6
+ # 142 interfaces, 30 traits, 119 enums — and their methods re-attributed to the file
7
+ # as free functions. ~19,000 imports edges dangled. 18 stubs shared one label.
8
+
9
+ node_types:
10
+
11
+ - name: php.file
12
+ container: true
13
+
14
+ - name: php.file_entry
15
+ container: true
16
+ parent: php.file
17
+ synthetic: true
18
+ # why: top-level code has no enclosing callable, so a call from module scope had no
19
+ # caller and the function looked dead — 18 file-caller edges out of ~195 known
20
+ # sites. A declared synthetic entry container gives that code somewhere to live.
21
+
22
+ - name: php.class_like
23
+ abstract: true
24
+ container: true
25
+
26
+ - name: php.class
27
+ parent: php.class_like
28
+
29
+ - name: php.interface
30
+ parent: php.class_like
31
+
32
+ - name: php.trait
33
+ parent: php.class_like
34
+
35
+ - name: php.enum
36
+ parent: php.class_like
37
+
38
+ - name: php.callable
39
+ abstract: true
40
+ container: true
41
+
42
+ - name: php.function
43
+ parent: php.callable
44
+
45
+ - name: php.method
46
+ parent: php.callable
47
+
48
+ # Members get their own types so an edge can terminate on one.
49
+ # why: no language emitted an edge pointing at a member. `Foo::$prop` pointed at the
50
+ # class, so "what writes this field" had no answer anywhere in the graph.
51
+ - name: php.property
52
+
53
+ - name: php.class_constant
54
+
55
+ - name: php.enum_case
@@ -0,0 +1,48 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # The edge kinds this pack declares. Finding them is in edges/find_structure.yaml.
4
+ #
5
+ # inherits ends at the abstract php.class_like, so a type named only by an extends and also by an
6
+ # implements elsewhere takes the more specific php.interface.
7
+ edge_kinds:
8
+
9
+ - kind: inherits
10
+ from: php.class_like
11
+ to: php.class_like
12
+
13
+ - kind: implements
14
+ from: [php.class, php.enum]
15
+ to: php.interface
16
+
17
+ - kind: mixes_in
18
+ from: php.class_like
19
+ to: php.trait
20
+
21
+ - kind: contains
22
+ from: php.class_like
23
+ to: php.method
24
+
25
+ - kind: calls
26
+ from: [php.function, php.method]
27
+ to: [php.function, php.method]
28
+
29
+ # The joins of a call through a property; edges/find_structure.yaml finds them.
30
+ - kind: declares_property
31
+ from: php.class_like
32
+ to: php.property
33
+
34
+ - kind: parameter_typed_as
35
+ from: php.parameter
36
+ to: php.parameter_type
37
+
38
+ - kind: assigned_value
39
+ from: php.member_assignment
40
+ to: php.member_assignment_value
41
+
42
+ - kind: has_call_site
43
+ from: php.method
44
+ to: php.call_site
45
+
46
+ - kind: call_site_in
47
+ from: php.call_site
48
+ to: php.method