diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:03:49 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:03:49 -0800 |
commit | dcc08f073b6873c69ab891d4f69f7c568e282df7 (patch) | |
tree | cbaa218be3f46078555b6bfb36c48659096a747a /tools/apicheck/src | |
parent | d3aa4000e42fd1036e0e3286843c5132f905d754 (diff) | |
download | build-dcc08f073b6873c69ab891d4f69f7c568e282df7.zip build-dcc08f073b6873c69ab891d4f69f7c568e282df7.tar.gz build-dcc08f073b6873c69ab891d4f69f7c568e282df7.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'tools/apicheck/src')
5 files changed, 110 insertions, 21 deletions
diff --git a/tools/apicheck/src/com/android/apicheck/ClassInfo.java b/tools/apicheck/src/com/android/apicheck/ClassInfo.java index 858ec8a..50f8a3c 100644 --- a/tools/apicheck/src/com/android/apicheck/ClassInfo.java +++ b/tools/apicheck/src/com/android/apicheck/ClassInfo.java @@ -174,14 +174,14 @@ public class ClassInfo { } } else { Errors.error(Errors.REMOVED_METHOD, mInfo.position(), - "Removed public constructor " + mInfo.qualifiedName()); + "Removed public constructor " + mInfo.prettySignature()); consistent = false; } } for (ConstructorInfo mInfo : cl.mConstructors.values()) { if (!mInfo.isInBoth()) { Errors.error(Errors.ADDED_METHOD, mInfo.position(), - "Added public constructor " + mInfo.qualifiedName()); + "Added public constructor " + mInfo.prettySignature()); consistent = false; } } @@ -224,10 +224,16 @@ public class ClassInfo { } if (!mScope.equals(cl.mScope)) { - consistent = false; - Errors.error(Errors.CHANGED_SCOPE, cl.position(), - "Class " + cl.qualifiedName() + " scope changed from " - + mScope + " to " + cl.mScope); + consistent = false; + Errors.error(Errors.CHANGED_SCOPE, cl.position(), + "Class " + cl.qualifiedName() + " scope changed from " + + mScope + " to " + cl.mScope); + } + + if (!mDeprecated.equals(cl.mDeprecated)) { + consistent = false; + Errors.error(Errors.CHANGED_DEPRECATED, cl.position(), + "Class " + cl.qualifiedName() + " has changed deprecation state"); } if (mSuperClassName != null) { diff --git a/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java b/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java index 5593d21..57d7617 100644 --- a/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java +++ b/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java @@ -81,6 +81,17 @@ public class ConstructorInfo implements AbstractMethodInfo { return baseName + name(); } + public String prettySignature() { + String params = ""; + for (ParameterInfo pInfo : mParameters) { + if (params.length() > 0) { + params += ", "; + } + params += pInfo.getType(); + } + return qualifiedName() + '(' + params + ')'; + } + public boolean isConsistent(ConstructorInfo mInfo) { mInfo.mExistsInBoth = true; mExistsInBoth = true; @@ -89,26 +100,32 @@ public class ConstructorInfo implements AbstractMethodInfo { if (mIsFinal != mInfo.mIsFinal) { consistent = false; Errors.error(Errors.CHANGED_FINAL, mInfo.position(), - "Method " + mInfo.qualifiedName() + " has changed 'final' qualifier"); + "Constructor " + mInfo.qualifiedName() + " has changed 'final' qualifier"); } if (mIsStatic != mInfo.mIsStatic) { consistent = false; Errors.error(Errors.CHANGED_FINAL, mInfo.position(), - "Method " + mInfo.qualifiedName() + " has changed 'static' qualifier"); + "Constructor " + mInfo.qualifiedName() + " has changed 'static' qualifier"); } if (!mScope.equals(mInfo.mScope)) { consistent = false; Errors.error(Errors.CHANGED_SCOPE, mInfo.position(), - "Method " + mInfo.qualifiedName() + " changed scope from " + "Constructor " + mInfo.qualifiedName() + " changed scope from " + mScope + " to " + mInfo.mScope); } + if (!mDeprecated.equals(mInfo.mDeprecated)) { + consistent = false; + Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(), + "Constructor " + mInfo.qualifiedName() + " has changed deprecation state"); + } + for (String exec : mExceptions) { if (!mInfo.mExceptions.contains(exec)) { Errors.error(Errors.CHANGED_THROWS, mInfo.position(), - "Method " + mInfo.qualifiedName() + " no longer throws exception " + "Constructor " + mInfo.qualifiedName() + " no longer throws exception " + exec); consistent = false; } @@ -117,7 +134,7 @@ public class ConstructorInfo implements AbstractMethodInfo { for (String exec : mInfo.mExceptions) { if (!mExceptions.contains(exec)) { Errors.error(Errors.CHANGED_THROWS, mInfo.position(), - "Method " + mInfo.qualifiedName() + " added thrown exception " + "Constructor " + mInfo.qualifiedName() + " added thrown exception " + exec); consistent = false; } diff --git a/tools/apicheck/src/com/android/apicheck/Errors.java b/tools/apicheck/src/com/android/apicheck/Errors.java index 84d9c17..cd4ba25 100644 --- a/tools/apicheck/src/com/android/apicheck/Errors.java +++ b/tools/apicheck/src/com/android/apicheck/Errors.java @@ -113,6 +113,7 @@ public class Errors public static Error CHANGED_THROWS = new Error(21, WARNING); public static Error CHANGED_NATIVE = new Error(22, HIDDEN); public static Error CHANGED_CLASS = new Error(23, WARNING); + public static Error CHANGED_DEPRECATED = new Error(24, WARNING); public static Error[] ERRORS = { PARSE_ERROR, @@ -137,6 +138,8 @@ public class Errors CHANGED_ABSTRACT, CHANGED_THROWS, CHANGED_NATIVE, + CHANGED_CLASS, + CHANGED_DEPRECATED, }; public static boolean setErrorLevel(int code, int level) { diff --git a/tools/apicheck/src/com/android/apicheck/FieldInfo.java b/tools/apicheck/src/com/android/apicheck/FieldInfo.java index 9b467af..d80d9f6 100644 --- a/tools/apicheck/src/com/android/apicheck/FieldInfo.java +++ b/tools/apicheck/src/com/android/apicheck/FieldInfo.java @@ -66,6 +66,40 @@ public class FieldInfo { return parentQName + name(); } + // Check the declared value with a typed comparison, not a string comparison, + // to accommodate toolchains with different fp -> string conversions. + public boolean valueEquals(FieldInfo other) { + // Type mismatch means nonequal, as does a null/non-null mismatch + if (!mType.equals(other.mType) + || ((mValue == null) != (other.mValue == null))) { + return false; + } + + // Null values are considered equal + if (mValue == null) { + return true; + } + + // Floating point gets an implementation-type comparison; all others just use the string + // If float/double parse fails, fall back to string comparison -- it means that it's a + // canonical droiddoc-generated constant expression that represents a NaN. + try { + if (mType.equals("float")) { + float val = Float.parseFloat(mValue); + float otherVal = Float.parseFloat(other.mValue); + return (val == otherVal); + } else if (mType.equals("double")) { + double val = Double.parseDouble(mValue); + double otherVal = Double.parseDouble(other.mValue); + return (val == otherVal); + } + } catch (NumberFormatException e) { + // fall through + } + + return mValue.equals(other.mValue); + } + public boolean isConsistent(FieldInfo fInfo) { fInfo.mExistsInBoth = true; mExistsInBoth = true; @@ -75,8 +109,8 @@ public class FieldInfo { "Field " + fInfo.qualifiedName() + " has changed type"); consistent = false; } - if ((mValue != null && !mValue.equals(fInfo.mValue)) || - (mValue == null && fInfo.mValue != null)) { + + if (!this.valueEquals(fInfo)) { Errors.error(Errors.CHANGED_VALUE, fInfo.position(), "Field " + fInfo.qualifiedName() + " has changed value from " + mValue + " to " + fInfo.mValue); @@ -114,6 +148,12 @@ public class FieldInfo { consistent = false; } + if (!mDeprecated.equals(fInfo.mDeprecated)) { + Errors.error(Errors.CHANGED_DEPRECATED, fInfo.position(), + "Field " + fInfo.qualifiedName() + " has changed deprecation state"); + consistent = false; + } + return consistent; } diff --git a/tools/apicheck/src/com/android/apicheck/MethodInfo.java b/tools/apicheck/src/com/android/apicheck/MethodInfo.java index 1f973dc..2994460 100644 --- a/tools/apicheck/src/com/android/apicheck/MethodInfo.java +++ b/tools/apicheck/src/com/android/apicheck/MethodInfo.java @@ -66,6 +66,17 @@ public class MethodInfo implements AbstractMethodInfo { return parentQName + name(); } + public String prettySignature() { + String params = ""; + for (ParameterInfo pInfo : mParameters) { + if (params.length() > 0) { + params += ", "; + } + params += pInfo.getType(); + } + return qualifiedName() + '(' + params + ')'; + } + public SourcePositionInfo position() { return mSourcePosition; } @@ -128,21 +139,33 @@ public class MethodInfo implements AbstractMethodInfo { + mScope + " to " + mInfo.mScope); } + if (!mDeprecated.equals(mInfo.mDeprecated)) { + Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(), + "Method " + mInfo.qualifiedName() + " has changed deprecation state"); + consistent = false; + } + for (String exec : mExceptions) { if (!mInfo.mExceptions.contains(exec)) { - Errors.error(Errors.CHANGED_THROWS, mInfo.position(), - "Method " + mInfo.qualifiedName() + " no longer throws exception " - + exec); - consistent = false; + // exclude 'throws' changes to finalize() overrides with no arguments + if (!name().equals("finalize") || (mParameters.size() > 0)) { + Errors.error(Errors.CHANGED_THROWS, mInfo.position(), + "Method " + mInfo.qualifiedName() + " no longer throws exception " + + exec); + consistent = false; + } } } for (String exec : mInfo.mExceptions) { + // exclude 'throws' changes to finalize() overrides with no arguments if (!mExceptions.contains(exec)) { - Errors.error(Errors.CHANGED_THROWS, mInfo.position(), - "Method " + mInfo.qualifiedName() + " added thrown exception " - + exec); - consistent = false; + if (!name().equals("finalize") || (mParameters.size() > 0)) { + Errors.error(Errors.CHANGED_THROWS, mInfo.position(), + "Method " + mInfo.qualifiedName() + " added thrown exception " + + exec); + consistent = false; + } } } |