;;; csharp-compilation.el --- compilation support for C# -*- lexical-binding: t; -*- ;; Copyright (C) 2020-2021 Free Software Foundation, Inc. ;; Author : Theodor Thornhill ;; Maintainer : Jostein Kjønigsen ;; Theodor Thornhill ;; Created : September 2020 ;; Modified : 2020 ;; Version : 2.0.0 ;; Keywords : c# languages oop mode ;; X-URL : https://github.com/emacs-csharp/csharp-mode ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (require 'compile) ;; When invoked by MSBuild, csc’s errors look like this: ;; subfolder\file.cs(6,18): error CS1006: Name of constructor must ;; match name of class [c:\Users\user\project.csproj] (defun csharp--compilation-error-file-resolve () "Resolve an msbuild error to a (filename . dirname) cons cell." ;; http://stackoverflow.com/a/18049590/429091 (cons (match-string 1) (file-name-directory (match-string 4)))) (defconst csharp-compilation-re-msbuild-error (concat "^[[:blank:]]*\\(?:[[:digit:]]+>\\)?" "\\([^(\r\n)]+\\)(\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)?): " "error [[:alnum:]]+: [^\r\n]+\\[\\([^]\r\n]+\\)\\]$") "Regexp to match compilation error from msbuild.") (defconst csharp-compilation-re-msbuild-warning (concat "^[[:blank:]]*\\(?:[[:digit:]]+>\\)?" "\\([^(\r\n)]+\\)(\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)?): " "warning [[:alnum:]]+: [^\r\n]+\\[\\([^]\r\n]+\\)\\]$") "Regexp to match compilation warning from msbuild.") ;; Notes on xbuild and devenv commonalities ;; ;; These regexes were tailored for xbuild, but apart from the concurrent ;; build-marker ("1>") they share exactly the same match-markers. ;; ;; If we don't exclude the match-markers explicitly, these regexes ;; will also be used to match for devenv as well, including the build-marker ;; in the file-name, causing the lookup to fail. ;; ;; So if we don't want devenv to fail, we actually need to handle it in our ;; xbuild-regexes, but then we automatically get devenv-support for free. (defconst csharp-compilation-re-xbuild-error (concat "^[[:blank:]]*\\(?:[[:digit:]]+>\\)?" "\\([^(\r\n)]+\\)(\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)?" ;; handle weird devenv output format with 4 numbers, not 2 by having optional ;; extra capture-groups. "\\(?:,\\([0-9]+\\)\\)*): " "error [[:alnum:]]+: .+$") "Regexp to match compilation error from xbuild.") (defconst csharp-compilation-re-xbuild-warning (concat "^[[:blank:]]*\\(?:[[:digit:]]+>\\)?" "\\([^(\r\n)]+\\)(\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)?" ;; handle weird devenv output format with 4 numbers, not 2 by having optional ;; extra capture-groups. "\\(?:,\\([0-9]+\\)\\)*): " "warning [[:alnum:]]+: .+$") "Regexp to match compilation warning from xbuild.") (defconst csharp-compilation-re-dotnet-error "\\([^\r\n]+\\) : error [A-Z]+[0-9]+:") (defconst csharp-compilation-re-dotnet-warning "\\([^\r\n]+\\) : warning [A-Z]+[0-9]+:") (defconst csharp-compilation-re-dotnet-testfail (concat "[[:blank:]]+Stack Trace:\n" "[[:blank:]]+at [^\n]+ in \\([^\n]+\\):line \\([0-9]+\\)")) (eval-after-load 'compile (lambda () (dolist (regexp `((dotnet-testfail ,csharp-compilation-re-dotnet-testfail 1 2) (xbuild-error ,csharp-compilation-re-xbuild-error 1 2 3 2) (xbuild-warning ,csharp-compilation-re-xbuild-warning 1 2 3 1) (msbuild-error ,csharp-compilation-re-msbuild-error csharp--compilation-error-file-resolve 2 3 2 nil (1 compilation-error-face) (4 compilation-error-face)) (msbuild-warning ,csharp-compilation-re-msbuild-warning csharp--compilation-error-file-resolve 2 3 1 nil (1 compilation-warning-face) (4 compilation-warning-face)) (dotnet-error ,csharp-compilation-re-dotnet-error 1) (dotnet-warning ,csharp-compilation-re-dotnet-warning 1 nil nil 1))) (add-to-list 'compilation-error-regexp-alist-alist regexp) (add-to-list 'compilation-error-regexp-alist (car regexp))))) (provide 'csharp-compilation) ;;; csharp-compilation.el ends here