Skip to content
This repository has been archived by the owner on Nov 13, 2023. It is now read-only.

Commit

Permalink
Add support for inlining annotations. Currently off by default.
Browse files Browse the repository at this point in the history
This means that if a type is annotated wiht @genType, and used another type in its definition, the other type will also be considered as annotated.

This is currently supported within one file, and not across files.

In config. Off by default at the moment.

See “Type Expansion” in #70
  • Loading branch information
cristianoc committed Oct 23, 2018
1 parent 2e87e3f commit efc25fc
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 11 deletions.
109 changes: 98 additions & 11 deletions src/EmitJs.re
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,97 @@ let emitImportTypes =
(env, emitters),
);

let inlineAnnotatedTypes =
(~config, ~typeDeclarations, typeMap: Translation.typeMap) => {
let visited = ref(StringSet.empty);
let markedAsGenType = ref(StringSet.empty);
let initialAnnotatedTypes =
typeMap
|> StringMap.bindings
|> List.filter(((_, (_, _, genTypeKind, _))) => genTypeKind == GenType);
let inlineTyp = ((_typeName, (_, typ, genTypeKind, _))) => {
let rec visit = typ =>
switch (typ) {
| Ident(typeName, _) =>
if (visited^ |> StringSet.mem(typeName)) {
();
} else {
visited := visited^ |> StringSet.add(typeName);
switch (typeMap |> StringMap.find(typeName)) {
| (_, _, GenType | GenTypeOpaque | Generated, _) => ()
| (_, typ1, NoGenType, _) =>
markedAsGenType := markedAsGenType^ |> StringSet.add(typeName);
logItem("Marking type %s as GenType\n", typeName);
typ1 |> visit;
| exception Not_found => ()
};
}
| Array(t, _) => t |> visit
| Enum(_) => ()
| Function({argTypes, retType}) =>
argTypes |> List.iter(visit);
retType |> visit;
| GroupOfLabeledArgs(fields)
| Object(fields)
| Record(fields) => fields |> List.iter(({typ}) => typ |> visit)
| Option(t)
| Nullable(t) => t |> visit
| Tuple(innerTypes) => innerTypes |> List.iter(visit)
| TypeVar(_) => ()
};
switch (genTypeKind) {
| GenType => typ |> visit
| Generated
| GenTypeOpaque
| NoGenType => ()
};
};
if (config.inlineAnnotations) {
initialAnnotatedTypes |> List.iter(inlineTyp);
};
let newTypeMap =
typeMap
|> StringMap.mapi((typeName, (args, typ, genTypeKind, importTypes)) =>
(
args,
typ,
markedAsGenType^ |> StringSet.mem(typeName) ?
GenType : genTypeKind,
importTypes,
)
);

let annotatedTypeDeclarations =
typeDeclarations
|> List.map(typeDeclaration =>
switch (
typeDeclaration.Translation.exportFromTypeDeclaration.exportKind
) {
| ExportType(exportType) =>
if (markedAsGenType^ |> StringSet.mem(exportType.resolvedTypeName)) {
{
...typeDeclaration,
exportFromTypeDeclaration: {
...typeDeclaration.exportFromTypeDeclaration,
genTypeKind: GenType,
},
};
} else {
typeDeclaration;
}
| _ => typeDeclaration
}
)
|> List.filter(
(
{exportFromTypeDeclaration: {genTypeKind}}: Translation.typeDeclaration,
) =>
genTypeKind != NoGenType
);

(newTypeMap, annotatedTypeDeclarations);
};

let emitTranslationAsString =
(
~config,
Expand All @@ -773,28 +864,24 @@ let emitTranslationAsString =
cmtExportTypeMapCache: StringMap.empty,
typesFromOtherFiles: StringMap.empty,
};
let exportTypeMap =
translation.typeDeclarations |> createExportTypeMap(~language);
let enumTables = Hashtbl.create(1);

let typeDeclarationsAnnotated =
let (exportTypeMap, annotatedTypeDeclarations) =
translation.typeDeclarations
|> List.filter(
(
{exportFromTypeDeclaration: {genTypeKind}}: Translation.typeDeclaration,
) =>
genTypeKind != NoGenType
|> createExportTypeMap(~language)
|> inlineAnnotatedTypes(
~config,
~typeDeclarations=translation.typeDeclarations,
);

let importTypesFromTypeDeclarations =
typeDeclarationsAnnotated
annotatedTypeDeclarations
|> List.map((typeDeclaration: Translation.typeDeclaration) =>
typeDeclaration.importTypes
)
|> List.concat;

let exportFromTypeDeclarations =
typeDeclarationsAnnotated
annotatedTypeDeclarations
|> List.map((typeDeclaration: Translation.typeDeclaration) =>
typeDeclaration.exportFromTypeDeclaration
);
Expand Down
2 changes: 2 additions & 0 deletions src/GenTypeCommon.re
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type config = {
bsBlockPath: string,
bsCurryPath: string,
importPath,
inlineAnnotations: bool,
language,
module_,
modulesMap: ModuleNameMap.t(ModuleName.t),
Expand All @@ -33,6 +34,7 @@ let defaultConfig = {
bsBlockPath: "bs-platform/lib/js/block.js",
bsCurryPath: "bs-platform/lib/js/curry.js",
importPath: Relative,
inlineAnnotations: false,
language: Flow,
module_: ES6,
modulesMap: ModuleNameMap.empty,
Expand Down
1 change: 1 addition & 0 deletions src/Paths.re
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ let readConfig = () => {
| _ => bsCurryPathString
};
{
...defaultConfig,
language,
module_,
importPath,
Expand Down

0 comments on commit efc25fc

Please sign in to comment.