2017-01-06 10:47:08 +00:00
|
|
|
require("amd-loader");
|
|
|
|
require("../../../test/setup_paths");
|
|
|
|
|
|
|
|
var parser = require("treehugger/js/parse");
|
|
|
|
var traverse = require("treehugger/traverse");
|
|
|
|
var scopeAnalyzer = require('plugins/c9.ide.language.javascript/scope_analyzer');
|
|
|
|
var infer = require('../infer');
|
|
|
|
var Value = require('../values').Value;
|
|
|
|
var externalize = require('../externalize').externalize;
|
|
|
|
var assert = require("assert");
|
|
|
|
var fs = require('fs');
|
|
|
|
var util = require('util');
|
|
|
|
|
|
|
|
disabledFeatures = {};
|
|
|
|
|
|
|
|
function canBeInstanceOf(n, guid) {
|
|
|
|
var yup = false;
|
|
|
|
//console.log("Can be instance of " + n);
|
|
|
|
console.log("Infering type of: " + n);
|
|
|
|
var values = infer.inferValues(n);
|
|
|
|
//console.log(values);
|
|
|
|
values.forEach(function(v) {
|
|
|
|
if (v.guid)
|
|
|
|
console.log("Could be: " + v.guid);
|
|
|
|
if (v.guid === guid) {
|
|
|
|
yup = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
v.get('__proto__').forEach(function(v) {
|
|
|
|
if (v.guid) {
|
|
|
|
console.log("Could be: " + v.guid);
|
|
|
|
}
|
|
|
|
if (v.guid === guid) {
|
|
|
|
yup = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (!yup && guid.search(/\/prototype$/) === -1) {
|
|
|
|
return canBeInstanceOf(n, guid + "/prototype");
|
|
|
|
}
|
|
|
|
else if (!yup) {
|
|
|
|
console.log(""+n);
|
|
|
|
console.log("Not what we expected: " + util.inspect(values, null, 7));
|
|
|
|
}
|
|
|
|
return yup;
|
|
|
|
}
|
|
|
|
|
|
|
|
function extractTypeAnnotations(code) {
|
|
|
|
var lines = code.split("\n");
|
|
|
|
var annotations = [];
|
|
|
|
for (var i = 0; i < lines.length; i++) {
|
|
|
|
var line = lines[i];
|
|
|
|
if (line.indexOf('//#') === 0) { // annotation line
|
|
|
|
var regex = /\^ ([^ \n\|]+)/g;
|
|
|
|
var match;
|
|
|
|
while (match = regex.exec(line)) {
|
|
|
|
var firstNonAnnoLineIdx = i-1;
|
|
|
|
while (firstNonAnnoLineIdx > 0 && lines[firstNonAnnoLineIdx].indexOf('//#') === 0)
|
|
|
|
firstNonAnnoLineIdx--;
|
|
|
|
annotations.push({
|
|
|
|
line: firstNonAnnoLineIdx,
|
|
|
|
col: match.index,
|
|
|
|
type: match[1]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return annotations;
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.buildTest = function(filename, exportSymbol) {
|
|
|
|
return function(done) {
|
2017-02-16 16:53:58 +00:00
|
|
|
var code = fs.readFileSync(__dirname + "/" + filename, 'utf-8').replace(/\r/g, "");
|
2017-01-06 10:47:08 +00:00
|
|
|
var builtins1 = fs.readFileSync(__dirname + "/../builtin.jst", 'utf-8');
|
|
|
|
var builtins2 = fs.readFileSync(__dirname + "/../builtin.custom.jst", 'utf-8');
|
|
|
|
var builtins3 = fs.readFileSync(__dirname + "/../builtin.nodejs.jst", 'utf-8');
|
|
|
|
var builtins = [JSON.parse(builtins1), JSON.parse(builtins2), JSON.parse(builtins3)];
|
|
|
|
var node = parser.parse(code);
|
|
|
|
traverse.addParentPointers(node);
|
|
|
|
scopeAnalyzer.analyze(code, node, function() { /* Risky, but we know this is sync in this context */ });
|
|
|
|
Value.enterContext('es5:unnamed');
|
|
|
|
var typeAnnotations = extractTypeAnnotations(code);
|
|
|
|
var scope = infer.createRootScope(node.getAnnotation("scope"), builtins);
|
|
|
|
Value.leaveContext();
|
|
|
|
Value.enterContext(filename);
|
|
|
|
infer.staticEval(scope, node);
|
|
|
|
// console.log("AST: "+node);
|
|
|
|
|
|
|
|
for (var i = 0; i < typeAnnotations.length; i++) {
|
|
|
|
var anno = typeAnnotations[i];
|
|
|
|
var n = node.findNode(anno);
|
|
|
|
assert.ok(canBeInstanceOf(n, anno.type), "Went wrong on this one: " + JSON.stringify(anno));
|
|
|
|
}
|
|
|
|
var exportValue;
|
|
|
|
if (exportSymbol) scope.get(exportSymbol).values.forEach(function(v) { exportValue = v; });
|
|
|
|
var extern = externalize(filename, exportValue);
|
|
|
|
if (exportSymbol) extern[exportSymbol] = exportValue.guid;
|
|
|
|
require('fs').writeFile(__dirname + "/" + filename + '.jst', JSON.stringify(extern, null, 2), done);
|
|
|
|
};
|
|
|
|
};
|