package org.erlide.engine.services.search; import org.erlide.engine.model.erlang.ErlangFunction; import org.erlide.util.ErlLogger; import org.erlide.util.Util; import com.ericsson.otp.erlang.OtpErlangAtom; import com.ericsson.otp.erlang.OtpErlangLong; import com.ericsson.otp.erlang.OtpErlangObject; import com.ericsson.otp.erlang.OtpErlangString; import com.ericsson.otp.erlang.OtpErlangTuple; public class OpenResult { private boolean externalCall = false; private String name; private String fun; private int arity; private String path; // TODO rewrite this to use SearchFor private boolean record = false; private boolean macro = false; private boolean localCall = false; private boolean include = false; private boolean variable = false; private boolean define = false; private boolean field = false; public OpenResult(final OtpErlangObject res) { if (!(res instanceof OtpErlangTuple)) { return; // not a call, ignore } final OtpErlangTuple openTuple = (OtpErlangTuple) res; final OtpErlangObject tag = openTuple.elementAt(0); if (!(tag instanceof OtpErlangAtom)) { return; } final String kind = ((OtpErlangAtom) tag).atomValue(); try { if ("external".equals(kind)) { final OtpErlangAtom element = (OtpErlangAtom) openTuple.elementAt(1); externalCall = true; name = element.atomValue(); fun = ((OtpErlangAtom) openTuple.elementAt(2)).atomValue(); arity = ((OtpErlangLong) openTuple.elementAt(3)).intValue(); path = null; if (openTuple.arity() > 4 && openTuple.elementAt(4) instanceof OtpErlangString) { path = ((OtpErlangString) openTuple.elementAt(4)).stringValue(); } } else if ("include".equals(kind)) { include = true; name = Util.stringValue(openTuple.elementAt(1)); } else if ("include_lib".equals(kind)) { include = true; name = Util.stringValue(openTuple.elementAt(1)); path = Util.stringValue(openTuple.elementAt(2)); } else if ("local".equals(kind)) { // local call localCall = true; final OtpErlangAtom element = (OtpErlangAtom) openTuple.elementAt(1); fun = element.atomValue(); arity = ((OtpErlangLong) openTuple.elementAt(2)).intValue(); // } else if (external.equals("variable")) { // final OtpErlangTuple mf = (OtpErlangTuple) tres.elementAt(1); // final OtpErlangAtom var = (OtpErlangAtom) mf.elementAt(0); } else if (kind.startsWith("record") || kind.startsWith("macro")) { macro = kind.startsWith("macro"); record = kind.startsWith("record"); define = kind.endsWith("_def"); final OtpErlangAtom element = (OtpErlangAtom) openTuple.elementAt(1); name = element.toString(); if (macro) { name = removeQuestionMark(name); } } else if ("variable".equals(kind)) { variable = true; final OtpErlangObject o = openTuple.elementAt(1); if (o instanceof OtpErlangTuple) { final OtpErlangTuple t = (OtpErlangTuple) o; final OtpErlangAtom a = (OtpErlangAtom) t.elementAt(0); name = a.atomValue(); } else if (o instanceof OtpErlangAtom) { final OtpErlangAtom a = (OtpErlangAtom) o; name = a.atomValue(); } } else if ("field".equals(kind)) { field = true; final OtpErlangAtom recordNameA = (OtpErlangAtom) openTuple.elementAt(1); fun = recordNameA.atomValue(); final OtpErlangAtom fieldNameA = (OtpErlangAtom) openTuple.elementAt(2); name = fieldNameA.atomValue(); } } catch (final Exception e) { ErlLogger.warn(e); } } public static String removeQuestionMark(final String name) { final int i = name.indexOf('?'); if (i == 0 || i == 1) { return name.substring(0, i) + name.substring(i + 1); } return name; } public boolean isExternalCall() { return externalCall; } public String getName() { return name; } public String getFun() { return fun; } public int getArity() { return arity; } public ErlangFunction getFunction() { return new ErlangFunction(fun, arity); } public String getPath() { return path; } public boolean isRecord() { return record; } public boolean isMacro() { return macro; } public boolean isLocalCall() { return localCall; } public boolean isInclude() { return include; } public boolean isVariable() { return variable; } public boolean isDefine() { return define; } @Override public String toString() { final StringBuilder b = new StringBuilder("OpenResult {"); if (record) { b.append("record"); if (define) { b.append("_def"); } b.append(' ').append(name); } else if (macro) { b.append("macro"); if (define) { b.append("_def"); } b.append(' ').append(name); } else if (include) { b.append("include \"").append(name).append('"'); } else if (record) { b.append("record ").append(name); } else if (externalCall) { b.append("external "); b.append(name).append(':').append(fun).append('/').append(arity); } else if (localCall) { b.append("local ").append(fun).append('/').append(arity); } else if (variable) { b.append("variable ").append(name); } else if (field) { b.append("record_field ").append(name).append('.').append(fun); } if (path != null && path.length() > 0) { b.append(" \"").append(path).append('"'); } b.append('}'); return b.toString(); } public boolean isField() { return field; } }