Commit 3d44c562 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Improved completion of JavaScript expressions.

parent 967ed09c
......@@ -129,7 +129,7 @@ void Document::setDocumentRevision(int revision)
_documentRevision = revision;
}
bool Document::parseQml()
bool Document::parse_helper(int startToken)
{
Q_ASSERT(! _engine);
Q_ASSERT(! _pool);
......@@ -144,8 +144,21 @@ bool Document::parseQml()
lexer.setCode(_source, /*line = */ 1);
_parsedCorrectly = parser.parse();
_ast = parser.ast();
switch (startToken) {
case QmlJSGrammar::T_FEED_UI_PROGRAM:
_parsedCorrectly = parser.parse();
break;
case QmlJSGrammar::T_FEED_JS_PROGRAM:
_parsedCorrectly = parser.parseProgram();
break;
case QmlJSGrammar::T_FEED_JS_EXPRESSION:
_parsedCorrectly = parser.parseExpression();
break;
default:
Q_ASSERT(0);
}
_ast = parser.rootNode();
_diagnosticMessages = parser.diagnosticMessages();
_bind = new Bind(this);
......@@ -153,51 +166,19 @@ bool Document::parseQml()
return _parsedCorrectly;
}
bool Document::parseJavaScript()
bool Document::parseQml()
{
Q_ASSERT(! _engine);
Q_ASSERT(! _pool);
Q_ASSERT(! _ast);
Q_ASSERT(! _bind);
_engine = new Engine();
_pool = new NodePool(_fileName, _engine);
Lexer lexer(_engine);
Parser parser(_engine);
lexer.setCode(_source, /*line = */ 1);
_parsedCorrectly = parser.parseProgram();
_ast = cast<Program*>(parser.rootNode());
_diagnosticMessages = parser.diagnosticMessages();
_bind = new Bind(this);
return parse_helper(QmlJSGrammar::T_FEED_UI_PROGRAM);
}
return _parsedCorrectly;
bool Document::parseJavaScript()
{
return parse_helper(QmlJSGrammar::T_FEED_JS_PROGRAM);
}
bool Document::parseExpression()
{
Q_ASSERT(! _engine);
Q_ASSERT(! _pool);
Q_ASSERT(! _ast);
_engine = new Engine();
_pool = new NodePool(_fileName, _engine);
Lexer lexer(_engine);
Parser parser(_engine);
lexer.setCode(_source, /*line = */ 1);
_parsedCorrectly = parser.parseExpression();
_ast = parser.rootNode();
if (_ast)
_ast = _ast->expressionCast();
_diagnosticMessages = parser.diagnosticMessages();
return _parsedCorrectly;
return parse_helper(QmlJSGrammar::T_FEED_JS_EXPRESSION);
}
Bind *Document::bind() const
......
......@@ -81,6 +81,9 @@ public:
QString path() const { return _path; }
QString componentName() const { return _componentName; }
private:
bool parse_helper(int kind);
private:
QmlJS::Engine *_engine;
NodePool *_pool;
......
......@@ -45,17 +45,31 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
// ### FIXME: May want to link to instantiating components from here.
if (bind->_rootObjectValue)
_context->pushScope(bind->_rootObjectValue);
qDebug() << "**** here" << currentObject;
ObjectValue *scopeObject = 0;
if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject))
scopeObject = bind->_qmlObjects.value(definition);
else if (UiObjectBinding *binding = cast<UiObjectBinding *>(currentObject))
scopeObject = bind->_qmlObjects.value(binding);
else if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(currentObject)) {
_context->pushScope(bind->_rootObjectValue);
if (scopeObject && scopeObject != bind->_rootObjectValue)
_context->pushScope(scopeObject);
ObjectValue *activation = engine()->newObject(/*prototype = */ 0);
for (FormalParameterList *it = fun->formals; it; it = it->next) {
if (it->name)
activation->setProperty(it->name->asString(), engine()->undefinedValue());
}
_context->pushScope(activation);
}
if (scopeObject) {
if (bind->_rootObjectValue)
_context->pushScope(bind->_rootObjectValue);
if (scopeObject != bind->_rootObjectValue)
_context->pushScope(scopeObject);
}
const QStringList &includedScripts = bind->includedScripts();
for (int index = includedScripts.size() - 1; index != -1; --index) {
......
......@@ -654,6 +654,7 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
// Set up the current scope chain.
AST::Node *declaringMember = semanticInfo.declaringMember(editor->position());
qDebug() << "*** declaring member:" << declaringMember;
context.build(declaringMember, document, snapshot);
// Search for the operator that triggered the completion.
......
......@@ -387,8 +387,8 @@ public:
{
_textDocument = textDocument;
_ranges.clear();
if (doc && doc->qmlProgram() != 0)
doc->qmlProgram()->accept(this);
if (doc && doc->ast() != 0)
doc->ast()->accept(this);
return _ranges;
}
......@@ -409,7 +409,6 @@ protected:
return true;
}
#if 0 // ### create ranges for function declarations.
virtual bool visit(AST::FunctionExpression *ast)
{
_ranges.append(createRange(ast));
......@@ -421,7 +420,6 @@ protected:
_ranges.append(createRange(ast));
return true;
}
#endif
Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast)
{
......@@ -448,6 +446,7 @@ protected:
range.end = QTextCursor(_textDocument);
range.end.setPosition(ast->rbraceToken.end());
return range;
}
......@@ -649,8 +648,9 @@ void QmlJSTextEditor::updateDocumentNow()
void QmlJSTextEditor::onDocumentUpdated(QmlJS::Document::Ptr doc)
{
if (file()->fileName() != doc->fileName())
if (file()->fileName() != doc->fileName()) {
return;
}
if (doc->documentRevision() != document()->revision()) {
// got an outdated document.
......
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