Skip to content

Commit

Permalink
[lang] Generate the Java code for the casted expression's overriding …
Browse files Browse the repository at this point in the history
…function.

see #767

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Nov 29, 2018
1 parent d428004 commit 0a62cdf
Show file tree
Hide file tree
Showing 26 changed files with 1,763 additions and 1,024 deletions.
Expand Up @@ -102,11 +102,21 @@ environment (Eclipse, IntelliJ...)
<td style="background: orange; color: white;">No</td>
<td style="background: orange; color: white;">No</td>
<td style="background: green; color: white;">Yes</td></tr>
<tr><td><a href="./general/Operators.md#operator-overloading">Operator overloading</a></td>
<tr><td><a href="./general/Operators.md#operator-overloading">Operator overloading (except assignment and type casting operators)</a></td>
<td style="background: green; color: white;">Yes</td>
<td style="background: orange; color: white;">No</td>
<td style="background: green; color: white;">Yes</td>
<td style="background: green; color: white;">Yes</td></tr>
<tr><td><a href="./general/Cast.md">Cast operator overloading</a></td>
<td style="background: green; color: white;">Yes</td>
<td style="background: orange; color: white;">No</td>
<td style="background: orange; color: white;">No</td>
<td style="background: orange; color: white;">No</td></tr>
<tr><td><a href="./general/Operators.md">Assignment operator overloading</a></td>
<td style="background: orange; color: white;">No</td>
<td style="background: orange; color: white;">No</td>
<td style="background: orange; color: white;">No</td>
<td style="background: orange; color: white;">No</td></tr>
<tr><td>Automatic detection of <a href="http://download.eclipse.org/modeling/tmf/xtext/javadoc/2.9/org/eclipse/xtext/xbase/lib/Pure.html">pure functions</a> and marking</td>
<td style="background: green; color: white;">Yes</td>
<td style="background: orange; color: white;">No</td>
Expand Down
Expand Up @@ -26,7 +26,7 @@ In SARL, you can perform the following kinds of conversions:

* **Implicit conversions:** No special syntax is required because the conversion is type safe and no data will be lost.
Examples include conversions from smaller to larger number types, and conversions from derived classes to base classes.
* **Explicit conversions (casts):** Explicit conversions require a cast operator. Casting is required when information
* **Explicit conversions (casts):** Explicit conversions require a casting operator. Casting is required when information
might be lost in the conversion, or when the conversion might not succeed for other reasons. Typical examples include
numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a
derived class.
Expand Down Expand Up @@ -61,56 +61,28 @@ The following table shows the predefined implicit conversions between SARL types

| From | To |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| array[] | |
| AtomicDouble | |
| AtomicInteger | |
| AtomicLong | |
| BigDecimal | |
| BigInteger | |
| boolean | |
| Boolean | |
| byte | |
| Byte | |
| char | |
| Character | |
| double | |
| Double | |
| float | |
| Float | |
| int | |
| Integer | |
| List<?> | |
| long | |
| Long | |
| short | |
| Short | |
| String | |
| T[] | List<T> |
| boolean | Boolean |
| Boolean | boolean |
| byte | Byte, short, int, long, float, double |
| Byte | byte, short, int, long, float, double |
| char | Character, String |
| Character | char, String |
| double | Double |
| Double | double |
| float | Float, double |
| Float | float, double |
| int | Integer, long, float, double |
| Integer | int, long, float, double |
| List<T> | T[] |
| long | Long, float, double |
| Long | long, float, double |
| short | Short, int, long, float, double |
| Short | short, int, long, float, double |
| String | char, Character (if string length is 1) |



[:Success:]
package io.sarl.docs.reference.gsr
class A {
def fct(x : byte) : Object {
var v1 = x as short
var v2 = x as int
var v3 = x as long
var v4 = x as float
var v5 = x as double
var v6 = x as Byte
var v7 = x as Short
var v8 = x as Integer
var v9 = x as Long
var v10 = x as Float
var v11 = x as Double
var v12 = x as BigInteger
var v13 = x as BigDecimal;
null
}
}
[:End:]


## Explicit Conversions

However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform
Expand Down Expand Up @@ -150,7 +122,7 @@ For object types, an explicit cast is required if you need to convert from a bas
class Animal {}
class Giraffe extends Animal {}
class Test {
static def Main : [:inttype!] {
static def Main : Object {
[:On]
// Create a new derived type
var g = new Giraffe
Expand All @@ -161,22 +133,23 @@ For object types, an explicit cast is required if you need to convert from a bas
// Explicit conversion is required to cast back to derived type.
// Note: This will compile but will throw an exception at run time if the right-side
// object is not in fact a Giraffe.
var g2 : Giraffe = a as Giraffe
var g2 : Giraffe
g2 = a as Giraffe
[:Off]
}
}
[:End:]


A cast operation between reference types does not change the run-time type of the underlying object; it only changes
A casting operation between reference types does not change the run-time type of the underlying object; it only changes
the type of the value that is being used as a reference to that object.



## Type Conversion Exceptions at Run Time

In some reference type conversions, the compiler cannot determine whether a cast will be valid. It is possible for
a cast operation that compiles correctly to fail at run time. As shown in the following example, a type cast
a castinng operation that compiles correctly to fail at run time. As shown in the following example, a type cast
that fails at run time will cause an [:classcastexception:] to be thrown.

[:Success:]
Expand All @@ -195,7 +168,8 @@ that fails at run time will cause an [:classcastexception:] to be thrown.
static def test(a : Animal) {
// Cause a [:classcastexception](ClassCastException) at run time
// because [:mammaltype!] is not convertible to [:reptiletype].
var r : Reptile = a as Reptile
var r : Reptile
r = a as Reptile
}
}
[:Off]
Expand Down Expand Up @@ -228,23 +202,24 @@ type to which the result of [:exprvar:] is to be converted. The [:instanceofoper

SARL enables programmers to declare conversions on classes or basic types so that classes or basic types can
be converted to and/or from other classes or basic types. Conversions are associated to the `as`
[casting operator](./Cast.md). When the compiler cannot proceed an implicit nor explicit casting, it tries
type casting operator. When the compiler cannot proceed an implicit nor explicit casting, it tries
to find within the current code scope the definition of a casting operator function.
Depending on the category of the type to cast to, the name of this casting operator function is different:

* **Object type:** the casting operator function's name must have the prefix `to` followed by the simple name
(first letter upper case) of the cast type.
(first letter upper case) of the cast type, e.g. `toString`.
* **Basic type:** the casting operator function's name must start with the name of the basic type (all lower
case) following by the post-fix `Value`.
case) following by the post-fix `Value`, e.g. `intValue`.

