mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-13 16:44:49 +08:00
WIP
This commit is contained in:
1145
dist/ueblueprint.js
vendored
1145
dist/ueblueprint.js
vendored
File diff suppressed because it is too large
Load Diff
8
dist/ueblueprint.min.js
vendored
8
dist/ueblueprint.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -7,13 +7,20 @@ export default class AlternativesEntity extends IEntity {
|
||||
/** @type {(typeof IEntity)[]} */
|
||||
static alternatives = []
|
||||
|
||||
static className() {
|
||||
let result = super.className()
|
||||
if (this.alternatives.length) {
|
||||
result += " (accepting: " + this.alternatives.map(v => v.className()).join(", ") + ")"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
static createGrammar() {
|
||||
return this.alternatives
|
||||
.map(entity => entity.grammar)
|
||||
.reduce((acc, cur) => !cur || cur === Grammar.unknownValue || acc === Grammar.unknownValue
|
||||
? Grammar.unknownValue
|
||||
: P.alt(acc, cur)
|
||||
)
|
||||
const grammars = this.alternatives.map(entity => entity.grammar)
|
||||
if (grammars.includes(Grammar.unknownValue)) {
|
||||
return Grammar.unknownValue
|
||||
}
|
||||
return P.alt(...grammars)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,21 +7,30 @@ export default class ArrayEntity extends IEntity {
|
||||
|
||||
/** @type {typeof IEntity} */
|
||||
static type
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
/** @param {InstanceType<T>[]} values */
|
||||
/** @param {ExtractType<T>[]} values */
|
||||
constructor(values = []) {
|
||||
super()
|
||||
this.values = values
|
||||
}
|
||||
|
||||
static createGrammar(elementGrammar = this.type.grammar) {
|
||||
static createGrammar(elementGrammar = this.type?.grammar ?? P.lazy(() => Grammar.unknownValue)) {
|
||||
return this.inlined
|
||||
? elementGrammar
|
||||
: P.seq(
|
||||
P.reg(/\(\s*/),
|
||||
elementGrammar.sepBy(Grammar.commaSeparation).opt(),
|
||||
P.reg(/\s*(?:,\s*)?\)/),
|
||||
).map(([_0, values, _3]) => new this(values instanceof Array ? values : []))
|
||||
P.reg(/\s*(,\s*)?\)/, 1),
|
||||
).map(([_0, values, trailing]) => {
|
||||
let self = this
|
||||
const hasTrailing = trailing !== undefined
|
||||
if (hasTrailing !== self.trailing) {
|
||||
self = self.flagTrailing(hasTrailing)
|
||||
}
|
||||
values = values instanceof Array ? values : []
|
||||
return new self(values)
|
||||
}).label(`ArrayEntity of ${this.type?.className() ?? "unknown values"}`)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,8 +38,10 @@ export default class ArrayEntity extends IEntity {
|
||||
* @param {NonNullable<T>} type
|
||||
*/
|
||||
static of(type) {
|
||||
const result = /** @type {(typeof ArrayEntity<T>) & { type: T }} */(this.asUniqueClass())
|
||||
result.type = type
|
||||
const result = /** @type {typeof ArrayEntity<T> & { type: ExtractType<T>, grammar: P<ArrayEntity<T>> }} */(
|
||||
this.asUniqueClass()
|
||||
)
|
||||
result.type = /** @type {ExtractType<T>} */(type)
|
||||
this.grammar = result.createGrammar()
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -56,18 +56,18 @@ export default class BlueprintEntity extends ObjectEntity {
|
||||
|
||||
/** @param {ObjectEntity} entity */
|
||||
mergeWith(entity) {
|
||||
if (!entity.ScriptVariables || entity.ScriptVariables.length === 0) {
|
||||
if (!entity.ScriptVariables || entity.ScriptVariables.values.length === 0) {
|
||||
return this
|
||||
}
|
||||
if (!this.ScriptVariables || this.ScriptVariables.length === 0) {
|
||||
if (!this.ScriptVariables || this.ScriptVariables.values.length === 0) {
|
||||
this.ScriptVariables = entity.ScriptVariables
|
||||
}
|
||||
let scriptVariables = Utility.mergeArrays(
|
||||
this.ScriptVariables,
|
||||
entity.ScriptVariables,
|
||||
this.ScriptVariables.values,
|
||||
entity.ScriptVariables.values,
|
||||
(l, r) => l.OriginalChangeId.value == r.OriginalChangeId.value
|
||||
)
|
||||
if (scriptVariables.length === this.ScriptVariables.length) {
|
||||
if (scriptVariables.length === this.ScriptVariables.values.length) {
|
||||
return this
|
||||
}
|
||||
const entries = scriptVariables.concat(scriptVariables).map((v, i) => {
|
||||
|
||||
@@ -3,7 +3,9 @@ import IEntity from "./IEntity.js"
|
||||
|
||||
export default class BooleanEntity extends IEntity {
|
||||
|
||||
static grammar = P.regArray(/(true)|false/i).map(v => v[1] ? new this(true) : new this(false))
|
||||
static grammar = P.regArray(/(true)|false/i)
|
||||
.map(v => v[1] ? new this(true) : new this(false))
|
||||
.label("BooleanEntity")
|
||||
|
||||
constructor(value = false) {
|
||||
super()
|
||||
@@ -14,7 +16,13 @@ export default class BooleanEntity extends IEntity {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
toString(insideString = false) {
|
||||
return this.value
|
||||
? insideString
|
||||
? "true"
|
||||
: "True"
|
||||
: insideString
|
||||
? "false"
|
||||
: "False"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
import IPrintableEntity from "./IPrintableEntity.js"
|
||||
import InvariantTextEntity from "./InvariantTextEntity.js"
|
||||
import LocalizedTextEntity from "./LocalizedTextEntity.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
|
||||
export default class FormatTextEntity extends IEntity {
|
||||
export default class FormatTextEntity extends IPrintableEntity {
|
||||
|
||||
static lookbehind = ["LOCGEN_FORMAT_NAMED", "LOCGEN_FORMAT_ORDERED"]
|
||||
static grammar = P.seq(
|
||||
// Resulting regex: /(LOCGEN_FORMAT_NAMED|LOCGEN_FORMAT_ORDERED)\s*/
|
||||
P.reg(new RegExp(String.raw`(${this.lookbehind.reduce((acc, cur) => acc + "|" + cur)})\s*\(\s*)`), 1),
|
||||
P.reg(new RegExp(String.raw`(${this.lookbehind.reduce((acc, cur) => acc + "|" + cur)})\s*`), 1),
|
||||
P.alt(
|
||||
...[StringEntity, LocalizedTextEntity, InvariantTextEntity, FormatTextEntity].map(type => type.grammar)
|
||||
).sepBy(P.reg(/\s*\,\s*/)),
|
||||
@@ -20,6 +20,7 @@ export default class FormatTextEntity extends IEntity {
|
||||
result.lookbehind = lookbehind
|
||||
return result
|
||||
})
|
||||
.label("FormatTextEntity")
|
||||
|
||||
/** @param {(StringEntity | LocalizedTextEntity | InvariantTextEntity | FormatTextEntity)[]} values */
|
||||
constructor(values) {
|
||||
@@ -27,20 +28,21 @@ export default class FormatTextEntity extends IEntity {
|
||||
this.values = values
|
||||
}
|
||||
|
||||
toString() {
|
||||
print() {
|
||||
const pattern = this.values?.[0]?.toString() // The pattern is always the first element of the array
|
||||
if (!pattern) {
|
||||
return ""
|
||||
}
|
||||
|
||||
const values = this.values.slice(1).map(v => v.toString())
|
||||
return this.lookbehind == "LOCGEN_FORMAT_NAMED"
|
||||
let result = this.Self().lookbehind == "LOCGEN_FORMAT_NAMED"
|
||||
? pattern.replaceAll(/\{([a-zA-Z]\w*)\}/g, (substring, arg) => {
|
||||
const argLocation = values.indexOf(arg) + 1
|
||||
return argLocation > 0 && argLocation < values.length
|
||||
? values[argLocation]
|
||||
: substring
|
||||
})
|
||||
: this.lookbehind == "LOCGEN_FORMAT_ORDERED"
|
||||
: this.Self().lookbehind == "LOCGEN_FORMAT_ORDERED"
|
||||
? pattern.replaceAll(/\{(\d+)\}/g, (substring, arg) => {
|
||||
const argValue = Number(arg)
|
||||
return argValue < values.length
|
||||
@@ -48,5 +50,6 @@ export default class FormatTextEntity extends IEntity {
|
||||
: substring
|
||||
})
|
||||
: ""
|
||||
result = this.Self().lookbehind + "(" + result + ")"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ export default class FunctionReferenceEntity extends IEntity {
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {ObjectReferenceEntity} */ this.MemberParent
|
||||
/** @type {String} */ this.MemberName
|
||||
/** @type {GuidEntity} */ this.MemberGuid
|
||||
/** @type {InstanceType<typeof FunctionReferenceEntity.attributes.MemberParent>} */ this.MemberParent
|
||||
/** @type {InstanceType<typeof FunctionReferenceEntity.attributes.MemberName>} */ this.MemberName
|
||||
/** @type {InstanceType<typeof FunctionReferenceEntity.attributes.MemberGuid>} */ this.MemberGuid
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ if (typeof window === "undefined") {
|
||||
|
||||
export default class GuidEntity extends IEntity {
|
||||
|
||||
static grammar = P.reg(/[0-9a-fA-F]{32}/).map(v => new this(v))
|
||||
static grammar = P.reg(/[0-9A-F]{32}/i).map(v => new this(v)).label("GuidEntity")
|
||||
|
||||
static generateGuid() {
|
||||
let values = new Uint32Array(4)
|
||||
|
||||
@@ -10,45 +10,22 @@ export default class IEntity {
|
||||
/** @type {(entity: Attribute, serialized: String) => String} */
|
||||
static notWrapped = (entity, serialized) => serialized
|
||||
|
||||
/** @type {(entity: Attribute, serialized: String) => String} */
|
||||
static bracketsWrapped = (entity, serialized) => `(${serialized})`
|
||||
/** @type {(entity: IEntity, serialized: String) => String} */
|
||||
static defaultWrapped = (entity, serialized) => `${entity.lookbehind}(${serialized})`
|
||||
|
||||
static wrap = this.notWrapped
|
||||
static wrap = this.defaultWrapped
|
||||
|
||||
static attributeSeparator = ","
|
||||
|
||||
static trailingSeparator = false
|
||||
|
||||
/** @type {(k: String) => String} */
|
||||
static printKey = k => k
|
||||
|
||||
/** @type {P<Parser>} */
|
||||
static grammar = P.failure()
|
||||
/** @type {P<InstanceType<typeof this>>} */
|
||||
static grammar = /** @type {any} */(P.failure())
|
||||
|
||||
/** @type {{ [key: String]: typeof IEntity }} */
|
||||
static attributes = {}
|
||||
|
||||
/** @type {String | String[]} */
|
||||
static lookbehind = ""
|
||||
|
||||
/** @type {typeof IEntity.lookbehind} */
|
||||
#lookbehind = this.Self().lookbehind
|
||||
get lookbehind() {
|
||||
return this.#lookbehind
|
||||
}
|
||||
set lookbehind(value) {
|
||||
throw this.#lookbehind = value
|
||||
}
|
||||
|
||||
/** @type {String[]} */
|
||||
#keys
|
||||
get keys() {
|
||||
return this.#keys ?? Object.keys(this.Self().attributes)
|
||||
}
|
||||
set keys(value) {
|
||||
this.#keys = [... new Set(value)]
|
||||
}
|
||||
|
||||
/** @type {(type: typeof IEntity) => InstanceType<typeof IEntity>} */
|
||||
static default
|
||||
static nullable = false
|
||||
@@ -58,10 +35,30 @@ export default class IEntity {
|
||||
static inlined = false // The key is a subobject or array and printed as inlined (A.B=123, A(0)=123)
|
||||
static quoted = false // Key is serialized with quotes
|
||||
static silent = false // Do not serialize if default
|
||||
static uninitialized = false // Do not initialize with default
|
||||
static trailing = false // Add attribute separator after the last attribute when serializing
|
||||
|
||||
/** @type {String | String[]} */
|
||||
static lookbehind = ""
|
||||
|
||||
#lookbehind = /** @type {String} */(this.Self().lookbehind)
|
||||
get lookbehind() {
|
||||
return this.#lookbehind
|
||||
}
|
||||
set lookbehind(value) {
|
||||
this.#lookbehind = value
|
||||
}
|
||||
|
||||
/** @type {String[]} */
|
||||
#keys
|
||||
get keys() {
|
||||
return this.#keys ?? Object.keys(this)
|
||||
}
|
||||
set keys(value) {
|
||||
this.#keys = [... new Set(value)]
|
||||
}
|
||||
|
||||
constructor(values = {}) {
|
||||
const keys = Utility.mergeArrays(Object.keys(values.attributes), Object.keys(this.Self().attributes))
|
||||
const keys = Utility.mergeArrays(Object.keys(values), Object.keys(this.Self().attributes))
|
||||
for (const key of keys) {
|
||||
if (values[key] !== undefined) {
|
||||
this[key] = values[key]
|
||||
@@ -75,6 +72,14 @@ export default class IEntity {
|
||||
}
|
||||
}
|
||||
|
||||
static className() {
|
||||
let self = this
|
||||
while (!self.name) {
|
||||
self = Object.getPrototypeOf(self)
|
||||
}
|
||||
return self.name
|
||||
}
|
||||
|
||||
/** @param {String} key */
|
||||
showProperty(key) {
|
||||
/** @type {IEntity} */
|
||||
@@ -104,6 +109,17 @@ export default class IEntity {
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
* @param {String} value
|
||||
*/
|
||||
static withLookbehind(value) {
|
||||
const result = this.asUniqueClass()
|
||||
result.lookbehind = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
@@ -144,6 +160,16 @@ export default class IEntity {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static flagQuoted(value = true) {
|
||||
const result = this.asUniqueClass()
|
||||
result.quoted = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
@@ -154,6 +180,16 @@ export default class IEntity {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {T}
|
||||
*/
|
||||
static flagTrailing(value = true) {
|
||||
const result = this.asUniqueClass()
|
||||
result.trailing = value
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {typeof IEntity} T
|
||||
* @this {InstanceType<T>}
|
||||
@@ -206,6 +242,9 @@ export default class IEntity {
|
||||
if (thisKeys.length != otherKeys.length) {
|
||||
return false
|
||||
}
|
||||
if (this.valueOf && other.valueOf) {
|
||||
return this.valueOf() === other.valueOf()
|
||||
}
|
||||
for (let i = 0; i < thisKeys.length; ++i) {
|
||||
if (!(this[thisKeys[i]] instanceof IEntity && this[thisKeys[i]].equals(other[otherKeys[i]]))) {
|
||||
return false
|
||||
@@ -250,7 +289,7 @@ export default class IEntity {
|
||||
}
|
||||
result += serialization
|
||||
}
|
||||
if (Self.trailingSeparator && result.length) {
|
||||
if (Self.trailing && result.length) {
|
||||
result += Self.attributeSeparator
|
||||
}
|
||||
return Self.wrap(this, result)
|
||||
|
||||
8
js/entity/IPrintableEntity.js
Normal file
8
js/entity/IPrintableEntity.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class IPrintableEntity extends IEntity {
|
||||
|
||||
print() {
|
||||
return this.toString()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import P from "parsernostrum"
|
||||
import NumberEntity from "./NumberEntity.js"
|
||||
|
||||
// @ts-expect-error
|
||||
export default class IntegerEntity extends NumberEntity {
|
||||
|
||||
static grammar = P.numberInteger.map(v => new this(v))
|
||||
|
||||
@@ -1,25 +1,39 @@
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Parsernostrum from "parsernostrum"
|
||||
import IPrintableEntity from "./IPrintableEntity.js"
|
||||
|
||||
export default class InvariantTextEntity extends IEntity {
|
||||
export default class InvariantTextEntity extends IPrintableEntity {
|
||||
|
||||
static lookbehind = "INVTEXT"
|
||||
|
||||
static grammar = P.alt(
|
||||
P.seq(
|
||||
P.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
|
||||
P.doubleQuotedString,
|
||||
P.reg(/\s*\)/)
|
||||
).map(([_0, value, _2]) => new this(value)),
|
||||
P.reg(new RegExp(this.lookbehind)).map(() => new this()) // InvariantTextEntity can not have arguments
|
||||
).map(value => new this(value))
|
||||
static grammar = Parsernostrum.alt(
|
||||
Parsernostrum.seq(
|
||||
Parsernostrum.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
|
||||
Parsernostrum.doubleQuotedString,
|
||||
Parsernostrum.reg(/\s*\)/)
|
||||
).map(([_0, value, _2]) => Number(value)),
|
||||
Parsernostrum.reg(new RegExp(this.lookbehind)).map(() => 0) // InvariantTextEntity can not have arguments
|
||||
)
|
||||
.map(value => new this(value))
|
||||
.label("InvariantTextEntity")
|
||||
|
||||
constructor(value = "") {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
toString() {
|
||||
print() {
|
||||
let xxxx = Parsernostrum.alt(
|
||||
Parsernostrum.seq(
|
||||
Parsernostrum.reg(new RegExp(`${this.lookbehind}\\s*\\(`)),
|
||||
Parsernostrum.doubleQuotedString,
|
||||
Parsernostrum.reg(/\s*\)/)
|
||||
).map(([_0, value, _2]) => Number(value)),
|
||||
Parsernostrum.reg(new RegExp(this.lookbehind)).map(() => 0) // InvariantTextEntity can not have arguments
|
||||
)
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.lookbehind + "(" + this.value + ")"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ export default class KeyBindingEntity extends IEntity {
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
/** @type {String} */ this.ActionName
|
||||
/** @type {Boolean} */ this.bShift
|
||||
/** @type {Boolean} */ this.bCtrl
|
||||
/** @type {Boolean} */ this.bAlt
|
||||
/** @type {Boolean} */ this.bCmd
|
||||
/** @type {IdentifierEntity} */ this.Key
|
||||
/** @type {InstanceType<typeof KeyBindingEntity.attributes.ActionName>} */ this.ActionName
|
||||
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bShift>} */ this.bShift
|
||||
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bCtrl>} */ this.bCtrl
|
||||
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bAlt>} */ this.bAlt
|
||||
/** @type {InstanceType<typeof KeyBindingEntity.attributes.bCmd>} */ this.bCmd
|
||||
/** @type {InstanceType<typeof KeyBindingEntity.attributes.Key>} */ this.Key
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default class LinearColorEntity extends IEntity {
|
||||
B: ColorChannelEntity.withDefault(),
|
||||
A: ColorChannelEntity.withDefault(type => new type(1)),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this, false)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("LinearColorEntity")
|
||||
|
||||
#H = new ColorChannelEntity()
|
||||
get H() {
|
||||
@@ -26,18 +26,35 @@ export default class LinearColorEntity extends IEntity {
|
||||
|
||||
#S = new ColorChannelEntity()
|
||||
get S() {
|
||||
return this.#H
|
||||
return this.#S
|
||||
}
|
||||
set S(value) {
|
||||
this.#H = value
|
||||
this.#S = value
|
||||
}
|
||||
|
||||
#V = new ColorChannelEntity()
|
||||
get V() {
|
||||
return this.#H
|
||||
return this.#V
|
||||
}
|
||||
set V(value) {
|
||||
this.#H = value
|
||||
this.#V = value
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
if (values instanceof Array) {
|
||||
values = {
|
||||
R: values[0] ?? 0,
|
||||
G: values[1] ?? 0,
|
||||
B: values[2] ?? 0,
|
||||
A: values[3] ?? 1,
|
||||
}
|
||||
}
|
||||
/** @type {InstanceType<typeof LinearColorEntity.attributes.R>} */ this.R
|
||||
/** @type {InstanceType<typeof LinearColorEntity.attributes.G>} */ this.G
|
||||
/** @type {InstanceType<typeof LinearColorEntity.attributes.B>} */ this.B
|
||||
/** @type {InstanceType<typeof LinearColorEntity.attributes.A>} */ this.A
|
||||
this.#updateHSV()
|
||||
}
|
||||
|
||||
/** @param {Number} x */
|
||||
@@ -129,23 +146,6 @@ export default class LinearColorEntity extends IEntity {
|
||||
)
|
||||
}
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
if (values instanceof Array) {
|
||||
values = {
|
||||
R: values[0] ?? 0,
|
||||
G: values[1] ?? 0,
|
||||
B: values[2] ?? 0,
|
||||
A: values[3] ?? 1,
|
||||
}
|
||||
}
|
||||
/** @type {ColorChannelEntity} */ this.R
|
||||
/** @type {ColorChannelEntity} */ this.G
|
||||
/** @type {ColorChannelEntity} */ this.B
|
||||
/** @type {ColorChannelEntity} */ this.A
|
||||
this.#updateHSV()
|
||||
}
|
||||
|
||||
#updateHSV() {
|
||||
const r = this.R.value
|
||||
const g = this.G.value
|
||||
@@ -311,8 +311,4 @@ export default class LinearColorEntity extends IEntity {
|
||||
toArray() {
|
||||
return [this.R.value, this.G.value, this.B.value, this.A.value]
|
||||
}
|
||||
|
||||
toString() {
|
||||
return Utility.printLinearColor(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
import P from "parsernostrum"
|
||||
import Utility from "../Utility.js"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import IPrintableEntity from "./IPrintableEntity.js"
|
||||
|
||||
export default class LocalizedTextEntity extends IEntity {
|
||||
export default class LocalizedTextEntity extends IPrintableEntity {
|
||||
|
||||
static lookbehind = "NSLOCTEXT"
|
||||
static grammar = P.regArray(new RegExp(
|
||||
String.raw`${this.attributes.lookbehind.default}\s*\(`
|
||||
String.raw`${this.lookbehind}\s*\(`
|
||||
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
|
||||
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
|
||||
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*`
|
||||
+ String.raw`(?:,\s+)?`
|
||||
+ String.raw`(,\s+)?`
|
||||
+ String.raw`\)`,
|
||||
"m"
|
||||
)).map(matchResult => new this(
|
||||
Utility.unescapeString(matchResult[1]),
|
||||
Utility.unescapeString(matchResult[2]),
|
||||
Utility.unescapeString(matchResult[3]),
|
||||
))
|
||||
)).map(matchResult => {
|
||||
const self = matchResult[4] ? this.flagTrailing() : this
|
||||
return new self(
|
||||
Utility.unescapeString(matchResult[1]),
|
||||
Utility.unescapeString(matchResult[2]),
|
||||
Utility.unescapeString(matchResult[3]),
|
||||
)
|
||||
}).label("LocalizedTextEntity")
|
||||
|
||||
#namespace
|
||||
get namespace() {
|
||||
@@ -44,7 +47,6 @@ export default class LocalizedTextEntity extends IEntity {
|
||||
this.#value = value
|
||||
}
|
||||
|
||||
|
||||
constructor(namespace = "", key = "", value = "") {
|
||||
super()
|
||||
this.namespace = namespace
|
||||
@@ -52,7 +54,12 @@ export default class LocalizedTextEntity extends IEntity {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
toString() {
|
||||
print() {
|
||||
return Utility.capitalFirstLetter(this.value)
|
||||
}
|
||||
|
||||
toString() {
|
||||
const trailer = this.Self().trailing ? ", " : ""
|
||||
return `${this.lookbehind}(${this.namespace}, ${this.key}, ${this.value}${trailer})`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ export default class MacroGraphReferenceEntity extends IEntity {
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {ObjectReferenceEntity} */ this.MacroGraph
|
||||
/** @type {ObjectReferenceEntity} */ this.GraphBlueprint
|
||||
/** @type {GuidEntity} */ this.GuidEntity
|
||||
/** @type {InstanceType<typeof MacroGraphReferenceEntity.attributes.MacroGraph>} */ this.MacroGraph
|
||||
/** @type {InstanceType<typeof MacroGraphReferenceEntity.attributes.GraphBlueprint>} */ this.GraphBlueprint
|
||||
/** @type {InstanceType<typeof MacroGraphReferenceEntity.attributes.GraphGuid>} */ this.GraphGuid
|
||||
}
|
||||
|
||||
getMacroName() {
|
||||
|
||||
@@ -6,7 +6,7 @@ export default class MirroredEntity extends IEntity {
|
||||
/** @type {typeof IEntity} */
|
||||
static type
|
||||
|
||||
/** @param {() => T} getter */
|
||||
/** @param {() => InstanceType<T>} getter */
|
||||
constructor(getter = null) {
|
||||
super()
|
||||
this.getter = getter
|
||||
@@ -32,7 +32,11 @@ export default class MirroredEntity extends IEntity {
|
||||
return result
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.getter().toString()
|
||||
toString(
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
printKey = this.Self().printKey,
|
||||
) {
|
||||
return this.getter().toString(insideString, indentation, printKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class NumberEntity extends IEntity {
|
||||
|
||||
static grammar = P.regArray(
|
||||
new RegExp(`(${P.number.getParser().parser.regexp.source})|(\\+?inf)|(-inf)`)
|
||||
new RegExp(`(${Grammar.numberRegexSource})|(\\+?inf)|(-inf)`)
|
||||
).map(([_0, n, plusInf, minusInf]) => new this(
|
||||
n ? Number(n) : plusInf ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY
|
||||
))
|
||||
)).label("NumberEntity")
|
||||
|
||||
/** @type {Number} */
|
||||
#value
|
||||
@@ -31,6 +32,12 @@ export default class NumberEntity extends IEntity {
|
||||
}
|
||||
|
||||
toString() {
|
||||
if (this.value === Number.POSITIVE_INFINITY) {
|
||||
return "+inf"
|
||||
}
|
||||
if (this.value === Number.NEGATIVE_INFINITY) {
|
||||
return "-inf"
|
||||
}
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,12 +28,14 @@ import VariableReferenceEntity from "./VariableReferenceEntity.js"
|
||||
|
||||
export default class ObjectEntity extends IEntity {
|
||||
|
||||
#_exported = false
|
||||
get _exported() {
|
||||
return this.#_exported
|
||||
static trailing = true
|
||||
|
||||
#exported = false
|
||||
get exported() {
|
||||
return this.#exported
|
||||
}
|
||||
set _exported(value) {
|
||||
this.#_exported = value
|
||||
set exported(value) {
|
||||
this.#exported = value
|
||||
}
|
||||
|
||||
static attributes = {
|
||||
@@ -130,7 +132,7 @@ export default class ObjectEntity extends IEntity {
|
||||
ScriptVariables: ArrayEntity.of(ScriptVariableEntity),
|
||||
Node: MirroredEntity.of(ObjectReferenceEntity),
|
||||
ExportedNodes: StringEntity,
|
||||
CustomProperties: ArrayEntity.of(AlternativesEntity.accepting(PinEntity, UnknownPinEntity)),
|
||||
CustomProperties: ArrayEntity.of(AlternativesEntity.accepting(PinEntity, UnknownPinEntity)).withDefault().flagSilent(),
|
||||
}
|
||||
static #nameRegex = /^(\w+?)(?:_(\d+))?$/
|
||||
static customPropertyGrammar = P.seq(
|
||||
@@ -144,28 +146,28 @@ export default class ObjectEntity extends IEntity {
|
||||
Grammar.symbolQuoted.map(v => [v, true]),
|
||||
Grammar.symbol.map(v => [v, false]),
|
||||
),
|
||||
P.reg(
|
||||
new RegExp(`\\s*\\(\\s*(\\d+)\\s*\\)\\s*\\=\\s*`),
|
||||
1
|
||||
).map(Number)
|
||||
P.reg(new RegExp(String.raw`\s*\(\s*(\d+)\s*\)\s*\=\s*`), 1).map(Number)
|
||||
)
|
||||
.chain(
|
||||
/** @param {[[String, Boolean], Number]} param */
|
||||
/** @param {[[keyof ObjectEntity.attributes, Boolean], Number]} param */
|
||||
([[symbol, quoted], index]) =>
|
||||
Grammar.grammarFor(this.attributes[symbol])
|
||||
.map(currentValue =>
|
||||
values => {
|
||||
(values[symbol] ??= [])[index] = currentValue
|
||||
Utility.objectSet(values, ["attributes", symbol, "quoted"], quoted)
|
||||
if (!this.attributes[symbol]?.inlined) {
|
||||
if (!values.attributes) {
|
||||
IEntity.defineAttributes(values, {})
|
||||
}
|
||||
Utility.objectSet(values, ["attributes", symbol, "type"], [currentValue.constructor])
|
||||
Utility.objectSet(values, ["attributes", symbol, "inlined"], true)
|
||||
this.attributes[symbol].grammar.map(currentValue =>
|
||||
values => {
|
||||
if (values[symbol] === undefined) {
|
||||
let arrayEntity = ArrayEntity
|
||||
if (quoted != arrayEntity.quoted) {
|
||||
arrayEntity = arrayEntity.flagQuoted(quoted)
|
||||
}
|
||||
if (!arrayEntity.inlined) {
|
||||
arrayEntity = arrayEntity.flagInlined()
|
||||
}
|
||||
values[symbol] = new arrayEntity()
|
||||
}
|
||||
)
|
||||
/** @type {ArrayEntity} */
|
||||
const target = values[symbol]
|
||||
target.values[index] = currentValue
|
||||
}
|
||||
)
|
||||
)
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
@@ -233,73 +235,71 @@ export default class ObjectEntity extends IEntity {
|
||||
super(values)
|
||||
|
||||
// Attributes
|
||||
/** @type {(PinEntity | UnknownPinEntity)[]} */ this.CustomProperties
|
||||
/** @type {Boolean} */ this.bIsPureFunc
|
||||
/** @type {Boolean} */ this.isExported
|
||||
/** @type {FunctionReferenceEntity} */ this.ComponentPropertyName
|
||||
/** @type {FunctionReferenceEntity} */ this.EventReference
|
||||
/** @type {FunctionReferenceEntity} */ this.FunctionReference
|
||||
/** @type {IdentifierEntity} */ this.AdvancedPinDisplay
|
||||
/** @type {IdentifierEntity} */ this.EnabledState
|
||||
/** @type {IntegerEntity} */ this.NodeHeight
|
||||
/** @type {IntegerEntity} */ this.NodePosX
|
||||
/** @type {IntegerEntity} */ this.NodePosY
|
||||
/** @type {IntegerEntity} */ this.NodeWidth
|
||||
/** @type {LinearColorEntity} */ this.CommentColor
|
||||
/** @type {LinearColorEntity} */ this.NodeTitleColor
|
||||
/** @type {MacroGraphReferenceEntity} */ this.MacroGraphReference
|
||||
/** @type {MirroredEntity} */ this.MaterialExpressionEditorX
|
||||
/** @type {MirroredEntity} */ this.MaterialExpressionEditorY
|
||||
/** @type {MirroredEntity} */ this.SizeX
|
||||
/** @type {MirroredEntity} */ this.SizeY
|
||||
/** @type {MirroredEntity} */ this.Text
|
||||
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionX
|
||||
/** @type {MirroredEntity<IntegerEntity>} */ this.PositionY
|
||||
/** @type {MirroredEntity<ObjectReferenceEntity>} */ this.Node
|
||||
/** @type {null[]} */ this.PinTags
|
||||
/** @type {Number} */ this.NumAdditionalInputs
|
||||
/** @type {ObjectReferenceEntity[]} */ this.InputPins
|
||||
/** @type {ObjectReferenceEntity[]} */ this.OutputPins
|
||||
/** @type {ObjectReferenceEntity} */ this.Archetype
|
||||
/** @type {ObjectReferenceEntity} */ this.BlueprintElementInstance
|
||||
/** @type {ObjectReferenceEntity} */ this.BlueprintElementType
|
||||
/** @type {ObjectReferenceEntity} */ this.Class
|
||||
/** @type {ObjectReferenceEntity} */ this.Enum
|
||||
/** @type {ObjectReferenceEntity} */ this.ExportPath
|
||||
/** @type {ObjectReferenceEntity} */ this.FunctionScript
|
||||
/** @type {ObjectReferenceEntity} */ this.Graph
|
||||
/** @type {ObjectReferenceEntity} */ this.MaterialExpression
|
||||
/** @type {ObjectReferenceEntity} */ this.MaterialExpressionComment
|
||||
/** @type {ObjectReferenceEntity} */ this.MaterialFunction
|
||||
/** @type {ObjectReferenceEntity} */ this.ObjectRef
|
||||
/** @type {ObjectReferenceEntity} */ this.PCGNode
|
||||
/** @type {ObjectReferenceEntity} */ this.SettingsInterface
|
||||
/** @type {ObjectReferenceEntity} */ this.StructType
|
||||
/** @type {ObjectReferenceEntity} */ this.TargetType
|
||||
/** @type {ScriptVariableEntity[]} */ this.ScriptVariables
|
||||
/** @type {String[]} */ this.EnumEntries
|
||||
/** @type {String[]} */ this.PinNames
|
||||
/** @type {String} */ this.CustomFunctionName
|
||||
/** @type {String} */ this.DelegatePropertyName
|
||||
/** @type {String} */ this.ExportedNodes
|
||||
/** @type {String} */ this.FunctionDisplayName
|
||||
/** @type {String} */ this.InputName
|
||||
/** @type {String} */ this.Name
|
||||
/** @type {String} */ this.NodeComment
|
||||
/** @type {String} */ this.NodeTitle
|
||||
/** @type {String} */ this.Operation
|
||||
/** @type {String} */ this.OpName
|
||||
/** @type {String} */ this.ProxyFactoryFunctionName
|
||||
/** @type {String} */ this.SubgraphInstance
|
||||
/** @type {String} */ this.Text
|
||||
/** @type {SymbolEntity} */ this.AxisKey
|
||||
/** @type {SymbolEntity} */ this.HiGenGridSize
|
||||
/** @type {SymbolEntity} */ this.InputAxisKey
|
||||
/** @type {SymbolEntity} */ this.InputKey
|
||||
/** @type {SymbolEntity} */ this.InputType
|
||||
/** @type {UnknownPinEntity[]} */ this.AddedPins
|
||||
/** @type {VariableReferenceEntity} */ this.DelegateReference
|
||||
/** @type {VariableReferenceEntity} */ this.VariableReference
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.AddedPins>} */ this.AddedPins
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.AdvancedPinDisplay>} */ this.AdvancedPinDisplay
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Archetype>} */ this.Archetype
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.AxisKey>} */ this.AxisKey
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.bIsPureFunc>} */ this.bIsPureFunc
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.BlueprintElementInstance>} */ this.BlueprintElementInstance
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.BlueprintElementType>} */ this.BlueprintElementType
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Class>} */ this.Class
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.CommentColor>} */ this.CommentColor
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.ComponentPropertyName>} */ this.ComponentPropertyName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.CustomFunctionName>} */ this.CustomFunctionName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.CustomProperties>} */ this.CustomProperties
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.DelegatePropertyName>} */ this.DelegatePropertyName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.DelegateReference>} */ this.DelegateReference
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.EnabledState>} */ this.EnabledState
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Enum>} */ this.Enum
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.EnumEntries>} */ this.EnumEntries
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.EventReference>} */ this.EventReference
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.ExportedNodes>} */ this.ExportedNodes
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.ExportPath>} */ this.ExportPath
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.FunctionDisplayName>} */ this.FunctionDisplayName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.FunctionReference>} */ this.FunctionReference
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.FunctionScript>} */ this.FunctionScript
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Graph>} */ this.Graph
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.HiGenGridSize>} */ this.HiGenGridSize
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.InputAxisKey>} */ this.InputAxisKey
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.InputKey>} */ this.InputKey
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.InputName>} */ this.InputName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.InputPins>} */ this.InputPins
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.InputType>} */ this.InputType
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.MacroGraphReference>} */ this.MacroGraphReference
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpression>} */ this.MaterialExpression
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpressionComment>} */ this.MaterialExpressionComment
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpressionEditorX>} */ this.MaterialExpressionEditorX
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialExpressionEditorY>} */ this.MaterialExpressionEditorY
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.MaterialFunction>} */ this.MaterialFunction
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Name>} */ this.Name
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Node>} */ this.Node
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeComment>} */ this.NodeComment
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeHeight>} */ this.NodeHeight
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodePosX>} */ this.NodePosX
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodePosY>} */ this.NodePosY
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeTitle>} */ this.NodeTitle
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeTitleColor>} */ this.NodeTitleColor
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NodeWidth>} */ this.NodeWidth
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.NumAdditionalInputs>} */ this.NumAdditionalInputs
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.ObjectRef>} */ this.ObjectRef
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Operation>} */ this.Operation
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.OpName>} */ this.OpName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.OutputPins>} */ this.OutputPins
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.PCGNode>} */ this.PCGNode
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.PinNames>} */ this.PinNames
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.PositionX>} */ this.PositionX
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.PositionY>} */ this.PositionY
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.ProxyFactoryFunctionName>} */ this.ProxyFactoryFunctionName
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.ScriptVariables>} */ this.ScriptVariables
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.SettingsInterface>} */ this.SettingsInterface
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.SizeX>} */ this.SizeX
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.SizeY>} */ this.SizeY
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.StructType>} */ this.StructType
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.SubgraphInstance>} */ this.SubgraphInstance
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.TargetType>} */ this.TargetType
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Text>} */ this.Text
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.Text>} */ this.Text
|
||||
/** @type {InstanceType<typeof ObjectEntity.attributes.VariableReference>} */ this.VariableReference
|
||||
|
||||
// Legacy nodes pins
|
||||
if (this["Pins"] instanceof Array) {
|
||||
@@ -481,10 +481,7 @@ export default class ObjectEntity extends IEntity {
|
||||
}
|
||||
|
||||
getCustomproperties(canCreate = false) {
|
||||
if (canCreate && !this.CustomProperties) {
|
||||
this.CustomProperties = []
|
||||
}
|
||||
return this.CustomProperties ?? []
|
||||
return this.CustomProperties.values
|
||||
}
|
||||
|
||||
/** @returns {PinEntity[]} */
|
||||
@@ -615,4 +612,44 @@ export default class ObjectEntity extends IEntity {
|
||||
additionalPinInserter() {
|
||||
return nodeVariadic(this)
|
||||
}
|
||||
|
||||
/** @param {String} key */
|
||||
showProperty(key) {
|
||||
switch (key) {
|
||||
case "Class":
|
||||
case "Name":
|
||||
case "Archetype":
|
||||
case "ExportPath":
|
||||
case "CustomProperties":
|
||||
// Serielized separately, check doWrite()
|
||||
return false
|
||||
}
|
||||
return super.showProperty(key)
|
||||
}
|
||||
|
||||
toString(
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
printKey = this.Self().printKey,
|
||||
) {
|
||||
const moreIndentation = indentation + Configuration.indentation
|
||||
let result = indentation + "Begin Object"
|
||||
+ (this.Class?.type || this.Class?.path ? ` Class=${this.Class.toString(insideString)}` : "")
|
||||
+ (this.Name ? ` Name=${this.Name.toString(insideString)}` : "")
|
||||
+ (this.Archetype ? ` Archetype=${this.Archetype.toString(insideString)}` : "")
|
||||
+ (this.ExportPath?.type || this.ExportPath?.path ? ` ExportPath=${this.ExportPath.toString(insideString)}` : "")
|
||||
+ "\n"
|
||||
+ super.toString(insideString, moreIndentation, k => this[k] instanceof ObjectEntity ? "" : k)
|
||||
+ (!this.CustomProperties.Self().ignored
|
||||
? this.getCustomproperties().map(pin =>
|
||||
moreIndentation
|
||||
+ printKey("CustomProperties ")
|
||||
+ pin.toString(insideString)
|
||||
+ this.Self().attributeSeparator
|
||||
).join("")
|
||||
: ""
|
||||
)
|
||||
+ indentation + "End Object"
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,14 @@ export default class ObjectReferenceEntity extends IEntity {
|
||||
+ `'(${Grammar.Regex.InsideSingleQuotedString.source})'`
|
||||
)).map(([_0, a, b]) => a ?? b)
|
||||
static typeReference = P.reg(
|
||||
// @ts-expect-error
|
||||
new RegExp(Grammar.Regex.Path.source + "|" + Grammar.symbol.getParser().regexp.source)
|
||||
)
|
||||
static fullReferenceGrammar = P.regArray(
|
||||
new RegExp(
|
||||
// @ts-expect-error
|
||||
"(" + this.typeReference.getParser().regexp.source + ")"
|
||||
// @ts-expect-error
|
||||
+ "(?:" + this.#quotedParser.getParser().parser.regexp.source + ")"
|
||||
)
|
||||
).map(([full, type, ...path]) => new this(type, path.find(v => v), full))
|
||||
@@ -30,7 +33,7 @@ export default class ObjectReferenceEntity extends IEntity {
|
||||
this.fullReferenceSerializedGrammar,
|
||||
this.fullReferenceGrammar,
|
||||
this.typeReferenceGrammar,
|
||||
)
|
||||
).label("ObjectReferenceEntity")
|
||||
|
||||
#type
|
||||
get type() {
|
||||
@@ -72,7 +75,11 @@ export default class ObjectReferenceEntity extends IEntity {
|
||||
return Utility.getNameFromPath(this.path.replace(/_C$/, ""), dropCounter)
|
||||
}
|
||||
|
||||
toString() {
|
||||
toString(
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
printKey = this.Self().printKey,
|
||||
) {
|
||||
return this.full
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
|
||||
export default class PathSymbolEntity extends IEntity {
|
||||
|
||||
static grammar = Grammar.symbol.map(v => new this(v))
|
||||
|
||||
constructor(value = "") {
|
||||
super()
|
||||
this.value = value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import Vector2DEntity from "./Vector2DEntity.js"
|
||||
import Vector4DEntity from "./Vector4DEntity.js"
|
||||
import VectorEntity from "./VectorEntity.js"
|
||||
|
||||
/** @template {TerminalAttribute} T */
|
||||
/** @template {IEntity} T */
|
||||
export default class PinEntity extends IEntity {
|
||||
|
||||
static lookbehind = "INVTEXT"
|
||||
@@ -120,25 +120,23 @@ export default class PinEntity extends IEntity {
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
/** @type {ObjectEntity} */ this.objectEntity
|
||||
/** @type {Number} */ this.pinIndex
|
||||
/** @type {GuidEntity} */ this.PinId
|
||||
/** @type {String} */ this.PinName
|
||||
/** @type {LocalizedTextEntity | String} */ this.PinFriendlyName
|
||||
/** @type {String} */ this.PinToolTip
|
||||
/** @type {String} */ this.Direction
|
||||
/** @type {PinTypeEntity} */ this.PinType
|
||||
/** @type {PinReferenceEntity[]} */ this.LinkedTo
|
||||
/** @type {T} */ this.DefaultValue
|
||||
/** @type {String} */ this.AutogeneratedDefaultValue
|
||||
/** @type {ObjectReferenceEntity} */ this.DefaultObject
|
||||
/** @type {GuidEntity} */ this.PersistentGuid
|
||||
/** @type {Boolean} */ this.bHidden
|
||||
/** @type {Boolean} */ this.bNotConnectable
|
||||
/** @type {Boolean} */ this.bDefaultValueIsReadOnly
|
||||
/** @type {Boolean} */ this.bDefaultValueIsIgnored
|
||||
/** @type {Boolean} */ this.bAdvancedView
|
||||
/** @type {Boolean} */ this.bOrphanedPin
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.PinId>} */ this.PinId
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.PinName>} */ this.PinName
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.PinFriendlyName>} */ this.PinFriendlyName
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.PinToolTip>} */ this.PinToolTip
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.Direction>} */ this.Direction
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.PinType>} */ this.PinType
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.LinkedTo>} */ this.LinkedTo
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.DefaultValue>} */ this.DefaultValue
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.AutogeneratedDefaultValue>} */ this.AutogeneratedDefaultValue
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.DefaultObject>} */ this.DefaultObject
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.PersistentGuid>} */ this.PersistentGuid
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.bHidden>} */ this.bHidden
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.bNotConnectable>} */ this.bNotConnectable
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.bDefaultValueIsReadOnly>} */ this.bDefaultValueIsReadOnly
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.bDefaultValueIsIgnored>} */ this.bDefaultValueIsIgnored
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.bAdvancedView>} */ this.bAdvancedView
|
||||
/** @type {InstanceType<typeof PinEntity.attributes.bOrphanedPin>} */ this.bOrphanedPin
|
||||
}
|
||||
|
||||
/** @param {ObjectEntity} objectEntity */
|
||||
@@ -227,7 +225,6 @@ export default class PinEntity extends IEntity {
|
||||
|
||||
getDefaultValue(maybeCreate = false) {
|
||||
if (this.DefaultValue === undefined && maybeCreate) {
|
||||
// @ts-expect-error
|
||||
this.DefaultValue = new (this.getEntityType(true))()
|
||||
}
|
||||
return this.DefaultValue
|
||||
@@ -271,10 +268,7 @@ export default class PinEntity extends IEntity {
|
||||
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
|
||||
)
|
||||
if (!linkFound) {
|
||||
(this.LinkedTo ??= []).push(new PinReferenceEntity({
|
||||
objectName: targetObjectName,
|
||||
pinGuid: targetPinEntity.PinId,
|
||||
}))
|
||||
(this.LinkedTo ??= []).push(new PinReferenceEntity(targetObjectName, targetPinEntity.PinId,))
|
||||
return true
|
||||
}
|
||||
return false // Already linked
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import P from "parsernostrum"
|
||||
import GuidEntity from "./GuidEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import PathSymbolEntity from "./PathSymbolEntity.js"
|
||||
import SymbolEntity from "./SymbolEntity.js"
|
||||
|
||||
export default class PinReferenceEntity extends IEntity {
|
||||
|
||||
static grammar = P.seq(
|
||||
PathSymbolEntity.grammar,
|
||||
SymbolEntity.grammar,
|
||||
P.whitespace,
|
||||
GuidEntity.grammar
|
||||
).map(([objectName, _1, pinGuid]) => new this(objectName, pinGuid))
|
||||
)
|
||||
.map(([objectName, _1, pinGuid]) => new this(objectName, pinGuid))
|
||||
.label("PinReferenceEntity")
|
||||
|
||||
/**
|
||||
* @param {PathSymbolEntity} objectName
|
||||
* @param {SymbolEntity} objectName
|
||||
* @param {GuidEntity} pinGuid
|
||||
*/
|
||||
constructor(objectName = null, pinGuid = null) {
|
||||
@@ -20,4 +22,12 @@ export default class PinReferenceEntity extends IEntity {
|
||||
this.objectName = objectName
|
||||
this.pinGuid = pinGuid
|
||||
}
|
||||
|
||||
toString(
|
||||
insideString = false,
|
||||
indentation = "",
|
||||
printKey = this.Self().printKey,
|
||||
) {
|
||||
return this.objectName.toString() + " " + this.pinGuid.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import BooleanEntity from "./BooleanEntity.js"
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity.js"
|
||||
import IEntity from "./IEntity.js"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity.js"
|
||||
import PathSymbolEntity from "./PathSymbolEntity.js"
|
||||
import StringEntity from "./StringEntity.js"
|
||||
import SymbolEntity from "./SymbolEntity.js"
|
||||
|
||||
export default class PinTypeEntity extends IEntity {
|
||||
|
||||
@@ -15,29 +15,29 @@ export default class PinTypeEntity extends IEntity {
|
||||
PinSubCategoryObject: ObjectReferenceEntity.withDefault(),
|
||||
PinSubCategoryMemberReference: FunctionReferenceEntity.withDefault(type => null),
|
||||
PinValueType: PinTypeEntity.withDefault(),
|
||||
ContainerType: PathSymbolEntity,
|
||||
ContainerType: SymbolEntity,
|
||||
bIsReference: BooleanEntity.withDefault(),
|
||||
bIsConst: BooleanEntity.withDefault(),
|
||||
bIsWeakPointer: BooleanEntity.withDefault(),
|
||||
bIsUObjectWrapper: BooleanEntity.withDefault(),
|
||||
bSerializeAsSinglePrecisionFloat: BooleanEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("PinTypeEntity")
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
/** @type {String} */ this.PinCategory
|
||||
/** @type {String} */ this.PinSubCategory
|
||||
/** @type {ObjectReferenceEntity} */ this.PinSubCategoryObject
|
||||
/** @type {FunctionReferenceEntity} */ this.PinSubCategoryMemberReference
|
||||
/** @type {PinTypeEntity} */ this.PinValueType
|
||||
/** @type {PathSymbolEntity} */ this.ContainerType
|
||||
/** @type {Boolean} */ this.bIsReference
|
||||
/** @type {Boolean} */ this.bIsConst
|
||||
/** @type {Boolean} */ this.bIsWeakPointer
|
||||
/** @type {Boolean} */ this.bIsUObjectWrapper
|
||||
/** @type {Boolean} */ this.bIsUObjectWrapper
|
||||
/** @type {Boolean} */ this.bSerializeAsSinglePrecisionFloat
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinCategory>} */ this.PinCategory
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinSubCategory>} */ this.PinSubCategory
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinSubCategoryObject>} */ this.PinSubCategoryObject
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinSubCategoryMemberReference>} */ this.PinSubCategoryMemberReference
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.PinValueType>} */ this.PinValueType
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.ContainerType>} */ this.ContainerType
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsReference>} */ this.bIsReference
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsConst>} */ this.bIsConst
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsWeakPointer>} */ this.bIsWeakPointer
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsUObjectWrapper>} */ this.bIsUObjectWrapper
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.bIsUObjectWrapper>} */ this.bIsUObjectWrapper
|
||||
/** @type {InstanceType<typeof PinTypeEntity.attributes.bSerializeAsSinglePrecisionFloat>} */ this.bSerializeAsSinglePrecisionFloat
|
||||
}
|
||||
|
||||
/** @param {PinTypeEntity} other */
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import Vector2DEntity from "./Vector2DEntity.js"
|
||||
|
||||
export default class RBSerializationVector2DEntity extends Vector2DEntity {
|
||||
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
/X\s*=\s*/.source + "(?<x>" + P.number.getParser().parser.regexp.source + ")"
|
||||
/X\s*=\s*/.source + "(?<x>" + Grammar.numberRegexSource + ")"
|
||||
+ "\\s+"
|
||||
+ /Y\s*=\s*/.source + "(?<y>" + P.number.getParser().parser.regexp.source + ")"
|
||||
+ /Y\s*=\s*/.source + "(?<y>" + Grammar.numberRegexSource + ")"
|
||||
)).map(({ groups: { x, y } }) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
})),
|
||||
Vector2DEntity.grammar
|
||||
)
|
||||
).label("RBSerializationVector2DEntity")
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ export default class RotatorEntity extends IEntity {
|
||||
P: NumberEntity.withDefault(),
|
||||
Y: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this, false)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("RotatorEntity")
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {NumberEntity} */ this.R
|
||||
/** @type {NumberEntity} */ this.P
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
/** @type {InstanceType<typeof RotatorEntity.attributes.R>} */ this.R
|
||||
/** @type {InstanceType<typeof RotatorEntity.attributes.P>} */ this.P
|
||||
/** @type {InstanceType<typeof RotatorEntity.attributes.Y>} */ this.Y
|
||||
}
|
||||
|
||||
getRoll() {
|
||||
|
||||
@@ -10,11 +10,11 @@ export default class ScriptVariableEntity extends IEntity {
|
||||
ScriptVariable: ObjectReferenceEntity,
|
||||
OriginalChangeId: GuidEntity,
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("ScriptVariableEntity")
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
/** @type {ObjectReferenceEntity} */ this.ScriptVariable
|
||||
/** @type {GuidEntity} */ this.OriginalChangeId
|
||||
/** @type {InstanceType<typeof ScriptVariableEntity.attributes.ScriptVariable>} */ this.ScriptVariable
|
||||
/** @type {InstanceType<typeof ScriptVariableEntity.attributes.OriginalChangeId>} */ this.OriginalChangeId
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import RotatorEntity from "./RotatorEntity.js"
|
||||
|
||||
export default class SimpleSerializationRotatorEntity extends RotatorEntity {
|
||||
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
`(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
)).map(([_, p, y, r]) => new this({
|
||||
R: Number(r),
|
||||
P: Number(p),
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import Vector2DEntity from "./Vector2DEntity.js"
|
||||
|
||||
export default class SimpleSerializationVector2DEntity extends Vector2DEntity {
|
||||
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
`(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
)).map(([_, x, y]) => new this({
|
||||
X: Number(x),
|
||||
Y: Number(y),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import Vector4DEntity from "./Vector4DEntity.js"
|
||||
|
||||
export default class SimpleSerializationVector4DEntity extends Vector4DEntity {
|
||||
@@ -6,16 +7,16 @@ export default class SimpleSerializationVector4DEntity extends Vector4DEntity {
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
const number = P.number.getParser().parser.regexp.source
|
||||
const number = Grammar.numberRegexSource
|
||||
return P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
`(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
))
|
||||
.map(([_0, x, y, z, w]) => new this({
|
||||
X: Number(x),
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import P from "parsernostrum"
|
||||
import Grammar from "../serialization/Grammar.js"
|
||||
import VectorEntity from "./VectorEntity.js"
|
||||
|
||||
export default class SimpleSerializationVectorEntity extends VectorEntity {
|
||||
|
||||
static grammar = P.alt(
|
||||
P.regArray(new RegExp(
|
||||
`(${P.number.getParser().parser.regexp.source})`
|
||||
`(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
+ String.raw`\s*,\s*`
|
||||
+ `(${P.number.getParser().parser.regexp.source})`
|
||||
+ `(${Grammar.numberRegexSource})`
|
||||
))
|
||||
.map(([_0, x, y, z]) => new this({
|
||||
X: Number(x),
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import P from "parsernostrum"
|
||||
import IEntity from "./IEntity.js"
|
||||
import Utility from "../Utility.js"
|
||||
import IPrintableEntity from "./IPrintableEntity.js"
|
||||
|
||||
export default class StringEntity extends IEntity {
|
||||
export default class StringEntity extends IPrintableEntity {
|
||||
|
||||
static grammar = P.doubleQuotedString.map(insideString => Utility.unescapeString(insideString))
|
||||
static grammar = P.doubleQuotedString
|
||||
.map(insideString => new this(Utility.unescapeString(insideString)))
|
||||
.label("StringEntity")
|
||||
|
||||
/** @param {String} value */
|
||||
constructor(value = "") {
|
||||
@@ -12,11 +14,19 @@ export default class StringEntity extends IEntity {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
print() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value.toString()
|
||||
toString(insideString = false) {
|
||||
let result = Utility.escapeString(this.value)
|
||||
if (!insideString) {
|
||||
result = `"${result}"`
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import IEntity from "./IEntity.js"
|
||||
|
||||
export default class SymbolEntity extends IEntity {
|
||||
|
||||
static grammar = Grammar.symbol.map(v => new this(v))
|
||||
static grammar = Grammar.symbol.map(v => new this(v)).label("SymbolEntity")
|
||||
|
||||
/** @param {String} value */
|
||||
constructor(value = "") {
|
||||
|
||||
@@ -4,7 +4,6 @@ import IEntity from "./IEntity.js"
|
||||
|
||||
export default class UnknownKeysEntity extends IEntity {
|
||||
|
||||
|
||||
static grammar = P.seq(
|
||||
// Lookbehind
|
||||
P.reg(new RegExp(`(${Grammar.Regex.Path.source}|${Grammar.Regex.Symbol.source}\\s*)?\\(\\s*`), 1),
|
||||
@@ -24,7 +23,7 @@ export default class UnknownKeysEntity extends IEntity {
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new this(values)
|
||||
})
|
||||
}).label("UnknownKeysEntity")
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
|
||||
@@ -16,5 +16,5 @@ export default class UnknownPinEntity extends PinEntity {
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
return new this(values)
|
||||
})
|
||||
}).label("UnknownPinEntity")
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@ export default class VariableReferenceEntity extends IEntity {
|
||||
MemberGuid: GuidEntity,
|
||||
bSelfContext: BooleanEntity,
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("VariableReferenceEntity")
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {String} */ this.MemberName
|
||||
/** @type {GuidEntity} */ this.GuidEntity
|
||||
/** @type {Boolean} */ this.bSelfContext
|
||||
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.MemberScope>} */ this.MemberScope
|
||||
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.MemberName>} */ this.MemberName
|
||||
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.MemberGuid>} */ this.MemberGuid
|
||||
/** @type {InstanceType<typeof VariableReferenceEntity.attributes.bSelfContext>} */ this.bSelfContext
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@ export default class Vector2DEntity extends IEntity {
|
||||
X: NumberEntity.withDefault(),
|
||||
Y: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this, false)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("Vector2DEntity")
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {NumberEntity} */ this.X
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
/** @type {InstanceType<typeof Vector2DEntity.attributes.X>} */ this.X
|
||||
/** @type {InstanceType<typeof Vector2DEntity.attributes.Y>} */ this.Y
|
||||
}
|
||||
|
||||
/** @returns {[Number, Number]} */
|
||||
|
||||
@@ -11,14 +11,14 @@ export default class Vector4DEntity extends IEntity {
|
||||
Z: NumberEntity.withDefault(),
|
||||
W: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(Vector4DEntity, false)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("Vector4DEntity")
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {NumberEntity} */ this.X
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
/** @type {NumberEntity} */ this.Z
|
||||
/** @type {NumberEntity} */ this.W
|
||||
/** @type {InstanceType<typeof Vector4DEntity.attributes.X>} */ this.X
|
||||
/** @type {InstanceType<typeof Vector4DEntity.attributes.Y>} */ this.Y
|
||||
/** @type {InstanceType<typeof Vector4DEntity.attributes.Z>} */ this.Z
|
||||
/** @type {InstanceType<typeof Vector4DEntity.attributes.W>} */ this.W
|
||||
}
|
||||
|
||||
/** @returns {[Number, Number, Number, Number]} */
|
||||
|
||||
@@ -10,13 +10,13 @@ export default class VectorEntity extends IEntity {
|
||||
Y: NumberEntity.withDefault(),
|
||||
Z: NumberEntity.withDefault(),
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(VectorEntity, false)
|
||||
static grammar = Grammar.createEntityGrammar(this).label("VectorEntity")
|
||||
|
||||
constructor(values) {
|
||||
super(values)
|
||||
/** @type {NumberEntity} */ this.X
|
||||
/** @type {NumberEntity} */ this.Y
|
||||
/** @type {NumberEntity} */ this.Z
|
||||
/** @type {InstanceType<typeof VectorEntity.attributes.X>} */ this.X
|
||||
/** @type {InstanceType<typeof VectorEntity.attributes.Y>} */ this.Y
|
||||
/** @type {InstanceType<typeof VectorEntity.attributes.X>} */ this.Z
|
||||
}
|
||||
|
||||
/** @returns {[Number, Number, Number]} */
|
||||
|
||||
@@ -8,6 +8,10 @@ import Serializable from "./Serializable.js"
|
||||
|
||||
export default class Grammar {
|
||||
|
||||
/** @type {String} */
|
||||
// @ts-expect-error
|
||||
static numberRegexSource = Parsernostrum.number.getParser().parser.regexp.source
|
||||
|
||||
static separatedBy = (source, separator, min = 1) =>
|
||||
new RegExp(
|
||||
source + "(?:" + separator + source + ")"
|
||||
@@ -188,46 +192,32 @@ export default class Grammar {
|
||||
|
||||
/**
|
||||
* @template {IEntity} T
|
||||
* @param {(new (...args: any) => T) & EntityConstructor} entityType
|
||||
* @param {Boolean | Number} acceptUnknownKeys Number to specify the limit or true, to let it be a reasonable value
|
||||
* @param {new (...args: any) => T} entityType
|
||||
* @return {Parsernostrum<T>}
|
||||
*/
|
||||
static createEntityGrammar(entityType, acceptUnknownKeys = true, entriesSeparator = this.commaSeparation) {
|
||||
const lookbehind = entityType.attributes.lookbehind.default
|
||||
static createEntityGrammar(entityType, entriesSeparator = this.commaSeparation) {
|
||||
const lookbehind = entityType.lookbehind instanceof Array ? entityType.lookbehind.join("|") : entityType.lookbehind
|
||||
return Parsernostrum.seq(
|
||||
Parsernostrum.reg(
|
||||
lookbehind instanceof Union
|
||||
? new RegExp(`(${lookbehind.values.reduce((acc, cur) => acc + "|" + cur)})\\s*\\(\\s*`)
|
||||
: lookbehind.constructor == String && lookbehind.length > 0
|
||||
? new RegExp(`(${lookbehind})\\s*\\(\\s*`)
|
||||
: /()\(\s*/,
|
||||
1
|
||||
),
|
||||
Parsernostrum.reg(new RegExp(String.raw`(${lookbehind})\s*\(\s*`), 1),
|
||||
this.createAttributeGrammar(entityType).sepBy(entriesSeparator),
|
||||
Parsernostrum.reg(/\s*(?:,\s*)?\)/), // trailing comma
|
||||
Parsernostrum.reg(/\s*(,\s*)?\)/, 1), // optional trailing comma
|
||||
)
|
||||
.map(([lookbehind, attributes, _2]) => {
|
||||
.map(([lookbehind, attributes, trailing]) => {
|
||||
let values = {}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
if (lookbehind.length) {
|
||||
values.lookbehind = lookbehind
|
||||
values["#lookbehind"] = lookbehind
|
||||
}
|
||||
attributes.forEach(attributeSetter => attributeSetter(values))
|
||||
values["#trailing"] = trailing !== undefined
|
||||
return values
|
||||
})
|
||||
// Decide if we accept the entity or not. It is accepted if it doesn't have too many unexpected keys
|
||||
.chain(values => {
|
||||
let totalKeys = Object.keys(values)
|
||||
let missingKey
|
||||
// Check missing values
|
||||
if (
|
||||
Object.keys(/** @type {AttributeDeclarations} */(entityType.attributes))
|
||||
.filter(key => entityType.attributes[key].expected)
|
||||
.find(key => !totalKeys.includes(key) && (missingKey = key))
|
||||
) {
|
||||
return Parsernostrum.failure()
|
||||
if (entityType.lookbehind instanceof Array || entityType.lookbehind !== lookbehind) {
|
||||
entityType = entityType.withLookbehind(lookbehind)
|
||||
}
|
||||
const unknownKeys = Object.keys(values).filter(key => !(key in entityType.attributes)).length
|
||||
if (!acceptUnknownKeys && unknownKeys > 0) {
|
||||
return Parsernostrum.failure()
|
||||
if (entityType.trailing !== values["#trailing"]) {
|
||||
entityType = entityType.flagTrailing(values["#trailing"])
|
||||
}
|
||||
return Parsernostrum.success().map(() => new entityType(values))
|
||||
})
|
||||
|
||||
@@ -19,7 +19,6 @@ import MacroGraphReferenceEntity from "../entity/MacroGraphReferenceEntity.js"
|
||||
import MirroredEntity from "../entity/MirroredEntity.js"
|
||||
import ObjectEntity from "../entity/ObjectEntity.js"
|
||||
import ObjectReferenceEntity from "../entity/ObjectReferenceEntity.js"
|
||||
import PathSymbolEntity from "../entity/PathSymbolEntity.js"
|
||||
import PinEntity from "../entity/PinEntity.js"
|
||||
import PinReferenceEntity from "../entity/PinReferenceEntity.js"
|
||||
import PinTypeEntity from "../entity/PinTypeEntity.js"
|
||||
@@ -49,34 +48,34 @@ import StringEntity from "../entity/StringEntity.js"
|
||||
import ArrayEntity from "../entity/ArrayEntity.js"
|
||||
import AlternativesEntity from "../entity/AlternativesEntity.js"
|
||||
|
||||
Grammar.unknownValue =
|
||||
Parsernostrum.alt(
|
||||
// Remember to keep the order, otherwise parsing might fail
|
||||
BooleanEntity.grammar,
|
||||
GuidEntity.grammar,
|
||||
Parsernostrum.str("None").map(() => ObjectReferenceEntity.createNoneInstance()),
|
||||
Grammar.null,
|
||||
NumberEntity.grammar,
|
||||
ObjectReferenceEntity.fullReferenceGrammar,
|
||||
StringEntity.grammar,
|
||||
LocalizedTextEntity.grammar,
|
||||
InvariantTextEntity.grammar,
|
||||
FormatTextEntity.grammar,
|
||||
PinReferenceEntity.grammar,
|
||||
Vector4DEntity.grammar,
|
||||
VectorEntity.grammar,
|
||||
RotatorEntity.grammar,
|
||||
LinearColorEntity.grammar,
|
||||
Vector2DEntity.grammar,
|
||||
UnknownKeysEntity.grammar,
|
||||
SymbolEntity.grammar,
|
||||
ArrayEntity.of(PinReferenceEntity).grammar,
|
||||
ArrayEntity.of(AlternativesEntity.accepting(NumberEntity, StringEntity, SymbolEntity)).grammar,
|
||||
Parsernostrum.lazy(() => ArrayEntity.createGrammar(Grammar.unknownValue)),
|
||||
)
|
||||
|
||||
export default function initializeSerializerFactory() {
|
||||
|
||||
Grammar.unknownValue =
|
||||
Parsernostrum.alt(
|
||||
// Remember to keep the order, otherwise parsing might fail
|
||||
BooleanEntity.grammar,
|
||||
GuidEntity.grammar,
|
||||
Parsernostrum.str("None").map(() => ObjectReferenceEntity.createNoneInstance()),
|
||||
Grammar.null,
|
||||
NumberEntity.grammar,
|
||||
ObjectReferenceEntity.fullReferenceGrammar,
|
||||
StringEntity.grammar,
|
||||
LocalizedTextEntity.grammar,
|
||||
InvariantTextEntity.grammar,
|
||||
FormatTextEntity.grammar,
|
||||
PinReferenceEntity.grammar,
|
||||
Vector4DEntity.grammar,
|
||||
VectorEntity.grammar,
|
||||
RotatorEntity.grammar,
|
||||
LinearColorEntity.grammar,
|
||||
Vector2DEntity.grammar,
|
||||
UnknownKeysEntity.grammar,
|
||||
SymbolEntity.grammar,
|
||||
ArrayEntity.of(PinReferenceEntity).grammar,
|
||||
ArrayEntity.of(AlternativesEntity.accepting(NumberEntity, StringEntity, SymbolEntity)).grammar,
|
||||
Parsernostrum.lazy(() => ArrayEntity.createGrammar(Grammar.unknownValue)),
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
null,
|
||||
new CustomSerializer(
|
||||
@@ -122,26 +121,6 @@ export default function initializeSerializerFactory() {
|
||||
)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
ByteEntity,
|
||||
new ToStringSerializer(ByteEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
ColorChannelEntity,
|
||||
new ToStringSerializer(ColorChannelEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
EnumDisplayValueEntity,
|
||||
new ToStringSerializer(EnumDisplayValueEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
EnumEntity,
|
||||
new ToStringSerializer(EnumEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
FormatTextEntity,
|
||||
new CustomSerializer(
|
||||
@@ -156,94 +135,11 @@ export default function initializeSerializerFactory() {
|
||||
FormatTextEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
FunctionReferenceEntity,
|
||||
new Serializer(FunctionReferenceEntity, Serializer.bracketsWrapped)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
GuidEntity,
|
||||
new ToStringSerializer(GuidEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
IdentifierEntity,
|
||||
new ToStringSerializer(IdentifierEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
Integer64Entity,
|
||||
new ToStringSerializer(Integer64Entity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
IntegerEntity,
|
||||
new ToStringSerializer(IntegerEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
InvariantTextEntity,
|
||||
new Serializer(InvariantTextEntity, (entity, v) => `${entity.getLookbehind()}(${v})`, ", ", false, "", () => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
KeyBindingEntity,
|
||||
new Serializer(KeyBindingEntity, Serializer.bracketsWrapped)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
LinearColorEntity,
|
||||
new Serializer(LinearColorEntity, Serializer.bracketsWrapped)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
LocalizedTextEntity,
|
||||
new Serializer(LocalizedTextEntity, (entity, v) => `${entity.getLookbehind()}(${v})`, ", ", false, "", () => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
MacroGraphReferenceEntity,
|
||||
new Serializer(MacroGraphReferenceEntity, Serializer.bracketsWrapped)
|
||||
)
|
||||
|
||||
SerializerFactory.registeOrSerializer(
|
||||
MirroredEntity,
|
||||
new CustomSerializer(
|
||||
(v, insideString) => SerializerFactory.getSerializer(v.getTargetType()).write(v.get(), insideString),
|
||||
MirroredEntity
|
||||
)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
Number,
|
||||
new ToStringSerializer(Number)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
ObjectEntity,
|
||||
new ObjectSerializer()
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
ObjectReferenceEntity,
|
||||
new ToStringSerializer(ObjectReferenceEntity, false)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PathSymbolEntity,
|
||||
new ToStringSerializer(PathSymbolEntity)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinEntity,
|
||||
new Serializer(PinEntity, (entity, v) => `${entity.getLookbehind()} (${v})`, ",", true)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinReferenceEntity,
|
||||
new Serializer(PinReferenceEntity, undefined, " ", false, "", () => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinTypeEntity,
|
||||
new Serializer(PinTypeEntity)
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { expect, test } from "@playwright/test"
|
||||
import Utility from "../js/Utility.js"
|
||||
import ArrayEntity from "../js/entity/ArrayEntity.js"
|
||||
import FormatTextEntity from "../js/entity/FormatTextEntity.js"
|
||||
import GuidEntity from "../js/entity/GuidEntity.js"
|
||||
import IntegerEntity from "../js/entity/IntegerEntity.js"
|
||||
import KeyBindingEntity from "../js/entity/KeyBindingEntity.js"
|
||||
import LinearColorEntity from "../js/entity/LinearColorEntity.js"
|
||||
import NumberEntity from "../js/entity/NumberEntity.js"
|
||||
import ObjectReferenceEntity from "../js/entity/ObjectReferenceEntity.js"
|
||||
import PinEntity from "../js/entity/PinEntity.js"
|
||||
import RotatorEntity from "../js/entity/RotatorEntity.js"
|
||||
import SimpleSerializationRotatorEntity from "../js/entity/SimpleSerializationRotatorEntity.js"
|
||||
import SimpleSerializationVector2DEntity from "../js/entity/SimpleSerializationVector2DEntity.js"
|
||||
import SimpleSerializationVectorEntity from "../js/entity/SimpleSerializationVectorEntity.js"
|
||||
import StringEntity from "../js/entity/StringEntity.js"
|
||||
import SymbolEntity from "../js/entity/SymbolEntity.js"
|
||||
import UnknownKeysEntity from "../js/entity/UnknownKeysEntity.js"
|
||||
import Vector2DEntity from "../js/entity/Vector2DEntity.js"
|
||||
@@ -23,30 +26,48 @@ test.beforeAll(() => initializeSerializerFactory())
|
||||
|
||||
test.describe.configure({ mode: "parallel" })
|
||||
|
||||
test("Array", () => {
|
||||
const serializer = SerializerFactory.getSerializer(Array)
|
||||
test("ArrayEntity", () => {
|
||||
let grammar = ArrayEntity.grammar
|
||||
|
||||
expect(serializer.read("()")).toStrictEqual([])
|
||||
expect(serializer.read("( )")).toStrictEqual([])
|
||||
expect(serializer.read("(1, 2, 3, 4, 5, 6)")).toStrictEqual([1, 2, 3, 4, 5, 6])
|
||||
expect(serializer.read(`(
|
||||
expect(grammar.parse("()")).toEqual(new ArrayEntity([]))
|
||||
expect(grammar.parse("( )")).toEqual(new ArrayEntity([]))
|
||||
expect(grammar.parse("(1, 2, 3, 4, 5, 6)")).toEqual(new ArrayEntity([
|
||||
new NumberEntity(1),
|
||||
new NumberEntity(2),
|
||||
new NumberEntity(3),
|
||||
new NumberEntity(4),
|
||||
new NumberEntity(5),
|
||||
new NumberEntity(6),
|
||||
]))
|
||||
expect(ArrayEntity.of(NumberEntity).grammar.parse("(2,4,6,8)")).toEqual(new ArrayEntity([
|
||||
new NumberEntity(2),
|
||||
new NumberEntity(4),
|
||||
new NumberEntity(6),
|
||||
new NumberEntity(8),
|
||||
]))
|
||||
expect(ArrayEntity.of(IntegerEntity).grammar.parse("(-0, -1, -2)")).toEqual(new ArrayEntity([
|
||||
new IntegerEntity(0),
|
||||
new IntegerEntity(-1),
|
||||
new IntegerEntity(-2),
|
||||
]))
|
||||
expect(() => ArrayEntity.of(IntegerEntity).grammar.parse("(-1, -2.1, -3)")).toThrowError()
|
||||
expect(grammar.parse(`(
|
||||
"alpha",
|
||||
"beta",
|
||||
123,
|
||||
3BEF2168446CAA32D5B54289FAB2F0BA,
|
||||
Some(a=1, b="2")
|
||||
)`)).toStrictEqual([
|
||||
"alpha",
|
||||
"beta",
|
||||
123,
|
||||
)`)).toStrictEqual(new ArrayEntity([
|
||||
new StringEntity("alpha"),
|
||||
new StringEntity("beta"),
|
||||
new NumberEntity(123),
|
||||
new GuidEntity("3BEF2168446CAA32D5B54289FAB2F0BA"),
|
||||
new UnknownKeysEntity({
|
||||
lookbehind: "Some",
|
||||
new (UnknownKeysEntity.withLookbehind("Some"))({
|
||||
a: 1,
|
||||
b: "2",
|
||||
})
|
||||
])
|
||||
expect(serializer.read(`(
|
||||
]))
|
||||
expect(grammar.parse(`(
|
||||
A(first = (9,8,7,6,5), second = 00000000000000000000000000000000),
|
||||
B(key="hello"),
|
||||
)`)).toStrictEqual([
|
||||
@@ -62,9 +83,9 @@ test("Array", () => {
|
||||
])
|
||||
|
||||
// Nested
|
||||
expect(serializer.read("((1, 2), (3, 4))")).toStrictEqual([[1, 2], [3, 4]])
|
||||
expect(serializer.read('(((1, 2), (3, 4)), 5)')).toStrictEqual([[[1, 2], [3, 4]], 5])
|
||||
expect(serializer.read(`(
|
||||
expect(grammar.parse("((1, 2), (3, 4))")).toStrictEqual([[1, 2], [3, 4]])
|
||||
expect(grammar.parse('(((1, 2), (3, 4)), 5)')).toStrictEqual([[[1, 2], [3, 4]], 5])
|
||||
expect(grammar.parse(`(
|
||||
One(a = (1,(2,(3,(4)))), b = ()),
|
||||
)`)).toStrictEqual([
|
||||
new UnknownKeysEntity({
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
import AttributeInfo from "../../js/entity/AttributeInfo.js"
|
||||
import IEntity from "../../js/entity/IEntity.js"
|
||||
import Union from "../../js/entity/Union.js"
|
||||
import NumberEntity from "../../js/entity/NumberEntity.js"
|
||||
import StringEntity from "../../js/entity/StringEntity.js"
|
||||
import Grammar from "../../js/serialization/Grammar.js"
|
||||
|
||||
export default class EntityF extends IEntity {
|
||||
|
||||
static lookbehind = ["Foo", "Bar"]
|
||||
static attributes = {
|
||||
...super.attributes,
|
||||
arg1: AttributeInfo.createType(Number),
|
||||
arg2: AttributeInfo.createType(String),
|
||||
lookbehind: new AttributeInfo({
|
||||
...super.attributes.lookbehind,
|
||||
default: new Union("Foo", "Bar"),
|
||||
})
|
||||
}
|
||||
|
||||
static grammar = this.createGrammar()
|
||||
|
||||
static createGrammar() {
|
||||
return Grammar.createEntityGrammar(this, false)
|
||||
arg1: NumberEntity,
|
||||
arg2: StringEntity,
|
||||
}
|
||||
static grammar = Grammar.createEntityGrammar(this)
|
||||
|
||||
constructor(values = {}) {
|
||||
super(values)
|
||||
|
||||
27
types.js
27
types.js
@@ -96,6 +96,19 @@
|
||||
* (value: T): typeof value.constructor,
|
||||
* }} TypeGetter
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {T extends [infer A extends EntityConstructor] ? InstanceType<A>
|
||||
* : T extends [infer A extends EntityConstructor, ...infer B] ? InstanceType<A> | UnionFromArray<B>
|
||||
* : never
|
||||
* } UnionFromArray
|
||||
*/
|
||||
/**
|
||||
* @template {EntityConstructor} T
|
||||
* @typedef {T extends AlternativesEntityConstructor & { alternatives: infer R } ? UnionFromArray<R>
|
||||
* : InstanceType<T>
|
||||
* } ExtractType
|
||||
*/
|
||||
/**
|
||||
* @typedef {typeof import("./js/Blueprint.js").default} BlueprintConstructor
|
||||
* @typedef {typeof import("./js/element/LinkElement.js").default} LinkElementConstructor
|
||||
@@ -103,6 +116,7 @@
|
||||
* @typedef {typeof import("./js/element/PinElement.js").default} PinElementConstructor
|
||||
* @typedef {typeof import("./js/element/WindowElement.js").default} WindowElementConstructor
|
||||
* @typedef {typeof import("./js/entity/IEntity.js").default} EntityConstructor
|
||||
* @typedef {typeof import("./js/entity/AlternativesEntity.js").default} AlternativesEntityConstructor
|
||||
* @typedef {typeof import("./js/entity/ObjectEntity.js").default} ObjectEntityConstructor
|
||||
*/
|
||||
/**
|
||||
@@ -207,20 +221,11 @@
|
||||
* @typedef {import("lit").CSSResult} CSSResult
|
||||
* @typedef {import("lit").PropertyValues} PropertyValues
|
||||
* @typedef {import("lit").TemplateResult} TemplateResult
|
||||
* @typedef {import("parsernostrum/src/parser/Parser.js").default} Parser
|
||||
*/
|
||||
/**
|
||||
* @template {AttributeConstructor<Attribute>} T
|
||||
* @typedef {import("./js/serialization/Serializer.js").default<T>} Serializer
|
||||
*/
|
||||
/**
|
||||
* @template {Attribute} T
|
||||
* @typedef {import("./js/entity/MirroredEntity.js").default<T>} MirroredEntity
|
||||
*/
|
||||
/**
|
||||
* @template {Attribute} T
|
||||
* @typedef {typeof import("./js/entity/MirroredEntity.js").default<T>} MirroredEntityConstructor
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {{
|
||||
@@ -228,3 +233,7 @@
|
||||
* evaluate<R>(pageFunction: (node: T) => R, options?: { timeout?: number }): Promise<R>
|
||||
* } & import("@playwright/test").Locator} Locator
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {import("parsernostrum").ProducerParser<T>} Parser
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user