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.io.PrintStream;
045: import java.util.*;
046: import org.netbeans.modules.cnd.api.model.*;
047: import org.netbeans.modules.cnd.api.model.deep.*;
048: import org.netbeans.modules.cnd.api.model.util.*;
049:
050: /**
051: * A list of high-level model declarations - variables and functions.
052: * @author Vladimir Kvashin
053: */
054: public class ModelList {
055:
056: private CsmFile file;
057: private Map<String, List<CsmDeclaration>> map = new HashMap<String, List<CsmDeclaration>>();
058: private List<CsmDeclaration> list = new ArrayList<CsmDeclaration>();
059: private List<CsmDeclaration> STUB = Collections.emptyList();
060:
061: public ModelList(CsmFile file) {
062: this .file = file;
063: add(file.getDeclarations());
064: }
065:
066: public ModelList(CsmClass cls) {
067: this .file = cls.getContainingFile();
068: add(cls.getMembers());
069: }
070:
071: private void add(Iterable<CsmDeclaration> currDeclarations) {
072: for (CsmDeclaration decl : currDeclarations) {
073: CsmDeclaration.Kind kind = decl.getKind();
074: if (kind == CsmDeclaration.Kind.CLASS
075: || kind == CsmDeclaration.Kind.UNION
076: || kind == CsmDeclaration.Kind.STRUCT) {
077: add((CsmClass) decl);
078: } else if (kind == CsmDeclaration.Kind.ENUM) {
079: add((CsmEnum) decl);
080: } else if (kind == CsmDeclaration.Kind.ENUMERATOR) {
081: add((CsmEnumerator) decl);
082: } else if (kind == CsmDeclaration.Kind.VARIABLE
083: || kind == CsmDeclaration.Kind.VARIABLE_DEFINITION) {
084: add((CsmVariable) decl);
085: } else if (kind == CsmDeclaration.Kind.FUNCTION
086: || kind == CsmDeclaration.Kind.FUNCTION_DEFINITION) {
087: add((CsmFunction) decl);
088: } else if (kind == CsmDeclaration.Kind.TEMPLATE_SPECIALIZATION) {
089: // TODO: implement as soon as template specializations are implemented
090: } else if (kind == CsmDeclaration.Kind.TYPEDEF) {
091: add((CsmTypedef) decl);
092: } else if (kind == CsmDeclaration.Kind.NAMESPACE_DEFINITION) {
093: add((CsmNamespaceDefinition) decl);
094: }
095: // The following does not make sense here:
096: // ASM
097: // TEMPLATE_DECLARATION
098: // NAMESPACE_ALIAS
099: // USING_DIRECTIVE
100: // USING_DECLARATION
101: // CLASS_FORWARD_DECLARATION
102: }
103: }
104:
105: public Iterable<CsmDeclaration> getDeclarations(String qualifiedName) {
106: List<CsmDeclaration> result = map.get(qualifiedName);
107: if (result == null && !qualifiedName.startsWith("::")) { // NOI18N
108: result = map.get("::" + qualifiedName); // NOI18N
109: }
110: return (result == null) ? STUB : result;
111: }
112:
113: public Iterable<CsmDeclaration> getDeclarations() {
114: return list;
115: }
116:
117: /** the same as getDeclarations, but creates a list */
118: private List<CsmDeclaration> getList(String qualifiedName) {
119: qualifiedName = qualifiedName.replaceAll(" ", ""); // NOI18N
120: List<CsmDeclaration> result = map.get(qualifiedName);
121: if (result == null) {
122: result = new ArrayList<CsmDeclaration>();
123: map.put(qualifiedName, result);
124: }
125: return result;
126: }
127:
128: private void add(CsmClass cls) {
129: add(cls.getMembers());
130: }
131:
132: private void add(CsmEnum enm) {
133: add(enm.getEnumerators());
134: }
135:
136: private void add(CsmNamespaceDefinition ns) {
137: add(ns.getDeclarations());
138: }
139:
140: private void add(CsmEnumerator enumerator) {
141: put(enumerator);
142: }
143:
144: private void add(CsmVariable var) {
145: put(var);
146: }
147:
148: private void add(CsmFunction funct) {
149: put(funct);
150: }
151:
152: private void add(CsmTypedef td) {
153: put(td);
154: }
155:
156: private void put(CsmFunction funct) {
157: List<CsmDeclaration> overloads = getList(funct
158: .getQualifiedName());
159: if (overloads.size() > 0) {
160: if (CsmKindUtilities.isFunctionDefinition(funct)) {
161: // if there is a declaration of this function in the list,
162: // replace it with this definition
163: CsmFunction decl = ((CsmFunctionDefinition) funct)
164: .getDeclaration();
165: if (decl != funct
166: && Collections.replaceAll(overloads, decl,
167: funct)) {
168: Collections.replaceAll(this .list, decl, funct);
169: } else {
170: overloads.add(funct);
171: this .list.add(funct);
172: }
173: } else { // this is just a declaration
174: CsmFunctionDefinition def = funct.getDefinition();
175: if (!overloads.contains(def)) {
176: overloads.add(funct);
177: this .list.add(funct);
178: }
179: }
180: } else {
181: overloads.add(funct);
182: this .list.add(funct);
183: }
184: }
185:
186: private void put(CsmDeclaration decl) {
187: String qName = ComparisonUtils.getQualifiedName(decl);
188: List<CsmDeclaration> overloads = getList(qName);
189: overloads.add(decl);
190: this .list.add(decl);
191: }
192:
193: public void dump(PrintStream ps, boolean bodies) {
194: ps.println("==== Model comparison list for " + file.getName()
195: + " " + file.getAbsolutePath()); // NOI18N
196: List<CsmDeclaration> sorted = new ArrayList<CsmDeclaration>(
197: list);
198: Collections.sort(sorted,
199: new ComparisonUtils.CsmDeclarationComparator());
200: for (CsmDeclaration decl : sorted) {
201: dump(ps, decl, bodies);
202: }
203: ps.println("\n"); // NOI18N
204: }
205:
206: private void dump(PrintStream ps, CsmDeclaration decl,
207: boolean bodies) {
208: ps.println(Tracer.toString(decl));
209: if (bodies && CsmKindUtilities.isFunctionDefinition(decl)) {
210: Node<CsmDeclaration> node = ModelTree
211: .createModelNode((CsmFunctionDefinition) decl);
212: Tracer tr = new Tracer(ps);
213: tr.indent();
214: tr.traceModel(node);
215: }
216: }
217:
218: }
|