All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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