From 4e4c2744ce7831d8471a44de4fda98e3c80f9e4e Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Mon, 1 Aug 2016 16:19:16 +0300 Subject: [PATCH] Improve type mismatch and unresolved variable exception messages --- .../UnresolvedReferenceException.java | 22 +++++++++++++++ .../sass/internal/parser/LexicalUnitImpl.java | 27 ++++++++++++++----- .../ArithmeticExpressionEvaluatorTest.java | 21 +++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/vaadin/sass/internal/expression/exception/UnresolvedReferenceException.java diff --git a/src/main/java/com/vaadin/sass/internal/expression/exception/UnresolvedReferenceException.java b/src/main/java/com/vaadin/sass/internal/expression/exception/UnresolvedReferenceException.java new file mode 100644 index 00000000..33436e15 --- /dev/null +++ b/src/main/java/com/vaadin/sass/internal/expression/exception/UnresolvedReferenceException.java @@ -0,0 +1,22 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.expression.exception; + +public class UnresolvedReferenceException extends RuntimeException { + public UnresolvedReferenceException(String errorExpr) { + super(errorExpr); + } +} diff --git a/src/main/java/com/vaadin/sass/internal/parser/LexicalUnitImpl.java b/src/main/java/com/vaadin/sass/internal/parser/LexicalUnitImpl.java index 9849b990..2a8ae530 100644 --- a/src/main/java/com/vaadin/sass/internal/parser/LexicalUnitImpl.java +++ b/src/main/java/com/vaadin/sass/internal/parser/LexicalUnitImpl.java @@ -37,6 +37,7 @@ import com.vaadin.sass.internal.ScssContext; import com.vaadin.sass.internal.expression.exception.IncompatibleUnitsException; +import com.vaadin.sass.internal.expression.exception.UnresolvedReferenceException; import com.vaadin.sass.internal.parser.function.AbsFunctionGenerator; import com.vaadin.sass.internal.parser.function.AdjustColorFunctionGenerator; import com.vaadin.sass.internal.parser.function.AlphaFunctionGenerator; @@ -401,15 +402,27 @@ public LexicalUnitImpl multiply(LexicalUnitImpl another) { } protected short checkAndGetUnit(LexicalUnitImpl another) { - if (getLexicalUnitType() != SAC_INTEGER - && getLexicalUnitType() != SAC_REAL - && another.getLexicalUnitType() != SAC_INTEGER - && another.getLexicalUnitType() != SAC_REAL + // are any variables still unresolved? + if (getLexicalUnitType() == SCSS_VARIABLE) { + // still unresolved + throw new UnresolvedReferenceException("unresolved:" + this); + } + if (another.getLexicalUnitType() == SCSS_VARIABLE) { + // still unresolved + throw new UnresolvedReferenceException("unresolved:" + another); + } + // if the units of the operands are not the same, is at least one of + // them numeric? + boolean isNumeric = getLexicalUnitType() == SAC_INTEGER + || getLexicalUnitType() == SAC_REAL; + boolean isAnotherNumeric = another.getLexicalUnitType() == SAC_INTEGER + || another.getLexicalUnitType() == SAC_REAL; + if (!isNumeric && !isAnotherNumeric && getLexicalUnitType() != another.getLexicalUnitType()) { - throw new IncompatibleUnitsException(printState()); + throw new IncompatibleUnitsException(printState() + " and " + + another.printState()); } - if (another.getLexicalUnitType() != SAC_INTEGER - && another.getLexicalUnitType() != SAC_REAL) { + if (!isAnotherNumeric) { return another.getLexicalUnitType(); } return getLexicalUnitType(); diff --git a/src/test/java/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java b/src/test/java/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java index 8ca21ed9..174119c3 100644 --- a/src/test/java/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java +++ b/src/test/java/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java @@ -24,6 +24,7 @@ import com.vaadin.sass.internal.ScssContext; import com.vaadin.sass.internal.expression.exception.ArithmeticException; import com.vaadin.sass.internal.expression.exception.IncompatibleUnitsException; +import com.vaadin.sass.internal.expression.exception.UnresolvedReferenceException; import com.vaadin.sass.internal.parser.LexicalUnitImpl; import com.vaadin.sass.internal.parser.SassListItem; @@ -59,6 +60,8 @@ private LexicalUnitImpl evaluate(SassListItem... terms) { 0, 0); private final LexicalUnitImpl operatorComma = LexicalUnitImpl.createComma( 2, 3); + private final LexicalUnitImpl unresolved = LexicalUnitImpl.createVariable( + 0, 0, "myvar"); @Test public void testPrecedenceSameAsAppearOrder() { @@ -82,6 +85,24 @@ public void testIncompatibleUnit() { evaluate(operand2cm, operatorMinus, operand3px); } + @Test + public void testAssumedFirstUnit() { + // 2 - 3px + LexicalUnitImpl result = evaluate(operand2, operatorMinus, operand3px); + Assert.assertEquals(-1, result.getIntegerValue()); + Assert.assertEquals(LexicalUnit.SAC_PIXEL, result.getLexicalUnitType()); + } + + @Test(expected = UnresolvedReferenceException.class) + public void testUnresolvedFirstOperand() { + evaluate(unresolved, operatorMinus, operand2); + } + + @Test(expected = UnresolvedReferenceException.class) + public void testUnresolvedSecondOperand() { + evaluate(operand2, operatorMinus, unresolved); + } + @Test public void testMultiplyWithUnitInfirstOperand() { // 2cm * 3 = 6cm