Hackしたいけど実現できていないこと(1)
id:taichitaichiから伝授されて以来、守っている掟がある。
「否定演算子(!)は見にくいので使わない」ことである。if(!foo) ではなく if(foo == false) と書く*1。
これを指摘するHackを作ろうと思った。
import org.ashikunep.irenka.dom.CtUnary; import org.ashikunep.irenka.dom.UnaryOperator; import org.ashikunep.irenka.toolkit.Messager; /** * 否定演算子をチェックするIrenka Hack。 * @author daisuke */ public class NotOperatorChecker { /** * インターフェイスに関する命名規則チェック。 * @param messager * @param unary 単項演算子 * @when {@link UnaryOperator#NOT} = unary.operator */ public void foundNotOperator(CtUnary<Boolean> unary, Messager messager) { messager.warn(unary, "否定演算子は推奨されません。\"!foo\"は\"foo == false\"に書き換えて下さい。"); } }
これを以下のコードに適用してみる。
public class TestClass { public static void main(String[] args) { boolean result = !Boolean.valueOf(args[0]); System.out.println(result); } }
すると、ビルダーが例外を吐いているようで、指摘が行われない。
java.lang.ClassCastException: java.lang.String
at org.ashikunep.irenka.query.ir.property.NavigatedProperty.apply(NavigatedProperty.java:98)
at org.ashikunep.irenka.query.ir.engine.SegmentResolver.visitProperty(SegmentResolver.java:109)
at org.ashikunep.irenka.query.ir.engine.SegmentResolver.visitProperty(SegmentResolver.java:1)
at org.ashikunep.irenka.query.ir.IrProperty.accept(IrProperty.java:88)
at org.ashikunep.irenka.query.ir.engine.ConstraintSegment.performPropagate(ConstraintSegment.java:140)
at org.ashikunep.irenka.query.ir.engine.ConstraintSegment.resolve(ConstraintSegment.java:82)
at org.ashikunep.irenka.query.ir.engine.IrQueryCursor.resolveSegment(IrQueryCursor.java:221)
at org.ashikunep.irenka.query.ir.engine.IrQueryCursor.push(IrQueryCursor.java:248)
at org.ashikunep.irenka.query.ir.engine.IrQueryCursor.prepare(IrQueryCursor.java:129)
at org.ashikunep.irenka.query.ir.engine.IrQueryCursor.hasNext(IrQueryCursor.java:81)
at org.ashikunep.irenka.apply.impl.DefaultHackApplier.applyActionToTarget(DefaultHackApplier.java:280)
at org.ashikunep.irenka.apply.impl.DefaultHackApplier.applyMatchActionToTarget(DefaultHackApplier.java:217)
at org.ashikunep.irenka.apply.impl.DefaultHackApplier.applyHackToTarget(DefaultHackApplier.java:173)
at org.ashikunep.irenka.apply.impl.DefaultHackApplier.applyHackToAll(DefaultHackApplier.java:129)
at org.ashikunep.irenka.apply.impl.DefaultHackApplier.apply(DefaultHackApplier.java:79)
at org.ashikunep.irenka.hack.engine.AbstractHackEngine.applyHacks(AbstractHackEngine.java:123)
at org.ashikunep.irenka.hack.engine.AbstractHackEngine.process(AbstractHackEngine.java:81)
at org.ashikunep.irenka.studio.JdtIrenkaBuildEngine.actionHack(JdtIrenkaBuildEngine.java:55)
at org.ashikunep.irenka.build.engine.IrenkaBuildEngine.build(IrenkaBuildEngine.java:54)
at org.ashikunep.irenka.studio.IrenkaBuilder.build(IrenkaBuilder.java:95)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:624)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:166)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:197)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:246)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:249)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:302)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:334)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:137)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
俺が間違っているのか、バグなのか…。まぁ、こういう時は大抵俺が間違ってるんだよなw
*1:値の反転の時は使っても良いんじゃないかと思っているけど。ex. boolean y = !x;