Skip to content

Propagate comments from record fields to gentype output #6333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}