protected override List <AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged) { hasChanged = false; var parent = expression as IParentNode; if (IsStatement && expression.Type == AphidExpressionType.BinaryOperatorExpression && expression.ToBinaryOperator().LeftOperand.Type == AphidExpressionType.IdentifierExpression && expression.ToBinaryOperator().RightOperand.Type == AphidExpressionType.FunctionExpression) { _rootFunctions.Add(expression.ToBinaryOperator().RightOperand.ToFunction()); return(null); } else if (expression.Type == AphidExpressionType.FunctionExpression && !_rootFunctions.Contains(expression.ToFunction())) { var parents = AphidTreeHelper.FirstOrDefaultPath(_ast, x => x == expression); if (parents.Length >= 3 && parents.Skip(1).First().Type == AphidExpressionType.BinaryOperatorExpression && parents.Skip(2).First().Type == AphidExpressionType.ObjectExpression) { return(null); } var eligible = GetEligibleMethodContainer(parents, out var after); if (eligible != null) { var id = QueueInsertion(expression.ToFunction(), eligible, after); hasChanged = true; return(new List <AphidExpression> { id }); } else { throw new NotImplementedException(); } } else { return(null); } }
protected override void EndRecursiveMutationPass(List <AphidExpression> ast) { foreach (var nvp in _insertions) { var decl = new BinaryOperatorExpression( new IdentifierExpression(nvp.Key), AphidTokenType.AssignmentOperator, nvp.Value); var label = AphidTreeHelper.FirstOrDefaultPath( ast, x => x?.Type == AphidExpressionType.IdentifierExpression && x.ToIdentifier().Identifier == nvp.Key); var parent = GetEligibleMethodContainer(label, out var before); List <AphidExpression> body; if (parent != null) { switch (parent.Type) { case AphidExpressionType.FunctionExpression: body = parent.ToFunction().Body; break; default: throw new NotImplementedException(); } body.Insert(body.IndexOf(before), decl); } else { ast.Insert(0, decl); } } _insertions.Clear(); }