From 13dfb0d5d17c28b65840d1606cc0c4ee445d02d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Galland?= Date: Fri, 9 Nov 2018 20:28:51 +0100 Subject: [PATCH] [lang] Make the closure serializable. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #885 Signed-off-by: Stéphane Galland --- .../io/sarl/lang/util/SerializableProxy.java | 153 + .../io/sarl/lang/compiler/SarlCompiler.java | 363 +- .../AbstractExtraLanguageValidator.java | 16 +- .../sarl/lang/jvmmodel/GenerationContext.java | 20 +- .../lang/jvmmodel/SARLJvmModelInferrer.java | 6 +- .../lang/util/ContextAwareTreeAppendable.java | 109 + .../lang/util/DelegateTreeAppendable.java | 239 ++ .../src/io/sarl/lang/util/Utils.java | 97 + pom.xml | 8 + .../eventserial/NetworkEventModule.java | 16 +- .../tests/bugs/network/Bug885.java | 171 + .../gson/GsonEventSerializerTest.java | 2 +- .../sarl/lang/tests/bugs/to00399/Bug291.java | 3 +- .../sarl/lang/tests/bugs/to00699/Bug623.java | 6 +- .../sarl/lang/tests/bugs/to00999/Bug819.java | 28 +- .../sarl/lang/tests/bugs/to00999/Bug885.java | 3164 +++++++++++++++++ .../compilation/aop/AgentCompilerTest.java | 3 +- .../src/foo/StaticTools.java | 16 + 18 files changed, 4380 insertions(+), 40 deletions(-) create mode 100644 main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/util/SerializableProxy.java create mode 100644 main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/ContextAwareTreeAppendable.java create mode 100644 main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/DelegateTreeAppendable.java create mode 100644 sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/bugs/network/Bug885.java create mode 100644 tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug885.java create mode 100644 tests/io.sarl.tests.testdata/src/foo/StaticTools.java diff --git a/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/util/SerializableProxy.java b/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/util/SerializableProxy.java new file mode 100644 index 0000000000..8bcefde64c --- /dev/null +++ b/main/coreplugins/io.sarl.lang.core/src/io/sarl/lang/util/SerializableProxy.java @@ -0,0 +1,153 @@ +/* + * $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.util; + +import java.io.InvalidClassException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.io.StreamCorruptedException; +import java.io.WriteAbortedException; +import java.lang.reflect.Constructor; + +/** + * An object that could be used as a proxy for serializing an object. + * + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @since 0.8.6 + */ +public class SerializableProxy implements Serializable { + + private static final long serialVersionUID = -2601677585237973795L; + + private final Class proxyType; + + private final Object[] values; + + /** Construct a proxy. + * + * @param type the inner or anonymous class of the object to create when deserializing. + * @param values the values to serialize. + */ + public SerializableProxy(Class type, Object... values) { + assert type.isLocalClass() || type.isAnonymousClass(); + this.proxyType = type; + this.values = values; + } + + /** Replies the value at the given index. + * + * @param the expected type of the data. + * @param index the index. + * @return the value. + */ + @SuppressWarnings("unchecked") + public T getValue(int index) { + return (T) this.values[index]; + } + + /** This function enables to deserialize an instance of this proxy. + * @throws ObjectStreamException if the deserialization fails + */ + private Object readResolve() throws ObjectStreamException { + Constructor compatible = null; + for (final Constructor candidate : this.proxyType.getDeclaredConstructors()) { + if (candidate != null && isCompatible(candidate)) { + if (compatible != null) { + throw new IllegalStateException(); + } + compatible = candidate; + } + } + if (compatible != null) { + if (!compatible.isAccessible()) { + compatible.setAccessible(true); + } + try { + final Object[] arguments = new Object[this.values.length + 1]; + System.arraycopy(this.values, 0, arguments, 1, this.values.length); + return compatible.newInstance(arguments); + } catch (Exception exception) { + throw new WriteAbortedException(exception.getLocalizedMessage(), exception); + } + } + throw new InvalidClassException("compatible constructor not found"); //$NON-NLS-1$ + } + + private boolean isCompatible(Constructor candidate) throws ObjectStreamException { + final Class[] parameterTypes = candidate.getParameterTypes(); + if (parameterTypes.length != this.values.length + 1) { + return false; + } + final Class enclosingType = this.proxyType.getEnclosingClass(); + if (!parameterTypes[0].isAssignableFrom(enclosingType)) { + return false; + } + for (int i = 0, j = 1; i < this.values.length; ++i, ++j) { + final Object param = this.values[i]; + assert j < parameterTypes.length; + Class clazz = parameterTypes[j]; + if (clazz.isPrimitive()) { + clazz = wrapperTypeFor(clazz); + } + if (param != null && !clazz.isInstance(param)) { + return false; + } + } + return true; + } + + @SuppressWarnings("checkstyle:npathcomplexity") + private static Class wrapperTypeFor(Class primitive) throws ObjectStreamException { + if (primitive == Boolean.TYPE) { + return Boolean.class; + } + if (primitive == Byte.TYPE) { + return Byte.class; + } + if (primitive == Character.TYPE) { + return Character.class; + } + if (primitive == Short.TYPE) { + return Short.class; + } + if (primitive == Integer.TYPE) { + return Integer.class; + } + if (primitive == Long.TYPE) { + return Long.class; + } + if (primitive == Float.TYPE) { + return Float.class; + } + if (primitive == Double.TYPE) { + return Double.class; + } + if (primitive == Void.TYPE) { + return Void.class; + } + throw new StreamCorruptedException(); + } + +} diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/compiler/SarlCompiler.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/compiler/SarlCompiler.java index c81b1dc84f..8560629189 100644 --- a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/compiler/SarlCompiler.java +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/compiler/SarlCompiler.java @@ -21,6 +21,11 @@ package io.sarl.lang.compiler; +import static com.google.common.collect.Sets.newHashSet; + +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -28,6 +33,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -49,11 +55,13 @@ import org.eclipse.xtext.common.types.JvmDoubleAnnotationValue; import org.eclipse.xtext.common.types.JvmEnumAnnotationValue; import org.eclipse.xtext.common.types.JvmExecutable; +import org.eclipse.xtext.common.types.JvmField; import org.eclipse.xtext.common.types.JvmFloatAnnotationValue; import org.eclipse.xtext.common.types.JvmFormalParameter; import org.eclipse.xtext.common.types.JvmIdentifiableElement; import org.eclipse.xtext.common.types.JvmIntAnnotationValue; import org.eclipse.xtext.common.types.JvmLongAnnotationValue; +import org.eclipse.xtext.common.types.JvmOperation; import org.eclipse.xtext.common.types.JvmShortAnnotationValue; import org.eclipse.xtext.common.types.JvmStringAnnotationValue; import org.eclipse.xtext.common.types.JvmTypeAnnotationValue; @@ -64,14 +72,17 @@ import org.eclipse.xtext.xbase.XAbstractFeatureCall; import org.eclipse.xtext.xbase.XBlockExpression; import org.eclipse.xtext.xbase.XBooleanLiteral; +import org.eclipse.xtext.xbase.XClosure; import org.eclipse.xtext.xbase.XExpression; import org.eclipse.xtext.xbase.XFeatureCall; +import org.eclipse.xtext.xbase.XMemberFeatureCall; import org.eclipse.xtext.xbase.XNumberLiteral; import org.eclipse.xtext.xbase.XStringLiteral; import org.eclipse.xtext.xbase.XTypeLiteral; import org.eclipse.xtext.xbase.XVariableDeclaration; import org.eclipse.xtext.xbase.compiler.IGeneratorConfigProvider; import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable; +import org.eclipse.xtext.xbase.lib.util.ReflectExtensions; import org.eclipse.xtext.xbase.typesystem.IBatchTypeResolver; import org.eclipse.xtext.xbase.typesystem.IResolvedTypes; import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference; @@ -84,6 +95,9 @@ import io.sarl.lang.sarl.SarlBreakExpression; import io.sarl.lang.sarl.SarlContinueExpression; import io.sarl.lang.typesystem.SARLExpressionHelper; +import io.sarl.lang.util.ContextAwareTreeAppendable; +import io.sarl.lang.util.SerializableProxy; +import io.sarl.lang.util.Utils; /** The compiler from SARL to the target language. @@ -104,7 +118,7 @@ * to generate as much as possible. * *

The compiler adds a return statement when the early exit statement in SARL is not an early exist statement - * in Java. In this case a Java "return" statement must be added impliclitly. + * in Java. In this case a Java "return" statement must be added implicitly. * *

