UNPKG

@specs-feup/clava

Version:

A C/C++ source-to-source compiler written in Typescript

142 lines (126 loc) 4.57 kB
import { Expression, Joinpoint, ParenType, PointerType, Scope, Statement, Type, VariableArrayType, Varref, } from "../Joinpoints.js"; import ClavaJoinPoints from "./ClavaJoinPoints.js"; import ClavaJavaTypes from "./ClavaJavaTypes.js"; /** * Utility methods related with the type join points. * */ export default class ClavaType { /** * @param type - The type to visit * @param exprFunction - A function that receives an $expr join point * * @returns The $type after applying the given exprFunction to its $expr nodes. If any of the fields of the type is visited, a copy of the type is returned. */ static visitExprInTypeCopy( $type: Type, exprFunction: (expr: Expression) => void ): Type { if ($type instanceof PointerType) { const $typeCopy = $type.copy() as PointerType; $typeCopy.setPointee( ClavaType.visitExprInTypeCopy($typeCopy.pointee, exprFunction) ); return $typeCopy; } if ($type instanceof ParenType) { const $typeCopy = $type.copy() as ParenType; $typeCopy.setDesugar( ClavaType.visitExprInTypeCopy($typeCopy.desugar, exprFunction) ); return $typeCopy; } if ($type instanceof VariableArrayType) { const $typeCopy = $type.copy() as VariableArrayType; $typeCopy.setSizeExpr($typeCopy.sizeExpr.copy() as Expression); exprFunction($typeCopy.sizeExpr); return $typeCopy; } return $type; } /** * @param type - A type join point that will be visited looking for $expr join points. Any visited nodes in the type (e.g., desugar) will be copied, so that the returned varrefs can be safely modified. * @param varrefs - An array (possibly empty) where the $varref join points found in the given type will be stored * * @returns A copy of the given $type, to which the varrefs refer to */ static getVarrefsInTypeCopy($type: Type, varrefs: Varref[]) { const exprFunction = function ($expr: Expression) { for (const $varref of $expr.getDescendantsAndSelf("varref") as Varref[]) { varrefs.push($varref); } }; return ClavaType.visitExprInTypeCopy($type, exprFunction); } /** * Makes sure the given parameter is an expression join point. * * @param $expression - If a string, returns a literal expression with the code of the string. Otherwise, returns $expression * @param isOptional - If false and $expression is undefined, throws an exception. Otherwise, returns undefined if $expression is undefined. */ static asExpression( $expression: Expression | undefined, isOptional = false ): Expression | undefined { if ($expression === undefined) { if (isOptional) { return undefined; } else { throw "ClavaType.asExpression: $expression is undefined. If this is allowed, set 'isOptional' to true."; } } return $expression; } /** * Makes sure the given parameter is a statement join point. * * @param code - If a string, returns a literal statement with the code of the string. Otherwise, tries to transform the given node to a $statement * @param isOptional - If false and code is undefined, throws an exception. Otherwise, returns undefined if code is undefined. */ static asStatement( code: Joinpoint | undefined, isOptional = false ): Statement | undefined { if (code === undefined) { if (isOptional) { return undefined; } else { throw "ClavaType.asStatement: code is undefined. If this is allowed, set 'isOptional' to true."; } } const newStmtNode = ClavaJavaTypes.ClavaNodes.toStmt(code.node); return ClavaJoinPoints.toJoinPoint(newStmtNode) as Statement; } /** * Makes sure the given parameter is a type join point. * * @param $type - If a string, returns a literal type with the code of the string. Otherwise, returns $type * * @deprecated This method does not do anything, it is only kept for compatibility with the old API */ static asType($type: Type): Type { return $type; } /** * Makes sure the given parameter is a scope join point. * * @param code - If a string, returns a literal statement with the code of the string. Otherwise, returns $statement */ static asScope(code: Joinpoint | undefined): Scope { const $newStmt = ClavaType.asStatement(code); const newScopeNode = ClavaJavaTypes.ClavaNodes.toCompoundStmt( $newStmt?.node ); return ClavaJoinPoints.toJoinPoint(newScopeNode) as Scope; } }