clirr-devel Mailing List for Clirr (Page 33)
Status: Alpha
Brought to you by:
lkuehne
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(15) |
Oct
(23) |
Nov
|
Dec
(25) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(9) |
Feb
|
Mar
|
Apr
|
May
(76) |
Jun
(207) |
Jul
(242) |
Aug
(42) |
Sep
(33) |
Oct
|
Nov
(7) |
Dec
(1) |
2005 |
Jan
|
Feb
|
Mar
(5) |
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
(66) |
Sep
(38) |
Oct
(6) |
Nov
|
Dec
(2) |
2006 |
Jan
(17) |
Feb
(5) |
Mar
(28) |
Apr
(6) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
(7) |
2007 |
Jan
|
Feb
|
Mar
|
Apr
(7) |
May
(33) |
Jun
(4) |
Jul
(3) |
Aug
|
Sep
(5) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
(4) |
Feb
(3) |
Mar
(2) |
Apr
|
May
(1) |
Jun
|
Jul
(6) |
Aug
(8) |
Sep
(5) |
Oct
(20) |
Nov
(7) |
Dec
(9) |
2009 |
Jan
(8) |
Feb
(3) |
Mar
(20) |
Apr
(10) |
May
(40) |
Jun
(11) |
Jul
(23) |
Aug
(4) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
(2) |
2010 |
Jan
(5) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
(6) |
May
(22) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
(1) |
Dec
(2) |
2014 |
Jan
(5) |
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2015 |
Jan
(1) |
Feb
(2) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Simon K. <s_k...@us...> - 2004-06-18 07:59:30
|
Update of /cvsroot/clirr/clirr/src/test/net/sf/clirr/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8197/test/net/sf/clirr/checks Added Files: ClassScopeCheckTest.java Log Message: Added check which determines whether a class has changed its scope (public/protected/package/private) between releases. Also added unit tests for this change. --- NEW FILE --- package net.sf.clirr.checks; import net.sf.clirr.framework.ClassChangeCheck; import net.sf.clirr.event.ApiDifference; import net.sf.clirr.event.Severity; import net.sf.clirr.event.ScopeSelector; import net.sf.clirr.framework.ClassSelector; /** * Tests for the ClassScopeCheck test. * * @author Simon Kitching */ public class ClassScopeCheckTest extends AbstractCheckTestCase { public void testAccessChangesAreReported() { ApiDifference[] expected = new ApiDifference[] { new ApiDifference("Decreased visibility of class from public to protected", Severity.ERROR, "testlib.scope.ClassScopeChange$A2", null, null), new ApiDifference("Decreased visibility of class from public to package", Severity.ERROR, "testlib.scope.ClassScopeChange$A3", null, null), new ApiDifference("Decreased visibility of class from public to private", Severity.ERROR, "testlib.scope.ClassScopeChange$A4", null, null), new ApiDifference("Increased visibility of class from protected to public", Severity.INFO, "testlib.scope.ClassScopeChange$B2", null, null), new ApiDifference("Decreased visibility of class from protected to package", Severity.ERROR, "testlib.scope.ClassScopeChange$B3", null, null), new ApiDifference("Decreased visibility of class from protected to private", Severity.ERROR, "testlib.scope.ClassScopeChange$B4", null, null), new ApiDifference("Increased visibility of class from package to public", Severity.INFO, "testlib.scope.ClassScopeChange$C2", null, null), new ApiDifference("Increased visibility of class from package to protected", Severity.INFO, "testlib.scope.ClassScopeChange$C3", null, null), new ApiDifference("Decreased visibility of class from package to private", Severity.ERROR, "testlib.scope.ClassScopeChange$C4", null, null), new ApiDifference("Increased visibility of class from private to public", Severity.INFO, "testlib.scope.ClassScopeChange$D2", null, null), new ApiDifference("Increased visibility of class from private to protected", Severity.INFO, "testlib.scope.ClassScopeChange$D3", null, null), new ApiDifference("Increased visibility of class from private to package", Severity.INFO, "testlib.scope.ClassScopeChange$D4", null, null), }; verify(expected); } protected ClassChangeCheck createCheck(TestDiffListener tdl) { ScopeSelector scopeSelector = new ScopeSelector(ScopeSelector.SCOPE_PRIVATE); return new ClassScopeCheck(tdl, scopeSelector); } protected ClassSelector createClassSelector() { // only check the testlib/scope/ClassScopeChange class. ClassSelector classSelector = new ClassSelector(ClassSelector.MODE_IF); classSelector.addClass("testlib.scope.ClassScopeChange"); return classSelector; } } |
From: Simon K. <s_k...@us...> - 2004-06-18 07:59:30
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8197/java/net/sf/clirr/checks Added Files: ClassScopeCheck.java Log Message: Added check which determines whether a class has changed its scope (public/protected/package/private) between releases. Also added unit tests for this change. --- NEW FILE --- ////////////////////////////////////////////////////////////////////////////// // Clirr: compares two versions of a java library for binary compatibility // Copyright (C) 2003 - 2004 Lars Kühne // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ////////////////////////////////////////////////////////////////////////////// package net.sf.clirr.checks; import net.sf.clirr.event.Severity; import net.sf.clirr.event.ScopeSelector; import net.sf.clirr.framework.AbstractDiffReporter; import net.sf.clirr.framework.ApiDiffDispatcher; import net.sf.clirr.framework.ClassChangeCheck; import net.sf.clirr.framework.CheckerException; import org.apache.bcel.classfile.JavaClass; /** * Detects changes in class access declaration, for both "top-level" classes, * and nested classes. * <p> * Java class files only ever contain scope specifiers of "public" or "package". * For top-level classes, this is expected: it is not possible to have a * top-level protected or private class. * <p> * However nested classes <i>can</i> be declared as protected or private. The * way to tell the real scope of a nested class is to ignore the scope in * the actual class file itself, and instead look in the "InnerClasses" * attribute stored on the enclosing class. This is exactly what the java * compiler does when compiling, and what the jvm does when verifying class * linkage at runtime. * * @author Simon Kitching */ public final class ClassScopeCheck extends AbstractDiffReporter implements ClassChangeCheck { private ScopeSelector scopeSelector; /** * Create a new instance of this check. * @param dispatcher the diff dispatcher that distributes the detected changes to the listeners. */ public ClassScopeCheck(ApiDiffDispatcher dispatcher, ScopeSelector scopeSelector) { super(dispatcher); this.scopeSelector = scopeSelector; } /** {@inheritDoc} */ public boolean check(JavaClass compatBaseline, JavaClass currentVersion) { ScopeSelector.Scope bScope; try { bScope = ScopeSelector.getClassScope(compatBaseline); } catch (CheckerException ex) { log(ex.getMessage() + " in old class version", Severity.ERROR, compatBaseline.getClassName(), null, null); return false; } ScopeSelector.Scope cScope; try { cScope = ScopeSelector.getClassScope(currentVersion); } catch (CheckerException ex) { log(ex.getMessage() + " in new class version", Severity.ERROR, compatBaseline.getClassName(), null, null); return false; } if (!scopeSelector.isSelected(bScope) && !scopeSelector.isSelected(cScope)) { // neither the old nor the new class are "visible" at the scope // the user of this class cares about, so just skip this test // and all following tests for this pair of classes. return false; } if (cScope.isMoreVisibleThan(bScope)) { log( "Increased visibility of class from " + bScope.getDesc() + " to " + cScope.getDesc(), Severity.INFO, compatBaseline.getClassName(), null, null); } else if (cScope.isLessVisibleThan(bScope)) { log( "Decreased visibility of class from " + bScope.getDesc() + " to " + cScope.getDesc(), Severity.ERROR, compatBaseline.getClassName(), null, null); } // Apply further checks only if both versions of the class have scopes // of interest. For example, when the user is only interested in // public & protected classes, then for classes which have just become // public/protected we just want to report that it is now "visible"; // because the class was not visible before the differences since its // last version are not relevant. And for classes which are no longer // public/protected, we just want to report that the whole class is no // longer "visible"; as it is not visible to users any changes to it // are irrelevant. return scopeSelector.isSelected(bScope) && scopeSelector.isSelected(cScope); } } |
From: Simon K. <s_k...@us...> - 2004-06-18 07:58:02
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7057/java/net/sf/clirr Modified Files: Checker.java Log Message: Add new ClassScopeCheck to list of checks. Also ensure each class loaded is stored into the associated Repository. Index: Checker.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/Checker.java,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- Checker.java 18 Jun 2004 07:33:20 -0000 1.17 +++ Checker.java 18 Jun 2004 07:57:53 -0000 1.18 @@ -34,6 +34,7 @@ import net.sf.clirr.checks.AddedClassCheck; import net.sf.clirr.checks.ClassHierarchyCheck; +import net.sf.clirr.checks.ClassScopeCheck; import net.sf.clirr.checks.ClassModifierCheck; import net.sf.clirr.checks.GenderChangeCheck; import net.sf.clirr.checks.InterfaceSetCheck; @@ -101,6 +102,7 @@ classSetChecks.add(new RemovedClassCheck(this)); classSetChecks.add(new AddedClassCheck(this)); + classChecks.add(new ClassScopeCheck(this, scopeSelector)); classChecks.add(new GenderChangeCheck(this)); classChecks.add(new ClassModifierCheck(this)); classChecks.add(new InterfaceSetCheck(this)); @@ -242,6 +244,7 @@ if (classSelector.isSelected(clazz)) { ret.add(clazz); + repository.storeClass(clazz); } } } |
From: Simon K. <s_k...@us...> - 2004-06-18 07:57:06
|
Update of /cvsroot/clirr/clirr/src/testinput/testlib-v2/testlib/scope In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6608/testinput/testlib-v2/testlib/scope Log Message: Directory /cvsroot/clirr/clirr/src/testinput/testlib-v2/testlib/scope added to the repository |
From: Simon K. <s_k...@us...> - 2004-06-18 07:56:53
|
Update of /cvsroot/clirr/clirr/src/testinput/testlib-v1/testlib/scope In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6433/testinput/testlib-v1/testlib/scope Log Message: Directory /cvsroot/clirr/clirr/src/testinput/testlib-v1/testlib/scope added to the repository |
From: Simon K. <s_k...@us...> - 2004-06-18 07:36:20
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21222/checks Modified Files: FieldSetCheck.java Log Message: Minor changes due to new ScopeSelector class API. Index: FieldSetCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/FieldSetCheck.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- FieldSetCheck.java 18 Jun 2004 06:52:10 -0000 1.9 +++ FieldSetCheck.java 18 Jun 2004 07:36:06 -0000 1.10 @@ -198,25 +198,25 @@ private void checkForVisibilityChange(Field bField, Field cField, JavaClass clazz) { - int bVisibility = ScopeSelector.getVisibilityRating(bField); - int cVisibility = ScopeSelector.getVisibilityRating(cField); + ScopeSelector.Scope bScope = ScopeSelector.getScope(bField); + ScopeSelector.Scope cScope = ScopeSelector.getScope(cField); - if (cVisibility > bVisibility) + if (cScope.isMoreVisibleThan(bScope)) { fireDiff( "Accessability of field " + bField.getName() + " has been increased" - + " from " + ScopeSelector.getScopeDesc(bField) - + " to " + ScopeSelector.getScopeDesc(cField), + + " from " + bScope.getDesc() + + " to " + cScope.getDesc(), Severity.INFO, clazz, cField); } - else if (cVisibility < bVisibility) + else if (cScope.isLessVisibleThan(bScope)) { fireDiff( "Accessibility of field " + bField.getName() + " has been weakened" - + " from " + ScopeSelector.getScopeDesc(bField) - + " to " + ScopeSelector.getScopeDesc(cField), + + " from " + bScope.getDesc() + + " to " + cScope.getDesc(), Severity.ERROR, clazz, cField); } } |
From: Simon K. <s_k...@us...> - 2004-06-18 07:35:31
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/cli In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20781/cli Modified Files: Clirr.java Log Message: Minor changes due to new ScopeSelector class API. Index: Clirr.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/cli/Clirr.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Clirr.java 13 Jun 2004 10:26:02 -0000 1.2 +++ Clirr.java 18 Jun 2004 07:35:22 -0000 1.3 @@ -23,8 +23,10 @@ import net.sf.clirr.event.DiffListener; import net.sf.clirr.event.PlainDiffListener; import net.sf.clirr.event.XmlDiffListener; +import net.sf.clirr.event.ScopeSelector; import net.sf.clirr.framework.CheckerException; import net.sf.clirr.framework.ClassSelector; + import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; @@ -100,8 +102,7 @@ Checker checker = new Checker(); if (showAll) { - checker.getScopeSelector().selectPrivate(true); - checker.getScopeSelector().selectPackage(true); + checker.getScopeSelector().setScope(ScopeSelector.SCOPE_PRIVATE); } DiffListener diffListener = null; |
From: Simon K. <s_k...@us...> - 2004-06-18 07:34:57
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/event In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20053/event Modified Files: ScopeSelector.java Log Message: Significant rewrite of class implementation. Add nested Scope class to represent different access scopes. Add functionality to determine real scope of nested classes. Index: ScopeSelector.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/event/ScopeSelector.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ScopeSelector.java 5 Jun 2004 16:15:13 -0000 1.1 +++ ScopeSelector.java 18 Jun 2004 07:34:48 -0000 1.2 @@ -18,7 +18,18 @@ ////////////////////////////////////////////////////////////////////////////// package net.sf.clirr.event; +import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.AccessFlags; +import org.apache.bcel.classfile.Attribute; +import org.apache.bcel.classfile.InnerClasses; +import org.apache.bcel.classfile.InnerClass; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.Constant; +import org.apache.bcel.classfile.ConstantUtf8; +import org.apache.bcel.util.Repository; +import org.apache.bcel.Constants; + +import net.sf.clirr.framework.CheckerException; /** * Selects zero or more java scope values (public, protected, package, @@ -33,10 +44,62 @@ */ public final class ScopeSelector { - private boolean selectPublic; - private boolean selectProtected; - private boolean selectPrivate; - private boolean selectPackage; + /** + * Represents an "accessability" level for a java class, field or method. + * <p> + * Change of access rights from lower to higher visibility rating is a + * binary-compatible change. Change of access rights from higher to + * lower is a binary-incompatible change. + * <p> + * Public > Protected > Package > Private + */ + public static final class Scope + { + private int vis; + private String desc; + private String decl; + + private Scope(int vis, String desc, String decl) + { + this.vis = vis; + this.desc = desc; + this.decl = decl; + } + + public boolean isMoreVisibleThan(Scope v) + { + return this.vis > v.vis; + } + + public boolean isLessVisibleThan(Scope v) + { + return this.vis < v.vis; + } + + public String getDesc() + { + return desc; + } + + public String getDecl() + { + return decl; + } + } + + /** Object representing private scoped objects. */ + public static final Scope SCOPE_PRIVATE = new Scope(0, "private", "private"); + + /** Object representing package scoped objects. */ + public static final Scope SCOPE_PACKAGE = new Scope(1, "package", ""); + + /** Object representing protected scoped objects. */ + public static final Scope SCOPE_PROTECTED = new Scope(2, "protected", "protected"); + + /** Object representing public scoped objects. */ + public static final Scope SCOPE_PUBLIC = new Scope(3, "public", "public"); + + private Scope scope = SCOPE_PROTECTED; /** * Construct an instance which selects public and protected objects and @@ -45,32 +108,30 @@ */ public ScopeSelector() { - selectPublic = true; - selectProtected = true; - } - - /** Enable/disable selection of public-scope objects. */ - public void selectPublic(boolean selected) - { - selectPublic = selected; } - /** Enable/disable selection of protected-scope objects. */ - public void selectProtected(boolean selected) + /** + * Construct an instance which selects public and protected objects and + * ignores package and private objects. The selectXXX methods can later + * be used to adjust this default behaviour. + */ + public ScopeSelector(Scope scope) { - selectProtected = selected; + this.scope = scope; } - /** Enable/disable selection of package-scope objects. */ - public void selectPackage(boolean selected) + /** Specify which scope objects are of interest. */ + public void setScope(Scope scope) { - selectPackage = selected; + this.scope = scope; } - /** Enable/disable selection of private-scope objects. */ - public void selectPrivate(boolean selected) + /** + * Get the scope that this object is configured with. + */ + public Scope getScope() { - selectPrivate = selected; + return scope; } /** @@ -79,172 +140,243 @@ */ public String toString() { - StringBuffer buf = new StringBuffer(); - - if (selectPublic) - { - buf.append("public"); - } - - if (selectProtected) - { - if (buf.length() != 0) - { - buf.append("+"); - } - - buf.append("protected"); - } - - if (selectPackage) - { - if (buf.length() != 0) - { - buf.append("+"); - } - - buf.append("package"); - } - - if (selectPrivate) - { - if (buf.length() != 0) - { - buf.append("+"); - } - - buf.append("private"); - } - - if (buf.length() == 0) - { - - return "none"; - } - else - { - - return buf.toString(); - } + return scope.getDesc(); } /** - * Given a BCEL object, return true if ths object's scope is one of the + * Given a BCEL object, return true if this object's scope is one of the * values this object is configured to match. * <p> - * Note that BCEL classes JavaClass, Field and Method all inherit from - * the AccessFlags base class and so are valid parameters to this - * method. + * Note that BCEL classes Field and Method inherit from the AccessFlags + * base class and so are valid parameters to this method. + * <p> + * Note that despite JavaClass objects extending AccessFlags, the + * methods which determine the accessability of a JavaClass fail + * miserably (bad bcel design) for nested classes. Therefore this + * method <i>must not</i> be passed a JavaClass object as a parameter. + * If this is done, a RuntimeException will be thrown to indicate a + * programmer error. * * @param object is the object whose scope is to be checked. * @return true if the object is selected. */ public boolean isSelected(AccessFlags object) { - if (object.isPublic()) - { - return selectPublic; - } - - if (object.isProtected()) - { - return selectProtected; - } - - if (object.isPrivate()) - { - return selectPrivate; - } + return !getScope(object).isLessVisibleThan(scope); + } - return selectPackage; + /** + * Return true if objects of the specified scope, or more visible, + * are selected by this selector. + * + * @param scope is the scope being checked + * @return true if objects of the specified scope are selected. + */ + public boolean isSelected(Scope scope) + { + return !scope.isLessVisibleThan(this.scope); } /** * Given a BCEL object, return the string which would be used in java * source code to declare that object's scope. <p> - * - * Note that BCEL classes JavaClass, Field and Method all inherit from - * the AccessFlags base class and so are valid parameters to this - * method. + * <p> + * Note that BCEL classes Field and Method inherit from the AccessFlags + * base class and so are valid parameters to this method. + * <p> + * Note that despite JavaClass objects extending AccessFlags, the + * methods which determine the accessability of a JavaClass fail + * miserably (bad bcel design) for nested classes. Therefore this + * method <i>must not</i> be passed a JavaClass object as a parameter. + * If this is done, a RuntimeException will be thrown to indicate a + * programmer error. */ public static String getScopeDecl(AccessFlags object) { - if (object.isPublic()) - { - return "public"; - } - - if (object.isProtected()) - { - return "protected"; - } - - if (object.isPrivate()) - { - return "private"; - } + return getScope(object).getDecl(); + } - return ""; + /** + * Given an integer representing an object's access flags, return the + * string which would be used in java source code to declare that object's + * scope. + * <p> + * Note that this method gives the wrong results for JavaClass objects + * which are nested classes. Use getClassScope(jclass).getDecl() instead. + */ + public static String getScopeDecl(int accessFlags) + { + return getScope(accessFlags).getDecl(); } /** * Given a BCEL object, return a string indicating whether the object is * public/protected/private/package scope. This is similar to * getScopeName, except for package-scope objects where this method - * returns the string "package". <p> - * - * Note that BCEL classes JavaClass, Field and Method all inherit from - * the AccessFlags base class and so are valid parameters to this - * method. + * returns the string "package". + * <p> + * Note that BCEL classes Field and Method inherit from the AccessFlags + * base class and so are valid parameters to this method. + * <p> + * Note that despite JavaClass objects extending AccessFlags, the + * methods which determine the accessability of a JavaClass fail + * miserably (bad bcel design) for nested classes. Therefore this + * method <i>must not</i> be passed a JavaClass object as a parameter. + * If this is done, a RuntimeException will be thrown to indicate a + * programmer error. */ public static String getScopeDesc(AccessFlags object) { - if (object.isPublic()) + return getScope(object).getDesc(); + } + + /** + * Given an integer representing the object's access flags, return a string + * indicating whether the object is public/protected/private/package scope. + * <p> + * This is similar to getScopeName, except for package-scope objects where + * this method returns the string "package". + * <p> + * Note that this method gives the wrong results for JavaClass objects + * which are nested classes. Use getClassScope(jclass).getDesc() instead. + */ + public static String getScopeDesc(int accessFlags) + { + return getScope(accessFlags).getDesc(); + } + + /** + * Get a Scope object representing the accessibility of the specified + * object. + * <p> + * Note that BCEL classes Field and Method inherit from the AccessFlags + * base class and so are valid parameters to this method. + * <p> + * Note that despite JavaClass objects extending AccessFlags, the + * methods which determine the accessability of a JavaClass fail + * miserably (bad bcel design) for nested classes. Therefore this + * method <i>must not</i> be passed a JavaClass object as a parameter. + * If this is done, a RuntimeException will be thrown to indicate a + * programmer error. Use getClassScope instead. + */ + public static Scope getScope(AccessFlags object) + { + if (object instanceof JavaClass) + { + throw new RuntimeException( + "getScope called for JavaClass object. This is not permitted;" + + " use method getClassScope for JavaClass objects."); + + } + + return getScope(object.getAccessFlags()); + } + + /** + * Get a Scope object representing the accessibility of the specified + * object. + * <p> + * Note that this method gives the wrong results for JavaClass objects + * which are nested classes. Use getClassScope(jclass) instead. + */ + public static Scope getScope(int accessFlags) + { + if ((accessFlags & Constants.ACC_PUBLIC) > 0) { - return "public"; + return SCOPE_PUBLIC; } - if (object.isProtected()) + if ((accessFlags & Constants.ACC_PROTECTED) > 0) { - return "protected"; + return SCOPE_PROTECTED; } - if (object.isPrivate()) + if ((accessFlags & Constants.ACC_PRIVATE) > 0) { - return "private"; + return SCOPE_PRIVATE; } - return "package"; + return SCOPE_PACKAGE; } /** - * Given a BCEL access flag field, return a rating indicating the - * "visibility" of the security of that access right. Change of access - * rights from lower to higher visibility rating is a binary-compatible - * change. Public = 3 Protected = 2 Package = 1 private = 0 <p> - * - * Note that BCEL classes JavaClass, Field and Method all inherit from - * the AccessFlags base class and so are valid parameters to this - * method. + * Java class files only ever contain scope specifiers of "public" or + * "package". For top-level classes, this is expected: it is not possible + * to have a top-level protected or private class. + * <p> + * However nested classes <i>can</i> be declared as protected or private. The + * way to tell the real scope of a nested class is to ignore the scope in + * the actual class file itself, and instead look in the "InnerClasses" + * attribute stored on the enclosing class. This is exactly what the java + * compiler does when compiling, and what the jvm does when verifying class + * linkage at runtime. + * <p> + * For a "top-level" class, this method just returns the access scope for + * the class itself. For nested classes, the enclosing class of the + * specified class is retrieved and its InnerClasses attribute checked to + * find the true scope for the specified class. + * <p> + * @throws CheckerException if the specified class is a nested class and + * the enclosing class could not be found, or if the supposedly enclosing + * class has no reference to the nested class. This exception is not + * expected to occur in practice, unless a truly screwed-up jar file is + * passed to clirr for inspection. */ - public static int getVisibilityRating(AccessFlags object) + public static Scope getClassScope(JavaClass jclass) throws CheckerException { - if (object.isPublic()) + int dollarPos = jclass.getClassName().indexOf('$'); + if (dollarPos == -1) { - return 3; + // not a nested class + return getScope(jclass.getAccessFlags()); } - if (object.isProtected()) + // ok this is a nested class + String jclassName = jclass.getClassName(); + String enclosingClassName = jclassName.substring(0, dollarPos); + String jclassNestedName = jclassName.substring(dollarPos + 1); + + Repository repo = jclass.getRepository(); + JavaClass enclosingClass = repo.findClass(enclosingClassName); + + if (enclosingClass == null) { - return 2; + throw new CheckerException( + "Unable to locate enclosing class " + enclosingClassName + + " for nested class " + jclassName); } - if (object.isPrivate()) + ConstantPool pool = enclosingClass.getConstantPool(); + Attribute[] attrs = enclosingClass.getAttributes(); + for (int i = 0; i < attrs.length; ++i) { - return 0; + if (attrs[i] instanceof InnerClasses) + { + InnerClasses ics = (InnerClasses) attrs[i]; + InnerClass[] icarray = ics.getInnerClasses(); + for (int j = 0; j < icarray.length; ++j) + { + InnerClass ic = icarray[j]; + int nameIndex = ic.getInnerNameIndex(); + + Constant nameconst = pool.getConstant(nameIndex); + if (nameconst instanceof ConstantUtf8) + { + String classname = ((ConstantUtf8) nameconst).getBytes(); + if (jclassNestedName.equals(classname)) + { + return getScope(ic.getInnerAccessFlags()); + } + } + } + } } - return 1; + // weird; no nested class info found + throw new CheckerException( + "Unable to find information in class " + enclosingClass.getClassName() + + " referring back to nested class " + jclassName); + } } |
From: Simon K. <s_k...@us...> - 2004-06-18 07:33:30
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18768 Modified Files: Checker.java Log Message: No longer use scopeSelector when building ClassSets. Filtering by scope is now done in the new ClassScopeCheck class. Index: Checker.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/Checker.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- Checker.java 18 Jun 2004 06:52:09 -0000 1.16 +++ Checker.java 18 Jun 2004 07:33:20 -0000 1.17 @@ -182,10 +182,10 @@ } final ClassSet origClasses = createClassSet( - origJars, origThirdPartyLoader, scopeSelector, classSelector); + origJars, origThirdPartyLoader, classSelector); final ClassSet newClasses = createClassSet( - newJars, newThirdPartyLoader, scopeSelector, classSelector); + newJars, newThirdPartyLoader, classSelector); reportDiffs(origClasses, newClasses); } @@ -198,8 +198,6 @@ * @param thirdPartyClasses loads classes that are referenced * by the classes in the jarFiles * - * @param scopeSelector scope of classes that should be included - * * @param classSelector is an object which determines which classes from the * old and new jars are to be compared. This parameter may be null, in * which case all classes in the old and new jars are compared. @@ -207,7 +205,6 @@ private static ClassSet createClassSet( File[] jarFiles, ClassLoader thirdPartyClasses, - ScopeSelector scopeSelector, ClassSelector classSelector) throws CheckerException { @@ -242,7 +239,7 @@ if (!zipEntry.isDirectory() && zipEntry.getName().endsWith(".class")) { JavaClass clazz = extractClass(zipEntry, zip, repository); - if (scopeSelector.isSelected(clazz) && classSelector.isSelected(clazz)) + if (classSelector.isSelected(clazz)) { ret.add(clazz); } |
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22759/checks Modified Files: ClassHierarchyCheck.java ClassModifierCheck.java FieldSetCheck.java GenderChangeCheck.java InterfaceSetCheck.java MethodSetCheck.java Log Message: Change check method prototype to return boolean. If false is returned, all following checks are skipped. Index: ClassHierarchyCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/ClassHierarchyCheck.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- ClassHierarchyCheck.java 23 May 2004 14:27:46 -0000 1.9 +++ ClassHierarchyCheck.java 18 Jun 2004 06:52:10 -0000 1.10 @@ -69,7 +69,7 @@ } /** {@inheritDoc} */ - public void check(JavaClass compatBaseline, JavaClass currentVersion) + public boolean check(JavaClass compatBaseline, JavaClass currentVersion) { JavaClass[] compatSuper = compatBaseline.getSuperClasses(); JavaClass[] currentSuper = currentVersion.getSuperClasses(); @@ -101,5 +101,7 @@ log("Removed " + s + " from the list of superclasses of " + className, Severity.ERROR, className, null, null); } + + return true; } } Index: ClassModifierCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/ClassModifierCheck.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ClassModifierCheck.java 22 May 2004 13:26:03 -0000 1.8 +++ ClassModifierCheck.java 18 Jun 2004 06:52:10 -0000 1.9 @@ -44,7 +44,7 @@ } /** {@inheritDoc} */ - public void check(JavaClass compatBaseLine, JavaClass currentVersion) + public boolean check(JavaClass compatBaseLine, JavaClass currentVersion) { final boolean currentIsFinal = currentVersion.isFinal(); final boolean compatIsFinal = compatBaseLine.isFinal(); @@ -82,6 +82,8 @@ log("Added abstract modifier in class " + className, Severity.ERROR, className, null, null); } + + return true; } } Index: FieldSetCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/FieldSetCheck.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- FieldSetCheck.java 5 Jun 2004 16:19:07 -0000 1.8 +++ FieldSetCheck.java 18 Jun 2004 06:52:10 -0000 1.9 @@ -64,7 +64,7 @@ this.scopeSelector = scopeSelector; } - public final void check(JavaClass compatBaseline, JavaClass currentVersion) + public final boolean check(JavaClass compatBaseline, JavaClass currentVersion) { final Field[] baselineFields = compatBaseline.getFields(); final Field[] currentFields = currentVersion.getFields(); @@ -76,6 +76,8 @@ final Field[] cFields = createSortedCopy(currentFields); checkForChanges(bFields, cFields, compatBaseline, currentVersion); + + return true; } private void checkForChanges( Index: GenderChangeCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/GenderChangeCheck.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- GenderChangeCheck.java 22 May 2004 13:26:03 -0000 1.7 +++ GenderChangeCheck.java 18 Jun 2004 06:52:10 -0000 1.8 @@ -52,7 +52,7 @@ /** {@inheritDoc} */ - public void check(JavaClass baseLine, JavaClass current) + public boolean check(JavaClass baseLine, JavaClass current) { if (baseLine.isClass() != current.isClass()) { @@ -61,6 +61,8 @@ baseLine.getClassName(), null, null) ); } + + return true; } // TODO: This should be a method in BCEL's ClassSet !!! Index: InterfaceSetCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/InterfaceSetCheck.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- InterfaceSetCheck.java 22 May 2004 13:26:03 -0000 1.8 +++ InterfaceSetCheck.java 18 Jun 2004 06:52:10 -0000 1.9 @@ -48,7 +48,7 @@ } /** {@inheritDoc} */ - public void check(JavaClass compatBaseline, JavaClass currentVersion) + public boolean check(JavaClass compatBaseline, JavaClass currentVersion) { JavaClass[] compatInterfaces = compatBaseline.getAllInterfaces(); JavaClass[] currentInterfaces = currentVersion.getAllInterfaces(); @@ -92,6 +92,8 @@ Severity.INFO, className, null, null); } } + + return true; } private Set createClassSet(JavaClass[] classes) Index: MethodSetCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/MethodSetCheck.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- MethodSetCheck.java 13 Jun 2004 11:43:24 -0000 1.9 +++ MethodSetCheck.java 18 Jun 2004 06:52:10 -0000 1.10 @@ -57,14 +57,14 @@ this.scopeSelector = scopeSelector; } - public final void check(JavaClass compatBaseline, JavaClass currentVersion) + public final boolean check(JavaClass compatBaseline, JavaClass currentVersion) { // Dont't report method problems when gender has changed, as // really the whole API is a pile of crap then - let GenderChange check // do it's job, and that's it if (compatBaseline.isInterface() ^ currentVersion.isInterface()) { - return; + return true; } // The main problem here is to figure out which old method corresponds to which new method. @@ -116,6 +116,8 @@ check(compatBaseline, iMethod, jMethod); } } + + return true; } private int[][] buildSimilarityTable(List baselineMethods, List currentMethods) |
From: Simon K. <s_k...@us...> - 2004-06-18 06:52:19
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/framework In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22759/framework Modified Files: ClassChangeCheck.java Log Message: Change check method prototype to return boolean. If false is returned, all following checks are skipped. Index: ClassChangeCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/framework/ClassChangeCheck.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ClassChangeCheck.java 22 May 2004 13:26:04 -0000 1.3 +++ ClassChangeCheck.java 18 Jun 2004 06:52:10 -0000 1.4 @@ -23,5 +23,5 @@ public interface ClassChangeCheck { - void check(JavaClass compatBaseline, JavaClass currentVersion); + boolean check(JavaClass compatBaseline, JavaClass currentVersion); } |
From: Simon K. <s_k...@us...> - 2004-06-18 06:52:18
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22759 Modified Files: Checker.java Log Message: Change check method prototype to return boolean. If false is returned, all following checks are skipped. Index: Checker.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/Checker.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- Checker.java 18 Jun 2004 06:36:22 -0000 1.15 +++ Checker.java 18 Jun 2004 06:52:09 -0000 1.16 @@ -351,10 +351,11 @@ if ((compatBaselineClass != null) && (currentClass != null)) { // class is available in both releases - for (Iterator it = classChecks.iterator(); it.hasNext();) + boolean continueTesting = true; + for (Iterator it = classChecks.iterator(); it.hasNext() && continueTesting;) { ClassChangeCheck classChangeCheck = (ClassChangeCheck) it.next(); - classChangeCheck.check(compatBaselineClass, currentClass); + continueTesting = classChangeCheck.check(compatBaselineClass, currentClass); } } } |
From: Simon K. <s_k...@us...> - 2004-06-18 06:36:31
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10377 Modified Files: Checker.java Log Message: Use CoIterator class. Index: Checker.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/Checker.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- Checker.java 13 Jun 2004 11:00:59 -0000 1.14 +++ Checker.java 18 Jun 2004 06:36:22 -0000 1.15 @@ -47,12 +47,15 @@ import net.sf.clirr.framework.ClassChangeCheck; import net.sf.clirr.framework.ClassSelector; import net.sf.clirr.framework.ClassSetChangeCheck; +import net.sf.clirr.framework.CoIterator; +import net.sf.clirr.framework.JavaClassNameComparator; +import net.sf.clirr.framework.CheckerException; + import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.util.ClassSet; import org.apache.bcel.util.Repository; import org.apache.bcel.util.ClassLoaderRepository; -import net.sf.clirr.framework.CheckerException; /** * This is the main class to be used by Clirr frontends, @@ -336,13 +339,18 @@ JavaClass[] compat = compatBaseline.toArray(); JavaClass[] current = currentVersion.toArray(); - for (int i = 0; i < compat.length; i++) + CoIterator iter = new CoIterator( + JavaClassNameComparator.COMPARATOR, compat, current); + + while (iter.hasNext()) { - JavaClass compatBaselineClass = compat[i]; - JavaClass currentClass = findClass(compatBaselineClass.getClassName(), current); - if (currentClass != null) + iter.next(); + + JavaClass compatBaselineClass = (JavaClass) iter.getLeft(); + JavaClass currentClass = (JavaClass) iter.getRight(); + if ((compatBaselineClass != null) && (currentClass != null)) { - // class still available in current release + // class is available in both releases for (Iterator it = classChecks.iterator(); it.hasNext();) { ClassChangeCheck classChangeCheck = (ClassChangeCheck) it.next(); @@ -351,18 +359,4 @@ } } } - - private JavaClass findClass(String className, JavaClass[] javaClasses) - { - for (int i = 0; i < javaClasses.length; i++) - { - JavaClass javaClass = javaClasses[i]; - if (javaClass.getClassName().equals(className)) - { - return javaClass; - } - } - return null; - } - } |
From: Simon K. <si...@ec...> - 2004-06-18 06:28:27
|
Hi Lars, I tried to run the unit tests for the latest clirr today, and got an error in the MethodSetCheckTest test. By reverting one version (1.6->1.5) of MethodSetCheckTest.java the problem goes away. Maybe you forgot to check in a change to the test-input dirs corresponding to the change you checked in to MethodSetCheckTest.java? Regards, Simon |
From: Simon K. <si...@ec...> - 2004-06-15 08:10:06
|
On Tue, 2004-06-15 at 03:57, bob mcwhirter wrote: > Just curious, is it like iDarwin/aDarwin? They track API changes, I think. It looks like iDarwin was intended to enforce rules like: * classes in pkg X must not reference classes in pkg Y This might be useful to verify, for example, that datamodel classes never reference UI classes. However this is not the intent of clirr. The problems clirr intends to solve are: (a) I released version 1.0 of this library last year. Now I'm about to commit a patch. Am I sure that this patch is binary compatible, ie users of this library can upgrade without recompiling? (b) I'm about to release a new version of library X. I need to write release notes - but what changes *have* I made to the API? (c) I'm a user of library X, and there is an upgrade but their release notes are useless. What changes have there been to the library API? And are they binary compatible (ie I can just install the new lib) or will I need to recompile my source code? Obviously clirr won't display *all* changes; some behavioural changes can be implemented without any API change. However it will detect most of them. The JDiff tool (jdiff.sourceforge.net) also attempts to cover some of this. But it does so by using javadoc doclets to analyse the source. Clirr analyses the jar files instead, hopefully making it much easier to use (and faster). And jdiff doesn't highlight binary incompatibilities, or provide an ant/maven plugin that can autodetect patches which break binary compatibility. I hope I've got this description right - I'm sure Lars will correct me if I've missed something. Cheers, Simon |
From: Simon K. <si...@ec...> - 2004-06-15 02:07:31
|
On Mon, 2004-06-14 at 01:23, Lars K=FChne wrote: > Simon Kitching wrote: >=20 > >I'll see if I can find a suitable IRC server & channel & post details. > >IRC is real easy to use. > > > > =20 > > >=20 > That would be great. >=20 > Here at home I'm online most Tuesday evenings. Currently we have the=20 > European football chamionships running, though, so I don't know if I ca= n=20 > make it this week. Setting priorities is the most important aspect of=20 > life... :-) Ok, I'll try to be logged in on Wed morning my time, and see if you turn up... As you haven't used IRC, here are some tips: I use "xchat" as an IRC client, "apt-get install xchat" for debian users. I think GAIM also supports IRC, but it is currently uninstallable for me unfortunately (price of using debian unstable!). And if you are a KDE user (probably are, in Germany) I see that "Konversation" and "ksirc" apps exist; haven't tried them. Select server=3D"irc.codehaus.org" All the IRC clients have a text entry field. Lines starting with "/" are commands, anything else gets sent to the forum. /help -- does the obvious /list -- shows the available forums, and # of people in each /join #clirr -- opens a new tab showing the "clirr" forum /userlist -- shows the names of everybody in the forum I hope to catch up with you sometime... Cheers, Simon |
From: bob m. <bo...@co...> - 2004-06-14 15:59:18
|
Just curious, is it like iDarwin/aDarwin? They track API changes, I thin= k. -bob On Mon, 14 Jun 2004, [ISO-8859-1] Lars K=FChne wrote: > Hi Bob, > > Clirr is a tool for detecting binary compatibility problems between > different releases of Java libraries. See http://clirr.sf.net for more = info. |
From: <lak...@t-...> - 2004-06-14 15:57:51
|
Hi Bob, Clirr is a tool for detecting binary compatibility problems between different releases of Java libraries. See http://clirr.sf.net for more info. Cheers, Lars bob mcwhirter wrote: >Sure, irc.codehaus.org is a-okay. > >What's clirr, btw? > > -bob > >On Sun, 13 Jun 2004, Vincent Massol wrote: > > > >>We could use the following if Bob is ok: >> >>irc.codehaus.org >>port: 6667 >>channel: clirr >> >>Thanks >>-Vincent >> >>PS: I'm ccing Lars as my emails still do not make it to the clirr-devel >>mailing list for some reason... I have an open ticket with SF. >> >> >> >>>-----Original Message----- >>>From: cli...@li... [mailto:clirr-devel- >>> >>> >>>Sent: 13 June 2004 15:01 >>>To: cli...@li... >>>Subject: Re: [Clirr-devel] code format >>> >>> >>> >>[snip] >> >> >> >>>>And by the way, as you are obviously online right now, is there an >>>> >>>> >>IRC >> >> >>>>channel we can chat on? >>>> >>>> >>>> >>>> >>>> >>>I'd love to, but - believe it or not - I have never used IRC (although >>> >>> >>I >> >> >>>am on Linux so I probably have all software in place), so I'd have to >>> >>> >>do >> >> >>>some reading first. >>> >>>Is there an IRC channel you are usually connected to (hope this is the >>>right terminology for IRC), and if so at which times of the day? >>> >>>Lars >>> >>> >> >> > >-- >Bob McWhirter bo...@we... >The Werken Company http://werken.com/ > > > |
From: bob m. <bo...@co...> - 2004-06-13 15:44:48
|
Sure, irc.codehaus.org is a-okay. What's clirr, btw? -bob On Sun, 13 Jun 2004, Vincent Massol wrote: > We could use the following if Bob is ok: > > irc.codehaus.org > port: 6667 > channel: clirr > > Thanks > -Vincent > > PS: I'm ccing Lars as my emails still do not make it to the clirr-devel > mailing list for some reason... I have an open ticket with SF. > > > -----Original Message----- > > From: cli...@li... [mailto:clirr-devel- > > ad...@li...] On Behalf Of Lars K=FChne > > Sent: 13 June 2004 15:01 > > To: cli...@li... > > Subject: Re: [Clirr-devel] code format > > > > [snip] > > > >And by the way, as you are obviously online right now, is there an > IRC > > >channel we can chat on? > > > > > > > > > > > > > I'd love to, but - believe it or not - I have never used IRC (althoug= h > I > > am on Linux so I probably have all software in place), so I'd have to > do > > some reading first. > > > > Is there an IRC channel you are usually connected to (hope this is th= e > > right terminology for IRC), and if so at which times of the day? > > > > Lars > > -- Bob McWhirter bo...@we... The Werken Company http://werken.com/ |
From: <lak...@t-...> - 2004-06-13 13:20:15
|
Simon Kitching wrote: >I'll see if I can find a suitable IRC server & channel & post details. >IRC is real easy to use. > > > That would be great. >But I'm off for some well-deserved sleep now! Catch you later in the >week maybe? > >Cheers, > >Simon > > > Good night! Here at home I'm online most Tuesday evenings. Currently we have the European football chamionships running, though, so I don't know if I can make it this week. Setting priorities is the most important aspect of life... :-) Lars |
From: Simon K. <si...@ec...> - 2004-06-13 13:08:09
|
On Mon, 2004-06-14 at 01:01, Lars K=FChne wrote: > >And by the way, as you are obviously online right now, is there an IRC > >channel we can chat on? > > > > =20 > > >=20 > I'd love to, but - believe it or not - I have never used IRC (although = I=20 > am on Linux so I probably have all software in place), so I'd have to d= o=20 > some reading first. >=20 > Is there an IRC channel you are usually connected to (hope this is the=20 > right terminology for IRC), and if so at which times of the day? I'm only a very occasional IRC user, but when I see my commit emails interlaced with yours, it's obvious we're both online :-). I'll see if I can find a suitable IRC server & channel & post details. IRC is real easy to use. But I'm off for some well-deserved sleep now! Catch you later in the week maybe? Cheers, Simon |
From: <lak...@t-...> - 2004-06-13 12:57:30
|
Simon Kitching wrote: >Hi Lars, > >Thanks for all the code prettifying :-). > >I'll try to run "maven checkstyle" before doing future checkins. > > > Thanks, that would be great. >Is there an option somewhere to automatically fix checkstyle problems >(he asks hopefully)? > > > Don't know, maybe some Checkstyle Eclipse plugin provide Quickfixes... I fixed most of the layout problems in my IDE by simply selecting the code and calling the "re-format code" function. The easiest way to handle checkstyle problems is probably not to introduce them in the first place. Configure your editor to strip trailing whitespace on save, use code templates (like "loop over an array") that have whitespace at the right places, etc. That should leave you with very few errors, and those usually cannot be fixed automatically... >And by the way, as you are obviously online right now, is there an IRC >channel we can chat on? > > > I'd love to, but - believe it or not - I have never used IRC (although I am on Linux so I probably have all software in place), so I'd have to do some reading first. Is there an IRC channel you are usually connected to (hope this is the right terminology for IRC), and if so at which times of the day? Lars |
From: SourceForge.net <no...@so...> - 2004-06-13 11:44:01
|
Feature Requests item #961229, was opened at 2004-05-27 00:54 Message generated for change (Comment added) made by lkuehne You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=590802&aid=961229&group_id=89627 Category: None Group: None >Status: Closed >Resolution: Fixed Priority: 5 Submitted By: Stephen Colebourne (scolebourne) Assigned to: Lars Kühne (lkuehne) Summary: Error messages raised on a class that hasn't changed Initial Comment: Not sure why, but these errors seem wrong as the code hasn't changed. Commons collections 3.0-HEAD ERROR: Method 'public java.lang.Object next()' has been removed in org.apache.commons.collections.map.AbstractLinkedMap$ LinkIterator ERROR: Method 'public java.lang.Object previous()' has been removed in org.apache.commons.collections.map.AbstractLinkedMap$ LinkIterator ERROR: Method 'public java.lang.Object next()' has been removed in org.apache.commons.collections.map.AbstractHashedMap $HashIterator ---------------------------------------------------------------------- >Comment By: Lars Kühne (lkuehne) Date: 2004-06-13 13:44 Message: Logged In: YES user_id=401384 The problem is fixed in CVS, will be part of release 0.4. Clirr now reports: INFO: Abstract method 'public java.lang.Object next()' is now specified by implemented interface java.util.Iterator in org.apache.commons.collections.map.AbstractHashedMap$HashIterator ---------------------------------------------------------------------- Comment By: Lars Kühne (lkuehne) Date: 2004-06-08 22:05 Message: Logged In: YES user_id=401384 I think I know what the problem is now: > javap -classpath commons-collections-3.0.jar -c 'org.apache.commons.collections.map.AbstractLinkedMap$LinkIterator' | grep public public abstract class org.apache.commons.collections.map.AbstractLinkedMap$LinkIterator extends java.lang.Object implements org.apache.commons.collections.OrderedIterator,org.apache.commons.collections.ResettableIterator{ public boolean hasNext(); public boolean hasPrevious(); public void remove(); public void reset(); public java.lang.String toString(); public abstract java.lang.Object previous(); public abstract java.lang.Object next(); > javap -classpath commons-collections.jar -c 'org.apache.commons.collections.map.AbstractLinkedMap$LinkIterator' | grep public public abstract class org.apache.commons.collections.map.AbstractLinkedMap$LinkIterator extends java.lang.Object implements org.apache.commons.collections.OrderedIterator,org.apache.commons.collections.ResettableIterator{ public boolean hasNext(); public boolean hasPrevious(); public void remove(); public void reset(); public java.lang.String toString(); Clirr is right, those methods *have* been removed (different compiler?), but removal of abstract methods should not lead to an error message if that method is specified by a superclass / interface. ---------------------------------------------------------------------- Comment By: Lars Kühne (lkuehne) Date: 2004-06-06 13:56 Message: Logged In: YES user_id=401384 Forget my comment on return type, I was looking at the 'next' field, not the method... ---------------------------------------------------------------------- Comment By: Lars Kühne (lkuehne) Date: 2004-06-06 10:44 Message: Logged In: YES user_id=401384 OK, thanks - I can reproduce this now. What's even more puzzeling is that the reported return type is incorrect, judging from the javadocs AbstractHashedMap$HashIterator.next() returns AbstractHashedMap.HashEntry, not Object. Will investigate... ---------------------------------------------------------------------- Comment By: Stephen Colebourne (scolebourne) Date: 2004-06-04 00:49 Message: Logged In: YES user_id=408725 HEAD file too big to attach. Try: http://cvs.apache.org/builds/jakarta- commons/nightly/commons-collections/ Javadoc on left (3.0 and HEAD) http://jakarta.apache.org/commons/collections/ ---------------------------------------------------------------------- Comment By: Stephen Colebourne (scolebourne) Date: 2004-06-04 00:48 Message: Logged In: YES user_id=408725 HEAD file too big to attach. Try: http://cvs.apache.org/builds/jakarta- commons/nightly/commons-collections/ Javadoc on left (3.0 and HEAD) http://jakarta.apache.org/commons/collections/ ---------------------------------------------------------------------- Comment By: Stephen Colebourne (scolebourne) Date: 2004-06-04 00:46 Message: Logged In: YES user_id=408725 Collections 3.0 vs CVS HEAD jar (attached) ---------------------------------------------------------------------- Comment By: Lars Kühne (lkuehne) Date: 2004-06-02 10:40 Message: Logged In: YES user_id=401384 Which versions of commons-collections are you testing against, and where can I find precompiled binaries and the javadoc for those versions? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=590802&aid=961229&group_id=89627 |
From: <lk...@us...> - 2004-06-13 11:43:33
|
Update of /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24191 Modified Files: MethodSetCheck.java Log Message: Removed abstract methods that are specified by an implemented interface are no longer reported as a compatibility problem. (RFE #961229) Index: MethodSetCheck.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/java/net/sf/clirr/checks/MethodSetCheck.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- MethodSetCheck.java 13 Jun 2004 11:00:59 -0000 1.8 +++ MethodSetCheck.java 13 Jun 2004 11:43:24 -0000 1.9 @@ -178,7 +178,12 @@ Method method = (Method) rmIterator.next(); String methodSignature = getMethodId(compatBaseline, method); String superClass = findSuperClassWithSignature(methodSignature, currentVersion); - reportMethodRemoved(compatBaseline, method, superClass); + String superInterface = null; + if (method.isAbstract()) + { + superInterface = findSuperInterfaceWithSignature(methodSignature, currentVersion); + } + reportMethodRemoved(compatBaseline, method, superClass, superInterface); } bNameToMethod.remove(name); } @@ -228,26 +233,64 @@ } /** + * Searches the class hierarchy for a method that has a certtain signature. + * @param methodSignature the sig we're looking for + * @param clazz class where search starts + * @return class name of a superinterface of clazz, might be null + */ + private String findSuperInterfaceWithSignature(String methodSignature, JavaClass clazz) + { + final JavaClass[] superClasses = clazz.getAllInterfaces(); + for (int i = 0; i < superClasses.length; i++) + { + JavaClass superClass = superClasses[i]; + final Method[] superMethods = superClass.getMethods(); + for (int j = 0; j < superMethods.length; j++) + { + Method superMethod = superMethods[j]; + final String superMethodSignature = getMethodId(superClass, superMethod); + if (methodSignature.equals(superMethodSignature)) + { + return superClass.getClassName(); + } + } + + } + return null; + } + + /** * Report that a method has been removed from a class. * @param oldClass the class where the method was available * @param oldMethod the method that has been removed * @param superClassName the superclass where the method is now available, might be null */ - private void reportMethodRemoved(JavaClass oldClass, Method oldMethod, String superClassName) + private void reportMethodRemoved( + JavaClass oldClass, + Method oldMethod, + String superClassName, + String superInterfaceName) { - if (superClassName == null) + if (superClassName != null) { fireDiff("Method '" + getMethodId(oldClass, oldMethod) - + "' has been removed", - Severity.ERROR, oldClass, oldMethod); + + "' is now implemented in superclass " + superClassName, + Severity.INFO, oldClass, oldMethod); + } + else if (superInterfaceName != null) + { + fireDiff("Abstract method '" + + getMethodId(oldClass, oldMethod) + + "' is now specified by implemented interface " + superInterfaceName, + Severity.INFO, oldClass, oldMethod); } else { fireDiff("Method '" + getMethodId(oldClass, oldMethod) - + "' is now implemented in superclass " + superClassName, - Severity.INFO, oldClass, oldMethod); + + "' has been removed", + Severity.ERROR, oldClass, oldMethod); } } |
From: <lk...@us...> - 2004-06-13 11:43:26
|
Update of /cvsroot/clirr/clirr/src/test/net/sf/clirr/checks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24081 Modified Files: MethodSetCheckTest.java Log Message: Removed abstract methods that are specified by an implemented interface are no longer reported as a compatibility problem. (RFE #961229) Index: MethodSetCheckTest.java =================================================================== RCS file: /cvsroot/clirr/clirr/src/test/net/sf/clirr/checks/MethodSetCheckTest.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- MethodSetCheckTest.java 8 Jun 2004 09:11:33 -0000 1.5 +++ MethodSetCheckTest.java 13 Jun 2004 11:43:18 -0000 1.6 @@ -29,6 +29,9 @@ new ApiDifference("Method 'public void moveToSuper()' is now implemented in superclass testlib.ComplexMethodMoveBase in testlib.ComplexMethodMoveSub", Severity.INFO, "testlib.ComplexMethodMoveSub", "public void moveToSuper()", null), + new ApiDifference("Abstract method 'public void method()' is now specified by implemented interface testlib.BaseInterface in testlib.AbstractImpl", + Severity.INFO, "testlib.AbstractImpl", "public void method()", null), + // Constructor changes new ApiDifference("Parameter 1 of 'protected MethodsChange(int)' has changed it's type to java.lang.Integer in testlib.MethodsChange", Severity.ERROR, "testlib.MethodsChange", "protected MethodsChange(int)", null), @@ -57,7 +60,7 @@ Severity.INFO, "testlib.MethodsChange", "public void becomesDeprecated()", null), new ApiDifference("Method 'public void becomesUndeprecated()' is no longer deprecated in testlib.MethodsChange", Severity.INFO, "testlib.MethodsChange", "public void becomesUndeprecated()", null), - + // declared exceptions // TODO }; |