Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Xbase: Fields in generated inner class not recognized, no problems as class in own file
Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777774] Mon, 04 December 2017 15:04 Go to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
Hi,

I'm struggeling with a strange problem currently.
In my Xbase based DSL I use Structures which are converted to Java Classes which contain attributes ( = fields).

So my DSL could look like this:
type Test : structure{
	attribute b : integer;
}
main{
	variable a : Test;
	a.b <-- 4;
}	


and the result should look something like this (you can ignore Serializable):
public class Model {
  public static class Test implements Serializable {
    public int b;
  }
  
  public static void main(final String[] Args) {
    Test a=  new Test();
    a.b = 4;
  }


If I build the class Test with the following as a class in a separate file it works perfectly fine.
The inferrer for this looks like this:
	def inferStructs(List<Composition> types, IJvmDeclaredTypeAcceptor acceptor){
			for(comp : types){
			if (comp instanceof Composition) {
					 acceptor.accept(comp.toClass(comp.name)) [
					 	superTypes += typeRef(Serializable)
						for (attribute : comp.attributes) {
							documentation = attribute.documentation
							val field = attribute.toField(attribute.name, getTypeRefFor(attribute.typing))
							field.visibility = JvmVisibility.PUBLIC
							members += field
						}
					]
				}
		}	
	}

getTypeRef() returns the correct type and creates the correct field.

If I use my method to create it inside the class as a static inner class I get an error.
This is the inferrer to create it as inner class:
	def inferStructsInClass(List<Composition> types, List<JvmMember> member){
		for(comp : types){
			if(comp instanceof Composition){
				member += comp.toClass(comp.name)[
					static = true
					superTypes += typeRef(Serializable)
					for(attribute : comp.attributes){
						val field = attribute.toField(attribute.name, getTypeRefFor(attribute.typing))
						field.visibility = JvmVisibility.PUBLIC
						members+=field
					}
				]
			}
		}
	}

The method where it gets called is the following:
	def dispatch void infer(Program element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { 

		val className = element.eResource.URI.trimFileExtension.lastSegment
		//inferStructs(element.types.filter(Composition).toList,acceptor)
		
		acceptor.accept(element.toClass(className)) [
			inferEnums(element.types.filter(Enumeration).toList, members)
			inferStructsInClass(element.types.filter(Composition).toList,members)	
			inferMethods((element.methods), members) /* Generate Mainblock */
			if (element.mainBlock !== null) {
		
				members += element.mainBlock.toMethod("main", typeRef(Void.TYPE)) [
					parameters += element.toParameter("Args", typeRef("java.lang.String").addArrayTypeDimension)
					static = true
					documentation = element.mainBlock.documentation
					body = element.mainBlock.body

				]
			}
		]
	}


The error I retrieve is the following:
java.lang.IllegalStateException: Cannot get name for JvmVoid:  (eProxyURI: platform:/resource/StructureTest/src/model/Model.athena#|1)
	at org.eclipse.xtext.xbase.compiler.output.SharedAppendableState.getName(SharedAppendableState.java:127)
	at org.eclipse.xtext.xbase.compiler.output.TreeAppendable.getName(TreeAppendable.java:461)
	at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.assignmentToJavaExpression(FeatureCallCompiler.java:889)
	at de.ubt.ai1.athena.xbase.compiler.AthenaCompiler.assignmentToJavaExpression(AthenaCompiler.java:245)
	at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.featureCalltoJavaExpression(FeatureCallCompiler.java:575)
	at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler._toJavaStatement(FeatureCallCompiler.java:162)
	at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.doInternalToJavaStatement(FeatureCallCompiler.java:111)
	at org.eclipse.xtext.xbase.compiler.XbaseCompiler.doInternalToJavaStatement(XbaseCompiler.java:385)
	at de.ubt.ai1.athena.xbase.compiler.AthenaCompiler.doInternalToJavaStatement(AthenaCompiler.java:263)
	at org.eclipse.xtext.xbase.compiler.AbstractXbaseCompiler.internalToJavaStatement(AbstractXbaseCompiler.java:473)
	at org.eclipse.xtext.xbase.compiler.XbaseCompiler._toJavaStatement(XbaseCompiler.java:410)
	at org.eclipse.xtext.xbase.compiler.XbaseCompiler.doInternalToJavaStatement(XbaseCompiler.java:349)
	at de.ubt.ai1.athena.xbase.compiler.AthenaCompiler.doInternalToJavaStatement(AthenaCompiler.java:263)
	at org.eclipse.xtext.xbase.compiler.AbstractXbaseCompiler.internalToJavaStatement(AbstractXbaseCompiler.java:473)
	at org.eclipse.xtext.xbase.compiler.AbstractXbaseCompiler.compile(AbstractXbaseCompiler.java:294)
	at org.eclipse.xtext.xbase.compiler.AbstractXbaseCompiler.compile(AbstractXbaseCompiler.java:274)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.compile(JvmModelGenerator.java:1057)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.generateExecutableBody(JvmModelGenerator.java:1034)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator._generateMember(JvmModelGenerator.java:798)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.generateMember(JvmModelGenerator.java:1660)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.lambda$generateMembersInBody$2(JvmModelGenerator.java:292)
	at org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow(ObjectExtensions.java:139)
	at org.eclipse.xtext.xbase.compiler.LoopExtensions.lambda$forEach$0(LoopExtensions.java:38)
	at java.lang.Iterable.forEach(Iterable.java:75)
	at org.eclipse.xtext.xbase.compiler.LoopExtensions.forEach(LoopExtensions.java:40)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.generateMembersInBody(JvmModelGenerator.java:295)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator._generateBody(JvmModelGenerator.java:269)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.generateBody(JvmModelGenerator.java:1632)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.generateType(JvmModelGenerator.java:226)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator._internalDoGenerate(JvmModelGenerator.java:213)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.internalDoGenerate(JvmModelGenerator.java:1615)
	at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.doGenerate(JvmModelGenerator.java:196)
	at org.eclipse.xtext.generator.GeneratorDelegate.doGenerate(GeneratorDelegate.java:45)
	at org.eclipse.xtext.generator.GeneratorDelegate.generate(GeneratorDelegate.java:34)
	at org.eclipse.xtext.builder.BuilderParticipant.handleChangedContents(BuilderParticipant.java:588)
	at org.eclipse.xtext.builder.BuilderParticipant.handleChangedContents(BuilderParticipant.java:573)
	at org.eclipse.xtext.builder.BuilderParticipant.doGenerate(BuilderParticipant.java:558)
	at org.eclipse.xtext.builder.BuilderParticipant.doBuild(BuilderParticipant.java:301)
	at org.eclipse.xtext.builder.BuilderParticipant.build(BuilderParticipant.java:259)
	at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant$DeferredBuilderParticipant.build(RegistryBuilderParticipant.java:161)
	at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant.build(RegistryBuilderParticipant.java:69)
	at org.eclipse.xtext.builder.impl.XtextBuilder.doBuild(XtextBuilder.java:291)
	at org.eclipse.xtext.builder.impl.XtextBuilder.incrementalBuild(XtextBuilder.java:267)
	at org.eclipse.xtext.builder.impl.XtextBuilder.build(XtextBuilder.java:161)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:735)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:301)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:304)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:360)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:383)
	at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:142)
	at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:232)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56)



