///////////////////////////////////////////////////
// This file is generated by build-interfaces.js //
///////////////////////////////////////////////////

import {
  LaraJoinPoint,
  registerJoinpointMapper,
  wrapJoinPoint,
  unwrapJoinPoint,
} from "@specs-feup/lara/api/LaraJoinPoint.js";

type PrivateMapper = {
  "Joinpoint": typeof Joinpoint,
  "Expr": typeof Expr,
  "FileJp": typeof FileJp,
  "Literal": typeof Literal,
  "LoopControl": typeof LoopControl,
  "NameValue": typeof NameValue,
  "OmpClause": typeof OmpClause,
  "OmpDataSharingClause": typeof OmpDataSharingClause,
  "OmpOrderedClause": typeof OmpOrderedClause,
  "OmpReductionClause": typeof OmpReductionClause,
  "Program": typeof Program,
  "ProgramUnit": typeof ProgramUnit,
  "RangeLoopControl": typeof RangeLoopControl,
  "RealLiteral": typeof RealLiteral,
  "Statement": typeof Statement,
  "StatementBlock": typeof StatementBlock,
  "StringLiteral": typeof StringLiteral,
  "Subroutine": typeof Subroutine,
  "UseStatement": typeof UseStatement,
  "BinaryOperator": typeof BinaryOperator,
  "Designator": typeof Designator,
  "ExecutableStatement": typeof ExecutableStatement,
  "Execution": typeof Execution,
  "IntLiteral": typeof IntLiteral,
  "MainProgram": typeof MainProgram,
  "OmpConstruct": typeof OmpConstruct,
  "OmpLoopConstruct": typeof OmpLoopConstruct,
  "Specification": typeof Specification,
  "ActionStatement": typeof ActionStatement,
  "AssignmentStatement": typeof AssignmentStatement,
  "CompilerDirective": typeof CompilerDirective,
  "DataRef": typeof DataRef,
  "DoStatement": typeof DoStatement,
  "OmpBlockConstruct": typeof OmpBlockConstruct,
  "ArraySubscriptExpr": typeof ArraySubscriptExpr,
};

type DefaultAttributeMap = {
  FileJp: "name",
}

export class Joinpoint extends LaraJoinPoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  /**
   * Returns an array with the children of the node
   */
  get children(): Joinpoint[] { return wrapJoinPoint(this._javaObject.getChildren()) }
  /**
   * String with the code represented by this node
   */
  get code(): string { return wrapJoinPoint(this._javaObject.getCode()) }
  /**
   * Returns an array with the descendants of the node
   */
  get descendants(): Joinpoint[] { return wrapJoinPoint(this._javaObject.getDescendants()) }
  /**
   * Returns the index of this join point in relation to its parent
   */
  get indexOfSelf(): number { return wrapJoinPoint(this._javaObject.getIndexOfSelf()) }
  /**
   * Returns the node that came before this node, or undefined if there is none
   */
  get leftJp(): Joinpoint { return wrapJoinPoint(this._javaObject.getLeftJp()) }
  /**
   * Returns the parent node in the AST, or undefined if it is the root node
   */
  get parent(): Joinpoint { return wrapJoinPoint(this._javaObject.getParent()) }
  /**
   * Returns the node that comes after this node, or undefined if there is none
   */
  get rightJp(): Joinpoint { return wrapJoinPoint(this._javaObject.getRightJp()) }
  /**
   * Returns the 'program' join point
   */
  get root(): Program { return wrapJoinPoint(this._javaObject.getRoot()) }
  /**
   * The nodes of the scope of the current join point. If this node has a body (e.g., loop, function) corresponds to the children of the body. Otherwise, returns an empty array
   */
  get scopeNodes(): Joinpoint[] { return wrapJoinPoint(this._javaObject.getScopeNodes()) }
  /**
   * True if the given node is a descendant of this node
   */
  contains(jp: Joinpoint): boolean { return wrapJoinPoint(this._javaObject.contains(unwrapJoinPoint(jp))); }
  /**
   * Looks for an ancestor joinpoint name, walking back on the AST
   */
  getAncestor(type: string): Joinpoint { return wrapJoinPoint(this._javaObject.getAncestor(unwrapJoinPoint(type))); }
  /**
   * Removes node associated to the joinpoint from the AST
   */
  detach(): Joinpoint { return wrapJoinPoint(this._javaObject.detach()); }
  /**
   * Replaces this node with the given node
   */
  replaceWith(node: Joinpoint): Joinpoint { return wrapJoinPoint(this._javaObject.replaceWith(unwrapJoinPoint(node))); }
}

  /**
   * Represents an expression
   */
