proguard.analysis.datastructure.CodeLocation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proguard-core Show documentation
Show all versions of proguard-core Show documentation
ProGuardCORE is a free library to read, analyze, modify, and write Java class files.
/*
* ProGuardCORE -- library to process Java bytecode.
*
* Copyright (c) 2002-2021 Guardsquare NV
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package proguard.analysis.datastructure;
import static proguard.classfile.util.ClassUtil.externalClassName;
import java.util.Objects;
import proguard.classfile.Clazz;
import proguard.classfile.Member;
import proguard.classfile.Signature;
/**
* Represents a unique location in the bytecode. It comprises the {@link Clazz} and {@link Member}
* where it is contained, the offset therein and the corresponding line number in the source file
* ({@link Location#UNKNOWN_LINE} if it is unknown). Consider the following pseudo-bytecode example
* which contains code location comments:
*
* {@code
* public class Test
* {
* // class "Test", member "field", line 3, offset 0
* public String field;
*
* public String toString()
* {
* // class "Test", member "toString", line 6, offset 0
* aload_0
* // class "Test", member "toString", line 6, offset 1
* getfield #1 <Test.field : Ljava/lang/String;>
* // class "Test", member "toString", line 6, offset 4
* areturn
* }
* }
*
* }
*
*
* - Inside methods: Like each location, instructions inside methods have a line number.
* But as there may be several expressions on the same line, to correctly identify each
* instruction we also need their bytecode offset. E.g. the {@code getfield} instruction
* inside {@code toString()} has the offset 1.
*
- Fields: In this case {@code Test#field}. A field location has a line number (3 in
* this example) but no offset, as this concept is only applicable to methods.
*
*/
public class CodeLocation extends Location {
public final Clazz clazz;
public final Member member;
public final int offset;
public final Signature signature;
/** Create a code location with an unknown ({@link Location#UNKNOWN_LINE}) line number. */
public CodeLocation(Clazz clazz, Member member, int offset) {
this(clazz, member, offset, UNKNOWN_LINE);
}
public CodeLocation(Clazz clazz, Member member, int offset, int line) {
super(line);
this.clazz = clazz;
this.member = member;
this.offset = offset;
this.signature = Signature.of(clazz, member);
}
public String getExternalClassName() {
return externalClassName(clazz.getName());
}
public String getMemberName() {
return member == null ? null : member.getName(clazz);
}
@Override
public String getName() {
return signature.getFqn();
}
@Override
public String toString() {
return signature + "+" + String.format("%04d", offset) + " (line " + line + ")";
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CodeLocation)) {
return false;
}
CodeLocation codeLocation = (CodeLocation) o;
return Objects.equals(signature, codeLocation.signature) && offset == codeLocation.offset;
}
@Override
public int hashCode() {
return Objects.hash(signature, offset);
}
@Override
public int compareTo(Location o) {
if (!o.getClass().equals(getClass())) {
return -1;
}
CodeLocation other = (CodeLocation) o;
// Locations are ordered first by member name (lexicographically
// increasing), then increasing line number and lastly increasing offset
if (signature.equals(other.signature)) {
if (line == other.line) {
return offset - other.offset;
}
return line - other.line;
}
return signature.compareTo(other.signature);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy