
js.ide.codebase.js Maven / Gradle / Ivy
var isNodeJs = typeof window === 'undefined' && typeof importScripts === 'undefined';
var prompto = prompto;
if(typeof prompto === 'undefined') {
prompto = isNodeJs ?
require("../../../../prompto-javascript/JavaScript-Core/src/test/prompto/parser/PromptoLoader").prompto :
require('prompto/index');
}
/* a function for inferring dialect from file extension */
function inferDialect(path) {
return path.substring(path.length-2, path.length-1).toUpperCase();
}
/* a function for parsing prompto code into declarations */
function parse(input, dialect, listener) {
var klass = prompto.parser[dialect + "CleverParser"];
var parser = new klass(input);
parser.removeErrorListeners();
if(listener)
parser.addErrorListener(listener);
return parser.parse();
}
/* a function for producing code from a declaration object */
function unparse(context, decl, dialect) {
var dialect = prompto.parser.Dialect[dialect];
var writer = new prompto.utils.CodeWriter(dialect, context.newChildContext());
if(decl.comments) {
decl.comments.forEach(function (cmt) {
cmt.toDialect(writer);
});
}
decl.toDialect(writer);
return writer.toString();
}
/* a function for translating current input to other dialect */
function translate(context, data, from, to) {
var decls = parse(data, from); // could be cached
var dialect = prompto.parser.Dialect[to];
var writer = new prompto.utils.CodeWriter(dialect, context.newChildContext());
decls.toDialect(writer);
return writer.toString();
}
/* a utility function to sort by field name */
function sortBy(a, f) {
return a.sort(function(i1,i2) {
return (i1[f]>i2[f]) ? 1 : ((i1[f]0;
});
};
/**
* An object which represents the delta between 2 catalogs
* The purpose of this class is to minimize the re-processing in the IDE
* when code is updated. Typically, various scenarios can occur:
* - code body change, this has not impact on the catalog
* - declaration removed
* - declaration added
* - declarations changed, which for global methods adds complexity because
* methods are displayed differently depending on their number of prototypes
* The below code is not optimized. The optimization is to only redisplay what is needed,
* not to optimize the calculation of what needs to be redisplayed.
* This follows the assumption that the number of overloads for a method name is generally very low (< 10).
*/
function Delta() {
this.removed = null;
this.added = null;
return this;
}
Delta.prototype.length = function() {
var length = 0;
if(this.removed)
length += this.removed.length();
if(this.added)
length += this.added.length();
return length;
};
Delta.prototype.getContent = function() {
return { removed : this.removed, added : this.added };
};
Delta.prototype.filterOutDuplicates = function() {
if(!this.removed && !this.added)
return 0;
if(!this.removed)
return this.added.length();
if(!this.added)
return this.removed.length();
var length = this.filterOutDuplicatesInLists(this.removed.attributes, this.added.attributes);
length += this.filterOutDuplicatesInMethods(this.removed.methods, this.added.methods)
length += this.filterOutDuplicatesInLists(this.removed.categories, this.added.categories);
length += this.filterOutDuplicatesInLists(this.removed.enumerations, this.added.enumerations);
length += this.filterOutDuplicatesInLists(this.removed.tests, this.added.tests);
return length;
};
Delta.prototype.filterOutDuplicatesInLists = function(a, b, field) {
if(a && b) {
if(field) {
sortBy(a, field);
sortBy(b, field);
} else {
a.sort();
b.sort();
}
for(var i=0,j=0;ivb) {
j++;
} else {
i++;
}
}
var length = a.length + b.length;
if(!a.length)
delete a;
if(!b.length)
delete b;
return length;
} else if(a)
return a.length;
else if(b)
return b.length;
else
return 0;
};
Delta.prototype.filterOutDuplicatesInMethods = function(a, b) {
if(a && b) {
sortBy(a, "name");
sortBy(b, "name");
for(var i=0,j=0;ib[j].name) {
j++;
} else {
i++;
}
}
var length = a.length + b.length;
if(!a.length)
delete a;
if(!b.length)
delete b;
return length;
} else if(a)
return a.length;
else if(b)
return b.length;
else
return 0;
}
Delta.prototype.adjustForMovingProtos = function(context) {
// methods with 1 proto are displayed differently than methods with multiple protos
// if proto cardinality changes from N to 1 or 1 to N, we need to rebuild the corresponding displays
if (this.removed && this.removed.methods) {
this.removed.methods.map(function (method) {
var decl = context.getRegisteredDeclaration(method.name);
if (decl && Object.keys(decl.protos).length == 1) // moved from N to 1
this.adjustMethodForRemovedProtos(method, decl);
}, this);
}
if (this.added && this.added.methods) {
this.added.methods.map(function (method) {
var decl = context.getRegisteredDeclaration(method.name);
if (decl && Object.keys(decl.protos).length - method.protos.length == 1) // moved from 1 to N
this.adjustMethodForAddedProtos(method, decl);
}, this);
}
// cleanup
if (this.removed && this.removed.methods) {
this.removed.methods.map(function (method) {
if(method.proto_to_remove) {
method.protos.push(method.proto_to_remove);
sortBy(method.protos, "proto");
delete method.proto_to_remove;
}
});
}
if (this.added && this.added.methods) {
this.added.methods.map(function (method) {
if(method.proto_to_add) {
method.protos.push(method.proto_to_add);
sortBy(method.protos, "proto");
delete method.proto_to_add;
}
});
}
};
Delta.prototype.adjustMethodForAddedProtos = function(method, decl)
{
var proto = this.findPreExistingProto(method, decl);
if(proto) {
var main = decl.protos[proto].isEligibleAsMain();
var proto_to_move = {proto: proto, main: main};
// add it to the remove list
if(!this.removed)
this.removed = new Catalog();
var removed = this.findOrCreateMethod(this.removed, method.name);
removed.proto_to_remove = proto_to_move;
// add it to the add list
method.proto_to_add = proto_to_move;
}
};
Delta.prototype.findPreExistingProto = function(method, decl) {
for(var proto in decl.protos) {
var found = false;
for(var i=0; !found && i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy