KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > InnerInfoPass


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base;
26
27 import org.aspectj.compiler.base.ast.*;
28 import org.aspectj.compiler.base.*;
29
30 import java.util.*;
31
32 /**
33  * This pass sets up information for TypeDec's about wherer they are as inners
34  * It is also used to check whether or not non-static references are allowed.
35  */

36 public final class InnerInfoPass extends WalkerPass {
37     public InnerInfoPass(JavaCompiler jc) { super(jc); }
38
39     public String JavaDoc getDisplayName() { return "setting inner info"; }
40
41     private static final int CU = 0; // compilation unit
42
private static final int MEMBER = 1; // class or aspect
43
private static final int STATICMEMBER = 2; // interface
44
private static final int DYNAMIC = 3; // local, enclosing guy available
45
private static final int STATIC = 4; // local, no enclosing guy available
46
private static final int NIGH_STATIC = 5; // local, no enclosing guy available,
47
// but one guy up is available
48

49     private int context = CU;
50
51     public ASTObject process(ASTObject object) {
52         object.walkInnerInfo(this);
53         object.postInnerInfo(this);
54         return object;
55     }
56
57     public int inCCall() { return setContext(NIGH_STATIC); }
58     public int inType(boolean isInterface) {
59         return setContext(isInterface ? STATICMEMBER : MEMBER);
60     }
61     public int inMember(boolean isStatic) {
62         return setContext(isStatic ? STATIC : DYNAMIC);
63     }
64     private int setContext(int c) {
65         int context = this.context;
66         this.context = c;
67         return context;
68     }
69     public void restoreContext(int context) {
70         this.context = context;
71     }
72
73     public boolean isStatic() {
74         return context != DYNAMIC;
75     }
76     
77     public boolean hasNonStaticAccess(ASTObject node, Type type) {
78         return isAccessible(type);
79 // Type lexType = node.getLexicalType();
80
// if (lexType == type) {
81
// return !isStatic();
82
// }
83
// //XXX insert more agressive handling here for inners
84
// return true;
85
}
86     
87     public void checkStaticAccess(ASTObject node, SemanticObject so) {
88         if (so.isStatic()) return;
89         
90         if (!hasNonStaticAccess(node, so.getDeclaringType())) {
91             node.showError("non-static " + so.getKind() + " " + so.getName() +
92             " cannot be referenced from a static context");
93         }
94     }
95
96     public static boolean isInner(Type t) {
97         if (! (t instanceof NameType)) return false;
98         NameType nt = (NameType) t;
99         return nt.isInner()
100             // we might not have processed it yet, if it's a member
101
// type. So we check...
102
|| (nt.getTypeDec().fromSource()
103                 && ! nt.isAspect()
104                 && ! nt.isPackageMember()
105                 && ! nt.isLocal()
106                 && ! nt.getTypeDec().isStatic()
107                 && ! nt.getDeclaringType().isInterface());
108     }
109
110     public boolean isInDynamicContext() {
111         return (context == MEMBER) || (context == DYNAMIC);
112     }
113
114     // ------------------------------
115

116     private List types = new ArrayList();
117     public void enterType(TypeDec dec) { types.add(dec.getType()); }
118     public void leaveType() { types.remove(types.size() - 1); }
119
120     public NameType currentType() {
121         return (NameType) types.get(types.size() - 1);
122     }
123     public NameType enclosingType() {
124         return (NameType) types.get(types.size() - 2);
125     }
126
127     public boolean isAccessibleExactly(Type t) {
128         return isAccessible(t, false);
129     }
130     public boolean isAccessible(Type t) {
131         return isAccessible(t, true);
132     }
133     public boolean isAccessible(Type t, boolean allowSubs) {
134         NameType current = (NameType) types.get(types.size() - 1);
135         if (current == t || (allowSubs && current.isSubtypeOf(t))) {
136             return (context == DYNAMIC);
137         }
138         if (! current.isInner()) return false;
139         for (int i = types.size() - 2; i >= 0; i--) {
140             current = (NameType) types.get(i);
141             if (current == t || (allowSubs && current.isSubtypeOf(t))) {
142                 return (context != STATIC);
143             } else if (! current.isInner()) {
144                 return false;
145             }
146         }
147         return false; //???
148
}
149 }
150
Popular Tags