Additionnally, the return type of the casting operator function must be the cast type.
Additionnally, the return type of the casting operator function must be the cast type, and not a sub-type of the
type specified as right operand of the casting operator.

A single parameter may be specified or not. It it is specified, it must corresponds to the expression to cast.
It means that the type of formal parameter is the expected type of the expression.
It means that the type of the formal parameter is the expected type of the expression.
If the formal parameter is ommitted, the current object (`this`) is assumed to be converted.

In the following example, the function [:tointegerfct:] if defined for converting a [:typetype:] to [:integertype:].
When the expression [:castexpr1:] is evaluated by the compiler, the function [:tointegerfct] is discovered and used
In the following example, the function [:tointegerfct:] is defined for converting a [:typetype:] to [:integertype:].
When the expression [:castexpr1:] is evaluated by the compiler, the function [:tointegerfct:] is discovered and used
for proceeding the cast.

[:Success:]
Expand All @@ -255,15 +230,15 @@ for proceeding the cast.
class Test {
def main {
var obj : Type
var val = [:castexpr1](obj as Integer)
var value = [:castexpr1](obj as Integer)
}
}
[:Off]
[:End:]

In the second example below, the function [:tointegerfct:] if defined in the same class as the one where the cast operator is
In the second example below, the function [:tointegerfct:] is defined in the same class as the one where the cast operator is
defined.
When the expression [:castexpr1:] is evaluated by the compiler, the function [:tointegerfct] is discovered and used
When the expression [:castexpr1:] is evaluated by the compiler, the function [:tointegerfct:] is discovered and used
for proceeding the cast.

[:Success:]
Expand All @@ -273,7 +248,7 @@ for proceeding the cast.
class Test {
def main {
var obj : Type
var val = obj as Integer
var value = obj as Integer
}
def [:tointegerfct!](v : Type) : [:integertype](Integer) { 0 }
}
Expand All @@ -296,7 +271,7 @@ The declarations of the [:tointegerfct:] are replaced by declarations of [:intva
class Test {
def main {
var obj : Type
var val = obj as int
var value = obj as int
}
}
[:Off]
Expand All @@ -310,17 +285,13 @@ The declarations of the [:tointegerfct:] are replaced by declarations of [:intva
class Test {
def main {
var obj : Type
var val r = obj as int
var value = obj as int
}
def [:intvaluefct!](v : Type) : [:inttype!] { 0 }
}
[:Off]
[:End:]

## Implicit Conversions

Coming soon.



[:Include:](../generalsyntaxref.inc)
Expand Down
1 change: 1 addition & 0 deletions main/coreplugins/io.sarl.lang.core/META-INF/MANIFEST.MF
Expand Up @@ -13,6 +13,7 @@ Export-Package: io.sarl.bootstrap,
io.sarl.lang.annotation,
io.sarl.lang.bugfixes.pending.pr106,
io.sarl.lang.core,
io.sarl.lang.scoping.extensions.cast,
io.sarl.lang.scoping.extensions.numbers.arithmetic,
io.sarl.lang.scoping.extensions.numbers.cast,
io.sarl.lang.scoping.extensions.numbers.comparison,
Expand Down
@@ -0,0 +1,48 @@
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014-2018 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.scoping.extensions.cast;

import java.util.List;

import javax.inject.Singleton;

/** Provide static functions related to the casting for primitive types that are not numbers.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 0.9
*/
@Singleton
public class GeneralCastImplicitlyImportedFeatures {

/** Fill the given list with the implicitly imported features.
*
* @param features the list to fill.
*/
@SuppressWarnings("static-method")
public void getImportedFeatures(List<Class<?>> features) {
features.add(PrimitiveCastExtensions.class);
}

}
@@ -0,0 +1,63 @@
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014-2018 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.scoping.extensions.cast;

import org.eclipse.xtext.xbase.lib.Inline;
import org.eclipse.xtext.xbase.lib.Pure;

/** Provide static functions related to the casting of primitives that are not numbers.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 0.9
*/
public final class PrimitiveCastExtensions {

private PrimitiveCastExtensions() {
//
}

/** Convert the given value to {@code String}.
*
* @param value a value of {@code boolean} type.
* @return the equivalent value to {@code value} of {@code String} type.
*/
@Pure
@Inline(value = "$2.toString($1)", imported = Boolean.class)
public static String toString(boolean value) {
return Boolean.toString(value);
}

/** Convert the given value to {@code String}.
*
* @param value a value of {@code char} type.
* @return the equivalent value to {@code value} of {@code String} type.
*/
@Pure
@Inline(value = "$2.toString($1)", imported = Character.class)
public static String toString(char value) {
return Character.toString(value);
}

}

0 comments on commit 0a62cdf

Please sign in to comment.