Remove non-testable reflection code from JavadocUtils. #1308

In `JavadocUtils` any reflection-related exception would mean programmer's mistake with no recovery. In such cases checked exceptions are useless, so new method in utils is provided to wrap any checked exceptions into unchecked ones.
This commit is contained in:
Michal Kordas 2015-07-12 23:17:30 +02:00
parent 1ef7197d95
commit e68f47ce99
4 changed files with 45 additions and 57 deletions

View File

@ -1185,7 +1185,7 @@
<regex><pattern>.*.checks.javadoc.JavadocStyleCheck</pattern><branchRate>89</branchRate><lineRate>98</lineRate></regex>
<regex><pattern>.*.checks.javadoc.JavadocTagContinuationIndentationCheck</pattern><branchRate>81</branchRate><lineRate>86</lineRate></regex>
<regex><pattern>.*.checks.javadoc.JavadocTypeCheck</pattern><branchRate>95</branchRate><lineRate>93</lineRate></regex>
<regex><pattern>.*.checks.javadoc.JavadocUtils</pattern><branchRate>94</branchRate><lineRate>98</lineRate></regex>
<regex><pattern>.*.checks.javadoc.JavadocUtils</pattern><branchRate>94</branchRate><lineRate>100</lineRate></regex>
<regex><pattern>.*.checks.javadoc.SummaryJavadocCheck</pattern><branchRate>93</branchRate><lineRate>100</lineRate></regex>
<regex><pattern>.*.checks.javadoc.TagParser</pattern><branchRate>92</branchRate><lineRate>98</lineRate></regex>
<regex><pattern>.*.checks.javadoc.WriteTagCheck</pattern><branchRate>100</branchRate><lineRate>91</lineRate></regex>

View File

@ -58,7 +58,7 @@ public final class Utils {
}
final String name = f.getName();
final int tokenValue = getTokenFieldValue(f, name);
final int tokenValue = getIntFromField(f, name);
builder.put(name, tokenValue);
if (tokenValue > tempTokenValueToName.length - 1) {
final String[] temp = new String[tokenValue + 1];
@ -365,19 +365,21 @@ public final class Utils {
}
/**
* That method exists as workaround for code-coverage 100% target to let test
* catch block (originally it was in static area).
* @param field token field
* @param name token name
* @return value of field
* Gets the value of a static or instance field of type int or of another primitive type
* convertible to type int via a widening conversion. Does not throw any checked exceptions.
* @param field from which the int should be extracted
* @param object to extract the int value from
* @return the value of the field converted to type int
* @throws IllegalStateException if this Field object is enforcing Java language access control
* and the underlying field is inaccessible
* @see Field#getInt(Object)
*/
private static int getTokenFieldValue(Field field, String name) {
public static int getIntFromField(Field field, Object object) {
try {
return field.getInt(name);
return field.getInt(object);
}
catch (final IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(
"Failed to instantiate collection of Java tokens", e);
catch (final IllegalAccessException exception) {
throw new IllegalStateException(exception);
}
}
}

View File

@ -27,6 +27,7 @@ import java.util.regex.Pattern;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.puppycrawl.tools.checkstyle.Utils;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.api.JavadocTagInfo;
@ -62,25 +63,18 @@ public final class JavadocUtils {
final String name = f.getName();
try {
final int tokenValue = f.getInt(name);
builder.put(name, tokenValue);
if (tokenValue > tempTokenValueToName.length - 1) {
final String[] temp = new String[tokenValue + 1];
System.arraycopy(tempTokenValueToName, 0, temp, 0, tempTokenValueToName.length);
tempTokenValueToName = temp;
}
if (tokenValue == -1) {
tempTokenValueToName[0] = name;
}
else {
tempTokenValueToName[tokenValue] = name;
}
final int tokenValue = Utils.getIntFromField(f, name);
builder.put(name, tokenValue);
if (tokenValue > tempTokenValueToName.length - 1) {
final String[] temp = new String[tokenValue + 1];
System.arraycopy(tempTokenValueToName, 0, temp, 0, tempTokenValueToName.length);
tempTokenValueToName = temp;
}
catch (IllegalAccessException ex) {
// rethrow as unchecked exception
throw new IllegalStateException(
"Failed to instantiate collection of Javadoc tokens", ex);
if (tokenValue == -1) {
tempTokenValueToName[0] = name;
}
else {
tempTokenValueToName[tokenValue] = name;
}
}

View File

@ -28,8 +28,6 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Dictionary;
@ -171,6 +169,25 @@ public class UtilsTest {
}
}
@Test
public void testGetIntFromAccessibleField() throws NoSuchFieldException {
Field field = Integer.class.getField("MAX_VALUE");
assertEquals(Integer.MAX_VALUE, Utils.getIntFromField(field, 0));
}
@Test
public void testGetIntFromInaccessibleField() throws NoSuchFieldException {
Field field = Integer.class.getDeclaredField("value");
try {
Utils.getIntFromField(field, 0);
}
catch (IllegalStateException expected) {
// expected
}
}
@Test
public void testTokenValueIncorrect() throws NoSuchMethodException {
Integer id = Integer.MAX_VALUE - 1;
@ -252,29 +269,4 @@ public class UtilsTest {
Assert.assertTrue(Utils.isCommentType(TokenTypes.BLOCK_COMMENT_END));
Assert.assertTrue(Utils.isCommentType(TokenTypes.COMMENT_CONTENT));
}
@Test
public void testGetTokenFieldValue() throws NoSuchMethodException {
Integer id = 0;
try {
// overwrite static field with new value
Method method = Utils.class.getDeclaredMethod("getTokenFieldValue",
Field.class, String.class);
method.setAccessible(true);
method.invoke(null, Field.class.getDeclaredField("modifiers"), "smth_strange");
fail();
}
catch (InvocationTargetException expected) {
// in method we throw IllegalStateException,
// but JDK wrap that in InvocationTargetException
assertEquals(IllegalStateException.class, expected.getCause().getClass());
assertEquals("Failed to instantiate collection of Java tokens",
expected.getCause().getMessage());
}
catch (Exception e) {
fail();
}
}
}