* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Language } from "../../Language.js"
import { IndentedPrinter } from "../../IndentedPrinter.js"
import { PrimitiveTypeList } from "../../peer-generation/PrimitiveType.js"
import * as idl from "../../idl/index.js"
import {
ExpressionStatement,
LanguageExpression,
LanguageStatement,
LanguageWriter,
Method,
PrintHint,
MethodModifier,
MethodSignature,
ReturnStatement
} from "../LanguageWriter.js"
import { ReferenceResolver } from "../../peer-generation/ReferenceResolver.js";
export class CLikeReturnStatement extends ReturnStatement {
constructor(public expression: LanguageExpression) { super(expression) }
write(writer: LanguageWriter): void {
writer.print(this.expression ? `return ${this.expression.asString()};` : "return;")
}
}
export class CLikeLoopStatement implements LanguageStatement {
constructor(private counter: string, private limit: string, private statement: LanguageStatement | undefined) {}
write(writer: LanguageWriter): void {
writer.print(`for (int ${this.counter} = 0; ${this.counter} < ${this.limit}; ${this.counter}++) {`)
if (this.statement) {
writer.pushIndent()
this.statement.write(writer)
writer.popIndent()
writer.print("}")
}
}
}
export class CLikeExpressionStatement extends ExpressionStatement {
constructor(public expression: LanguageExpression) { super(expression) }
write(writer: LanguageWriter): void {
const text = this.expression.asString()
if (text.length > 0) {
writer.print(`${this.expression.asString()};`)
}
}
}
class CLikeThrowErrorStatement implements LanguageStatement {
constructor(public exception: LanguageExpression) { }
write(writer: LanguageWriter): void {
writer.print(`throw ${this.exception.asString()};`)
}
}
export abstract class CLikeLanguageWriter extends LanguageWriter {
protected constructor(printer: IndentedPrinter, resolver: ReferenceResolver, language: Language) {
super(printer, resolver, language)
}
writeFunctionDeclaration(name: string, signature: MethodSignature): void {
this.writeMethodDeclaration(name, signature)
}
writeFunctionImplementation(name: string, signature: MethodSignature, op: (writer: this) => void): void {
this.writeMethodImplementation(new Method(name, signature), op)
}
makeThrowError(message: string | LanguageExpression): LanguageStatement {
if (typeof message === 'string')
message = this.makeString(`new Error("${message}")`)
return new CLikeThrowErrorStatement(message)
}
makeEquals(args: LanguageExpression[]): LanguageExpression {
return this.makeNaryOp("==", args)
}
writeMethodCall(receiver: string, method: string, params: string[], nullable = false): void {
this.printer.print(`${receiver}.${method}(${params.join(", ")});`)
}
writeMethodDeclaration(name: string, signature: MethodSignature, modifiers?: MethodModifier[]): void {
this.writeDeclaration(name, signature, modifiers, ";")
}
writeEnum(name: string, members: { name: string, stringId: string | undefined, numberId: number }[], options: { isExport: boolean, isDeclare?: boolean }, op: (writer: LanguageWriter) => void): void {
throw new Error("WriteEnum for C-family languages is not implemented")
}
writeMethodImplementation(method: Method, op: (writer: this) => void) {
this.writeDeclaration(method.name, method.signature, method.modifiers)
this.printer.print(`{`)
this.pushIndent()
op(this)
this.popIndent()
this.printer.print(`}`)
}
protected writeDeclaration(name: string, signature: MethodSignature, modifiers?: MethodModifier[], postfix?: string): void {
let prefix = modifiers
?.filter(it => this.supportedModifiers.includes(it))
.map(it => this.mapMethodModifier(it)).join(" ")
prefix = prefix ? prefix + " " : ""
this.print(`${prefix}${this.stringifyMethodReturnType(signature.returnType, signature.retHint())} ${name}(${signature.args.map((it, index) => `${this.stringifyMethodArgType(it, signature.argHint(index))} ${signature.argName(index)}`).join(", ")})${postfix ?? ""}`)
}
protected stringifyMethodReturnType(type: idl.IDLType, _?:PrintHint): string {
return this.getNodeName(type)
}
protected stringifyMethodArgType(type: idl.IDLType, _?:PrintHint): string {
return this.getNodeName(type)
}
}