forked from qt-creator/qt-creator
Improved completion of JavaScript expressions.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user