/*
 * JMockit Coverage
 * Copyright (c) 2006-2010 Rogério Liesenfeld
 * All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package mockit.coverage.reporting.parsing;

import java.util.*;

public final class FileParser
{
   private static final class PendingClass
   {
      final String className;
      int braceBalance;

      PendingClass(String className)
      {
         this.className = className;
      }
   }

   public final LineParser lineParser = new LineParser();
   public final List<PendingClass> currentClasses = new ArrayList<PendingClass>(2);

   private PendingClass currentClass;
   private boolean openingBraceForClassFound;
   private int currentBraceBalance;
   private boolean insideMethodBody;

   public boolean parseCurrentLine(String line)
   {
      boolean lineWithCodeElements = lineParser.parse(line);

      if (lineWithCodeElements) {
         LineElement firstElement = lineParser.getInitialElement();
         LineElement classDeclaration = firstElement.findWord("class");

         if (classDeclaration != null) {
            firstElement = classDeclaration.getNextCodeElement();
            String className = firstElement.getText();

            if (currentClass != null) {
               currentClass.braceBalance = currentBraceBalance;
            }

            currentClass = new PendingClass(className);
            currentClasses.add(currentClass);
            currentBraceBalance = 0;
         }

         if (currentClass != null) {
            // TODO: how to deal with classes defined entirely in one line?
            currentBraceBalance += firstElement.getBraceBalanceUntilEndOfLine();

            if (!openingBraceForClassFound && currentBraceBalance > 0) {
               openingBraceForClassFound = true;
            }
            else if (openingBraceForClassFound && currentBraceBalance == 0) {
               restorePreviousPendingClassIfAny();
            }
         }
      }

      return lineWithCodeElements;
   }

   private void restorePreviousPendingClassIfAny()
   {
      currentClasses.remove(currentClass);

      if (currentClasses.isEmpty()) {
         currentClass = null;
      }
      else {
         currentClass = currentClasses.get(currentClasses.size() - 1);
         currentBraceBalance = currentClass.braceBalance;
      }
   }

   public String getCurrentlyPendingClass()
   {
      return currentClass == null ? null : currentClass.className;
   }
}

@@ -1777,46 +1777,8 @@
 ce;%0D
-%0A   private boolean insideMethodBody;%0D
 %0A%0D%0A 
@@ -1841,39 +1841,13 @@
     
-boolean lineWithCodeElements = 
+if (!
 line
@@ -1864,27 +1864,27 @@
 se(line)
-;%0D%0A
+) %7B
 %0D%0A      
 if (line
@@ -1879,40 +1879,37 @@
     
-if (lineWithCodeElements) %7B%0D%0A   
+   return false;%0D%0A      %7D%0D%0A%0D%0A
     
@@ -1966,27 +1966,24 @@
 Element();%0D%0A
-   
       LineEl
@@ -2044,27 +2044,24 @@
 );%0D%0A%0D%0A      
-  
- 
 if (classDec
@@ -2073,35 +2073,32 @@
 ion != null) %7B%0D%0A
-   
          firstEl
@@ -2147,24 +2147,303 @@
 t();%0D%0A      
+   registerStartOfClassDeclaration(firstElement);%0D%0A      %7D%0D%0A%0D%0A      if (currentClass != null) %7B%0D%0A         detectPotentialEndOfClassDeclaration(firstElement);%0D%0A      %7D%0D%0A%0D%0A      return true;%0D%0A   %7D%0D%0A%0D%0A   private void registerStartOfClassDeclaration(LineElement firstElement)%0D%0A   %7B%0D%0A
       String
@@ -2484,30 +2484,24 @@
 );%0D%0A%0D%0A      
-   
-   
 if (currentC
@@ -2513,30 +2513,24 @@
 != null) %7B%0D%0A
-      
          cur
@@ -2572,30 +2572,24 @@
 ceBalance;%0D%0A
-      
       %7D%0D%0A%0D%0A 
@@ -2585,38 +2585,32 @@
      %7D%0D%0A%0D%0A      
-    
-  
 currentClass = n
@@ -2634,30 +2634,24 @@
 lassName);%0D%0A
-      
       curren
@@ -2677,38 +2677,32 @@
 tClass);%0D%0A      
- 
-     
 currentBraceBala
@@ -2711,22 +2711,16 @@
 e = 0;%0D%0A
-      
    %7D%0D%0A%0D%0A
@@ -2726,49 +2726,91 @@
 %0A   
-      if (currentClass != null) %7B
+private void detectPotentialEndOfClassDeclaration(LineElement firstElement)
 %0D%0A   
- 
-  
+%7B%0D%0A
     
@@ -2876,22 +2876,16 @@
  line?%0D%0A
-      
       cu
@@ -2960,22 +2960,16 @@
 %0D%0A      
-   
-   
 if (!ope
@@ -3031,22 +3031,16 @@
         
-      
 openingB
@@ -3076,29 +3076,17 @@
     
-      %7D%0D%0A   
+%7D%0D%0A
       
-   
 else
@@ -3157,22 +3157,16 @@
         
-      
 restoreP
@@ -3204,74 +3204,9 @@
     
-      %7D%0D%0A         %7D%0D%0A      %7D%0D%0A%0D%0A      return lineWithCodeElements;
+%7D
 %0D%0A  

Simple refactorings.