Bug 457617 - [xbase][refactoring] Renaming a static method replaces references with fully qualified name
Summary: [xbase][refactoring] Renaming a static method replaces references with fully ...
Status: NEW
Alias: None
Product: TMF
Classification: Modeling
Component: Xtext (show other bugs)
Version: 2.7.3   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: triaged
Depends on:
Blocks:
 
Reported: 2015-01-15 10:45 EST by Lorenzo Bettini CLA
Modified: 2017-08-04 05:28 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lorenzo Bettini CLA 2015-01-15 10:45:55 EST
In an Xbase language, when you refactor an element inferred to a static method, existing references are replaced with the fully qualified name of the renamed element.  This happens in Xtend as well.

For example, given this Xtend program

package mypackage

class MyXtendFile {
	def static void foo() {
		foo()
	}
}

select "foo", start refactoring, e.g, as "bar" and press ENTER; after refactoring the modified program is

package mypackage

class MyXtendFile {
	def static void bar() {
		mypackage.MyXtendFile.bar()
	}
}
Comment 1 Lorenzo Bettini CLA 2015-01-15 10:53:07 EST
Some additional comments (see also https://www.eclipse.org/forums/index.php/t/943988/): I tried to debug a little bit what is going on during refactoring; I don't know whether this can help, but I found suspicious what happens in this method

RefactoringScopeReferenceSerializer

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);
...
		Iterable<IEObjectDescription> descriptionsForCrossRef = scope.getElements(target);
		String bestRefText = null;
		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;

the call to refTextEvaluator.isValid(desc) returns false; this happens because

return new RefTextEvaluator() {

public boolean isValid(IEObjectDescription newTarget) {
	IScope scope = linkingScopeProvider.getScope(referringElement, reference);
	IEObjectDescription element = scope.getSingleElement(newTarget.getName());
	// TODO here we need to simulate linking with the new name instead of the old name
	if(element instanceof IIdentifiableElementDescription) {
		IIdentifiableElementDescription casted = (IIdentifiableElementDescription) element;
		if(!casted.isVisible() || !casted.isValidStaticState())
			return false;
		}

casted.isValidStaticState() returns

false since its implicitReceiverType is NOT null (it is the inferred Java class).