forked from qt-creator/qt-creator
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: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
@@ -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,7 +533,7 @@ bool CheckSymbols::visit(CallAST *ast)
|
||||
const QByteArray expression = textOf(access);
|
||||
|
||||
const QList<LookupItem> candidates =
|
||||
typeOfExpression(QLatin1String(expression), enclosingScope(),
|
||||
typeOfExpression(expression, enclosingScope(),
|
||||
TypeOfExpression::Preprocess);
|
||||
|
||||
NameAST *memberName = access->member_name;
|
||||
@@ -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,7 +1681,8 @@ 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),
|
||||
const QList<LookupItem> result =
|
||||
typeOfExpression(currentFile->textOf(binaryAST->right_expression).toUtf8(),
|
||||
scope,
|
||||
TypeOfExpression::Preprocess);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user