package annotations.el;

import checkers.nullness.quals.*;
import checkers.javari.quals.*;

import annotations.util.*;

/**
 * A {@link LocalLocation} holds location information for a local
 * variable: slot index, scope start, and scope length.
 */
public final /*@ReadOnly*/ class LocalLocation {
    /**
     * The slot index of the local variable.
     */
    public final int index;

    /**
     * The start of the local variable's scope (or live range), as an offset
     * from the beginning of the method code in bytes.
     */
    public final int scopeStart;

    /**
     * The length of the local variable's scope (or live range), in bytes.
     */
    public final int scopeLength;

    /**
     * Constructs a new {@link LocalLocation}; the arguments are assigned to
     * the fields of the same names.
     */
    public LocalLocation(int index, int scopeStart, int scopeLength) {
        this.index = index;
        this.scopeStart = scopeStart;
        this.scopeLength = scopeLength;
    }

    /**
     * Returns whether this {@link LocalLocation} equals <code>o</code>; a
     * slightly faster variant of {@link #equals(Object)} for when the argument
     * is statically known to be another nonnull {@link LocalLocation}.
     */
    public boolean equals(LocalLocation l) {
        return index == l.index && scopeStart == l.scopeStart
                && scopeLength == l.scopeLength;
    }

    /**
     * This {@link LocalLocation} equals <code>o</code> if and only if
     * <code>o</code> is another nonnull {@link LocalLocation} and
     * <code>this</code> and <code>o</code> have equal {@link #index},
     * {@link #scopeStart}, and {@link #scopeLength}.
     */
    @Override
    public boolean equals(/*@ReadOnly*/ Object o) {
        return o instanceof LocalLocation
                && equals((LocalLocation) o);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() /*@ReadOnly*/ {
         Hasher h = new Hasher();
        h.mash(index);
        h.mash(scopeStart);
        h.mash(scopeLength);
        return h.hash;
    }

    @Override
    public String toString() {
     return "LocalLocation(" + index + ", " + scopeStart + ", " + scopeLength + ")";
    }
}

@@ -891,28 +891,25 @@
 ngth) %7B%0A    
-    
+%09
 this.index =
@@ -990,34 +990,272 @@
 copeLength;%0A    
-%7D%0A
+    this.varname = null;%0A    %7D%0A%0A    public final String varname;%0A    %0A    public LocalLocation(String varname) %7B%0A    %09this.index = -1;%0A        this.scopeStart = -1;%0A        this.scopeLength = -1;%0A    %09this.varname = varname;%0A    %7D%0A    %0A    
 %0A    /**%0A     * 
@@ -1542,16 +1542,17 @@
  return 
+(
 index ==
@@ -1633,24 +1633,89 @@
 .scopeLength
+) %7C%7C%0A                (varname!=null && varname.equals(l.varname))
 ;%0A    %7D%0A%0A   
@@ -2248,21 +2248,41 @@
 / %7B%0A    
-     
+%09if (varname==null) %7B%0A%09%09%09
 Hasher h
@@ -2298,24 +2298,19 @@
 sher();%0A
-        
+%09%09%09
 h.mash(i
@@ -2316,24 +2316,19 @@
 index);%0A
-        
+%09%09%09
 h.mash(s
@@ -2339,24 +2339,19 @@
 Start);%0A
-        
+%09%09%09
 h.mash(s
@@ -2367,30 +2367,73 @@
 h);%0A
-   
+%09%09%09return h.hash;%0A%09%09%7D else %7B%0A
     
- 
+%09%09
 return 
-h.hash;
+varname.hashCode();%0A%09%09%7D
 %0A   
@@ -2481,25 +2481,52 @@
 ing() %7B%0A    
- 
+%09if (varname==null) %7B%0A    %09%09
 return %22Loca
@@ -2593,16 +2593,88 @@
  + %22)%22;%0A
+    %09%7D else %7B%0A    %09%09return %22LocalLocation(%5C%22%22 + varname + %22%5C%22)%22;%0A    %09%7D%0A
     %7D%0A%7D%0A

Store either the local variable identifier or the byte code range.