diff --git a/CHANGELOG.md b/CHANGELOG.md index 23ad12b6..210158af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added NAG (`nagfor`) compiler support for linting + ([#476](https://github.com/fortran-lang/vscode-fortran-support/issues/476)) - Added `Modern Fortran`, `fortls` and `fpm` as keywords to the extension ([#536](https://github.com/fortran-lang/vscode-fortran-support/issues/536)) diff --git a/README.md b/README.md index 9a3857c3..80a5afa0 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ - GoTo/Peek implementation and Find/Peek references - Project-wide and Document symbol detection and Renaming - [Native Language Server integration](#language-server-integration) with [`fortls`](https://github.com/gnikit/fortls) -- [Linting support](#linting) for GCC's [`gfortran`](https://gcc.gnu.org/wiki/GFortran), and Intel's [`ifort`](https://www.intel.com/content/www/us/en/developer/tools/oneapi/fortran-compiler.html), `ifx` +- [Linting support](#linting): GNU's [`gfortran`](https://gcc.gnu.org/wiki/GFortran), Intel's [`ifort`](https://www.intel.com/content/www/us/en/developer/tools/oneapi/fortran-compiler.html), `ifx`, NAG's [`nagfor`](https://www.nag.co.uk/nagfor/) - [Interactive Debugger with UI](#debugging) - [Formatting](#formatting) with [findent](https://github.com/gnikit/findent-pypi) or [fprettify](https://github.com/pseewald/fprettify) - [Code snippets](#snippets) (more can be defined by the user [see](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_create-your-own-snippets)) @@ -81,6 +81,12 @@ For more about the Language Server's capabilities please refer to the Linting allows for compiler error and warning detection while coding without the user having to compile. +| Vendor | Compiler | +| --------------------------------------------------------------------------------------------- | -------------- | +| [GNU](https://gcc.gnu.org/wiki/GFortran) | `gfortran` | +| [Intel](https://www.intel.com/content/www/us/en/developer/tools/oneapi/fortran-compiler.html) | `ifort`, `ifx` | +| [NAG](https://www.nag.com/) | `nagfor` | + Using an invalid if expression ![alt](assets/gif/lint-demo.gif) diff --git a/package.json b/package.json index 337579c5..a7a095e5 100644 --- a/package.json +++ b/package.json @@ -195,6 +195,7 @@ "gfortran", "ifort", "ifx", + "nagfor", "Disabled" ], "markdownDescription": "Compiler used for linting support." diff --git a/src/features/linter-provider.ts b/src/features/linter-provider.ts index 8f00b65d..4d581a6c 100644 --- a/src/features/linter-provider.ts +++ b/src/features/linter-provider.ts @@ -132,7 +132,8 @@ export class FortranLintingProvider { ...args, ...this.getIncludeParams(includePaths), // include paths textDocument.fileName, - `-o ${fileNameWithoutExtension}.mod`, + '-o', + `${fileNameWithoutExtension}.mod`, ]; return argList.map(arg => arg.trim()).filter(arg => arg !== ''); @@ -148,6 +149,10 @@ export class FortranLintingProvider { modFlag = '-module'; break; + case 'nagfor': + modFlag = '-mdir'; + break; + default: modFlag = '-J'; break; @@ -270,7 +275,7 @@ export class FortranLintingProvider { // gfortran and flang have compiler flags for restricting the width of // the code. // You can always override by passing in the correct args as extraArgs - if (compiler !== 'ifort' && compiler !== 'ifx') { + if (compiler === 'gfortran') { const ln: number = config.get('fortls.maxLineLength'); const lnStr: string = ln === -1 ? 'none' : ln.toString(); args.push(`-ffree-line-length-${lnStr}`, `-ffixed-line-length-${lnStr}`); @@ -379,11 +384,59 @@ export class FortranLintingProvider { } return diagnostics; + case 'nagfor': + return this.linterParserNagfor(matches); + default: break; } } + private linterParserNagfor(matches: RegExpMatchArray[]) { + const diagnostics: vscode.Diagnostic[] = []; + for (const m of matches) { + const g = m.groups; + const fname: string = g['fname']; + const lineNo: number = parseInt(g['ln']); + const msg_type: string = g['sev1']; + const msg: string = g['msg1']; + // NAGFOR does not have a column number, so get the entire line + const range = vscode.window.activeTextEditor.document.lineAt(lineNo - 1).range; + + let severity: vscode.DiagnosticSeverity; + switch (msg_type.toLowerCase()) { + case 'panic': + case 'fatal': + case 'error': + case 'fatal error': + severity = vscode.DiagnosticSeverity.Error; + break; + + case 'extension': + case 'questionable': + case 'deleted feature used': + case 'warning': + severity = vscode.DiagnosticSeverity.Warning; + break; + + case 'remark': + case 'note': + case 'info': + severity = vscode.DiagnosticSeverity.Information; + break; + + default: + severity = vscode.DiagnosticSeverity.Error; + console.log('Unknown severity: ' + msg_type); + break; + } + + const d = new vscode.Diagnostic(range, msg, severity); + diagnostics.push(d); + } + return diagnostics; + } + /** * Different compilers, display errors in different ways, hence we need * different regular expressions to interpret their output. @@ -427,6 +480,9 @@ export class FortranLintingProvider { // see https://regex101.com/r/GZ0Lzz/2 return /^(?(?:\w:\\)?.*)\((?\d+)\):\s*(?:#(?:(?\w*):\s*(?.*$))|(?\w*)\s*(?.*$)(?:\s*.*\s*)(?-*\^))/gm; + case 'nagfor': + return /^(?Remark|Info|Note|Warning|Questionable|Extension|Deleted feature used|Error|Fatal(?: Error)?|Panic)(\(\w+\))?: (?[\S ]+), line (?\d+): (?.+)$/gm; + default: vscode.window.showErrorMessage('Unsupported linter, change your linter.compiler option'); } @@ -454,6 +510,9 @@ export class FortranLintingProvider { case 'ifort': return ['-syntax-only', '-fpp']; + case 'nagfor': + return ['-M', '-quiet']; + default: break; } diff --git a/updates/RELEASE_NOTES-v3.2.md b/updates/RELEASE_NOTES-v3.2.md index ecdf33d0..163631ad 100644 --- a/updates/RELEASE_NOTES-v3.2.md +++ b/updates/RELEASE_NOTES-v3.2.md @@ -1,6 +1,19 @@ # What's New (v3.2) -## Changes +## 🎉 Modern Fortran Release of v3.2 🎉! + +- [Linting](#linting) +- [Other Changes](#other-changes) + - [Added](#added) + - [Changed](#changed) + - [Fixed](#fixed) + +## Linting + +Added linting support for [NAG](https://www.nag.com/content/nag-fortran-compiler)'s +`nagfor` compiler. Compiler diagnostics should now be served via the _Modern Fortran_ linter. + +## Other Changes ### Added