diff --git a/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/scoping/extensions/cast/PrimitiveCastExtensions.java b/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/scoping/extensions/cast/PrimitiveCastExtensions.java index 7f68bef51c..ac051b2ea3 100644 --- a/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/scoping/extensions/cast/PrimitiveCastExtensions.java +++ b/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/scoping/extensions/cast/PrimitiveCastExtensions.java @@ -21,6 +21,12 @@ package io.sarl.lang.scoping.extensions.cast; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import com.google.common.util.concurrent.AtomicDouble; import org.eclipse.xtext.xbase.lib.Inline; import org.eclipse.xtext.xbase.lib.Pure; @@ -60,4 +66,312 @@ public static String toString(char value) { return Character.toString(value); } + /** Decodes a {@code CharSequence} into a {@code byte}. + * + *

In opposite to the functions of {@link Byte}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link Byte#decode(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code byte} type. + * @since 0.9 + * @see Byte#decode(String) + */ + @Pure + public static byte byteValue(CharSequence value) { + try { + return Byte.decode(value.toString()); + } catch (Throwable exception) { + // Silent exception. + } + return 0; + } + + /** Decodes a {@code CharSequence} into a {@code short}. + * + *

In opposite to the functions of {@link Short}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link Short#decode(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code short} type. + * @since 0.9 + * @see Short#decode(String) + */ + @Pure + public static short shortValue(CharSequence value) { + try { + return Short.decode(value.toString()); + } catch (Throwable exception) { + // Silent exception. + } + return 0; + } + + /** Decodes a {@code CharSequence} into a {@code int}. + * + *

In opposite to the functions of {@link Integer}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link Integer#decode(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code int} type. + * @since 0.9 + * @see Integer#decode(String) + */ + @Pure + public static int intValue(CharSequence value) { + try { + return Integer.decode(value.toString()); + } catch (Throwable exception) { + // Silent exception. + } + return 0; + } + + /** Decodes a {@code CharSequence} into a {@code long}. + * + *

In opposite to the functions of {@link Long}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link Long#decode(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code long} type. + * @since 0.9 + * @see Long#decode(String) + */ + @Pure + public static long longValue(CharSequence value) { + try { + return Long.decode(value.toString()); + } catch (Throwable exception) { + // Silent exception. + } + return 0; + } + + /** Decodes a {@code CharSequence} into a {@code float}. + * + *

In opposite to the functions of {@link Float}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link Float#valueOf(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code float} type. + * @since 0.9 + * @see Float#valueOf(String) + */ + @Pure + public static float floatValue(CharSequence value) { + try { + return Float.parseFloat(value.toString()); + } catch (Throwable exception) { + // Silent exception. + } + return 0; + } + + /** Decodes a {@code CharSequence} into a {@code double}. + * + *

In opposite to the functions of {@link Double}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link Double#valueOf(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code double} type. + * @since 0.9 + * @see Double#valueOf(String) + */ + @Pure + public static double doubleValue(CharSequence value) { + try { + return Double.parseDouble(value.toString()); + } catch (Throwable exception) { + // Silent exception. + } + return 0; + } + + /** Decodes a {@code CharSequence} into a {@code AtomicInteger}. + * + *

In opposite to the functions of {@link Integer}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link #intValue(CharSequence)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code AtomicInteger} type. + * @since 0.9 + * @see #intValue(CharSequence) + */ + @Pure + @Inline(value = "new $2($3.intValue($1))", imported = {AtomicInteger.class, PrimitiveCastExtensions.class}) + public static AtomicInteger toAtomicInteger(CharSequence value) { + return new AtomicInteger(intValue(value)); + } + + /** Decodes a {@code CharSequence} into a {@code AtomicLong}. + * + *

In opposite to the functions of {@link Long}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link #longValue(CharSequence)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code AtomicLong} type. + * @since 0.9 + * @see #longValue(CharSequence) + */ + @Pure + @Inline(value = "new $2($3.longValue($1))", imported = {AtomicLong.class, PrimitiveCastExtensions.class}) + public static AtomicLong toAtomicLong(CharSequence value) { + return new AtomicLong(longValue(value)); + } + + /** Decodes a {@code CharSequence} into a {@code AtomicDouble}. + * + *

In opposite to the functions of {@link Double}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link #doubleValue(CharSequence)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code AtomicDouble} type. + * @since 0.9 + * @see #doubleValue(CharSequence) + */ + @Pure + @Inline(value = "new $2($3.doubleValue($1))", imported = {AtomicDouble.class, PrimitiveCastExtensions.class}) + public static AtomicDouble toAtomicDouble(CharSequence value) { + return new AtomicDouble(doubleValue(value)); + } + + private static boolean startsWith(CharSequence value, String prefix, int index) { + if (value == null) { + return prefix == null; + } + final int prefixLength = prefix.length(); + if (value.length() == 0) { + return prefixLength == 0; + } + final int eoffset = index + prefixLength; + if (eoffset > value.length()) { + return false; + } + int idx0 = index; + for (int idx1 = 0; idx1 < prefixLength; ++idx1, ++idx0) { + if (value.charAt(idx0) != prefix.charAt(idx1)) { + return false; + } + } + return true; + } + + /** Decodes a {@code CharSequence} into a {@code BigInteger}. + * + *

In opposite to the functions of {@link Integer}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link BigInteger#BigInteger(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code BigInteger} type. + * @since 0.9 + * @see #intValue(CharSequence) + */ + @Pure + @SuppressWarnings("checkstyle:magicnumber") + public static BigInteger toBigInteger(CharSequence value) { + try { + boolean negative = false; + int index = 0; + final char firstChar = value.charAt(0); + + // Handle sign, if present + if (firstChar == '-') { + negative = true; + ++index; + } else if (firstChar == '+') { + ++index; + } + + // Handle radix specifier, if present + int radix = 10; + if (startsWith(value, "0x", index) || startsWith(value, "0X", index)) { //$NON-NLS-1$ //$NON-NLS-2$ + index += 2; + radix = 16; + } else if (startsWith(value, "#", index)) { //$NON-NLS-1$ + ++index; + radix = 16; + } else if (startsWith(value, "0", index) && value.length() > 1 + index) { //$NON-NLS-1$ + ++index; + radix = 8; + } + final CharSequence endValue; + if (index > 0) { + endValue = value.subSequence(index, value.length()); + } else { + endValue = value; + } + final BigInteger number = new BigInteger(endValue.toString(), radix); + if (negative) { + return number.negate(); + } + return number; + } catch (Throwable exception) { + // Silent error + } + return BigInteger.valueOf(0); + } + + /** Decodes a {@code CharSequence} into a {@code BigDecimal}. + * + *

In opposite to the functions of {@link Double}, this function is + * null-safe and does not generate a {@link NumberFormatException}. + * If the given string cannot by parsed, {@code 0} is replied. + * + *

See {@link BigDecimal#BigDecimal(String)} for details on the accepted formats + * for the input string of characters. + * + * @param value a value of {@code CharSequence} type. + * @return the equivalent value to {@code value} of {@code BigInteger} type. + * @since 0.9 + * @see #intValue(CharSequence) + */ + @Pure + public static BigDecimal toBigDecimal(CharSequence value) { + try { + return new BigDecimal(value.toString()); + } catch (Throwable exception) { + // Silent error + } + return BigDecimal.valueOf(0.); + } + } diff --git a/tests/io.sarl.lang.core.tests/src/test/java/io/sarl/lang/core/tests/scoping/extensions/cast/CodeTest.java b/tests/io.sarl.lang.core.tests/src/test/java/io/sarl/lang/core/tests/scoping/extensions/cast/CodeTest.java new file mode 100644 index 0000000000..06f323c352 --- /dev/null +++ b/tests/io.sarl.lang.core.tests/src/test/java/io/sarl/lang/core/tests/scoping/extensions/cast/CodeTest.java @@ -0,0 +1,170 @@ +/* + * $Id$ + * + * SARL is an general-purpose agent programming language. + * More details on http://www.sarl.io + * + * Copyright (C) 2014-2019 the original authors or authors. + * + * 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 io.sarl.lang.core.tests.scoping.extensions.cast; + +import org.junit.Test; + +import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions; +import io.sarl.tests.api.AbstractSarlTest; + +/** + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + */ +@SuppressWarnings("all") +public class CodeTest extends AbstractSarlTest { + + @Test + public void toString_boolean() { + assertEquals(Boolean.TRUE.toString(), PrimitiveCastExtensions.toString(true)); + assertEquals(Boolean.FALSE.toString(), PrimitiveCastExtensions.toString(false)); + } + + @Test + public void toString_char() { + assertEquals("a", PrimitiveCastExtensions.toString('a')); + } + + @Test + public void byteValue_CharSequence() { + assertEquals(4, PrimitiveCastExtensions.byteValue("4")); + assertEquals(10, PrimitiveCastExtensions.byteValue("0xa")); + assertEquals(-4, PrimitiveCastExtensions.byteValue("-4")); + assertEquals(-10, PrimitiveCastExtensions.byteValue("-0xa")); + assertEquals(0, PrimitiveCastExtensions.byteValue("")); + assertEquals(0, PrimitiveCastExtensions.byteValue("z")); + assertEquals(0, PrimitiveCastExtensions.byteValue(null)); + } + + @Test + public void shortValue_CharSequence() { + assertEquals(4, PrimitiveCastExtensions.shortValue("4")); + assertEquals(10, PrimitiveCastExtensions.shortValue("0xa")); + assertEquals(-4, PrimitiveCastExtensions.shortValue("-4")); + assertEquals(-10, PrimitiveCastExtensions.shortValue("-0xa")); + assertEquals(0, PrimitiveCastExtensions.shortValue("")); + assertEquals(0, PrimitiveCastExtensions.shortValue("z")); + assertEquals(0, PrimitiveCastExtensions.shortValue(null)); + } + + @Test + public void intValue_CharSequence() { + assertEquals(4, PrimitiveCastExtensions.intValue("4")); + assertEquals(10, PrimitiveCastExtensions.intValue("0xa")); + assertEquals(-4, PrimitiveCastExtensions.intValue("-4")); + assertEquals(-10, PrimitiveCastExtensions.intValue("-0xa")); + assertEquals(0, PrimitiveCastExtensions.intValue("")); + assertEquals(0, PrimitiveCastExtensions.intValue("z")); + assertEquals(0, PrimitiveCastExtensions.intValue(null)); + } + + @Test + public void longValue_CharSequence() { + assertEquals(4l, PrimitiveCastExtensions.longValue("4")); + assertEquals(10l, PrimitiveCastExtensions.longValue("0xa")); + assertEquals(-4l, PrimitiveCastExtensions.longValue("-4")); + assertEquals(-10l, PrimitiveCastExtensions.longValue("-0xa")); + assertEquals(0l, PrimitiveCastExtensions.longValue("")); + assertEquals(0l, PrimitiveCastExtensions.longValue("z")); + assertEquals(0l, PrimitiveCastExtensions.longValue(null)); + } + + @Test + public void floatValue_CharSequence() { + assertEpsilonEquals(4f, PrimitiveCastExtensions.floatValue("4")); + assertEpsilonEquals(0f, PrimitiveCastExtensions.floatValue("0xa")); + assertEpsilonEquals(-4f, PrimitiveCastExtensions.floatValue("-4")); + assertEpsilonEquals(0f, PrimitiveCastExtensions.floatValue("-0xa")); + assertEpsilonEquals(0f, PrimitiveCastExtensions.floatValue("")); + assertEpsilonEquals(0f, PrimitiveCastExtensions.floatValue("z")); + assertEpsilonEquals(0f, PrimitiveCastExtensions.floatValue(null)); + } + + @Test + public void doubleValue_CharSequence() { + assertEpsilonEquals(4., PrimitiveCastExtensions.doubleValue("4")); + assertEpsilonEquals(0., PrimitiveCastExtensions.doubleValue("0xa")); + assertEpsilonEquals(-4., PrimitiveCastExtensions.doubleValue("-4")); + assertEpsilonEquals(0., PrimitiveCastExtensions.doubleValue("-0xa")); + assertEpsilonEquals(0., PrimitiveCastExtensions.doubleValue("")); + assertEpsilonEquals(0., PrimitiveCastExtensions.doubleValue("z")); + assertEpsilonEquals(0., PrimitiveCastExtensions.doubleValue(null)); + } + + @Test + public void toAtomicInteger_CharSequence() { + assertEpsilonEquals(4., PrimitiveCastExtensions.toAtomicInteger("4").doubleValue()); + assertEpsilonEquals(10., PrimitiveCastExtensions.toAtomicInteger("0xa").doubleValue()); + assertEpsilonEquals(-4., PrimitiveCastExtensions.toAtomicInteger("-4").doubleValue()); + assertEpsilonEquals(-10., PrimitiveCastExtensions.toAtomicInteger("-0xa").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicInteger("").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicInteger("z").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicInteger(null).doubleValue()); + } + + @Test + public void toAtomicLong_CharSequence() { + assertEpsilonEquals(4., PrimitiveCastExtensions.toAtomicLong("4").doubleValue()); + assertEpsilonEquals(10., PrimitiveCastExtensions.toAtomicLong("0xa").doubleValue()); + assertEpsilonEquals(-4., PrimitiveCastExtensions.toAtomicLong("-4").doubleValue()); + assertEpsilonEquals(-10., PrimitiveCastExtensions.toAtomicLong("-0xa").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicLong("").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicLong("z").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicLong(null).doubleValue()); + } + + @Test + public void toAtomicDouble_CharSequence() { + assertEpsilonEquals(4., PrimitiveCastExtensions.toAtomicDouble("4").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicDouble("0xa").doubleValue()); + assertEpsilonEquals(-4., PrimitiveCastExtensions.toAtomicDouble("-4").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicDouble("-0xa").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicDouble("").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicDouble("z").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toAtomicDouble(null).doubleValue()); + } + + @Test + public void toBigInteger_CharSequence() { + assertEpsilonEquals(4., PrimitiveCastExtensions.toBigInteger("4").doubleValue()); + assertEpsilonEquals(10., PrimitiveCastExtensions.toBigInteger("0xa").doubleValue()); + assertEpsilonEquals(-4., PrimitiveCastExtensions.toBigInteger("-4").doubleValue()); + assertEpsilonEquals(-10., PrimitiveCastExtensions.toBigInteger("-0xa").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigInteger("").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigInteger("z").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigInteger(null).doubleValue()); + } + + @Test + public void toBigDecimal_CharSequence() { + assertEpsilonEquals(4., PrimitiveCastExtensions.toBigDecimal("4").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigDecimal("0xa").doubleValue()); + assertEpsilonEquals(-4., PrimitiveCastExtensions.toBigDecimal("-4").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigDecimal("-0xa").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigDecimal("").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigDecimal("z").doubleValue()); + assertEpsilonEquals(0., PrimitiveCastExtensions.toBigDecimal(null).doubleValue()); + } + +} diff --git a/tests/io.sarl.lang.core.tests/src/test/java/io/sarl/lang/core/tests/scoping/extensions/cast/CompilerTest.java b/tests/io.sarl.lang.core.tests/src/test/java/io/sarl/lang/core/tests/scoping/extensions/cast/CompilerTest.java new file mode 100644 index 0000000000..f8120208df --- /dev/null +++ b/tests/io.sarl.lang.core.tests/src/test/java/io/sarl/lang/core/tests/scoping/extensions/cast/CompilerTest.java @@ -0,0 +1,705 @@ +/* + * $Id$ + * + * SARL is an general-purpose agent programming language. + * More details on http://www.sarl.io + * + * Copyright (C) 2014-2019 the original authors or authors. + * + * 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 io.sarl.lang.core.tests.scoping.extensions.cast; + +import org.eclipse.xtext.common.types.TypesPackage; +import org.junit.Test; +import org.junit.runner.RunWith; + +import io.sarl.lang.SARLVersion; +import io.sarl.lang.sarl.SarlPackage; +import io.sarl.lang.sarl.SarlScript; +import io.sarl.lang.validation.IssueCodes; +import io.sarl.tests.api.AbstractSarlTest; +import io.sarl.tests.api.MassiveCompilationSuite; +import io.sarl.tests.api.MassiveCompilationSuite.CompilationTest; +import io.sarl.tests.api.MassiveCompilationSuite.Context; + +/** + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + */ +@RunWith(MassiveCompilationSuite.class) +@SuppressWarnings("all") +public class CompilerTest extends AbstractSarlTest { + + private static final String BOOLEAN_AS_STRING_SARL = multilineString( + "class A {", + " def fct(left : boolean) : String {", + " left as String", + " }", + "}"); + + private static final String BOOLEAN_AS_STRING_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public String fct(final boolean left) {", + " return Boolean.toString(left);", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void boolean_as_string_issues() throws Exception { + validate(file(BOOLEAN_AS_STRING_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toString'"); + } + + @CompilationTest + public static void boolean_as_string(Context ctx) throws Exception { + ctx.compileTo(BOOLEAN_AS_STRING_SARL, BOOLEAN_AS_STRING_JAVA); + } + + private static final String CHAR_AS_STRING_SARL = multilineString( + "class A {", + " def fct(left : char) : String {", + " left as String", + " }", + "}"); + + private static final String CHAR_AS_STRING_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public String fct(final char left) {", + " return Character.toString(left);", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void char_as_string_issues() throws Exception { + validate(file(CHAR_AS_STRING_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toString'"); + } + + @CompilationTest + public static void char_as_string(Context ctx) throws Exception { + ctx.compileTo(CHAR_AS_STRING_SARL, CHAR_AS_STRING_JAVA); + } + + private static final String STRING_AS_BYTE_SARL = multilineString( + "class A {", + " def fct(left : String) : byte {", + " left as byte", + " }", + "}"); + + private static final String STRING_AS_BYTE_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public byte fct(final String left) {", + " return (left == null ? 0 : PrimitiveCastExtensions.byteValue(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_byte_issues() throws Exception { + validate(file(STRING_AS_BYTE_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'byteValue'"); + } + + @CompilationTest + public static void string_as_byte(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_BYTE_SARL, STRING_AS_BYTE_JAVA); + } + + private static final String STRING_AS_SHORT_SARL = multilineString( + "class A {", + " def fct(left : String) : short {", + " left as short", + " }", + "}"); + + private static final String STRING_AS_SHORT_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public short fct(final String left) {", + " return (left == null ? 0 : PrimitiveCastExtensions.shortValue(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_short_issues() throws Exception { + validate(file(STRING_AS_SHORT_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'shortValue'"); + } + + @CompilationTest + public static void string_as_short(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_SHORT_SARL, STRING_AS_SHORT_JAVA); + } + + private static final String STRING_AS_INT_SARL = multilineString( + "class A {", + " def fct(left : String) : int {", + " left as int", + " }", + "}"); + + private static final String STRING_AS_INT_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public int fct(final String left) {", + " return (left == null ? 0 : PrimitiveCastExtensions.intValue(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_int_issues() throws Exception { + validate(file(STRING_AS_INT_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'intValue'"); + } + + @CompilationTest + public static void string_as_int(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_INT_SARL, STRING_AS_INT_JAVA); + } + + private static final String STRING_AS_LONG_SARL = multilineString( + "class A {", + " def fct(left : String) : long {", + " left as long", + " }", + "}"); + + private static final String STRING_AS_LONG_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public long fct(final String left) {", + " return (left == null ? 0 : PrimitiveCastExtensions.longValue(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_long_issues() throws Exception { + validate(file(STRING_AS_LONG_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'longValue'"); + } + + @CompilationTest + public static void string_as_long(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_LONG_SARL, STRING_AS_LONG_JAVA); + } + + private static final String STRING_AS_FLOAT_SARL = multilineString( + "class A {", + " def fct(left : String) : float {", + " left as float", + " }", + "}"); + + private static final String STRING_AS_FLOAT_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public float fct(final String left) {", + " return (left == null ? 0 : PrimitiveCastExtensions.floatValue(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_float_issues() throws Exception { + validate(file(STRING_AS_FLOAT_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'floatValue'"); + } + + @CompilationTest + public static void string_as_float(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_FLOAT_SARL, STRING_AS_FLOAT_JAVA); + } + + private static final String STRING_AS_DOUBLE_SARL = multilineString( + "class A {", + " def fct(left : String) : double {", + " left as double", + " }", + "}"); + + private static final String STRING_AS_DOUBLE_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public double fct(final String left) {", + " return (left == null ? 0 : PrimitiveCastExtensions.doubleValue(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_double_issues() throws Exception { + validate(file(STRING_AS_DOUBLE_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'doubleValue'"); + } + + @CompilationTest + public static void string_as_double(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_DOUBLE_SARL, STRING_AS_DOUBLE_JAVA); + } + + private static final String STRING_AS_ATOMICINTEGER_SARL = multilineString( + "import java.util.concurrent.atomic.AtomicInteger", + "class A {", + " def fct(left : String) : AtomicInteger {", + " left as AtomicInteger", + " }", + "}"); + + private static final String STRING_AS_ATOMICINTEGER_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import java.util.concurrent.atomic.AtomicInteger;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public AtomicInteger fct(final String left) {", + " return (left == null ? null : new AtomicInteger(PrimitiveCastExtensions.intValue(left)));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_atomicinteger_issues() throws Exception { + validate(file(STRING_AS_ATOMICINTEGER_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toAtomicInteger'"); + } + + @CompilationTest + public static void string_as_atomicinteger(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_ATOMICINTEGER_SARL, STRING_AS_ATOMICINTEGER_JAVA); + } + + private static final String STRING_AS_ATOMICLONG_SARL = multilineString( + "import java.util.concurrent.atomic.AtomicLong", + "class A {", + " def fct(left : String) : AtomicLong {", + " left as AtomicLong", + " }", + "}"); + + private static final String STRING_AS_ATOMICLONG_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import java.util.concurrent.atomic.AtomicLong;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public AtomicLong fct(final String left) {", + " return (left == null ? null : new AtomicLong(PrimitiveCastExtensions.longValue(left)));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_atomiclong_issues() throws Exception { + validate(file(STRING_AS_ATOMICLONG_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toAtomicLong'"); + } + + @CompilationTest + public static void string_as_atomiclong(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_ATOMICLONG_SARL, STRING_AS_ATOMICLONG_JAVA); + } + + private static final String STRING_AS_ATOMICDOUBLE_SARL = multilineString( + "import com.google.common.util.concurrent.AtomicDouble", + "class A {", + " def fct(left : String) : AtomicDouble {", + " left as AtomicDouble", + " }", + "}"); + + private static final String STRING_AS_ATOMICDOUBLE_JAVA = multilineString( + "import com.google.common.util.concurrent.AtomicDouble;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public AtomicDouble fct(final String left) {", + " return (left == null ? null : new AtomicDouble(PrimitiveCastExtensions.doubleValue(left)));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_atomicdouble_issues() throws Exception { + validate(file(STRING_AS_ATOMICDOUBLE_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toAtomicDouble'"); + } + + @CompilationTest + public static void string_as_atomicdouble(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_ATOMICDOUBLE_SARL, STRING_AS_ATOMICDOUBLE_JAVA); + } + + private static final String STRING_AS_BIGINTEGER_SARL = multilineString( + "import java.math.BigInteger", + "class A {", + " def fct(left : String) : BigInteger {", + " left as BigInteger", + " }", + "}"); + + private static final String STRING_AS_BIGINTEGER_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import java.math.BigInteger;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public BigInteger fct(final String left) {", + " return (left == null ? null : PrimitiveCastExtensions.toBigInteger(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_biginteger_issues() throws Exception { + validate(file(STRING_AS_BIGINTEGER_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toBigInteger'"); + } + + @CompilationTest + public static void string_as_biginteger(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_BIGINTEGER_SARL, STRING_AS_BIGINTEGER_JAVA); + } + + private static final String STRING_AS_BIGDECIMAL_SARL = multilineString( + "import java.math.BigDecimal", + "class A {", + " def fct(left : String) : BigDecimal {", + " left as BigDecimal", + " }", + "}"); + + private static final String STRING_AS_BIGDECIMAL_JAVA = multilineString( + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.scoping.extensions.cast.PrimitiveCastExtensions;", + "import java.math.BigDecimal;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_CLASS + ")", + "@SuppressWarnings(\"all\")", + "public class A {", + " @Pure", + " public BigDecimal fct(final String left) {", + " return (left == null ? null : PrimitiveCastExtensions.toBigDecimal(left));", + " }", + " ", + " @SyntheticMember", + " public A() {", + " super();", + " }", + "}", + ""); + + @Test + public void string_as_bigdecimal_issues() throws Exception { + validate(file(STRING_AS_BIGDECIMAL_SARL)) + .assertNoErrors( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.INVALID_CAST) + .assertNoWarnings( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + org.eclipse.xtext.xbase.validation.IssueCodes.OBSOLETE_CAST) + .assertWarning( + TypesPackage.eINSTANCE.getJvmParameterizedTypeReference(), + IssueCodes.POTENTIAL_INEFFICIENT_VALUE_CONVERSION, + "'toBigDecimal'"); + } + + @CompilationTest + public static void string_as_bigdecimal(Context ctx) throws Exception { + ctx.compileTo(STRING_AS_BIGDECIMAL_SARL, STRING_AS_BIGDECIMAL_JAVA); + } + +}