PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/content/file/FileComponentReferences.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 596 lines | 478 code | 47 blank | 71 comment | 82 complexity | fe263f928ead79247e5699a0f967077f MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2010 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.cnd.modelimpl.content.file;
  43. import java.io.IOException;
  44. import java.io.PrintWriter;
  45. import java.util.*;
  46. import java.util.concurrent.locks.ReadWriteLock;
  47. import java.util.concurrent.locks.ReentrantReadWriteLock;
  48. import java.util.logging.Level;
  49. import java.util.logging.Logger;
  50. import org.netbeans.modules.cnd.api.model.CsmFile;
  51. import org.netbeans.modules.cnd.api.model.CsmObject;
  52. import org.netbeans.modules.cnd.api.model.CsmUID;
  53. import org.netbeans.modules.cnd.api.model.util.UIDs;
  54. import org.netbeans.modules.cnd.api.model.xref.CsmReference;
  55. import org.netbeans.modules.cnd.api.model.xref.CsmReferenceKind;
  56. import org.netbeans.modules.cnd.modelimpl.csm.core.FileImpl;
  57. import org.netbeans.modules.cnd.modelimpl.csm.core.PositionManager;
  58. import org.netbeans.modules.cnd.modelimpl.csm.core.Utils;
  59. import org.netbeans.modules.cnd.modelimpl.repository.FileReferencesKey;
  60. import org.netbeans.modules.cnd.modelimpl.repository.PersistentUtils;
  61. import org.netbeans.modules.cnd.modelimpl.textcache.NameCache;
  62. import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
  63. import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
  64. import org.netbeans.modules.cnd.modelimpl.uid.UIDProviderIml;
  65. import org.netbeans.modules.cnd.repository.spi.Persistent;
  66. import org.netbeans.modules.cnd.repository.spi.RepositoryDataInput;
  67. import org.netbeans.modules.cnd.repository.spi.RepositoryDataOutput;
  68. import org.netbeans.modules.cnd.repository.support.SelfPersistent;
  69. /**
  70. *
  71. * @author Alexander Simon
  72. */
  73. public class FileComponentReferences extends FileComponent implements Persistent, SelfPersistent {
  74. private static final boolean TRACE = false;
  75. //private static int request = 0;
  76. //private static int request_hit = 0;
  77. //private static int respons = 0;
  78. //private static int respons_hit = 0;
  79. public static boolean isKindOf(CsmReference ref, Set<CsmReferenceKind> kinds) {
  80. return ref instanceof FileComponentReferences.ReferenceImpl && kinds.contains(ref.getKind());
  81. }
  82. private final SortedMap<ReferenceImpl, CsmUID<CsmObject>> references;
  83. private final SortedMap<ReferenceImpl, CsmUID<CsmObject>> type2classifier;
  84. private final Map<CsmUID<?>, Collection<ReferenceImpl>> obj2refs = new HashMap<CsmUID<?>, Collection<ReferenceImpl>>();
  85. private final ReadWriteLock referencesLock = new ReentrantReadWriteLock();
  86. private final CsmUID<CsmFile> fileUID;
  87. // empty stub
  88. private static final FileComponentReferences EMPTY = new FileComponentReferences() {
  89. @Override
  90. void put() {
  91. }
  92. };
  93. public static FileComponentReferences empty() {
  94. return EMPTY;
  95. }
  96. FileComponentReferences(FileComponentReferences other, boolean empty) {
  97. super(other);
  98. try {
  99. if (!empty) {
  100. other.referencesLock.readLock().lock();
  101. }
  102. references = new TreeMap<ReferenceImpl, CsmUID<CsmObject>>(
  103. empty ? Collections.<ReferenceImpl, CsmUID<CsmObject>>emptyMap() : other.references);
  104. type2classifier = new TreeMap<ReferenceImpl, CsmUID<CsmObject>>(
  105. empty ? Collections.<ReferenceImpl, CsmUID<CsmObject>>emptyMap() : other.type2classifier);
  106. } finally {
  107. if (!empty) {
  108. other.referencesLock.readLock().unlock();
  109. }
  110. }
  111. this.fileUID = other.fileUID;
  112. }
  113. public FileComponentReferences(FileImpl file) {
  114. super(new FileReferencesKey(file));
  115. references = new TreeMap<ReferenceImpl, CsmUID<CsmObject>>();
  116. type2classifier = new TreeMap<ReferenceImpl, CsmUID<CsmObject>>();
  117. this.fileUID = file.getUID();
  118. }
  119. public FileComponentReferences(RepositoryDataInput input) throws IOException {
  120. super(input);
  121. UIDObjectFactory defaultFactory = UIDObjectFactory.getDefaultFactory();
  122. fileUID = defaultFactory.readUID(input);
  123. references = defaultFactory.readReferencesSortedToUIDMap(input, fileUID);
  124. type2classifier = defaultFactory.readReferencesSortedToUIDMap(input, fileUID);
  125. int size = input.readInt();
  126. for (int i = 0; i < size; i++) {
  127. CsmUID<CsmObject> key = defaultFactory.readUID(input);
  128. int refSize = input.readInt();
  129. ArrayList<FileComponentReferences.ReferenceImpl> value = new ArrayList<FileComponentReferences.ReferenceImpl>(refSize);
  130. for (int j = 0; j < refSize; j++) {
  131. FileComponentReferences.ReferenceImpl val = new FileComponentReferences.ReferenceImpl(fileUID, key, defaultFactory, input);
  132. value.add(val);
  133. }
  134. value.trimToSize();
  135. obj2refs.put(key, value);
  136. }
  137. }
  138. // only for EMPTY static field
  139. private FileComponentReferences() {
  140. super((org.netbeans.modules.cnd.repository.spi.Key)null);
  141. references = new TreeMap<ReferenceImpl, CsmUID<CsmObject>>();
  142. type2classifier = new TreeMap<ReferenceImpl, CsmUID<CsmObject>>();
  143. fileUID = null;
  144. }
  145. public void clean() {
  146. referencesLock.writeLock().lock();
  147. try {
  148. references.clear();
  149. type2classifier.clear();
  150. obj2refs.clear();
  151. } finally {
  152. referencesLock.writeLock().unlock();
  153. }
  154. put();
  155. }
  156. public Collection<CsmReference> getReferences(Collection<CsmObject> objects) {
  157. Set<CsmUID<CsmObject>> searchFor = new HashSet<CsmUID<CsmObject>>(objects.size());
  158. for(CsmObject obj : objects) {
  159. CsmUID<CsmObject> uid = UIDs.get(obj);
  160. searchFor.add(uid);
  161. }
  162. List<CsmReference> res = new ArrayList<CsmReference>();
  163. referencesLock.readLock().lock();
  164. try {
  165. for (CsmUID<CsmObject> csmUID : searchFor) {
  166. Collection<ReferenceImpl> val = obj2refs.get(csmUID);
  167. if (val != null) {
  168. res.addAll(val);
  169. }
  170. }
  171. } finally {
  172. referencesLock.readLock().unlock();
  173. }
  174. return res;
  175. }
  176. public Collection<CsmReference> getReferences() {
  177. List<CsmReference> res = new ArrayList<CsmReference>();
  178. referencesLock.readLock().lock();
  179. try {
  180. for(Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : references.entrySet()) {
  181. res.add(entry.getKey());
  182. }
  183. } finally {
  184. referencesLock.readLock().unlock();
  185. }
  186. return res;
  187. }
  188. public CsmReference getReference(int offset) {
  189. return getReferenceImpl(offset, references);
  190. }
  191. public CsmReference getResolvedReference(CsmReference ref) {
  192. referencesLock.readLock().lock();
  193. try {
  194. for(Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : type2classifier.tailMap(new ReferenceImpl(ref.getStartOffset(), ref.getEndOffset(), ref.getText())).entrySet()) {
  195. if (entry.getKey().start == ref.getStartOffset() &&
  196. entry.getKey().end == ref.getEndOffset() &&
  197. entry.getKey().identifier.equals(ref.getText())) {
  198. //request_hit++;
  199. return entry.getKey();
  200. } else {
  201. return null;
  202. }
  203. }
  204. } finally {
  205. referencesLock.readLock().unlock();
  206. }
  207. return null;
  208. }
  209. ReferenceImpl getReferenceImpl(int offset, SortedMap<ReferenceImpl, CsmUID<CsmObject>> storage) {
  210. //if (request > 0 && request%1000 == 0) {
  211. // System.err.println("Reference statictic:");
  212. // System.err.println("\tRequest:"+request+" hit "+request_hit);
  213. // System.err.println("\tPut:"+respons+" hit "+respons_hit);
  214. //}
  215. //request++;
  216. referencesLock.readLock().lock();
  217. try {
  218. for(Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : storage.tailMap(new ReferenceImpl(offset)).entrySet()) {
  219. if (entry.getKey().start <= offset && offset < entry.getKey().end) {
  220. //request_hit++;
  221. return entry.getKey();
  222. } else {
  223. return null;
  224. }
  225. }
  226. } finally {
  227. referencesLock.readLock().unlock();
  228. }
  229. return null;
  230. }
  231. public boolean addResolvedReference(CsmReference ref, CsmObject cls) {
  232. return addReferenceImpl(ref, cls, type2classifier, false);
  233. }
  234. public void removeResolvedReference(CsmReference ref) {
  235. CsmUID<CsmObject> remove;
  236. referencesLock.writeLock().lock();
  237. try {
  238. remove = type2classifier.remove(new ReferenceImpl(ref.getStartOffset(), ref.getEndOffset(), ref.getText()));
  239. } finally {
  240. referencesLock.writeLock().unlock();
  241. }
  242. if (remove != null) {
  243. put();
  244. }
  245. }
  246. public boolean addReference(CsmReference ref, CsmObject referencedObject) {
  247. return addReferenceImpl(ref, referencedObject, references, true);
  248. }
  249. private boolean addReferenceImpl(CsmReference ref, CsmObject referencedObject, Map<ReferenceImpl, CsmUID<CsmObject>> storage, boolean index) {
  250. //respons++;
  251. if (!UIDCsmConverter.isIdentifiable(referencedObject)) {
  252. // ignore local references
  253. if (TRACE) {
  254. new Exception("Ignore reference to local object "+referencedObject).printStackTrace(System.err); // NOI18N
  255. }
  256. return false;
  257. }
  258. CsmUID<CsmObject> referencedUID = UIDs.get(referencedObject);
  259. if (!UIDProviderIml.isPersistable(referencedUID)) {
  260. // ignore local references
  261. if (TRACE) {
  262. new Exception("Ignore reference to local object "+referencedObject).printStackTrace(System.err); // NOI18N
  263. }
  264. return false;
  265. }
  266. CsmObject owner = ref.getOwner(); // storing
  267. CsmUID<CsmObject> ownerUID = getUID(owner, "Ignore local owners ", TRACE); // NOI18N
  268. CsmObject closestTopLevelObject = ref.getClosestTopLevelObject();
  269. CsmUID<CsmObject> closestTopLevelObjectUID = getUID(closestTopLevelObject, "Why local top level object? ", true); // NOI18N
  270. assert closestTopLevelObjectUID == null || UIDProviderIml.isPersistable(closestTopLevelObjectUID) : "not persistable top level object " + closestTopLevelObject;
  271. ReferenceImpl refImpl = new ReferenceImpl(fileUID, ref, referencedUID, ownerUID, closestTopLevelObjectUID);
  272. //if (ref.getContainingFile().getAbsolutePath().toString().endsWith("ConjunctionScorer.cpp")) {
  273. // if (("sort".contentEquals(ref.getText())) && ref.getStartOffset() == 1478) {
  274. // Logger.getLogger("xRef").log(Level.INFO, "{0} \n with {1} \n and owner {2}\n", new Object[]{ref, referencedObject, ownerUID});
  275. // }
  276. //}
  277. referencesLock.writeLock().lock();
  278. try {
  279. CsmUID<CsmObject> old = storage.put(refImpl, referencedUID);
  280. if (index) {
  281. if (!referencedUID.equals(old) && old != null) {
  282. Collection<ReferenceImpl> refsToOld = obj2refs.get(old);
  283. if (refsToOld != null) {
  284. refsToOld.remove(refImpl);
  285. if (refsToOld.isEmpty()) {
  286. obj2refs.remove(old);
  287. }
  288. }
  289. }
  290. Collection<FileComponentReferences.ReferenceImpl> value = obj2refs.get(referencedUID);
  291. if (value == null) {
  292. value = new HashSet<ReferenceImpl>(1);
  293. obj2refs.put(referencedUID, value);
  294. }
  295. value.add(refImpl);
  296. }
  297. } finally {
  298. referencesLock.writeLock().unlock();
  299. }
  300. put();
  301. //respons_hit++;
  302. if (index) {
  303. ReferencesIndex.put(referencedUID, fileUID, refImpl);
  304. }
  305. return true;
  306. }
  307. private CsmUID<CsmObject> getUID(CsmObject csmObject, String warning, boolean trace) {
  308. CsmUID<CsmObject> csmObjectUID = null;
  309. if (csmObject != null) {
  310. if (UIDCsmConverter.isIdentifiable(csmObject)) {
  311. CsmUID<CsmObject> aClosestTopLevelObjectUID = UIDs.get(csmObject);
  312. if (UIDProviderIml.isPersistable(aClosestTopLevelObjectUID)) {
  313. csmObjectUID = aClosestTopLevelObjectUID;
  314. } else {
  315. if (trace) {
  316. Utils.LOG.log(Level.WARNING, "{0} {1}\n {2}", new Object[] {warning, csmObject, new Exception()});
  317. }
  318. }
  319. } else {
  320. if (trace) {
  321. Utils.LOG.log(Level.WARNING, "{0} {1}\n {2}", new Object[] {warning, csmObject, new Exception()});
  322. }
  323. }
  324. }
  325. return csmObjectUID;
  326. }
  327. @Override
  328. public void write(RepositoryDataOutput out) throws IOException {
  329. super.write(out);
  330. UIDObjectFactory defaultFactory = UIDObjectFactory.getDefaultFactory();
  331. defaultFactory.writeUID(fileUID, out);
  332. referencesLock.readLock().lock();
  333. try {
  334. out.writeInt(references.size());
  335. for(Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : references.entrySet()) {
  336. defaultFactory.writeUID(entry.getValue(), out);
  337. entry.getKey().write(defaultFactory, out);
  338. }
  339. out.writeInt(type2classifier.size());
  340. for(Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : type2classifier.entrySet()) {
  341. defaultFactory.writeUID(entry.getValue(), out);
  342. entry.getKey().write(defaultFactory, out);
  343. }
  344. out.writeInt(obj2refs.size());
  345. for (Map.Entry<CsmUID<?>, Collection<FileComponentReferences.ReferenceImpl>> entry : obj2refs.entrySet()) {
  346. defaultFactory.writeUID(entry.getKey(), out);
  347. Collection<ReferenceImpl> value = entry.getValue();
  348. out.writeInt(value.size());
  349. for (ReferenceImpl referenceImpl : value) {
  350. referenceImpl.write(defaultFactory, out);
  351. }
  352. }
  353. } finally {
  354. referencesLock.readLock().unlock();
  355. }
  356. }
  357. public void dump(PrintWriter printOut) {
  358. printOut.printf("Has %d references:\n", references.size());// NOI18N
  359. for (Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : references.entrySet()) {
  360. printOut.printf("ref %s\n\t%s:\n", entry.getKey().toString(true), entry.getValue());// NOI18N
  361. }
  362. printOut.printf("Has %d type2classifier:\n", type2classifier.size());// NOI18N
  363. for (Map.Entry<ReferenceImpl, CsmUID<CsmObject>> entry : type2classifier.entrySet()) {
  364. printOut.printf("type ref %s\n\t%s:\n", entry.getKey().toString(true), entry.getValue());// NOI18N
  365. }
  366. printOut.printf("Has %d obj2refs:\n", obj2refs.size());// NOI18N
  367. int refNum = 0;
  368. for (Map.Entry<CsmUID<?>, Collection<FileComponentReferences.ReferenceImpl>> entry : obj2refs.entrySet()) {
  369. printOut.printf("refs on %s:\n", entry.getKey());// NOI18N
  370. Collection<ReferenceImpl> value = new TreeSet<ReferenceImpl>(ReferencesIndex.REF_COMPARATOR);
  371. value.addAll(entry.getValue());
  372. refNum += value.size();
  373. int index = 1;
  374. for (ReferenceImpl referenceImpl : value) {
  375. printOut.printf("[%d] %s\n", index++, referenceImpl.toString(true));// NOI18N
  376. }
  377. }
  378. if (refNum != references.size()) {
  379. printOut.printf("DIFFERENT number of references refs=%d vs obj2refs=%d:\n", references.size(), refNum);// NOI18N
  380. }
  381. }
  382. public static final class ReferenceImpl implements CsmReference, Comparable<ReferenceImpl>{
  383. private final CsmUID<CsmFile> file;
  384. private final CsmReferenceKind refKind;
  385. private final CsmUID<CsmObject> refObj;
  386. private final int start;
  387. private final int end;
  388. private final CharSequence identifier;
  389. private final CsmUID<CsmObject> ownerUID;
  390. private final CsmUID<CsmObject> closestTopLevelObjectUID;
  391. // to search
  392. private ReferenceImpl(int start) {
  393. this.start = start;
  394. this.end = start;
  395. this.file = null;
  396. this.refKind = null;
  397. this.refObj = null;
  398. this.identifier = null;
  399. this.ownerUID = null;
  400. this.closestTopLevelObjectUID = null;
  401. }
  402. // to remove
  403. private ReferenceImpl(int start, int end, CharSequence identifier) {
  404. this.start = start;
  405. this.end = end;
  406. this.file = null;
  407. this.refKind = null;
  408. this.refObj = null;
  409. this.identifier = identifier;
  410. this.ownerUID = null;
  411. this.closestTopLevelObjectUID = null;
  412. }
  413. private ReferenceImpl(CsmUID<CsmFile> fileUID, CsmReference delegate, CsmUID<CsmObject> refObj, CsmUID<CsmObject> ownerUID, CsmUID<CsmObject> closestTopLevelObjectUID) {
  414. this.file = fileUID;
  415. this.refKind = delegate.getKind();
  416. this.refObj = refObj;
  417. assert refObj != null;
  418. this.start = PositionManager.createPositionID(fileUID, delegate.getStartOffset(), PositionManager.Position.Bias.FOWARD);
  419. this.end = PositionManager.createPositionID(fileUID, delegate.getEndOffset(), PositionManager.Position.Bias.BACKWARD);
  420. this.identifier = NameCache.getManager().getString(delegate.getText());
  421. this.ownerUID = ownerUID;
  422. this.closestTopLevelObjectUID = closestTopLevelObjectUID;
  423. }
  424. public ReferenceImpl(CsmUID<CsmFile> fileUID, CsmUID<CsmObject> refObj, UIDObjectFactory defaultFactory, RepositoryDataInput input) throws IOException {
  425. this.file = fileUID;
  426. this.refObj = refObj;
  427. assert refObj != null;
  428. this.start = input.readInt();
  429. this.end = input.readInt();
  430. this.identifier = PersistentUtils.readUTF(input, NameCache.getManager());
  431. this.refKind = CsmReferenceKind.values()[input.readByte()];
  432. this.ownerUID = defaultFactory.readUID(input);
  433. this.closestTopLevelObjectUID = defaultFactory.readUID(input);
  434. }
  435. void write(UIDObjectFactory defaultFactory, RepositoryDataOutput out) throws IOException {
  436. out.writeInt(this.start);
  437. out.writeInt(this.end);
  438. PersistentUtils.writeUTF(identifier, out);
  439. out.writeByte(this.refKind.ordinal());
  440. defaultFactory.writeUID(this.ownerUID, out);
  441. defaultFactory.writeUID(this.closestTopLevelObjectUID, out);
  442. }
  443. @Override
  444. public CsmReferenceKind getKind() {
  445. return refKind;
  446. }
  447. @Override
  448. public CsmObject getReferencedObject() {
  449. CsmObject out = UIDCsmConverter.UIDtoCsmObject(refObj);
  450. if (out == null) {
  451. Logger.getLogger("xRef").log(Level.FINE, "how can we store nulls? {0}", refObj); // NOI18N
  452. }
  453. return out;
  454. }
  455. @Override
  456. public CsmObject getOwner() {
  457. return UIDCsmConverter.UIDtoCsmObject(ownerUID);
  458. }
  459. @Override
  460. public CsmObject getClosestTopLevelObject() {
  461. return UIDCsmConverter.UIDtoCsmObject(closestTopLevelObjectUID);
  462. }
  463. @Override
  464. public CsmFile getContainingFile() {
  465. return file.getObject();
  466. }
  467. public CsmUID<CsmFile> getContainingFileUID() {
  468. return file;
  469. }
  470. @Override
  471. public int getStartOffset() {
  472. return PositionManager.getOffset(file, start);
  473. }
  474. @Override
  475. public int getEndOffset() {
  476. return PositionManager.getOffset(file, end);
  477. }
  478. @Override
  479. public Position getStartPosition() {
  480. return PositionManager.getPosition(file, start);
  481. }
  482. @Override
  483. public Position getEndPosition() {
  484. return PositionManager.getPosition(file, end);
  485. }
  486. @Override
  487. public CharSequence getText() {
  488. return identifier;
  489. }
  490. @Override
  491. public int hashCode() {
  492. int hash = 5;
  493. hash = 17 * hash + this.start;
  494. hash = 17 * hash + this.end;
  495. hash = 17 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
  496. return hash;
  497. }
  498. @Override
  499. public boolean equals(Object obj) {
  500. if (obj == null) {
  501. return false;
  502. }
  503. if (getClass() != obj.getClass()) {
  504. return false;
  505. }
  506. final ReferenceImpl other = (ReferenceImpl) obj;
  507. if (this.start != other.start) {
  508. return false;
  509. }
  510. if (this.end != other.end) {
  511. return false;
  512. }
  513. if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
  514. return false;
  515. }
  516. return true;
  517. }
  518. @Override
  519. public int compareTo(ReferenceImpl o) {
  520. int res = start - o.end;
  521. if (res > 0) {
  522. return res;
  523. }
  524. res = end - o.start;
  525. if (res < 0) {
  526. return res;
  527. }
  528. // we are equal now
  529. res = 0;
  530. if (identifier != null && o.identifier != null) {
  531. res = identifier.hashCode() - o.identifier.hashCode();
  532. }
  533. return res;
  534. }
  535. @Override
  536. public String toString() {
  537. return toString(false);
  538. }
  539. /*package*/ String toString(boolean minimal) {
  540. if (minimal) {
  541. String stString = PositionManager.getPosition(file, start).toString();
  542. String endString = PositionManager.getPosition(file, end).toString();
  543. return identifier+"["+stString+"-"+endString+"] refKind=" + refKind; // NOI18N
  544. } else {
  545. return identifier+"["+start+","+end+"] file=" + file + ";refKind=" + refKind + ";refObj=" + refObj + ";topUID=" + closestTopLevelObjectUID + ";ownerUID=" + ownerUID + '}'; // NOI18N
  546. }
  547. }
  548. }
  549. }