Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Error on first generation regarding superType
Error on first generation regarding superType [message #1792763] Mon, 23 July 2018 15:43 Go to next message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
With the DSL I create a number of subclasses instead of a single class for each needed class. In the example I only created one subclass but in the real usecase for DSL there could be too many to create an own class for each one. (thats the reason why I attempt to create subclasses)

The error only appears on the first code generation. Instead of the expected
"class A extends B"
Xtext generates
"class A implements B"

After the second code generation it works as expected.

The issue appears with the "IdWithKeyElementInferrerExtension" (part of the inferrer).

With the following method I could fix the problem with the generated class(container for the subclasses) itself:
void IJvmDeclaredTypeAcceptor.accept(JvmGenericType type, Procedure1<? super JvmGenericType> lateInitialization)


acceptor.accept(
		element.toClass(element.name) [
			packageName = element.packageName
			[...]
		],
		[superTypes += BaseClass.typeRef
		])


But I have no clue how or if it is possible to set the inheritance reference for the subclasses in the "lateInitialization".

Example project is in the attachments.
Re: Error on first generation regarding superType [message #1792767 is a reply to message #1792763] Mon, 23 July 2018 16:13 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
hi

please please provide minimal samples if you ask for help.

your inferrer pattern looks wired.

the default pattern is

acceptor.accecpt(element.toClass()) [
// late init
]
you can reference the outer class like this

 val outer = it
				if (!element.valueClasses.isEmpty) {
					for (vClass : element.valueClasses) {
						val className = vClass.name.toCamelCase
						members += element.toClass(className) [
							static = true
							//TODO 
							superTypes += outer.typeRef


or you dont use that wired wired pattern for names

acceptor.accept(
element.toClass(element.packageName + "." +element.name)) [
....

superTypes += (element.packageName + "." +element.name) .typeRef


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error on first generation regarding superType [message #1792800 is a reply to message #1792767] Tue, 24 July 2018 09:23 Go to previous messageGo to next message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
I included the projects rather than parts of the code since I had no clue which part could case this behaviour.
After I changed the inferrer back to the default pattern and used the "outer" reference the "extends" is created correctly.

I use the weird name pattern "(element.packageName + "." +element.name) .typeRef" only within the acceptor for the visitor class for the parameter within the "toMethod".
If I simply use the name of the "valueClass" alone the reference doesn't get resolved.

		acceptor.accept(element.toClass(visitor)) [
			packageName = element.packageName
			interface = true
			for (vClass : element.valueClasses) {
				val vName = vClass.name.toCamelCase
				members += element.toMethod("visit" + vName, typeRef("void")) [
					abstract = true
					parameters += toParameter(
						vClass,
						"value",
						vName.typeRef
					)
				]
			}
		]

This leads to the generated code:
public abstract void visitSubClassOne(final SubClassOne value);

With the error that SubClassOne couldn't be resolved. (most likely because it is a subclass of the "parent" class)

If I use the weird name pattern:
		acceptor.accept(element.toClass(visitor)) [
			packageName = element.packageName
			interface = true
			for (vClass : element.valueClasses) {
				val vName = vClass.name.toCamelCase
				members += element.toMethod("visit" + vName, typeRef("void")) [
					abstract = true
					parameters += toParameter(
						vClass,
						"value",
						(element.fullyQualifiedName.toString + "." + vName).typeRef
					)
				]
			}
		]


This method gets generated:
public abstract void visitSubClassOne(final ParentClass.SubClassOne value);


Not ideal but since it is in the same package at least it worked.

The implicit question is: What would be the correct way to reference a subclass?

[Updated on: Tue, 24 July 2018 09:25]

Report message to a moderator

Re: Error on first generation regarding superType [message #1792824 is a reply to message #1792800] Tue, 24 July 2018 13:41 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
so i said: use "(element.packageName + "." +element.name) .typeRef" everywhere

for the inner class please try path.to.Outer$Inner


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error on first generation regarding superType [message #1792830 is a reply to message #1792767] Tue, 24 July 2018 14:13 Go to previous messageGo to next message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
Christian Dietrich wrote on Mon, 23 July 2018 16:13


[...]
or you dont use that wired wired pattern for names

acceptor.accept(
element.toClass(element.packageName + "." +element.name)) [
....

superTypes += (element.packageName + "." +element.name) .typeRef


Ok, sry! Missunderstood your response. Thought I should NOT use it.

The obvious answer for the subclass is almost embarrassing :D
(element.packageName + "." +element.name + "." + {classNameHere}).typeRef

Sometimes you are so fixed in your perspective that you don't see the simple solution. :(

Thank you very much!
Re: Error on first generation regarding superType [message #1793970 is a reply to message #1792824] Tue, 21 August 2018 11:53 Go to previous messageGo to next message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
Christian Dietrich wrote on Tue, 24 July 2018 13:41
so i said: use "(element.packageName + "." +element.name) .typeRef" everywhere

for the inner class please try path.to.Outer$Inner


I got a follow up question regarding the syntax of the inner classes reference.

At the moment I'm trying to extend from inner classes.
The goal is to create stubs once for further non-generated custom code. (Generation Gap)

As a little overview:
interface I
	
abstract class A implements I {
	abstract class B extends A
	abstract class C extends A
}

class BImpl extends B {
}


Within the inferrer I use this part to generate the "Impl" classes and set the supertype:
for(vClass: element.valueClasses) {
	acceptor.accept(element.toClass(vClass.name +"Impl")) [
		packageName = element.packageName
					
		superTypes += (element.packageName + "." + element.name + "." + vClass.name).typeRef
		members += element.toField("test", String.typeRef)
	]
}

This is the reduced example I used to try to fix the extends "issues". (If you are wondering why there is no OutputConfigurationAdapter for the "generate once" part)

If I edit the generated file and change the implements back to extends all seems fine and it can be resolved. Therefore I guess XText cannot find or know the inner class during the generation?

The pattern "(element.packageName + "." + element.name + "." + vClass.name).typeRef" works in the method context:
for (vClass : element.valueClasses) {
	val vName = vClass.name.toCamelCase
	members += element.toMethod("visit" + vName, void.typeRef) [
		abstract = true
		parameters += vClass.toParameter("value", (element.packageName + "." + element.name+ "." + vName).typeRef)
	]
}


I hope I provided enough context without an updated example project.
Re: Error on first generation regarding superType [message #1793971 is a reply to message #1793970] Tue, 21 August 2018 11:59 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
no please provide a hello world grammar and inferrer showing the problem

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error on first generation regarding superType [message #1793973 is a reply to message #1793971] Tue, 21 August 2018 12:07 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member

Model:
	"model" name=ID;


	def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
		acceptor.accept(element.toClass("dummy.Outer")) [
			members+=element.toClass("Inner1") [
				static = true
			]
			members+=element.toClass("Inner2") [
				static = true
			]
		]
		acceptor.accept(element.toClass("dummy.Outer2")) [
			superTypes+="dummy.Outer$Inner1".typeRef
		]
	}


works fine for me


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error on first generation regarding superType [message #1793974 is a reply to message #1793971] Tue, 21 August 2018 12:26 Go to previous messageGo to next message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
Well. Nevermind. The one thing I didn't try was taking your "suggestion"/answer literally!

"path.to.Outer$Inner " was the solution.
Instead of "(element.packageName + "." + element.name + "." + vClass.name).typeRef" I tried this during building the example
"(element.packageName + "." + element.name + "$" + vClass.name).typeRef" and it works.

Edit: And again, you are faster as usual ;)

[Updated on: Tue, 21 August 2018 12:48]

Report message to a moderator

Re: Error on first generation regarding superType [message #1794286 is a reply to message #1793974] Tue, 28 August 2018 13:03 Go to previous messageGo to next message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
This is a simplified version of my Xtext project with the same extends/implements "error".

I have no clue how to fix it. Like I stated above, I had a working solution but for some reason that I can't figure out the generation now fails.

For the context how I "test" the generation:
* Delete the generated package by hand
* Add a single character/comment or whitespace to the dsl and save it.
Re: Error on first generation regarding superType [message #1794299 is a reply to message #1794286] Tue, 28 August 2018 15:22 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
again. already have you the answer before

bad:

acceptor.accept(element.toClass(element.name + implExtention)) [
packageName=package


good:

acceptor.accept(element.toClass(package + "." + element.name + implExtention)) [


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error on first generation regarding superType [message #1794398 is a reply to message #1794299] Thu, 30 August 2018 09:46 Go to previous message
Karsten Wilken is currently offline Karsten WilkenFriend
Messages: 59
Registered: August 2016
Member
Thank you very much! In the small example this looks stupid.. but it was the last toClass where I didn't change it and just c&p it to the example.
Previous Topic:Add Xtext nature during import of projects containing DSLs
Next Topic:Library issue with New Project Wizard in 2.14
Goto Forum:
  


Current Time: Thu Mar 28 17:25:03 GMT 2024

Powered by FUDForum. Page generated in 0.04207 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top