1
0
mirror of https://github.com/DanilaFe/abacus synced 2024-12-22 15:30:09 -08:00

Merge pull request #32 from DanilaFe/promotion-exception

Add an exception thrown when promotion fails.
This commit is contained in:
Danila Fedorin 2017-09-20 12:16:00 -07:00 committed by GitHub
commit fcd4694203
3 changed files with 29 additions and 6 deletions

View File

@ -0,0 +1,24 @@
package org.nwapw.abacus.exception;
/**
* Exception thrown when a promotion fails.
*/
public class PromotionException extends AbacusException {
/**
* Creates a new PromotionException with the default message
* and no additional information.
*/
public PromotionException() {
this("");
}
/**
* Creates a new PromotionException with the given additional message.
* @param message the additional message to include with the error.
*/
public PromotionException(String message) {
super("Failed to promote number instances.", message);
}
}

View File

@ -1,6 +1,7 @@
package org.nwapw.abacus.number package org.nwapw.abacus.number
import org.nwapw.abacus.Abacus import org.nwapw.abacus.Abacus
import org.nwapw.abacus.exception.PromotionException
import org.nwapw.abacus.plugin.NumberImplementation import org.nwapw.abacus.plugin.NumberImplementation
import org.nwapw.abacus.plugin.PluginListener import org.nwapw.abacus.plugin.PluginListener
import org.nwapw.abacus.plugin.PluginManager import org.nwapw.abacus.plugin.PluginManager
@ -45,14 +46,14 @@ class PromotionManager(val abacus: Abacus) : PluginListener {
* @param numbers the numbers to promote. * @param numbers the numbers to promote.
* @return the resulting promotion result. * @return the resulting promotion result.
*/ */
fun promote(vararg numbers: NumberInterface): PromotionResult? { fun promote(vararg numbers: NumberInterface): PromotionResult {
val pluginManager = abacus.pluginManager val pluginManager = abacus.pluginManager
val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) } val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) }
val highestPriority = implementations.sortedBy { it.priority }.last() val highestPriority = implementations.sortedBy { it.priority }.last()
return PromotionResult(items = numbers.map { return PromotionResult(items = numbers.map {
if(it.javaClass == highestPriority.implementation) it if(it.javaClass == highestPriority.implementation) it
else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority] else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority]
?.promote(it) ?: return null ?.promote(it) ?: throw PromotionException()
}.toTypedArray(), promotedTo = highestPriority) }.toTypedArray(), promotedTo = highestPriority)
} }

View File

@ -36,15 +36,13 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer<Nu
is NumberBinaryNode -> { is NumberBinaryNode -> {
val left = children[0] as NumberInterface val left = children[0] as NumberInterface
val right = children[1] as NumberInterface val right = children[1] as NumberInterface
val promotionResult = promotionManager.promote(left, right) ?: val promotionResult = promotionManager.promote(left, right)
throw EvaluationException("promotion failed.")
context.numberImplementation = promotionResult.promotedTo context.numberImplementation = promotionResult.promotedTo
abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items) abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items)
} }
is FunctionNode -> { is FunctionNode -> {
val promotionResult = promotionManager val promotionResult = promotionManager
.promote(*children.map { it as NumberInterface }.toTypedArray()) ?: .promote(*children.map { it as NumberInterface }.toTypedArray())
throw EvaluationException("promotion failed.")
context.numberImplementation = promotionResult.promotedTo context.numberImplementation = promotionResult.promotedTo
abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items) abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items)
} }