From e9c3326229d500e59f4dbaf394d9b266508bd663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Galland?= Date: Fri, 24 Jun 2016 23:38:54 +0200 Subject: [PATCH] [lang] Restrict Pure function detection. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #414 Signed-off-by: Stéphane Galland --- .../lang/jvmmodel/SARLJvmModelInferrer.java | 162 +++++++++++------- .../lang/typing/SARLExpressionHelper.java | 26 ++- .../compilation/aop/AgentCompilerTest.java | 122 +++++++++++++ 3 files changed, 250 insertions(+), 60 deletions(-) diff --git a/plugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java b/plugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java index 1588a23100..3f5cf48c16 100644 --- a/plugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java +++ b/plugins/io.sarl.lang/src/io/sarl/lang/jvmmodel/SARLJvmModelInferrer.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -39,6 +40,7 @@ import javax.annotation.Generated; import com.google.common.base.Objects; +import com.google.common.base.Predicate; import com.google.common.base.Strings; import com.google.common.collect.Iterables; import com.google.inject.Inject; @@ -243,6 +245,20 @@ public class SARLJvmModelInferrer extends XtendJvmModelInferrer { */ private Map ctx = new TreeMap<>(); + /** See the filter in the super class. + */ + private static final Predicate ANNOTATION_TRANSLATION_FILTER = (annotation) -> { + if (annotation == null || annotation.getAnnotation() == null) { + return false; + } + //JvmType annotationType = annotation.getAnnotation(); + //if (annotationType instanceof JvmAnnotationType + // && DisableCodeGenerationAdapter.isDisabled((JvmDeclaredType) annotationType)) { + // return false; + //} + return true; + }; + private static String contextKey(JvmIdentifiableElement type) { return type.eResource().getURI() + "/" + type.getQualifiedName(); //$NON-NLS-1$ } @@ -1020,7 +1036,7 @@ protected void transform(XtendField source, JvmGenericType container) { */ @Override @SuppressWarnings({"checkstyle:methodlength", "checkstyle:cyclomaticcomplexity", - "checkstyle:npathcomplexity"}) + "checkstyle:npathcomplexity"}) protected void transform(final XtendFunction source, final JvmGenericType container, boolean allowDispatch) { final GenerationContext context = getContext(container); @@ -1104,12 +1120,12 @@ protected void transform(final XtendFunction source, final JvmGenericType contai if (returnType == null && expression != null && ((!(expression instanceof XBlockExpression)) - || (!((XBlockExpression) expression).getExpressions().isEmpty()))) { + || (!((XBlockExpression) expression).getExpressions().isEmpty()))) { returnType = this.typeBuilder.inferredType(expression); } } else if (expression != null && ((!(expression instanceof XBlockExpression)) - || (!((XBlockExpression) expression).getExpressions().isEmpty()))) { + || (!((XBlockExpression) expression).getExpressions().isEmpty()))) { returnType = this.typeBuilder.inferredType(expression); } final JvmTypeReference selectedReturnType; @@ -1197,8 +1213,8 @@ protected void transform(final XtendFunction source, final JvmGenericType contai cp.getAnnotations().add(this._annotationTypesBuilder.annotationRef( DefaultValue.class, this.sarlSignatureProvider.qualifyDefaultValueID( - implementedOperation.getDeclaringType().getIdentifier(), - ovalue))); + implementedOperation.getDeclaringType().getIdentifier(), + ovalue))); } } } @@ -1220,7 +1236,7 @@ public void run() { if (ak != null && (context == null || (!context.getInheritedFinalOperations().containsKey(ak) - && !context.getInheritedOverridableOperations().containsKey(ak)))) { + && !context.getInheritedOverridableOperations().containsKey(ak)))) { // Generate the additional constructor that is invoke the main constructor previously generated. final JvmOperation operation2 = SARLJvmModelInferrer.this.typesFactory.createJvmOperation(); @@ -1245,7 +1261,7 @@ public void run() { if (source.isOverride() && !Utils.hasAnnotation(operation, Override.class) && SARLJvmModelInferrer.this.typeReferences.findDeclaredType( - Override.class, source) != null) { + Override.class, source) != null) { operation.getAnnotations().add( SARLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class)); } @@ -1517,18 +1533,21 @@ protected void transform(SarlCapacityUses source, JvmGenericType container) { operation.setFinal(false); operation.setVisibility(JvmVisibility.PRIVATE); operation.setStatic(false); - operation.setSimpleName(entry.getValue().getSimpleName()); + final JvmOperation implementedOperation = entry.getValue(); + operation.setSimpleName(implementedOperation.getSimpleName()); + final boolean isVarArgs = implementedOperation.isVarArgs(); + operation.setVarArgs(isVarArgs); container.getMembers().add(operation); this.associator.associatePrimary(source, operation); this.typeExtensions.setSynthetic(operation, true); // Type parameters - copyAndFixTypeParameters(entry.getValue().getTypeParameters(), operation); + copyAndFixTypeParameters(implementedOperation.getTypeParameters(), operation); // Return type operation.setReturnType(cloneWithTypeParametersAndProxies( - entry.getValue(), - entry.getValue().getReturnType(), + implementedOperation, + implementedOperation.getReturnType(), operation)); // Parameters @@ -1536,11 +1555,11 @@ protected void transform(SarlCapacityUses source, JvmGenericType container) { final List inlineArgs = CollectionLiterals.newArrayList(); List argTypes = CollectionLiterals.newArrayList(); int i = 1; - for (JvmFormalParameter param : entry.getValue().getParameters()) { + for (JvmFormalParameter param : implementedOperation.getParameters()) { JvmFormalParameter jvmParam = this.typesFactory.createJvmFormalParameter(); jvmParam.setName(param.getSimpleName()); jvmParam.setParameterType(cloneWithTypeParametersAndProxies( - entry.getValue(), + implementedOperation, param.getParameterType(), operation)); this.associator.associate(source, jvmParam); @@ -1553,50 +1572,50 @@ protected void transform(SarlCapacityUses source, JvmGenericType container) { } // Documentation - String hyperrefLink = capacityType.getIdentifier() + "#" //$NON-NLS-1$ - + entry.getValue().getSimpleName() + "(" //$NON-NLS-1$ - + IterableExtensions.join(argTypes, ",") + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - this.typeBuilder.setDocumentation(operation, - MessageFormat.format( - Messages.SARLJvmModelInferrer_13, - hyperrefLink)); - final boolean isVarArgs = entry.getValue().isVarArgs(); - operation.setVarArgs(isVarArgs); - + if (!copyAndCleanDocumentationTo(implementedOperation, operation)) { + final String hyperrefLink = capacityType.getIdentifier() + "#" //$NON-NLS-1$ + + implementedOperation.getSimpleName() + "(" //$NON-NLS-1$ + + IterableExtensions.join(argTypes, ",") + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + this.typeBuilder.setDocumentation(operation, + MessageFormat.format( + Messages.SARLJvmModelInferrer_13, + hyperrefLink)); + } // Exceptions - for (JvmTypeReference exception : entry.getValue().getExceptions()) { + for (JvmTypeReference exception : implementedOperation.getExceptions()) { operation.getExceptions().add(this.typeBuilder.cloneWithProxies(exception)); } // Body this.typeBuilder.setBody(operation, (it) -> { if (!Objects.equal("void", //$NON-NLS-1$ - entry.getValue().getReturnType().getIdentifier())) { + implementedOperation.getReturnType().getIdentifier())) { it.append("return "); //$NON-NLS-1$ } it.append("getSkill("); //$NON-NLS-1$ - it.append(entry.getValue().getDeclaringType().getQualifiedName()); + it.append(implementedOperation.getDeclaringType().getQualifiedName()); it.append(".class)."); //$NON-NLS-1$ - it.append(entry.getValue().getSimpleName()); + it.append(implementedOperation.getSimpleName()); it.append("("); //$NON-NLS-1$ it.append(IterableExtensions.join(args, ", ")); //$NON-NLS-1$ it.append(");"); //$NON-NLS-1$ }); - // Annotations - translateAnnotationsTo(source.getAnnotations(), operation); + // Copy annotations from the implemented method + translateAnnotationsTo(implementedOperation.getAnnotations(), operation, + FiredEvent.class, Generated.class, ImportedCapacityFeature.class); // Add the inline annotation // The Xtext inline evaluator is considering the function arguments, not the // function formal parameters. Consequently, inline cannot be used for functions // with variadic parameters. if (!Utils.hasAnnotation(operation, Inline.class)) { - JvmDeclaredType declaringType = entry.getValue().getDeclaringType(); + JvmDeclaredType declaringType = implementedOperation.getDeclaringType(); StringBuilder it = new StringBuilder(); it.append("getSkill("); //$NON-NLS-1$ it.append(declaringType.getQualifiedName()); it.append(".class)."); //$NON-NLS-1$ - it.append(entry.getValue().getSimpleName()); + it.append(implementedOperation.getSimpleName()); it.append("("); //$NON-NLS-1$ it.append(IterableExtensions.join(inlineArgs, ", ")); //$NON-NLS-1$ it.append(")"); //$NON-NLS-1$ @@ -1604,12 +1623,12 @@ protected void transform(SarlCapacityUses source, JvmGenericType container) { } // Copy the EarlyExit Annotation from the capacity - if (Utils.hasAnnotation(entry.getValue(), EarlyExit.class)) { + if (Utils.hasAnnotation(implementedOperation, EarlyExit.class)) { operation.getAnnotations().add(this._annotationTypesBuilder.annotationRef(EarlyExit.class)); } // Copy the FiredEvent annotation from the capacity - List firedEvents = Utils.annotationClasses(entry.getValue(), FiredEvent.class); + List firedEvents = Utils.annotationClasses(implementedOperation, FiredEvent.class); if (!firedEvents.isEmpty()) { operation.getAnnotations().add(annotationClassRef(FiredEvent.class, firedEvents)); } @@ -1622,7 +1641,7 @@ protected void transform(SarlCapacityUses source, JvmGenericType container) { Collections.singletonList(capacityType))); // context.getInheritedOperationsToImplement().remove(entry.getKey()); - context.getInheritedOverridableOperations().put(entry.getKey(), entry.getValue()); + context.getInheritedOverridableOperations().put(entry.getKey(), implementedOperation); context.setActionIndex(context.getActionIndex() + 1); } } @@ -1673,7 +1692,7 @@ protected void appendSarlMembers( for (XtendMember feature : container.getMembers()) { if (context.isSupportedMember(feature) && ((feature instanceof SarlCapacityUses) - || (feature instanceof SarlRequiredCapacity))) { + || (feature instanceof SarlRequiredCapacity))) { transform(feature, featureContainerType, false); } } @@ -1748,8 +1767,8 @@ protected void appendSyntheticDefaultValuedParameterMethods( // Find the definition of the operation from the inheritance context. final JvmOperation redefinedOperation = context.getInheritedOverridableOperations().get( this.sarlSignatureProvider.createActionPrototype( - missedOperation.getKey().getActionName(), - this.sarlSignatureProvider.createParameterTypesFromString(originalSignature))); + missedOperation.getKey().getActionName(), + this.sarlSignatureProvider.createParameterTypesFromString(originalSignature))); if (redefinedOperation != null) { ActionParameterTypes parameterTypes = this.sarlSignatureProvider.createParameterTypesFromJvmModel( redefinedOperation.isVarArgs(), redefinedOperation.getParameters()); @@ -1789,8 +1808,8 @@ protected void appendSyntheticDefaultValuedParameterMethods( InferredValuedParameter inferredParameter = (InferredValuedParameter) parameter; arguments.add( this.sarlSignatureProvider.toJavaArgument( - target.getIdentifier(), - inferredParameter.getCallingArgument())); + target.getIdentifier(), + inferredParameter.getCallingArgument())); } else { arguments.add(parameter.getName()); JvmFormalParameter jvmParam = this.typesFactory.createJvmFormalParameter(); @@ -1955,7 +1974,7 @@ protected void appendEventGuardEvaluators(JvmGenericType container) { final GenerationContext context = getContext(container); if (context != null) { Collection>>> allEvaluators - = context.getGuardEvaluationCodes(); + = context.getGuardEvaluationCodes(); if (allEvaluators == null || allEvaluators.isEmpty()) { return; } @@ -2074,21 +2093,21 @@ protected void appendToStringFunctions(GenerationContext context, XtendTypeDecla source, "attributesToString", //$NON-NLS-1$ SARLJvmModelInferrer.this._typeReferenceBuilder.typeRef(String.class), (it2) -> { - it2.setVisibility(JvmVisibility.PROTECTED); - SARLJvmModelInferrer.this.typeBuilder.setDocumentation(it2, - MessageFormat.format(Messages.SARLJvmModelInferrer_2, - target.getSimpleName())); - SARLJvmModelInferrer.this.typeBuilder.setBody(it2, (it3) -> { - it3.append("StringBuilder result = new StringBuilder(" //$NON-NLS-1$ - + "super.attributesToString());").newLine(); //$NON-NLS-1$ - for (JvmField attr : declaredInstanceFields) { - it3.append("result.append(\"" + attr.getSimpleName() //$NON-NLS-1$ - + " = \").append(this." //$NON-NLS-1$ - + attr.getSimpleName() + ");").newLine(); //$NON-NLS-1$ - } - it3.append("return result.toString();"); //$NON-NLS-1$ + it2.setVisibility(JvmVisibility.PROTECTED); + SARLJvmModelInferrer.this.typeBuilder.setDocumentation(it2, + MessageFormat.format(Messages.SARLJvmModelInferrer_2, + target.getSimpleName())); + SARLJvmModelInferrer.this.typeBuilder.setBody(it2, (it3) -> { + it3.append("StringBuilder result = new StringBuilder(" //$NON-NLS-1$ + + "super.attributesToString());").newLine(); //$NON-NLS-1$ + for (JvmField attr : declaredInstanceFields) { + it3.append("result.append(\"" + attr.getSimpleName() //$NON-NLS-1$ + + " = \").append(this." //$NON-NLS-1$ + + attr.getSimpleName() + ");").newLine(); //$NON-NLS-1$ + } + it3.append("return result.toString();"); //$NON-NLS-1$ + }); }); - }); if (op != null) { appendGeneratedAnnotation(op); op.getAnnotations().add(SARLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Pure.class)); @@ -2289,8 +2308,8 @@ protected List translateSarlFormalParametersForSyntheticOperation(JvmExe if (parameterSpec instanceof InferredValuedParameter) { arguments.add( this.sarlSignatureProvider.toJavaArgument( - actionContainer.getIdentifier(), - ((InferredValuedParameter) parameterSpec).getCallingArgument())); + actionContainer.getIdentifier(), + ((InferredValuedParameter) parameterSpec).getCallingArgument())); } else { EObject param = parameterSpec.getParameter(); String paramName = parameterSpec.getName(); @@ -2308,6 +2327,31 @@ protected List translateSarlFormalParametersForSyntheticOperation(JvmExe return arguments; } + /** Copy the annotations, except the ones given as parameters. + * + * @param annotations the annotations to copy. + * @param target the target. + * @param exceptions the annotations to skip. + */ + @SuppressWarnings("static-method") + protected void translateAnnotationsTo(List annotations, JvmAnnotationTarget target, + Class... exceptions) { + final Set excepts = new HashSet<>(); + for (final Class type : exceptions) { + excepts.add(type.getName()); + } + final List addition = new ArrayList<>(); + for (final JvmAnnotationReference annotation : Iterables.filter(annotations, (an) -> { + if (!ANNOTATION_TRANSLATION_FILTER.apply(an)) { + return false; + } + return !excepts.contains(an.getAnnotation().getIdentifier()); + })) { + addition.add(annotation); + } + target.getAnnotations().addAll(addition); + } + /** Generate the "equals()" operation. * This function was deprecated in Xbase, and should be provided by DSL * providers now. @@ -2578,14 +2622,15 @@ protected void copyReference(EReference ereference, EObject eobject, EObject cop * * @param sourceOperation the source for the documentation. * @param targetOperation the target for the documentation. + * @return true if a documentation was added. */ - protected void copyAndCleanDocumentationTo(JvmOperation sourceOperation, JvmOperation targetOperation) { + protected boolean copyAndCleanDocumentationTo(JvmOperation sourceOperation, JvmOperation targetOperation) { assert (sourceOperation != null); assert (targetOperation != null); String comment = SARLJvmModelInferrer.this.typeBuilder.getDocumentation(sourceOperation); if (Strings.isNullOrEmpty(comment)) { - return; + return false; } Set targetParams = new TreeSet<>(); @@ -2603,6 +2648,7 @@ protected void copyAndCleanDocumentationTo(JvmOperation sourceOperation, JvmOper } SARLJvmModelInferrer.this.typeBuilder.setDocumentation(targetOperation, comment); + return true; } } diff --git a/plugins/io.sarl.lang/src/io/sarl/lang/typing/SARLExpressionHelper.java b/plugins/io.sarl.lang/src/io/sarl/lang/typing/SARLExpressionHelper.java index b380fb9a87..57e2a93724 100644 --- a/plugins/io.sarl.lang/src/io/sarl/lang/typing/SARLExpressionHelper.java +++ b/plugins/io.sarl.lang/src/io/sarl/lang/typing/SARLExpressionHelper.java @@ -24,10 +24,14 @@ import java.util.List; import java.util.regex.Pattern; +import javax.inject.Inject; + import com.google.inject.Singleton; import org.eclipse.xtend.core.typing.XtendExpressionHelper; +import org.eclipse.xtext.common.types.JvmFormalParameter; import org.eclipse.xtext.common.types.JvmIdentifiableElement; import org.eclipse.xtext.common.types.JvmOperation; +import org.eclipse.xtext.common.types.JvmTypeReference; import org.eclipse.xtext.xbase.XAbstractFeatureCall; import org.eclipse.xtext.xbase.XBlockExpression; import org.eclipse.xtext.xbase.XCastedExpression; @@ -35,6 +39,9 @@ import org.eclipse.xtext.xbase.XInstanceOfExpression; import org.eclipse.xtext.xbase.XSynchronizedExpression; import org.eclipse.xtext.xbase.lib.Pure; +import org.eclipse.xtext.xbase.typesystem.util.CommonTypeComputationServices; + +import io.sarl.lang.util.Utils; /** * Helper on expressions. @@ -60,6 +67,9 @@ public class SARLExpressionHelper extends XtendExpressionHelper { private final Pattern pattern; + @Inject + private CommonTypeComputationServices services; + /** Construct the helper. */ public SARLExpressionHelper() { @@ -71,8 +81,10 @@ public boolean hasSideEffects(XAbstractFeatureCall featureCall, boolean inspectC if (super.hasSideEffects(featureCall, inspectContents)) { JvmIdentifiableElement feature = featureCall.getFeature(); if ((feature != null) && (!feature.eIsProxy()) && (feature instanceof JvmOperation)) { - String name = ((JvmOperation) feature).getSimpleName(); - if (name != null && this.pattern.matcher(name).find()) { + final JvmOperation op = (JvmOperation) feature; + final String name = op.getSimpleName(); + if (name != null && this.pattern.matcher(name).find() + && hasPrimitiveParameters(op)) { return false; } } @@ -81,6 +93,16 @@ public boolean hasSideEffects(XAbstractFeatureCall featureCall, boolean inspectC return false; } + private boolean hasPrimitiveParameters(JvmOperation op) { + for (final JvmFormalParameter parameter : op.getParameters()) { + JvmTypeReference type = parameter.getParameterType(); + if (type == null || !Utils.toLightweightTypeReference(type, this.services).isPrimitive()) { + return false; + } + } + return true; + } + /** Replies if the given expression has a side effect in the context of a guard. * *

