diff --git a/ets2panda/bindings/native/src/bridges.cpp b/ets2panda/bindings/native/src/bridges.cpp index 19790f849e81c7860fc8d24b3c12703d2cfc05ae..b4f7bfdc24a1c97389df0e12cfda66fb76eaa250 100644 --- a/ets2panda/bindings/native/src/bridges.cpp +++ b/ets2panda/bindings/native/src/bridges.cpp @@ -66,3 +66,10 @@ KNativePointer impl_ContextErrorMessage(KNativePointer contextPtr) return new std::string(GetPublicImpl()->ContextErrorMessage(context)); } TS_INTEROP_1(ContextErrorMessage, KNativePointer, KNativePointer) + +KNativePointer impl_GetAllErrorMessages(KNativePointer contextPtr) +{ + auto context = reinterpret_cast(contextPtr); + return new std::string(GetPublicImpl()->GetAllErrorMessages(context)); +} +TS_INTEROP_1(GetAllErrorMessages, KNativePointer, KNativePointer) diff --git a/ets2panda/bindings/src/Es2pandaNativeModule.ts b/ets2panda/bindings/src/Es2pandaNativeModule.ts index fed3212068ed20047a871a21c53c228b75fd8556..2f9ce38fdc024d08e2b0d106062c8097c3836782 100644 --- a/ets2panda/bindings/src/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/Es2pandaNativeModule.ts @@ -54,6 +54,10 @@ export class Es2pandaNativeModule { throw new Error('Not implemented'); } + _GetAllErrorMessages(context: KPtr): KPtr { + throw new Error('Not implemented'); + } + _AstNodeDumpModifiers(context: KPtr, node: KPtr): KPtr { throw new Error('Not implemented'); } diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index 55b4555ac353d47a3f959090b5591ccd1960ef60..71121b6f1d3db5afd3df5a0fde82da297f9fa6d2 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -65,9 +65,7 @@ import { DependentModuleConfig, JobInfo, KPointer, - ModuleInfo, - PathsConfig, - ES2PANDA_MODE + ModuleInfo } from '../types'; import { ArkTSConfigGenerator } from './generate_arktsconfig'; import { SetupClusterOptions } from '../types'; @@ -201,7 +199,8 @@ export abstract class BaseMode { const logData: LogData = LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_DECLGEN_FAIL, 'Generate declaration files failed.', - error.message + error.message, + fileInfo.filePath ); this.logger.printError(logData); } @@ -286,7 +285,8 @@ export abstract class BaseMode { const logData: LogData = LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_COMPILE_ABC_FAIL, 'Compile abc files failed.', - error.message + error.message, + fileInfo.filePath ); this.logger.printError(logData); } @@ -962,10 +962,20 @@ export abstract class BaseMode { success: boolean; filePath?: string; error?: string; + isDeclFile?: boolean; }) => { if (message.success) { return; } + if (message.isDeclFile) { + this.logger.printError(LogDataFactory.newInstance( + ErrorCode.BUILDSYSTEM_DECLGEN_FAIL, + 'Generate declaration files failed in worker.', + message.error || 'Unknown error', + message.filePath + )); + return; + } this.logger.printError(LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_COMPILE_ABC_FAIL, 'Compile abc files failed in worker.', diff --git a/ets2panda/driver/build_system/src/build/compile_worker.ts b/ets2panda/driver/build_system/src/build/compile_worker.ts index 9e4218cbd80ae1c60d01a543d0421fa783575a0e..d9f719d3eb8b8abf84170b9983cfe4667b82f497 100644 --- a/ets2panda/driver/build_system/src/build/compile_worker.ts +++ b/ets2panda/driver/build_system/src/build/compile_worker.ts @@ -30,12 +30,7 @@ import { BUILD_MODE, OHOS_MODULE_TYPE } from '../types'; -import { - LogData, - LogDataFactory, - Logger -} from '../logger'; -import { ErrorCode } from '../error_code'; +import { Logger } from '../logger'; process.on('message', (message: { taskList: CompileFileInfo[]; @@ -106,18 +101,12 @@ process.on('message', (message: { } catch (error) { errorStatus = true; if (error instanceof Error) { - const logData: LogData = LogDataFactory.newInstance( - ErrorCode.BUILDSYSTEM_COMPILE_ABC_FAIL, - 'Compile abc files failed.', - error.message - ); - Logger.getInstance().printError(logData); + process.send({ + success: false, + filePath: fileInfo.filePath, + error: 'Compile abc files failed.\n' + error.message + }); } - process.send({ - success: false, - filePath: fileInfo.filePath, - error: 'Compile abc files failed.' - }); } finally { if (!errorStatus) { // when error occur,wrapper will destroy context. diff --git a/ets2panda/driver/build_system/src/build/declgen_worker.ts b/ets2panda/driver/build_system/src/build/declgen_worker.ts index 42d9f819b80c09cbeff66c729502774de1306b1d..872eb49db1761b085a6db34df3b4e6f48249a49f 100644 --- a/ets2panda/driver/build_system/src/build/declgen_worker.ts +++ b/ets2panda/driver/build_system/src/build/declgen_worker.ts @@ -15,8 +15,7 @@ import { CompileFileInfo, ModuleInfo } from '../types'; import { BuildConfig } from '../types'; -import { LogData, LogDataFactory, Logger } from '../logger'; -import { ErrorCode } from '../error_code'; +import { Logger } from '../logger'; import * as fs from 'fs'; import * as path from 'path'; import { changeFileExtension, ensurePathExists } from '../utils'; @@ -104,18 +103,13 @@ process.on('message', (message: { } catch (error) { errorStatus = true; if (error instanceof Error) { - const logData: LogData = LogDataFactory.newInstance( - ErrorCode.BUILDSYSTEM_DECLGEN_FAIL, - 'Generate declaration files failed in worker.', - error.message - ); - logger.printError(logData); + process.send({ + success: false, + isDeclFile: true, + filePath: fileInfo.filePath, + error: 'Generate declaration files failed.\n' + error.message + }); } - process.send({ - success: false, - filePath: fileInfo.filePath, - error: 'Generate declaration files failed in worker.' - }); } finally { if (!errorStatus) { // when error occur,wrapper will destroy context. diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 22757da10544d6a06e5924b8458c742af99d1ef6..3935c32f7dfca6b0a9c0adc8fbc85e8996037b7b 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -288,6 +288,23 @@ extern "C" void DestroyConfig(es2panda_Config *config) delete cfg; } +extern "C" __attribute__((unused)) char const *GetAllErrorMessages(es2panda_Context *context) +{ + auto *ctx = reinterpret_cast(context); + ES2PANDA_ASSERT(ctx != nullptr); + ES2PANDA_ASSERT(ctx->config != nullptr); + ES2PANDA_ASSERT(ctx->allocator != nullptr); + auto *cfg = reinterpret_cast(ctx->config); + ES2PANDA_ASSERT(cfg != nullptr); + ES2PANDA_ASSERT(cfg->diagnosticEngine != nullptr); + auto allMessages = cfg->diagnosticEngine->PrintAndFlushErrorDiagnostic(); + size_t bufferSize = allMessages.length() + 1; + char *cStringMessages = reinterpret_cast(ctx->allocator->Alloc(bufferSize)); + [[maybe_unused]] auto err = memcpy_s(cStringMessages, bufferSize, allMessages.c_str(), bufferSize); + ES2PANDA_ASSERT(err == EOK); + return cStringMessages; +} + extern "C" const es2panda_Options *ConfigGetOptions(es2panda_Config *config) { auto options = reinterpret_cast(config)->options; @@ -1298,6 +1315,7 @@ es2panda_Impl g_impl = { MemFinalize, CreateConfig, DestroyConfig, + GetAllErrorMessages, ConfigGetOptions, CreateContextFromFile, CreateCacheContextFromFile, diff --git a/ets2panda/public/es2panda_lib.h b/ets2panda/public/es2panda_lib.h index cb861ee1db29d39f66954afc6a69e7cd148e28c6..cbc9e0a411e5a470a203255e5fd6f472cefcb5ed 100644 --- a/ets2panda/public/es2panda_lib.h +++ b/ets2panda/public/es2panda_lib.h @@ -181,6 +181,7 @@ struct CAPI_EXPORT es2panda_Impl { es2panda_Config *(*CreateConfig)(int argc, char const *const *argv); void (*DestroyConfig)(es2panda_Config *config); + char const *(*GetAllErrorMessages)(es2panda_Context *context); const es2panda_Options *(*ConfigGetOptions)(es2panda_Config *config); es2panda_Context *(*CreateContextFromFile)(es2panda_Config *config, char const *source_file_name); diff --git a/ets2panda/public/es2panda_lib.idl.erb b/ets2panda/public/es2panda_lib.idl.erb index dcff86fb9eb1a8fab4d0ab88f7e4e5eba1ac04a4..3d997031adc25c515d03dd285653d65c1056b5a3 100644 --- a/ets2panda/public/es2panda_lib.idl.erb +++ b/ets2panda/public/es2panda_lib.idl.erb @@ -169,6 +169,7 @@ typedef u64 Es2panda<%= name %>; interface es2panda_Impl { es2panda_Config CreateConfig(i32 argc, sequence argv); void DestroyConfig(es2panda_Config config); + String GetAllErrorMessages(es2panda_Context context); es2panda_Options ConfigGetOptions(es2panda_Config config); es2panda_Context CreateContextFromFile(es2panda_Config config, String source_file_name); diff --git a/ets2panda/util/diagnosticEngine.cpp b/ets2panda/util/diagnosticEngine.cpp index 6f92ba5cd065f7bf3b877256e57fda3718ce48d4..5b1c798ae52425667a8f12b2c0977e94c1e93cf2 100644 --- a/ets2panda/util/diagnosticEngine.cpp +++ b/ets2panda/util/diagnosticEngine.cpp @@ -22,14 +22,19 @@ namespace ark::es2panda::util { -void CLIDiagnosticPrinter::Print(const DiagnosticBase &diagnostic) const +void CLIDiagnosticPrinter::Print(const DiagnosticBase &diagnostic, std::ostream &out) const { - std::cout << DiagnosticTypeToString(diagnostic.Type()) << ": " << diagnostic.Message(); + out << DiagnosticTypeToString(diagnostic.Type()) << ": " << diagnostic.Message(); if (!diagnostic.File().empty()) { - std::cout << " [" << util::BaseName(diagnostic.File()) << ":" << diagnostic.Line() << ":" << diagnostic.Offset() - << "]"; + out << " [" << util::BaseName(diagnostic.File()) << ":" << diagnostic.Line() << ":" << diagnostic.Offset() + << "]"; } - std::cout << std::endl; + out << std::endl; +} + +void CLIDiagnosticPrinter::Print(const DiagnosticBase &diagnostic) const +{ + Print(diagnostic, std::cout); } const DiagnosticStorage &DiagnosticEngine::GetDiagnosticStorage(DiagnosticType type) @@ -82,6 +87,37 @@ DiagnosticStorage DiagnosticEngine::GetAllDiagnostic() return merged; } +DiagnosticStorage DiagnosticEngine::GetErrorDiagnostic() +{ + size_t errorCount = 0; + for (const auto &vec : diagnostics_) { + if (!vec.empty() && IsError(vec.front()->Type())) { + errorCount += vec.size(); + } + } + + DiagnosticStorage merged; + merged.reserve(errorCount); + for (const auto &vec : diagnostics_) { + if (!vec.empty() && IsError(vec.front()->Type())) { + merged.insert(merged.end(), vec.begin(), vec.end()); + } + } + return merged; +} + +std::string DiagnosticEngine::PrintAndFlushErrorDiagnostic() +{ + auto log = GetErrorDiagnostic(); + std::sort(log.begin(), log.end(), [](const auto &lhs, const auto &rhs) { return *lhs < *rhs; }); + auto last = std::unique(log.begin(), log.end(), [](const auto &lhs, const auto &rhs) { return *lhs == *rhs; }); + std::ostringstream oss; + for (auto it = log.begin(); it != last; ++it) { + printer_->Print(**it, oss); + } + return oss.str(); +} + void DiagnosticEngine::FlushDiagnostic() { auto log = GetAllDiagnostic(); diff --git a/ets2panda/util/diagnosticEngine.h b/ets2panda/util/diagnosticEngine.h index d50fd12b24ca92eb93193df6cb4811dcaec1a700..a283b8d67eeb82e9bc1cc6304eb25c8da62d78a4 100644 --- a/ets2panda/util/diagnosticEngine.h +++ b/ets2panda/util/diagnosticEngine.h @@ -34,6 +34,7 @@ public: virtual ~DiagnosticPrinter() = default; virtual void Print(const DiagnosticBase &diagnostic) const = 0; + virtual void Print(const DiagnosticBase &diagnostic, std::ostream &out) const = 0; }; class CLIDiagnosticPrinter : public DiagnosticPrinter { @@ -44,6 +45,7 @@ public: ~CLIDiagnosticPrinter() override = default; void Print(const DiagnosticBase &diagnostic) const override; + void Print(const DiagnosticBase &diagnostic, std::ostream &out) const override; }; using DiagnosticStorage = std::vector>; @@ -134,6 +136,7 @@ public: } void FlushDiagnostic(); + std::string PrintAndFlushErrorDiagnostic(); void SetWError(bool wError) { wError_ = wError; @@ -174,6 +177,7 @@ private: bool IsError(DiagnosticType type) const; DiagnosticStorage GetAllDiagnostic(); + DiagnosticStorage GetErrorDiagnostic(); void WriteLog(const DiagnosticBase &error); private: