0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.cnd.api.model.util;
0043:
0044: import java.io.File;
0045: import java.io.PrintStream;
0046: import java.util.*;
0047:
0048: import org.netbeans.modules.cnd.api.model.*;
0049: import org.netbeans.modules.cnd.api.model.deep.*;
0050: import org.netbeans.modules.cnd.utils.cache.CharSequenceKey;
0051:
0052: /**
0053: * Misc. static methods used for tracing of code model objects
0054: * @author vk155633
0055: */
0056: public class CsmTracer {
0057:
0058: private static final String NULL_TEXT = "null"; // NOI18N
0059:
0060: private final int step = 4;
0061: private StringBuilder indentBuffer = new StringBuilder();
0062: private boolean deep = true;
0063: private boolean testUniqueName = false;
0064: private PrintStream printStream;
0065:
0066: public void setPrintStream(PrintStream printStream) {
0067: this .printStream = printStream;
0068: }
0069:
0070: //TODO: remove as soon as regression tests are fixed
0071:
0072: public CsmTracer() {
0073: printStream = System.out;
0074: }
0075:
0076: public CsmTracer(boolean useStdErr) {
0077: printStream = useStdErr ? System.err : System.out;
0078: }
0079:
0080: public CsmTracer(PrintStream printStream) {
0081: this .printStream = printStream;
0082: }
0083:
0084: public void setDeep(boolean deep) {
0085: this .deep = deep;
0086: }
0087:
0088: public void setTestUniqueName(boolean value) {
0089: testUniqueName = value;
0090: }
0091:
0092: public void indent() {
0093: setupIndentBuffer(indentBuffer.length() + step);
0094: }
0095:
0096: public void unindent() {
0097: setupIndentBuffer(indentBuffer.length() - step);
0098: }
0099:
0100: private void setupIndentBuffer(int len) {
0101: if (len <= 0) {
0102: indentBuffer.setLength(0);
0103: } else {
0104: indentBuffer.setLength(len);
0105: for (int i = 0; i < len; i++) {
0106: indentBuffer.setCharAt(i, ' ');
0107: }
0108: }
0109: }
0110:
0111: public void print(String s) {
0112: print(s, true);
0113: }
0114:
0115: protected PrintStream getStream() {
0116: return printStream;
0117: }
0118:
0119: public void print(String s, boolean newline) {
0120: PrintStream stream = getStream();
0121: if (newline) {
0122: stream.print('\n');
0123: stream.print(indentBuffer.toString());
0124: }
0125: stream.print(s);
0126: }
0127:
0128: public static String toString(CsmObject obj) {
0129: String out;
0130: if (CsmKindUtilities.isMacro(obj)) {
0131: out = toString((CsmMacro) obj);
0132: } else if (CsmKindUtilities.isInclude(obj)) {
0133: out = toString((CsmInclude) obj);
0134: } else if (CsmKindUtilities.isNamespace(obj)) {
0135: out = toString((CsmNamespace) obj);
0136: } else if (CsmKindUtilities.isClassifier(obj)) {
0137: out = toString((CsmClassifier) obj);
0138: } else if (CsmKindUtilities.isFunction(obj)) {
0139: out = toString((CsmFunction) obj);
0140: } else if (CsmKindUtilities.isVariable(obj)) {
0141: out = toString((CsmVariable) obj);
0142: } else if (CsmKindUtilities.isDeclaration(obj)) {
0143: out = toString((CsmDeclaration) obj);
0144: } else if (CsmKindUtilities.isType(obj)) {
0145: out = "TYPE " + toString((CsmType) obj, true); // NOI18N
0146: } else if (CsmKindUtilities.isExpression(obj)) {
0147: out = toString((CsmExpression) obj, true);
0148: } else if (CsmKindUtilities.isStatement(obj)) {
0149: out = toString((CsmStatement) obj);
0150: } else if (CsmKindUtilities.isOffsetable(obj)) {
0151: out = getOffsetString(obj, true);
0152: } else if (CsmKindUtilities.isFile(obj)) {
0153: out = "FILE " + toString((CsmFile) obj); // NOI18N
0154: } else {
0155: out = (obj == null ? "" : "UNKNOWN CSM OBJECT ") + obj; // NOI18N
0156: }
0157: return out;
0158: }
0159:
0160: public static String toString(CsmNamespace nsp) {
0161: if (nsp == null) {
0162: return NULL_TEXT; // NOI18N
0163: }
0164: return "NS " + nsp.getQualifiedName(); // NOI18N
0165: }
0166:
0167: public static String toString(CsmMacro macro) {
0168: if (macro == null) {
0169: return NULL_TEXT; // NOI18N
0170: }
0171: return "MACROS " + macro; // NOI18N
0172: }
0173:
0174: public static String toString(CsmInclude incl) {
0175: if (incl == null) {
0176: return NULL_TEXT; // NOI18N
0177: }
0178: return "INCLUDE " + incl; // NOI18N
0179: }
0180:
0181: public static String toString(CsmStatement stmt) {
0182: if (stmt == null) {
0183: return NULL_TEXT; // NOI18N
0184: }
0185: StringBuilder sb = new StringBuilder();
0186: sb.append("STMT ").append(stmt.getKind()).append(" "); // NOI18N
0187: sb.append("text='"); // NOI18N
0188: sb.append(stmt.getText());
0189: sb.append("'"); // NOI18N
0190: return sb.toString();
0191: }
0192:
0193: public static String toString(CsmExpression expr, boolean traceKind) {
0194: if (expr == null) {
0195: return NULL_TEXT; // NOI18N
0196: }
0197: StringBuilder sb = new StringBuilder();
0198: if (traceKind) {
0199: sb.append("EXPR ").append(expr.getKind()).append(" "); // NOI18N
0200: }
0201: sb.append("text='"); // NOI18N
0202: sb.append(expr.getText());
0203: sb.append("'"); // NOI18N
0204: return sb.toString();
0205: }
0206:
0207: // public boolean isDummyUnresolved(CsmClassifier decl) {
0208: // return decl == null || decl.getClass().getName().endsWith("Unresolved$UnresolvedClass");
0209: // }
0210:
0211: public static String toString(CsmInheritance inh) {
0212: StringBuilder sb = new StringBuilder();
0213:
0214: sb.append("CLASS="); // NOI18N
0215: CsmClassifier cls = inh.getCsmClassifier();
0216: //sb.append(isDummyUnresolved(cls) ? "<unresolved>" : cls.getQualifiedName());
0217: sb.append(cls == null ? NULL_TEXT : cls.getQualifiedName()); // NOI18N
0218:
0219: sb.append(" VISIBILITY==" + inh.getVisibility()); // NOI18N
0220: sb.append(" virtual==" + inh.isVirtual()); // NOI18N
0221:
0222: sb.append(" text='"); // NOI18N
0223: sb.append(inh.getText());
0224: sb.append("'"); // NOI18N
0225: return sb.toString();
0226: }
0227:
0228: public static String toString(CsmCondition condition) {
0229: if (condition == null) {
0230: return NULL_TEXT; // NOI18N
0231: }
0232: StringBuilder sb = new StringBuilder(condition.getKind()
0233: .toString());
0234: sb.append(' ');
0235: if (condition.getKind() == CsmCondition.Kind.EXPRESSION) {
0236: sb.append(toString(condition.getExpression(), false));
0237: } else { // condition.getKind() == CsmCondition.Kind.DECLARATION
0238: CsmVariable var = condition.getDeclaration();
0239: sb.append(toString(var, false));
0240: }
0241: return sb.toString();
0242: }
0243:
0244: public static String toString(CsmDeclaration decl) {
0245: return decl.getKind() + " " + toString(decl, true); // NOI18N
0246: }
0247:
0248: private static String toString(CsmDeclaration decl,
0249: boolean traceFile) {
0250: if (decl == null) {
0251: return NULL_TEXT;
0252: }
0253: return decl.getQualifiedName()
0254: + getOffsetString(decl, traceFile);
0255: }
0256:
0257: public static String toString(CsmClassifier cls) {
0258: return cls.getKind() + " " + toString(cls, true); // NOI18N
0259: }
0260:
0261: private static String toString(CsmClassifier cls, boolean traceFile) {
0262: if (cls == null) {
0263: return NULL_TEXT;
0264: }
0265: return cls.getQualifiedName() + getOffsetString(cls, traceFile);
0266: }
0267:
0268: private static String toString(CsmType type, boolean traceFile) {
0269: StringBuilder sb = new StringBuilder();
0270: if (type == null) {
0271: sb.append(NULL_TEXT); // NOI18N
0272: } else {
0273: if (type.isConst()) {
0274: sb.append("const "); // NOI18N
0275: }
0276: if (type.isPointer()) {
0277: for (int i = 0; i < type.getPointerDepth(); i++) {
0278: sb.append("*"); // NOI18N
0279: }
0280: }
0281: if (type.isReference())
0282: sb.append("&"); // NOI18N
0283: CsmClassifier classifier = type.getClassifier();
0284: if (classifier != null) {
0285: sb.append(classifier.getQualifiedName());
0286: // if( classifier instanceof CsmOffsetable ) {
0287: // CsmOffsetable offs = (CsmOffsetable) classifier;
0288: // sb.append("(Declared in ");
0289: // sb.append(offs.getContainingFile());
0290: // sb.append(' ');
0291: // sb.append(getOffsetString(offs));
0292: // sb.append(')');
0293: // }
0294: } else {
0295: sb.append("<*no_classifier*>"); // NOI18N
0296: }
0297:
0298: for (int i = 0; i < type.getArrayDepth(); i++) {
0299: sb.append("[]"); // NOI18N
0300: }
0301: sb.append(" TEXT=" + type.getText()); // NOI18N
0302: }
0303: if (type instanceof CsmOffsetable) {
0304: sb.append(' ');
0305: sb.append(getOffsetString(type, traceFile));
0306: }
0307: return sb.toString();
0308: }
0309:
0310: public static String toString(CsmFile file) {
0311: if (file == null) {
0312: return NULL_TEXT; // NOI18N
0313: }
0314: File parent = new File(file.getAbsolutePath().toString())
0315: .getParentFile();
0316: return (parent != null ? parent.getName() + "/" : "")
0317: + file.getName(); // NOI18N
0318: }
0319:
0320: public static String toString(CsmVariable var) {
0321: return var.getKind() + " " + toString(var, true); // NOI18N
0322: }
0323:
0324: private static String toString(CsmVariable var, boolean traceFile) {
0325: if (var == null) {
0326: return NULL_TEXT; // NOI18N
0327: }
0328: StringBuilder sb = new StringBuilder(var.getName());
0329: sb.append(getOffsetString(var, traceFile));
0330: sb.append(" TYPE: " + toString(var.getType(), false)); // NOI18N
0331: sb.append(" INIT: " + toString(var.getInitialValue(), false)); // NOI18N
0332: sb.append(" " + getScopeString(var)); // NOI18N
0333: return sb.toString();
0334: }
0335:
0336: public static String toString(CsmFunction fun) {
0337: return fun.getKind() + " " + toString(fun, true); // NOI18N
0338: }
0339:
0340: private static String toString(CsmFunction fun, boolean signature) {
0341: if (fun == null) {
0342: return NULL_TEXT; // NOI18N
0343: } else {
0344: return (signature ? fun.getSignature().toString() : fun
0345: .getName().toString())
0346: + ' ' + getOffsetString(fun, signature);
0347: }
0348: }
0349:
0350: public void dumpModel(CsmFunction fun) {
0351: print("FUNCTION " + fun.getName() + getOffsetString(fun, false)
0352: + ' ' + getBriefClassName(fun) + // NOI18N
0353: ' ' + getScopeString(fun)); // NOI18N
0354: if (fun instanceof CsmFunctionDefinition) {
0355: if (deep) {
0356: //indent();
0357: dumpStatement(((CsmFunctionDefinition) fun).getBody());
0358: //unindent();
0359: }
0360: }
0361: indent();
0362: print("DEFINITION: " + toString(fun.getDefinition(), false)); // NOI18N
0363: print("SIGNATURE " + fun.getSignature()); // NOI18N
0364: // if (CsmKindUtilities.isMethod(fun)) {
0365: // if (((CsmMethod)fun).isVirtual()) {
0366: // print("VIRTUAL"); // NOI18N
0367: // }
0368: // }
0369: print("UNIQUE NAME " + fun.getUniqueName()); // NOI18N
0370: if (fun instanceof CsmFriendFunction) {
0371: print("REFERENCED FRIEND FUNCTION: "
0372: + toString(((CsmFriendFunction) fun)
0373: .getReferencedFunction(), false)); // NOI18N
0374: }
0375: dumpParameters(fun.getParameters());
0376: print("RETURNS " + toString(fun.getReturnType(), false)); // NOI18N
0377: unindent();
0378: }
0379:
0380: public void dumpModel(CsmFunctionDefinition fun) {
0381: CsmFunction decl = fun.getDeclaration();
0382: print("FUNCTION DEFINITION " + fun.getName() + ' '
0383: + getOffsetString(fun, false)
0384: + // NOI18N
0385: ' ' + getBriefClassName(fun) + ' '
0386: + getScopeString(fun)); // NOI18N
0387: indent();
0388: print("SIGNATURE " + fun.getSignature()); // NOI18N
0389: // if (CsmKindUtilities.isMethod(fun)) {
0390: // if (((CsmMethod)fun).isVirtual()) {
0391: // print("VIRTUAL"); // NOI18N
0392: // }
0393: // }
0394: print("UNIQUE NAME " + fun.getUniqueName()); // NOI18N
0395: print("DECLARATION: " + toString(decl, false)); // NOI18N
0396: dumpParameters(fun.getParameters());
0397: print("RETURNS " + toString(fun.getReturnType(), false)); // NOI18N
0398: if (deep) {
0399: dumpStatement((CsmStatement) fun.getBody());
0400: }
0401: unindent();
0402: }
0403:
0404: public static String getScopeString(CsmScopeElement el) {
0405: StringBuilder sb = new StringBuilder("SCOPE: "); // NOI18N
0406: int initLen = sb.length();
0407: CsmScope scope = el.getScope();
0408: if (scope == null) {
0409: sb.append(NULL_TEXT);
0410: } else {
0411: if (CsmKindUtilities.isFile(scope)) {
0412: sb.append(((CsmFile) scope).getName());
0413: } else {
0414: if (CsmKindUtilities.isNamedElement(scope)) {
0415: sb.append(((CsmNamedElement) scope).getName());
0416: sb.append(' ');
0417: } else {
0418: if (CsmKindUtilities.isStatement(scope)) {
0419: CsmStatement stmt = (CsmStatement) scope;
0420: sb.append("Stmt "); // NOI18N
0421: }
0422: if (CsmKindUtilities.isOffsetable(scope)) {
0423: sb.append(getOffsetString(scope, false));
0424: }
0425: }
0426: }
0427: if (sb.length() == initLen) {
0428: sb.append("???"); // NOI18N
0429: }
0430: }
0431: return sb.toString();
0432: }
0433:
0434: public static String getOffsetString(CsmObject obj,
0435: boolean traceFile) {
0436: //return " [" + obj.getStartOffset() + '-' + obj.getEndOffset() + ']';
0437: // CsmOffsetable.Position start = obj.getStartPosition();
0438: // CsmOffsetable.Position end = obj.getEndPosition();
0439: if (!CsmKindUtilities.isOffsetable(obj)) {
0440: return ""; // NOI18N
0441: }
0442: CsmOffsetable offs = (CsmOffsetable) obj;
0443: return " ["
0444: + offs.getStartPosition()
0445: + '-'
0446: + offs.getEndPosition()
0447: + ']'
0448: + (traceFile ? " " + toString(offs.getContainingFile())
0449: : ""); // NOI18N
0450: }
0451:
0452: public String getBriefClassName(Object o) {
0453: return getBriefClassName(o.getClass());
0454: }
0455:
0456: public String getBriefClassName(Class cls) {
0457: String name = cls.getName();
0458: int pos = name.lastIndexOf('.');
0459: if (pos > 0) {
0460: name = name.substring(pos + 1);
0461: }
0462: return name;
0463: }
0464:
0465: public void dumpParameters(Collection/*<CsmParameter>*/parameters) {
0466: print("PARAMETERS:"); // NOI18N
0467: if (parameters != null && parameters.size() > 0) {
0468: indent();
0469: for (Iterator iter = parameters.iterator(); iter.hasNext();) {
0470: print(toString((CsmParameter) iter.next(), false));
0471: }
0472: unindent();
0473: }
0474: }
0475:
0476: public void dumpStatement(CsmStatement stmt) {
0477: if (stmt == null) {
0478: print("STATEMENT is null"); // NOI18N
0479: return;
0480: }
0481: print("STATEMENT " + stmt.getKind() + ' '
0482: + getOffsetString(stmt, false) + ' '
0483: + getScopeString(stmt)); // NOI18N
0484: indent();
0485: CsmStatement.Kind kind = stmt.getKind();
0486: if (kind == CsmStatement.Kind.COMPOUND) {
0487: dumpStatement((CsmCompoundStatement) stmt);
0488: } else if (kind == CsmStatement.Kind.IF) {
0489: dumpStatement((CsmIfStatement) stmt);
0490: } else if (kind == CsmStatement.Kind.TRY_CATCH) {
0491: dumpStatement((CsmTryCatchStatement) stmt);
0492: } else if (kind == CsmStatement.Kind.CATCH) {
0493: dumpStatement((CsmExceptionHandler) stmt);
0494: } else if (kind == CsmStatement.Kind.DECLARATION) {
0495: dumpStatement((CsmDeclarationStatement) stmt);
0496: } else if (kind == CsmStatement.Kind.WHILE
0497: || kind == CsmStatement.Kind.DO_WHILE) {
0498: dumpStatement((CsmLoopStatement) stmt);
0499: } else if (kind == CsmStatement.Kind.FOR) {
0500: dumpStatement((CsmForStatement) stmt);
0501: } else if (kind == CsmStatement.Kind.SWITCH) {
0502: dumpStatement((CsmSwitchStatement) stmt);
0503: } else if (kind == CsmStatement.Kind.CASE) {
0504: dumpStatement((CsmCaseStatement) stmt);
0505: } else if (kind == CsmStatement.Kind.BREAK) {
0506: } else if (kind == CsmStatement.Kind.CONTINUE) {
0507: } else if (kind == CsmStatement.Kind.DEFAULT) {
0508: } else if (kind == CsmStatement.Kind.EXPRESSION) {
0509: print(" text: '" + stmt.getText() + '\'', false); // NOI18N
0510: } else if (kind == CsmStatement.Kind.GOTO) {
0511: print(" text: '" + stmt.getText() + '\'', false); // NOI18N
0512: } else if (kind == CsmStatement.Kind.LABEL) {
0513: print(" text: '" + stmt.getText() + '\'', false); // NOI18N
0514: } else if (kind == CsmStatement.Kind.RETURN) {
0515: print(" text: '" + stmt.getText() + '\'', false); // NOI18N
0516: } else {
0517: print("unexpected statement kind"); // NOI18N
0518: }
0519: unindent();
0520: }
0521:
0522: public void dumpStatement(CsmCompoundStatement stmt) {
0523: if (stmt != null) {
0524: for (Iterator iter = stmt.getStatements().iterator(); iter
0525: .hasNext();) {
0526: dumpStatement((CsmStatement) iter.next());
0527: }
0528: }
0529: }
0530:
0531: public void dumpStatement(CsmTryCatchStatement stmt) {
0532: print("TRY:"); // NOI18N
0533: dumpStatement(stmt.getTryStatement());
0534: print("HANDLERS:"); // NOI18N
0535: for (Iterator iter = stmt.getHandlers().iterator(); iter
0536: .hasNext();) {
0537: dumpStatement((CsmStatement) iter.next());
0538: }
0539: }
0540:
0541: public void dumpStatement(CsmExceptionHandler stmt) {
0542: print("PARAMETER: " + toString(stmt.getParameter(), false)); // NOI18N
0543: dumpStatement((CsmCompoundStatement) stmt);
0544: }
0545:
0546: public void dumpStatement(CsmIfStatement stmt) {
0547: print("CONDITION " + toString(stmt.getCondition())); // NOI18N
0548: print("THEN: "); // NOI18N
0549: indent();
0550: dumpStatement(stmt.getThen());
0551: unindent();
0552: print("ELSE: "); // NOI18N
0553: indent();
0554: dumpStatement(stmt.getElse());
0555: unindent();
0556: }
0557:
0558: public void dumpStatement(CsmDeclarationStatement stmt) {
0559: for (Iterator iter = stmt.getDeclarators().iterator(); iter
0560: .hasNext();) {
0561: dumpModel((CsmDeclaration) iter.next());
0562: }
0563: }
0564:
0565: public void dumpStatement(CsmLoopStatement stmt) {
0566: print("CONDITION: " + toString(stmt.getCondition())
0567: + " isPostCheck()=" + stmt.isPostCheck()); // NOI18N
0568: print("BODY:"); // NOI18N
0569: indent();
0570: dumpStatement(stmt.getBody());
0571: unindent();
0572: }
0573:
0574: public void dumpStatement(CsmForStatement stmt) {
0575: print("INIT:"); // NOI18N
0576: indent();
0577: dumpStatement(stmt.getInitStatement());
0578: unindent();
0579: print("ITERATION: "
0580: + toString(stmt.getIterationExpression(), false)); // NOI18N
0581: print("CONDITION: " + toString(stmt.getCondition())); // NOI18N
0582: print("BODY:"); // NOI18N
0583: indent();
0584: dumpStatement(stmt.getBody());
0585: unindent();
0586: }
0587:
0588: public void dumpStatement(CsmSwitchStatement stmt) {
0589: print("CONDITION: " + toString(stmt.getCondition())); // NOI18N
0590: print("BODY:"); // NOI18N
0591: indent();
0592: dumpStatement(stmt.getBody());
0593: unindent();
0594: }
0595:
0596: public void dumpStatement(CsmCaseStatement stmt) {
0597: print(" EXPRESSION: " + toString(stmt.getExpression(), false),
0598: false); // NOI18N
0599: }
0600:
0601: public void dumpNamespaceDefinitions(CsmNamespace nsp) {
0602: print("NAMESPACE DEFINITIONS for " + nsp.getName() + " ("
0603: + nsp.getQualifiedName() + ") "); // NOI18N
0604: indent();
0605: for (Iterator iter = nsp.getDefinitions().iterator(); iter
0606: .hasNext();) {
0607: CsmNamespaceDefinition def = (CsmNamespaceDefinition) iter
0608: .next();
0609: print(def.getContainingFile().getName().toString() + ' '
0610: + getOffsetString(def, false));
0611: }
0612: unindent();
0613: }
0614:
0615: public void dumpModel(CsmProject project) {
0616: CsmNamespace nsp = project.getGlobalNamespace();
0617: print("\n========== Dumping model of PROJECT "
0618: + project.getName(), true); // NOI18N
0619: dumpModel(nsp);
0620: }
0621:
0622: public void dumpModel(CsmNamespace nsp) {
0623: if (!nsp.isGlobal()) {
0624: dumpNamespaceDefinitions(nsp);
0625: print("NAMESPACE " + nsp.getName() + " ("
0626: + nsp.getQualifiedName() + ") "); // NOI18N
0627: indent();
0628: }
0629: for (Iterator<CsmOffsetableDeclaration> iter = getSortedDeclarations(nsp); iter
0630: .hasNext();) {
0631: dumpModel(iter.next());
0632: }
0633: for (Iterator<CsmNamespace> iter = getSortedNestedNamespaces(nsp); iter
0634: .hasNext();) {
0635: dumpModel(iter.next());
0636: }
0637: if (!nsp.isGlobal()) {
0638: unindent();
0639: }
0640: }
0641:
0642: private Iterator<CsmOffsetableDeclaration> getSortedDeclarations(
0643: CsmNamespace nsp) {
0644: SortedMap<String, CsmOffsetableDeclaration> map = new TreeMap<String, CsmOffsetableDeclaration>();
0645: for (CsmOffsetableDeclaration decl : nsp.getDeclarations()) {
0646: map.put(getSortKey(decl), decl);
0647: }
0648: return map.values().iterator();
0649: }
0650:
0651: private Iterator<CsmNamespace> getSortedNestedNamespaces(
0652: CsmNamespace nsp) {
0653: SortedMap<CharSequence, CsmNamespace> map = new TreeMap<CharSequence, CsmNamespace>(
0654: CharSequenceKey.Comparator);
0655: for (CsmNamespace decl : nsp.getNestedNamespaces()) {
0656: map.put(decl.getQualifiedName(), decl);
0657: }
0658: return map.values().iterator();
0659: }
0660:
0661: private static String getSortKey(CsmDeclaration declaration) {
0662: StringBuilder sb = new StringBuilder();
0663: if (declaration instanceof CsmOffsetable) {
0664: sb.append(((CsmOffsetable) declaration).getContainingFile()
0665: .getAbsolutePath());
0666: int start = ((CsmOffsetable) declaration).getStartOffset();
0667: String s = Integer.toString(start);
0668: int gap = 8 - s.length();
0669: while (gap-- > 0) {
0670: sb.append('0');
0671: }
0672: sb.append(s);
0673: sb.append(declaration.getName());
0674: } else {
0675: // actually this never happens
0676: // since of all declarations only CsmBuiltin isn't CsmOffsetable
0677: // and CsmBuiltin is never added to any file
0678: sb.append(declaration.getUniqueName());
0679: }
0680: return sb.toString();
0681: }
0682:
0683: public void dumpModel(CsmFile file) {
0684: dumpModel(file, "\n========== Dumping model of FILE "
0685: + file.getName()); // NOI18N
0686: }
0687:
0688: public void dumpModel(CsmFile file, String title) {
0689: print(title);
0690: Collection<CsmInclude> includes = file.getIncludes();
0691: print("Includes:"); // NOI18N
0692: if (includes.size() > 0) {
0693: for (Iterator<CsmInclude> iter = includes.iterator(); iter
0694: .hasNext();) {
0695: CsmInclude o = iter.next();
0696: print(o.toString());
0697: }
0698: } else {
0699: indent();
0700: print("<no includes>");
0701: unindent(); // NOI18N
0702: }
0703: Collection macros = file.getMacros();
0704: print("Macros:"); // NOI18N
0705: if (macros.size() > 0) {
0706: for (Iterator iter = macros.iterator(); iter.hasNext();) {
0707: CsmMacro o = (CsmMacro) iter.next();
0708: print(o.toString());
0709: }
0710: } else {
0711: indent();
0712: print("<no macros>");
0713: unindent(); // NOI18N
0714: }
0715: Collection/*CsmDeclaration*/objects = file.getDeclarations();
0716: for (Iterator iter = objects.iterator(); iter.hasNext();) {
0717: dumpModel((CsmDeclaration) iter.next());
0718: }
0719: }
0720:
0721: public void dumpModel(CsmVariable var) {
0722: print((var.isExtern() ? "EXTERN " : "") + "VARIABLE "
0723: + toString(var, false)); // NOI18N
0724: CsmVariableDefinition def = var.getDefinition();
0725: if (def != null) {
0726: indent();
0727: print("DEFINITION: " + toString(def, false)); // NOI18N
0728: unindent();
0729: }
0730: }
0731:
0732: public void dumpModel(CsmVariableDefinition var) {
0733: CsmVariable decl = var.getDeclaration();
0734: print("VARIABLE DEFINITION " + toString(var, false)); // NOI18N
0735: indent();
0736: print("DECLARATION: " + toString(decl, false)); // NOI18N
0737: unindent();
0738: }
0739:
0740: // public void dumpModel(CsmField field) {
0741: // StringBuilder sb = new StringBuilder("FIELD "); // NOI18N
0742: // sb.append(field.getVisibility().toString());
0743: // if( field.isStatic() ) {
0744: // sb.append(" STATIC "); // NOI18N
0745: // }
0746: // sb.append(" " + toString(field.getType(), false)); // NOI18N
0747: // sb.append(' ');
0748: // sb.append(field.getName());
0749: // sb.append(getOffsetString(field, false));
0750: // print(sb.toString());
0751: // CsmVariableDefinition def = field.getDefinition();
0752: // if (def != null){
0753: // indent();
0754: // print("DEFINITION: " + toString(def, false)); // NOI18N
0755: // unindent();
0756: // }
0757: // }
0758:
0759: public void dumpModel(CsmField field) {
0760: StringBuilder sb = new StringBuilder("FIELD "); // NOI18N
0761: sb.append(field.getVisibility().toString());
0762: if (field.isStatic()) {
0763: sb.append(" static"); // NOI18N
0764: }
0765: sb.append(" "); // NOI18N
0766:
0767: sb.append(toString(field, false));
0768: print(sb.toString());
0769: CsmVariableDefinition def = field.getDefinition();
0770: if (def != null) {
0771: indent();
0772: print("DEFINITION: " + toString(def, false)); // NOI18N
0773: unindent();
0774: }
0775: }
0776:
0777: public void checkUniqueName(CsmDeclaration decl) {
0778: CharSequence uname = decl.getUniqueName();
0779: if ((decl instanceof CsmOffsetableDeclaration)
0780: && needsCheckUniqueName(decl)) {
0781: CsmProject project = ((CsmOffsetable) decl)
0782: .getContainingFile().getProject();
0783: CsmDeclaration found = project.findDeclaration(uname);
0784: if (found == null) {
0785: print("Unique name check failed: cant't find in project: "
0786: + uname); // NOI18N
0787: } else if (found != decl) {
0788: print("Unique name check failed: declaration found in project differs "
0789: + uname); // NOI18N
0790: }
0791: }
0792: if (!uname.toString().startsWith(decl.getKind().toString())) {
0793: print("Warning: unique name '" + uname
0794: + "' desn't start with "
0795: + decl.getKind().toString()); // NOI18N
0796: }
0797: }
0798:
0799: protected boolean needsCheckUniqueName(CsmDeclaration decl) {
0800: if (decl.getName().length() == 0) {
0801: return false;
0802: } else if (decl.getKind() == CsmDeclaration.Kind.USING_DECLARATION) {
0803: return false;
0804: } else if (decl.getKind() == CsmDeclaration.Kind.USING_DIRECTIVE) {
0805: return false;
0806: } else if (decl.getKind() == CsmDeclaration.Kind.ASM) {
0807: return false;
0808: } else if (decl.getKind() == CsmDeclaration.Kind.BUILT_IN) {
0809: return false;
0810: } else if (decl.getKind() == CsmDeclaration.Kind.CLASS_FORWARD_DECLARATION) {
0811: return false;
0812: } else if (decl.getKind() == CsmDeclaration.Kind.FUNCTION_DEFINITION) {
0813: return false;
0814: } else if (decl.getKind() == CsmDeclaration.Kind.NAMESPACE_ALIAS) {
0815: return false;
0816: } else if (decl.getKind() == CsmDeclaration.Kind.NAMESPACE_DEFINITION) {
0817: return false;
0818: }
0819: // else if( decl.getKind() == CsmDeclaration.Kind.TYPEDEF ) {
0820: // return false;
0821: // }
0822: else if (decl.getKind() == CsmDeclaration.Kind.VARIABLE_DEFINITION) {
0823: return false;
0824: } else if (decl.getKind() == CsmDeclaration.Kind.VARIABLE) {
0825: if (CsmKindUtilities.isLocalVariable(decl)) {
0826: return false;
0827: } else if (CsmKindUtilities.isFileLocalVariable(decl)) {
0828: return false;
0829: }
0830: }
0831: return true;
0832: }
0833:
0834: public void dumpModel(CsmDeclaration decl) {
0835: if (testUniqueName
0836: && (decl instanceof CsmOffsetableDeclaration)) {
0837: checkUniqueName(decl);
0838: }
0839: if (CsmKindUtilities.isClass(decl)) {
0840: dumpModel((CsmClass) decl);
0841: } else if (decl.getKind() == CsmDeclaration.Kind.ENUM) {
0842: dumpModel((CsmEnum) decl);
0843: } else if (decl.getKind() == CsmDeclaration.Kind.NAMESPACE_DEFINITION) {
0844: dumpModel((CsmNamespaceDefinition) decl);
0845: } else if (decl.getKind() == CsmDeclaration.Kind.FUNCTION) {
0846: dumpModel((CsmFunction) decl);
0847: } else if (decl.getKind() == CsmDeclaration.Kind.FUNCTION_DEFINITION) {
0848: dumpModel((CsmFunctionDefinition) decl);
0849: } else if (decl.getKind() == CsmDeclaration.Kind.VARIABLE) {
0850: dumpModel((CsmVariable) decl);
0851: } else if (decl.getKind() == CsmDeclaration.Kind.VARIABLE_DEFINITION) {
0852: dumpModel((CsmVariableDefinition) decl);
0853: } else if (decl.getKind() == CsmDeclaration.Kind.NAMESPACE_ALIAS) {
0854: dumpModel((CsmNamespaceAlias) decl);
0855: } else if (decl.getKind() == CsmDeclaration.Kind.USING_DECLARATION) {
0856: dumpModel((CsmUsingDeclaration) decl);
0857: } else if (decl.getKind() == CsmDeclaration.Kind.USING_DIRECTIVE) {
0858: dumpModel((CsmUsingDirective) decl);
0859: } else if (decl.getKind() == CsmDeclaration.Kind.TYPEDEF) {
0860: dumpModel((CsmTypedef) decl);
0861: } else {
0862: String ofStr = getOffsetString(decl, false);
0863: print("" + decl.getKind() + ' ' + decl.getName() + ofStr);
0864: }
0865: }
0866:
0867: public void dumpModel(CsmNamespaceAlias alias) {
0868: CsmNamespace referencedNamespace = alias
0869: .getReferencedNamespace();
0870: String refNsName = (referencedNamespace == null) ? NULL_TEXT
0871: : referencedNamespace.getQualifiedName().toString(); // NOI18N
0872: print("ALIAS " + alias.getAlias() + ' ' + refNsName + ' '
0873: + getOffsetString(alias, false) + // NOI18N
0874: ' ' + getScopeString(alias)); // NOI18N
0875: }
0876:
0877: public void dumpModel(CsmUsingDeclaration ud) {
0878: CsmOffsetableDeclaration decl = (CsmOffsetableDeclaration) ud
0879: .getReferencedDeclaration();
0880: String qname = decl == null ? NULL_TEXT : decl
0881: .getQualifiedName().toString(); // NOI18N
0882: print("USING DECL. " + ud.getName() + ' '
0883: + getOffsetString(ud, false) + "; REF DECL: " + qname
0884: + // NOI18N
0885: ' ' + getOffsetString(decl, false) + ' '
0886: + getScopeString(ud)); // NOI18N
0887: }
0888:
0889: public void dumpModel(CsmTypedef td) {
0890: print("TYPEDEF " + td.getName() + ' '
0891: + getOffsetString(td, false) + " TYPE: "
0892: + toString(td.getType(), false) + // NOI18N
0893: ' ' + getScopeString(td)); // NOI18N
0894: }
0895:
0896: public void dumpModel(CsmUsingDirective ud) {
0897: CsmNamespace nsp = ud.getReferencedNamespace();
0898: print("USING NAMESPACE. " + ud.getName()
0899: + ' '
0900: + getOffsetString(ud, false)
0901: + // NOI18N
0902: "; REF NS: "
0903: + (nsp == null ? NULL_TEXT : nsp.getQualifiedName())
0904: + ' ' + getScopeString(ud)); // NOI18N
0905: }
0906:
0907: public void dumpModel(CsmClass cls) {
0908: String kw = (cls.getKind() == CsmDeclaration.Kind.CLASS) ? "CLASS"
0909: : // NOI18N
0910: (cls.getKind() == CsmDeclaration.Kind.STRUCT) ? "STRUCT"
0911: : // NOI18N
0912: (cls.getKind() == CsmDeclaration.Kind.UNION) ? "UNION"
0913: : // NOI18N
0914: "<unknown-CsmClass-kind>"; // NOI18N
0915:
0916: String tmplStr = cls.isTemplate() ? "<>" : ""; // NOI18N
0917: print(kw + ' ' + cls.getName() + tmplStr + " ("
0918: + cls.getQualifiedName()
0919: + " )"
0920: + // NOI18N
0921: getOffsetString(cls, false) + " lcurly="
0922: + cls.getLeftBracketOffset() + ' '
0923: + getScopeString(cls)); // NOI18N
0924:
0925: indent();
0926: print("BASE CLASSES:"); // NOI18N
0927: indent();
0928: for (Iterator iter = cls.getBaseClasses().iterator(); iter
0929: .hasNext();) {
0930: CsmInheritance inh = (CsmInheritance) iter.next();
0931: print(toString(inh));
0932: }
0933: unindent();
0934: print("MEMBERS:"); // NOI18N
0935: indent();
0936: Collection/*<CsmMember>*/members = cls.getMembers();
0937: for (Iterator iter = members.iterator(); iter.hasNext();) {
0938: CsmMember member = (CsmMember) iter.next();
0939: if (CsmKindUtilities.isClass(member)) {
0940: dumpModel((CsmClass) member);
0941: } else if (member.getKind() == CsmDeclaration.Kind.ENUM) {
0942: dumpModel((CsmEnum) member);
0943: } else if (member.getKind() == CsmDeclaration.Kind.VARIABLE) {
0944: dumpModel((CsmField) member);
0945: } else if (member.getKind() == CsmDeclaration.Kind.FUNCTION) {
0946: dumpModel((CsmFunction) member);
0947: } else if (member.getKind() == CsmDeclaration.Kind.FUNCTION_DEFINITION) { // inline function
0948: dumpModel((CsmFunctionDefinition) member);
0949: } else if (member.getKind() == CsmDeclaration.Kind.TYPEDEF) {
0950: dumpModel((CsmTypedef) member);
0951: } else {
0952: StringBuilder sb = new StringBuilder(member.getKind()
0953: .toString());
0954: sb.append(' ');
0955: sb.append(member.getVisibility().toString());
0956: if (member.isStatic()) {
0957: sb.append(" static"); // NOI18N
0958: }
0959: sb.append(' ');
0960: sb.append(member.getName());
0961: sb.append(getOffsetString(member, false));
0962: sb.append(' ');
0963: sb.append(getBriefClassName(member));
0964: print(sb.toString());
0965: }
0966: }
0967: unindent();
0968: Collection/*<CsmMember>*/friends = cls.getFriends();
0969: if (!friends.isEmpty()) {
0970: print("FRIENDS:"); // NOI18N
0971: indent();
0972: for (Iterator iter = friends.iterator(); iter.hasNext();) {
0973: CsmFriend friend = (CsmFriend) iter.next();
0974: if (friend.getKind() == CsmDeclaration.Kind.CLASS_FRIEND_DECLARATION) {
0975: CsmFriendClass frClass = (CsmFriendClass) friend;
0976: StringBuilder sb = new StringBuilder(frClass
0977: .getKind().toString());
0978: sb.append(' ');
0979: sb.append(friend.getName());
0980: sb.append(getOffsetString(friend, false));
0981: sb.append(' ');
0982: sb.append(getBriefClassName(friend));
0983: print(sb.toString());
0984: indent();
0985: CsmClass refClass = frClass.getReferencedClass();
0986: print("REFERENCED CLASS: " + refClass == null ? "*UNRESOLVED*"
0987: : refClass.getUniqueName().toString()); // NOI18N
0988: unindent();
0989: } else if (friend.getKind() == CsmDeclaration.Kind.FUNCTION) {
0990: dumpModel((CsmFunction) friend);
0991: } else if (friend.getKind() == CsmDeclaration.Kind.FUNCTION_DEFINITION) { // inline function
0992: dumpModel((CsmFunctionDefinition) friend);
0993: } else {
0994: assert false : "unexpected friend object " + friend;
0995: }
0996: }
0997: unindent();
0998: }
0999: unindent();
1000: }
1001:
1002: public void dumpModel(CsmEnum enumeration) {
1003: print("ENUM " + enumeration.getName()
1004: + getOffsetString(enumeration, false) + ' '
1005: + getScopeString(enumeration)); // NOI18N
1006: indent();
1007: for (Iterator iter = enumeration.getEnumerators().iterator(); iter
1008: .hasNext();) {
1009: CsmEnumerator enumerator = (CsmEnumerator) iter.next();
1010: StringBuilder sb = new StringBuilder(enumerator.getName());
1011: if (enumerator.getExplicitValue() != null) {
1012: sb.append(' ');
1013: sb.append(enumerator.getExplicitValue().getText()
1014: + getOffsetString(enumerator, false));
1015: }
1016: print(sb.toString());
1017: }
1018: unindent();
1019: }
1020:
1021: public void dumpModel(CsmNamespaceDefinition nsp) {
1022: print("NAMESPACE DEFINITOIN " + nsp.getName()
1023: + getOffsetString(nsp, false) + ' '
1024: + getScopeString(nsp)); // NOI18N
1025: indent();
1026: for (Iterator iter = nsp.getDeclarations().iterator(); iter
1027: .hasNext();) {
1028: dumpModel((CsmDeclaration) iter.next());
1029: }
1030: unindent();
1031: }
1032:
1033: private Object modelChangeEventLock = new Object();
1034:
1035: public void dumpModelChangeEvent(CsmChangeEvent e) {
1036: synchronized (modelChangeEventLock) {
1037: print("Model Changed Event:"); // NOI18N
1038: dumpFilesCollection(e.getNewFiles(), "New files"); // NOI18N
1039: dumpFilesCollection(e.getRemovedFiles(), "Removed files"); // NOI18N
1040: dumpFilesCollection(e.getChangedFiles(), "Changed files"); // NOI18N
1041: dumpDeclarationsCollection(e.getNewDeclarations(),
1042: "New declarations"); // NOI18N
1043: dumpDeclarationsCollection(e.getRemovedDeclarations(),
1044: "Removed declarations"); // NOI18N
1045: dumpDeclarationsCollection(e.getChangedDeclarations()
1046: .keySet(), "Changed declarations"); // NOI18N
1047: dumpNamespacesCollection(e.getNewNamespaces(),
1048: "New namespaces"); // NOI18N
1049: dumpNamespacesCollection(e.getRemovedNamespaces(),
1050: "Removed namespaces"); // NOI18N
1051: print("");
1052: }
1053: }
1054:
1055: public void dumpFilesCollection(Collection/*<CsmFile>*/files,
1056: String title) {
1057: if (!files.isEmpty()) {
1058: print(title);
1059: indent();
1060: dumpFilesCollection(files);
1061: unindent();
1062: }
1063: }
1064:
1065: public void dumpFilesCollection(Collection/*<CsmFile>*/files) {
1066: if (!files.isEmpty()) {
1067: for (Iterator iter = files.iterator(); iter.hasNext();) {
1068: CsmFile file = (CsmFile) iter.next();
1069: print(file == null ? NULL_TEXT : file.getAbsolutePath()
1070: .toString()); // NOI18N
1071: }
1072: }
1073: }
1074:
1075: public void dumpDeclarationsCollection(
1076: Collection/*<CsmDeclaration>*/declarations, String title) {
1077: if (!declarations.isEmpty()) {
1078: print(title);
1079: indent();
1080: dumpDeclarationsCollection(declarations);
1081: unindent();
1082: }
1083: }
1084:
1085: public void dumpDeclarationsCollection(
1086: Collection/*<CsmDeclaration>*/declarations) {
1087: if (!declarations.isEmpty()) {
1088: for (Iterator iter = declarations.iterator(); iter
1089: .hasNext();) {
1090: CsmDeclaration decl = (CsmDeclaration) iter.next();
1091: print(decl == null ? NULL_TEXT : (decl.getUniqueName()
1092: + " of kind: " + decl.getKind())); // NOI18N
1093: }
1094: }
1095: }
1096:
1097: public void dumpNamespacesCollection(
1098: Collection/*<CsmNamespace>*/namespaces, String title) {
1099: if (!namespaces.isEmpty()) {
1100: print(title);
1101: indent();
1102: dumpNamespacesCollection(namespaces);
1103: unindent();
1104: }
1105: }
1106:
1107: public void dumpNamespacesCollection(
1108: Collection/*<CsmNamespace>*/namespaces) {
1109: if (!namespaces.isEmpty()) {
1110: for (Iterator iter = namespaces.iterator(); iter.hasNext();) {
1111: CsmNamespace nsp = (CsmNamespace) iter.next();
1112: print(nsp == null ? NULL_TEXT : nsp.getQualifiedName()
1113: .toString()); // NOI18N
1114: }
1115: }
1116: }
1117: }
|