diff --git a/.classpath b/.classpath index addbf00fc..c291f0a82 100644 --- a/.classpath +++ b/.classpath @@ -15,5 +15,7 @@ + + diff --git a/build.xml b/build.xml index 7f6d5a808..3581f9cc7 100755 --- a/build.xml +++ b/build.xml @@ -112,6 +112,8 @@ + + @@ -328,7 +330,7 @@ - + @@ -393,7 +395,7 @@ - + diff --git a/lib/ast-dependencies.jar b/lib/ast-dependencies.jar new file mode 100644 index 000000000..404aa2fdc Binary files /dev/null and b/lib/ast-dependencies.jar differ diff --git a/lib/ast.jar b/lib/ast.jar new file mode 100644 index 000000000..6396ea1b5 Binary files /dev/null and b/lib/ast.jar differ diff --git a/src/java/eu/rssw/pct/oedoc/ClassDocumentationVisitor.java b/src/java/eu/rssw/pct/oedoc/ClassDocumentationVisitor.java index ebfd5b237..6dbb445d6 100644 --- a/src/java/eu/rssw/pct/oedoc/ClassDocumentationVisitor.java +++ b/src/java/eu/rssw/pct/oedoc/ClassDocumentationVisitor.java @@ -10,10 +10,12 @@ import antlr.CommonHiddenStreamToken; +import com.openedge.pdt.core.ast.ASTNode; import com.openedge.pdt.core.ast.ConstructorDeclaration; import com.openedge.pdt.core.ast.EventDeclaration; import com.openedge.pdt.core.ast.MethodDeclaration; import com.openedge.pdt.core.ast.ProgressParserTokenTypes; +import com.openedge.pdt.core.ast.ProgressTokenTypes; import com.openedge.pdt.core.ast.PropertyDeclaration; import com.openedge.pdt.core.ast.PropertyMethod; import com.openedge.pdt.core.ast.SimpleToken; @@ -24,7 +26,6 @@ import com.openedge.pdt.core.ast.model.IParameter; import com.openedge.pdt.core.ast.visitor.ASTVisitor; -import eu.rssw.parser.ParserUtils; import eu.rssw.rcode.AccessModifier; import eu.rssw.rcode.ClassCompilationUnit; import eu.rssw.rcode.Constructor; @@ -100,7 +101,7 @@ public boolean visit(PropertyDeclaration decl) { prop.dataType = decl.getDataType().getName(); prop.extent = decl.getExtent(); prop.modifier = AccessModifier.from(decl.getAccessModifier()); - prop.propertyComment = ParserUtils.findPreviousComment(decl); + prop.propertyComment = findPreviousComment(decl); cu.properties.add(prop); return true; @@ -136,7 +137,7 @@ public boolean visit(ConstructorDeclaration decl) { constr.modifier = AccessModifier.STATIC; else constr.modifier = AccessModifier.from(decl.getAccessModifier()); - constr.constrComment = ParserUtils.findPreviousComment(decl); + constr.constrComment = findPreviousComment(decl); if (decl.getParameters() != null) { for (IParameter p : decl.getParameters()) { @@ -165,7 +166,7 @@ public boolean visit(MethodDeclaration decl) { method.isStatic = decl.isStatic(); method.isFinal = decl.isFinal(); method.isAbstract = decl.isAbstract(); - method.methodComment = ParserUtils.findPreviousComment(decl); + method.methodComment = findPreviousComment(decl); cu.methods.add(method); if (decl.getParameters() != null) { @@ -198,7 +199,7 @@ public boolean visit(EventDeclaration decl) { event.isAbstract = decl.isAbstract(); if (decl.isDelegate()) event.delegateName = decl.getDelegateName(); - event.eventComment = ParserUtils.findPreviousComment(decl); + event.eventComment = findPreviousComment(decl); cu.events.add(event); if (decl.getParameters() != null) { @@ -233,4 +234,24 @@ else if (decl.getChild(ProgressParserTokenTypes.ASSEMBLY) != null) return true; } + + /** + * Renvoie le *dernier* commentaire + * + * @param node + * @return + */ + public static String findPreviousComment(ASTNode node) { + if ((node.getHiddenPrevious() != null) && (node.getHiddenPrevious().getType() == ProgressTokenTypes.ML__COMMENT)) { + return node.getHiddenPrevious().getText(); + } + IASTNode n = node.getPrevSibling(); + while ((n != null) && (n.getType() == ProgressParserTokenTypes.ANNOTATION)) { + if ((n.getHiddenPrevious() != null) && (n.getHiddenPrevious().getType() == ProgressTokenTypes.ML__COMMENT)) + return n.getHiddenPrevious().getText(); + n = n.getPrevSibling(); + } + return null; + } + } \ No newline at end of file diff --git a/src/java/eu/rssw/pct/oedoc/OpenEdgeDocumentation115.java b/src/java/eu/rssw/pct/oedoc/OpenEdgeDocumentation115.java new file mode 100644 index 000000000..7a81ee3f8 --- /dev/null +++ b/src/java/eu/rssw/pct/oedoc/OpenEdgeDocumentation115.java @@ -0,0 +1,241 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "Ant" and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package eu.rssw.pct.oedoc; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Path; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; + +import com.openedge.core.runtime.IPropath; +import com.openedge.core.runtime.Propath; +import com.openedge.pdt.core.ast.ASTManager; +import com.openedge.pdt.core.ast.ASTNode; +import com.openedge.pdt.core.ast.IASTManager; +import com.openedge.pdt.core.ast.PropathASTContext; +import com.openedge.pdt.core.ast.model.IASTContext; +import com.openedge.pdt.core.ast.model.IASTNode; +import com.openedge.pdt.core.ast.model.ICompilationUnit; +import com.phenix.pct.Messages; +import com.phenix.pct.PCT; + +/** + * Class for generating XML documentation from OpenEdge classes + * + * @author Gilles QUERRET + */ +public class OpenEdgeDocumentation115 extends PCT { + private File destDir = null; + private String encoding = null; + private List filesets = new ArrayList(); + protected Path propath = null; + + public OpenEdgeDocumentation115() { + super(); + createPropath(); + } + + /** + * Adds a set of files to archive. + * + * @param set FileSet + */ + public void addFileset(FileSet set) { + filesets.add(set); + } + + /** + * Build dir + * + * @param dir Directory + */ + public void setBuildDir(File dir) { + + } + + /** + * Destination directory + * + * @param destFile Directory + */ + public void setDestDir(File dir) { + this.destDir = dir; + } + + /** + * Codepage to use when reading files + * + * @param encoding String + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * Set the propath to be used when running the procedure + * + * @param propath an Ant Path object containing the propath + */ + public void addPropath(Path propath) { + createPropath().append(propath); + } + + /** + * Creates a new Path instance + * + * @return Path + */ + public Path createPropath() { + if (this.propath == null) { + this.propath = new Path(this.getProject()); + } + + return this.propath; + } + + /** + * Do the work + * + * @throws BuildException Something went wrong + */ + public void execute() throws BuildException { + checkDlcHome(); + + // Destination directory must exist + if (this.destDir == null) { + throw new BuildException(Messages.getString("OpenEdgeClassDocumentation.0")); + } + // There must be at least one fileset + if (this.filesets.size() == 0) { + throw new BuildException(Messages.getString("OpenEdgeClassDocumentation.1")); + } + IPropath pp = new Propath(new org.eclipse.core.runtime.Path(getProject().getBaseDir().getAbsolutePath()), propath.list()); + IASTContext astContext = new PropathASTContext(pp); + IProgressMonitor monitor = new NullProgressMonitor(); + IASTManager astMgr = ASTManager.getASTManager(); + + log("Generating XML documentation (11.5+ method)", Project.MSG_INFO); + try { + for (FileSet fs : filesets) { + // And get files from fileset + String[] dsfiles = fs.getDirectoryScanner(this.getProject()).getIncludedFiles(); + + for (int i = 0; i < dsfiles.length; i++) { + File file = new File(fs.getDir(this.getProject()), dsfiles[i]); + log("Generating AST for " + file.getAbsolutePath(), Project.MSG_VERBOSE); + int extPos = file.getName().lastIndexOf('.'); + String ext = file.getName().substring(extPos); + boolean isClass = ".cls".equalsIgnoreCase(ext); + + ICompilationUnit root = astMgr.createAST(file, astContext, monitor, IASTManager.EXPAND_ON, IASTManager.DLEVEL_FULL); + if (isClass) { + ClassDocumentationVisitor visitor = new ClassDocumentationVisitor(); + log("Executing AST ClassVisitor " + file.getAbsolutePath(), Project.MSG_VERBOSE); + root.accept(visitor); + if (visitor.getPackageName().length() == 0) + visitor.toXML(new File(destDir, visitor.getClassName() + ".xml")); + else + visitor.toXML(new File(destDir, visitor.getPackageName() + "." + + visitor.getClassName() + ".xml")); + } else { + ProcedureDocumentationVisitor visitor = new ProcedureDocumentationVisitor(); + log("Executing AST ProcedureVisitor " + file.getAbsolutePath(), Project.MSG_VERBOSE); + root.accept(visitor); + File destFile = new File(destDir, dsfiles[i] + ".xml"); + destFile.getParentFile().mkdirs(); + visitor.toXML(destFile); + } + } + } + } catch (IOException caught) { + throw new BuildException(caught); + } catch (JAXBException caught) { + throw new BuildException(caught); + } + } + + public static void setSourceRange(ASTNode node) { + if (node instanceof ICompilationUnit) { + node.setStartPosition(1); + } + + if ((node.getFirstChild1() == null) || (node.getType() == 22)) { + node.setStartPosition(node.getTokenStart()); + node.setLength(node.getTokenLength()); + } + + IASTNode prev = null; + for (IASTNode child = node.getFirstChild1(); child != null; child = child.getNextSibling1()) { + ((ASTNode) child).setParent(node); + if (prev != null) { + ((ASTNode) child).setPrevSibling(prev); + } + prev = child; + + if (child.getType() != 22) { + setSourceRange((ASTNode) child); + } + } + } + +} diff --git a/src/java/eu/rssw/pct/oedoc/ProcedureDocumentationVisitor.java b/src/java/eu/rssw/pct/oedoc/ProcedureDocumentationVisitor.java index c0fba2b0d..3d12d6487 100644 --- a/src/java/eu/rssw/pct/oedoc/ProcedureDocumentationVisitor.java +++ b/src/java/eu/rssw/pct/oedoc/ProcedureDocumentationVisitor.java @@ -5,10 +5,13 @@ import javax.xml.bind.JAXBException; +import com.openedge.pdt.core.ast.ASTNode; import com.openedge.pdt.core.ast.ProcedureDeclaration; +import com.openedge.pdt.core.ast.ProgressParserTokenTypes; +import com.openedge.pdt.core.ast.ProgressTokenTypes; +import com.openedge.pdt.core.ast.model.IASTNode; import com.openedge.pdt.core.ast.visitor.ASTVisitor; -import eu.rssw.parser.ParserUtils; import eu.rssw.rcode.Parameter; import eu.rssw.rcode.ParameterMode; import eu.rssw.rcode.Procedure; @@ -45,7 +48,7 @@ public boolean visit(ProcedureDeclaration decl) { Procedure method = new Procedure(); method.procedureName = decl.getName(); method.signature = decl.getSignature(); - method.procedureComment = ParserUtils.findPreviousComment(decl); + method.procedureComment = findPreviousComment(decl); cu.procedures.add(method); if (decl.getParameters() != null) { @@ -66,4 +69,23 @@ public boolean visit(ProcedureDeclaration decl) { return true; } + /** + * Renvoie le *dernier* commentaire + * + * @param node + * @return + */ + public static String findPreviousComment(ASTNode node) { + if ((node.getHiddenPrevious() != null) && (node.getHiddenPrevious().getType() == ProgressTokenTypes.ML__COMMENT)) { + return node.getHiddenPrevious().getText(); + } + IASTNode n = node.getPrevSibling(); + while ((n != null) && (n.getType() == ProgressParserTokenTypes.ANNOTATION)) { + if ((n.getHiddenPrevious() != null) && (n.getHiddenPrevious().getType() == ProgressTokenTypes.ML__COMMENT)) + return n.getHiddenPrevious().getText(); + n = n.getPrevSibling(); + } + return null; + } + } \ No newline at end of file diff --git a/src/java/eu/rssw/pct/oedoc/antlib.xml b/src/java/eu/rssw/pct/oedoc/antlib.xml index f8322fcae..64d4c7229 100644 --- a/src/java/eu/rssw/pct/oedoc/antlib.xml +++ b/src/java/eu/rssw/pct/oedoc/antlib.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/java/extras115.properties b/src/java/extras115.properties new file mode 100644 index 000000000..939f45387 --- /dev/null +++ b/src/java/extras115.properties @@ -0,0 +1,3 @@ +ClassDocumentation=eu.rssw.pct.oedoc.OpenEdgeDocumentation115 +HTMLDocumentation=eu.rssw.pct.oedoc.OpenEdgeHTMLDocumentation +XMLDocumentation=eu.rssw.pct.oedoc.OpenEdgeXMLDocumentation diff --git a/tests/ClassDocumentation/test1/build.xml b/tests/ClassDocumentation/test1/build.xml index 7637391fc..f0a678524 100644 --- a/tests/ClassDocumentation/test1/build.xml +++ b/tests/ClassDocumentation/test1/build.xml @@ -1,6 +1,6 @@ - + diff --git a/tests/ClassDocumentation/test3/build.xml b/tests/ClassDocumentation/test3/build.xml index b686af0f7..7a7c8d8c6 100644 --- a/tests/ClassDocumentation/test3/build.xml +++ b/tests/ClassDocumentation/test3/build.xml @@ -1,6 +1,6 @@ - + diff --git a/tests/ClassDocumentation/test4/build.xml b/tests/ClassDocumentation/test4/build.xml index 0e38248ba..79396ca48 100644 --- a/tests/ClassDocumentation/test4/build.xml +++ b/tests/ClassDocumentation/test4/build.xml @@ -1,6 +1,6 @@ - + diff --git a/tests/ClassDocumentation/test5/build.xml b/tests/ClassDocumentation/test5/build.xml index 7e12f962b..8093a5c43 100644 --- a/tests/ClassDocumentation/test5/build.xml +++ b/tests/ClassDocumentation/test5/build.xml @@ -1,6 +1,6 @@ - +