001 // This file is part of the RECODER library and protected by the LGPL.
002
003 package recoder.abstraction;
004
005 import recoder.NamedModelElement;
006 import recoder.bytecode.AccessFlags;
007 import recoder.convenience.Format;
008 import recoder.service.ProgramModelInfo;
009 import recoder.util.Order;
010
011 /**
012 * An entity of the program meta model.
013 *
014 * @author AL
015 * @author RN
016 */
017 public interface ProgramModelElement extends NamedModelElement, AccessFlags {
018
019 /**
020 * Returns the maximal expanded name including all applicable qualifiers.
021 *
022 * @return the full name of this program model element.
023 */
024 String getFullName();
025
026 /**
027 * Returns the <i>binary</i> name. The binary name
028 * is the name this program model element would have in bytecode, i.e.,
029 * how it either is read by the bytecode parser, or the name a compiler
030 * would give this element during the compilation process (if this program
031 * model element is represented in source code).
032 * See JLS, §13.1
033 * @since 0.92
034 * <!--@param useSlashes if <code>true</code>, slashes are used instead of dots in
035 * the result, e.g., java/lang/Object instead of java.lang.Object.-->
036 * @return the bytecode name of this program model element
037 */
038 String getBinaryName();
039
040 /**
041 * Returns the instance that can retrieve information about this program
042 * model element.
043 *
044 * @return the program model info of this element.
045 */
046 ProgramModelInfo getProgramModelInfo();
047
048 /**
049 * Sets the instance that can retrieve information about this program model
050 * element. Should not be called from outside a service.
051 *
052 * @param pmi
053 * the program model info to be used for this element.
054 */
055 void setProgramModelInfo(ProgramModelInfo pmi);
056
057 /**
058 * Lexical order objects comparing full names. For partial names, use the
059 * corresponding order of {@link recoder.NamedModelElement}.
060 */
061 Order LEXICAL_ORDER = new LexicalOrder();
062
063 /**
064 * Lexical order on full names of program model elements. For partial names,
065 * use the corresponding order of {@link recoder.NamedModelElement}. Null
066 * elements are considered as empty strings. Program elements are kept
067 * unambiguous by attaching source code file name and positions.
068 */
069 class LexicalOrder implements Order {
070 public final int hashCode(Object x) {
071 if (x == null) {
072 return 0;
073 }
074 String name = Format.toString("%N|%p|%u", (ProgramModelElement) x);
075 if (name == null) {
076 return 0;
077 }
078 return name.hashCode();
079 }
080
081 @SuppressWarnings("all") public final boolean isComparable(Object x, Object y) {
082 return true;
083 }
084
085 private int diff(ProgramModelElement n1, ProgramModelElement n2) {
086 if (n1 == n2) {
087 return 0;
088 }
089 String s1 = (n1 == null) ? "" : Format.toString("%N", n1);
090 String s2 = (n2 == null) ? "" : Format.toString("%N", n2);
091 int res = diff(s1, s2);
092 if (res == 0) {
093 s1 = Format.toString("%p|%u", n1);
094 s2 = Format.toString("%p|%u", n2);
095 res = diff(s1, s2);
096 }
097 return res;
098 }
099
100 private int diff(String s1, String s2) {
101 if (s1 == null) {
102 s1 = "";
103 }
104 if (s2 == null) {
105 s2 = "";
106 }
107 int len1 = s1.length();
108 int len2 = s2.length();
109 for (int i = 0, m = Math.min(len1, len2); i < m; i++) {
110 char c1 = s1.charAt(i);
111 char c2 = s2.charAt(i);
112 if (c1 != c2) {
113 return c1 - c2;
114 }
115 }
116 return len1 - len2;
117 }
118
119 public final boolean equals(Object x, Object y) {
120 return diff((ProgramModelElement) x, (ProgramModelElement) y) == 0;
121 }
122
123 public final boolean less(Object x, Object y) {
124 return diff((ProgramModelElement) x, (ProgramModelElement) y) < 0;
125 }
126
127 public final boolean greater(Object x, Object y) {
128 return diff((ProgramModelElement) x, (ProgramModelElement) y) > 0;
129 }
130
131 public final boolean lessOrEquals(Object x, Object y) {
132 return diff((ProgramModelElement) x, (ProgramModelElement) y) <= 0;
133 }
134
135 public final boolean greaterOrEquals(Object x, Object y) {
136 return diff((ProgramModelElement) x, (ProgramModelElement) y) >= 0;
137 }
138 }
139 }