Skip to content

Commit

Permalink
fix: dotnet and typescript generation
Browse files Browse the repository at this point in the history
  • Loading branch information
krvital committed Sep 26, 2024
1 parent 758b3f9 commit 22fd4e3
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 72 deletions.
3 changes: 3 additions & 0 deletions src/aidbox_sdk/converter.clj
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@
(->> all-schemas
(map (fn [schema]
{:name (:id schema)
:deps (if-let [base (:base schema)]
[(->pascal-case (url->resource-name base))]
[])
:base (when-let [base (:base schema)]
(->pascal-case (url->resource-name base)))
:elements (->> (resolve-elements search-params-schemas (:id schema))
Expand Down
140 changes: 85 additions & 55 deletions src/aidbox_sdk/generator/dotnet.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,39 @@
(:import
[aidbox_sdk.generator CodeGenerator]))

(defn polymorphic-element->property [element]
(defn ->lang-type [fhir-type]
(case fhir-type
;; Primitive Types
"boolean" "bool"
"instant" "string"
"time" "string"
"date" "string"
"dateTime" "string"
"decimal" "number"

"integer" "int"
"unsignedInt" "long"
"positiveInt" "long"

"integer64" "long"
"base64Binary" "string"

"uri" "string"
"url" "string"
"canonical" "string"
"oid" "string"
"uuid" "string"

"string" "string"
"code" "string"
"markdown" "string"
"id" "string"
"xhtml" "string"

;; else
fhir-type))

(defn generate-polymorphic-property [element]
(str "public object?"
" "
(uppercase-first-letter (:name element))
Expand Down Expand Up @@ -81,39 +113,39 @@
(defn url->resource-name [url]
(last (str/split (str url) #"/")))

(defn ->backbone-type [element]
(str/replace (str (:base element) (uppercase-first-letter (:name element))) "[-_]" ""))

(defn generate-property
"Generates class property from schema element."
[element]
(let [name (uppercase-first-letter (:name element))
type (str
;; TODO this is not enough
;; In order to properly put "new" modifier we must know if
;; there is a same property in ancestor classes
(when (:meta element)
"new ")
(when (and (:required element)
(not (:meta element))) "required ")
(or (:value element) (:type element))
(:generic element)
(when (:array element) "[]")
(when (and (not (:required element))
(not (:literal element))) "?"))
accessor (if (or (:meta element)
(:codeable-concept-pattern element))
"{ get; }"
"{ get; set; }")]
(if (contains? element :choices)
(polymorphic-element->property element)
(str "public " type " " name " " accessor
(when (and (:required element)
(:codeable-concept-pattern element)) " = new()")
(:meta element)))))
[{:keys [name array required value type choices] :as element}]
(let [name (uppercase-first-letter name)
lang-type (str/replace (or value type "") #"_" "")
type (str
(when required "required ")
lang-type
(:generic element)
(when array "[]")
(when (and (not required)
(not (:literal element))) "?"))]
(cond choices
(generate-polymorphic-property element)

(= (:type element) "Meta")
(if (:profile element)
(format "public new Meta Meta { get; } = new() { Profile = [\"%s\"] };" (:profile element))
(format "public %s Meta { get; set; }" name))

:else
(str "public " type " " name " { get; set; }"
(when (and (:required element)
(:codeable-concept-pattern element)) " = new()")
(:meta element)))))

(defn class-name
"Generate class name from schema url."
[url]
(let [n (uppercase-first-letter
(url->resource-name url))]
[resource-name]
(let [n (->pascal-case resource-name)]
(cond
(= n "Expression") "ResourceExpression"
(= n "Reference") "ResourceReference"
Expand All @@ -123,7 +155,10 @@
(let [base-class (url->resource-name (:base schema))
schema-name (or (:url schema) (:name schema))
generic (when (= (:type schema) "Bundle") "<T>")
class-name' (class-name (str schema-name generic))
class-name' (class-name (str (or (:resource-name schema)
;; need for BackboneElement
(:name schema)
"") generic))
elements (->> (:elements schema)
(map #(if (and (= (:base %) "Bundle_Entry")
(= (:name %) "resource"))
Expand All @@ -135,9 +170,6 @@
(map u/add-indent)
(str/join "\n"))

base-class (cond (= base-class "Resource") "Base.Resource"
(= base-class "DomainResource") "DomainResource, IResource"
:else base-class)
base-class-name (when-not (str/blank? base-class)
(str " : " (uppercase-first-letter base-class)))]

Expand All @@ -160,16 +192,15 @@
enums []
delegates []}}]
(->> (conj []
(if deps
(apply u/using (map :module deps))
[])
(if deps (apply u/using (map :module deps)) [])
(u/namespace name')
classes
interfaces
structs
enums
delegates)
(flatten)
(remove str/blank?)
(str/join "\n\n")))

(defn package->directory
Expand Down Expand Up @@ -222,10 +253,8 @@
[{:path (datatypes-file-path)
:content (generate-module
:name "Aidbox.FHIR.Base"
:classes (map (fn [ir-schema]
(generate-class ir-schema
(map generate-class (:backbone-elements ir-schema))))
ir-schemas))}])
:deps []
:classes (map generate-class ir-schemas))}])

(generate-resource-module [_ ir-schema]
{:path (resource-file-path ir-schema)
Expand All @@ -238,24 +267,25 @@

(generate-search-params [_ ir-schemas]
(map (fn [ir-schema]
{:path (io/file "search" (str (:name ir-schema) "SearchParameters.cs"))
:content
(generate-module
:name "Aidbox.FHIR.Search"
:classes (generate-class
{:name (str (:name ir-schema) "SearchParameters")
:base (when (:base ir-schema)
(str (:base ir-schema) "SearchParameters"))
:elements (map (fn [el] (update el :name ->pascal-case))
(:elements ir-schema))}))})
ir-schemas))
{:path (io/file "search" (str (:name ir-schema) "SearchParameters.cs"))
:content
(generate-module
:name "Aidbox.FHIR.Search"
:classes (generate-class
{:name (str (:name ir-schema) "SearchParameters")
:resource-name (str (:name ir-schema) "SearchParameters")
:base (when (:base ir-schema)
(str (:base ir-schema) "SearchParameters"))
:elements (map (fn [el] (update el :name ->pascal-case))
(:elements ir-schema))}))})
ir-schemas))

(generate-constraints [_ constraint-ir-schemas]
(mapv (fn [[name' schema]]
{:path (constraint-file-path schema name')
:content (generate-constraint-module
(assoc schema :url name'))})
constraint-ir-schemas))
{:path (constraint-file-path schema name')
:content (generate-constraint-module
(assoc schema :url name'))})
constraint-ir-schemas))

(generate-sdk-files [_] (generator/prepare-sdk-files :dotnet)))

Expand Down
10 changes: 6 additions & 4 deletions src/aidbox_sdk/generator/typescript.clj
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,15 @@
(generate-polymorphic-property element)

(= type "Meta")
(format "%s: Meta & { profile: [\"%s\"] }" name profile)
(if profile
(format "%s: Meta & { profile: [\"%s\"] };" name profile)
(format "%s: Meta;" name))

:else
(let [type' (if (= "BackboneElement" type)
(->backbone-type element)
(->lang-type (:type element)))]
(str name (when-not required "?") ": " type' (when array "[]") ";"))))
(str (->camel-case name) (when-not required "?") ": " type' (when array "[]") ";"))))

(defn generate-class
"Generates TypeScript type from IR (intermediate representation) schema."
Expand Down Expand Up @@ -192,11 +194,11 @@
:classes [(generate-class ir-schema
(map generate-class (:backbone-elements ir-schema)))]})})

(generate-search-params [_ ir-schemas] []
(generate-search-params [_ ir-schemas]
(map (fn [ir-schema]
{:path (search-param-filepath ir-schema)
:content (generate-module
:deps (:deps ir-schema)
:deps (map #(format "%sSearchParameters" %) (:deps ir-schema))
:classes [(generate-class
{:name (format "%sSearchParameters" (:name ir-schema))
:base (when (:base ir-schema)
Expand Down
Loading

0 comments on commit 22fd4e3

Please sign in to comment.