/** * erlyberly, erlang trace debugger * Copyright (C) 2016 Andy Till * * 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/>. */ package erlyberly; import com.ericsson.otp.erlang.OtpErlangAtom; import com.ericsson.otp.erlang.OtpErlangLong; import com.ericsson.otp.erlang.OtpErlangObject; import com.ericsson.otp.erlang.OtpErlangTuple; public class ModFunc implements Comparable<ModFunc> { private final String moduleName; private final String funcName; private final int arity; private final boolean exported; private final boolean synthetic; public ModFunc(String moduleName, String funcName, int arity, boolean exported, boolean synthetic) { this.moduleName = (moduleName != null) ? moduleName.replace("'", "") : null; this.funcName = (funcName != null) ? funcName.replace("'", "") : null; this.arity = arity; this.exported = exported; this.synthetic = synthetic; } public String getModuleName() { return moduleName; } public String getFuncName() { return funcName; } public int getArity() { return arity; } public boolean isExported() { return exported; } public boolean isSynthetic() { return synthetic; } @Override public String toString() { if(funcName == null) { return ErlyBerly.getTermFormatter().moduleNameToString(moduleName); } return funcName + "/" + arity; } public String toFullString() { if(funcName == null) { return ErlyBerly.getTermFormatter().moduleNameToString(moduleName); } return ErlyBerly.getTermFormatter().modFuncArityToString(moduleName, funcName, arity); } public static ModFunc toFunc(OtpErlangAtom moduleName, OtpErlangObject e, boolean exported) { OtpErlangAtom funcNameAtom = (OtpErlangAtom) ((OtpErlangTuple) e).elementAt(0); OtpErlangLong arity = (OtpErlangLong) ((OtpErlangTuple) e).elementAt(1); String funcName = funcNameAtom.atomValue(); return new ModFunc( moduleName.atomValue(), funcName, (int)arity.longValue(), exported, funcName.startsWith("-") ); } public static ModFunc toModule(OtpErlangAtom moduleName) { return new ModFunc( moduleName.atomValue(), null, 0, false, false ); } @Override public int compareTo(ModFunc o) { if(funcName == null) { return moduleName.compareTo(o.moduleName); } int comp = funcName.compareTo(o.funcName); if(comp == 0) { comp = Integer.compare(arity, o.arity); } return comp; } public boolean isModule() { return (funcName == null); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + arity; result = prime * result + ((funcName == null) ? 0 : funcName.hashCode()); result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ModFunc other = (ModFunc) obj; if (arity != other.arity) return false; if (funcName == null) { if (other.funcName != null) return false; } else if (!funcName.equals(other.funcName)) return false; if (moduleName == null) { if (other.moduleName != null) return false; } else if (!moduleName.equals(other.moduleName)) return false; return true; } public boolean isModuleInfo() { return "module_info".equals(funcName) && (arity == 0 || arity == 1); } }