QmlJS: Share Context.

Previously Context was not entirely thread safe and had to be
copied locally. Now it is thread safe and its lifetime
managed by QSharedPointer.

The non-safe parts were moved into ScopeChain in a previous commit.

Change-Id: I851a93de85cbd6391dbea0fe33b011e2e093addb
Reviewed-on: http://codereview.qt.nokia.com/1695
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
This commit is contained in:
Christian Kamm
2011-07-13 15:04:27 +02:00
parent f87dc61986
commit 9dc9674c6b
28 changed files with 129 additions and 91 deletions

View File

@@ -201,7 +201,7 @@ private:
const Interpreter::Value *getPropertyValue(const Interpreter::ObjectValue *object,
const QStringList &propertyNames,
const Interpreter::Context *context)
const Interpreter::ContextPtr &context)
{
if (propertyNames.isEmpty() || !object)
return 0;
@@ -422,7 +422,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface
const QList<AST::Node *> path = semanticInfo.rangePath(m_interface->position());
LookupContext::Ptr lookupContext = semanticInfo.lookupContext(path);
const Interpreter::Context *context = lookupContext->context();
const Interpreter::ContextPtr &context = lookupContext->context();
const Interpreter::ScopeChain &scopeChain = lookupContext->scopeChain();
// Search for the operator that triggered the completion.

View File

@@ -554,7 +554,7 @@ LookupContext::Ptr SemanticInfo::lookupContext(const QList<QmlJS::AST::Node *> &
if (m_context.isNull())
return LookupContext::create(document, snapshot, path);
return LookupContext::create(document, *m_context, path);
return LookupContext::create(document, m_context, path);
}
static bool importContainsCursor(UiImport *importAst, unsigned cursorPosition)

View File

@@ -131,7 +131,7 @@ public: // attributes
QList<QmlJS::DiagnosticMessage> semanticMessages;
private:
QSharedPointer<const QmlJS::Interpreter::Context> m_context;
QmlJS::Interpreter::ContextPtr m_context;
friend class Internal::SemanticHighlighter;
};

View File

