use ty_plugin_protocol::{
CallReturnPatch, CallSignaturePatch, CallableSignature, ClassPatch, FieldPatch,
MemberAccessPatch, MemberPatch, Parameter, ParameterKind, PluginDiagnostic, PluginResponse,
TypeExpr,
};
#[must_use]
pub fn positional_or_keyword(name: impl Into<String>, ty: TypeExpr) -> Parameter {
parameter(
Some(name.into()),
ParameterKind::PositionalOrKeyword,
Some(ty),
true,
)
}
#[must_use]
pub fn keyword_only(name: impl Into<String>, ty: TypeExpr) -> Parameter {
parameter(
Some(name.into()),
ParameterKind::KeywordOnly,
Some(ty),
true,
)
}
#[must_use]
pub fn optional(mut parameter: Parameter) -> Parameter {
parameter.required = false;
parameter
}
fn parameter(
name: Option<String>,
kind: ParameterKind,
type_expr: Option<TypeExpr>,
required: bool,
) -> Parameter {
Parameter {
name,
kind,
type_expr,
required,
}
}
#[must_use]
pub fn signature(
parameters: impl IntoIterator<Item = Parameter>,
return_type: TypeExpr,
) -> CallableSignature {
CallableSignature {
parameters: parameters.into_iter().collect(),
return_type,
}
}
#[must_use]
pub fn init_field(name: impl Into<String>, ty: TypeExpr) -> FieldPatch {
let name = name.into();
FieldPatch {
name: name.clone(),
descriptor: None,
instance_get_type: ty.clone(),
instance_set_type: Some(ty.clone()),
constructor_parameter: Some(keyword_only(name, ty)),
has_default: false,
}
}
#[must_use]
pub fn field_with_parameter(
name: impl Into<String>,
get_type: TypeExpr,
set_type: Option<TypeExpr>,
constructor_parameter: Option<Parameter>,
) -> FieldPatch {
FieldPatch {
name: name.into(),
descriptor: None,
instance_get_type: get_type,
instance_set_type: set_type,
constructor_parameter,
has_default: false,
}
}
#[must_use]
pub fn member(name: impl Into<String>, ty: TypeExpr) -> MemberPatch {
MemberPatch {
name: name.into(),
access: MemberAccessPatch::value(ty),
read_only: false,
diagnostics: Vec::new(),
}
}
#[must_use]
pub fn descriptor_member(
name: impl Into<String>,
class_type: Option<TypeExpr>,
get_type: TypeExpr,
set_type: Option<TypeExpr>,
) -> MemberPatch {
MemberPatch {
name: name.into(),
access: MemberAccessPatch::Descriptor {
class_type,
instance_get_type: get_type,
instance_set_type: set_type,
},
read_only: false,
diagnostics: Vec::new(),
}
}
#[must_use]
pub fn call_return(return_type: TypeExpr) -> PluginResponse {
PluginResponse::CallReturnPatch(CallReturnPatch {
return_type,
diagnostics: Vec::new(),
result_metadata: None,
})
}
#[must_use]
pub fn call_signature(signature: CallableSignature) -> PluginResponse {
PluginResponse::CallSignaturePatch(CallSignaturePatch {
signature,
diagnostics: Vec::new(),
})
}
#[derive(Debug, Clone)]
pub struct ClassPatchBuilder {
patch: ClassPatch,
}
impl Default for ClassPatchBuilder {
fn default() -> Self {
Self::new()
}
}
impl ClassPatchBuilder {
#[must_use]
pub fn new() -> Self {
Self {
patch: ClassPatch {
fields: Vec::new(),
class_members: Vec::new(),
instance_members: Vec::new(),
constructor: None,
diagnostics: Vec::new(),
},
}
}
#[must_use]
pub fn field(mut self, field: FieldPatch) -> Self {
self.patch.fields.push(field);
self
}
#[must_use]
pub fn class_member(mut self, member: MemberPatch) -> Self {
self.patch.class_members.push(member);
self
}
#[must_use]
pub fn instance_member(mut self, member: MemberPatch) -> Self {
self.patch.instance_members.push(member);
self
}
#[must_use]
pub fn constructor(mut self, signature: CallableSignature) -> Self {
self.patch.constructor = Some(signature);
self
}
#[must_use]
pub fn diagnostic(mut self, diagnostic: PluginDiagnostic) -> Self {
self.patch.diagnostics.push(diagnostic);
self
}
#[must_use]
pub fn build(self) -> ClassPatch {
self.patch
}
#[must_use]
pub fn response(self) -> PluginResponse {
PluginResponse::ClassPatch(self.patch)
}
}