Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » TypeReference for nested annotations class
TypeReference for nested annotations class [message #1765494] Sun, 11 June 2017 03:54 Go to next message
Amit Yadav is currently offline Amit YadavFriend
Messages: 28
Registered: June 2017
Junior Member
Hello,

I am trying to use a library in by JvmModelInferrer. The library say has a class like this

package com.example;

class Blah {
...
..
public @interface Chat { }
}

This package resides in a example.jar file. I have confirmed that this jar exist on the class path.

I am trying to build a annotation type reference for 'chat' using
_annotationTypesBuilder.annotationRef(Blah.Chat.class);
and
_annotationTypesBuilder.annotationRef("com.example.Blah$Chat");

However, I am getting this error

java.lang.IllegalArgumentException: The type com.example.Blah.Chat is not on the classpath.
at org.eclipse.xtext.xbase.jvmmodel.JvmAnnotationReferenceBuilder.annotationRef(JvmAnnotationReferenceBuilder.java:83)

and

java.lang.IllegalArgumentException: The type com.example.Blah$Chat is not on the classpath.
at org.eclipse.xtext.xbase.jvmmodel.JvmAnnotationReferenceBuilder.annotationRef(JvmAnnotationReferenceBuilder.java:83)

I did some digging and it seems that the type is converted to com/example/Blah/Chat.class and the the classLoader is called to find this class. However since Chat is nested annotation definition, there is no such class. As expected com/example/Blah.class exists.

Is there a solution for this problem?

Thanks,

Amit
Re: TypeReference for nested annotations class [message #1765497 is a reply to message #1765494] Sun, 11 June 2017 07:06 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
the following works for me

def dispatch infer(Entity entity, extension IJvmDeclaredTypeAcceptor acceptor, boolean prelinkingPhase) {
accept(entity.toClass( entity.fullyQualifiedName )) [

annotations += annotationRef("org.eclipse.xtext.example.domainmodel.lib.Blah$Chat")


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: TypeReference for nested annotations class [message #1778676 is a reply to message #1765497] Tue, 19 December 2017 18:32 Go to previous messageGo to next message
Martin Trummer is currently offline Martin TrummerFriend
Messages: 17
Registered: December 2017
Junior Member
Great that I found this post, I also wasted some hours, because I have expected that this works:
annotationRef(Blah.Chat.class);


Is there a way to get around hardcoding the qualified class name as string?
annotations += annotationRef("org.eclipse.xtext.example.domainmodel.lib.Blah$Chat")

e.g. maybe some library function?
Re: TypeReference for nested annotations class [message #1778886 is a reply to message #1778676] Fri, 22 December 2017 21:00 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
I assume you can ask the class for a canonical name or some other name

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: TypeReference for nested annotations class [message #1778985 is a reply to message #1778886] Wed, 27 December 2017 15:44 Go to previous messageGo to next message
Martin Trummer is currently offline Martin TrummerFriend
Messages: 17
Registered: December 2017
Junior Member
I think it's a bug, that this function
JvmAnnotationReferenceBuilder.annotationRef(Class<?> annotationType, String... values)
does not handle nested classes correctly.

Since I found no function that correctly uses the $ sign for nested classes, I've created a hacky util function that works for now - it simply replaces a dot that is followed by an upper-case letter with a $ sign (except for the first occurance).

	/**
	 * Returns the canonical class name and uses '$' for nested classes if required.
	 * This class assumes the java-naming guidelines (classes must begin
	 * with an upper-case letter)
	 */
	static def String canonicalClassNameNestingAware(Class<?> clazz) {
		// e.g. "org.immutables.value.Value.Immutable"
		val st = new StringTokenizer(clazz.canonicalName, '.')
		var result = new StringBuilder
		var tokenStartedWithUpperCase = false
		while (st.hasMoreTokens) {
			val nextToken = st.nextToken
			if (tokenStartedWithUpperCase) {
				result.append('$')
			} else {
				tokenStartedWithUpperCase = Character.isUpperCase(nextToken.charAt(0))
				if (result.length != 0) {
					result.append('.')	
				}
			}
			result.append(nextToken)
		}
		return result.toString
	}


example usage:
        import org.immutables.value.Value

	@Test
	def void testNestedClassName() {
		 val canonicalName = ClassNameUtil.canonicalClassNameNestingAware(Value.Immutable)
		 assertEquals("org.immutables.value.Value$Immutable", canonicalName)		
	}	

Re: TypeReference for nested annotations class [message #1779007 is a reply to message #1778985] Thu, 28 December 2017 09:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
tokenStartedWithUpperCase is a very "optimitic" assumption unfortunately.
can you please file a bug at https://github.com/eclipse/xtext-extras/


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: TypeReference for nested annotations class [message #1779034 is a reply to message #1779007] Fri, 29 December 2017 13:42 Go to previous message
Martin Trummer is currently offline Martin TrummerFriend
Messages: 17
Registered: December 2017
Junior Member
created issue 217
Previous Topic:Xtext strange parsing error
Next Topic:Quickfix NullPointerException in PartialSerializer
Goto Forum:
  


Current Time: Thu Apr 25 00:08:21 GMT 2024

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

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

Back to the top