Skip to content

Commit

Permalink
Propagate comments from record fields to gentype output (#6333)
Browse files Browse the repository at this point in the history
* propagate comments from record fields to gentype output

* changelog
  • Loading branch information
zth authored Jul 27, 2023
1 parent 062452f commit 43e1175
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
# 11.0.0-beta.5 (Unreleased)

#### :rocket: New Feature

- GenType: Propagate comments from record fields to emitted TypeScript types. https://github.com/rescript-lang/rescript-compiler/pull/6333

# 11.0.0-beta.4

#### :rocket: New Feature
Expand Down
18 changes: 14 additions & 4 deletions jscomp/gentype/Annotation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ let tagIsOneOfTheGenTypeAnnotations s =
let tagIsGenTypeIgnoreInterface s =
s = "genType.ignoreInterface" || s = "gentype.ignoreInterface"

let tagIsOcamlDoc s = s = "ocaml.doc"
let tagIsDoc s =
match s with
| "ocaml.doc" | "res.doc" -> true
| _ -> false
let tagIsInternLocal s = s = "internal.local"

let rec getAttributePayload checkText (attributes : Typedtree.attributes) =
Expand Down Expand Up @@ -143,12 +146,19 @@ let getAttributeImportRenaming attributes =
(Some importString, Some renameString)
| _ -> (None, genTypeAsRenaming)

let getDocString attributes =
let docPayload = attributes |> getAttributePayload tagIsOcamlDoc in
let getDocPayload attributes =
let docPayload = attributes |> getAttributePayload tagIsDoc in
match docPayload with
| Some (_, StringPayload docString) -> "/** " ^ docString ^ " */\n"
| Some (_, StringPayload docString) -> Some docString
| _ -> None

let mkDocString maybeDoc =
match maybeDoc with
| Some docString -> "/** " ^ docString ^ " */\n"
| _ -> ""

let getDocString attributes = getDocPayload attributes |> mkDocString

let hasAttribute checkText (attributes : Typedtree.attributes) =
getAttributePayload checkText attributes <> None

Expand Down
18 changes: 14 additions & 4 deletions jscomp/gentype/EmitType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ let typeReactRef ~type_ =
nameJS = reactRefCurrent;
optional = Mandatory;
type_ = Null type_;
docString = None;
};
] )

Expand Down Expand Up @@ -162,12 +163,13 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
in
let noPayloadsRendered = noPayloads |> List.map labelJSToString in
let field ~name value =
let field ~name ?docString value =
{
mutable_ = Mutable;
nameJS = name;
optional = Mandatory;
type_ = TypeVar value;
docString;
}
in
let fields fields =
Expand Down Expand Up @@ -232,7 +234,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
^ "| "))

and renderField ~config ~indent ~typeNameIsInterface ~inFunType
{mutable_; nameJS = lbl; optional; type_} =
{mutable_; nameJS = lbl; optional; type_; docString} =
let optMarker =
match optional == Optional with
| true -> "?"
Expand All @@ -249,8 +251,16 @@ and renderField ~config ~indent ~typeNameIsInterface ~inFunType
| false -> EmitText.quotes lbl
in

Indent.break ~indent ^ mutMarker ^ lbl ^ optMarker ^ ": "
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
let defStr =
mutMarker ^ lbl ^ optMarker ^ ": "
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
in
match docString with
| None -> Indent.break ~indent ^ defStr
| Some docString ->
(* Always print comments on newline before definition. *)
let indentStr = indent |> Option.value ~default:"" in
"\n" ^ indentStr ^ "/**" ^ docString ^ "*/\n" ^ indentStr ^ defStr

and renderFields ~config ~indent ~inFunType ~typeNameIsInterface fields =
let indent1 = indent |> Indent.more in
Expand Down
1 change: 1 addition & 0 deletions jscomp/gentype/ExportModule.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and exportModuleItemToFields =
nameJS = fieldName;
optional = Mandatory;
type_ = typeForType;
docString = None;
}
in
let fieldForValue = {fieldForType with type_ = typeForValue} in
Expand Down
1 change: 1 addition & 0 deletions jscomp/gentype/GenTypeCommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ and field = {
nameJS: string;
optional: optional;
type_: type_;
docString: string option;
}

