Example for Semantic Refactoring [message #1796284] |
Tue, 09 October 2018 10:34  |
Eclipse User |
|
|
|
Hello Everyone,
Since Xtext 2.13 there is the new interface for semantic editing that is described in this blog post: https://typefox.io/xtext-2-13-0-released-semantic-editing-made-easy
In my project I have to do some renaming so i wanted to give it a try. Are there any demo Project where I can see how to use the mechanism?
I want to create an API that can be called headlessly (without eclipse). It should for instance be able to find specific elements with specific names and rename them and all the cross references to that element in other files too.
Without an example I am completely lost.
It would be awesome if somebody could point me to a working example or could elaborate the steps necessary in order to achieve my goal.
All the best,
Lukas
|
|
|
|
Re: Example for Semantic Refactoring [message #1796288 is a reply to message #1796286] |
Tue, 09 October 2018 11:54   |
Eclipse User |
|
|
|
Thank you for your fast reply.
I know that I can rename elements using alt + shift + r in the editor and I guess that somehow the Methods in the classes you pointed me to are called.
But I would like to develop an api that I will call headlessly.
i tryed to develop a minimal working example:
Consider this Grammar
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model:
person+=Person*
groups+= Group*;
Person:
Student | Teacher
;
Group:
StudentGroup | TeacherGroup
;
Student:
'student' name=ID
;
Teacher:
'teacher' name=ID
;
StudentGroup:
'students' name=ID '{' members+=[Student|ID] (',' members+=[Student|ID])* '}'
;
TeacherGroup:
'teachers' name=ID '{' members+=[Teacher|ID] (',' members+=[Teacher|ID])* '}'
;
And these .mydsl files:
a.mydsl
student Paule
student /*here is a comment*/ Asterix
teacher Asterix
students allStudents {
Paule,
Asterix,
Miracolix
}
teachers allTeachers {
Asterix
}
b.mydsl
Now I want to have a java function that takes a number of resources and performs renaming of students
so calling renameStudents('a.mydsl', 'b.mydsl', 'Asterix', 'Obelix')
The function should modify the given resources and the files should look like this
a_new.mydsl
student Paule
student /*here is a comment*/ Obelix
teacher Asterix
students allStudents {
Paule,
Obelix,
Miracolix
}
teachers allTeachers {
Asterix
}
b.mydsl
Also i could imagine more semantic adjustments that are a little more complex than renaming.
[Updated on: Tue, 09 October 2018 11:57] by Moderator
|
|
|
|
|
|
Re: Example for Semantic Refactoring [message #1796362 is a reply to message #1796357] |
Thu, 11 October 2018 11:37   |
Eclipse User |
|
|
|
here is a very pure and incomplete example
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID ('from' from=[Greeting]) ? '!';
package org.xtext.example.mydsl3.tests
import com.google.inject.Inject
import com.google.inject.Provider
import java.io.ByteArrayOutputStream
import org.apache.log4j.Logger
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.xtext.ide.refactoring.IRenameStrategy2
import org.eclipse.xtext.ide.refactoring.RefactoringIssueAcceptor
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.serializer.IEmfResourceChange
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.extensions.InjectionExtension
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.util.ITextRegion
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.^extension.ExtendWith
import org.xtext.example.mydsl3.myDsl.Model
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.resource.IResourceServiceProvider
import org.eclipse.xtext.ide.serializer.ITextDocumentChange
@ExtendWith(InjectionExtension)
@InjectWith(MyDslInjectorProvider)
class MyDslParsingTest {
@Inject
ParseHelper<Model> parseHelper
@Inject
Provider<IChangeSerializer> changeSerializerProvider
@Inject
IRenameStrategy2 renameStrategy
@Inject
IResourceServiceProvider.Registry registry
@Test
def void loadModel() {
var model = '''
Hello Xtext!
Hello World from Xtext!
'''
val result = parseHelper.parse(model)
Assertions.assertNotNull(result)
val errors = result.eResource.errors
val resourceSet = result.eResource.resourceSet
Assertions.assertTrue(errors.isEmpty, '''Unexpected errors: ?errors.join(", ")?''')
val g0 = result.greetings.head
val RefactoringIssueAcceptor issueAcceptor = new RefactoringIssueAcceptor() {
override add(Severity severity, String message, URI resourceUri) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
override add(Severity severity, String message, EObject element) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
override add(Severity severity, String message, Object... params) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
override add(Severity severity, String message, URI uri, ResourceSet resourceSet) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
override add(Severity severity, String message, EObject element, ITextRegion region) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
override add(Severity severity, String message, Exception exc, Logger log) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
}
val change = new RenameChange(g0.name + "2", EcoreUtil.getURI(g0))
val changeSerializer = changeSerializerProvider.get
val context = new RenameContext(#[change], resourceSet, changeSerializer, issueAcceptor)
renameStrategy.applyRename(context)
val model2 = new StringBuilder(model)
changeSerializer.applyModifications [
e| println(e.class)
if (e instanceof ITextDocumentChange) {
for (r : e.replacements.sortBy[r|r.endOffset].reverse) {
model2.replace(r.offset, r.offset+r.length, r.replacementText);
}
} else {
//TODO handle this case. see org.eclipse.xtext.ide.server.rename.ChangeConverter._handleReplacements(IEmfResourceChange)
}
]
println(model2)
}
}
|
|
|
|
|
|
Re: Example for Semantic Refactoring [message #1796506 is a reply to message #1796495] |
Mon, 15 October 2018 09:25  |
Eclipse User |
|
|
|
for my prototype i did no care about messing up dependencies. ....
sorry i thought you were either able to add all needed to runtimemodule/mydsl module
or create a new injector provider class that uses MyDslIdeModule too and use that class in the test.
[Updated on: Mon, 15 October 2018 09:26] by Moderator
|
|
|
Powered by
FUDForum. Page generated in 0.05834 seconds