Skip to content

Commit

Permalink
Add preferences to handle clang-tidy functionality when clangd v9+ is…
Browse files Browse the repository at this point in the history
… used.

Fixes issue #4579
This is a new linter for C/C++. There are two ways to initiate the linter:
  - From the preferences
  - Adding a new file located in the same folder of the files or a parent folder: .clang-tidy

Signed-off-by: Jacques Bouthillier <jacques.bouthillier@ericsson.com>
  • Loading branch information
lmcbout committed Mar 25, 2019
1 parent 5cbb4f1 commit 29299e4
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 12 deletions.
25 changes: 15 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Change Log

## v0.5.0

- [cpp] added new clang-tidy and clang-tidy-checks preferences to lint cpp program when clangd v9+ is used.
- [plugin] `workspace.openTextDocument` API now respects the contributed `FileSystemProviders`

Breaking changes:

- [editor] computation of resource context keys moved to core [#4531](https://github.com/theia-ide/theia/pull/4531)
- [plugin] support multiple windows per a backend [#4509](https://github.com/theia-ide/theia/issues/4509)
- Some plugin bindings are scoped per a connection now. Clients, who contribute/rebind these bindings, will need to scope them per a connection as well.
Expand All @@ -12,6 +15,7 @@ Breaking changes:
- In side bars a widget title is rendered as an icon.

## v0.4.0

- [application-manager] added support for pre-load HTML templates
- [console] added support for console `when` contexts
- [core] added support for os `when` contexts
Expand Down Expand Up @@ -86,8 +90,8 @@ Breaking changes:
- [workspace] fixed displaying the `Open With...` context menu only when more than one open handler is present
- [mini-browser] improved handling of iframe errors and time-outs


Breaking changes:

- menus aligned with built-in VS Code menus [#4173](https://github.com/theia-ide/theia/pull/4173)
- navigator context menu group changes:
- `1_open` and `4_new` replaced by `navigation` group
Expand Down Expand Up @@ -123,8 +127,8 @@ Breaking changes:
- `affects` function is added to `PreferenceChangeEvent` and `PreferenceChange` interface
- `navigator.exclude` preference is renamed to `files.exclude` [#4274](https://github.com/theia-ide/theia/pull/4274)


## v0.3.19

- [core] added `hostname` alias
- [core] added new `editor.formatOnSave` preference, to format documents on manual save
- [core] added support for setting end of line character
Expand Down Expand Up @@ -164,8 +168,8 @@ Breaking changes:
- [task] fixed cwd path
- [workspace] added multiple-root support for `WorkspaceService.getWorkspaceRootUri()`


## v0.3.18

- [core] added a preference to define how to handle application exit
- [core] added a way to prevent application exit from extensions
- [core] added functionality to prevent application exit if some editors are dirty
Expand Down Expand Up @@ -203,8 +207,8 @@ Breaking changes:
- [workspace] fixed long label computations for multiple-root workspaces
- [xterm] updated Xterm to `3.9.1`


## v0.3.17

- Added better widget error handling for different use cases (ex: no workspace present, no repository present, ...)
- Addressed multiple backend memory leaks
- Prefixed quick-open commands for easier categorization and searching
Expand Down Expand Up @@ -241,8 +245,8 @@ Breaking changes:
- [workspace] added the context menu item `Collapse All` for the file navigator
- [workspace] included workspace path as part of the URL fragment


## v0.3.16

- Reverted [cpp] Add debugging for C/C++ programs. This feature will come back in its own cpp-specific repo
- [callhierarchy][typescript] adapt to hierarchical document symbols
- [core] added methods to un-register menus, commands and keybindings
Expand All @@ -254,8 +258,8 @@ Breaking changes:
- [terminal] added 'open in terminal' to navigator
- [windows] implemented drives selector for the file dialog


## v0.3.15

- [cpp] added debugging for C/C++ programs
- [debug] added debug toolbar
- [debug] resolved variables in configurations
Expand All @@ -265,8 +269,8 @@ Breaking changes:
- [plug-in] added `menus` contribution point
- [workspace] added multi-root workspace support with vscode compatibility


## v0.3.13

- Re-implemented additional widgets using React
- Re-implemented miscellaneous components using React
- [cpp] added a status bar button to select an active cpp build configuration
Expand All @@ -280,12 +284,12 @@ Breaking changes:
- [ts] added support for one ls for all JavaScript related languages
- [workspace] added support for recently opened workspaces history


## v0.3.12

- New Plugin system !
- See [design](https://github.com/theia-ide/theia/issues/1482) and [documentation](https://github.com/theia-ide/theia/blob/master/packages/plugin/API.md) for more details.
- See [design](https://github.com/theia-ide/theia/issues/1482) and [documentation](https://github.com/theia-ide/theia/blob/master/packages/plugin/API.md) for more details.
- Introducing [Task API](https://github.com/theia-ide/theia/pull/2086).
- Note, the format of tasks.json has been changed. For details, see the Task extension's [README.md](https://github.com/theia-ide/theia/blob/master/packages/task/README.md).
- Note, the format of tasks.json has been changed. For details, see the Task extension's [README.md](https://github.com/theia-ide/theia/blob/master/packages/task/README.md).
- Added an UI when developing plugins
- Migrated widgets to `react`
- Theia alerts you when the opening of a new tab is denied by the browser
Expand All @@ -301,6 +305,7 @@ Breaking changes:
- `HTML` files now open in the editor by default

## v0.3.11

- Added search and replace widget
- Added the ability to delete files on OSX with cmd+backspace
- Added the ability to set more finely grained logger levels
Expand Down
24 changes: 24 additions & 0 deletions packages/cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,30 @@ To get this working, you need to enable clangd's global index using the
"cpp.clangdArgs": "--background-index"
}

## Using the clang-tidy linter

Note: This functionality is available when using clangd 9 and later.

You can set the preference 'cpp.clangTidy' to enable the clang-tidy linter included in clangd. When the preference is set, there are two ways to chose which of its built-in checks clang-tidy will use:

- using the preferences: 'cpp.clangTidyChecks'
- using the file '.clang-tidy' . The file is located in the same folder of the files or a parent folder.

Note: using the preference checks will supersede the value found in the .clang-tidy file.

The syntax used to fill the checks can be found at http://clang.llvm.org/extra/clang-tidy/

clang-tidy has its own checks and can also run Clang static analyzer checks. Each check has a name ([see link above for full list](http://clang.llvm.org/extra/clang-tidy/)). Clang-tidy takes as input the checks that should run, in the form of a comma-separated list of positive and negative (prefixed with -) globs. Positive globs add subsets of checks, negative globs remove them.

There are two ways to configure clang-tidy's checks: through a Theia preference or using a .clang-tidy config file. Here are examples for both:"

- for the preferences: "cpp.clangTidyChecks": "*,-readability-*"
- Meaning: enables all list-checks and disable all readability-* checks

- for the .clang-tidy file: Checks: "-*,readability-*"
- Meaning: disable all list-checks and enable all readability-* checks

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
- [一 (Secondary) GNU General Public License, version 2 with the GNU Classpath Exception](https://projects.eclipse.org/license/secondary-gpl-2.0-cp)
9 changes: 8 additions & 1 deletion packages/cpp/src/browser/cpp-language-client-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export class CppLanguageClientContribution extends BaseLanguageClientContributio
@postConstruct()
protected init() {
this.cppBuildConfigurations.onActiveConfigChange(config => this.onActiveBuildConfigChanged(config));
this.cppPreferences.onPreferenceChanged(e => {
if (this.running) {
this.restart();
}
});
}

protected onReady(languageClient: ILanguageClient): void {
Expand Down Expand Up @@ -140,7 +145,9 @@ export class CppLanguageClientContribution extends BaseLanguageClientContributio
protected getStartParameters(): CppStartParameters {
return {
clangdExecutable: this.cppPreferences['cpp.clangdExecutable'],
clangdArgs: this.cppPreferences['cpp.clangdArgs']
clangdArgs: this.cppPreferences['cpp.clangdArgs'],
clangTidy: this.cppPreferences['cpp.clangTidy'],
clangTidyChecks: this.cppPreferences['cpp.clangTidyChecks']
};
}
}
12 changes: 12 additions & 0 deletions packages/cpp/src/browser/cpp-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ export const cppPreferencesSchema: PreferenceSchema = {
description: 'Specify the arguments to pass to clangd when starting the language server.',
default: '',
type: 'string'
},
'cpp.clangTidy': {
description: 'Enable/disable C/C++ linting.',
default: false,
type: 'boolean'
},
'cpp.clangTidyChecks': {
description: 'Specify comma separated arguments to pass to clang-tidy. Activated only if cpp.clang-tidy is enabled',
default: '',
type: 'string'
}
}
};
Expand All @@ -70,6 +80,8 @@ export class CppConfiguration {
'cpp.experimentalCommands': boolean;
'cpp.clangdExecutable': string;
'cpp.clangdArgs': string;
'cpp.clangTidy': boolean;
'cpp.clangTidyChecks': string;
}

export const CppPreferences = Symbol('CppPreferences');
Expand Down
2 changes: 2 additions & 0 deletions packages/cpp/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ export const CLANGD_EXECUTABLE_DEFAULT = 'clangd';
export interface CppStartParameters {
clangdExecutable: string;
clangdArgs: string;
clangTidy?: boolean;
clangTidyChecks?: string;
}
29 changes: 28 additions & 1 deletion packages/cpp/src/node/cpp-contribution.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2017 Ericsson and others.
* Copyright (C) 2017-2019 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -42,7 +42,34 @@ export class CppContribution extends BaseLanguageServerContribution {
|| undefined
);

const clangTidy = parameters && parameters.clangTidy;
const clangTidyChecks = parameters && parameters.clangTidyChecks;

if (clangTidy) {
const supportsClangTidy = await this.testSupportsClangTidy(command);
if (supportsClangTidy) {
args.push('-clang-tidy');
if (typeof clangTidyChecks === 'string' && clangTidyChecks.length > 0) {
args.push(`-clang-tidy-checks=${clangTidyChecks}`);
}
}
}
const serverConnection = await this.createProcessStreamConnectionAsync(command, args);
this.forward(clientConnection, serverConnection);
}

protected async testSupportsClangTidy(command: string): Promise<boolean> {
// clangd should fail if -clang-tidy flag is not supported
// but if it is supported, it will run forever until killed/stopped.
// to avoid that, we pass -version flag which makes it exit early.
const process = await super.spawnProcessAsync(command, ['-clang-tidy', '-version']);
return new Promise<boolean>(resolve => {
process.errorOutput.on('data', (data: string) => {
if (data.includes('-clang-tidy')) {
resolve(false);
}
});
process.errorOutput.once('close', () => resolve(true));
});
}
}

0 comments on commit 29299e4

Please sign in to comment.