3 Commits

Author SHA1 Message Date
7bc9adebaa Fix some keyword errors 2024-01-18 19:08:44 +01:00
e15ce1f0a0 Fix more 2023-11-30 00:16:53 +01:00
f93755604a Improve esm compatability 2023-11-30 00:13:10 +01:00
10 changed files with 84 additions and 41 deletions

View File

@ -41,6 +41,10 @@ class TestSrvimpl : Example.TestServiceServer<int>
throw new Exception("This is a remote error :)");
}
public override Task<double> FunctionWithKeywords(double type, double static_, double event_, int ctx)
{
throw new NotImplementedException();
}
}
class CopyTransportS2 : Example.JRpcTransport

View File

@ -52,6 +52,8 @@ service TestService {
FunctionWithArrayAsParamAndReturn(values1: float[], values2: float[]): float[];
FunctionWithKeywords(type: float, static: float, event: float): float;
}
type Test2 {
@ -59,6 +61,12 @@ type Test2 {
age: int;
}
type TestKeywords {
type: float;
static: float;
event: float;
}
service SimpleTestService {
@Description("asdasdasd")
GetTest(name: string, age: int): Test2;

View File

@ -1,6 +1,6 @@
{
"name": "@hibas123/jrpcgen",
"version": "1.2.14",
"version": "1.2.17",
"main": "lib/index.js",
"license": "MIT",
"packageManager": "yarn@3.1.1",
@ -48,4 +48,4 @@
"dependencies": {
"fs-extra": "^10.0.0"
}
}
}

View File

@ -115,8 +115,8 @@ export default function parse(tokens: Token[], file: string): Parsed {
return idx;
};
const eatText = (): [string, number] => {
checkTypes("text");
const eatText = (allowKeyword?: boolean): [string, number] => {
checkTypes(...(allowKeyword ? ["text", "keyword"] : ["text"]));
let val = currentToken.value;
let idx = currentToken.startIdx;
eatToken();
@ -351,7 +351,7 @@ export default function parse(tokens: Token[], file: string): Parsed {
if (currentToken.value !== ")") {
while (true) {
const [name] = eatText();
const [name] = eatText(true);
eatToken(":");
const [type] = eatText();
let array = false;

View File

@ -8,6 +8,7 @@ import {
import { CompileTarget } from "../compile";
import { LineAppender } from "../utils";
import chalk from "chalk";
const conversion = {
boolean: "bool",
@ -22,6 +23,16 @@ function toCSharpType(type: string): string {
return (conversion as any)[type] || type;
}
// TODO: Add other keywords as well!
const keywords = new Set(["event", "internal", "public", "private", "static"]);
const fixKeywordName = (name: string) => {
if (keywords.has(name)) {
return `${name}_`;
}
return name;
}
export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
name: string = "c#";
@ -61,11 +72,20 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
a(0, ``);
a(0, `public class ${definition.name} {`);
for (const field of definition.fields) {
let fn = field.name;
if (keywords.has(field.name)) {
console.log(
chalk.yellow("[RUST] WARNING:"),
`Field name '${fn}' is not allowed in C#. Renaming to '${fn}_'`
);
fn = fixKeywordName(fn);
a(1, `[JsonPropertyName("${fn}")]`);
}
if (field.array) {
a(
1,
`public IList<${toCSharpType(field.type)}>? ${
field.name
`public IList<${toCSharpType(field.type)}>? ${fn
} { get; set; }`
);
} else if (field.map) {
@ -73,12 +93,12 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
1,
`public Dictionary<${toCSharpType(field.map)}, ${toCSharpType(
field.type
)}>? ${field.name} { get; set; }`
)}>? ${fn} { get; set; }`
);
} else {
a(
1,
`public ${toCSharpType(field.type)}? ${field.name} { get; set; }`
`public ${toCSharpType(field.type)}? ${fn} { get; set; }`
);
}
}
@ -127,10 +147,12 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
for (const fnc of definition.functions) {
let params = fnc.inputs
.map((inp) => {
let name = fixKeywordName(inp.name);
if (inp.array) {
return `List<${toCSharpType(inp.type)}> ${inp.name}`;
return `List<${toCSharpType(inp.type)}> ${name}`;
} else {
return `${toCSharpType(inp.type)} ${inp.name}`;
return `${toCSharpType(inp.type)} ${name}`;
}
})
.join(", ");
@ -139,7 +161,7 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
a(
2,
`var param = new JsonArray(${fnc.inputs
.map((e) => `JsonSerializer.SerializeToNode(${e.name})`)
.map((e) => `JsonSerializer.SerializeToNode(${fixKeywordName(e.name)})`)
.join(", ")});`
);
@ -219,10 +241,11 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
for (const fnc of definition.functions) {
let params = [
...fnc.inputs.map((inp) => {
let name = fixKeywordName(inp.name)
if (inp.array) {
return `List<${toCSharpType(inp.type)}> ${inp.name}`;
return `List<${toCSharpType(inp.type)}> ${name}`;
} else {
return `${toCSharpType(inp.type)} ${inp.name}`;
return `${toCSharpType(inp.type)} ${name}`;
}
}),
"TContext ctx",
@ -272,15 +295,15 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
a(
4,
pref +
`this.${fnc.name}(${[
...fnc.inputs.map((inp, idx) => {
let type = inp.array
? `List<${toCSharpType(inp.type)}>`
: `${toCSharpType(inp.type)}`;
return `param[${idx}]!.Deserialize<${type}>()`;
}),
"context",
].join(", ")});`
`this.${fnc.name}(${[
...fnc.inputs.map((inp, idx) => {
let type = inp.array
? `List<${toCSharpType(inp.type)}>`
: `${toCSharpType(inp.type)}`;
return `param[${idx}]!.Deserialize<${type}>()`;
}),
"context",
].join(", ")});`
);
if (fnc.return && fnc.return.type != "void") {
@ -314,5 +337,5 @@ export class CSharpTarget extends CompileTarget<{ csharp_namespace: string }> {
this.generateServiceServer(definition);
}
finalize(steps: Step[]): void {}
finalize(steps: Step[]): void { }
}

View File

@ -23,6 +23,16 @@ function toSnake(input: string) {
);
}
// TODO: Add other keywords as well!
const keywords = new Set(["type", "static"]);
const fixKeywordName = (name: string) => {
if (keywords.has(name)) {
return `${name}_`;
}
return name;
}
export class RustTarget extends CompileTarget<{ rust_crate: string }> {
name: string = "rust";
@ -74,14 +84,14 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> {
a(1, `#[allow(non_snake_case)]`);
let fn = `pub ${field.name}:`;
if (field.name == "type") {
if (keywords.has(field.name)) {
// TODO: Add other keywords as well!
console.log(
chalk.yellow("[RUST] WARNING:"),
"Field name 'type' is not allowed in Rust. Renaming to 'type_'"
`Field name '${field.name}' is not allowed in Rust. Renaming to '${field.name}_'`
);
fn = `pub type_:`;
a(1, `#[serde(rename = "type")]`);
fn = `pub ${fixKeywordName(field.name)}:`;
a(1, `#[serde(rename = "${field.name}")]`);
}
let opts = "";
let opte = "";
@ -156,7 +166,7 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> {
a(0, ``);
for (const fnc of definition.functions) {
let params = fnc.inputs
.map((i) => i.name + ": " + typeToRust(i.type, i.array))
.map((i) => fixKeywordName(i.name) + ": " + typeToRust(i.type, i.array))
.join(", ");
let ret = fnc.return
? typeToRust(fnc.return.type, fnc.return.array)
@ -167,7 +177,7 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> {
a(3, `jsonrpc: "2.0".to_owned(),`);
a(3, `id: None, // 'id' will be set by the send_request function`);
a(3, `method: "${definition.name}.${fnc.name}".to_owned(),`);
a(3, `params: json!([${fnc.inputs.map((e) => e.name)}])`);
a(3, `params: json!([${fnc.inputs.map((e) => fixKeywordName(e.name))}])`);
a(2, `};`);
a(2, ``);
if (fnc.return) {
@ -220,7 +230,7 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> {
let params =
fnc.inputs.length > 0
? fnc.inputs
.map((i) => i.name + ": " + typeToRust(i.type, i.array))
.map((i) => fixKeywordName(i.name) + ": " + typeToRust(i.type, i.array))
.join(", ")
: "";
let ret = fnc.return

View File

@ -33,7 +33,7 @@ export class TypescriptTarget extends CompileTarget {
}
private generateImport(imports: string, path: string) {
return `import ${imports} from "${path + (this.flavour === "esm" ? ".ts" : "")
return `import ${imports} from "${path + (this.flavour === "esm" ? ".js" : "")
}";\n`;
}
@ -207,7 +207,7 @@ export class TypescriptTarget extends CompileTarget {
this.writeFormattedFile(
"service_client.ts",
this.generateImport(
"{ RequestObject, ResponseObject, ErrorCodes, Logging }",
"{ type RequestObject, type ResponseObject, ErrorCodes, Logging }",
"./service_base"
) +
this.generateImport(" { VerificationError }", "./ts_base") +
@ -304,7 +304,7 @@ export class TypescriptTarget extends CompileTarget {
this.writeFormattedFile(
"service_server.ts",
this.generateImport(
"{ RequestObject, ResponseObject, ErrorCodes, Logging }",
"{ type RequestObject, type ResponseObject, ErrorCodes, Logging }",
"./service_base"
) +
this.generateImport(" { VerificationError }", "./ts_base") +

View File

@ -1,5 +1,3 @@
import { isGeneratorFunction } from "util/types";
function form_verficiation_error_message(type?: string, field?: string) {
let msg = "Parameter verification failed! ";
if (type && field) {

View File

@ -1,7 +1,7 @@
//@template-ignore
import { VerificationError } from "./ts_base";
//@template-ignore
import { RequestObject, ResponseObject, ErrorCodes, Logging } from "./ts_service_base";
import { type RequestObject, type ResponseObject, ErrorCodes, Logging } from "./ts_service_base";
export type IMessageCallback = (data: any) => void;

View File

@ -1,14 +1,14 @@
//@template-ignore
import { VerificationError } from "./ts_base";
//@template-ignore
import { RequestObject, ResponseObject, ErrorCodes, Logging } from "./ts_service_base";
import { type RequestObject, type ResponseObject, ErrorCodes, Logging } from "./ts_service_base";
export class Service<T> {
public name: string = null as any;
public functions = new Set<string>();
constructor() {}
constructor() { }
}
type ISendMessageCB = (data: any, catchedErr?: Error) => void;
@ -37,7 +37,7 @@ class Session<T> {
this.ctx = ctx || {};
}
send(data: any, catchedErr?:Error) {
send(data: any, catchedErr?: Error) {
Logging.log("SERVER: Sending Message", data)
this._send(data, catchedErr);
}
@ -95,7 +95,7 @@ class Session<T> {
}
let result = await (service as any)["_" + fncName](data.params, this.ctx);
if(data.id) { //Request
if (data.id) { //Request
this.send({
jsonrpc: "2.0",
id: data.id,