--- java.hints/src/org/netbeans/modules/java/hints/EmptyStatements.java +++ java.hints/src/org/netbeans/modules/java/hints/EmptyStatements.java @@ -30,365 +30,133 @@ */ package org.netbeans.modules.java.hints; -import org.netbeans.modules.java.hints.spi.support.FixFactory; import com.sun.source.tree.IfTree; import com.sun.source.tree.Tree; import com.sun.source.tree.Tree.Kind; import com.sun.source.util.TreePath; -import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.EnumSet; import java.util.List; -import java.util.Set; -import org.netbeans.api.java.lexer.JavaTokenId; -import org.netbeans.api.java.source.CompilationInfo; -import org.netbeans.api.java.source.JavaSource; -import org.netbeans.api.java.source.Task; -import org.netbeans.api.java.source.TreePathHandle; -import org.netbeans.api.java.source.WorkingCopy; -import org.netbeans.modules.java.hints.spi.AbstractHint; -import org.netbeans.spi.editor.hints.ChangeInfo; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.java.hints.spi.support.FixFactory; import org.netbeans.spi.editor.hints.ErrorDescription; -import org.netbeans.spi.editor.hints.ErrorDescriptionFactory; import org.netbeans.spi.editor.hints.Fix; -import org.openide.filesystems.FileObject; -import org.openide.util.Exceptions; +import org.netbeans.spi.editor.hints.Severity; +import org.netbeans.spi.java.hints.Hint; +import org.netbeans.spi.java.hints.HintContext; +import org.netbeans.spi.java.hints.JavaFixUtilities; +import org.netbeans.spi.java.hints.TriggerTreeKind; import org.openide.util.NbBundle; /** * * @author phrebejk + * @author markiewb (refactoring) */ -public class EmptyStatements extends AbstractHint { +public class EmptyStatements { private static final String SUPPRESS_WARNINGS_KEY = "empty-statement"; - static final EnumSet nonRelevant = EnumSet.of( - JavaTokenId.LINE_COMMENT, - JavaTokenId.BLOCK_COMMENT, - JavaTokenId.JAVADOC_COMMENT, - JavaTokenId.WHITESPACE - ); + @Hint(displayName = "#LBL_Empty_BLOCK", description = "#DSC_Empty_BLOCK", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_BLOCK") + @TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) + @NbBundle.Messages({"ERR_EmptyBLOCK=Remove semicolon"}) + public static ErrorDescription forBLOCK(HintContext ctx) { - private String EMPTY_STATEMENTS_ID = "EmptyStatements_"; // NOI18N - - private Tree.Kind treeKind; - private Set treeKinds = EnumSet.of(Tree.Kind.EMPTY_STATEMENT); - private Set NO_KINDS = EnumSet.noneOf(Tree.Kind.class); - - private static EmptyStatements delegate; - private static EmptyStatements esFor; - private static EmptyStatements esWhile; - private static EmptyStatements esDoWhile; - private static EmptyStatements esIf; - private static EmptyStatements esBlock; - - private EmptyStatements( Tree.Kind treeKind ) { - super( treeKind == Tree.Kind.IF ? false : true, true, HintSeverity.WARNING, SUPPRESS_WARNINGS_KEY ); - this.treeKind = treeKind; + Tree parent = ctx.getPath().getParentPath().getLeaf(); + if (!EnumSet.of(Kind.BLOCK).contains(parent.getKind())) { + return null; } - public static EmptyStatements createDelegate() { - return getDelegate(); - } + final List fixes = new ArrayList<>(); + fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), ctx.getPath(), SUPPRESS_WARNINGS_KEY)); + fixes.add(JavaFixUtilities.removeFromParent(ctx, Bundle.ERR_EmptyBLOCK(), ctx.getPath())); - public static EmptyStatements createFor() { - EmptyStatements d = getDelegate(); - d.esFor = new EmptyStatements( Tree.Kind.FOR_LOOP ); - return d.esFor; + return createErrorDescription(ctx, ctx.getPath().getLeaf(), fixes, Kind.BLOCK); } - public static EmptyStatements createWhile() { - EmptyStatements d = getDelegate(); - d.esWhile = new EmptyStatements( Tree.Kind.WHILE_LOOP ); - return d.esWhile; + @Hint(displayName = "#LBL_Empty_WHILE_LOOP", description = "#DSC_Empty_WHILE_LOOP", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_WHILE_LOOP") + @TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) + public static ErrorDescription forWHILE_LOOP(HintContext ctx) { + final TreePath parentPath = ctx.getPath().getParentPath(); + final Tree parentLeaf = parentPath.getLeaf(); + if (!EnumSet.of(Kind.WHILE_LOOP).contains(parentLeaf.getKind())) { + return null; } - public static EmptyStatements createDoWhile() { - EmptyStatements d = getDelegate(); - d.esDoWhile = new EmptyStatements( Tree.Kind.DO_WHILE_LOOP ); - return d.esDoWhile; - } + final List fixes = new ArrayList<>(); + fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), parentPath, SUPPRESS_WARNINGS_KEY)); - public static EmptyStatements createIf() { - EmptyStatements d = getDelegate(); - d.esIf = new EmptyStatements( Tree.Kind.IF ); - return d.esIf; + return createErrorDescription(ctx, parentLeaf, fixes, Kind.WHILE_LOOP); } - public static EmptyStatements createBlock() { - EmptyStatements d = getDelegate(); - d.esBlock = new EmptyStatements( Tree.Kind.BLOCK ); - return d.esBlock; - } + @Hint(displayName = "#LBL_Empty_IF", description = "#DSC_Empty_IF", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_IF", enabled = false) + @TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) + public static ErrorDescription forIF(HintContext ctx) { + final TreePath treePath = ctx.getPath(); - public static synchronized EmptyStatements getDelegate() { - if ( delegate == null ) { - delegate = new EmptyStatements(null); - } - return delegate; - } - - public Set getTreeKinds() { - return treeKind == null ? treeKinds : NO_KINDS; - } - - public List run(CompilationInfo compilationInfo, TreePath treePath) { - - Tree tree = treePath.getLeaf(); - - if( tree.getKind() != Tree.Kind.EMPTY_STATEMENT ) { - return null; - } - Tree parent = treePath.getParentPath().getLeaf(); - - if ( !isEnabled(parent.getKind()) ) { + if (!EnumSet.of(Kind.IF).contains(parent.getKind())) { return null; } - ErrorDescription ed = null; - - switch( parent.getKind() ) { - case FOR_LOOP: - case ENHANCED_FOR_LOOP: - case WHILE_LOOP: - case DO_WHILE_LOOP: - - ed = createErrorDescription(treePath.getParentPath(), parent.getKind(), compilationInfo); - if ( ed != null ) { - return Collections.singletonList(ed); + TreePath treePathForWarning = treePath; + IfTree it = (IfTree) parent; + if (it.getThenStatement() != null + && it.getThenStatement().getKind() == Tree.Kind.EMPTY_STATEMENT) { + treePathForWarning = treePath.getParentPath(); } - break; - case BLOCK: - ed = createErrorDescription(treePath, parent.getKind(), compilationInfo); - if ( ed != null ) { - return Collections.singletonList(ed); + if (it.getElseStatement() != null + && it.getElseStatement().getKind() == Tree.Kind.EMPTY_STATEMENT) { + treePathForWarning = treePath; } - break; - case IF: - List result = new ArrayList(2); - IfTree it = (IfTree)parent; - if ( it.getThenStatement() != null && - it.getThenStatement().getKind() == Tree.Kind.EMPTY_STATEMENT ) { - result.add( createErrorDescription(treePath.getParentPath(), parent.getKind(), compilationInfo) ); - } - if ( it.getElseStatement() != null && - it.getElseStatement().getKind() == Tree.Kind.EMPTY_STATEMENT ) { - result.add( createErrorDescription(treePath, parent.getKind(), compilationInfo) ); - } - return result; - } - return Collections.emptyList(); - } + final List fixes = new ArrayList<>(); + fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), treePathForWarning, SUPPRESS_WARNINGS_KEY)); - public void cancel() { - // Does nothing + return createErrorDescription(ctx, parent, fixes, parent.getKind()); } - public String getId() { - return EMPTY_STATEMENTS_ID + treeKind; - } + @Hint(displayName = "#LBL_Empty_FOR_LOOP", description = "#DSC_Empty_FOR_LOOP", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_FOR_LOOP") + @TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) + public static ErrorDescription forFOR_LOOP(HintContext ctx) { - public String getDisplayName() { - if ( treeKind == null ) { - return "Empty Statements Delegate"; // NOI18N + Tree parent = ctx.getPath().getParentPath().getLeaf(); + if (!EnumSet.of(Kind.FOR_LOOP, Kind.ENHANCED_FOR_LOOP).contains(parent.getKind())) { + return null; } - return NbBundle.getMessage(EmptyStatements.class, "LBL_Empty_" + treeKind.toString() ); // NOI18N - } - public String getDescription() { - if ( treeKind == null ) { - return "Empty Statements Delegate"; // NOI18N - } - return NbBundle.getMessage(EmptyStatements.class, "DSC_Empty_" + treeKind.toString() ); // NOI18N - } + final List fixes = new ArrayList<>(); + fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), ctx.getPath().getParentPath(), SUPPRESS_WARNINGS_KEY)); - // Private methods --------------------------------------------------------- - - private ErrorDescription createErrorDescription( TreePath tp, Tree.Kind kind, CompilationInfo info ) { - - return ErrorDescriptionFactory.createErrorDescription( - getSeverity().toEditorSeverity(), - // getDisplayName(), - NbBundle.getMessage(EmptyStatements.class, "LBL_Empty_" + kind.toString()), - // Collections.singletonList(new EmptyStatementFix( info.getFileObject(), TreePathHandle.create(tp, info) ) ), - FixFactory.createSuppressWarnings( info, tp, SUPPRESS_WARNINGS_KEY), - info.getFileObject(), - (int)info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf()), - (int)info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf())); + return createErrorDescription(ctx, parent, fixes, parent.getKind()); } - private boolean isEnabled( Tree.Kind kind ) { - switch( kind ) { - case FOR_LOOP: - case ENHANCED_FOR_LOOP: - return esFor.isEnabled(); - case WHILE_LOOP: - return esWhile.isEnabled(); - case DO_WHILE_LOOP: - return esDoWhile.isEnabled(); - case BLOCK: - return esBlock.isEnabled(); - case IF: - return esIf.isEnabled(); - } - return false; - } + @Hint(displayName = "#LBL_Empty_DO_WHILE_LOOP", description = "#DSC_Empty_DO_WHILE_LOOP", category = "empty", hintKind = Hint.Kind.INSPECTION, severity = Severity.WARNING, suppressWarnings = SUPPRESS_WARNINGS_KEY, id = "EmptyStatements_DO_WHILE_LOOP") + @TriggerTreeKind(Tree.Kind.EMPTY_STATEMENT) + public static ErrorDescription forDO_WHILE_LOOP(HintContext ctx) { - /* - private List checkifStatements( StatementTree thenSt, StatementTree elseSt, TreePath tp, CompilationInfo info ) { - - boolean fixThen = false; - boolean fixElse = false; - - if ( thenSt != null && - thenSt.getKind() != Tree.Kind.EMPTY_STATEMENT && - thenSt.getKind() != Tree.Kind.BLOCK && - thenSt.getKind() != Tree.Kind.ERRONEOUS && - !isErroneousExpression( thenSt )) { - fixThen = true; - } - - if ( elseSt != null && - elseSt.getKind() != Tree.Kind.EMPTY_STATEMENT && - elseSt.getKind() != Tree.Kind.BLOCK && - elseSt.getKind() != Tree.Kind.ERRONEOUS && - !isErroneousExpression( elseSt )) { - fixElse = true; - } - - List result = new ArrayList(); - - if ( fixThen ) { - EmptyStatementFix bf = new EmptyStatementFix( info.getFileObject(), TreePathHandle.create(tp, info)); - bf.fixThen = fixThen; - bf.fixElse = fixElse; - result.add( ErrorDescriptionFactory.createErrorDescription( - getSeverity().toEditorSeverity(), - getDisplayName(), - Collections.singletonList( bf ), - info.getFileObject(), - (int)info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), thenSt ), - (int)info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), thenSt ) ) ); - } - - if ( fixElse ) { - EmptyStatementFix bf = new EmptyStatementFix( info.getFileObject(), TreePathHandle.create(tp, info)); - bf.fixThen = fixThen; - bf.fixElse = fixElse; - result.add( ErrorDescriptionFactory.createErrorDescription( - getSeverity().toEditorSeverity(), - getDisplayName(), - Collections.singletonList( bf ), - info.getFileObject(), - (int)info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), elseSt ), - (int)info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), elseSt ) ) ); - - } - - return result; - } - - private boolean isErroneousExpression(StatementTree statement) { - if ( statement instanceof ExpressionStatementTree ) { - if ( ((ExpressionStatementTree)statement).getExpression().getKind() == Kind.ERRONEOUS ) { - return true; - } - } - return false; - } - */ - - private static class EmptyStatementFix implements Fix, Task { - - - FileObject file; - TreePathHandle tph; - Tree.Kind kind; - - boolean fixThen; - boolean fixElse; - - public EmptyStatementFix(FileObject file, TreePathHandle tph, Tree.Kind kind ) { - this.file = file; - this.tph = tph; - this.kind = kind; - } - - public String getText() { - return NbBundle.getMessage(Braces.class, "LBL_Empty_Fix" + kind.toString()); // NOI18N - } - - public ChangeInfo implement() { - JavaSource js = JavaSource.forFileObject(file); - try { - js.runModificationTask(this).commit(); - } - catch( IOException e ) { - Exceptions.printStackTrace(e); - } + Tree parent = ctx.getPath().getParentPath().getLeaf(); + if (!Kind.DO_WHILE_LOOP.equals(parent.getKind())) { return null; } - public void run(WorkingCopy copy) throws Exception { - /* - copy.toPhase(JavaSource.Phase.PARSED); - TreePath path = tph.resolve(copy); + final List fixes = new ArrayList<>(); + fixes.add(FixFactory.createSuppressWarningsFix(ctx.getInfo(), ctx.getPath().getParentPath(), SUPPRESS_WARNINGS_KEY)); - if ( path != null ) { - - TreeMaker make = copy.getTreeMaker(); - Tree oldTree = path.getLeaf(); - - switch( oldTree.getKind() ) { - case FOR_LOOP: - ForLoopTree oldFor = (ForLoopTree)oldTree; - StatementTree oldBlock = oldFor.getStatement(); - BlockTree newBlock = make.Block(Collections.singletonList(oldBlock), false); - copy.rewrite(oldBlock, newBlock); - break; - case ENHANCED_FOR_LOOP: - EnhancedForLoopTree oldEnhancedFor = (EnhancedForLoopTree)oldTree; - oldBlock = oldEnhancedFor.getStatement(); - newBlock = make.Block(Collections.singletonList(oldBlock), false); - copy.rewrite(oldBlock, newBlock); - break; - case WHILE_LOOP: - WhileLoopTree oldWhile = (WhileLoopTree)oldTree; - oldBlock = oldWhile.getStatement(); - newBlock = make.Block(Collections.singletonList(oldBlock), false); - copy.rewrite(oldBlock, newBlock); - break; - case DO_WHILE_LOOP: - DoWhileLoopTree oldDoWhile = (DoWhileLoopTree)oldTree; - oldBlock = oldDoWhile.getStatement(); - newBlock = make.Block(Collections.singletonList(oldBlock), false); - copy.rewrite(oldBlock, newBlock); - break; - case IF: - IfTree oldIf = (IfTree)oldTree; - if ( fixThen ) { - oldBlock = oldIf.getThenStatement(); - newBlock = make.Block(Collections.singletonList(oldBlock), false); - copy.rewrite(oldBlock, newBlock); + return createErrorDescription(ctx, parent, fixes, parent.getKind()); } - if ( fixElse ) { - oldBlock = oldIf.getElseStatement(); - newBlock = make.Block(Collections.singletonList(oldBlock), false); - copy.rewrite(oldBlock, newBlock); - } - } - } + /** + * package private for reuse in unit tests. */ + static String getDisplayName(@NonNull Kind treeKind) { + //same pattern as in @Hint(displayName = "#LBL_Empty_XXXX" + return NbBundle.getMessage(EmptyStatements.class, "LBL_Empty_" + treeKind.toString()); // NOI18N } - + private static ErrorDescription createErrorDescription(HintContext ctx, final Tree leaf, final List fixes, Kind treeKind) { + int start = (int) ctx.getInfo().getTrees().getSourcePositions().getStartPosition(ctx.getInfo().getCompilationUnit(), leaf); + int end = (int) ctx.getInfo().getTrees().getSourcePositions().getEndPosition(ctx.getInfo().getCompilationUnit(), leaf); + return org.netbeans.spi.java.hints.ErrorDescriptionFactory.forSpan(ctx, start, end, getDisplayName(treeKind), fixes.toArray(new Fix[fixes.size()])); } - - - } --- java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml +++ java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml @@ -288,26 +288,7 @@ - - - - - - - - - - - - - - - - - - - - + --- java.hints/test/unit/src/org/netbeans/modules/java/hints/RemoveEmptyStatementTest.java +++ java.hints/test/unit/src/org/netbeans/modules/java/hints/RemoveEmptyStatementTest.java @@ -0,0 +1,165 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2014 Sun Microsystems, Inc. + */ +package org.netbeans.modules.java.hints; + +import com.sun.source.tree.Tree; +import org.junit.Test; +import static org.netbeans.modules.java.hints.EmptyStatements.getDisplayName; +import org.netbeans.modules.java.hints.test.api.HintTest; + +/** + * + * @author markiewb + */ +public class RemoveEmptyStatementTest { + + @Test + public void testRemoveEmptyBLOCK() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " System.out.println(\"hello world\");;\n" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .findWarning("3:42-3:43:warning:" + getDisplayName(Tree.Kind.BLOCK)) + .applyFix(Bundle.ERR_EmptyBLOCK()) + .assertCompilable() + .assertOutput("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " System.out.println(\"hello world\");\n" + + " }\n" + + "}\n"); + } + + @Test + public void testRemoveEmptyWHILE_LOOP() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " while(true);\n" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .findWarning("3:8-3:20:warning:" + getDisplayName(Tree.Kind.WHILE_LOOP)) + .assertFixes(); + } + + @Test + public void testRemoveEmptyFOR_LOOP() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " for(int i=0;i<10;i++);\n" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .findWarning("3:8-3:30:warning:" + getDisplayName(Tree.Kind.FOR_LOOP)) + .assertFixes(); + } + + @Test + public void testRemoveEmptyENHANCED_FOR_LOOP() throws Exception { + + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " java.util.List list = new java.util.ArrayList();" + + " for(String s:list);\n" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .findWarning("3:80-3:99:warning:" + getDisplayName(Tree.Kind.ENHANCED_FOR_LOOP)) + .assertFixes(); + } + + @Test + public void testRemoveEmptyDO_WHILE_LOOP() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " do;while(true);\n" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .findWarning("3:8-3:23:warning:" + getDisplayName(Tree.Kind.DO_WHILE_LOOP)) + .assertFixes(); + } + + @Test + public void testRemoveEmptyIF() throws Exception { + final String ifWarn = "3:8-4:13:warning:" + getDisplayName(Tree.Kind.IF); + final String elseWarn = "3:8-4:13:warning:" + getDisplayName(Tree.Kind.IF); + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " if (\"1\".equals(\"1\")); \n" + + " else;" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .assertWarnings(ifWarn, elseWarn) + .findWarning(ifWarn) + .assertFixes(); + + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public static void main(String[] args) {\n" + + " if (\"1\".equals(\"1\")); \n" + + " else;" + + " }\n" + + "}\n") + .run(EmptyStatements.class) + .assertWarnings(ifWarn, elseWarn) + .findWarning(elseWarn) + .assertFixes(); + } + +}