diff --git a/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProviderTest.java b/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProviderTest.java new file mode 100644 index 0000000000..ed00e67b97 --- /dev/null +++ b/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProviderTest.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2026 Avaloq Group AG and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Avaloq Group AG - initial API and implementation + *******************************************************************************/ +package com.avaloq.tools.ddk.xtext.ui.editor.findrefs; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.xtext.resource.IReferenceDescription; +import org.eclipse.xtext.resource.IResourceDescription; +import org.eclipse.xtext.resource.IResourceDescriptions; +import org.eclipse.xtext.ui.editor.findrefs.ReferenceSearchResult; +import org.junit.jupiter.api.Test; + + +/** + * Tests for {@link FastReferenceSearchResultContentProvider}. + */ +@SuppressWarnings("nls") +public class FastReferenceSearchResultContentProviderTest { + + private static final URI FIRST_SOURCE = URI.createURI("platform:/resource/project/a.test#/0"); + private static final URI SECOND_SOURCE = URI.createURI("platform:/resource/project/b.test#/0"); + @Test + public void inputChangedToleratesReferencesAcceptedWhileRepopulating() { + List matchingReferences = new ArrayList<>(); + matchingReferences.add(reference(FIRST_SOURCE)); + ReferenceSearchResult searchResult = mock(ReferenceSearchResult.class); + when(searchResult.getMatchingReferences()).thenReturn(matchingReferences); + + // the search thread accepts another reference while the UI thread is repopulating from the live list + IResourceDescription resourceDescription = mock(IResourceDescription.class); + when(resourceDescription.getURI()).thenReturn(FIRST_SOURCE.trimFragment()); + IResourceDescriptions resourceDescriptions = mock(IResourceDescriptions.class); + when(resourceDescriptions.getResourceDescription(any())).thenAnswer(invocation -> { + if (matchingReferences.size() == 1) { + matchingReferences.add(reference(SECOND_SOURCE)); + } + return resourceDescription; + }); + + FastReferenceSearchResultContentProvider provider = new FastReferenceSearchResultContentProvider(resourceDescriptions); + TreeViewer viewer = mock(TreeViewer.class); + assertDoesNotThrow(() -> provider.inputChanged(viewer, null, searchResult)); + } + + private static IReferenceDescription reference(final URI sourceEObjectUri) { + IReferenceDescription reference = mock(IReferenceDescription.class); + when(reference.getSourceEObjectUri()).thenReturn(sourceEObjectUri); + return reference; + } + +} diff --git a/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/test/XtextUiTestSuite.java b/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/test/XtextUiTestSuite.java index 7a3be78266..2eaf9266eb 100644 --- a/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/test/XtextUiTestSuite.java +++ b/com.avaloq.tools.ddk.xtext.ui.test/src/com/avaloq/tools/ddk/xtext/ui/test/XtextUiTestSuite.java @@ -14,6 +14,7 @@ import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.Suite; +import com.avaloq.tools.ddk.xtext.ui.editor.findrefs.FastReferenceSearchResultContentProviderTest; import com.avaloq.tools.ddk.xtext.ui.quickfix.WorkbenchResolutionAdaptorRunTest; import com.avaloq.tools.ddk.xtext.ui.quickfix.WorkbenchResolutionAdaptorTest; import com.avaloq.tools.ddk.xtext.ui.templates.ResourceNameTemplateVariableResolverTest; @@ -31,7 +32,8 @@ WorkbenchResolutionAdaptorTest.class, TemplateProposalProviderHelperTest.class, ResourceNameTemplateVariableResolverTest.class, - SimpleEnumTemplateVariableResolverTest.class + SimpleEnumTemplateVariableResolverTest.class, + FastReferenceSearchResultContentProviderTest.class // @Format-On }) public class XtextUiTestSuite { diff --git a/com.avaloq.tools.ddk.xtext.ui/META-INF/MANIFEST.MF b/com.avaloq.tools.ddk.xtext.ui/META-INF/MANIFEST.MF index 609ac52451..79e450c5d7 100644 --- a/com.avaloq.tools.ddk.xtext.ui/META-INF/MANIFEST.MF +++ b/com.avaloq.tools.ddk.xtext.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: com.avaloq.tools.ddk.xtext.ui Bundle-SymbolicName: com.avaloq.tools.ddk.xtext.ui;singleton:=true -Bundle-Version: 17.3.3.qualifier +Bundle-Version: 17.3.4.qualifier Bundle-Vendor: Avaloq Group AG Bundle-RequiredExecutionEnvironment: JavaSE-21 Bundle-ActivationPolicy: lazy diff --git a/com.avaloq.tools.ddk.xtext.ui/pom.xml b/com.avaloq.tools.ddk.xtext.ui/pom.xml index c0672c7749..46bec80919 100644 --- a/com.avaloq.tools.ddk.xtext.ui/pom.xml +++ b/com.avaloq.tools.ddk.xtext.ui/pom.xml @@ -6,7 +6,7 @@ 18.0.1-SNAPSHOT ../ddk-parent - 17.3.3-SNAPSHOT + 17.3.4-SNAPSHOT com.avaloq.tools.ddk com.avaloq.tools.ddk.xtext.ui eclipse-plugin diff --git a/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProvider.java b/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProvider.java index 657f032922..bb6c7ba4ae 100644 --- a/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProvider.java +++ b/com.avaloq.tools.ddk.xtext.ui/src/com/avaloq/tools/ddk/xtext/ui/editor/findrefs/FastReferenceSearchResultContentProvider.java @@ -115,8 +115,11 @@ public void inputChanged(final Viewer v, final Object oldInput, final Object new if (newInput instanceof ReferenceSearchResult && v instanceof TreeViewer) { ((ReferenceSearchResult) newInput).addListener(this); this.viewer = (TreeViewer) v; - for (IReferenceDescription referenceDescription : ((ReferenceSearchResult) newInput).getMatchingReferences()) { - addReference(referenceDescription); + // iterate a copy: the search job may still be appending to the live list + for (IReferenceDescription referenceDescription : Lists.newArrayList(((ReferenceSearchResult) newInput).getMatchingReferences())) { + if (referenceDescription != null) { + addReference(referenceDescription); + } } } }