UNPKG

@specs-feup/lara

Version:

A js port of the popular framework for building source-to-source compilers

250 lines (208 loc) 7.3 kB
////////////////////////////////////////////////////// // This file is generated by build-LaraJoinPoint.js // ////////////////////////////////////////////////////// /* eslint-disable @typescript-eslint/no-explicit-any */ import JavaTypes from "./lara/util/JavaTypes.js"; /** * Type for type equality assertion. If T is equal to U, return Y, otherwise return N. * Source: https://github.com/Microsoft/TypeScript/issues/27024#issuecomment-421529650 * @example * type A = Equals<string, string, "Y", "N">; // "Y" * type B = Equals<string, number, "Y", "N">; // "N" */ type Equals<T, U, Y = unknown, N = never> = (<G>() => G extends T ? 1 : 2) extends (<G>() => G extends U ? 1 : 2) ? Y : N; type DefaultAttributeHelper< T extends typeof LaraJoinPoint, DefaultAttributeMap, PrivateMapper, > = { [K in keyof DefaultAttributeMap]: K extends keyof PrivateMapper ? Equals<T, PrivateMapper[K], DefaultAttributeMap[K], never> : never; }[keyof DefaultAttributeMap]; // Extract the type A from A | undefined type ExtractedType<T> = T extends undefined ? never : T; export type DefaultAttribute<T extends typeof LaraJoinPoint> = DefaultAttributeHelper< T, ExtractedType<T["_defaultAttributeInfo"]["map"]>, ExtractedType<T["_defaultAttributeInfo"]["type"]> >; type NameFromWrapperClassHelper<T extends typeof LaraJoinPoint, U> = { [K in keyof U]: Equals<T, U[K], K, never>; }[keyof U]; export type NameFromWrapperClass<T extends typeof LaraJoinPoint> = NameFromWrapperClassHelper< T, ExtractedType<T["_defaultAttributeInfo"]["jpMapper"]> >; export class LaraJoinPoint { /** * @internal */ static readonly _defaultAttributeInfo: {readonly map?: any, readonly name: string | null, readonly type?: any, readonly jpMapper?: any} = { name: null, }; /** * @internal */ _javaObject!: any; constructor(obj: any) { this._javaObject = obj; } get dump(): string { return wrapJoinPoint(this._javaObject.getDump()) } get joinPointType(): string { return wrapJoinPoint(this._javaObject.getJoinPointType()) } get node(): object { return (this._javaObject.getNode()) } get self(): LaraJoinPoint { return wrapJoinPoint(this._javaObject.getSelf()) } get super(): LaraJoinPoint { return wrapJoinPoint(this._javaObject.getSuper()) } get children(): LaraJoinPoint[] { return wrapJoinPoint(this._javaObject.getChildren()) } get descendants(): LaraJoinPoint[] { return wrapJoinPoint(this._javaObject.getDescendants()) } get scopeNodes(): LaraJoinPoint[] { return wrapJoinPoint(this._javaObject.getScopeNodes()) } insert(position: "before" | "after" | "replace", code: string): LaraJoinPoint[]; insert(position: "before" | "after" | "replace", joinpoint: LaraJoinPoint): LaraJoinPoint[]; insert(p1: "before" | "after" | "replace", p2: string | LaraJoinPoint): LaraJoinPoint[] { return wrapJoinPoint(this._javaObject.insert(unwrapJoinPoint(p1), unwrapJoinPoint(p2))); } toString(): string { return wrapJoinPoint(this._javaObject.toString()); } equals(jp: LaraJoinPoint): boolean { return wrapJoinPoint(this._javaObject.equals(unwrapJoinPoint(jp))); } instanceOf(name: string): boolean; instanceOf(names: string[]): boolean; instanceOf(p1: string | string[]): boolean { return wrapJoinPoint(this._javaObject.instanceOf(unwrapJoinPoint(p1))); } } /** * Converts Java join point objects to TypeScript objects. */ export interface JoinpointMapper { toJpClass(jpTypename: string): typeof LaraJoinPoint | undefined; toJpInstance(jpTypename: string, javaJp: any): LaraJoinPoint | undefined; fromJpClass(jpType: typeof LaraJoinPoint): string | undefined; } const JoinpointMappers: JoinpointMapper[] = []; /** * This function is for internal use only. DO NOT USE IT! */ export function clearJoinpointMappers(): void { JoinpointMappers.length = 0; } /** * This function is for internal use only. DO NOT USE IT! */ export function getJoinpointMappers(): JoinpointMapper[] { return JoinpointMappers; } /** * For mappers based on objects */ export type JoinpointMapperType = { [key: string]: typeof LaraJoinPoint }; export function registerJoinpointMapper(mapper: JoinpointMapperType): void { // Create mapper from object const jpMapper: JoinpointMapper = { toJpClass(jpTypename: string) { return mapper[jpTypename]; }, toJpInstance(jpTypename: string, javaJp: any) { const jpClass = this.toJpClass(jpTypename); if (jpClass) { return new jpClass(javaJp); } return undefined; }, fromJpClass(jpType: typeof LaraJoinPoint) { return Object.keys(mapper).find((key) => mapper[key] === jpType); }, }; JoinpointMappers.push(jpMapper); } /** * For mappers based on functions */ export type JoinpointMapperFunction = ( jpTypename: string ) => typeof LaraJoinPoint | undefined; export function registerJoinpointMapperFunction( mapper: JoinpointMapperFunction ): void { // Create mapper from function const jpMapper = { toJpClass(jpTypename: string): typeof LaraJoinPoint | undefined { return mapper(jpTypename); }, toJpInstance(jpTypename: string, javaJp: any): LaraJoinPoint | undefined { const jpClass = this.toJpClass(jpTypename); if (jpClass) { return new jpClass(javaJp); } return undefined; }, // Not possible to implement with just a function fromJpClass(jpType: typeof LaraJoinPoint): string | undefined { return undefined; }, }; JoinpointMappers.push(jpMapper); } export function wrapJoinPoint(obj: any): any { if (JoinpointMappers.length === 0) { return obj; } if (obj === undefined) { return obj; } if (obj instanceof LaraJoinPoint) { return obj; } if (ArrayBuffer.isView(obj)) { return Array.from(obj as any).map(wrapJoinPoint); } if (typeof obj !== "object") { return obj; } if (Array.isArray(obj)) { return obj.map(wrapJoinPoint); } if (!JavaTypes.isJavaObject(obj)) { return obj; } if ( JavaTypes.instanceOf(obj, "pt.up.fe.specs.jsengine.node.UndefinedValue") ) { return undefined; } if ( JavaTypes.instanceOf(obj, "java.util.ArrayList") ) { return obj.toArray().map(wrapJoinPoint); } if ( JavaTypes.instanceOf(obj, "org.suikasoft.jOptions.DataStore.DataClass") && !JavaTypes.instanceOf(obj, "pt.up.fe.specs.clava.ClavaNode") ) { return obj; } if (obj.getClass().isEnum()) { return obj.toString(); } const isJavaJoinPoint = JavaTypes.JoinPoint.isJoinPoint(obj); if (!isJavaJoinPoint) { throw new Error( `Given Java join point is a Java class but is not a JoinPoint: ${obj.getClass()}` ); } const jpType: string = obj.getJoinPointType(); // Iterate in reverse order, to give priority to most recently added mappers for (let i = JoinpointMappers.length - 1; i >= 0; i--) { const mapper = JoinpointMappers[i]; const laraJp = mapper.toJpInstance(jpType, obj); if (laraJp) { return laraJp; } } throw new Error("No mapper found for join point type: " + jpType); } export function unwrapJoinPoint(obj: any): any { if (obj instanceof LaraJoinPoint) { return obj._javaObject; } if (Array.isArray(obj)) { return obj.map(unwrapJoinPoint); } return obj; }