All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.coverage.paths.Node Maven / Gradle / Ivy

Go to download

JMockit Coverage is a code coverage tool with several metrics (line, path, data) capable of generating HTML reports. It is designed with ease of use in mind, avoiding the need for complex configuration. Instead, smart (but overridable) defaults are employed, such as the selection of which classes to consider for coverage, and where to find sources files for report generation.

There is a newer version: 1.23
Show newest version
/*
 * Copyright (c) 2006-2015 Rogério Liesenfeld
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
 */
package mockit.coverage.paths;

import java.util.*;
import java.io.*;
import javax.annotation.*;

@SuppressWarnings("ClassReferencesSubclass")
public class Node implements Serializable
{
   private static final long serialVersionUID = 7521062699264845946L;

   @Nonnull private final transient ThreadLocal reached = new ThreadLocal();
   public final int line;
   protected int segment;

   private Node(int line) { this.line = line; }

   void setSegmentAccordingToPrecedingNode(@Nonnull Node precedingNode)
   {
      int currentSegment = precedingNode.segment;
      segment = precedingNode instanceof Fork ? currentSegment + 1 : currentSegment;
   }

   public final int getSegment() { return segment; }

   final void setReached(@Nullable Boolean reached) { this.reached.set(reached); }
   final boolean wasReached() { return reached.get() != null; }

   @Override
   public final String toString() { return getClass().getSimpleName() + ':' + line + '-' + segment; }

   static final class Entry extends Node
   {
      private static final long serialVersionUID = -3065417917872259568L;
      @Nullable Fork nextNode;

      Entry(int entryLine) { super(entryLine); }
   }

   interface ConditionalSuccessor extends Serializable
   {
      void addToPath(@Nonnull Path path);
   }

   interface GotoSuccessor extends Serializable
   {
      void setNextNodeAfterGoto(@Nonnull Join newJoin);
   }

   static final class Exit extends Node implements ConditionalSuccessor
   {
      private static final long serialVersionUID = -4801498566218642509L;
      @Nonnull final List paths = new ArrayList(4);

      Exit(int exitLine) { super(exitLine); }

      @Override
      public void addToPath(@Nonnull Path path)
      {
         path.addNode(this);
         paths.add(path);
      }
   }

   static final class BasicBlock extends Node implements ConditionalSuccessor, GotoSuccessor
   {
      private static final long serialVersionUID = 2637678937923952603L;
      @Nullable ConditionalSuccessor nextConsecutiveNode;
      @Nullable private Join nextNodeAfterGoto;

      BasicBlock(int startingLine) { super(startingLine); }

      @Override @SuppressWarnings("NullableProblems")
      public void setNextNodeAfterGoto(@Nonnull Join newJoin) { nextNodeAfterGoto = newJoin; }

      @Override
      public void addToPath(@Nonnull Path path)
      {
         path.addNode(this);

         if (nextNodeAfterGoto != null) {
            assert nextConsecutiveNode == null;
            nextNodeAfterGoto.addToPath(path);
         }
         else if (nextConsecutiveNode != null) {
            nextConsecutiveNode.addToPath(path);
         }
      }
   }

   public abstract static class Fork extends Node implements ConditionalSuccessor
   {
      private static final long serialVersionUID = -4995089238476806249L;

      Fork(int line) { super(line); }

      abstract void addNextNode(@Nonnull Join nextNode);

      static void createAlternatePath(@Nonnull Path parentPath, @Nonnull Join targetJoin)
      {
         Path alternatePath = new Path(parentPath, targetJoin.fromTrivialFork);
         targetJoin.addToPath(alternatePath);
      }
   }

   static final class SimpleFork extends Fork
   {
      private static final long serialVersionUID = -521666665272332763L;
      @Nullable ConditionalSuccessor nextConsecutiveNode;
      @Nullable private Join nextNodeAfterJump;

      SimpleFork(int line) { super(line); }

      @Override
      void addNextNode(@Nonnull Join nextNode) { nextNodeAfterJump = nextNode; }

      @Override
      public void addToPath(@Nonnull Path path)
      {
         path.addNode(this);

         if (nextNodeAfterJump != null) {
            createAlternatePath(path, nextNodeAfterJump);
         }

         if (nextConsecutiveNode != null) {
            nextConsecutiveNode.addToPath(path);
         }
      }
   }

   static final class MultiFork extends Fork
   {
      private static final long serialVersionUID = 1220318686622690670L;
      @Nonnull private final List caseNodes = new ArrayList();

      MultiFork(int line) { super(line); }

      @Override
      void addNextNode(@Nonnull Join nextNode) { caseNodes.add(nextNode); }

      @Override
      public void addToPath(@Nonnull Path path)
      {
         path.addNode(this);

         for (Join caseJoin : caseNodes) {
            createAlternatePath(path, caseJoin);
         }
      }
   }

   static final class Join extends Node implements ConditionalSuccessor, GotoSuccessor
   {
      private static final long serialVersionUID = -1983522899831071765L;
      @Nullable ConditionalSuccessor nextNode;
      transient boolean fromTrivialFork;

      Join(int joiningLine) { super(joiningLine); }

      @Override
      public void setNextNodeAfterGoto(@Nonnull Join newJoin) { nextNode = newJoin; }

      @Override
      public void addToPath(@Nonnull Path path)
      {
         path.addNode(this);

         // TODO: can be null when there is a try..finally block; see WhileStatements#whileTrueContainingTryFinally
         if (nextNode != null) {
            nextNode.addToPath(path);
         }
      }

      @Override
      void setSegmentAccordingToPrecedingNode(@Nonnull Node precedingNode)
      {
         segment = precedingNode.segment + 1;
      }
   }

   static final class Goto extends Node implements ConditionalSuccessor, GotoSuccessor
   {
      private static final long serialVersionUID = -4715451134432419220L;
      private Join nextNodeAfterGoto;

      Goto(int line) { super(line); }

      @Override
      public void setNextNodeAfterGoto(@Nonnull Join newJoin) { nextNodeAfterGoto = newJoin; }

      @Override
      public void addToPath(@Nonnull Path path)
      {
         path.addNode(this);
         nextNodeAfterGoto.addToPath(path);
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy