Commit 890a1bef authored by Sergio Pérez's avatar Sergio Pérez
Browse files

* Node.Type.AnonymousRoutine added

* Anonymous functions considered (fun(X) -> ... end)
* Shadowing in Anonymous Functions and LCs improved
parent 40b40855
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -35,14 +35,16 @@ public class LASTBuilder {
	}

	// Add expression
	public static int addRoutine(LAST last, int parentId, Where where, String name, LDASTNodeInfo info)
	public static int addRoutine(LAST last, int parentId, Where where, String name, boolean anonymous,LDASTNodeInfo info)
	{
		final Node parent = LASTBuilder.getParentNode(last, parentId, where);
		final String routineName = name == null ? "routine" : "routine" + "\\n" + name;
		final Node routine;
		final LDASTNodeInfo expInfo = new LDASTNodeInfo(info, true);

		routine = LASTBuilder.addNode(last, parent, Node.Type.Routine, name, routineName, expInfo);
		Node.Type routineType = anonymous ? Node.Type.AnonymousRoutine : Node.Type.Routine;

		routine = LASTBuilder.addNode(last, parent, routineType, name, routineName, expInfo);

		return routine.getId();
	}
@@ -50,7 +52,7 @@ public class LASTBuilder {
	{
		final Node parent = last.getNode(functionId);
		final Node.Type parentType = parent.getType();
		if (parentType != Node.Type.Routine)
		if (parentType != Node.Type.Routine && parentType != Node.Type.AnonymousRoutine)
			throw new RuntimeException("A " + parentType + " cannot contain a clause");

		final LDASTNodeInfo expInfo = new LDASTNodeInfo(info, true);
+13 −6
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@ public abstract class LASTFactory
{
	private LAST last;
	private final Stack<Branch> branches = new Stack<Branch>();
	final protected Map<String,Integer> currentLabels = new HashMap<String,Integer>();
	final protected Map<String,List<Integer>> unresolvedLabels = new HashMap<String,List<Integer>>();
	final protected Map<String,Integer> currentLabels = new HashMap<>();
	final protected Map<String,List<Integer>> unresolvedLabels = new HashMap<>();
	
	private <R> void processElements(R[] elements)
	{	
@@ -84,16 +84,23 @@ public abstract class LASTFactory
	protected <R> void addRoutine(String name, Iterable<R> clauses, LDASTNodeInfo info)
	{
		final R[] clauses0 = this.getArray(clauses);
		this.addRoutine(name, clauses0, info);
		this.addRoutine(name, clauses0, false, info);
	}
	protected <R> void addRoutine(String name, R[] clauses, LDASTNodeInfo info)
	protected <R> void addRoutine(String name, Iterable<R> clauses, boolean anonymous, LDASTNodeInfo info)
	{
		final R[] clauses0 = this.getArray(clauses);
		this.addRoutine(name, clauses0, anonymous, info);
	}
	protected <R> void addRoutine(String name, R[] clauses, boolean anonymous, LDASTNodeInfo info)
	{
		final Branch parent = this.branches.peek();
		final int parentId = parent.getNodeId();
		final Where where = parent.getWhere();
		final int routineId = LASTBuilder.addRoutine(this.last, parentId, where, name, info);
		final int routineId = LASTBuilder.addRoutine(this.last, parentId, where, name, anonymous, info);

		Node.Type routineType = anonymous ? Node.Type.AnonymousRoutine : Node.Type.Routine;

		this.branches.push(new Branch(routineId, Node.Type.Routine, info));
		this.branches.push(new Branch(routineId, routineType, info));
		this.processElements(clauses);
		this.branches.pop();
	}
+5 −5
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ public abstract class EdgeGenerator {
				break;
			case List:
			case DataConstructor:
				final List<Node> children = edg.getChildren(pattern);
				final List<Node> children = edg.getChildrenNonResult(pattern);
				implicitRestrictions.add(pattern);
				for (Node child : children)
					implicitRestrictions.addAll(this.getImplicitRestrictions(child));
@@ -111,8 +111,8 @@ public abstract class EdgeGenerator {
		}
		else if ((patternType == Node.Type.DataConstructor || patternType == Node.Type.List) && expressionType == patternType)
		{
			final List<Node> patternNodeChildren = edg.getChildren(pattern);
			final List<Node> expressionNodeChildren = edg.getChildren(expression);
			final List<Node> patternNodeChildren = edg.getChildrenNonResult(pattern);
			final List<Node> expressionNodeChildren = edg.getChildrenNonResult(expression);

			if (patternNodeChildren.size() == expressionNodeChildren.size())
			{
@@ -179,8 +179,8 @@ public abstract class EdgeGenerator {
					patternMatch.isCompleteMatch() && valueMatch.isCompleteMatch());
		} else if ((parameterType == Node.Type.DataConstructor || // Parameter = Tuple ({X,Y}) || List ([X,Y])
				parameterType == Node.Type.List) && argumentType == parameterType) { // Argument = Same as pattern
			final List<Node> parameterChildren = edg.getChildren(parameter);
			final List<Node> argumentChildren = edg.getChildren(argument);
			final List<Node> parameterChildren = edg.getChildrenNonResult(parameter);
			final List<Node> argumentChildren = edg.getChildrenNonResult(argument);

			if (parameterChildren.size() == argumentChildren.size())
			{
+8 −7
Original line number Diff line number Diff line
@@ -360,8 +360,7 @@ public class InterproceduralEdgeGenerator extends EdgeGenerator
		final Node nameNode = edg.getChild(callee, Node.Type.Name);
		final Node scopeValue = edg.getChild(scopeNode, Node.Type.Value);
		final Node routineArguments = edg.getChild(call, Node.Type.Arguments);
		final List<Node> arguments = edg.getChildren(routineArguments);
		arguments.removeIf(n -> n.getType() == Node.Type.Result);
		final List<Node> arguments = edg.getChildrenNonResult(routineArguments);

		// Module
		final Node moduleRef = scopeValue == null ? edg.getAncestor(call, Node.Type.Module) : scopeValue;
@@ -414,8 +413,8 @@ public class InterproceduralEdgeGenerator extends EdgeGenerator
			}

			final Node clauseParameters = edg.getChild(clause, Node.Type.Parameters);
			final List<Node> parameters = edg.getChildren(clauseParameters);
			parameters.removeIf(n -> n.getType() == Node.Type.Result);
			final List<Node> parameters = edg.getChildrenNonResult(clauseParameters);


			if (arguments.size() != parameters.size())
				continue;
@@ -428,15 +427,17 @@ public class InterproceduralEdgeGenerator extends EdgeGenerator
	private List<Node> getMatchingClausesErlang(List<Node> possibleClauses, Node call)
	{
		final List<Node> matchingClauses = new LinkedList<>();

		final Set<Node> ignoredRoutines = new HashSet<>();
		for (Node possibleClause : possibleClauses) {
			final Node routineNode = edg.getParent(possibleClause);
			if (ignoredRoutines.contains(routineNode))
				continue;
			MatchStatus matchingClause = this.matchClauseErlang(possibleClause, call);
			if (matchingClause.isMatch())
				matchingClauses.add(possibleClause);
			if (matchingClause.isCompleteMatch())
				return matchingClauses;
				ignoredRoutines.add(routineNode);
		}

		return matchingClauses;
	}
	private MatchStatus matchClauseErlang(Node possibleClause, Node call)
+4 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ public class Node implements Visitable {
		Module,

		// Routine
		Routine, Clause, Parameters(true),
		Routine, AnonymousRoutine, Clause, Parameters(true),

		// Expressions
		List, DataConstructor, DataConstructorAccess, FieldAccess,
@@ -240,6 +240,9 @@ public class Node implements Visitable {
			case Routine:
				visitor.visitRoutine(this, argument);
				break;
			case AnonymousRoutine:
				visitor.visitAnonymousRoutine(this, argument);
				break;
			case Clause:
				visitor.visitClause(this, argument);
				break;
Loading