1use super::{code::KtCode, slot::KtPropertyValue, types::KtType};
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
10pub enum KtVis {
11 #[default]
12 Default,
13 Public,
14 Internal,
15 Private,
16}
17
18impl KtVis {
19 pub(crate) fn prefix(self) -> &'static str {
20 match self {
21 KtVis::Default => "",
22 KtVis::Public => "public ",
23 KtVis::Internal => "internal ",
24 KtVis::Private => "private ",
25 }
26 }
27}
28
29#[derive(Clone, Debug)]
32pub struct KtFile {
33 pub package: String,
34 pub decls: Vec<KtDecl>,
35 pub extra_imports: Vec<String>,
39 pub banner: Option<String>,
42}
43
44impl KtFile {
45 pub fn new(package: impl Into<String>) -> Self {
46 Self {
47 package: package.into(),
48 decls: Vec::new(),
49 extra_imports: Vec::new(),
50 banner: None,
51 }
52 }
53
54 pub fn banner(mut self, text: impl Into<String>) -> Self {
57 self.banner = Some(text.into());
58 self
59 }
60
61 pub fn decl(mut self, d: impl Into<KtDecl>) -> Self {
62 self.decls.push(d.into());
63 self
64 }
65
66 pub fn import(mut self, fqn: impl Into<String>) -> Self {
68 self.extra_imports.push(fqn.into());
69 self
70 }
71
72 pub fn imports(mut self, fqns: impl IntoIterator<Item = String>) -> Self {
73 self.extra_imports.extend(fqns);
74 self
75 }
76}
77
78#[derive(Clone, Debug)]
80pub enum KtDecl {
81 Class(KtClass),
82 Fun(KtFun),
83 FunInterface(KtFunInterface),
84 Property(KtProperty),
85 TypeAlias {
86 vis: KtVis,
87 name: String,
88 target: KtType,
89 },
90 Raw {
93 name: String,
94 code: KtCode,
95 },
96}
97
98impl KtDecl {
99 pub fn name(&self) -> &str {
101 match self {
102 KtDecl::Class(c) => &c.name,
103 KtDecl::Fun(f) => &f.name,
104 KtDecl::FunInterface(i) => &i.name,
105 KtDecl::Property(p) => &p.name,
106 KtDecl::TypeAlias { name, .. } => name,
107 KtDecl::Raw { name, .. } => name,
108 }
109 }
110}
111
112impl From<KtClass> for KtDecl {
113 fn from(c: KtClass) -> Self {
114 KtDecl::Class(c)
115 }
116}
117impl From<KtFunInterface> for KtDecl {
118 fn from(i: KtFunInterface) -> Self {
119 KtDecl::FunInterface(i)
120 }
121}
122impl From<KtFun> for KtDecl {
123 fn from(f: KtFun) -> Self {
124 KtDecl::Fun(f)
125 }
126}
127impl From<KtProperty> for KtDecl {
128 fn from(p: KtProperty) -> Self {
129 KtDecl::Property(p)
130 }
131}
132
133#[derive(Clone, Debug)]
144pub struct KtFunSig {
145 pub name: String,
146 pub vis: KtVis,
147 pub annotations: Vec<String>,
148 pub kdoc: Option<String>,
149 pub generics: Vec<String>,
151 pub receiver: Option<KtType>,
155 pub params: Vec<KtParam>,
156 pub ret: Option<KtType>,
157}
158
159impl KtFunSig {
160 pub fn new(name: impl Into<String>) -> Self {
161 Self {
162 name: name.into(),
163 vis: KtVis::Default,
164 annotations: Vec::new(),
165 kdoc: None,
166 generics: Vec::new(),
167 receiver: None,
168 params: Vec::new(),
169 ret: None,
170 }
171 }
172 pub fn vis(mut self, v: KtVis) -> Self {
173 self.vis = v;
174 self
175 }
176 pub fn receiver(mut self, ty: KtType) -> Self {
178 self.receiver = Some(ty);
179 self
180 }
181 pub fn annotation(mut self, a: impl Into<String>) -> Self {
182 self.annotations.push(a.into());
183 self
184 }
185 pub fn kdoc(mut self, d: impl Into<String>) -> Self {
186 self.kdoc = Some(d.into());
187 self
188 }
189 pub fn generic(mut self, g: impl Into<String>) -> Self {
190 self.generics.push(g.into());
191 self
192 }
193 pub fn param(mut self, p: KtParam) -> Self {
194 self.params.push(p);
195 self
196 }
197 pub fn returns(mut self, ty: KtType) -> Self {
198 self.ret = Some(ty);
199 self
200 }
201}
202
203impl From<KtFunSig> for KtFun {
204 fn from(s: KtFunSig) -> Self {
206 KtFun {
207 name: s.name,
208 vis: s.vis,
209 modifiers: Vec::new(),
210 annotations: s.annotations,
211 kdoc: s.kdoc,
212 generics: s.generics,
213 receiver: s.receiver,
214 params: s.params,
215 ret: s.ret,
216 body: KtBody::None,
217 }
218 }
219}
220
221impl From<KtFunSig> for KtDecl {
222 fn from(s: KtFunSig) -> Self {
223 KtDecl::Fun(s.into())
224 }
225}
226
227#[derive(Clone, Debug)]
235pub struct KtFunInterface {
236 pub vis: KtVis,
237 pub name: String,
238 pub type_params: Vec<String>,
240 pub kdoc: Option<String>,
241 pub method: KtFunSig,
243}
244
245impl KtFunInterface {
246 pub fn new(name: impl Into<String>, method: KtFunSig) -> Self {
247 Self {
248 vis: KtVis::Default,
249 name: name.into(),
250 type_params: Vec::new(),
251 kdoc: None,
252 method,
253 }
254 }
255 pub fn vis(mut self, v: KtVis) -> Self {
256 self.vis = v;
257 self
258 }
259 pub fn type_param(mut self, p: impl Into<String>) -> Self {
260 self.type_params.push(p.into());
261 self
262 }
263 pub fn kdoc(mut self, d: impl Into<String>) -> Self {
264 self.kdoc = Some(d.into());
265 self
266 }
267}
268
269#[derive(Clone, Copy, Debug, PartialEq, Eq)]
271pub enum KtClassModifier {
272 Abstract,
273 Open,
274 Sealed,
275}
276
277#[derive(Clone, Debug)]
285pub enum KtClassKind {
286 Class {
288 modifier: Option<KtClassModifier>,
289 ctor: Vec<KtCtorParam>,
290 },
291 Data {
294 ctor: Vec<KtCtorParam>,
295 },
296 Value {
299 field: Box<KtCtorParam>,
300 },
301 Enum {
304 ctor: Vec<KtCtorParam>,
305 entries: Vec<KtEnumEntry>,
306 },
307 Object,
308 Interface,
311 SealedInterface,
315 DataObject,
318}
319
320impl KtClassKind {
321 pub fn ctor_params(&self) -> &[KtCtorParam] {
324 match self {
325 KtClassKind::Class { ctor, .. }
326 | KtClassKind::Data { ctor }
327 | KtClassKind::Enum { ctor, .. } => ctor,
328 KtClassKind::Value { field } => std::slice::from_ref(field),
329 KtClassKind::Object
330 | KtClassKind::Interface
331 | KtClassKind::SealedInterface
332 | KtClassKind::DataObject => &[],
333 }
334 }
335
336 pub fn entries(&self) -> &[KtEnumEntry] {
338 match self {
339 KtClassKind::Enum { entries, .. } => entries,
340 _ => &[],
341 }
342 }
343
344 pub(crate) fn keyword(&self) -> &'static str {
346 match self {
347 KtClassKind::Class { modifier: None, .. } => "class",
348 KtClassKind::Class {
349 modifier: Some(KtClassModifier::Abstract),
350 ..
351 } => "abstract class",
352 KtClassKind::Class {
353 modifier: Some(KtClassModifier::Open),
354 ..
355 } => "open class",
356 KtClassKind::Class {
357 modifier: Some(KtClassModifier::Sealed),
358 ..
359 } => "sealed class",
360 KtClassKind::Data { .. } => "data class",
361 KtClassKind::Enum { .. } => "enum class",
362 KtClassKind::Value { .. } => "value class",
363 KtClassKind::Object => "object",
364 KtClassKind::Interface => "interface",
365 KtClassKind::SealedInterface => "sealed interface",
366 KtClassKind::DataObject => "data object",
367 }
368 }
369}
370
371#[derive(Clone, Debug)]
372pub struct KtEnumEntry {
373 pub name: String,
374 pub args: Option<KtCode>,
376}
377
378impl KtEnumEntry {
379 pub fn new(name: impl Into<String>) -> Self {
381 Self {
382 name: name.into(),
383 args: None,
384 }
385 }
386 pub fn with_args(name: impl Into<String>, args: impl Into<String>) -> Self {
388 Self {
389 name: name.into(),
390 args: Some(KtCode::new().line(args.into())),
391 }
392 }
393}
394
395#[derive(Clone, Debug)]
397pub struct KtCtorParam {
398 pub name: String,
399 pub ty: KtType,
400 pub prop: Option<bool>,
402 pub overrides: bool,
405 pub vis: KtVis,
406 pub default: Option<KtCode>,
407 pub annotations: Vec<String>,
408}
409
410impl KtCtorParam {
411 pub fn new(name: impl Into<String>, ty: KtType) -> Self {
412 Self {
413 name: name.into(),
414 ty,
415 prop: None,
416 overrides: false,
417 vis: KtVis::Default,
418 default: None,
419 annotations: Vec::new(),
420 }
421 }
422 pub fn val(mut self) -> Self {
423 self.prop = Some(false);
424 self
425 }
426 pub fn overrides(mut self) -> Self {
428 self.overrides = true;
429 self
430 }
431 pub fn var(mut self) -> Self {
432 self.prop = Some(true);
433 self
434 }
435 pub fn vis(mut self, v: KtVis) -> Self {
436 self.vis = v;
437 self
438 }
439 pub fn default(mut self, d: impl Into<String>) -> Self {
440 self.default = Some(KtCode::new().line(d.into()));
441 self
442 }
443 pub fn annotation(mut self, a: impl Into<String>) -> Self {
444 self.annotations.push(a.into());
445 self
446 }
447}
448
449#[derive(Clone, Debug)]
451pub struct KtSuperclass {
452 pub ty: KtType,
453 pub args: Option<KtCode>,
457}
458
459#[derive(Clone, Debug, Default)]
466pub struct KtSupertypes {
467 pub superclass: Option<KtSuperclass>,
468 pub interfaces: Vec<KtType>,
470}
471
472impl KtSupertypes {
473 pub fn iter(&self) -> impl Iterator<Item = (&KtType, Option<&KtCode>)> {
475 self.superclass
476 .iter()
477 .map(|s| (&s.ty, s.args.as_ref()))
478 .chain(self.interfaces.iter().map(|t| (t, None)))
479 }
480
481 pub fn is_empty(&self) -> bool {
482 self.superclass.is_none() && self.interfaces.is_empty()
483 }
484
485 fn set_superclass(&mut self, ty: KtType, args: Option<&str>, what: &str) {
491 if let Some(existing) = &self.superclass {
492 panic!(
493 "{what} already extends `{}`; Kotlin allows only one superclass \
494 (use `implements` for interfaces)",
495 existing.ty
496 );
497 }
498 self.superclass = Some(KtSuperclass {
499 ty,
500 args: args.map(|s| KtCode::new().line(s.to_string())),
501 });
502 }
503}
504
505#[derive(Clone, Debug, Default)]
523pub struct KtCompanion {
524 pub name: Option<String>,
529 pub vis: KtVis,
530 pub kdoc: Option<String>,
531 pub annotations: Vec<String>,
532 pub supertypes: KtSupertypes,
534 pub members: Vec<KtDecl>,
535}
536
537impl KtCompanion {
538 pub fn new() -> Self {
540 Self::default()
541 }
542 pub fn named(name: impl Into<String>) -> Self {
549 let name = name.into();
550 assert!(
551 !name.is_empty(),
552 "a companion object's name cannot be empty — use `KtCompanion::new()` \
553 for the anonymous form"
554 );
555 Self {
556 name: Some(name),
557 ..Self::default()
558 }
559 }
560 pub fn vis(mut self, v: KtVis) -> Self {
561 self.vis = v;
562 self
563 }
564 pub fn kdoc(mut self, d: impl Into<String>) -> Self {
565 self.kdoc = Some(d.into());
566 self
567 }
568 pub fn annotation(mut self, a: impl Into<String>) -> Self {
569 self.annotations.push(a.into());
570 self
571 }
572 pub fn extends(mut self, ty: KtType, args: Option<&str>) -> Self {
579 self.supertypes.set_superclass(ty, args, "companion object");
580 self
581 }
582
583 pub fn implements(mut self, ty: KtType) -> Self {
585 self.supertypes.interfaces.push(ty);
586 self
587 }
588 pub fn member(mut self, d: impl Into<KtDecl>) -> Self {
589 self.members.push(d.into());
590 self
591 }
592}
593
594fn describe_prop(prop: Option<bool>) -> &'static str {
595 match prop {
596 None => "a plain constructor parameter",
597 Some(false) => "a `val`",
598 Some(true) => "a `var`",
599 }
600}
601
602fn assert_data_property(p: &KtCtorParam) {
604 assert!(
605 p.prop.is_some(),
606 "every `data class` constructor parameter must be a property, but `{}` is {} — \
607 call `.val()` or `.var()` on it",
608 p.name,
609 describe_prop(p.prop),
610 );
611}
612
613#[derive(Clone, Debug)]
615pub struct KtClass {
616 pub kind: KtClassKind,
618 pub name: String,
619 pub vis: KtVis,
620 pub annotations: Vec<String>,
621 pub kdoc: Option<String>,
622 pub supertypes: KtSupertypes,
624 pub members: Vec<KtDecl>,
625 pub companion: Option<Box<KtCompanion>>,
629}
630
631impl KtClass {
632 pub fn new(kind: KtClassKind, name: impl Into<String>) -> Self {
633 Self {
634 kind,
635 name: name.into(),
636 vis: KtVis::Default,
637 annotations: Vec::new(),
638 kdoc: None,
639 supertypes: KtSupertypes::default(),
640 members: Vec::new(),
641 companion: None,
642 }
643 }
644
645 pub fn class_(name: impl Into<String>) -> Self {
648 Self::new(
649 KtClassKind::Class {
650 modifier: None,
651 ctor: Vec::new(),
652 },
653 name,
654 )
655 }
656 pub fn class_with(modifier: KtClassModifier, name: impl Into<String>) -> Self {
658 Self::new(
659 KtClassKind::Class {
660 modifier: Some(modifier),
661 ctor: Vec::new(),
662 },
663 name,
664 )
665 }
666 pub fn data(name: impl Into<String>, first: KtCtorParam) -> Self {
675 assert_data_property(&first);
676 Self::new(KtClassKind::Data { ctor: vec![first] }, name)
677 }
678 pub fn value(name: impl Into<String>, field: KtCtorParam) -> Self {
685 assert!(
686 field.prop == Some(false),
687 "`value class` wraps a single read-only property, but `{}` is {} — \
688 call `.val()` on it",
689 field.name,
690 describe_prop(field.prop),
691 );
692 Self::new(
693 KtClassKind::Value {
694 field: Box::new(field),
695 },
696 name,
697 )
698 }
699 pub fn enum_(name: impl Into<String>) -> Self {
701 Self::new(
702 KtClassKind::Enum {
703 ctor: Vec::new(),
704 entries: Vec::new(),
705 },
706 name,
707 )
708 }
709 pub fn object_(name: impl Into<String>) -> Self {
710 Self::new(KtClassKind::Object, name)
711 }
712 pub fn data_object(name: impl Into<String>) -> Self {
713 Self::new(KtClassKind::DataObject, name)
714 }
715 pub fn interface_(name: impl Into<String>) -> Self {
716 Self::new(KtClassKind::Interface, name)
717 }
718 pub fn sealed_interface(name: impl Into<String>) -> Self {
719 Self::new(KtClassKind::SealedInterface, name)
720 }
721 pub fn ctor_params(&self) -> &[KtCtorParam] {
723 self.kind.ctor_params()
724 }
725
726 pub fn vis(mut self, v: KtVis) -> Self {
727 self.vis = v;
728 self
729 }
730 pub fn annotation(mut self, a: impl Into<String>) -> Self {
731 self.annotations.push(a.into());
732 self
733 }
734 pub fn kdoc(mut self, d: impl Into<String>) -> Self {
735 self.kdoc = Some(d.into());
736 self
737 }
738 pub fn ctor_param(mut self, p: KtCtorParam) -> Self {
748 if matches!(self.kind, KtClassKind::Data { .. }) {
749 assert_data_property(&p);
750 }
751 match &mut self.kind {
752 KtClassKind::Class { ctor, .. }
753 | KtClassKind::Data { ctor }
754 | KtClassKind::Enum { ctor, .. } => ctor.push(p),
755 other => panic!(
756 "`{}` has no primary constructor to add parameter `{}` to",
757 other.keyword(),
758 p.name
759 ),
760 }
761 self
762 }
763
764 pub fn entry(mut self, e: KtEnumEntry) -> Self {
770 match &mut self.kind {
771 KtClassKind::Enum { entries, .. } => entries.push(e),
772 other => panic!(
773 "`{}` is not an enum class; cannot add entry `{}`",
774 other.keyword(),
775 e.name
776 ),
777 }
778 self
779 }
780 pub fn extends(mut self, ty: KtType, args: Option<&str>) -> Self {
789 let what = format!("class `{}`", self.name);
790 self.supertypes.set_superclass(ty, args, &what);
791 self
792 }
793
794 pub fn implements(mut self, ty: KtType) -> Self {
796 self.supertypes.interfaces.push(ty);
797 self
798 }
799 pub fn member(mut self, d: impl Into<KtDecl>) -> Self {
800 self.members.push(d.into());
801 self
802 }
803 pub fn companion(mut self, c: KtCompanion) -> Self {
804 self.companion = Some(Box::new(c));
805 self
806 }
807}
808
809#[derive(Clone, Debug, Default)]
811pub enum KtBody {
812 #[default]
817 None,
818 Expr(KtCode),
820 Block(KtCode),
822 External,
826}
827
828#[derive(Clone, Debug)]
830pub struct KtFun {
831 pub name: String,
832 pub vis: KtVis,
833 pub modifiers: Vec<String>,
836 pub annotations: Vec<String>,
837 pub kdoc: Option<String>,
838 pub generics: Vec<String>,
840 pub receiver: Option<KtType>,
843 pub params: Vec<KtParam>,
844 pub ret: Option<KtType>,
845 pub body: KtBody,
846}
847
848impl KtFun {
849 pub fn new(name: impl Into<String>) -> Self {
850 Self {
851 name: name.into(),
852 vis: KtVis::Default,
853 modifiers: Vec::new(),
854 annotations: Vec::new(),
855 kdoc: None,
856 generics: Vec::new(),
857 receiver: None,
858 params: Vec::new(),
859 ret: None,
860 body: KtBody::None,
861 }
862 }
863
864 pub fn vis(mut self, v: KtVis) -> Self {
865 self.vis = v;
866 self
867 }
868 pub fn receiver(mut self, ty: KtType) -> Self {
870 self.receiver = Some(ty);
871 self
872 }
873 pub fn modifier(mut self, m: impl Into<String>) -> Self {
880 let m = m.into();
881 assert!(
885 !m.split_whitespace().any(|w| w == "external"),
886 "`external` is not a modifier here — use `KtFun::external()`, which \
887 also rules out giving the function a body"
888 );
889 self.modifiers.push(m);
890 self
891 }
892 pub fn annotation(mut self, a: impl Into<String>) -> Self {
893 self.annotations.push(a.into());
894 self
895 }
896 pub fn kdoc(mut self, d: impl Into<String>) -> Self {
897 self.kdoc = Some(d.into());
898 self
899 }
900 pub fn generic(mut self, g: impl Into<String>) -> Self {
901 self.generics.push(g.into());
902 self
903 }
904 pub fn param(mut self, p: KtParam) -> Self {
905 self.params.push(p);
906 self
907 }
908 pub fn returns(mut self, ty: KtType) -> Self {
909 self.ret = Some(ty);
910 self
911 }
912 pub fn body(mut self, c: KtCode) -> Self {
913 self.body = KtBody::Block(c);
914 self
915 }
916 pub fn expr_body(mut self, c: KtCode) -> Self {
917 self.body = KtBody::Expr(c);
918 self
919 }
920 pub fn external(mut self) -> Self {
922 self.body = KtBody::External;
923 self
924 }
925
926 pub fn signature(&self) -> KtFunSig {
930 KtFunSig {
931 name: self.name.clone(),
932 vis: self.vis,
933 annotations: self.annotations.clone(),
934 kdoc: self.kdoc.clone(),
935 generics: self.generics.clone(),
936 receiver: self.receiver.clone(),
937 params: self.params.clone(),
938 ret: self.ret.clone(),
939 }
940 }
941}
942
943#[derive(Clone, Debug)]
945pub struct KtParam {
946 pub name: String,
947 pub ty: KtType,
948 pub default: Option<KtCode>,
949}
950
951impl KtParam {
952 pub fn new(name: impl Into<String>, ty: KtType) -> Self {
953 Self {
954 name: name.into(),
955 ty,
956 default: None,
957 }
958 }
959 pub fn default(mut self, d: impl Into<String>) -> Self {
960 self.default = Some(KtCode::new().line(d.into()));
961 self
962 }
963}
964
965#[derive(Clone, Debug)]
967pub struct KtProperty {
968 pub name: String,
969 pub ty: Option<KtType>,
970 pub value: KtPropertyValue,
974 pub mutable: bool,
975 pub vis: KtVis,
976 pub annotations: Vec<String>,
978 pub modifiers: Vec<String>,
981 pub kdoc: Option<String>,
982 pub accessors: Option<KtCode>,
984}
985
986impl KtProperty {
987 pub fn val(name: impl Into<String>) -> Self {
988 Self {
989 name: name.into(),
990 ty: None,
991 value: KtPropertyValue::None,
992 mutable: false,
993 vis: KtVis::Default,
994 annotations: Vec::new(),
995 modifiers: Vec::new(),
996 kdoc: None,
997 accessors: None,
998 }
999 }
1000 pub fn var(name: impl Into<String>) -> Self {
1001 Self {
1002 mutable: true,
1003 ..Self::val(name)
1004 }
1005 }
1006 pub fn ty(mut self, t: KtType) -> Self {
1007 self.ty = Some(t);
1008 self
1009 }
1010 pub fn initializer(mut self, i: impl Into<String>) -> Self {
1011 self.value = KtPropertyValue::Initializer(KtCode::new().line(i.into()));
1012 self
1013 }
1014 pub fn delegate(mut self, d: impl Into<String>) -> Self {
1015 self.value = KtPropertyValue::Delegate(KtCode::new().line(d.into()));
1016 self
1017 }
1018 pub fn vis(mut self, v: KtVis) -> Self {
1019 self.vis = v;
1020 self
1021 }
1022 pub fn annotation(mut self, a: impl Into<String>) -> Self {
1023 self.annotations.push(a.into());
1024 self
1025 }
1026 pub fn modifier(mut self, m: impl Into<String>) -> Self {
1027 self.modifiers.push(m.into());
1028 self
1029 }
1030 pub fn kdoc(mut self, d: impl Into<String>) -> Self {
1031 self.kdoc = Some(d.into());
1032 self
1033 }
1034 pub fn accessors(mut self, c: KtCode) -> Self {
1035 self.accessors = Some(c);
1036 self
1037 }
1038}