/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SKSL_FUNCTIONDEFINITION
#define SKSL_FUNCTIONDEFINITION

#include "src/sksl/SkSLPosition.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
#include "src/sksl/ir/SkSLIRNode.h"
#include "src/sksl/ir/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLStatement.h"

#include <memory>
#include <string>
#include <utility>

namespace SkSL {

class Context;
class SymbolTable;

/**
 * A function definition (a declaration plus an associated block of code).
 */
class FunctionDefinition final : public ProgramElement {
public:
    inline static constexpr Kind kIRNodeKind = Kind::kFunction;

    FunctionDefinition(Position pos,
                       const FunctionDeclaration* declaration,
                       bool builtin,
                       std::unique_ptr<Statement> body)
            : INHERITED(pos, kIRNodeKind)
            , fDeclaration(declaration)
            , fBuiltin(builtin)
            , fBody(std::move(body)) {}

    /**
     * Coerces `return` statements to the return type of the function, and reports errors in the
     * function that can't be detected at the individual statement level:
     *
     *     - `break` and `continue` statements must be in reasonable places.
     *     - Non-void functions are required to return a value on all paths.
     *     - Vertex main() functions don't allow early returns.
     *     - Limits on overall stack size are enforced.
     *
     * This will return a FunctionDefinition even if an error is detected; this leads to better
     * diagnostics overall. (Returning null here leads to spurious "function 'f()' was not defined"
     * errors when trying to call a function with an error in it.)
     */
    static std::unique_ptr<FunctionDefinition> Convert(const Context& context,
                                                       Position pos,
                                                       const FunctionDeclaration& function,
                                                       std::unique_ptr<Statement> body,
                                                       bool builtin);

    static std::unique_ptr<FunctionDefinition> Make(const Context& context,
                                                    Position pos,
                                                    const FunctionDeclaration& function,
                                                    std::unique_ptr<Statement> body,
                                                    bool builtin);

    const FunctionDeclaration& declaration() const {
        return *fDeclaration;
    }

    bool isBuiltin() const {
        return fBuiltin;
    }

    std::unique_ptr<Statement>& body() {
        return fBody;
    }

    const std::unique_ptr<Statement>& body() const {
        return fBody;
    }

    const SymbolTable* parameterSymbolTable() const;

    std::unique_ptr<ProgramElement> clone() const override;

    std::string description() const override {
        return this->declaration().description() + " " + this->body()->description();
    }

private:
    const FunctionDeclaration* fDeclaration;
    bool fBuiltin;
    std::unique_ptr<Statement> fBody;

    using INHERITED = ProgramElement;
};

}  // namespace SkSL

#endif
