Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[apex] Add validation of ApexDoc comments #1314

Merged
merged 7 commits into from
Sep 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/

package net.sourceforge.pmd.lang.apex.ast;

public class ASTFormalComment extends AbstractApexNodeBase {
private String token;

public ASTFormalComment(String token) {
super(ASTFormalComment.class);
this.token = token;
}

@Override
Object jjtAccept(ApexParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}

public String getToken() {
return token;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@

package net.sourceforge.pmd.lang.apex.ast;

import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;

import apex.jorje.data.Location;
import apex.jorje.data.Locations;
import apex.jorje.semantic.ast.AstNode;
import apex.jorje.semantic.exception.UnexpectedCodePathException;

public abstract class AbstractApexNode<T extends AstNode> extends AbstractNode implements ApexNode<T> {
public abstract class AbstractApexNode<T extends AstNode> extends AbstractApexNodeBase implements ApexNode<T> {

protected final T node;

Expand All @@ -28,90 +26,13 @@ void calculateLineNumbers(SourceCodePositioner positioner) {
}

Location loc = node.getLoc();
int startOffset = loc.getStartIndex();
int endOffset = loc.getEndIndex();
// end column will be interpreted as inclusive, while endOffset/endIndex
// is exclusive
endOffset -= 1;

this.beginLine = positioner.lineNumberFromOffset(startOffset);
this.beginColumn = positioner.columnFromOffset(this.beginLine, startOffset);
this.endLine = positioner.lineNumberFromOffset(endOffset);
this.endColumn = positioner.columnFromOffset(this.endLine, endOffset);

if (this.endColumn < 0) {
this.endColumn = 0;
}
calculateLineNumbers(positioner, loc.getStartIndex(), loc.getEndIndex());
}

protected void handleSourceCode(String source) {
// default implementation does nothing
}

@Override
public int getBeginLine() {
if (this.beginLine > 0) {
return this.beginLine;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getBeginLine();
}
throw new RuntimeException("Unable to determine beginning line of Node.");
}

@Override
public int getBeginColumn() {
if (this.beginColumn > 0) {
return this.beginColumn;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getBeginColumn();
}
throw new RuntimeException("Unable to determine beginning column of Node.");
}

@Override
public int getEndLine() {
if (this.endLine > 0) {
return this.endLine;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getEndLine();
}
throw new RuntimeException("Unable to determine ending line of Node.");
}

@Override
public int getEndColumn() {
if (this.endColumn > 0) {
return this.endColumn;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getEndColumn();
}
throw new RuntimeException("Unable to determine ending column of Node.");
}

/**
* Accept the visitor. *
*/
@Override
public Object childrenAccept(ApexParserVisitor visitor, Object data) {
if (children != null) {
for (int i = 0; i < children.length; ++i) {
@SuppressWarnings("unchecked")
// we know that the children here are all ApexNodes
ApexNode<T> apexNode = (ApexNode<T>) children[i];
apexNode.jjtAccept(visitor, data);
}
}
return data;
}

@Override
public T getNode() {
return node;
Expand All @@ -132,15 +53,6 @@ protected boolean hasRealLoc() {
}
}




@Override
public final String getXPathNodeName() {
return this.getClass().getSimpleName().replaceFirst("^AST", "");
}


public String getLocation() {
if (hasRealLoc()) {
return String.valueOf(node.getLoc());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/

package net.sourceforge.pmd.lang.apex.ast;

import net.sourceforge.pmd.lang.ast.AbstractNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;

public abstract class AbstractApexNodeBase extends AbstractNode {

public AbstractApexNodeBase(int id) {
super(id);
}

public AbstractApexNodeBase(Class<?> klass) {
super(klass.hashCode());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all instances of a node type using this constructor would have the same id.. I'm not sure it would affect our current use, but maybe we should avoid this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind, we already did it this way.. to be revised in a different PR

}

public void calculateLineNumbers(SourceCodePositioner positioner, int startOffset, int endOffset) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should not be public - it's enough, if it can be called from classes within the same package (net.sourceforge.pmd.lang.apex.ast).

// end column will be interpreted as inclusive, while endOffset/endIndex
// is exclusive
endOffset -= 1;

this.beginLine = positioner.lineNumberFromOffset(startOffset);
this.beginColumn = positioner.columnFromOffset(this.beginLine, startOffset);
this.endLine = positioner.lineNumberFromOffset(endOffset);
this.endColumn = positioner.columnFromOffset(this.endLine, endOffset);

if (this.endColumn < 0) {
this.endColumn = 0;
}
}

/**
* Accept the visitor. *
*/
abstract Object jjtAccept(ApexParserVisitor visitor, Object data);

/**
* Accept the visitor. *
*/
public Object childrenAccept(ApexParserVisitor visitor, Object data) {
if (children != null) {
for (int i = 0; i < children.length; ++i) {
@SuppressWarnings("unchecked")
// we know that the children here are all ApexNodes
AbstractApexNodeBase apexNode = (AbstractApexNodeBase) children[i];
apexNode.jjtAccept(visitor, data);
}
}
return data;
}

@Override
public int getBeginLine() {
if (this.beginLine > 0) {
return this.beginLine;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getBeginLine();
}
throw new RuntimeException("Unable to determine beginning line of Node.");
}

@Override
public int getBeginColumn() {
if (this.beginColumn > 0) {
return this.beginColumn;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getBeginColumn();
}
throw new RuntimeException("Unable to determine beginning column of Node.");
}

@Override
public int getEndLine() {
if (this.endLine > 0) {
return this.endLine;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getEndLine();
}
throw new RuntimeException("Unable to determine ending line of Node.");
}

@Override
public int getEndColumn() {
if (this.endColumn > 0) {
return this.endColumn;
}
Node parent = jjtGetParent();
if (parent != null) {
return parent.getEndColumn();
}
throw new RuntimeException("Unable to determine ending column of Node.");
}

@Override
public final String getXPathNodeName() {
return this.getClass().getSimpleName().replaceFirst("^AST", "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package net.sourceforge.pmd.lang.apex.ast;

public interface ApexParserVisitor {
Object visit(AbstractApexNodeBase node, Object data);

Object visit(ApexNode<?> node, Object data);

Object visit(ASTAnnotation node, Object data);
Expand Down Expand Up @@ -67,6 +69,8 @@ public interface ApexParserVisitor {

Object visit(ASTFieldDeclarationStatements node, Object data);

Object visit(ASTFormalComment node, Object data);

Object visit(ASTForEachStatement node, Object data);

Object visit(ASTForLoopStatement node, Object data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
package net.sourceforge.pmd.lang.apex.ast;

public class ApexParserVisitorAdapter implements ApexParserVisitor {
@Override
public Object visit(AbstractApexNodeBase node, Object data) {
return node.childrenAccept(this, data);
}

@Override
public Object visit(ApexNode<?> node, Object data) {
return node.childrenAccept(this, data);
Expand Down Expand Up @@ -449,4 +454,9 @@ public Object visit(ASTNewKeyValueObjectExpression node, Object data) {
public Object visit(ASTStatementExecuted node, Object data) {
return visit((ApexNode<?>) node, data);
}

@Override
public Object visit(ASTFormalComment node, Object data) {
return visit((AbstractApexNodeBase) node, data);
}
}
Loading