18QQmlScriptBlob::QQmlScriptBlob(
const QUrl &url, QQmlTypeLoader *loader, IsESModule isESModule)
19 : QQmlNotifyingBlob(url, JavaScriptFile, loader)
20 , m_isModule(isESModule == IsESModule::Yes)
28void QQmlScriptBlob::dataReceived(
const SourceCodeData &data)
30 assertTypeLoaderThread();
32 if (data.isCacheable()) {
33 if (m_typeLoader->readCacheFile()) {
34 auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>();
36 if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
37 initializeFromCompilationUnit(std::move(unit));
40 qCDebug(DBG_DISK_CACHE()) <<
"Error loading" << urlString()
41 <<
"from disk cache:" << error;
47 if (m_cachedUnitStatus == QQmlMetaType::CachedUnitLookupError::VersionMismatch)
48 setError(QQmlTypeLoader::tr(
"File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile"));
50 setError(QQmlTypeLoader::tr(
"No such file or directory"));
55 QString source = data.readAll(&error);
56 if (!error.isEmpty()) {
61 QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit;
64 QList<QQmlJS::DiagnosticMessage> diagnostics;
65 unit = QV4::Compiler::Codegen::compileModule(
66 m_typeLoader->isDebugging(), urlString(), source, data.sourceTimeStamp(),
68 QList<QQmlError> errors = QQmlEnginePrivate::qmlErrorFromDiagnostics(urlString(), diagnostics);
69 if (!errors.isEmpty()) {
74 QmlIR::Document irUnit(urlString(), finalUrlString(), m_typeLoader->isDebugging());
76 irUnit.jsModule.sourceTimeStamp = data.sourceTimeStamp();
78 QmlIR::ScriptDirectivesCollector collector(&irUnit);
79 irUnit.jsParserEngine.setDirectives(&collector);
81 QList<QQmlError> errors;
82 const QString fragment = finalUrl().fragment();
83 irUnit.javaScriptCompilationUnit = QV4::Script::precompile(
84 &irUnit.jsModule, &irUnit.jsParserEngine, &irUnit.jsGenerator, urlString(),
85 source, &errors, fragment == QLatin1String(
"global")
86 ? QV4::Compiler::ContextType::Global
87 : QV4::Compiler::ContextType::ScriptImportedByQML,
88 fragment == QLatin1String(
"include")
89 ? QV4::Script::InheritContext::Yes
90 : QV4::Script::InheritContext::No);
93 if (!errors.isEmpty()) {
98 QmlIR::QmlUnitGenerator qmlGenerator;
99 qmlGenerator.generate(irUnit);
100 unit = std::move(irUnit.javaScriptCompilationUnit);
103 if (m_typeLoader->writeCacheFile()) {
105 if (unit->saveToDisk(url(), &errorString)) {
107 if (!unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
111 qCDebug(DBG_DISK_CACHE()) <<
"Error saving cached version of"
112 << unit->fileName() <<
"to disk:" << errorString;
116 initializeFromCompilationUnit(std::move(unit));
119void QQmlScriptBlob::initializeFromCachedUnit(
const QQmlPrivate::CachedQmlUnit *cachedUnit)
121 assertTypeLoaderThread();
122 initializeFromCompilationUnit(QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(
123 cachedUnit->qmlData, cachedUnit->aotCompiledFunctions, urlString(), finalUrlString()));
126void QQmlScriptBlob::done()
128 assertTypeLoaderThread();
134 for (
int ii = 0; ii < m_scripts.size(); ++ii) {
135 const ScriptReference &script = m_scripts.at(ii);
140 if (script.script->isError()) {
141 QList<QQmlError> errors = script.script->errors();
144 error.setLine(qmlConvertSourceCoordinate<quint32,
int>(script.location.line()));
145 error.setColumn(qmlConvertSourceCoordinate<quint32,
int>(script.location.column()));
146 error.setDescription(QQmlTypeLoader::tr(
"Script %1 unavailable").arg(script.script->urlString()));
147 errors.prepend(error);
154 m_scriptData->typeNameCache.adopt(
new QQmlTypeNameCache(m_importCache));
158 for (
int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
159 const ScriptReference &script = m_scripts.at(scriptIndex);
161 m_scriptData->scripts.append(script.script->scriptData());
163 if (!script.nameSpace.isNull()) {
164 if (!ns.contains(script.nameSpace)) {
165 ns.insert(script.nameSpace);
166 m_scriptData->typeNameCache->add(script.nameSpace);
169 m_scriptData->typeNameCache->add(script.qualifier, scriptIndex, script.nameSpace);
172 m_importCache->populateCache(m_scriptData->typeNameCache.data());
175 if (
auto cu = m_scriptData->compilationUnit()) {
176 cu->qmlType = QQmlMetaType::findCompositeType(url(), cu, QQmlMetaType::JavaScript);
177 for (
const auto &script : std::as_const(m_scripts))
178 cu->dependentScripts.append(script.script->scriptData());
179 QQmlMetaType::registerInternalCompositeType(cu);
190void QQmlScriptBlob::scriptImported(
const QQmlRefPointer<QQmlScriptBlob> &blob,
const QV4::CompiledData::Location &location,
const QString &qualifier,
const QString &nameSpace)
192 assertTypeLoaderThread();
196 ref.location = location;
197 ref.qualifier = qualifier;
198 ref.nameSpace = nameSpace;