/*
*  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
*  Copyright (C) 2001 Peter Kelly (pmk@post.com)
*  Copyright (C) 2003-2009, 2013, 2016 Apple Inc. All rights reserved.
*  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
*  Copyright (C) 2007 Maks Orlovich
*  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Library General Public
*  License as published by the Free Software Foundation; either
*  version 2 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Library General Public License for more details.
*
*  You should have received a copy of the GNU Library General Public License
*  along with this library; see the file COPYING.LIB.  If not, write to
*  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
*  Boston, MA 02110-1301, USA.
*
*/

#include "config.h"
#include "Nodes.h"
#include "NodeConstructors.h"

#include "ExecutableInfo.h"
#include "ModuleScopeData.h"
#include <wtf/Assertions.h>

namespace JSC {

DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArenaRoot);

// ------------------------------ StatementNode --------------------------------

void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
{
    m_lastLine = lastLine;
    m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
    ASSERT(m_position.offset >= m_position.lineStartOffset);
}

// ------------------------------ SourceElements --------------------------------

void SourceElements::append(StatementNode* statement)
{
    if (statement->isEmptyStatement())
        return;

    if (!m_head) {
        m_head = statement;
        m_tail = statement;
        return;
    }

    m_tail->setNext(statement);
    m_tail = statement;
}

StatementNode* SourceElements::singleStatement() const
{
    return m_head == m_tail ? m_head : nullptr;
}

StatementNode* SourceElements::lastStatement() const
{
    return m_tail;
}

bool SourceElements::hasCompletionValue() const
{
    for (StatementNode* statement = m_head; statement; statement = statement->next()) {
        if (statement->hasCompletionValue())
            return true;
    }

    return false;
}

bool SourceElements::hasEarlyBreakOrContinue() const
{
    for (StatementNode* statement = m_head; statement; statement = statement->next()) {
        if (statement->isBreak() || statement->isContinue())
            return true;
        if (statement->hasCompletionValue())
            return false;
    }

    return false;
}

// ------------------------------ BlockNode ------------------------------------

StatementNode* BlockNode::lastStatement() const
{
    return m_statements ? m_statements->lastStatement() : nullptr;
}

StatementNode* BlockNode::singleStatement() const
{
    return m_statements ? m_statements->singleStatement() : nullptr;
}

bool BlockNode::hasCompletionValue() const
{
    return m_statements ? m_statements->hasCompletionValue() : false;
}

bool BlockNode::hasEarlyBreakOrContinue() const
{
    return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
}

// ------------------------------ ScopeNode -----------------------------

ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, LexicalScopeFeatures lexicalScopeFeatures)
    : StatementNode(endLocation)
    , ParserArenaRoot(parserArena)
    , m_startLineNumber(startLocation.line)
    , m_startStartOffset(startLocation.startOffset)
    , m_startLineStartOffset(startLocation.lineStartOffset)
    , m_features(NoFeatures)
    , m_lexicalScopeFeatures(lexicalScopeFeatures)
    , m_innerArrowFunctionCodeFeatures(NoInnerArrowFunctionFeatures)
    , m_numConstants(0)
    , m_statements(nullptr)
{
}

ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
    : StatementNode(endLocation)
    , ParserArenaRoot(parserArena)
    , VariableEnvironmentNode(WTFMove(lexicalVariables), WTFMove(funcStack))
    , m_startLineNumber(startLocation.line)
    , m_startStartOffset(startLocation.startOffset)
    , m_startLineStartOffset(startLocation.lineStartOffset)
    , m_features(features)
    , m_lexicalScopeFeatures(lexicalScopeFeatures)
    , m_innerArrowFunctionCodeFeatures(innerArrowFunctionCodeFeatures)
    , m_source(source)
    , m_varDeclarations(WTFMove(varEnvironment))
    , m_sloppyModeHoistedFunctions(WTFMove(sloppyModeHoistedFunctions))
    , m_numConstants(numConstants)
    , m_statements(children)
{
}

StatementNode* ScopeNode::singleStatement() const
{
    return m_statements ? m_statements->singleStatement() : nullptr;
}

bool ScopeNode::hasCompletionValue() const
{
    return m_statements ? m_statements->hasCompletionValue() : false;
}

bool ScopeNode::hasEarlyBreakOrContinue() const
{
    return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
}

// ------------------------------ ProgramNode -----------------------------

ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
    : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
    , m_startColumn(startColumn)
    , m_endColumn(endColumn)
{
}

// ------------------------------ ModuleProgramNode -----------------------------

ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
    : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
    , m_startColumn(startColumn)
    , m_endColumn(endColumn)
    , m_usesAwait(features & AwaitFeature)
    , m_moduleScopeData(*WTFMove(moduleScopeData))
{
}

// ------------------------------ EvalNode -----------------------------

EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
    : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
    , m_endColumn(endColumn)
{
}

// ------------------------------ FunctionMetadataNode -----------------------------

