You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2016/06/05 13:43:59 UTC

[jira] [Commented] (GROOVY-7854) Annotation value cannot be concatenated constant

    [ https://issues.apache.org/jira/browse/GROOVY-7854?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15315881#comment-15315881 ] 

Paul King commented on GROOVY-7854:
-----------------------------------

This is a known limitation. We could patch it - a sketch of the idea is below - shown just for Strings not numbers yet - in case anyone else wants to play before I get time again to look further. But this would be the first time we have done such inlining, so we'd need to think it through a little carefully.
{code}
+++ src/main/org/codehaus/groovy/classgen/AnnotationVisitor.java
@@ -76,9 +76,9 @@
         Map<String, Expression> attributes = node.getMembers();
         for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
             String attrName = entry.getKey();
-            Expression attrExpr = transformInlineConstants(entry.getValue());
-            entry.setValue(attrExpr);
             ClassNode attrType = getAttributeType(node, attrName);
+            Expression attrExpr = transformInlineConstants(entry.getValue(), attrType);
+            entry.setValue(attrExpr);
             visitExpression(attrName, attrExpr, attrType);
         }
         VMPluginFactory.getPlugin().configureAnnotation(node);
@@ -119,7 +119,7 @@
         return true;
     }
 
-    private Expression transformInlineConstants(Expression exp) {
+    private Expression transformInlineConstants(Expression exp, ClassNode attrType) {
         if (exp instanceof PropertyExpression) {
             PropertyExpression pe = (PropertyExpression) exp;
             if (pe.getObjectExpression() instanceof ClassExpression) {
@@ -133,15 +133,26 @@
                     if (field != null && Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) {
                         return new ConstantExpression(field.get(null));
                     }
                } catch (Exception e) {
                     // ignore, leave property expression in place and we'll report later
                 }
             }
+        } else if (exp instanceof BinaryExpression && (ClassHelper.STRING_TYPE.equals(attrType) || attrType
+                .isArray() && ClassHelper.STRING_TYPE.equals(attrType.getComponentType()))) {
+            BinaryExpression be = (BinaryExpression) exp;
+            if (be.getOperation().getText().equals("+")) {
+                Expression left = transformInlineConstants(be.getLeftExpression(), attrType);
+                Expression right = transformInlineConstants(be.getRightExpression(), attrType);
+                if (left instanceof ConstantExpression && right instanceof ConstantExpression) {
+                    return new ConstantExpression((String) ((ConstantExpression)left).getValue() +
+                            (String) ((ConstantExpression) right).getValue());
+                }
+            }
         } else if (exp instanceof ListExpression) {
             ListExpression le = (ListExpression) exp;
             ListExpression result = new ListExpression();
             for (Expression e : le.getExpressions()) {
-                result.addExpression(transformInlineConstants(e));
+                result.addExpression(transformInlineConstants(e, attrType));
             }
             return result;
         }
{code}

> Annotation value cannot be concatenated constant
> ------------------------------------------------
>
>                 Key: GROOVY-7854
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7854
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Static compilation
>    Affects Versions: 2.4.6
>         Environment: - OS X 
> - Java(TM) SE Runtime Environment (build 1.8.0_66-b17) 
> - IntelliJ Idea 14 CE \w Groovy plugin 
> - Gradle 2.2
>            Reporter: Simo Tuokko
>
> Following code as .java class works ok:
> {code:title=UserDAO.java|borderStyle=solid}
> public abstract class UserDAO {
>     public static final String Select_User_join_Addresses_Features_Images =
>         "select "+
>         "u.*, a.*, f.*, i.* "+
>         "from users u "+
>         "left outer join addresses a on (u.id = a.user_id) "+
>         "left outer join userfeatures f on (u.id = f.user_id) "+
>         "left outer join images i on (u.id = i.user_id) ";
>     public static final String Select_User_by_id =
>             Select_User_join_Addresses_Features_Images + "where u.id = :id";
>     public static final String Select_User_by_email =
>             Select_User_join_Addresses_Features_Images + "where u.email = lower(:email)";
>     @SqlQuery(Select_User_by_id)
>     abstract FoldingList<User> findById(@Bind("id") long id);
> }
> {code}
> However if I write and compile it as Groovy, I get "Expected 'UserDAO.Select_User_by_id' to be an inline constant of type java.lang.String not a property expression" error from compiler.
> Also if works if those constant String are in separate .java class that is accessed from annotation (within a .groovy class), but not if they are in separate .groovy file.
> So the difference seems to be that constant strings are not concatenated at compile-time in Groovy, but in Java they are? Is this by design or is it a bug that can be fixed?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)