<commit_before>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 <NAME> <<EMAIL>>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2.1 of the Licence, 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "parser.h"

#include "engine.h"
#include "exception.h"
#include "filter.h"
#include "grantlee_version.h"
#include "nodebuiltins_p.h"
#include "taglibraryinterface.h"
#include "template.h"
#include "template_p.h"

#include <QtCore/QFile>

using namespace Grantlee;

namespace Grantlee
{

class ParserPrivate
{
public:
  ParserPrivate( Parser *parser, const QList<Token> &tokenList )
      : q_ptr( parser ),
      m_tokenList( tokenList ) {

  }

  NodeList extendNodeList( NodeList list, Node *node );

  /**
    Parses the template to create a Nodelist.
    The given @p parent is the parent of each node in the returned list.
  */
  NodeList parse( QObject *parent, const QStringList &stopAt = QStringList() );

  void openLibrary( TagLibraryInterface * library );
  Q_DECLARE_PUBLIC( Parser )
  Parser * const q_ptr;

  QList<Token> m_tokenList;

  QHash<QString, AbstractNodeFactory*> m_nodeFactories;
  QHash<QString, Filter::Ptr> m_filters;

  NodeList m_nodeList;
};

}

void ParserPrivate::openLibrary( TagLibraryInterface *library )
{
  Q_Q( Parser );
  QHashIterator<QString, AbstractNodeFactory*> nodeIt( library->nodeFactories() );

  TemplateImpl *ti = qobject_cast<TemplateImpl *>( q->parent() );

  Engine const *cengine = ti->engine();
  if ( !cengine )
    return;
  Engine *engine = const_cast<Engine *>( cengine );

  while ( nodeIt.hasNext() ) {
    nodeIt.next();
    nodeIt.value()->setEngine( engine );
    m_nodeFactories.insert( nodeIt.key(), nodeIt.value() );
  }
  QHashIterator<QString, Filter*> filterIt( library->filters() );
  while ( filterIt.hasNext() ) {
    filterIt.next();
    Filter::Ptr f = Filter::Ptr( filterIt.value() );
    m_filters.insert( filterIt.key(), f );
  }
}

Parser::Parser( const QList<Token> &tokenList, QObject *parent )
    : QObject( parent ), d_ptr( new ParserPrivate( this, tokenList ) )
{
  Q_D( Parser );

  TemplateImpl *ti = qobject_cast<TemplateImpl *>( parent );

  Engine const *cengine = ti->engine();
  if ( !cengine )
    return;
  Engine *engine = const_cast<Engine *>( cengine );
  engine->loadDefaultLibraries();
  Q_FOREACH( const QString &libraryName, engine->defaultLibraries() ) {
    TagLibraryInterface *library = engine->loadLibrary( libraryName );
    if ( !library )
      continue;
    d->openLibrary( library );
  }
}

Parser::~Parser()
{
  // Don't delete filters here because filters must out-live the parser in the
  // filter expressions.
  qDeleteAll( d_ptr->m_nodeFactories );
  delete d_ptr;
}


void Parser::setTokens( const QList< Token >& tokenList )
{
  Q_D( Parser );
  d->m_tokenList = tokenList;
}


void Parser::loadLib( const QString &name )
{
  Q_D( Parser );
  TemplateImpl *ti = qobject_cast<TemplateImpl *>( parent() );
  Engine const *cengine = ti->engine();
  if ( !cengine )
    return;
  Engine *engine = const_cast<Engine *>( cengine );
  TagLibraryInterface *library = engine->loadLibrary( name );
  if ( !library )
    return;
  d->openLibrary( library );
}

NodeList ParserPrivate::extendNodeList( NodeList list, Node *node )
{
  if ( node->mustBeFirst() && list.containsNonText() ) {
    throw Grantlee::Exception( TagSyntaxError, QString::fromLatin1(
        "Node appeared twice in template: %1" ).arg( QLatin1String( node->metaObject()->className() ) ) );
  }

  list.append( node );
  return list;
}

void Parser::skipPast( const QString &tag )
{
  while ( hasNextToken() ) {
    const Token token = takeNextToken();
    if ( token.tokenType == BlockToken && token.content.trimmed() == tag )
      return;
  }
  throw Grantlee::Exception( UnclosedBlockTagError, QString::fromLatin1( "No closing tag found for %1" ).arg( tag ) );
}<commit_msg>Remove dead code. The parser must be a child of the engine.<commit_after>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 <NAME> <<EMAIL>>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2.1 of the Licence, 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "parser.h"

