001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package dwarfvsmodel;
043:
044: import java.util.*;
045: import org.netbeans.modules.cnd.api.model.*;
046: import org.netbeans.modules.cnd.api.model.deep.*;
047:
048: /**
049: * Misc. model-related utility functions
050: * @author vk155633
051: */
052: public class ModelTree {
053:
054: public static Node<CsmDeclaration> createModelNode(
055: CsmFunctionDefinition modelDefinition) {
056: Node<CsmDeclaration> root = new Node<CsmDeclaration>();
057: addCompoundStatement(root, modelDefinition.getBody());
058: Comparator<CsmDeclaration> comparator = new ComparisonUtils.CsmDeclarationComparator();
059: root.flatten();
060: root.sort(comparator);
061: // for( Node<CsmDeclaration> child : root.getSubnodes() ) {
062: // child.flatten();
063: // child.sort(comparator);
064: // }
065: return root;
066: }
067:
068: private static Node<CsmDeclaration> createModelNode(
069: Iterable<CsmStatement> modelStatements) {
070: Node<CsmDeclaration> node = new Node<CsmDeclaration>();
071: for (CsmStatement stmt : modelStatements) {
072: addStatement(node, stmt);
073: }
074: return node;
075: }
076:
077: private static void addStatement(Node<CsmDeclaration> node,
078: CsmStatement stmt) {
079: if (stmt != null) {
080: CsmStatement.Kind kind = stmt.getKind();
081: if (kind == CsmStatement.Kind.DECLARATION) {
082: addDeclarationStatement(node,
083: (CsmDeclarationStatement) stmt);
084: } else if (kind == CsmStatement.Kind.COMPOUND) {
085: addCompoundStatement(node, (CsmCompoundStatement) stmt);
086: } else if (kind == CsmStatement.Kind.DO_WHILE) {
087: addLoopStatement(node, (CsmLoopStatement) stmt);
088: } else if (kind == CsmStatement.Kind.WHILE) {
089: addLoopStatement(node, (CsmLoopStatement) stmt);
090: } else if (kind == CsmStatement.Kind.FOR) {
091: addForStatement(node, (CsmForStatement) stmt);
092: } else if (kind == CsmStatement.Kind.SWITCH) {
093: addSwitchStatement(node, (CsmSwitchStatement) stmt);
094: } else if (kind == CsmStatement.Kind.TRY_CATCH) {
095: addTryCatchStatement(node, (CsmTryCatchStatement) stmt);
096: } else if (kind == CsmStatement.Kind.IF) {
097: addIfStatement(node, (CsmIfStatement) stmt);
098: }
099: }
100: }
101:
102: private static void addCompoundStatement(Node<CsmDeclaration> node,
103: CsmCompoundStatement stmt) {
104: List<CsmStatement> statements = (stmt == null) ? new ArrayList<CsmStatement>(
105: 1)
106: : stmt.getStatements();
107: node.addSubnode(createModelNode(statements));
108: }
109:
110: private static void addDeclarationStatement(
111: Node<CsmDeclaration> node, CsmDeclarationStatement stmt) {
112: for (CsmDeclaration decl : (Iterable<CsmDeclaration>) stmt
113: .getDeclarators()) {
114: node.addDeclaration(decl);
115: }
116: }
117:
118: private static void addCondition(Node<CsmDeclaration> node,
119: CsmCondition condition) {
120: if (condition != null) {
121: if (condition.getKind() == CsmCondition.Kind.DECLARATION) {
122: node.addDeclaration(condition.getDeclaration());
123: }
124: }
125: }
126:
127: private static void addLoopOrCondBody(Node<CsmDeclaration> node,
128: CsmStatement body) {
129: if (body != null) {
130: if (body.getKind() == CsmStatement.Kind.COMPOUND) {
131: //addCompoundStatement(node, (CsmCompoundStatement) body);
132: List<CsmStatement> statements = (List<CsmStatement>) ((CsmCompoundStatement) body)
133: .getStatements();
134: if (statements != null) {
135: for (CsmStatement stmt : statements) {
136: addStatement(node, stmt);
137: }
138: }
139: } else {
140: Node<CsmDeclaration> subnode = new Node<CsmDeclaration>();
141: addStatement(subnode, body);
142: node.addSubnode(subnode);
143: }
144: }
145: }
146:
147: private static void addLoopStatement(Node<CsmDeclaration> node,
148: CsmLoopStatement stmt) {
149:
150: boolean nested = stmt.getCondition() != null
151: && stmt.getCondition().getKind() == CsmCondition.Kind.DECLARATION;
152: Node<CsmDeclaration> subnode = nested ? new Node<CsmDeclaration>()
153: : node;
154: addCondition(subnode, stmt.getCondition());
155: addStatementNestedIfNeed(subnode, stmt.getBody());
156: if (nested) {
157: node.addSubnode(subnode);
158: }
159: }
160:
161: private static void addForStatement(Node<CsmDeclaration> node,
162: CsmForStatement stmt) {
163: boolean nested = stmt.getInitStatement() != null
164: && stmt.getInitStatement().getKind() == CsmStatement.Kind.DECLARATION;
165: Node<CsmDeclaration> subnode = nested ? new Node<CsmDeclaration>()
166: : node;
167: addStatement(subnode, stmt.getInitStatement());
168: addCondition(subnode, stmt.getCondition());
169: addStatementNestedIfNeed(subnode, stmt.getBody());
170: if (nested) {
171: node.addSubnode(subnode);
172: }
173: }
174:
175: private static void addSwitchStatement(Node<CsmDeclaration> node,
176: CsmSwitchStatement stmt) {
177:
178: boolean nested = stmt.getCondition() != null
179: && stmt.getCondition().getKind() == CsmCondition.Kind.DECLARATION;
180: Node<CsmDeclaration> subnode = nested ? new Node<CsmDeclaration>()
181: : node;
182:
183: addCondition(subnode, stmt.getCondition());
184: addLoopOrCondBody(subnode, stmt.getBody());
185:
186: if (nested) {
187: node.addSubnode(subnode);
188: }
189: }
190:
191: private static void addTryCatchStatement(Node<CsmDeclaration> node,
192: CsmTryCatchStatement stmt) {
193: addStatement(node, stmt.getTryStatement());
194: for (CsmExceptionHandler handler : (List<CsmExceptionHandler>) stmt
195: .getHandlers()) {
196: addExceptionHandler(node, handler);
197: }
198: }
199:
200: private static void addExceptionHandler(Node<CsmDeclaration> node,
201: CsmExceptionHandler stmt) {
202: if (stmt.isCatchAll()) {
203: addCompoundStatement(node, stmt);
204: } else {
205: Node<CsmDeclaration> subnode = new Node<CsmDeclaration>();
206: subnode.addDeclaration(stmt.getParameter());
207: addCompoundStatement(subnode, stmt);
208: node.addSubnode(subnode);
209: }
210: }
211:
212: private static void addIfStatement(Node<CsmDeclaration> node,
213: CsmIfStatement stmt) {
214: boolean nested = stmt.getCondition() != null
215: && stmt.getCondition().getKind() == CsmCondition.Kind.DECLARATION;
216: Node<CsmDeclaration> subnode = nested ? new Node<CsmDeclaration>()
217: : node;
218: addCondition(subnode, stmt.getCondition());
219: addStatementNestedIfNeed(subnode, stmt.getThen());
220: addStatementNestedIfNeed(subnode, stmt.getElse());
221: if (nested) {
222: node.addSubnode(subnode);
223: }
224: }
225:
226: private static void addStatementNestedIfNeed(
227: Node<CsmDeclaration> node, CsmStatement stmt) {
228: if (stmt != null) {
229: if (stmt.getKind() == CsmStatement.Kind.COMPOUND) {
230: addStatement(node, stmt);
231: } else {
232: Node<CsmDeclaration> subnode = new Node<CsmDeclaration>();
233: addStatement(subnode, stmt);
234: node.addSubnode(subnode);
235: }
236: }
237: }
238: }
|