Пример #1
0
  /**
   * Méthode appelée pour le calcul de la cohésion entre 2 fonctions.
   *
   * <p>Calcule le pourcentage de paramètres similaires entre les deux fonctions sur l'ensemble des
   * paramètres des deux fonctions.
   *
   * @param f1 Une fonction d'un modèle de code source
   * @param f2 Une autre fonction d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   * @see #cohesion(Function, Function)
   */
  private double cohesionArguments(Function f1, Function f2) {
    double result = 0.0;
    double nbCommon = 0;

    Set<LocalVariable> argsFct1 = f1.getArguments();
    Set<LocalVariable> argsFct2 = f2.getArguments();
    Set<LocalVariable> args = new HashSet<LocalVariable>();

    for (LocalVariable arg1 : argsFct1) {
      for (LocalVariable arg2 : argsFct2) {
        if (arg1.getType().equals(arg2.getType())) {
          if (similarity.similar(arg1.getName(), arg2.getName())) {
            ++nbCommon;
          }
        }

        args.add(arg1);
        args.add(arg2);
      }
    }

    if (args.size() > 0) {
      result = 100.0 * nbCommon / args.size();
    }

    return result;
  }
Пример #2
0
  /**
   * Méthode appelée pour le calcul de la cohésion entre 2 fonctions.
   *
   * <p>Calcule le pourcentage de types utilisés en commun dans les deux fonctions sur le nombre
   * total de types utilisés dans les deux fonctions.
   *
   * @param f1 Une fonction d'un modèle de code source
   * @param f2 Une autre fonction d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   * @see #cohesion(Function, Function)
   */
  private double cohesionTypes(Function f1, Function f2) {
    double result = 0.0;

    Map<ComplexType, Integer> usedTypesFct1 = f1.getTotalComplexTypes();
    Map<ComplexType, Integer> usedTypesFct2 = f2.getTotalComplexTypes();

    Set<ComplexType> usedTypesTotal = new HashSet<ComplexType>();
    Set<ComplexType> usedTypesCommon = new HashSet<ComplexType>();

    for (ComplexType t : usedTypesFct1.keySet()) {
      if (t.equals(PrimitiveType.voidType) == false
          && t.equals(ComplexType.anonymousType) == false) {
        usedTypesTotal.add(t);
      }
    }

    for (ComplexType t : usedTypesFct2.keySet()) {
      if (t.equals(PrimitiveType.voidType) == false
          && t.equals(ComplexType.anonymousType) == false) {
        boolean newType = usedTypesTotal.add(t);

        if (newType == false) {
          usedTypesCommon.add(t);
        }
      }
    }

    if (usedTypesTotal.size() > 0) {
      result = (100.0 * usedTypesCommon.size()) / usedTypesTotal.size();
    }

    return result;
  }
Пример #3
0
  /**
   * Méthode appelée pour le calcul de la cohésion entre 2 fonctions.
   *
   * <p>Calcule le pourcentage d'appels de fonction communs dans les deux fonctions sur le nombre
   * total d'appels dans les deux fonctions. Les paramètres des appels ne sont pas pris en compte.
   *
   * @param f1 Une fonction d'un modèle de code source
   * @param f2 Une autre fonction d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   * @see #cohesion(Function, Function)
   */
  private double cohesionCalls(Function f1, Function f2) {
    double result = 0.0;

    Set<Call> calls1 = f1.getTotalCalls();
    Set<Call> calls2 = f2.getTotalCalls();

    Set<Function> fctCalledTotal = new HashSet<Function>();
    Set<Function> fctCalledCommon = new HashSet<Function>();

    for (Call call : calls1) {
      fctCalledTotal.add(call.getFunction());
    }

    for (Call call : calls2) {
      boolean added = false;

      added = fctCalledTotal.add(call.getFunction());

      if (added == false) {
        fctCalledCommon.add(call.getFunction());
      }
    }

    if (fctCalledTotal.size() > 0) {
      result = (100.0 * fctCalledCommon.size()) / fctCalledTotal.size();
    }

    return result;
  }
Пример #4
0
  /**
   * Méthode appelée pour le calcul de la cohésion entre 2 fonctions.
   *
   * <p>Calcule le pourcentage de variables locales similaires entre les deux fonctions sur le
   * nombre total de variables locales utilisées dans les deux fonctions.
   *
   * @param f1 Une fonction d'un modèle de code source
   * @param f2 Une autre fonction d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   * @see #cohesion(Function, Function)
   */
  private double cohesionLocalVars(Function f1, Function f2) {
    double result = 0.0;
    double nbCommon = 0;

    Map<LocalVariable, Integer> localVars1 = f1.getLocalVariables();
    Map<LocalVariable, Integer> localVars2 = f2.getLocalVariables();

    for (LocalVariable var1 : localVars1.keySet()) {
      for (LocalVariable var2 : localVars2.keySet()) {
        if (var1.getName().length() >= VARNAME_MIN_LEN
            && var2.getName().length() >= VARNAME_MIN_LEN) {
          if (var1.getType().equals(var2.getType())) {
            if (similarity.similar(var1.getName(), var2.getName())) {
              ++nbCommon;
            }
          }
        }
      }
    }

    double nbPairs = localVars1.size() * localVars2.size();

    if (nbPairs > 0) {
      result = 100.0 * nbCommon / nbPairs;
    }

    return result;
  }
