From 06efa58762d243a6ebcc09aea57b81b338e628a4 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Wed, 20 Jan 2021 19:40:23 +0100 Subject: [fixes #1538] Use Enter and MemberEnter to update type mirrors --- .../lombok/javac/handlers/HandleConstructor.java | 24 +--- src/core/lombok/javac/handlers/HandleGetter.java | 3 +- src/core/lombok/javac/handlers/HandleSetter.java | 14 +- .../lombok/javac/handlers/HandleSuperBuilder.java | 2 +- .../lombok/javac/handlers/HandleUtilityClass.java | 5 +- src/core/lombok/javac/handlers/HandleWith.java | 7 +- src/core/lombok/javac/handlers/HandleWithBy.java | 7 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 141 +++++++++------------ 8 files changed, 70 insertions(+), 133 deletions(-) (limited to 'src/core/lombok/javac') diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 490fd151..b582490b 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -28,8 +28,6 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Symbol.ClassSymbol; -import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBlock; @@ -57,7 +55,6 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.configuration.CheckerFrameworkVersion; import lombok.delombok.LombokOptionsFactory; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; @@ -249,30 +246,17 @@ public class HandleConstructor { if (noArgs && noArgsConstructorExists(typeNode)) return; - ListBuffer argTypes = new ListBuffer(); - for (JavacNode fieldNode : fields) { - Type mirror = getMirrorForFieldType(fieldNode); - if (mirror == null) { - argTypes = null; - break; - } - argTypes.append(mirror); - } - List argTypes_ = argTypes == null ? null : argTypes.toList(); - if (!(skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS)) { JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source); - injectMethod(typeNode, constr, argTypes_, Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID)); + injectMethod(typeNode, constr); } - generateStaticConstructor(staticConstrRequired, typeNode, staticName, level, allToDefault, fields, source, argTypes_); + generateStaticConstructor(staticConstrRequired, typeNode, staticName, level, allToDefault, fields, source); } - private void generateStaticConstructor(boolean staticConstrRequired, JavacNode typeNode, String staticName, AccessLevel level, boolean allToDefault, List fields, JavacNode source, List argTypes_) { + private void generateStaticConstructor(boolean staticConstrRequired, JavacNode typeNode, String staticName, AccessLevel level, boolean allToDefault, List fields, JavacNode source) { if (staticConstrRequired) { - ClassSymbol sym = ((JCClassDecl) typeNode.get()).sym; - Type returnType = sym == null ? null : sym.type; JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, allToDefault ? List.nil() : fields, source); - injectMethod(typeNode, staticConstr, argTypes_, returnType); + injectMethod(typeNode, staticConstr); } } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 200ce1d7..4b2d01e1 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -47,7 +47,6 @@ import lombok.javac.JavacTreeMaker.TypeTag; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBinary; @@ -219,7 +218,7 @@ public class HandleGetter extends JavacAnnotationHandler { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), source, lazy, onMethod), List.nil(), getMirrorForFieldType(fieldNode)); + injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), source, lazy, onMethod)); } public JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, boolean lazy, List onMethod) { diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index e6e8e66e..9943bcc8 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -41,8 +41,6 @@ import lombok.javac.JavacTreeMaker; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Symbol.ClassSymbol; -import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBlock; @@ -188,17 +186,7 @@ public class HandleSetter extends JavacAnnotationHandler { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); JCMethodDecl createdSetter = createSetter(access, fieldNode, fieldNode.getTreeMaker(), sourceNode, onMethod, onParam); - Type fieldType = getMirrorForFieldType(fieldNode); - Type returnType; - - if (shouldReturnThis(fieldNode)) { - ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym; - returnType = sym == null ? null : sym.type; - } else { - returnType = Javac.createVoidType(fieldNode.getSymbolTable(), CTC_VOID); - } - - injectMethod(fieldNode.up(), createdSetter, fieldType == null ? null : List.of(fieldType), returnType); + injectMethod(fieldNode.up(), createdSetter); } public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, JavacNode source, List onMethod, List onParam) { diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index a462fa53..d9e55a56 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -585,7 +585,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { null, List.nil(), params.toList(), List.nil(), maker.Block(0L, statements.toList()), null), job.sourceNode); - injectMethod(job.parentType, constr, null, Javac.createVoidType(job.builderType.getSymbolTable(), CTC_VOID)); + injectMethod(job.parentType, constr); } private JCMethodDecl generateBuilderMethod(SuperBuilderJob job) { diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java index b400098b..cd05c285 100644 --- a/src/core/lombok/javac/handlers/HandleUtilityClass.java +++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java @@ -22,13 +22,11 @@ package lombok.javac.handlers; import static lombok.core.handlers.HandlerUtil.handleExperimentalFlagUsage; -import static lombok.javac.Javac.CTC_VOID; import static lombok.javac.handlers.JavacHandlerUtil.*; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Type; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; @@ -46,7 +44,6 @@ import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; import lombok.experimental.UtilityClass; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; @@ -147,7 +144,7 @@ public class HandleUtilityClass extends JavacAnnotationHandler { JCBlock block = maker.Block(0L, createThrowStatement(typeNode, maker)); JCMethodDecl methodDef = maker.MethodDef(mods, name, null, List.nil(), List.nil(), List.nil(), block, null); JCMethodDecl constructor = recursiveSetGeneratedBy(methodDef, typeNode); - JavacHandlerUtil.injectMethod(typeNode, constructor, List.nil(), Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID)); + JavacHandlerUtil.injectMethod(typeNode, constructor); } private List createThrowStatement(JavacNode typeNode, JavacTreeMaker maker) { diff --git a/src/core/lombok/javac/handlers/HandleWith.java b/src/core/lombok/javac/handlers/HandleWith.java index 387f3ecd..249df096 100644 --- a/src/core/lombok/javac/handlers/HandleWith.java +++ b/src/core/lombok/javac/handlers/HandleWith.java @@ -41,8 +41,6 @@ import lombok.javac.handlers.JavacHandlerUtil.CopyJavadoc; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; @@ -212,11 +210,8 @@ public class HandleWith extends JavacAnnotationHandler { JCMethodDecl createdWith = createWith(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, onParam, makeAbstract); createRelevantNonNullAnnotation(fieldNode, createdWith); - ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym; - Type returnType = sym == null ? null : sym.type; - recursiveSetGeneratedBy(createdWith, source); - injectMethod(typeNode, createdWith, List.of(getMirrorForFieldType(fieldNode)), returnType); + injectMethod(typeNode, createdWith); } public JCMethodDecl createWith(long access, JavacNode field, JavacTreeMaker maker, JavacNode source, List onMethod, List onParam, boolean makeAbstract) { diff --git a/src/core/lombok/javac/handlers/HandleWithBy.java b/src/core/lombok/javac/handlers/HandleWithBy.java index dfbb6830..ed0ed863 100644 --- a/src/core/lombok/javac/handlers/HandleWithBy.java +++ b/src/core/lombok/javac/handlers/HandleWithBy.java @@ -46,8 +46,6 @@ import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; @@ -206,11 +204,8 @@ public class HandleWithBy extends JavacAnnotationHandler { long access = toJavacModifier(level); JCMethodDecl createdWithBy = createWithBy(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, makeAbstract); - ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym; - Type returnType = sym == null ? null : sym.type; - recursiveSetGeneratedBy(createdWithBy, source); - injectMethod(typeNode, createdWithBy, List.of(getMirrorForFieldType(fieldNode)), returnType); + injectMethod(typeNode, createdWithBy); } private static final LombokImmutableList NAME_JUF_FUNCTION = LombokImmutableList.of("java", "util", "function", "Function"); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 5cbe08da..98c037b7 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -37,19 +37,18 @@ import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; -import javax.lang.model.element.Element; - -import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; -import com.sun.tools.javac.code.Symbol.MethodSymbol; -import com.sun.tools.javac.code.Symbol.VarSymbol; -import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.Type.MethodType; +import com.sun.tools.javac.comp.Annotate; +import com.sun.tools.javac.comp.AttrContext; +import com.sun.tools.javac.comp.Enter; +import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.comp.MemberEnter; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; @@ -1012,12 +1011,6 @@ public class JavacHandlerUtil { return call; } - public static Type getMirrorForFieldType(JavacNode fieldNode) { - Element fieldElement = fieldNode.getElement(); - if (fieldElement instanceof VarSymbol) return ((VarSymbol) fieldElement).type; - return null; - } - /** * Adds the given new field declaration to the provided type AST Node. * The field carries the @{@link SuppressWarnings}("all") annotation. @@ -1073,6 +1066,8 @@ public class JavacHandlerUtil { insertAfter.tail = fieldEntry; } + EnterReflect.memberEnter(field, typeNode); + return typeNode.add(field, Kind.FIELD); } @@ -1148,24 +1143,6 @@ public class JavacHandlerUtil { } } } - - static class JCAnnotationReflect { - private static Field ATTRIBUTE; - - static { - try { - ATTRIBUTE = Permit.getField(JCAnnotation.class, "attribute"); - } catch (Exception ignore) {} - } - - static Attribute.Compound getAttribute(JCAnnotation jcAnnotation) { - try { - return (Attribute.Compound) ATTRIBUTE.get(jcAnnotation); - } catch (Exception e) { - return null; - } - } - } // jdk9 support, types have changed, names stay the same static class ClassSymbolMembersField { @@ -1206,8 +1183,10 @@ public class JavacHandlerUtil { } } - public static void injectMethod(JavacNode typeNode, JCMethodDecl method) { - injectMethod(typeNode, method, null, null); + + @Deprecated + public static void injectMethod(JavacNode typeNode, JCMethodDecl method, List paramTypes, Type returnType) { + injectMethod(typeNode, method); } /** @@ -1216,9 +1195,7 @@ public class JavacHandlerUtil { * * Also takes care of updating the JavacAST. */ - public static void injectMethod(JavacNode typeNode, JCMethodDecl method, List paramTypes, Type returnType) { - Context context = typeNode.getContext(); - Symtab symtab = Symtab.instance(context); + public static void injectMethod(JavacNode typeNode, JCMethodDecl method) { JCClassDecl type = (JCClassDecl) typeNode.get(); if (method.getName().contentEquals("")) { @@ -1242,55 +1219,11 @@ public class JavacHandlerUtil { addGenerated(method.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(method)), typeNode.getContext()); type.defs = type.defs.append(method); - List params = null; - if (method.getParameters() != null && !method.getParameters().isEmpty()) { - ListBuffer newParams = new ListBuffer(); - for (int i = 0; i < method.getParameters().size(); i++) { - JCTree.JCVariableDecl param = method.getParameters().get(i); - if (param.sym == null) { - Type paramType = paramTypes == null ? param.getType().type : paramTypes.get(i); - VarSymbol varSymbol = new VarSymbol(param.mods.flags, param.name, paramType, symtab.noSymbol); - varSymbol.adr = 1 << i; - List annotations = param.getModifiers().getAnnotations(); - if (annotations != null && !annotations.isEmpty()) { - ListBuffer newAnnotations = new ListBuffer(); - for (JCAnnotation jcAnnotation : annotations) { - Attribute.Compound attribute = JCAnnotationReflect.getAttribute(jcAnnotation); - if (attribute != null) { - newAnnotations.append(attribute); - } - } - if (annotations.length() == newAnnotations.length()) { - varSymbol.appendAttributes(newAnnotations.toList()); - } - } - newParams.append(varSymbol); - } else { - newParams.append(param.sym); - } - } - params = newParams.toList(); - if (params.length() != method.getParameters().length()) params = null; - } - - fixMethodMirror(typeNode.getContext(), typeNode.getElement(), method.getModifiers().flags, method.getName(), paramTypes, params, returnType); + EnterReflect.memberEnter(method, typeNode); typeNode.add(method, Kind.METHOD); } - private static void fixMethodMirror(Context context, Element typeMirror, long access, Name methodName, List paramTypes, List params, Type returnType) { - if (typeMirror == null || paramTypes == null || returnType == null) return; - ClassSymbol cs = (ClassSymbol) typeMirror; - MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.nil(), Symtab.instance(context).methodClass), cs); - if (params != null && !params.isEmpty()) { - methodSymbol.params = params; - for (VarSymbol varSymbol : params) { - varSymbol.owner = methodSymbol; - } - } - ClassSymbolMembersField.enter(cs, methodSymbol); - } - /** * Adds an inner type (class, interface, enum) to the given type. Cannot inject top-level types. * @@ -1303,9 +1236,55 @@ public class JavacHandlerUtil { addSuppressWarningsAll(type.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(type)), typeNode.getContext()); addGenerated(type.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(type)), typeNode.getContext()); typeDecl.defs = typeDecl.defs.append(type); + + EnterReflect.classEnter(type, typeNode); + return typeNode.add(type, Kind.TYPE); } + static class EnterReflect { + private static final Method classEnter; + private static final Method memberEnter; + private static final Method blockAnnotations; + private static final Method unblockAnnotations; + + static { + classEnter = Permit.permissiveGetMethod(Enter.class, "classEnter", JCTree.class, Env.class); + memberEnter = Permit.permissiveGetMethod(MemberEnter.class, "memberEnter", JCTree.class, Env.class); + + Method block = Permit.permissiveGetMethod(Annotate.class, "blockAnnotations"); + if (block == null) block = Permit.permissiveGetMethod(Annotate.class, "enterStart"); + blockAnnotations = block; + + Method unblock = Permit.permissiveGetMethod(Annotate.class, "unblockAnnotations"); + if (unblock == null) unblock = Permit.permissiveGetMethod(Annotate.class, "enterDone"); + unblockAnnotations = unblock; + } + + static Type classEnter(JCTree tree, JavacNode parent) { + Enter enter = Enter.instance(parent.getContext()); + Env classEnv = enter.getEnv((TypeSymbol) parent.getElement()); + Type type = (Type) Permit.invokeSneaky(classEnter, enter, tree, classEnv); + if (type == null) return null; + type.complete(); + return type; + } + + static void memberEnter(JCTree tree, JavacNode parent) { + Context context = parent.getContext(); + MemberEnter me = MemberEnter.instance(context); + Annotate annotate = Annotate.instance(context); + Enter enter = Enter.instance(context); + + Env classEnv = enter.getEnv((TypeSymbol) parent.getElement()); + if (classEnv == null) return; + + Permit.invokeSneaky(blockAnnotations, annotate); + Permit.invokeSneaky(memberEnter, me, tree, classEnv); + Permit.invokeSneaky(unblockAnnotations, annotate); + } + } + public static long addFinalIfNeeded(long flags, Context context) { boolean addFinal = LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateFinalParams(); -- cgit From 332062be9d47f19352b40ca9a603847061861b55 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Thu, 21 Jan 2021 08:56:53 +0100 Subject: Clear invalid types of unboxed annotations --- .../lombok/javac/handlers/JavacHandlerUtil.java | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'src/core/lombok/javac') diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 98c037b7..8233f20b 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -37,6 +37,7 @@ import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; +import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Scope; @@ -1143,6 +1144,35 @@ public class JavacHandlerUtil { } } } + + static class JCAnnotationReflect { + private static final Field ATTRIBUTE; + + static { + ATTRIBUTE = Permit.permissiveGetField(JCAnnotation.class, "attribute"); + } + + static Attribute.Compound getAttribute(JCAnnotation jcAnnotation) { + if (ATTRIBUTE != null) { + try { + return (Attribute.Compound) ATTRIBUTE.get(jcAnnotation); + } catch (Exception e) { + // Ignore + } + } + return null; + } + + static void setAttribute(JCAnnotation jcAnnotation, Attribute.Compound attribute) { + if (ATTRIBUTE != null) { + try { + Permit.set(ATTRIBUTE, jcAnnotation, attribute); + } catch (Exception e) { + // Ignore + } + } + } + } // jdk9 support, types have changed, names stay the same static class ClassSymbolMembersField { @@ -1783,10 +1813,49 @@ public class JavacHandlerUtil { addError(errorName, annotationNode); } } + for (JCAnnotation annotation : result) { + clearTypes(annotation); + } ast.args = params.toList(); return result.toList(); } + /** + * Removes all type information from the provided tree. + */ + private static void clearTypes(JCTree tree) { + tree.accept(new TreeScanner() { + @Override public void scan(JCTree tree) { + tree.type = null; + super.scan(tree); + } + @Override public void visitClassDef(JCClassDecl tree) { + tree.sym = null; + super.visitClassDef(tree); + } + @Override public void visitMethodDef(JCMethodDecl tree) { + tree.sym = null; + super.visitMethodDef(tree); + } + @Override public void visitVarDef(JCVariableDecl tree) { + tree.sym = null; + super.visitVarDef(tree); + } + @Override public void visitSelect(JCFieldAccess tree) { + tree.sym = null; + super.visitSelect(tree); + } + @Override public void visitIdent(JCIdent tree) { + tree.sym = null; + super.visitIdent(tree); + } + @Override public void visitAnnotation(JCAnnotation tree) { + JCAnnotationReflect.setAttribute(tree, null); + super.visitAnnotation(tree); + } + }); + } + private static void addError(String errorName, JavacNode node) { if (node.getLatestJavaSpecSupported() < 8) { node.addError("The correct format up to JDK7 is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))"); -- cgit