@specs-feup/kadabra
Version:
A Java source-to-source compiler written in Typescript
130 lines (117 loc) • 3.52 kB
text/typescript
import { getAPINames, convertPrimitive } from "./Utils.js";
import { Class } from "../Joinpoints.js";
/**
* Create an atomic field in the given class. This aspect provides outputs such as get and set of the field
*/
export function NewAtomic(
$class: Class,
type: string,
fieldName: string,
initValue: string,
isStatic: boolean = true
) {
const convert = convertPrimitive(type);
let atomicType: string = "java.util.concurrent.atomic.Atomic";
let atomicTypeSimple: string = "Atomic";
if (convert.isPrimitive) {
atomicType += convert.wrapper;
atomicTypeSimple += convert.wrapper;
} else {
atomicType += "Reference<" + type + ">";
atomicTypeSimple += "Reference<>";
}
const init = initValue || "";
const mods = ["private"];
if (isStatic) {
mods.push("static");
}
const field = $class.newField(
mods,
atomicType,
fieldName,
"new " + atomicTypeSimple + "(" + init + ")"
);
const reference = field.declarator + "." + field.name;
const name = field.name;
const get = reference + ".get()";
const set = function (value: string) {
return reference + ".set(" + value + ")";
};
return { reference, name, field, get, set };
}
export function NewThread(
$class: Class,
threadName: string = "thread",
adaptCode: string = ""
) {
const names = getAPINames();
//Add thread field
const $thread = $class.newField(
["private", "static"],
names.thread,
threadName,
"new " + names.thread + "()"
);
//And the method to execute
const threadMethod = $class.newMethod(
["private", "static"],
"void",
threadName + "Method",
[],
[],
adaptCode
);
const name = $thread.name;
const reference = $thread.declarator + "." + name;
const start =
reference +
".start(" +
threadMethod.declarator +
"::" +
threadMethod.name +
")";
const stop = reference + ".terminate()";
const running = reference + ".isRunning()";
const setCode = (code: string) => {
threadMethod.body.replaceWith(code);
}; //allows adaptation code rewritting
return { start, stop, running, setCode, name, reference };
}
export function NewChannel(
keyTypeI: string,
valueTypeI: string,
$class: Class,
capacity: string,
channelName = "channel",
isStatic = true
) {
let convert = convertPrimitive(keyTypeI);
const keyType: string = convert.wrapper;
convert = convertPrimitive(valueTypeI);
const valueType: string = convert.wrapper;
const names = getAPINames();
const genericTuple = "<" + keyType + "," + valueType + ">";
const channelType = names.channel + genericTuple;
const productType = names.product + genericTuple;
const init = "KadabraChannel.newInstance(" + capacity + ")";
const mods = ["private"];
if (isStatic) {
mods.push("static");
}
const $channel = $class.newField(mods, channelType, channelName, init);
const reference = $channel.declarator + "." + $channel.name;
const offer = function (key: string, value: string) {
return reference + ".offer(" + key + "," + value + ")";
};
const take = reference + ".take()";
return {
$channel,
reference,
offer,
take,
keyType,
valueType,
channelType,
productType,
};
}