Skip to content
Permalink
Browse files
[JENKINS-38865] Move the AST classes from Groovy to Java to reduce co…
…mplexity of consumption
  • Loading branch information
stephenc committed Oct 12, 2016
1 parent df00d99 commit 817fb991530f5b520e35b0509652808d34c4d132
Showing 3 changed files with 143 additions and 85 deletions.
@@ -21,33 +21,31 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jenkinsci.plugins.pipeline.modeldefinition.ast
package org.jenkinsci.plugins.pipeline.modeldefinition.ast;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import net.sf.json.JSONArray
import net.sf.json.JSONObject
import org.codehaus.groovy.ast.ASTNode
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator
import javax.annotation.Nonnull;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.codehaus.groovy.ast.ASTNode;
import org.jenkinsci.plugins.pipeline.modeldefinition.validator.ModelValidator;

import javax.annotation.Nonnull

/**
* @author Andrew Bayer
*/
@ToString(excludes = "sourceLocation")
@EqualsAndHashCode(excludes = "sourceLocation")
@SuppressFBWarnings(value="SE_NO_SERIALVERSIONID")
public abstract class ModelASTElement {
/**
* The sourceLocation is a reference to whatever section of the original source we're parsed from corresponds to this
* element. When parsed from Pipeline Script, it's an {@link ASTNode}, and when parsed from JSON, it's a {@link JSONObject}.
*/
Object sourceLocation;
private Object sourceLocation;

ModelASTElement(Object sourceLocation) {
this.sourceLocation = sourceLocation
this.sourceLocation = sourceLocation;
}

public Object getSourceLocation() {
return sourceLocation;
}

public void setSourceLocation(Object sourceLocation) {
this.sourceLocation = sourceLocation;
}

/**
@@ -56,14 +54,14 @@ public abstract class ModelASTElement {
* @return Generally a {@link JSONObject} or {@link JSONArray} but for some leaf nodes, may be a {@link String} or
* other simple class.
*/
public abstract Object toJSON()
public abstract Object toJSON();

/**
* Translates this element and any children it may have into Pipeline Config-formatted Groovy, without any indentations.
*
* @return A simple {@link String} of Groovy code for this element and its children.
*/
public abstract String toGroovy()
public abstract String toGroovy();

/**
* Called to do whatever validation is necessary for this element. Overridden in most cases.
@@ -78,8 +76,38 @@ public void validate(@Nonnull ModelValidator validator) {
* Removes the source location value from this element.
*/
public void removeSourceLocation() {
sourceLocation = null
sourceLocation = null;
}

/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "ModelASTElement{}";
}

/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

return true;
}

/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return ModelASTElement.class.hashCode();
}
}

@@ -21,31 +21,27 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jenkinsci.plugins.pipeline.modeldefinition.ast
package org.jenkinsci.plugins.pipeline.modeldefinition.ast;

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import net.sf.json.JSONObject
import net.sf.json.JSONObject;

/**
* Represents the value in a key/value pair, as used in {@link ModelASTEnvironment}, {@link ModelASTNamedArgumentList} and elsewhere.
*
* @author Andrew Bayer
* @author Kohsuke Kawaguchi
*/
@ToString(includeSuper = true, includeSuperProperties = true)
@EqualsAndHashCode(callSuper = true)
public abstract class ModelASTValue extends ModelASTElement implements ModelASTMethodArg {
/* package */ ModelASTValue(Object sourceLocation, Object v) {
super(sourceLocation)
this.value = v
super(sourceLocation);
this.value = v;
}

Object value
private Object value;

/**
* If the value can be determined without side-effect at AST parsing time,
* this method returns true, and {@Link #getValue()} returns its value.
* this method returns true, and {@link #getValue()} returns its value.
*/
public abstract boolean isLiteral();

@@ -63,53 +59,87 @@ public abstract class ModelASTValue extends ModelASTElement implements ModelASTM
* "${foobar(x)}"
*/
public Object getValue() {
return value
return value;
}

@Override
public JSONObject toJSON() {
return new JSONObject()
.accumulate("isLiteral", isLiteral())
.accumulate("value", getValue())
.accumulate("value", getValue());
}

public static final ModelASTValue fromConstant(final Object o, Object sourceLocation) {
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}

ModelASTValue that = (ModelASTValue) o;

return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null;

}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (getValue() != null ? getValue().hashCode() : 0);
return result;
}

@Override
public String toString() {
return "ModelASTValue{" +
"value=" + value +
'}';
}