I already checked my method (AthenaCompiler, de.ubt.ai1.athena.xbase.compiler.AthenaCompiler.assignmentToJavaExpression(AthenaCompiler.java:245)) and found out, that the Feature of the expression (expr.getFeature() where expr is an Assignemtn) for the working case is "JvmFieldImplCustom" (which seems correct) whereas it is "JvmVoid" for the not working class when the class is generated as a inner class.

Has anyone an idea why this doesn't work?
Thanks in advance!
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777776 is a reply to message #1777774] Mon, 04 December 2017 15:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
the name of the inner class is Outer$Test

or in import it explictedly

import xxx.Outer.Test


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777781 is a reply to message #1777776] Mon, 04 December 2017 15:51 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
Hi,
thanks for your input.
What do I need to change to take into account that the innername is not what I was expecting? Or how do I implement an explicit import of a dynamicly generated class?
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777782 is a reply to message #1777781] Mon, 04 December 2017 15:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
you implement a implicit import by adption XImportSection*ScopeProvider

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777783 is a reply to message #1777776] Mon, 04 December 2017 15:53 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
-- posted it twice by accident

[Updated on: Mon, 04 December 2017 16:00]

Report message to a moderator

Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777796 is a reply to message #1777783] Mon, 04 December 2017 16:48 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
Now I tried to implement it like in the example here: https://www.eclipse.org/forums/index.php/t/1079851/

