/** * Notify checks that we are about to begin walking a tree. * @param rootAST the root of the tree. * @param contents the contents of the file the AST was generated from. * @param astState state of AST. */ private void notifyBegin(DetailAST rootAST, FileContents contents, AstState astState) { final Set<AbstractCheck> checks; if (astState == AstState.WITH_COMMENTS) { checks = commentChecks; } else { checks = ordinaryChecks; } for (AbstractCheck check : checks) { check.setFileContents(contents); check.clearMessages(); check.beginTree(rootAST); } }
/** * Notify checks that we have finished walking a tree. * @param rootAST the root of the tree. * @param astState state of AST. */ private void notifyEnd(DetailAST rootAST, AstState astState) { final Set<AbstractCheck> checks; if (astState == AstState.WITH_COMMENTS) { checks = commentChecks; } else { checks = ordinaryChecks; } for (AbstractCheck check : checks) { check.finishTree(rootAST); messages.addAll(check.getMessages()); } }
private static void validatePropertySectionPropertyTokens(String fileName, String sectionName, AbstractCheck check, List<Node> columns) { Assert.assertEquals(fileName + " section '" + sectionName + "' should have the basic token description", "tokens to check", columns.get(1) .getTextContent()); Assert.assertEquals( fileName + " section '" + sectionName + "' should have all the acceptable tokens", "subset of tokens " + CheckUtil.getTokenText(check.getAcceptableTokens(), check.getRequiredTokens()), columns.get(2).getTextContent() .replaceAll("\\s+", " ").trim()); Assert.assertEquals(fileName + " section '" + sectionName + "' should have all the default tokens", CheckUtil.getTokenText(check.getDefaultTokens(), check.getRequiredTokens()), columns.get(3).getTextContent().replaceAll("\\s+", " ").trim()); }
/** * Validates that check's required tokens are subset of default tokens. * @param check to validate * @throws CheckstyleException when validation of default tokens fails */ private static void validateDefaultTokens(AbstractCheck check) throws CheckstyleException { final int[] defaultTokens = check.getDefaultTokens(); Arrays.sort(defaultTokens); for (final int token : check.getRequiredTokens()) { if (Arrays.binarySearch(defaultTokens, token) < 0) { final String message = String.format(Locale.ROOT, "Token \"%s\" from required " + "tokens was not found in default tokens list in check %s", token, check.getClass().getName()); throw new CheckstyleException(message); } } }
validateDefaultTokens(check); final int[] tokens; final Set<String> checkTokens = check.getTokenNames(); if (checkTokens.isEmpty()) { tokens = check.getDefaultTokens(); tokens = check.getRequiredTokens(); final int[] acceptableTokens = check.getAcceptableTokens(); Arrays.sort(acceptableTokens); for (String token : checkTokens) { registerCheck(element, check); if (check.isCommentNodesRequired()) { commentChecks.add(check);
@Test public void testClearMessages() { final AbstractCheck check = new DummyAbstractCheck(); check.log(1, "key", "args"); Assert.assertEquals("Invalid message size", 1, check.getMessages().size()); check.clearMessages(); Assert.assertEquals("Invalid message size", 0, check.getMessages().size()); }
/** * Checks if stateful field is cleared during {@link AbstractCheck#beginTree} in check. * * @param check check object which field is to be verified * @param astToVisit ast to pass into check methods * @param fieldName name of the field to be checked * @param isClear function for checking field state * @return {@code true} if state of the field is cleared * @throws NoSuchFieldException if there is no field with the * {@code fieldName} in the {@code check} * @throws IllegalAccessException if the field is inaccessible */ public static boolean isStatefulFieldClearedDuringBeginTree(AbstractCheck check, DetailAST astToVisit, String fieldName, Predicate<Object> isClear) throws NoSuchFieldException, IllegalAccessException { check.beginTree(astToVisit); check.visitToken(astToVisit); check.beginTree(null); final Field resultField = getClassDeclaredField(check.getClass(), fieldName); return isClear.test(resultField.get(check)); }
@Test public void testCustomMessageWithParameters() throws Exception { final DefaultConfiguration config = createModuleConfig(emptyCheck.getClass()); config.addMessage("msgKey", "This is a custom message with {0}."); emptyCheck.configure(config); emptyCheck.log(1, "msgKey", "TestParam"); final SortedSet<LocalizedMessage> messages = emptyCheck.getMessages(); assertEquals("Amount of messages differs from expected", 1, messages.size()); assertEquals("Message differs from expected", "This is a custom message with TestParam.", messages.first().getMessage()); }
@Override public void finishTree(final DetailAST rootAST) { super.finishTree(rootAST); this.prevClassName = ""; } }
@Test public void testDefaultTokensAreSubsetOfAcceptableTokens() throws Exception { for (Class<?> check : CheckUtil.getCheckstyleChecks()) { if (AbstractCheck.class.isAssignableFrom(check)) { final AbstractCheck testedCheck = (AbstractCheck) check.getDeclaredConstructor() .newInstance(); final int[] defaultTokens = testedCheck.getDefaultTokens(); final int[] acceptableTokens = testedCheck.getAcceptableTokens(); if (!isSubset(defaultTokens, acceptableTokens)) { final String errorMessage = String.format(Locale.ROOT, "%s's default tokens must be a subset" + " of acceptable tokens.", check.getName()); Assert.fail(errorMessage); } } } }
@Test public void testRequiredTokensAreSubsetOfAcceptableTokens() throws Exception { for (Class<?> check : CheckUtil.getCheckstyleChecks()) { if (AbstractCheck.class.isAssignableFrom(check)) { final AbstractCheck testedCheck = (AbstractCheck) check.getDeclaredConstructor() .newInstance(); final int[] requiredTokens = testedCheck.getRequiredTokens(); final int[] acceptableTokens = testedCheck.getAcceptableTokens(); if (!isSubset(requiredTokens, acceptableTokens)) { final String errorMessage = String.format(Locale.ROOT, "%s's required tokens must be a subset" + " of acceptable tokens.", check.getName()); Assert.fail(errorMessage); } } } }
/** * Notify checks that leaving a node. * @param ast * the node to notify for * @param astState state of AST. */ private void notifyLeave(DetailAST ast, AstState astState) { final Collection<AbstractCheck> visitors = getListOfChecks(ast, astState); if (visitors != null) { for (AbstractCheck check : visitors) { check.leaveToken(ast); } } }
@Override public void setupChild(Configuration childConf) throws CheckstyleException { ModuleFactory moduleFactory = createModuleFactory(); String name = childConf.getName(); Object module = moduleFactory.createModule(name); if (!(module instanceof AbstractCheck)) { throw new CheckstyleException("OptionalCheck is not allowed as a parent of " + name + " Please review 'Parent Module' section for this Check."); } if (this.check != null) { throw new CheckstyleException("Can only make a single check optional"); } AbstractCheck check = (AbstractCheck) module; check.contextualize(this.childContext); check.configure(childConf); check.init(); this.check = check; }
@Override public void init() { super.init(); initWasCalled = true; }
@Test public void testGetLine() throws Exception { final AbstractCheck check = new AbstractCheck() { @Override public int[] getDefaultTokens() { return CommonUtil.EMPTY_INT_ARRAY; } @Override public int[] getAcceptableTokens() { return getDefaultTokens(); } @Override public int[] getRequiredTokens() { return getDefaultTokens(); } }; check.setFileContents(new FileContents(new FileText( new File(getPath("InputAbstractCheckTestFileContents.java")), Charset.defaultCharset().name()))); Assert.assertEquals("Invalid line content", " * I'm a javadoc", check.getLine(3)); }
@Test public void testGetAcceptable() { final AbstractCheck check = new AbstractCheck() { @Override public int[] getDefaultTokens() { return CommonUtil.EMPTY_INT_ARRAY; } @Override public int[] getAcceptableTokens() { return getDefaultTokens(); } @Override public int[] getRequiredTokens() { return getDefaultTokens(); } }; // Eventually it will become clear abstract method Assert.assertArrayEquals("Invalid number of tokens, should be empty", CommonUtil.EMPTY_INT_ARRAY, check.getAcceptableTokens()); }
@Test public void testGetRequiredTokens() { final AbstractCheck check = new AbstractCheck() { @Override public int[] getDefaultTokens() { return CommonUtil.EMPTY_INT_ARRAY; } @Override public int[] getAcceptableTokens() { return getDefaultTokens(); } @Override public int[] getRequiredTokens() { return getDefaultTokens(); } }; // Eventually it will become clear abstract method Assert.assertArrayEquals("Invalid number of tokens, should be empty", CommonUtil.EMPTY_INT_ARRAY, check.getRequiredTokens()); }
@Override public void beginTree(DetailAST rootAST) { super.beginTree(rootAST); stringMap.clear(); }
@Override public SortedSet<LocalizedMessage> getMessages() { return this.check.getMessages(); }
@Override public int[] getDefaultTokens() { return this.check.getDefaultTokens(); }