This function differs from {@link #hasSideEffects(XExpression)} because it explore the diff --git a/tests/io.sarl.lang.tests/src/io/sarl/lang/tests/compilation/aop/AgentCompilerTest.java b/tests/io.sarl.lang.tests/src/io/sarl/lang/tests/compilation/aop/AgentCompilerTest.java index f7b0496b41..6d255a2c6a 100644 --- a/tests/io.sarl.lang.tests/src/io/sarl/lang/tests/compilation/aop/AgentCompilerTest.java +++ b/tests/io.sarl.lang.tests/src/io/sarl/lang/tests/compilation/aop/AgentCompilerTest.java @@ -2177,4 +2177,126 @@ public void multipleEventsWithoutUses_sameEventMultipleTimesWithGuards02() throw this.compiler.compile(source, (r) -> assertEquals(expectedMyAgent, r.getGeneratedCode("foo.test.MyAgent"))); } + @Test + public void usePureCapacityFunction() throws Exception { + final String source = multilineString( + "package foo.test", + "capacity C1 { @Pure def myfct : int }", + "agent MyAgent {", + " uses C1", + " def testFct {", + " var v = myfct", + " }", + "}"); + final String expectedMyAgent = multilineString( + "package foo.test;", + "", + "import foo.test.C1;", + "import io.sarl.lang.annotation.ImportedCapacityFeature;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import java.util.UUID;", + "import javax.annotation.Generated;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Inline;", + "import org.eclipse.xtext.xbase.lib.Pure;", + "", + "@SarlSpecification(\"0.4\")", + "@SuppressWarnings(\"all\")", + "public class MyAgent extends Agent {", + " protected void testFct() {", + " int v = this.getSkill(foo.test.C1.class).myfct();", + " }", + " ", + " /**", + " * See the capacity {@link foo.test.C1#myfct()}.", + " * ", + " * @see foo.test.C1#myfct()", + " */", + " @Pure", + " @Inline(value = \"getSkill(foo.test.C1.class).myfct()\", imported = C1.class)", + " @Generated(\"io.sarl.lang.jvmmodel.SARLJvmModelInferrer\")", + " @ImportedCapacityFeature(C1.class)", + " private int myfct() {", + " return getSkill(foo.test.C1.class).myfct();", + " }", + " ", + " /**", + " * Construct an agent.", + " * @param builtinCapacityProvider - provider of the built-in capacities.", + " * @param parentID - identifier of the parent. It is the identifier of the parent agent and the enclosing contect, at the same time.", + " * @param agentID - identifier of the agent. If null the agent identifier will be computed randomly.", + " */", + " @Inject", + " @Generated(\"io.sarl.lang.jvmmodel.SARLJvmModelInferrer\")", + " public MyAgent(final BuiltinCapacitiesProvider builtinCapacityProvider, final UUID parentID, final UUID agentID) {", + " super(builtinCapacityProvider, parentID, agentID);", + " }", + "}", + "" + ); + this.compiler.compile(source, (r) -> assertEquals(expectedMyAgent, r.getGeneratedCode("foo.test.MyAgent"))); + } + + @Test + public void useNotPureCapacityFunction() throws Exception { + final String source = multilineString( + "package foo.test", + "capacity C1 { def myfct : int }", + "agent MyAgent {", + " uses C1", + " def testFct {", + " var v = myfct", + " }", + "}"); + final String expectedMyAgent = multilineString( + "package foo.test;", + "", + "import foo.test.C1;", + "import io.sarl.lang.annotation.ImportedCapacityFeature;", + "import io.sarl.lang.annotation.SarlSpecification;", + "import io.sarl.lang.core.Agent;", + "import io.sarl.lang.core.BuiltinCapacitiesProvider;", + "import java.util.UUID;", + "import javax.annotation.Generated;", + "import javax.inject.Inject;", + "import org.eclipse.xtext.xbase.lib.Inline;", + "", + "@SarlSpecification(\"0.4\")", + "@SuppressWarnings(\"all\")", + "public class MyAgent extends Agent {", + " protected void testFct() {", + " int v = this.getSkill(foo.test.C1.class).myfct();", + " }", + " ", + " /**", + " * See the capacity {@link foo.test.C1#myfct()}.", + " * ", + " * @see foo.test.C1#myfct()", + " */", + " @Inline(value = \"getSkill(foo.test.C1.class).myfct()\", imported = C1.class)", + " @Generated(\"io.sarl.lang.jvmmodel.SARLJvmModelInferrer\")", + " @ImportedCapacityFeature(C1.class)", + " private int myfct() {", + " return getSkill(foo.test.C1.class).myfct();", + " }", + " ", + " /**", + " * Construct an agent.", + " * @param builtinCapacityProvider - provider of the built-in capacities.", + " * @param parentID - identifier of the parent. It is the identifier of the parent agent and the enclosing contect, at the same time.", + " * @param agentID - identifier of the agent. If null the agent identifier will be computed randomly.", + " */", + " @Inject", + " @Generated(\"io.sarl.lang.jvmmodel.SARLJvmModelInferrer\")", + " public MyAgent(final BuiltinCapacitiesProvider builtinCapacityProvider, final UUID parentID, final UUID agentID) {", + " super(builtinCapacityProvider, parentID, agentID);", + " }", + "}", + "" + ); + this.compiler.compile(source, (r) -> assertEquals(expectedMyAgent, r.getGeneratedCode("foo.test.MyAgent"))); + } + }