1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
12 
13 import org.eclipse.jdt.internal.compiler.ASTVisitor;
14 import org.eclipse.jdt.internal.compiler.lookup.*;
15 
16 public class JavadocFieldReference extends FieldReference {
17 
18 	public int tagSourceStart, tagSourceEnd;
19 	public int tagValue;
20 	public MethodBinding methodBinding;
21 	public boolean superAccess = false;
22 
JavadocFieldReference(char[] source, long pos)23 	public JavadocFieldReference(char[] source, long pos) {
24 		super(source, pos);
25 		this.bits |= InsideJavadoc;
26 	}
27 
28 	/*
29 	public Binding getBinding() {
30 		if (this.methodBinding != null) {
31 			return this.methodBinding;
32 		}
33 		return this.binding;
34 	}
35 	*/
36 
37 	/*
38 	 * Resolves type on a Block or Class scope.
39 	 */
internalResolveType(Scope scope)40 	private TypeBinding internalResolveType(Scope scope) {
41 
42 		this.constant = NotAConstant;
43 		if (this.receiver == null) {
44 			this.receiverType = scope.enclosingSourceType();
45 		} else if (scope.kind == Scope.CLASS_SCOPE) {
46 			this.receiverType = this.receiver.resolveType((ClassScope) scope);
47 		} else {
48 			this.receiverType = this.receiver.resolveType((BlockScope)scope);
49 		}
50 		if (this.receiverType == null) {
51 			return null;
52 		}
53 
54 		Binding fieldBinding = (this.receiver != null && this.receiver.isThis())
55 			? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/)
56 			: scope.getField(this.receiverType, this.token, this);
57 		if (!fieldBinding.isValidBinding()) {
58 			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
59 			switch (fieldBinding.problemId()) {
60 				case ProblemReasons.NonStaticReferenceInConstructorInvocation:
61 				case ProblemReasons.NonStaticReferenceInStaticContext:
62 				case ProblemReasons.InheritedNameHidesEnclosingName :
63 					FieldBinding closestMatch = ((ProblemFieldBinding)fieldBinding).closestMatch;
64 					if (closestMatch != null) {
65 						fieldBinding = closestMatch; // ignore problem if can reach target field through it
66 					}
67 			}
68 		}
69 		if (!fieldBinding.isValidBinding() || !(fieldBinding instanceof FieldBinding)) {
70 			if (this.receiverType instanceof ReferenceBinding) {
71 				ReferenceBinding refBinding = (ReferenceBinding) this.receiverType;
72 				MethodBinding[] methodBindings = refBinding.getMethods(this.token);
73 				if (methodBindings == null) {
74 					scope.problemReporter().javadocInvalidField(this.sourceStart, this.sourceEnd, fieldBinding, this.receiverType, scope.getDeclarationModifiers());
75 				} else {
76 					switch (methodBindings.length) {
77 						case 0:
78 							scope.problemReporter().javadocInvalidField(this.sourceStart, this.sourceEnd, fieldBinding, this.receiverType, scope.getDeclarationModifiers());
79 							break;
80 						case 1:
81 							this.methodBinding = methodBindings[0];
82 							break;
83 						default:
84 							this.methodBinding = methodBindings[0];
85 							scope.problemReporter().javadocAmbiguousMethodReference(this.sourceStart, this.sourceEnd, fieldBinding, scope.getDeclarationModifiers());
86 							break;
87 					}
88 				}
89 			}
90 			return null;
91 		}
92 		this.binding = (FieldBinding) fieldBinding;
93 
94 		if (isFieldUseDeprecated(this.binding, scope, (this.bits & IsStrictlyAssignedMASK) != 0)) {
95 			scope.problemReporter().javadocDeprecatedField(this.binding, this, scope.getDeclarationModifiers());
96 		}
97 		return this.resolvedType = this.binding.type;
98 	}
99 
100 	/* (non-Javadoc)
101 	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isSuperAccess()
102 	 */
isSuperAccess()103 	public boolean isSuperAccess() {
104 		return this.superAccess;
105 	}
106 
printExpression(int indent, StringBuffer output)107 	public StringBuffer printExpression(int indent, StringBuffer output) {
108 
109 		if (this.receiver != null) {
110 			this.receiver.printExpression(0, output);
111 		}
112 		output.append('#').append(this.token);
113 		return output;
114 	}
115 
116 	/* (non-Javadoc)
117 	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
118 	 */
resolveType(BlockScope scope)119 	public TypeBinding resolveType(BlockScope scope) {
120 		return internalResolveType(scope);
121 	}
122 
123 	/* (non-Javadoc)
124 	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
125 	 */
resolveType(ClassScope scope)126 	public TypeBinding resolveType(ClassScope scope) {
127 		return internalResolveType(scope);
128 	}
129 
130 	/* (non-Javadoc)
131 	 * Redefine to capture javadoc specific signatures
132 	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
133 	 */
traverse(ASTVisitor visitor, BlockScope scope)134 	public void traverse(ASTVisitor visitor, BlockScope scope) {
135 
136 		if (visitor.visit(this, scope)) {
137 			if (this.receiver != null) {
138 				this.receiver.traverse(visitor, scope);
139 			}
140 		}
141 		visitor.endVisit(this, scope);
142 	}
143 }
144