150 linhas
4.8 KiB
JavaScript
150 linhas
4.8 KiB
JavaScript
/*globals define */
|
|
/*jshint browser: true*/
|
|
|
|
define([
|
|
'panels/TextEditor/TextEditorControl',
|
|
'deepforge/lua',
|
|
'underscore',
|
|
'text!./DefaultCodeTemplate.ejs'
|
|
], function (
|
|
TextEditorControl,
|
|
lua,
|
|
_,
|
|
CODE_TEMPLATE
|
|
) {
|
|
|
|
'use strict';
|
|
|
|
var ClassCodeEditorControl,
|
|
getBoilerplate = _.template(CODE_TEMPLATE);
|
|
|
|
ClassCodeEditorControl = function (options) {
|
|
options.attributeName = 'code';
|
|
TextEditorControl.call(this, options);
|
|
};
|
|
|
|
_.extend(
|
|
ClassCodeEditorControl.prototype,
|
|
TextEditorControl.prototype
|
|
);
|
|
|
|
// input/output updates are actually activeNode updates
|
|
ClassCodeEditorControl.prototype._onUpdate = function (id) {
|
|
if (id === this._currentNodeId) {
|
|
TextEditorControl.prototype._onUpdate.call(this, id);
|
|
}
|
|
};
|
|
|
|
ClassCodeEditorControl.prototype._getObjectDescriptor = function (nodeId) {
|
|
var desc = TextEditorControl.prototype._getObjectDescriptor.call(this, nodeId),
|
|
node = this._client.getNode(nodeId),
|
|
ownCode = node.getOwnAttribute(this.ATTRIBUTE_NAME);
|
|
|
|
// If the 'text' attribute is not set, and it's not inheriting anything
|
|
if (!desc.text && ownCode === undefined) {
|
|
desc.text = getBoilerplate(desc);
|
|
}
|
|
return desc;
|
|
};
|
|
|
|
ClassCodeEditorControl.prototype.saveTextFor = function (id, text) {
|
|
// On save, update the node's name
|
|
// For now, simply use regex to grab the returned name
|
|
var i = text.lastIndexOf('return') + 7,
|
|
returned = text.substring(i),
|
|
match = returned.match(/[a-zA-Z0-9_]+/),
|
|
node = this._client.getNode(id),
|
|
nodeName = node.getAttribute('name'),
|
|
baseName = null,
|
|
basePath,
|
|
name,
|
|
ast;
|
|
|
|
if (match) {
|
|
name = match[0];
|
|
}
|
|
|
|
// Check if the base needs to be updated
|
|
try {
|
|
ast = lua.parser.parse(text);
|
|
lua.codegen.traverse(curr => {
|
|
// Check for inheritance of the given type
|
|
if (curr.type === 'expr.call') {
|
|
var object = curr.func.self.val,
|
|
method = curr.func.key.val,
|
|
child,
|
|
base;
|
|
|
|
if (object === 'torch' && method === 'class') {
|
|
child = curr.args[0];
|
|
base = curr.args[1];
|
|
|
|
// If the first argument is the given class, get the base
|
|
if (child.type === 'const.string' && child.val === name) {
|
|
if (base && base.type === 'const.string') {
|
|
baseName = base.val;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})(ast);
|
|
|
|
// Get the base path from the base name
|
|
basePath = this.getBasePathFromName(baseName);
|
|
if (!basePath) {
|
|
this._logger.warn(`Could not find base type matching the name ${baseName}`);
|
|
}
|
|
} catch(e) {
|
|
this._logger.warn(`Invalid lua code. Parser failed: ${e}`);
|
|
}
|
|
|
|
this._client.startTransaction(`Updating class "${name || nodeName}"`);
|
|
if (name) {
|
|
this._client.setAttributes(id, 'name', name);
|
|
}
|
|
if (basePath) {
|
|
this._client.setBase(id, basePath);
|
|
} else { // Set base back to 'Complex'
|
|
while (node && (node.getAttribute('name') !== 'Complex' ||
|
|
node.isAbstract() !== true)) {
|
|
node = this._client.getNode(node.getBaseId());
|
|
}
|
|
|
|
if (node) { // node is the base class type
|
|
this._client.setBase(id, node.getId());
|
|
} else {
|
|
this._logger.warn(`Could not find the base class type from ${id}`);
|
|
}
|
|
}
|
|
|
|
TextEditorControl.prototype.saveTextFor.call(this, id, text, true);
|
|
this._client.completeTransaction();
|
|
};
|
|
|
|
ClassCodeEditorControl.prototype.getBasePathFromName = function (baseName) {
|
|
var metanodes = this._client.getAllMetaNodes(),
|
|
nameMatches = [],
|
|
classNode,
|
|
i;
|
|
|
|
for (i = metanodes.length; i--;) {
|
|
if (metanodes[i].getAttribute('name') === baseName) {
|
|
nameMatches.push(metanodes[i]);
|
|
}
|
|
if (metanodes[i].getAttribute('name') === 'Complex') {
|
|
classNode = metanodes[i];
|
|
}
|
|
}
|
|
|
|
for (i = nameMatches.length; i--;) {
|
|
if (this._client.isTypeOf(nameMatches[i].getId(), classNode.getId())) {
|
|
return nameMatches[i].getId();
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
return ClassCodeEditorControl;
|
|
});
|