UNPKG

@specs-feup/alpakka

Version:

Alpakka is a [LARA Framework](https://github.com/specs-feup/lara-framework) source-to-source compiler for Android's [smali](https://github.com/google/smali) syntax. It enables the analysis and transformation of Android apps through APK files.

135 lines (110 loc) 3.41 kB
import BaseGraph from "./BaseGraph.js"; import BaseNode from "./BaseNode.js"; import { EdgeBuilder, EdgeConstructor, EdgeTypeGuard } from "./Edge.js"; import Graph from "./Graph.js"; import cytoscape from "@specs-feup/lara/api/libs/cytoscape-3.26.0.js"; namespace BaseEdge { export class Class< D extends Data = Data, S extends ScratchData = ScratchData, > { #graph: BaseGraph.Class; #edge: cytoscape.EdgeSingular; // _d and _sd are a hack to force typescript to typecheck // D and S in .as() method. constructor( graph: BaseGraph.Class, edge: cytoscape.EdgeSingular, _d: D = {} as any, _sd: S = {} as any, ) { this.#graph = graph; this.#edge = edge; } get data(): D { return this.#edge.data(); } get scratchData(): S { return this.#edge.scratch(Graph.scratchNamespace); } get id(): string { return this.#edge.id(); } get source(): BaseNode.Class { return new BaseNode.Class(this.#graph, this.#edge.source()); } set source(node: BaseNode.Class) { this.#edge.move({ source: node.id }); } get target(): BaseNode.Class { return new BaseNode.Class(this.#graph, this.#edge.target()); } set target(node: BaseNode.Class) { this.#edge.move({ target: node.id }); } is<D2 extends Data, S2 extends ScratchData>( guard: EdgeTypeGuard<D2, S2>, ): this is BaseEdge.Class<D2, S2> { const data = this.data; const scratchData = this.scratchData; const result = guard.isDataCompatible(data) && guard.isScratchDataCompatible(scratchData); // Have typescript statically check that the types are correct // in the implementation of this function. result && (data satisfies D2) && (scratchData satisfies S2); return result; } as<E extends BaseEdge.Class<D, S>>(EdgeType: EdgeConstructor<D, S, E>): E { return new EdgeType(this.#graph, this.#edge, this.data, this.scratchData); } init<D2 extends BaseEdge.Data, S2 extends BaseEdge.ScratchData>( builder: EdgeBuilder<D2, S2>, ): BaseEdge.Class<D2, S2> { const initedData = builder.buildData(this.data); const initedScratchData = builder.buildScratchData(this.scratchData); this.#edge.data(initedData); this.#edge.scratch(Graph.scratchNamespace, initedScratchData); return new BaseEdge.Class( this.#graph, this.#edge, initedData, initedScratchData, ); } remove() { this.#edge.remove(); } get graph(): BaseGraph.Class { return this.#graph; } toCy(): cytoscape.EdgeSingular { return this.#edge; } } export class Builder implements EdgeBuilder<Data, ScratchData> { buildData(data: BaseEdge.Data): Data { return data; } buildScratchData(scratchData: BaseEdge.ScratchData): ScratchData { return scratchData; } } export const TypeGuard: EdgeTypeGuard<Data, ScratchData> = { isDataCompatible(data: BaseEdge.Data): data is Data { return true; }, isScratchDataCompatible( scratchData: BaseEdge.ScratchData, ): scratchData is ScratchData { return true; }, }; export interface Data { id: string; source: string; target: string; } export interface ScratchData {} } export default BaseEdge;