Skip to content

Commit

Permalink
dirty: fix #68
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed May 10, 2024
1 parent a563bfe commit 4351de6
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 51 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
v0.8.2 - Properties starting with `static` or `private` would be ignored
v0.8.2 - Properties starting with `static` or `private` would be ignored
v0.8.3 - Dirty fix to issue #68. Add __JSON_Stringify callable to global scope.
123 changes: 104 additions & 19 deletions assembly/src/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
tabCode,
formFeedCode,
newLineCode,

commaWord,
quoteWord,

Expand All @@ -50,7 +50,7 @@ export namespace JSON {
/**
* Stringifies valid JSON data.
* ```js
* JSON.stringify<T>(data)
* __JSON_Stringify<T>(data)
* ```
* @param data T
* @returns string
Expand Down Expand Up @@ -104,26 +104,29 @@ export namespace JSON {
// @ts-ignore
for (let i = 0; i < data.length - 1; i++) {
// @ts-ignore
result.write(JSON.stringify(unchecked(data[i])));
result.write(__JSON_Stringify(unchecked(data[i])));
result.writeCodePoint(commaCode);
}
// @ts-ignore
result.write(JSON.stringify(unchecked(data[data.length - 1])));
result.write(__JSON_Stringify(unchecked(data[data.length - 1])));
result.writeCodePoint(rightBracketCode);
return result.toString();
}
} else if (data instanceof Map) {
let result = new StringSink(leftBraceWord);
let keys = data.keys();
let values = data.values();
for (let i = 0; i < data.size; i++) {
const end = data.size - 1;
for (let i = 0; i < end; i++) {
result.write(serializeString(unchecked(keys[i]).toString()));
result.writeCodePoint(colonCode);
result.write(JSON.stringify(unchecked(values[i])));
if (i < data.size - 1) {
result.writeCodePoint(commaCode);
}
result.write(__JSON_Stringify(unchecked(values[i])));
result.writeCodePoint(commaCode);
}
result.write(serializeString(unchecked(keys[end]).toString()));
result.writeCodePoint(colonCode);
result.write(__JSON_Stringify(unchecked(values[end])));

result.writeCodePoint(rightBraceCode);
return result.toString();
} else {
Expand All @@ -135,7 +138,7 @@ export namespace JSON {
/**
* Stringifies valid JSON data.
* ```js
* JSON.stringify<T>(data)
* __JSON_Stringify<T>(data)
* ```
* @param data T
* @returns string
Expand Down Expand Up @@ -198,11 +201,11 @@ export namespace JSON {
// @ts-ignore
for (let i = 0; i < data.length - 1; i++) {
// @ts-ignore
result.write(JSON.stringify(unchecked(data[i])));
result.write(__JSON_Stringify(unchecked(data[i])));
result.writeCodePoint(commaCode);
}
// @ts-ignore
result.write(JSON.stringify(unchecked(data[data.length - 1])));
result.write(__JSON_Stringify(unchecked(data[data.length - 1])));
result.writeCodePoint(rightBracketCode);
out = result.toString();
return;
Expand Down Expand Up @@ -350,7 +353,7 @@ export namespace JSON {

// @ts-ignore: Decorator
@inline function parseString(data: string, start: i32 = 0, end: i32 = 0): string {
end = end || data.length - 1;
end = end || data.length - 1;
let result = StringSink.withCapacity(end - start - 1);
let last = start + 1;
for (let i = last; i < end; i++) {
Expand Down Expand Up @@ -444,7 +447,7 @@ export namespace JSON {
const schema: nonnull<T> = changetype<nonnull<T>>(
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
);

// @ts-ignore
if (initializeDefaultValues) schema.__JSON_Initialize();

Expand Down Expand Up @@ -579,7 +582,7 @@ export namespace JSON {
const map: nonnull<T> = changetype<nonnull<T>>(
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
);

if (!isDefined(map.set)) {
return unreachable();
}
Expand Down Expand Up @@ -652,7 +655,7 @@ export namespace JSON {
key.reinst(data, outerLoopIndex, stringValueIndex);
}
isKey = true;
} else {
} else {
if (isString<valueof<T>>()) {
const value = parseString(data, outerLoopIndex - 1, stringValueIndex);
map.set(parseMapKey<indexof<T>>(key), value);
Expand Down Expand Up @@ -702,7 +705,7 @@ export namespace JSON {
if (char === colonCode || char === commaCode || char === rightBraceCode || isSpace(char)) {
if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
map.set(parseMapKey<indexof<T>>(key), parseNumber<valueof<T>>(data.slice(outerLoopIndex - 1, numberValueIndex)));
}
}
outerLoopIndex = numberValueIndex;
isKey = false;
break;
Expand Down Expand Up @@ -754,7 +757,7 @@ export namespace JSON {
return parseObjectArray<T>(data);
}
}

return unreachable();
}

Expand Down Expand Up @@ -876,7 +879,7 @@ export namespace JSON {
return result;
}

function parseDate(dateTimeString: string): Date {
function parseDate(dateTimeString: string): Date {
// Use AssemblyScript's date parser
const d = Date.fromString(dateTimeString);

Expand All @@ -891,3 +894,85 @@ function parseDate(dateTimeString: string): Date {
let type = changetype<T>(0);
return type instanceof Map;
}

// Dirty fix
// @ts-ignore: Decorator
@global @inline function __JSON_Stringify<T>(data: T): string {
// String
if (isString<T>() && data != null) {
return serializeString(data as string);
} else if (isBoolean<T>()) {
return data ? "true" : "false";
} else if (isNullable<T>() && data == null) {
return nullWord;
// @ts-ignore
} else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
// @ts-ignore
return data.toString();
// @ts-ignore: Hidden function
} else if (isDefined(data.__JSON_Serialize)) {
// @ts-ignore: Hidden function
return data.__JSON_Serialize();
} else if (data instanceof Date) {
return `"${data.toISOString()}"`;
} else if (isArrayLike<T>()) {
// @ts-ignore
if (data.length == 0) {
return emptyArrayWord;
// @ts-ignore
} else if (isString<valueof<T>>()) {
let result = leftBracketWord;
// @ts-ignore
for (let i = 0; i < data.length - 1; i++) {
// @ts-ignore
result += serializeString(unchecked(data[i]));
result += commaWord;
}
// @ts-ignore
result += serializeString(unchecked(data[data.length - 1]));
result += rightBracketWord;
return result;
// @ts-ignore
} else if (isBoolean<valueof<T>>()) {
// @ts-ignore
return leftBracketWord + data.join(commaWord) + rightBracketWord;
// @ts-ignore
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
// @ts-ignore
return leftBracketWord + data.join(commaWord) + rightBracketWord;
} else {
let result = new StringSink(leftBracketWord);
// @ts-ignore
for (let i = 0; i < data.length - 1; i++) {
// @ts-ignore
result.write(__JSON_Stringify(unchecked(data[i])));
result.writeCodePoint(commaCode);
}
// @ts-ignore
result.write(__JSON_Stringify(unchecked(data[data.length - 1])));
result.writeCodePoint(rightBracketCode);
return result.toString();
}
} else if (data instanceof Map) {
let result = new StringSink(leftBraceWord);
let keys = data.keys();
let values = data.values();
const end = data.size - 1;
for (let i = 0; i < end; i++) {
result.write(serializeString(unchecked(keys[i]).toString()));
result.writeCodePoint(colonCode);
result.write(__JSON_Stringify(unchecked(values[i])));
result.writeCodePoint(commaCode);
}
result.write(serializeString(unchecked(keys[end]).toString()));
result.writeCodePoint(colonCode);
result.write(__JSON_Stringify(unchecked(values[end])));

result.writeCodePoint(rightBraceCode);
return result.toString();
} else {
throw new Error(
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
);
}
}
18 changes: 1 addition & 17 deletions assembly/test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
import { JSON } from "./src/json";
@json
class Person {
staticprng: i32 = 23;
public country: string = '';

constructor(id: u32) {
this.staticprng = 321;
const seed = id.toString();
this.country = this.getCountry();
}

// temp method, returns hard-coded string for now
private getCountry(): string {
return "USA";
}
}

import { Person } from "./p"
const person = new Person(1);
person.staticprng = 32
let result = JSON.stringify<Person>(person);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "json-as",
"version": "0.8.2",
"version": "0.8.3",
"description": "JSON encoder/decoder for AssemblyScript",
"types": "assembly/index.ts",
"author": "Jairus Tanaka",
Expand Down
12 changes: 6 additions & 6 deletions transform/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class AsJSONTransform extends BaseVisitor {
}
}
else {
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${JSON.stringify<${type}>(this.${name})},`);
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${__JSON_Stringify<${type}>(this.${name})},`);
// @ts-ignore
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
this.${name} = __parseObjectValue<${type}>(val_start ? data.slice(val_start, val_end) : data, initializeDefaultValues);
Expand Down Expand Up @@ -194,11 +194,11 @@ class AsJSONTransform extends BaseVisitor {
//
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');
// ... So we have to do it the long way:
const s = 'import { Virtual as __Virtual } from "as-virtual/assembly";';
const t = new Tokenizer(new Source(0 /* SourceKind.User */, "index.ts", s));
const p = new Parser();
p.currentSource = t.source;
const stmt = p.parseTopLevelStatement(t);
const txt = 'import { Virtual as __Virtual } from "as-virtual/assembly";';
const tokenizer = new Tokenizer(new Source(0 /* SourceKind.User */, node.normalizedPath, txt));
const parser = new Parser();
parser.currentSource = tokenizer.source;
const stmt = parser.parseTopLevelStatement(tokenizer);
// Add the import statement to the top of the source.
node.statements.unshift(stmt);
}
Expand Down
2 changes: 1 addition & 1 deletion transform/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@json-as/transform",
"version": "0.8.2",
"version": "0.8.3",
"description": "JSON encoder/decoder for AssemblyScript",
"main": "./lib/index.js",
"author": "Jairus Tanaka",
Expand Down
12 changes: 6 additions & 6 deletions transform/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class AsJSONTransform extends BaseVisitor {
}
} else {
this.currentClass.encodeStmts.push(
`${encodeKey(aliasName)}:\${JSON.stringify<${type}>(this.${name})},`
`${encodeKey(aliasName)}:\${__JSON_Stringify<${type}>(this.${name})},`
);
// @ts-ignore
this.currentClass.setDataStmts.push(
Expand Down Expand Up @@ -246,11 +246,11 @@ class AsJSONTransform extends BaseVisitor {
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');

// ... So we have to do it the long way:
const s = 'import { Virtual as __Virtual } from "as-virtual/assembly";'
const t = new Tokenizer(new Source(SourceKind.User, "index.ts", s));
const p = new Parser();
p.currentSource = t.source;
const stmt = p.parseTopLevelStatement(t)!;
const txt = 'import { Virtual as __Virtual } from "as-virtual/assembly";'
const tokenizer = new Tokenizer(new Source(SourceKind.User, node.normalizedPath, txt));
const parser = new Parser();
parser.currentSource = tokenizer.source;
const stmt = parser.parseTopLevelStatement(tokenizer)!;

// Add the import statement to the top of the source.
node.statements.unshift(stmt);
Expand Down

0 comments on commit 4351de6

Please sign in to comment.