export class Expr extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents a source file (e.g., .f90)
   */
export class FileJp extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: "name",
  };
  /**
   * The name of the folder
   */
  get foldername(): string { return wrapJoinPoint(this._javaObject.getFoldername()) }
  /**
   * The name of the file
   */
  get name(): string { return wrapJoinPoint(this._javaObject.getName()) }
}

  /**
   * Represents a literal
   */
export class Literal extends Expr {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get literal(): string { return wrapJoinPoint(this._javaObject.getLiteral()) }
}

  /**
   * Represents the loop control structure, with specialized subclasses for different loop kinds
   */
export class LoopControl extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents a name/value pair in a compiler directive
   */
export class NameValue extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get name(): string { return wrapJoinPoint(this._javaObject.getName()) }
}

  /**
   * Represents an OpenMP clause
   */
export class OmpClause extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents an OpenMP datasharing clause (public, private, ...)
   */
export class OmpDataSharingClause extends OmpClause {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class OmpOrderedClause extends OmpClause {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class OmpReductionClause extends OmpClause {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents the complete program and is the top-most join point in the hierarchy
   */
export class Program extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class ProgramUnit extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  /**
   * Returns the unit's specification part
   */
  get specification(): Specification { return wrapJoinPoint(this._javaObject.getSpecification()) }
}

export class RangeLoopControl extends LoopControl {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get lower(): Expr { return wrapJoinPoint(this._javaObject.getLower()) }
  get upper(): Expr { return wrapJoinPoint(this._javaObject.getUpper()) }
  get var(): DataRef { return wrapJoinPoint(this._javaObject.getVar()) }
}

export class RealLiteral extends Literal {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents a Fortran statement
   */
export class Statement extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get isFirst(): boolean { return wrapJoinPoint(this._javaObject.getIsFirst()) }
  get isLast(): boolean { return wrapJoinPoint(this._javaObject.getIsLast()) }
}

export class StatementBlock extends Joinpoint {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get stmts(): Statement[] { return wrapJoinPoint(this._javaObject.getStmts()) }
}

export class StringLiteral extends Literal {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class Subroutine extends ProgramUnit {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class UseStatement extends Statement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get moduleName(): string { return wrapJoinPoint(this._javaObject.getModuleName()) }
}

  /**
   * Represents a binary operation
   */
export class BinaryOperator extends Expr {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get kind(): "add" | "sub" | "mul" | "div" | "gt" | "ge" | "lt" | "le" | "eq" | "ne" { return wrapJoinPoint(this._javaObject.getKind()) }
  get left(): Expr { return wrapJoinPoint(this._javaObject.getLeft()) }
  set left(value: Expr) { this._javaObject.setLeft(unwrapJoinPoint(value)); }
  get right(): Expr { return wrapJoinPoint(this._javaObject.getRight()) }
  set right(value: Expr) { this._javaObject.setRight(unwrapJoinPoint(value)); }
  /**
   * Sets the left-hand side of the operation
   */
  setLeft(lhs: Expr): void { return wrapJoinPoint(this._javaObject.setLeft(unwrapJoinPoint(lhs))); }
  /**
   * Sets the right-hand side of the operation
   */
  setRight(rhs: Expr): void { return wrapJoinPoint(this._javaObject.setRight(unwrapJoinPoint(rhs))); }
}

  /**
   * Represents a designator
   */
export class Designator extends Expr {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents an executable statement
   */
export class ExecutableStatement extends Statement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class Execution extends StatementBlock {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get executableStmts(): ExecutableStatement[] { return wrapJoinPoint(this._javaObject.getExecutableStmts()) }
  insertBegin(stmt: ExecutableStatement): void { return wrapJoinPoint(this._javaObject.insertBegin(unwrapJoinPoint(stmt))); }
  insertEnd(stmt: ExecutableStatement): void { return wrapJoinPoint(this._javaObject.insertEnd(unwrapJoinPoint(stmt))); }
}

export class IntLiteral extends Literal {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

export class MainProgram extends ProgramUnit {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents a generic OpenMP construct
   */
export class OmpConstruct extends ExecutableStatement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get clauses(): OmpClause[] { return wrapJoinPoint(this._javaObject.getClauses()) }
  set clauses(value: OmpClause[]) { this._javaObject.setClauses(unwrapJoinPoint(value)); }
  /**
   * Sets the construct's clauses
   */
  setClauses(clauses: OmpClause[]): void { return wrapJoinPoint(this._javaObject.setClauses(unwrapJoinPoint(clauses))); }
  setDirective(directive: string): void { return wrapJoinPoint(this._javaObject.setDirective(unwrapJoinPoint(directive))); }
}

