19QQmlScriptBlob::QQmlScriptBlob(
const QUrl &url, QQmlTypeLoader *loader, IsESModule isESModule)
20 : QQmlNotifyingBlob(url, JavaScriptFile, loader)
21 , m_isModule(isESModule == IsESModule::Yes)
29void QQmlScriptBlob::dataReceived(
const SourceCodeData &data)
31 assertTypeLoaderThread();
33 if (data.isCacheable()) {
34 if (m_typeLoader->readCacheFile()) {
35 auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>();
37 if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
38 initializeFromCompilationUnit(std::move(unit));
41 qCDebug(DBG_DISK_CACHE()) <<
"Error loading" << urlString()
42 <<
"from disk cache:" << error;
48 if (m_cachedUnitStatus == QQmlMetaType::CachedUnitLookupError::VersionMismatch)
49 setError(QQmlTypeLoader::tr(
"File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile"));
51 setError(QQmlTypeLoader::tr(
"No such file or directory"));
56 QString source = data.readAll(&error);
57 if (!error.isEmpty()) {
62 QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit;
65 QList<QQmlJS::DiagnosticMessage> diagnostics;
66 unit = QV4::Compiler::Codegen::compileModule(
67 m_typeLoader->isDebugging(), urlString(), source, data.sourceTimeStamp(),
69 QList<QQmlError> errors = QQmlEnginePrivate::qmlErrorFromDiagnostics(urlString(), diagnostics);
70 if (!errors.isEmpty()) {
75 QmlIR::Document irUnit(urlString(), finalUrlString(), m_typeLoader->isDebugging());
77 irUnit.jsModule.sourceTimeStamp = data.sourceTimeStamp();
79 QmlIR::ScriptDirectivesCollector collector(&irUnit);
80 irUnit.jsParserEngine.setDirectives(&collector);
82 QList<QQmlError> errors;
83 const QString fragment = finalUrl().fragment();
84 irUnit.javaScriptCompilationUnit = QV4::Script::precompile(
85 &irUnit.jsModule, &irUnit.jsParserEngine, &irUnit.jsGenerator, urlString(),
86 source, &errors, fragment == QLatin1String(
"global")
87 ? QV4::Compiler::ContextType::Global
88 : QV4::Compiler::ContextType::ScriptImportedByQML,
89 fragment == QLatin1String(
"include")
90 ? QV4::Script::InheritContext::Yes
91 : QV4::Script::InheritContext::No);
94 if (!errors.isEmpty()) {
99 QmlIR::QmlUnitGenerator qmlGenerator;
100 qmlGenerator.generate(irUnit);
101 unit = std::move(irUnit.javaScriptCompilationUnit);
104 if (m_typeLoader->writeCacheFile()) {
106 if (unit->saveToDisk(url(), &errorString)) {
108 if (!unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
112 qCDebug(DBG_DISK_CACHE()) <<
"Error saving cached version of"
113 << unit->fileName() <<
"to disk:" << errorString;
117 initializeFromCompilationUnit(std::move(unit));
120void QQmlScriptBlob::initializeFromCachedUnit(
const QQmlPrivate::CachedQmlUnit *cachedUnit)
122 assertTypeLoaderThread();
123 initializeFromCompilationUnit(QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(
124 cachedUnit->qmlData, cachedUnit->aotCompiledFunctions, urlString(), finalUrlString()));
127void QQmlScriptBlob::done()
129 assertTypeLoaderThread();
135 for (
int ii = 0; ii < m_scripts.size(); ++ii) {
136 const ScriptReference &script = m_scripts.at(ii);
141 if (script.script->isError()) {
142 QList<QQmlError> errors = script.script->errors();
145 error.setLine(qmlConvertSourceCoordinate<quint32,
int>(script.location.line()));
146 error.setColumn(qmlConvertSourceCoordinate<quint32,
int>(script.location.column()));
147 error.setDescription(QQmlTypeLoader::tr(
"Script %1 unavailable").arg(script.script->urlString()));
148 errors.prepend(error);
155 m_scriptData->typeNameCache.adopt(
new QQmlTypeNameCache(m_importCache));
159 for (
int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
160 const ScriptReference &script = m_scripts.at(scriptIndex);
162 m_scriptData->scripts.append(script.script->scriptData());
164 if (!script.nameSpace.isNull()) {
165 if (!ns.contains(script.nameSpace)) {
166 ns.insert(script.nameSpace);
167 m_scriptData->typeNameCache->add(script.nameSpace);
170 m_scriptData->typeNameCache->add(script.qualifier, scriptIndex, script.nameSpace);
173 m_importCache->populateCache(m_scriptData->typeNameCache.data());
176 if (
auto cu = m_scriptData->compilationUnit()) {
177 cu->qmlType = QQmlMetaType::findCompositeType(url(), cu, QQmlMetaType::JavaScript);
178 for (
const auto &script : std::as_const(m_scripts))
179 cu->dependentScripts.append(script.script->scriptData());
180 QQmlMetaType::registerInternalCompositeType(cu);
191void QQmlScriptBlob::scriptImported(
const QQmlRefPointer<QQmlScriptBlob> &blob,
const QV4::CompiledData::Location &location,
const QString &qualifier,
const QString &nameSpace)
193 assertTypeLoaderThread();
197 ref.location = location;
198 ref.qualifier = qualifier;
199 ref.nameSpace = nameSpace;