public static ModelASTValue fromConstant(final Object o, Object sourceLocation) {
return new ModelASTValue(sourceLocation, o) {
@Override
boolean isLiteral() {
public boolean isLiteral() {
return true;
}

@Override
public String toGroovy() {
if (o instanceof String) {
if (o.indexOf('\n') == -1) {
return "'${o.replace("'", "\\'")}'"
if (getValue() instanceof String) {
String str = (String) getValue();
if (str.indexOf('\n') == -1) {
return "'" + str.replace("'", "\\'") + "'";
} else {
return "\'\'\'${o.replace('\'\'\'',"\\\'\\\\'\\\\'")}\'\'\'"
return "'''" + str.replace("'''", "\\'\\'\\'") + "'''";
}
} else {
return o
return getValue().toString();
}
}
}
};
}

public static final ModelASTValue fromGString(String gstring, Object sourceLocation) {
public static ModelASTValue fromGString(final String gstring, Object sourceLocation) {
return new ModelASTValue(sourceLocation, gstring) {
@Override
boolean isLiteral() {
public boolean isLiteral() {
return false;
}

@Override
public String toGroovy() {
if (gstring.startsWith('${') && gstring.endsWith('}')) {
return gstring.substring(2, gstring.length() - 1)
String gstring = (String)getValue();
if (gstring.startsWith("${") && gstring.endsWith("}")) {
return gstring.substring(2, gstring.length() - 1);
} else {
return gstring
return gstring;
}
}
}
};
}
}
@@ -23,62 +23,62 @@
*/


package org.jenkinsci.plugins.pipeline.modeldefinition.validator

import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTAgent
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBranch
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBuildCondition
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBuildParameter
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBuildParameters
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTEnvironment
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTJobProperties
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTJobProperty
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTMethodCall
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTNotifications
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPipelineDef
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPostBuild
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStage
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTools
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTrigger
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTriggers
package org.jenkinsci.plugins.pipeline.modeldefinition.validator;

import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTAgent;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBranch;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBuildCondition;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBuildParameter;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTBuildParameters;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTEnvironment;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTJobProperties;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTJobProperty;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTMethodCall;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTNotifications;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPipelineDef;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTPostBuild;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStage;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStep;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTools;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTrigger;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTTriggers;


public interface ModelValidator {
public boolean validateElement(ModelASTAgent agent)
boolean validateElement(ModelASTAgent agent);

public boolean validateElement(ModelASTBranch branch)
boolean validateElement(ModelASTBranch branch);

public boolean validateElement(ModelASTPostBuild postBuild)
boolean validateElement(ModelASTPostBuild postBuild);

public boolean validateElement(ModelASTNotifications notifications)
boolean validateElement(ModelASTNotifications notifications);

public boolean validateElement(ModelASTBuildCondition buildCondition)
boolean validateElement(ModelASTBuildCondition buildCondition);

public boolean validateElement(ModelASTEnvironment environment)
boolean validateElement(ModelASTEnvironment environment);

public boolean validateElement(ModelASTTools tools)
boolean validateElement(ModelASTTools tools);

public boolean validateElement(ModelASTStep step)
boolean validateElement(ModelASTStep step);

public boolean validateElement(ModelASTMethodCall methodCall)
boolean validateElement(ModelASTMethodCall methodCall);

public boolean validateElement(ModelASTJobProperties jobProperties)
boolean validateElement(ModelASTJobProperties jobProperties);

public boolean validateElement(ModelASTTriggers triggers)
boolean validateElement(ModelASTTriggers triggers);

public boolean validateElement(ModelASTBuildParameters buildParameters)
boolean validateElement(ModelASTBuildParameters buildParameters);

public boolean validateElement(ModelASTJobProperty jobProperty)
boolean validateElement(ModelASTJobProperty jobProperty);

public boolean validateElement(ModelASTTrigger trigger)
boolean validateElement(ModelASTTrigger trigger);

public boolean validateElement(ModelASTBuildParameter buildParameter)
boolean validateElement(ModelASTBuildParameter buildParameter);

public boolean validateElement(ModelASTPipelineDef pipelineDef)
boolean validateElement(ModelASTPipelineDef pipelineDef);

public boolean validateElement(ModelASTStage stage)
boolean validateElement(ModelASTStage stage);

public boolean validateElement(ModelASTStages stages)
boolean validateElement(ModelASTStages stages);
}

0 comments on commit 817fb99

Please sign in to comment.