package com.jantvrdik.intellij.latte.settings; import com.intellij.util.xmlb.annotations.Attribute; import org.apache.commons.lang.builder.HashCodeBuilder; import org.jetbrains.annotations.Nullable; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Objects; public class LatteArgumentSettings implements Serializable { private String name; private Type[] types; private String validType; private boolean required; private boolean repeatable; public LatteArgumentSettings() { super(); } public LatteArgumentSettings(String name, Type[] types, String validType, boolean required, boolean repeatable) { this.name = name; this.types = types; this.validType = validType; this.required = required; this.repeatable = repeatable; } public void setName(String name) { this.name = name; } public void setTypes(String types) { this.types = getTypes(types); } @Attribute("Name") public String getName() { return name; } @Attribute("Types") public String getTypes() { StringBuilder stringBuilder = new StringBuilder(); for (Type type : types) { stringBuilder.append(type.toString()); } return stringBuilder.toString(); } @Attribute("ValidType") public String getValidType() { return validType; } @Attribute("Required") public boolean isRequired() { return required; } @Attribute("Repeatable") public boolean isRepeatable() { return repeatable; } public Type[] getArgumentTypes() { return types; } public String toReadableString() { List<String> readableTypes = new ArrayList<>(); for (Type type : types) { if (type.readableString == null) { readableTypes.add(type.getPrefix() + name); } else { readableTypes.add(type.readableString); } } String outString = String.join("|", readableTypes); if (isRepeatable()) { outString = outString + ", …"; } if (!isRequired()) { outString = "[" + outString + "]"; } return outString; } public enum Type { /** match with foo, bar, foo_123, ... */ PHP_IDENTIFIER, /** match with $var, foo(), \Bar::, ... (-> | :: property|method|constant) */ PHP_EXPRESSION("expression"), /** match with PHP_EXPRESSION */ PHP_CONDITION("condition"), /** match with class names \Foo, \Foo\Bar, ... */ PHP_CLASS_NAME("ClassName"), /** match with `$var` */ VARIABLE("$", true), /** match with `$var` and mark it as definition */ VARIABLE_DEFINITION("$", true), /** match with [type] $variable = expr, and mark variable as definition */ VARIABLE_DEFINITION_EXPRESSION("[type] $variable = expr"), /** match with [type] $var and mark all variables as definition */ VARIABLE_DEFINITION_ITEM("[type] $var"), /** match with #block */ BLOCK("#block"), /** match with PHP_IDENTIFIER */ BLOCK_USAGE("block"), /** match with `none` */ NONE("none"), /** match with php types definition eg.: \Foo|string|null */ PHP_TYPE, /** match with content-type */ CONTENT_TYPE("content-type"), /** match with default, Foo:detail, handleFoo!, ... */ LINK_DESTINATION("destination"), /** match with PHP_EXPRESSION or KEY_VALUE */ LINK_PARAMETERS("param|name => param"), /** match with VARIABLE */ CONTROL("$control"), /** match with , var => value, … */ KEY_VALUE(", var => value"); private @Nullable String readableString = null; private @Nullable String prefix = null; Type() { } Type(@Nullable String readableString) { this(readableString, false); } Type(@Nullable String prefix, boolean isPrefix) { if (isPrefix) { this.prefix = prefix; } else { this.readableString = prefix; } } private String getPrefix() { return prefix != null ? prefix : ""; } } @Nullable public static Type[] getTypes(@Nullable String type) { if (type == null) { return null; } List<Type> out = new ArrayList<>(); for (String currentType : type.split(",")) { currentType = currentType.trim(); boolean valid = false; for (Type c : Type.values()) { if (c.name().equals(currentType)) { out.add(Type.valueOf(currentType.trim())); valid = true; break; } } if (!valid) { return null; } } return out.toArray(new Type[0]); } @Override public int hashCode() { return new HashCodeBuilder() .append(this.name) .append(this.getTypes()) .append(this.required) .append(this.validType) .append(this.repeatable) .toHashCode(); } @Override public boolean equals(Object obj) { return obj instanceof LatteArgumentSettings && Objects.equals(((LatteArgumentSettings) obj).name, this.name) && Objects.equals(((LatteArgumentSettings) obj).getTypes(), this.getTypes()) && Objects.equals(((LatteArgumentSettings) obj).required, this.required) && Objects.equals(((LatteArgumentSettings) obj).validType, this.validType) && Objects.equals(((LatteArgumentSettings) obj).repeatable, this.repeatable); } }