My XImportSectionNamespaceScopeProvider looks like this now:
override protected internalGetImportedNamespaceResolvers(EObject context, boolean ignoreCase){
		val result = newArrayList
		result += super.internalGetImportedNamespaceResolvers(context, ignoreCase)
		
		if(context instanceof Program){
			var program = context as Program
			for(type : program.types){
				if(type instanceof Composition){
					println(type.name)
					result += this.createImportedNamespaceResolver("generated.Model."+type.name+".*", ignoreCase) // package: generated, Outer class: model , Inner class: Test e.g.; how could access the Outer Class Name (= file Name) here?
				}
				
			}
		}
	
		return result
	}


For some reason I never get a Composition as an EObject.
My grammar for this is the following:
Program:
	{Program}
	(types+=Type | methods+=Method | mainBlock=MainBlock)*
;
...
Type:
	(Enumeration | Composition);

DataType:
	(SimpleDataType | ComplexDataType | ListType);

ListType:
	=> ('list' '<' type=DataType) '>';

ComplexDataType:
	{ComplexDataType} typeName=[Type];

Composition:
	{Composition} 'type' name=ID ':' 'structure' '{' (attributes+=Attribute)* '}';

Attribute:
	{Attribute}
	'attribute' name=ID ':' typing=DataType ';';

Enumeration:
	{Enumeration} 'type' name=ID ':' 'enumeration' '{' values+=EnumTypeValue (',' values+=EnumTypeValue)* '}';

EnumTypeValue:
	name=ID;

SimpleDataType:
	{SimpleDataType} typeName=('integer' | 'string' | 'rational' | 'boolean');

	



Type is to create the Compositions while ComplexDataType is to access the Compositions.
Unfortunatly this part doesn't generate the import statement like I expected. The code runs but the statement isnt created. Probably I am doing something wrong, but I don't know what.
Thanks in Advance
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777797 is a reply to message #1777796] Mon, 04 December 2017 17:02 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Sorry you need to debug the code yourself

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777798 is a reply to message #1777797] Mon, 04 December 2017 17:15 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
I will try, thanks anyway!
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777799 is a reply to message #1777797] Mon, 04 December 2017 17:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
another question: are you already on xtext 2.13?
cannot reproduce with simple example


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777800 is a reply to message #1777799] Mon, 04 December 2017 17:17 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
I am currently on xtext 2.12, but I will update and try it with xtext 2.13.
If it helps, I can give you access to my bitbucket.
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777802 is a reply to message #1777800] Mon, 04 December 2017 17:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
please test with 213

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777804 is a reply to message #1777802] Mon, 04 December 2017 18:00 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
So I tested it in 2.13 but it unfortunatly didn't fix the problem.

