1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpeclipse.internal.compiler.ast;
13 import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
14 import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
15 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
16 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
17 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
18 import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypeBinding;
19 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
20 import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope;
21 import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
22 import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding;
23 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
25 public class FieldDeclaration extends AbstractVariableDeclaration {
26 public FieldBinding binding;
27 boolean hasBeenResolved = false;
29 //allows to retrieve both the "type" part of the declaration (part1)
30 //and also the part that decribe the name and the init and optionally
31 //some other dimension ! ....
32 //public int[] a, b[] = X, c ;
33 //for b that would give for
34 // - part1 : public int[]
37 public int endPart1Position;
38 public int endPart2Position;
40 public FieldDeclaration() {
43 public FieldDeclaration(
44 Expression initialization,
49 this.initialization = initialization;
52 //due to some declaration like
53 // int x, y = 3, z , x ;
54 //the sourceStart and the sourceEnd is ONLY on the name
55 this.sourceStart = sourceStart;
56 this.sourceEnd = sourceEnd;
59 public FlowInfo analyseCode(
60 MethodScope initializationScope,
61 FlowContext flowContext,
64 if (this.binding != null && this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
65 if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
66 initializationScope.problemReporter().unusedPrivateField(this);
69 // cannot define static non-constant field inside nested class
71 && binding.isValidBinding()
73 && binding.constant == NotAConstant
74 && binding.declaringClass.isNestedType()
75 && binding.declaringClass.isClass()
76 && !binding.declaringClass.isStatic()) {
77 initializationScope.problemReporter().unexpectedStaticModifierForField(
78 (SourceTypeBinding) binding.declaringClass,
82 if (initialization != null) {
85 .analyseCode(initializationScope, flowContext, flowInfo)
86 .unconditionalInits();
87 flowInfo.markAsDefinitelyAssigned(binding);
93 * Code generation for a field declaration:
94 * standard assignment to a field
96 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
97 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
99 // public void generateCode(BlockScope currentScope, CodeStream codeStream) {
101 // if ((bits & IsReachableMASK) == 0) {
104 // // do not generate initialization code if final and static (constant is then
105 // // recorded inside the field itself).
106 // int pc = codeStream.position;
108 // if (initialization != null
109 // && !((isStatic = binding.isStatic()) && binding.constant != NotAConstant)) {
110 // // non-static field, need receiver
112 // codeStream.aload_0();
113 // // generate initialization value
114 // initialization.generateCode(currentScope, codeStream, true);
115 // // store into field
117 // codeStream.putstatic(binding);
119 // codeStream.putfield(binding);
122 // codeStream.recordPositionsFrom(pc, this.sourceStart);
125 public TypeBinding getTypeBinding(Scope scope) {
127 return type.getTypeBinding(scope);
130 public boolean isField() {
135 public boolean isStatic() {
138 return binding.isStatic();
139 return (modifiers & AccStatic) != 0;
142 public String name() {
144 return String.valueOf(name);
147 public void resolve(MethodScope initializationScope) {
149 // the two <constant = Constant.NotAConstant> could be regrouped into
150 // a single line but it is clearer to have two lines while the reason of their
151 // existence is not at all the same. See comment for the second one.
153 //--------------------------------------------------------
154 if (!this.hasBeenResolved && binding != null && this.binding.isValidBinding()) {
156 this.hasBeenResolved = true;
158 if (isTypeUseDeprecated(this.binding.type, initializationScope))
159 initializationScope.problemReporter().deprecatedType(this.binding.type, this.type);
161 this.type.resolvedType = this.binding.type; // update binding for type reference
163 // the resolution of the initialization hasn't been done
164 if (this.initialization == null) {
165 this.binding.constant = Constant.NotAConstant;
167 int previous = initializationScope.fieldDeclarationIndex;
169 initializationScope.fieldDeclarationIndex = this.binding.id;
171 // break dead-lock cycles by forcing constant to NotAConstant
172 this.binding.constant = Constant.NotAConstant;
174 TypeBinding typeBinding = this.binding.type;
175 TypeBinding initializationTypeBinding;
177 if (initialization instanceof ArrayInitializer) {
179 if ((initializationTypeBinding = this.initialization.resolveTypeExpecting(initializationScope, typeBinding)) != null) {
180 ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationTypeBinding;
181 this.initialization.implicitWidening(typeBinding, initializationTypeBinding);
183 } else if ((initializationTypeBinding = initialization.resolveType(initializationScope)) != null) {
185 if (this.initialization.isConstantValueOfTypeAssignableToType(initializationTypeBinding, typeBinding)
186 || (typeBinding.isBaseType() && BaseTypeBinding.isWidening(typeBinding.id, initializationTypeBinding.id))) {
188 this.initialization.implicitWidening(typeBinding, initializationTypeBinding);
190 } else if (initializationTypeBinding.isCompatibleWith(typeBinding)) {
191 this.initialization.implicitWidening(typeBinding, initializationTypeBinding);
194 initializationScope.problemReporter().typeMismatchError(initializationTypeBinding, typeBinding, this);
196 if (this.binding.isFinal()){ // cast from constant actual type to variable type
197 this.binding.constant =
198 this.initialization.constant.castTo(
199 (this.binding.type.id << 4) + this.initialization.constant.typeID());
202 this.binding.constant = NotAConstant;
205 initializationScope.fieldDeclarationIndex = previous;
206 if (this.binding.constant == null)
207 this.binding.constant = Constant.NotAConstant;
213 public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) {
215 if (visitor.visit(this, scope)) {
216 type.traverse(visitor, scope);
217 if (initialization != null)
218 initialization.traverse(visitor, scope);
220 visitor.endVisit(this, scope);