estyle/estyle/Generator.cpp

1441 lines
42 KiB
C++

/**
* @author Edouard DUPIN
* @copyright 2017, Edouard DUPIN, all right reserved
* @license MPL-2 (see license file)
*/
#include <estyle/Generator.hpp>
#include <estyle/debug.hpp>
void estyle::Generator::indentationPush() {
m_indentation++;
}
void estyle::Generator::indentationPop() {
m_indentation--;
}
void estyle::Generator::offsetPush(int32_t _count) {
m_offsetStack.pushBack(_count);
m_offset += _count;
}
void estyle::Generator::offsetPushAuto() {
int32_t offset = 0;
for (int64_t iii=m_output.size()-1; iii>=0; --iii) {
if ( m_output[iii] == '\n'
|| m_output[iii] == '\t') {
break;
}
offset++;
}
offsetPush(offset-m_offset);
}
void estyle::Generator::offsetPop() {
m_offset -= m_offsetStack.back();
m_offsetStack.popBack();
}
void estyle::Generator::typePush(etk::String _data) {
m_typeStack.pushBack(_data);
m_type = m_typeStack.back();
}
void estyle::Generator::typePop() {
m_typeStack.popBack();
if (m_typeStack.size() != 0) {
m_type = m_typeStack.back();
} else {
m_type = "block";
}
}
/*
/ **
*
* /
*/
#define DOXYGEN_MULTI_LINE__NORMAL (0)
/*
/ *!
*
* /
*/
#define DOXYGEN_MULTI_LINE__NORMAL_EXCLAMATION (1)
/*
/ **
* /
*/
#define DOXYGEN_MULTI_LINE__NORMAL_NO_STAR (2)
/*
/ *!
* /
*/
#define DOXYGEN_MULTI_LINE__NORMAL_NO_STAR_EXCLAMATION (3)
/*
///
///
///
*/
#define DOXYGEN_MULTI_LINE__NORMAL_SINGLE_LINE (4)
/*
//!
//!
//!
*/
#define DOXYGEN_MULTI_LINE__NORMAL_SINGLE_LINE_EXCLAMATION (5)
static void setPropertyDoxygenMultiLine(eproperty::List<int32_t>& _data) {
_data.add(DOXYGEN_MULTI_LINE__NORMAL, "normal");
_data.add(DOXYGEN_MULTI_LINE__NORMAL_EXCLAMATION, "normal-exclamation");
_data.add(DOXYGEN_MULTI_LINE__NORMAL_NO_STAR, "no-star");
_data.add(DOXYGEN_MULTI_LINE__NORMAL_NO_STAR_EXCLAMATION, "no-star-exclamation");
_data.add(DOXYGEN_MULTI_LINE__NORMAL_SINGLE_LINE, "single-line");
_data.add(DOXYGEN_MULTI_LINE__NORMAL_SINGLE_LINE_EXCLAMATION, "single-line-exclamation");
}
void estyle::Generator::clear() {
m_offset = 0;
m_offsetStack.clear();
m_type = "block";
m_typeStack.clear();
//m_lexer;
m_indentation = 0;
m_output = "";
}
estyle::Generator::Generator():
propertyEndOfLine(this, "end-of-line", true, "true: End with \\n, false \\r\\n"),
propertyIndentWithTabulation(this, "indent-with-tabs", true, "true: indent with tabs: '\\t', false indent win space:' '"),
propertyIndentSize(this, "indent-size", 4, "default 4 sapce in one tabulation indentation"),
propertyDoxygenOneLine(this, "doxygen-1-line-type", true, "true: single line doxygen comment is done with '//!', false '///'"),
propertyDoxygenMultipleLine(this, "doxygen-N-line-type", DOXYGEN_MULTI_LINE__NORMAL, "0: /** */ ..."),
propertySemiColonReturnBetweenAction(this, "semi-colon-return-between-action", false, "true: 2 action separate with a ';' element have a newLine added")
{
setPropertyDoxygenMultiLine(propertyDoxygenMultipleLine);
propertyBrace.set("if", etk::move(estyle::GroupProperty(this, "brace", "if")));
propertyBrace.set("else", etk::move(estyle::GroupProperty(this, "brace", "else")));
propertyBrace.set("function", etk::move(estyle::GroupProperty(this, "brace", "function", false)));
propertyBrace.set("for", etk::move(estyle::GroupProperty(this, "brace", "for")));
propertyBrace.set("while", etk::move(estyle::GroupProperty(this, "brace", "while")));
propertyBrace.set("namespace", etk::move(estyle::GroupProperty(this, "brace", "namespace", false)));
propertyBrace.set("block", etk::move(estyle::GroupProperty(this, "brace", "block", false)));
propertyBrace.set("do-while", etk::move(estyle::GroupProperty(this, "brace", "do-while")));
propertyBrace.set("switch", etk::move(estyle::GroupProperty(this, "brace", "switch", false)));
propertyBrace.set("class", etk::move(estyle::GroupProperty(this, "brace", "class", false)));
propertyBrace.set("struct", etk::move(estyle::GroupProperty(this, "brace", "struct", false)));
propertyBrace.set("try", etk::move(estyle::GroupProperty(this, "brace", "try", false)));
propertyBrace.set("catch", etk::move(estyle::GroupProperty(this, "brace", "catch", false)));
propertyParenthese.set("if", etk::move(estyle::GroupProperty(this, "parenthese", "if")));
propertyParenthese.set("for", etk::move(estyle::GroupProperty(this, "parenthese", "for")));
propertyParenthese.set("while", etk::move(estyle::GroupProperty(this, "parenthese", "while")));
propertyParenthese.set("do-while", etk::move(estyle::GroupProperty(this, "parenthese", "do-while")));
propertyParenthese.set("switch", etk::move(estyle::GroupProperty(this, "parenthese", "switch")));
propertyParenthese.set("block", etk::move(estyle::GroupProperty(this, "parenthese", "block")));
etk::String type = "if";
propertyCondition.set(type, etk::move(eproperty::List<int8_t>(this, "condition-" + type + "-mode", 0, "Contion generic property")));
propertyCondition[type].add(0, "none");
propertyCondition[type].add(1, "magic");
//propertyCondition[type].add(2, "right");
//propertyCondition[type].add(3, "left");
type = "for";
propertyCondition.set(type, etk::move(eproperty::List<int8_t>(this, "condition-" + type + "-mode", 0, "Contion generic property")));
propertyCondition[type].add(0, "none");
propertyCondition[type].add(1, "magic");
//propertyCondition[type].add(2, "right");
//propertyCondition[type].add(3, "left");
type = "while";
propertyCondition.set(type, etk::move(eproperty::List<int8_t>(this, "condition-" + type + "-mode", 0, "Contion generic property")));
propertyCondition[type].add(0, "none");
propertyCondition[type].add(1, "magic");
//propertyCondition[type].add(2, "right");
//propertyCondition[type].add(3, "left");
type = "do-while";
propertyCondition.set(type, etk::move(eproperty::List<int8_t>(this, "condition-" + type + "-mode", 0, "Contion generic property")));
propertyCondition[type].add(0, "none");
propertyCondition[type].add(1, "magic");
//propertyCondition[type].add(2, "right");
//propertyCondition[type].add(3, "left");
/*
type = "function";
propertyCondition.set(type, etk::move(eproperty::List<int8_t>(this, "condition-" + type + "-mode", 0, "Contion generic property"));
propertyCondition[type].add(0, "none");
propertyCondition[type].add(1, "magic");
//propertyCondition[type].add(2, "right");
//propertyCondition[type].add(3, "left");
*/
}
estyle::Generator::~Generator() {
}
etk::String estyle::Generator::getEndOfLine() {
if (propertyEndOfLine.get() == true) {
return "\n";
}
return "\r\n";
}
etk::String estyle::Generator::getDoxygenOneLine() {
if (propertyDoxygenOneLine.get() == true) {
return "//!";
}
return "///";
}
etk::String estyle::Generator::getDoxygenNLine(const etk::String& _data) {
if (propertyDoxygenMultipleLine.get() == 0) {
}
etk::String out;
out += "/**";
out += _data;
out += "*/";
return out;
}
void estyle::Generator::addNewLine(bool _force) {
if (_force == false) {
while ( ( m_output.back() == ' '
|| m_output.back() == '\t')
&& m_output.size()>0) {
m_output.popBack();
}
}
if (m_output.size() == 0) {
return;
}
if (m_output.back() == '\0') {
ESTYLE_TODO("TODO : Do indentation... : '" << m_output << "'");
}
if (m_output.back() == '\n') {
return;
}
m_output += getEndOfLine();
}
void estyle::Generator::addNewLineIfSemiColon() {
if (m_output.size() == 0) {
return;
}
if ( m_output.back() == ';'
&& propertySemiColonReturnBetweenAction.get() == true) {
m_output += getEndOfLine();
}
}
void estyle::Generator::addIndent() {
if (m_output.size() == 0) {
return;
}
if (m_output.back() == '\0') {
ESTYLE_TODO("TODO : Do indentation... : '" << m_output << "'");
}
if (m_output.back() == '\n') {
if (propertyIndentWithTabulation.get() == true) {
for (int32_t iii=0; iii<m_indentation; ++iii) {
m_output += "\t";
}
} else {
for (int32_t iii=0; iii<m_indentation; ++iii) {
for (int32_t jjj=0; jjj<propertyIndentSize.get(); ++jjj) {
m_output += " ";
}
}
}
for (int32_t ooo=0; ooo<m_offset; ++ooo) {
m_output += " ";
}
return;
}
}
void estyle::Generator::addSpace(bool _force) {
if (_force == false) {
while ( ( m_output.back() == ' '
|| m_output.back() == '\t')
&& m_output.size()>0) {
m_output.popBack();
}
}
if (m_output.size() == 0) {
return;
}
if (m_output.back() == '\0') {
ESTYLE_TODO("TODO : Do indentation... : '" << m_output << "'");
}
if (m_output.back() == '\n') {
addIndent();
return;
}
if ( m_output.back() == ' '
|| m_output.back() == '\t') {
return;
}
m_output += " ";
}
void estyle::Generator::addSpaceIfNeeded() {
if (m_output.size() == 0) {
return;
}
if (m_output.back() == '\0') {
return;
}
if (m_output.back() == '\n') {
return;
}
if ( ( m_output.back() >= '0'
&& m_output.back() <= '9' )
|| ( m_output.back() >= 'a'
&& m_output.back() <= 'z' )
|| ( m_output.back() >= 'A'
&& m_output.back() <= 'Z' )
|| m_output.back() == '_' ) {
m_output += " ";
}
}
static bool startWithText(const etk::String& _data) {
if (_data.size() == 0) {
return false;
}
if ( ( _data[0] >= '0'
&& _data[0] <= '9' )
|| ( _data[0] >= 'a'
&& _data[0] <= 'z' )
|| ( _data[0] >= 'A'
&& _data[0] <= 'Z' )
|| _data[0] == '_' ) {
return true;
}
return false;
}
bool estyle::Generator::onNewLine() {
if (m_output.size() == 0) {
return true;
}
if (m_output.back() == '\n') {
return true;
}
return false;
}
enum class stack {
NAMESPACE,
CLASS,
STRUCT,
BLOCK,
DO,
WHILE,
FOR,
IF,
ELSE,
PTHESE_CONDITION,
PTHESE,
};
etk::Vector<enum stack> m_urrentStack;
etk::String estyle::Generator::process(const etk::String& _code) {
clear();
m_lexer.lexify(_code);
process(0, m_lexer.size(), estyle::lexer::END_OF_FILE);
return m_output;
}
int32_t estyle::Generator::process(int32_t _startId,
int32_t _stopId,
enum estyle::lexer::tocken _endTocken1,
enum estyle::lexer::tocken _endTocken2,
enum estyle::lexer::tocken _endTocken3,
enum estyle::lexer::tocken _endTocken4) {
for (int64_t iii = _startId; iii < _stopId; ++iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
if ( elem == _endTocken1
|| elem == _endTocken2
|| elem == _endTocken3
|| elem == _endTocken4) {
return iii;
}
if (elem == estyle::lexer::RESERVED_COMMENT_1_LINE) {
addNewLineIfSemiColon();
m_output += "//";
m_output += m_lexer.getData(iii);
m_output += getEndOfLine();
continue;
}
if (elem == estyle::lexer::RESERVED_DOCUMENTATION_1_LINE) {
addNewLineIfSemiColon();
m_output += getDoxygenOneLine();
m_output += m_lexer.getData(iii);
m_output += getEndOfLine();
continue;
}
if (elem == estyle::lexer::RESERVED_COMMENT_N_LINE) {
addNewLineIfSemiColon();
addSpace();
m_output += "/*";
m_output += m_lexer.getData(iii);
m_output += "*/";
if (iii+1 < m_lexer.size()) {
if (m_lexer.getTocken(iii+1) == estyle::lexer::RESERVED_NEW_LINE) {
m_output += getEndOfLine();
++iii;
}
}
continue;
}
if (elem == estyle::lexer::RESERVED_DOCUMENTATION_1_LINE) {
addNewLineIfSemiColon();
addSpace();
m_output += getDoxygenNLine(m_lexer.getData(iii));
m_output += getEndOfLine();
// TODO : Some mode can create error like /** */ becaming /// ...
if (iii+1 < m_lexer.size()) {
if (m_lexer.getTocken(iii+1) == estyle::lexer::RESERVED_NEW_LINE) {
m_output += getEndOfLine();
++iii;
}
}
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_SIZE_T) {
addNewLineIfSemiColon();
addSpace();
m_output += "size_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_008) {
addNewLineIfSemiColon();
addSpace();
m_output += "int8_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_008_UNSIGNED) {
addNewLineIfSemiColon();
addSpace();
m_output += "uint8_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_016) {
addNewLineIfSemiColon();
addSpace();
m_output += "int16_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_016_UNSIGNED) {
addNewLineIfSemiColon();
addSpace();
m_output += "uint16_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_032) {
addNewLineIfSemiColon();
addSpace();
m_output += "int32_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_032_UNSIGNED) {
addNewLineIfSemiColon();
addSpace();
m_output += "uint32_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_064) {
addNewLineIfSemiColon();
addSpace();
m_output += "int64_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_064_UNSIGNED) {
addNewLineIfSemiColon();
addSpace();
m_output += "uint64_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_128) {
addNewLineIfSemiColon();
addSpace();
m_output += "int128_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_INTEGER_128_UNSIGNED) {
addNewLineIfSemiColon();
addSpace();
m_output += "uint128_t";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_FLOAT_32) {
addNewLineIfSemiColon();
addSpace();
m_output += "float";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_FLOAT_64) {
addNewLineIfSemiColon();
addSpace();
m_output += "double";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_FLOAT_96) {
addNewLineIfSemiColon();
addSpace();
m_output += "triple";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_BOOLEAN) {
addNewLineIfSemiColon();
addSpace();
m_output += "bool";
continue;
}
if (elem == estyle::lexer::BASIC_TYPE_VOID) {
addNewLineIfSemiColon();
addSpace();
m_output += "void";
continue;
}
if (elem == estyle::lexer::SEMICOLON) {
addNewLineIfSemiColon();
m_output += ";";
continue;
}
if (elem == estyle::lexer::ID) {
addNewLineIfSemiColon();
//addSpace();
addIndent();
m_output += m_lexer.getData(iii);
continue;
}
if (elem == estyle::lexer::EQUAL) {
addNewLineIfSemiColon();
addSpace();
m_output += "=";
continue;
}
if (elem == estyle::lexer::STRING) {
addNewLineIfSemiColon();
m_output += "\"";
m_output += m_lexer.getData(iii);
m_output += "\"";
continue;
}
if (elem == estyle::lexer::SIMPLE_QUOTE_STRING) {
addNewLineIfSemiColon();
m_output += "'";
m_output += m_lexer.getData(iii);
m_output += "'";
continue;
}
if (elem == estyle::lexer::BRACE_IN) {
typePush("block");
int32_t subGenerationStart = iii+1;
int32_t subGenerationStop = endOfSection(iii);
iii = generateBrace(subGenerationStart, subGenerationStop, true, false);
iii--;
typePop();
/*
addNewLineIfSemiColon();
m_urrentStack.pushBack(stack::BLOCK);
addNewLine();
addSpace();
m_output += "{";
m_output += getEndOfLine();
indentationPush();
*/
continue;
}
if (elem == estyle::lexer::BRACE_OUT) {
addNewLineIfSemiColon();
indentationPop();
ESTYLE_ERROR("Get '}' without other than a '{' element in stack of type ...");
addNewLine();
addSpace();
m_output += "}";
m_output += getEndOfLine();
continue;
}
if (elem == estyle::lexer::ELEMENT_COMPLEX_TYPE) {
addNewLineIfSemiColon();
// complex type is special to generate...
etk::String type = generateType(iii);
addSpace();
m_output += type;
continue;
}
if (elem == estyle::lexer::RESERVED_FOR) {
addNewLineIfSemiColon();
addIndent();
addSpaceIfNeeded();
m_output += "for";
typePush("for");
offsetPush(4);
bool errorOccured = false;
// TODO : do this ==> not implemented
for (int64_t jjj=iii+1; jjj<m_lexer.size(); ++jjj) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(jjj);
if (elem == estyle::lexer::RESERVED_NEW_LINE) {
// OK ==> normal case ...
} else if (elem == estyle::lexer::PARENTHESE_IN) {
// find condition section ...
int64_t lastElementCondition = endOfSection(jjj);
// now we need to count the number of actions ... must be 3 inside (A;B;C)
int32_t nbAction = countCurrentAction(jjj, lastElementCondition);
if (nbAction != 2) {
ESTYLE_ERROR("Get not enought action in 'for' " << nbAction << " != 2 (action is ended with a ';' element");
typePop();
errorOccured = true;
break;
}
int32_t rawSize = countRawSize(jjj+1, lastElementCondition);
int64_t endSectionA = endOfAction(jjj);
int32_t nbElementSectionA = endSectionA - (jjj+1);
int64_t endSectionB = endOfAction(endSectionA);
int32_t nbElementSectionB = endSectionB - (endSectionA+1);
int32_t nbElementSectionC = lastElementCondition - (endSectionB+1);
if ( nbElementSectionA == 0
&& nbElementSectionB == 0
&& nbElementSectionC == 0) {
m_output += "(;;)";
} else {
m_output += "(";
// write section A
process(jjj+1, endSectionA);
m_output += ";";
ESTYLE_WARNING("big size: " << propertyParenthese[m_type].oneLineMaxSize.get() << " <= " << rawSize);
if ( propertyParenthese[m_type].oneLineMaxSize.get() <= rawSize
|| propertyParenthese[m_type].oneLineMaxSize.get() == -1) {
addNewLine();
addIndent();
} else {
m_output += " ";
}
// write section B
process(endSectionA+1, endSectionB);
m_output += ";";
if ( propertyParenthese[m_type].oneLineMaxSize.get() <= rawSize
|| propertyParenthese[m_type].oneLineMaxSize.get() == -1) {
addNewLine();
addIndent();
} else {
m_output += " ";
}
// Write section C
process(endSectionB+1, lastElementCondition);
m_output += ")";
}
iii = lastElementCondition;
break;
} else {
ESTYLE_ERROR("Get 'for' without '(' element");
typePop();
errorOccured = true;
break;
}
}
if (errorOccured == true) {
continue;
}
offsetPop();
bool needBrace = false;
bool haveBrace = false;
int32_t subGenerationStart = iii+1;
int32_t subGenerationStop = iii+1;
// Check if next action is inside {} or not ...
if (nextIs(iii+1, estyle::lexer::BRACE_IN) == true) {
haveBrace = true;
// no need to add one ...
int32_t countAction = countCurrent(iii+1, m_lexer.size(), estyle::lexer::tocken::SEMICOLON);
ESTYLE_ERROR("nbAction = " << countAction);
if (countAction != 1) {
needBrace = true;
}
subGenerationStart = iii+2;
subGenerationStop = endOfSection(iii+1);
} else {
// only 1 instruction:
int32_t sectionEnd = endOfAction(iii+1);
subGenerationStop = sectionEnd+1;
}
iii = generateBrace(subGenerationStart, subGenerationStop, needBrace, true);
if (haveBrace == true) {
iii--;
} else {
iii -= 2;
}
typePop();
continue;
}
if ( elem == estyle::lexer::RESERVED_IF
|| elem == estyle::lexer::RESERVED_WHILE
|| elem == estyle::lexer::RESERVED_DO) {
addNewLineIfSemiColon();
addIndent();
addSpaceIfNeeded();
if (elem == estyle::lexer::RESERVED_IF) {
m_output += "if";
typePush("if");
if (previousIs(iii, estyle::lexer::RESERVED_ELSE) == true) {
offsetPush(4 + 5);
} else {
offsetPush(4);
}
} else if (elem == estyle::lexer::RESERVED_WHILE) {
m_output += "while";
typePush("while");
offsetPush(7);
} else {
m_output += "do";
typePush("do-while");
}
bool haveError = false;
if (elem != estyle::lexer::RESERVED_DO) {
for (int64_t jjj=iii+1; jjj<m_lexer.size(); ++jjj) {
enum estyle::lexer::tocken elem2 = m_lexer.getTocken(jjj);
if (elem2 == estyle::lexer::RESERVED_NEW_LINE) {
// OK ==> normal case ...
} else if (elem2 == estyle::lexer::PARENTHESE_IN) {
// find condition section ...
iii = generateCondition(jjj);
break;
} else {
ESTYLE_ERROR("Get '" << elem << "' without '(' element");
haveError = true;
break;
}
}
offsetPop();
if (haveError == true) {
typePop();
continue;
}
}
bool needBrace = false;
bool haveBrace = false;
int32_t subGenerationStart = iii+1;
int32_t subGenerationStop = iii+1;
// Check if next action is inside {} or not ...
if (nextIs(iii+1, estyle::lexer::BRACE_IN) == true) {
haveBrace = true;
// no need to add one ...
int32_t countAction = countCurrent(iii+1, m_lexer.size(), estyle::lexer::tocken::SEMICOLON);
if (countAction != 1) {
needBrace = true;
}
subGenerationStart = iii+2;
subGenerationStop = endOfSection(iii+1);
} else {
// only 1 instruction:
int32_t sectionEnd = endOfAction(iii+1);
subGenerationStop = sectionEnd+1;
}
iii = generateBrace(subGenerationStart,
subGenerationStop,
needBrace,
elem == estyle::lexer::RESERVED_IF);
if (haveBrace == true) {
iii--;
} else {
iii -= 2;
}
if (elem == estyle::lexer::RESERVED_DO) {
if (nextIs(iii+1, estyle::lexer::RESERVED_WHILE) == false) {
ESTYLE_ERROR("find a 'do ... ' without 'while' ...");
typePop();
continue;
} else {
addSpaceIfNeeded();
iii++;
m_output += "while";
offsetPush(6);
for (int64_t jjj=iii+1; jjj<m_lexer.size(); ++jjj) {
enum estyle::lexer::tocken elem2 = m_lexer.getTocken(jjj);
if (elem2 == estyle::lexer::RESERVED_NEW_LINE) {
// OK ==> normal case ...
} else if (elem2 == estyle::lexer::PARENTHESE_IN) {
// find condition section ...
iii = generateCondition(jjj);
break;
} else {
ESTYLE_ERROR("Get 'do ... while ' without '(' element");
haveError = true;
break;
}
}
offsetPop();
if (haveError == true) {
typePop();
continue;
}
}
}
typePop();
continue;
}
if (elem == estyle::lexer::RESERVED_ELSE) {
addNewLineIfSemiColon();
typePush("else");
addSpaceIfNeeded();
m_output += "else";
// special case ==> nothing special to do for the else element...
if (nextIs(iii+1, estyle::lexer::RESERVED_IF) == true) {
typePop();
continue;
}
bool needBrace = false;
bool haveBrace = false;
int32_t subGenerationStart = iii+1;
int32_t subGenerationStop = iii+1;
if (nextIs(iii+1, estyle::lexer::BRACE_IN) == true) {
haveBrace = true;
int32_t countAction = countCurrent(iii+1, m_lexer.size(), estyle::lexer::tocken::SEMICOLON);
if (countAction != 1) {
needBrace = true;
}
subGenerationStart = iii+2;
subGenerationStop = endOfSection(iii+1);
} else {
// only 1 instruction:
int32_t sectionEnd = endOfAction(iii+1);
subGenerationStop = sectionEnd+1;
}
iii = generateBrace(subGenerationStart, subGenerationStop, needBrace, true);
if (haveBrace == true) {
iii--;
} else {
iii -= 2;
}
typePop();
continue;
}
if ( elem == estyle::lexer::RESERVED_NAMESPACE
|| elem == estyle::lexer::RESERVED_CLASS
|| elem == estyle::lexer::RESERVED_STRUCT) {
addNewLineIfSemiColon();
addSpaceIfNeeded();
if (elem == estyle::lexer::RESERVED_NAMESPACE) {
typePush("namespace");
m_output += "namespace";
} else if (elem == estyle::lexer::RESERVED_CLASS) {
typePush("class");
m_output += "class";
} else if (elem == estyle::lexer::RESERVED_STRUCT) {
typePush("struct");
m_output += "struct";
} else {
if (startWithText(m_lexer.getData(iii)) == true) {
addSpaceIfNeeded();
}
m_output += m_lexer.getData(iii);
continue;
}
// special case ==> nothing special to do for the else element...
if (nextIs(iii+1, estyle::lexer::BRACE_IN) == false) {
if (nextIs(iii+1, estyle::lexer::ID) == true) {
// normal case ==> empty namespace / struct / class
addSpaceIfNeeded();
iii++;
m_output += m_lexer.getData(iii);
} else {
ESTYLE_ERROR("mamespace must be followed by an ID or a brace");
typePop();
continue;
}
}
bool needBrace = false;
bool haveBrace = false;
int32_t subGenerationStart = iii+1;
int32_t subGenerationStop = iii+1;
if (nextIs(iii+1, estyle::lexer::BRACE_IN) == true) {
haveBrace = true;
int32_t countAction = countCurrent(iii+1, m_lexer.size(), estyle::lexer::tocken::SEMICOLON);
if (countAction != 1) {
needBrace = true;
}
subGenerationStart = iii+2;
subGenerationStop = endOfSection(iii+1);
} else {
ESTYLE_ERROR("Missing { in " << elem);
typePop();
continue;
}
iii = generateBrace(subGenerationStart, subGenerationStop, needBrace, true);
if (haveBrace == true) {
iii--;
} else {
iii -= 2;
}
typePop();
continue;
}
if ( elem == estyle::lexer::ELEMENT_FUNCTION
|| elem == estyle::lexer::ELEMENT_FUNCTION_DECLARATION) {
addNewLineIfSemiColon();
addSpaceIfNeeded();
typePush("function");
//addSpace();
m_output += m_lexer.getData(iii);
//offsetPush(m_lexer.getData(iii).size() + 2);
offsetPushAuto();
for (int64_t jjj=iii+1; jjj<m_lexer.size(); ++jjj) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(jjj);
if (elem == estyle::lexer::RESERVED_NEW_LINE) {
// OK ==> normal case ...
} else if (elem == estyle::lexer::PARENTHESE_IN) {
// find condition section ...
iii = generateFunction(jjj);
break;
} else {
ESTYLE_ERROR("Get '" << m_lexer.getData(iii) << "' (function) without '(' element");
}
}
offsetPop();
if (elem == estyle::lexer::ELEMENT_FUNCTION_DECLARATION) {
// nothing more to do ... end of declaration
continue;
}
int32_t subGenerationStart = iii+1;
int32_t subGenerationStop = iii+1;
subGenerationStart = iii+2;
subGenerationStop = endOfSection(iii+1);
iii = generateBrace(subGenerationStart, subGenerationStop, true);
//iii--;
typePop();
}
// default other case:
//addSpace();
if (startWithText(m_lexer.getData(iii)) == true) {
addSpaceIfNeeded();
}
m_output += m_lexer.getData(iii);
}
return _stopId+1;
}
int64_t estyle::Generator::generateBrace(int64_t _start, int64_t _stop, bool _needBrace, bool _checkElse) {
/*
ESTYLE_ERROR(" single " << propertyBrace[m_type].single.get());
ESTYLE_ERROR(" inNewLineBefore " << propertyBrace[m_type].inNewLineBefore.get());
ESTYLE_ERROR(" inSpaceBefore " << propertyBrace[m_type].inSpaceBefore.get());
ESTYLE_ERROR(" inSpaceAfter " << propertyBrace[m_type].inSpaceAfter.get());
ESTYLE_ERROR(" inNewLineAfter " << propertyBrace[m_type].inNewLineAfter.get());
ESTYLE_ERROR(" outNewLineBefore " << propertyBrace[m_type].outNewLineBefore.get());
ESTYLE_ERROR(" outSpaceBefore " << propertyBrace[m_type].outSpaceBefore.get());
ESTYLE_ERROR(" outSpaceAfter " << propertyBrace[m_type].outSpaceAfter.get());
ESTYLE_ERROR(" outNewLineAfter " << propertyBrace[m_type].outNewLineAfter.get());
*/
int32_t rawSize = countRawSize(_start, _stop);
ESTYLE_ERROR(" rawSize = " << rawSize);
bool removeNewLine = propertyBrace[m_type].oneLineMaxSize.get() >= rawSize;
ESTYLE_ERROR("check: " << propertyBrace[m_type].oneLineMaxSize.get() << " >= " << rawSize);
if (_needBrace == false) {
if (propertyBrace[m_type].single.get() == false) {
_needBrace = true;
}
}
if ( _needBrace == true
|| rawSize == 0) {
if (propertyBrace[m_type].inIndentBefore.get() == true) {
indentationPush();
addIndent();
}
if ( propertyBrace[m_type].inNewLineBefore.get() == true
&& removeNewLine == false) {
addNewLine();
addSpace();
} else if (propertyBrace[m_type].inSpaceBefore.get() == true) {
addSpace();
}
m_output += "{";
if (propertyBrace[m_type].inIndentAfter.get() == true) {
indentationPush();
}
if ( propertyBrace[m_type].inNewLineAfter.get() == true
&& removeNewLine == false) {
addNewLine();
} else if ( propertyBrace[m_type].inSpaceAfter.get() == true
&& rawSize != 0) {
addSpace();
}
if (rawSize == 0) {
if ( m_output.back() == '\n'
|| m_output.back() == '\r') {
if (propertyBrace[m_type].emptyIndent.get() == true) {
addIndent();
addNewLine(true);
}
} else if (propertyBrace[m_type].emptySpace.get() == true) {
addSpace();
}
}
} else {
if (propertyBrace[m_type].singleIndent.get() == true) {
indentationPush();
}
if ( propertyBrace[m_type].singleInNewLine.get() == true
&& removeNewLine == false) {
addNewLine();
} else if (propertyBrace[m_type].singleInSpace.get() == true) {
addSpace();
} else {
addSpaceIfNeeded();
}
}
// TODO: maybe check the last element
int64_t out = process(_start, _stop);
if (_needBrace == true) {
if (propertyBrace[m_type].outUnIndentBefore.get() == true) {
indentationPop();
}
if ( propertyBrace[m_type].outNewLineBefore.get() == true
&& removeNewLine == false) {
addNewLine();
addSpace();
} else if ( propertyBrace[m_type].outSpaceBefore.get() == true
&& rawSize != 0) {
addSpace();
}
m_output += "}";
if (propertyBrace[m_type].outUnIndentAfter.get() == true) {
indentationPop();
}
if ( propertyBrace[m_type].outSpaceAfter.get() == true
&& propertyBrace[m_type].outNewLineAfter.get() == false) {
// add 1 space if needed
addSpace();
}
// special case for a else after a condition ...
if (_checkElse == true) {
if (nextIs(_stop, estyle::lexer::RESERVED_ELSE) == false) {
if (propertyBrace[m_type].outNewLineAfter.get() == true) {
addNewLine();
}
}
} else {
if (propertyBrace[m_type].outNewLineAfter.get() == true) {
addNewLine();
}
}
} else {
if (propertyBrace[m_type].singleIndent.get() == true) {
indentationPop();
}
if (propertyBrace[m_type].singleOutSpace.get() == true) {
// add 1 space if needed
addSpace();
}
// special case for a else after a condition ...
if (_checkElse == true) {
if (nextIs(_stop, estyle::lexer::RESERVED_ELSE) == false) {
if (propertyBrace[m_type].singleOutNewLine.get() == true) {
addNewLine();
}
}
} else {
if (propertyBrace[m_type].singleOutNewLine.get() == true) {
addNewLine();
}
}
}
return out;
}
// go ackward and find if previous is the corect type (remove) \n and empty space ==> not comment they need to add it (wrong place but not may job ...
bool estyle::Generator::previousIs(int64_t _pos, enum estyle::lexer::tocken _previousType) {
for (int32_t iii=_pos-1; iii>0; --iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
if (elem == estyle::lexer::RESERVED_NEW_LINE) {
continue;
}
return elem == _previousType;
}
return false;
}
bool estyle::Generator::nextIs(int64_t _pos, enum estyle::lexer::tocken _nextType) {
for (int32_t iii=_pos; iii<m_lexer.size(); ++iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
ESTYLE_VERBOSE("check if next: " << _nextType << " on " << elem);
if (elem == estyle::lexer::RESERVED_NEW_LINE) {
continue;
}
return elem == _nextType;
}
return false;
}
int64_t estyle::Generator::generateCondition(int64_t _pos) {
ESTYLE_INFO(" single " << propertyParenthese[m_type].single.get());
ESTYLE_INFO(" inNewLineBefore " << propertyParenthese[m_type].inNewLineBefore.get());
ESTYLE_INFO(" inNewLineAfter " << propertyParenthese[m_type].inNewLineAfter.get());
ESTYLE_INFO(" inSpaceBefore " << propertyParenthese[m_type].inSpaceBefore.get());
ESTYLE_INFO(" inSpaceAfter " << propertyParenthese[m_type].inSpaceAfter.get());
ESTYLE_INFO(" inIndentBefore " << propertyParenthese[m_type].inIndentBefore.get());
ESTYLE_INFO(" inIndentAfter " << propertyParenthese[m_type].inIndentAfter.get());
ESTYLE_INFO(" outNewLineBefore " << propertyParenthese[m_type].outNewLineBefore.get());
ESTYLE_INFO(" outNewLineAfter " << propertyParenthese[m_type].outNewLineAfter.get());
ESTYLE_INFO(" outSpaceBefore " << propertyParenthese[m_type].outSpaceBefore.get());
ESTYLE_INFO(" outSpaceAfter " << propertyParenthese[m_type].outSpaceAfter.get());
ESTYLE_INFO(" outUnIndentBefore " << propertyParenthese[m_type].outUnIndentBefore.get());
ESTYLE_INFO(" outUnIndentAfter " << propertyParenthese[m_type].outUnIndentAfter.get());
int32_t sectionEnd = endOfSection(_pos);
int32_t nbCondition = countCurrentLevelCondition(_pos);
int32_t rawSize = countRawSize(_pos, sectionEnd);
bool removeNewLine = propertyParenthese[m_type].oneLineMaxSize.get() >= rawSize;
if (propertyParenthese[m_type].oneLineMaxSize.get() == -1) {
removeNewLine = false;
}
if (propertyParenthese[m_type].inIndentBefore.get() == true) {
ESTYLE_INFO(" ==> indent Before");
indentationPush();
addIndent();
}
if ( propertyParenthese[m_type].inNewLineBefore.get() == true
&& removeNewLine == false) {
addNewLine();
addSpace();
} else if (propertyParenthese[m_type].inSpaceBefore.get() == true) {
addSpace();
}
m_output += "(";
if (propertyParenthese[m_type].inIndentAfter.get() == true) {
ESTYLE_INFO(" ==> indent After");
indentationPush();
}
if ( propertyParenthese[m_type].inNewLineAfter.get() == true
&& removeNewLine == false) {
addNewLine();
} else if ( propertyParenthese[m_type].inSpaceAfter.get() == true
&& rawSize != 0) {
addSpace();
}
if (rawSize == 0) {
if ( m_output.back() == '\n'
|| m_output.back() == '\r') {
if (propertyParenthese[m_type].emptyIndent.get() == true) {
addIndent();
addNewLine(true);
}
} else if (propertyParenthese[m_type].emptySpace.get() == true) {
addSpace();
}
}
if ( nbCondition == 0
|| removeNewLine == true
|| propertyCondition[m_type].get() == 0) {
ESTYLE_WARNING("==> only one element");
process(_pos+1, sectionEnd);
} else {
if (propertyCondition[m_type].get() == 1) {
m_output += " ";
offsetPushAuto();
for (int64_t iii=_pos+1; iii<=sectionEnd; ++iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
if (elem == estyle::lexer::PARENTHESE_IN) {
iii = generateCondition(iii);
} else if ( elem == estyle::lexer::AND_AND
|| elem == estyle::lexer::OR_OR) {
addNewLine();
offsetPop();
addSpace();
offsetPush(5);
m_output += " " + m_lexer.getData(iii) + " ";
} else {
iii = process(iii, sectionEnd, estyle::lexer::AND_AND, estyle::lexer::OR_OR, estyle::lexer::PARENTHESE_IN, estyle::lexer::PARENTHESE_OUT);
iii--;
}
}
} else {
ESTYLE_ERROR("UN-impllemented methode of condition ... ==> TODO");
process(_pos+1, sectionEnd);
}
offsetPop();
}
if (propertyParenthese[m_type].outUnIndentBefore.get() == true) {
indentationPop();
}
if ( propertyParenthese[m_type].outNewLineBefore.get() == true
&& removeNewLine == false) {
addNewLine();
addSpace();
} else if ( propertyParenthese[m_type].outSpaceBefore.get() == true
&& rawSize != 0) {
addSpace();
}
m_output += ")";
if (propertyParenthese[m_type].outUnIndentAfter.get() == true) {
indentationPop();
}
if ( propertyParenthese[m_type].outSpaceAfter.get() == true
&& propertyParenthese[m_type].outNewLineAfter.get() == false) {
// add 1 space if needed
addSpace();
}
if (propertyParenthese[m_type].outNewLineAfter.get() == true) {
addNewLine();
}
return sectionEnd;
}
int64_t estyle::Generator::generateFunction(int64_t _pos) {
int32_t sectionEnd = endOfSection(_pos);
int32_t nbParameters = countCurrentParameters(_pos);
m_output += "(";
offsetPushAuto();
if (nbParameters == 0) {
process(_pos + 1, sectionEnd);
} else {
for (int64_t iii=_pos+1; iii<=sectionEnd; ++iii) {
iii = process(iii, sectionEnd, estyle::lexer::COMA, estyle::lexer::PARENTHESE_OUT);
if (nextIs(iii-1, estyle::lexer::PARENTHESE_OUT) == false) {
m_output += ",";
addNewLine();
addSpace();
}
}
}
//addSpace();
m_output += ")";
offsetPop();
return sectionEnd;
}
int64_t estyle::Generator::endOfSection(int64_t _pos) {
ESTYLE_VERBOSE(" " << m_lexer.getTocken(_pos) << " " << _pos << " [BEGIN]");
enum estyle::lexer::tocken endTocken = estyle::lexer::END_OF_FILE;
enum estyle::lexer::tocken elem = m_lexer.getTocken(_pos);
if (elem == estyle::lexer::PARENTHESE_IN) {
endTocken = estyle::lexer::PARENTHESE_OUT;
} else if (elem == estyle::lexer::BRACKET_IN) {
endTocken = estyle::lexer::BRACKET_OUT;
} else if (elem == estyle::lexer::BRACE_IN) {
endTocken = estyle::lexer::BRACE_OUT;
} else {
ESTYLE_ERROR("can not get end position of " << m_lexer.getTocken(_pos));
return _pos;
}
for (int64_t iii=_pos+1; iii < m_lexer.size(); ++iii) {
elem = m_lexer.getTocken(iii);
if (elem == endTocken) {
return iii;
}
if ( elem == estyle::lexer::PARENTHESE_IN
|| elem == estyle::lexer::BRACKET_IN
|| elem == estyle::lexer::BRACE_IN) {
iii = endOfSection(iii);
}
}
return m_lexer.size();
}
int64_t estyle::Generator::endOfAction(int64_t _pos) {
ESTYLE_VERBOSE(" " << m_lexer.getTocken(_pos) << " " << _pos << " [BEGIN]");
for (int64_t iii=_pos+1; iii < m_lexer.size(); ++iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
if (elem == estyle::lexer::SEMICOLON) {
return iii;
}
if ( elem == estyle::lexer::PARENTHESE_IN
|| elem == estyle::lexer::BRACKET_IN
|| elem == estyle::lexer::BRACE_IN) {
iii = endOfSection(iii);
return iii;
}
}
return m_lexer.size();
}
int32_t estyle::Generator::countCurrent(int64_t _pos,
int64_t _posEnd,
enum estyle::lexer::tocken _type1,
enum estyle::lexer::tocken _type2,
enum estyle::lexer::tocken _type3,
enum estyle::lexer::tocken _type4) {
int32_t out = 0;
enum estyle::lexer::tocken endTocken = estyle::lexer::END_OF_FILE;
enum estyle::lexer::tocken elem = m_lexer.getTocken(_pos);
if (elem == estyle::lexer::PARENTHESE_IN) {
endTocken = estyle::lexer::PARENTHESE_OUT;
} else if (elem == estyle::lexer::BRACKET_IN) {
endTocken = estyle::lexer::BRACKET_OUT;
} else if (elem == estyle::lexer::BRACE_IN) {
endTocken = estyle::lexer::BRACE_OUT;
} else {
ESTYLE_ERROR("can not get end position of " << m_lexer.getTocken(_pos));
return _pos;
}
int64_t lastStart = _pos+1;
int64_t iii;
for (iii=_pos+1; iii < _posEnd; ++iii) {
elem = m_lexer.getTocken(iii);
if (elem == endTocken) {
/*
ESTYLE_ERROR("end tocke detected : " << iii << " > " << (lastStart+1) );
if (iii > lastStart+1) {
out++;
}
*/
return out;
}
if ( elem == estyle::lexer::PARENTHESE_IN
|| elem == estyle::lexer::BRACKET_IN
|| elem == estyle::lexer::BRACE_IN) {
iii = endOfSection(iii);
}
if ( _type1 == elem
|| _type2 == elem
|| _type3 == elem
|| _type4 == elem) {
out++;
ESTYLE_ERROR("detect type : " << iii);
lastStart = iii;
}
}
/*
if (iii == lastStart+1) {
out++;
}
*/
return out;
}
int32_t estyle::Generator::countCurrentLevelCondition(int64_t _pos) {
return countCurrent(_pos,
m_lexer.size(),
estyle::lexer::AND_AND,
estyle::lexer::OR_OR);
}
int32_t estyle::Generator::countCurrentParameters(int64_t _pos) {
return countCurrent(_pos,
m_lexer.size(),
estyle::lexer::COMA);
}
int32_t estyle::Generator::countCurrentAction(int64_t _pos) {
return countCurrent(_pos,
m_lexer.size(),
estyle::lexer::SEMICOLON);
}
int32_t estyle::Generator::countCurrentAction(int64_t _pos, int64_t _posEnd) {
return countCurrent(_pos,
_posEnd,
estyle::lexer::SEMICOLON);
}
int32_t estyle::Generator::countCurrentLevelComa(int64_t _pos) {
int32_t out = 0;
enum estyle::lexer::tocken endTocken = estyle::lexer::END_OF_FILE;
enum estyle::lexer::tocken elem = m_lexer.getTocken(_pos);
if (elem == estyle::lexer::PARENTHESE_IN) {
endTocken = estyle::lexer::PARENTHESE_OUT;
} else if (elem == estyle::lexer::BRACKET_IN) {
endTocken = estyle::lexer::BRACKET_OUT;
} else if (elem == estyle::lexer::BRACE_IN) {
endTocken = estyle::lexer::BRACE_OUT;
} else {
ESTYLE_ERROR("can not get end position of " << m_lexer.getTocken(_pos));
return _pos;
}
for (int64_t iii=_pos+1; iii < m_lexer.size(); ++iii) {
elem = m_lexer.getTocken(iii);
if (elem == endTocken) {
return out;
}
if ( elem == estyle::lexer::PARENTHESE_IN
|| elem == estyle::lexer::BRACKET_IN
|| elem == estyle::lexer::BRACE_IN) {
iii = endOfSection(iii);
}
if (elem == estyle::lexer::COMA) {
out++;
}
}
return out;
}
int32_t estyle::Generator::getWhileCondition(int64_t _pos) {
enum estyle::lexer::tocken endTocken = estyle::lexer::PARENTHESE_OUT;
for (int64_t iii=_pos; iii < m_lexer.size(); ++iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
if (elem == endTocken) {
return iii;
}
if ( elem == estyle::lexer::PARENTHESE_IN
|| elem == estyle::lexer::BRACKET_IN
|| elem == estyle::lexer::BRACE_IN) {
iii = endOfSection(iii);
}
if ( elem == estyle::lexer::AND_AND
|| elem == estyle::lexer::OR_OR) {
return iii;
}
}
return m_lexer.size();
}
etk::String estyle::Generator::generateType(int64_t _pos) {
etk::String out;
enum estyle::lexer::tocken elem = m_lexer.getTocken(_pos);
if (elem == estyle::lexer::ELEMENT_COMPLEX_TYPE) {
etk::Vector<estyle::LexerElement> listElement = m_lexer.getSubList(_pos);
for (size_t iii=0; iii<listElement.size(); ++iii) {
enum estyle::lexer::tocken elem2 = listElement[iii].getTocken();
if (elem2 == estyle::lexer::RESERVED_NEW_LINE) {
continue;
}
if (iii != 0) {
out += " ";
}
out += m_lexer.getDataSource(listElement[iii].getStart(), listElement[iii].getStop());
}
} else {
out = m_lexer.getData(_pos);
}
return out;
}
int32_t estyle::Generator::countRawSize(int64_t _pos, int64_t _posEnd) {
int32_t out = 0;
for (int64_t iii=_pos; iii<_posEnd; ++iii) {
enum estyle::lexer::tocken elem = m_lexer.getTocken(iii);
if (elem == estyle::lexer::ELEMENT_COMPLEX_TYPE) {
etk::Vector<estyle::LexerElement> listElement = m_lexer.getSubList(_pos);
for (size_t jjj=0; jjj<listElement.size(); ++jjj) {
enum estyle::lexer::tocken elem2 = listElement[jjj].getTocken();
if (elem2 == estyle::lexer::RESERVED_NEW_LINE) {
continue;
}
out += (listElement[jjj].getStop() - listElement[jjj].getStart());
}
} else {
ESTYLE_WARNING("add Size : '" << m_lexer.getData(iii) << "' " << out << " +=" << m_lexer.getData(iii).size());
out += m_lexer.getData(iii).size();
}
}
return out;
}