001: /*
002: * @(#)SourceOrderDeclScanner.java 1.5 04/09/16
003: *
004: * Copyright (c) 2004, Sun Microsystems, Inc.
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions are met:
009: *
010: * * Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: * * Neither the name of the Sun Microsystems, Inc. nor the names of
016: * its contributors may be used to endorse or promote products derived from
017: * this software without specific prior written permission.
018: *
019: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
020: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
021: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
022: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
023: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
024: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
025: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
026: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
027: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
028: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
029: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030: */
031:
032: package com.sun.mirror.util;
033:
034: import com.sun.mirror.declaration.*;
035:
036: import java.util.SortedSet;
037: import java.util.TreeSet;
038:
039: /**
040: * A visitor for declarations that scans declarations contained within
041: * the given declaration in source code order. For example, when
042: * visiting a class, the methods, fields, constructors, and nested
043: * types of the class are also visited.
044: *
045: * To control the processing done on a declaration, users of this
046: * class pass in their own visitors for pre and post processing. The
047: * preprocessing visitor is called before the contained declarations
048: * are scanned; the postprocessing visitor is called after the
049: * contained declarations are scanned.
050: *
051: * @author Joseph D. Darcy
052: * @author Scott Seligman
053: * @version 1.5 04/09/16
054: * @since 1.5
055: */
056: class SourceOrderDeclScanner extends DeclarationScanner {
057: static class SourceOrderComparator implements
058: java.util.Comparator<Declaration> {
059: SourceOrderComparator() {
060: }
061:
062: static boolean equals(Declaration d1, Declaration d2) {
063: return d1 == d2 || (d1 != null && d1.equals(d2));
064: }
065:
066: private static class DeclPartialOrder extends
067: com.sun.mirror.util.SimpleDeclarationVisitor {
068: private int value = 1000;
069:
070: private static int staticAdjust(Declaration d) {
071: return d.getModifiers().contains(Modifier.STATIC) ? 0
072: : 1;
073: }
074:
075: DeclPartialOrder() {
076: }
077:
078: public int getValue() {
079: return value;
080: }
081:
082: @Override
083: public void visitTypeParameterDeclaration(
084: TypeParameterDeclaration d) {
085: value = 0;
086: }
087:
088: @Override
089: public void visitEnumConstantDeclaration(
090: EnumConstantDeclaration d) {
091: value = 1;
092: }
093:
094: @Override
095: public void visitClassDeclaration(ClassDeclaration d) {
096: value = 2 + staticAdjust(d);
097: }
098:
099: @Override
100: public void visitInterfaceDeclaration(InterfaceDeclaration d) {
101: value = 4;
102: }
103:
104: @Override
105: public void visitEnumDeclaration(EnumDeclaration d) {
106: value = 6;
107: }
108:
109: @Override
110: public void visitAnnotationTypeDeclaration(
111: AnnotationTypeDeclaration d) {
112: value = 8;
113: }
114:
115: @Override
116: public void visitFieldDeclaration(FieldDeclaration d) {
117: value = 10 + staticAdjust(d);
118: }
119:
120: @Override
121: public void visitConstructorDeclaration(
122: ConstructorDeclaration d) {
123: value = 12;
124: }
125:
126: @Override
127: public void visitMethodDeclaration(MethodDeclaration d) {
128: value = 14 + staticAdjust(d);
129: }
130: }
131:
132: private int compareEqualPosition(Declaration d1, Declaration d2) {
133: assert d1.getPosition() == d2.getPosition();
134:
135: DeclPartialOrder dpo1 = new DeclPartialOrder();
136: DeclPartialOrder dpo2 = new DeclPartialOrder();
137:
138: d1.accept(dpo1);
139: d2.accept(dpo2);
140:
141: int difference = dpo1.getValue() - dpo2.getValue();
142: if (difference != 0)
143: return difference;
144: else {
145: int result = d1.getSimpleName().compareTo(
146: d2.getSimpleName());
147: if (result != 0)
148: return result;
149: return (Long.signum((long) System.identityHashCode(d1)
150: - (long) System.identityHashCode(d2)));
151: }
152: }
153:
154: public int compare(Declaration d1, Declaration d2) {
155: if (equals(d1, d2))
156: return 0;
157:
158: SourcePosition p1 = d1.getPosition();
159: SourcePosition p2 = d2.getPosition();
160:
161: if (p1 == null && p2 != null)
162: return 1;
163: else if (p1 != null && p2 == null)
164: return -1;
165: else if (p1 == null && p2 == null)
166: return compareEqualPosition(d1, d2);
167: else {
168: assert p1 != null && p2 != null;
169: int fileComp = p1.file().compareTo(p2.file());
170: if (fileComp == 0) {
171: long diff = (long) p1.line() - (long) p2.line();
172: if (diff == 0) {
173: diff = Long.signum((long) p1.column()
174: - (long) p2.column());
175: if (diff != 0)
176: return (int) diff;
177: else {
178: // declarations may be two
179: // compiler-generated members with the
180: // same source position
181: return compareEqualPosition(d1, d2);
182: }
183: } else
184: return (diff < 0) ? -1 : 1;
185: } else
186: return fileComp;
187: }
188: }
189: }
190:
191: final static java.util.Comparator<Declaration> comparator = new SourceOrderComparator();
192:
193: SourceOrderDeclScanner(DeclarationVisitor pre,
194: DeclarationVisitor post) {
195: super (pre, post);
196: }
197:
198: /**
199: * Visits a type declaration.
200: *
201: * @param d the declaration to visit
202: */
203: public void visitTypeDeclaration(TypeDeclaration d) {
204: d.accept(pre);
205:
206: SortedSet<Declaration> decls = new TreeSet<Declaration>(
207: SourceOrderDeclScanner.comparator);
208:
209: for (TypeParameterDeclaration tpDecl : d
210: .getFormalTypeParameters()) {
211: decls.add(tpDecl);
212: }
213:
214: for (FieldDeclaration fieldDecl : d.getFields()) {
215: decls.add(fieldDecl);
216: }
217:
218: for (MethodDeclaration methodDecl : d.getMethods()) {
219: decls.add(methodDecl);
220: }
221:
222: for (TypeDeclaration typeDecl : d.getNestedTypes()) {
223: decls.add(typeDecl);
224: }
225:
226: for (Declaration decl : decls)
227: decl.accept(this );
228:
229: d.accept(post);
230: }
231:
232: /**
233: * Visits a class declaration.
234: *
235: * @param d the declaration to visit
236: */
237: public void visitClassDeclaration(ClassDeclaration d) {
238: d.accept(pre);
239:
240: SortedSet<Declaration> decls = new TreeSet<Declaration>(
241: SourceOrderDeclScanner.comparator);
242:
243: for (TypeParameterDeclaration tpDecl : d
244: .getFormalTypeParameters()) {
245: decls.add(tpDecl);
246: }
247:
248: for (FieldDeclaration fieldDecl : d.getFields()) {
249: decls.add(fieldDecl);
250: }
251:
252: for (MethodDeclaration methodDecl : d.getMethods()) {
253: decls.add(methodDecl);
254: }
255:
256: for (TypeDeclaration typeDecl : d.getNestedTypes()) {
257: decls.add(typeDecl);
258: }
259:
260: for (ConstructorDeclaration ctorDecl : d.getConstructors()) {
261: decls.add(ctorDecl);
262: }
263:
264: for (Declaration decl : decls)
265: decl.accept(this );
266:
267: d.accept(post);
268: }
269:
270: public void visitExecutableDeclaration(ExecutableDeclaration d) {
271: d.accept(pre);
272:
273: SortedSet<Declaration> decls = new TreeSet<Declaration>(
274: SourceOrderDeclScanner.comparator);
275:
276: for (TypeParameterDeclaration tpDecl : d
277: .getFormalTypeParameters())
278: decls.add(tpDecl);
279:
280: for (ParameterDeclaration pDecl : d.getParameters())
281: decls.add(pDecl);
282:
283: for (Declaration decl : decls)
284: decl.accept(this);
285:
286: d.accept(post);
287: }
288:
289: }
|