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 <eric.mil...@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);

Reply via email to