package sizzle.functions;

import sizzle.types.Ast.*;

/**
 * Boa domain-specific functions for computing software engineering metrics.
 * 
 * @author rdyer
 */
public class BoaMetricIntrinsics {
	////////////////////////////////
	// Number of Attributes (NOA) //
	////////////////////////////////

	private static class BoaNOAVisitor extends BoaCountingVisitor {
		@Override
		public boolean preVisit(final Declaration node) {
			if (node.getKind() == TypeKind.CLASS)
				count += node.getFieldsCount();
			return true;
		}
	}
	private static BoaNOAVisitor noaVisitor = new BoaNOAVisitor();

	/**
	 * Computes the Number of Attributes (NOA) metric for a node.
	 * 
	 * @param node the node to compute NOA for
	 * @return the NOA value for decl
	 */
	@FunctionSpec(name = "get_metric_noa", returnType = "int", formalParameters = { "Declaration" })
	public static long getMetricNOA(final Declaration node) {
		noaVisitor.initialize().visit(node);
		return noaVisitor.count;
	}

	////////////////////////////////
	// Number of Operations (NOO) //
	////////////////////////////////

	private static class BoaNOOVisitor extends BoaCountingVisitor {
		@Override
		public boolean preVisit(final Declaration node) {
			if (node.getKind() == TypeKind.CLASS)
				count += node.getMethodsCount();
    		return true;
		}
	}
	private static BoaNOOVisitor nooVisitor = new BoaNOOVisitor();

	/**
	 * Computes the Number of Operations (NOO) metric for a node.
	 * 
	 * @param node the node to compute NOO for
	 * @return the NOO value for decl
	 */
	@FunctionSpec(name = "get_metric_noo", returnType = "int", formalParameters = { "Declaration" })
	public static long getMetricNOO(final Declaration node) {
		nooVisitor.initialize().visit(node);
		return nooVisitor.count;
	}

	////////////////////////////////////
	// Number of Public Methods (NPM) //
	////////////////////////////////////

	private static class BoaNPMVisitor extends BoaCountingVisitor {
		@Override
		public boolean preVisit(final Method node) {
    		if (BoaModifierIntrinsics.hasModifierPublic(node))
    			count++;
    		return true;
		}
	}
	private static BoaNPMVisitor npmVisitor = new BoaNPMVisitor();

	/**
	 * Computes the Number of Public Methods (NPM) metric for a node.
	 * 
	 * @param node the node to compute NPM for
	 * @return the NPM value for decl
	 */
	@FunctionSpec(name = "get_metric_npm", returnType = "int", formalParameters = { "Declaration" })
	public static long getMetricNPM(final Declaration node) {
		npmVisitor.initialize().visit(node);
		return npmVisitor.count;
	}
}

@@ -20,16 +20,43 @@
 tions;%0A%0A
+import java.util.HashMap;%0A%0A
 import s
@@ -2571,11 +2571,1153 @@
 ount;%0A%09%7D
+%0A%0A%09////////////////////////////////%0A%09// Number of Children (NOC) //%0A%09////////////////////////////////%0A%0A%09private static class BoaNOCVisitor extends BoaCollectingVisitor%3CString,Long%3E %7B%0A%09%09private String ns;%0A%09%09@Override%0A%09%09protected boolean preVisit(Namespace node) %7B%0A%09%09%09this.ns = node.getName();%0A%09%09%09return super.preVisit(node);%0A%09%09%7D%0A%09%09@Override%0A%09%09protected boolean preVisit(Declaration node) %7B%0A%09%09%09for (final Type t : node.getParentsList()) %7B%0A%09%09%09%09final String key = ns + %22.%22 + t.getName();%0A%09%09%09%09final long val = map.containsKey(key) ? map.get(key) : 0;%0A%09%09%09%09map.put(key, val + 1);%0A%09%09%09%7D%0A%09%09%09return super.preVisit(node);%0A%09%09%7D%0A%09%7D%0A%09private static BoaNOCVisitor nocVisitor = new BoaNOCVisitor();%0A%0A%09/**%0A%09 * (Partially) Computes the Number of Children (NOC) metric.%0A%09 * %0A%09 * @param node the node to compute NOC for%0A%09 * @return a map containing partial computation of the NOC metric%0A%09 */%0A%09@FunctionSpec(name = %22get_metric_noc%22, returnType = %22map%5Bstring%5D of int%22, formalParameters = %7B %22ASTRoot%22 %7D)%0A%09public static HashMap%3CString,Long%3E getMetricNOC(final ASTRoot node) %7B%0A%09%09nocVisitor.initialize(new HashMap%3CString,Long%3E()).visit(node);%0A%09%09return nocVisitor.map;%0A%09%7D
 %0A%7D%0A

add number of children (NOC) visitor