/*
* Copyright 2010 Henry Coles
*
* 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 org.pitest.mutationtest.engine;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.pitest.classinfo.ClassName;
/**
* Uniquely identifies a mutation
*/
public final class MutationIdentifier implements Comparable<MutationIdentifier> {
/**
* The location at which the mutation occurs
*/
private final Location location;
/**
* The indexes to the instructions within the method at which the mutation
* occurs.
*
* Usually this will be a single instruction, but may be multiple if the
* mutation has been inlined by the compiler to implement a finally block
*/
private final List<Integer> indexes;
/**
* Name of the mutation operator that created this mutation
*/
private final String mutator;
public MutationIdentifier(final Location location, final int index,
final String mutatorUniqueId) {
this(location, Collections.singleton(index), mutatorUniqueId);
}
public MutationIdentifier(final Location location,
final Collection<Integer> indexes, final String mutatorUniqueId) {
this.location = location;
this.indexes = new ArrayList<Integer>(indexes);
this.mutator = mutatorUniqueId;
}
/**
* Returns the location of the mutations
*
* @return the location of the mutation
*/
public Location getLocation() {
return this.location;
}
/**
* Returns the name of the mutator that created this mutation
*
* @return the mutator name
*/
public String getMutator() {
return this.mutator;
}
/**
* Returns the index to the first instruction on which this mutation occurs.
* This index is specific to how ASM represents the bytecode.
*
* @return the zero based index to the instruction
*/
public int getFirstIndex() {
return this.indexes.iterator().next();
}
@Override
public String toString() {
return "MutationIdentifier [location=" + this.location + ", indexes="
+ this.indexes + ", mutator=" + this.mutator + "]";
}
/**
* Returns true if this mutation has a matching identifier
*
* @param id
* the MutationIdentifier to match
* @return true if the MutationIdentifier matches otherwise false
*/
public boolean matches(final MutationIdentifier id) {
return this.location.equals(id.location) && this.mutator.equals(id.mutator)
&& this.indexes.contains(id.getFirstIndex());
}
/**
* Returns the class in which this mutation is located
*
* @return class in which mutation is located
*/
public ClassName getClassName() {
return this.location.getClassName();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result)
+ ((this.indexes == null) ? 0 : this.indexes.hashCode());
result = (prime * result)
+ ((this.location == null) ? 0 : this.location.hashCode());
result = (prime * result)
+ ((this.mutator == null) ? 0 : this.mutator.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MutationIdentifier other = (MutationIdentifier) obj;
if (this.indexes == null) {
if (other.indexes != null) {
return false;
}
} else if (!this.indexes.equals(other.indexes)) {
return false;
}
if (this.location == null) {
if (other.location != null) {
return false;
}
} else if (!this.location.equals(other.location)) {
return false;
}
if (this.mutator == null) {
if (other.mutator != null) {
return false;
}
} else if (!this.mutator.equals(other.mutator)) {
return false;
}
return true;
}
@Override
public int compareTo(final MutationIdentifier other) {
int comp = this.location.compareTo(other.getLocation());
if (comp != 0) {
return comp;
}
comp = this.mutator.compareTo(other.getMutator());
if (comp != 0) {
return comp;
}
return this.indexes.get(0).compareTo(other.indexes.get(0));
}
}