Source Code Cross Referenced for ScopeAnalyzer.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » dom » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.corext.dom 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jdt.internal.corext.dom;
011:
012:        import java.util.ArrayList;
013:        import java.util.Collection;
014:        import java.util.HashSet;
015:        import java.util.List;
016:
017:        import org.eclipse.jdt.core.dom.AST;
018:        import org.eclipse.jdt.core.dom.ASTNode;
019:        import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
020:        import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
021:        import org.eclipse.jdt.core.dom.Block;
022:        import org.eclipse.jdt.core.dom.BodyDeclaration;
023:        import org.eclipse.jdt.core.dom.CatchClause;
024:        import org.eclipse.jdt.core.dom.ClassInstanceCreation;
025:        import org.eclipse.jdt.core.dom.CompilationUnit;
026:        import org.eclipse.jdt.core.dom.Expression;
027:        import org.eclipse.jdt.core.dom.FieldAccess;
028:        import org.eclipse.jdt.core.dom.ForStatement;
029:        import org.eclipse.jdt.core.dom.IBinding;
030:        import org.eclipse.jdt.core.dom.IMethodBinding;
031:        import org.eclipse.jdt.core.dom.ITypeBinding;
032:        import org.eclipse.jdt.core.dom.IVariableBinding;
033:        import org.eclipse.jdt.core.dom.ImportDeclaration;
034:        import org.eclipse.jdt.core.dom.Initializer;
035:        import org.eclipse.jdt.core.dom.MethodDeclaration;
036:        import org.eclipse.jdt.core.dom.MethodInvocation;
037:        import org.eclipse.jdt.core.dom.Modifier;
038:        import org.eclipse.jdt.core.dom.QualifiedName;
039:        import org.eclipse.jdt.core.dom.SimpleName;
040:        import org.eclipse.jdt.core.dom.Statement;
041:        import org.eclipse.jdt.core.dom.SuperMethodInvocation;
042:        import org.eclipse.jdt.core.dom.SwitchCase;
043:        import org.eclipse.jdt.core.dom.SwitchStatement;
044:        import org.eclipse.jdt.core.dom.Type;
045:        import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
046:        import org.eclipse.jdt.core.dom.TypeParameter;
047:        import org.eclipse.jdt.core.dom.VariableDeclaration;
048:        import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
049:        import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
050:
051:        import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
052:
053:        /**
054:         * Evaluates all fields, methods and types available (declared) at a given offset
055:         * in a compilation unit (Code assist that returns IBindings)
056:         */
057:        public class ScopeAnalyzer {
058:
059:            private static final IBinding[] NO_BINDING = new IBinding[0];
060:
061:            /**
062:             * Flag to specify that method should be reported.
063:             */
064:            public static final int METHODS = 1;
065:
066:            /**
067:             * Flag to specify that variables should be reported.
068:             */
069:            public static final int VARIABLES = 2;
070:
071:            /**
072:             * Flag to specify that types should be reported.
073:             */
074:            public static final int TYPES = 4;
075:
076:            /**
077:             * Flag to specify that only visible elements should be added.
078:             */
079:            public static final int CHECK_VISIBILITY = 16;
080:
081:            private static interface IBindingRequestor {
082:                boolean acceptBinding(IBinding binding);
083:            }
084:
085:            private static class DefaultBindingRequestor implements 
086:                    IBindingRequestor {
087:
088:                private final List fResult;
089:                private final HashSet fNamesAdded;
090:                private final int fFlags;
091:                private final ITypeBinding fParentTypeBinding;
092:
093:                public DefaultBindingRequestor(ITypeBinding parentTypeBinding,
094:                        int flags) {
095:                    fParentTypeBinding = parentTypeBinding;
096:                    fFlags = flags;
097:                    fResult = new ArrayList();
098:                    fNamesAdded = new HashSet();
099:                }
100:
101:                public DefaultBindingRequestor() {
102:                    this (null, 0);
103:                }
104:
105:                /**
106:                 * {@inheritDoc}
107:                 */
108:                public boolean acceptBinding(IBinding binding) {
109:                    if (binding == null)
110:                        return false;
111:
112:                    String signature = getSignature(binding);
113:                    if (signature != null && fNamesAdded.add(signature)) { // avoid duplicated results from inheritance
114:                        fResult.add(binding);
115:                    }
116:                    return false;
117:                }
118:
119:                public List getResult() {
120:                    if (hasFlag(CHECK_VISIBILITY, fFlags)) {
121:                        for (int i = fResult.size() - 1; i >= 0; i--) {
122:                            IBinding binding = (IBinding) fResult.get(i);
123:                            if (!isVisible(binding, fParentTypeBinding)) {
124:                                fResult.remove(i);
125:                            }
126:                        }
127:                    }
128:                    return fResult;
129:                }
130:
131:            }
132:
133:            private HashSet fTypesVisited;
134:
135:            private CompilationUnit fRoot;
136:
137:            public ScopeAnalyzer(CompilationUnit root) {
138:                fTypesVisited = new HashSet();
139:                fRoot = root;
140:            }
141:
142:            private void clearLists() {
143:                fTypesVisited.clear();
144:            }
145:
146:            private static String getSignature(IBinding binding) {
147:                if (binding != null) {
148:                    switch (binding.getKind()) {
149:                    case IBinding.METHOD:
150:                        StringBuffer buf = new StringBuffer();
151:                        buf.append('M');
152:                        buf.append(binding.getName()).append('(');
153:                        ITypeBinding[] parameters = ((IMethodBinding) binding)
154:                                .getParameterTypes();
155:                        for (int i = 0; i < parameters.length; i++) {
156:                            if (i > 0) {
157:                                buf.append(',');
158:                            }
159:                            ITypeBinding paramType = parameters[i].getErasure();
160:                            buf.append(paramType.getQualifiedName());
161:                        }
162:                        buf.append(')');
163:                        return buf.toString();
164:                    case IBinding.VARIABLE:
165:                        return 'V' + binding.getName();
166:                    case IBinding.TYPE:
167:                        return 'T' + binding.getName();
168:                    }
169:                }
170:                return null;
171:            }
172:
173:            static final boolean hasFlag(int property, int flags) {
174:                return (flags & property) != 0;
175:            }
176:
177:            /**
178:             * Collects all elements available in a type and its hierarchy
179:             * @param binding The type binding
180:             * @param flags Flags defining the elements to report
181:             * @param requestor the requestor to which all results are reported
182:             * @return return <code>true</code> if the requestor has reported the binding as found and no further results are required
183:             */
184:            private boolean addInherited(ITypeBinding binding, int flags,
185:                    IBindingRequestor requestor) {
186:                if (!fTypesVisited.add(binding)) {
187:                    return false;
188:                }
189:                if (hasFlag(VARIABLES, flags)) {
190:                    IVariableBinding[] variableBindings = binding
191:                            .getDeclaredFields();
192:                    for (int i = 0; i < variableBindings.length; i++) {
193:                        if (requestor.acceptBinding(variableBindings[i]))
194:                            return true;
195:                    }
196:                }
197:
198:                if (hasFlag(METHODS, flags)) {
199:                    IMethodBinding[] methodBindings = binding
200:                            .getDeclaredMethods();
201:                    for (int i = 0; i < methodBindings.length; i++) {
202:                        IMethodBinding curr = methodBindings[i];
203:                        if (!curr.isSynthetic() && !curr.isConstructor()) {
204:                            if (requestor.acceptBinding(curr))
205:                                return true;
206:                        }
207:                    }
208:                }
209:
210:                if (hasFlag(TYPES, flags)) {
211:                    ITypeBinding[] typeBindings = binding.getDeclaredTypes();
212:                    for (int i = 0; i < typeBindings.length; i++) {
213:                        ITypeBinding curr = typeBindings[i];
214:                        if (requestor.acceptBinding(curr))
215:                            return true;
216:                    }
217:                }
218:
219:                ITypeBinding super Class = binding.getSuperclass();
220:                if (super Class != null) {
221:                    if (addInherited(super Class, flags, requestor)) // recursive
222:                        return true;
223:                } else if (binding.isArray()) {
224:                    if (addInherited(fRoot.getAST().resolveWellKnownType(
225:                            "java.lang.Object"), flags, requestor)) //$NON-NLS-1$
226:                        return true;
227:                }
228:
229:                ITypeBinding[] interfaces = binding.getInterfaces(); // includes looking for methods: abstract, unimplemented methods
230:                for (int i = 0; i < interfaces.length; i++) {
231:                    if (addInherited(interfaces[i], flags, requestor)) // recursive
232:                        return true;
233:                }
234:                return false;
235:            }
236:
237:            /**
238:             * Collects all elements available in a type: its hierarchy and its outer scopes.
239:             * @param binding The type binding
240:             * @param flags Flags defining the elements to report
241:             * @param requestor the requestor to which all results are reported
242:             * @return return <code>true</code> if the requestor has reported the binding as found and no further results are required
243:             */
244:            private boolean addTypeDeclarations(ITypeBinding binding,
245:                    int flags, IBindingRequestor requestor) {
246:                if (hasFlag(TYPES, flags) && !binding.isAnonymous()) {
247:                    if (requestor.acceptBinding(binding))
248:                        return true;
249:
250:                    ITypeBinding[] typeParameters = binding.getTypeParameters();
251:                    for (int i = 0; i < typeParameters.length; i++) {
252:                        if (requestor.acceptBinding(typeParameters[i]))
253:                            return true;
254:                    }
255:                }
256:
257:                addInherited(binding, flags, requestor); // add inherited 
258:
259:                if (binding.isLocal()) {
260:                    addOuterDeclarationsForLocalType(binding, flags, requestor);
261:                } else {
262:                    ITypeBinding declaringClass = binding.getDeclaringClass();
263:                    if (declaringClass != null) {
264:                        if (addTypeDeclarations(declaringClass, flags,
265:                                requestor)) // Recursively add inherited
266:                            return true;
267:                    } else if (hasFlag(TYPES, flags)) {
268:                        if (fRoot.findDeclaringNode(binding) != null) {
269:                            List types = fRoot.types();
270:                            for (int i = 0; i < types.size(); i++) {
271:                                if (requestor
272:                                        .acceptBinding(((AbstractTypeDeclaration) types
273:                                                .get(i)).resolveBinding()))
274:                                    return true;
275:                            }
276:                        }
277:                    }
278:                }
279:                return false;
280:            }
281:
282:            private boolean addOuterDeclarationsForLocalType(
283:                    ITypeBinding localBinding, int flags,
284:                    IBindingRequestor requestor) {
285:                ASTNode node = fRoot.findDeclaringNode(localBinding);
286:                if (node == null) {
287:                    return false;
288:                }
289:
290:                if (node instanceof  AbstractTypeDeclaration
291:                        || node instanceof  AnonymousClassDeclaration) {
292:                    if (addLocalDeclarations(node.getParent(), flags, requestor))
293:                        return true;
294:
295:                    ITypeBinding parentTypeBinding = Bindings
296:                            .getBindingOfParentType(node.getParent());
297:                    if (parentTypeBinding != null) {
298:                        if (addTypeDeclarations(parentTypeBinding, flags,
299:                                requestor))
300:                            return true;
301:                    }
302:
303:                }
304:                return false;
305:            }
306:
307:            private static ITypeBinding getBinding(Expression node) {
308:                if (node != null) {
309:                    return node.resolveTypeBinding();
310:                }
311:                return null;
312:            }
313:
314:            private static ITypeBinding getQualifier(SimpleName selector) {
315:                ASTNode parent = selector.getParent();
316:                switch (parent.getNodeType()) {
317:                case ASTNode.METHOD_INVOCATION:
318:                    MethodInvocation decl = (MethodInvocation) parent;
319:                    if (selector == decl.getName()) {
320:                        return getBinding(decl.getExpression());
321:                    }
322:                    return null;
323:                case ASTNode.QUALIFIED_NAME:
324:                    QualifiedName qualifiedName = (QualifiedName) parent;
325:                    if (selector == qualifiedName.getName()) {
326:                        return getBinding(qualifiedName.getQualifier());
327:                    }
328:                    return null;
329:                case ASTNode.FIELD_ACCESS:
330:                    FieldAccess fieldAccess = (FieldAccess) parent;
331:                    if (selector == fieldAccess.getName()) {
332:                        return getBinding(fieldAccess.getExpression());
333:                    }
334:                    return null;
335:                case ASTNode.SUPER_FIELD_ACCESS: {
336:                    ITypeBinding curr = Bindings.getBindingOfParentType(parent);
337:                    return curr.getSuperclass();
338:                }
339:                case ASTNode.SUPER_METHOD_INVOCATION: {
340:                    SuperMethodInvocation super Inv = (SuperMethodInvocation) parent;
341:                    if (selector == super Inv.getName()) {
342:                        ITypeBinding curr = Bindings
343:                                .getBindingOfParentType(parent);
344:                        return curr.getSuperclass();
345:                    }
346:                    return null;
347:                }
348:                default:
349:                    if (parent instanceof  Type) {
350:                        // bug 67644: in 'a.new X()', all member types of A are visible as location of X. 
351:                        ASTNode normalizedNode = ASTNodes
352:                                .getNormalizedNode(parent);
353:                        if (normalizedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) {
354:                            ClassInstanceCreation creation = (ClassInstanceCreation) normalizedNode
355:                                    .getParent();
356:                            return getBinding(creation.getExpression());
357:                        }
358:                    }
359:                    return null;
360:                }
361:            }
362:
363:            public IBinding[] getDeclarationsInScope(SimpleName selector,
364:                    int flags) {
365:                try {
366:                    // special case for switch on enum
367:                    if (selector.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) {
368:                        ITypeBinding binding = ((SwitchStatement) selector
369:                                .getParent().getParent()).getExpression()
370:                                .resolveTypeBinding();
371:                        if (binding != null && binding.isEnum()) {
372:                            return getEnumContants(binding);
373:                        }
374:                    }
375:
376:                    ITypeBinding parentTypeBinding = Bindings
377:                            .getBindingOfParentType(selector);
378:                    if (parentTypeBinding != null) {
379:                        ITypeBinding binding = getQualifier(selector);
380:                        DefaultBindingRequestor requestor = new DefaultBindingRequestor(
381:                                parentTypeBinding, flags);
382:                        if (binding == null) {
383:                            addLocalDeclarations(selector, flags, requestor);
384:                            addTypeDeclarations(parentTypeBinding, flags,
385:                                    requestor);
386:                        } else {
387:                            addInherited(binding, flags, requestor);
388:                        }
389:
390:                        List result = requestor.getResult();
391:                        return (IBinding[]) result.toArray(new IBinding[result
392:                                .size()]);
393:                    }
394:                    return NO_BINDING;
395:                } finally {
396:                    clearLists();
397:                }
398:            }
399:
400:            private static class SearchRequestor implements  IBindingRequestor {
401:
402:                private final int fFlags;
403:                private final ITypeBinding fParentTypeBinding;
404:                private final IBinding fToSearch;
405:                private boolean fFound;
406:                private boolean fIsVisible;
407:
408:                public SearchRequestor(IBinding toSearch,
409:                        ITypeBinding parentTypeBinding, int flag) {
410:                    fFlags = flag;
411:                    fToSearch = toSearch;
412:                    fParentTypeBinding = parentTypeBinding;
413:                    fFound = false;
414:                    fIsVisible = true;
415:                }
416:
417:                public boolean acceptBinding(IBinding binding) {
418:                    if (fFound)
419:                        return true;
420:
421:                    if (binding == null)
422:                        return false;
423:
424:                    if (fToSearch.getKind() != binding.getKind()) {
425:                        return false;
426:                    }
427:
428:                    boolean checkVisibility = hasFlag(CHECK_VISIBILITY, fFlags);
429:                    if (binding == fToSearch) {
430:                        fFound = true;
431:                    } else {
432:                        IBinding bindingDeclaration = Bindings
433:                                .getDeclaration(binding);
434:                        if (bindingDeclaration == fToSearch) {
435:                            fFound = true;
436:                        } else if (bindingDeclaration.getName().equals(
437:                                fToSearch.getName())) {
438:                            String signature = getSignature(bindingDeclaration);
439:                            if (signature != null
440:                                    && signature
441:                                            .equals(getSignature(fToSearch))) {
442:                                if (checkVisibility) {
443:                                    fIsVisible = false;
444:                                }
445:                                return true; // found element that hides the binding to find
446:                            }
447:                        }
448:                    }
449:
450:                    if (fFound && checkVisibility) {
451:                        fIsVisible = ScopeAnalyzer.isVisible(binding,
452:                                fParentTypeBinding);
453:                    }
454:                    return fFound;
455:                }
456:
457:                public boolean found() {
458:                    return fFound;
459:                }
460:
461:                public boolean isVisible() {
462:                    return fIsVisible;
463:                }
464:            }
465:
466:            public boolean isDeclaredInScope(IBinding declaration,
467:                    SimpleName selector, int flags) {
468:                try {
469:                    // special case for switch on enum
470:                    if (selector.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) {
471:                        ITypeBinding binding = ((SwitchStatement) selector
472:                                .getParent().getParent()).getExpression()
473:                                .resolveTypeBinding();
474:                        if (binding != null && binding.isEnum()) {
475:                            return hasEnumContants(declaration, binding
476:                                    .getTypeDeclaration());
477:                        }
478:                    }
479:
480:                    ITypeBinding parentTypeBinding = Bindings
481:                            .getBindingOfParentTypeContext(selector);
482:                    if (parentTypeBinding != null) {
483:                        ITypeBinding binding = getQualifier(selector);
484:                        SearchRequestor requestor = new SearchRequestor(
485:                                declaration, parentTypeBinding, flags);
486:                        if (binding == null) {
487:                            addLocalDeclarations(selector, flags, requestor);
488:                            if (requestor.found())
489:                                return requestor.isVisible();
490:                            addTypeDeclarations(parentTypeBinding, flags,
491:                                    requestor);
492:                            if (requestor.found())
493:                                return requestor.isVisible();
494:                        } else {
495:                            addInherited(binding, flags, requestor);
496:                            if (requestor.found())
497:                                return requestor.isVisible();
498:                        }
499:                    }
500:                    return false;
501:                } finally {
502:                    clearLists();
503:                }
504:            }
505:
506:            private IVariableBinding[] getEnumContants(ITypeBinding binding) {
507:                IVariableBinding[] declaredFields = binding.getDeclaredFields();
508:                ArrayList res = new ArrayList(declaredFields.length);
509:                for (int i = 0; i < declaredFields.length; i++) {
510:                    IVariableBinding curr = declaredFields[i];
511:                    if (curr.isEnumConstant()) {
512:                        res.add(curr);
513:                    }
514:                }
515:                return (IVariableBinding[]) res
516:                        .toArray(new IVariableBinding[res.size()]);
517:            }
518:
519:            private boolean hasEnumContants(IBinding declaration,
520:                    ITypeBinding binding) {
521:                IVariableBinding[] declaredFields = binding.getDeclaredFields();
522:                for (int i = 0; i < declaredFields.length; i++) {
523:                    IVariableBinding curr = declaredFields[i];
524:                    if (curr == declaration)
525:                        return true;
526:                }
527:                return false;
528:            }
529:
530:            public IBinding[] getDeclarationsInScope(int offset, int flags) {
531:                NodeFinder finder = new NodeFinder(offset, 0);
532:                fRoot.accept(finder);
533:                ASTNode node = finder.getCoveringNode();
534:                if (node == null) {
535:                    return NO_BINDING;
536:                }
537:
538:                if (node instanceof  SimpleName) {
539:                    return getDeclarationsInScope((SimpleName) node, flags);
540:                }
541:
542:                try {
543:                    ITypeBinding binding = Bindings
544:                            .getBindingOfParentType(node);
545:                    DefaultBindingRequestor requestor = new DefaultBindingRequestor(
546:                            binding, flags);
547:                    addLocalDeclarations(node, offset, flags, requestor);
548:                    if (binding != null) {
549:                        addTypeDeclarations(binding, flags, requestor);
550:                    }
551:                    List result = requestor.getResult();
552:                    return (IBinding[]) result.toArray(new IBinding[result
553:                            .size()]);
554:                } finally {
555:                    clearLists();
556:                }
557:            }
558:
559:            private static ITypeBinding getDeclaringType(IBinding binding) {
560:                switch (binding.getKind()) {
561:                case IBinding.VARIABLE:
562:                    return ((IVariableBinding) binding).getDeclaringClass();
563:                case IBinding.METHOD:
564:                    return ((IMethodBinding) binding).getDeclaringClass();
565:                case IBinding.TYPE:
566:                    ITypeBinding typeBinding = (ITypeBinding) binding;
567:                    if (typeBinding.getDeclaringClass() != null) {
568:                        return typeBinding;
569:                    }
570:                    return typeBinding;
571:                }
572:                return null;
573:            }
574:
575:            /**
576:             * Evaluates if the declaration is visible in a certain context. 
577:             * @param binding The binding of the declaration to examine
578:             * @param context The context to test in
579:             * @return Returns 
580:             */
581:            public static boolean isVisible(IBinding binding,
582:                    ITypeBinding context) {
583:                if (binding.getKind() == IBinding.VARIABLE
584:                        && !((IVariableBinding) binding).isField()) {
585:                    return true; // all local variables found are visible
586:                }
587:                ITypeBinding declaring = getDeclaringType(binding);
588:                if (declaring == null) {
589:                    return false;
590:                }
591:
592:                int modifiers = binding.getModifiers();
593:                if (Modifier.isPublic(modifiers) || declaring.isInterface()) {
594:                    return true;
595:                } else if (Modifier.isProtected(modifiers)
596:                        || !Modifier.isPrivate(modifiers)) {
597:                    if (declaring.getPackage() == context.getPackage()) {
598:                        return true;
599:                    }
600:                    return isTypeInScope(declaring, context, Modifier
601:                            .isProtected(modifiers));
602:                }
603:                // private visibility
604:                return isTypeInScope(declaring, context, false);
605:            }
606:
607:            private static boolean isTypeInScope(ITypeBinding declaring,
608:                    ITypeBinding context, boolean includeHierarchy) {
609:                ITypeBinding curr = context;
610:                while (curr != null && curr != declaring) {
611:                    if (includeHierarchy
612:                            && Bindings.isSuperType(declaring, curr)) {
613:                        return true;
614:                    }
615:                    curr = curr.getDeclaringClass();
616:                }
617:                return curr == declaring;
618:            }
619:
620:            public IBinding[] getDeclarationsAfter(int offset, int flags) {
621:                try {
622:                    NodeFinder finder = new NodeFinder(offset, 0);
623:                    fRoot.accept(finder);
624:                    ASTNode node = finder.getCoveringNode();
625:                    if (node == null) {
626:                        return null;
627:                    }
628:
629:                    ASTNode declaration = ASTResolving
630:                            .findParentStatement(node);
631:                    while (declaration instanceof  Statement
632:                            && declaration.getNodeType() != ASTNode.BLOCK) {
633:                        declaration = declaration.getParent();
634:                    }
635:
636:                    if (declaration instanceof  Block) {
637:                        DefaultBindingRequestor requestor = new DefaultBindingRequestor();
638:                        DeclarationsAfterVisitor visitor = new DeclarationsAfterVisitor(
639:                                node.getStartPosition(), flags, requestor);
640:                        declaration.accept(visitor);
641:                        List result = requestor.getResult();
642:                        return (IBinding[]) result.toArray(new IBinding[result
643:                                .size()]);
644:                    }
645:                    return NO_BINDING;
646:                } finally {
647:                    clearLists();
648:                }
649:            }
650:
651:            private class ScopeAnalyzerVisitor extends HierarchicalASTVisitor {
652:
653:                private int fPosition;
654:                private int fFlags;
655:                private final IBindingRequestor fRequestor;
656:                private boolean fBreak;
657:
658:                public ScopeAnalyzerVisitor(int position, int flags,
659:                        IBindingRequestor requestor) {
660:                    fPosition = position;
661:                    fFlags = flags;
662:                    fRequestor = requestor;
663:                    fBreak = false;
664:                }
665:
666:                private boolean isInside(ASTNode node) {
667:                    int start = node.getStartPosition();
668:                    int end = start + node.getLength();
669:
670:                    return start <= fPosition && fPosition < end;
671:                }
672:
673:                public boolean visit(MethodDeclaration node) {
674:                    if (isInside(node)) {
675:                        Block body = node.getBody();
676:                        if (body != null) {
677:                            body.accept(this );
678:                        }
679:                        visitBackwards(node.parameters());
680:                        if (node.getAST().apiLevel() >= AST.JLS3) {
681:                            visitBackwards(node.typeParameters());
682:                        }
683:                    }
684:                    return false;
685:                }
686:
687:                /* (non-Javadoc)
688:                 * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter)
689:                 */
690:                public boolean visit(TypeParameter node) {
691:                    if (hasFlag(TYPES, fFlags)
692:                            && node.getStartPosition() < fPosition) {
693:                        fBreak = fRequestor.acceptBinding(node.getName()
694:                                .resolveBinding());
695:                    }
696:                    return !fBreak;
697:                }
698:
699:                public boolean visit(SwitchCase node) {
700:                    // switch on enum allows to use enum constants without qualification
701:                    if (hasFlag(VARIABLES, fFlags) && !node.isDefault()
702:                            && isInside(node.getExpression())) {
703:                        SwitchStatement switchStatement = (SwitchStatement) node
704:                                .getParent();
705:                        ITypeBinding binding = switchStatement.getExpression()
706:                                .resolveTypeBinding();
707:                        if (binding != null && binding.isEnum()) {
708:                            IVariableBinding[] declaredFields = binding
709:                                    .getDeclaredFields();
710:                            for (int i = 0; i < declaredFields.length; i++) {
711:                                IVariableBinding curr = declaredFields[i];
712:                                if (curr.isEnumConstant()) {
713:                                    fBreak = fRequestor.acceptBinding(curr);
714:                                    if (fBreak)
715:                                        return false;
716:                                }
717:                            }
718:                        }
719:                    }
720:                    return false;
721:                }
722:
723:                public boolean visit(Initializer node) {
724:                    return !fBreak && isInside(node);
725:                }
726:
727:                public boolean visit(Statement node) {
728:                    return !fBreak && isInside(node);
729:                }
730:
731:                public boolean visit(ASTNode node) {
732:                    return false;
733:                }
734:
735:                public boolean visit(Block node) {
736:                    if (isInside(node)) {
737:                        visitBackwards(node.statements());
738:                    }
739:                    return false;
740:                }
741:
742:                public boolean visit(VariableDeclaration node) {
743:                    if (hasFlag(VARIABLES, fFlags)
744:                            && node.getStartPosition() < fPosition) {
745:                        fBreak = fRequestor
746:                                .acceptBinding(node.resolveBinding());
747:                    }
748:                    return !fBreak;
749:                }
750:
751:                public boolean visit(VariableDeclarationStatement node) {
752:                    visitBackwards(node.fragments());
753:                    return false;
754:                }
755:
756:                public boolean visit(VariableDeclarationExpression node) {
757:                    visitBackwards(node.fragments());
758:                    return false;
759:                }
760:
761:                public boolean visit(CatchClause node) {
762:                    if (isInside(node)) {
763:                        node.getBody().accept(this );
764:                        node.getException().accept(this );
765:                    }
766:                    return false;
767:                }
768:
769:                public boolean visit(ForStatement node) {
770:                    if (isInside(node)) {
771:                        node.getBody().accept(this );
772:                        visitBackwards(node.initializers());
773:                    }
774:                    return false;
775:                }
776:
777:                public boolean visit(TypeDeclarationStatement node) {
778:                    if (hasFlag(TYPES, fFlags)
779:                            && node.getStartPosition() + node.getLength() < fPosition) {
780:                        fBreak = fRequestor
781:                                .acceptBinding(node.resolveBinding());
782:                        return false;
783:                    }
784:                    return !fBreak && isInside(node);
785:                }
786:
787:                private void visitBackwards(List list) {
788:                    if (fBreak)
789:                        return;
790:
791:                    for (int i = list.size() - 1; i >= 0; i--) {
792:                        ASTNode curr = (ASTNode) list.get(i);
793:                        if (curr.getStartPosition() < fPosition) {
794:                            curr.accept(this );
795:                        }
796:                    }
797:                }
798:            }
799:
800:            private class DeclarationsAfterVisitor extends
801:                    HierarchicalASTVisitor {
802:                private final int fPosition;
803:                private final int fFlags;
804:                private final IBindingRequestor fRequestor;
805:                private boolean fBreak;
806:
807:                public DeclarationsAfterVisitor(int position, int flags,
808:                        IBindingRequestor requestor) {
809:                    fPosition = position;
810:                    fFlags = flags;
811:                    fRequestor = requestor;
812:                    fBreak = false;
813:                }
814:
815:                public boolean visit(ASTNode node) {
816:                    return !fBreak;
817:                }
818:
819:                public boolean visit(VariableDeclaration node) {
820:                    if (hasFlag(VARIABLES, fFlags)
821:                            && fPosition < node.getStartPosition()) {
822:                        fBreak = fRequestor
823:                                .acceptBinding(node.resolveBinding());
824:                    }
825:                    return false;
826:                }
827:
828:                public boolean visit(AnonymousClassDeclaration node) {
829:                    return false;
830:                }
831:
832:                public boolean visit(TypeDeclarationStatement node) {
833:                    if (hasFlag(TYPES, fFlags)
834:                            && fPosition < node.getStartPosition()) {
835:                        fBreak = fRequestor
836:                                .acceptBinding(node.resolveBinding());
837:                    }
838:                    return false;
839:                }
840:            }
841:
842:            private boolean addLocalDeclarations(ASTNode node, int flags,
843:                    IBindingRequestor requestor) {
844:                return addLocalDeclarations(node, node.getStartPosition(),
845:                        flags, requestor);
846:            }
847:
848:            private boolean addLocalDeclarations(ASTNode node, int offset,
849:                    int flags, IBindingRequestor requestor) {
850:                if (hasFlag(VARIABLES, flags) || hasFlag(TYPES, flags)) {
851:                    BodyDeclaration declaration = ASTResolving
852:                            .findParentBodyDeclaration(node);
853:                    if (declaration instanceof  MethodDeclaration
854:                            || declaration instanceof  Initializer) {
855:                        ScopeAnalyzerVisitor visitor = new ScopeAnalyzerVisitor(
856:                                offset, flags, requestor);
857:                        declaration.accept(visitor);
858:                        return visitor.fBreak;
859:                    }
860:                }
861:                return false;
862:            }
863:
864:            public Collection getUsedVariableNames(int offset, int length) {
865:                HashSet result = new HashSet();
866:                IBinding[] bindingsBefore = getDeclarationsInScope(offset,
867:                        VARIABLES);
868:                for (int i = 0; i < bindingsBefore.length; i++) {
869:                    result.add(bindingsBefore[i].getName());
870:                }
871:                IBinding[] bindingsAfter = getDeclarationsAfter(
872:                        offset + length, VARIABLES);
873:                for (int i = 0; i < bindingsAfter.length; i++) {
874:                    result.add(bindingsAfter[i].getName());
875:                }
876:                List imports = fRoot.imports();
877:                for (int i = 0; i < imports.size(); i++) {
878:                    ImportDeclaration decl = (ImportDeclaration) imports.get(i);
879:                    if (decl.isStatic() && !decl.isOnDemand()) {
880:                        result.add(ASTNodes.getSimpleNameIdentifier(decl
881:                                .getName()));
882:                    }
883:                }
884:                return result;
885:            }
886:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.