#android #xml #android-studio-3.0 #checkstyle #codacy
#Android #xml #android-studio-3.0 #checkstyle #codacy
Вопрос:
Я хочу добавить пользовательские правила в checkstyle.xml чтобы я мог просматривать их на панели управления codacy. При этом я сталкиваюсь со следующими проблемами.
-
Я написал пользовательский класс для проверки неиспользуемых частных методов в
классах. В Android Studio отображается ошибка создания экземпляра, и
документация checkstyle не дает никаких подсказок относительно того, как создать экземпляр пользовательского класса правил и добавить его в качестве модуля. -
Checklist.xml настраивается с помощью Codacy dashboard, но не показывает детали на самой панели.
-
Даже в документации codacy говорится, что мы можем добавлять пользовательские правила XML, но я не могу добавить в нее пользовательские правила для XML, и проект, клонированный с Github, распознается только как java project. Я делюсь приведенными ниже фрагментами кода.
Вот ошибка из Android Studio https://ibb.co/613PL9t
Вот Checkstyle.xml
<module name="Checker">
<module name="NewlineAtEndOfFile" />
<module name="FileLength" />
<module name="FileTabCharacter" />
<module name="TreeWalker">
<module name="packageName.MethodCallWithoutObjectCreation" />
<module name="ArrayTypeStyle" />
<module name="UpperEll" />
<module name="Indentation">
<property name="caseIndent" value="4" />
</module>
</module>
Вот UnusedPrivateMethodCheck.Класс Java
public class UnusedPrivateMethodCheck
extends AbstractCheck {
/**
* Controls if checks skips serialization methods.
*/
private boolean mAllowSerializationMethods;
public int[] getDefaultTokens() {
return new int[]{
TokenTypes.METHOD_DEF,
};
}
@Override
public int[] getAcceptableTokens() {
return new int[0];
}
@Override
public int[] getRequiredTokens() {
return new int[0];
}
public String getErrorKey() {
return "unused.method";
}
public void setAllowSerializationMethods(boolean aFlag) {
mAllowSerializationMethods = aFlag;
}
public boolean mustCheckReferenceCount(DetailAST aAST) {
final DetailAST mods = aAST.findFirstToken(TokenTypes.MODIFIERS);
if ((mods == null)
|| (ScopeUtils.getScopeFromMods(mods) != Scope.PRIVATE)) {
return false;
}
return !mAllowSerializationMethods
|| !(isWriteObject(aAST) || isReadObject(aAST)
|| isWriteReplaceOrReadResolve(aAST));
}
/**
* Checks if a given method is writeObject().
*
* @param aAST method def to check
* @return true if this is a writeObject() definition
*/
private boolean isWriteObject(DetailAST aAST) {
// name is writeObject...
final DetailAST ident = aAST.findFirstToken(TokenTypes.IDENT);
if (!"writeObject".equals(ident.getText())) {
return false;
}
// returns void...
final DetailAST typeAST =
(DetailAST) aAST.findFirstToken(TokenTypes.TYPE).getFirstChild();
if (typeAST.getType() != TokenTypes.LITERAL_VOID) {
return false;
}
// should have one parameter...
final DetailAST params = aAST.findFirstToken(TokenTypes.PARAMETERS);
if (params == null || params.getChildCount() != 1) {
return false;
}
// and paramter's type should be java.io.ObjectOutputStream
final DetailAST type =
(DetailAST) ((DetailAST) params.getFirstChild())
.findFirstToken(TokenTypes.TYPE).getFirstChild();
final String typeName = FullIdent.createFullIdent(type).getText();
if (!"java.io.ObjectOutputStream".equals(typeName)
amp;amp; !"ObjectOutputStream".equals(typeName)) {
return false;
}
// and, finally, it should throws java.io.IOException
final DetailAST throwsAST =
aAST.findFirstToken(TokenTypes.LITERAL_THROWS);
if (throwsAST == null || throwsAST.getChildCount() != 1) {
return false;
}
final DetailAST expt = (DetailAST) throwsAST.getFirstChild();
final String exceptionName = FullIdent.createFullIdent(expt).getText();
if (!"java.io.IOException".equals(exceptionName)
amp;amp; !"IOException".equals(exceptionName)) {
return false;
}
return true;
}
/**
* Checks if a given method is readObject().
*
* @param aAST method def to check
* @return true if this is a readObject() definition
*/
private boolean isReadObject(DetailAST aAST) {
// name is readObject...
final DetailAST ident = aAST.findFirstToken(TokenTypes.IDENT);
if (!"readObject".equals(ident.getText())) {
return false;
}
// returns void...
final DetailAST typeAST =
(DetailAST) aAST.findFirstToken(TokenTypes.TYPE).getFirstChild();
if (typeAST.getType() != TokenTypes.LITERAL_VOID) {
return false;
}
// should have one parameter...
final DetailAST params = aAST.findFirstToken(TokenTypes.PARAMETERS);
if (params == null || params.getChildCount() != 1) {
return false;
}
// and paramter's type should be java.io.ObjectInputStream
final DetailAST type =
(DetailAST) ((DetailAST) params.getFirstChild())
.findFirstToken(TokenTypes.TYPE).getFirstChild();
final String typeName = FullIdent.createFullIdent(type).getText();
if (!"java.io.ObjectInputStream".equals(typeName)
amp;amp; !"ObjectInputStream".equals(typeName)) {
return false;
}
// and, finally, it should throws java.io.IOException
// and java.lang.ClassNotFoundException
final DetailAST throwsAST =
aAST.findFirstToken(TokenTypes.LITERAL_THROWS);
if (throwsAST == null || throwsAST.getChildCount() != 3) {
return false;
}
final DetailAST excpt1 = (DetailAST) throwsAST.getFirstChild();
final String exception1 = FullIdent.createFullIdent(excpt1).getText();
final String exception2 =
FullIdent.createFullIdent(throwsAST.getLastChild()).getText();
if (!"java.io.IOException".equals(exception1)
amp;amp; !"IOException".equals(exception1)
amp;amp; !"java.io.IOException".equals(exception2)
amp;amp; !"IOException".equals(exception2)
|| !"java.lang.ClassNotFoundException".equals(exception1)
amp;amp; !"ClassNotFoundException".equals(exception1)
amp;amp; !"java.lang.ClassNotFoundException".equals(exception2)
amp;amp; !"ClassNotFoundException".equals(exception2)) {
return false;
}
return true;
}
/**
* Checks if a given method is writeReplace() or readResolve().
*
* @param aAST method def to check
* @return true if this is a writeReplace() definition
*/
private boolean isWriteReplaceOrReadResolve(DetailAST aAST) {
// name is writeReplace or readResolve...
final DetailAST ident = aAST.findFirstToken(TokenTypes.IDENT);
if (!"writeReplace".equals(ident.getText())
amp;amp; !"readResolve".equals(ident.getText())) {
return false;
}
// returns Object...
final DetailAST typeAST =
(DetailAST) aAST.findFirstToken(TokenTypes.TYPE).getFirstChild();
if (typeAST.getType() != TokenTypes.DOT
amp;amp; typeAST.getType() != TokenTypes.IDENT) {
return false;
}
// should have no parameters...
final DetailAST params = aAST.findFirstToken(TokenTypes.PARAMETERS);
if (params != null amp;amp; params.getChildCount() != 0) {
return false;
}
// and, finally, it should throws java.io.ObjectStreamException
final DetailAST throwsAST =
aAST.findFirstToken(TokenTypes.LITERAL_THROWS);
if (throwsAST == null || throwsAST.getChildCount() != 1) {
return false;
}
final DetailAST excpt = (DetailAST) throwsAST.getFirstChild();
final String exception = FullIdent.createFullIdent(excpt).getText();
if (!"java.io.ObjectStreamException".equals(exception)
amp;amp; !"ObjectStreamException".equals(exception)) {
return false;
}
return true;
}
}
Из-за этого я получаю ошибку типа Unable to instantiate UnusedPrivateMethodCheckCheck
Комментарии:
1. На вашем скриншоте показан другой код, чем тот, который был вставлен.
Check
иAbstractUsageCheck
не являются классами последней версии checkstyle. Я рекомендую использовать последнюю версию checkstyle. Если вам нужна поддержка более старой версии checkstyle, пожалуйста, укажите версию, которую вы используете. Также, пожалуйста, скопируйте / вставьте полный текстunable to instantiate
сообщения об ошибке.2. codacy не поддерживает пользовательские правила, если я правильно помню
3. @rveach Спасибо за ваш комментарий, поскольку это действительно помогло мне разобраться в структуре Checkstyle, и в соответствии с вашими предложениями я заменил устаревшие классы из последней версии checkstyle, то есть версии 8.1, а также заменил скриншот, на котором четко видно, что не удается создать экземпляр сообщения об ошибке
4. @pedrorijo91 Меня беспокоят документы codacy, в которых упоминается, что вы можете настраивать шаблоны кода с помощью различных плагинов, таких как Checkstyle. Я не могу настроить правила для XML-файла layout. Я обращаюсь за помощью по тому же