Parent: [c04411] (diff)

Child: [7626e3] (diff)

Download this file

PHPMetrics.rsc    147 lines (119 with data), 4.2 kB

module PHPMetrics

extend lang::php::m3::Core;
import lang::php::m3::Uses;
import lang::php::stats::Stats;
import PHP;

@metric{StaticNameResolutionHistogram}
@doc{Histogram counting type names that could be resolved to a certain number of declarations}
@friendlyName{StaticNameResolutionHistogram}
@appliesTo{php()}
map[int, int] getNameResolutionHistogram(rel[Language, loc, M3] m3s = ())
{
	models = { m | <php(), _, m> <- m3s };

	m3 = composeM3s(|project:///|, models);

	m3@uses = { <l, n> | <l, n> <- m3@uses, n.scheme in ["php+class", "php+interface", "php+trait"] };

	m3 = addPredefinedDeclarations(m3);

	useDecl = resolveUsesToPossibleDeclarations(propagateAliasesInUses(m3));
	
	return countNumPossibleDeclarations(useDecl);
}


private set[str] varClassMetrics = {
						"class consts with variable class name",
						"object creation with variable class name",
						"calls of static methods with variable targets",
						"fetches of static properties with variable targets"};
		
private	set[str] varVarMetrics = {
						"assignments into variable-variables",
						"assignments w/ops into variable-variables",
						"list assignments into variable-variables",
						"ref assignments into variable-variables",
						"fetches of properties with variable names"};
						//"uses of variable-variables (including the above)",

private	set[str] varFuncMetrics = {
						"calls of variable function names",
						"calls of variable method names",
						"calls of static methods with variable names",
						"fetches of static properties with variable names"};

private set[str] varArgsMetrics = {"var-args support functions"};

private set[str] varIncludeMetrics = {"includes with non-literal paths"};

private set[str] overloadMetrics = {
						"definitions of overloads: set",
						"definitions of overloads: get",
						"definitions of overloads: isset",
						"definitions of overloads: unset",
						"definitions of overloads: call",
						"definitions of overloads: callStatic"};

private set[str] varLabelMetrics = {
						"break with non-literal argument",
						"continue with non-literal argument"};	

@memo
private map[str, int] getCounts(System sys) = featureCounts(sys);

private int sumMetrics(rel[Language, loc, AST] asts, set[str] metricNames)
{
	System sys = ( ast.file : ast.script  | <php(), _, ast> <- asts );

	counts = getCounts(sys);

	return sum([counts[n] | n <- metricNames]);
}

@metric{numVarVar}
@doc{number of variable variable references}
@friendlyName{numVarVar}
@appliesTo{php()}
public int getNumberOfVarVarUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, varVarMetrics);
}

@metric{numVarClass}
@doc{number of variable class references}
@friendlyName{numVarClass}
@appliesTo{php()}
public int getNumberOfVarClassUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, varClassMetrics);
}

@metric{numVarFunc}
@doc{number of variable accesses to functions or methods}
@friendlyName{numVarFunc}
@appliesTo{php()}
public int getNumberOfVarFuncUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, varFuncMetrics);
}

@metric{numVarArgs}
@doc{number of var args methods}
@friendlyName{numVarArgs}
@appliesTo{php()}
public int getNumberOfVarArgsUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, varArgsMetrics);
}

@metric{numVarIncludes}
@doc{number of variable includes}
@friendlyName{numVarIncludes}
@appliesTo{php()}
public int getNumberOfVarIncludeUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, varIncludeMetrics);
}

@metric{numOverloads}
@doc{number of overload uses}
@friendlyName{numVarOverloads}
@appliesTo{php()}
public int getNumberOfOverloadUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, overloadMetrics);
}

@metric{numVarLabels}
@doc{number of variable label references}
@friendlyName{numVarLabels}
@appliesTo{php()}
public int getNumberOfVarLabelUses(rel[Language, loc, AST] asts = ())
{
	 return sumMetrics(asts, varLabelMetrics);
}

@metric{numEvals}
@doc{number of calls to eval}
@friendlyName{numEvals}
@appliesTo{php()}
public int getNumberOfEvalCalls(rel[Language, loc, AST] asts = ())
{
	return (0 | it + 1 | /call(name(name(/eval/i)), _) <- asts);
}