public boolean throwsException(ClassInfo exception) { for (ClassInfo e : mThrownExceptions) { if (e.qualifiedName().equals(exception.qualifiedName())) { return true; } } return false; }
private boolean inList(ClassInfo item, ThrowsTagInfo[] list) { int len = list.length; String qn = item.qualifiedName(); for (int i = 0; i < len; i++) { ClassInfo ex = list[i].exception(); if (ex != null && ex.qualifiedName().equals(qn)) { return true; } } return false; }
public ThrowsTagInfo[] throwsTags() { if (mThrowsTags == null) { ThrowsTagInfo[] documented = comment().throwsTags(); ArrayList<ThrowsTagInfo> rv = new ArrayList<ThrowsTagInfo>(); int len = documented.length; for (int i = 0; i < len; i++) { rv.add(documented[i]); } for (ClassInfo cl : mThrownExceptions) { if (documented == null || !inList(cl, documented)) { rv.add( new ThrowsTagInfo( "@throws", "@throws", cl.qualifiedName(), cl, "", containingClass(), position())); } } mThrowsTags = rv.toArray(new ThrowsTagInfo[rv.size()]); } return mThrowsTags; }
public boolean isConsistent(MethodInfo mInfo) { boolean consistent = true; if (this.mReturnType != mInfo.mReturnType && !this.mReturnType.equals(mInfo.mReturnType)) { if (!mReturnType.isPrimitive() && !mInfo.mReturnType.isPrimitive()) { // Check to see if our class extends the old class. ApiInfo infoApi = mInfo.containingClass().containingPackage().containingApi(); ClassInfo infoReturnClass = infoApi.findClass(mInfo.mReturnType.qualifiedTypeName()); // Find the classes. consistent = infoReturnClass != null && infoReturnClass.isAssignableTo(mReturnType.qualifiedTypeName()); } else { consistent = false; } if (!consistent) { Errors.error( Errors.CHANGED_TYPE, mInfo.position(), "Method " + mInfo.qualifiedName() + " has changed return type from " + mReturnType + " to " + mInfo.mReturnType); } } if (mIsAbstract != mInfo.mIsAbstract) { consistent = false; Errors.error( Errors.CHANGED_ABSTRACT, mInfo.position(), "Method " + mInfo.qualifiedName() + " has changed 'abstract' qualifier"); } if (mIsNative != mInfo.mIsNative) { consistent = false; Errors.error( Errors.CHANGED_NATIVE, mInfo.position(), "Method " + mInfo.qualifiedName() + " has changed 'native' qualifier"); } if (!mIsStatic) { // Compiler-generated methods vary in their 'final' qualifier between versions of // the compiler, so this check needs to be quite narrow. A change in 'final' // status of a method is only relevant if (a) the method is not declared 'static' // and (b) the method is not already inferred to be 'final' by virtue of its class. if (!isEffectivelyFinal() && mInfo.isEffectivelyFinal()) { consistent = false; Errors.error( Errors.ADDED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName() + " has added 'final' qualifier"); } else if (isEffectivelyFinal() && !mInfo.isEffectivelyFinal()) { consistent = false; Errors.error( Errors.REMOVED_FINAL, mInfo.position(), "Method " + mInfo.qualifiedName() + " has removed 'final' qualifier"); } } if (mIsStatic != mInfo.mIsStatic) { consistent = false; Errors.error( Errors.CHANGED_STATIC, mInfo.position(), "Method " + mInfo.qualifiedName() + " has changed 'static' qualifier"); } if (!scope().equals(mInfo.scope())) { consistent = false; Errors.error( Errors.CHANGED_SCOPE, mInfo.position(), "Method " + mInfo.qualifiedName() + " changed scope from " + scope() + " to " + mInfo.scope()); } if (!isDeprecated() == mInfo.isDeprecated()) { Errors.error( Errors.CHANGED_DEPRECATED, mInfo.position(), "Method " + mInfo.qualifiedName() + " has changed deprecation state " + isDeprecated() + " --> " + mInfo.isDeprecated()); consistent = false; } // see JLS 3 13.4.20 "Adding or deleting a synchronized modifier of a method does not break " // "compatibility with existing binaries." /* if (mIsSynchronized != mInfo.mIsSynchronized) { Errors.error(Errors.CHANGED_SYNCHRONIZED, mInfo.position(), "Method " + mInfo.qualifiedName() + " has changed 'synchronized' qualifier from " + mIsSynchronized + " to " + mInfo.mIsSynchronized); consistent = false; } */ for (ClassInfo exception : thrownExceptions()) { if (!mInfo.throwsException(exception)) { // exclude 'throws' changes to finalize() overrides with no arguments if (!name().equals("finalize") || (!mParameters.isEmpty())) { Errors.error( Errors.CHANGED_THROWS, mInfo.position(), "Method " + mInfo.qualifiedName() + " no longer throws exception " + exception.qualifiedName()); consistent = false; } } } for (ClassInfo exec : mInfo.thrownExceptions()) { // exclude 'throws' changes to finalize() overrides with no arguments if (!throwsException(exec)) { if (!name().equals("finalize") || (!mParameters.isEmpty())) { Errors.error( Errors.CHANGED_THROWS, mInfo.position(), "Method " + mInfo.qualifiedName() + " added thrown exception " + exec.qualifiedName()); consistent = false; } } } return consistent; }