Skip to content

Commit

Permalink
[lang] No "unused function" warning when a function is inoked with it…
Browse files Browse the repository at this point in the history
…s parameters' default values.

close #895

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Dec 18, 2018
1 parent 53f9864 commit 342b3f6
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,7 @@ protected void transform(final XtendFunction source, final JvmGenericType contai
operation2.setNative(false);
operation2.setStrictFloatingPoint(false);
operation2.setSynchronized(false);
this.associator.associate(source, operation2);

copyTypeParametersFromJvmOperation(operation, operation2);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ private Messages() {
public static String SARLValidator_91;
public static String SARLValidator_92;
public static String SARLValidator_93;
public static String SARLValidator_94;
public static String SARLSyntaxErrorMessageProvider_0;
public static String SARLSyntaxErrorMessageProvider_1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import static org.eclipse.xtend.core.validation.IssueCodes.OBSOLETE_OVERRIDE;
import static org.eclipse.xtend.core.validation.IssueCodes.OVERRIDDEN_FINAL;
import static org.eclipse.xtend.core.validation.IssueCodes.OVERRIDE_REDUCES_VISIBILITY;
import static org.eclipse.xtend.core.validation.IssueCodes.UNUSED_PRIVATE_MEMBER;
import static org.eclipse.xtend.core.validation.IssueCodes.XBASE_LIB_NOT_ON_CLASSPATH;
import static org.eclipse.xtend.core.xtend.XtendPackage.Literals.XTEND_CLASS__IMPLEMENTS;
import static org.eclipse.xtend.core.xtend.XtendPackage.Literals.XTEND_FIELD__NAME;
Expand Down Expand Up @@ -123,6 +124,7 @@
import org.eclipse.xtend.core.xtend.XtendInterface;
import org.eclipse.xtend.core.xtend.XtendMember;
import org.eclipse.xtend.core.xtend.XtendPackage;
import org.eclipse.xtend.core.xtend.XtendParameter;
import org.eclipse.xtend.core.xtend.XtendTypeDeclaration;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtend.lib.annotations.Data;
Expand Down Expand Up @@ -184,6 +186,7 @@
import org.eclipse.xtext.xbase.typesystem.references.StandardTypeReferenceOwner;
import org.eclipse.xtext.xbase.util.XbaseUsageCrossReferencer;
import org.eclipse.xtext.xbase.validation.FeatureNameValidator;
import org.eclipse.xtext.xbase.validation.UIStrings;

import io.sarl.lang.SARLVersion;
import io.sarl.lang.annotation.EarlyExit;
Expand Down Expand Up @@ -404,6 +407,9 @@ public class SARLValidator extends AbstractSARLValidator {
@Inject
private IImmutableTypeValidator immutableTypeValidator;

@Inject
private UIStrings uiStrings;

// Update the annotation target information
{
final ImmutableMultimap.Builder<Class<?>, ElementType> result = ImmutableMultimap.builder();
Expand Down Expand Up @@ -969,8 +975,7 @@ public void checkFinalFieldInitialization(SarlAgent agent) {
* @param feature the syntactic feature related to the supertypes.
* @param defaultSignatures the signatures of the default constructors for the given container.
*/
@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity",
"checkstyle:nestedifdepth"})
@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity", "checkstyle:nestedifdepth"})
protected void checkSuperConstructor(
XtendTypeDeclaration container,
EStructuralFeature feature,
Expand Down Expand Up @@ -2890,6 +2895,56 @@ public void checkTopElementsAreUnique(SarlScript script) {
}
}

/** Replies if the given function has a default value for one of its parameters.
*
* @param function the function to test.
* @return {@code true} if one parameter has a default value.
*/
@SuppressWarnings("static-method")
protected boolean isDefaultValuedParameterFunction(XtendFunction function) {
for (final XtendParameter parameter : function.getParameters()) {
if (parameter instanceof SarlFormalParameter) {
final SarlFormalParameter sarlParameter = (SarlFormalParameter) parameter;
if (sarlParameter.getDefaultValue() != null) {
return true;
}
}
}
return false;
}

@Check
@Override
public void checkLocalUsageOfDeclaredXtendFunction(XtendFunction function) {
if (doCheckValidMemberName(function) && !isIgnored(UNUSED_PRIVATE_MEMBER)) {
final JvmOperation mainOperation;
if (function.isDispatch()) {
mainOperation = this.associations.getDispatchOperation(function);
} else {
mainOperation = this.associations.getDirectlyInferredOperation(function);
}
if (mainOperation != null && mainOperation.getVisibility() == JvmVisibility.PRIVATE) {
final EObject outerType = getOutermostType(function);
boolean isUsed = isLocallyUsed(mainOperation, outerType);
if (!isUsed && isDefaultValuedParameterFunction(function)) {
for (final EObject jvmElement : this.associations.getJvmElements(function)) {
if (jvmElement != mainOperation && jvmElement instanceof JvmOperation
&& isLocallyUsed(jvmElement, outerType)) {
isUsed = true;
// break the loop
break;
}
}
}
if (!isUsed) {
final String message = MessageFormat.format(Messages.SARLValidator_94,
mainOperation.getSimpleName(), this.uiStrings.parameters(mainOperation), getDeclaratorName(mainOperation));
addIssueToState(UNUSED_PRIVATE_MEMBER, message, XtendPackage.Literals.XTEND_FUNCTION__NAME);
}
}
}
}

/** The modifier validator for constructors.
*
* @author $Author: sgalland$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ SARLValidator_90=Forbidden annotation to the agent-oriented feature of type {0}.
SARLValidator_91=The field {0} should be synchronized for avoiding value inconsistency due to parallel execution.
SARLValidator_92=Discouraged use of the feature ''{0}'. You should not use the feature ''{0}'', or one of its member as argument of an action because it may be change by a border effect.
SARLValidator_93=Duplicate type {0}.
SARLValidator_94=The method {0}{1} from the type {2} is never used locally.
SARLSyntaxErrorMessageProvider_0=''{0}'' is a reserved keyword which is not allowed as identifier. Please choose another word or alternatively confuse your co-workers by escaping it like this: "{1}".
SARLSyntaxErrorMessageProvider_1=''{0}'' is a reserved keyword which is not allowed as identifier. Please choose another word.
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* 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.xtend.core.validation.IssueCodes;
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: Invalid "function not used" warning for functions with default valued parameter.
*
* <p>https://github.com/sarl/sarl/issues/895
*
* @author $Author: sgalland$
* @author $Author: alombard$
* @version $Name$ $Revision$ $Date$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @see "https://github.com/sarl/sarl/issues/895"
*/
@SuppressWarnings("all")
public class Bug895 extends AbstractSarlTest {

private static final String CALL_WITH_DEFAULT_VALUE = multilineString(
"package io.sarl.lang.tests.bug895",
"class X {",
" private def f1(param : int = 0) : void {",
" }",
" def f {",
" f1",
" }",
"}");


@Test
public void callWithDefaultValue() throws Exception {
SarlScript mas = file(CALL_WITH_DEFAULT_VALUE);
final Validator validator = validate(mas);
validator.assertNoWarnings(
SarlPackage.eINSTANCE.getSarlAction(),
IssueCodes.UNUSED_PRIVATE_MEMBER);
}

private static final String CALL_WITH_EXPLICIT_VALUE = multilineString(
"package io.sarl.lang.tests.bug895",
"class X {",
" private def f1(param : int = 0) : void {",
" }",
" def f {",
" f1(4)",
" }",
"}");


@Test
public void callWithExplicitValue() throws Exception {
SarlScript mas = file(CALL_WITH_EXPLICIT_VALUE);
final Validator validator = validate(mas);
validator.assertNoWarnings(
SarlPackage.eINSTANCE.getSarlAction(),
IssueCodes.UNUSED_PRIVATE_MEMBER);
}

private static final String CALL_WITH_CLASSIC_ARGUMENT = multilineString(
"package io.sarl.lang.tests.bug895",
"class X {",
" private def f1(param : int) : void {",
" }",
" def f {",
" f1(4)",
" }",
"}");


@Test
public void callWithClassicArgument() throws Exception {
SarlScript mas = file(CALL_WITH_CLASSIC_ARGUMENT);
final Validator validator = validate(mas);
validator.assertNoWarnings(
SarlPackage.eINSTANCE.getSarlAction(),
IssueCodes.UNUSED_PRIVATE_MEMBER);
}

private static final String NO_CALL_WITH_CLASSIC_ARGUMENT = multilineString(
"package io.sarl.lang.tests.bug895",
"class X {",
" private def f1(param : int) : void {",
" }",
" private def f2 : void {",
" }",
" def f {",
" f2",
" }",
"}");


@Test
public void noCallWithClassicArgument() throws Exception {
SarlScript mas = file(NO_CALL_WITH_CLASSIC_ARGUMENT);
final Validator validator = validate(mas);
validator.assertWarning(
SarlPackage.eINSTANCE.getSarlAction(),
IssueCodes.UNUSED_PRIVATE_MEMBER,
"f1(int)");
}

}

0 comments on commit 342b3f6

Please sign in to comment.