I tried to change something in the compiler to create the assignment myself like this:
	/* Converts some parts of assignments to java */
	override assignmentToJavaExpression(XAssignment expr, ITreeAppendable b, boolean isExpressionContext) {
		var feature = expr.getFeature()
		// println("Feat:" + expr.getFeature())
	
		if(feature instanceof JvmVoid){
			var hacky_string = expr.toString
			println(hacky_string)
			hacky_string = "wert"
			b.append(expr.assignable.toString)
			b.append(".")
			b.append(hacky_string)
			b.append(" = ")
			internalToConvertedExpression(expr.value, b)
			return
		} ..


But this is obviusly very ugly and could be called at unwanted situations too, so thats not the best solution (and has to be written to be dynamic as well, but this should serve as an example..).

Any other places I could look at?
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777805 is a reply to message #1777804] Mon, 04 December 2017 18:10 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
i fear without having the code i cannot reproduce this

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777806 is a reply to message #1777805] Mon, 04 December 2017 18:12 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
If you've got the time, I can gan give you access to my repository. Just send me an pm (if there is a pm system here) with an mail address and I will give you access to it.
If not, that's no problem :). I will try and see if I can fix it myself.

[Updated on: Mon, 04 December 2017 18:15]

Report message to a moderator

Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777807 is a reply to message #1777806] Mon, 04 December 2017 18:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
no pm but you can guess <first>.<last> at itemis dot de

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777808 is a reply to message #1777807] Mon, 04 December 2017 18:26 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
You should hace access now.
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777811 is a reply to message #1777808] Mon, 04 December 2017 19:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
you somehow managed to swallow all typesystem/scoping errors

de.ubt.ai1.athena.xbase.typing.AthenaTypeComputer.addLocalToCurrentScope(XVariableDeclaration, ITypeComputationState)

does not deal with the inner class thing.
it searches class Test


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777812 is a reply to message #1777811] Mon, 04 December 2017 19:19 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
you e.g. dont traverse nested types in jdttypeprovider calls

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777813 is a reply to message #1777812] Mon, 04 December 2017 19:30 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
and you nameprovider does not inherit xbasequalifiednameprovider

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777814 is a reply to message #1777812] Mon, 04 December 2017 19:32 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
Quote:
de.ubt.ai1.athena.xbase.typing.AthenaTypeComputer.addLocalToCurrentScope(XVariableDeclaration, ITypeComputationState)

Isn't meant to be for the inner class, it is meant to be used for AdditionalVariableDeclarations.

Some errors are missing because I overrode them in the validator. They avoid some of the logic I want to use in my language. I know, my language isn't the best use case to use Xbase, but it was meant to be a university project to find out, if it's worth the effort to use xbase.

Quote:
you e.g. dont traverse nested types in jdttypeprovider calls

What exactly do you mean by this, where do I have to traverse them?
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777815 is a reply to message #1777814] Mon, 04 December 2017 19:43 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
the problem is that the type computer cannot find "Test" as type.
the rest is follow up problems.

and the name provider does not create names for xbase stuff due your customizations


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777816 is a reply to message #1777815] Mon, 04 December 2017 19:45 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
=> maybe after fixing name provider searching for generated.myclass$Test works

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777818 is a reply to message #1777815] Mon, 04 December 2017 20:02 Go to previous messageGo to next message
René Bärnreuther is currently offline René BärnreutherFriend
Messages: 31
Registered: October 2017
Member
Thanks for your input.
But I think, this is too much effort for the reward I get of it especially because it works just fine if it's the outer class and everything else works like its supposed to for my use case.
Thanks a lot for your time and help! I appreciate it.
Re: Xbase: Fields in generated inner class not recognized, no problems as class in own file [message #1777819 is a reply to message #1777818] Mon, 04 December 2017 20:09 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
i dont think content assit etc is all broken

should be a onliner in name provider eg.

class AthenaQualifiedNameProvider extends XbaseQualifiedNameProvider {

.....
public final static SimpleAttributeResolver<EObject, String> SIMPLENAME_RESOLVER = SimpleAttributeResolver.newResolver(String, "simpleName");

public override getFullyQualifiedName(EObject obj) {
if(obj instanceof Variable){
....
}
if (1==1) return super.getFullyQualifiedName(obj)
....
//return qualifiedNameConverter.toQualifiedName(name);
}

and similar in the computer

//TODO replace xxx with file name last segment
state.assignType(vr, getTypeForName("generated.xxx$"+comp.name, state))


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:case insensitive in xtext grammar
Next Topic:How to extend OpenGeneratedFileHandler to position the cursor in the right region
Goto Forum:
  


Current Time: Fri Apr 19 20:10:24 GMT 2024

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

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

Back to the top