Browse Source

Improves decorator resolvers

main
Eric Amodio 2 years ago
parent
commit
efc360d5c1
4 changed files with 69 additions and 64 deletions
  1. +2
    -20
      src/system/decorators/gate.ts
  2. +2
    -22
      src/system/decorators/memoize.ts
  3. +63
    -0
      src/system/decorators/resolver.ts
  4. +2
    -22
      src/system/decorators/serialize.ts

+ 2
- 20
src/system/decorators/gate.ts View File

@ -1,22 +1,6 @@
'use strict';
import { Uri } from 'vscode';
import { is as isPromise } from '../promise';
const emptyStr = '';
function defaultResolver(...args: any[]): string {
if (args.length === 1) {
const arg0 = args[0];
if (arg0 == null) return emptyStr;
if (typeof arg0 === 'string') return arg0;
if (typeof arg0 === 'number' || typeof arg0 === 'boolean' || arg0 instanceof Error) return String(arg0);
if (arg0 instanceof Uri) return arg0.toString();
return JSON.stringify(arg0);
}
return JSON.stringify(args);
}
import { resolveProp } from './resolver';
export function gate<T extends (...arg: any) => any>(resolver?: (...args: Parameters<T>) => string) {
return (target: any, key: string, descriptor: PropertyDescriptor) => {
@ -31,9 +15,7 @@ export function gate any>(resolver?: (...args: Parame
const gateKey = `$gate$${key}`;
descriptor.value = function (this: any, ...args: any[]) {
const prop =
args.length === 0 ? gateKey : `${gateKey}$${(resolver ?? defaultResolver)(...(args as Parameters<T>))}`;
const prop = resolveProp(gateKey, resolver, ...(args as Parameters<T>));
if (!Object.prototype.hasOwnProperty.call(this, prop)) {
Object.defineProperty(this, prop, {
configurable: false,

+ 2
- 22
src/system/decorators/memoize.ts View File

@ -1,21 +1,5 @@
'use strict';
const emptyStr = '';
function defaultResolver(...args: any[]): string {
if (args.length === 1) {
const arg0 = args[0];
if (arg0 == null) return emptyStr;
if (typeof arg0 === 'string') return arg0;
if (typeof arg0 === 'number' || typeof arg0 === 'boolean') {
return String(arg0);
}
return JSON.stringify(arg0);
}
return JSON.stringify(args);
}
import { resolveProp } from './resolver';
export function memoize<T extends (...arg: any) => any>(resolver?: (...args: Parameters<T>) => string) {
return (target: any, key: string, descriptor: PropertyDescriptor & Record<string, any>) => {
@ -38,11 +22,7 @@ export function memoize any>(resolver?: (...args: Par
let result;
descriptor[fnKey] = function (...args: any[]) {
const prop =
fnKey === 'get' || args.length === 0
? memoizeKey
: `${memoizeKey}$${(resolver ?? defaultResolver)(...(args as Parameters<T>))}`;
const prop = resolveProp(memoizeKey, resolver, ...(args as Parameters<T>));
if (Object.prototype.hasOwnProperty.call(this, prop)) {
result = this[prop];

+ 63
- 0
src/system/decorators/resolver.ts View File

@ -0,0 +1,63 @@
'use strict';
import { Uri } from 'vscode';
function replacer(key: string, value: any): any {
if (key === '') return value;
if (value == null) return value;
if (value instanceof Error) return String(value);
if (value instanceof Uri) {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if ('sha' in (value as any) && (value as any).sha) {
return `${(value as any).sha}:${value.toString()}`;
}
return value.toString();
}
return value;
}
export function defaultResolver(...args: any[]): string {
if (args.length === 0) return '';
if (args.length !== 1) {
return JSON.stringify(args, replacer);
}
const arg0 = args[0];
if (arg0 == null) return '';
if (typeof arg0 === 'string') return arg0;
if (typeof arg0 === 'number' || typeof arg0 === 'boolean' || arg0 instanceof Error) return String(arg0);
if (arg0 instanceof Uri) {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if ('sha' in (arg0 as any) && (arg0 as any).sha) {
return `${(arg0 as any).sha}:${arg0.toString()}`;
}
return arg0.toString();
}
return JSON.stringify(arg0, replacer);
}
export type Resolver<T extends (...arg: any) => any> = (...args: Parameters<T>) => string;
export function resolveProp<T extends (...arg: any) => any>(
key: string,
resolver: Resolver<T> | undefined,
...args: Parameters<T>
) {
if (args.length === 0) return key;
let resolved;
if (resolver != null) {
try {
resolved = resolver(...args);
} catch {
debugger;
resolved = defaultResolver(...(args as any));
}
} else {
resolved = defaultResolver(...(args as any));
}
return `${key}$${resolved}`;
}

+ 2
- 22
src/system/decorators/serialize.ts View File

@ -1,21 +1,5 @@
'use strict';
import { Uri } from 'vscode';
const emptyStr = '';
function defaultResolver(...args: any[]): string {
if (args.length === 1) {
const arg0 = args[0];
if (arg0 === undefined) return emptyStr;
if (typeof arg0 === 'string') return arg0;
if (typeof arg0 === 'number' || typeof arg0 === 'boolean' || arg0 instanceof Error) return String(arg0);
if (arg0 instanceof Uri) return arg0.toString();
return JSON.stringify(arg0);
}
return JSON.stringify(args);
}
import { resolveProp } from './resolver';
export function serialize<T extends (...arg: any) => any>(
resolver?: (...args: Parameters<T>) => string,
@ -32,11 +16,7 @@ export function serialize any>(
const serializeKey = `$serialize$${key}`;
descriptor.value = function (this: any, ...args: any[]) {
const prop =
args.length === 0
? serializeKey
: `${serializeKey}$${(resolver ?? defaultResolver)(...(args as Parameters<T>))}`;
const prop = resolveProp(serializeKey, resolver, ...(args as Parameters<T>));
if (!Object.prototype.hasOwnProperty.call(this, prop)) {
Object.defineProperty(this, prop, {
configurable: false,

Loading…
Cancel
Save