• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.tools.jdi;
27 import com.sun.jdi.*;
28 
29 public class LocalVariableImpl extends MirrorImpl
30                                implements LocalVariable, ValueContainer
31 {
32     private final Method method;
33     private final int slot;
34     private final Location scopeStart;
35     private final Location scopeEnd;
36     private final String name;
37     private final String signature;
38     private String genericSignature = null;
39 
LocalVariableImpl(VirtualMachine vm, Method method, int slot, Location scopeStart, Location scopeEnd, String name, String signature, String genericSignature)40     LocalVariableImpl(VirtualMachine vm, Method method,
41                       int slot, Location scopeStart, Location scopeEnd,
42                       String name, String signature,
43                       String genericSignature) {
44         super(vm);
45         this.method = method;
46         this.slot = slot;
47         this.scopeStart = scopeStart;
48         this.scopeEnd = scopeEnd;
49         this.name = name;
50         this.signature = signature;
51         if (genericSignature != null && genericSignature.length() > 0) {
52             this.genericSignature = genericSignature;
53         } else {
54             // The Spec says to return null for non-generic types
55             this.genericSignature = null;
56         }
57     }
58 
equals(Object obj)59     public boolean equals(Object obj) {
60         if ((obj != null) && (obj instanceof LocalVariableImpl)) {
61             LocalVariableImpl other = (LocalVariableImpl)obj;
62             return ((slot() == other.slot()) &&
63                     (scopeStart != null) &&
64                     (scopeStart.equals(other.scopeStart)) &&
65                     (super.equals(obj)));
66         } else {
67             return false;
68         }
69     }
70 
hashCode()71     public int hashCode() {
72         /*
73          * TO DO: Better hash code
74          */
75         return ((scopeStart.hashCode() << 4) + slot());
76     }
77 
compareTo(LocalVariable object)78     public int compareTo(LocalVariable object) {
79         LocalVariableImpl other = (LocalVariableImpl)object;
80 
81         int rc = scopeStart.compareTo(other.scopeStart);
82         if (rc == 0) {
83             rc = slot() - other.slot();
84         }
85         return rc;
86     }
87 
name()88     public String name() {
89         return name;
90     }
91 
92     /**
93      * @return a text representation of the declared type
94      * of this variable.
95      */
typeName()96     public String typeName() {
97         JNITypeParser parser = new JNITypeParser(signature);
98         return parser.typeName();
99     }
100 
type()101     public Type type() throws ClassNotLoadedException {
102         return findType(signature());
103     }
104 
findType(String signature)105     public Type findType(String signature) throws ClassNotLoadedException {
106         ReferenceTypeImpl enclosing = (ReferenceTypeImpl)method.declaringType();
107         return enclosing.findType(signature);
108     }
109 
signature()110     public String signature() {
111         return signature;
112     }
113 
genericSignature()114     public String genericSignature() {
115         return genericSignature;
116     }
117 
isVisible(StackFrame frame)118     public boolean isVisible(StackFrame frame) {
119         validateMirror(frame);
120         Method frameMethod = frame.location().method();
121 
122         if (!frameMethod.equals(method)) {
123             throw new IllegalArgumentException(
124                        "frame method different than variable's method");
125         }
126 
127         // this is here to cover the possibility that we will
128         // allow LocalVariables for native methods.  If we do
129         // so we will have to re-examinine this.
130         if (frameMethod.isNative()) {
131             return false;
132         }
133 
134         return ((scopeStart.compareTo(frame.location()) <= 0)
135              && (scopeEnd.compareTo(frame.location()) >= 0));
136     }
137 
isArgument()138     public boolean isArgument() {
139         try {
140             MethodImpl method = (MethodImpl)scopeStart.method();
141             return (slot < method.argSlotCount());
142         } catch (AbsentInformationException e) {
143             // If this variable object exists, there shouldn't be absent info
144             throw new InternalException();
145         }
146     }
147 
slot()148     int slot() {
149         return slot;
150     }
151 
152     /*
153      * Compilers/VMs can have byte code ranges for variables of the
154      * same names that overlap. This is because the byte code ranges
155      * aren't necessarily scopes; they may have more to do with the
156      * lifetime of the variable's slot, depending on implementation.
157      *
158      * This method determines whether this variable hides an
159      * identically named variable; ie, their byte code ranges overlap
160      * this one starts after the given one. If it returns true this
161      * variable should be preferred when looking for a single variable
162      * with its name when both variables are visible.
163      */
hides(LocalVariable other)164     boolean hides(LocalVariable other) {
165         LocalVariableImpl otherImpl = (LocalVariableImpl)other;
166         if (!method.equals(otherImpl.method) ||
167             !name.equals(otherImpl.name)) {
168             return false;
169         } else {
170             return (scopeStart.compareTo(otherImpl.scopeStart) > 0);
171         }
172     }
173 
toString()174     public String toString() {
175        return name() + " in " + method.toString() +
176               "@" + scopeStart.toString();
177     }
178 }
179