Name conflicts while renaming [message #1805122] |
Mon, 08 April 2019 00:47  |
Eclipse User |
|
|
|
Hi,
I am facing issue in rename.
When I try to rename element and put the new name which is already present previous to the place where rename has been triggered, it shows the name conflicts.
But when I try to rename element and put new name which is already present after the place where rename has been triggered, it does not show the name conflicts and rename happens successfully.
I have created a small example to explain that.
Grammar:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals hidden(WS, ML_COMMENT, SL_COMMENT, TEST_STMT)
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
conts+=Cont* procs+=Proc*;
Cont:
'Cont' name=ID '{' items+=Item* '}' ;
Item: 'Item' name=ID;
Proc:
'Link' item1=[Item|ID] 'OF' con1=[Cont|ID] 'TO' item2=[Item|ID] 'OF' con2=[Cont|ID]
;
//Test statement
terminal TEST_STMT : 'FreeText: ' -> '.';
Sample Model:
Cont container1 {
Item item1
}
Cont container2 {
Item item2
}
Link item1 OF container1 TO item2 OF container2
In the above example, when i try to rename "container2" to "container1", it shows name conflicts. But it does not show name conflicts when I try to rename "container1" to "container2".
According to me it should throw error (name conflicts) for both the cases.
How can i achieve this?
Could you please help me with this regard.
Thanks and regards,
Virag Purnam
|
|
|
|
|
|
|
|
|
Re: Name conflicts while renaming [message #1806768 is a reply to message #1805129] |
Wed, 15 May 2019 01:14   |
Eclipse User |
|
|
|
Hi Mr. Christian Dietrich,
I have done code changes in RefactoringCrossReferenceSerializer class to check the duplicate name. I have attached code here.
Do you see any side effect of this code change?
Your comments will be helpful.
Thanks and regards,
Virag Purnam
import static org.eclipse.ltk.core.refactoring.RefactoringStatus.ERROR;
import static org.eclipse.ltk.core.refactoring.RefactoringStatus.WARNING;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.linking.impl.LinkingHelper;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.serializer.tokens.SerializerScopeProviderBinding;
import org.eclipse.xtext.ui.refactoring.impl.RefactoringCrossReferenceSerializer;
import org.eclipse.xtext.ui.refactoring.impl.StatusWrapper;
import org.eclipse.xtext.ui.refactoring.impl.RefactoringCrossReferenceSerializer.RefTextEvaluator;
import org.eclipse.xtext.util.ITextRegion;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import com.google.inject.Inject;
public class CustomRefactoringCrossReferenceSerializer extends RefactoringCrossReferenceSerializer {
private static final Logger log = Logger.getLogger(CustomRefactoringCrossReferenceSerializer.class);
@Inject
@SerializerScopeProviderBinding
private IScopeProvider scopeProvider;
@Inject
private IValueConverterService valueConverter;
@Inject
private LinkingHelper linkingHelper;
@Inject
private IQualifiedNameConverter qualifiedNameConverter;
public String getCrossRefText(EObject owner, CrossReference crossref, EObject target,
RefTextEvaluator refTextEvaluator, ITextRegion linkTextRegion, StatusWrapper status) {
try {
final EReference ref = GrammarUtil.getReference(crossref, owner.eClass());
final IScope scope = scopeProvider.getScope(owner, ref);
if (scope == null) {
throw new IllegalStateException("Could not create scope for the given cross reference.");
}
String ruleName = linkingHelper.getRuleNameFrom(crossref);
/*
* Code added here
*/
// Getting all elements in the scope
Iterable<IEObjectDescription> allElements = scope.getAllElements();
List<String> names = new ArrayList<>();
// Check for duplicate names after refactoring
for(IEObjectDescription desc : allElements) {
String unconvertedRefText = qualifiedNameConverter.toString(desc.getName());
String convertedRefText = valueConverter.toString(unconvertedRefText, ruleName);
if(names.contains(convertedRefText)) {
return null;
} else {
names.add(convertedRefText);
}
}
/*
* Ends here
*/
Iterable<IEObjectDescription> descriptionsForCrossRef = scope.getElements(target);
String bestRefText = null;
List<String> badNames = new ArrayList<String>();
for (IEObjectDescription desc : descriptionsForCrossRef) {
try {
String unconvertedRefText = qualifiedNameConverter.toString(desc.getName());
String convertedRefText = valueConverter.toString(unconvertedRefText, ruleName);
if (refTextEvaluator.isValid(desc) && (bestRefText == null || refTextEvaluator.isBetterThan(convertedRefText, bestRefText)))
bestRefText = convertedRefText;
} catch (ValueConverterException e) {
// this is a problem only if we don't find any matching value
badNames.add(desc.getName().toString());
}
}
if (bestRefText == null && !badNames.isEmpty()) {
status.add(WARNING,
"Misconfigured language: New reference text has invalid syntax. Following names are in the scope: " + IterableExtensions.join(badNames, ", "), owner, linkTextRegion);
}
return bestRefText;
} catch (Exception exc) {
log.error(exc.getMessage(), exc);
status.add(ERROR, exc.getMessage(), owner, linkTextRegion);
return null;
}
}
}
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.28799 seconds