You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2020/02/14 22:07:05 UTC

[groovy] branch ImmutableClassNode created (now 4764b93)

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a change to branch ImmutableClassNode
in repository https://gitbox.apache.org/repos/asf/groovy.git.


      at 4764b93  ImmutableClassNode for protecting highly-available ClassNode instances

This branch includes the following new commits:

     new 4764b93  ImmutableClassNode for protecting highly-available ClassNode instances

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[groovy] 01/01: ImmutableClassNode for protecting highly-available ClassNode instances

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch ImmutableClassNode
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 4764b9368bfa150efa822bbf467e7ada5d53ef63
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Feb 14 16:06:37 2020 -0600

    ImmutableClassNode for protecting highly-available ClassNode instances
---
 .../codehaus/groovy/antlr/AntlrParserPlugin.java   |  33 +++-
 .../java/org/codehaus/groovy/ast/ClassHelper.java  |   2 +-
 .../java/org/codehaus/groovy/ast/ClassNode.java    |  10 +-
 .../java/org/codehaus/groovy/ast/GenericsType.java |  13 +-
 .../codehaus/groovy/ast/ImmutableClassNode.java    | 199 +++++++++++++++++++++
 .../codehaus/groovy/control/ResolveVisitor.java    |   6 +
 .../apache/groovy/parser/antlr4/AstBuilder.java    |  30 +++-
 7 files changed, 268 insertions(+), 25 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
index c7c095f..1e2ae0e 100644
--- a/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
+++ b/src/main/java/org/codehaus/groovy/antlr/AntlrParserPlugin.java
@@ -43,6 +43,7 @@ import org.codehaus.groovy.ast.ConstructorNode;
 import org.codehaus.groovy.ast.EnumConstantClassNode;
 import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.ImmutableClassNode;
 import org.codehaus.groovy.ast.ImportNode;
 import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
@@ -123,6 +124,7 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
 import java.io.Reader;
