import * as llvm from "llvm-node" ; import * as ts from "typescript" ; import { emitClassDeclaration } from "./codegen/declaration" ; import { getOrEmitFunctionForCall } from "./codegen/expression" ; import { LLVMGenerator } from "./codegen/generator" ; import { error } from "./diagnostics" ; import { getTypeArguments , isProperty } from "./tsc-utils" ; export function replaceExtension ( filePath , extension ) { return filePath . replace ( /\.[^\.\/\\]+$/ , "" ) + extension ; } export function keepInsertionPoint < T > ( builder , emit ) { const backup = builder . getInsertBlock ( ) ; const result = emit ( ) ; builder . setInsertionPoint ( backup ) ; return result ; } export function createLLVMFunction ( returnType , parameterTypes , name , module ) { const type = llvm . FunctionType . get ( returnType , parameterTypes , false ) ; const linkage = llvm . LinkageTypes . ExternalLinkage ; return llvm . Function . create ( type , linkage , name , module ) ; } export function isValueType ( type ) { return type . isDoubleTy ( ) || type . isIntegerTy ( ) || type . isPointerTy ( ) || isLLVMString ( type ) ; } export function isLLVMString ( type ) { return type . isStructTy ( ) && type . name === "string" ; } export function getStoredProperties ( type , checker ) { return checker . getPropertiesOfType ( type ) . filter ( isProperty ) ; } export function getMethod ( type , name , argumentTypes , generator ) { const typeDeclaration = type . symbol . valueDeclaration ; if ( ! ts . isClassDeclaration ( typeDeclaration ) ) { return error ( "Cannot get method of non-class type" ) ; } emitClassDeclaration ( typeDeclaration , getTypeArguments ( type ) , generator . symbolTable . globalScope , generator ) ; let declaration ; switch ( name ) { case "constructor" : declaration = typeDeclaration . members . find ( ts . isConstructorDeclaration ) ; break ; case "subscript" : declaration = typeDeclaration . members . find ( ts . isIndexSignatureDeclaration ) ; break ; default : const propertySymbol = generator . checker . getPropertyOfType ( type , name ) ! ; declaration = propertySymbol . valueDeclaration ; break ; } if ( ! declaration ) { return error ( "Member declaration not found" ) ; } return getOrEmitFunctionForCall ( declaration , type , argumentTypes , generator ) ; }