1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.internal.compiler.ASTVisitor; 14 import org.eclipse.jdt.internal.compiler.impl.*; 15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 16 import org.eclipse.jdt.internal.compiler.codegen.*; 17 import org.eclipse.jdt.internal.compiler.flow.*; 18 import org.eclipse.jdt.internal.compiler.lookup.*; 19 20 public class FieldDeclaration extends AbstractVariableDeclaration { 21 22 public FieldBinding binding; 23 public Javadoc javadoc; 24 25 33 public int endPart1Position; 34 public int endPart2Position; 35 36 public FieldDeclaration() { 37 } 39 40 public FieldDeclaration( char[] name, int sourceStart, int sourceEnd) { 41 this.name = name; 42 this.sourceStart = sourceStart; 46 this.sourceEnd = sourceEnd; 47 } 48 49 public FlowInfo analyseCode(MethodScope initializationScope, FlowContext flowContext, FlowInfo flowInfo) { 50 if (this.binding != null && !this.binding.isUsed()) { 51 if (this.binding.isPrivate() || (this.binding.declaringClass != null && this.binding.declaringClass.isLocalType())) { 52 if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { 53 initializationScope.problemReporter().unusedPrivateField(this); 54 } 55 } 56 } 57 if (this.binding != null 59 && this.binding.isValidBinding() 60 && this.binding.isStatic() 61 && this.binding.constant() == Constant.NotAConstant 62 && this.binding.declaringClass.isNestedType() 63 && !this.binding.declaringClass.isStatic()) { 64 initializationScope.problemReporter().unexpectedStaticModifierForField( 65 (SourceTypeBinding) this.binding.declaringClass, 66 this); 67 } 68 69 if (this.initialization != null) { 70 flowInfo = 71 this.initialization 72 .analyseCode(initializationScope, flowContext, flowInfo) 73 .unconditionalInits(); 74 flowInfo.markAsDefinitelyAssigned(this.binding); 75 } 76 return flowInfo; 77 } 78 79 86 public void generateCode(BlockScope currentScope, CodeStream codeStream) { 87 if ((this.bits & IsReachable) == 0) { 88 return; 89 } 90 int pc = codeStream.position; 93 boolean isStatic; 94 if (this.initialization != null 95 && !((isStatic = this.binding.isStatic()) && this.binding.constant() != Constant.NotAConstant)) { 96 if (!isStatic) 98 codeStream.aload_0(); 99 this.initialization.generateCode(currentScope, codeStream, true); 101 if (isStatic) { 103 codeStream.putstatic(this.binding); 104 } else { 105 codeStream.putfield(this.binding); 106 } 107 } 108 codeStream.recordPositionsFrom(pc, this.sourceStart); 109 } 110 111 114 public int getKind() { 115 return this.type == null ? ENUM_CONSTANT : FIELD; 116 } 117 118 public boolean isStatic() { 119 if (this.binding != null) 120 return this.binding.isStatic(); 121 return (this.modifiers & ClassFileConstants.AccStatic) != 0; 122 } 123 124 public StringBuffer printStatement(int indent, StringBuffer output) { 125 if (this.javadoc != null) { 126 this.javadoc.print(indent, output); 127 } 128 return super.printStatement(indent, output); 129 } 130 131 public void resolve(MethodScope initializationScope) { 132 136 if ((this.bits & ASTNode.HasBeenResolved) != 0) return; 138 if (this.binding == null || !this.binding.isValidBinding()) return; 139 140 this.bits |= ASTNode.HasBeenResolved; 141 142 ClassScope classScope = initializationScope.enclosingClassScope(); 145 146 if (classScope != null) { 147 checkHiding: { 148 SourceTypeBinding declaringType = classScope.enclosingSourceType(); 149 checkHidingSuperField: { 150 if (declaringType.superclass == null) break checkHidingSuperField; 151 Binding existingVariable = classScope.findField(declaringType.superclass, this.name, this, false ); 152 if (existingVariable == null) break checkHidingSuperField; if (!existingVariable.isValidBinding()) break checkHidingSuperField; if (existingVariable instanceof FieldBinding) { 155 FieldBinding existingField = (FieldBinding) existingVariable; 156 if (existingField.original() == this.binding) break checkHidingSuperField; } 158 initializationScope.problemReporter().fieldHiding(this, existingVariable); 160 break checkHiding; } 162 Scope outerScope = classScope.parent; 165 if (outerScope.kind == Scope.COMPILATION_UNIT_SCOPE) break checkHiding; 166 Binding existingVariable = outerScope.getBinding(this.name, Binding.VARIABLE, this, false ); 167 if (existingVariable == null) break checkHiding; 168 if (!existingVariable.isValidBinding()) break checkHiding; 169 if (existingVariable == this.binding) break checkHiding; 170 if (existingVariable instanceof FieldBinding) { 171 FieldBinding existingField = (FieldBinding) existingVariable; 172 if (existingField.original() == this.binding) break checkHiding; 173 if (!existingField.isStatic() && declaringType.isStatic()) break checkHiding; 174 } 175 initializationScope.problemReporter().fieldHiding(this, existingVariable); 177 } 178 } 179 180 if (this.type != null ) { this.type.resolvedType = this.binding.type; } 183 184 FieldBinding previousField = initializationScope.initializedField; 185 int previousFieldID = initializationScope.lastVisibleFieldID; 186 try { 187 initializationScope.initializedField = this.binding; 188 initializationScope.lastVisibleFieldID = this.binding.id; 189 190 resolveAnnotations(initializationScope, this.annotations, this.binding); 191 if ((this.binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0 193 && (this.binding.modifiers & ClassFileConstants.AccDeprecated) != 0 194 && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { 195 initializationScope.problemReporter().missingDeprecatedAnnotationForField(this); 196 } 197 if (this.initialization == null) { 199 this.binding.setConstant(Constant.NotAConstant); 200 } else { 201 this.binding.setConstant(Constant.NotAConstant); 203 204 TypeBinding fieldType = this.binding.type; 205 TypeBinding initializationType; 206 this.initialization.setExpectedType(fieldType); if (this.initialization instanceof ArrayInitializer) { 208 209 if ((initializationType = this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) { 210 ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType; 211 this.initialization.computeConversion(initializationScope, fieldType, initializationType); 212 } 213 } else if ((initializationType = this.initialization.resolveType(initializationScope)) != null) { 214 215 if (fieldType != initializationType) initializationScope.compilationUnitScope().recordTypeConversion(fieldType, initializationType); 217 if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, fieldType) 218 || (fieldType.isBaseType() && BaseTypeBinding.isWidening(fieldType.id, initializationType.id)) 219 || initializationType.isCompatibleWith(fieldType)) { 220 this.initialization.computeConversion(initializationScope, fieldType, initializationType); 221 if (initializationType.needsUncheckedConversion(fieldType)) { 222 initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType); 223 } 224 if (this.initialization instanceof CastExpression 225 && (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) { 226 CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization); 227 } 228 } else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) 229 || (initializationType.isBaseType() && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 && !fieldType.isBaseType() 232 && initialization.isConstantValueOfTypeAssignableToType(initializationType, initializationScope.environment().computeBoxingType(fieldType)))) { 233 this.initialization.computeConversion(initializationScope, fieldType, initializationType); 234 if (this.initialization instanceof CastExpression 235 && (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) { 236 CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization); 237 } 238 } else { 239 initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this); 240 } 241 if (this.binding.isFinal()){ this.binding.setConstant(this.initialization.constant.castTo((this.binding.type.id << 4) + this.initialization.constant.typeID())); 243 } 244 } else { 245 this.binding.setConstant(Constant.NotAConstant); 246 } 247 if (this.binding == Assignment.getDirectBinding(this.initialization)) { 249 initializationScope.problemReporter().assignmentHasNoEffect(this, this.name); 250 } 251 } 252 if (this.javadoc != null) { 254 259 this.javadoc.resolve(initializationScope); 260 } else if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) { 261 initializationScope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers); 262 } 263 } finally { 264 initializationScope.initializedField = previousField; 265 initializationScope.lastVisibleFieldID = previousFieldID; 266 if (this.binding.constant() == null) 267 this.binding.setConstant(Constant.NotAConstant); 268 } 269 } 270 271 public void traverse(ASTVisitor visitor, MethodScope scope) { 272 if (visitor.visit(this, scope)) { 273 if (this.javadoc != null) { 274 this.javadoc.traverse(visitor, scope); 275 } 276 if (this.annotations != null) { 277 int annotationsLength = this.annotations.length; 278 for (int i = 0; i < annotationsLength; i++) 279 this.annotations[i].traverse(visitor, scope); 280 } 281 if (this.type != null) { 282 this.type.traverse(visitor, scope); 283 } 284 if (this.initialization != null) 285 this.initialization.traverse(visitor, scope); 286 } 287 visitor.endVisit(this, scope); 288 } 289 } 290 | Popular Tags |