Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@SuppressWarnings({"checkstyle:AbstractClassName"})
public abstract class DispatchingCheckImpl extends AbstractCheckImpl {

// CPD-OFF — incidental token overlap (DI field + trace/try idiom), not an extractable unit (#1339)
@Inject
private ITraceSet traceSet;

Expand Down Expand Up @@ -72,6 +73,7 @@ public boolean validate(final EClass eClass, final EObject object, final Diagnos

State state = new State();
state.chain = diagnostics;
// CPD-ON
state.eventCollector = eventCollector;

validate(checkMode, object, state);
Expand Down Expand Up @@ -123,6 +125,7 @@ protected void validate(final String contextName, final String qContextName, fin
if (!disabledMethodTracker.isDisabled(contextName)) {
Collector eventCollector = diagnosticCollector.getEventCollector();
try {
// CPD-OFF — incidental token overlap (DI field + trace/try idiom), not an extractable unit (#1339)
traceStart(qContextName, object, eventCollector);
checkAction.run();
} catch (Exception e) {
Expand Down Expand Up @@ -160,6 +163,7 @@ protected static class State implements ValidationMessageAcceptorMixin, Diagnost
// CHECKSTYLE:OFF
public DiagnosticChain chain;
public CheckType currentCheckType;
// CPD-ON
public boolean hasErrors;
public ResourceValidationRuleSummaryEvent.Collector eventCollector;
// CHECKSTYLE:ON
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,18 @@ protected boolean isExtensionEnabled(final IPluginModelBase base, final CheckCat
return !config.isGenerateLanguageInternalChecks();
}

/**
* Documentation extensions do not reference a generated target class, so documentation helpers have no target class name and
* provide their own {@link #isExtensionUpdateRequired} logic that never consults it.
*
* @param catalog
* the check catalog
* @return never returns normally
*/
@SuppressWarnings("PMD.UnusedFormalParameter")
@Override
protected String getTargetClassName(final CheckCatalog catalog) {
throw new UnsupportedOperationException("Documentation extension helpers have no target class"); //$NON-NLS-1$
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,41 @@ protected boolean isExtensionUpdateRequired(final CheckCatalog catalog, final IP
return extension.getPoint().equals(getExtensionPointId()); // if points are different, given extension must not be updated
}

/**
* Checks whether a class-referencing extension (validator / quickfix) needs updating: it must point at this helper's
* extension point and reference exactly one element whose target class, language and catalog name still match the
* check catalog. Shared by the validator and quickfix helpers, whose only difference is {@link #getTargetClassName}.
*
* @param catalog
* the catalog
* @param extension
* the extension
* @param elements
* the elements
* @return true, if the extension must be regenerated
*/
protected boolean isTargetClassExtensionUpdateRequired(final CheckCatalog catalog, final IPluginExtension extension, final Iterable<IPluginElement> elements) {
// CHECKSTYLE:OFF
// @Format-Off
return getExtensionPointId().equals(extension.getPoint())
&& (!extensionNameMatches(extension, catalog)
|| Iterables.size(elements) != 1
|| !targetClassMatches(Iterables.get(elements, 0), getTargetClassName(catalog))
|| catalog.getGrammar() == null && Iterables.get(elements, 0).getAttribute(LANGUAGE_ELEMENT_TAG) != null
|| catalog.getGrammar() != null && !languageNameMatches(Iterables.get(elements, 0), catalog.getGrammar().getName()));
// @Format-On
// CHECKSTYLE:ON
}

/**
* Gets the target class name based on the package path of given check catalog.
*
* @param catalog
* the check catalog
* @return the target class FQN
*/
protected abstract String getTargetClassName(CheckCatalog catalog);

/**
* Updates a given extension to values calculated using given check catalog.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ public String getExtensionPointName(final CheckCatalog catalog) {
* the check catalog
* @return the target class FQN
*/
private String getTargetClassName(final CheckCatalog catalog) {
@Override
protected String getTargetClassName(final CheckCatalog catalog) {
return getFromServiceProvider(CheckGeneratorNaming.class, catalog).qualifiedPreferenceInitializerClassName(catalog);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,14 @@ protected void doUpdateExtension(final CheckCatalog catalog, final IPluginExtens
* the check catalog
* @return the target class FQN
*/
private String getTargetClassName(final CheckCatalog catalog) {
@Override
protected String getTargetClassName(final CheckCatalog catalog) {
return getFromServiceProvider(CheckGeneratorNaming.class, catalog).qualifiedQuickfixClassName(catalog);
}

@Override
public boolean isExtensionUpdateRequired(final CheckCatalog catalog, final IPluginExtension extension, final Iterable<IPluginElement> elements) {
// CHECKSTYLE:OFF
// @Format-Off
return QUICKFIX_EXTENSION_POINT_ID.equals(extension.getPoint())
&& (!extensionNameMatches(extension, catalog)
|| Iterables.size(elements) != 1
|| !targetClassMatches(Iterables.get(elements, 0), getTargetClassName(catalog))
|| catalog.getGrammar() == null && Iterables.get(elements, 0).getAttribute(LANGUAGE_ELEMENT_TAG) != null
|| catalog.getGrammar() != null && !languageNameMatches(Iterables.get(elements, 0), catalog.getGrammar().getName()));
// @Format-On
// CHECKSTYLE:ON
return isTargetClassExtensionUpdateRequired(catalog, extension, elements);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,14 @@ private String getCatalogResourceName(final CheckCatalog catalog) {
* the check catalog
* @return the target class FQN
*/
private String getTargetClassName(final CheckCatalog catalog) {
@Override
protected String getTargetClassName(final CheckCatalog catalog) {
return getFromServiceProvider(CheckGeneratorNaming.class, catalog).qualifiedValidatorClassName(catalog);
}

@Override
public boolean isExtensionUpdateRequired(final CheckCatalog catalog, final IPluginExtension extension, final Iterable<IPluginElement> elements) {
// CHECKSTYLE:OFF
// @Format-Off
return CHECK_EXTENSION_POINT_ID.equals(extension.getPoint())
&& (!extensionNameMatches(extension, catalog)
|| Iterables.size(elements) != 1
|| !targetClassMatches(Iterables.get(elements, 0), getTargetClassName(catalog))
|| catalog.getGrammar() == null && Iterables.get(elements, 0).getAttribute(LANGUAGE_ELEMENT_TAG) != null
|| catalog.getGrammar() != null && !languageNameMatches(Iterables.get(elements, 0), catalog.getGrammar().getName())
);
// @Format-On
// CHECKSTYLE:ON
return isTargetClassExtensionUpdateRequired(catalog, extension, elements);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ default Test (
}
""";

// CPD-OFF — sibling test-class scaffolding, kept explicit (#1339)
@Override
protected AbstractXtextTestUtil getXtextTestUtil() {
return CheckCfgTestUtil.getInstance();
Expand All @@ -70,6 +71,7 @@ protected void afterAllTests() {

@Test
public void testConfiguredParameterProposals() {
// CPD-ON
final String source = SOURCE_TEMPLATE.formatted(TestPropertySpecificationWithExpectedValues.INSTANCE.getName(), expected(TestPropertySpecificationWithExpectedValues.INSTANCE.getExpectedValues()));
assertKernelSourceProposals("ConfiguredParameterProposals.checkcfg", source);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

public class CheckCfgConfiguredParameterValidationsTest extends AbstractValidationTest {

// CPD-OFF — sibling test-class scaffolding, kept explicit (#1339)
@Override
protected AbstractXtextTestUtil getXtextTestUtil() {
return CheckCfgTestUtil.getInstance();
Expand All @@ -53,6 +54,7 @@ protected void afterAllTests() {

@Test
public void testConfiguredParameterValues() {
// CPD-ON
final TestPropertySpecificationWithExpectedValues allowedOnly = TestPropertySpecificationWithExpectedValues.INSTANCE;
final TestPropertySpecificationWithOutExpectedValues acceptsAny = TestPropertySpecificationWithOutExpectedValues.INSTANCE;
final String source = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@ void testUnnamedFormalAfterNamed4() {
assertSame(unnamedFormal2, matchResult.getUnnamedFormalsAfterNamed().get(1), UNNAMED_FORMAL_AFTER_NAMED_NOT_LOCATED);
}

// CPD-OFF — explicit parameterized test cases, kept readable over shared (#1339)
@Test
void testForceMatchByPosition1() {
List<NamedFormalParameter> formals = new ArrayList<NamedFormalParameter>();
Expand Down Expand Up @@ -946,5 +947,6 @@ void testForceMatchByPosition3() {
checkParameterMatch(IParameterMatchChecker.MatchStatus.MATCH, actuals.get(1), formals.get(1), matches.get(1));
checkParameterMatch(IParameterMatchChecker.MatchStatus.MATCH, actuals.get(2), formals.get(2), matches.get(2));
}
// CPD-ON

}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ protected XtendFileAccess doGetXtendStubFile() {
protected void appendTo(final TargetStringConcatenation builder) {
builder.append("import com.avaloq.tools.ddk.xtext.formatting.ExtendedLineEntry");
builder.newLine();
// CPD-OFF — parallel Xtend/Java formatter-stub emission, kept explicit (#1339)
builder.append("import java.util.List");

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will coalesce these in a follow-up PR.

builder.newLine();
builder.newLine();
Expand All @@ -184,6 +185,7 @@ protected void appendTo(final TargetStringConcatenation builder) {
builder.append(" */");
builder.newLine();
builder.append("class ");
// CPD-ON
builder.append(getFormatterStub(getGrammar()).getSimpleName());
builder.append(" extends ");
builder.append(FormatGeneratorUtil.getFormatterName(getGrammar(), "Abstract"));
Expand Down Expand Up @@ -251,6 +253,7 @@ protected void appendTo(final TargetStringConcatenation builder) {
builder.append("import java.util.List;");
builder.newLine();
builder.newLine();
// CPD-OFF — parallel Xtend/Java formatter-stub emission, kept explicit (#1339)
builder.append("import org.eclipse.xtext.TerminalRule;");
builder.newLine();
builder.newLine();
Expand All @@ -271,6 +274,7 @@ protected void appendTo(final TargetStringConcatenation builder) {
builder.append(" */");
builder.newLine();
builder.append("public class ");
// CPD-ON
builder.append(getFormatterStub(getGrammar()).getSimpleName());
builder.append(" extends ");
builder.append(FormatGeneratorUtil.getFormatterName(getGrammar(), "Abstract"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
*/
@SuppressWarnings({"nls", "checkstyle:MethodName", "PMD.UnusedFormalParameter"})
public class FormatJvmModelInferrer extends AbstractModelInferrer {
// CPD-OFF — migrated Xtend dispatch/emission code, kept faithful; de-dup is a migration follow-up (#1339)
// CHECKSTYLE:CONSTANTS-OFF the repeated literals are Java source fragments emitted by this generator, not nameable constants
// CHECKSTYLE:CHECK-OFF LambdaBodyLength the model-inference closures mirror the Xtext JvmTypesBuilder API and are kept whole

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ public void apply(final EObject root, final Integer pos) {
* actual message
*/
private void createErrorMessage(final Integer pos, final List<Resource.Diagnostic> diagnosticsOnTargetPosition, final boolean issueFound, final boolean expectedSeverityMatches, final int actualSeverity, final boolean expectedMessageMatches, final String actualMessage) {
// CPD-OFF — test scaffolding; per-test clarity beats extraction (#1339)
StringBuilder errorMessage = new StringBuilder(200);
if (issueMustBeFound && !issueFound) {
errorMessage.append("Expected issue not found. Code '").append(issueCode).append('\n');
Expand All @@ -398,6 +399,7 @@ private void createErrorMessage(final Integer pos, final List<Resource.Diagnosti
}
memorizeErrorOnPosition(pos, errorMessage.toString());
}
// CPD-ON
}

/**
Expand Down Expand Up @@ -1002,6 +1004,7 @@ public static void assertNoLinkingErrorsOnResource(final EObject object, final S
*/
@SuppressWarnings("PMD.UnusedFormalParameter")
public static void assertLinkingErrorsOnResourceExist(final EObject object, final String referenceType, final String... referenceNames) {
// CPD-OFF — test scaffolding; per-test clarity beats extraction (#1339)
final List<Resource.Diagnostic> linkingErrors = object.eResource().getErrors().stream().filter(error -> error instanceof XtextLinkingDiagnostic).collect(Collectors.toList());
final List<String> errorMessages = Lists.transform(linkingErrors, Resource.Diagnostic::getMessage);
for (final String referenceName : referenceNames) {
Expand All @@ -1012,6 +1015,7 @@ public static void assertLinkingErrorsOnResourceExist(final EObject object, fina
break;
}
}
// CPD-ON
assertTrue(found, NLS.bind("Expected linking error on \"{0}\" but could not find it", referenceName));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,15 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.xtext.linking.lazy.LazyLinkingResource;

import com.google.common.collect.Iterables;
Expand Down Expand Up @@ -209,43 +205,6 @@ protected final CharSequence encodeFingerprint(final ExportItem export) {
}
}

/**
* Return an Iterable containing all the contents of the given feature of the given object. If the
* feature is not many-valued, the resulting iterable will have one element. If the feature is an EReference,
* the iterable may contain proxies. The iterable may contain null values.
*
* @param <T>
* The Generic type of the objects in the iterable
* @param obj
* The object
* @param feature
* The feature
* @return An iterable over all the contents of the feature of the object.
*/
@SuppressWarnings("unchecked")
private <T> Iterable<T> featureIterable(final EObject obj, final EStructuralFeature feature) {
if (feature == null) {
return Collections.emptyList();
}
if (feature.isMany()) {
if (feature instanceof EAttribute || ((EReference) feature).isContainment()) {
return (Iterable<T>) obj.eGet(feature);
}
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
EList<T> list = (EList<T>) obj.eGet(feature);
if (list instanceof InternalEList<T> internalList) {
return internalList.basicIterator(); // Don't resolve
} else {
return list.iterator();
}
}
};
}
return Collections.singletonList((T) obj.eGet(feature, false)); // Don't resolve
}

/**
* Generate a fingerprint for the target object using its URI.
*
Expand Down Expand Up @@ -319,7 +278,7 @@ protected CharSequence fingerprintFeature(final EObject obj, final EReference re
if (obj == null) {
return NULL_STRING;
}
final Iterable<? extends EObject> targets = featureIterable(obj, ref);
final Iterable<? extends EObject> targets = FingerprintFeatures.featureIterable(obj, ref);
if (targets == null) {
return NULL_STRING;
}
Expand Down Expand Up @@ -370,7 +329,7 @@ protected CharSequence fingerprintFeature(final EObject obj, final EAttribute at
if (obj == null) {
return NULL_STRING;
}
final Iterable<? extends Object> values = featureIterable(obj, attr);
final Iterable<? extends Object> values = FingerprintFeatures.featureIterable(obj, attr);
if (values == null) {
return NULL_STRING;
}
Expand Down Expand Up @@ -468,7 +427,7 @@ protected ExportItem fingerprintRef(final EObject obj, final EReference ref, fin
if (obj == null) {
return NO_EXPORT;
}
final Iterable<? extends EObject> targets = featureIterable(obj, ref);
final Iterable<? extends EObject> targets = FingerprintFeatures.featureIterable(obj, ref);
if (targets == null) {
return NO_EXPORT;
}
Expand Down
Loading