FunctionMetadataNode::FunctionMetadataNode(
    ParserArena&, const JSTokenLocation& startLocation, 
    const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, 
    int functionKeywordStart, int functionNameStart, int parametersStart, LexicalScopeFeatures lexicalScopeFeatures,
    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
        : Node(endLocation)
        , m_lexicalScopeFeatures(lexicalScopeFeatures)
        , m_superBinding(static_cast<unsigned>(superBinding))
        , m_constructorKind(static_cast<unsigned>(constructorKind))
        , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
        , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
        , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
        , m_parseMode(mode)
        , m_startColumn(startColumn)
        , m_endColumn(endColumn)
        , m_functionKeywordStart(functionKeywordStart)
        , m_functionNameStart(functionNameStart)
        , m_parametersStart(parametersStart)
        , m_startStartOffset(startLocation.startOffset)
        , m_parameterCount(parameterCount)
{
    ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
    ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
}

FunctionMetadataNode::FunctionMetadataNode(
    const JSTokenLocation& startLocation, 
    const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, 
    int functionKeywordStart, int functionNameStart, int parametersStart, LexicalScopeFeatures lexicalScopeFeatures, 
    ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
        : Node(endLocation)
        , m_lexicalScopeFeatures(lexicalScopeFeatures)
        , m_superBinding(static_cast<unsigned>(superBinding))
        , m_constructorKind(static_cast<unsigned>(constructorKind))
        , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
        , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
        , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
        , m_parseMode(mode)
        , m_startColumn(startColumn)
        , m_endColumn(endColumn)
        , m_functionKeywordStart(functionKeywordStart)
        , m_functionNameStart(functionNameStart)
        , m_parametersStart(parametersStart)
        , m_startStartOffset(startLocation.startOffset)
        , m_parameterCount(parameterCount)
{
    ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
    ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
}

void FunctionMetadataNode::finishParsing(const SourceCode& source, const Identifier& ident, FunctionMode functionMode)
{
    m_source = source;
    m_ident = ident;
    m_functionMode = functionMode;
}

void FunctionMetadataNode::setEndPosition(JSTextPosition position)
{
    m_lastLine = position.line;
    m_endColumn = position.offset - position.lineStartOffset;
}

bool FunctionMetadataNode::operator==(const FunctionMetadataNode& other) const
{
    return m_parseMode == other.m_parseMode
        && m_lexicalScopeFeatures == other.m_lexicalScopeFeatures
        && m_superBinding == other.m_superBinding
        && m_constructorKind == other.m_constructorKind
        && m_isArrowFunctionBodyExpression == other.m_isArrowFunctionBodyExpression
        && m_ident == other.m_ident
        && m_ecmaName == other.m_ecmaName
        && m_functionMode == other.m_functionMode
        && m_startColumn == other.m_startColumn
        && m_endColumn == other.m_endColumn
        && m_functionKeywordStart == other.m_functionKeywordStart
        && m_functionNameStart == other.m_functionNameStart
        && m_parametersStart == other.m_parametersStart
        && m_source == other.m_source
        && m_classSource == other.m_classSource
        && m_startStartOffset == other.m_startStartOffset
        && m_parameterCount == other.m_parameterCount
        && m_lastLine == other.m_lastLine
        && m_position == other.m_position;
}

void FunctionMetadataNode::dump(PrintStream& stream) const
{
    stream.println("m_parseMode ", static_cast<uint32_t>(m_parseMode));
    stream.println("m_lexicalScopeFeatures ", m_lexicalScopeFeatures);
    stream.println("m_superBinding ", m_superBinding);
    stream.println("m_constructorKind ", m_constructorKind);
    stream.println("m_isArrowFunctionBodyExpression ", m_isArrowFunctionBodyExpression);
    stream.println("m_ident ", m_ident);
    stream.println("m_ecmaName ", m_ecmaName);
    stream.println("m_functionMode ", static_cast<uint32_t>(m_functionMode));
    stream.println("m_startColumn ", m_startColumn);
    stream.println("m_endColumn ", m_endColumn);
    stream.println("m_functionKeywordStart ", m_functionKeywordStart);
    stream.println("m_functionNameStart ", m_functionNameStart);
    stream.println("m_parametersStart ", m_parametersStart);
    stream.println("m_classSource.isNull() ", m_classSource.isNull());
    stream.println("m_startStartOffset ", m_startStartOffset);
    stream.println("m_parameterCount ", m_parameterCount);
    stream.println("m_lastLine ", m_lastLine);
    stream.println("position().line ", position().line);
    stream.println("position().offset ", position().offset);
    stream.println("position().lineStartOffset ", position().lineStartOffset);
}

// ------------------------------ FunctionNode -----------------------------

FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
    : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
    , m_parameters(parameters)
    , m_startColumn(startColumn)
    , m_endColumn(endColumn)
{
}

void FunctionNode::finishParsing(const Identifier& ident, FunctionMode functionMode)
{
    ASSERT(!source().isNull());
    m_ident = ident;
    m_functionMode = functionMode;
}

bool PropertyListNode::hasStaticallyNamedProperty(const Identifier& propName)
{
    PropertyListNode* list = this;
    while (list) {
        if (list->m_node->isStaticClassProperty()) {
            const Identifier* currentNodeName = list->m_node->name();
            if (currentNodeName && *currentNodeName == propName)
                return true;
        }
        list = list->m_next;
    }
    return false;
}

// FIXME: calculate this feature once when parsing the property list.
// https://bugs.webkit.org/show_bug.cgi?id=206174
bool PropertyListNode::shouldCreateLexicalScopeForClass(PropertyListNode* list)
{
    while (list) {
        if (list->m_node->isComputedClassField() || list->m_node->isPrivate())
            return true;
        list = list->m_next;
    }
    return false;
}

// ------------------------------ ClassExprNode -----------------------------

// FIXME: calculate this feature once when parsing the property list.
// https://bugs.webkit.org/show_bug.cgi?id=206174
bool PropertyListNode::hasInstanceFields() const
{
    for (auto list = this; list; list = list->m_next) {
        if (list->m_node->isInstanceClassField())
            return true;
    }
    return false;
}

VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables)
    : m_lexicalVariables(WTFMove(lexicalVariables))
{
}

VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables, FunctionStack&& functionStack)
    : m_lexicalVariables(WTFMove(lexicalVariables))
    , m_functionStack(WTFMove(functionStack))
{
}

} // namespace JSC
