PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/netbeans-7.3/cnd.dwarfdiscovery/src/org/netbeans/modules/cnd/dwarfdiscovery/litemodel/DwarfRenderer.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 472 lines | 396 code | 29 blank | 47 comment | 118 complexity | 21d5ac082af178d8e95ce7f6967848e5 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.dwarfdiscovery.litemodel;
  43. import java.io.IOException;
  44. import java.io.PrintStream;
  45. import java.util.HashMap;
  46. import java.util.HashSet;
  47. import java.util.List;
  48. import java.util.Map;
  49. import java.util.Set;
  50. import java.util.TreeMap;
  51. import org.netbeans.modules.cnd.dwarfdump.CompilationUnit;
  52. import org.netbeans.modules.cnd.dwarfdump.CompilationUnitInterface;
  53. import org.netbeans.modules.cnd.dwarfdump.dwarf.DwarfEntry;
  54. import org.netbeans.modules.cnd.dwarfdump.dwarfconsts.TAG;
  55. import org.netbeans.modules.cnd.litemodel.api.Declaration;
  56. /**
  57. *
  58. * @author Alexander Simon
  59. */
  60. public class DwarfRenderer {
  61. private static final boolean TRACE = true;
  62. private boolean PROCESS_TOP_LEVEL_DECLARATIONS = true;
  63. private boolean LIMIT_TO_COMPILATION_UNIT = true;
  64. private Map<String, String> onePath = new HashMap<String, String>();
  65. private Set<Declaration> sourceInfoMap = new HashSet<Declaration>();
  66. private String filePath;
  67. private String compDir;
  68. private Set<Long> antiLoop;
  69. private int fileEntryIdx = 0;
  70. private DwarfRenderer() {
  71. }
  72. public static DwarfRenderer createFullRenderer() {
  73. DwarfRenderer dwarfRenderer = new DwarfRenderer();
  74. dwarfRenderer.PROCESS_TOP_LEVEL_DECLARATIONS = false;
  75. dwarfRenderer.LIMIT_TO_COMPILATION_UNIT = false;
  76. return dwarfRenderer;
  77. }
  78. public static DwarfRenderer createTopLevelDeclarationsRenderer() {
  79. DwarfRenderer dwarfRenderer = new DwarfRenderer();
  80. dwarfRenderer.PROCESS_TOP_LEVEL_DECLARATIONS = true;
  81. dwarfRenderer.LIMIT_TO_COMPILATION_UNIT = false;
  82. return dwarfRenderer;
  83. }
  84. public static DwarfRenderer createTopLevelDeclarationsCompilationUnitsRenderer() {
  85. DwarfRenderer dwarfRenderer = new DwarfRenderer();
  86. dwarfRenderer.PROCESS_TOP_LEVEL_DECLARATIONS = true;
  87. dwarfRenderer.LIMIT_TO_COMPILATION_UNIT = true;
  88. return dwarfRenderer;
  89. }
  90. public void dumpModel(PrintStream out) {
  91. Map<String, Map<String, Declaration>> res = getLWM();
  92. for(Map.Entry<String, Map<String, Declaration>> entry : res.entrySet()) {
  93. out.println(entry.getKey());
  94. for(Map.Entry<String, Declaration> e : entry.getValue().entrySet()) {
  95. if (e.getValue().getReferencedType() != null) {
  96. out.println("\t"+e.getValue().getQName()+" ("+e.getValue().getKind()+") "+e.getValue().getReferencedType()+" :"+e.getValue().getLine()); // NOI18N
  97. } else {
  98. out.println("\t"+e.getValue().getQName()+" ("+e.getValue().getKind()+") :"+e.getValue().getLine()); // NOI18N
  99. }
  100. }
  101. }
  102. }
  103. public Map<String, Map<String, Declaration>> getLWM() {
  104. Map<String, Map<String, Declaration>> res = new TreeMap<String, Map<String, Declaration>>();
  105. for (Declaration d : sourceInfoMap) {
  106. Map<String, Declaration> map = res.get(d.getFileName());
  107. if (map == null) {
  108. map = new TreeMap<String, Declaration>();
  109. res.put(d.getFileName(), map);
  110. }
  111. map.put(d.getQName(), d);
  112. }
  113. return res;
  114. }
  115. public void process(CompilationUnitInterface compilationUnit) throws IOException {
  116. filePath = compilationUnit.getSourceFileAbsolutePath();
  117. compDir = compilationUnit.getCompilationDir();
  118. antiLoop = new HashSet<Long>();
  119. if (compilationUnit instanceof CompilationUnit) {
  120. CompilationUnit cu = (CompilationUnit) compilationUnit;
  121. if (PROCESS_TOP_LEVEL_DECLARATIONS) {
  122. processEntries(cu, cu.getTopLevelEntries(), null);
  123. } else {
  124. processEntries(cu, cu.getDeclarations(false), null);
  125. }
  126. }
  127. }
  128. private void processEntries(CompilationUnit compilationUnit, List<DwarfEntry> declarations, MyDeclaration parent) throws IOException {
  129. if (LIMIT_TO_COMPILATION_UNIT) {
  130. fileEntryIdx = compilationUnit.getStatementList().getFileEntryIdx(compilationUnit.getSourceFileName());
  131. }
  132. for (DwarfEntry entry : declarations) {
  133. prosessEntry(compilationUnit, entry, parent);
  134. }
  135. }
  136. private void prosessEntry(CompilationUnit compilationUnit, DwarfEntry entry, MyDeclaration parent) throws IOException {
  137. if (antiLoop.contains(entry.getRefference())) {
  138. return;
  139. }
  140. antiLoop.add(entry.getRefference());
  141. switch (entry.getKind()) {
  142. case DW_TAG_enumerator:
  143. case DW_TAG_variable:
  144. case DW_TAG_member:
  145. case DW_TAG_inlined_subroutine:
  146. case DW_TAG_subprogram:
  147. case DW_TAG_SUN_dtor:
  148. case DW_TAG_SUN_function_template:
  149. {
  150. if (!LIMIT_TO_COMPILATION_UNIT || entry.isEntryDefinedInFile(fileEntryIdx)) {
  151. MyDeclaration functionToLine = null;
  152. if (entry.getLine() >= 0 && entry.getDeclarationFilePath() != null) {
  153. functionToLine = new MyDeclaration(filePath, compDir, entry, onePath);
  154. if (functionToLine.getQName() != null) {
  155. sourceInfoMap.add(functionToLine);
  156. } else {
  157. if (TRACE) {
  158. System.err.println("Entry has empty qname\n"+entry); // NOI18N
  159. }
  160. }
  161. } else if (parent != null && parent.getLine() >= 0 && parent.getFileName() != null) {
  162. functionToLine = new MyDeclaration(entry, parent, onePath);
  163. if (functionToLine.getQName() != null) {
  164. sourceInfoMap.add(functionToLine);
  165. } else {
  166. if (TRACE) {
  167. System.err.println("Entry has empty qname\n"+entry); // NOI18N
  168. }
  169. }
  170. }
  171. if (functionToLine != null) {
  172. switch (entry.getKind()) {
  173. case DW_TAG_variable:
  174. case DW_TAG_member:
  175. case DW_TAG_inlined_subroutine:
  176. case DW_TAG_subprogram:
  177. case DW_TAG_SUN_function_template:
  178. DwarfEntry type = compilationUnit.getReferencedType(entry);
  179. if (type != null) {
  180. functionToLine.setReferencedType(type, onePath);
  181. }
  182. }
  183. }
  184. }
  185. break;
  186. }
  187. case DW_TAG_inheritance:
  188. {
  189. DwarfEntry inh = compilationUnit.getReferencedType(entry);
  190. if (inh != null) {
  191. if (parent != null && parent.getLine() >= 0 && parent.getFileName() != null) {
  192. MyDeclaration functionToLine = new MyDeclaration(entry, parent, inh, onePath);
  193. if (functionToLine.getQName() != null) {
  194. sourceInfoMap.add(functionToLine);
  195. } else {
  196. if (TRACE) {
  197. System.err.println("Entry has empty qname\n"+inh); // NOI18N
  198. }
  199. }
  200. }
  201. }
  202. break;
  203. }
  204. case DW_TAG_friend:
  205. {
  206. DwarfEntry friend = compilationUnit.getReferencedFriend(entry);
  207. if (friend != null) {
  208. if (parent != null && parent.getLine() >= 0 && parent.getFileName() != null) {
  209. MyDeclaration functionToLine = new MyDeclaration(entry, parent, friend, onePath);
  210. if (functionToLine.getQName() != null) {
  211. sourceInfoMap.add(functionToLine);
  212. } else {
  213. if (TRACE) {
  214. System.err.println("Entry has empty qname\n"+friend); // NOI18N
  215. }
  216. }
  217. }
  218. }
  219. break;
  220. }
  221. case DW_TAG_namespace:
  222. {
  223. if (!LIMIT_TO_COMPILATION_UNIT || entry.isEntryDefinedInFile(fileEntryIdx)) {
  224. MyDeclaration aParent = null;
  225. if (entry.getLine() >= 0 && entry.getDeclarationFilePath() != null) {
  226. aParent = new MyDeclaration(filePath, compDir, entry, onePath);
  227. if (aParent.getQName() != null) {
  228. sourceInfoMap.add(aParent);
  229. } else {
  230. if (TRACE) {
  231. System.err.println("Entry has empty qname\n"+entry); // NOI18N
  232. }
  233. }
  234. }
  235. processEntries(compilationUnit, entry.getChildren(), aParent);
  236. }
  237. break;
  238. }
  239. case DW_TAG_SUN_class_template:
  240. case DW_TAG_SUN_struct_template:
  241. case DW_TAG_SUN_union_template:
  242. case DW_TAG_class_type:
  243. case DW_TAG_structure_type:
  244. case DW_TAG_union_type:
  245. case DW_TAG_enumeration_type:
  246. {
  247. if (!LIMIT_TO_COMPILATION_UNIT || entry.isEntryDefinedInFile(fileEntryIdx)) {
  248. MyDeclaration aParent = null;
  249. if (entry.getLine() >= 0 && entry.getDeclarationFilePath() != null) {
  250. aParent = new MyDeclaration(filePath, compDir, entry, onePath);
  251. if (aParent.getQName() != null) {
  252. sourceInfoMap.add(aParent);
  253. } else {
  254. if (TRACE) {
  255. System.err.println("Entry has empty qname\n"+entry); // NOI18N
  256. }
  257. }
  258. }
  259. processEntries(compilationUnit, entry.getChildren(), aParent);
  260. }
  261. break;
  262. }
  263. case DW_TAG_typedef:
  264. case DW_TAG_const_type:
  265. case DW_TAG_pointer_type:
  266. case DW_TAG_reference_type:
  267. case DW_TAG_array_type:
  268. case DW_TAG_ptr_to_member_type:
  269. {
  270. if (!LIMIT_TO_COMPILATION_UNIT || entry.isEntryDefinedInFile(fileEntryIdx)) {
  271. MyDeclaration functionToLine = null;
  272. if (entry.getLine() >= 0 && entry.getDeclarationFilePath() != null) {
  273. functionToLine = new MyDeclaration(filePath, compDir, entry, onePath);
  274. if (functionToLine.getQName() != null) {
  275. sourceInfoMap.add(functionToLine);
  276. } else {
  277. if (TRACE) {
  278. System.err.println("Entry has empty qname\n"+entry); // NOI18N
  279. }
  280. }
  281. }
  282. DwarfEntry type = compilationUnit.getReferencedType(entry);
  283. if (functionToLine != null && type != null) {
  284. functionToLine.setReferencedType(type, onePath);
  285. prosessEntry(compilationUnit, type, null);
  286. }
  287. }
  288. break;
  289. }
  290. }
  291. }
  292. private static final class MyDeclaration implements Declaration {
  293. private final int baseLine;
  294. private final String filePath;
  295. private final Kind kind;
  296. private final String qname;
  297. private String referencedType;
  298. public MyDeclaration(String filePath, String compDir, DwarfEntry entry, Map<String, String> onePath) throws IOException {
  299. kind = kind2kind(entry.getKind());
  300. baseLine = entry.getLine();
  301. qname = initName(entry, onePath);
  302. this.filePath = initPath(filePath, compDir, entry, onePath);
  303. }
  304. private Kind kind2kind(org.netbeans.modules.cnd.dwarfdump.dwarfconsts.TAG tag) {
  305. return Kind.valueOf(tag.toString().substring(7));
  306. }
  307. private void setReferencedType(DwarfEntry entry, Map<String, String> onePath) throws IOException {
  308. referencedType = getString(entry.getType(), onePath);
  309. }
  310. @Override
  311. public String getReferencedType(){
  312. return referencedType;
  313. }
  314. private String initName(DwarfEntry entry, Map<String, String> onePath) throws IOException {
  315. if (entry.getKind() == TAG.DW_TAG_subprogram) {
  316. return getString(entry.getQualifiedName() + entry.getParametersString(false), onePath);
  317. } else {
  318. return getString(entry.getQualifiedName(), onePath);
  319. }
  320. }
  321. public MyDeclaration(DwarfEntry entry, MyDeclaration parent, Map<String, String> onePath) throws IOException {
  322. kind = kind2kind(entry.getKind());
  323. baseLine = parent.getLine();
  324. qname = initName(entry, onePath);
  325. this.filePath = parent.getFileName();
  326. }
  327. public MyDeclaration(DwarfEntry entry, MyDeclaration parent, DwarfEntry reference, Map<String, String> onePath) throws IOException {
  328. kind = kind2kind(entry.getKind());
  329. baseLine = parent.getLine();
  330. qname = initName(reference, onePath);
  331. this.filePath = parent.getFileName();
  332. }
  333. @Override
  334. public String getFileName() {
  335. return filePath;
  336. }
  337. @Override
  338. public int getLine() {
  339. return baseLine;
  340. }
  341. @Override
  342. public Kind getKind() {
  343. return kind;
  344. }
  345. @Override
  346. public String getQName() {
  347. return qname;
  348. }
  349. private String normalizeFile(String path) {
  350. //String aPath = CndFileUtils.normalizeFile(new File(path)).getAbsolutePath();
  351. path = path.replace("/./", "/"); // NOI18N
  352. while (true) {
  353. int i = path.indexOf("/../"); // NOI18N
  354. if (i < 0) {
  355. break;
  356. }
  357. int prev = -1;
  358. for (int j = i - 1; j >= 0; j--) {
  359. if (path.charAt(j) == '/') {
  360. prev = j;
  361. break;
  362. }
  363. }
  364. if (prev == -1) {
  365. break;
  366. }
  367. path = path.substring(0, prev)+path.substring(i+3);
  368. }
  369. //assert aPath.equals(path);
  370. return path;
  371. }
  372. private String initPath(String filePath, String compDir, DwarfEntry entry, Map<String, String> onePath) throws IOException{
  373. String res = _initPath(filePath, compDir, entry);
  374. res = res.replace('\\', '/');
  375. if (res.indexOf("/../")>=0 || res.indexOf("/./")>=0) { // NOI18N
  376. res = normalizeFile(res);
  377. }
  378. return getString(res, onePath);
  379. }
  380. private String getString(String path, Map<String, String> onePath) {
  381. String cached = onePath.get(path);
  382. if (cached == null) {
  383. onePath.put(path, path);
  384. cached = path;
  385. }
  386. return cached;
  387. }
  388. private String _initPath(String filePath, String compDir, DwarfEntry entry) throws IOException{
  389. String entyFilePath = entry.getDeclarationFilePath();
  390. if (entyFilePath != null && filePath.endsWith(entyFilePath)) {
  391. return filePath;
  392. } else {
  393. if (entyFilePath != null &&
  394. (entyFilePath.startsWith("/") || // NOI18N
  395. entyFilePath.length()>2 && entyFilePath.charAt(1) == ':')){ // NOI18N
  396. return entyFilePath;
  397. } else {
  398. if (compDir.endsWith("/") || compDir.endsWith("\\")) { // NOI18N
  399. return compDir+entyFilePath;
  400. } else {
  401. return compDir+"/"+entyFilePath; // NOI18N
  402. }
  403. }
  404. }
  405. }
  406. @Override
  407. public String toString() {
  408. return qname+"("+kind+") "+filePath+"("+baseLine+")"; // NOI18N
  409. }
  410. @Override
  411. public boolean equals(Object obj) {
  412. if (obj instanceof MyDeclaration) {
  413. MyDeclaration other = (MyDeclaration) obj;
  414. if (baseLine != other.baseLine) {
  415. return false;
  416. }
  417. if (kind != other.kind) {
  418. return false;
  419. }
  420. if (!filePath.equals(other.filePath)) {
  421. return false;
  422. }
  423. if (!qname.equals(other.qname)) {
  424. return false;
  425. }
  426. return true;
  427. }
  428. return false;
  429. }
  430. @Override
  431. public int hashCode() {
  432. int hash = 5;
  433. hash = 83 * hash + this.baseLine;
  434. hash = 83 * hash + this.filePath.hashCode();
  435. hash = 83 * hash + this.kind.ordinal();
  436. hash = 83 * hash + this.qname.hashCode();
  437. return hash;
  438. }
  439. }
  440. }