Skip to content

Commit

Permalink
Merge pull request #226 from LorenzoBettini/task_217-Outline_should_h…
Browse files Browse the repository at this point in the history
…ighlight_modified_elements

Task 217 outline should highlight modified elements
  • Loading branch information
LorenzoBettini committed Jul 23, 2020
2 parents 630a2e0 + 2d48aba commit f2b1857
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import org.junit.runner.RunWith

import static org.assertj.core.api.Assertions.assertThat
import static org.mockito.Mockito.*
import edelta.resource.derivedstate.EdeltaDerivedStateHelper
import edelta.resource.derivedstate.EdeltaModifiedElements

@RunWith(XtextRunner)
@InjectWith(EdeltaInjectorProvider)
Expand All @@ -44,10 +46,12 @@ class EdeltaInterpreterResourceListenerTest extends EdeltaAbstractTest {

@Inject IResourceScopeCache cache
@Inject EdeltaInterpreterDiagnosticHelper diagnosticHelper
@Inject EdeltaDerivedStateHelper derivedStateHelper
var EdeltaInterpreterResourceListener listener
var EPackage ePackage
var Resource resource
var EdeltaENamedElementXExpressionMap enamedElementXExpressionMap
var EdeltaModifiedElements modifiedElements
var Provider<String> stringProvider

@Before
Expand All @@ -59,9 +63,10 @@ class EdeltaInterpreterResourceListenerTest extends EdeltaAbstractTest {
]
]
resource = "".parse.eResource
enamedElementXExpressionMap = new EdeltaENamedElementXExpressionMap
enamedElementXExpressionMap = derivedStateHelper.getEnamedElementXExpressionMap(resource)
modifiedElements = derivedStateHelper.getModifiedElements(resource)
listener = new EdeltaInterpreterResourceListener(
cache, resource, enamedElementXExpressionMap, diagnosticHelper
cache, resource, derivedStateHelper, diagnosticHelper
)
stringProvider = spy(new SpiedProvider)
ePackage.eAdapters += listener
Expand Down Expand Up @@ -259,6 +264,33 @@ class EdeltaInterpreterResourceListenerTest extends EdeltaAbstractTest {
assertThat(resource.validate).hasSize(1)
}

@Test
def void testModifiedElementsIsUpdatedWhenNameIsChanged() {
val currentExpression = mock(XExpression)
listener.setCurrentExpression(currentExpression)
val element = ecoreFactory.createEClass
ePackage.EClassifiers += element
assertThat(modifiedElements)
.containsExactlyInAnyOrder(element, ePackage)
}

@Test
def void testModifiedElementsIsUpdatedWhenElementIsAdded() {
val currentExpression = mock(XExpression)
listener.setCurrentExpression(currentExpression)
val element = ePackage.EClassifiers.get(0)
// change the name
element.name = "Modified"
assertThat(modifiedElements)
.containsExactlyInAnyOrder(element, ePackage)
}

@Test
def void testModifiedElementsIsEmptyWhenNothingIsChanged() {
ePackage.eAdapters -= listener
assertThat(modifiedElements).isEmpty
}

