@specs-feup/lara
Version:
A js port of the popular framework for building source-to-source compilers
142 lines • 6.72 kB
TypeScript
import { LaraJoinPoint, type NameFromWrapperClass, type DefaultAttribute } from "../LaraJoinPoint.js";
import { type JpFilterRules } from "../lara/util/JpFilter.js";
import JoinPoints from "./JoinPoints.js";
import TraversalType from "./TraversalType.js";
/**
* @internal Lara Common Language dirty hack. IMPROPER USAGE WILL BREAK THE WHOLE WEAVER!
*/
export declare function setSelectorJoinPointsClass(value?: typeof JoinPoints): void;
/**
* Extracts the return type of a method or the type of a property.
*/
type MemberType<T, key extends keyof T> = key extends never ? never : T[key] extends (...args: never) => infer R ? R : T[key];
type FilterFunction<T, Class> = (value: T, obj: Class) => boolean;
/**
* If the type is a string, expands it to a string or a RegExp.
*/
type StringExpander<T> = T extends string ? T | RegExp : T;
/**
* Expand type to allow for the basic type or a filter function accepting the basic type.
*/
type FilterFunctionExpander<T, Class> = T extends never ? never : T | FilterFunction<T, Class>;
/**
* Filter type for Joinpoints. It can be a string to filter using the default attribute of the Joinpoint, or an object where each key represents the name of a join point attribute, and the value the pattern that we will use to match against the attribute.
*/
type JpFilter<T> = {
-readonly [key in keyof T]?: StringExpander<FilterFunctionExpander<MemberType<T, key>, T>>;
};
type JpFilterFunction<T extends typeof LaraJoinPoint = typeof LaraJoinPoint> = (jp: InstanceType<T>) => boolean;
type AllowedDefaultAttributeTypes = StringExpander<string | number | bigint | boolean>;
export type Filter_WrapperVariant<T extends typeof LaraJoinPoint> = Omit<JpFilter<InstanceType<T>>, "toString"> | JpFilterFunction<T> | StringExpander<Extract<MemberType<InstanceType<T>, DefaultAttribute<T>>, AllowedDefaultAttributeTypes>>;
export type Filter_StringVariant = string | RegExp | ((str: string) => boolean) | JpFilterRules;
type SelectorChainAttributes<T extends typeof LaraJoinPoint> = {
_starting_point: LaraJoinPoint;
[key: string]: LaraJoinPoint | undefined;
} & {
[K in T as NameFromWrapperClass<K>]?: InstanceType<K>;
};
/**
* Selects join points according to their type and filter rules.
*
* @param $baseJp - starting join point for the search.
* @param inclusive - if true, $baseJp is included in the search.
*
*/
export default class Selector<JpT extends typeof LaraJoinPoint = typeof LaraJoinPoint, ChU extends typeof LaraJoinPoint = JpT> {
private $currentJps;
private lastName;
private $baseJp;
private addBaseJp;
private static STARTING_POINT;
constructor($baseJp?: LaraJoinPoint, inclusive?: boolean);
private static copyChain;
private static newJpChain;
private static parseWrapperFilter;
static convertStringFilterToWrapperFilter(joinPointType?: string, filter?: Filter_StringVariant): JpFilterFunction;
/**
* Generator function, allows Selector to be used in for..of statements.
*
* Returns join points iteratively, as if .get() was called.
*/
[Symbol.iterator](): Generator<InstanceType<JpT>, void, unknown>;
/**
* @param type - type of the join point to search.
* @param filter - filter rules for the search.
* @param traversal - AST traversal type, according to TraversalType
*
* @returns The results of the search.
*/
search<T extends typeof LaraJoinPoint>(type?: T, filter?: Filter_WrapperVariant<T>, traversal?: TraversalType): Selector<T, ChU | T>;
/**
* @deprecated Use the new search function variant that accepts a wrapper class.
*
* @param name - type of the join point to search.
* @param filter - filter rules for the search.
* @param traversal - AST traversal type, according to TraversalType
*
* @returns The results of the search.
*/
search(type?: string, filter?: Filter_StringVariant, traversal?: TraversalType): Selector;
/**
* Search in the children of the previously selected nodes.
*
* @param type - type of the join point to search.
* @param filter - filter rules for the search.
*
* @returns The results of the search.
*/
children<T extends typeof LaraJoinPoint>(type?: T, filter?: Filter_WrapperVariant<T>): Selector<T, ChU | T>;
/**
* Search in the children of the previously selected nodes.
*
* @deprecated Use the new children function variant that accepts a wrapper class.
*
* @param name - type of the join point to search.
* @param filter - filter rules for the search.
*
* @returns The results of the search.
*/
children(name?: string, filter?: Filter_StringVariant): Selector;
/**
* If previously select nodes have the concept of scope (e.g. if, loop), search the direct children of that scope.
*
* @param type - type of the join point to search.
* @param filter - filter rules for the search.
*
* @returns The results of the search.
*/
scope<T extends typeof LaraJoinPoint>(type?: T, filter?: Filter_WrapperVariant<T>): Selector<T, ChU | T>;
/**
* If previously select nodes have the concept of scope (e.g. if, loop), search the direct children of that scope.
*
* @deprecated Use the new scope function variant that accepts a wrapper class.
*
* @param name - type of the join point to search.
* @param filter - filter rules for the search.
*
* @returns The results of the search.
*/
scope(name?: string, filter?: Filter_StringVariant): Selector;
private searchPrivate;
private addJps;
/**
* @returns an array with the join points of the last chain (e.g., search("function").search("call").get() returns an array of $call join points).
*/
get(): InstanceType<JpT>[];
/**
* @returns An array of objects where each object maps the name of the join point to the corresponding join point that was searched, as well as creating mappings of the format \<joinpoint_name\>_\<repetition\>. For instance, if the search chain has the same name multiple times (e.g., search("loop").search("loop")), the chain object will have an attribute "loop" mapped to the last loop of the chain, an attribute "loop_0" mapped to the first loop of the chain and an attribute "loop_1" mapped to the second loop of the chain.
*/
chain(): SelectorChainAttributes<ChU>[];
/**
* Same as .first()
*
* @returns The first selected node
*/
getFirst(): InstanceType<JpT> | undefined;
/**
* @returns the first selected node
*/
first(): InstanceType<JpT> | undefined;
}
export {};
//# sourceMappingURL=Selector.d.ts.map