Пример #5
0
  /**
   * Méthode appelée pour le calcul de la cohésion entre 2 fonctions.
   *
   * <p>Calcule le pourcentage de variables globales au programme accédées en commun sur le nombre
   * total de variables globales au programme accédées dans les deux fonctions.
   *
   * @param f1 Une fonction d'un modèle de code source
   * @param f2 Une autre fonction d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   * @see #cohesion(Function, Function)
   */
  private double cohesionGlobalVars(Function f1, Function f2) {
    double result = 0.0;

    Map<GlobalVariable, Integer> globalVars1 = f1.getCoreGlobalVariables();
    Map<GlobalVariable, Integer> globalVars2 = f2.getCoreGlobalVariables();

    Set<GlobalVariable> globalVarsTotal = new HashSet<GlobalVariable>();
    Set<GlobalVariable> globalVarsCommon = new HashSet<GlobalVariable>();

    for (GlobalVariable var : globalVars1.keySet()) {
      globalVarsTotal.add(var);
    }

    for (GlobalVariable var : globalVars2.keySet()) {
      boolean newVar = globalVarsTotal.add(var);

      if (newVar == false) {
        globalVarsCommon.add(var);
      }
    }

    if (globalVarsTotal.size() > 0) {
      result = (100.0 * globalVarsCommon.size()) / globalVarsTotal.size();
    }

    return result;
  }
Пример #6
0
  /**
   * Évalue la cohésion entre une fonction et un type.
   *
   * <p>La cohésion entre une fonction <em>f</em> et un type <em>t</em> est égal au pourcentage
   * d'utilisations de <em>t</em> par <em>f</em> sur le nombre total d'utilisations de l'ensemble
   * des types utilisés par <em>f</em>.
   *
   * @param fct Une fonction d'un modèle de code source
   * @param type Un type d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   */
  private double cohesion(final Function fct, ComplexType type) {
    double result = 0.0;
    double nbUsesOfType = 0.0;
    double total = 0.0; // Total uses of types

    Map<ComplexType, Integer> usedTypes = fct.getTotalComplexTypes();

    for (ComplexType t : usedTypes.keySet()) {
      if (t.equals(type)) {
        nbUsesOfType += usedTypes.get(t);
      }

      total += usedTypes.get(t);
    }

    // Same file ?
    if (fct.getSourceFile() != null && type.getSourceFile() != null) {
      if (fct.getSourceFile().equals(type.getSourceFile())) {
        nbUsesOfType *= BONUS_SAME_FILE;
      }
    }

    if (total > 0) {
      result = 100.0 * nbUsesOfType / total;
    }

    return result;
  }
Пример #7
0
  /**
   * Évalue la cohésion entre une fonction et une variable globale.
   *
   * <p>La cohésion entre une fonction f et une variable globale au programme (resp. au fichier) v
   * est égale au pourcentage d'accès à v sur le nombre total d'accès à des variables globales.
   *
   * @param fct Une fonction d'un modèle de code source
   * @param var Une variable d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   */
  private double cohesion(final Function fct, GlobalVariable var) {
    double result = 0.0;
    double total = 0.0; // Total accesses
    double nbAccessToVar = 0.0;

    Map<GlobalVariable, Integer> fctVars = fct.getCoreGlobalVariables();

    for (Integer n : fctVars.values()) {
      total += n;
    }

    if (fctVars.containsKey(var)) {
      nbAccessToVar = fctVars.get(var);

      // Same file ?
      if (fct.getSourceFile() != null && var.getSourceFile() != null) {
        if (fct.getSourceFile().equals(var.getSourceFile())) {
          nbAccessToVar *= BONUS_SAME_FILE;
        }
      }
    }

    if (total > 0) {
      result = 100.0 * nbAccessToVar / total;
    }

    return result;
  }
Пример #8
0
  /**
   * Évalue la cohésion de 2 fonctions.
   *
   * <p>La cohésion de 2 fonctions est évaluée sur la moyenne des pourcentages :
   *
   * <ul>
   *   <li>de variables globales communes
   *   <li>de variables locales communes
   *   <li>de types communs
   *   <li>d'appels de fonction communs
   * </ul>
   *
   * et sur l'appartenance à un même fichier.
   *
   * @param f1 Une fonction d'un modèle de code source
   * @param f2 Une autre fonction d'un modèle de code source
   * @return Un double entre 0.0 et 100.0
   */
  private double cohesion(final Function f1, final Function f2) {
    double result = 0.0;

    double cc = this.cohesionCalls(f1, f2);
    double cg = this.cohesionGlobalVars(f1, f2);
    double cl = this.cohesionLocalVars(f1, f2);
    double ct = this.cohesionTypes(f1, f2);
    double ca = this.cohesionArguments(f1, f2);

    result += WEIGHT_FCT_COHESION_CALLS * cc;
    result += WEIGHT_FCT_COHESION_GLOBALS * cg;
    result += WEIGHT_FCT_COHESION_LOCALS * cl;
    result += WEIGHT_FCT_COHESION_TYPES * ct;
    result += WEIGHT_FCT_COHESION_ARGS * ca;

    if (f1.getSourceFile() != null && f2.getSourceFile() != null) {
      if (f1.getSourceFile().equals(f2.getSourceFile())) {
        result *= BONUS_SAME_FILE;
      }
    }

    result /=
        WEIGHT_FCT_COHESION_CALLS
            + WEIGHT_FCT_COHESION_GLOBALS
            + WEIGHT_FCT_COHESION_LOCALS
            + WEIGHT_FCT_COHESION_TYPES
            + WEIGHT_FCT_COHESION_ARGS;

    result = (result > 100.0) ? 100.0 : result;

    // System.out.println(f1.getName() + " - " + f2.getName() + " : "
    // + "CC=" + cc + " CG=" + cg + " CL=" + cl + " CT=" + ct
    // + " CA=" + ca + " -- " + result); // DBG

    return result;
  }