QmlJSTools::SemanticInfo SemanticInfoUpdater::makeNewSemanticInfo(const QmlJS::Document::Ptr &doc, const QmlJS::Snapshot &snapshot)
{
    using namespace QmlJS;

    QmlJSTools::SemanticInfo semanticInfo;
    semanticInfo.document = doc;
    semanticInfo.snapshot = snapshot;

    ModelManagerInterface *modelManager = ModelManagerInterface::instance();

    Link link(semanticInfo.snapshot, modelManager->defaultVContext(doc->language(), doc), modelManager->builtins(doc));
    semanticInfo.context = link(doc, &semanticInfo.semanticMessages);

    ScopeChain *scopeChain = new ScopeChain(doc, semanticInfo.context);
    semanticInfo.setRootScopeChain(QSharedPointer<const ScopeChain>(scopeChain));

    if (doc->language() == Dialect::Json) {
        Utils::JsonSchema *schema = QmlJSEditorPlugin::jsonManager()->schemaForFile(doc->fileName());
        if (schema) {
            JsonCheck jsonChecker(doc);
            semanticInfo.staticAnalysisMessages = jsonChecker(schema);
        }
    } else {
        Check checker(doc, semanticInfo.context);
        semanticInfo.staticAnalysisMessages = checker();
    }

    return semanticInfo;
}
void QmlProfilerDetailsRewriter::documentReady(QmlJS::Document::Ptr doc)
{
    // this could be triggered by an unrelated reload in Creator
    if (!d->m_pendingDocs.contains(doc->fileName()))
        return;

    // if the file could not be opened this slot is still triggered but source will be an empty string
    QString source = doc->source();
    if (!source.isEmpty()) {
        QTextStream st(&source, QIODevice::ReadOnly);

        for (int i = d->m_pendingEvents.count()-1; i>=0; i--) {
            PendingEvent ev = d->m_pendingEvents[i];
            if (ev.localFile == doc->fileName()) {
                d->m_pendingEvents.removeAt(i);
                rewriteDetailsForLocation(st, doc, ev.requestId, ev.location);
            }
        }
    }

    d->m_pendingDocs.removeOne(doc->fileName());

    if (d->m_pendingDocs.isEmpty()) {
        disconnect(QmlJS::ModelManagerInterface::instance(),
                   SIGNAL(documentUpdated(QmlJS::Document::Ptr)),
                   this,
                   SLOT(documentReady(QmlJS::Document::Ptr)));
        emit eventDetailsChanged();
    }
}
예제 #3
0
static bool checkIfEditorIsQtQuick(Core::IEditor *editor)
{
    if (isQmlFile(Core::EditorManager::currentEditor())) {
        QmlJS::Document::Ptr document = QmlJS::ModelManagerInterface::instance()->snapshot().document(
                Core::EditorManager::currentEditor()->document()->filePath());
        if (!document.isNull())
            return document->language() == QmlJS::Language::QmlQtQuick1
                    || document->language() == QmlJS::Language::QmlQtQuick2
                    || document->language() == QmlJS::Language::Qml;
    }

    return false;
}
예제 #4
0
void QmlJSTextEditorWidget::onDocumentUpdated(QmlJS::Document::Ptr doc)
{
    if (editorDocument()->filePath() != doc->fileName())
        return;

    if (doc->editorRevision() != editorRevision()) {
        // Maybe a dependency changed and our semantic info is now outdated.
        // Ignore 0-revision documents though, we get them when a file is initially opened
        // in an editor.
        if (doc->editorRevision() != 0)
            updateSemanticInfo();
        return;
    }

    //qDebug() << doc->fileName() << "was reparsed";

    if (doc->ast()) {
        // got a correctly parsed (or recovered) file.
        m_futureSemanticInfoRevision = doc->editorRevision();
        m_semanticInfoUpdater->update(doc, m_modelManager->snapshot());
        setExtraSelections(CodeWarningsSelection, QList<QTextEdit::ExtraSelection>());
    } else if (Document::isFullySupportedLanguage(doc->language())) {
        // show parsing errors
        QList<QTextEdit::ExtraSelection> selections;
        appendExtraSelectionsForMessages(&selections, doc->diagnosticMessages(), document());
        setExtraSelections(CodeWarningsSelection, selections);
    } else {
        setExtraSelections(CodeWarningsSelection, QList<QTextEdit::ExtraSelection>());
    }
}
예제 #5
0
static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr> futureInterface,
        const QmlJS::Document::Ptr &qmlJSDoc,
        const Core::Id &id,
        const QString &proFile = QString())
{
    if (qmlJSDoc.isNull())
        return false;
    QmlJS::AST::Node *ast = qmlJSDoc->ast();
    QTC_ASSERT(ast, return false);
    TestQmlVisitor qmlVisitor(qmlJSDoc);
    QmlJS::AST::Node::accept(ast, &qmlVisitor);

    const QString testCaseName = qmlVisitor.testCaseName();
    const TestCodeLocationAndType tcLocationAndType = qmlVisitor.testCaseLocation();
    const QMap<QString, TestCodeLocationAndType> &testFunctions = qmlVisitor.testFunctions();

    QuickTestParseResult *parseResult = new QuickTestParseResult(id);
    parseResult->proFile = proFile;
    parseResult->itemType = TestTreeItem::TestCase;
    QMap<QString, TestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
    const QMap<QString, TestCodeLocationAndType>::ConstIterator end = testFunctions.end();
    for ( ; it != end; ++it) {
        const TestCodeLocationAndType &loc = it.value();
        QuickTestParseResult *funcResult = new QuickTestParseResult(id);
        funcResult->name = it.key();
        funcResult->displayName = it.key();
        funcResult->itemType = loc.m_type;
        funcResult->fileName = loc.m_name;
        funcResult->line = loc.m_line;
        funcResult->column = loc.m_column;
        funcResult->proFile = proFile;

        parseResult->children.append(funcResult);
    }
    if (!testCaseName.isEmpty()) {
        parseResult->fileName = tcLocationAndType.m_name;
        parseResult->name = testCaseName;
        parseResult->line = tcLocationAndType.m_line;
        parseResult->column = tcLocationAndType.m_column;
    }
    futureInterface.reportResult(TestParseResultPtr(parseResult));
    return true;
}
예제 #6
0
void QmlJsTodoItemsScanner::processDocument(QmlJS::Document::Ptr doc)
{
    QList<TodoItem> itemList;

    foreach (const QmlJS::AST::SourceLocation &sourceLocation, doc->engine()->comments()) {
        QString source = doc->source().mid(sourceLocation.begin(), sourceLocation.length).trimmed();

        // Process every line
        // TODO: Do not create QStringList, just iterate through a string tracking line endings.
        QStringList commentLines = source.split(QLatin1Char('\n'), QString::SkipEmptyParts);
        quint32 startLine = sourceLocation.startLine;
        for (int j = 0; j < commentLines.count(); ++j) {
            const QString &commentLine = commentLines.at(j);
            processCommentLine(doc->fileName(), commentLine, startLine + j, itemList);
        }

    }

    emit itemsFetched(doc->fileName(), itemList);
}
예제 #7
0
QmlJSLiveTextPreview::QmlJSLiveTextPreview(const QmlJS::Document::Ptr &doc,
                                           const QmlJS::Document::Ptr &initDoc,
                                           ClientProxy *clientProxy,
                                           QObject* parent)
    : QObject(parent)
    , m_previousDoc(doc)
    , m_initialDoc(initDoc)
    , m_applyChangesToQmlInspector(true)
    , m_clientProxy(clientProxy)
{
    Q_ASSERT(doc->fileName() == initDoc->fileName());
    m_filename = doc->fileName();

    connect(modelManager(), SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)),
            SLOT(documentChanged(QmlJS::Document::Ptr)));

    if (m_clientProxy.data()) {
        connect(m_clientProxy.data(), SIGNAL(objectTreeUpdated()), SLOT(updateDebugIds()));
    }
}
QString ObjectPropertiesView::propertyBaseClass(const QDeclarativeDebugObjectReference &object, const QDeclarativeDebugPropertyReference &property, int &depth)
{
    ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
    QmlJSEditor::ModelManagerInterface *modelManager = pluginManager->getObject<QmlJSEditor::ModelManagerInterface>();
    QmlJS::Snapshot snapshot = modelManager->snapshot();

    QmlJS::Document::Ptr document = snapshot.document(object.source().url().path());
    if (document.isNull()) {

        QFile inFile(object.source().url().path());
        QString contents;
        if (inFile.open(QIODevice::ReadOnly)) {
            QTextStream ins(&inFile);
            contents = ins.readAll();
            inFile.close();
        }

        document = QmlJS::Document::create(object.source().url().path());
        document->setSource(contents);
        if (!document->parse())
            return QString();

        snapshot.insert(document);
    }

    PropertyTypeFinder find(document, snapshot, modelManager->importPaths());
    QString baseClassName = find(object.source().lineNumber(), object.source().columnNumber(), property.name());

    if (baseClassName.isEmpty()) {
        if (!object.idString().isEmpty())
            baseClassName = object.idString();
        else
            baseClassName = QString("<%1>").arg(object.className());
    }

    depth = find.depth();

    return baseClassName;

}
void QmlProfilerDetailsRewriter::rewriteDetailsForLocation(QTextStream &textDoc,
        QmlJS::Document::Ptr doc, int requestId, const QmlDebug::QmlEventLocation &location)
{
    PropertyVisitor propertyVisitor;
    QmlJS::AST::Node *node = propertyVisitor(doc->ast(), location.line, location.column);

    if (!node)
        return;

    qint64 startPos = node->firstSourceLocation().begin();
    qint64 len = node->lastSourceLocation().end() - startPos;

    textDoc.seek(startPos);
    QString details = textDoc.read(len).replace(QLatin1Char('\n'), QLatin1Char(' ')).simplified();

    emit rewriteDetailsString(requestId, details);
}
예제 #10
0
void QmlJsTodoItemsScanner::documentUpdated(QmlJS::Document::Ptr doc)
{
    if (shouldProcessFile(doc->fileName()))
        processDocument(doc);
}
QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document)
    : RefactoringFile(editor)
    , m_qmljsDocument(document)
{
    m_fileName = document->fileName();
}
void LocatorData::onDocumentUpdated(const QmlJS::Document::Ptr &doc)
{
    QList<Entry> entries = FunctionFinder().run(doc);
    m_entries.insert(doc->fileName(), entries);
}