def createEObjectDiagnosticMock(EObject problematicObject) {
mock(EObjectDiagnosticImpl) => [
when(getProblematicObject).thenReturn(problematicObject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import edelta.interpreter.EdeltaInterpreterDiagnostic;
import edelta.interpreter.EdeltaInterpreterDiagnosticHelper;
import edelta.interpreter.EdeltaInterpreterResourceListener;
import edelta.resource.derivedstate.EdeltaDerivedStateHelper;
import edelta.resource.derivedstate.EdeltaENamedElementXExpressionMap;
import edelta.resource.derivedstate.EdeltaModifiedElements;
import edelta.tests.EdeltaAbstractTest;
import edelta.tests.EdeltaInjectorProvider;
import edelta.validation.EdeltaValidator;
Expand Down Expand Up @@ -61,6 +63,9 @@ public String get() {
@Inject
private EdeltaInterpreterDiagnosticHelper diagnosticHelper;

@Inject
private EdeltaDerivedStateHelper derivedStateHelper;

private EdeltaInterpreterResourceListener listener;

private EPackage ePackage;
Expand All @@ -69,6 +74,8 @@ public String get() {

private EdeltaENamedElementXExpressionMap enamedElementXExpressionMap;

private EdeltaModifiedElements modifiedElements;

private Provider<String> stringProvider;

@Before
Expand All @@ -88,10 +95,10 @@ public void setup() {
EPackage _doubleArrow = ObjectExtensions.<EPackage>operator_doubleArrow(_createEPackage, _function);
this.ePackage = _doubleArrow;
this.resource = this._parseHelper.parse("").eResource();
EdeltaENamedElementXExpressionMap _edeltaENamedElementXExpressionMap = new EdeltaENamedElementXExpressionMap();
this.enamedElementXExpressionMap = _edeltaENamedElementXExpressionMap;
this.enamedElementXExpressionMap = this.derivedStateHelper.getEnamedElementXExpressionMap(this.resource);
this.modifiedElements = this.derivedStateHelper.getModifiedElements(this.resource);
EdeltaInterpreterResourceListener _edeltaInterpreterResourceListener = new EdeltaInterpreterResourceListener(
this.cache, this.resource, this.enamedElementXExpressionMap, this.diagnosticHelper);
this.cache, this.resource, this.derivedStateHelper, this.diagnosticHelper);
this.listener = _edeltaInterpreterResourceListener;
EdeltaInterpreterResourceListenerTest.SpiedProvider _spiedProvider = new EdeltaInterpreterResourceListenerTest.SpiedProvider();
this.stringProvider = Mockito.<Provider<String>>spy(_spiedProvider);
Expand Down Expand Up @@ -290,6 +297,32 @@ public void testEClassCycleWhenAddingSuperType() {
Assertions.<Issue>assertThat(this._validationTestHelper.validate(this.resource)).hasSize(1);
}

@Test
public void testModifiedElementsIsUpdatedWhenNameIsChanged() {
final XExpression currentExpression = Mockito.<XExpression>mock(XExpression.class);
this.listener.setCurrentExpression(currentExpression);
final EClass element = EdeltaInterpreterResourceListenerTest.ecoreFactory.createEClass();
EList<EClassifier> _eClassifiers = this.ePackage.getEClassifiers();
_eClassifiers.add(element);
Assertions.<ENamedElement>assertThat(this.modifiedElements).containsExactlyInAnyOrder(element, this.ePackage);
}

@Test
public void testModifiedElementsIsUpdatedWhenElementIsAdded() {
final XExpression currentExpression = Mockito.<XExpression>mock(XExpression.class);
this.listener.setCurrentExpression(currentExpression);
final EClassifier element = this.ePackage.getEClassifiers().get(0);
element.setName("Modified");
Assertions.<ENamedElement>assertThat(this.modifiedElements).containsExactlyInAnyOrder(element, this.ePackage);
}

@Test
public void testModifiedElementsIsEmptyWhenNothingIsChanged() {
EList<Adapter> _eAdapters = this.ePackage.eAdapters();
_eAdapters.remove(this.listener);
Assertions.<ENamedElement>assertThat(this.modifiedElements).isEmpty();
}

public EObjectDiagnosticImpl createEObjectDiagnosticMock(final EObject problematicObject) {
EObjectDiagnosticImpl _mock = Mockito.<EObjectDiagnosticImpl>mock(EObjectDiagnosticImpl.class);
final Procedure1<EObjectDiagnosticImpl> _function = (EObjectDiagnosticImpl it) -> {
Expand Down
3 changes: 2 additions & 1 deletion edelta.parent/edelta.ui.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Require-Bundle: edelta,
org.eclipse.xtext.testing,
org.eclipse.xtext.xbase.testing,
org.eclipse.xtext.ui.testing,
org.eclipse.xtext.xbase.ui.testing
org.eclipse.xtext.xbase.ui.testing,
edelta.testing.libraries;bundle-version="0.9.0"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: edelta.ui.tests;x-internal=true
Import-Package: org.hamcrest.core,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package edelta.ui.tests;

import static org.assertj.core.api.Assertions.assertThat;

import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.xtext.testing.InjectWith;
import org.eclipse.xtext.testing.XtextRunner;
import org.eclipse.xtext.testing.util.ParseHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.google.inject.Inject;

import edelta.edelta.EdeltaProgram;
import edelta.resource.derivedstate.EdeltaDerivedStateHelper;
import edelta.ui.labeling.EdeltaLabelProvider;

@RunWith(XtextRunner.class)
@InjectWith(EdeltaUiInjectorProvider.class)
public class EdeltaLabelProviderTest {

@Inject
private EdeltaLabelProvider labelProvider;

@Inject
private EdeltaDerivedStateHelper derivedStateHelper;

@Inject
private ParseHelper<EdeltaProgram> parseHelper;

private Resource resource;

private static EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE;

@Before
public void setup() throws Exception {
resource = parseHelper.parse("").eResource();
}

@Test
public void testEPackageStyledString() {
var ePackage = ecoreFactory.createEPackage();
resource.getContents().add(ePackage);
StyledString styledText = labelProvider.getStyledText(ePackage);
assertThat(styledText.getStyleRanges()).isEmpty();
}

@Test
public void testStyledStringWhenNotModified() {
var element = ecoreFactory.createEClass();
resource.getContents().add(element);
StyledString styledText = labelProvider.getStyledText(element);
assertThat(styledText.getStyleRanges()).isEmpty();
}

@Test
public void testStyledStringWhenModified() {
var element = ecoreFactory.createEClass();
element.setName("aclass");
resource.getContents().add(element);
derivedStateHelper.getModifiedElements(resource).add(element);
StyledString styledText = labelProvider.getStyledText(element);
assertThat(styledText.getStyleRanges()).isNotEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,27 @@ class EdeltaOutlineTest extends AbstractOutlineTest {
)
}
@Test @Flaky
def void testOutlineWhenNoElementIsModifiedThenTheEPackageIsNotShown() {
println("*** Executing testOutlineWhenNoElementIsModified...")
// wait for build so that ecores are indexed
// and then found by the test programs
waitForBuild
'''
metamodel "mypackage"

modifyEcore aModification epackage mypackage {

}
'''.assertAllLabels(
'''
test
aModification(EPackage) : void
'''
)
}
def private allOtherContents()
'''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,33 @@ public void testOutlineWithRemovedElementsInModifyEcore() {
}
}

@Test
@Flaky
public void testOutlineWhenNoElementIsModifiedThenTheEPackageIsNotShown() {
try {
InputOutput.<String>println("*** Executing testOutlineWhenNoElementIsModified...");
IResourcesSetupUtil.waitForBuild();
StringConcatenation _builder = new StringConcatenation();
_builder.append("metamodel \"mypackage\"");
_builder.newLine();
_builder.newLine();
_builder.append("modifyEcore aModification epackage mypackage {");
_builder.newLine();
_builder.newLine();
_builder.append("}");
_builder.newLine();
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("test");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("aModification(EPackage) : void");
_builder_1.newLine();
this.assertAllLabels(_builder, _builder_1);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}

private CharSequence allOtherContents() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("MyClass");
Expand Down
5 changes: 3 additions & 2 deletions edelta.parent/edelta.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ Require-Bundle: edelta,
Import-Package: org.apache.log4j
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: edelta.ui.contentassist,
edelta.ui.editor,
edelta.ui.internal,
edelta.ui.labeling,
edelta.ui.quickfix,
edelta.ui.wizard,
edelta.ui.editor
edelta.ui.wizard
Bundle-Activator: edelta.ui.internal.EdeltaActivator
Automatic-Module-Name: edelta.ui
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@

import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.xbase.annotations.ui.labeling.XbaseWithAnnotationsLabelProvider;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations;
Expand All @@ -18,6 +23,7 @@

import edelta.edelta.EdeltaModifyEcoreOperation;
import edelta.edelta.EdeltaOperation;
import edelta.resource.derivedstate.EdeltaDerivedStateHelper;

/**
* Provides labels for EObjects.
Expand All @@ -29,8 +35,18 @@ public class EdeltaLabelProvider extends XbaseWithAnnotationsLabelProvider {
@Inject
private IJvmModelAssociations jvmModelAssociations;

@Inject
private EdeltaDerivedStateHelper derivedStateHelper;

private AdapterFactoryLabelProvider delegate;

private static final Styler BOLD_FONT_STYLER = new Styler() {
@Override
public void applyStyles(final TextStyle textStyle) {
textStyle.font = JFaceResources.getFontRegistry().getBold("Edelta");
}
};

@Inject
public EdeltaLabelProvider(final AdapterFactoryLabelProvider delegate) {
super(delegate);
Expand All @@ -53,14 +69,21 @@ public ImageDescriptor image(final EdeltaModifyEcoreOperation m) {
return this.imageDescriptor(this.inferredJavaMethod(m));
}

public String text(final ENamedElement e) {
public Object text(final ENamedElement e) {
// delegate to the default Ecore edit label provider
// for Ecore model elements.
return delegate.getText(e);
final var text = delegate.getText(e);
if (e instanceof EPackage) {
return text; // no need to highlight EPackage
// since only the ones with modified elements are shown in the outline
}
if (derivedStateHelper.getModifiedElements(e.eResource()).contains(e)) {
return new StyledString(text, BOLD_FONT_STYLER);
}
return text;
}

private JvmOperation inferredJavaMethod(final EObject e) {
return head(filter(
jvmModelAssociations.getJvmElements(e), JvmOperation.class));
return head(filter(jvmModelAssociations.getJvmElements(e), JvmOperation.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
package edelta.ui.outline;

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.xtext.ui.editor.outline.IOutlineNode;
import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider;

Expand All @@ -24,17 +23,21 @@ public class EdeltaOutlineTreeProvider extends DefaultOutlineTreeProvider {
private EdeltaDerivedStateHelper derivedStateHelper;

protected void _createChildren(final IOutlineNode parentNode, final EdeltaProgram p) {
for (final EdeltaOperation o : p.getOperations()) {
for (final var o : p.getOperations()) {
this.createNode(parentNode, o);
}
for (final EdeltaModifyEcoreOperation o : p.getModifyEcoreOperations()) {
for (final var o : p.getModifyEcoreOperations()) {
this.createNode(parentNode, o);
}
for (final EPackage copiedEPackage : this.derivedStateHelper.getCopiedEPackagesMap(p.eResource()).values()) {
final var eResource = p.eResource();
final var modifiedElements = derivedStateHelper.getModifiedElements(eResource);
for (final var ePackage : this.derivedStateHelper.getCopiedEPackagesMap(eResource).values()) {
// the cool thing is that we don't need to provide
// customization in the label provider for EPackage and EClass
// since Xtext defaults to the .edit plugin :)
this.createNode(parentNode, copiedEPackage);
if (modifiedElements.contains(ePackage))
this.createNode(parentNode, ePackage);
// only show EPackage with some modifications
}
}

Expand Down

0 comments on commit f2b1857

Please sign in to comment.