/*******************************************************************************
* PSHDL is a library and (trans-)compiler for PSHDL input. It generates
* output suitable for implementation or simulation of it.
*
* Copyright (C) 2014 Karsten Becker (feedback (at) pshdl (dot) org)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* This License does not grant permission to use the trade names, trademarks,
* service marks, or product names of the Licensor, except as required for
* reasonable and customary use in describing the origin of the Work.
*
* Contributors:
* Karsten Becker - initial API and implementation
******************************************************************************/
package org.pshdl.model.impl;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.pshdl.model.HDLClass;
import org.pshdl.model.HDLEnum;
import org.pshdl.model.HDLExpression;
import org.pshdl.model.HDLFunctionParameter;
import org.pshdl.model.HDLFunctionParameter.RWType;
import org.pshdl.model.HDLFunctionParameter.Type;
import org.pshdl.model.HDLInterface;
import org.pshdl.model.HDLObject;
import org.pshdl.model.HDLVariable;
import org.pshdl.model.IHDLObject;
import org.pshdl.model.extensions.ScopingExtension;
import org.pshdl.model.utils.CopyFilter;
import org.pshdl.model.utils.HDLProblemException;
import org.pshdl.model.utils.HDLQualifiedName;
import org.pshdl.model.validation.Problem;
import org.pshdl.model.validation.builtin.ErrorCode;
import com.google.common.base.Optional;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
@SuppressWarnings("all")
public abstract class AbstractHDLFunctionParameter extends HDLObject {
/**
* Constructs a new instance of {@link AbstractHDLFunctionParameter}
*
* @param container
* the value for container. Can be <code>null</code>.
* @param rw
* the value for rw. If <code>null</code>, {@link RWType#READ} is
* used as default.
* @param type
* the value for type. Can <b>not</b> be <code>null</code>.
* @param enumSpec
* the value for enumSpec. Can be <code>null</code>.
* @param ifSpec
* the value for ifSpec. Can be <code>null</code>.
* @param funcSpec
* the value for funcSpec. Can be <code>null</code>.
* @param funcReturnSpec
* the value for funcReturnSpec. Can be <code>null</code>.
* @param name
* the value for name. Can be <code>null</code>.
* @param width
* the value for width. Can be <code>null</code>.
* @param dim
* the value for dim. Can be <code>null</code>.
* @param constant
* the value for constant. Can <b>not</b> be <code>null</code>.
* @param validate
* if <code>true</code> the parameters will be validated.
*/
public AbstractHDLFunctionParameter(int id, @Nullable IHDLObject container, @Nullable RWType rw, @Nonnull Type type, @Nullable HDLQualifiedName enumSpec,
@Nullable HDLQualifiedName ifSpec, @Nullable Iterable<HDLFunctionParameter> funcSpec, @Nullable HDLFunctionParameter funcReturnSpec, @Nullable HDLVariable name,
@Nullable HDLExpression width, @Nullable Iterable<HDLExpression> dim, @Nonnull Boolean constant, boolean validate) {
super(id, container, validate);
if (validate) {
rw = validateRw(rw);
}
this.rw = rw;
if (validate) {
type = validateType(type);
}
this.type = type;
if (validate) {
enumSpec = validateEnumSpec(enumSpec);
}
this.enumSpec = enumSpec;
if (validate) {
ifSpec = validateIfSpec(ifSpec);
}
this.ifSpec = ifSpec;
if (validate) {
funcSpec = validateFuncSpec(funcSpec);
}
this.funcSpec = new ArrayList<HDLFunctionParameter>();
if (funcSpec != null) {
for (final HDLFunctionParameter newValue : funcSpec) {
this.funcSpec.add(newValue);
}
}
if (validate) {
funcReturnSpec = validateFuncReturnSpec(funcReturnSpec);
}
if (funcReturnSpec != null) {
this.funcReturnSpec = funcReturnSpec;
} else {
this.funcReturnSpec = null;
}
if (validate) {
name = validateName(name);
}
if (name != null) {
this.name = name;
} else {
this.name = null;
}
if (validate) {
width = validateWidth(width);
}
if (width != null) {
this.width = width;
} else {
this.width = null;
}
if (validate) {
dim = validateDim(dim);
}
this.dim = new ArrayList<HDLExpression>();
if (dim != null) {
for (final HDLExpression newValue : dim) {
this.dim.add(newValue);
}
}
if (validate) {
constant = validateConstant(constant);
}
this.constant = constant;
}
public AbstractHDLFunctionParameter() {
super();
this.rw = null;
this.type = null;
this.enumSpec = null;
this.ifSpec = null;
this.funcSpec = new ArrayList<HDLFunctionParameter>();
this.funcReturnSpec = null;
this.name = null;
this.width = null;
this.dim = new ArrayList<HDLExpression>();
this.constant = null;
}
protected final RWType rw;
/**
* Get the rw field. If <code>null</code>, {@link RWType#READ} is used as
* default.
*
* @return the field
*/
@Nonnull
public RWType getRw() {
return rw == null ? RWType.READ : rw;
}
protected RWType validateRw(RWType rw) {
return rw == null ? RWType.READ : rw;
}
protected final Type type;
/**
* Get the type field. Can <b>not</b> be <code>null</code>.
*
* @return the field
*/
@Nonnull
public Type getType() {
return type;
}
protected Type validateType(Type type) {
if (type == null)
throw new IllegalArgumentException("The field type can not be null!");
return type;
}
protected final HDLQualifiedName enumSpec;
@Nullable
public Optional<HDLEnum> resolveEnumSpec() {
if (!frozen)
throw new IllegalArgumentException("Object not frozen");
return ScopingExtension.INST.resolveEnum(this, enumSpec);
}
public HDLQualifiedName getEnumSpecRefName() {
return enumSpec;
}
protected HDLQualifiedName validateEnumSpec(HDLQualifiedName enumSpec) {
return enumSpec;
}
protected final HDLQualifiedName ifSpec;
@Nullable
public Optional<HDLInterface> resolveIfSpec() {
if (!frozen)
throw new IllegalArgumentException("Object not frozen");
return ScopingExtension.INST.resolveInterface(this, ifSpec);
}
public HDLQualifiedName getIfSpecRefName() {
return ifSpec;
}
protected HDLQualifiedName validateIfSpec(HDLQualifiedName ifSpec) {
return ifSpec;
}
protected final ArrayList<HDLFunctionParameter> funcSpec;
/**
* Get the funcSpec field. Can be <code>null</code>.
*
* @return a clone of the field. Will never return <code>null</code>.
*/
@Nonnull
public ArrayList<HDLFunctionParameter> getFuncSpec() {
return (ArrayList<HDLFunctionParameter>) funcSpec.clone();
}
protected Iterable<HDLFunctionParameter> validateFuncSpec(Iterable<HDLFunctionParameter> funcSpec) {
if (funcSpec == null)
return new ArrayList<HDLFunctionParameter>();
return funcSpec;
}
protected final HDLFunctionParameter funcReturnSpec;
/**
* Get the funcReturnSpec field. Can be <code>null</code>.
*
* @return the field
*/
@Nullable
public HDLFunctionParameter getFuncReturnSpec() {
return funcReturnSpec;
}
protected HDLFunctionParameter validateFuncReturnSpec(HDLFunctionParameter funcReturnSpec) {
return funcReturnSpec;
}
protected final HDLVariable name;
/**
* Get the name field. Can be <code>null</code>.
*
* @return the field
*/
@Nullable
public HDLVariable getName() {
return name;
}
protected HDLVariable validateName(HDLVariable name) {
return name;
}
protected final HDLExpression width;
/**
* Get the width field. Can be <code>null</code>.
*
* @return the field
*/
@Nullable
public HDLExpression getWidth() {
return width;
}
protected HDLExpression validateWidth(HDLExpression width) {
return width;
}
protected final ArrayList<HDLExpression> dim;
/**
* Get the dim field. Can be <code>null</code>.
*
* @return a clone of the field. Will never return <code>null</code>.
*/
@Nonnull
public ArrayList<HDLExpression> getDim() {
return (ArrayList<HDLExpression>) dim.clone();
}
protected Iterable<HDLExpression> validateDim(Iterable<HDLExpression> dim) {
if (dim == null)
return new ArrayList<HDLExpression>();
return dim;
}
protected final Boolean constant;
/**
* Get the constant field. Can <b>not</b> be <code>null</code>.
*
* @return the field
*/
@Nonnull
public Boolean getConstant() {
return constant;
}
protected Boolean validateConstant(Boolean constant) {
if (constant == null)
throw new IllegalArgumentException("The field constant can not be null!");
return constant;
}
/**
* Creates a copy of this class with the same fields.
*
* @return a new instance of this class.
*/
@Override
@Nonnull
public HDLFunctionParameter copy() {
final HDLFunctionParameter newObject = new HDLFunctionParameter(id, null, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
copyMetaData(this, newObject, false);
return newObject;
}
/**
* Creates a copy of this class with the same fields.
*
* @return a new instance of this class.
*/
@Override
@Nonnull
public HDLFunctionParameter copyFiltered(CopyFilter filter) {
final RWType filteredrw = filter.copyObject("rw", this, rw);
final Type filteredtype = filter.copyObject("type", this, type);
final HDLQualifiedName filteredenumSpec = filter.copyObject("enumSpec", this, enumSpec);
final HDLQualifiedName filteredifSpec = filter.copyObject("ifSpec", this, ifSpec);
final ArrayList<HDLFunctionParameter> filteredfuncSpec = filter.copyContainer("funcSpec", this, funcSpec);
final HDLFunctionParameter filteredfuncReturnSpec = filter.copyObject("funcReturnSpec", this, funcReturnSpec);
final HDLVariable filteredname = filter.copyObject("name", this, name);
final HDLExpression filteredwidth = filter.copyObject("width", this, width);
final ArrayList<HDLExpression> filtereddim = filter.copyContainer("dim", this, dim);
final Boolean filteredconstant = filter.copyObject("constant", this, constant);
return filter.postFilter((HDLFunctionParameter) this, new HDLFunctionParameter(id, null, filteredrw, filteredtype, filteredenumSpec, filteredifSpec, filteredfuncSpec,
filteredfuncReturnSpec, filteredname, filteredwidth, filtereddim, filteredconstant, false));
}
/**
* Creates a deep copy of this class with the same fields and freezes it.
*
* @return a new instance of this class.
*/
@Override
@Nonnull
public HDLFunctionParameter copyDeepFrozen(IHDLObject container) {
final HDLFunctionParameter copy = copyFiltered(CopyFilter.DEEP_META);
copy.freeze(container);
return copy;
}
/**
* Setter for the field {@link #getContainer()}.
*
* @param container
* sets the new container of this object. Can be
* <code>null</code>.
* @return the same instance of {@link HDLFunctionParameter} with the
* updated container field.
*/
@Override
@Nonnull
public HDLFunctionParameter setContainer(@Nullable IHDLObject container) {
return (HDLFunctionParameter) super.setContainer(container);
}
/**
* Setter for the field {@link #getRw()}.
*
* @param rw
* sets the new rw of this object. If <code>null</code>,
* {@link RWType#READ} is used as default.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* rw field.
*/
@Nonnull
public HDLFunctionParameter setRw(@Nullable RWType rw) {
rw = validateRw(rw);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getType()}.
*
* @param type
* sets the new type of this object. Can <b>not</b> be
* <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* type field.
*/
@Nonnull
public HDLFunctionParameter setType(@Nonnull Type type) {
type = validateType(type);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getEnumSpec()}.
*
* @param enumSpec
* sets the new enumSpec of this object. Can be <code>null</code>
* .
* @return a new instance of {@link HDLFunctionParameter} with the updated
* enumSpec field.
*/
@Nonnull
public HDLFunctionParameter setEnumSpec(@Nullable HDLQualifiedName enumSpec) {
enumSpec = validateEnumSpec(enumSpec);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getIfSpec()}.
*
* @param ifSpec
* sets the new ifSpec of this object. Can be <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* ifSpec field.
*/
@Nonnull
public HDLFunctionParameter setIfSpec(@Nullable HDLQualifiedName ifSpec) {
ifSpec = validateIfSpec(ifSpec);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getFuncSpec()}.
*
* @param funcSpec
* sets the new funcSpec of this object. Can be <code>null</code>
* .
* @return a new instance of {@link HDLFunctionParameter} with the updated
* funcSpec field.
*/
@Nonnull
public HDLFunctionParameter setFuncSpec(@Nullable Iterable<HDLFunctionParameter> funcSpec) {
funcSpec = validateFuncSpec(funcSpec);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Adds a new value to the field {@link #getFuncSpec()}.
*
* @param newFuncSpec
* the value that should be added to the field
* {@link #getFuncSpec()}
* @return a new instance of {@link HDLFunctionParameter} with the updated
* funcSpec field.
*/
@Nonnull
public HDLFunctionParameter addFuncSpec(@Nullable HDLFunctionParameter newFuncSpec) {
if (newFuncSpec == null)
throw new IllegalArgumentException("Element of funcSpec can not be null!");
final ArrayList<HDLFunctionParameter> funcSpec = (ArrayList<HDLFunctionParameter>) this.funcSpec.clone();
funcSpec.add(newFuncSpec);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Removes a value from the field {@link #getFuncSpec()}.
*
* @param newFuncSpec
* the value that should be removed from the field
* {@link #getFuncSpec()}
* @return a new instance of {@link HDLFunctionParameter} with the updated
* funcSpec field.
*/
@Nonnull
public HDLFunctionParameter removeFuncSpec(@Nullable HDLFunctionParameter newFuncSpec) {
if (newFuncSpec == null)
throw new IllegalArgumentException("Removed element of funcSpec can not be null!");
final ArrayList<HDLFunctionParameter> funcSpec = (ArrayList<HDLFunctionParameter>) this.funcSpec.clone();
funcSpec.remove(newFuncSpec);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Removes a value from the field {@link #getFuncSpec()}.
*
* @param idx
* the index of the value that should be removed from the field
* {@link #getFuncSpec()}
* @return a new instance of {@link HDLFunctionParameter} with the updated
* funcSpec field.
*/
@Nonnull
public HDLFunctionParameter removeFuncSpec(int idx) {
final ArrayList<HDLFunctionParameter> funcSpec = (ArrayList<HDLFunctionParameter>) this.funcSpec.clone();
funcSpec.remove(idx);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getFuncReturnSpec()}.
*
* @param funcReturnSpec
* sets the new funcReturnSpec of this object. Can be
* <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* funcReturnSpec field.
*/
@Nonnull
public HDLFunctionParameter setFuncReturnSpec(@Nullable HDLFunctionParameter funcReturnSpec) {
funcReturnSpec = validateFuncReturnSpec(funcReturnSpec);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getName()}.
*
* @param name
* sets the new name of this object. Can be <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* name field.
*/
@Nonnull
public HDLFunctionParameter setName(@Nullable HDLVariable name) {
name = validateName(name);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getWidth()}.
*
* @param width
* sets the new width of this object. Can be <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* width field.
*/
@Nonnull
public HDLFunctionParameter setWidth(@Nullable HDLExpression width) {
width = validateWidth(width);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getDim()}.
*
* @param dim
* sets the new dim of this object. Can be <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* dim field.
*/
@Nonnull
public HDLFunctionParameter setDim(@Nullable Iterable<HDLExpression> dim) {
dim = validateDim(dim);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Adds a new value to the field {@link #getDim()}.
*
* @param newDim
* the value that should be added to the field {@link #getDim()}
* @return a new instance of {@link HDLFunctionParameter} with the updated
* dim field.
*/
@Nonnull
public HDLFunctionParameter addDim(@Nullable HDLExpression newDim) {
if (newDim == null)
throw new IllegalArgumentException("Element of dim can not be null!");
final ArrayList<HDLExpression> dim = (ArrayList<HDLExpression>) this.dim.clone();
dim.add(newDim);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Removes a value from the field {@link #getDim()}.
*
* @param newDim
* the value that should be removed from the field
* {@link #getDim()}
* @return a new instance of {@link HDLFunctionParameter} with the updated
* dim field.
*/
@Nonnull
public HDLFunctionParameter removeDim(@Nullable HDLExpression newDim) {
if (newDim == null)
throw new IllegalArgumentException("Removed element of dim can not be null!");
final ArrayList<HDLExpression> dim = (ArrayList<HDLExpression>) this.dim.clone();
dim.remove(newDim);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Removes a value from the field {@link #getDim()}.
*
* @param idx
* the index of the value that should be removed from the field
* {@link #getDim()}
* @return a new instance of {@link HDLFunctionParameter} with the updated
* dim field.
*/
@Nonnull
public HDLFunctionParameter removeDim(int idx) {
final ArrayList<HDLExpression> dim = (ArrayList<HDLExpression>) this.dim.clone();
dim.remove(idx);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getConstant()}.
*
* @param constant
* sets the new constant of this object. Can <b>not</b> be
* <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* constant field.
*/
@Nonnull
public HDLFunctionParameter setConstant(@Nonnull Boolean constant) {
constant = validateConstant(constant);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
/**
* Setter for the field {@link #getConstant()}.
*
* @param constant
* sets the new constant of this object. Can <b>not</b> be
* <code>null</code>.
* @return a new instance of {@link HDLFunctionParameter} with the updated
* constant field.
*/
@Nonnull
public HDLFunctionParameter setConstant(boolean constant) {
constant = validateConstant(constant);
final HDLFunctionParameter res = new HDLFunctionParameter(id, container, rw, type, enumSpec, ifSpec, funcSpec, funcReturnSpec, name, width, dim, constant, false);
return res;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof AbstractHDLFunctionParameter))
return false;
if (!super.equals(obj))
return false;
final AbstractHDLFunctionParameter other = (AbstractHDLFunctionParameter) obj;
if (rw == null) {
if (other.rw != null)
return false;
} else if (!rw.equals(other.rw))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (enumSpec == null) {
if (other.enumSpec != null)
return false;
} else if (!enumSpec.equals(other.enumSpec))
return false;
if (ifSpec == null) {
if (other.ifSpec != null)
return false;
} else if (!ifSpec.equals(other.ifSpec))
return false;
if (funcSpec == null) {
if (other.funcSpec != null)
return false;
} else if (!funcSpec.equals(other.funcSpec))
return false;
if (funcReturnSpec == null) {
if (other.funcReturnSpec != null)
return false;
} else if (!funcReturnSpec.equals(other.funcReturnSpec))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (width == null) {
if (other.width != null)
return false;
} else if (!width.equals(other.width))
return false;
if (dim == null) {
if (other.dim != null)
return false;
} else if (!dim.equals(other.dim))
return false;
if (constant == null) {
if (other.constant != null)
return false;
} else if (!constant.equals(other.constant))
return false;
return true;
}
private Integer hashCache;
@Override
public int hashCode() {
if (hashCache != null)
return hashCache;
int result = super.hashCode();
final int prime = 31;
result = (prime * result) + ((rw == null) ? 0 : rw.hashCode());
result = (prime * result) + ((type == null) ? 0 : type.hashCode());
result = (prime * result) + ((enumSpec == null) ? 0 : enumSpec.hashCode());
result = (prime * result) + ((ifSpec == null) ? 0 : ifSpec.hashCode());
result = (prime * result) + ((funcSpec == null) ? 0 : funcSpec.hashCode());
result = (prime * result) + ((funcReturnSpec == null) ? 0 : funcReturnSpec.hashCode());
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
result = (prime * result) + ((width == null) ? 0 : width.hashCode());
result = (prime * result) + ((dim == null) ? 0 : dim.hashCode());
result = (prime * result) + ((constant == null) ? 0 : constant.hashCode());
hashCache = result;
return result;
}
@Override
public String toConstructionString(String spacing) {
final boolean first = true;
final StringBuilder sb = new StringBuilder();
sb.append('\n').append(spacing).append("new HDLFunctionParameter()");
if (rw != null) {
sb.append("\n").append(spacing + "\t").append(".setRw(RWType.").append(rw.name() + ")");
}
if (type != null) {
sb.append("\n").append(spacing + "\t").append(".setType(Type.").append(type.name() + ")");
}
if (enumSpec != null) {
sb.append(".setEnumSpec(HDLQualifiedName.create(\"").append(enumSpec).append("\"))");
}
if (ifSpec != null) {
sb.append(".setIfSpec(HDLQualifiedName.create(\"").append(ifSpec).append("\"))");
}
if (funcSpec != null) {
if (funcSpec.size() > 0) {
sb.append('\n').append(spacing);
for (final HDLFunctionParameter o : funcSpec) {
sb.append(".addFuncSpec(").append(o.toConstructionString(spacing + "\t\t"));
sb.append('\n').append(spacing).append(")");
}
}
}
if (funcReturnSpec != null) {
sb.append(".setFuncReturnSpec(").append(funcReturnSpec.toConstructionString(spacing + "\t")).append(")");
}
if (name != null) {
sb.append(".setName(").append(name.toConstructionString(spacing + "\t")).append(")");
}
if (width != null) {
sb.append(".setWidth(").append(width.toConstructionString(spacing + "\t")).append(")");
}
if (dim != null) {
if (dim.size() > 0) {
sb.append('\n').append(spacing);
for (final HDLExpression o : dim) {
sb.append(".addDim(").append(o.toConstructionString(spacing + "\t\t"));
sb.append('\n').append(spacing).append(")");
}
}
}
if (constant != null) {
sb.append(".setConstant(").append(constant).append(")");
}
return sb.toString();
}
@Override
public void validateAllFields(IHDLObject expectedParent, boolean checkResolve) {
super.validateAllFields(expectedParent, checkResolve);
validateRw(getRw());
validateType(getType());
validateEnumSpec(getEnumSpecRefName());
if (checkResolve && (getEnumSpecRefName() != null))
if (!resolveEnumSpec().isPresent())
throw new HDLProblemException(new Problem(ErrorCode.UNRESOLVED_REFERENCE, this, "to:" + getEnumSpecRefName()));
validateIfSpec(getIfSpecRefName());
if (checkResolve && (getIfSpecRefName() != null))
if (!resolveIfSpec().isPresent())
throw new HDLProblemException(new Problem(ErrorCode.UNRESOLVED_REFERENCE, this, "to:" + getIfSpecRefName()));
validateFuncSpec(getFuncSpec());
if (getFuncSpec() != null) {
for (final HDLFunctionParameter o : getFuncSpec()) {
o.validateAllFields(this, checkResolve);
}
}
validateFuncReturnSpec(getFuncReturnSpec());
if (getFuncReturnSpec() != null) {
getFuncReturnSpec().validateAllFields(this, checkResolve);
}
validateName(getName());
if (getName() != null) {
getName().validateAllFields(this, checkResolve);
}
validateWidth(getWidth());
if (getWidth() != null) {
getWidth().validateAllFields(this, checkResolve);
}
validateDim(getDim());
if (getDim() != null) {
for (final HDLExpression o : getDim()) {
o.validateAllFields(this, checkResolve);
}
}
validateConstant(getConstant());
}
@Override
public EnumSet<HDLClass> getClassSet() {
return EnumSet.of(HDLClass.HDLFunctionParameter, HDLClass.HDLObject);
}
@Override
public Iterator<IHDLObject> deepIterator() {
return new Iterator<IHDLObject>() {
private int pos = 0;
private Iterator<? extends IHDLObject> current;
@Override
public boolean hasNext() {
if ((current != null) && !current.hasNext()) {
current = null;
}
while (current == null) {
switch (pos++) {
case 0:
if ((funcSpec != null) && (funcSpec.size() != 0)) {
final List<Iterator<? extends IHDLObject>> iters = Lists.newArrayListWithCapacity(funcSpec.size());
for (final HDLFunctionParameter o : funcSpec) {
iters.add(Iterators.forArray(o));
iters.add(o.deepIterator());
}
current = Iterators.concat(iters.iterator());
}
break;
case 1:
if (funcReturnSpec != null) {
current = Iterators.concat(Iterators.forArray(funcReturnSpec), funcReturnSpec.deepIterator());
}
break;
case 2:
if (name != null) {
current = Iterators.concat(Iterators.forArray(name), name.deepIterator());
}
break;
case 3:
if (width != null) {
current = Iterators.concat(Iterators.forArray(width), width.deepIterator());
}
break;
case 4:
if ((dim != null) && (dim.size() != 0)) {
final List<Iterator<? extends IHDLObject>> iters = Lists.newArrayListWithCapacity(dim.size());
for (final HDLExpression o : dim) {
iters.add(Iterators.forArray(o));
iters.add(o.deepIterator());
}
current = Iterators.concat(iters.iterator());
}
break;
default:
return false;
}
}
return (current != null) && current.hasNext();
}
@Override
public IHDLObject next() {
return current.next();
}
@Override
public void remove() {
throw new IllegalArgumentException("Not supported");
}
};
}
@Override
public Iterator<IHDLObject> iterator() {
return new Iterator<IHDLObject>() {
private int pos = 0;
private Iterator<? extends IHDLObject> current;
@Override
public boolean hasNext() {
if ((current != null) && !current.hasNext()) {
current = null;
}
while (current == null) {
switch (pos++) {
case 0:
if ((funcSpec != null) && (funcSpec.size() != 0)) {
current = funcSpec.iterator();
}
break;
case 1:
if (funcReturnSpec != null) {
current = Iterators.singletonIterator(funcReturnSpec);
}
break;
case 2:
if (name != null) {
current = Iterators.singletonIterator(name);
}
break;
case 3:
if (width != null) {
current = Iterators.singletonIterator(width);
}
break;
case 4:
if ((dim != null) && (dim.size() != 0)) {
current = dim.iterator();
}
break;
default:
return false;
}
}
return (current != null) && current.hasNext();
}
@Override
public IHDLObject next() {
return current.next();
}
@Override
public void remove() {
throw new IllegalArgumentException("Not supported");
}
};
}
}