and function_ = {argTypes: argType list; retType: type_; typeVars: string list}
Expand Down
16 changes: 14 additions & 2 deletions jscomp/gentype/NamedArgs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,25 @@ let rec groupReversed ~revCurGroup ~revResult labeledTypes =
(* Add it to the current group, not result. *)
groupReversed
~revCurGroup:
({mutable_ = Immutable; nameJS = name; optional = Optional; type_}
({
mutable_ = Immutable;
nameJS = name;
optional = Optional;
type_;
docString = None;
}
:: revCurGroup)
~revResult tl
| _, (Label name, type_) :: tl ->
groupReversed
~revCurGroup:
({mutable_ = Immutable; nameJS = name; optional = Mandatory; type_}
({
mutable_ = Immutable;
nameJS = name;
optional = Mandatory;
type_;
docString = None;
}
:: revCurGroup)
~revResult tl
| [], [] -> revResult
Expand Down
11 changes: 7 additions & 4 deletions jscomp/gentype/TranslateTypeDeclarations.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,26 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
mutability,
ld_type
|> TranslateTypeExprFromTypes.translateTypeExprFromTypes ~config
~typeEnv ))
~typeEnv,
Annotation.getDocPayload ld_attributes ))
in
let dependencies =
fieldTranslations
|> List.map (fun (_, _, {TranslateTypeExprFromTypes.dependencies}) ->
|> List.map (fun (_, _, {TranslateTypeExprFromTypes.dependencies}, _) ->
dependencies)
|> List.concat
in
let fields =
fieldTranslations
|> List.map (fun (name, mutable_, {TranslateTypeExprFromTypes.type_}) ->
|> List.map
(fun (name, mutable_, {TranslateTypeExprFromTypes.type_}, docString)
->
let optional, type1 =
match type_ with
| Option type1 when isOptional name -> (Optional, type1)
| _ -> (Mandatory, type_)
in
{mutable_; nameJS = name; optional; type_ = type1})
{mutable_; nameJS = name; optional; type_ = type1; docString})
in
let type_ =
match fields with
Expand Down
8 changes: 6 additions & 2 deletions jscomp/gentype/TranslateTypeExprFromTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ let translateObjType closedFlag fieldsTranslations =
| _ -> (Mandatory, t)
in
let name = name |> Runtime.mangleObjectField in
{mutable_; nameJS = name; optional; type_})
{mutable_; nameJS = name; optional; type_; docString = None})
in
let type_ = Object (closedFlag, fields) in
{dependencies; type_}
Expand Down Expand Up @@ -126,6 +126,7 @@ let translateConstr ~config ~paramsTranslation ~(path : Path.t) ~typeEnv =
nameJS = "contents";
optional = Mandatory;
type_ = paramTranslation.type_;
docString = None;
};
] );
}
Expand Down Expand Up @@ -465,7 +466,7 @@ and signatureToModuleRuntimeRepresentation ~config ~typeVarsGen ~typeEnv
|> List.map (fun signatureItem ->
match signatureItem with
| Types.Sig_value (_id, {val_kind = Val_prim _}) -> ([], [])
| Types.Sig_value (id, {val_type = typeExpr}) ->
| Types.Sig_value (id, {val_type = typeExpr; val_attributes}) ->
let {dependencies; type_} =
typeExpr
|> translateTypeExprFromTypes_ ~config ~typeVarsGen ~typeEnv
Expand All @@ -476,6 +477,7 @@ and signatureToModuleRuntimeRepresentation ~config ~typeVarsGen ~typeEnv
nameJS = id |> Ident.name;
optional = Mandatory;
type_;
docString = Annotation.getDocPayload val_attributes;
}
in
(dependencies, [field])
Expand All @@ -499,6 +501,8 @@ and signatureToModuleRuntimeRepresentation ~config ~typeVarsGen ~typeEnv
nameJS = id |> Ident.name;
optional = Mandatory;
type_;
docString =
Annotation.getDocPayload moduleDeclaration.md_attributes;
}
in
(dependencies, [field])
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions jscomp/gentype_tests/typescript-react-example/src/Comments.bs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions jscomp/gentype_tests/typescript-react-example/src/Comments.gen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* TypeScript file generated from Comments.res by genType. */
/* eslint-disable import/first */


// @ts-ignore: Implicit any on import
import * as CommentsBS__Es6Import from './Comments.bs';
const CommentsBS: any = CommentsBS__Es6Import;

// tslint:disable-next-line:interface-over-type-literal
export type DecideSubject_payload = {
/** A hint to use as a guide when thinking of your poem.*/
readonly hint: string };

// tslint:disable-next-line:max-classes-per-file
export abstract class DecideSubject_input { protected opaque!: any }; /* simulate opaque types */

// tslint:disable-next-line:interface-over-type-literal
export type DecideSubject_output = {
/** The text of the poem.*/
readonly text: string;
/** The prompt used to generate the poem.*/
readonly prompt: string;
/** The system prompt used to generate the poem.*/
readonly systemPrompt: string
};

/** Decide on a subject matter for a poem. */
export const DecideSubject__placeholder: (run:string, times:number) => void = CommentsBS.DecideSubject._placeholder;

export const DecideSubject: { _placeholder: (run:string, times:number) => void } = CommentsBS.DecideSubject
24 changes: 24 additions & 0 deletions jscomp/gentype_tests/typescript-react-example/src/Comments.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@genType /** A module for deciding on a subject matter for a poem.*/
module DecideSubject = {
type payload = {
/** A hint to use as a guide when thinking of your poem.*/
hint: string,
}
/** The input used to generate the prompt and system prompt.*/
type input
/** The output from evaluating the llm prompt*/
type output = {
/** The text of the poem.*/
text: string,
/** The prompt used to generate the poem.*/
prompt: string,
/** The system prompt used to generate the poem.*/
systemPrompt: string,
}

@genType /** Decide on a subject matter for a poem.*/
let _placeholder = (
@ocaml.doc("The runner specification") run: string,
@ocaml.doc("The number of times to cycle through the runner") times: int,
) => (run, times)->ignore
}

0 comments on commit 43e1175

Please sign in to comment.