Improved completion of JavaScript expressions.

This commit is contained in:
Roberto Raggi
2010-02-08 21:37:59 +01:00
parent 967ed09c29
commit 3d44c5621d
5 changed files with 50 additions and 51 deletions
+22 -41
View File
@@ -129,7 +129,7 @@ void Document::setDocumentRevision(int revision)
_documentRevision = revision; _documentRevision = revision;
} }
bool Document::parseQml() bool Document::parse_helper(int startToken)
{ {
Q_ASSERT(! _engine); Q_ASSERT(! _engine);
Q_ASSERT(! _pool); Q_ASSERT(! _pool);
@@ -144,8 +144,21 @@ bool Document::parseQml()
lexer.setCode(_source, /*line = */ 1); lexer.setCode(_source, /*line = */ 1);
switch (startToken) {
case QmlJSGrammar::T_FEED_UI_PROGRAM:
_parsedCorrectly = parser.parse(); _parsedCorrectly = parser.parse();
_ast = parser.ast(); 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(); _diagnosticMessages = parser.diagnosticMessages();
_bind = new Bind(this); _bind = new Bind(this);
@@ -153,51 +166,19 @@ bool Document::parseQml()
return _parsedCorrectly; return _parsedCorrectly;
} }
bool Document::parseQml()
{
return parse_helper(QmlJSGrammar::T_FEED_UI_PROGRAM);
}
bool Document::parseJavaScript() bool Document::parseJavaScript()
{ {
Q_ASSERT(! _engine); return parse_helper(QmlJSGrammar::T_FEED_JS_PROGRAM);
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 _parsedCorrectly;
} }
bool Document::parseExpression() bool Document::parseExpression()
{ {
Q_ASSERT(! _engine); return parse_helper(QmlJSGrammar::T_FEED_JS_EXPRESSION);
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;
} }
Bind *Document::bind() const Bind *Document::bind() const
+3
View File
@@ -81,6 +81,9 @@ public:
QString path() const { return _path; } QString path() const { return _path; }
QString componentName() const { return _componentName; } QString componentName() const { return _componentName; }
private:
bool parse_helper(int kind);
private: private:
QmlJS::Engine *_engine; QmlJS::Engine *_engine;
NodePool *_pool; NodePool *_pool;
+17 -3
View File
@@ -45,17 +45,31 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
// ### FIXME: May want to link to instantiating components from here. // ### FIXME: May want to link to instantiating components from here.
if (bind->_rootObjectValue) qDebug() << "**** here" << currentObject;
_context->pushScope(bind->_rootObjectValue);
ObjectValue *scopeObject = 0; ObjectValue *scopeObject = 0;
if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject)) if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject))
scopeObject = bind->_qmlObjects.value(definition); scopeObject = bind->_qmlObjects.value(definition);
else if (UiObjectBinding *binding = cast<UiObjectBinding *>(currentObject)) else if (UiObjectBinding *binding = cast<UiObjectBinding *>(currentObject))
scopeObject = bind->_qmlObjects.value(binding); scopeObject = bind->_qmlObjects.value(binding);
else if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(currentObject)) {
_context->pushScope(bind->_rootObjectValue);
if (scopeObject && scopeObject != bind->_rootObjectValue) 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); _context->pushScope(scopeObject);
}
const QStringList &includedScripts = bind->includedScripts(); const QStringList &includedScripts = bind->includedScripts();
for (int index = includedScripts.size() - 1; index != -1; --index) { 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. // Set up the current scope chain.
AST::Node *declaringMember = semanticInfo.declaringMember(editor->position()); AST::Node *declaringMember = semanticInfo.declaringMember(editor->position());
qDebug() << "*** declaring member:" << declaringMember;
context.build(declaringMember, document, snapshot); context.build(declaringMember, document, snapshot);
// Search for the operator that triggered the completion. // Search for the operator that triggered the completion.
+5 -5
View File
@@ -387,8 +387,8 @@ public:
{ {
_textDocument = textDocument; _textDocument = textDocument;
_ranges.clear(); _ranges.clear();
if (doc && doc->qmlProgram() != 0) if (doc && doc->ast() != 0)
doc->qmlProgram()->accept(this); doc->ast()->accept(this);
return _ranges; return _ranges;
} }
@@ -409,7 +409,6 @@ protected:
return true; return true;
} }
#if 0 // ### create ranges for function declarations.
virtual bool visit(AST::FunctionExpression *ast) virtual bool visit(AST::FunctionExpression *ast)
{ {
_ranges.append(createRange(ast)); _ranges.append(createRange(ast));
@@ -421,7 +420,6 @@ protected:
_ranges.append(createRange(ast)); _ranges.append(createRange(ast));
return true; return true;
} }
#endif
Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast) Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast)
{ {
@@ -448,6 +446,7 @@ protected:
range.end = QTextCursor(_textDocument); range.end = QTextCursor(_textDocument);
range.end.setPosition(ast->rbraceToken.end()); range.end.setPosition(ast->rbraceToken.end());
return range; return range;
} }
@@ -649,8 +648,9 @@ void QmlJSTextEditor::updateDocumentNow()
void QmlJSTextEditor::onDocumentUpdated(QmlJS::Document::Ptr doc) void QmlJSTextEditor::onDocumentUpdated(QmlJS::Document::Ptr doc)
{ {
if (file()->fileName() != doc->fileName()) if (file()->fileName() != doc->fileName()) {
return; return;
}
if (doc->documentRevision() != document()->revision()) { if (doc->documentRevision() != document()->revision()) {
// got an outdated document. // got an outdated document.