
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 * https://github.com/D-Programming-Language/dmd/blob/master/src/delegatize.c
 */

#include "root/dsystem.h"

#include "mars.h"
#include "expression.h"
#include "statement.h"
#include "mtype.h"
#include "utf.h"
#include "declaration.h"
#include "aggregate.h"
#include "scope.h"
#include "init.h"
#include "tokens.h"


bool walkPostorder(Expression *e, StoppableVisitor *v);
void lambdaSetParent(Expression *e, Scope *sc);
bool lambdaCheckForNestedRef(Expression *e, Scope *sc);
Expression *semantic(Expression *e, Scope *sc);

/********************************************
 * Convert from expression to delegate that returns the expression,
 * i.e. convert:
 *      expr
 * to:
 *      typeof(expr) delegate() { return expr; }
 */
Expression *toDelegate(Expression *e, Type* t, Scope *sc)
{
    //printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), e->toChars());
    Loc loc = e->loc;

    TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
    if (t->hasWild())
        tf->mod = MODwild;
    FuncLiteralDeclaration *fld =
        new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);

    sc = sc->push();
    sc->parent = fld;           // set current function to be the delegate
    lambdaSetParent(e, sc);
    bool r = lambdaCheckForNestedRef(e, sc);
    sc = sc->pop();

    if (r)
        return new ErrorExp();

    Statement *s;
    if (t->ty == Tvoid)
        s = new ExpStatement(loc, e);
    else
        s = new ReturnStatement(loc, e);
    fld->fbody = s;

    e = new FuncExp(loc, fld);
    e = semantic(e, sc);
    return e;
}

/******************************************
 * Patch the parent of declarations to be the new function literal.
 */
void lambdaSetParent(Expression *e, Scope *sc)
{
    class LambdaSetParent : public StoppableVisitor
    {
        Scope *sc;
    public:
        LambdaSetParent(Scope *sc) : sc(sc) {}

        void visit(Expression *)
        {
        }

        void visit(DeclarationExp *e)
        {
            e->declaration->parent = sc->parent;
        }

        void visit(IndexExp *e)
        {
            if (e->lengthVar)
            {
                //printf("lengthVar\n");
                e->lengthVar->parent = sc->parent;
            }
        }

        void visit(SliceExp *e)
        {
            if (e->lengthVar)
            {
                //printf("lengthVar\n");
                e->lengthVar->parent = sc->parent;
            }
        }
    };

    LambdaSetParent lsp(sc);
    walkPostorder(e, &lsp);
}

/*******************************************
 * Look for references to variables in a scope enclosing the new function literal.
 * Returns true if error occurs.
 */
bool lambdaCheckForNestedRef(Expression *e, Scope *sc)
{
    class LambdaCheckForNestedRef : public StoppableVisitor
    {
    public:
        Scope *sc;
        bool result;

        LambdaCheckForNestedRef(Scope *sc)
            : sc(sc), result(false)
        {
        }

        void visit(Expression *)
        {
        }

        void visit(SymOffExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
                result = v->checkNestedReference(sc, Loc());
        }

        void visit(VarExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
                result = v->checkNestedReference(sc, Loc());
        }

        void visit(ThisExp *e)
        {
            if (e->var)
                result = e->var->checkNestedReference(sc, Loc());
        }

        void visit(DeclarationExp *e)
        {
            VarDeclaration *v = e->declaration->isVarDeclaration();
            if (v)
            {
                result = v->checkNestedReference(sc, Loc());
                if (result)
                    return;

                /* Some expressions cause the frontend to create a temporary.
                 * For example, structs with cpctors replace the original
                 * expression e with:
                 *  __cpcttmp = __cpcttmp.cpctor(e);
                 *
                 * In this instance, we need to ensure that the original
                 * expression e does not have any nested references by
                 * checking the declaration initializer too.
                 */
                if (v->_init && v->_init->isExpInitializer())
                {
                    Expression *ie = initializerToExpression(v->_init);
                    result = lambdaCheckForNestedRef(ie, sc);
                }
            }
        }
    };

    LambdaCheckForNestedRef v(sc);
    walkPostorder(e, &v);
    return v.result;
}

bool checkNestedRef(Dsymbol *s, Dsymbol *p)
{
    while (s)
    {
        if (s == p) // hit!
            return false;

        if (FuncDeclaration *fd = s->isFuncDeclaration())
        {
            if (!fd->isThis() && !fd->isNested())
                break;

            // Bugzilla 15332: change to delegate if fd is actually nested.
            if (FuncLiteralDeclaration *fld = fd->isFuncLiteralDeclaration())
                fld->tok = TOKdelegate;
        }
        if (AggregateDeclaration *ad = s->isAggregateDeclaration())
        {
            if (ad->storage_class & STCstatic)
                break;
        }
        s = s->toParent2();
    }
    return true;
}
