Skip to content
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

Gentype: make output DCE-friendly #6508

Merged
merged 2 commits into from
Dec 18, 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 @@ -25,6 +25,10 @@
- GenType: support mutual recursive types inside modules. https://github.com/rescript-lang/rescript-compiler/pull/6528
- Workaround for `@as`in labels in uncurried externals, which was broken. https://github.com/rescript-lang/rescript-compiler/pull/6527

#### :nail_care: Polish

- GenType: make outputs DCE-friendly. https://github.com/rescript-lang/rescript-compiler/pull/6508

# 11.0.0-rc.7

#### :rocket: New Feature
Expand Down
12 changes: 5 additions & 7 deletions jscomp/gentype/EmitJs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ let emitCodeItem ~config ~emitters ~moduleItemsEmitter ~env ~fileName
in
let valueNameTypeChecked = valueName ^ "TypeChecked" in
let emitters =
(importedAsName ^ restOfPath) ^ ";"
importedAsName ^ restOfPath
|> EmitType.emitExportConst ~config
~comment:
("In case of type error, check the type of '" ^ valueName
Expand All @@ -224,9 +224,8 @@ let emitCodeItem ~config ~emitters ~moduleItemsEmitter ~env ~fileName
| false -> valueName
in
let emitters =
(valueNameTypeChecked
|> EmitType.emitTypeCast ~config ~type_ ~typeNameIsInterface)
^ ";"
valueNameTypeChecked
|> EmitType.emitTypeCast ~config ~type_ ~typeNameIsInterface
|> EmitType.emitExportConst
~comment:
("Export '" ^ valueNameNotDefault
Expand Down Expand Up @@ -359,10 +358,9 @@ let emitCodeItem ~config ~emitters ~moduleItemsEmitter ~env ~fileName
| _ -> emitters
in
let emitters =
((fileNameBs |> ModuleName.toString)
(fileNameBs |> ModuleName.toString)
^ "."
^ (moduleAccessPath |> Runtime.emitModuleAccessPath ~config))
^ ";"
^ (moduleAccessPath |> Runtime.emitModuleAccessPath ~config)
|> EmitType.emitExportConst ~config ~docString ~early:false ~emitters
~name ~type_ ~typeNameIsInterface
in
Expand Down
44 changes: 17 additions & 27 deletions jscomp/gentype/EmitType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -308,18 +308,15 @@ and renderFunType ~config ~indent ~inFunType ~typeNameIsInterface ~typeVars
let typeToString ~config ~typeNameIsInterface type_ =
type_ |> renderType ~config ~typeNameIsInterface ~inFunType:false

let ofType ~config ~typeNameIsInterface ~type_ s =
s ^ ": " ^ (type_ |> typeToString ~config ~typeNameIsInterface)

let emitExportConst ~early ?(comment = "") ~config
?(docString = DocString.empty) ~emitters ~name ~type_ ~typeNameIsInterface
line =
let typeString = type_ |> typeToString ~config ~typeNameIsInterface in
(match comment = "" with
| true -> comment
| false -> "// " ^ comment ^ "\n")
^ DocString.render docString ^ "export const "
^ (name |> ofType ~config ~typeNameIsInterface ~type_)
^ " = " ^ line
^ DocString.render docString ^ "export const " ^ name ^ ": " ^ typeString
^ " = " ^ line ^ " as any;"
|> (match early with
| true -> Emitters.exportEarly
| false -> Emitters.export)
Expand Down Expand Up @@ -388,27 +385,20 @@ let emitRequire ~importedValueOrComponent ~early ~emitters ~(config : Config.t)
|> ImportPath.chopExtensionSafe (* for backward compatibility *)
| _ -> importPath
in
match config.module_ with
| ES6 when not importedValueOrComponent ->
let moduleNameString = ModuleName.toString moduleName in
(let es6ImportModule = moduleNameString ^ "__Es6Import" in
"import * as " ^ es6ImportModule ^ " from '"
^ (importPath |> ImportPath.emit)
^ "';\n" ^ "const " ^ moduleNameString ^ ": any = " ^ es6ImportModule ^ ";")
|> (match early with
| true -> Emitters.requireEarly
| false -> Emitters.require)
~emitters
| _ ->
"const "
^ ModuleName.toString moduleName
^ " = require('"
^ (importPath |> ImportPath.emit)
^ "');"
|> (match early with
| true -> Emitters.requireEarly
| false -> Emitters.require)
~emitters
let moduleNameString = ModuleName.toString moduleName in
let importPathString = ImportPath.emit importPath in
let output =
match config.module_ with
| ES6 when not importedValueOrComponent ->
"import * as " ^ moduleNameString ^ " from '" ^ importPathString ^ "';"
| _ ->
"const " ^ moduleNameString ^ " = require('" ^ importPathString ^ "');"
in
output
|> (match early with
| true -> Emitters.requireEarly
| false -> Emitters.require)
~emitters

let require ~early =
match early with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
/* eslint-disable */
/* tslint:disable */

import * as CommentsBS__Es6Import from './Comments.bs';
const CommentsBS: any = CommentsBS__Es6Import;
import * as CommentsBS from './Comments.bs';

export type DecideSubject_payload = {
/** A hint to use as a guide when thinking of your poem. */
Expand All @@ -24,8 +23,8 @@ export type DecideSubject_output = {
};

/** 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._placeholder as any;

export const DecideSubject: {
/** Decide on a subject matter for a poem. */
_placeholder: (run:string, times:number) => void } = CommentsBS.DecideSubject
_placeholder: (run:string, times:number) => void } = CommentsBS.DecideSubject as any;
52 changes: 26 additions & 26 deletions jscomp/gentype_tests/typescript-react-example/src/Core.gen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import {someFunWithNullThenOptionalArgs as someFunWithNullThenOptionalArgsNotChe
import {someFunWithNullUndefinedArg as someFunWithNullUndefinedArgNotChecked} from './CoreTS';

// In case of type error, check the type of 'someFunWithNullThenOptionalArgs' in 'Core.res' and './CoreTS'.
export const someFunWithNullThenOptionalArgsTypeChecked: (_1:(null | string), _2:(undefined | string)) => string = someFunWithNullThenOptionalArgsNotChecked;
export const someFunWithNullThenOptionalArgsTypeChecked: (_1:(null | string), _2:(undefined | string)) => string = someFunWithNullThenOptionalArgsNotChecked as any;

// Export 'someFunWithNullThenOptionalArgs' early to allow circular import from the '.bs.js' file.
export const someFunWithNullThenOptionalArgs: unknown = someFunWithNullThenOptionalArgsTypeChecked as (_1:(null | string), _2:(undefined | string)) => string;
export const someFunWithNullThenOptionalArgs: unknown = someFunWithNullThenOptionalArgsTypeChecked as (_1:(null | string), _2:(undefined | string)) => string as any;

// In case of type error, check the type of 'someFunWithNullUndefinedArg' in 'Core.res' and './CoreTS'.
export const someFunWithNullUndefinedArgTypeChecked: (_1:(null | undefined | string), _2:number) => string = someFunWithNullUndefinedArgNotChecked;
export const someFunWithNullUndefinedArgTypeChecked: (_1:(null | undefined | string), _2:number) => string = someFunWithNullUndefinedArgNotChecked as any;

// Export 'someFunWithNullUndefinedArg' early to allow circular import from the '.bs.js' file.
export const someFunWithNullUndefinedArg: unknown = someFunWithNullUndefinedArgTypeChecked as (_1:(null | undefined | string), _2:number) => string;
export const someFunWithNullUndefinedArg: unknown = someFunWithNullUndefinedArgTypeChecked as (_1:(null | undefined | string), _2:number) => string as any;

const CoreBS = require('./Core.bs');

Expand All @@ -27,46 +27,46 @@ export type t1 = { readonly x?: string };

export type t2 = { readonly x: (undefined | string) };

export const null0: (x:(null | number)) => (null | number) = CoreBS.null0;
export const null0: (x:(null | number)) => (null | number) = CoreBS.null0 as any;

export const null1: (x:(null | number)) => (null | number) = CoreBS.null1;
export const null1: (x:(null | number)) => (null | number) = CoreBS.null1 as any;

export const nullable0: (x:(null | undefined | number)) => (null | undefined | number) = CoreBS.nullable0;
export const nullable0: (x:(null | undefined | number)) => (null | undefined | number) = CoreBS.nullable0 as any;

export const nullable1: (x:(null | undefined | number)) => (null | undefined | number) = CoreBS.nullable1;
export const nullable1: (x:(null | undefined | number)) => (null | undefined | number) = CoreBS.nullable1 as any;

export const undefined0: (x:(undefined | number)) => (undefined | number) = CoreBS.undefined0;
export const undefined0: (x:(undefined | number)) => (undefined | number) = CoreBS.undefined0 as any;

export const undefined1: (x:(undefined | number)) => (undefined | number) = CoreBS.undefined1;
export const undefined1: (x:(undefined | number)) => (undefined | number) = CoreBS.undefined1 as any;

export const dict0: (x:{[id: string]: string}) => {[id: string]: string} = CoreBS.dict0;
export const dict0: (x:{[id: string]: string}) => {[id: string]: string} = CoreBS.dict0 as any;

export const dict1: (x:{[id: string]: string}) => {[id: string]: string} = CoreBS.dict1;
export const dict1: (x:{[id: string]: string}) => {[id: string]: string} = CoreBS.dict1 as any;

export const promise0: (x:Promise<string>) => Promise<string> = CoreBS.promise0;
export const promise0: (x:Promise<string>) => Promise<string> = CoreBS.promise0 as any;

export const promise1: (x:Promise<string>) => Promise<string> = CoreBS.promise1;
export const promise1: (x:Promise<string>) => Promise<string> = CoreBS.promise1 as any;

export const date0: (x:Date) => Date = CoreBS.date0;
export const date0: (x:Date) => Date = CoreBS.date0 as any;

export const date1: (x:Date) => Date = CoreBS.date1;
export const date1: (x:Date) => Date = CoreBS.date1 as any;

export const bigint0: (x:BigInt) => BigInt = CoreBS.bigint0;
export const bigint0: (x:BigInt) => BigInt = CoreBS.bigint0 as any;

export const bigint1: (x:BigInt) => BigInt = CoreBS.bigint1;
export const bigint1: (x:BigInt) => BigInt = CoreBS.bigint1 as any;

export const regexp0: (x:RegExp) => RegExp = CoreBS.regexp0;
export const regexp0: (x:RegExp) => RegExp = CoreBS.regexp0 as any;

export const regexp1: (x:RegExp) => RegExp = CoreBS.regexp1;
export const regexp1: (x:RegExp) => RegExp = CoreBS.regexp1 as any;

export const map1: (x:Map<string,number>) => Map<string,number> = CoreBS.map1;
export const map1: (x:Map<string,number>) => Map<string,number> = CoreBS.map1 as any;

export const weakmap1: (x:WeakMap<number[],number>) => WeakMap<number[],number> = CoreBS.weakmap1;
export const weakmap1: (x:WeakMap<number[],number>) => WeakMap<number[],number> = CoreBS.weakmap1 as any;

export const set1: (x:Set<string>) => Set<string> = CoreBS.set1;
export const set1: (x:Set<string>) => Set<string> = CoreBS.set1 as any;

export const weakset1: (x:WeakSet<number[]>) => WeakSet<number[]> = CoreBS.weakset1;
export const weakset1: (x:WeakSet<number[]>) => WeakSet<number[]> = CoreBS.weakset1 as any;

export const option0: (x:(undefined | string)) => (undefined | string) = CoreBS.option0;
export const option0: (x:(undefined | string)) => (undefined | string) = CoreBS.option0 as any;

export const option1: (x:(undefined | variant)) => (undefined | variant) = CoreBS.option1;
export const option1: (x:(undefined | variant)) => (undefined | variant) = CoreBS.option1 as any;
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,46 @@
/* eslint-disable */
/* tslint:disable */

import * as DocstringsBS__Es6Import from './Docstrings.bs';
const DocstringsBS: any = DocstringsBS__Es6Import;
import * as DocstringsBS from './Docstrings.bs';

export type t = "A" | "B";

/** hello */
export const flat: number = DocstringsBS.flat;
export const flat: number = DocstringsBS.flat as any;

/** \n * Sign a message with a key.\n *\n * @param message - A message to be signed\n * @param key - The key with which to sign the message\n * @returns A signed message\n */
export const signMessage: (message:string, key:number) => string = DocstringsBS.signMessage;
export const signMessage: (message:string, key:number) => string = DocstringsBS.signMessage as any;

export const one: (a:number) => number = DocstringsBS.one;
export const one: (a:number) => number = DocstringsBS.one as any;

export const two: (a:number, b:number) => number = DocstringsBS.two;
export const two: (a:number, b:number) => number = DocstringsBS.two as any;

export const tree: (a:number, b:number, c:number) => number = DocstringsBS.tree;
export const tree: (a:number, b:number, c:number) => number = DocstringsBS.tree as any;

export const oneU: (a:number) => number = DocstringsBS.oneU;
export const oneU: (a:number) => number = DocstringsBS.oneU as any;

export const twoU: (a:number, b:number) => number = DocstringsBS.twoU;
export const twoU: (a:number, b:number) => number = DocstringsBS.twoU as any;

export const treeU: (a:number, b:number, c:number) => number = DocstringsBS.treeU;
export const treeU: (a:number, b:number, c:number) => number = DocstringsBS.treeU as any;

export const useParam: (param:number) => number = DocstringsBS.useParam;
export const useParam: (param:number) => number = DocstringsBS.useParam as any;

export const useParamU: (param:number) => number = DocstringsBS.useParamU;
export const useParamU: (param:number) => number = DocstringsBS.useParamU as any;

export const unnamed1: (param:number) => number = DocstringsBS.unnamed1;
export const unnamed1: (param:number) => number = DocstringsBS.unnamed1 as any;

export const unnamed1U: (param:number) => number = DocstringsBS.unnamed1U;
export const unnamed1U: (param:number) => number = DocstringsBS.unnamed1U as any;

export const unnamed2: (param_0:number, param_1:number) => number = DocstringsBS.unnamed2;
export const unnamed2: (param_0:number, param_1:number) => number = DocstringsBS.unnamed2 as any;

export const unnamed2U: (param_0:number, param_1:number) => number = DocstringsBS.unnamed2U;
export const unnamed2U: (param_0:number, param_1:number) => number = DocstringsBS.unnamed2U as any;

export const grouped: (x:number, y:number, a:number, b:number, c:number, z:number) => number = DocstringsBS.grouped;
export const grouped: (x:number, y:number, a:number, b:number, c:number, z:number) => number = DocstringsBS.grouped as any;

export const unitArgWithoutConversion: () => string = DocstringsBS.unitArgWithoutConversion;
export const unitArgWithoutConversion: () => string = DocstringsBS.unitArgWithoutConversion as any;

export const unitArgWithoutConversionU: () => string = DocstringsBS.unitArgWithoutConversionU;
export const unitArgWithoutConversionU: () => string = DocstringsBS.unitArgWithoutConversionU as any;

export const unitArgWithConversion: () => t = DocstringsBS.unitArgWithConversion;
export const unitArgWithConversion: () => t = DocstringsBS.unitArgWithConversion as any;

export const unitArgWithConversionU: () => t = DocstringsBS.unitArgWithConversionU;
export const unitArgWithConversionU: () => t = DocstringsBS.unitArgWithConversionU as any;
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
/* eslint-disable */
/* tslint:disable */

import * as EmitModuleIfNoConversionBS__Es6Import from './EmitModuleIfNoConversion.bs';
const EmitModuleIfNoConversionBS: any = EmitModuleIfNoConversionBS__Es6Import;
import * as EmitModuleIfNoConversionBS from './EmitModuleIfNoConversion.bs';

export type t = "A" | { TAG: "B"; readonly name: string };

export const X_foo: (t:t) => void = EmitModuleIfNoConversionBS.X.foo;
export const X_foo: (t:t) => void = EmitModuleIfNoConversionBS.X.foo as any;

export const X_x: number = EmitModuleIfNoConversionBS.X.x;
export const X_x: number = EmitModuleIfNoConversionBS.X.x as any;

export const Y_x: string = EmitModuleIfNoConversionBS.Y.x;
export const Y_x: string = EmitModuleIfNoConversionBS.Y.x as any;

export const Y: { x: string } = EmitModuleIfNoConversionBS.Y
export const Y: { x: string } = EmitModuleIfNoConversionBS.Y as any;

export const X: { x: number; foo: (t:t) => void } = EmitModuleIfNoConversionBS.X
export const X: { x: number; foo: (t:t) => void } = EmitModuleIfNoConversionBS.X as any;
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@

import * as React from 'react';

import * as ExportWithRenameBS__Es6Import from './ExportWithRename.bs';
const ExportWithRenameBS: any = ExportWithRenameBS__Es6Import;
import * as ExportWithRenameBS from './ExportWithRename.bs';

export type Props = { readonly s: string };

export const Renamed: React.ComponentType<{ readonly s: string }> = ExportWithRenameBS.make;
export const Renamed: React.ComponentType<{ readonly s: string }> = ExportWithRenameBS.make as any;
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
/* eslint-disable */
/* tslint:disable */

import * as FirstClassModulesBS__Es6Import from './FirstClassModules.bs';
const FirstClassModulesBS: any = FirstClassModulesBS__Es6Import;
import * as FirstClassModulesBS from './FirstClassModules.bs';

export type MT_t = number;

Expand All @@ -24,7 +23,7 @@ export type firstClassModule = {
readonly y: string
};

export const firstClassModule: firstClassModule = FirstClassModulesBS.firstClassModule;
export const firstClassModule: firstClassModule = FirstClassModulesBS.firstClassModule as any;

export const testConvert: (m:{
readonly x: number;
Expand All @@ -50,7 +49,7 @@ export const testConvert: (m:{
};
readonly Z: unknown;
readonly y: string
} = FirstClassModulesBS.testConvert;
} = FirstClassModulesBS.testConvert as any;

export const someFunctorAsFunction: (x:{
readonly x: number;
Expand All @@ -64,4 +63,4 @@ export const someFunctorAsFunction: (x:{
};
readonly Z: unknown;
readonly y: string
}) => { readonly ww: string } = FirstClassModulesBS.someFunctorAsFunction;
}) => { readonly ww: string } = FirstClassModulesBS.someFunctorAsFunction as any;
Loading