+import java.lang.annotation.Annotation;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -419,7 +421,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
             if (node.getNumberOfChildren() == 0) {
                 String name = identifier(node);
                 // import is like  "import Foo"
-                ClassNode type = ClassHelper.make(name);
+                ClassNode type = makeClassNode(name);
                 configureAST(type, importNode);
                 addImport(type, name, alias, annotations);
                 imp = last(output.getImports());
@@ -434,7 +436,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
                 if (isStatic) {
                     // import is like "import static foo.Bar.*"
                     // packageName is actually a className in this case
-                    ClassNode type = ClassHelper.make(packageName);
+                    ClassNode type = makeClassNode(packageName);
                     configureAST(type, importNode);
                     addStaticStarImport(type, packageName, annotations);
                     imp = output.getStaticStarImports().get(packageName);
@@ -453,14 +455,14 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
                 if (isStatic) {
                     // import is like "import static foo.Bar.method"
                     // packageName is really class name in this case
-                    ClassNode type = ClassHelper.make(packageName);
+                    ClassNode type = makeClassNode(packageName);
                     configureAST(type, importNode);
                     addStaticImport(type, name, alias, annotations);
                     imp = output.getStaticImports().get(alias == null ? name : alias);
                     configureAST(imp, importNode);
                 } else {
                     // import is like "import foo.Bar"
-                    ClassNode type = ClassHelper.make(packageName + "." + name);
+                    ClassNode type = makeClassNode(packageName + "." + name);
                     configureAST(type, importNode);
                     addImport(type, name, alias, annotations);
                     imp = last(output.getImports());
@@ -631,7 +633,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
         List<AnnotationNode> annotations = new ArrayList<>();
 
         if (isType(TRAIT_DEF, classDef)) {
-            annotations.add(new AnnotationNode(ClassHelper.makeCached(Trait.class)));
+            annotations.add(makeAnnotationNode(Trait.class));
         }
 
         AST node = classDef.getFirstChild();
@@ -876,7 +878,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
             checkNoInvalidModifier(methodDef, "Method", modifiers, Opcodes.ACC_VOLATILE, "volatile");
             node = node.getNextSibling();
         }
-
         if (isAnInterface()) {
             modifiers |= Opcodes.ACC_ABSTRACT;
         }
@@ -1022,7 +1023,6 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
             modifiers = modifiers(node, annotations, modifiers);
             node = node.getNextSibling();
         }
-
         if (classNode.isInterface()) {
             modifiers |= Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
             if ((modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) == 0) {
@@ -1292,7 +1292,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
     protected AnnotationNode annotation(AST annotationNode) {
         annotationBeingDef = true;
         AST node = annotationNode.getFirstChild();
-        AnnotationNode annotatedNode = new AnnotationNode(ClassHelper.make(qualifiedName(node)));
+        AnnotationNode annotatedNode = new AnnotationNode(makeType(annotationNode));
         configureAST(annotatedNode, annotationNode);
         while (true) {
             node = node.getNextSibling();
@@ -3002,7 +3002,7 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
                 answer = makeArray(makeTypeWithArguments(node), node);
             } else {
                 checkTypeArgs(node, false);
-                answer = ClassHelper.make(qualifiedName(node));
+                answer = makeClassNode(qualifiedName(node));
                 if (answer.isUsingGenerics()) {
                     ClassNode proxy = ClassHelper.makeWithoutCaching(answer.getName());
                     proxy.setRedirect(answer);
@@ -3115,6 +3115,21 @@ public class AntlrParserPlugin extends ASTHelper implements ParserPlugin, Groovy
         }
     }
 
+    protected static AnnotationNode makeAnnotationNode(Class<? extends Annotation> type) {
+        AnnotationNode node = new AnnotationNode(ClassHelper.makeCached(type));
+        return node;
+    }
+
+    protected static ClassNode makeClassNode(String name) {
+        ClassNode node = ClassHelper.make(name);
+        if (node instanceof ImmutableClassNode && !ClassHelper.isPrimitiveType(node)) {
+            ClassNode wrapper = ClassHelper.makeWithoutCaching(name);
+            wrapper.setRedirect(node);
+            node = wrapper;
+        }
+        return node;
+    }
+
     protected static Token makeToken(int typeCode, AST node) {
         return Token.newSymbol(typeCode, node.getLine(), node.getColumn());
     }
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index 17bcc8d..214126d 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -179,7 +179,7 @@ public class ClassHelper {
         final SoftReference<ClassNode> classNodeSoftReference = ClassHelperCache.classCache.get(c);
         ClassNode classNode;
         if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) {
-            classNode = new ClassNode(c);
+            classNode = new ImmutableClassNode(c);
             ClassHelperCache.classCache.put(c, new SoftReference<ClassNode>(classNode));
             VMPluginFactory.getPlugin().setAdditionalClassInformation(classNode);
         }
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 15f6eb0..3218b4e 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -110,7 +110,7 @@ import static java.util.stream.Collectors.joining;
  */
 public class ClassNode extends AnnotatedNode implements Opcodes {
 
-    private static class MapOfLists {
+    protected static class MapOfLists {
         Map<Object, List<MethodNode>> map;
 
         List<MethodNode> get(Object key) {
@@ -129,8 +129,8 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     }
 
     public static final ClassNode[] EMPTY_ARRAY = new ClassNode[0];
-    public static final ClassNode THIS = new ClassNode(Object.class);
-    public static final ClassNode SUPER = new ClassNode(Object.class);
+    public static final ClassNode THIS = new ImmutableClassNode(Object.class);
+    public static final ClassNode SUPER = new ImmutableClassNode(Object.class);
 
     private String name;
     private int modifiers;
@@ -139,7 +139,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     private MixinNode[] mixins;
     private List<Statement> objectInitializers;
     private List<ConstructorNode> constructors;
-    private MapOfLists methods;
+    protected MapOfLists methods;
     private List<MethodNode> methodsList;
     private LinkedList<FieldNode> fields;
     private List<PropertyNode> properties;
@@ -164,7 +164,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     // clazz!=null when resolved
     protected Class clazz;
     // only false when this classNode is constructed from a class
-    private volatile boolean lazyInitDone = true;
+    protected volatile boolean lazyInitDone = true;
     // not null if if the ClassNode is an array
     private ClassNode componentType;
     // if not null this instance is handled as proxy
diff --git a/src/main/java/org/codehaus/groovy/ast/GenericsType.java b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
index 700204f..bf0cd51 100644
--- a/src/main/java/org/codehaus/groovy/ast/GenericsType.java
+++ b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
@@ -41,6 +41,15 @@ public class GenericsType extends ASTNode {
     private final ClassNode[] upperBounds;
     private boolean placeholder, resolved, wildcard;
 
+    public GenericsType(final ClassNode type) {
+        this(type, null, null);
+    }
+
+    protected GenericsType(final ClassNode[] upperBounds, final ClassNode lowerBound) {
+        this.lowerBound = lowerBound;
+        this.upperBounds = upperBounds;
+    }
+
     public GenericsType(final ClassNode type, final ClassNode[] upperBounds, final ClassNode lowerBound) {
         setType(type);
         this.lowerBound = lowerBound;
@@ -49,10 +58,6 @@ public class GenericsType extends ASTNode {
         setName(placeholder ? type.getUnresolvedName() : type.getName());
     }
 
-    public GenericsType(final ClassNode basicType) {
-        this(basicType, null, null);
-    }
-
     public ClassNode getType() {
         return type;
     }
diff --git a/src/main/java/org/codehaus/groovy/ast/ImmutableClassNode.java b/src/main/java/org/codehaus/groovy/ast/ImmutableClassNode.java
new file mode 100644
index 0000000..df90540
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/ImmutableClassNode.java
@@ -0,0 +1,199 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast;
+
+import org.codehaus.groovy.GroovyBugError;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A {@link ClassNode} where the {@link GenericsType} information is immutable.
+ */
+public class ImmutableClassNode extends ClassNode {
+
+    private volatile boolean genericsInitialized;
+    private volatile boolean writeProtected;
+
+    public ImmutableClassNode(final Class<?> c) {
+        super(c);
+    }
+
+    // ASTNode overrides:
+
+    @Override
+    public void setColumnNumber(int n) {}
+
+    @Override
+    public void setLastColumnNumber(int n) {}
+
+    @Override
+    public void setLastLineNumber(int n) {}
+
+    @Override
+    public void setLineNumber(int n) {}
+
+    @Override
+    public void setNodeMetaData(Object k, Object v) {}
+
+    @Override
+    public Object putNodeMetaData(Object k, Object v) {
+        return getNodeMetaData(k);
+    }
+
+    @Override
+    public void setSourcePosition(ASTNode n) {}
+
+    // AnnotatedNode overrides:
+
+    @Override
+    public void setDeclaringClass(ClassNode cn) {}
+
+    @Override
+    public void setHasNoRealSourcePosition(boolean b) {}
+
+    @Override
+    public void setSynthetic(boolean b) {}
+
+    // ClassNode overrides:
+
+    @Override
+    public List<MethodNode> getDeclaredMethods(final String name) {
+        if (lazyInitDone && !writeProtected) {
+            synchronized (methods) {
+                if (!writeProtected) {
+                    writeProtected = true;
+                    if (methods.map == null || methods.map.isEmpty()) {
+                        methods.map = Collections.emptyMap();
+                    } else {
+                        for (Object key : methods.map.keySet()) {
+                            List<MethodNode> list = methods.get(key);
+                            methods.map.put(key, Collections.unmodifiableList(list));
+                        }
+                        methods.map = Collections.unmodifiableMap(methods.map);
+                    }
+                }
+            }
+        }
+        return super.getDeclaredMethods(name);
+    }
+
+    @Override
+    public void setAnnotated(boolean b) {}
+
+    @Override
+    protected void setCompileUnit(CompileUnit cu) {}
+
+    @Override
+    public void setEnclosingMethod(MethodNode mn) {}
+
+    @Override
+    public void setGenericsPlaceHolder(boolean b) {}
+
+    //public void setInterfaces(ClassNode[] cn) {}
+
+    @Override
+    public void setModifiers(int bf) {}
+
+    @Override
+    public void setModule(ModuleNode mn) {}
+
+    @Override
+    public String setName(String s) {
+        return getName();
+    }
+
+    //public void setRedirect(ClassNode cn) {}
+
+    @Override
+    public void setSuperClass(ClassNode cn) {}
+
+    @Override
+    public void setScript(boolean b) {}
+
+    @Override
+    public void setScriptBody(boolean b) {}
+
+    @Override
+    public void setStaticClass(boolean b) {}
+
+    @Override
+    public void setSyntheticPublic(boolean b) {}
+
+    //public void setUnresolvedSuperClass(ClassNode cn) {}
+
+    @Override
+    public void setUsingGenerics(boolean b) {}
+
+    @Override
+    public void setGenericsTypes(GenericsType[] genericsTypes) {
+        if (genericsInitialized && genericsTypes != super.getGenericsTypes()) {
+            throw new GroovyBugError("Attempt to change an immutable Groovy class: " + getName());
+        }
+        if (genericsTypes != null) {
+            GenericsType[] immutable = new GenericsType[genericsTypes.length];
+            for (int i = 0, n = genericsTypes.length; i < n; i += 1) {
+                immutable[i] = new ImmutableGenericsType(genericsTypes[i], getName());
+            }
+            genericsTypes = immutable;
+        }
+        super.setGenericsTypes(genericsTypes);
+        genericsInitialized = true;
+    }
+
+    static class ImmutableGenericsType extends GenericsType {
+
+        ImmutableGenericsType(final GenericsType delegate, final String typeName) {
+            super(delegate.getUpperBounds(), delegate.getLowerBound());
+            this.typeName = typeName;
+            super.setName(delegate.getName());
+            super.setType(delegate.getType());
+            super.setResolved(delegate.isResolved());
+            super.setWildcard(delegate.isWildcard());
+            super.setPlaceholder(delegate.isPlaceholder());
+        }
+
+        private final String typeName;
+
+        @Override
+        public void setType(ClassNode cn) {
+            throw new GroovyBugError("Attempt to change an immutable Groovy class: " + typeName);
+        }
+
+        @Override
+        public void setPlaceholder(boolean b) {
+            throw new GroovyBugError("Attempt to change an immutable Groovy class: " + typeName);
+        }
+
+        @Override
+        public void setResolved(boolean b) {
+            throw new GroovyBugError("Attempt to change an immutable Groovy class: " + typeName);
+        }
+
+        @Override
+        public void setName(String s) {
+            throw new GroovyBugError("Attempt to change an immutable Groovy class: " + typeName);
+        }
+
+        @Override
+        public void setWildcard(boolean b) {
+            throw new GroovyBugError("Attempt to change an immutable Groovy class: " + typeName);
+        }
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 07c3c88..a3db9b6 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -33,6 +33,7 @@ import org.codehaus.groovy.ast.DynamicVariable;
 import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.GenericsType;
 import org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
+import org.codehaus.groovy.ast.ImmutableClassNode;
 import org.codehaus.groovy.ast.ImportNode;
 import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
@@ -1028,6 +1029,11 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
         if (className != null) {
             ClassNode type = ClassHelper.make(className);
             if (resolve(type)) {
+                if (type instanceof ImmutableClassNode && !ClassHelper.isPrimitiveType(type)) {
+                    ClassNode wrapper = ClassHelper.makeWithoutCaching(className);
+                    wrapper.setRedirect(type);
+                    type = wrapper;
+                }
                 return new ClassExpression(type);
             }
         }
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index b4ae68b..8fbf7b5 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -49,6 +49,7 @@ import org.codehaus.groovy.ast.ConstructorNode;
 import org.codehaus.groovy.ast.EnumConstantClassNode;
 import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.ImmutableClassNode;
 import org.codehaus.groovy.ast.ImportNode;
 import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
@@ -127,6 +128,7 @@ import org.objectweb.asm.Opcodes;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.lang.annotation.Annotation;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -281,6 +283,7 @@ import static org.apache.groovy.parser.antlr4.GroovyLangParser.PrimitiveTypeCont
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedClassNameContext;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedClassNameListContext;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedNameContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedNameElementContext;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.QualifiedStandardClassNameContext;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.RegexExprAltContext;
 import static org.apache.groovy.parser.antlr4.GroovyLangParser.RelationalExprAltContext;
@@ -499,18 +502,18 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         if (hasStatic) {
             if (hasStar) { // e.g. import static java.lang.Math.*
                 String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
-                ClassNode type = ClassHelper.make(qualifiedName);
+                ClassNode type = makeClassNode(qualifiedName);
                 configureAST(type, ctx);
 
                 moduleNode.addStaticStarImport(type.getText(), type, annotationNodeList);
 
                 importNode = last(moduleNode.getStaticStarImports().values());
             } else { // e.g. import static java.lang.Math.pow
-                List<GroovyParserRuleContext> identifierList = new LinkedList<>(ctx.qualifiedName().qualifiedNameElement());
+                List<? extends QualifiedNameElementContext> identifierList = ctx.qualifiedName().qualifiedNameElement();
                 int identifierListSize = identifierList.size();
                 String name = identifierList.get(identifierListSize - 1).getText();
                 ClassNode classNode =
-                        ClassHelper.make(
+                        makeClassNode(
                                 identifierList.stream()
                                         .limit(identifierListSize - 1)
                                         .map(ParseTree::getText)
@@ -534,7 +537,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
             } else { // e.g. import java.util.Map
                 String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
                 String name = last(ctx.qualifiedName().qualifiedNameElement()).getText();
-                ClassNode classNode = ClassHelper.make(qualifiedName);
+                ClassNode classNode = makeClassNode(qualifiedName);
                 String alias = hasAlias
                         ? ctx.alias.getText()
                         : name;
@@ -549,6 +552,21 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         return configureAST(importNode, ctx);
     }
 
+    private static AnnotationNode makeAnnotationNode(Class<? extends Annotation> type) {
+        AnnotationNode node = new AnnotationNode(ClassHelper.make(type));
+        return node;
+    }
+
+    private static ClassNode makeClassNode(String name) {
+        ClassNode node = ClassHelper.make(name);
+        if (node instanceof ImmutableClassNode && !ClassHelper.isPrimitiveType(node)) {
+            ClassNode wrapper = ClassHelper.makeWithoutCaching(name);
+            wrapper.setRedirect(node);
+            node = wrapper;
+        }
+        return node;
+    }
+
     // statement {    --------------------------------------------------------------------
 
     @Override
@@ -1122,7 +1140,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         boolean isInterfaceWithDefaultMethods = (isInterface && this.containsDefaultMethods(ctx));
 
         if (isInterfaceWithDefaultMethods || asBoolean(ctx.TRAIT())) {
-            classNode.addAnnotation(new AnnotationNode(ClassHelper.makeCached(Trait.class)));
+            classNode.addAnnotation(makeAnnotationNode(Trait.class));
         }
         classNode.addAnnotations(modifierManager.getAnnotations());
 
@@ -4125,7 +4143,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     }
 
     private ClassNode createClassNode(GroovyParserRuleContext ctx) {
-        ClassNode result = ClassHelper.make(ctx.getText());
+        ClassNode result = makeClassNode(ctx.getText());
 
         if (!isTrue(ctx, IS_INSIDE_INSTANCEOF_EXPR)) { // type in the "instanceof" expression should not have proxy to redirect to it
             result = this.proxyClassNode(result);