Skip to content

Commit

Permalink
Complete with generation mode enhancing.
Browse files Browse the repository at this point in the history
  • Loading branch information
samchon committed Oct 8, 2024
1 parent 4a30214 commit b890b9c
Show file tree
Hide file tree
Showing 61 changed files with 7,600 additions and 432 deletions.
2 changes: 1 addition & 1 deletion benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@
"suppress-warnings": "^1.0.2",
"tstl": "^3.0.0",
"uuid": "^9.0.1",
"typia": "../typia-7.0.0-dev.20241007.tgz"
"typia": "../typia-7.0.0-dev.20241009-3.tgz"
}
}
9 changes: 7 additions & 2 deletions deploy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ const main = async (): Promise<void> => {
name: "test",
commands:
tag === "tgz" && template === true
? ["npm run template", "npm run build", "npm start"]
: ["npm run build", "npm start"],
? [
"npm run template",
"npm run build",
"npm start",
"npm run generate",
]
: ["npm run build", "npm start", "npm run generate"],
},
{
name: "test-esm",
Expand Down
2 changes: 1 addition & 1 deletion errors/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
"typescript": "^5.3.2"
},
"dependencies": {
"typia": "../typia-7.0.0-dev.20241007.tgz"
"typia": "../typia-7.0.0-dev.20241009-3.tgz"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typia",
"version": "7.0.0-dev.20241007",
"version": "7.0.0-dev.20241009-3",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/typescript-json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json",
"version": "7.0.0-dev.20241007",
"version": "7.0.0-dev.20241009-3",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -63,7 +63,7 @@
},
"homepage": "https://typia.io",
"dependencies": {
"typia": "7.0.0-dev.20241007"
"typia": "7.0.0-dev.20241009-3"
},
"peerDependencies": {
"typescript": ">=4.8.0 <5.7.0"
Expand Down
2 changes: 1 addition & 1 deletion src/IRandomGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface IRandomGenerator {
bigint(schema: OpenApi.IJsonSchema.IInteger): bigint;
string(schema: OpenApi.IJsonSchema.IString): string;
array<T>(
schema: OpenApi.IJsonSchema.IArray & {
schema: Omit<OpenApi.IJsonSchema.IArray, "items"> & {
element: (index: number, count: number) => T;
},
): T[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface $__IProtobufWriter {
export interface $IProtobufWriter {
bool(value: boolean): void;
int32(value: number): void;
sint32(value: number): void;
Expand Down
4 changes: 2 additions & 2 deletions src/internal/$ProtobufSizer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { $__IProtobufWriter } from "./private/$__IProtobufWriter";
import { $IProtobufWriter } from "./$IProtobufWriter";

/// @reference https://github.com/piotr-oles/as-proto/blob/main/packages/as-proto/assembly/internal/FixedSizer.ts
export class $ProtobufSizer implements $__IProtobufWriter {
export class $ProtobufSizer implements $IProtobufWriter {
/**
* Total length.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/internal/$ProtobufWriter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Singleton } from "../utils/Singleton";

import { $IProtobufWriter } from "./$IProtobufWriter";
import { $ProtobufSizer } from "./$ProtobufSizer";
import { $__IProtobufWriter } from "./private/$__IProtobufWriter";

/// @reference https://github.com/piotr-oles/as-proto/blob/main/packages/as-proto/assembly/internal/FixedWriter.ts
export class $ProtobufWriter implements $__IProtobufWriter {
export class $ProtobufWriter implements $IProtobufWriter {
/**
* Related sizer
*/
Expand Down
1 change: 0 additions & 1 deletion src/internal/$jsonStringifyString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* This `$string` function is a part of `fast-json-stringify` at that time, and
* still being used in `typia` for the string serialization.
*
* @internal
* @reference https://github.com/fastify/fast-json-stringify/blob/master/lib/serializer.js
* @blog https://dev.to/samchon/good-bye-typescript-is-ancestor-of-typia-20000x-faster-validator-49fi
*/
Expand Down
32 changes: 15 additions & 17 deletions src/programmers/AssertProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ export namespace AssertProgrammer {
undefined,
[
IdentifierFactory.parameter("input", TypeFactory.keyword("any")),
Guardian.parameter(props.init),
Guardian.parameter({
context: props.context,
init: props.init,
}),
],
props.config.guard
? ts.factory.createTypePredicateNode(
Expand Down Expand Up @@ -417,13 +420,16 @@ export namespace AssertProgrammer {

export namespace Guardian {
export const identifier = () => ts.factory.createIdentifier("errorFactory");
export const parameter = (init: ts.Expression | undefined) =>
export const parameter = (props: {
context: ITypiaContext;
init: ts.Expression | undefined;
}) =>
IdentifierFactory.parameter(
"errorFactory",
type(),
init ?? ts.factory.createToken(ts.SyntaxKind.QuestionToken),
type(props.context),
props.init ?? ts.factory.createToken(ts.SyntaxKind.QuestionToken),
);
export const type = () =>
export const type = (context: ITypiaContext) =>
ts.factory.createFunctionTypeNode(
undefined,
[
Expand All @@ -432,18 +438,10 @@ export namespace AssertProgrammer {
undefined,
ts.factory.createIdentifier("p"),
undefined,
ts.factory.createImportTypeNode(
ts.factory.createLiteralTypeNode(
ts.factory.createStringLiteral("typia"),
),
undefined,
ts.factory.createQualifiedName(
ts.factory.createIdentifier("TypeGuardError"),
ts.factory.createIdentifier("IProps"),
),
undefined,
false,
),
context.importer.type({
file: "typia",
name: "TypeGuardError.IProps",
}),
undefined,
),
],
Expand Down
175 changes: 125 additions & 50 deletions src/programmers/ImportProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,99 @@ import { MapUtil } from "../utils/MapUtil";
export class ImportProgrammer {
private readonly assets_: Map<string, IAsset> = new Map();

public constructor() {}
/* -----------------------------------------------------------
ENROLLMENTS
----------------------------------------------------------- */
public default(props: ImportProgrammer.IDefault): ts.Identifier {
const asset: IAsset = this.take(props.file);
asset.default ??= props;
asset.default.type ||= props.type;
return ts.factory.createIdentifier(asset.default.name);
}

public instance(props: ImportProgrammer.IInstance): ts.Identifier {
const alias: string = props.alias ?? props.name;
const asset: IAsset = this.take(props.file);
const instance: ImportProgrammer.IInstance = MapUtil.take(
asset.instances,
alias,
() => props,
);
instance.type ||= props.type;
return ts.factory.createIdentifier(alias);
}

public namespace(props: { file: string; name: string }): ts.Identifier {
public namespace(props: ImportProgrammer.INamespace): ts.Identifier {
const asset: IAsset = this.take(props.file);
asset.namespace ??= props.name;
return ts.factory.createIdentifier(asset.namespace);
asset.namespace ??= props;
asset.namespace.type ||= props.type;
return ts.factory.createIdentifier(asset.namespace.name);
}

public type(props: {
file: string;
name: string | ts.EntityName;
arguments?: ts.TypeNode[];
}): ts.ImportTypeNode {
return ts.factory.createImportTypeNode(
ts.factory.createLiteralTypeNode(
ts.factory.createStringLiteral(props.file),
),
undefined,
typeof props.name === "string"
? ts.factory.createIdentifier(props.name)
: props.name,
props.arguments,
);
}

/**
* @internal
*/
public internal(name: string): ts.PropertyAccessExpression {
if (name.startsWith("$") === false) name = `$${name}`;
this.namespace({
file: `typia/lib/internal/${name}.js`,
name: alias(name),
type: false,
});
return ts.factory.createPropertyAccessExpression(
this.namespace({
file: `typia/lib/internal/${name}.js`,
name: alias(name),
type: false,
}),
name,
);
}

/**
* @internal
*/
public getInternalText(name: string): string {
if (name.startsWith("$") === false) name = `$${name}`;
const asset: IAsset | undefined = this.take(
`typia/lib/internal/${name}.js`,
);
if (!asset?.namespace) throw new Error(`Internal asset not found: ${name}`);
return `${asset.namespace.name}.${name}`;
}

/**
* @internal
*/
private take(file: string): IAsset {
return MapUtil.take(this.assets_, file, () => ({
file,
default: null,
namespace: null,
instances: new Map(),
}));
}

/* -----------------------------------------------------------
PROGRAM STATEMENTS
----------------------------------------------------------- */
public toStatements(): ts.ImportDeclaration[] {
const statements: ts.ImportDeclaration[] = [];
for (const asset of this.assets_.values()) {
Expand All @@ -24,28 +109,38 @@ export class ImportProgrammer {
false,
undefined,
ts.factory.createNamespaceImport(
ts.factory.createIdentifier(asset.namespace),
ts.factory.createIdentifier(asset.namespace.name),
),
),
ts.factory.createStringLiteral(asset.file),
),
);
if (asset.default !== null || asset.instances.size > 0)
if (asset.default !== null)
statements.push(
ts.factory.createImportDeclaration(
undefined,
ts.factory.createImportClause(
asset.default.type,
ts.factory.createIdentifier(asset.default.name),
undefined,
),
ts.factory.createStringLiteral(asset.file),
),
);
if (asset.instances.size > 0)
statements.push(
ts.factory.createImportDeclaration(
undefined,
ts.factory.createImportClause(
false,
asset.default !== null
? ts.factory.createIdentifier(asset.default)
: undefined,
undefined,
asset.instances.size > 0
? ts.factory.createNamedImports(
[...asset.instances].map((name) =>
[...asset.instances.values()].map((ins) =>
ts.factory.createImportSpecifier(
false,
ins.type,
undefined,
ts.factory.createIdentifier(name),
ts.factory.createIdentifier(ins.alias ?? ins.name),
),
),
)
Expand All @@ -58,52 +153,32 @@ export class ImportProgrammer {
}
return statements;
}
}

/**
* @internal
*/
public internal(name: string): ts.PropertyAccessExpression {
if (name.startsWith("$") === false) name = `$${name}`;
return ts.factory.createPropertyAccessExpression(
this.namespace({
file: `typia/lib/internal/${name}.js`,
name: alias(name),
}),
name,
);
export namespace ImportProgrammer {
export interface IDefault {
file: string;
name: string;
type: boolean;
}

/**
* @internal
*/
public getInternalText(name: string): string {
if (name.startsWith("$") === false) name = `$${name}`;
const asset: IAsset | undefined = this.take(
`typia/lib/internal/${name}.js`,
);
if (asset === undefined)
throw new Error(`Internal asset not found: ${name}`);
return `${asset.namespace}.${name}`;
export interface IInstance {
file: string;
name: string;
alias: string | null;
type: boolean;
}

/**
* @internal
*/
private take(file: string): IAsset {
return MapUtil.take(this.assets_, file, () => ({
file,
default: null,
namespace: null,
instances: new Set(),
}));
export interface INamespace {
file: string;
name: string;
type: boolean;
}
}

interface IAsset {
file: string;
default: string | null;
namespace: string | null;
instances: Set<string>;
default: ImportProgrammer.IDefault | null;
namespace: ImportProgrammer.INamespace | null;
instances: Map<string, ImportProgrammer.IInstance>;
}

const alias = (str: string) => `__${str}`;
Loading

0 comments on commit b890b9c

Please sign in to comment.