
js.prompto.runtime.MethodFinder.js Maven / Gradle / Ivy
var PromptoError = require("../error/PromptoError").PromptoError;
var CategoryType = null;
var Score = require("./Score").Score;
exports.resolve = function() {
CategoryType = require("../type/CategoryType").CategoryType;
}
function MethodFinder(context, methodCall) {
this.context = context;
this.methodCall = methodCall;
return this;
}
MethodFinder.prototype.findMethod = function(checkInstance) {
var selector = this.methodCall.method;
var candidates = selector.getCandidates(this.context, checkInstance);
if(candidates.length==0)
this.context.problemListener.reportUnknownMethod(this.methodCall.method.id);
var compatibles = this.filterCompatible(candidates, checkInstance);
switch(compatibles.length) {
case 0:
this.context.problemListener.reportNoMatchingPrototype(this.methodCall);
case 1:
return compatibles[0];
default:
return this.findMostSpecific(compatibles, checkInstance);
}
};
MethodFinder.prototype.findMostSpecific = function(candidates, checkInstance) {
var candidate = null;
var ambiguous = [];
candidates.forEach(function(c) {
if(candidate==null)
candidate = c;
else {
var score = this.scoreMostSpecific(candidate, c, checkInstance);
switch(score) {
case Score.WORSE:
candidate = c;
ambiguous = [];
break;
case Score.BETTER:
break;
case Score.SIMILAR:
ambiguous.push(c);
break;
}
}
}, this);
if(ambiguous.length>0) {
throw new SyntaxError("Too many prototypes!"); // TODO refine
}
return candidate;
}
MethodFinder.prototype.scoreMostSpecific = function(d1, d2, checkInstance) {
try {
var s1 = this.context.newLocalContext();
d1.registerArguments(s1);
var s2 = this.context.newLocalContext();
d2.registerArguments(s2);
var ass1 = this.methodCall.makeAssignments(this.context, d1);
var ass2 = this.methodCall.makeAssignments(this.context, d2);
for(var i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy