groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject [groovy] 02/05: makeType refactor (closes #1009)
Date Thu, 26 Sep 2019 10:38:13 GMT
This is an automated email from the ASF dual-hosted git repository.

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

commit fc721725690495c34056205de796fdf863a7c8a2
Author: Paul King <paulk@asert.com.au>
AuthorDate: Thu Sep 26 18:15:13 2019 +1000

    makeType refactor (closes #1009)
---
 .../org/codehaus/groovy/ast/tools/Antlr2Utils.java | 41 +++++++++++++++++++
 .../org/codehaus/groovy/ast/tools/Antlr4Utils.java | 18 +++++++++
 .../codehaus/groovy/ast/tools/GenericsUtils.java   | 10 ++---
 .../MarkupTemplateTypeCheckingExtension.groovy     | 46 ++++++++++------------
 4 files changed, 83 insertions(+), 32 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/tools/Antlr2Utils.java b/src/main/java/org/codehaus/groovy/ast/tools/Antlr2Utils.java
new file mode 100644
index 0000000..922d4ee
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/tools/Antlr2Utils.java
@@ -0,0 +1,41 @@
+package org.codehaus.groovy.ast.tools;
+
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+import groovy.lang.GroovyRuntimeException;
+import org.codehaus.groovy.antlr.AntlrParserPlugin;
+import org.codehaus.groovy.antlr.parser.GroovyLexer;
+import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.ModuleNode;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.syntax.ParserException;
+import org.codehaus.groovy.syntax.Reduction;
+
+import java.io.StringReader;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Antlr2Utils {
+    private Antlr2Utils() {
+    }
+
+    public static ClassNode parse(String option) {
+        GroovyLexer lexer = new GroovyLexer(new StringReader("DummyNode<" + option + ">"));
+        try {
+            final GroovyRecognizer rn = GroovyRecognizer.make(lexer);
+            rn.classOrInterfaceType(true);
+            final AtomicReference<ClassNode> ref = new AtomicReference<ClassNode>();
+            AntlrParserPlugin plugin = new AntlrParserPlugin() {
+                @Override
+                public ModuleNode buildAST(final SourceUnit sourceUnit, final ClassLoader
classLoader, final Reduction cst) throws ParserException {
+                    ref.set(makeTypeWithArguments(rn.getAST()));
+                    return null;
+                }
+            };
+            plugin.buildAST(null, null, null);
+            return ref.get();
+        } catch (RecognitionException | TokenStreamException | ParserException e) {
+            throw new GroovyRuntimeException("Unable to parse '" + option + "'", e);
+        }
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/Antlr4Utils.java b/src/main/java/org/codehaus/groovy/ast/tools/Antlr4Utils.java
new file mode 100644
index 0000000..18e8aae
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/tools/Antlr4Utils.java
@@ -0,0 +1,18 @@
+package org.codehaus.groovy.ast.tools;
+
+import org.apache.groovy.parser.antlr4.Antlr4ParserPlugin;
+import org.apache.groovy.parser.antlr4.Antlr4PluginFactory;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.ParserPluginFactory;
+
+public class Antlr4Utils {
+    private Antlr4Utils() {
+    }
+
+    public static ClassNode parse(String option, CompilerConfiguration configuration) {
+        Antlr4PluginFactory antlr4PluginFactory = (Antlr4PluginFactory) ParserPluginFactory.antlr4(configuration);
+        Antlr4ParserPlugin antlr4ParserPlugin = (Antlr4ParserPlugin) antlr4PluginFactory.createParserPlugin();
+        return antlr4ParserPlugin.makeType(option);
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 69beb13..f3c6f92 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -18,10 +18,9 @@
  */
 package org.codehaus.groovy.ast.tools;
 
+import groovy.lang.GroovyRuntimeException;
 import groovy.lang.Tuple2;
 import groovy.transform.stc.IncorrectTypeHintException;
-import org.apache.groovy.parser.antlr4.Antlr4ParserPlugin;
-import org.apache.groovy.parser.antlr4.Antlr4PluginFactory;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.ClassHelper;
@@ -33,7 +32,6 @@ import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.stmt.EmptyStatement;
 import org.codehaus.groovy.control.CompilationFailedException;
 import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.ParserPluginFactory;
 import org.codehaus.groovy.control.ResolveVisitor;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.runtime.memoize.ConcurrentSoftCache;
@@ -584,9 +582,7 @@ public class GenericsUtils {
             final ASTNode usage) {
 
         try {
-            Antlr4PluginFactory antlr4PluginFactory = (Antlr4PluginFactory) ParserPluginFactory.antlr4(compilationUnit.getConfiguration());
-            Antlr4ParserPlugin antlr4ParserPlugin = (Antlr4ParserPlugin) antlr4PluginFactory.createParserPlugin();
-            ClassNode parsedNode = antlr4ParserPlugin.makeType("DummyNode<" + option +
">");
+            ClassNode parsedNode = Antlr4Utils.parse("DummyNode<" + option + ">", compilationUnit.getConfiguration());
 
             // the returned node is DummyNode<Param1, Param2, Param3, ...)
             GenericsType[] parsedNodeGenericsTypes = parsedNode.getGenericsTypes();
@@ -599,7 +595,7 @@ public class GenericsUtils {
                 signature[i] = resolveClassNode(sourceUnit, compilationUnit, mn, usage, genericsType.getType());
             }
             return signature;
-        } catch (CompilationFailedException e) {
+        } catch (GroovyRuntimeException e) {
             sourceUnit.addError(new IncorrectTypeHintException(mn, e, usage.getLineNumber(),
usage.getColumnNumber()));
         }
         return null;
diff --git a/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
b/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
index 7db4dc7..865068b 100644
--- a/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
+++ b/subprojects/groovy-templates/src/main/groovy/groovy/text/markup/MarkupTemplateTypeCheckingExtension.groovy
@@ -19,8 +19,6 @@
 package groovy.text.markup
 
 import groovy.transform.CompileStatic
-import org.apache.groovy.parser.antlr4.Antlr4ParserPlugin
-import org.apache.groovy.parser.antlr4.Antlr4PluginFactory
 import org.codehaus.groovy.ast.ASTNode
 import org.codehaus.groovy.ast.ClassCodeExpressionTransformer
 import org.codehaus.groovy.ast.ClassHelper
@@ -38,8 +36,8 @@ import org.codehaus.groovy.ast.expr.MethodCallExpression
 import org.codehaus.groovy.ast.expr.TupleExpression
 import org.codehaus.groovy.ast.expr.VariableExpression
 import org.codehaus.groovy.ast.stmt.EmptyStatement
+import org.codehaus.groovy.ast.tools.Antlr4Utils
 import org.codehaus.groovy.control.CompilerConfiguration
-import org.codehaus.groovy.control.ParserPluginFactory
 import org.codehaus.groovy.control.ResolveVisitor
 import org.codehaus.groovy.control.SourceUnit
 import org.codehaus.groovy.control.messages.SyntaxErrorMessage
@@ -65,7 +63,7 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
 
         beforeVisitClass { classNode ->
             def modelTypes = MarkupTemplateEngine.TemplateGroovyClassLoader.modelTypes.get()
-            if (modelTypes!=null) {
+            if (modelTypes != null) {
                 modelTypesClassNodes = [:]
                 modelTypes.each { k, v ->
                     modelTypesClassNodes[k] = buildNodeFromString(v, context)
@@ -73,13 +71,13 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
             }
             def modelTypesFromTemplate = classNode.getNodeMetaData(MarkupTemplateEngine.MODELTYPES_ASTKEY)
             if (modelTypesFromTemplate) {
-                if (modelTypesClassNodes==null) {
+                if (modelTypesClassNodes == null) {
                     modelTypesClassNodes = modelTypesFromTemplate
                 } else {
                     modelTypesClassNodes.putAll(modelTypesFromTemplate)
                 }
             }
-            if (modelTypesClassNodes==null) {
+            if (modelTypesClassNodes == null) {
                 // push a new error collector, we want type checking errors to be silent
                 context.pushErrorCollector()
             }
@@ -92,16 +90,16 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
             }
         }
         methodNotFound { receiver, name, argList, argTypes, call ->
-            if ("getAt"==name && OBJECT_TYPE==receiver) {
+            if ("getAt" == name && OBJECT_TYPE == receiver) {
                 // GROOVY-6940
                 def enclosingBinaryExpression = context.enclosingBinaryExpression
                 if (enclosingBinaryExpression.leftExpression.is(call.objectExpression)) {
                     def stack = context.enclosingBinaryExpressionStack
-                    if (stack.size()>1) {
+                    if (stack.size() > 1) {
                         def superEnclosing = stack.get(1)
                         def opType = superEnclosing.operation.type
                         if (superEnclosing.leftExpression.is(enclosingBinaryExpression) &&
isAssignment(opType)) {
-                            if (opType== Types.ASSIGN) {
+                            if (opType == Types.ASSIGN) {
                                 // type checker looks for getAt() but we need to replace
the super binary expression with a putAt
                                 // foo[x] = y --> foo.putAt(x,y)
                                 def mce = new MethodCallExpression(
@@ -125,7 +123,7 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
                     currentScope.builderCalls << call
                     return makeDynamic(call, OBJECT_TYPE)
                 }
-                if (modelTypesClassNodes==null) {
+                if (modelTypesClassNodes == null) {
                     // unchecked mode
                     return makeDynamic(call, OBJECT_TYPE)
                 }
@@ -133,15 +131,15 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
         }
 
         onMethodSelection { call, node ->
-            if (isMethodCallExpression(call) && modelTypesClassNodes!=null) {
+            if (isMethodCallExpression(call) && modelTypesClassNodes != null) {
                 def args = getArguments(call).expressions
-                if (args.size()==1) {
-                    String varName = isConstantExpression(args[0])?args[0].text:call.getNodeMetaData(MarkupBuilderCodeTransformer.TARGET_VARIABLE)
+                if (args.size() == 1) {
+                    String varName = isConstantExpression(args[0]) ? args[0].text : call.getNodeMetaData(MarkupBuilderCodeTransformer.TARGET_VARIABLE)
                     def type = modelTypesClassNodes[varName]
                     if (type) {
-                        if (call.objectExpression.text=='this.getModel()') {
+                        if (call.objectExpression.text == 'this.getModel()') {
                             storeType(call, type)
-                        } else if (call.methodAsString=='tryEscape') {
+                        } else if (call.methodAsString == 'tryEscape') {
                             storeType(call, type)
                         }
                     }
@@ -150,8 +148,8 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
         }
 
         unresolvedProperty { pexp ->
-            if (pexp.objectExpression.text=='this.getModel()') {
-                if (modelTypesClassNodes!=null) {
+            if (pexp.objectExpression.text == 'this.getModel()') {
+                if (modelTypesClassNodes != null) {
                     // type checked mode detected!
                     def type = modelTypesClassNodes[pexp.propertyAsString]
                     if (type) {
@@ -160,7 +158,7 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
                 } else {
                     makeDynamic(pexp)
                 }
-            } else if (modelTypesClassNodes==null) {
+            } else if (modelTypesClassNodes == null) {
                 // dynamic mode
                 makeDynamic(pexp)
             }
@@ -175,10 +173,8 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
 
     @CompileStatic
     private static ClassNode buildNodeFromString(String option, TypeCheckingContext ctx)
{
-        Antlr4PluginFactory antlr4PluginFactory = (Antlr4PluginFactory) ParserPluginFactory.antlr4(CompilerConfiguration.DEFAULT)
-        Antlr4ParserPlugin antlr4ParserPlugin = (Antlr4ParserPlugin) antlr4PluginFactory.createParserPlugin()
-        ClassNode parsedNode = antlr4ParserPlugin.makeType(option)
-        ClassNode dummyClass = new ClassNode("dummy", 0, ClassHelper.OBJECT_TYPE)
+        ClassNode parsedNode = Antlr4Utils.parse(option, CompilerConfiguration.DEFAULT)
+        ClassNode dummyClass = new ClassNode("dummy", 0, OBJECT_TYPE)
         dummyClass.setModule(new ModuleNode(ctx.source))
         MethodNode dummyMN = new MethodNode(
                 "dummy",
@@ -193,13 +189,13 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
             @Override
             void addError(final String msg, final ASTNode expr) {
                 ctx.errorCollector.addErrorAndContinue(new SyntaxErrorMessage(
-                        new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(),
expr.getLastLineNumber(), expr.getLastColumnNumber()),
+                        new SyntaxException(msg + '\n', expr.lineNumber, expr.columnNumber,
expr.lastLineNumber, expr.lastColumnNumber),
                         ctx.source)
                 )
             }
         }
         visitor.startResolving(dummyClass, ctx.source)
-        return dummyMN.getReturnType()
+        return dummyMN.returnType
     }
 
     private static class BuilderMethodReplacer extends ClassCodeExpressionTransformer {
@@ -242,7 +238,7 @@ class MarkupTemplateTypeCheckingExtension extends GroovyTypeCheckingExtensionSup
                                 new ConstantExpression(exp.getMethodAsString()),
                                 new ArrayExpression(
                                         OBJECT_TYPE,
-                                        [* args]
+                                        [*args]
                                 )
                         )
                 )


Mime
View raw message