mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
[LS] overhauled rename service
- delegate to rename language of the declaration of the renamed target - allow to trigger rename with caret right after the identifier - support versioned documents Closes #917, closes #916 and closes #1072
This commit is contained in:
parent
61bdf5d638
commit
a290419be4
16 changed files with 516 additions and 61 deletions
|
@ -39,13 +39,24 @@ class RenameTest extends AbstractTestLangLanguageServerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
def void testRenameOnDeclaration() {
|
||||
doTest(firstFile, new Position(0,5))
|
||||
def void testRenameBeforeDeclaration() {
|
||||
doTest(firstFile, new Position(0, 4))
|
||||
}
|
||||
|
||||
@Test
|
||||
def void testRenameOnDeclaration() {
|
||||
doTest(firstFile, new Position(0, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
def void testRenameAfterDeclaration() {
|
||||
doTest(firstFile, new Position(0, 8))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
def void testRenameOnReference() {
|
||||
doTest(firstFile, new Position(1,5))
|
||||
doTest(firstFile, new Position(1, 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -12,6 +12,9 @@ import org.eclipse.lsp4j.RenameParams
|
|||
import org.eclipse.lsp4j.TextDocumentIdentifier
|
||||
import org.eclipse.xtext.testing.AbstractLanguageServerTest
|
||||
import org.junit.Test
|
||||
import org.eclipse.lsp4j.ClientCapabilities
|
||||
import org.eclipse.lsp4j.WorkspaceClientCapabilities
|
||||
import org.eclipse.lsp4j.WorkspaceEditCapabilities
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
|
@ -38,9 +41,9 @@ class RenameTest2 extends AbstractLanguageServerTest {
|
|||
val workspaceEdit = languageServer.rename(params).get
|
||||
assertEquals('''
|
||||
changes :
|
||||
Foo.fileawaretestlanguage : Bar [[2, 8] .. [2, 11]]
|
||||
Bar [[3, 5] .. [3, 8]]
|
||||
documentChanges :
|
||||
Foo.fileawaretestlanguage <1> : Bar [[2, 8] .. [2, 11]]
|
||||
Bar [[3, 5] .. [3, 8]]
|
||||
'''.toString, toExpectation(workspaceEdit))
|
||||
}
|
||||
|
||||
|
@ -64,11 +67,21 @@ class RenameTest2 extends AbstractLanguageServerTest {
|
|||
val workspaceEdit = languageServer.rename(params).get
|
||||
assertEquals('''
|
||||
changes :
|
||||
Foo.fileawaretestlanguage : Baz [[2, 8] .. [2, 11]]
|
||||
documentChanges :
|
||||
Foo.fileawaretestlanguage <1> : Baz [[2, 8] .. [2, 11]]
|
||||
Bar [[5, 5] .. [5, 16]]
|
||||
Bar [[6, 5] .. [6, 12]]
|
||||
documentChanges :
|
||||
'''.toString, toExpectation(workspaceEdit))
|
||||
}
|
||||
|
||||
|
||||
override protected initialize() {
|
||||
super.initialize([params | params.capabilities = new ClientCapabilities => [
|
||||
workspace = new WorkspaceClientCapabilities => [
|
||||
workspaceEdit = new WorkspaceEditCapabilities => [
|
||||
documentChanges = true
|
||||
]
|
||||
]
|
||||
]])
|
||||
}
|
||||
}
|
|
@ -28,7 +28,9 @@ import org.eclipse.lsp4j.Range;
|
|||
import org.eclipse.lsp4j.SemanticHighlightingInformation;
|
||||
import org.eclipse.lsp4j.SignatureHelp;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.TextDocumentEdit;
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
|
@ -334,6 +336,8 @@ public class CompletionTest extends AbstractTestLangLanguageServerTest {
|
|||
return _toExpectation((DocumentHighlightKind)it);
|
||||
} else if (it instanceof String) {
|
||||
return _toExpectation((String)it);
|
||||
} else if (it instanceof VersionedTextDocumentIdentifier) {
|
||||
return _toExpectation((VersionedTextDocumentIdentifier)it);
|
||||
} else if (it instanceof Pair) {
|
||||
return _toExpectation((Pair<SemanticHighlightingInformation, List<List<String>>>)it);
|
||||
} else if (it == null) {
|
||||
|
@ -366,6 +370,8 @@ public class CompletionTest extends AbstractTestLangLanguageServerTest {
|
|||
return _toExpectation((SignatureHelp)it);
|
||||
} else if (it instanceof SymbolInformation) {
|
||||
return _toExpectation((SymbolInformation)it);
|
||||
} else if (it instanceof TextDocumentEdit) {
|
||||
return _toExpectation((TextDocumentEdit)it);
|
||||
} else if (it instanceof TextEdit) {
|
||||
return _toExpectation((TextEdit)it);
|
||||
} else if (it instanceof WorkspaceEdit) {
|
||||
|
|
|
@ -51,12 +51,24 @@ public class RenameTest extends AbstractTestLangLanguageServerTest {
|
|||
this.initialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameBeforeDeclaration() {
|
||||
Position _position = new Position(0, 4);
|
||||
this.doTest(this.firstFile, _position);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameOnDeclaration() {
|
||||
Position _position = new Position(0, 5);
|
||||
this.doTest(this.firstFile, _position);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameAfterDeclaration() {
|
||||
Position _position = new Position(0, 8);
|
||||
this.doTest(this.firstFile, _position);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameOnReference() {
|
||||
Position _position = new Position(1, 5);
|
||||
|
|
|
@ -7,13 +7,20 @@
|
|||
*/
|
||||
package org.eclipse.xtext.ide.tests.server;
|
||||
|
||||
import org.eclipse.lsp4j.ClientCapabilities;
|
||||
import org.eclipse.lsp4j.InitializeParams;
|
||||
import org.eclipse.lsp4j.InitializeResult;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.RenameParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceEditCapabilities;
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
import org.eclipse.xtext.testing.AbstractLanguageServerTest;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -49,14 +56,14 @@ public class RenameTest2 extends AbstractLanguageServerTest {
|
|||
StringConcatenation _builder_1 = new StringConcatenation();
|
||||
_builder_1.append("changes :");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append("documentChanges : ");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append(" ");
|
||||
_builder_1.append("Foo.fileawaretestlanguage : Bar [[2, 8] .. [2, 11]]");
|
||||
_builder_1.append("Foo.fileawaretestlanguage <1> : Bar [[2, 8] .. [2, 11]]");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append(" ");
|
||||
_builder_1.append("Bar [[3, 5] .. [3, 8]]");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append("documentChanges : ");
|
||||
_builder_1.newLine();
|
||||
this.assertEquals(_builder_1.toString(), this.toExpectation(workspaceEdit));
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
|
@ -99,8 +106,10 @@ public class RenameTest2 extends AbstractLanguageServerTest {
|
|||
StringConcatenation _builder_1 = new StringConcatenation();
|
||||
_builder_1.append("changes :");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append("documentChanges : ");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append(" ");
|
||||
_builder_1.append("Foo.fileawaretestlanguage : Baz [[2, 8] .. [2, 11]]");
|
||||
_builder_1.append("Foo.fileawaretestlanguage <1> : Baz [[2, 8] .. [2, 11]]");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append(" ");
|
||||
_builder_1.append("Bar [[5, 5] .. [5, 16]]");
|
||||
|
@ -108,11 +117,32 @@ public class RenameTest2 extends AbstractLanguageServerTest {
|
|||
_builder_1.append(" ");
|
||||
_builder_1.append("Bar [[6, 5] .. [6, 12]]");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append("documentChanges : ");
|
||||
_builder_1.newLine();
|
||||
this.assertEquals(_builder_1.toString(), this.toExpectation(workspaceEdit));
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InitializeResult initialize() {
|
||||
final Procedure1<InitializeParams> _function = (InitializeParams params) -> {
|
||||
ClientCapabilities _clientCapabilities = new ClientCapabilities();
|
||||
final Procedure1<ClientCapabilities> _function_1 = (ClientCapabilities it) -> {
|
||||
WorkspaceClientCapabilities _workspaceClientCapabilities = new WorkspaceClientCapabilities();
|
||||
final Procedure1<WorkspaceClientCapabilities> _function_2 = (WorkspaceClientCapabilities it_1) -> {
|
||||
WorkspaceEditCapabilities _workspaceEditCapabilities = new WorkspaceEditCapabilities();
|
||||
final Procedure1<WorkspaceEditCapabilities> _function_3 = (WorkspaceEditCapabilities it_2) -> {
|
||||
it_2.setDocumentChanges(Boolean.valueOf(true));
|
||||
};
|
||||
WorkspaceEditCapabilities _doubleArrow = ObjectExtensions.<WorkspaceEditCapabilities>operator_doubleArrow(_workspaceEditCapabilities, _function_3);
|
||||
it_1.setWorkspaceEdit(_doubleArrow);
|
||||
};
|
||||
WorkspaceClientCapabilities _doubleArrow = ObjectExtensions.<WorkspaceClientCapabilities>operator_doubleArrow(_workspaceClientCapabilities, _function_2);
|
||||
it.setWorkspace(_doubleArrow);
|
||||
};
|
||||
ClientCapabilities _doubleArrow = ObjectExtensions.<ClientCapabilities>operator_doubleArrow(_clientCapabilities, _function_1);
|
||||
params.setCapabilities(_doubleArrow);
|
||||
};
|
||||
return super.initialize(_function);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ import static org.eclipse.xtext.diagnostics.Severity.*
|
|||
import com.google.common.collect.ImmutableMultimap
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import org.eclipse.xtext.findReferences.IReferenceFinder.IResourceAccess
|
||||
import org.eclipse.xtext.ide.server.rename.IRenameServiceExtension
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
|
@ -607,14 +608,19 @@ import org.eclipse.xtext.findReferences.IReferenceFinder.IResourceAccess
|
|||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
||||
override rename(RenameParams params) {
|
||||
override rename(RenameParams renameParams) {
|
||||
return requestManager.runRead[ cancelIndicator |
|
||||
val uri = params.textDocument.uri.toUri
|
||||
val uri = renameParams.textDocument.uri.toUri
|
||||
val resourceServiceProvider = uri.resourceServiceProvider
|
||||
val renameService = resourceServiceProvider?.get(IRenameService)
|
||||
if (renameService === null)
|
||||
return new WorkspaceEdit
|
||||
renameService.rename(workspaceManager, params, cancelIndicator)
|
||||
if (renameService instanceof IRenameServiceExtension) {
|
||||
val options = new IRenameServiceExtension.Options(params?.capabilities?.workspace?.workspaceEdit?.documentChanges === Boolean.TRUE)
|
||||
renameService.rename(workspaceManager, renameParams, options, cancelIndicator)
|
||||
} else {
|
||||
renameService.rename(workspaceManager, renameParams, cancelIndicator)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,14 @@ import org.eclipse.emf.common.util.URI
|
|||
import org.eclipse.emf.ecore.resource.Resource
|
||||
import org.eclipse.emf.ecore.xmi.XMLResource
|
||||
import org.eclipse.lsp4j.Range
|
||||
import org.eclipse.lsp4j.TextDocumentEdit
|
||||
import org.eclipse.lsp4j.TextEdit
|
||||
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
|
||||
import org.eclipse.lsp4j.WorkspaceEdit
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either
|
||||
import org.eclipse.xtext.ide.serializer.IEmfResourceChange
|
||||
import org.eclipse.xtext.ide.serializer.ITextDocumentChange
|
||||
import org.eclipse.xtext.ide.server.Document
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager
|
||||
import org.eclipse.xtext.parser.IEncodingProvider
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider
|
||||
|
@ -31,21 +35,35 @@ class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
|
||||
static class Factory {
|
||||
|
||||
@Inject IResourceServiceProvider.Registry registry
|
||||
@Inject protected IResourceServiceProvider.Registry registry
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #create(WorkspaceManager, WorkspaceEdit, boolean} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
def ChangeConverter create(WorkspaceManager workspaceManager, WorkspaceEdit edit) {
|
||||
new ChangeConverter(workspaceManager, registry, edit)
|
||||
new ChangeConverter(workspaceManager, registry, edit, null)
|
||||
}
|
||||
|
||||
def ChangeConverter create(WorkspaceManager workspaceManager, WorkspaceEdit edit, IRenameServiceExtension.Options options) {
|
||||
new ChangeConverter(workspaceManager, registry, edit, options)
|
||||
}
|
||||
}
|
||||
|
||||
val WorkspaceManager workspaceManager
|
||||
val IResourceServiceProvider.Registry registry
|
||||
val WorkspaceEdit edit
|
||||
val IRenameServiceExtension.Options options
|
||||
|
||||
protected new(WorkspaceManager workspaceManager, IResourceServiceProvider.Registry registry, WorkspaceEdit edit) {
|
||||
protected new(WorkspaceManager workspaceManager, IResourceServiceProvider.Registry registry, WorkspaceEdit edit, IRenameServiceExtension.Options options) {
|
||||
this.workspaceManager = workspaceManager
|
||||
this.registry = registry
|
||||
this.edit = edit
|
||||
this.options = options
|
||||
if (options?.clientSupportsVerisonedDocuments)
|
||||
this.edit.documentChanges = newArrayList
|
||||
else
|
||||
this.edit.changes = newLinkedHashMap
|
||||
}
|
||||
|
||||
override accept(IEmfResourceChange change) {
|
||||
|
@ -61,7 +79,7 @@ class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
workspaceManager.doRead(uri) [ document, resource |
|
||||
val range = new Range(document.getPosition(0), document.getPosition(document.contents.length))
|
||||
val textEdit = new TextEdit(range, newContent)
|
||||
addTextEdit(uri, textEdit)
|
||||
addTextEdit(uri, document, textEdit)
|
||||
]
|
||||
} finally {
|
||||
outputStream.close
|
||||
|
@ -88,12 +106,24 @@ class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
val range = new Range(start, end)
|
||||
new TextEdit(range, replacement.replacementText)
|
||||
]
|
||||
addTextEdit(uri, textEdits)
|
||||
addTextEdit(uri, document, textEdits)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
protected def addTextEdit(URI uri, TextEdit... textEdit) {
|
||||
edit.changes.put(uri.toString, textEdit)
|
||||
protected def addTextEdit(URI theUri, Document document, TextEdit... textEdits) {
|
||||
if (options?.clientSupportsVerisonedDocuments) {
|
||||
edit.documentChanges +=
|
||||
Either.forLeft(new TextDocumentEdit => [
|
||||
textDocument = new VersionedTextDocumentIdentifier => [
|
||||
uri = theUri.toString
|
||||
version = document.version
|
||||
]
|
||||
edits = textEdits
|
||||
])
|
||||
} else {
|
||||
edit.changes.put(theUri.toString, textEdits)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,13 +9,34 @@ package org.eclipse.xtext.ide.server.rename
|
|||
|
||||
import org.eclipse.lsp4j.RenameParams
|
||||
import org.eclipse.lsp4j.WorkspaceEdit
|
||||
import org.eclipse.xtend.lib.annotations.Data
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager
|
||||
import org.eclipse.xtext.util.CancelIndicator
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.13
|
||||
* @deprectated implement IRenameService2 instead.
|
||||
*/
|
||||
@Deprecated
|
||||
interface IRenameService {
|
||||
def WorkspaceEdit rename(WorkspaceManager workspaceManager, RenameParams renameParams, CancelIndicator cancelIndicator)
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of rename refactoring for a language.
|
||||
*
|
||||
* As opposed to {@link IRenameService} this returns {@link TextDocumentChanges} if the
|
||||
* client supports versioned documents.
|
||||
*
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.17
|
||||
*/
|
||||
interface IRenameServiceExtension {
|
||||
def WorkspaceEdit rename(WorkspaceManager workspaceManager, RenameParams renameParams, Options options, CancelIndicator cancelIndicator)
|
||||
|
||||
@Data
|
||||
class Options {
|
||||
boolean clientSupportsVerisonedDocuments
|
||||
}
|
||||
}
|
|
@ -9,59 +9,86 @@ package org.eclipse.xtext.ide.server.rename
|
|||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Provider
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil
|
||||
import org.eclipse.lsp4j.Position
|
||||
import org.eclipse.lsp4j.RenameParams
|
||||
import org.eclipse.lsp4j.WorkspaceEdit
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.TerminalRule
|
||||
import org.eclipse.xtext.ide.refactoring.IRenameStrategy2
|
||||
import org.eclipse.xtext.ide.refactoring.RenameChange
|
||||
import org.eclipse.xtext.ide.refactoring.RenameContext
|
||||
import org.eclipse.xtext.ide.serializer.IChangeSerializer
|
||||
import org.eclipse.xtext.ide.server.Document
|
||||
import org.eclipse.xtext.ide.server.UriExtensions
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager
|
||||
import org.eclipse.xtext.nodemodel.ILeafNode
|
||||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
|
||||
import org.eclipse.xtext.parsetree.reconstr.impl.TokenUtil
|
||||
import org.eclipse.xtext.resource.EObjectAtOffsetHelper
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider
|
||||
import org.eclipse.xtext.resource.XtextResource
|
||||
import org.eclipse.xtext.util.CancelIndicator
|
||||
import static org.eclipse.xtext.ide.refactoring.RefactoringIssueAcceptor.Severity.*
|
||||
import org.eclipse.xtext.ide.refactoring.IRenameStrategy2
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider
|
||||
import org.eclipse.xtext.util.CancelIndicator
|
||||
|
||||
import static org.eclipse.xtext.ide.refactoring.RefactoringIssueAcceptor.Severity.*
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.13
|
||||
*/
|
||||
class RenameService implements IRenameService {
|
||||
@Accessors(PROTECTED_GETTER)
|
||||
class RenameService implements IRenameService, IRenameServiceExtension {
|
||||
|
||||
@Inject extension EObjectAtOffsetHelper
|
||||
@Inject extension EObjectAtOffsetHelper eObjectAtOffsetHelper
|
||||
|
||||
@Inject IRenameStrategy2 renameStrategy
|
||||
|
||||
@Inject ChangeConverter.Factory converterFactory
|
||||
|
||||
@Inject extension UriExtensions
|
||||
@Inject extension UriExtensions uriExtensions
|
||||
|
||||
@Inject Provider<IChangeSerializer> changeSerializerProvider
|
||||
|
||||
@Inject Provider<ServerRefactoringIssueAcceptor> issueProvider
|
||||
|
||||
@Inject IResourceServiceProvider.Registry serviceProviderRegistry
|
||||
|
||||
@Inject TokenUtil tokenUtil
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #rename(WorkspaceManager, RenameParams, Options, CancelIndicator)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
override rename(WorkspaceManager workspaceManager, RenameParams renameParams, CancelIndicator cancelIndicator) {
|
||||
rename(workspaceManager, renameParams, new Options(false), cancelIndicator)
|
||||
}
|
||||
|
||||
override rename(WorkspaceManager workspaceManager, RenameParams renameParams, Options options, CancelIndicator cancelIndicator) {
|
||||
val uri = renameParams.textDocument.uri.toUri
|
||||
val issueAcceptor = issueProvider.get
|
||||
workspaceManager.doRead(uri) [ document, resource |
|
||||
workspaceManager.doRead(uri) [ document, resource |
|
||||
val projectManager = workspaceManager.getProjectManager(uri)
|
||||
val resourceSet = projectManager.createNewResourceSet(projectManager.indexState.resourceDescriptions)
|
||||
resourceSet.loadOptions.put(ResourceDescriptionsProvider.LIVE_SCOPE, true)
|
||||
val offset = document.getOffSet(renameParams.position)
|
||||
val workspaceEdit = new WorkspaceEdit
|
||||
val xtextResource = resourceSet.getResource(resource.URI, true)
|
||||
if (xtextResource instanceof XtextResource) {
|
||||
val element = xtextResource.resolveElementAt(offset)
|
||||
val element = xtextResource.getElementAtOffset(document, renameParams.position)
|
||||
if (element === null || element.eIsProxy) {
|
||||
issueAcceptor.add(FATAL, '''No element found at position line:«renameParams.position.line» column:«renameParams.position.character»''')
|
||||
issueAcceptor.add(
|
||||
FATAL, '''No element found at position line:«renameParams.position.line» column:«renameParams.position.character»''')
|
||||
} else {
|
||||
val services = serviceProviderRegistry.getResourceServiceProvider(element.eResource.URI)
|
||||
val changeSerializer = services.get(IChangeSerializer)
|
||||
val change = new RenameChange(renameParams.newName, EcoreUtil.getURI(element))
|
||||
val changeSerializer = changeSerializerProvider.get
|
||||
val context = new RenameContext(#[change], resourceSet, changeSerializer, issueAcceptor)
|
||||
val renameStrategy = services.get(IRenameStrategy2)
|
||||
renameStrategy.applyRename(context)
|
||||
val changeConverter = converterFactory.create(workspaceManager, workspaceEdit)
|
||||
val converterFactory = services.get(ChangeConverter.Factory)
|
||||
val changeConverter = converterFactory.create(workspaceManager, workspaceEdit, options)
|
||||
changeSerializer.applyModifications(changeConverter)
|
||||
}
|
||||
} else {
|
||||
|
@ -70,4 +97,19 @@ class RenameService implements IRenameService {
|
|||
return workspaceEdit
|
||||
]
|
||||
}
|
||||
|
||||
protected def EObject getElementAtOffset(XtextResource xtextResource, Document document, Position caretPosition) {
|
||||
val caretOffset = document.getOffSet(caretPosition)
|
||||
val leafNode = NodeModelUtils.findLeafNodeAtOffset(xtextResource.parseResult.rootNode, caretOffset)
|
||||
val offset = if (caretOffset > 0 && leafNode.offset === caretOffset && !isIdentifier(leafNode))
|
||||
caretOffset - 1
|
||||
else
|
||||
caretOffset
|
||||
return xtextResource.resolveElementAt(offset)
|
||||
}
|
||||
|
||||
protected def isIdentifier(ILeafNode leafNode) {
|
||||
return leafNode.grammarElement instanceof TerminalRule
|
||||
&& !tokenUtil.isWhitespaceOrCommentNode(leafNode)
|
||||
}
|
||||
}
|
|
@ -83,6 +83,7 @@ import org.eclipse.lsp4j.TextDocumentSyncKind;
|
|||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceEditCapabilities;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.Endpoint;
|
||||
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
|
||||
|
@ -120,6 +121,7 @@ import org.eclipse.xtext.ide.server.formatting.FormattingService;
|
|||
import org.eclipse.xtext.ide.server.hover.IHoverService;
|
||||
import org.eclipse.xtext.ide.server.occurrences.IDocumentHighlightService;
|
||||
import org.eclipse.xtext.ide.server.rename.IRenameService;
|
||||
import org.eclipse.xtext.ide.server.rename.IRenameServiceExtension;
|
||||
import org.eclipse.xtext.ide.server.semanticHighlight.SemanticHighlightingRegistry;
|
||||
import org.eclipse.xtext.ide.server.signatureHelp.ISignatureHelpService;
|
||||
import org.eclipse.xtext.ide.server.symbol.DocumentSymbolService;
|
||||
|
@ -925,11 +927,11 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<WorkspaceEdit> rename(final RenameParams params) {
|
||||
public CompletableFuture<WorkspaceEdit> rename(final RenameParams renameParams) {
|
||||
final Function1<CancelIndicator, WorkspaceEdit> _function = (CancelIndicator cancelIndicator) -> {
|
||||
WorkspaceEdit _xblockexpression = null;
|
||||
{
|
||||
final URI uri = this._uriExtensions.toUri(params.getTextDocument().getUri());
|
||||
final URI uri = this._uriExtensions.toUri(renameParams.getTextDocument().getUri());
|
||||
final IResourceServiceProvider resourceServiceProvider = this.languagesRegistry.getResourceServiceProvider(uri);
|
||||
IRenameService _get = null;
|
||||
if (resourceServiceProvider!=null) {
|
||||
|
@ -939,7 +941,35 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
|
|||
if ((renameService == null)) {
|
||||
return new WorkspaceEdit();
|
||||
}
|
||||
_xblockexpression = renameService.rename(this.workspaceManager, params, cancelIndicator);
|
||||
WorkspaceEdit _xifexpression = null;
|
||||
if ((renameService instanceof IRenameServiceExtension)) {
|
||||
WorkspaceEdit _xblockexpression_1 = null;
|
||||
{
|
||||
ClientCapabilities _capabilities = null;
|
||||
if (this.params!=null) {
|
||||
_capabilities=this.params.getCapabilities();
|
||||
}
|
||||
WorkspaceClientCapabilities _workspace = null;
|
||||
if (_capabilities!=null) {
|
||||
_workspace=_capabilities.getWorkspace();
|
||||
}
|
||||
WorkspaceEditCapabilities _workspaceEdit = null;
|
||||
if (_workspace!=null) {
|
||||
_workspaceEdit=_workspace.getWorkspaceEdit();
|
||||
}
|
||||
Boolean _documentChanges = null;
|
||||
if (_workspaceEdit!=null) {
|
||||
_documentChanges=_workspaceEdit.getDocumentChanges();
|
||||
}
|
||||
boolean _tripleEquals = (_documentChanges == Boolean.TRUE);
|
||||
final IRenameServiceExtension.Options options = new IRenameServiceExtension.Options(_tripleEquals);
|
||||
_xblockexpression_1 = ((IRenameServiceExtension)renameService).rename(this.workspaceManager, renameParams, options, cancelIndicator);
|
||||
}
|
||||
_xifexpression = _xblockexpression_1;
|
||||
} else {
|
||||
_xifexpression = renameService.rename(this.workspaceManager, renameParams, cancelIndicator);
|
||||
}
|
||||
_xblockexpression = _xifexpression;
|
||||
}
|
||||
return _xblockexpression;
|
||||
};
|
||||
|
|
|
@ -17,22 +17,30 @@ import org.eclipse.emf.ecore.resource.Resource;
|
|||
import org.eclipse.emf.ecore.xmi.XMLResource;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.ResourceOperation;
|
||||
import org.eclipse.lsp4j.TextDocumentEdit;
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextReplacement;
|
||||
import org.eclipse.xtext.ide.serializer.IEmfResourceChange;
|
||||
import org.eclipse.xtext.ide.serializer.ITextDocumentChange;
|
||||
import org.eclipse.xtext.ide.server.Document;
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager;
|
||||
import org.eclipse.xtext.ide.server.rename.IRenameServiceExtension;
|
||||
import org.eclipse.xtext.parser.IEncodingProvider;
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider;
|
||||
import org.eclipse.xtext.resource.XtextResource;
|
||||
import org.eclipse.xtext.util.IAcceptor;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Conversions;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function2;
|
||||
import org.eclipse.xtext.xbase.lib.ListExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
|
@ -42,10 +50,18 @@ import org.eclipse.xtext.xbase.lib.ListExtensions;
|
|||
public class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
||||
public static class Factory {
|
||||
@Inject
|
||||
private IResourceServiceProvider.Registry registry;
|
||||
protected IResourceServiceProvider.Registry registry;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #create(WorkspaceManager, WorkspaceEdit, boolean} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public ChangeConverter create(final WorkspaceManager workspaceManager, final WorkspaceEdit edit) {
|
||||
return new ChangeConverter(workspaceManager, this.registry, edit);
|
||||
return new ChangeConverter(workspaceManager, this.registry, edit, null);
|
||||
}
|
||||
|
||||
public ChangeConverter create(final WorkspaceManager workspaceManager, final WorkspaceEdit edit, final IRenameServiceExtension.Options options) {
|
||||
return new ChangeConverter(workspaceManager, this.registry, edit, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,10 +71,22 @@ public class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
|
||||
private final WorkspaceEdit edit;
|
||||
|
||||
protected ChangeConverter(final WorkspaceManager workspaceManager, final IResourceServiceProvider.Registry registry, final WorkspaceEdit edit) {
|
||||
private final IRenameServiceExtension.Options options;
|
||||
|
||||
protected ChangeConverter(final WorkspaceManager workspaceManager, final IResourceServiceProvider.Registry registry, final WorkspaceEdit edit, final IRenameServiceExtension.Options options) {
|
||||
this.workspaceManager = workspaceManager;
|
||||
this.registry = registry;
|
||||
this.edit = edit;
|
||||
this.options = options;
|
||||
boolean _isClientSupportsVerisonedDocuments = false;
|
||||
if (options!=null) {
|
||||
_isClientSupportsVerisonedDocuments=options.isClientSupportsVerisonedDocuments();
|
||||
}
|
||||
if (_isClientSupportsVerisonedDocuments) {
|
||||
this.edit.setDocumentChanges(CollectionLiterals.<Either<TextDocumentEdit, ResourceOperation>>newArrayList());
|
||||
} else {
|
||||
this.edit.setChanges(CollectionLiterals.<String, List<TextEdit>>newLinkedHashMap());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,18 +103,18 @@ public class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
byte[] _byteArray = outputStream.toByteArray();
|
||||
String _charset = this.getCharset(change.getResource());
|
||||
final String newContent = new String(_byteArray, _charset);
|
||||
final Function2<Document, XtextResource, List<TextEdit>> _function = (Document document, XtextResource resource) -> {
|
||||
List<TextEdit> _xblockexpression = null;
|
||||
final Function2<Document, XtextResource, Object> _function = (Document document, XtextResource resource) -> {
|
||||
Object _xblockexpression = null;
|
||||
{
|
||||
Position _position = document.getPosition(0);
|
||||
Position _position_1 = document.getPosition(document.getContents().length());
|
||||
final Range range = new Range(_position, _position_1);
|
||||
final TextEdit textEdit = new TextEdit(range, newContent);
|
||||
_xblockexpression = this.addTextEdit(uri, textEdit);
|
||||
_xblockexpression = this.addTextEdit(uri, document, textEdit);
|
||||
}
|
||||
return _xblockexpression;
|
||||
};
|
||||
this.workspaceManager.<List<TextEdit>>doRead(uri, _function);
|
||||
this.workspaceManager.<Object>doRead(uri, _function);
|
||||
} finally {
|
||||
outputStream.close();
|
||||
}
|
||||
|
@ -121,8 +149,8 @@ public class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
boolean _greaterThan = (_size > 0);
|
||||
if (_greaterThan) {
|
||||
final URI uri = change.getNewURI();
|
||||
final Function2<Document, XtextResource, List<TextEdit>> _function = (Document document, XtextResource resource) -> {
|
||||
List<TextEdit> _xblockexpression = null;
|
||||
final Function2<Document, XtextResource, Object> _function = (Document document, XtextResource resource) -> {
|
||||
Object _xblockexpression = null;
|
||||
{
|
||||
final Function1<ITextReplacement, TextEdit> _function_1 = (ITextReplacement replacement) -> {
|
||||
TextEdit _xblockexpression_1 = null;
|
||||
|
@ -139,16 +167,40 @@ public class ChangeConverter implements IAcceptor<IEmfResourceChange> {
|
|||
return _xblockexpression_1;
|
||||
};
|
||||
final List<TextEdit> textEdits = ListExtensions.<ITextReplacement, TextEdit>map(change.getReplacements(), _function_1);
|
||||
_xblockexpression = this.addTextEdit(uri, ((TextEdit[])Conversions.unwrapArray(textEdits, TextEdit.class)));
|
||||
_xblockexpression = this.addTextEdit(uri, document, ((TextEdit[])Conversions.unwrapArray(textEdits, TextEdit.class)));
|
||||
}
|
||||
return _xblockexpression;
|
||||
};
|
||||
this.workspaceManager.<List<TextEdit>>doRead(uri, _function);
|
||||
this.workspaceManager.<Object>doRead(uri, _function);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<TextEdit> addTextEdit(final URI uri, final TextEdit... textEdit) {
|
||||
return this.edit.getChanges().put(uri.toString(), ((List<TextEdit>)Conversions.doWrapArray(textEdit)));
|
||||
protected Object addTextEdit(final URI theUri, final Document document, final TextEdit... textEdits) {
|
||||
Object _xifexpression = null;
|
||||
boolean _isClientSupportsVerisonedDocuments = false;
|
||||
if (this.options!=null) {
|
||||
_isClientSupportsVerisonedDocuments=this.options.isClientSupportsVerisonedDocuments();
|
||||
}
|
||||
if (_isClientSupportsVerisonedDocuments) {
|
||||
List<Either<TextDocumentEdit, ResourceOperation>> _documentChanges = this.edit.getDocumentChanges();
|
||||
TextDocumentEdit _textDocumentEdit = new TextDocumentEdit();
|
||||
final Procedure1<TextDocumentEdit> _function = (TextDocumentEdit it) -> {
|
||||
VersionedTextDocumentIdentifier _versionedTextDocumentIdentifier = new VersionedTextDocumentIdentifier();
|
||||
final Procedure1<VersionedTextDocumentIdentifier> _function_1 = (VersionedTextDocumentIdentifier it_1) -> {
|
||||
it_1.setUri(theUri.toString());
|
||||
it_1.setVersion(document.getVersion());
|
||||
};
|
||||
VersionedTextDocumentIdentifier _doubleArrow = ObjectExtensions.<VersionedTextDocumentIdentifier>operator_doubleArrow(_versionedTextDocumentIdentifier, _function_1);
|
||||
it.setTextDocument(_doubleArrow);
|
||||
it.setEdits(((List<TextEdit>)Conversions.doWrapArray(textEdits)));
|
||||
};
|
||||
TextDocumentEdit _doubleArrow = ObjectExtensions.<TextDocumentEdit>operator_doubleArrow(_textDocumentEdit, _function);
|
||||
Either<TextDocumentEdit, ResourceOperation> _forLeft = Either.<TextDocumentEdit, ResourceOperation>forLeft(_doubleArrow);
|
||||
_xifexpression = Boolean.valueOf(_documentChanges.add(_forLeft));
|
||||
} else {
|
||||
_xifexpression = this.edit.getChanges().put(theUri.toString(), ((List<TextEdit>)Conversions.doWrapArray(textEdits)));
|
||||
}
|
||||
return _xifexpression;
|
||||
}
|
||||
|
||||
protected void handleReplacements(final IEmfResourceChange change) {
|
||||
|
|
|
@ -15,7 +15,9 @@ import org.eclipse.xtext.util.CancelIndicator;
|
|||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.13
|
||||
* @deprectated implement IRenameService2 instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("all")
|
||||
public interface IRenameService {
|
||||
public abstract WorkspaceEdit rename(final WorkspaceManager workspaceManager, final RenameParams renameParams, final CancelIndicator cancelIndicator);
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Copyright (c) 2017 TypeFox GmbH (http://www.typefox.io) 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
|
||||
*/
|
||||
package org.eclipse.xtext.ide.server.rename;
|
||||
|
||||
import org.eclipse.lsp4j.RenameParams;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.xtend.lib.annotations.Data;
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager;
|
||||
import org.eclipse.xtext.util.CancelIndicator;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* The implementation of rename refactoring for a language.
|
||||
*
|
||||
* As opposed to {@link IRenameService} this returns {@link TextDocumentChanges} if the
|
||||
* client supports versioned documents.
|
||||
*
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.17
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public interface IRenameServiceExtension {
|
||||
@Data
|
||||
public static class Options {
|
||||
private final boolean clientSupportsVerisonedDocuments;
|
||||
|
||||
public Options(final boolean clientSupportsVerisonedDocuments) {
|
||||
super();
|
||||
this.clientSupportsVerisonedDocuments = clientSupportsVerisonedDocuments;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public int hashCode() {
|
||||
return 31 * 1 + (this.clientSupportsVerisonedDocuments ? 1231 : 1237);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
IRenameServiceExtension.Options other = (IRenameServiceExtension.Options) obj;
|
||||
if (other.clientSupportsVerisonedDocuments != this.clientSupportsVerisonedDocuments)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("clientSupportsVerisonedDocuments", this.clientSupportsVerisonedDocuments);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Pure
|
||||
public boolean isClientSupportsVerisonedDocuments() {
|
||||
return this.clientSupportsVerisonedDocuments;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract WorkspaceEdit rename(final WorkspaceManager workspaceManager, final RenameParams renameParams, final IRenameServiceExtension.Options options, final CancelIndicator cancelIndicator);
|
||||
}
|
|
@ -14,9 +14,13 @@ import org.eclipse.emf.common.util.URI;
|
|||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.RenameParams;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.xtend.lib.annotations.AccessorType;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
import org.eclipse.xtext.TerminalRule;
|
||||
import org.eclipse.xtext.ide.refactoring.IRenameStrategy2;
|
||||
import org.eclipse.xtext.ide.refactoring.RefactoringIssueAcceptor;
|
||||
import org.eclipse.xtext.ide.refactoring.RenameChange;
|
||||
|
@ -28,8 +32,13 @@ import org.eclipse.xtext.ide.server.UriExtensions;
|
|||
import org.eclipse.xtext.ide.server.WorkspaceManager;
|
||||
import org.eclipse.xtext.ide.server.rename.ChangeConverter;
|
||||
import org.eclipse.xtext.ide.server.rename.IRenameService;
|
||||
import org.eclipse.xtext.ide.server.rename.IRenameServiceExtension;
|
||||
import org.eclipse.xtext.ide.server.rename.ServerRefactoringIssueAcceptor;
|
||||
import org.eclipse.xtext.nodemodel.ILeafNode;
|
||||
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
|
||||
import org.eclipse.xtext.parsetree.reconstr.impl.TokenUtil;
|
||||
import org.eclipse.xtext.resource.EObjectAtOffsetHelper;
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider;
|
||||
import org.eclipse.xtext.resource.XtextResource;
|
||||
import org.eclipse.xtext.resource.XtextResourceSet;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
|
||||
|
@ -37,16 +46,18 @@ import org.eclipse.xtext.util.CancelIndicator;
|
|||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Extension;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function2;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
|
||||
/**
|
||||
* @author koehnlein - Initial contribution and API
|
||||
* @since 2.13
|
||||
*/
|
||||
@Accessors(AccessorType.PROTECTED_GETTER)
|
||||
@SuppressWarnings("all")
|
||||
public class RenameService implements IRenameService {
|
||||
public class RenameService implements IRenameService, IRenameServiceExtension {
|
||||
@Inject
|
||||
@Extension
|
||||
private EObjectAtOffsetHelper _eObjectAtOffsetHelper;
|
||||
private EObjectAtOffsetHelper eObjectAtOffsetHelper;
|
||||
|
||||
@Inject
|
||||
private IRenameStrategy2 renameStrategy;
|
||||
|
@ -56,7 +67,7 @@ public class RenameService implements IRenameService {
|
|||
|
||||
@Inject
|
||||
@Extension
|
||||
private UriExtensions _uriExtensions;
|
||||
private UriExtensions uriExtensions;
|
||||
|
||||
@Inject
|
||||
private Provider<IChangeSerializer> changeSerializerProvider;
|
||||
|
@ -64,21 +75,37 @@ public class RenameService implements IRenameService {
|
|||
@Inject
|
||||
private Provider<ServerRefactoringIssueAcceptor> issueProvider;
|
||||
|
||||
@Inject
|
||||
private IResourceServiceProvider.Registry serviceProviderRegistry;
|
||||
|
||||
@Inject
|
||||
private TokenUtil tokenUtil;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #rename(WorkspaceManager, RenameParams, Options, CancelIndicator)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public WorkspaceEdit rename(final WorkspaceManager workspaceManager, final RenameParams renameParams, final CancelIndicator cancelIndicator) {
|
||||
IRenameServiceExtension.Options _options = new IRenameServiceExtension.Options(false);
|
||||
return this.rename(workspaceManager, renameParams, _options, cancelIndicator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkspaceEdit rename(final WorkspaceManager workspaceManager, final RenameParams renameParams, final IRenameServiceExtension.Options options, final CancelIndicator cancelIndicator) {
|
||||
WorkspaceEdit _xblockexpression = null;
|
||||
{
|
||||
final URI uri = this._uriExtensions.toUri(renameParams.getTextDocument().getUri());
|
||||
final URI uri = this.uriExtensions.toUri(renameParams.getTextDocument().getUri());
|
||||
final ServerRefactoringIssueAcceptor issueAcceptor = this.issueProvider.get();
|
||||
final Function2<Document, XtextResource, WorkspaceEdit> _function = (Document document, XtextResource resource) -> {
|
||||
final ProjectManager projectManager = workspaceManager.getProjectManager(uri);
|
||||
final XtextResourceSet resourceSet = projectManager.createNewResourceSet(projectManager.getIndexState().getResourceDescriptions());
|
||||
resourceSet.getLoadOptions().put(ResourceDescriptionsProvider.LIVE_SCOPE, Boolean.valueOf(true));
|
||||
final int offset = document.getOffSet(renameParams.getPosition());
|
||||
final WorkspaceEdit workspaceEdit = new WorkspaceEdit();
|
||||
final Resource xtextResource = resourceSet.getResource(resource.getURI(), true);
|
||||
if ((xtextResource instanceof XtextResource)) {
|
||||
final EObject element = this._eObjectAtOffsetHelper.resolveElementAt(((XtextResource)xtextResource), offset);
|
||||
final EObject element = this.getElementAtOffset(((XtextResource)xtextResource), document, renameParams.getPosition());
|
||||
if (((element == null) || element.eIsProxy())) {
|
||||
StringConcatenation _builder = new StringConcatenation();
|
||||
_builder.append("No element found at position line:");
|
||||
|
@ -87,15 +114,19 @@ public class RenameService implements IRenameService {
|
|||
_builder.append(" column:");
|
||||
int _character = renameParams.getPosition().getCharacter();
|
||||
_builder.append(_character);
|
||||
issueAcceptor.add(RefactoringIssueAcceptor.Severity.FATAL, _builder.toString());
|
||||
issueAcceptor.add(
|
||||
RefactoringIssueAcceptor.Severity.FATAL, _builder.toString());
|
||||
} else {
|
||||
final IResourceServiceProvider services = this.serviceProviderRegistry.getResourceServiceProvider(element.eResource().getURI());
|
||||
final IChangeSerializer changeSerializer = services.<IChangeSerializer>get(IChangeSerializer.class);
|
||||
String _newName = renameParams.getNewName();
|
||||
URI _uRI = EcoreUtil.getURI(element);
|
||||
final RenameChange change = new RenameChange(_newName, _uRI);
|
||||
final IChangeSerializer changeSerializer = this.changeSerializerProvider.get();
|
||||
final RenameContext context = new RenameContext(Collections.<RenameChange>unmodifiableList(CollectionLiterals.<RenameChange>newArrayList(change)), resourceSet, changeSerializer, issueAcceptor);
|
||||
this.renameStrategy.applyRename(context);
|
||||
final ChangeConverter changeConverter = this.converterFactory.create(workspaceManager, workspaceEdit);
|
||||
final IRenameStrategy2 renameStrategy = services.<IRenameStrategy2>get(IRenameStrategy2.class);
|
||||
renameStrategy.applyRename(context);
|
||||
final ChangeConverter.Factory converterFactory = services.<ChangeConverter.Factory>get(ChangeConverter.Factory.class);
|
||||
final ChangeConverter changeConverter = converterFactory.create(workspaceManager, workspaceEdit, options);
|
||||
changeSerializer.applyModifications(changeConverter);
|
||||
}
|
||||
} else {
|
||||
|
@ -107,4 +138,61 @@ public class RenameService implements IRenameService {
|
|||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
protected EObject getElementAtOffset(final XtextResource xtextResource, final Document document, final Position caretPosition) {
|
||||
final int caretOffset = document.getOffSet(caretPosition);
|
||||
final ILeafNode leafNode = NodeModelUtils.findLeafNodeAtOffset(xtextResource.getParseResult().getRootNode(), caretOffset);
|
||||
int _xifexpression = (int) 0;
|
||||
if ((((caretOffset > 0) && (leafNode.getOffset() == caretOffset)) && (!this.isIdentifier(leafNode)))) {
|
||||
_xifexpression = (caretOffset - 1);
|
||||
} else {
|
||||
_xifexpression = caretOffset;
|
||||
}
|
||||
final int offset = _xifexpression;
|
||||
return this.eObjectAtOffsetHelper.resolveElementAt(xtextResource, offset);
|
||||
}
|
||||
|
||||
protected boolean isIdentifier(final ILeafNode leafNode) {
|
||||
return ((leafNode.getGrammarElement() instanceof TerminalRule) && (!this.tokenUtil.isWhitespaceOrCommentNode(leafNode)));
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected EObjectAtOffsetHelper getEObjectAtOffsetHelper() {
|
||||
return this.eObjectAtOffsetHelper;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected IRenameStrategy2 getRenameStrategy() {
|
||||
return this.renameStrategy;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected ChangeConverter.Factory getConverterFactory() {
|
||||
return this.converterFactory;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected UriExtensions getUriExtensions() {
|
||||
return this.uriExtensions;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected Provider<IChangeSerializer> getChangeSerializerProvider() {
|
||||
return this.changeSerializerProvider;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected Provider<ServerRefactoringIssueAcceptor> getIssueProvider() {
|
||||
return this.issueProvider;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected IResourceServiceProvider.Registry getServiceProviderRegistry() {
|
||||
return this.serviceProviderRegistry;
|
||||
}
|
||||
|
||||
@Pure
|
||||
protected TokenUtil getTokenUtil() {
|
||||
return this.tokenUtil;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,10 +54,12 @@ import org.eclipse.lsp4j.SemanticHighlightingInformation
|
|||
import org.eclipse.lsp4j.SemanticHighlightingParams
|
||||
import org.eclipse.lsp4j.SignatureHelp
|
||||
import org.eclipse.lsp4j.SymbolInformation
|
||||
import org.eclipse.lsp4j.TextDocumentEdit
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier
|
||||
import org.eclipse.lsp4j.TextDocumentItem
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams
|
||||
import org.eclipse.lsp4j.TextEdit
|
||||
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier
|
||||
import org.eclipse.lsp4j.WorkspaceEdit
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams
|
||||
import org.eclipse.lsp4j.jsonrpc.Endpoint
|
||||
|
@ -419,6 +421,15 @@ abstract class AbstractLanguageServerTest implements Endpoint {
|
|||
edit : «edit.toExpectation»
|
||||
'''
|
||||
|
||||
protected def dispatch String toExpectation(TextDocumentEdit e) '''
|
||||
«e.textDocument.toExpectation» : «e.edits.toExpectation»
|
||||
'''
|
||||
|
||||
protected def dispatch String toExpectation(VersionedTextDocumentIdentifier v)
|
||||
'''«org.eclipse.emf.common.util.URI.createURI(v.uri).lastSegment» <«v.version»>'''
|
||||
|
||||
|
||||
|
||||
@Accessors static class TestCodeActionConfiguration extends TextDocumentPositionConfiguration {
|
||||
String expectedCodeActions = ''
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ import org.eclipse.lsp4j.SignatureHelp;
|
|||
import org.eclipse.lsp4j.SignatureInformation;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.TextDocumentClientCapabilities;
|
||||
import org.eclipse.lsp4j.TextDocumentEdit;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.TextDocumentItem;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
|
@ -936,6 +937,28 @@ public abstract class AbstractLanguageServerTest implements Endpoint {
|
|||
return _builder.toString();
|
||||
}
|
||||
|
||||
protected String _toExpectation(final TextDocumentEdit e) {
|
||||
StringConcatenation _builder = new StringConcatenation();
|
||||
String _expectation = this.toExpectation(e.getTextDocument());
|
||||
_builder.append(_expectation);
|
||||
_builder.append(" : ");
|
||||
String _expectation_1 = this.toExpectation(e.getEdits());
|
||||
_builder.append(_expectation_1);
|
||||
_builder.newLineIfNotEmpty();
|
||||
return _builder.toString();
|
||||
}
|
||||
|
||||
protected String _toExpectation(final VersionedTextDocumentIdentifier v) {
|
||||
StringConcatenation _builder = new StringConcatenation();
|
||||
String _lastSegment = org.eclipse.emf.common.util.URI.createURI(v.getUri()).lastSegment();
|
||||
_builder.append(_lastSegment);
|
||||
_builder.append(" <");
|
||||
Integer _version = v.getVersion();
|
||||
_builder.append(_version);
|
||||
_builder.append(">");
|
||||
return _builder.toString();
|
||||
}
|
||||
|
||||
protected void testCodeAction(final Procedure1<? super AbstractLanguageServerTest.TestCodeActionConfiguration> configurator) {
|
||||
try {
|
||||
@Extension
|
||||
|
@ -1459,6 +1482,8 @@ public abstract class AbstractLanguageServerTest implements Endpoint {
|
|||
return _toExpectation((DocumentHighlightKind)it);
|
||||
} else if (it instanceof String) {
|
||||
return _toExpectation((String)it);
|
||||
} else if (it instanceof VersionedTextDocumentIdentifier) {
|
||||
return _toExpectation((VersionedTextDocumentIdentifier)it);
|
||||
} else if (it instanceof Pair) {
|
||||
return _toExpectation((Pair<SemanticHighlightingInformation, List<List<String>>>)it);
|
||||
} else if (it == null) {
|
||||
|
@ -1491,6 +1516,8 @@ public abstract class AbstractLanguageServerTest implements Endpoint {
|
|||
return _toExpectation((SignatureHelp)it);
|
||||
} else if (it instanceof SymbolInformation) {
|
||||
return _toExpectation((SymbolInformation)it);
|
||||
} else if (it instanceof TextDocumentEdit) {
|
||||
return _toExpectation((TextDocumentEdit)it);
|
||||
} else if (it instanceof TextEdit) {
|
||||
return _toExpectation((TextEdit)it);
|
||||
} else if (it instanceof WorkspaceEdit) {
|
||||
|
|
Loading…
Reference in a new issue