c9-core/plugins/c9.ide.language.javascript..../infer_arguments.js

139 wiersze
4.6 KiB
JavaScript

define(function(require, exports, module) {
var tree = require("treehugger/tree");
var FunctionValue = require('./values').FunctionValue;
var ValueCollection = require('./values').ValueCollection;
/**
* Gets the index of the selected function argument, or returns -1 if N/A.
*/
module.exports.getArgIndex = function(node, doc, cursorPos) {
var cursorTreePos = { line: cursorPos.row, col: cursorPos.column };
var result = -1;
node.rewrite(
'Call(e, args)', function(b) {
// Try to determine at which argument the cursor is located in order
// to be able to show a label
result = -1;
var line = doc.getLine(cursorPos.row);
if (line[b.args.getPos().ec + 1] && line[b.args.getPos().ec + 1].match(/[ ,]/))
b.args.getPos().ec++;
if (b.args.length === 0 && this.getPos().ec - 1 === cursorPos.column) {
result = 0;
}
else if (b.args.length === 0 && line.substr(cursorPos.column).match(/^\s*\)/)) {
result = 0;
}
else if (!tree.inRange(this.getPos(), cursorTreePos, true)) {
return this;
}
else if (cursorPos.row === this.getPos().sl && line.substr(0, cursorPos.column + 1).match(/,\s*\)$/)) {
result = b.args.length;
return this;
}
for (var i = 0; i < b.args.length; i++) {
if (b.args[i].cons === "ERROR" && result === -1) {
result = i;
break;
}
b.args[i].traverseTopDown(function() {
var pos = this.getPos();
if (this === node) {
result = i;
return this;
}
else if (pos && pos.sl <= cursorPos.row && pos.sc <= cursorPos.column) {
if (pos.sl === cursorPos.row && pos.ec === cursorPos.column - 1 && line[pos.ec] === ")")
return result = -1;
result = i;
}
});
}
return this;
}
);
return result;
};
module.exports.extractArgumentNames = function(v, showOptionals) {
var args = [];
var argsCode = [];
var inferredArguments = v.callOnly;
var opt;
var fargs = v instanceof FunctionValue ? v.getFargs() : [];
var argColl = extractArgumentValues(v, fargs, 0);
for (var idx = 0; fargs.length ? idx < fargs.length : !argColl.isEmpty(); idx++) {
var argName;
if (fargs[idx]) {
argName = fargs[idx].id || fargs[idx];
if (showOptionals && fargs[idx].opt) {
argName = "[" + argName + "]";
opt = opt || idx;
}
}
else {
argName = "arg" + idx;
inferredArguments = true;
}
args.push(argName);
argsCode.push(fargToClosure(fargs[idx]) || valueCollToClosure(argName, argColl));
argColl = extractArgumentValues(v, fargs, idx + 1);
}
return {
argNames: args,
argValueCodes: argsCode,
inferredNames: inferredArguments,
opt: opt
};
};
var extractArgumentValues = function(v, fargs, index) {
var result;
if (fargs[index] && fargs[index].id) {
result = new ValueCollection();
if (fargs[index].type)
result.extend(fargs[index].type);
}
else {
result = v.get("arg" + index);
}
return result;
};
function fargToClosure(farg) {
if (!farg || !farg.fargs)
return null;
var args = [];
for (var i = 0; i < farg.fargs.length; i++) {
args.push(farg.fargs[i].id || farg.fargs[i]);
}
return "function(" + args.join(", ") + ") {\n ^^\n}";
}
function valueCollToClosure(name, coll) {
var result;
coll.forEach(function(v) {
if (result)
return;
if (v instanceof FunctionValue) {
var args = [];
var fargs = v.getFargs();
var argColl = extractArgumentValues(v, fargs, idx);
for (var idx = 0; !argColl.isEmpty() || idx < fargs.length; idx++) {
var argName;
if (fargs[idx])
argName = fargs[idx].id || fargs[idx];
else
argName = "arg" + idx;
args.push(argName);
argColl = extractArgumentValues(v, fargs, idx + 1);
}
result = "function(" + args.join(", ") + ") {\n ^^\n}";
}
});
return result;
}
});