Вы всегда можете посмотреть на код компилятора F # в качестве одного примера (хотя в реальном мире код всегда немного беспорядочный :)):
https://github.com/fsharp/fsharp/blob/master/src/fsharp/ErrorLogger.fs
У нас естьИнтерфейс ErrorLogger с предупреждениями и «приемниками» ошибок, а также различными частями ошибок и предупреждений компилятора «приемников» для активного регистратора через интерфейс.
При обнаружении ошибки может быть сложно решить, следует ли выкидывать(и отказаться от локального потока управления) или войти и продолжить (чтобы получить больше информации, но рискуете больше каскадных ошибок).Есть много стратегий, чтобы справиться с этим, но все заканчивают тем, что были хитрыми, так как ваш типичный промышленный компилятор имеет тысячи диагностических средств, и люди могут писать неправильный код, по-видимому, бесконечным количеством способов и универсальным подходом для всех.Решение вряд ли обеспечит наилучший опыт для каждой ошибки или даже для каждой распространенной ошибки.
Как кто-то сказал, компиляторы универсально записывают вывод в stdout / stderr в каноническом формате.MSBuild и Visual Studio анализируют выходные данные сборки, чтобы высветить список ошибок и ошибки в интерфейсе IDE.Для инкрементной обратной связи при наборе (а не построении) VS также «размещает» внешний интерфейс компилятора в процессе и читает сообщения об ошибках непосредственно из «приемников».
Пока выпо крайней мере, у одной границы абстракции (например, функции LogWarning
и LogError
, которая может быть даже глобальной, просто убедитесь, что ее используют все предупреждения / ошибки), тогда вы всегда сможете реорганизовать систему для удовлетворения меняющихся потребностей / проектов.