@@ -78,7 +78,7 @@ class FindUsages: protected Visitor
public:
typedef QList<AST::SourceLocation> Result;
FindUsages(Document::Ptr doc, Context *context)
FindUsages(Document::Ptr doc, const ContextPtr &context)
: _doc(doc)
, _scopeChain(doc, context)
, _builder(&_scopeChain)
@@ -303,7 +303,7 @@ class FindTypeUsages: protected Visitor
public:
typedef QList<AST::SourceLocation> Result;
FindTypeUsages(Document::Ptr doc, Context *context)
FindTypeUsages(Document::Ptr doc, const ContextPtr &context)
: _doc(doc)
, _context(context)
, _scopeChain(doc, context)
@@ -450,7 +450,7 @@ private:
Result _usages;
Document::Ptr _doc;
Context *_context;
ContextPtr _context;
ScopeChain _scopeChain;
ScopeBuilder _builder;
@@ -693,13 +693,13 @@ static QString matchingLine(unsigned position, const QString &source)
class ProcessFile: public std::unary_function<QString, QList<FindReferences::Usage> >
{
const Context &context;
ContextPtr context;
typedef FindReferences::Usage Usage;
QString name;
const ObjectValue *scope;
public:
ProcessFile(const Context &context,
ProcessFile(const ContextPtr &context,
QString name,
const ObjectValue *scope)
: context(context), name(name), scope(scope)
@@ -709,14 +709,12 @@ public:
{
QList<Usage> usages;
Document::Ptr doc = context.snapshot().document(fileName);
Document::Ptr doc = context->snapshot().document(fileName);
if (!doc)
return usages;
Context contextCopy(context);
// find all idenfifier expressions, try to resolve them and check if the result is in scope
FindUsages findUsages(doc, &contextCopy);
FindUsages findUsages(doc, context);
FindUsages::Result results = findUsages(name, scope);
foreach (const AST::SourceLocation &loc, results)
usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length));
@@ -727,13 +725,13 @@ public:
class SearchFileForType: public std::unary_function<QString, QList<FindReferences::Usage> >
{
const Context &context;
ContextPtr context;
typedef FindReferences::Usage Usage;
QString name;
const ObjectValue *scope;
public:
SearchFileForType(const Context &context,
SearchFileForType(const ContextPtr &context,
QString name,
const ObjectValue *scope)
: context(context), name(name), scope(scope)
@@ -743,14 +741,12 @@ public:
{
QList<Usage> usages;
Document::Ptr doc = context.snapshot().document(fileName);
Document::Ptr doc = context->snapshot().document(fileName);
if (!doc)
return usages;
Context contextCopy(context);
// find all idenfifier expressions, try to resolve them and check if the result is in scope
FindTypeUsages findUsages(doc, &contextCopy);
FindTypeUsages findUsages(doc, context);
FindTypeUsages::Result results = findUsages(name, scope);
foreach (const AST::SourceLocation &loc, results)
usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length));
@@ -821,9 +817,9 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
Link link(snapshot, modelManager->importPaths(), modelManager->builtins(doc));
Context context = link();
ContextPtr context = link();
ScopeChain scopeChain(doc, &context);
ScopeChain scopeChain(doc, context);
ScopeBuilder builder(&scopeChain);
ScopeAstPath astPath(doc);
builder.push(astPath(offset));
@@ -861,7 +857,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
const ObjectValue *scope = findTarget.scope();
if (!scope)
return;
scope->lookupMember(name, &context, &scope);
scope->lookupMember(name, context, &scope);
if (!scope)
return;
future.reportResult(searchStarting);

View File

@@ -269,7 +269,7 @@ void HoverHandler::operateTooltip(TextEditor::ITextEditor *editor, const QPoint
}
void HoverHandler::prettyPrintTooltip(const QmlJS::Interpreter::Value *value,
const QmlJS::Interpreter::Context *context)
const QmlJS::Interpreter::ContextPtr &context)
{
if (! value)
return;

View File

@@ -80,7 +80,7 @@ private:
QmlJS::AST::UiImport *node);
void prettyPrintTooltip(const QmlJS::Interpreter::Value *value,
const QmlJS::Interpreter::Context *context);
const QmlJS::Interpreter::ContextPtr &context);
TextEditor::HelpItem qmlHelpItem(const QmlJS::LookupContext::Ptr &lookupContext,
QmlJS::AST::Node *node) const;

View File

@@ -135,7 +135,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const SemanticHighlighterSource &
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QmlJS::Link link(snapshot, modelManager->importPaths(), modelManager->builtins(doc));
QmlJS::Interpreter::Context *ctx = new QmlJS::Interpreter::Context(link(doc, &semanticInfo.semanticMessages));
QmlJS::Interpreter::ContextPtr ctx = link(doc, &semanticInfo.semanticMessages);
semanticInfo.m_context = QSharedPointer<const QmlJS::Interpreter::Context>(ctx);
QmlJS::Check checker(doc, ctx);

View File

@@ -99,7 +99,7 @@ void QmlOutlineItem::setItemData(const QMap<int, QVariant> &roles)
}
}
QString QmlOutlineItem::prettyPrint(const Interpreter::Value *value, const Interpreter::Context *context) const
QString QmlOutlineItem::prettyPrint(const Interpreter::Value *value, const Interpreter::ContextPtr &context) const
{
if (! value)
return QString();

View File

@@ -65,7 +65,7 @@ public:
void setItemData(const QMap<int, QVariant> &roles);
private:
QString prettyPrint(const QmlJS::Interpreter::Value *value, const QmlJS::Interpreter::Context *context) const;
QString prettyPrint(const QmlJS::Interpreter::Value *value, const QmlJS::Interpreter::ContextPtr &context) const;
QmlOutlineModel *m_outlineModel;
};