Commit fd179ed9 authored by Leandro Melo's avatar Leandro Melo

C++: Accept UTF-8 byte arrays in type of expression

The model uses UTF-8 internally and it makes more sense to only
convert when necessary.

A following commit will rename the source/setSource methods in
document for more clarity too.

Change-Id: I960ea0754efabd1436ad4b4299a57faeb65a8bee
Reviewed-by: default avatarRoberto Raggi <roberto.raggi@nokia.com>
parent edcb065e
......@@ -282,7 +282,7 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken, Scope *
const unsigned begin = tokenAt(startToken).begin();
const unsigned end = tokenAt(endToken).end();
const QString expression = _source.mid(begin, end - begin);
const QByteArray expression = _source.mid(begin, end - begin);
// qDebug() << "*** check expression:" << expression;
if (! scope)
......
......@@ -71,32 +71,31 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
m_environment.clear();
}
QList<LookupItem> TypeOfExpression::operator()(const QString &expression,
QList<LookupItem> TypeOfExpression::operator()(const QByteArray &utf8code,
Scope *scope,
PreprocessMode mode)
{
QString code = expression;
Document::Ptr expressionDoc;
if (mode == Preprocess)
code = preprocessedExpression(expression);
Document::Ptr expressionDoc = documentForExpression(code);
expressionDoc = documentForExpression(preprocessedExpression(utf8code));
else
expressionDoc = documentForExpression(utf8code);
expressionDoc->check();
return this->operator ()(extractExpressionAST(expressionDoc),
expressionDoc,
scope);
}
QList<LookupItem> TypeOfExpression::reference(const QString &expression,
QList<LookupItem> TypeOfExpression::reference(const QByteArray &utf8code,
Scope *scope,
PreprocessMode mode)
{
QString code = expression;
Document::Ptr expressionDoc;
if (mode == Preprocess)
code = preprocessedExpression(expression);
Document::Ptr expressionDoc = documentForExpression(code);
expressionDoc = documentForExpression(preprocessedExpression(utf8code));
else
expressionDoc = documentForExpression(utf8code);
expressionDoc->check();
return reference(extractExpressionAST(expressionDoc), expressionDoc, scope);
}
......@@ -141,9 +140,9 @@ QList<LookupItem> TypeOfExpression::reference(ExpressionAST *expression,
return items;
}
QString TypeOfExpression::preprocess(const QString &expression) const
QByteArray TypeOfExpression::preprocess(const QByteArray &utf8code) const
{
return preprocessedExpression(expression);
return preprocessedExpression(utf8code);
}
ExpressionAST *TypeOfExpression::ast() const
......@@ -174,12 +173,11 @@ ExpressionAST *TypeOfExpression::extractExpressionAST(Document::Ptr doc) const
return doc->translationUnit()->ast()->asExpression();
}
Document::Ptr TypeOfExpression::documentForExpression(const QString &expression) const
Document::Ptr TypeOfExpression::documentForExpression(const QByteArray &utf8code) const
{
// create the expression's AST.
Document::Ptr doc = Document::create(QLatin1String("<completion>"));
const QByteArray bytes = expression.toUtf8();
doc->setSource(bytes);
doc->setSource(utf8code);
doc->parse(Document::ParseExpression);
return doc;
}
......@@ -198,10 +196,10 @@ void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env,
}
}
QString TypeOfExpression::preprocessedExpression(const QString &expression) const
QByteArray TypeOfExpression::preprocessedExpression(const QByteArray &utf8code) const
{
if (expression.trimmed().isEmpty())
return expression;
if (utf8code.trimmed().isEmpty())
return utf8code;
if (! m_environment) {
Environment *env = new Environment(); // ### cache the environment.
......@@ -211,9 +209,6 @@ QString TypeOfExpression::preprocessedExpression(const QString &expression) cons
m_environment = QSharedPointer<Environment>(env);
}
const QByteArray code = expression.toUtf8();
Preprocessor preproc(0, m_environment.data());
const QByteArray preprocessedCode = preproc("<expression>", code);
return QString::fromUtf8(preprocessedCode.constData(), preprocessedCode.size());
return preproc("<expression>", utf8code);
}
......@@ -40,6 +40,7 @@
#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QByteArray>
namespace CPlusPlus {
......@@ -81,7 +82,7 @@ public:
* @param expression The expression to evaluate.
* @param scope The scope enclosing the expression.
*/
QList<LookupItem> operator()(const QString &expression,
QList<LookupItem> operator()(const QByteArray &utf8code,
Scope *scope,
PreprocessMode mode = NoPreprocess);
......@@ -101,7 +102,7 @@ public:
Document::Ptr document,
Scope *scope);
QList<LookupItem> reference(const QString &expression,
QList<LookupItem> reference(const QByteArray &utf8code,
Scope *scope,
PreprocessMode mode = NoPreprocess);
......@@ -109,7 +110,7 @@ public:
Document::Ptr document,
Scope *scope);
QString preprocess(const QString &expression) const;
QByteArray preprocess(const QByteArray &utf8code) const;
/**
* Returns the AST of the last evaluated expression.
......@@ -126,12 +127,12 @@ public:
private:
ExpressionAST *extractExpressionAST(Document::Ptr doc) const;
Document::Ptr documentForExpression(const QString &expression) const;
Document::Ptr documentForExpression(const QByteArray &utf8code) const;
void processEnvironment(Document::Ptr doc, Environment *env,
QSet<QString> *processed) const;
QString preprocessedExpression(const QString &expression) const;
QByteArray preprocessedExpression(const QByteArray &utf8code) const;
private:
Document::Ptr m_thisDocument;
......
......@@ -109,7 +109,7 @@ CPlusPlus::Symbol *AnalyzerUtils::findSymbolUnderCursor()
CPlusPlus::TypeOfExpression typeOfExpression;
typeOfExpression.init(doc, snapshot);
const QList<CPlusPlus::LookupItem> &lookupItems = typeOfExpression(expression, scope);
const QList<CPlusPlus::LookupItem> &lookupItems = typeOfExpression(expression.toUtf8(), scope);
if (lookupItems.isEmpty())
return 0;
......
......@@ -508,8 +508,7 @@ bool CheckSymbols::visit(MemberAccessAST *ast)
const QByteArray expression = _doc->source().mid(start.begin(), end.end() - start.begin());
const QList<LookupItem> candidates =
typeOfExpression(QLatin1String(expression), enclosingScope(),
TypeOfExpression::Preprocess);
typeOfExpression(expression, enclosingScope(), TypeOfExpression::Preprocess);
addClassMember(candidates, ast->member_name);
}
}
......@@ -534,8 +533,8 @@ bool CheckSymbols::visit(CallAST *ast)
const QByteArray expression = textOf(access);
const QList<LookupItem> candidates =
typeOfExpression(QLatin1String(expression), enclosingScope(),
TypeOfExpression::Preprocess);
typeOfExpression(expression, enclosingScope(),
TypeOfExpression::Preprocess);
NameAST *memberName = access->member_name;
if (QualifiedNameAST *q = memberName->asQualifiedName())
......@@ -552,7 +551,7 @@ bool CheckSymbols::visit(CallAST *ast)
exprName = q->unqualified_name;
const QList<LookupItem> candidates =
typeOfExpression(QLatin1String(textOf(idExpr)), enclosingScope(),
typeOfExpression(textOf(idExpr), enclosingScope(),
TypeOfExpression::Preprocess);
addVirtualMethod(candidates, exprName, argumentCount);
}
......
......@@ -362,7 +362,8 @@ struct CanonicalSymbol
static Symbol *canonicalSymbol(Scope *scope, const QString &code, TypeOfExpression &typeOfExpression)
{
const QList<LookupItem> results = typeOfExpression(code, scope, TypeOfExpression::Preprocess);
const QList<LookupItem> results =
typeOfExpression(code.toUtf8(), scope, TypeOfExpression::Preprocess);
for (int i = results.size() - 1; i != -1; --i) {
const LookupItem &r = results.at(i);
......@@ -1374,7 +1375,8 @@ CPPEditorWidget::Link CPPEditorWidget::findLinkAt(const QTextCursor &cursor,
TypeOfExpression typeOfExpression;
typeOfExpression.init(doc, snapshot);
const QList<LookupItem> resolvedSymbols = typeOfExpression.reference(expression, scope, TypeOfExpression::Preprocess);
const QList<LookupItem> resolvedSymbols =
typeOfExpression.reference(expression.toUtf8(), scope, TypeOfExpression::Preprocess);
if (!resolvedSymbols.isEmpty()) {
LookupItem result = skipForwardDeclarations(resolvedSymbols);
......
......@@ -121,7 +121,7 @@ void CppElementEvaluator::execute()
TypeOfExpression typeOfExpression;
typeOfExpression.init(doc, snapshot);
const QList<LookupItem> &lookupItems = typeOfExpression(expression, scope);
const QList<LookupItem> &lookupItems = typeOfExpression(expression.toUtf8(), scope);
if (lookupItems.isEmpty())
return;
......
......@@ -575,7 +575,8 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ
newDeclText[i] = QLatin1Char('\n');
}
newDeclText.append(QLatin1String("{}"));
const QString newDeclTextPreprocessed = typeOfExpression.preprocess(newDeclText);
const QString newDeclTextPreprocessed =
QString::fromUtf8(typeOfExpression.preprocess(newDeclText.toUtf8()));
Document::Ptr newDeclDoc = Document::create(QLatin1String("<decl>"));
newDeclDoc->setSource(newDeclTextPreprocessed.toUtf8());
......
......@@ -1681,9 +1681,10 @@ private:
typeOfExpression.init(assistInterface()->semanticInfo().doc,
assistInterface()->snapshot(), assistInterface()->context().bindings());
Scope *scope = currentFile->scopeAt(binaryAST->firstToken());
const QList<LookupItem> result = typeOfExpression(currentFile->textOf(binaryAST->right_expression),
scope,
TypeOfExpression::Preprocess);
const QList<LookupItem> result =
typeOfExpression(currentFile->textOf(binaryAST->right_expression).toUtf8(),
scope,
TypeOfExpression::Preprocess);
if (! result.isEmpty()) {
......
......@@ -1051,7 +1051,7 @@ bool CppCompletionAssistProcessor::tryObjCCompletion()
if (!scope)
return false;
const QList<LookupItem> items = (*m_model->m_typeOfExpression)(expr, scope);
const QList<LookupItem> items = (*m_model->m_typeOfExpression)(expr.toUtf8(), scope);
LookupContext lookupContext(thisDocument, m_interface->snapshot());
foreach (const LookupItem &item, items) {
......@@ -1254,7 +1254,7 @@ int CppCompletionAssistProcessor::startCompletionInternal(const QString fileName
if (expression.isEmpty()) {
if (m_model->m_completionOperator == T_EOF_SYMBOL || m_model->m_completionOperator == T_COLON_COLON) {
(void) (*m_model->m_typeOfExpression)(expression, scope);
(void) (*m_model->m_typeOfExpression)(expression.toUtf8(), scope);
globalCompletion(scope);
if (m_completions.isEmpty())
return -1;
......@@ -1267,14 +1267,15 @@ int CppCompletionAssistProcessor::startCompletionInternal(const QString fileName
}
}
QByteArray utf8Exp = expression.toUtf8();
QList<LookupItem> results =
(*m_model->m_typeOfExpression)(expression, scope, TypeOfExpression::Preprocess);
(*m_model->m_typeOfExpression)(utf8Exp, scope, TypeOfExpression::Preprocess);
if (results.isEmpty()) {
if (m_model->m_completionOperator == T_SIGNAL || m_model->m_completionOperator == T_SLOT) {
if (! (expression.isEmpty() || expression == QLatin1String("this"))) {
expression = QLatin1String("this");
results = (*m_model->m_typeOfExpression)(expression, scope);
results = (*m_model->m_typeOfExpression)(utf8Exp, scope);
}
if (results.isEmpty())
......@@ -1295,7 +1296,7 @@ int CppCompletionAssistProcessor::startCompletionInternal(const QString fileName
// Resolve the type of this expression
const QList<LookupItem> results =
(*m_model->m_typeOfExpression)(baseExpression, scope,
(*m_model->m_typeOfExpression)(baseExpression.toUtf8(), scope,
TypeOfExpression::Preprocess);
// If it's a class, add completions for the constructors
......
......@@ -506,7 +506,7 @@ static QString toQmlType(const FullySpecifiedType &type)
static Class *lookupClass(const QString &expression, Scope *scope, TypeOfExpression &typeOf)
{
QList<LookupItem> results = typeOf(expression, scope);
QList<LookupItem> results = typeOf(expression.toUtf8(), scope);
Class *klass = 0;
foreach (const LookupItem &item, results) {
if (item.declaration()) {
......@@ -576,7 +576,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject(
if (QtEnum *qtEnum = member->asQtEnum()) {
// find the matching enum
Enum *e = 0;
QList<LookupItem> result = typeOf(namePrinter(qtEnum->name()), klass);
QList<LookupItem> result = typeOf(namePrinter(qtEnum->name()).toUtf8(), klass);
foreach (const LookupItem &item, result) {
if (item.declaration()) {
e = item.declaration()->asEnum();
......@@ -648,7 +648,7 @@ static void buildContextProperties(
foreach (const ContextProperty &property, contextPropertyDescriptions) {
Scope *scope = doc->scopeAt(property.line, property.column);
QList<LookupItem> results = typeOf(property.expression, scope);
QList<LookupItem> results = typeOf(property.expression.toUtf8(), scope);
QString typeName;
if (!results.isEmpty()) {
LookupItem result = results.first();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment