MatchMetrics.java
/*
** Module : MemberMetrics.java
** Abstract : container for metrics state related to the usage of a given class member
**
** Copyright (c) 2021-2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- --------------------------------------Description---------------------------------------
** 001 GES 20210408 First version.
** 002 CA 20230928 Refactored the fuzzy method resolution to be used by runtime, too.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.uast;
/**
* Stores metrics state related to the usage of a given class member. This state cannot be stored in the
* member data itself, since it is different at every usage location of the given member.
*/
public class MatchMetrics
implements Comparable<MatchMetrics>
{
/** The member to which the metrics refer. */
MethodData data;
/** Number of exact matches. */
int exact = 0;
/** Number of matches due to widening or narrowing conversion. */
int cvt = 0;
/** Number of exact extent matches (none to none, fixed to fixed, indeterminate to indeterminate). */
int extExact = 0;
/** Number of matches due to fixed extent to indeterminate conversion. */
int extCvt = 0;
/** Number of wildcard matches. */
int wildcard = 0;
/** Number of OO inheritance levels the caller type is from the callee type. */
int[] ooLvl;
/** Type overrides needed due to fuzzy matching. */
String[] overrides;
/**
* Construct an instance which references the given member.
*
* @param data
* The member being referenced.
*/
public MatchMetrics(MethodData data)
{
this.data = data;
this.ooLvl = new int[data.getSignature().length];
this.overrides = new String[data.getSignature().length];
}
/**
* Compares this object with the given other object to calculate a relative ordering between the two
* instances.
*
* @param other
* The other instance. Must NOT be {@code null}.
*
* @return -1, 0 or 1 if this instance is less than, equal to, or greater than the other object.
*
* @throws NullPointerException
* If the parameter is {@code null}.
*/
public int compareTo(MatchMetrics other)
{
int diffExact = exact - other.exact;
int diffCvt = cvt - other.cvt;
int diffExt = extExact - other.extExact;
int diffExtCvt = extCvt - other.extCvt;
if (diffExact == 0 && diffCvt == 0 && diffExt == 0 && diffExtCvt == 0)
{
return compareInheritanceLevels(other);
}
else if (diffExact > 0 ||
(diffExact == 0 && diffCvt > 0) ||
(diffExact == 0 && diffCvt == 0 && diffExt > 0) ||
(diffExact == 0 && diffCvt == 0 && diffExt == 0 && diffExtCvt > 0))
{
return 1;
}
else
{
return -1;
}
}
/**
* Report if the two instances have equivalent state.
*
* @param other
* The other instance to check against.
*
* @return {@code true} if the other instance is non-null, is the same class and the state is equivalent
* as reported by {@link #compareTo}. {@code false} otherwise.
*/
public boolean equals(Object other)
{
if (other == null || !(other instanceof MatchMetrics))
{
return false;
}
return compareTo((MatchMetrics) other) == 0;
}
/**
* Render the state of the instance in a text form.
*
* @return The rendered instance.
*/
public String toString()
{
return String.format("METRICS %d exact; %d cvt; %d extExact; %d extCvt; %d wildcard; " +
"%s ooLvl; %s overrides; \n %s data",
exact,
cvt,
extExact,
extCvt,
wildcard,
ooLvl,
overrides,
data);
}
/**
* Compares this object with the given other object to calculate if one of them matched based on OO
* inheritance and is "closer" in its relationship. The first OO level that is different will
* determine the outcome unless no OO levels are different in which case the instances are equivalent.
*
* @param other
* The other instance. Must NOT be {@code null}.
*
* @return -1, 0 or 1 if this instance is less than (farther than), equal to, or greater than (closer
* than) the other object.
*
* @throws NullPointerException
* If the parameter is {@code null}.
*/
private int compareInheritanceLevels(MatchMetrics other)
{
for (int i = 0; i < ooLvl.length; i++)
{
int diff = ooLvl[i] - other.ooLvl[i];
if (diff > 0)
{
// farther away than other
return -1;
}
else if (diff < 0)
{
// closer than other
return 1;
}
}
// no difference across the entire array
return 0;
}
}