#include "engine.h"
#include "exception.h"
#include "filter.h"
#include "grantlee_version.h"
#include "nodebuiltins_p.h"
#include "taglibraryinterface.h"
#include "template.h"
#include "template_p.h"

#include <QtCore/QFile>

using namespace Grantlee;

namespace Grantlee
{

class ParserPrivate
{
public:
  ParserPrivate( Parser *parser, const QList<Token> &tokenList )
      : q_ptr( parser ),
      m_tokenList( tokenList ) {

  }

  NodeList extendNodeList( NodeList list, Node *node );

  /**
    Parses the template to create a Nodelist.
    The given @p parent is the parent of each node in the returned list.
  */
  NodeList parse( QObject *parent, const QStringList &stopAt = QStringList() );

  void openLibrary( TagLibraryInterface * library );
  Q_DECLARE_PUBLIC( Parser )
  Parser * const q_ptr;

  QList<Token> m_tokenList;

  QHash<QString, AbstractNodeFactory*> m_nodeFactories;
  QHash<QString, Filter::Ptr> m_filters;

  NodeList m_nodeList;
};

}

void ParserPrivate::openLibrary( TagLibraryInterface *library )
{
  Q_Q( Parser );
  QHashIterator<QString, AbstractNodeFactory*> nodeIt( library->nodeFactories() );

  TemplateImpl *ti = qobject_cast<TemplateImpl *>( q->parent() );

  Engine const *cengine = ti->engine();
  Q_ASSERT( cengine );
  Engine *engine = const_cast<Engine *>( cengine );

  while ( nodeIt.hasNext() ) {
    nodeIt.next();
    nodeIt.value()->setEngine( engine );
    m_nodeFactories.insert( nodeIt.key(), nodeIt.value() );
  }
  QHashIterator<QString, Filter*> filterIt( library->filters() );
  while ( filterIt.hasNext() ) {
    filterIt.next();
    Filter::Ptr f = Filter::Ptr( filterIt.value() );
    m_filters.insert( filterIt.key(), f );
  }
}

Parser::Parser( const QList<Token> &tokenList, QObject *parent )
    : QObject( parent ), d_ptr( new ParserPrivate( this, tokenList ) )
{
  Q_D( Parser );

  TemplateImpl *ti = qobject_cast<TemplateImpl *>( parent );

  Engine const *cengine = ti->engine();
  Q_ASSERT( cengine );

  Engine *engine = const_cast<Engine *>( cengine );
  engine->loadDefaultLibraries();
  Q_FOREACH( const QString &libraryName, engine->defaultLibraries() ) {
    TagLibraryInterface *library = engine->loadLibrary( libraryName );
    if ( !library )
      continue;
    d->openLibrary( library );
  }
}

Parser::~Parser()
{
  // Don't delete filters here because filters must out-live the parser in the
  // filter expressions.
  qDeleteAll( d_ptr->m_nodeFactories );
  delete d_ptr;
}


void Parser::setTokens( const QList< Token >& tokenList )
{
  Q_D( Parser );
  d->m_tokenList = tokenList;
}


void Parser::loadLib( const QString &name )
{
  Q_D( Parser );
  TemplateImpl *ti = qobject_cast<TemplateImpl *>( parent() );
  Engine const *cengine = ti->engine();
  Q_ASSERT( cengine );
  Engine *engine = const_cast<Engine *>( cengine );
  TagLibraryInterface *library = engine->loadLibrary( name );
  if ( !library )
    return;
  d->openLibrary( library );
}

NodeList ParserPrivate::extendNodeList( NodeList list, Node *node )
{
  if ( node->mustBeFirst() && list.containsNonText() ) {
    throw Grantlee::Exception( TagSyntaxError, QString::fromLatin1(
        "Node appeared twice in template: %1" ).arg( QLatin1String( node->metaObject()->className() ) ) );
  }

  list.append( node );
  return list;
}

void Parser::skipPast( const QString &tag )
{
  while ( hasNextToken() ) {
    const Token token = takeNextToken();
    if ( token.tokenType == BlockToken && token.content.trimmed() == tag )
      return;
  }
  throw Grantlee::Exception( UnclosedBlockTagError, QString::fromLatin1( "No closing tag found for %1" ).arg( tag ) );
}
{'fraction_non_alphanumeric': 0.12169134140870345, 'fraction_numerical': 0.0033647375504710633, 'mean_word_length': 4.01800787844682, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6926519', 'n_tokens_mistral': 2841, 'n_tokens_neox': 2772, 'n_words': 840}