#include "GuiLanguageAutoComplete.h"
#include "../../GuiApplication.h"
namespace
{
namespace
{
namespace
{
using
namespace
elements
;
using
namespace
regex
;
using
namespace
parsing
;
using
namespace
parsing
::
tabling
;
using
namespace
collections
;
void
::
(
elements
::
*
,
&
,
compositions
::
*
,
)
{
GuiTextBoxAutoCompleteBase
::
(
,
,
,
);
::
::
(
,
,
,
);
}
void
::
()
{
GuiTextBoxAutoCompleteBase
::
();
::
::
();
if
(
&&
)
{
EnsureAutoCompleteFinished
();
}
}
void
::
(
&
)
{
GuiTextBoxAutoCompleteBase
::
(
);
::
::
(
);
if
(
&&
)
{
if
(
() &&
.
&&
.
==
L""
&&
.
!=
L""
)
{
=
();
if
(
selectedItem
!=
L""
)
{
=
();
=
.
;
=
->
().
(
begin
,
end
);
editingText
.
;
if
(
()
().
().
(
editingText
))
{
.
begin
;
.
=
selectedItem
+
.
;
();
}
}
}
}
}
void
::
(
const
&
)
{
GuiTextBoxAutoCompleteBase
::
(
);
::
::
(
);
if
(
&&
)
{
=
true
;
SPIN_LOCK(editTraceLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
.
(
);
}
}
}
void
::
(
const
&
)
{
GuiTextBoxAutoCompleteBase
::
(
);
::
::
(
);
if
(
&&
)
{
SPIN_LOCK(editTraceLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
;
trace
.
=
.
;
trace
.
.
;
trace
.
.
;
trace
.
.
;
trace
.
.
;
if
(
trace
.
trace
.
)
{
=
trace
.
;
trace
.
trace
.
;
trace
.
temp
;
}
if
(
trace
.
trace
.
)
{
=
trace
.
;
trace
.
trace
.
;
trace
.
temp
;
}
.
(
trace
);
}
SPIN_LOCK(contextLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
if
(
.
.
)
{
if
(
)
{
;
input
.
=
.
.
;
(
input
);
}
else
if
(
.
.
==
.
)
{
(
.
);
}
}
}
}
}
void
::
(
)
{
GuiTextBoxAutoCompleteBase
::
(
);
::
::
(
);
if
(
&&
)
{
=
false
;
}
}
void
::
(
const
&
)
{
if
(
&&
)
{
()->
(
->
(), [=]()
{
(
);
});
}
}
void
::
CollectLeftRecursiveRules
()
{
.
();
<
>
=
();
<
>
=
parser
();
=
table
();
=
table
();
for
(
=
0
;
i
<
stateCount
;
i
++)
{
for
(
=
0
;
j
<
tokenCount
;
j
++)
{
<
::
>
=
table
(
i
,
j
);
if
(
bag
)
{
FOREACH(Ptr<ParsingTable::TransitionItem>, item, bag->transitionItems)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
::
>>&
= ::
vl
::
collections
::
(
bag
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
::
>
;
__foreach_iterator__
.
(
item
);)
{
FOREACH(ParsingTable::Instruction, ins, item->instructions)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
>&
= ::
vl
::
collections
::
(
item
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
;
__foreach_iterator__
.
(
ins
);)
{
if
(
ins
.
==
::
::
)
{
if
(!
.
(
ins
.
))
{
.
(
ins
.
);
}
}
}
}
}
}
}
}
::
(
)
{
=
0
;
=
.
() -
1
;
while
(
start
<=
end
)
{
= (
start
+
end
) /
2
;
&
=
middle
];
if
(
<
trace
.
)
{
end
=
middle
-
1
;
}
else
if
(
>
trace
.
)
{
start
=
middle
+
1
;
}
else
{
while
(
middle
<
.
() -
1
)
{
if
(
middle
+
1
].
==
middle
].
)
{
middle
++;
}
else
{
break
;
}
}
return
middle
;
}
}
return
-
1
;
}
::
(
,
const
regex
::
&
)
{
<
>
=
();
;
lastToken
.
=
0
;
FOREACH(RegexToken, token, tokens)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
token
);)
{
if
(
(
token
.
,
token
.
+
1
)
)
{
if
(
table
(
token
.
)!=-
1
&&
lastToken
.
)
{
(
lastToken
.
,
lastToken
.
);
}
break
;
}
lastToken
token
;
}
return
;
}
void
::
(
&
)
{
,
;
{
SPIN_LOCK(editTraceLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
=
(
.
.
);
if
(
traceIndex
== -
1
)
return
;
&
=
traceIndex
];
startPos
trace
.
;
endPos
trace
.
;
}
const
&
=
()
();
=
lexer
.
(
.
.
);
startPos
(
startPos
,
tokens
);
}
(
startPos
.
,
startPos
.
);
(
endPos
.
,
endPos
.
);
(
start
,
end
);
*
=
.
.
(
range
);
*
=
0
;
if
(!
found
||
startPos
==
(
0
,
0
))
{
found
=
.
.
.
();
}
if
(!
selectedNode
)
{
*
=
0
;
*
=
found
;
while
(
current
)
{
*
=
dynamic_cast
<
*>(
current
);
if
(
obj
)
{
FOREACH(WString, rule, obj->GetCreatorRules())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
obj
->
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
rule
);)
{
if
(
.
(
rule
))
{
lrec
=
obj
;
break
;
}
}
if
(
obj
&&
lrec
&&
lrec
!=
obj
)
{
selectedNode
=
lrec
;
break
;
}
}
current
=
current
->
();
}
}
if
(!
selectedNode
)
{
*
=
found
;
while
(
current
)
{
*
=
dynamic_cast
<
*>(
current
);
if
(
obj
)
{
selectedNode
=
obj
;
break
;
}
current
=
current
->
();
}
}
if
(
selectedNode
)
{
start
selectedNode
->
().
;
end
selectedNode
->
().
;
.
selectedNode
->
()
selectedNode
->
().
() -
1
];
.
selectedNode
->
();
.
dynamic_cast
<
*>(
selectedNode
);
.
.
;
.
=
.
.
;
if
(
start
.
>=
0
&&
end
.
>=
0
)
{
.
=
.
.
.
(
start
.
,
end
.
-
start
.
+
1
).
();
}
}
}
bool
::
(
&
,
elements
::
text
::
&
,
&
)
{
(
.
.
.
,
.
.
.
);
=
.
() <=
1
?
(
start
.
,
start
.
+
.
(
0
).
)
:
(
start
.
+
.
() -
1
,
.
(
.
() -
1
).
)
;
if
(
start
&&
<=
end
)
{
.
-=
start
.
;
if
(
.
==
0
)
{
.
-=
start
.
;
}
return
true
;
}
else
{
return
false
;
}
}
void
::
(
&
)
{
<
>
;
{
SPIN_LOCK(editTraceLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
(
usedTrace
,
(
)
.Where([&newContext](
const
&
)
{
return
(
value
.
L""
||
value
.
!=
L""
) &&
value
.
>
.
;
})
);
}
}
bool
=
false
;
if
(
usedTrace
.
() >
0
)
{
if
(
usedTrace
0
].
!=
.
+
1
)
{
failed
=
true
;
}
else
{
text
::
(
nullptr
);
lines
.
(
.
);
FOREACH(TextEditNotifyStruct, trace, usedTrace)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
usedTrace
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
trace
);)
{
=
trace
.
;
=
trace
.
;
if
(
(
,
lines
,
start
) &&
(
,
lines
,
end
))
{
lines
.
(
start
,
end
,
trace
.
);
}
else
{
failed
=
true
;
break
;
}
}
if
(!
failed
)
{
.
lines
.
();
}
}
}
if
(
failed
)
{
.
0
;
}
if
(
usedTrace
.
() >
0
)
{
.
=
usedTrace
usedTrace
.
() -
1
].
;
}
}
void
::
(
collections
::
<
parsing
::
tabling
::
::
*>&
)
{
FOREACH(ParsingState::Future*, future, futures)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
*>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
*
;
__foreach_iterator__
.
(
future
);)
{
delete
future
;
}
.
();
}
regex
::
*
::
(
parsing
::
tabling
::
&
,
parsing
::
tabling
::
ParsingTransitionCollector
&
,
,
collections
::
<
parsing
::
tabling
::
::
*>&
,
collections
::
<
parsing
::
tabling
::
::
*>&
)
{
const
<
::
>&
=
.
();
for
(
=
0
;
index
<
transitions
.
();
index
++)
{
const
::
&
=
transitions
index
];
switch
(
transition
.
)
{
case
::
::
:
break
;
case
::
::
:
index
=
.
(
.
GetAmbiguityBeginFromBranch
(
index
));
break
;
case
::
::
:
break
;
case
::
::
:
{
if
(
transition
.
)
{
(
transition
.
->
,
transition
.
->
+
1
);
if
(
tokenEnd
)
{
return
transition
.
;
}
else
if
(
tokenEnd
)
{
if
(!
()
().
().
(
transition
.
->
,
transition
.
->
))
{
return
transition
.
;
}
}
}
=
transition
.
;
<
::
*>
;
if
(
.
() >
0
)
{
FOREACH(ParsingState::Future*, future, recoveryFutures)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
*>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
*
;
__foreach_iterator__
.
(
future
);)
{
.
(
tableTokenIndex
,
future
,
possibilities
);
}
}
else
{
FOREACH(ParsingState::Future*, future, nonRecoveryFutures)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
*>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
*
;
__foreach_iterator__
.
(
future
);)
{
.
(
tableTokenIndex
,
future
,
possibilities
);
}
}
<
::
*>
;
for
(
=
0
;
i
<
possibilities
.
();
i
++)
{
::
*
=
possibilities
i
];
bool
=
false
;
FOREACH(ParsingState::Future*, future, selectedPossibilities)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
*>&
= ::
vl
::
collections
::
(
selectedPossibilities
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
*
;
__foreach_iterator__
.
(
future
);)
{
if
(
candidateFuture
->
==
future
->
&&
candidateFuture
->
==
future
->
&&
candidateFuture
->
.
() ==
future
->
.
()
)
{
bool
=
true
;
for
(
=
0
;
j
<
future
->
.
();
j
++)
{
if
(
candidateFuture
->
i
] !=
future
->
i
])
{
same
=
false
;
break
;
}
}
if
((
duplicated
=
same
))
{
break
;
}
}
}
if
(
duplicated
)
{
delete
candidateFuture
;
}
else
{
selectedPossibilities
.
(
candidateFuture
);
}
}
if
(
transition
.
||
transition
.
==
::
)
{
(
);
(
);
(
,
selectedPossibilities
);
}
else
{
(
);
(
,
selectedPossibilities
);
}
}
break
;
default
:;
}
}
return
0
;
}
regex
::
*
::
(
parsing
::
tabling
::
&
,
parsing
::
tabling
::
ParsingTransitionCollector
&
,
,
&
,
collections
::
<
>&
)
{
.
(
.
);
<
::
*>
,
;
nonRecoveryFutures
.
(
.
());
*
=
(
,
,
,
nonRecoveryFutures
,
recoveryFutures
);
<
::
*>
;
for
(
=
0
;
i
<
nonRecoveryFutures
.
();
i
++)
{
.
(
::
,
nonRecoveryFutures
i
],
nonRecoveryFutures
);
.
(
::
,
nonRecoveryFutures
i
],
nonRecoveryFutures
);
}
FOREACH(ParsingState::Future*, future, nonRecoveryFutures)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
*>&
= ::
vl
::
collections
::
(
nonRecoveryFutures
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
*
;
__foreach_iterator__
.
(
future
);)
{
=
.
()
();
for
(
=
::
;
i
<
count
;
i
++)
{
.
(
i
,
future
,
possibilities
);
}
}
FOREACH(ParsingState::Future*, future, possibilities)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
*>&
= ::
vl
::
collections
::
(
possibilities
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
*
;
__foreach_iterator__
.
(
future
);)
{
if
(!
.
(
future
->
))
{
.
(
future
->
);
}
}
(
possibilities
);
(
nonRecoveryFutures
);
(
recoveryFutures
);
return
token
;
}
::
GlobalTextPosToModifiedTextPos
(
&
,
)
{
.
-=
.
.
.
;
if
(
.
==
0
)
{
.
-=
.
.
.
;
}
return
;
}
::
ModifiedTextPosToGlobalTextPos
(
&
,
)
{
if
(
.
==
0
)
{
.
+=
.
.
.
;
}
.
+=
.
.
.
;
return
;
}
void
::
(
&
)
{
(
.
,
());
state
.
(
.
);
ParsingTransitionCollector
;
<
<
>>
;
if
(
(
state
,
collector
,
errors
))
{
if
(!
.
)
{
;
builder
.
();
bool
=
true
;
FOREACH(ParsingState::TransitionResult, transition, collector.GetTransitions())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
::
>&
= ::
vl
::
collections
::
(
collector
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
::
;
__foreach_iterator__
.
(
transition
);)
{
if
(!(
succeeded
=
builder
.
(
transition
)))
{
break
;
}
}
if
(
succeeded
)
{
<
>
=
builder
.
();
.
parsedNode
.
<
>();
.
();
}
}
if
(
.
)
{
;
SPIN_LOCK(editTraceLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
=
(
.
);
if
(
index
== -
1
)
{
return
;
}
else
{
trace
index
];
}
}
=
GlobalTextPosToModifiedTextPos
(
,
trace
.
);
<
>
=
new
;
<
>
;
*
=
(
state
,
collector
,
stopPosition
,
,
tableTokenIndices
);
{
FOREACH(vint, token, tableTokenIndices)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
tableTokenIndices
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
token
);)
{
=
token
-
::
;
if
(
regexToken
>=
0
)
{
autoComplete
.
(
regexToken
);
if
(
(
regexToken
).
)
{
autoComplete
.
(
regexToken
);
}
}
}
if
(
editingToken
)
{
(
editingToken
->
,
editingToken
->
);
if
(
tokenPos
stopPosition
)
{
stopPosition
tokenPos
;
}
}
,
;
{
startPos
ModifiedTextPosToGlobalTextPos
(
,
stopPosition
);
autoComplete
startPos
;
endPos
trace
.
;
if
(
.
.
)
{
startPos
GlobalTextPosToModifiedTextPos
(
,
startPos
);
endPos
GlobalTextPosToModifiedTextPos
(
,
endPos
);
}
if
(
startPos
endPos
&&
endPos
.
>
0
)
{
endPos
.
--;
}
}
if
(
editingToken
&&
(
editingToken
->
).
)
{
(
(
startPos
.
,
startPos
.
),
(
endPos
.
,
endPos
.
));
::
(*
autoComplete
.
(),
range
,
.
.
(),
.
());
}
}
.
autoComplete
;
}
}
}
void
::
(
const
&
)
{
SPIN_LOCK(contextLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
if
(
.
<
.
.
)
{
return
;
}
}
;
bool
=
false
;
if
(
.
)
{
newContext
.
;
(
newContext
);
byGlobalCorrection
=
true
;
}
else
{
SPIN_LOCK(contextLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
newContext
;
newContext
.
0
;
newContext
.
0
;
}
if
(
newContext
.
)
{
(
newContext
);
}
}
if
(
newContext
.
)
{
(
newContext
);
}
SPIN_LOCK(contextLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
newContext
;
}
if
(
newContext
.
)
{
(
);
()->
(
->
(), [=]()
{
(
newContext
,
byGlobalCorrection
);
});
}
}
void
::
(
const
&
,
bool
)
{
bool
=
true
;
bool
=
false
;
<
>
=
.
;
if
(!
autoComplete
)
{
openList
=
false
;
}
if
(
openList
)
{
if
(
autoComplete
.
() +
autoComplete
.
() ==
0
)
{
openList
=
false
;
}
}
,
;
;
if
(
openList
)
{
SPIN_LOCK(editTraceLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
=
(
.
);
if
(
traceIndex
== -
1
)
{
return
;
}
if
(
traceIndex
>
0
&&
traceIndex
-
1
].
==
.
)
{
traceIndex
--;
}
if
(
traceIndex
>=
0
)
{
&
=
traceIndex
];
if
(!
trace
.
)
{
openList
=
false
;
}
}
if
(
openList
)
{
keepListState
=
true
;
startPosition
autoComplete
;
endPosition
.
() -
1
].
;
for
(
=
traceIndex
;
i
<
.
();
i
++)
{
&
=
i
];
if
(
trace
.
!=
L""
||
trace
.
!=
L""
)
{
keepListState
=
false
;
}
if
(
trace
.
startPosition
)
{
openList
=
false
;
break
;
}
}
}
if
(
traceIndex
>
0
)
{
.
(
0
,
traceIndex
);
}
}
}
if
(
&& !
())
{
return
;
}
if
(
openList
&&
)
{
editingText
->
().
(
startPosition
,
endPosition
);
if
(
()
().
().
(
editingText
))
{
openList
=
false
;
}
}
if
(
autoComplete
&& ((!
keepListState
&&
openList
) ||
()))
{
<
>
;
<
>
;
FOREACH(vint, token, autoComplete->shownCandidates)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
autoComplete
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
token
);)
{
=
(
token
).
;
if
(
literal
!=
L""
&& !
itemKeys
.
(
literal
))
{
;
item
.
literal
;
item
.
= -
1
;
itemValues
.
(
itemKeys
.
(
literal
),
item
);
}
}
if
(
autoComplete
)
{
FOREACH(ParsingCandidateItem, item, autoComplete->candidateItems)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
autoComplete
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
item
);)
{
if
(
autoComplete
(
item
.
))
{
if
(
item
.
!=
L""
&& !
itemKeys
.
(
item
.
))
{
itemValues
.
(
itemKeys
.
(
item
.
),
item
);
}
}
}
}
<
GuiTextBoxAutoCompleteBase
::
>
;
for
(
=
0
;
i
<
itemValues
.
();
i
++)
{
auto
&
=
itemValues
i
];
if
(
item
.
.
())
{
if
(
auto
=
())
{
item
.
analyzer
CreateTagForCandidateItem
(
item
);
}
}
GuiTextBoxAutoCompleteBase
::
;
candidateItem
.
text
item
.
;
candidateItem
.
item
.
;
candidateItems
.
(
candidateItem
);
}
(
candidateItems
);
}
if
(!
keepListState
)
{
if
(
openList
)
{
(
startPosition
);
}
else
{
();
}
}
if
(
())
{
(
editingText
);
}
}
void
::
()
{
(
()
());
CollectLeftRecursiveRules
();
(
this
);
}
void
::
(
&
)
{
if
(
auto
=
())
{
if
(
.
&&
.
)
{
analyzer
(*
.
.
(),
,
.
);
}
}
}
void
::
EnsureAutoCompleteFinished
()
{
();
SPIN_LOCK(contextLock)
if
(
bool
=
true
)
for
(
const
::
&
=
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
();
}
}
::
(
<
>
)
:
::
(
)
,editing(
false
)
{
();
}
::
(
<
parsing
::
tabling
::
>
,
const
&
)
:
::
(
new
(
,
))
,editing(
false
)
{
();
}
::
()
{
EnsureAutoCompleteFinished
();
(
this
);
}
<
>
::
()
{
return
;
}
}
}
}