in Arriba/Arriba/Model/Query/QueryParser.cs [409:504]
private IExpression ParseOperatorAndValue(string columnName, bool includeHintTerms, bool wasExplicitColumnName)
{
if (!IsCompareOperator(_scanner.Current.Type))
{
// If this is the end of the query and the start of an operator, assume the user wants to finish typing it
string possibleOperatorPrefix = String.Empty;
if (_scanner.IsLastToken())
{
if (_scanner.Current.Content == "|" || _scanner.Current.Content == "!")
{
possibleOperatorPrefix = _scanner.Current.Content;
_scanner.Next();
}
}
if (wasExplicitColumnName)
{
// "[ColumnName]" -> make it a not equals empty term, indicate operator needs completion
if (includeHintTerms)
{
return new TermExpression(columnName, Operator.NotEquals, String.Empty) { Guidance = new IntelliSenseGuidance(possibleOperatorPrefix, QueryTokenCategory.CompareOperator) };
}
else
{
return null;
}
}
else
{
if (possibleOperatorPrefix == String.Empty)
{
// "BareTerm" -> next thing could be a compare operator or another term
return new TermExpression(columnName) { Guidance = new IntelliSenseGuidance(String.Empty, QueryTokenCategory.CompareOperator | QueryTokenCategory.BooleanOperator | QueryTokenCategory.Term) };
}
else
{
// "BareTerm !" -> could be a compare operator or boolean operator, but can't be a column or term because it would require escaping
return new TermExpression(columnName) { Guidance = new IntelliSenseGuidance(possibleOperatorPrefix, QueryTokenCategory.CompareOperator | QueryTokenCategory.BooleanOperator) };
}
}
}
Operator op = ConvertToOperator(_scanner.Current.Type);
string opString = _scanner.Current.Content;
_scanner.Next();
// Parse value
bool hadExplicitValueCompletion;
string value = ParseValue(out hadExplicitValueCompletion);
if (value == null)
{
if (String.IsNullOrEmpty(_scanner.Current.Prefix))
{
// "[ColumnName] =" -> if no space after operator, suggest operator until space is typed
if (includeHintTerms)
{
return new TermExpression(columnName, op, String.Empty) { Guidance = new IntelliSenseGuidance(opString, QueryTokenCategory.CompareOperator) };
}
else
{
return null;
}
}
else
{
// "[ColumnName] = " -> time for the value
if (includeHintTerms)
{
return new TermExpression(columnName, op, String.Empty) { Guidance = new IntelliSenseGuidance(String.Empty, QueryTokenCategory.Value) };
}
else
{
return null;
}
}
}
else
{
if (!hadExplicitValueCompletion)
{
// "[ColumnName] = \"Value" -> indicate value incomplete
return new TermExpression(columnName, op, value) { Guidance = new IntelliSenseGuidance(value, QueryTokenCategory.Value) };
}
else if (_scanner.Current.Type == TokenType.End && String.IsNullOrEmpty(_scanner.Current.Prefix))
{
// "[ColumnName] = \"Value\"" [no trailing space] -> don't suggest anything yet
return new TermExpression(columnName, op, value) { Guidance = new IntelliSenseGuidance(String.Empty, QueryTokenCategory.None) };
}
else
{
// "[ColumnName] = \"Value\" " [trailing space] -> time for next term (boolean operator, next column name, or next bare value)
return new TermExpression(columnName, op, value) { Guidance = new IntelliSenseGuidance(String.Empty, QueryTokenCategory.BooleanOperator | QueryTokenCategory.Term) };
}
}
}