The roles of the different generation tools are:

    *
  • {@link SARLJvmModelInferrer}: Generating the expected Java Ecore model from the SARL Ecore model.
  • @@ -128,6 +142,8 @@ public class SarlCompiler extends XtendCompiler { private static final String INLINE_IMPORTED_NAME = "imported"; //$NON-NLS-1$ + private static final String SERIALIZABLE_CLOSURE_LOCAL_REFERENCES = "serializableClosure.localReferences"; //$NON-NLS-1$ + private static final Pattern INLINE_VARIABLE_PATTERN = Pattern.compile("\\" + INLINE_VARIABLE_PREFIX //$NON-NLS-1$ + "(\\" + INLINE_VARIABLE_PREFIX + "|[0-9]+)"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -149,6 +165,10 @@ public class SarlCompiler extends XtendCompiler { @Inject private ISarlEarlyExitComputer earlyExit; + //FIXME: Remove according to https://github.com/eclipse/xtext-extras/pull/331 + @Inject + private ReflectExtensions reflect; + private volatile boolean isOnJavaEarlyExit; @SuppressWarnings({"checkstyle:returncount", "checkstyle:npathcomplexity", "checkstyle:cyclomaticcomplexity"}) @@ -381,6 +401,19 @@ protected void _toJavaStatement(SarlContinueExpression breakExpression, ITreeApp appendable.newLine().append("continue;"); //$NON-NLS-1$ } + @Override + protected void _toJavaStatement(XClosure closure, ITreeAppendable appendable, boolean isReferenced) { + // This function is implemented in order to generate static inner class when the closure + // cannot be represented neither by a Java 8 lambda nor a not-static inner class. + // It solves the issues related to the serialization and deserialization of the closures. + final LightweightTypeReference type = getLightweightType(closure); + final JvmOperation operation = findImplementingOperation(type); + if (!canCompileToJavaLambda(closure, type, operation) && !canBeNotStaticAnonymousClass(closure, type, operation)) { + toSerializableAnonymousClassProxyDefinition(closure, appendable, type, operation); + } + super._toJavaStatement(closure, appendable, isReferenced); + } + /** Generate the Java code to the preparation statements for the assert keyword. * * @param assertExpression the expression. @@ -546,14 +579,19 @@ protected boolean internalCanCompileToJavaExpression(XExpression expression, ITr @Override protected boolean isVariableDeclarationRequired(XExpression expression, ITreeAppendable appendable, boolean recursive) { + // Add the following test for avoiding to create an variable declaration when the expression has already a name. + final String refName = getReferenceName(expression, appendable); + if (!Strings.isEmpty(refName)) { + return false; + } // Overridden for enabling the expressions that are specific to SARL - final EObject container = expression.eContainer(); if (expression instanceof SarlBreakExpression) { return false; } if (expression instanceof SarlContinueExpression) { return false; } + final EObject container = expression.eContainer(); if (container instanceof SarlAssertExpression) { return false; } @@ -595,4 +633,325 @@ public ITreeAppendable compile(XExpression expr, ITreeAppendable parentAppendabl return super.compile(expr, parentAppendable, expectedReturnType, declaredExceptions); } + @SuppressWarnings({"checkstyle:nestedifdepth", "checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"}) + private List getReferencedExternalCalls(XExpression expression, + List exclusion, boolean enableExpressionNaming, ITreeAppendable appendable) { + // This function is implemented in order to generate static inner class when the closure + // cannot be represented neither by a Java 8 lambda nor a not-static inner class. + // It solves the issues related to the serialization and deserialization of the closures. + final List references = new ArrayList<>(); + final Set identifiers = new TreeSet<>(); + for (final XAbstractFeatureCall featureCall : EcoreUtil2.getAllContentsOfType(expression, XAbstractFeatureCall.class)) { + if (featureCall instanceof XMemberFeatureCall || featureCall instanceof XFeatureCall) { + final JvmIdentifiableElement feature = featureCall.getFeature(); + XAbstractFeatureCall selected = null; + boolean forceNaming = false; + XAbstractFeatureCall root = null; + if (feature instanceof JvmFormalParameter) { + if (!exclusion.contains(feature)) { + selected = featureCall; + forceNaming = true; + } + } else if (feature instanceof XVariableDeclaration) { + if (!EcoreUtil.isAncestor(expression, feature)) { + selected = featureCall; + forceNaming = true; + } + } else if (feature instanceof JvmField) { + selected = featureCall; + forceNaming = true; + } else if (featureCall instanceof XFeatureCall) { + selected = featureCall; + } else if (featureCall instanceof XMemberFeatureCall && feature instanceof JvmOperation) { + final JvmOperation operation = (JvmOperation) feature; + if (operation.isStatic()) { + root = Utils.getRootFeatureCall(featureCall, expression, exclusion); + if (root != null && root != featureCall) { + selected = featureCall; + } + } + } + if (selected != null) { + if (root == null) { + root = Utils.getRootFeatureCall(selected, expression, exclusion); + } + if (root != null) { + if (enableExpressionNaming) { + final String refName = getReferenceName(root, appendable); + if (!forceNaming || Strings.isEmpty(refName)) { + final String proposedName = "$" + makeJavaIdentifier(getFavoriteVariableName(root)); //$NON-NLS-1$ + appendable.declareSyntheticVariable(root, proposedName); + } + } + updateReferenceList(references, identifiers, root); + } + } + } + } + return references; + } + + private static void updateReferenceList(List references, Set identifiers, + XAbstractFeatureCall featureCall) { + final JvmIdentifiableElement feature = featureCall.getFeature(); + if (feature instanceof JvmFormalParameter || feature instanceof XVariableDeclaration || feature instanceof JvmField) { + if (identifiers.add(feature.getIdentifier())) { + references.add(featureCall); + } + } else if (!references.contains(featureCall)) { + references.add(featureCall); + } + } + + @Override + protected void prepareExpression(XExpression arg, ITreeAppendable appendable) { + // This function is implemented in order to generate static inner class when the closure + // cannot be represented neither by a Java 8 lambda nor a not-static inner class. + // It solves the issues related to the serialization and deserialization of the closures. + if (arg instanceof XAbstractFeatureCall && appendable instanceof ContextAwareTreeAppendable) { + final XAbstractFeatureCall featureCall = (XAbstractFeatureCall) arg; + final ContextAwareTreeAppendable cappendable = (ContextAwareTreeAppendable) appendable; + final List localReferences = cappendable.getContextualValue(SERIALIZABLE_CLOSURE_LOCAL_REFERENCES); + if (localReferences != null) { + final XAbstractFeatureCall root = Utils.getRootFeatureCall(featureCall); + if (localReferences.contains(root)) { + return; + } + } + } + super.prepareExpression(arg, appendable); + } + + @SuppressWarnings("checkstyle:npathcomplexity") + private ITreeAppendable toSerializableAnonymousClassProxyDefinition(XClosure closure, ITreeAppendable appendable, + LightweightTypeReference type, JvmOperation operation) { + // This function is implemented in order to generate static inner class when the closure + // cannot be represented neither by a Java 8 lambda nor a not-static inner class. + // It solves the issues related to the serialization and deserialization of the closures. + final String implementationType = appendable.declareUniqueNameVariable(type, "$SerializableClosureProxy"); //$NON-NLS-1$ + appendable.newLine().append("class "); //$NON-NLS-1$ + appendable.append(implementationType); + if (type.isInterfaceType()) { + appendable.append(" implements "); //$NON-NLS-1$ + } else { + appendable.append(" extends "); //$NON-NLS-1$ + } + appendable.append(type); + appendable.append(" {"); //$NON-NLS-1$ + appendable.increaseIndentation(); + + appendable.openPseudoScope(); + try { + final List closureParams = closure.getFormalParameters(); + final List localReferences = getReferencedExternalCalls( + closure.getExpression(), closureParams, true, appendable); + try { + appendable.openScope(); + + for (final XAbstractFeatureCall call : localReferences) { + final LightweightTypeReference exprType = toLightweight(getType(call), closure); + final String paramName = getReferenceName(call, appendable); + appendable.newLine().newLine().append("private final ").append(exprType); //$NON-NLS-1$ + appendable.append(" ").append(paramName).append(";"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + appendable.newLine().newLine().append("public ").append(implementationType).append("("); //$NON-NLS-1$//$NON-NLS-2$ + boolean first = true; + for (final XAbstractFeatureCall call : localReferences) { + if (first) { + first = false; + } else { + appendable.append(", "); //$NON-NLS-1$ + } + final LightweightTypeReference exprType = toLightweight(getType(call), closure); + final String paramName = getReferenceName(call, appendable); + appendable.append("final ").append(exprType).append(" ").append(paramName); //$NON-NLS-1$ //$NON-NLS-2$ + } + + appendable.append(") {").increaseIndentation(); //$NON-NLS-1$ + for (final XAbstractFeatureCall call : localReferences) { + final String varName = getReferenceName(call, appendable); + appendable.newLine().append("this.").append(varName).append(" = "); //$NON-NLS-1$//$NON-NLS-2$ + appendable.append(varName).append(";"); //$NON-NLS-1$ + } + appendable.decreaseIndentation().newLine().append("}").newLine(); //$NON-NLS-1$ + + final LightweightTypeReference returnType = getClosureOperationReturnType(type, operation); + appendOperationVisibility(appendable, operation); + if (!operation.getTypeParameters().isEmpty()) { + //FIXME: Remove reflect according to https://github.com/eclipse/xtext-extras/pull/331 + this.reflect.invoke(this, "appendTypeParameters", appendable, operation, type); //$NON-NLS-1$ + } + appendable.append(returnType); + appendable.append(" ").append(operation.getSimpleName()); //$NON-NLS-1$ + appendable.append("("); //$NON-NLS-1$ + final boolean isVarArgs = operation.isVarArgs(); + for (int i = 0; i < closureParams.size(); i++) { + final JvmFormalParameter closureParam = closureParams.get(i); + final LightweightTypeReference parameterType = getClosureOperationParameterType(type, operation, i); + if (isVarArgs && i == closureParams.size() - 1 && parameterType.isArray()) { + appendClosureParameterVarArgs(closureParam, parameterType.getComponentType(), appendable); + } else { + appendClosureParameter(closureParam, parameterType, appendable); + } + if (i != closureParams.size() - 1) { + appendable.append(", "); //$NON-NLS-1$ + } + } + appendable.append(")"); //$NON-NLS-1$ + if (!operation.getExceptions().isEmpty()) { + appendable.append(" throws "); //$NON-NLS-1$ + for (int i = 0; i < operation.getExceptions().size(); ++i) { + serialize(operation.getExceptions().get(i), closure, appendable, false, false, false, false); + if (i != operation.getExceptions().size() - 1) { + appendable.append(", "); //$NON-NLS-1$ + } + } + } + appendable.append(" {"); //$NON-NLS-1$ + appendable.increaseIndentation(); + reassignThisInClosure(appendable, null); + final ContextAwareTreeAppendable contextAppendable = new ContextAwareTreeAppendable(appendable); + contextAppendable.defineContextualValue(SERIALIZABLE_CLOSURE_LOCAL_REFERENCES, localReferences); + compile(closure.getExpression(), + contextAppendable, + returnType, newHashSet(operation.getExceptions())); + //FIXME: Remove reflect according to https://github.com/eclipse/xtext-extras/pull/331 + this.reflect.invoke(this, "closeBlock", appendable); //$NON-NLS-1$ + } catch (Exception exception) { + throw new RuntimeException(exception); + } finally { + appendable.closeScope(); + } + appendable.decreaseIndentation().newLine().append("}"); //$NON-NLS-1$ + } finally { + appendable.closeScope(); + } + return appendable; + } + + @Override + protected ITreeAppendable toAnonymousClass(XClosure closure, ITreeAppendable appendable, LightweightTypeReference type, + JvmOperation operation) { + // This function is implemented in order to generate static inner class when the closure + // cannot be represented neither by a Java 8 lambda nor a not-static inner class. + // It solves the issues related to the serialization and deserialization of the closures. + if (canBeNotStaticAnonymousClass(closure, type, operation) + || Strings.isEmpty(getVarName(type, appendable))) { + return super.toAnonymousClass(closure, appendable, type, operation); + } + return toSerializableAnonymousClass(closure, appendable, type, operation); + } + + @SuppressWarnings("checkstyle:npathcomplexity") + private ITreeAppendable toSerializableAnonymousClass(XClosure closure, ITreeAppendable appendable, + LightweightTypeReference type, JvmOperation operation) { + // This function is implemented in order to generate static inner class when the closure + // cannot be represented neither by a Java 8 lambda nor a not-static inner class. + // It solves the issues related to the serialization and deserialization of the closures. + final List closureParams = closure.getFormalParameters(); + appendable.openPseudoScope(); + try { + final List localReferences = getReferencedExternalCalls( + closure.getExpression(), closureParams, false, appendable); + final LightweightTypeReference returnType = getClosureOperationReturnType(type, operation); + appendable.append("new ").append(type).append("() {"); //$NON-NLS-1$ //$NON-NLS-2$ + appendable.increaseIndentation(); + try { + appendable.openScope(); + String selfVariable = null; + if (needSyntheticSelfVariable(closure, type)) { + appendable.newLine().append("final "); //$NON-NLS-1$ + appendable.append(type).append(" "); //$NON-NLS-1$ + selfVariable = appendable.declareVariable(type.getType(), "_self"); //$NON-NLS-1$ + appendable.append(selfVariable); + appendable.append(" = this;"); //$NON-NLS-1$ + } + appendOperationVisibility(appendable, operation); + if (!operation.getTypeParameters().isEmpty()) { + //FIXME: Remove reflect according to https://github.com/eclipse/xtext-extras/pull/331 + this.reflect.invoke(this, "appendTypeParameters", appendable, operation, type); //$NON-NLS-1$ + } + appendable.append(returnType); + appendable.append(" ").append(operation.getSimpleName()); //$NON-NLS-1$ + appendable.append("("); //$NON-NLS-1$ + final boolean isVarArgs = operation.isVarArgs(); + for (int i = 0; i < closureParams.size(); i++) { + final JvmFormalParameter closureParam = closureParams.get(i); + final LightweightTypeReference parameterType = getClosureOperationParameterType(type, operation, i); + if (isVarArgs && i == closureParams.size() - 1 && parameterType.isArray()) { + appendClosureParameterVarArgs(closureParam, parameterType.getComponentType(), appendable); + } else { + appendClosureParameter(closureParam, parameterType, appendable); + } + if (i != closureParams.size() - 1) { + appendable.append(", "); //$NON-NLS-1$ + } + } + appendable.append(")"); //$NON-NLS-1$ + if (!operation.getExceptions().isEmpty()) { + appendable.append(" throws "); //$NON-NLS-1$ + for (int i = 0; i < operation.getExceptions().size(); ++i) { + serialize(operation.getExceptions().get(i), closure, appendable, false, false, false, false); + if (i != operation.getExceptions().size() - 1) { + appendable.append(", "); //$NON-NLS-1$ + } + } + } + appendable.append(" {"); //$NON-NLS-1$ + appendable.increaseIndentation(); + if (selfVariable == null) { + reassignThisInClosure(appendable, type.getType()); + } else { + // We have already assigned the closure type to _self, so don't assign it again + reassignThisInClosure(appendable, null); + } + compile(closure.getExpression(), appendable, returnType, newHashSet(operation.getExceptions())); + //FIXME: Remove reflect according to https://github.com/eclipse/xtext-extras/pull/331 + this.reflect.invoke(this, "closeBlock", appendable); //$NON-NLS-1$ + } catch (Exception exception) { + throw new RuntimeException(exception); + } finally { + appendable.closeScope(); + } + appendable.newLine().append("private ").append(Object.class).append(" writeReplace() throws "); //$NON-NLS-1$//$NON-NLS-2$ + appendable.append(ObjectStreamException.class).append(" {").increaseIndentation().newLine(); //$NON-NLS-1$ + appendable.append("return new ").append(SerializableProxy.class); //$NON-NLS-1$ + appendable.append("(").append(appendable.getName(type)).append(".class"); //$NON-NLS-1$ //$NON-NLS-2$ + for (final XAbstractFeatureCall call : localReferences) { + appendable.append(", "); //$NON-NLS-1$ + compileAsJavaExpression(call, appendable, returnType); + } + + appendable.append(");").decreaseIndentation().newLine().append("}"); //$NON-NLS-1$ //$NON-NLS-2$ + appendable.decreaseIndentation().newLine().append("}"); //$NON-NLS-1$ + } finally { + appendable.closeScope(); + } + return appendable; + } + + /** Replies if the given closure could be represented by an not static anonymous class. + * + * @param closure the closure. + * @param typeRef the type of the closure. + * @param operation the operation to implement. + * @return {@code true} if the given closure could be represented by a not-static anonymous class. + * @since 0.8.6 + */ + @SuppressWarnings("static-method") + protected boolean canBeNotStaticAnonymousClass(XClosure closure, LightweightTypeReference typeRef, + JvmOperation operation) { + return !typeRef.isSubtypeOf(Serializable.class); + } + + @Override + protected boolean canCompileToJavaLambda(XClosure closure, LightweightTypeReference typeRef, + JvmOperation operation) { + // This function overrides the super one in order to avoid the generation of a Java 8 lambda when + // the implemented interface is serializable. In this case, it will avoid issue for serialization and + // deserialization of the closure. + return !typeRef.isSubtypeOf(Serializable.class) && super.canCompileToJavaLambda(closure, typeRef, operation); + } + } diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/extralanguage/validator/AbstractExtraLanguageValidator.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/extralanguage/validator/AbstractExtraLanguageValidator.java index 79ee68cb52..2fdb7ffda7 100644 --- a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/extralanguage/validator/AbstractExtraLanguageValidator.java +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/extralanguage/validator/AbstractExtraLanguageValidator.java @@ -246,7 +246,7 @@ private Iterable getMethods(EObject currentObject) { protected boolean isResponsible(Map context, EObject eObject) { // Skip the validation of an feature call if one of its container was validated previously if (eObject instanceof XMemberFeatureCall || eObject instanceof XFeatureCall) { - final XAbstractFeatureCall rootFeatureCall = getRootFeatureCall((XAbstractFeatureCall) eObject); + final XAbstractFeatureCall rootFeatureCall = Utils.getRootFeatureCall((XAbstractFeatureCall) eObject); return !isCheckedFeatureCall(context, rootFeatureCall); } return true; @@ -432,7 +432,7 @@ private static void setCheckedFeatureCall(Map context, EObject e protected void doCheckMemberFeatureCallMapping(XAbstractFeatureCall featureCall, Procedure3 typeErrorHandler, Function2 featureErrorHandler) { - final XAbstractFeatureCall rootFeatureCall = getRootFeatureCall(featureCall); + final XAbstractFeatureCall rootFeatureCall = Utils.getRootFeatureCall(featureCall); final Map context = getContext().getContext(); if (isCheckedFeatureCall(context, rootFeatureCall)) { // One of the containing expressions was already checked. @@ -444,18 +444,6 @@ protected void doCheckMemberFeatureCallMapping(XAbstractFeatureCall featureCall, internalCheckMemberFeaturCallMapping(rootFeatureCall, typeErrorHandler, featureErrorHandler); } - private static XAbstractFeatureCall getRootFeatureCall(XAbstractFeatureCall featureCall) { - final EObject container = featureCall.eContainer(); - final XAbstractFeatureCall rootFeatureCall; - if (container instanceof XMemberFeatureCall || container instanceof XFeatureCall) { - rootFeatureCall = (XAbstractFeatureCall) Utils.getFirstContainerForPredicate(featureCall, - it -> it.eContainer() != null && !(it.eContainer() instanceof XMemberFeatureCall || it.eContainer() instanceof XFeatureCall)); - } else { - rootFeatureCall = featureCall; - } - return rootFeatureCall; - } - private boolean internalCheckMemberFeaturCallMapping(XAbstractFeatureCall featureCall, Procedure3 typeErrorHandler, Function2 featureErrorHandler) { diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/GenerationContext.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/GenerationContext.java index cf817e7f23..2a9a1264d7 100644 --- a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/GenerationContext.java +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/GenerationContext.java @@ -32,6 +32,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtend.core.xtend.XtendMember; import org.eclipse.xtext.common.types.JvmConstructor; +import org.eclipse.xtext.common.types.JvmDeclaredType; import org.eclipse.xtext.common.types.JvmOperation; import org.eclipse.xtext.util.JavaVersion; import org.eclipse.xtext.xbase.compiler.GeneratorConfig; @@ -57,7 +58,7 @@ */ abstract class GenerationContext { - private final String identifier; + private final JvmDeclaredType target; /** Compute serial number for serializable objects. */ @@ -138,10 +139,10 @@ abstract class GenerationContext { /** Construct a information about the generation. * * @param owner the object for which the context is created. - * @param identifier the identifier of the type for which the context is opened. + * @param target the target type for which the context is opened. */ - GenerationContext(EObject owner, String identifier) { - this.identifier = identifier; + GenerationContext(EObject owner, JvmDeclaredType target) { + this.target = target; this.contextObject = owner; } @@ -173,7 +174,16 @@ public void setParentContext(GenerationContext parent) { * @return the identifier of the context's type. */ public String getTypeIdentifier() { - return this.identifier; + return this.target.getIdentifier(); + } + + /** Replies the associated type. + * + * @return the context's type. + * @since 0.8.6 + */ + public JvmDeclaredType getType() { + return this.target; } /** Replies the generator configuration. diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java index a44c5b46dc..1953d60bf0 100644 --- a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java @@ -471,7 +471,7 @@ protected void initializeLocalTypes(GenerationContext context, JvmFeature featur /** {@inheritDoc}. * - *

    Overridden for: removing the existing associated body, and delaying the local type inferrence. + *

    Overridden for: removing the existing associated body, and delaying the local type inference. */ @Override protected void setBody(JvmExecutable executable, XExpression expression) { @@ -517,12 +517,12 @@ protected void setBody(JvmExecutable executable, Procedure1 exp * @param supportedMemberTypes the types of the supported members. * @return the created context. */ - protected final synchronized GenerationContext openContext(EObject sarlObject, JvmIdentifiableElement type, + protected final synchronized GenerationContext openContext(EObject sarlObject, JvmDeclaredType type, final Iterable> supportedMemberTypes) { assert type != null; assert supportedMemberTypes != null; this.sarlSignatureProvider.clear(type); - final GenerationContext context = new GenerationContext(sarlObject, type.getIdentifier()) { + final GenerationContext context = new GenerationContext(sarlObject, type) { @Override public boolean isSupportedMember(XtendMember member) { for (final Class supportedMemberType : supportedMemberTypes) { diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/ContextAwareTreeAppendable.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/ContextAwareTreeAppendable.java new file mode 100644 index 0000000000..7da6fce547 --- /dev/null +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/ContextAwareTreeAppendable.java @@ -0,0 +1,109 @@ +/* + * $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.util; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable; + +/** + * A delegating tree appendable which is aware of th current compilation context. + * + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @since 0.8.6 + */ +public class ContextAwareTreeAppendable extends DelegateTreeAppendable { + + private final Map values; + + /** Constructor. + * + * @param delegate the appendable to delegate to. + */ + public ContextAwareTreeAppendable(ITreeAppendable delegate) { + super(delegate); + this.values = new HashMap<>(); + } + + /** Constructor. + * + * @param contextualValues the contextual values. + * @param delegate the appendable to delegate to. + */ + protected ContextAwareTreeAppendable(Map contextualValues, ITreeAppendable delegate) { + super(delegate); + this.values = contextualValues; + } + + @Override + protected ITreeAppendable createDelegateToChild(ITreeAppendable child) { + return new ContextAwareTreeAppendable(this.values, child); + } + + /** Define a contextual value. + * + * @param the type of the value. + * @param key the name of the value. + * @param value the value itself. + * @return the previous value associated to the key, or {@code null} if none. + */ + @SuppressWarnings("unchecked") + public T defineContextualValue(String key, Object value) { + return (T) this.values.put(key, value); + } + + /** Define a contextual value. + * + * @param the type of the value. + * @param key the name of the value. + * @return the previous value associated to the key, or {@code null} if none. + */ + @SuppressWarnings("unchecked") + public T deleteContextualValue(String key) { + return (T) this.values.remove(key); + } + + /** Replies the contextual value associated to the given key. + * + * @param the type of the value. + * @param key the name of the value. + * @return the value associated to the key, or {@code null} if none. + */ + @SuppressWarnings("unchecked") + public T getContextualValue(String key) { + return (T) this.values.get(key); + } + + /** Replies if a contextual value is associated to the given key. + * + * @param key the name of the value. + * @return {@code true} if a value is associated to the key, or {@code false} if none. + */ + public boolean hasContextualValue(String key) { + return this.values.containsKey(key); + } + +} diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/DelegateTreeAppendable.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/DelegateTreeAppendable.java new file mode 100644 index 0000000000..fc47d6cc1d --- /dev/null +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/DelegateTreeAppendable.java @@ -0,0 +1,239 @@ +/* + * $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.util; + +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.xtext.common.types.JvmType; +import org.eclipse.xtext.generator.trace.AbstractTraceRegion; +import org.eclipse.xtext.generator.trace.ILocationData; +import org.eclipse.xtext.generator.trace.TraceNotFoundException; +import org.eclipse.xtext.xbase.compiler.GeneratorConfig; +import org.eclipse.xtext.xbase.compiler.output.ErrorTreeAppendable; +import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable; +import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference; + +/** + * A delegating tree appendable. + * + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @since 0.8.6 + */ +public class DelegateTreeAppendable implements ITreeAppendable { + + private final ITreeAppendable delegate; + + /** Constructor. + * + * @param delegate the appendable to delegate to. + */ + public DelegateTreeAppendable(ITreeAppendable delegate) { + assert delegate != null; + this.delegate = delegate; + } + + /** {@inheritDoc} + * @deprecated imports are handled by external components. + */ + @Override + @Deprecated + public List getImports() { + return this.delegate.getImports(); + } + + @Override + public void openScope() { + this.delegate.openScope(); + } + + @Override + public void openPseudoScope() { + this.delegate.openPseudoScope(); + } + + @Override + public String declareVariable(Object key, String proposedName) { + return this.delegate.declareVariable(key, proposedName); + } + + @Override + public String declareSyntheticVariable(Object key, String proposedName) { + return this.delegate.declareSyntheticVariable(key, proposedName); + } + + @Override + public String declareUniqueNameVariable(Object key, String proposedName) { + return this.delegate.declareUniqueNameVariable(key, proposedName); + } + + @Override + public String getName(Object key) { + return this.delegate.getName(key); + } + + @Override + public String removeName(Object key) throws IllegalStateException { + return this.delegate.removeName(key); + } + + @Override + public boolean hasName(Object key) { + return this.delegate.hasName(key); + } + + @Override + public Object getObject(String name) { + return this.delegate.getObject(name); + } + + @Override + public boolean hasObject(String name) { + return this.delegate.hasObject(name); + } + + @Override + public void closeScope() { + this.delegate.closeScope(); + } + + @Override + public int length() { + return this.delegate.length(); + } + + @Override + public String getContent() { + return this.delegate.getContent(); + } + + @Override + public GeneratorConfig getGeneratorConfig() { + return this.delegate.getGeneratorConfig(); + } + + @Override + public boolean isJava() { + return this.delegate.isJava(); + } + + @Override + public AbstractTraceRegion getTraceRegion() throws TraceNotFoundException { + return this.delegate.getTraceRegion(); + } + + @Override + public ITreeAppendable trace(EObject object, boolean useForDebugging) { + return createDelegateToChild(this.delegate.trace(object, useForDebugging)); + } + + @Override + public ITreeAppendable trace(EObject object) { + return createDelegateToChild(this.delegate.trace(object)); + } + + @Override + public ITreeAppendable trace(Iterable objects) { + return createDelegateToChild(this.delegate.trace(objects)); + } + + @Override + public ITreeAppendable trace(EObject object, EStructuralFeature feature, int indexInList) { + return createDelegateToChild(this.delegate.trace(object, feature, indexInList)); + } + + @Override + public ITreeAppendable trace(ILocationData location) { + return createDelegateToChild(this.delegate.trace(location)); + } + + @Override + public ITreeAppendable trace(ILocationData location, boolean useForDebugging) { + return createDelegateToChild(this.delegate.trace(location, useForDebugging)); + } + + /** Create a child appendable. + * + * @param child the child to delegate to. + * @return the child. + */ + @SuppressWarnings("static-method") + protected ITreeAppendable createDelegateToChild(ITreeAppendable child) { + return new DelegateTreeAppendable(child); + } + + @Override + public ErrorTreeAppendable errorChild() { + return this.delegate.errorChild(); + } + + @Override + public ITreeAppendable append(JvmType type) { + this.delegate.append(type); + return this; + } + + @Override + public ITreeAppendable append(Class type) { + this.delegate.append(type); + return this; + } + + @Override + public ITreeAppendable append(LightweightTypeReference typeRef) { + this.delegate.append(typeRef); + return this; + } + + @Override + public ITreeAppendable append(CharSequence content) { + this.delegate.append(content); + return this; + } + + @Override + public ITreeAppendable decreaseIndentation() { + this.delegate.decreaseIndentation(); + return this; + } + + @Override + public ITreeAppendable increaseIndentation() { + this.delegate.increaseIndentation(); + return this; + } + + @Override + public ITreeAppendable newLine() { + this.delegate.newLine(); + return this; + } + + @Override + public String toString() { + return this.delegate.toString(); + } +} diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/Utils.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/Utils.java index 62d33bfec9..d7b8277f30 100644 --- a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/Utils.java +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/util/Utils.java @@ -42,6 +42,7 @@ import java.util.regex.Pattern; import com.google.common.base.Strings; +import com.google.common.collect.Iterables; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; @@ -79,7 +80,11 @@ import org.eclipse.xtext.serializer.ISerializer; import org.eclipse.xtext.util.EmfFormatter; import org.eclipse.xtext.util.XtextVersion; +import org.eclipse.xtext.xbase.XAbstractFeatureCall; import org.eclipse.xtext.xbase.XExpression; +import org.eclipse.xtext.xbase.XFeatureCall; +import org.eclipse.xtext.xbase.XMemberFeatureCall; +import org.eclipse.xtext.xbase.XVariableDeclaration; import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation; import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotationElementValuePair; import org.eclipse.xtext.xbase.compiler.ImportManager; @@ -1679,4 +1684,96 @@ public static void copyTypeParametersFromJvmOperation(List inp } } + /** Replies the root feature call into a sequence of feature calls. + * + * @param featureCall the leaf feature call. + * @return the root feature call. + * @since 0.8.6 + * @see #getRootFeatureCall(XAbstractFeatureCall, XExpression, List) + */ + public static XAbstractFeatureCall getRootFeatureCall(XAbstractFeatureCall featureCall) { + final EObject container = featureCall.eContainer(); + final XAbstractFeatureCall rootFeatureCall; + if (container instanceof XMemberFeatureCall || container instanceof XFeatureCall) { + rootFeatureCall = (XAbstractFeatureCall) getFirstContainerForPredicate(featureCall, + it -> it.eContainer() != null && !(it.eContainer() instanceof XMemberFeatureCall || it.eContainer() instanceof XFeatureCall)); + } else { + rootFeatureCall = featureCall; + } + return rootFeatureCall; + } + + /** Replies the root feature call into a sequence of feature calls that has + * not reference to elements declared within the container, and that are + * not one of the container's parameters. + * + * @param featureCall the leaf feature call. + * @param container the container of the feature call. + * @param containerParameters the parameters of the container. + * @return the root feature call, or {@code null} if there is no root feature call. + * @since 0.8.6 + * @see #getRootFeatureCall(XAbstractFeatureCall) + */ + public static XAbstractFeatureCall getRootFeatureCall(XAbstractFeatureCall featureCall, + XExpression container, List containerParameters) { + if (hasLocalParameters(featureCall, container, containerParameters) + || !(featureCall instanceof XMemberFeatureCall || featureCall instanceof XFeatureCall)) { + return null; + } + XAbstractFeatureCall current = featureCall; + EObject currentContainer = current.eContainer(); + while (currentContainer != null) { + if (currentContainer instanceof XMemberFeatureCall || currentContainer instanceof XFeatureCall) { + final XAbstractFeatureCall c = (XAbstractFeatureCall) currentContainer; + if (hasLocalParameters(c, container, containerParameters)) { + return current; + } + current = c; + currentContainer = current.eContainer(); + } else { + return current; + } + } + return current; + } + + private static boolean hasLocalParameters(EObject current, XExpression container, List containerParameters) { + if (current instanceof XAbstractFeatureCall) { + final XAbstractFeatureCall featureCall = (XAbstractFeatureCall) current; + if (isLocalEntity(featureCall, container, containerParameters)) { + return true; + } + for (final XExpression argument : featureCall.getActualArguments()) { + final Iterable iterable; + if (argument instanceof XAbstractFeatureCall) { + iterable = Iterables.concat( + Collections.singletonList((XAbstractFeatureCall) argument), + EcoreUtil2.getAllContentsOfType(argument, XAbstractFeatureCall.class)); + } else { + iterable = EcoreUtil2.getAllContentsOfType(argument, XAbstractFeatureCall.class); + } + for (final XAbstractFeatureCall c : iterable) { + if (isLocalEntity(c, container, containerParameters)) { + return true; + } + } + } + } + return false; + } + + private static boolean isLocalEntity(XAbstractFeatureCall featureCall, XExpression container, List containerParameters) { + final JvmIdentifiableElement feature = featureCall.getFeature(); + if (feature instanceof JvmFormalParameter) { + if (containerParameters.contains(feature)) { + return true; + } + } else if (feature instanceof XVariableDeclaration) { + if (EcoreUtil.isAncestor(container, feature)) { + return true; + } + } + return false; + } + } diff --git a/pom.xml b/pom.xml index fe69f8a4c7..c4b815b977 100644 --- a/pom.xml +++ b/pom.xml @@ -204,6 +204,14 @@ Documentation Contributor + + Alexandre Lombard + alexandre.lombard@utbm.fr + https://github.com/alexandrelombard + + Unit Tests + + Ludovico de Nittis aasonykk@gmail.com diff --git a/sre/io.janusproject/io.janusproject.plugin/src/io/janusproject/modules/eventserial/NetworkEventModule.java b/sre/io.janusproject/io.janusproject.plugin/src/io/janusproject/modules/eventserial/NetworkEventModule.java index f570b5d04a..a5c1736e62 100644 --- a/sre/io.janusproject/io.janusproject.plugin/src/io/janusproject/modules/eventserial/NetworkEventModule.java +++ b/sre/io.janusproject/io.janusproject.plugin/src/io/janusproject/modules/eventserial/NetworkEventModule.java @@ -21,6 +21,7 @@ package io.janusproject.modules.eventserial; +import java.text.DateFormat; import java.util.Properties; import com.google.gson.Gson; @@ -48,14 +49,18 @@ */ public class NetworkEventModule extends AbstractModule { + private static final Class DEFAULT_EVENT_SERIALIZER = GsonEventSerializer.class; + + private static final Class DEFAULT_EVENT_ENCRYPTER = PlainTextEventEncrypter.class; + /** * Replies the default values for the properties supported by Janus config. * * @param defaultValues filled with the default values supported by the Janus platform. */ public static void getDefaultValues(Properties defaultValues) { - defaultValues.put(NetworkConfig.SERIALIZER_CLASSNAME, GsonEventSerializer.class.getName()); - defaultValues.put(NetworkConfig.ENCRYPTER_CLASSNAME, PlainTextEventEncrypter.class.getName()); + defaultValues.put(NetworkConfig.SERIALIZER_CLASSNAME, DEFAULT_EVENT_SERIALIZER.getName()); + defaultValues.put(NetworkConfig.ENCRYPTER_CLASSNAME, DEFAULT_EVENT_ENCRYPTER.getName()); } @Override @@ -66,6 +71,9 @@ protected void configure() { @Provides private static Gson createGson() { final GsonBuilder builder = new GsonBuilder() + .enableComplexMapKeySerialization() + .serializeSpecialFloatingPointValues() + .setDateFormat(DateFormat.SHORT, DateFormat.FULL) .registerTypeAdapter(Class.class, new GsonEventSerializer.ClassTypeAdapter()); // Make the serializer pretty when the application is launched in debug mode (ie. with assertions enabled). if (NetworkEventModule.class.desiredAssertionStatus()) { @@ -76,7 +84,7 @@ private static Gson createGson() { @Provides private static EventSerializer createEventSerializer(Injector injector) { - Class serializerType = GsonEventSerializer.class; + Class serializerType = DEFAULT_EVENT_SERIALIZER; final String serializerClassname = JanusConfig.getSystemProperty(NetworkConfig.SERIALIZER_CLASSNAME); if (serializerClassname != null && !serializerClassname.isEmpty()) { final Class type; @@ -113,7 +121,7 @@ private static EventEncrypter getEncrypter(Injector injector) { if (aesKey != null && !aesKey.isEmpty()) { encrypterType = AESEventEncrypter.class; } else { - encrypterType = PlainTextEventEncrypter.class; + encrypterType = DEFAULT_EVENT_ENCRYPTER; } } assert injector != null; diff --git a/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/bugs/network/Bug885.java b/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/bugs/network/Bug885.java new file mode 100644 index 0000000000..15e4d9c5b7 --- /dev/null +++ b/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/bugs/network/Bug885.java @@ -0,0 +1,171 @@ +/* + * $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.janusproject.tests.bugs.network; + +import java.io.ObjectStreamException; +import java.util.Collection; +import java.util.UUID; + +import com.google.common.base.Objects; +import org.junit.Ignore; +import org.junit.Test; + +import io.janusproject.tests.testutils.AbstractJanusRunTest; + +import io.sarl.core.DefaultContextInteractions; +import io.sarl.core.Logging; +import io.sarl.lang.SARLVersion; +import io.sarl.lang.annotation.PerceptGuardEvaluator; +import io.sarl.lang.annotation.SarlElementType; +import io.sarl.lang.annotation.SarlSpecification; +import io.sarl.lang.core.Address; +import io.sarl.lang.core.Event; +import io.sarl.lang.core.Scope; +import io.sarl.lang.sarl.SarlPackage; +import io.sarl.lang.util.SerializableProxy; + +/** Tests for issue #885: Guards are not evaluated when the event is fired across multiple kernels. + * + *

    See: https://github.com/sarl/sarl/issues/885 + * + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @see "https://github.com/sarl/sarl/issues/885" + */ +@SuppressWarnings("all") +public class Bug885 extends AbstractJanusRunTest { + + @Test + @Ignore + public void runPing() throws Exception { + runJanus(PingAgent.class, true, false, NO_TIMEOUT); + } + + @Test + @Ignore + public void runPong() throws Exception { + runJanus(PongAgent.class, true, false, NO_TIMEOUT); + } + + @SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING) + @SarlElementType(SarlPackage.SARL_EVENT) + static class Ping extends Event { + } + + @SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING) + @SarlElementType(SarlPackage.SARL_EVENT) + static class Pong extends Event { + } + + @SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING) + @SarlElementType(SarlPackage.SARL_AGENT) + static class PongAgent extends TestingAgent { + + public PongAgent(UUID parentID, UUID agentID) { + super(parentID, agentID); + } + + @Override + protected boolean runAgentTest() { + getSkill(Logging.class).info("ready to receive ping"); + return false; + } + + @PerceptGuardEvaluator + private void guardPing(Ping occurrence, Collection handlers) { + handlers.add(() -> onPing(occurrence)); + } + + private void onPing(Ping occurrence) { + getSkill(Logging.class).info("receive ping: " + occurrence); + class $SerializableClosureProxy implements Scope

    { + private final UUID uuid; + public $SerializableClosureProxy(UUID uuid) { + this.uuid = uuid; + } + @Override + public boolean matches(final Address it) { + return Objects.equal(it.getUUID(), this.uuid); + } + } + Scope
    scope = new Scope
    () { + @Override + public boolean matches(Address it) { + return Objects.equal(it.getUUID(), occurrence.getSource().getUUID()); + } + private Object writeReplace() throws ObjectStreamException { + return new SerializableProxy($SerializableClosureProxy.class, occurrence.getSource().getUUID()); + } + }; + getSkill(DefaultContextInteractions.class).emit(new Pong(), scope); + } + + } + + @SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING) + @SarlElementType(SarlPackage.SARL_AGENT) + static class PingAgent extends TestingAgent { + + public PingAgent(UUID parentID, UUID agentID) { + super(parentID, agentID); + } + + @Override + protected boolean runAgentTest() { + getSkill(Logging.class).info("initiate ping-pong protocol"); + getSkill(DefaultContextInteractions.class).emit(new Ping()); + return false; + } + + @PerceptGuardEvaluator + private void guardPong(Pong occurrence, Collection handlers) { + handlers.add(() -> onPong(occurrence)); + } + + private void onPong(Pong occurrence) { + getSkill(Logging.class).info("Receiver pong: " + occurrence); + class $SerializableClosureProxy implements Scope
    { + private final UUID uuid; + public $SerializableClosureProxy(UUID uuid) { + this.uuid = uuid; + } + @Override + public boolean matches(final Address it) { + return Objects.equal(it.getUUID(), this.uuid); + } + } + Scope
    scope = new Scope
    () { + @Override + public boolean matches(Address it) { + return Objects.equal(it.getUUID(), occurrence.getSource().getUUID()); + } + private Object writeReplace() throws ObjectStreamException { + return new SerializableProxy($SerializableClosureProxy.class, occurrence.getSource().getUUID()); + } + }; + getSkill(DefaultContextInteractions.class).emit(new Ping(), scope); + } + + } + +} diff --git a/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/kernel/services/gson/GsonEventSerializerTest.java b/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/kernel/services/gson/GsonEventSerializerTest.java index 2c6f126d70..a82a50c522 100644 --- a/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/kernel/services/gson/GsonEventSerializerTest.java +++ b/sre/io.janusproject/io.janusproject.tests/src/test/java/io/janusproject/tests/kernel/services/gson/GsonEventSerializerTest.java @@ -179,7 +179,7 @@ public void serialize() throws Exception { assertArrayEquals(this.serializedScope, e.getScope()); - System.out.println(Arrays.toString(e.getCustomHeaders())); + //System.out.println(Arrays.toString(e.getCustomHeaders())); assertArrayEquals(this.serializedHeader, e.getCustomHeaders()); diff --git a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00399/Bug291.java b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00399/Bug291.java index 1f4458909b..9fd04dfb72 100644 --- a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00399/Bug291.java +++ b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00399/Bug291.java @@ -77,8 +77,7 @@ public class Bug291 extends AbstractSarlTest { "public class S1 extends Skill implements C1 {", " public int myfct() {", " AgentTrait _caller = Capacities.getCaller();", - " boolean _tripleEquals = (_caller == null);", - " if (_tripleEquals) {", + " if ((_caller == null)) {", " }", " return 0;", " }", diff --git a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00699/Bug623.java b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00699/Bug623.java index b8a77e07b8..bafa5e49f8 100644 --- a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00699/Bug623.java +++ b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00699/Bug623.java @@ -185,14 +185,12 @@ public void compiling_03() throws Exception { " int _xblockexpression = (int) 0;", " {", " int vv = 4;", - " int _vv = vv;", - " vv = (_vv + 1);", + " vv = (vv + 1);", " final Function1 _function = (Integer it) -> {", " return Integer.valueOf((it.intValue() + vv));", " };", " this.fct2(_function);", - " int _vv_1 = vv;", - " vv = (_vv_1 + 1);", + " vv = (vv + 1);", " _xblockexpression = vv;", " }", " return _xblockexpression;", diff --git a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug819.java b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug819.java index d6219c2852..1c62ccdc6a 100644 --- a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug819.java +++ b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug819.java @@ -94,6 +94,8 @@ public class Bug819 extends AbstractSarlTest { "import io.sarl.lang.core.Scope;", "import io.sarl.lang.core.Skill;", "import io.sarl.lang.util.ClearableReference;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", "import java.util.Collection;", "import java.util.UUID;", "import javax.inject.Inject;", @@ -111,9 +113,29 @@ public class Bug819 extends AbstractSarlTest { " id = _$CAPACITY_USE$IO_SARL_CORE_LIFECYCLE$CALLER.spawn(Agent2.class, \"Gilbert\");", " DefaultContextInteractions _$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS$CALLER = this.$castSkill(DefaultContextInteractions.class, (this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS == null || this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS.get() == null) ? (this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS = this.$getSkill(DefaultContextInteractions.class)) : this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS);", " Hello _hello = new Hello();", - " final Scope
    _function = (Address it) -> {", - " UUID _uUID = it.getUUID();", - " return Objects.equal(_uUID, id);", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID id;", + " ", + " public $SerializableClosureProxy(final UUID id) {", + " this.id = id;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, id);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, id);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, id);", + " }", " };", " _$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS$CALLER.emit(_hello, _function);", " }", diff --git a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug885.java b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug885.java new file mode 100644 index 0000000000..440fc78edc --- /dev/null +++ b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/bugs/to00999/Bug885.java @@ -0,0 +1,3164 @@ +/* + * 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.tests.bugs.to00999; + +import com.google.inject.Inject; +import org.eclipse.xtext.xbase.testing.CompilationTestHelper; +import org.junit.Test; + +import io.sarl.lang.SARLVersion; +import io.sarl.lang.sarl.SarlPackage; +import io.sarl.lang.sarl.SarlScript; +import io.sarl.tests.api.AbstractSarlTest; +import io.sarl.tests.api.AbstractSarlTest.Validator; + +/** Testing class for issue: Guards are not evaluated when the event is fired across multiple kernels. + * + *

    https://github.com/sarl/sarl/issues/885 + * + * @author $Author: sgalland$ + * @author $Author: alombard$ + * @version $Name$ $Revision$ $Date$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @see "https://github.com/sarl/sarl/issues/885" + */ +@SuppressWarnings("all") +public class Bug885 extends AbstractSarlTest { + + @Inject + private CompilationTestHelper compiler; + + private static final String SNIPSET_LOCAL_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent Boot {", + " def f(s : Scope

    ) {", + " }", + " def f2(s : Scope
    , p : Address) {", + " f [ it.UUID == p.UUID ]", + " }", + "}"); + + private static final String EXPECTED_LOCAL_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s, final Address p) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = p.getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, p.getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalParameter() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_PARAMETER, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_PARAMETER, actual); + }); + } + + private static final String SNIPSET_LOCAL_VARIABLE = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " var p : Address = null", + " f [ it.UUID == p.UUID ]", + " }", + "}"); + + private static final String EXPECTED_LOCAL_VARIABLE = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " Address p = null;", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = p.getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, p.getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalVariable() throws Exception { + /*SarlScript mas = file(SNIPSET02); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_VARIABLE, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_VARIABLE, actual); + }); + } + + private static final String SNIPSET_FIELD = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " var p : Address = null", + " def f2(s : Scope
    ) {", + " f [ it.UUID == p.UUID ]", + " }", + "}"); + + private static final String EXPECTED_FIELD = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " private Address p = null;", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = Boot.this.p.getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.p.getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Override", + " @Pure", + " @SyntheticMember", + " public boolean equals(final Object obj) {", + " return super.equals(obj);", + " }", + " ", + " @Override", + " @Pure", + " @SyntheticMember", + " public int hashCode() {", + " int result = super.hashCode();", + " return result;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingField() throws Exception { + SarlScript mas = file(SNIPSET_FIELD); + final Validator validator = validate(mas); + validator.assertNoErrors(); + this.compiler.compile(SNIPSET_FIELD, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_FIELD, actual); + }); + } + + private static final String SNIPSET_SUPER_FIELD = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent SuperBoot {", + " protected var p : Address = null", + "}", + "agent Boot extends SuperBoot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == p.UUID ]", + " }", + "}"); + + private static final String EXPECTED_SUPER_FIELD = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.tests.bug885.SuperBoot;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends SuperBoot {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = Boot.this.p.getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.p.getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingSuperField() throws Exception { + /*SarlScript mas = file(SNIPSET04); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_SUPER_FIELD, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_SUPER_FIELD, actual); + }); + } + + private static final String SNIPSET_LOCAL_FUNCTION_01 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF.UUID ]", + " }", + " def callF : Address { null }", + "}"); + + private static final String EXPECTED_LOCAL_FUNCTION_01 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = Boot.this.callF().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected Address callF() {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalFunction_01() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_FUNCTION_01, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_FUNCTION_01, actual); + }); + } + + private static final String SNIPSET_LOCAL_FUNCTION_02 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF ]", + " }", + " def callF : UUID { null }", + "}"); + + private static final String EXPECTED_LOCAL_FUNCTION_02 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF();", + " return Objects.equal(_uUID, _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected UUID callF() {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalFunction_02() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_FUNCTION_02, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_FUNCTION_02, actual); + }); + } + + private static final String SNIPSET_SUPER_FUNCTION_01 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent SuperBoot {", + " def callF : Address { null }", + "}", + "agent Boot extends SuperBoot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF.UUID ]", + " }", + "}"); + + private static final String EXPECTED_SUPER_FUNCTION_01 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.tests.bug885.SuperBoot;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends SuperBoot {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = Boot.this.callF().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingSuperFunction_01() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_SUPER_FUNCTION_01, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_SUPER_FUNCTION_01, actual); + }); + } + + private static final String SNIPSET_SUPER_FUNCTION_02 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent SuperBoot {", + " def callF : UUID { null }", + "}", + "agent Boot extends SuperBoot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF ]", + " }", + "}"); + + private static final String EXPECTED_SUPER_FUNCTION_02 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.tests.bug885.SuperBoot;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends SuperBoot {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF();", + " return Objects.equal(_uUID, _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingSuperFunction_02() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_SUPER_FUNCTION_02, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_SUPER_FUNCTION_02, actual); + }); + } + + private static final String SNIPSET_EXTENSION_FIELD = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "class Provider {", + " def callF : Address { null }", + "}", + "agent Boot {", + " extension var p : Provider", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF.UUID ]", + " }", + "}"); + + private static final String EXPECTED_EXTENSION_FIELD = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.tests.bug885.Provider;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Extension;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Extension", + " private Provider p;", + " ", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = Boot.this.p.callF().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.p.callF().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Override", + " @Pure", + " @SyntheticMember", + " public boolean equals(final Object obj) {", + " return super.equals(obj);", + " }", + " ", + " @Override", + " @Pure", + " @SyntheticMember", + " public int hashCode() {", + " int result = super.hashCode();", + " return result;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingExtensionField() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_EXTENSION_FIELD, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_EXTENSION_FIELD, actual); + }); + } + + private static final String SNIPSET_EXTENSION_VARIABLE = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "class Provider {", + " def callF : Address { null }", + "}", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " extension var p : Provider", + " f [ it.UUID == callF.UUID ]", + " }", + "}"); + + private static final String EXPECTED_EXTENSION_VARIABLE = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.tests.bug885.Provider;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Extension;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " @Extension", + " Provider p = null;", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = p.callF().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, p.callF().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingExtensionVariable() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_EXTENSION_VARIABLE, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_EXTENSION_VARIABLE, actual); + }); + } + + private static final String SNIPSET_EXTENSION_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "class Provider {", + " def callF : Address { null }", + "}", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    , extension p : Provider) {", + " f [ it.UUID == callF.UUID ]", + " }", + "}"); + + private static final String EXPECTED_EXTENSION_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.tests.bug885.Provider;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Extension;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s, @Extension final Provider p) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = p.callF().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, p.callF().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingExtensionParameter() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_EXTENSION_PARAMETER, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_EXTENSION_PARAMETER, actual); + }); + } + + private static final String SNIPSET_STATIC_IMPORT = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "import static foo.StaticTools.*", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == getAdr.UUID ]", + " }", + "}"); + + private static final String EXPECTED_STATIC_IMPORT = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import foo.StaticTools;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = StaticTools.getAdr().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, StaticTools.getAdr().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingStaticImport() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_STATIC_IMPORT, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_STATIC_IMPORT, actual); + }); + } + + private static final String SNIPSET_STATIC_EXTENSION_IMPORT = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "import static extension foo.StaticTools.*", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == new Object().getAdr2.UUID ]", + " }", + "}"); + + private static final String EXPECTED_STATIC_EXTENSION_IMPORT = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import foo.StaticTools;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = StaticTools.getAdr2(new Object()).getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, StaticTools.getAdr2(new Object()).getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingStaticExtensionImport() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_STATIC_EXTENSION_IMPORT, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_STATIC_EXTENSION_IMPORT, actual); + }); + } + + private static final String SNIPSET_LOCAL_INSTANCE_CREATION_01 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF(new Object()) ]", + " }", + " def callF(p : Object) : UUID { null }", + "}"); + + private static final String EXPECTED_LOCAL_INSTANCE_CREATION_01 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " Object _object = new Object();", + " UUID _callF = Boot.this.callF(_object);", + " return Objects.equal(_uUID, _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF(new Object()));", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected UUID callF(final Object p) {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalInstanceCreation01() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_INSTANCE_CREATION_01, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_INSTANCE_CREATION_01, actual); + }); + } + + private static final String SNIPSET_LOCAL_INSTANCE_CREATION_02 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == new Object ]", + " }", + "}"); + + private static final String EXPECTED_LOCAL_INSTANCE_CREATION_02 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " public $SerializableClosureProxy() {", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " Object _object = new Object();", + " return Objects.equal(_uUID, _object);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " Object _object = new Object();", + " return Objects.equal(_uUID, _object);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class);", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalInstanceCreation02() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_INSTANCE_CREATION_02, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_INSTANCE_CREATION_02, actual); + }); + } + + private static final String SNIPSET_ARITHMETIC_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF(1+2*3) ]", + " }", + " def callF(p : Object) : UUID { null }", + "}"); + + private static final String EXPECTED_ARITHMETIC_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF(Integer.valueOf((1 + (2 * 3))));", + " return Objects.equal(_uUID, _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF(Integer.valueOf((1 + (2 * 3)))));", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected UUID callF(final Object p) {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingArithmetiParameter() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_ARITHMETIC_PARAMETER, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_ARITHMETIC_PARAMETER, actual); + }); + } + + private static final String SNIPSET_IF_THEN_ON_IT = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ if (it !== null) { it.UUID == callF(1+2*3) } else { false } ]", + " }", + " def callF(p : Object) : UUID { null }", + "}"); + + private static final String EXPECTED_IF_THEN_ON_IT = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xifexpression = false;", + " if ((it != null)) {", + " UUID _uUID = it.getUUID();", + " _xifexpression = Objects.equal(_uUID, $_callF);", + " } else {", + " _xifexpression = false;", + " }", + " return _xifexpression;", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xifexpression = false;", + " if ((it != null)) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF(Integer.valueOf((1 + (2 * 3))));", + " _xifexpression = Objects.equal(_uUID, _callF);", + " } else {", + " _xifexpression = false;", + " }", + " return _xifexpression;", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF(Integer.valueOf((1 + (2 * 3)))));", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected UUID callF(final Object p) {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingIfThenOnIt() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_IF_THEN_ON_IT, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_IF_THEN_ON_IT, actual); + }); + } + + private static final String SNIPSET_IF_THEN_ON_LOCAL_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ if (s !== null) { it.UUID == callF(1+2*3) } else { false } ]", + " }", + " def callF(p : Object) : UUID { null }", + "}"); + + private static final String EXPECTED_IF_THEN_ON_LOCAL_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final Scope
    s;", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final Scope
    s, final UUID $_callF) {", + " this.s = s;", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xifexpression = false;", + " if ((s != null)) {", + " UUID _uUID = it.getUUID();", + " _xifexpression = Objects.equal(_uUID, $_callF);", + " } else {", + " _xifexpression = false;", + " }", + " return _xifexpression;", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xifexpression = false;", + " if ((s != null)) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF(Integer.valueOf((1 + (2 * 3))));", + " _xifexpression = Objects.equal(_uUID, _callF);", + " } else {", + " _xifexpression = false;", + " }", + " return _xifexpression;", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, s, this.callF(Integer.valueOf((1 + (2 * 3)))));", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected UUID callF(final Object p) {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingIfThenOnLocalParameter() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_IF_THEN_ON_LOCAL_PARAMETER, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_IF_THEN_ON_LOCAL_PARAMETER, actual); + }); + } + + private static final String SNIPSET_IS_ME = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.core.DefaultContextInteractions", + "event MyEvent", + "agent MyAgent {", + " uses DefaultContextInteractions", + " on MyEvent [!it.source.isMe] {", + " new MyEvent().emit [it == occurrence.source]", + " }", + "}"); + + private static final String EXPECTED_IS_ME = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.core.DefaultContextInteractions;", + "import io.sarl.lang.annotation.ImportedCapacityFeature;", + "import io.sarl.lang.annotation.PerceptGuardEvaluator;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.core.Skill;", + "import io.sarl.lang.tests.bug885.MyEvent;", + "import io.sarl.lang.util.ClearableReference;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.Collection;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Extension;", + "import org.eclipse.xtext.xbase.lib.Inline;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class MyAgent extends Agent {", + " private void $behaviorUnit$MyEvent$0(final MyEvent occurrence) {", + " DefaultContextInteractions _$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS$CALLER = this.$castSkill(DefaultContextInteractions.class, (this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS == null || this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS.get() == null) ? (this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS = this.$getSkill(DefaultContextInteractions.class)) : this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS);", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final Address $_source;", + " ", + " public $SerializableClosureProxy(final Address $_source) {", + " this.$_source = $_source;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " return Objects.equal(it, $_source);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " Address _source = occurrence.getSource();", + " return Objects.equal(it, _source);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, occurrence.getSource());", + " }", + " };", + " _$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS$CALLER.emit(new MyEvent(), _function);", + " }", + " ", + " @SyntheticMember", + " @Pure", + " private boolean $behaviorUnitGuard$MyEvent$0(final MyEvent it, final MyEvent occurrence) {", + " boolean _isMe = (it.getSource() != null && this.getID().equals(it.getSource().getUUID()));", + " return (!_isMe);", + " }", + " ", + " @Extension", + " @ImportedCapacityFeature(DefaultContextInteractions.class)", + " @SyntheticMember", + " private transient ClearableReference $CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS;", + " ", + " @SyntheticMember", + " @Pure", + " @Inline(value = \"$castSkill(DefaultContextInteractions.class, ($0$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS == null || $0$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS.get() == null) ? ($0$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS = $0$getSkill(DefaultContextInteractions.class)) : $0$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS)\", imported = DefaultContextInteractions.class)", + " private DefaultContextInteractions $CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS$CALLER() {", + " if (this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS == null || this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS.get() == null) {", + " this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS = $getSkill(DefaultContextInteractions.class);", + " }", + " return $castSkill(DefaultContextInteractions.class, this.$CAPACITY_USE$IO_SARL_CORE_DEFAULTCONTEXTINTERACTIONS);", + " }", + " ", + " @SyntheticMember", + " @PerceptGuardEvaluator", + " private void $guardEvaluator$MyEvent(final MyEvent occurrence, final Collection ___SARLlocal_runnableCollection) {", + " assert occurrence != null;", + " assert ___SARLlocal_runnableCollection != null;", + " if ($behaviorUnitGuard$MyEvent$0(occurrence, occurrence)) {", + " ___SARLlocal_runnableCollection.add(() -> $behaviorUnit$MyEvent$0(occurrence));", + " }", + " }", + " ", + " @SyntheticMember", + " public MyAgent(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public MyAgent(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public MyAgent(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingIsMe() throws Exception { + this.compiler.compile(SNIPSET_IS_ME, (it) -> { + final String actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.MyAgent"); + assertEquals(EXPECTED_IS_ME, actual); + }); + } + + private static final String SNIPSET_MULTIPLE_LAMBDA = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF(1+2*3) ]", + " f [ it.UUID != callF(1+2*3) ]", + " }", + " def callF(p : Object) : UUID { null }", + "}"); + + private static final String EXPECTED_MULTIPLE_LAMBDA = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF(Integer.valueOf((1 + (2 * 3))));", + " return Objects.equal(_uUID, _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF(Integer.valueOf((1 + (2 * 3)))));", + " }", + " };", + " this.f(_function);", + " class $SerializableClosureProxy_1 implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy_1(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return (!Objects.equal(_uUID, $_callF));", + " }", + " }", + " final Scope
    _function_1 = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.this.callF(Integer.valueOf((1 + (2 * 3))));", + " return (!Objects.equal(_uUID, _callF));", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy_1.class, this.callF(Integer.valueOf((1 + (2 * 3)))));", + " }", + " };", + " this.f(_function_1);", + " }", + " ", + " @Pure", + " protected UUID callF(final Object p) {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingMultipleLambda() throws Exception { + this.compiler.compile(SNIPSET_MULTIPLE_LAMBDA, (it) -> { + final String actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_MULTIPLE_LAMBDA, actual); + }); + } + + private static final String SNIPSET_LOCAL_STATIC_FUNCTION_01 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF.UUID ]", + " }", + " static def callF : Address { null }", + "}"); + + private static final String EXPECTED_LOCAL_STATIC_FUNCTION_01 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_uUID;", + " ", + " public $SerializableClosureProxy(final UUID $_uUID) {", + " this.$_uUID = $_uUID;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_uUID);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = Boot.callF().getUUID();", + " return Objects.equal(_uUID, _uUID_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, Boot.callF().getUUID());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected static Address callF() {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalStaticFunction_01() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_STATIC_FUNCTION_01, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_STATIC_FUNCTION_01, actual); + }); + } + + private static final String SNIPSET_LOCAL_STATIC_FUNCTION_02 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == callF ]", + " }", + " static def callF : UUID { null }", + "}"); + + private static final String EXPECTED_LOCAL_STATIC_FUNCTION_02 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_callF;", + " ", + " public $SerializableClosureProxy(final UUID $_callF) {", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " UUID _callF = Boot.callF();", + " return Objects.equal(_uUID, _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, Boot.callF());", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected static UUID callF() {", + " return null;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalStaticFunction_02() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_STATIC_FUNCTION_02, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_STATIC_FUNCTION_02, actual); + }); + } + private static final String SNIPSET_NO_EXTERNAL_REFERENCE = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ it.UUID == null ]", + " }", + "}"); + + private static final String EXPECTED_NO_EXTERNAL_REFERENCE = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " public $SerializableClosureProxy() {", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, null);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " UUID _uUID = it.getUUID();", + " return Objects.equal(_uUID, null);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class);", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingNotExternalReference() throws Exception { + /*SarlScript mas = file(SNIPSET01); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_NO_EXTERNAL_REFERENCE, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_NO_EXTERNAL_REFERENCE, actual); + }); + } + + private static final String SNIPSET_CLOSURE_VARIABLE = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ var p : Address = null", + " it.UUID == p.UUID ]", + " }", + "}"); + + private static final String EXPECTED_CLOSURE_VARIABLE = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import com.google.common.base.Objects;", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " public $SerializableClosureProxy() {", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xblockexpression = false;", + " {", + " Address p = null;", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = p.getUUID();", + " _xblockexpression = Objects.equal(_uUID, _uUID_1);", + " }", + " return _xblockexpression;", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xblockexpression = false;", + " {", + " Address p = null;", + " UUID _uUID = it.getUUID();", + " UUID _uUID_1 = p.getUUID();", + " _xblockexpression = Objects.equal(_uUID, _uUID_1);", + " }", + " return _xblockexpression;", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class);", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingClosureVariable() throws Exception { + /*SarlScript mas = file(SNIPSET02); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_CLOSURE_VARIABLE, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_CLOSURE_VARIABLE, actual); + }); + } + + private static final String SNIPSET_LOCAL_VARIABLE_AS_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ var p : Address = null", + " s.matches(p)", + " ]", + " }", + "}"); + + private static final String EXPECTED_LOCAL_VARIABLE_AS_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final Scope
    s;", + " ", + " public $SerializableClosureProxy(final Scope
    s) {", + " this.s = s;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xblockexpression = false;", + " {", + " Address p = null;", + " _xblockexpression = s.matches(p);", + " }", + " return _xblockexpression;", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " boolean _xblockexpression = false;", + " {", + " Address p = null;", + " _xblockexpression = s.matches(p);", + " }", + " return _xblockexpression;", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, s);", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingLocalVariavleAsParameter() throws Exception { + /*SarlScript mas = file(SNIPSET02); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_LOCAL_VARIABLE_AS_PARAMETER, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_LOCAL_VARIABLE_AS_PARAMETER, actual); + }); + } + + private static final String SNIPSET_MULTIPLE_CALLS_TO_SAME_FUNCTION = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2 {", + " f [ callF(1+2) == callF(5) ]", + " }", + " def callF(a : int) : int { 0 }", + "}"); + + private static final String EXPECTED_MULTIPLE_CALLS_TO_SAME_FUNCTION = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2() {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final int $_callF;", + " ", + " private final int $_callF_2;", + " ", + " public $SerializableClosureProxy(final int $_callF, final int $_callF_2) {", + " this.$_callF = $_callF;", + " this.$_callF_2 = $_callF_2;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " return ($_callF == $_callF_2);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " int _callF = Boot.this.callF((1 + 2));", + " int _callF_1 = Boot.this.callF(5);", + " return (_callF == _callF_1);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, this.callF((1 + 2)), this.callF(5));", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected int callF(final int a) {", + " return 0;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingMultipleCallsToSameFunction() throws Exception { + /*SarlScript mas = file(SNIPSET02); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_MULTIPLE_CALLS_TO_SAME_FUNCTION, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_MULTIPLE_CALLS_TO_SAME_FUNCTION, actual); + }); + } + + private static final String SNIPSET_MULTIPLE_CALLS_TO_SAME_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " def f(s : Scope
    ) {", + " }", + " def f2(p : int) {", + " f [ p == callF(p) ]", + " }", + " def callF(a : int) : int { a }", + "}"); + + private static final String EXPECTED_MULTIPLE_CALLS_TO_SAME_PARAMETER = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final int p) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final int p;", + " ", + " private final int $_callF;", + " ", + " public $SerializableClosureProxy(final int p, final int $_callF) {", + " this.p = p;", + " this.$_callF = $_callF;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " return (p == $_callF);", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " int _callF = Boot.this.callF(p);", + " return (p == _callF);", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, p, this.callF(p));", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Pure", + " protected int callF(final int a) {", + " return a;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingMultipleCallsToSameParameter() throws Exception { + /*SarlScript mas = file(SNIPSET02); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_MULTIPLE_CALLS_TO_SAME_PARAMETER, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_MULTIPLE_CALLS_TO_SAME_PARAMETER, actual); + }); + } + + private static final String SNIPSET_COMPLEX_LAMBDA_01 = multilineString( + "package io.sarl.lang.tests.bug885", + "import io.sarl.lang.core.Scope", + "import io.sarl.lang.core.Address", + "import java.util.UUID", + "", + "agent Boot {", + " var field : int", + " def f(s : Scope
    ) {", + " }", + " def f2(s : Scope
    ) {", + " f [ var p : Address = null", + " var r = UUID::randomUUID !== null", + " for (var i = 0; i < field; i++) {", + " if (p !== null && s !== null) {", + " r = r && !s.matches(p)", + " }", + " }", + " return r", + " ]", + " }", + "}"); + + private static final String EXPECTED_COMPLEX_LAMBDA_01 = multilineString( + "package io.sarl.lang.tests.bug885;", + "", + "import io.sarl.lang.annotation.SarlElementType;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.annotation.SyntheticMember;", + "import io.sarl.lang.core.Address;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import io.sarl.lang.core.DynamicSkillProvider;", + "import io.sarl.lang.core.Scope;", + "import io.sarl.lang.util.SerializableProxy;", + "import java.io.ObjectStreamException;", + "import java.util.UUID;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"" + SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING + "\")", + "@SarlElementType(" + SarlPackage.SARL_AGENT + ")", + "@SuppressWarnings(\"all\")", + "public class Boot extends Agent {", + " private int field;", + " ", + " @Pure", + " protected void f(final Scope
    s) {", + " }", + " ", + " @Pure", + " protected void f2(final Scope
    s) {", + " class $SerializableClosureProxy implements Scope
    {", + " ", + " private final UUID $_randomUUID;", + " ", + " private final int $_field;", + " ", + " private final Scope
    s;", + " ", + " public $SerializableClosureProxy(final UUID $_randomUUID, final int $_field, final Scope
    s) {", + " this.$_randomUUID = $_randomUUID;", + " this.$_field = $_field;", + " this.s = s;", + " }", + " ", + " @Override", + " public boolean matches(final Address it) {", + " Address p = null;", + " boolean r = ($_randomUUID != null);", + " for (int i = 0; (i < $_field); i++) {", + " if (((p != null) && (s != null))) {", + " r = (r && (!s.matches(p)));", + " }", + " }", + " return r;", + " }", + " }", + " final Scope
    _function = new Scope
    () {", + " @Override", + " public boolean matches(final Address it) {", + " Address p = null;", + " UUID _randomUUID = UUID.randomUUID();", + " boolean r = (_randomUUID != null);", + " for (int i = 0; (i < Boot.this.field); i++) {", + " if (((p != null) && (s != null))) {", + " r = (r && (!s.matches(p)));", + " }", + " }", + " return r;", + " }", + " private Object writeReplace() throws ObjectStreamException {", + " return new SerializableProxy($SerializableClosureProxy.class, UUID.randomUUID(), this.field, s);", + " }", + " };", + " this.f(_function);", + " }", + " ", + " @Override", + " @Pure", + " @SyntheticMember", + " public boolean equals(final Object obj) {", + " if (this == obj)", + " return true;", + " if (obj == null)", + " return false;", + " if (getClass() != obj.getClass())", + " return false;", + " Boot other = (Boot) obj;", + " if (other.field != this.field)", + " return false;", + " return super.equals(obj);", + " }", + " ", + " @Override", + " @Pure", + " @SyntheticMember", + " public int hashCode() {", + " int result = super.hashCode();", + " final int prime = 31;", + " result = prime * result + this.field;", + " return result;", + " }", + " ", + " @SyntheticMember", + " public Boot(final UUID arg0, final UUID arg1) {", + " super(arg0, arg1);", + " }", + " ", + " @SyntheticMember", + " @Deprecated", + " @Inject", + " public Boot(final BuiltinCapacitiesProvider arg0, final UUID arg1, final UUID arg2) {", + " super(arg0, arg1, arg2);", + " }", + " ", + " @SyntheticMember", + " @Inject", + " public Boot(final UUID arg0, final UUID arg1, final DynamicSkillProvider arg2) {", + " super(arg0, arg1, arg2);", + " }", + "}", + ""); + + @Test + public void compilingComplexLambda01() throws Exception { + /*SarlScript mas = file(SNIPSET02); + final Validator validator = validate(mas); + validator.assertNoErrors();*/ + this.compiler.compile(SNIPSET_COMPLEX_LAMBDA_01, (it) -> { + String actual; + actual = it.getGeneratedCode("io.sarl.lang.tests.bug885.Boot"); + assertEquals(EXPECTED_COMPLEX_LAMBDA_01, actual); + }); + } + + +} diff --git a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/general/compilation/aop/AgentCompilerTest.java b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/general/compilation/aop/AgentCompilerTest.java index 4bd468a416..a5fd536e70 100644 --- a/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/general/compilation/aop/AgentCompilerTest.java +++ b/tests/io.sarl.lang.tests/src/test/java/io/sarl/lang/tests/general/compilation/aop/AgentCompilerTest.java @@ -2483,8 +2483,7 @@ public void duplicateEventHandler() throws Exception { " @Pure", " private boolean $behaviorUnitGuard$Initialize$1(final Initialize it, final Initialize occurrence) {", " boolean _isEmpty = occurrence.parameters.isEmpty();", - " boolean _not = (!_isEmpty);", - " return _not;", + " return (!_isEmpty);", " }", " ", " @SyntheticMember", diff --git a/tests/io.sarl.tests.testdata/src/foo/StaticTools.java b/tests/io.sarl.tests.testdata/src/foo/StaticTools.java new file mode 100644 index 0000000000..2735882a7d --- /dev/null +++ b/tests/io.sarl.tests.testdata/src/foo/StaticTools.java @@ -0,0 +1,16 @@ +package foo; + +import io.sarl.lang.core.Address; + +@SuppressWarnings("all") +public class StaticTools { + + public static Address getAdr() { + return null; + } + + public static Address getAdr2(Object value) { + return null; + } + +}