Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generates problem markers for a C++ project using clang-tidy #5533

Merged
merged 1 commit into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 56 additions & 4 deletions packages/cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ To get this working, you need to enable clangd's global index using the

## Using the clang-tidy linter

Note: This functionality is available when using clangd 9 and later.
**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:
You can set the preference 'cpp.clangTidy' to enable the clang-tidy linter included in clangd. When the preference is enabled, there are two ways to choose 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.
- using the file '.clang-tidy' . This 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.
**Note**: When the preference setting for "cpp.clangTidyChecks" is set, the configs will be merged with the configuration found in the ".clang-tidy" file. If you want to drop the configs from ".clang-tidy", you'd need to disable it in "cpp.clangTidyChecks" with **"cpp.clangTidyChecks": "-*"**.

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

Expand All @@ -102,6 +102,58 @@ There are two ways to configure clang-tidy's checks: through a Theia preference
- for the .clang-tidy file: Checks: "-*,readability-*"
- Meaning: disable all list-checks and enable all readability-* checks

### Running clang-tidy as a task

To be able to run clang-tidy as a task, you need to install the program.
vince-fugnitto marked this conversation as resolved.
Show resolved Hide resolved

```bash
UNIX
sudo apt-get install clang-tidy
Note: not all operating system are currently supported with this linter yet.
```

```
The clang-tidy task will read the "checks" and other configuration fields from the ".clang-tidy" file located in the closest parent directory of the source file.
P.S. You do not need to provide a value for each field.

Those configurations fields can be:
Checks
CheckOptions
FormatStyle
HeaderFilterRegex
User
WarningsAsErrors

You can run the following command to have an idea of the fields found in file ".clang-tidy"
clang-tidy -dump-config
```

In .theia/tasks.json, add the following:

```json
{
"label": "[Task] clang-tidy",
"type": "shell",
"cwd": "${workspaceFolder}",
"command": "clang-tidy",
"args": [
"*"
],
"options": {},
"problemMatcher": [
"$clangTidyMatcher"
]
}
```

If you want a description for each task field, see [theia/packages/task/src/browser/task-schema-updater.ts]( https://github.com/theia-ide/theia/blob/531aa3bde8dea7f022ea41beaee3aace65ce54de/packages/task/src/browser/task-schema-updater.ts#L62 )

```bash
When there is no compilation database, clang-tidy could run but you may need to be more specific which files to select. One way is to replace the "args" from the "*" to
"**/*.cpp" to only parse files with the "cpp" extension or
"**/*.c" to parse the "c" files extension.
```

## License

- [Eclipse Public License 2.0](http://www.eclipse.org/legal/epl-2.0/)
Expand Down
11 changes: 8 additions & 3 deletions packages/cpp/src/browser/cpp-task-provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import { TaskResolverRegistry } from '@theia/task/lib/browser/task-contribution'
import { CppBuildConfigurationManager, CppBuildConfiguration } from './cpp-build-configurations';
import { Event } from '@theia/core';
import { expect } from 'chai';
import { TaskConfiguration } from '@theia/task/src/common';
import { TaskConfiguration } from '@theia/task/lib/common';
import { ProcessTaskConfiguration } from '@theia/task/lib/common/process/task-protocol';
import { TaskDefinitionRegistry } from '@theia/task/lib/browser';
import { TaskDefinitionRegistry } from '@theia/task/lib/browser/task-definition-registry';
import { ProblemMatcherRegistry } from '@theia/task/lib/browser/task-problem-matcher-registry';
import { ProblemPatternRegistry } from '@theia/task/lib/browser/task-problem-pattern-registry';

// The object under test.
let taskProvider: CppTaskProvider;
Expand Down Expand Up @@ -67,9 +69,12 @@ class MockCppBuildConfigurationManager implements CppBuildConfigurationManager {
beforeEach(function () {
const container: Container = new Container();
container.bind(CppTaskProvider).toSelf().inSingletonScope();
container.bind(CppBuildConfigurationManager).to(MockCppBuildConfigurationManager);
container.bind(TaskResolverRegistry).toSelf().inSingletonScope();
container.bind(TaskDefinitionRegistry).toSelf().inSingletonScope();
container.bind(CppBuildConfigurationManager).to(MockCppBuildConfigurationManager);
container.bind(ProblemMatcherRegistry).toSelf().inSingletonScope();
container.bind(ProblemPatternRegistry).toSelf().inSingletonScope();

taskProvider = container.get(CppTaskProvider);

// Register a task resolver of type 'shell', on which the cpp build tasks
Expand Down
31 changes: 28 additions & 3 deletions packages/cpp/src/browser/cpp-task-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import parseArgv = require('string-argv');
import { inject, injectable, postConstruct } from 'inversify';
import { ProcessTaskConfiguration } from '@theia/task/lib/common/process/task-protocol';
import { TaskDefinitionRegistry } from '@theia/task/lib/browser';
import { TaskContribution, TaskProvider, TaskProviderRegistry, TaskResolver, TaskResolverRegistry } from '@theia/task/lib/browser/task-contribution';
import { CppBuildConfigurationManager, CppBuildConfiguration } from './cpp-build-configurations';
import { ContributedTaskConfiguration, TaskConfiguration, } from '@theia/task/lib/common/task-protocol';
import { ContributedTaskConfiguration, TaskConfiguration } from '@theia/task/lib/common/task-protocol';
import { TaskDefinitionRegistry } from '@theia/task/lib/browser/task-definition-registry';
import { ProblemMatcherRegistry } from '@theia/task/lib/browser/task-problem-matcher-registry';
import { ProblemPatternRegistry } from '@theia/task/lib/browser/task-problem-pattern-registry';

/**
* Data required to define a C/C++ build task the user could run.
Expand All @@ -38,10 +40,33 @@ export class CppTaskProvider implements TaskContribution, TaskProvider, TaskReso
@inject(TaskResolverRegistry) protected readonly taskResolverRegistry: TaskResolverRegistry;
@inject(TaskDefinitionRegistry) protected readonly taskDefinitionRegistry: TaskDefinitionRegistry;
@inject(CppBuildConfigurationManager) protected readonly cppBuildConfigurationManager: CppBuildConfigurationManager;
@inject(ProblemMatcherRegistry) protected readonly problemMatcherRegistry: ProblemMatcherRegistry;
@inject(ProblemPatternRegistry) protected readonly problemPatternRegistry: ProblemPatternRegistry;

@postConstruct()
protected init(): void {
this.registerTaskDefinition();
this.problemPatternRegistry.register({
'name': 'clangTidyPattern',
'regexp': '^(.+):(\\d+):(\\d+):\\s+(error|warning|info|note):\\s+(.+?)\\s+\\[(.+)\\]$',
'file': 1,
'line': 2,
'character': 3,
'severity': 4,
'message': 5,
'code': 6
});
this.problemMatcherRegistry.register({
'name': 'clangTidyMatcher',
'label': 'Clang-tidy problems',
'owner': 'clang-tidy',
'source': 'clang-tidy-task',
'applyTo': 'alldocuments',
'fileLocation': [
'absolute'
],
'pattern': 'clangTidyPattern'
});
}

registerProviders(registry: TaskProviderRegistry) {
Expand Down Expand Up @@ -77,7 +102,7 @@ export class CppTaskProvider implements TaskContribution, TaskProvider, TaskReso
type: 'shell',
command,
args,
options: { cwd: task.config.directory }
cwd: task.config.directory,
};
return resolver.resolveTask(resolvedTask);
}
Expand Down