use ocaml folded decls
commit87e30bf2aeba2f3791bd6ab625acb627d98c65e9
authorLucian Wischik <ljw@meta.com>
Tue, 6 Dec 2022 05:47:45 +0000 (5 21:47 -0800)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Tue, 6 Dec 2022 05:47:45 +0000 (5 21:47 -0800)
tree023472b114055f658770486f4107580d0d3e28cc
parent23c2c896de647199abf4f77a6ccf6cf9dcbf7b8c
use ocaml folded decls

Summary:
This switches the "Decl_service_client" backend to work with ocaml-generated folded decls. (After this change, there are no longer any consumers of shallow decls).

The landscape of decls within the typechecker is a bit confusing. Let me explain a little. There are a few overlapping abstractions...
* **Shallow_classes_provider** is the API for shallow class decls - getting, caching locally, generating, storing.
* **Decl_provider** is the API for all other shallow decls (funs, typedefs, modules, consts), getting, caching locally, generating, storing. It is also the API entrypoint for folded decls - getting caching locally. It defers to a different module "decl_folded_class.ml" for generating and storing.
* **Decl_store** is an API mostly used under the hood for doing the getting+storing of items in shmem with a process-local cache. It is used by decl_folded_class.ml as it folds. It does slightly different things for zoncolan (where they use distribution instead of a single shmem) and for rust_provider (where generation+getting are rolled together).

I have a few goals with this diff:
1. hh_decl should do all generating of shallow decls, via a "get" API that also parses/generates if necessary. This makes it a nice black box.
2. ocaml's decl_folded_class.ml should do generating of folded decls, but should store/get them from hh_decl, via "store/get" APIs that solely store/get and have no generation
3. For the things we fetch out of hh_decl, we should have a unitary process-local cache for them. Unitary means one single cache in which all things exist and fight for space amongst each other, rather than a load of separate caches one for each kind of thing. I don't have evidence that this will be better, but I kind of suspect it will.

This diff rewrites **decl_service_client.ml**. This module has two roles: (1) the repository of process-local-caches, (2) the bridge between ocaml and rust.
1. I made **Shallow_classes_provider** and **Decl_provider** just call directly into decl_service_client when they need a decl. They delegate all generation+caching+sharing to this module.
2. I made it provide a **Decl_store** implementation. This is narrowly focused: it only supports get_folded_class and store_folded_class, and these two APIs are purely for storage; they don't do any generation. That way, when we ask Decl_provider for folded decls, it can defer to **decl_folded_class.ml** in the normal way, which can do the generation in the normal way -- calling into Shallow_classes_provider as necessary, doing the folding algorithm in ocaml, using Decl_store to get+cache+store folded decls in shmem.

## How to read this diff

1. Start at hh_worker_common then provider_backend.ml. This shows how we construct stuff.
2. Read through decl_service_client, which is the meat of this diff
3. Nicely, Decl_provider didn't need to be changed. Everything here just fits in.

## Still to do

I removed the "filename" cache. In future diffs, I will change it so the hot path gets all the information it needs solely from decl APIs. The filename-related APIs will solely be used on the slow path, to formulate error messages.

Reviewed By: zhyty

Differential Revision: D41250119

fbshipit-source-id: 91c2595d7cb5289fde9c26ac1d8e8452460cc7a2
hphp/hack/src/providers/dune
hphp/hack/src/providers/provider_backend.ml
hphp/hack/src/providers/provider_backend.mli
hphp/hack/src/stubs/decl_service_client.ml