You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/04/08 11:24:05 UTC
[groovy] branch master updated: remove some antlr2-related classes
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 5312406 remove some antlr2-related classes
5312406 is described below
commit 5312406e88743eba55262d83abffda86ae54e024
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Apr 8 21:23:57 2020 +1000
remove some antlr2-related classes
---
.../groovy/tools/groovydoc/GroovyDocParser.java | 144 ---
.../tools/groovydoc/GroovyRootDocBuilder.java | 7 +-
.../groovydoc/SimpleGroovyClassDocAssembler.java | 1023 --------------------
3 files changed, 2 insertions(+), 1172 deletions(-)
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocParser.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocParser.java
deleted file mode 100644
index 9bc81fa..0000000
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocParser.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.tools.groovydoc;
-
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-import antlr.collections.AST;
-import org.codehaus.groovy.antlr.AntlrASTProcessor;
-import org.codehaus.groovy.antlr.SourceBuffer;
-import org.codehaus.groovy.antlr.UnicodeEscapingReader;
-import org.codehaus.groovy.antlr.java.Groovifier;
-import org.codehaus.groovy.antlr.java.Java2GroovyConverter;
-import org.codehaus.groovy.antlr.java.JavaLexer;
-import org.codehaus.groovy.antlr.java.JavaRecognizer;
-import org.codehaus.groovy.antlr.parser.GroovyLexer;
-import org.codehaus.groovy.antlr.parser.GroovyRecognizer;
-import org.codehaus.groovy.antlr.treewalker.PreOrderTraversal;
-import org.codehaus.groovy.antlr.treewalker.SourceCodeTraversal;
-import org.codehaus.groovy.antlr.treewalker.Visitor;
-import org.codehaus.groovy.groovydoc.GroovyClassDoc;
-import org.codehaus.groovy.tools.shell.util.Logger;
-
-import java.io.StringReader;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-/*
- * todo: order methods alphabetically (implement compareTo enough?)
- */
-public class GroovyDocParser implements GroovyDocParserI {
- private final List<LinkArgument> links;
- private final Properties properties;
- private final Logger log = Logger.create(GroovyDocParser.class);
-
- public GroovyDocParser(List<LinkArgument> links, Properties properties) {
- this.links = links;
- this.properties = properties;
- }
-
- public Map<String, GroovyClassDoc> getClassDocsFromSingleSource(String packagePath, String file, String src)
- throws RuntimeException {
- if (file.indexOf(".java") > 0) { // simple (for now) decision on java or groovy
- // java
- return parseJava(packagePath, file, src);
- }
- if (file.indexOf(".sourcefile") > 0) {
- // java (special name used for testing)
- return parseJava(packagePath, file, src);
- }
- // not java, try groovy instead :-)
- return parseGroovy(packagePath, file, src);
- }
-
- private Map<String, GroovyClassDoc> parseJava(String packagePath, String file, String src)
- throws RuntimeException {
- SourceBuffer sourceBuffer = new SourceBuffer();
- JavaRecognizer parser = getJavaParser(src, sourceBuffer);
- String[] tokenNames = parser.getTokenNames();
- try {
- parser.compilationUnit();
- } catch (OutOfMemoryError e) {
- log.error("Out of memory while processing: " + packagePath + "/" + file);
- throw e;
- } catch (RecognitionException | TokenStreamException e) {
- throw new RuntimeException(e);
- }
- AST ast = parser.getAST();
-
- // modify the Java AST into a Groovy AST (just token types)
- Visitor java2groovyConverter = new Java2GroovyConverter(tokenNames);
- AntlrASTProcessor java2groovyTraverser = new PreOrderTraversal(java2groovyConverter);
- java2groovyTraverser.process(ast);
-
- // now mutate (groovify) the ast into groovy
- Visitor groovifier = new Groovifier(tokenNames, false);
- AntlrASTProcessor groovifierTraverser = new PreOrderTraversal(groovifier);
- groovifierTraverser.process(ast);
-
- // now do the business
- SimpleGroovyClassDocAssembler visitor = new SimpleGroovyClassDocAssembler(packagePath, file, sourceBuffer, links, properties, false);
- AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);
-
- traverser.process(ast);
-
- return visitor.getGroovyClassDocs();
- }
-
- private Map<String, GroovyClassDoc> parseGroovy(String packagePath, String file, String src)
- throws RuntimeException {
- SourceBuffer sourceBuffer = new SourceBuffer();
- GroovyRecognizer parser = getGroovyParser(src, sourceBuffer);
- try {
- parser.compilationUnit();
- } catch (OutOfMemoryError e) {
- log.error("Out of memory while processing: " + packagePath + "/" + file);
- throw e;
- } catch (RecognitionException | TokenStreamException e) {
- throw new RuntimeException(e);
- }
- AST ast = parser.getAST();
-
- // now do the business
- SimpleGroovyClassDocAssembler visitor = new SimpleGroovyClassDocAssembler(packagePath, file, sourceBuffer, links, properties, true);
- AntlrASTProcessor traverser = new SourceCodeTraversal(visitor);
- traverser.process(ast);
- return visitor.getGroovyClassDocs();
- }
-
- private static JavaRecognizer getJavaParser(String input, SourceBuffer sourceBuffer) {
- UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input), sourceBuffer);
- JavaLexer lexer = new JavaLexer(unicodeReader);
- unicodeReader.setLexer(lexer);
- JavaRecognizer parser = JavaRecognizer.make(lexer);
- parser.setSourceBuffer(sourceBuffer);
- return parser;
- }
-
- private static GroovyRecognizer getGroovyParser(String input, SourceBuffer sourceBuffer) {
- UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(new StringReader(input), sourceBuffer);
- GroovyLexer lexer = new GroovyLexer(unicodeReader);
- unicodeReader.setLexer(lexer);
- GroovyRecognizer parser = GroovyRecognizer.make(lexer);
- parser.setSourceBuffer(sourceBuffer);
- return parser;
- }
-
-}
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java
index 702fff9..52ce415 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.java
@@ -22,6 +22,7 @@ import org.apache.groovy.groovydoc.tools.GroovyDocUtil;
import org.codehaus.groovy.groovydoc.GroovyClassDoc;
import org.codehaus.groovy.groovydoc.GroovyRootDoc;
import org.codehaus.groovy.runtime.ResourceGroovyMethods;
+import org.codehaus.groovy.tools.groovydoc.antlr4.GroovyDocParser;
import org.codehaus.groovy.tools.shell.util.Logger;
import java.io.File;
@@ -35,7 +36,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;
-import static org.apache.groovy.util.SystemUtil.getSystemPropertySafe;
import static org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc.CODE_REGEX;
import static org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc.LINK_REGEX;
import static org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc.TAG_REGEX;
@@ -121,10 +121,7 @@ public class GroovyRootDocBuilder {
return;
}
try {
- final boolean newParser = Boolean.parseBoolean(getSystemPropertySafe("groovy.antlr4", "true"));
-
- GroovyDocParserI docParser = newParser ? new org.codehaus.groovy.tools.groovydoc.antlr4.GroovyDocParser(links, properties)
- : new GroovyDocParser(links, properties);
+ GroovyDocParserI docParser = new GroovyDocParser(links, properties);
Map<String, GroovyClassDoc> classDocs = docParser.getClassDocsFromSingleSource(packagePath, file, src);
rootDoc.putAllClasses(classDocs);
if (isAbsolute) {
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java
deleted file mode 100644
index b1ab917..0000000
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDocAssembler.java
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
- * 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.tools.groovydoc;
-
-import antlr.collections.AST;
-import org.codehaus.groovy.antlr.GroovySourceAST;
-import org.codehaus.groovy.antlr.LineColumn;
-import org.codehaus.groovy.antlr.SourceBuffer;
-import org.codehaus.groovy.antlr.parser.GroovyTokenTypes;
-import org.codehaus.groovy.antlr.treewalker.VisitorAdapter;
-import org.codehaus.groovy.control.ResolveVisitor;
-import org.codehaus.groovy.groovydoc.GroovyAnnotationRef;
-import org.codehaus.groovy.groovydoc.GroovyClassDoc;
-import org.codehaus.groovy.groovydoc.GroovyConstructorDoc;
-import org.codehaus.groovy.groovydoc.GroovyFieldDoc;
-import org.codehaus.groovy.groovydoc.GroovyMethodDoc;
-import org.codehaus.groovy.groovydoc.GroovyType;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Stack;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class SimpleGroovyClassDocAssembler extends VisitorAdapter implements GroovyTokenTypes {
- private static final String FS = "/";
- private static final Pattern PREV_JAVADOC_COMMENT_PATTERN = Pattern.compile("(?s)/\\*\\*(.*?)\\*/");
- private final Stack<GroovySourceAST> stack;
- private final Map<String, GroovyClassDoc> classDocs;
- private final List<String> importedClassesAndPackages;
- private final Map<String, String> aliases;
- private final List<LinkArgument> links;
- private final Properties properties;
- private SimpleGroovyFieldDoc currentFieldDoc;
- private final SourceBuffer sourceBuffer;
- private String packagePath;
- private LineColumn lastLineCol;
- private boolean insideEnum;
- private Map<String, SimpleGroovyClassDoc> foundClasses;
- private final boolean isGroovy;
- private final boolean deferSetup;
- private final String className;
-
- public SimpleGroovyClassDocAssembler(String packagePath, String file, SourceBuffer sourceBuffer, List<LinkArgument> links, Properties properties, boolean isGroovy) {
- this.sourceBuffer = sourceBuffer;
- this.packagePath = packagePath;
- this.links = links;
- this.properties = properties;
- this.isGroovy = isGroovy;
-
- stack = new Stack<GroovySourceAST>();
- classDocs = new LinkedHashMap<String, GroovyClassDoc>();
- if (file != null && file.contains(".")) {
- // todo: replace this simple idea of default class name
- int idx = file.lastIndexOf(".");
- className = file.substring(0, idx);
- } else {
- className = file;
- }
-
- deferSetup = packagePath.equals("DefaultPackage");
- importedClassesAndPackages = new ArrayList<String>();
- aliases = new LinkedHashMap<String, String>();
- if (!deferSetup) setUpImports(packagePath, links, isGroovy, className);
- lastLineCol = new LineColumn(1, 1);
- }
-
- private void setUpImports(String packagePath, List<LinkArgument> links, boolean isGroovy, String className) {
- importedClassesAndPackages.add(packagePath + "/*"); // everything in this package
- if (isGroovy) {
- for (String pkg : ResolveVisitor.DEFAULT_IMPORTS) {
- importedClassesAndPackages.add(pkg.replace('.', '/') + "*");
- }
- } else {
- importedClassesAndPackages.add("java/lang/*");
- }
- SimpleGroovyClassDoc currentClassDoc = new SimpleGroovyClassDoc(importedClassesAndPackages, aliases, className, links);
- currentClassDoc.setFullPathName(packagePath + FS + className);
- currentClassDoc.setGroovy(isGroovy);
- classDocs.put(currentClassDoc.getFullPathName(), currentClassDoc);
- }
-
- public Map<String, GroovyClassDoc> getGroovyClassDocs() {
- postProcessClassDocs();
- return classDocs;
- }
-
- @Override
- public void visitInterfaceDef(GroovySourceAST t, int visit) {
- visitClassDef(t, visit);
- }
-
- @Override
- public void visitTraitDef(GroovySourceAST t, int visit) {
- visitClassDef(t, visit);
- }
-
- @Override
- public void visitEnumDef(GroovySourceAST t, int visit) {
- visitClassDef(t, visit);
- SimpleGroovyClassDoc currentClassDoc = getCurrentOrTopLevelClassDoc(t);
- if (visit == CLOSING_VISIT && currentClassDoc != null) {
- adjustForAutomaticEnumMethods(currentClassDoc);
- }
- }
-
- @Override
- public void visitAnnotationDef(GroovySourceAST t, int visit) {
- visitClassDef(t, visit);
- }
-
- @Override
- public void visitClassDef(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT) {
- SimpleGroovyClassDoc parent = getCurrentClassDoc();
- String shortName = getIdentFor(t);
- String className = shortName;
- if (parent != null && isNested() && !insideAnonymousInnerClass()) {
- className = parent.name() + "." + className;
- } else {
- foundClasses = new LinkedHashMap<String, SimpleGroovyClassDoc>();
- }
- SimpleGroovyClassDoc current = (SimpleGroovyClassDoc) classDocs.get(packagePath + FS + className);
- if (current == null) {
- current = new SimpleGroovyClassDoc(importedClassesAndPackages, aliases, className, links);
- current.setGroovy(isGroovy);
- }
- current.setRawCommentText(getJavaDocCommentsBeforeNode(t));
- current.setFullPathName(packagePath + FS + current.name());
- current.setTokenType(t.getType());
- current.setNameWithTypeArgs(getIdentPlusTypeArgsFor(t));
- processAnnotations(t, current);
- processModifiers(t, current);
- classDocs.put(current.getFullPathName(), current);
- foundClasses.put(shortName, current);
- if (parent != null) {
- parent.addNested(current);
- current.setOuter(parent);
- }
- }
- }
-
- @Override
- public void visitPackageDef(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT && deferSetup) {
- String packageWithSlashes = extractImportPath(t);
- setUpImports(packageWithSlashes, links, isGroovy, className);
- }
- }
-
- @Override
- public void visitImport(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT) {
- String importTextWithSlashesInsteadOfDots = extractImportPath(t);
-
- GroovySourceAST child = t.childOfType(LITERAL_as);
- if (child != null) {
- String alias = child.childOfType(DOT).getNextSibling().getText();
-
- child = child.childOfType(DOT);
- importTextWithSlashesInsteadOfDots = recurseDownImportBranch(child);
-
- aliases.put(alias, importTextWithSlashesInsteadOfDots);
- }
-
- importedClassesAndPackages.add(importTextWithSlashesInsteadOfDots);
- }
- }
-
-// TODO is this needed so we can click through on default values?
-// @Override
-// public void visitStaticImport(GroovySourceAST t, int visit) {
-// if (visit == OPENING_VISIT) {
-// // TODO
-// String importTextWithSlashesInsteadOfDots = extractImportPath(t);
-// System.out.println(currentClassDoc.name() + " has static import: " + importTextWithSlashesInsteadOfDots);
-// }
-// }
-
- @Override
- public void visitExtendsClause(GroovySourceAST t, int visit) {
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- if (visit == OPENING_VISIT) {
- for (GroovySourceAST superClassNode : findTypeNames(t)) {
- String superClassName = extractName(superClassNode);
- if (currentClassDoc.isInterface()) {
- currentClassDoc.addInterfaceName(superClassName);
- } else {
- currentClassDoc.setSuperClassName(superClassName);
- }
- }
- }
- }
-
- @Override
- public void visitImplementsClause(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT) {
- for (GroovySourceAST classNode : findTypeNames(t)) {
- getCurrentClassDoc().addInterfaceName(extractName(classNode));
- }
- }
- }
-
- private static List<GroovySourceAST> findTypeNames(GroovySourceAST t) {
- List<GroovySourceAST> types = new ArrayList<GroovySourceAST>();
- for (AST child = t.getFirstChild(); child != null; child = child.getNextSibling()) {
- GroovySourceAST groovySourceAST = (GroovySourceAST) child;
- if (groovySourceAST.getType() == TYPE) {
- types.add((GroovySourceAST) groovySourceAST.getFirstChild());
- } else {
- types.add(groovySourceAST);
- }
- }
- return types;
- }
-
- @Override
- public void visitCtorIdent(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT && !insideEnum && !insideAnonymousInnerClass()) {
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- SimpleGroovyConstructorDoc currentConstructorDoc = new SimpleGroovyConstructorDoc(currentClassDoc.name(), currentClassDoc);
- currentConstructorDoc.setRawCommentText(getJavaDocCommentsBeforeNode(t));
- processModifiers(t, currentConstructorDoc);
- addParametersTo(t, currentConstructorDoc);
- processAnnotations(t, currentConstructorDoc);
- currentClassDoc.add(currentConstructorDoc);
- }
- }
-
- @Override
- public void visitMethodDef(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT && !insideEnum && !insideAnonymousInnerClass()) {
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- if (currentClassDoc == null) {
- // assume we have a script
- if ("true".equals(properties.getProperty("processScripts", "true"))) {
- currentClassDoc = getOrMakeScriptClassDoc();
- } else {
- return;
- }
- }
- SimpleGroovyMethodDoc currentMethodDoc = createMethod(t, currentClassDoc);
- StringBuilder params = new StringBuilder();
- getTypeParameters(t.childOfType(TYPE_PARAMETERS), params, "def");
- currentMethodDoc.setTypeParameters(params.toString());
- currentClassDoc.add(currentMethodDoc);
- }
- }
-
- private SimpleGroovyClassDoc getOrMakeScriptClassDoc() {
- SimpleGroovyClassDoc currentClassDoc;
- if (foundClasses != null && foundClasses.containsKey(className)) {
- currentClassDoc = foundClasses.get(className);
- } else {
- currentClassDoc = new SimpleGroovyClassDoc(importedClassesAndPackages, aliases, className, links);
- currentClassDoc.setFullPathName(packagePath + FS + className);
- currentClassDoc.setPublic(true);
- currentClassDoc.setScript(true);
- currentClassDoc.setGroovy(isGroovy);
- currentClassDoc.setSuperClassName("groovy/lang/Script");
- if ("true".equals(properties.getProperty("includeMainForScripts", "true"))) {
- currentClassDoc.add(createMainMethod(currentClassDoc));
- }
- classDocs.put(currentClassDoc.getFullPathName(), currentClassDoc);
- if (foundClasses == null) {
- foundClasses = new LinkedHashMap<String, SimpleGroovyClassDoc>();
- }
- foundClasses.put(className, currentClassDoc);
- }
- return currentClassDoc;
- }
-
- private void processPropertiesFromGetterSetter(SimpleGroovyMethodDoc currentMethodDoc) {
- String methodName = currentMethodDoc.name();
- int len = methodName.length();
- String prefix = null;
- String propName = null;
- if (len > 3 && methodName.startsWith("get")) {
- prefix = "get";
- propName = methodName.substring(3);
- } else if (len > 3 && methodName.startsWith("set")) {
- prefix = "set";
- propName = methodName.substring(3);
- } else if (len > 2 && methodName.startsWith("is")) {
- prefix = "is";
- propName = methodName.substring(2);
- } else {
- // Not a (get/set/is) method that contains a property name
- return;
- }
-
- SimpleGroovyClassDoc classDoc = getCurrentClassDoc();
- // TODO: not sure why but groovy.ui.view.BasicContentPane#buildOutputArea classDoc is null
- if (classDoc == null) {
- return;
- }
- GroovyMethodDoc[] methods = classDoc.methods();
-
- //find expected method name
- String expectedMethodName = null;
- if ("set".equals(prefix) && (currentMethodDoc.parameters().length >= 1 && !currentMethodDoc.parameters()[0].typeName().equals("boolean"))) {
- expectedMethodName = "get" + propName;
- } else if ("get".equals(prefix) && !currentMethodDoc.returnType().typeName().equals("boolean")) {
- expectedMethodName = "set" + propName;
- } else if ("is".equals(prefix)) {
- expectedMethodName = "set" + propName;
- } else {
- expectedMethodName = "is" + propName;
- }
-
- for (GroovyMethodDoc methodDoc : methods) {
- if (methodDoc.name().equals(expectedMethodName)) {
-
- //extract the field name
- String fieldName = propName.substring(0, 1).toLowerCase() + propName.substring(1);
- SimpleGroovyFieldDoc currentFieldDoc = new SimpleGroovyFieldDoc(fieldName, classDoc);
-
- //find the type of the field; if it's a setter, need to get the type of the params
- if(expectedMethodName.startsWith("set") && methodDoc.parameters().length >= 1) {
- String typeName = methodDoc.parameters()[0].typeName();
- currentFieldDoc.setType(new SimpleGroovyType(typeName));
- } else {
- //if it's not setter, get the type info of the return type of the get* method
- currentFieldDoc.setType(methodDoc.returnType());
- }
-
- if (methodDoc.isPublic() && currentMethodDoc.isPublic()) {
- classDoc.addProperty(currentFieldDoc);
- break;
- }
- }
- }
- }
-
- private SimpleGroovyMethodDoc createMethod(GroovySourceAST t, SimpleGroovyClassDoc currentClassDoc) {
- String methodName = getIdentFor(t);
- SimpleGroovyMethodDoc currentMethodDoc = new SimpleGroovyMethodDoc(methodName, currentClassDoc);
- currentMethodDoc.setRawCommentText(getJavaDocCommentsBeforeNode(t));
- processModifiers(t, currentMethodDoc);
- currentMethodDoc.setReturnType(new SimpleGroovyType(getTypeOrDefault(t)));
- addParametersTo(t, currentMethodDoc);
- processAnnotations(t, currentMethodDoc);
- processPropertiesFromGetterSetter(currentMethodDoc);
- return currentMethodDoc;
- }
-
- private static GroovyMethodDoc createMainMethod(SimpleGroovyClassDoc currentClassDoc) {
- SimpleGroovyMethodDoc mainMethod = new SimpleGroovyMethodDoc("main", currentClassDoc);
- mainMethod.setPublic(true);
- mainMethod.setStatic(true);
- mainMethod.setCommentText("Implicit main method for Groovy Scripts");
- mainMethod.setFirstSentenceCommentText(mainMethod.commentText());
- SimpleGroovyParameter args = new SimpleGroovyParameter("args");
- GroovyType argsType = new SimpleGroovyType("java.lang.String[]");
- args.setType(argsType);
- mainMethod.add(args);
- GroovyType returnType = new SimpleGroovyType("void");
- mainMethod.setReturnType(returnType);
- return mainMethod;
- }
-
- @Override
- public void visitAnnotationFieldDef(GroovySourceAST t, int visit) {
- if (isGroovy && visit == OPENING_VISIT) {
- // TODO shouldn't really be treating annotation fields as methods - remove this hack
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- SimpleGroovyMethodDoc currentMethodDoc = createMethod(t, currentClassDoc);
- String defaultText = getDefaultValue(t);
- if (defaultText != null) {
- String orig = currentMethodDoc.getRawCommentText();
- currentMethodDoc.setRawCommentText(orig + "\n* @default " + defaultText);
- }
- currentClassDoc.add(currentMethodDoc);
- } else if (visit == OPENING_VISIT) {
-// if (visit == OPENING_VISIT) {
- visitVariableDef(t, visit);
- String defaultText = getDefaultValue(t);
- if (isGroovy) {
- currentFieldDoc.setPublic(true);
- }
- if (defaultText != null) {
- currentFieldDoc.setConstantValueExpression(defaultText);
- String orig = currentFieldDoc.getRawCommentText();
- currentFieldDoc.setRawCommentText(orig + "\n* @default " + defaultText);
- }
- }
- }
-
- @Override
- public void visitEnumConstantDef(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT) {
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- insideEnum = true;
- String enumConstantName = getIdentFor(t);
- SimpleGroovyFieldDoc currentEnumConstantDoc = new SimpleGroovyFieldDoc(enumConstantName, currentClassDoc);
- currentEnumConstantDoc.setRawCommentText(getJavaDocCommentsBeforeNode(t));
- processModifiers(t, currentEnumConstantDoc);
- String typeName = getTypeNodeAsText(t.childOfType(TYPE), currentClassDoc.getTypeDescription());
- currentEnumConstantDoc.setType(new SimpleGroovyType(typeName));
- currentClassDoc.addEnumConstant(currentEnumConstantDoc);
- } else if (visit == CLOSING_VISIT) {
- insideEnum = false;
- }
- }
-
- @Override
- public void visitVariableDef(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT && !insideAnonymousInnerClass()) {
- boolean validField = true;
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- if (currentClassDoc == null) {
- // assume we have a script (and it may have a @Field)
- if ("true".equals(properties.getProperty("processScripts", "true"))) {
- currentClassDoc = getOrMakeScriptClassDoc();
- validField = false;
- } else {
- return;
- }
- } else if (!isFieldDefinition()) {
- return;
- }
- String fieldName = getIdentFor(t);
- if (fieldName.isEmpty()) return; // multi-assignment
- currentFieldDoc = new SimpleGroovyFieldDoc(fieldName, currentClassDoc);
- currentFieldDoc.setRawCommentText(getJavaDocCommentsBeforeNode(t));
- boolean isProp = processModifiers(t, currentFieldDoc);
- currentFieldDoc.setType(new SimpleGroovyType(getTypeOrDefault(t)));
- processAnnotations(t, currentFieldDoc);
- if (!validField) { // look for @Field
- for (GroovyAnnotationRef ref : currentFieldDoc.annotations()) {
- if ("Field".equals(ref.name()) || "groovy/transform/Field".equals(ref.name())) {
- validField = true;
- break;
- }
- }
- }
- if (!validField) return;
- if (isProp) {
- currentClassDoc.addProperty(currentFieldDoc);
- } else {
- currentClassDoc.add(currentFieldDoc);
- }
- }
- }
-
- @Override
- public void visitAssign(GroovySourceAST t, int visit) {
- gobbleComments(t, visit);
- }
-
- @Override
- public void visitMethodCall(GroovySourceAST t, int visit) {
- gobbleComments(t, visit);
- }
-
- private void gobbleComments(GroovySourceAST t, int visit) {
- if (visit == OPENING_VISIT) {
- SimpleGroovyClassDoc currentClassDoc = getCurrentClassDoc();
- if (currentClassDoc == null || currentClassDoc.isScript()) {
- if (t.getLine() > lastLineCol.getLine() ||
- (t.getLine() == lastLineCol.getLine() && t.getColumn() > lastLineCol.getColumn())) {
- getJavaDocCommentsBeforeNode(t);
- // not normally set for non-major types but appropriate for a script
- lastLineCol = new LineColumn(t.getLine(), t.getColumn());
- }
- }
- }
- }
-
- // Step through ClassDocs and tie up loose ends
- private void postProcessClassDocs() {
- for (GroovyClassDoc groovyClassDoc : classDocs.values()) {
- SimpleGroovyClassDoc classDoc = (SimpleGroovyClassDoc) groovyClassDoc;
-
- // potentially add default constructor to class docs (but not interfaces)
- if (classDoc.isClass()) {
- GroovyConstructorDoc[] constructors = classDoc.constructors();
- if (constructors != null && constructors.length == 0) { // add default constructor to doc
- // name of class for the constructor
- GroovyConstructorDoc constructorDoc = new SimpleGroovyConstructorDoc(classDoc.name(), classDoc);
- // don't forget to tell the class about this default constructor.
- classDoc.add(constructorDoc);
- }
- }
- }
- }
-
- private boolean isNested() {
- return getCurrentClassDoc() != null;
- }
-
- private static boolean isTopLevelConstruct(GroovySourceAST node) {
- if (node == null) return false;
- int type = node.getType();
- return type == CLASS_DEF || type == INTERFACE_DEF || type == TRAIT_DEF || type == ANNOTATION_DEF || type == ENUM_DEF;
- }
-
- private static void adjustForAutomaticEnumMethods(SimpleGroovyClassDoc currentClassDoc) {
- SimpleGroovyMethodDoc valueOf = new SimpleGroovyMethodDoc("valueOf", currentClassDoc);
- valueOf.setRawCommentText("Returns the enum constant of this type with the specified name.");
- SimpleGroovyParameter parameter = new SimpleGroovyParameter("name");
- parameter.setTypeName("String");
- valueOf.add(parameter);
- valueOf.setReturnType(new SimpleGroovyType(currentClassDoc.name()));
- currentClassDoc.add(valueOf);
-
- SimpleGroovyMethodDoc values = new SimpleGroovyMethodDoc("values", currentClassDoc);
- values.setRawCommentText("Returns an array containing the constants of this enum type, in the order they are declared.");
- values.setReturnType(new SimpleGroovyType(currentClassDoc.name() + "[]"));
- currentClassDoc.add(values);
- }
-
- private String extractImportPath(GroovySourceAST t) {
- return recurseDownImportBranch(getPackageDotType(t));
- }
-
- private static GroovySourceAST getPackageDotType(GroovySourceAST t) {
- GroovySourceAST child = t.childOfType(DOT);
- if (child == null) {
- child = t.childOfType(IDENT);
- }
- return child;
- }
-
- private String recurseDownImportBranch(GroovySourceAST t) {
- if (t != null) {
- if (t.getType() == DOT) {
- GroovySourceAST firstChild = (GroovySourceAST) t.getFirstChild();
- GroovySourceAST secondChild = (GroovySourceAST) firstChild.getNextSibling();
- return (recurseDownImportBranch(firstChild) + "/" + recurseDownImportBranch(secondChild));
- }
- if (t.getType() == IDENT) {
- return t.getText();
- }
- if (t.getType() == STAR) {
- return t.getText();
- }
- }
- return "";
- }
-
- private void addAnnotationRef(SimpleGroovyProgramElementDoc node, GroovySourceAST t) {
- GroovySourceAST classNode = getPackageDotType(t);
- if (classNode != null) {
- node.addAnnotationRef(new SimpleGroovyAnnotationRef(extractName(classNode), getChildTextFromSource(t).trim()));
- }
- }
-
- private void addAnnotationRef(SimpleGroovyParameter node, GroovySourceAST t) {
- GroovySourceAST classNode = getPackageDotType(t);
- if (classNode != null) {
- node.addAnnotationRef(new SimpleGroovyAnnotationRef(extractName(classNode), getChildTextFromSource(t).trim()));
- }
- }
-
- private void addAnnotationRefs(SimpleGroovyProgramElementDoc node, List<GroovySourceAST> nodes) {
- for (GroovySourceAST t : nodes) {
- addAnnotationRef(node, t);
- }
- }
-
- private void processAnnotations(GroovySourceAST t, SimpleGroovyProgramElementDoc node) {
- GroovySourceAST modifiers = t.childOfType(MODIFIERS);
- if (modifiers != null) {
- addAnnotationRefs(node, modifiers.childrenOfType(ANNOTATION));
- }
- }
-
- // hack warning! fragile! TODO find a better way
- private String getDefaultValue(GroovySourceAST t) {
- GroovySourceAST child = (GroovySourceAST) t.getFirstChild();
- if (t.getNumberOfChildren() != 4) return null;
- for (int i = 1; i < t.getNumberOfChildren(); i++) {
- child = (GroovySourceAST) child.getNextSibling();
- }
- GroovySourceAST nodeToProcess = child;
- if (child.getType() != ANNOTATION_ARRAY_INIT && child.getNumberOfChildren() > 0) {
- nodeToProcess = (GroovySourceAST) child.getFirstChild();
- }
- return getChildTextFromSource(nodeToProcess, ";");
- }
-
- private String getChildTextFromSource(GroovySourceAST child) {
- return sourceBuffer.getSnippet(
- new LineColumn(child.getLine(), child.getColumn()),
- new LineColumn(child.getLineLast(), child.getColumnLast()));
- }
-
- private String getChildTextFromSource(GroovySourceAST child, String tokens) {
- String text = sourceBuffer.getSnippet(
- new LineColumn(child.getLine(), child.getColumn()),
- new LineColumn(child.getLine() + 1, 0));
- StringTokenizer st = new StringTokenizer(text, tokens);
- return st.nextToken();
- }
-
- private boolean isFieldDefinition() {
- GroovySourceAST parentNode = getParentNode();
- return parentNode != null && parentNode.getType() == OBJBLOCK;
- }
-
- private boolean insideAnonymousInnerClass() {
- GroovySourceAST grandParentNode = getGrandParentNode();
- return grandParentNode != null && grandParentNode.getType() == LITERAL_new;
- }
-
- // return true if a property is found
- private boolean processModifiers(GroovySourceAST t, SimpleGroovyAbstractableElementDoc memberOrClass) {
- GroovySourceAST modifiers = t.childOfType(MODIFIERS);
- boolean hasNonPublicVisibility = false;
- boolean hasPublicVisibility = false;
- if (modifiers != null) {
- AST currentModifier = modifiers.getFirstChild();
- while (currentModifier != null) {
- int type = currentModifier.getType();
- switch (type) {
- case LITERAL_public:
- memberOrClass.setPublic(true);
- hasPublicVisibility = true;
- break;
- case LITERAL_protected:
- memberOrClass.setProtected(true);
- hasNonPublicVisibility = true;
- break;
- case LITERAL_private:
- memberOrClass.setPrivate(true);
- hasNonPublicVisibility = true;
- break;
- case LITERAL_static:
- memberOrClass.setStatic(true);
- break;
- case FINAL:
- memberOrClass.setFinal(true);
- break;
- case ABSTRACT:
- memberOrClass.setAbstract(true);
- break;
- default:
- }
- currentModifier = currentModifier.getNextSibling();
- }
- if (!hasNonPublicVisibility && isGroovy && !(memberOrClass instanceof GroovyFieldDoc)) {
- // in groovy, methods and classes are assumed public, unless informed otherwise
- if (isPackageScope(modifiers)) {
- memberOrClass.setPackagePrivate(true);
- hasNonPublicVisibility = true;
- } else {
- memberOrClass.setPublic(true);
- }
- } else if (!hasNonPublicVisibility && !hasPublicVisibility && !isGroovy) {
- if (insideInterface(memberOrClass) || insideAnnotationDef(memberOrClass)) {
- memberOrClass.setPublic(true);
- } else {
- memberOrClass.setPackagePrivate(true);
- }
- }
- if (memberOrClass instanceof GroovyFieldDoc && isGroovy && !hasNonPublicVisibility && !hasPublicVisibility) {
- if (isPackageScope(modifiers)) {
- memberOrClass.setPackagePrivate(true);
- hasNonPublicVisibility = true;
- }
- }
- if (memberOrClass instanceof GroovyFieldDoc && !hasNonPublicVisibility && !hasPublicVisibility && isGroovy) return true;
- } else if (isGroovy && !(memberOrClass instanceof GroovyFieldDoc)) {
- // in groovy, methods and classes are assumed public, unless informed otherwise
- memberOrClass.setPublic(true);
- } else if (!isGroovy) {
- if (insideInterface(memberOrClass) || insideAnnotationDef(memberOrClass)) {
- memberOrClass.setPublic(true);
- } else {
- memberOrClass.setPackagePrivate(true);
- }
- }
- return memberOrClass instanceof GroovyFieldDoc && isGroovy && !hasNonPublicVisibility && !hasPublicVisibility;
- }
-
- private boolean isPackageScope(GroovySourceAST modifiers) {
- List<String> names = getAnnotationNames(modifiers);
- return names.contains("groovy/transform/PackageScope") || names.contains("PackageScope");
- }
-
- private List<String> getAnnotationNames(GroovySourceAST modifiers) {
- List<String> annotationNames = new ArrayList<String>();
- List<GroovySourceAST> annotations = modifiers.childrenOfType(ANNOTATION);
- for (GroovySourceAST annotation : annotations) {
- annotationNames.add(buildName((GroovySourceAST) annotation.getFirstChild()));
- }
- return annotationNames;
- }
-
- private boolean insideInterface(SimpleGroovyAbstractableElementDoc memberOrClass) {
- SimpleGroovyClassDoc current = getCurrentClassDoc();
- if (current == null || current == memberOrClass) return false;
- return current.isInterface();
- }
-
- private boolean insideAnnotationDef(SimpleGroovyAbstractableElementDoc memberOrClass) {
- SimpleGroovyClassDoc current = getCurrentClassDoc();
- if (current == null || current == memberOrClass) return false;
- return current.isAnnotationType();
- }
-
- // todo - If no comment before node, then get comment from same node on parent class - ouch!
-
- private String getJavaDocCommentsBeforeNode(GroovySourceAST t) {
- String result = "";
- LineColumn thisLineCol = new LineColumn(t.getLine(), t.getColumn());
- String text = sourceBuffer.getSnippet(lastLineCol, thisLineCol);
- if (text != null) {
- Matcher m = PREV_JAVADOC_COMMENT_PATTERN.matcher(text);
- if (m.find()) {
- result = m.group(1);
- }
- }
- if (isMajorType(t)) {
- lastLineCol = thisLineCol;
- }
- return result;
- }
-
- private static boolean isMajorType(GroovySourceAST t) {
- if (t == null) return false;
- int tt = t.getType();
- return tt == CLASS_DEF || tt == TRAIT_DEF || tt == INTERFACE_DEF || tt == METHOD_DEF || tt == ANNOTATION_DEF || tt == ENUM_DEF ||
- tt == VARIABLE_DEF || tt == ANNOTATION_FIELD_DEF || tt == ENUM_CONSTANT_DEF || tt == CTOR_IDENT;
- }
-
- private static String getText(GroovySourceAST node) {
- String returnValue = null;
- if (node != null) {
- returnValue = node.getText();
- }
- return returnValue;
- }
-
- // preempt resolve as info is partially available here (aliases and star imports won't match here)
- private String extractName(GroovySourceAST typeNode) {
- String typeName = buildName(typeNode);
- if (!typeName.contains("/")) {
- String slashName = "/" + typeName;
- // Groovy currently resolves this to last found so traverse in reverse order
- for (int i = importedClassesAndPackages.size() - 1; i >= 0; i--) {
- String name = importedClassesAndPackages.get(i);
- if (!aliases.containsValue(name) && name.endsWith(slashName)) {
- typeName = name;
- break;
- }
- }
- }
- return typeName;
- }
-
- private String buildName(GroovySourceAST t) {
- if (t != null) {
- if (t.getType() == DOT) {
- GroovySourceAST firstChild = (GroovySourceAST) t.getFirstChild();
- GroovySourceAST secondChild = (GroovySourceAST) firstChild.getNextSibling();
- return (buildName(firstChild) + "/" + buildName(secondChild));
- }
- if (t.getType() == IDENT) {
- return t.getText();
- }
- }
- return "";
- }
-
- private String getTypeOrDefault(GroovySourceAST t) {
- GroovySourceAST typeNode = t.childOfType(TYPE);
- return getTypeNodeAsText(typeNode, "def");
- }
-
- private String getTypeNodeAsText(GroovySourceAST typeNode, String defaultText) {
- // TODO refactor to retain richer type information rather than converting to String
- if (typeNode == null) {
- return defaultText;
- }
- if (typeNode.getType() == TYPE) {
- return getAsText(typeNode, defaultText);
- } else if (typeNode.getType() == TYPE_ARGUMENT) {
- return getTypeNodeAsText((GroovySourceAST) typeNode.getFirstChild(), defaultText);
- } else if (typeNode.getType() == WILDCARD_TYPE) {
- AST next = typeNode.getNextSibling();
- if (next == null && typeNode.getFirstChild() != null) {
- // Java2Groovy produces a slightly different tree structure (TODO fix converter or java.g instead?)
- next = typeNode.getFirstChild();
- }
- if (next == null) return "?";
- String boundType = getTypeNodeAsText((GroovySourceAST) next.getFirstChild(), defaultText);
- if (next.getType() == TYPE_UPPER_BOUNDS) return "? extends " + boundType;
- if (next.getType() == TYPE_LOWER_BOUNDS) return "? super " + boundType;
- } else if (typeNode.getType() == IDENT) {
- String ident = getAsTextCurrent(typeNode, defaultText);
- AST next = typeNode.getNextSibling();
- if (next == null && typeNode.getFirstChild() != null) {
- // Java2Groovy produces a slightly different tree structure (TODO fix converter or java.g instead?)
- next = typeNode.getFirstChild();
- }
- if (next == null) return ident;
- String boundType = getTypeNodeAsText((GroovySourceAST) next.getFirstChild(), defaultText);
- if (next.getType() == TYPE_UPPER_BOUNDS) return ident + " extends " + boundType;
- if (next.getType() == TYPE_LOWER_BOUNDS) return ident + " super " + boundType;
- }
- return defaultText;
- }
-
- private String getAsText(GroovySourceAST typeNode, String defaultText) {
- GroovySourceAST child = (GroovySourceAST) typeNode.getFirstChild();
- return getAsTextCurrent(child, defaultText);
- }
-
- private String getAsTextCurrent(GroovySourceAST node, String defaultText) {
- if (node == null) return defaultText;
- switch (node.getType()) {
- // literals
- case LITERAL_boolean:
- return "boolean";
- case LITERAL_byte:
- return "byte";
- case LITERAL_char:
- return "char";
- // note: LITERAL_def never created
- case LITERAL_double:
- return "double";
- case LITERAL_float:
- return "float";
- case LITERAL_int:
- return "int";
- case LITERAL_long:
- return "long";
- case LITERAL_short:
- return "short";
- case LITERAL_void:
- return "void";
- case ARRAY_DECLARATOR:
- String componentType = getAsText(node, defaultText);
- if (!componentType.equals("def")) return componentType + "[]";
- return "java/lang/Object[]";
- // identifiers
- case IDENT:
- StringBuilder ident = new StringBuilder();
- ident.append(node.getText());
- GroovySourceAST identChild = (GroovySourceAST) node.getFirstChild();
- getTypeArguments(identChild, ident, defaultText);
- return ident.toString();
- case DOT:
- StringBuilder dot = new StringBuilder();
- GroovySourceAST dotChild = (GroovySourceAST) node.getFirstChild();
- while (dotChild != null) {
- if (dotChild.getType() == IDENT || dotChild.getType() == DOT) {
- if (dot.length() > 0) dot.append("/");
- dot.append(getAsTextCurrent(dotChild, defaultText));
- } else if (dotChild.getType() == TYPE_ARGUMENTS) {
- getTypeArguments(dotChild, dot, defaultText);
- }
- dotChild = (GroovySourceAST) dotChild.getNextSibling();
- }
- return dot.toString();
- }
- return defaultText;
- }
-
- private void getTypeArguments(GroovySourceAST child, StringBuilder result, String defaultText) {
- if (child != null && child.getType() == TYPE_ARGUMENTS && child.getNumberOfChildren() > 0) {
- result.append("<");
- GroovySourceAST typeArgumentsNext = (GroovySourceAST) child.getFirstChild();
- List<String> typeArgumentParts = new ArrayList<String>();
- while (typeArgumentsNext != null) {
- if (typeArgumentsNext.getType() == TYPE_ARGUMENT && typeArgumentsNext.getNumberOfChildren() > 0) {
- typeArgumentParts.add(getTypeNodeAsText((GroovySourceAST) typeArgumentsNext.getFirstChild(), defaultText));
- }
- typeArgumentsNext = (GroovySourceAST) typeArgumentsNext.getNextSibling();
- }
- result.append(DefaultGroovyMethods.join((Iterable)typeArgumentParts, ", "));
- result.append(">");
- }
- }
-
- private void getTypeParameters(GroovySourceAST child, StringBuilder result, String defaultText) {
- if (child != null && child.getType() == TYPE_PARAMETERS && child.getNumberOfChildren() > 0) {
- result.append("<");
- GroovySourceAST typeParametersNext = (GroovySourceAST) child.getFirstChild();
- List<String> typeParameterParts = new ArrayList<String>();
- while (typeParametersNext != null) {
- if (typeParametersNext.getType() == TYPE_PARAMETER && typeParametersNext.getNumberOfChildren() > 0) {
- typeParameterParts.add(getTypeNodeAsText((GroovySourceAST) typeParametersNext.getFirstChild(), defaultText));
- }
- typeParametersNext = (GroovySourceAST) typeParametersNext.getNextSibling();
- }
- result.append(DefaultGroovyMethods.join((Iterable)typeParameterParts, ", "));
- result.append(">");
- }
- }
-
- private void addParametersTo(GroovySourceAST t, SimpleGroovyExecutableMemberDoc executableMemberDoc) {
- // parameters
- GroovySourceAST parametersNode = t.childOfType(PARAMETERS);
- if (parametersNode != null && parametersNode.getNumberOfChildren() > 0) {
- GroovySourceAST currentNode = (GroovySourceAST) parametersNode.getFirstChild();
- while (currentNode != null) {
- String parameterTypeName = getTypeOrDefault(currentNode);
- String parameterName = getText(currentNode.childOfType(IDENT));
- SimpleGroovyParameter parameter = new SimpleGroovyParameter(parameterName);
- parameter.setVararg(currentNode.getType() == VARIABLE_PARAMETER_DEF);
- parameter.setTypeName(parameterTypeName);
- GroovySourceAST modifiers = currentNode.childOfType(MODIFIERS);
- if (modifiers != null) {
- List<GroovySourceAST> annotations = modifiers.childrenOfType(ANNOTATION);
- for (GroovySourceAST a : annotations) {
- addAnnotationRef(parameter, a);
- }
- }
- executableMemberDoc.add(parameter);
- if (currentNode.getNumberOfChildren() == 4) {
- handleDefaultValue(currentNode, parameter);
- }
- currentNode = (GroovySourceAST) currentNode.getNextSibling();
- }
- }
- }
-
- private void handleDefaultValue(GroovySourceAST currentNode, SimpleGroovyParameter parameter) {
- GroovySourceAST paramPart = (GroovySourceAST) currentNode.getFirstChild();
- for (int i = 1; i < currentNode.getNumberOfChildren(); i++) {
- paramPart = (GroovySourceAST) paramPart.getNextSibling();
- }
- GroovySourceAST nodeToProcess = paramPart;
- if (paramPart.getNumberOfChildren() > 0) {
- nodeToProcess = (GroovySourceAST) paramPart.getFirstChild();
- }
- // hack warning!
- // TODO handle , and ) when they occur within Strings
- parameter.setDefaultValue(getChildTextFromSource(nodeToProcess, ",)"));
- }
-
- public void push(GroovySourceAST t) {
- stack.push(t);
- }
-
- public GroovySourceAST pop() {
- if (!stack.empty()) {
- return stack.pop();
- }
- return null;
- }
-
- private GroovySourceAST getParentNode() {
- GroovySourceAST parentNode = null;
- GroovySourceAST currentNode = stack.pop();
- if (!stack.empty()) {
- parentNode = stack.peek();
- }
- stack.push(currentNode);
- return parentNode;
- }
-
- private GroovySourceAST getGrandParentNode() {
- GroovySourceAST grandParentNode = null;
- GroovySourceAST parentNode;
- GroovySourceAST currentNode = stack.pop();
- if (!stack.empty()) {
- parentNode = stack.pop();
- if (!stack.empty()) {
- grandParentNode = stack.peek();
- }
- stack.push(parentNode);
- }
- stack.push(currentNode);
- return grandParentNode;
- }
-
- private SimpleGroovyClassDoc getCurrentOrTopLevelClassDoc(GroovySourceAST node) {
- SimpleGroovyClassDoc current = getCurrentClassDoc();
- if (current != null) return current;
- return foundClasses.get(getIdentFor(node));
- }
-
- private SimpleGroovyClassDoc getCurrentClassDoc() {
- if (stack.isEmpty()) return null;
- GroovySourceAST node = getParentNode();
- if (isTopLevelConstruct(node) && foundClasses != null) {
- return foundClasses.get(getIdentFor(node));
- }
- GroovySourceAST saved = stack.pop();
- SimpleGroovyClassDoc result = getCurrentClassDoc();
- stack.push(saved);
- return result;
- }
-
- private static String getIdentFor(GroovySourceAST gpn) {
- GroovySourceAST ident = gpn.childOfType(IDENT);
- return ident == null ? "" : ident.getText();
- }
-
- private String getIdentPlusTypeArgsFor(GroovySourceAST gpn) {
- GroovySourceAST groovySourceAST = gpn.childOfType(IDENT);
- StringBuilder ident = new StringBuilder();
- ident.append(groovySourceAST.getText());
- GroovySourceAST typeParams = (GroovySourceAST) groovySourceAST.getNextSibling();
- getTypeParameters(typeParams, ident, "def");
- return ident.toString();
- }
-}