diff --git a/dist/ueblueprint.js b/dist/ueblueprint.js index 863b51a..84457b8 100644 --- a/dist/ueblueprint.js +++ b/dist/ueblueprint.js @@ -215,6 +215,7 @@ class ObjectReference extends Primitive { } class FunctionReferenceEntity extends Entity { + static attributes = { MemberParent: ObjectReference, MemberName: "" @@ -256,19 +257,16 @@ class Guid extends Primitive { } } -class LocalizedTextEntity extends Primitive { +class LocalizedTextEntity extends Entity { - /** - * - * @param {String} namespace - * @param {String} key - * @param {String} value - */ - constructor(namespace, key, value) { - super(); - this.namespace = namespace; - this.key = key; - this.value = value; + static attributes = { + namespace: String, + key: String, + value: String + } + + getAttributes() { + return LocalizedTextEntity.attributes } toString() { @@ -424,7 +422,11 @@ class Grammar { P.string(","), r.String.trim(P.optWhitespace), // value P.string(")"), - (_, namespace, __, key, ___, value, ____) => new LocalizedTextEntity(namespace, key, value) + (_, namespace, __, key, ___, value, ____) => new LocalizedTextEntity({ + namespace: namespace, + key: key, + value: value + }) ) PinReference = r => P.seqMap( r.PathSymbol, @@ -563,17 +565,20 @@ class Serializer { static grammar = Parsimmon.createLanguage(new Grammar()) - constructor(entityType, prefix = "", separator = ",", trailingSeparator = false) { + constructor(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) { this.entityType = entityType; - this.prefix = prefix; - this.separator = separator; - this.trailingSeparator = trailingSeparator; + this.prefix = prefix ?? ""; + this.separator = separator ?? ","; + this.trailingSeparator = trailingSeparator ?? false; + this.attributeValueConjunctionSign = attributeValueConjunctionSign ?? "="; + this.attributeKeyPrinter = attributeKeyPrinter ?? (k => k.join(".")); } writeValue(value) { if (value === null) { return "()" } + // This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically) switch (value?.constructor) { case Function: return this.writeValue(value()) @@ -603,7 +608,11 @@ class Serializer { // Recursive call when finding an object result += this.subWrite(fullKey, value, this.prefix, this.separator); } else if (this.showProperty(fullKey, value)) { - result += (result.length ? this.separator : "") + this.prefix + fullKey.join(".") + "=" + this.writeValue(value); + result += (result.length ? this.separator : "") + + this.prefix + + this.attributeKeyPrinter(fullKey) + + this.attributeValueConjunctionSign + + this.writeValue(value); } } if (this.trailingSeparator && result.length) { @@ -625,9 +634,9 @@ class Serializer { class GeneralSerializer extends Serializer { - constructor(keyword = "", entityType, prefix = "", separator = ",", trailingSeparator = false) { - super(entityType, prefix, separator, trailingSeparator); - this.keyword = keyword; + constructor(keyword, entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) { + super(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter); + this.keyword = keyword ?? ""; } read(value) { @@ -641,7 +650,7 @@ class GeneralSerializer extends Serializer { } write(object) { - let result = `${this.key ?? ""}(${this.subWrite([], object)})`; + let result = `${this.keyword}(${this.subWrite([], object)})`; return result } } @@ -690,6 +699,7 @@ End Object`; SerializerFactory.registerSerializer(ObjectEntity, new ObjectSerializer()); SerializerFactory.registerSerializer(PinEntity, new GeneralSerializer("Pin ", PinEntity, "", ",", true)); -SerializerFactory.registerSerializer(FunctionReferenceEntity, new GeneralSerializer("", FunctionReferenceEntity, "", ",", false)); +SerializerFactory.registerSerializer(FunctionReferenceEntity, new GeneralSerializer("", FunctionReferenceEntity, "", ",", false)); +SerializerFactory.registerSerializer(LocalizedTextEntity, new GeneralSerializer("NSLOCTEXT", LocalizedTextEntity, "", ",", false, "", _ => "")); export { ObjectEntity, SerializerFactory }; diff --git a/js/entity/FunctionReferenceEntity.js b/js/entity/FunctionReferenceEntity.js index 9d4a9c4..e319a9a 100755 --- a/js/entity/FunctionReferenceEntity.js +++ b/js/entity/FunctionReferenceEntity.js @@ -2,6 +2,7 @@ import Entity from "./Entity" import ObjectReference from "./primitive/ObjectReference" export default class FunctionReferenceEntity extends Entity { + static attributes = { MemberParent: ObjectReference, MemberName: "" diff --git a/js/entity/LocalizedTextEntity.js b/js/entity/LocalizedTextEntity.js new file mode 100755 index 0000000..0209c5a --- /dev/null +++ b/js/entity/LocalizedTextEntity.js @@ -0,0 +1,19 @@ +import Entity from "./Entity" + +export default class LocalizedTextEntity extends Entity { + + static attributes = { + namespace: String, + key: String, + value: String + } + + getAttributes() { + return LocalizedTextEntity.attributes + } + + toString() { + "NSLOCTEXT(" + `"${this.namespace}"` + ", " + `"${this.key}"` + ", " + `"${this.value}"` + ")" + } + +} diff --git a/js/entity/PinEntity.js b/js/entity/PinEntity.js index c3e962e..c51e8d3 100755 --- a/js/entity/PinEntity.js +++ b/js/entity/PinEntity.js @@ -1,6 +1,6 @@ import Entity from "./Entity" import Guid from "./primitive/Guid" -import LocalizedTextEntity from "./primitive/LocalizedTextEntity" +import LocalizedTextEntity from "./LocalizedTextEntity" import ObjectReference from "./primitive/ObjectReference" import PinReferenceEntity from "./PinReferenceEntity" import TypeInitialization from "./TypeInitialization" diff --git a/js/entity/primitive/Guid.js b/js/entity/primitive/Guid.js index 13430b5..1c9e9b5 100755 --- a/js/entity/primitive/Guid.js +++ b/js/entity/primitive/Guid.js @@ -3,7 +3,7 @@ import Primitive from "./Primitive" export default class Guid extends Primitive { static generateGuid(random) { - let values = new Uint32Array(4); + let values = new Uint32Array(4) if (random === true) { crypto.getRandomValues(values) } diff --git a/js/entity/primitive/LocalizedTextEntity.js b/js/entity/primitive/LocalizedTextEntity.js deleted file mode 100755 index 0aca8d9..0000000 --- a/js/entity/primitive/LocalizedTextEntity.js +++ /dev/null @@ -1,22 +0,0 @@ -import Primitive from "./Primitive" - -export default class LocalizedTextEntity extends Primitive { - - /** - * - * @param {String} namespace - * @param {String} key - * @param {String} value - */ - constructor(namespace, key, value) { - super() - this.namespace = namespace - this.key = key - this.value = value - } - - toString() { - "NSLOCTEXT(" + `"${this.namespace}"` + ", " + `"${this.key}"` + ", " + `"${this.value}"` + ")" - } - -} diff --git a/js/export.js b/js/export.js index 37ce579..7adf9ae 100755 --- a/js/export.js +++ b/js/export.js @@ -4,9 +4,11 @@ import ObjectSerializer from "./serialization/ObjectSerializer" import PinEntity from "./entity/PinEntity" import SerializerFactory from "./serialization/SerializerFactory" import FunctionReferenceEntity from "./entity/FunctionReferenceEntity" +import LocalizedTextEntity from "./entity/LocalizedTextEntity" SerializerFactory.registerSerializer(ObjectEntity, new ObjectSerializer()) SerializerFactory.registerSerializer(PinEntity, new GeneralSerializer("Pin ", PinEntity, "", ",", true)) SerializerFactory.registerSerializer(FunctionReferenceEntity, new GeneralSerializer("", FunctionReferenceEntity, "", ",", false)) +SerializerFactory.registerSerializer(LocalizedTextEntity, new GeneralSerializer("NSLOCTEXT", LocalizedTextEntity, "", ",", false, "", _ => "")) export { SerializerFactory as SerializerFactory, ObjectEntity as ObjectEntity } \ No newline at end of file diff --git a/js/serialization/GeneralSerializer.js b/js/serialization/GeneralSerializer.js index 5960442..965f513 100755 --- a/js/serialization/GeneralSerializer.js +++ b/js/serialization/GeneralSerializer.js @@ -3,9 +3,9 @@ import Serializer from "./Serializer" export default class GeneralSerializer extends Serializer { - constructor(keyword = "", entityType, prefix = "", separator = ",", trailingSeparator = false) { - super(entityType, prefix, separator, trailingSeparator) - this.keyword = keyword + constructor(keyword, entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) { + super(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) + this.keyword = keyword ?? "" } read(value) { @@ -19,7 +19,7 @@ export default class GeneralSerializer extends Serializer { } write(object) { - let result = `${this.key ?? ""}(${this.subWrite([], object)})` + let result = `${this.keyword}(${this.subWrite([], object)})` return result } } diff --git a/js/serialization/Grammar.js b/js/serialization/Grammar.js index 9482e6e..26b8b53 100755 --- a/js/serialization/Grammar.js +++ b/js/serialization/Grammar.js @@ -1,7 +1,7 @@ import FunctionReferenceEntity from "../entity/FunctionReferenceEntity" import Guid from "../entity/primitive/Guid" import Integer from "../entity/primitive/Integer" -import LocalizedTextEntity from "../entity/primitive/LocalizedTextEntity" +import LocalizedTextEntity from "../entity/LocalizedTextEntity" import ObjectEntity from "../entity/ObjectEntity" import ObjectReference from "../entity/primitive/ObjectReference" import Parsimmon from "parsimmon" @@ -54,7 +54,11 @@ export default class Grammar { P.string(","), r.String.trim(P.optWhitespace), // value P.string(")"), - (_, namespace, __, key, ___, value, ____) => new LocalizedTextEntity(namespace, key, value) + (_, namespace, __, key, ___, value, ____) => new LocalizedTextEntity({ + namespace: namespace, + key: key, + value: value + }) ) PinReference = r => P.seqMap( r.PathSymbol, diff --git a/js/serialization/Serializer.js b/js/serialization/Serializer.js index 4bb0831..c0dbcea 100755 --- a/js/serialization/Serializer.js +++ b/js/serialization/Serializer.js @@ -11,17 +11,20 @@ export default class Serializer { static grammar = Parsimmon.createLanguage(new Grammar()) - constructor(entityType, prefix = "", separator = ",", trailingSeparator = false) { + constructor(entityType, prefix, separator, trailingSeparator, attributeValueConjunctionSign, attributeKeyPrinter) { this.entityType = entityType - this.prefix = prefix - this.separator = separator - this.trailingSeparator = trailingSeparator + this.prefix = prefix ?? "" + this.separator = separator ?? "," + this.trailingSeparator = trailingSeparator ?? false + this.attributeValueConjunctionSign = attributeValueConjunctionSign ?? "=" + this.attributeKeyPrinter = attributeKeyPrinter ?? (k => k.join(".")) } writeValue(value) { if (value === null) { return "()" } + // This is an exact match (and not instanceof) to hit also primitive types (by accessing value.constructor they are converted to objects automatically) switch (value?.constructor) { case Function: return this.writeValue(value()) @@ -51,7 +54,11 @@ export default class Serializer { // Recursive call when finding an object result += this.subWrite(fullKey, value, this.prefix, this.separator) } else if (this.showProperty(fullKey, value)) { - result += (result.length ? this.separator : "") + this.prefix + fullKey.join(".") + "=" + this.writeValue(value) + result += (result.length ? this.separator : "") + + this.prefix + + this.attributeKeyPrinter(fullKey) + + this.attributeValueConjunctionSign + + this.writeValue(value) } } if (this.trailingSeparator && result.length) {