public TypeBinding resolveType(BlockScope scope) { // field and/or local are done before type lookups // the only available value for the restrictiveFlag BEFORE // the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField this.actualReceiverType = scope.enclosingReceiverType(); this.constant = Constant.NotAConstant; if (( /*this.codegenBinding =*/ this.binding = scope.getBinding( this.tokens, this.bits & ASTNode.RestrictiveFlagMASK, this, true /*resolve*/)) .isValidBinding()) { switch (this.bits & ASTNode.RestrictiveFlagMASK) { case Binding.VARIABLE: // ============only variable=========== case Binding.TYPE | Binding.VARIABLE: if (this.binding instanceof LocalVariableBinding) { this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits this.bits |= Binding.LOCAL; return this.resolvedType = getOtherFieldBindings(scope); } if (this.binding instanceof FieldBinding) { FieldBinding fieldBinding = (FieldBinding) this.binding; MethodScope methodScope = scope.methodScope(); // check for forward references if (this.indexOfFirstFieldBinding == 1 && methodScope.enclosingSourceType() == fieldBinding.original().declaringClass && methodScope.lastVisibleFieldID >= 0 && fieldBinding.id >= methodScope.lastVisibleFieldID && (!fieldBinding.isStatic() || methodScope.isStatic)) { scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); } this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits this.bits |= Binding.FIELD; // // check for deprecated receiver type // // deprecation check for receiver type if not first token // if (indexOfFirstFieldBinding > 1) { // if (isTypeUseDeprecated(this.actualReceiverType, scope)) // scope.problemReporter().deprecatedType(this.actualReceiverType, this); // } return this.resolvedType = getOtherFieldBindings(scope); } // thus it was a type this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits this.bits |= Binding.TYPE; case Binding.TYPE: // =============only type ============== TypeBinding type = (TypeBinding) this.binding; // if (isTypeUseDeprecated(type, scope)) // scope.problemReporter().deprecatedType(type, this); return this.resolvedType = type; } } // ========error cases=============== return this.resolvedType = this.reportError(scope); }
/** Check and/or redirect the field access to the delegate receiver if any */ public TypeBinding checkFieldAccess(BlockScope scope) { FieldBinding fieldBinding = (FieldBinding) this.binding; MethodScope methodScope = scope.methodScope(); // check for forward references if (this.indexOfFirstFieldBinding == 1 && methodScope.enclosingSourceType() == fieldBinding.original().declaringClass && methodScope.lastVisibleFieldID >= 0 && fieldBinding.id >= methodScope.lastVisibleFieldID && (!fieldBinding.isStatic() || methodScope.isStatic)) { scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); } this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits this.bits |= Binding.FIELD; return getOtherFieldBindings(scope); }
public FlowInfo analyseCode( MethodScope initializationScope, FlowContext flowContext, FlowInfo flowInfo) { if (this.binding != null && !this.binding.isUsed()) { if (this.binding.isPrivate() || (this.binding.declaringClass != null && this.binding.declaringClass.isLocalType())) { if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { initializationScope.problemReporter().unusedPrivateField(this); } } } if (this.initialization != null) { flowInfo = this.initialization .analyseCode(initializationScope, flowContext, flowInfo) .unconditionalInits(); flowInfo.markAsDefinitelyAssigned(this.binding); } return flowInfo; }
/* * Look for missing method @param tags */ private char[][] missingParamTags(Binding paramNameRefBinding, MethodScope methScope) { // Verify if there's some possible param tag AbstractMethodDeclaration md = methScope.referenceMethod(); int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length; if (md == null) return null; int argumentsSize = md.arguments == null ? 0 : md.arguments.length; if (argumentsSize == 0) return null; // Store all method arguments if there's no @param in javadoc if (paramTagsSize == 0) { char[][] missingParams = new char[argumentsSize][]; for (int i = 0; i < argumentsSize; i++) { missingParams[i] = md.arguments[i].name; } return missingParams; } // Look for missing arguments char[][] missingParams = new char[argumentsSize][]; int size = 0; for (int i = 0; i < argumentsSize; i++) { Argument arg = md.arguments[i]; boolean found = false; int paramNameRefCount = 0; for (int j = 0; j < paramTagsSize && !found; j++) { JavadocSingleNameReference param = this.paramReferences[j]; if (arg.binding == param.binding) { if (param.binding == paramNameRefBinding) { // do not count first occurence of param name reference paramNameRefCount++; found = paramNameRefCount > 1; } else { found = true; } } } if (!found) { missingParams[size++] = arg.name; } } if (size > 0) { if (size != argumentsSize) { System.arraycopy(missingParams, 0, missingParams = new char[size][], 0, size); } return missingParams; } return null; }
public void resolve(MethodScope initializationScope) { // the two <constant = Constant.NotAConstant> could be regrouped into // a single line but it is clearer to have two lines while the reason of their // existence is not at all the same. See comment for the second one. // -------------------------------------------------------- if ((this.bits & ASTNode.HasBeenResolved) != 0) return; if (this.binding == null || !this.binding.isValidBinding()) return; this.bits |= ASTNode.HasBeenResolved; // check if field is hiding some variable - issue is that field binding already got inserted in // scope // thus must lookup separately in super type and outer context ClassScope classScope = initializationScope.enclosingClassScope(); if (classScope != null) { checkHiding: { SourceTypeBinding declaringType = classScope.enclosingSourceType(); checkHidingSuperField: { if (declaringType.superclass == null) break checkHidingSuperField; Binding existingVariable = classScope.findField( declaringType.superclass, this.name, this, false /*do not resolve hidden field*/); if (existingVariable == null) break checkHidingSuperField; // keep checking outer scenario if (!existingVariable.isValidBinding()) break checkHidingSuperField; // keep checking outer scenario if (existingVariable instanceof FieldBinding) { FieldBinding existingField = (FieldBinding) existingVariable; if (existingField.original() == this.binding) break checkHidingSuperField; // keep checking outer scenario } // collision with supertype field initializationScope.problemReporter().fieldHiding(this, existingVariable); break checkHiding; // already found a matching field } // only corner case is: lookup of outer field through static declaringType, which isn't // detected by #getBinding as lookup starts // from outer scope. Subsequent static contexts are detected for free. Scope outerScope = classScope.parent; if (outerScope.kind == Scope.COMPILATION_UNIT_SCOPE) break checkHiding; Binding existingVariable = outerScope.getBinding( this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/); if (existingVariable == null) break checkHiding; if (!existingVariable.isValidBinding()) break checkHiding; if (existingVariable == this.binding) break checkHiding; if (existingVariable instanceof FieldBinding) { FieldBinding existingField = (FieldBinding) existingVariable; if (existingField.original() == this.binding) break checkHiding; if (!existingField.isStatic() && declaringType.isStatic()) break checkHiding; } // collision with outer field or local variable initializationScope.problemReporter().fieldHiding(this, existingVariable); } } if (this.type != null) { // enum constants have no declared type this.type.resolvedType = this.binding.type; // update binding for type reference } FieldBinding previousField = initializationScope.initializedField; int previousFieldID = initializationScope.lastVisibleFieldID; try { initializationScope.initializedField = this.binding; initializationScope.lastVisibleFieldID = this.binding.id; // resolveAnnotations(initializationScope, this.annotations, this.binding); // the resolution of the initialization hasn't been done if (this.initialization != null) { TypeBinding fieldType = this.binding.type; TypeBinding initializationType; this.initialization.setExpectedType( fieldType); // needed in case of generic method invocation if (this.initialization instanceof ArrayInitializer) { if ((initializationType = this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) { ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType; } } else if ((initializationType = this.initialization.resolveType(initializationScope)) != null) { if (fieldType != initializationType) // must call before computeConversion() and typeMismatchError() initializationScope .compilationUnitScope() .recordTypeConversion(fieldType, initializationType); if (this.initialization.isConstantValueOfTypeAssignableToType( initializationType, fieldType) || (fieldType.isBaseType() && BaseTypeBinding.isWidening(fieldType.id, initializationType.id)) || initializationType.isCompatibleWith(fieldType)) { } else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) || (initializationType.isBaseType() // narrowing then boxing ? && initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 // autoboxing && !fieldType.isBaseType() && initialization.isConstantValueOfTypeAssignableToType( initializationType, initializationScope.environment().computeBoxingType(fieldType)))) { } else { initializationScope .problemReporter() .typeMismatchError(initializationType, fieldType, this); } } // check for assignment with no effect if (this.binding == Assignment.getDirectBinding(this.initialization)) { initializationScope.problemReporter().assignmentHasNoEffect(this, this.name); } } // Resolve Javadoc comment if one is present if (this.javadoc != null) { /* if (classScope != null) { this.javadoc.resolve(classScope); } */ this.javadoc.resolve(initializationScope); } else if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) { initializationScope .problemReporter() .javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers); } } finally { initializationScope.initializedField = previousField; initializationScope.lastVisibleFieldID = previousFieldID; } }