  /**
   * Represents an OpenMP loop construct (such as do or do parallel)
   */
export class OmpLoopConstruct extends OmpConstruct {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  setLoop(loop: DoStatement): void { return wrapJoinPoint(this._javaObject.setLoop(unwrapJoinPoint(loop))); }
}

export class Specification extends StatementBlock {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  /**
   * Adds a UseStmt to a specification part. The statement is inserted at the beginning.
   */
  addUseStmt(stmt: UseStatement): void { return wrapJoinPoint(this._javaObject.addUseStmt(unwrapJoinPoint(stmt))); }
}

  /**
   * Represents an action statement
   */
export class ActionStatement extends ExecutableStatement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
}

  /**
   * Represents an assignment statement
   */
export class AssignmentStatement extends ActionStatement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get expr(): Expr { return wrapJoinPoint(this._javaObject.getExpr()) }
  get variable(): DataRef { return wrapJoinPoint(this._javaObject.getVariable()) }
}

export class CompilerDirective extends ExecutableStatement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  /**
   * Returns the directive's contents as a string
   */
  get directiveString(): string { return wrapJoinPoint(this._javaObject.getDirectiveString()) }
  get pairs(): NameValue[] { return wrapJoinPoint(this._javaObject.getPairs()) }
}

  /**
   * Represents a data reference
   */
export class DataRef extends Designator {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get name(): string { return wrapJoinPoint(this._javaObject.getName()) }
}

  /**
   * Represents a do loop
   */
export class DoStatement extends ExecutableStatement {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get body(): Execution { return wrapJoinPoint(this._javaObject.getBody()) }
  get control(): LoopControl { return wrapJoinPoint(this._javaObject.getControl()) }
}

  /**
   * Represents an OpenMP block construct (such as parallel or task)
   */
export class OmpBlockConstruct extends OmpConstruct {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  setBody(body: Execution): void { return wrapJoinPoint(this._javaObject.setBody(unwrapJoinPoint(body))); }
}

  /**
   * Represents an access to one (or several) elements of an array
   */
export class ArraySubscriptExpr extends DataRef {
  /**
   * @internal
   */
  static readonly _defaultAttributeInfo: {readonly map?: DefaultAttributeMap, readonly name: string | null, readonly type?: PrivateMapper, readonly jpMapper?: typeof JoinpointMapper} = {
    name: null,
  };
  get subscripts(): Expr[] { return wrapJoinPoint(this._javaObject.getSubscripts()) }
  get var(): DataRef { return wrapJoinPoint(this._javaObject.getVar()) }
}

const JoinpointMapper = {
  joinpoint: Joinpoint,
  expr: Expr,
  file: FileJp,
  literal: Literal,
  loopControl: LoopControl,
  nameValue: NameValue,
  ompClause: OmpClause,
  ompDataSharingClause: OmpDataSharingClause,
  ompOrderedClause: OmpOrderedClause,
  ompReductionClause: OmpReductionClause,
  program: Program,
  programUnit: ProgramUnit,
  rangeLoopControl: RangeLoopControl,
  realLiteral: RealLiteral,
  statement: Statement,
  statementBlock: StatementBlock,
  stringLiteral: StringLiteral,
  subroutine: Subroutine,
  useStatement: UseStatement,
  binaryOperator: BinaryOperator,
  designator: Designator,
  executableStatement: ExecutableStatement,
  execution: Execution,
  intLiteral: IntLiteral,
  mainProgram: MainProgram,
  ompConstruct: OmpConstruct,
  ompLoopConstruct: OmpLoopConstruct,
  specification: Specification,
  actionStatement: ActionStatement,
  assignmentStatement: AssignmentStatement,
  compilerDirective: CompilerDirective,
  dataRef: DataRef,
  doStatement: DoStatement,
  ompBlockConstruct: OmpBlockConstruct,
  arraySubscriptExpr: ArraySubscriptExpr,
};

let registered = false;
if (!registered) {
  registerJoinpointMapper(JoinpointMapper);
  registered = true;
}

