pub use serde_json;
pub use ty_plugin_protocol as protocol;
pub mod dsl;
mod manifest;
#[cfg(target_arch = "wasm32")]
pub mod wasm;
pub use manifest::ManifestBuilder;
use ty_plugin_protocol::{
AnalyzeClassRequest, BuildProjectIndexRequest, CallRequest, DependencyRequest, MutationRequest,
PluginManifest, PluginRequest, PluginResponse, ResolveMemberRequest,
};
pub trait Plugin {
fn manifest(&self) -> PluginManifest;
fn analyze_class(&self, request: &AnalyzeClassRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn build_project_index(&self, request: &BuildProjectIndexRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn resolve_class_member(&self, request: &ResolveMemberRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn resolve_instance_member(&self, request: &ResolveMemberRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn adjust_call_signature(&self, request: &CallRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn adjust_call_return(&self, request: &CallRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn additional_dependencies(&self, request: &DependencyRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn validate_mutation(&self, request: &MutationRequest) -> PluginResponse {
let _ = request;
PluginResponse::NoChange
}
fn handle(&self, request: &PluginRequest) -> PluginResponse {
match request {
PluginRequest::Manifest => PluginResponse::Manifest(self.manifest()),
PluginRequest::BuildProjectIndex(request) => self.build_project_index(request),
PluginRequest::AnalyzeClass(request) => self.analyze_class(request),
PluginRequest::ResolveClassMember(request) => self.resolve_class_member(request),
PluginRequest::ResolveInstanceMember(request) => self.resolve_instance_member(request),
PluginRequest::AdjustCallSignature(request) => self.adjust_call_signature(request),
PluginRequest::AdjustCallReturn(request) => self.adjust_call_return(request),
PluginRequest::AdditionalDependencies(request) => self.additional_dependencies(request),
PluginRequest::ValidateMutation(request) => self.validate_mutation(request),
}
}
fn handle_json(&self, request_json: &str) -> Result<String, DispatchError> {
let request = serde_json::from_str::<PluginRequest>(request_json)
.map_err(DispatchError::DecodeRequest)?;
let response = self.handle(&request);
serde_json::to_string(&response).map_err(DispatchError::EncodeResponse)
}
}
#[derive(Debug, thiserror::Error)]
pub enum DispatchError {
#[error("failed to decode plugin request: {0}")]
DecodeRequest(#[source] serde_json::Error),
#[error("failed to encode plugin response: {0}")]
EncodeResponse(#[source] serde_json::Error),
}
#[macro_export]
macro_rules! export_plugin {
($plugin:expr) => {
#[cfg(target_arch = "wasm32")]
#[unsafe(no_mangle)]
pub extern "C" fn ty_plugin_alloc(len: u32) -> u32 {
$crate::wasm::alloc(len)
}
#[cfg(target_arch = "wasm32")]
#[unsafe(no_mangle)]
pub extern "C" fn ty_plugin_handle(ptr: u32, len: u32) -> u64 {
$crate::wasm::handle(&$plugin, ptr, len)
}
};
}