@bscotch/gml-parser
Version:
A parser for GML (GameMaker Language) files for programmatic manipulation and analysis of GameMaker projects.
117 lines • 3.56 kB
JavaScript
import { Reference } from './project.location.js';
import { Flags } from './signifiers.flags.js';
import { getTypes } from './types.checks.js';
import { TypeStore } from './types.js';
import { assert } from './util.js';
export class Signifier extends Flags {
name;
$tag = 'Sym';
description = undefined;
type = new TypeStore();
/** For function params, the index of this param */
idx = undefined;
/** The Type containing this member */
parent;
/**
* If this is a native entity (built into GameMaker),
* this is set to the name of the module it came from.
*/
_native = undefined;
/**
* If `true`, then this definitely exists but may not have a place where it
* is declared. E.g. the `global` variable. In that case this would be set to
* `true`. Otherwise `undefined` is interpreted to mean that this thing
* does not have a definite declaration.
*/
_def = undefined;
refs = new Set();
constructor(parent, name, type) {
super();
this.name = name;
if (type) {
this.setType(type);
}
this.parent = parent;
}
get isRenameable() {
return (!!this.name &&
!this.native &&
!['other', 'self', 'global'].includes(this.name));
}
/**
* Create a new Signifier instance with the same properties as this one,
* except for its refs. Note that it is a shallow copy!
*/
copy() {
const copy = new Signifier(this.parent, this.name);
copy.description = this.description;
copy.type = this.type;
copy.idx = this.idx;
copy._native = this._native;
copy._def = this._def;
copy.flags = this.flags;
return copy;
}
addRef(location, isDef = false) {
const ref = Reference.fromRange(location, this);
ref.isDef = isDef;
this.refs.add(ref);
location.file.addRef(ref);
return ref;
}
unsetDef() {
assert(!this.native, 'Cannot unset def on a native entity');
this._def = undefined;
}
get def() {
return this._def;
}
set def(location) {
assert(location, 'Cannot set def to undefined');
if (this._def || this.native) {
// Then we have already set a declaration location, so we should
// not be setting it again.
return;
}
this._def = location;
}
definedAt(location) {
this.def = location;
return this;
}
get native() {
return this._native;
}
set native(nativeModule) {
this._native = nativeModule;
if (nativeModule) {
this._def = {};
}
}
describe(description) {
this.description = description;
return this;
}
setType(newType) {
this.type.type = getTypes(newType);
// if (newType instanceof Type) {
// newType.signifier = this;
// }
return this;
}
/** @deprecated Types should be set in one go instead of added piecemeal */
addType(newType) {
// We may have duplicate types, but that information is
// still useful since the same type information may have
// come from multiple assignment statements.
this.type.addType(newType);
return this;
}
get isTyped() {
return this.type.type.length > 0;
}
getTypeByKind(kind) {
return this.type.type.find((t) => t.kind === kind);
}
}
//# sourceMappingURL=signifiers.js.map