[ https://issues.apache.org/jira/browse/GROOVY-7854?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15315881#comment-15315881 ]
Paul King edited comment on GROOVY-7854 at 6/5/16 1:49 PM: ----------------------------------------------------------- This is a known limitation. We could remove this limitation - 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} was (Author: paulk): 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)